├── .github ├── FUNDING.yml └── workflows │ └── ci-mac.yaml ├── .gitignore ├── .gitmodules ├── CODE_OF_CONDUCT.md ├── LICENSE ├── PropertyListEditor.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ └── PropertyListEditor.xcscheme ├── PropertyListEditor ├── Classes │ ├── ApplicationDelegate.swift │ ├── PropertyListContent.swift │ ├── PropertyListDocument.swift │ ├── PropertyListNode.swift │ ├── PropertyListTextColorTransformer.swift │ ├── PropertyListTypeTransformer.swift │ ├── PropertyListValueTransformer.swift │ ├── PropertyListViewController.swift │ └── PropertyListWindowController.swift ├── Info.plist ├── PropertyListEditor.entitlements └── UI │ └── Base.lproj │ └── Main.storyboard └── README.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: macmade 2 | -------------------------------------------------------------------------------- /.github/workflows/ci-mac.yaml: -------------------------------------------------------------------------------- 1 | name: ci-mac 2 | on: [push] 3 | jobs: 4 | ci: 5 | runs-on: macos-latest 6 | strategy: 7 | matrix: 8 | run-config: 9 | - { scheme: 'PropertyListEditor', configuration: 'Debug', project: 'PropertyListEditor.xcodeproj', build: 1, analyze: 1, test: 0, info: 1, destination: 'platform=macOS' } 10 | - { scheme: 'PropertyListEditor', configuration: 'Release', project: 'PropertyListEditor.xcodeproj', build: 1, analyze: 1, test: 0, info: 1, destination: 'platform=macOS' } 11 | steps: 12 | 13 | - uses: actions/checkout@v1 14 | with: 15 | submodules: 'recursive' 16 | 17 | - uses: macmade/action-xcodebuild@v1.0.0 18 | 19 | - uses: macmade/action-slack@v1.0.0 20 | if: ${{ always() }} 21 | env: 22 | SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} 23 | with: 24 | channel: '#ci' 25 | status: ${{ job.status }} 26 | title: ${{ matrix.run-config[ 'scheme' ] }} - ${{ matrix.run-config[ 'configuration' ] }} 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac Finder 2 | .DS_Store 3 | .Trashes 4 | Icon? 5 | 6 | # Thumbnails 7 | ._* 8 | 9 | # Files that might appear on external disk 10 | .Spotlight-V100 11 | .Trashes 12 | 13 | # Xcode 14 | *.pbxuser 15 | *.mode1v3 16 | *.mode2v3 17 | *.perspectivev3 18 | *.xccheckout 19 | *.profraw 20 | !default.pbxuser 21 | !default.mode1v3 22 | !default.mode2v3 23 | !default.perspectivev3 24 | xcuserdata 25 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Submodules/xcconfig"] 2 | path = Submodules/xcconfig 3 | url = https://github.com/macmade/xcconfig.git 4 | [submodule "Submodules/GitHubUpdates"] 5 | path = Submodules/GitHubUpdates 6 | url = https://github.com/macmade/GitHubUpdates.git 7 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | xs-labs.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2021 Jean-David Gadina - www.xs-labs.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /PropertyListEditor.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 05CFC4F326C01DAF00D76BA7 /* PropertyListDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05CFC4F226C01DAF00D76BA7 /* PropertyListDocument.swift */; }; 11 | 05CFC51726C020DE00D76BA7 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 05CFC51526C020DE00D76BA7 /* Main.storyboard */; }; 12 | 05CFC51926C021DC00D76BA7 /* PropertyListWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05CFC51826C021DC00D76BA7 /* PropertyListWindowController.swift */; }; 13 | 05CFC51B26C0222100D76BA7 /* PropertyListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05CFC51A26C0222100D76BA7 /* PropertyListViewController.swift */; }; 14 | 05CFC51D26C0275F00D76BA7 /* PropertyListContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05CFC51C26C0275F00D76BA7 /* PropertyListContent.swift */; }; 15 | 05CFC52326C17F8400D76BA7 /* PropertyListValueTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05CFC52226C17F8400D76BA7 /* PropertyListValueTransformer.swift */; }; 16 | 05CFC52726C17FBD00D76BA7 /* PropertyListTypeTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05CFC52626C17FBD00D76BA7 /* PropertyListTypeTransformer.swift */; }; 17 | 05CFC52926C1807500D76BA7 /* PropertyListTextColorTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05CFC52826C1807500D76BA7 /* PropertyListTextColorTransformer.swift */; }; 18 | 05FC7E7326BAA5BF0033FC23 /* ApplicationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05FC7E6F26BAA5BF0033FC23 /* ApplicationDelegate.swift */; }; 19 | 05FC7EB126BB62B70033FC23 /* PropertyListNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05FC7EB026BB62B70033FC23 /* PropertyListNode.swift */; }; 20 | 05FC7EBD26BB6F560033FC23 /* GitHubUpdates.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05FC7EBA26BB6F4C0033FC23 /* GitHubUpdates.framework */; }; 21 | 05FC7EBE26BB6F560033FC23 /* GitHubUpdates.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 05FC7EBA26BB6F4C0033FC23 /* GitHubUpdates.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXContainerItemProxy section */ 25 | 05FC7EB926BB6F4C0033FC23 /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = 05FC7EB426BB6F4C0033FC23 /* GitHubUpdates.xcodeproj */; 28 | proxyType = 2; 29 | remoteGlobalIDString = 05F82B251EF32EA700EC8A93; 30 | remoteInfo = GitHubUpdates; 31 | }; 32 | 05FC7EBB26BB6F4C0033FC23 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = 05FC7EB426BB6F4C0033FC23 /* GitHubUpdates.xcodeproj */; 35 | proxyType = 2; 36 | remoteGlobalIDString = 0555EBA01EF3DDA10016167F; 37 | remoteInfo = Relauncher; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXCopyFilesBuildPhase section */ 42 | 05FC7EBF26BB6F560033FC23 /* Embed Frameworks */ = { 43 | isa = PBXCopyFilesBuildPhase; 44 | buildActionMask = 2147483647; 45 | dstPath = ""; 46 | dstSubfolderSpec = 10; 47 | files = ( 48 | 05FC7EBE26BB6F560033FC23 /* GitHubUpdates.framework in Embed Frameworks */, 49 | ); 50 | name = "Embed Frameworks"; 51 | runOnlyForDeploymentPostprocessing = 0; 52 | }; 53 | /* End PBXCopyFilesBuildPhase section */ 54 | 55 | /* Begin PBXFileReference section */ 56 | 054C893826B9786C0006A91C /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 57 | 054C893926B9786C0006A91C /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 58 | 054C893B26B979510006A91C /* Release - ccache.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Release - ccache.xcconfig"; sourceTree = ""; }; 59 | 054C893C26B979510006A91C /* Common.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Common.xcconfig; sourceTree = ""; }; 60 | 054C893D26B979510006A91C /* Debug - ccache.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Debug - ccache.xcconfig"; sourceTree = ""; }; 61 | 054C893E26B979510006A91C /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; 62 | 054C893F26B979510006A91C /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 63 | 054C894026B979510006A91C /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 64 | 054C894126B979510006A91C /* Release - Library.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Release - Library.xcconfig"; sourceTree = ""; }; 65 | 054C894326B979510006A91C /* Signing.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Signing.xcconfig; sourceTree = ""; }; 66 | 054C894426B979510006A91C /* Architectures.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Architectures.xcconfig; sourceTree = ""; }; 67 | 054C894626B979510006A91C /* Issues.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Issues.xcconfig; sourceTree = ""; }; 68 | 054C894826B979510006A91C /* Apple-APIs.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Apple-APIs.xcconfig"; sourceTree = ""; }; 69 | 054C894926B979510006A91C /* Generic-Issues.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Generic-Issues.xcconfig"; sourceTree = ""; }; 70 | 054C894A26B979510006A91C /* Security.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Security.xcconfig; sourceTree = ""; }; 71 | 054C894B26B979510006A91C /* Objective-C.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Objective-C.xcconfig"; sourceTree = ""; }; 72 | 054C894C26B979510006A91C /* Analysis-Policy.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Analysis-Policy.xcconfig"; sourceTree = ""; }; 73 | 054C894D26B979510006A91C /* Deployment.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Deployment.xcconfig; sourceTree = ""; }; 74 | 054C894E26B979510006A91C /* Build-Options.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Build-Options.xcconfig"; sourceTree = ""; }; 75 | 054C894F26B979510006A91C /* Swift-Compiler.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Swift-Compiler.xcconfig"; sourceTree = ""; }; 76 | 054C895026B979510006A91C /* Static-Analyzer.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Static-Analyzer.xcconfig"; sourceTree = ""; }; 77 | 054C895226B979510006A91C /* Warnings-Policies.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Warnings-Policies.xcconfig"; sourceTree = ""; }; 78 | 054C895326B979510006A91C /* Code-Generation.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Code-Generation.xcconfig"; sourceTree = ""; }; 79 | 054C895426B979510006A91C /* Language.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Language.xcconfig; sourceTree = ""; }; 80 | 054C895526B979510006A91C /* General.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = General.xcconfig; sourceTree = ""; }; 81 | 054C895626B979510006A91C /* Search-Paths.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Search-Paths.xcconfig"; sourceTree = ""; }; 82 | 054C895726B979510006A91C /* Apple-LLVM.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Apple-LLVM.xcconfig"; sourceTree = ""; }; 83 | 054C895A26B979510006A91C /* Modules.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Modules.xcconfig; sourceTree = ""; }; 84 | 054C895B26B979510006A91C /* Objective-C.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Objective-C.xcconfig"; sourceTree = ""; }; 85 | 054C895C26B979510006A91C /* C++.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "C++.xcconfig"; sourceTree = ""; }; 86 | 054C895D26B979510006A91C /* Code-Generation.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Code-Generation.xcconfig"; sourceTree = ""; }; 87 | 054C895E26B979510006A91C /* Address-Sanitizer.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Address-Sanitizer.xcconfig"; sourceTree = ""; }; 88 | 054C895F26B979510006A91C /* Language.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Language.xcconfig; sourceTree = ""; }; 89 | 054C896026B979510006A91C /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 90 | 054C896126B979510006A91C /* Undefined-Behavior-Sanitizer.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Undefined-Behavior-Sanitizer.xcconfig"; sourceTree = ""; }; 91 | 054C896226B979510006A91C /* Warning-Policies.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Warning-Policies.xcconfig"; sourceTree = ""; }; 92 | 054C896426B979510006A91C /* Objective-C-ARC.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Objective-C-ARC.xcconfig"; sourceTree = ""; }; 93 | 054C896526B979510006A91C /* Objective-C.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Objective-C.xcconfig"; sourceTree = ""; }; 94 | 054C896626B979510006A91C /* C++.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "C++.xcconfig"; sourceTree = ""; }; 95 | 054C896726B979510006A91C /* All-Languages.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "All-Languages.xcconfig"; sourceTree = ""; }; 96 | 054C896826B979510006A91C /* Preprocessing.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Preprocessing.xcconfig; sourceTree = ""; }; 97 | 054C896926B979510006A91C /* Debug - Library.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Debug - Library.xcconfig"; sourceTree = ""; }; 98 | 054C896A26B979510006A91C /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; 99 | 054C896C26B979510006A91C /* ccache-config.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "ccache-config.sh"; sourceTree = ""; }; 100 | 054C896D26B979510006A91C /* ccache.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ccache.sh; sourceTree = ""; }; 101 | 054C896E26B979510006A91C /* Debug - zld.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Debug - zld.xcconfig"; sourceTree = ""; }; 102 | 05A808E826C00A7A00837A91 /* PropertyListEditor.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = PropertyListEditor.entitlements; sourceTree = ""; }; 103 | 05CFC4F226C01DAF00D76BA7 /* PropertyListDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PropertyListDocument.swift; sourceTree = ""; }; 104 | 05CFC51626C020DE00D76BA7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 105 | 05CFC51826C021DC00D76BA7 /* PropertyListWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PropertyListWindowController.swift; sourceTree = ""; }; 106 | 05CFC51A26C0222100D76BA7 /* PropertyListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PropertyListViewController.swift; sourceTree = ""; }; 107 | 05CFC51C26C0275F00D76BA7 /* PropertyListContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PropertyListContent.swift; sourceTree = ""; }; 108 | 05CFC52226C17F8400D76BA7 /* PropertyListValueTransformer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PropertyListValueTransformer.swift; sourceTree = ""; }; 109 | 05CFC52626C17FBD00D76BA7 /* PropertyListTypeTransformer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PropertyListTypeTransformer.swift; sourceTree = ""; }; 110 | 05CFC52826C1807500D76BA7 /* PropertyListTextColorTransformer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PropertyListTextColorTransformer.swift; sourceTree = ""; }; 111 | 05FC7E6026BAA5850033FC23 /* PropertyList Editor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "PropertyList Editor.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 112 | 05FC7E6926BAA5860033FC23 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 113 | 05FC7E6F26BAA5BF0033FC23 /* ApplicationDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationDelegate.swift; sourceTree = ""; }; 114 | 05FC7EB026BB62B70033FC23 /* PropertyListNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PropertyListNode.swift; sourceTree = ""; }; 115 | 05FC7EB426BB6F4C0033FC23 /* GitHubUpdates.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GitHubUpdates.xcodeproj; path = Submodules/GitHubUpdates/GitHubUpdates.xcodeproj; sourceTree = ""; }; 116 | /* End PBXFileReference section */ 117 | 118 | /* Begin PBXFrameworksBuildPhase section */ 119 | 05FC7E5D26BAA5850033FC23 /* Frameworks */ = { 120 | isa = PBXFrameworksBuildPhase; 121 | buildActionMask = 2147483647; 122 | files = ( 123 | 05FC7EBD26BB6F560033FC23 /* GitHubUpdates.framework in Frameworks */, 124 | ); 125 | runOnlyForDeploymentPostprocessing = 0; 126 | }; 127 | /* End PBXFrameworksBuildPhase section */ 128 | 129 | /* Begin PBXGroup section */ 130 | 054C88B826B8838F0006A91C = { 131 | isa = PBXGroup; 132 | children = ( 133 | 054C893826B9786C0006A91C /* LICENSE */, 134 | 054C893926B9786C0006A91C /* README.md */, 135 | 05FC7EB426BB6F4C0033FC23 /* GitHubUpdates.xcodeproj */, 136 | 054C893A26B979510006A91C /* xcconfig */, 137 | 05FC7E6126BAA5850033FC23 /* PropertyListEditor */, 138 | 054C88C226B8838F0006A91C /* Products */, 139 | 054C88FF26B89D9A0006A91C /* Frameworks */, 140 | ); 141 | sourceTree = ""; 142 | }; 143 | 054C88C226B8838F0006A91C /* Products */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | 05FC7E6026BAA5850033FC23 /* PropertyList Editor.app */, 147 | ); 148 | name = Products; 149 | sourceTree = ""; 150 | }; 151 | 054C88FF26B89D9A0006A91C /* Frameworks */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | ); 155 | name = Frameworks; 156 | sourceTree = ""; 157 | }; 158 | 054C893A26B979510006A91C /* xcconfig */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | 054C893B26B979510006A91C /* Release - ccache.xcconfig */, 162 | 054C893C26B979510006A91C /* Common.xcconfig */, 163 | 054C893D26B979510006A91C /* Debug - ccache.xcconfig */, 164 | 054C893E26B979510006A91C /* Debug.xcconfig */, 165 | 054C893F26B979510006A91C /* Release.xcconfig */, 166 | 054C894026B979510006A91C /* README.md */, 167 | 054C894126B979510006A91C /* Release - Library.xcconfig */, 168 | 054C894226B979510006A91C /* Common */, 169 | 054C896926B979510006A91C /* Debug - Library.xcconfig */, 170 | 054C896A26B979510006A91C /* .gitignore */, 171 | 054C896B26B979510006A91C /* Scripts */, 172 | 054C896E26B979510006A91C /* Debug - zld.xcconfig */, 173 | ); 174 | name = xcconfig; 175 | path = Submodules/xcconfig; 176 | sourceTree = ""; 177 | }; 178 | 054C894226B979510006A91C /* Common */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | 054C894326B979510006A91C /* Signing.xcconfig */, 182 | 054C894426B979510006A91C /* Architectures.xcconfig */, 183 | 054C894526B979510006A91C /* Static-Analyzer */, 184 | 054C894D26B979510006A91C /* Deployment.xcconfig */, 185 | 054C894E26B979510006A91C /* Build-Options.xcconfig */, 186 | 054C894F26B979510006A91C /* Swift-Compiler.xcconfig */, 187 | 054C895026B979510006A91C /* Static-Analyzer.xcconfig */, 188 | 054C895126B979510006A91C /* Swift-Compiler */, 189 | 054C895626B979510006A91C /* Search-Paths.xcconfig */, 190 | 054C895726B979510006A91C /* Apple-LLVM.xcconfig */, 191 | 054C895826B979510006A91C /* Apple-LLVM */, 192 | ); 193 | path = Common; 194 | sourceTree = ""; 195 | }; 196 | 054C894526B979510006A91C /* Static-Analyzer */ = { 197 | isa = PBXGroup; 198 | children = ( 199 | 054C894626B979510006A91C /* Issues.xcconfig */, 200 | 054C894726B979510006A91C /* Issues */, 201 | ); 202 | path = "Static-Analyzer"; 203 | sourceTree = ""; 204 | }; 205 | 054C894726B979510006A91C /* Issues */ = { 206 | isa = PBXGroup; 207 | children = ( 208 | 054C894826B979510006A91C /* Apple-APIs.xcconfig */, 209 | 054C894926B979510006A91C /* Generic-Issues.xcconfig */, 210 | 054C894A26B979510006A91C /* Security.xcconfig */, 211 | 054C894B26B979510006A91C /* Objective-C.xcconfig */, 212 | 054C894C26B979510006A91C /* Analysis-Policy.xcconfig */, 213 | ); 214 | path = Issues; 215 | sourceTree = ""; 216 | }; 217 | 054C895126B979510006A91C /* Swift-Compiler */ = { 218 | isa = PBXGroup; 219 | children = ( 220 | 054C895226B979510006A91C /* Warnings-Policies.xcconfig */, 221 | 054C895326B979510006A91C /* Code-Generation.xcconfig */, 222 | 054C895426B979510006A91C /* Language.xcconfig */, 223 | 054C895526B979510006A91C /* General.xcconfig */, 224 | ); 225 | path = "Swift-Compiler"; 226 | sourceTree = ""; 227 | }; 228 | 054C895826B979510006A91C /* Apple-LLVM */ = { 229 | isa = PBXGroup; 230 | children = ( 231 | 054C895926B979510006A91C /* Language */, 232 | 054C895D26B979510006A91C /* Code-Generation.xcconfig */, 233 | 054C895E26B979510006A91C /* Address-Sanitizer.xcconfig */, 234 | 054C895F26B979510006A91C /* Language.xcconfig */, 235 | 054C896026B979510006A91C /* Warnings.xcconfig */, 236 | 054C896126B979510006A91C /* Undefined-Behavior-Sanitizer.xcconfig */, 237 | 054C896226B979510006A91C /* Warning-Policies.xcconfig */, 238 | 054C896326B979510006A91C /* Warnings */, 239 | 054C896826B979510006A91C /* Preprocessing.xcconfig */, 240 | ); 241 | path = "Apple-LLVM"; 242 | sourceTree = ""; 243 | }; 244 | 054C895926B979510006A91C /* Language */ = { 245 | isa = PBXGroup; 246 | children = ( 247 | 054C895A26B979510006A91C /* Modules.xcconfig */, 248 | 054C895B26B979510006A91C /* Objective-C.xcconfig */, 249 | 054C895C26B979510006A91C /* C++.xcconfig */, 250 | ); 251 | path = Language; 252 | sourceTree = ""; 253 | }; 254 | 054C896326B979510006A91C /* Warnings */ = { 255 | isa = PBXGroup; 256 | children = ( 257 | 054C896426B979510006A91C /* Objective-C-ARC.xcconfig */, 258 | 054C896526B979510006A91C /* Objective-C.xcconfig */, 259 | 054C896626B979510006A91C /* C++.xcconfig */, 260 | 054C896726B979510006A91C /* All-Languages.xcconfig */, 261 | ); 262 | path = Warnings; 263 | sourceTree = ""; 264 | }; 265 | 054C896B26B979510006A91C /* Scripts */ = { 266 | isa = PBXGroup; 267 | children = ( 268 | 054C896C26B979510006A91C /* ccache-config.sh */, 269 | 054C896D26B979510006A91C /* ccache.sh */, 270 | ); 271 | path = Scripts; 272 | sourceTree = ""; 273 | }; 274 | 05FC7E6126BAA5850033FC23 /* PropertyListEditor */ = { 275 | isa = PBXGroup; 276 | children = ( 277 | 05FC7E6E26BAA5BF0033FC23 /* Classes */, 278 | 05FC7E6926BAA5860033FC23 /* Info.plist */, 279 | 05A808E826C00A7A00837A91 /* PropertyListEditor.entitlements */, 280 | 05FC7E7026BAA5BF0033FC23 /* UI */, 281 | ); 282 | path = PropertyListEditor; 283 | sourceTree = ""; 284 | }; 285 | 05FC7E6E26BAA5BF0033FC23 /* Classes */ = { 286 | isa = PBXGroup; 287 | children = ( 288 | 05FC7E6F26BAA5BF0033FC23 /* ApplicationDelegate.swift */, 289 | 05CFC51C26C0275F00D76BA7 /* PropertyListContent.swift */, 290 | 05CFC4F226C01DAF00D76BA7 /* PropertyListDocument.swift */, 291 | 05FC7EB026BB62B70033FC23 /* PropertyListNode.swift */, 292 | 05CFC52626C17FBD00D76BA7 /* PropertyListTypeTransformer.swift */, 293 | 05CFC52226C17F8400D76BA7 /* PropertyListValueTransformer.swift */, 294 | 05CFC52826C1807500D76BA7 /* PropertyListTextColorTransformer.swift */, 295 | 05CFC51A26C0222100D76BA7 /* PropertyListViewController.swift */, 296 | 05CFC51826C021DC00D76BA7 /* PropertyListWindowController.swift */, 297 | ); 298 | path = Classes; 299 | sourceTree = ""; 300 | }; 301 | 05FC7E7026BAA5BF0033FC23 /* UI */ = { 302 | isa = PBXGroup; 303 | children = ( 304 | 05CFC51526C020DE00D76BA7 /* Main.storyboard */, 305 | ); 306 | path = UI; 307 | sourceTree = ""; 308 | }; 309 | 05FC7EB526BB6F4C0033FC23 /* Products */ = { 310 | isa = PBXGroup; 311 | children = ( 312 | 05FC7EBA26BB6F4C0033FC23 /* GitHubUpdates.framework */, 313 | 05FC7EBC26BB6F4C0033FC23 /* Relauncher */, 314 | ); 315 | name = Products; 316 | sourceTree = ""; 317 | }; 318 | /* End PBXGroup section */ 319 | 320 | /* Begin PBXNativeTarget section */ 321 | 05FC7E5F26BAA5850033FC23 /* PropertyList Editor */ = { 322 | isa = PBXNativeTarget; 323 | buildConfigurationList = 05FC7E6B26BAA5860033FC23 /* Build configuration list for PBXNativeTarget "PropertyList Editor" */; 324 | buildPhases = ( 325 | 05FC7E5C26BAA5850033FC23 /* Sources */, 326 | 05FC7E5D26BAA5850033FC23 /* Frameworks */, 327 | 05FC7EC626BB740C0033FC23 /* ShellScript */, 328 | 05FC7E5E26BAA5850033FC23 /* Resources */, 329 | 05FC7EBF26BB6F560033FC23 /* Embed Frameworks */, 330 | ); 331 | buildRules = ( 332 | ); 333 | dependencies = ( 334 | ); 335 | name = "PropertyList Editor"; 336 | productName = DSStoreView; 337 | productReference = 05FC7E6026BAA5850033FC23 /* PropertyList Editor.app */; 338 | productType = "com.apple.product-type.application"; 339 | }; 340 | /* End PBXNativeTarget section */ 341 | 342 | /* Begin PBXProject section */ 343 | 054C88B926B8838F0006A91C /* Project object */ = { 344 | isa = PBXProject; 345 | attributes = { 346 | LastSwiftUpdateCheck = 1250; 347 | LastUpgradeCheck = 1250; 348 | TargetAttributes = { 349 | 05FC7E5F26BAA5850033FC23 = { 350 | CreatedOnToolsVersion = 12.5.1; 351 | }; 352 | }; 353 | }; 354 | buildConfigurationList = 054C88BC26B8838F0006A91C /* Build configuration list for PBXProject "PropertyListEditor" */; 355 | compatibilityVersion = "Xcode 9.3"; 356 | developmentRegion = en; 357 | hasScannedForEncodings = 0; 358 | knownRegions = ( 359 | en, 360 | Base, 361 | ); 362 | mainGroup = 054C88B826B8838F0006A91C; 363 | productRefGroup = 054C88C226B8838F0006A91C /* Products */; 364 | projectDirPath = ""; 365 | projectReferences = ( 366 | { 367 | ProductGroup = 05FC7EB526BB6F4C0033FC23 /* Products */; 368 | ProjectRef = 05FC7EB426BB6F4C0033FC23 /* GitHubUpdates.xcodeproj */; 369 | }, 370 | ); 371 | projectRoot = ""; 372 | targets = ( 373 | 05FC7E5F26BAA5850033FC23 /* PropertyList Editor */, 374 | ); 375 | }; 376 | /* End PBXProject section */ 377 | 378 | /* Begin PBXReferenceProxy section */ 379 | 05FC7EBA26BB6F4C0033FC23 /* GitHubUpdates.framework */ = { 380 | isa = PBXReferenceProxy; 381 | fileType = wrapper.framework; 382 | path = GitHubUpdates.framework; 383 | remoteRef = 05FC7EB926BB6F4C0033FC23 /* PBXContainerItemProxy */; 384 | sourceTree = BUILT_PRODUCTS_DIR; 385 | }; 386 | 05FC7EBC26BB6F4C0033FC23 /* Relauncher */ = { 387 | isa = PBXReferenceProxy; 388 | fileType = "compiled.mach-o.executable"; 389 | path = Relauncher; 390 | remoteRef = 05FC7EBB26BB6F4C0033FC23 /* PBXContainerItemProxy */; 391 | sourceTree = BUILT_PRODUCTS_DIR; 392 | }; 393 | /* End PBXReferenceProxy section */ 394 | 395 | /* Begin PBXResourcesBuildPhase section */ 396 | 05FC7E5E26BAA5850033FC23 /* Resources */ = { 397 | isa = PBXResourcesBuildPhase; 398 | buildActionMask = 2147483647; 399 | files = ( 400 | 05CFC51726C020DE00D76BA7 /* Main.storyboard in Resources */, 401 | ); 402 | runOnlyForDeploymentPostprocessing = 0; 403 | }; 404 | /* End PBXResourcesBuildPhase section */ 405 | 406 | /* Begin PBXShellScriptBuildPhase section */ 407 | 05FC7EC626BB740C0033FC23 /* ShellScript */ = { 408 | isa = PBXShellScriptBuildPhase; 409 | buildActionMask = 2147483647; 410 | files = ( 411 | ); 412 | inputFileListPaths = ( 413 | ); 414 | inputPaths = ( 415 | ); 416 | outputFileListPaths = ( 417 | ); 418 | outputPaths = ( 419 | ); 420 | runOnlyForDeploymentPostprocessing = 0; 421 | shellPath = /bin/sh; 422 | shellScript = "#!/bin/bash\nif [ \"${CONFIGURATION}\" = \"Release\" ]; then\n plist=\"PropertyListEditor/Info.plist\"\n rev=$(git rev-list `git branch | grep -e \"^*\" | cut -d' ' -f 2` | wc -l)\n /usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $rev\" \"$plist\"\nfi\n"; 423 | }; 424 | /* End PBXShellScriptBuildPhase section */ 425 | 426 | /* Begin PBXSourcesBuildPhase section */ 427 | 05FC7E5C26BAA5850033FC23 /* Sources */ = { 428 | isa = PBXSourcesBuildPhase; 429 | buildActionMask = 2147483647; 430 | files = ( 431 | 05CFC51D26C0275F00D76BA7 /* PropertyListContent.swift in Sources */, 432 | 05CFC4F326C01DAF00D76BA7 /* PropertyListDocument.swift in Sources */, 433 | 05FC7E7326BAA5BF0033FC23 /* ApplicationDelegate.swift in Sources */, 434 | 05CFC52326C17F8400D76BA7 /* PropertyListValueTransformer.swift in Sources */, 435 | 05CFC52726C17FBD00D76BA7 /* PropertyListTypeTransformer.swift in Sources */, 436 | 05CFC51926C021DC00D76BA7 /* PropertyListWindowController.swift in Sources */, 437 | 05FC7EB126BB62B70033FC23 /* PropertyListNode.swift in Sources */, 438 | 05CFC52926C1807500D76BA7 /* PropertyListTextColorTransformer.swift in Sources */, 439 | 05CFC51B26C0222100D76BA7 /* PropertyListViewController.swift in Sources */, 440 | ); 441 | runOnlyForDeploymentPostprocessing = 0; 442 | }; 443 | /* End PBXSourcesBuildPhase section */ 444 | 445 | /* Begin PBXVariantGroup section */ 446 | 05CFC51526C020DE00D76BA7 /* Main.storyboard */ = { 447 | isa = PBXVariantGroup; 448 | children = ( 449 | 05CFC51626C020DE00D76BA7 /* Base */, 450 | ); 451 | name = Main.storyboard; 452 | sourceTree = ""; 453 | }; 454 | /* End PBXVariantGroup section */ 455 | 456 | /* Begin XCBuildConfiguration section */ 457 | 054C88C626B8838F0006A91C /* Debug */ = { 458 | isa = XCBuildConfiguration; 459 | baseConfigurationReference = 054C893E26B979510006A91C /* Debug.xcconfig */; 460 | buildSettings = { 461 | }; 462 | name = Debug; 463 | }; 464 | 054C88C726B8838F0006A91C /* Release */ = { 465 | isa = XCBuildConfiguration; 466 | baseConfigurationReference = 054C893F26B979510006A91C /* Release.xcconfig */; 467 | buildSettings = { 468 | }; 469 | name = Release; 470 | }; 471 | 05FC7E6C26BAA5860033FC23 /* Debug */ = { 472 | isa = XCBuildConfiguration; 473 | buildSettings = { 474 | CODE_SIGN_ENTITLEMENTS = PropertyListEditor/PropertyListEditor.entitlements; 475 | INFOPLIST_FILE = PropertyListEditor/Info.plist; 476 | LD_RUNPATH_SEARCH_PATHS = ( 477 | "$(inherited)", 478 | "@executable_path/../Frameworks", 479 | ); 480 | PRODUCT_BUNDLE_IDENTIFIER = "com.xs-labs.PropertyListEditor"; 481 | PRODUCT_NAME = "$(TARGET_NAME)"; 482 | }; 483 | name = Debug; 484 | }; 485 | 05FC7E6D26BAA5860033FC23 /* Release */ = { 486 | isa = XCBuildConfiguration; 487 | buildSettings = { 488 | CODE_SIGN_ENTITLEMENTS = PropertyListEditor/PropertyListEditor.entitlements; 489 | INFOPLIST_FILE = PropertyListEditor/Info.plist; 490 | LD_RUNPATH_SEARCH_PATHS = ( 491 | "$(inherited)", 492 | "@executable_path/../Frameworks", 493 | ); 494 | PRODUCT_BUNDLE_IDENTIFIER = "com.xs-labs.PropertyListEditor"; 495 | PRODUCT_NAME = "$(TARGET_NAME)"; 496 | }; 497 | name = Release; 498 | }; 499 | /* End XCBuildConfiguration section */ 500 | 501 | /* Begin XCConfigurationList section */ 502 | 054C88BC26B8838F0006A91C /* Build configuration list for PBXProject "PropertyListEditor" */ = { 503 | isa = XCConfigurationList; 504 | buildConfigurations = ( 505 | 054C88C626B8838F0006A91C /* Debug */, 506 | 054C88C726B8838F0006A91C /* Release */, 507 | ); 508 | defaultConfigurationIsVisible = 0; 509 | defaultConfigurationName = Release; 510 | }; 511 | 05FC7E6B26BAA5860033FC23 /* Build configuration list for PBXNativeTarget "PropertyList Editor" */ = { 512 | isa = XCConfigurationList; 513 | buildConfigurations = ( 514 | 05FC7E6C26BAA5860033FC23 /* Debug */, 515 | 05FC7E6D26BAA5860033FC23 /* Release */, 516 | ); 517 | defaultConfigurationIsVisible = 0; 518 | defaultConfigurationName = Release; 519 | }; 520 | /* End XCConfigurationList section */ 521 | }; 522 | rootObject = 054C88B926B8838F0006A91C /* Project object */; 523 | } 524 | -------------------------------------------------------------------------------- /PropertyListEditor.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PropertyListEditor.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /PropertyListEditor.xcodeproj/xcshareddata/xcschemes/PropertyListEditor.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 61 | 67 | 68 | 69 | 70 | 72 | 73 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /PropertyListEditor/Classes/ApplicationDelegate.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2021 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | import GitHubUpdates 27 | 28 | @main class ApplicationDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate 29 | { 30 | @IBOutlet private var updater: GitHubUpdater! 31 | 32 | func applicationDidFinishLaunching( _ notification: Notification ) 33 | { 34 | DispatchQueue.main.asyncAfter( deadline: .now() + .seconds( 2 ) ) 35 | { 36 | self.updater.checkForUpdatesInBackground() 37 | } 38 | } 39 | 40 | func applicationShouldTerminateAfterLastWindowClosed( _ sender: NSApplication ) -> Bool 41 | { 42 | false 43 | } 44 | 45 | @IBAction func checkForUpdates( _ sender: Any? ) 46 | { 47 | self.updater.checkForUpdates( sender ) 48 | } 49 | 50 | @IBAction func invertAppearance( _ sender: Any? ) 51 | { 52 | switch NSApp.effectiveAppearance.name 53 | { 54 | case .aqua: NSApp.appearance = NSAppearance( named: .darkAqua ) 55 | case .darkAqua: NSApp.appearance = NSAppearance( named: .aqua ) 56 | case .accessibilityHighContrastAqua: NSApp.appearance = NSAppearance( named: .accessibilityHighContrastDarkAqua ) 57 | case .accessibilityHighContrastDarkAqua: NSApp.appearance = NSAppearance( named: .accessibilityHighContrastAqua ) 58 | case .vibrantLight: NSApp.appearance = NSAppearance( named: .vibrantDark ) 59 | case .vibrantDark: NSApp.appearance = NSAppearance( named: .vibrantLight ) 60 | case .accessibilityHighContrastVibrantLight: NSApp.appearance = NSAppearance( named: .accessibilityHighContrastVibrantDark ) 61 | case .accessibilityHighContrastVibrantDark: NSApp.appearance = NSAppearance( named: .accessibilityHighContrastVibrantLight ) 62 | 63 | default: NSSound.beep() 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /PropertyListEditor/Classes/PropertyListContent.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2021 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | 27 | public class PropertyListContent: NSObject 28 | { 29 | @objc public private( set ) dynamic var node = PropertyListNode() 30 | @objc public private( set ) dynamic var format = PropertyListSerialization.PropertyListFormat.xml 31 | 32 | public func read( data: Data ) throws 33 | { 34 | var format = PropertyListSerialization.PropertyListFormat.xml 35 | let plist = try PropertyListSerialization.propertyList( from: data, options: .mutableContainers, format: &format ) 36 | self.node = PropertyListNode( key: "Property List", propertyList: plist ) 37 | self.format = format 38 | } 39 | 40 | public func data() throws -> Data 41 | { 42 | try PropertyListSerialization.data( fromPropertyList: self.node.value, format: self.format, options: 0 ) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /PropertyListEditor/Classes/PropertyListDocument.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2021 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | 27 | public class PropertyListDocument: NSDocument 28 | { 29 | @objc public private( set ) dynamic var content = PropertyListContent() 30 | @objc public private( set ) dynamic var viewController: NSViewController? 31 | 32 | public override class var autosavesInPlace: Bool 33 | { 34 | true 35 | } 36 | 37 | public override func canAsynchronouslyWrite( to url: URL, ofType typeName: String, for saveOperation: NSDocument.SaveOperationType ) -> Bool 38 | { 39 | true 40 | } 41 | 42 | public override class func canConcurrentlyReadDocuments( ofType type: String ) -> Bool 43 | { 44 | return type == "com.apple.property-list" 45 | } 46 | 47 | public override func makeWindowControllers() 48 | { 49 | let storyboard = NSStoryboard( name: "Main", bundle: nil ) 50 | 51 | guard let windowController = storyboard.instantiateController( withIdentifier: "Document Window Controller" ) as? PropertyListWindowController else 52 | { 53 | return 54 | } 55 | 56 | guard let viewController = windowController.contentViewController as? PropertyListViewController else 57 | { 58 | return 59 | } 60 | 61 | viewController.representedObject = self 62 | self.viewController = viewController 63 | 64 | self.addWindowController( windowController ) 65 | } 66 | 67 | public override func read( from data: Data, ofType type: String ) throws 68 | { 69 | try self.content.read( data: data ) 70 | } 71 | 72 | public override func data( ofType typeName: String ) throws -> Data 73 | { 74 | try self.content.data() 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /PropertyListEditor/Classes/PropertyListNode.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2021 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | 27 | public class PropertyListNode: NSObject 28 | { 29 | @objc public private( set ) dynamic var key: String 30 | @objc public private( set ) dynamic var value: Any 31 | @objc public private( set ) dynamic var children = [ PropertyListNode ]() 32 | 33 | public convenience override init() 34 | { 35 | self.init( key: "Property List", propertyList: NSMutableDictionary() ) 36 | } 37 | 38 | public init( key: String, propertyList: Any ) 39 | { 40 | self.key = key 41 | self.value = propertyList 42 | 43 | super.init() 44 | 45 | if let array = propertyList as? NSArray 46 | { 47 | var i = 0 48 | 49 | array.forEach 50 | { 51 | self.addChild( key: "Item \( i )", propertyList: $0 ) 52 | 53 | i += 1 54 | } 55 | } 56 | else if let set = propertyList as? NSOrderedSet 57 | { 58 | var i = 0 59 | 60 | set.forEach 61 | { 62 | self.addChild( key: "Item \( i )", propertyList: $0 ) 63 | 64 | i += 1 65 | } 66 | } 67 | else if let set = propertyList as? NSSet 68 | { 69 | var i = 0 70 | 71 | set.forEach 72 | { 73 | self.addChild( key: "Item \( i )", propertyList: $0 ) 74 | 75 | i += 1 76 | } 77 | } 78 | else if let dict = propertyList as? NSDictionary 79 | { 80 | dict.forEach { self.addChild( key: "\( $0.key )", propertyList: $0.value ) } 81 | } 82 | else if let tuple = propertyList as? ( Any, [ AnyHashable : Any ] ) 83 | { 84 | tuple.1.forEach { self.addChild( key: "\( $0.key )", propertyList: $0.value ) } 85 | } 86 | else if let tuple = propertyList as? ( Any, [ Any ] ) 87 | { 88 | var i = 0 89 | 90 | tuple.1.forEach 91 | { 92 | self.addChild( key: "Item \( i )", propertyList: $0 ) 93 | 94 | i += 1 95 | } 96 | } 97 | } 98 | 99 | @discardableResult 100 | private func addChild( key: String, propertyList: Any ) -> PropertyListNode 101 | { 102 | let child = PropertyListNode( key: key, propertyList: propertyList ) 103 | 104 | self.children.append( child ) 105 | 106 | return child 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /PropertyListEditor/Classes/PropertyListTextColorTransformer.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2021 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | 27 | @objc( PropertyListTextColorTransformer ) 28 | public class PropertyListTextColorTransformer: ValueTransformer 29 | { 30 | public override class func transformedValueClass() -> AnyClass 31 | { 32 | NSColor.self 33 | } 34 | 35 | public override class func allowsReverseTransformation() -> Bool 36 | { 37 | false 38 | } 39 | 40 | public override func transformedValue( _ value: Any? ) -> Any? 41 | { 42 | guard let node = value as? PropertyListNode else 43 | { 44 | return NSColor.labelColor 45 | } 46 | 47 | return node.children.count > 0 ? NSColor.secondaryLabelColor : NSColor.labelColor 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /PropertyListEditor/Classes/PropertyListTypeTransformer.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2021 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Foundation 26 | 27 | @objc( PropertyListTypeTransformer ) 28 | public class PropertyListTypeTransformer: ValueTransformer 29 | { 30 | public override class func transformedValueClass() -> AnyClass 31 | { 32 | NSString.self 33 | } 34 | 35 | public override class func allowsReverseTransformation() -> Bool 36 | { 37 | false 38 | } 39 | 40 | public override func transformedValue( _ value: Any? ) -> Any? 41 | { 42 | guard let node = value as? PropertyListNode else 43 | { 44 | return "--" 45 | } 46 | 47 | if let _ = node.value as? String 48 | { 49 | return "String" 50 | } 51 | else if let _ = node.value as? Bool 52 | { 53 | return "Boolean" 54 | } 55 | else if let _ = node.value as? NSNumber 56 | { 57 | return "Number" 58 | } 59 | else if let _ = node.value as? Data 60 | { 61 | return "Data" 62 | } 63 | else if let _ = node.value as? Date 64 | { 65 | return "Date" 66 | } 67 | else if let _ = node.value as? URL 68 | { 69 | return "URL" 70 | } 71 | else if let _ = node.value as? UUID 72 | { 73 | return "UUID" 74 | } 75 | else if let _ = node.value as? NSArray 76 | { 77 | return "Array" 78 | } 79 | else if let _ = node.value as? NSOrderedSet 80 | { 81 | return "Ordered Set" 82 | } 83 | else if let _ = node.value as? NSSet 84 | { 85 | return "Set" 86 | } 87 | else if let _ = node.value as? NSDictionary 88 | { 89 | return "Dictionary" 90 | } 91 | 92 | return "--" 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /PropertyListEditor/Classes/PropertyListValueTransformer.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2021 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Foundation 26 | 27 | @objc( PropertyListValueTransformer ) 28 | public class PropertyListValueTransformer: ValueTransformer 29 | { 30 | private static var dateFormatter: DateFormatter 31 | { 32 | let formatter = DateFormatter() 33 | 34 | formatter.dateStyle = .full 35 | formatter.timeStyle = .medium 36 | formatter.doesRelativeDateFormatting = false 37 | 38 | return formatter 39 | } 40 | 41 | public override class func transformedValueClass() -> AnyClass 42 | { 43 | NSString.self 44 | } 45 | 46 | public override class func allowsReverseTransformation() -> Bool 47 | { 48 | false 49 | } 50 | 51 | public override func transformedValue( _ value: Any? ) -> Any? 52 | { 53 | guard let node = value as? PropertyListNode else 54 | { 55 | return "--" 56 | } 57 | 58 | if let str = node.value as? String 59 | { 60 | return str 61 | } 62 | else if let bool = node.value as? Bool 63 | { 64 | return bool ? "True" : "False" 65 | } 66 | else if let num = node.value as? NSNumber 67 | { 68 | return num.stringValue 69 | } 70 | else if let data = node.value as? Data 71 | { 72 | return data.base64EncodedString() 73 | } 74 | else if let date = node.value as? Date 75 | { 76 | return PropertyListValueTransformer.dateFormatter.string( from: date ) 77 | } 78 | else if let url = node.value as? URL 79 | { 80 | return url.absoluteString 81 | } 82 | else if let uuid = node.value as? UUID 83 | { 84 | return uuid.uuidString 85 | } 86 | else if let array = node.value as? NSArray 87 | { 88 | return "\( array.count ) Items" 89 | } 90 | else if let set = node.value as? NSOrderedSet 91 | { 92 | return "\( set.count ) Items" 93 | } 94 | else if let set = node.value as? NSSet 95 | { 96 | return "\( set.count ) Items" 97 | } 98 | else if let dict = node.value as? NSDictionary 99 | { 100 | return "\( dict.count ) Items" 101 | } 102 | 103 | return "--" 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /PropertyListEditor/Classes/PropertyListViewController.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2021 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | 27 | public class PropertyListViewController: NSViewController 28 | { 29 | @IBOutlet private var treeController: NSTreeController! 30 | @IBOutlet private var outlineView: NSOutlineView! 31 | 32 | public override var representedObject: Any? 33 | { 34 | didSet 35 | { 36 | self.update() 37 | } 38 | } 39 | 40 | public weak var document: PropertyListDocument? 41 | { 42 | self.representedObject as? PropertyListDocument 43 | } 44 | 45 | public override func viewDidLoad() 46 | { 47 | super.viewDidLoad() 48 | 49 | self.outlineView.sortDescriptors = [ NSSortDescriptor( key: "key", ascending: true, selector: #selector( NSString.localizedCaseInsensitiveCompare( _: ) ) ) ] 50 | } 51 | 52 | private func update() 53 | { 54 | self.treeController.content = nil 55 | 56 | guard let document = self.document else 57 | { 58 | return 59 | } 60 | 61 | self.treeController.addObject( document.content.node ) 62 | 63 | DispatchQueue.main.async 64 | { 65 | if let item = self.outlineView.item( atRow: 0 ) 66 | { 67 | self.outlineView.expandItem( item ) 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /PropertyListEditor/Classes/PropertyListWindowController.swift: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2021 Jean-David Gadina - www.xs-labs.com 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | ******************************************************************************/ 24 | 25 | import Cocoa 26 | 27 | public class PropertyListWindowController: NSWindowController 28 | { 29 | required init?( coder: NSCoder ) 30 | { 31 | super.init( coder: coder ) 32 | 33 | shouldCascadeWindows = true 34 | } 35 | 36 | public override func windowDidLoad() 37 | { 38 | super.windowDidLoad() 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /PropertyListEditor/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | Icon 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0.0 21 | CFBundleVersion 22 | 37 23 | LSApplicationCategoryType 24 | public.app-category.utilities 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2021 XS-Labs. All rights reserved. 29 | NSPrincipalClass 30 | NSApplication 31 | NSMainStoryboardFile 32 | Main 33 | UTImportedTypeDeclarations 34 | 35 | 36 | UTTypeIcons 37 | 38 | UTTypeIconText 39 | plist 40 | UTTypeIconBadgeName 41 | property-list-badge 42 | 43 | UTTypeIdentifier 44 | com.apple.property-list 45 | UTTypeDescription 46 | Property List 47 | UTTypeConformsTo 48 | 49 | public.data 50 | 51 | UTTypeTagSpecification 52 | 53 | public.filename-extension 54 | 55 | plist 56 | 57 | 58 | 59 | 60 | UTTypeIcons 61 | 62 | UTTypeIconText 63 | plist 64 | UTTypeIconBadgeName 65 | 66 | 67 | UTTypeIdentifier 68 | com.apple.xml-property-list 69 | UTTypeDescription 70 | XML Property List 71 | UTTypeConformsTo 72 | 73 | public.xml 74 | com.apple.property-list 75 | 76 | UTTypeTagSpecification 77 | 78 | public.filename-extension 79 | 80 | plist 81 | 82 | 83 | 84 | 85 | UTTypeIcons 86 | 87 | UTTypeIconText 88 | plist 89 | UTTypeIconBadgeName 90 | 91 | 92 | UTTypeIdentifier 93 | com.apple.binary-property-list 94 | UTTypeDescription 95 | Binary Property List 96 | UTTypeConformsTo 97 | 98 | com.apple.property-list 99 | 100 | UTTypeTagSpecification 101 | 102 | public.filename-extension 103 | 104 | plist 105 | 106 | 107 | 108 | 109 | UTTypeIcons 110 | 111 | UTTypeIconText 112 | plist 113 | UTTypeIconBadgeName 114 | 115 | 116 | UTTypeIdentifier 117 | com.apple.ascii-property-list 118 | UTTypeDescription 119 | ASCII Property List 120 | UTTypeConformsTo 121 | 122 | public.text 123 | com.apple.property-list 124 | 125 | UTTypeTagSpecification 126 | 127 | public.filename-extension 128 | 129 | plist 130 | 131 | 132 | 133 | 134 | CFBundleDocumentTypes 135 | 136 | 137 | CFBundleTypeName 138 | Property List 139 | CFBundleTypeIconSystemGenerated 140 | 141 | CFBundleTypeRole 142 | Editor 143 | LSItemContentTypes 144 | 145 | com.apple.property-list 146 | 147 | LSIsAppleDefaultForType 148 | 149 | CFBundleTypeIconFile 150 | 151 | NSDocumentClass 152 | $(PRODUCT_MODULE_NAME).PropertyListDocument 153 | 154 | 155 | CFBundleTypeExtensions 156 | 157 | plist 158 | 159 | LSIsAppleDefaultForType 160 | 161 | CFBundleTypeIconSystemGenerated 162 | 163 | CFBundleTypeName 164 | XML Property List 165 | CFBundleTypeIconFile 166 | 167 | LSItemContentTypes 168 | 169 | com.apple.xml-property-list 170 | 171 | CFBundleTypeRole 172 | Editor 173 | NSDocumentClass 174 | $(PRODUCT_MODULE_NAME).PropertyListDocument 175 | 176 | 177 | CFBundleTypeExtensions 178 | 179 | plist 180 | 181 | LSIsAppleDefaultForType 182 | 183 | CFBundleTypeIconSystemGenerated 184 | 185 | CFBundleTypeName 186 | Binary Property List 187 | CFBundleTypeIconFile 188 | 189 | LSItemContentTypes 190 | 191 | com.apple.binary-property-list 192 | 193 | CFBundleTypeRole 194 | Editor 195 | NSDocumentClass 196 | $(PRODUCT_MODULE_NAME).PropertyListDocument 197 | 198 | 199 | CFBundleTypeExtensions 200 | 201 | plist 202 | 203 | LSIsAppleDefaultForType 204 | 205 | CFBundleTypeIconSystemGenerated 206 | 207 | CFBundleTypeName 208 | ASCII Property List 209 | CFBundleTypeIconFile 210 | 211 | LSItemContentTypes 212 | 213 | com.apple.dt.document.ascii-property-list 214 | 215 | CFBundleTypeRole 216 | Editor 217 | NSDocumentClass 218 | $(PRODUCT_MODULE_NAME).PropertyListDocument 219 | 220 | 221 | 222 | 223 | -------------------------------------------------------------------------------- /PropertyListEditor/PropertyListEditor.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-write 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /PropertyListEditor/UI/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | Default 530 | 531 | 532 | 533 | 534 | 535 | 536 | Left to Right 537 | 538 | 539 | 540 | 541 | 542 | 543 | Right to Left 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | Default 555 | 556 | 557 | 558 | 559 | 560 | 561 | Left to Right 562 | 563 | 564 | 565 | 566 | 567 | 568 | Right to Left 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | PropertyListTypeTransformer 812 | 813 | 814 | 815 | 816 | PropertyListTypeTransformer 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | PropertyListTextColorTransformer 861 | 862 | 863 | 864 | 865 | PropertyListValueTransformer 866 | 867 | 868 | 869 | 870 | PropertyListValueTransformer 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 900 | 904 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PropertyListEditor 2 | ================== 3 | 4 | [![Build Status](https://img.shields.io/github/actions/workflow/status/macmade/PropertyListEditor/ci-mac.yaml?label=macOS&logo=apple)](https://github.com/macmade/PropertyListEditor/actions/workflows/ci-mac.yaml) 5 | [![Issues](http://img.shields.io/github/issues/macmade/PropertyListEditor.svg?logo=github)](https://github.com/macmade/PropertyListEditor/issues) 6 | ![Status](https://img.shields.io/badge/status-active-brightgreen.svg?logo=git) 7 | ![License](https://img.shields.io/badge/license-mit-brightgreen.svg?logo=open-source-initiative) 8 | [![Contact](https://img.shields.io/badge/follow-@macmade-blue.svg?logo=twitter&style=social)](https://twitter.com/macmade) 9 | [![Sponsor](https://img.shields.io/badge/sponsor-macmade-pink.svg?logo=github-sponsors&style=social)](https://github.com/sponsors/macmade) 10 | 11 | ### About 12 | 13 | ... 14 | 15 | License 16 | ------- 17 | 18 | Project is released under the terms of the MIT License. 19 | 20 | Repository Infos 21 | ---------------- 22 | 23 | Owner: Jean-David Gadina - XS-Labs 24 | Web: www.xs-labs.com 25 | Blog: www.noxeos.com 26 | Twitter: @macmade 27 | GitHub: github.com/macmade 28 | LinkedIn: ch.linkedin.com/in/macmade/ 29 | StackOverflow: stackoverflow.com/users/182676/macmade 30 | --------------------------------------------------------------------------------