diff --git a/Evergreen.xcodeproj/project.pbxproj b/Evergreen.xcodeproj/project.pbxproj index 248260f52..a16ec029e 100644 --- a/Evergreen.xcodeproj/project.pbxproj +++ b/Evergreen.xcodeproj/project.pbxproj @@ -24,6 +24,8 @@ 84B06FD01ED37F7D00F0B54B /* DB5.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84B06FCC1ED37F7200F0B54B /* DB5.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 84B06FE91ED3803A00F0B54B /* RSFeedFinder.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84B06FE61ED3803200F0B54B /* RSFeedFinder.framework */; }; 84B06FEA1ED3803A00F0B54B /* RSFeedFinder.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84B06FE61ED3803200F0B54B /* RSFeedFinder.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 84B06FFD1ED3818D00F0B54B /* RSTree.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84B06FFA1ED3818000F0B54B /* RSTree.framework */; }; + 84B06FFE1ED3818D00F0B54B /* RSTree.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84B06FFA1ED3818000F0B54B /* RSTree.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -188,6 +190,27 @@ remoteGlobalIDString = 84BAAE1E1C8E6B3B009F5239; remoteInfo = RSFeedFinder; }; + 84B06FF91ED3818000F0B54B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84B06FF41ED3818000F0B54B /* RSTree.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 842A0BE11CFCB9BC00BF746C; + remoteInfo = RSTree; + }; + 84B06FFB1ED3818000F0B54B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84B06FF41ED3818000F0B54B /* RSTree.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 842A0BEB1CFCB9BC00BF746C; + remoteInfo = RSTreeTests; + }; + 84B06FFF1ED3818D00F0B54B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84B06FF41ED3818000F0B54B /* RSTree.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 842A0BE01CFCB9BC00BF746C; + remoteInfo = RSTree; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -199,6 +222,7 @@ files = ( 84B06FB31ED37DBD00F0B54B /* RSDatabase.framework in Embed Frameworks */, 84B06FEA1ED3803A00F0B54B /* RSFeedFinder.framework in Embed Frameworks */, + 84B06FFE1ED3818D00F0B54B /* RSTree.framework in Embed Frameworks */, 84B06FAF1ED37DBD00F0B54B /* RSCore.framework in Embed Frameworks */, 84B06FD01ED37F7D00F0B54B /* DB5.framework in Embed Frameworks */, 84B06FC31ED37E9600F0B54B /* RSWeb.framework in Embed Frameworks */, @@ -225,6 +249,7 @@ 84B06FB61ED37E8B00F0B54B /* RSWeb.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSWeb.xcodeproj; path = Frameworks/RSWeb/RSWeb.xcodeproj; sourceTree = ""; }; 84B06FC61ED37F7200F0B54B /* DB5.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = DB5.xcodeproj; path = Frameworks/DB5/DB5.xcodeproj; sourceTree = ""; }; 84B06FE01ED3803200F0B54B /* RSFeedFinder.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSFeedFinder.xcodeproj; path = Frameworks/RSFeedFinder/RSFeedFinder.xcodeproj; sourceTree = ""; }; + 84B06FF41ED3818000F0B54B /* RSTree.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSTree.xcodeproj; path = Frameworks/RSTree/RSTree.xcodeproj; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -234,6 +259,7 @@ files = ( 84B06FB21ED37DBD00F0B54B /* RSDatabase.framework in Frameworks */, 84B06FE91ED3803A00F0B54B /* RSFeedFinder.framework in Frameworks */, + 84B06FFD1ED3818D00F0B54B /* RSTree.framework in Frameworks */, 84B06FAE1ED37DBD00F0B54B /* RSCore.framework in Frameworks */, 84B06FCF1ED37F7D00F0B54B /* DB5.framework in Frameworks */, 84B06FC21ED37E9600F0B54B /* RSWeb.framework in Frameworks */, @@ -265,6 +291,7 @@ 84B06FA21ED37DAC00F0B54B /* RSCore.xcodeproj */, 84B06F961ED37DA000F0B54B /* RSDatabase.xcodeproj */, 84B06FE01ED3803200F0B54B /* RSFeedFinder.xcodeproj */, + 84B06FF41ED3818000F0B54B /* RSTree.xcodeproj */, 84B06FB61ED37E8B00F0B54B /* RSWeb.xcodeproj */, 84B06F761ED37BCA00F0B54B /* RSXML.xcodeproj */, ); @@ -346,6 +373,15 @@ name = Products; sourceTree = ""; }; + 84B06FF51ED3818000F0B54B /* Products */ = { + isa = PBXGroup; + children = ( + 84B06FFA1ED3818000F0B54B /* RSTree.framework */, + 84B06FFC1ED3818000F0B54B /* RSTreeTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -367,6 +403,7 @@ 84B06FC51ED37E9600F0B54B /* PBXTargetDependency */, 84B06FD21ED37F7D00F0B54B /* PBXTargetDependency */, 84B06FEC1ED3803A00F0B54B /* PBXTargetDependency */, + 84B070001ED3818D00F0B54B /* PBXTargetDependency */, ); name = Evergreen; productName = Evergreen; @@ -442,6 +479,10 @@ ProductGroup = 84B06FE11ED3803200F0B54B /* Products */; ProjectRef = 84B06FE01ED3803200F0B54B /* RSFeedFinder.xcodeproj */; }, + { + ProductGroup = 84B06FF51ED3818000F0B54B /* Products */; + ProjectRef = 84B06FF41ED3818000F0B54B /* RSTree.xcodeproj */; + }, { ProductGroup = 84B06FB71ED37E8B00F0B54B /* Products */; ProjectRef = 84B06FB61ED37E8B00F0B54B /* RSWeb.xcodeproj */; @@ -572,6 +613,20 @@ remoteRef = 84B06FE71ED3803200F0B54B /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + 84B06FFA1ED3818000F0B54B /* RSTree.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = RSTree.framework; + remoteRef = 84B06FF91ED3818000F0B54B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 84B06FFC1ED3818000F0B54B /* RSTreeTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = RSTreeTests.xctest; + remoteRef = 84B06FFB1ED3818000F0B54B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ @@ -649,6 +704,11 @@ name = RSFeedFinder; targetProxy = 84B06FEB1ED3803A00F0B54B /* PBXContainerItemProxy */; }; + 84B070001ED3818D00F0B54B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = RSTree; + targetProxy = 84B06FFF1ED3818D00F0B54B /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ diff --git a/Frameworks/RSTree/RSTree.xcodeproj/project.pbxproj b/Frameworks/RSTree/RSTree.xcodeproj/project.pbxproj new file mode 100644 index 000000000..c87e7edba --- /dev/null +++ b/Frameworks/RSTree/RSTree.xcodeproj/project.pbxproj @@ -0,0 +1,420 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 842A0BE51CFCB9BC00BF746C /* RSTree.h in Headers */ = {isa = PBXBuildFile; fileRef = 842A0BE41CFCB9BC00BF746C /* RSTree.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 842A0BEC1CFCB9BC00BF746C /* RSTree.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 842A0BE11CFCB9BC00BF746C /* RSTree.framework */; }; + 842A0BF11CFCB9BC00BF746C /* RSTreeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 842A0BF01CFCB9BC00BF746C /* RSTreeTests.swift */; }; + 842F4D0A1D7E027100C88094 /* NSOutlineView+RSTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = 842F4D091D7E027100C88094 /* NSOutlineView+RSTree.swift */; }; + 84B1EF931D5BC2A7008533AE /* TopLevelRepresentedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B1EF921D5BC2A7008533AE /* TopLevelRepresentedObject.swift */; }; + 84C567CA1CFCBA0E005B711B /* TreeController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C567C91CFCBA0E005B711B /* TreeController.swift */; }; + 84C567CC1CFCBA16005B711B /* Node.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C567CB1CFCBA16005B711B /* Node.swift */; }; + 84FEB30D1D7DE284008A237C /* NodePath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FEB30C1D7DE284008A237C /* NodePath.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 842A0BED1CFCB9BC00BF746C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 842A0BD81CFCB9BC00BF746C /* Project object */; + proxyType = 1; + remoteGlobalIDString = 842A0BE01CFCB9BC00BF746C; + remoteInfo = RSTree; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 842A0BE11CFCB9BC00BF746C /* RSTree.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RSTree.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 842A0BE41CFCB9BC00BF746C /* RSTree.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RSTree.h; path = RSTree/RSTree.h; sourceTree = ""; }; + 842A0BE61CFCB9BC00BF746C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = RSTree/Info.plist; sourceTree = ""; }; + 842A0BEB1CFCB9BC00BF746C /* RSTreeTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RSTreeTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 842A0BF01CFCB9BC00BF746C /* RSTreeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RSTreeTests.swift; sourceTree = ""; }; + 842A0BF21CFCB9BC00BF746C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 842F4D091D7E027100C88094 /* NSOutlineView+RSTree.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "NSOutlineView+RSTree.swift"; path = "RSTree/NSOutlineView+RSTree.swift"; sourceTree = ""; }; + 84B1EF921D5BC2A7008533AE /* TopLevelRepresentedObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TopLevelRepresentedObject.swift; path = RSTree/TopLevelRepresentedObject.swift; sourceTree = ""; }; + 84C567C91CFCBA0E005B711B /* TreeController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = TreeController.swift; path = RSTree/TreeController.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 84C567CB1CFCBA16005B711B /* Node.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = Node.swift; path = RSTree/Node.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 84FEB30C1D7DE284008A237C /* NodePath.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = NodePath.swift; path = RSTree/NodePath.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 842A0BDD1CFCB9BC00BF746C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 842A0BE81CFCB9BC00BF746C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 842A0BEC1CFCB9BC00BF746C /* RSTree.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 842A0BD71CFCB9BC00BF746C = { + isa = PBXGroup; + children = ( + 842A0BE41CFCB9BC00BF746C /* RSTree.h */, + 84C567C91CFCBA0E005B711B /* TreeController.swift */, + 84C567CB1CFCBA16005B711B /* Node.swift */, + 84FEB30C1D7DE284008A237C /* NodePath.swift */, + 84B1EF921D5BC2A7008533AE /* TopLevelRepresentedObject.swift */, + 842F4D091D7E027100C88094 /* NSOutlineView+RSTree.swift */, + 842A0BE61CFCB9BC00BF746C /* Info.plist */, + 842A0BEF1CFCB9BC00BF746C /* RSTreeTests */, + 842A0BE21CFCB9BC00BF746C /* Products */, + ); + sourceTree = ""; + }; + 842A0BE21CFCB9BC00BF746C /* Products */ = { + isa = PBXGroup; + children = ( + 842A0BE11CFCB9BC00BF746C /* RSTree.framework */, + 842A0BEB1CFCB9BC00BF746C /* RSTreeTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 842A0BEF1CFCB9BC00BF746C /* RSTreeTests */ = { + isa = PBXGroup; + children = ( + 842A0BF01CFCB9BC00BF746C /* RSTreeTests.swift */, + 842A0BF21CFCB9BC00BF746C /* Info.plist */, + ); + path = RSTreeTests; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 842A0BDE1CFCB9BC00BF746C /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 842A0BE51CFCB9BC00BF746C /* RSTree.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 842A0BE01CFCB9BC00BF746C /* RSTree */ = { + isa = PBXNativeTarget; + buildConfigurationList = 842A0BF51CFCB9BC00BF746C /* Build configuration list for PBXNativeTarget "RSTree" */; + buildPhases = ( + 842A0BDC1CFCB9BC00BF746C /* Sources */, + 842A0BDD1CFCB9BC00BF746C /* Frameworks */, + 842A0BDE1CFCB9BC00BF746C /* Headers */, + 842A0BDF1CFCB9BC00BF746C /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = RSTree; + productName = RSTree; + productReference = 842A0BE11CFCB9BC00BF746C /* RSTree.framework */; + productType = "com.apple.product-type.framework"; + }; + 842A0BEA1CFCB9BC00BF746C /* RSTreeTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 842A0BF81CFCB9BC00BF746C /* Build configuration list for PBXNativeTarget "RSTreeTests" */; + buildPhases = ( + 842A0BE71CFCB9BC00BF746C /* Sources */, + 842A0BE81CFCB9BC00BF746C /* Frameworks */, + 842A0BE91CFCB9BC00BF746C /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 842A0BEE1CFCB9BC00BF746C /* PBXTargetDependency */, + ); + name = RSTreeTests; + productName = RSTreeTests; + productReference = 842A0BEB1CFCB9BC00BF746C /* RSTreeTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 842A0BD81CFCB9BC00BF746C /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0730; + LastUpgradeCheck = 0730; + ORGANIZATIONNAME = "Ranchero Software, LLC"; + TargetAttributes = { + 842A0BE01CFCB9BC00BF746C = { + CreatedOnToolsVersion = 7.3; + LastSwiftMigration = 0800; + }; + 842A0BEA1CFCB9BC00BF746C = { + CreatedOnToolsVersion = 7.3; + LastSwiftMigration = 0800; + }; + }; + }; + buildConfigurationList = 842A0BDB1CFCB9BC00BF746C /* Build configuration list for PBXProject "RSTree" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 842A0BD71CFCB9BC00BF746C; + productRefGroup = 842A0BE21CFCB9BC00BF746C /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 842A0BE01CFCB9BC00BF746C /* RSTree */, + 842A0BEA1CFCB9BC00BF746C /* RSTreeTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 842A0BDF1CFCB9BC00BF746C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 842A0BE91CFCB9BC00BF746C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 842A0BDC1CFCB9BC00BF746C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 842F4D0A1D7E027100C88094 /* NSOutlineView+RSTree.swift in Sources */, + 84FEB30D1D7DE284008A237C /* NodePath.swift in Sources */, + 84C567CA1CFCBA0E005B711B /* TreeController.swift in Sources */, + 84C567CC1CFCBA16005B711B /* Node.swift in Sources */, + 84B1EF931D5BC2A7008533AE /* TopLevelRepresentedObject.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 842A0BE71CFCB9BC00BF746C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 842A0BF11CFCB9BC00BF746C /* RSTreeTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 842A0BEE1CFCB9BC00BF746C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 842A0BE01CFCB9BC00BF746C /* RSTree */; + targetProxy = 842A0BED1CFCB9BC00BF746C /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 842A0BF31CFCB9BC00BF746C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 842A0BF41CFCB9BC00BF746C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 842A0BF61CFCB9BC00BF746C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + COMBINE_HIDPI_IMAGES = YES; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_VERSION = A; + INFOPLIST_FILE = RSTree/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.RSTree; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 842A0BF71CFCB9BC00BF746C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + COMBINE_HIDPI_IMAGES = YES; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_VERSION = A; + INFOPLIST_FILE = RSTree/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.RSTree; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 842A0BF91CFCB9BC00BF746C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = RSTreeTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.RSTreeTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 842A0BFA1CFCB9BC00BF746C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = RSTreeTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.RSTreeTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 842A0BDB1CFCB9BC00BF746C /* Build configuration list for PBXProject "RSTree" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 842A0BF31CFCB9BC00BF746C /* Debug */, + 842A0BF41CFCB9BC00BF746C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 842A0BF51CFCB9BC00BF746C /* Build configuration list for PBXNativeTarget "RSTree" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 842A0BF61CFCB9BC00BF746C /* Debug */, + 842A0BF71CFCB9BC00BF746C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 842A0BF81CFCB9BC00BF746C /* Build configuration list for PBXNativeTarget "RSTreeTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 842A0BF91CFCB9BC00BF746C /* Debug */, + 842A0BFA1CFCB9BC00BF746C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 842A0BD81CFCB9BC00BF746C /* Project object */; +} diff --git a/Frameworks/RSTree/RSTree.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Frameworks/RSTree/RSTree.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..a896eeea0 --- /dev/null +++ b/Frameworks/RSTree/RSTree.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Frameworks/RSTree/RSTree/Info.plist b/Frameworks/RSTree/RSTree/Info.plist new file mode 100644 index 000000000..3343335ab --- /dev/null +++ b/Frameworks/RSTree/RSTree/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSHumanReadableCopyright + Copyright © 2016 Ranchero Software, LLC. All rights reserved. + NSPrincipalClass + + + diff --git a/Frameworks/RSTree/RSTree/NSOutlineView+RSTree.swift b/Frameworks/RSTree/RSTree/NSOutlineView+RSTree.swift new file mode 100644 index 000000000..0ac4c64b9 --- /dev/null +++ b/Frameworks/RSTree/RSTree/NSOutlineView+RSTree.swift @@ -0,0 +1,54 @@ +// +// NSOutlineView+RSTree.swift +// RSTree +// +// Created by Brent Simmons on 9/5/16. +// Copyright © 2016 Ranchero Software, LLC. All rights reserved. +// + +import Cocoa + +public extension NSOutlineView { + + @discardableResult + public func revealAndSelectNodeAtPath(_ nodePath: NodePath) -> Bool { + + // Returns true on success. Expands folders on the way. May succeed partially (returns false, in that case). + + let numberOfNodes = nodePath.components.count + if numberOfNodes < 2 { + return false + } + + let indexOfNodeToSelect = numberOfNodes - 1 + + for i in 1...indexOfNodeToSelect { // Start at 1 to skip root node. + + let oneNode = nodePath.components[i] + let oneRow = row(forItem: oneNode) + if oneRow < 0 { + return false + } + + if i == indexOfNodeToSelect { + selectRowIndexes(NSIndexSet(index: oneRow) as IndexSet, byExtendingSelection: false) + scrollRowToVisible(oneRow) + return true + } + else { + expandItem(oneNode) + } + } + + return false + } + + @discardableResult + public func revealAndSelectRepresentedObject(_ representedObject: AnyObject, _ treeController: TreeController) -> Bool { + + guard let nodePath = NodePath(representedObject: representedObject, treeController: treeController) else { + return false + } + return revealAndSelectNodeAtPath(nodePath) + } +} diff --git a/Frameworks/RSTree/RSTree/Node.swift b/Frameworks/RSTree/RSTree/Node.swift new file mode 100644 index 000000000..e31d61f40 --- /dev/null +++ b/Frameworks/RSTree/RSTree/Node.swift @@ -0,0 +1,112 @@ +// +// Node.swift +// Rainier +// +// Created by Brent Simmons on 7/21/15. +// Copyright © 2015 Ranchero Software, LLC. All rights reserved. +// + +import Foundation + +public final class Node: Equatable { + + public weak var parent: Node? + public let representedObject: AnyObject + public var canHaveChildNodes = false + public var isGroupItem = false + public var childNodes: [Node]? + + public var isRoot: Bool { + get { + if let _ = parent { + return false + } + return true + } + } + + public var numberOfChildNodes: Int { + get { + return childNodes?.count ?? 0 + } + } + + public var indexPath: IndexPath { + get { + if let parent = parent { + let parentPath = parent.indexPath + if let childIndex = parent.indexOfChild(self) { + return parentPath.appending(childIndex) + } + preconditionFailure("A Node’s parent must contain it as a child.") + } + return IndexPath(index: 0) //root node + } + } + + public var level: Int { + get { + if let parent = parent { + return parent.level + 1 + } + return 0 + } + } + + public var isLeaf: Bool { + get { + return numberOfChildNodes < 1 + } + } + + public init(representedObject: AnyObject, parent: Node?) { + + self.representedObject = representedObject + self.parent = parent + } + + public class func genericRootNode() -> Node { + + let node = Node(representedObject: TopLevelRepresentedObject(), parent: nil) + node.canHaveChildNodes = true + return node + } + + public func childAtIndex(_ index: Int) -> Node? { + + guard let childNodes = childNodes else { + return nil + } + if index >= childNodes.count || index < 0 { + return nil + } + return childNodes[index] + } + + public func indexOfChild(_ node: Node) -> Int? { + + return childNodes?.index{ (oneChildNode) -> Bool in + oneChildNode === node + } + } + + public func childNodeRepresentingObject(_ obj: AnyObject) -> Node? { + + guard let childNodes = childNodes else { + return nil + } + + for oneNode in childNodes { + if oneNode.representedObject === obj { + return oneNode + } + } + return nil + } +} + + +public func ==(lhs: Node, rhs: Node) -> Bool { + + return lhs === rhs +} diff --git a/Frameworks/RSTree/RSTree/NodePath.swift b/Frameworks/RSTree/RSTree/NodePath.swift new file mode 100644 index 000000000..1e9fee5d9 --- /dev/null +++ b/Frameworks/RSTree/RSTree/NodePath.swift @@ -0,0 +1,42 @@ +// +// NodePath.swift +// RSTree +// +// Created by Brent Simmons on 9/5/16. +// Copyright © 2016 Ranchero Software, LLC. All rights reserved. +// + +import Foundation + +public struct NodePath { + + let components: [Node] + + public init(node: Node) { + + var tempArray = [node] + + var nomad: Node = node + while true { + if let parent = nomad.parent { + tempArray.append(parent) + nomad = parent + } + else { + break + } + } + + self.components = tempArray.reversed() + } + + public init?(representedObject: AnyObject, treeController: TreeController) { + + if let node = treeController.nodeInTreeRepresentingObject(representedObject) { + self.init(node: node) + } + else { + return nil + } + } +} diff --git a/Frameworks/RSTree/RSTree/RSTree.h b/Frameworks/RSTree/RSTree/RSTree.h new file mode 100644 index 000000000..c49255a53 --- /dev/null +++ b/Frameworks/RSTree/RSTree/RSTree.h @@ -0,0 +1,19 @@ +// +// RSTree.h +// RSTree +// +// Created by Brent Simmons on 5/30/16. +// Copyright © 2016 Ranchero Software, LLC. All rights reserved. +// + +#import + +//! Project version number for RSTree. +FOUNDATION_EXPORT double RSTreeVersionNumber; + +//! Project version string for RSTree. +FOUNDATION_EXPORT const unsigned char RSTreeVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Frameworks/RSTree/RSTree/TopLevelRepresentedObject.swift b/Frameworks/RSTree/RSTree/TopLevelRepresentedObject.swift new file mode 100644 index 000000000..7d18d71cf --- /dev/null +++ b/Frameworks/RSTree/RSTree/TopLevelRepresentedObject.swift @@ -0,0 +1,15 @@ +// +// TopLevelRepresentedObject.swift +// RSTree +// +// Created by Brent Simmons on 8/10/16. +// Copyright © 2016 Ranchero Software, LLC. All rights reserved. +// + +import Foundation + +// Handy to use as the represented object for a root node. Not required to use it, though. + +final class TopLevelRepresentedObject { + +} diff --git a/Frameworks/RSTree/RSTree/TreeController.swift b/Frameworks/RSTree/RSTree/TreeController.swift new file mode 100644 index 000000000..5d1d6c0fa --- /dev/null +++ b/Frameworks/RSTree/RSTree/TreeController.swift @@ -0,0 +1,121 @@ +// +// TreeController.swift +// Rainier +// +// Created by Brent Simmons on 5/29/16. +// Copyright © 2016 Ranchero Software, LLC. All rights reserved. +// + +import Foundation + +public protocol TreeControllerDelegate: class { + + func treeController(treeController: TreeController, childNodesFor: Node) -> [Node]? +} + +public typealias NodeVisitBlock = (_ : Node) -> Void + +public final class TreeController { + + fileprivate weak var delegate: TreeControllerDelegate? + public let rootNode: Node + + public init(delegate: TreeControllerDelegate, rootNode: Node) { + + self.delegate = delegate + self.rootNode = rootNode + rebuild() + } + + public convenience init(delegate: TreeControllerDelegate) { + + self.init(delegate: delegate, rootNode: Node.genericRootNode()) + } + + @discardableResult + public func rebuild() -> Bool { + + // Rebuild and re-sort. Return true if any changes in the entire tree. + + return rebuildChildNodes(node: rootNode) + } + + public func visitNodes(_ visitBlock: NodeVisitBlock) { + + visitNode(rootNode, visitBlock) + } + + public func nodeInArrayRepresentingObject(nodes: [Node], representedObject: AnyObject, recurse: Bool = false) -> Node? { + + for oneNode in nodes { + + if oneNode.representedObject === representedObject { + return oneNode + } + + if recurse, oneNode.canHaveChildNodes, let childNodes = oneNode.childNodes { + if let foundNode = nodeInArrayRepresentingObject(nodes: childNodes, representedObject: representedObject, recurse: recurse) { + return foundNode + } + + } + } + return nil + } + + public func nodeInTreeRepresentingObject(_ representedObject: AnyObject) -> Node? { + + return nodeInArrayRepresentingObject(nodes: [rootNode], representedObject: representedObject, recurse: true) + } +} + +private extension TreeController { + + func visitNode(_ node: Node, _ visitBlock: NodeVisitBlock) { + + visitBlock(node) + node.childNodes?.forEach{ (oneChildNode) in + visitNode(oneChildNode, visitBlock) + } + } + + func nodeArraysAreEqual(_ nodeArray1: [Node]?, _ nodeArray2: [Node]?) -> Bool { + + if nodeArray1 == nil && nodeArray2 == nil { + return true + } + if nodeArray1 != nil && nodeArray2 == nil { + return false + } + if nodeArray1 == nil && nodeArray2 != nil { + return false + } + + return nodeArray1! == nodeArray2! + } + + func rebuildChildNodes(node: Node) -> Bool { + + if !node.canHaveChildNodes { + return false + } + + var childNodesDidChange = false + + let childNodes = delegate?.treeController(treeController: self, childNodesFor: node) + + childNodesDidChange = !nodeArraysAreEqual(childNodes, node.childNodes) + if (childNodesDidChange) { + node.childNodes = childNodes + } + + childNodes?.forEach{ (oneChildNode) in + if rebuildChildNodes(node: oneChildNode) { + childNodesDidChange = true + } + } + + return childNodesDidChange + } + +} diff --git a/Frameworks/RSTree/RSTreeTests/Info.plist b/Frameworks/RSTree/RSTreeTests/Info.plist new file mode 100644 index 000000000..ba72822e8 --- /dev/null +++ b/Frameworks/RSTree/RSTreeTests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Frameworks/RSTree/RSTreeTests/RSTreeTests.swift b/Frameworks/RSTree/RSTreeTests/RSTreeTests.swift new file mode 100644 index 000000000..57b84076f --- /dev/null +++ b/Frameworks/RSTree/RSTreeTests/RSTreeTests.swift @@ -0,0 +1,36 @@ +// +// RSTreeTests.swift +// RSTreeTests +// +// Created by Brent Simmons on 5/30/16. +// Copyright © 2016 Ranchero Software, LLC. All rights reserved. +// + +import XCTest +@testable import RSTree + +class RSTreeTests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +}