├── .github
└── FUNDING.yml
├── .gitignore
├── .gitmodules
├── HexFiendFramework
├── HexFiend.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── include
│ └── HexFiend
│ │ ├── HFAnnotatedTree.h
│ │ ├── HFAssert.h
│ │ ├── HFAttributedByteArray.h
│ │ ├── HFBTree.h
│ │ ├── HFBTreeByteArray.h
│ │ ├── HFBinaryGlyphTable.h
│ │ ├── HFBinaryTextRepresenter.h
│ │ ├── HFByteArray.h
│ │ ├── HFByteArrayEditScript.h
│ │ ├── HFByteArrayProxiedData.h
│ │ ├── HFByteArray_Internal.h
│ │ ├── HFByteRangeAttribute.h
│ │ ├── HFByteRangeAttributeArray.h
│ │ ├── HFByteSlice.h
│ │ ├── HFByteSliceFileOperation.h
│ │ ├── HFByteSliceFileOperationQueueEntry.h
│ │ ├── HFByteSlice_Private.h
│ │ ├── HFByteTheme.h
│ │ ├── HFByteThemeColor.h
│ │ ├── HFCancelButton.h
│ │ ├── HFColorRange.h
│ │ ├── HFColumnRepresenter.h
│ │ ├── HFColumnView.h
│ │ ├── HFController.h
│ │ ├── HFControllerCoalescedUndo.h
│ │ ├── HFCustomEncoding.h
│ │ ├── HFEncodingManager.h
│ │ ├── HFFastMemchr.h
│ │ ├── HFFileByteSlice.h
│ │ ├── HFFileReference.h
│ │ ├── HFFrameworkPrefix.h
│ │ ├── HFFullMemoryByteArray.h
│ │ ├── HFFullMemoryByteSlice.h
│ │ ├── HFFunctions.h
│ │ ├── HFGlyphTrie.h
│ │ ├── HFHelperProcessSharedCode.h
│ │ ├── HFHexGlyphTable.h
│ │ ├── HFHexPasteboardOwner.h
│ │ ├── HFHexTextRepresenter.h
│ │ ├── HFLayoutRepresenter.h
│ │ ├── HFLineCountingRepresenter.h
│ │ ├── HFLineCountingView.h
│ │ ├── HFNSStringEncoding.h
│ │ ├── HFObjectGraph.h
│ │ ├── HFPasteboardOwner.h
│ │ ├── HFProgressTracker.h
│ │ ├── HFRandomDataByteSlice.h
│ │ ├── HFRepresenter.h
│ │ ├── HFRepresenterBinaryTextView.h
│ │ ├── HFRepresenterHexTextView.h
│ │ ├── HFRepresenterStringEncodingTextView.h
│ │ ├── HFRepresenterTextView.h
│ │ ├── HFRepresenterTextViewCallout.h
│ │ ├── HFRepresenter_Internal.h
│ │ ├── HFSharedMemoryByteSlice.h
│ │ ├── HFStatusBarRepresenter.h
│ │ ├── HFStringEncoding.h
│ │ ├── HFStringEncodingTextRepresenter.h
│ │ ├── HFTest.h
│ │ ├── HFTextField.h
│ │ ├── HFTextRepresenter.h
│ │ ├── HFTextRepresenter_Internal.h
│ │ ├── HFTextSelectionPulseView.h
│ │ ├── HFTextView.h
│ │ ├── HFTextVisualStyleRun.h
│ │ ├── HFTypes.h
│ │ ├── HFUIUtils.h
│ │ ├── HFVerticalScrollerRepresenter.h
│ │ ├── HexFiend-Swift.h
│ │ └── HexFiend.h
└── src
│ ├── HFAnnotatedTree.h
│ ├── HFAnnotatedTree.m
│ ├── HFAssert.h
│ ├── HFAttributedByteArray.h
│ ├── HFAttributedByteArray.m
│ ├── HFBTree.h
│ ├── HFBTree.m
│ ├── HFBTreeByteArray.h
│ ├── HFBTreeByteArray.m
│ ├── HFBinaryGlyphTable.h
│ ├── HFBinaryGlyphTable.m
│ ├── HFBinaryTextRepresenter.h
│ ├── HFBinaryTextRepresenter.m
│ ├── HFByteArray.h
│ ├── HFByteArray.m
│ ├── HFByteArrayEditScript.h
│ ├── HFByteArrayEditScript.m
│ ├── HFByteArrayProxiedData.h
│ ├── HFByteArrayProxiedData.m
│ ├── HFByteArray_FileWriting.m
│ ├── HFByteArray_FindReplace.m
│ ├── HFByteArray_Internal.h
│ ├── HFByteRangeAttribute.h
│ ├── HFByteRangeAttribute.m
│ ├── HFByteRangeAttributeArray.h
│ ├── HFByteRangeAttributeArray.m
│ ├── HFByteSlice.h
│ ├── HFByteSlice.m
│ ├── HFByteSliceFileOperation.h
│ ├── HFByteSliceFileOperation.m
│ ├── HFByteSliceFileOperationQueueEntry.h
│ ├── HFByteSliceFileOperationQueueEntry.m
│ ├── HFByteSlice_Private.h
│ ├── HFByteTheme.h
│ ├── HFByteTheme.m
│ ├── HFByteThemeColor.h
│ ├── HFCancelButton.h
│ ├── HFCancelButton.m
│ ├── HFColorRange.h
│ ├── HFColorRange.m
│ ├── HFColumnRepresenter.h
│ ├── HFColumnRepresenter.m
│ ├── HFColumnView.h
│ ├── HFColumnView.m
│ ├── HFController.h
│ ├── HFController.m
│ ├── HFControllerCoalescedUndo.h
│ ├── HFControllerCoalescedUndo.m
│ ├── HFCustomEncoding.h
│ ├── HFCustomEncoding.m
│ ├── HFEncodingManager.h
│ ├── HFEncodingManager.m
│ ├── HFFastMemchr.h
│ ├── HFFastMemchr.m
│ ├── HFFileByteSlice.h
│ ├── HFFileByteSlice.m
│ ├── HFFileReference.h
│ ├── HFFileReference.m
│ ├── HFFrameworkPrefix.h
│ ├── HFFullMemoryByteArray.h
│ ├── HFFullMemoryByteArray.m
│ ├── HFFullMemoryByteSlice.h
│ ├── HFFullMemoryByteSlice.m
│ ├── HFFunctions.h
│ ├── HFFunctions.m
│ ├── HFGlyphTrie.h
│ ├── HFGlyphTrie.m
│ ├── HFHelperProcessSharedCode.h
│ ├── HFHexGlyphTable.h
│ ├── HFHexGlyphTable.m
│ ├── HFHexPasteboardOwner.h
│ ├── HFHexPasteboardOwner.m
│ ├── HFHexTextRepresenter.h
│ ├── HFHexTextRepresenter.m
│ ├── HFLayoutRepresenter.h
│ ├── HFLayoutRepresenter.m
│ ├── HFLineCountingRepresenter.h
│ ├── HFLineCountingRepresenter.m
│ ├── HFLineCountingView.h
│ ├── HFLineCountingView.m
│ ├── HFNSStringEncoding.h
│ ├── HFNSStringEncoding.m
│ ├── HFObjectGraph.h
│ ├── HFObjectGraph.m
│ ├── HFPasteboardOwner.h
│ ├── HFPasteboardOwner.m
│ ├── HFProgressTracker.h
│ ├── HFProgressTracker.m
│ ├── HFRandomDataByteSlice.h
│ ├── HFRandomDataByteSlice.m
│ ├── HFRepresenter.h
│ ├── HFRepresenter.m
│ ├── HFRepresenterBinaryTextView.h
│ ├── HFRepresenterBinaryTextView.m
│ ├── HFRepresenterHexTextView.h
│ ├── HFRepresenterHexTextView.m
│ ├── HFRepresenterStringEncodingTextView.h
│ ├── HFRepresenterStringEncodingTextView.m
│ ├── HFRepresenterTextView.h
│ ├── HFRepresenterTextView.m
│ ├── HFRepresenterTextViewCallout.h
│ ├── HFRepresenterTextViewCallout.m
│ ├── HFRepresenter_Internal.h
│ ├── HFSharedMemoryByteSlice.h
│ ├── HFSharedMemoryByteSlice.m
│ ├── HFStatusBarRepresenter.h
│ ├── HFStatusBarRepresenter.m
│ ├── HFStringEncoding.h
│ ├── HFStringEncoding.m
│ ├── HFStringEncodingTextRepresenter.h
│ ├── HFStringEncodingTextRepresenter.m
│ ├── HFTest.h
│ ├── HFTextField.h
│ ├── HFTextField.m
│ ├── HFTextRepresenter.h
│ ├── HFTextRepresenter.m
│ ├── HFTextRepresenter_Internal.h
│ ├── HFTextRepresenter_KeyBinding.m
│ ├── HFTextSelectionPulseView.h
│ ├── HFTextSelectionPulseView.m
│ ├── HFTextView.h
│ ├── HFTextView.m
│ ├── HFTextVisualStyleRun.h
│ ├── HFTextVisualStyleRun.m
│ ├── HFTypes.h
│ ├── HFUIUtils.h
│ ├── HFUIUtils.m
│ ├── HFVerticalScrollerRepresenter.h
│ ├── HFVerticalScrollerRepresenter.m
│ ├── HexFiend-Swift.h
│ └── HexFiend.h
├── HexFiendShims
├── include
│ ├── HFByteTheme.h
│ └── HexFiend-Swift.h
└── src
│ └── HFByteTheme.m
├── LICENSE
├── LNPropertyListEditor
├── LNPropertyListEditor.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── LNPropertyListEditor.xcscheme
├── LNPropertyListEditor
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── minus.imageset
│ │ │ ├── Contents.json
│ │ │ └── minus.pdf
│ │ └── plus.imageset
│ │ │ ├── Contents.json
│ │ │ └── plus.pdf
│ ├── Implementation
│ │ ├── LNPropertyListCellTextField.h
│ │ ├── LNPropertyListCellTextField.m
│ │ ├── LNPropertyListCellView.h
│ │ ├── LNPropertyListCellView.m
│ │ ├── LNPropertyListDataEditorPanel.h
│ │ ├── LNPropertyListDataEditorPanel.m
│ │ ├── LNPropertyListDatePicker.h
│ │ ├── LNPropertyListDatePicker.m
│ │ ├── LNPropertyListDatePickerCell.h
│ │ ├── LNPropertyListDatePickerCell.mm
│ │ ├── LNPropertyListDatePickerPanel.h
│ │ ├── LNPropertyListDatePickerPanel.m
│ │ ├── LNPropertyListEditor-Private.h
│ │ ├── LNPropertyListEditor.m
│ │ ├── LNPropertyListEditorOutline.xib
│ │ ├── LNPropertyListNode-Private.h
│ │ ├── LNPropertyListNode.m
│ │ ├── LNPropertyListOutlineView.h
│ │ ├── LNPropertyListOutlineView.m
│ │ ├── LNPropertyListPopUpButtonCell.h
│ │ ├── LNPropertyListPopUpButtonCell.m
│ │ ├── LNPropertyListRowView.h
│ │ ├── LNPropertyListRowView.m
│ │ ├── NSObject+LNPropertyListValueSorting.h
│ │ ├── NSObject+LNPropertyListValueSorting.m
│ │ ├── _LNPropertyListDatePicker.h
│ │ └── _LNPropertyListDatePicker.m
│ ├── Info.plist
│ ├── LNPropertyListEditor.h
│ └── LNPropertyListNode.h
└── include
│ └── LNPropertyListEditor
│ ├── LNPropertyListEditor.h
│ └── LNPropertyListNode.h
├── LNPropertyListEditorExample
├── LNPropertyListEditorExample.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── LNPropertyListEditorExample.xcscheme
└── LNPropertyListEditorExample
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Base.lproj
│ └── Main.storyboard
│ ├── Info.plist
│ ├── ViewController.h
│ ├── ViewController.m
│ └── main.m
├── Package.swift
├── README.md
├── Supplements
├── Screenshot_1_Dark.png
└── Screenshot_2_Dark.png
├── prepare_spm_support.rb
└── releaseVersion.sh
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: LeoNatan
2 | custom: ['paypal.me/LeoNatan25']
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xccheckout
23 | *.xcscmblueprint
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 | *.ipa
28 | *.dSYM.zip
29 | *.dSYM
30 |
31 | # CocoaPods
32 | #
33 | # We recommend against adding the Pods directory to your .gitignore. However
34 | # you should judge for yourself, the pros and cons are mentioned at:
35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
36 | #
37 | # Pods/
38 |
39 | # Carthage
40 | #
41 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
42 | # Carthage/Checkouts
43 |
44 | Carthage/Build
45 |
46 | # fastlane
47 | #
48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
49 | # screenshots whenever they are needed.
50 | # For more information about the recommended setup visit:
51 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
52 |
53 | fastlane/report.xml
54 | fastlane/Preview.html
55 | fastlane/screenshots
56 | fastlane/test_output
57 |
58 | # Code Injection
59 | #
60 | # After new code Injection tools there's a generated folder /iOSInjectionProject
61 | # https://github.com/johnno1962/injectionforxcode
62 |
63 | iOSInjectionProject/
64 | /_tmp_release_notes.md
65 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "HexFiend"]
2 | path = HexFiend
3 | url = https://github.com/HexFiend/HexFiend.git
4 |
--------------------------------------------------------------------------------
/HexFiendFramework/HexFiend.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/HexFiendFramework/HexFiend.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFAnnotatedTree.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFAnnotatedTree.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFAssert.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFAssert.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFAttributedByteArray.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFAttributedByteArray.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFBTree.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/BTree/HFBTree.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFBTreeByteArray.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFBTreeByteArray.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFBinaryGlyphTable.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFBinaryGlyphTable.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFBinaryTextRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFBinaryTextRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFByteArray.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFByteArray.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFByteArrayEditScript.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFByteArrayEditScript.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFByteArrayProxiedData.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFByteArrayProxiedData.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFByteArray_Internal.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFByteArray_Internal.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFByteRangeAttribute.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFByteRangeAttribute.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFByteRangeAttributeArray.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFByteRangeAttributeArray.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFByteSlice.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFByteSlice.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFByteSliceFileOperation.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFByteSliceFileOperation.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFByteSliceFileOperationQueueEntry.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFByteSliceFileOperationQueueEntry.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFByteSlice_Private.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFByteSlice_Private.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFByteTheme.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiendShims/include/HFByteTheme.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFByteThemeColor.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFByteThemeColor.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFCancelButton.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFCancelButton.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFColorRange.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFColorRange.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFColumnRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFColumnRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFColumnView.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFColumnView.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFController.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFController.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFControllerCoalescedUndo.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFControllerCoalescedUndo.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFCustomEncoding.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFCustomEncoding.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFEncodingManager.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFEncodingManager.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFFastMemchr.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFFastMemchr.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFFileByteSlice.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFFileByteSlice.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFFileReference.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFFileReference.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFFrameworkPrefix.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFFrameworkPrefix.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFFullMemoryByteArray.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFFullMemoryByteArray.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFFullMemoryByteSlice.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFFullMemoryByteSlice.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFFunctions.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFFunctions.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFGlyphTrie.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFGlyphTrie.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFHelperProcessSharedCode.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFHelperProcessSharedCode.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFHexGlyphTable.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFHexGlyphTable.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFHexPasteboardOwner.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFHexPasteboardOwner.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFHexTextRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFHexTextRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFLayoutRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFLayoutRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFLineCountingRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFLineCountingRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFLineCountingView.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFLineCountingView.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFNSStringEncoding.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFNSStringEncoding.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFObjectGraph.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFObjectGraph.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFPasteboardOwner.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFPasteboardOwner.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFProgressTracker.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFProgressTracker.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFRandomDataByteSlice.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFRandomDataByteSlice.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFRepresenterBinaryTextView.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFRepresenterBinaryTextView.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFRepresenterHexTextView.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFRepresenterHexTextView.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFRepresenterStringEncodingTextView.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFRepresenterStringEncodingTextView.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFRepresenterTextView.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFRepresenterTextView.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFRepresenterTextViewCallout.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFRepresenterTextViewCallout.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFRepresenter_Internal.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFRepresenter_Internal.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFSharedMemoryByteSlice.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFSharedMemoryByteSlice.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFStatusBarRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFStatusBarRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFStringEncoding.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFStringEncoding.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFStringEncodingTextRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFStringEncodingTextRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFTest.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/tests/HFTest.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFTextField.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFTextField.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFTextRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFTextRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFTextRepresenter_Internal.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFTextRepresenter_Internal.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFTextSelectionPulseView.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFTextSelectionPulseView.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFTextView.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFTextView.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFTextVisualStyleRun.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFTextVisualStyleRun.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFTypes.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFTypes.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFUIUtils.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFUIUtils.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HFVerticalScrollerRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HFVerticalScrollerRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HexFiend-Swift.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiendShims/include/HexFiend-Swift.h
--------------------------------------------------------------------------------
/HexFiendFramework/include/HexFiend/HexFiend.h:
--------------------------------------------------------------------------------
1 | ../../../HexFiend/framework/sources/HexFiend.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFAnnotatedTree.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFAnnotatedTree.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFAnnotatedTree.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFAnnotatedTree.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFAssert.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFAssert.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFAttributedByteArray.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFAttributedByteArray.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFAttributedByteArray.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFAttributedByteArray.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFBTree.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/BTree/HFBTree.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFBTree.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/BTree/HFBTree.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFBTreeByteArray.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFBTreeByteArray.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFBTreeByteArray.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFBTreeByteArray.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFBinaryGlyphTable.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFBinaryGlyphTable.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFBinaryGlyphTable.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFBinaryGlyphTable.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFBinaryTextRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFBinaryTextRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFBinaryTextRepresenter.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFBinaryTextRepresenter.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteArray.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteArray.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteArray.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteArray.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteArrayEditScript.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteArrayEditScript.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteArrayEditScript.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteArrayEditScript.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteArrayProxiedData.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteArrayProxiedData.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteArrayProxiedData.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteArrayProxiedData.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteArray_FileWriting.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteArray_FileWriting.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteArray_FindReplace.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteArray_FindReplace.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteArray_Internal.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteArray_Internal.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteRangeAttribute.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteRangeAttribute.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteRangeAttribute.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteRangeAttribute.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteRangeAttributeArray.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteRangeAttributeArray.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteRangeAttributeArray.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteRangeAttributeArray.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteSlice.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteSlice.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteSlice.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteSlice.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteSliceFileOperation.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteSliceFileOperation.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteSliceFileOperation.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteSliceFileOperation.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteSliceFileOperationQueueEntry.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteSliceFileOperationQueueEntry.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteSliceFileOperationQueueEntry.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteSliceFileOperationQueueEntry.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteSlice_Private.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteSlice_Private.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteTheme.h:
--------------------------------------------------------------------------------
1 | ../../HexFiendShims/include/HFByteTheme.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteTheme.m:
--------------------------------------------------------------------------------
1 | ../../HexFiendShims/src/HFByteTheme.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFByteThemeColor.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFByteThemeColor.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFCancelButton.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFCancelButton.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFCancelButton.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFCancelButton.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFColorRange.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFColorRange.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFColorRange.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFColorRange.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFColumnRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFColumnRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFColumnRepresenter.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFColumnRepresenter.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFColumnView.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFColumnView.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFColumnView.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFColumnView.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFController.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFController.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFController.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFController.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFControllerCoalescedUndo.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFControllerCoalescedUndo.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFControllerCoalescedUndo.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFControllerCoalescedUndo.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFCustomEncoding.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFCustomEncoding.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFCustomEncoding.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFCustomEncoding.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFEncodingManager.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFEncodingManager.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFEncodingManager.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFEncodingManager.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFFastMemchr.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFFastMemchr.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFFastMemchr.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFFastMemchr.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFFileByteSlice.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFFileByteSlice.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFFileByteSlice.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFFileByteSlice.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFFileReference.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFFileReference.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFFileReference.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFFileReference.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFFrameworkPrefix.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFFrameworkPrefix.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFFullMemoryByteArray.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFFullMemoryByteArray.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFFullMemoryByteArray.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFFullMemoryByteArray.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFFullMemoryByteSlice.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFFullMemoryByteSlice.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFFullMemoryByteSlice.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFFullMemoryByteSlice.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFFunctions.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFFunctions.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFFunctions.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFFunctions.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFGlyphTrie.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFGlyphTrie.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFGlyphTrie.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFGlyphTrie.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFHelperProcessSharedCode.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFHelperProcessSharedCode.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFHexGlyphTable.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFHexGlyphTable.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFHexGlyphTable.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFHexGlyphTable.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFHexPasteboardOwner.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFHexPasteboardOwner.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFHexPasteboardOwner.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFHexPasteboardOwner.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFHexTextRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFHexTextRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFHexTextRepresenter.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFHexTextRepresenter.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFLayoutRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFLayoutRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFLayoutRepresenter.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFLayoutRepresenter.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFLineCountingRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFLineCountingRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFLineCountingRepresenter.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFLineCountingRepresenter.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFLineCountingView.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFLineCountingView.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFLineCountingView.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFLineCountingView.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFNSStringEncoding.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFNSStringEncoding.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFNSStringEncoding.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFNSStringEncoding.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFObjectGraph.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFObjectGraph.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFObjectGraph.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFObjectGraph.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFPasteboardOwner.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFPasteboardOwner.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFPasteboardOwner.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFPasteboardOwner.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFProgressTracker.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFProgressTracker.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFProgressTracker.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFProgressTracker.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFRandomDataByteSlice.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFRandomDataByteSlice.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFRandomDataByteSlice.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFRandomDataByteSlice.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFRepresenter.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFRepresenter.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFRepresenterBinaryTextView.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFRepresenterBinaryTextView.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFRepresenterBinaryTextView.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFRepresenterBinaryTextView.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFRepresenterHexTextView.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFRepresenterHexTextView.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFRepresenterHexTextView.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFRepresenterHexTextView.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFRepresenterStringEncodingTextView.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFRepresenterStringEncodingTextView.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFRepresenterStringEncodingTextView.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFRepresenterStringEncodingTextView.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFRepresenterTextView.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFRepresenterTextView.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFRepresenterTextView.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFRepresenterTextView.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFRepresenterTextViewCallout.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFRepresenterTextViewCallout.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFRepresenterTextViewCallout.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFRepresenterTextViewCallout.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFRepresenter_Internal.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFRepresenter_Internal.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFSharedMemoryByteSlice.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFSharedMemoryByteSlice.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFSharedMemoryByteSlice.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFSharedMemoryByteSlice.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFStatusBarRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFStatusBarRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFStatusBarRepresenter.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFStatusBarRepresenter.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFStringEncoding.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFStringEncoding.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFStringEncoding.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFStringEncoding.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFStringEncodingTextRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFStringEncodingTextRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFStringEncodingTextRepresenter.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFStringEncodingTextRepresenter.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFTest.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/tests/HFTest.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFTextField.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFTextField.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFTextField.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFTextField.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFTextRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFTextRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFTextRepresenter.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFTextRepresenter.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFTextRepresenter_Internal.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFTextRepresenter_Internal.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFTextRepresenter_KeyBinding.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFTextRepresenter_KeyBinding.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFTextSelectionPulseView.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFTextSelectionPulseView.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFTextSelectionPulseView.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFTextSelectionPulseView.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFTextView.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFTextView.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFTextView.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFTextView.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFTextVisualStyleRun.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFTextVisualStyleRun.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFTextVisualStyleRun.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFTextVisualStyleRun.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFTypes.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFTypes.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFUIUtils.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFUIUtils.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFUIUtils.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFUIUtils.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFVerticalScrollerRepresenter.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFVerticalScrollerRepresenter.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HFVerticalScrollerRepresenter.m:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HFVerticalScrollerRepresenter.m
--------------------------------------------------------------------------------
/HexFiendFramework/src/HexFiend-Swift.h:
--------------------------------------------------------------------------------
1 | ../../HexFiendShims/include/HexFiend-Swift.h
--------------------------------------------------------------------------------
/HexFiendFramework/src/HexFiend.h:
--------------------------------------------------------------------------------
1 | ../../HexFiend/framework/sources/HexFiend.h
--------------------------------------------------------------------------------
/HexFiendShims/include/HFByteTheme.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface HFByteTheme : NSObject
5 |
6 | @property (readonly) struct HFByteThemeColor* darkColorTable;
7 | @property (readonly) struct HFByteThemeColor* lightColorTable;
8 |
9 | @end
10 |
--------------------------------------------------------------------------------
/HexFiendShims/include/HexFiend-Swift.h:
--------------------------------------------------------------------------------
1 | #import
--------------------------------------------------------------------------------
/HexFiendShims/src/HFByteTheme.m:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @implementation HFByteTheme @end
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018-2021 Leo Natan
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 all
13 | 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 THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 54;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 391FF02B2084060000005D0F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 391FF02A2084060000005D0F /* Assets.xcassets */; };
11 | 391FF02F208412CC00005D0F /* LNPropertyListRowView.h in Headers */ = {isa = PBXBuildFile; fileRef = 391FF02D208412CC00005D0F /* LNPropertyListRowView.h */; settings = {ATTRIBUTES = (Private, ); }; };
12 | 391FF030208412CC00005D0F /* LNPropertyListRowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 391FF02E208412CC00005D0F /* LNPropertyListRowView.m */; };
13 | 391FF0332084270400005D0F /* LNPropertyListOutlineView.h in Headers */ = {isa = PBXBuildFile; fileRef = 391FF0312084270400005D0F /* LNPropertyListOutlineView.h */; settings = {ATTRIBUTES = (Private, ); }; };
14 | 391FF0342084270400005D0F /* LNPropertyListOutlineView.m in Sources */ = {isa = PBXBuildFile; fileRef = 391FF0322084270400005D0F /* LNPropertyListOutlineView.m */; };
15 | 3925913A263C52B100AF78D3 /* LNPropertyListCellTextField.h in Headers */ = {isa = PBXBuildFile; fileRef = 39259138263C52B100AF78D3 /* LNPropertyListCellTextField.h */; settings = {ATTRIBUTES = (Private, ); }; };
16 | 3925913B263C52B100AF78D3 /* LNPropertyListCellTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 39259139263C52B100AF78D3 /* LNPropertyListCellTextField.m */; };
17 | 393E1872207F61C2002E6136 /* LNPropertyListEditorOutline.xib in Resources */ = {isa = PBXBuildFile; fileRef = 393E1871207F61C2002E6136 /* LNPropertyListEditorOutline.xib */; };
18 | 393E1875207F64A0002E6136 /* LNPropertyListEditor.h in Headers */ = {isa = PBXBuildFile; fileRef = 393E1873207F64A0002E6136 /* LNPropertyListEditor.h */; settings = {ATTRIBUTES = (Public, ); }; };
19 | 393E1876207F64A0002E6136 /* LNPropertyListEditor.m in Sources */ = {isa = PBXBuildFile; fileRef = 393E1874207F64A0002E6136 /* LNPropertyListEditor.m */; };
20 | 393E1879207F68B4002E6136 /* LNPropertyListNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 393E1877207F68B4002E6136 /* LNPropertyListNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
21 | 393E187A207F68B4002E6136 /* LNPropertyListNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 393E1878207F68B4002E6136 /* LNPropertyListNode.m */; };
22 | 393E1882207FAD26002E6136 /* LNPropertyListNode-Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 393E1881207FAD26002E6136 /* LNPropertyListNode-Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
23 | 393E1885207FAEC6002E6136 /* LNPropertyListCellView.h in Headers */ = {isa = PBXBuildFile; fileRef = 393E1883207FAEC6002E6136 /* LNPropertyListCellView.h */; settings = {ATTRIBUTES = (Private, ); }; };
24 | 393E1886207FAEC6002E6136 /* LNPropertyListCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 393E1884207FAEC6002E6136 /* LNPropertyListCellView.m */; };
25 | 3941486F2095E85900A21F96 /* LNPropertyListDatePickerCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 3941486D2095E85900A21F96 /* LNPropertyListDatePickerCell.h */; settings = {ATTRIBUTES = (Private, ); }; };
26 | 394148702095E85900A21F96 /* LNPropertyListDatePickerCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3941486E2095E85900A21F96 /* LNPropertyListDatePickerCell.mm */; };
27 | 3946906C20976ED300B4A457 /* LNPropertyListDatePicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 3946906A20976ED300B4A457 /* LNPropertyListDatePicker.h */; settings = {ATTRIBUTES = (Private, ); }; };
28 | 3946906D20976ED300B4A457 /* LNPropertyListDatePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 3946906B20976ED300B4A457 /* LNPropertyListDatePicker.m */; };
29 | 39D1276E26D9255D007E64D1 /* HexFiend.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 39D1276B26D9254C007E64D1 /* HexFiend.framework */; };
30 | 39D1276F26D9255D007E64D1 /* HexFiend.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 39D1276B26D9254C007E64D1 /* HexFiend.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
31 | 39D1528F23289668009124C8 /* LNPropertyListDatePickerPanel.h in Headers */ = {isa = PBXBuildFile; fileRef = 39D1528D23289668009124C8 /* LNPropertyListDatePickerPanel.h */; settings = {ATTRIBUTES = (Private, ); }; };
32 | 39D1529023289668009124C8 /* LNPropertyListDatePickerPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = 39D1528E23289668009124C8 /* LNPropertyListDatePickerPanel.m */; };
33 | 39D152962328A9C4009124C8 /* _LNPropertyListDatePicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 39D152942328A9C4009124C8 /* _LNPropertyListDatePicker.h */; settings = {ATTRIBUTES = (Private, ); }; };
34 | 39D152972328A9C4009124C8 /* _LNPropertyListDatePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 39D152952328A9C4009124C8 /* _LNPropertyListDatePicker.m */; };
35 | 39D55F2026D82C100013B105 /* LNPropertyListDataEditorPanel.h in Headers */ = {isa = PBXBuildFile; fileRef = 39D55F1E26D82C100013B105 /* LNPropertyListDataEditorPanel.h */; settings = {ATTRIBUTES = (Private, ); }; };
36 | 39D55F2126D82C100013B105 /* LNPropertyListDataEditorPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = 39D55F1F26D82C100013B105 /* LNPropertyListDataEditorPanel.m */; };
37 | 39DE8E942092030500ED16B4 /* LNPropertyListPopUpButtonCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 39DE8E922092030500ED16B4 /* LNPropertyListPopUpButtonCell.h */; settings = {ATTRIBUTES = (Private, ); }; };
38 | 39DE8E952092030500ED16B4 /* LNPropertyListPopUpButtonCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 39DE8E932092030500ED16B4 /* LNPropertyListPopUpButtonCell.m */; };
39 | 39DE8E9C2092214400ED16B4 /* LNPropertyListEditor-Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 39DE8E9B2092214300ED16B4 /* LNPropertyListEditor-Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
40 | 39F537F3264305AF00AB263A /* NSObject+LNPropertyListValueSorting.h in Headers */ = {isa = PBXBuildFile; fileRef = 39F537F1264305AF00AB263A /* NSObject+LNPropertyListValueSorting.h */; settings = {ATTRIBUTES = (Private, ); }; };
41 | 39F537F4264305AF00AB263A /* NSObject+LNPropertyListValueSorting.m in Sources */ = {isa = PBXBuildFile; fileRef = 39F537F2264305AF00AB263A /* NSObject+LNPropertyListValueSorting.m */; };
42 | /* End PBXBuildFile section */
43 |
44 | /* Begin PBXContainerItemProxy section */
45 | 39D1276A26D9254C007E64D1 /* PBXContainerItemProxy */ = {
46 | isa = PBXContainerItemProxy;
47 | containerPortal = 39D1276626D9254C007E64D1 /* HexFiend.xcodeproj */;
48 | proxyType = 2;
49 | remoteGlobalIDString = 2A5473BE36E204DC14FF8C9C;
50 | remoteInfo = HexFiend;
51 | };
52 | 39D1276C26D92552007E64D1 /* PBXContainerItemProxy */ = {
53 | isa = PBXContainerItemProxy;
54 | containerPortal = 39D1276626D9254C007E64D1 /* HexFiend.xcodeproj */;
55 | proxyType = 1;
56 | remoteGlobalIDString = AFF1D22ED47CE0FD180F70EB;
57 | remoteInfo = HexFiend;
58 | };
59 | /* End PBXContainerItemProxy section */
60 |
61 | /* Begin PBXCopyFilesBuildPhase section */
62 | 39D55F1D26D829970013B105 /* Embed Frameworks */ = {
63 | isa = PBXCopyFilesBuildPhase;
64 | buildActionMask = 2147483647;
65 | dstPath = "";
66 | dstSubfolderSpec = 10;
67 | files = (
68 | 39D1276F26D9255D007E64D1 /* HexFiend.framework in Embed Frameworks */,
69 | );
70 | name = "Embed Frameworks";
71 | runOnlyForDeploymentPostprocessing = 0;
72 | };
73 | /* End PBXCopyFilesBuildPhase section */
74 |
75 | /* Begin PBXFileReference section */
76 | 391FF02A2084060000005D0F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
77 | 391FF02D208412CC00005D0F /* LNPropertyListRowView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LNPropertyListRowView.h; sourceTree = ""; };
78 | 391FF02E208412CC00005D0F /* LNPropertyListRowView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LNPropertyListRowView.m; sourceTree = ""; };
79 | 391FF0312084270400005D0F /* LNPropertyListOutlineView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LNPropertyListOutlineView.h; sourceTree = ""; };
80 | 391FF0322084270400005D0F /* LNPropertyListOutlineView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LNPropertyListOutlineView.m; sourceTree = ""; };
81 | 39259138263C52B100AF78D3 /* LNPropertyListCellTextField.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LNPropertyListCellTextField.h; sourceTree = ""; };
82 | 39259139263C52B100AF78D3 /* LNPropertyListCellTextField.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LNPropertyListCellTextField.m; sourceTree = ""; };
83 | 393E1839207F6119002E6136 /* LNPropertyListEditor.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LNPropertyListEditor.framework; sourceTree = BUILT_PRODUCTS_DIR; };
84 | 393E183D207F6119002E6136 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
85 | 393E1871207F61C2002E6136 /* LNPropertyListEditorOutline.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LNPropertyListEditorOutline.xib; sourceTree = ""; };
86 | 393E1873207F64A0002E6136 /* LNPropertyListEditor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LNPropertyListEditor.h; sourceTree = ""; };
87 | 393E1874207F64A0002E6136 /* LNPropertyListEditor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LNPropertyListEditor.m; sourceTree = ""; };
88 | 393E1877207F68B4002E6136 /* LNPropertyListNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LNPropertyListNode.h; sourceTree = ""; };
89 | 393E1878207F68B4002E6136 /* LNPropertyListNode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LNPropertyListNode.m; sourceTree = ""; };
90 | 393E1881207FAD26002E6136 /* LNPropertyListNode-Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "LNPropertyListNode-Private.h"; sourceTree = ""; };
91 | 393E1883207FAEC6002E6136 /* LNPropertyListCellView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LNPropertyListCellView.h; sourceTree = ""; };
92 | 393E1884207FAEC6002E6136 /* LNPropertyListCellView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LNPropertyListCellView.m; sourceTree = ""; };
93 | 3941486D2095E85900A21F96 /* LNPropertyListDatePickerCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LNPropertyListDatePickerCell.h; sourceTree = ""; };
94 | 3941486E2095E85900A21F96 /* LNPropertyListDatePickerCell.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = LNPropertyListDatePickerCell.mm; sourceTree = ""; };
95 | 3946906A20976ED300B4A457 /* LNPropertyListDatePicker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LNPropertyListDatePicker.h; sourceTree = ""; };
96 | 3946906B20976ED300B4A457 /* LNPropertyListDatePicker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LNPropertyListDatePicker.m; sourceTree = ""; };
97 | 39D1276626D9254C007E64D1 /* HexFiend.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = HexFiend.xcodeproj; path = ../HexFiendFramework/HexFiend.xcodeproj; sourceTree = ""; };
98 | 39D1528D23289668009124C8 /* LNPropertyListDatePickerPanel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LNPropertyListDatePickerPanel.h; sourceTree = ""; };
99 | 39D1528E23289668009124C8 /* LNPropertyListDatePickerPanel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LNPropertyListDatePickerPanel.m; sourceTree = ""; };
100 | 39D152942328A9C4009124C8 /* _LNPropertyListDatePicker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _LNPropertyListDatePicker.h; sourceTree = ""; };
101 | 39D152952328A9C4009124C8 /* _LNPropertyListDatePicker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = _LNPropertyListDatePicker.m; sourceTree = ""; };
102 | 39D55F1E26D82C100013B105 /* LNPropertyListDataEditorPanel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LNPropertyListDataEditorPanel.h; sourceTree = ""; };
103 | 39D55F1F26D82C100013B105 /* LNPropertyListDataEditorPanel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LNPropertyListDataEditorPanel.m; sourceTree = ""; };
104 | 39DE8E922092030500ED16B4 /* LNPropertyListPopUpButtonCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LNPropertyListPopUpButtonCell.h; sourceTree = ""; };
105 | 39DE8E932092030500ED16B4 /* LNPropertyListPopUpButtonCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LNPropertyListPopUpButtonCell.m; sourceTree = ""; };
106 | 39DE8E9B2092214300ED16B4 /* LNPropertyListEditor-Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "LNPropertyListEditor-Private.h"; sourceTree = ""; };
107 | 39F537F1264305AF00AB263A /* NSObject+LNPropertyListValueSorting.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSObject+LNPropertyListValueSorting.h"; sourceTree = ""; };
108 | 39F537F2264305AF00AB263A /* NSObject+LNPropertyListValueSorting.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSObject+LNPropertyListValueSorting.m"; sourceTree = ""; };
109 | /* End PBXFileReference section */
110 |
111 | /* Begin PBXFrameworksBuildPhase section */
112 | 393E1835207F6119002E6136 /* Frameworks */ = {
113 | isa = PBXFrameworksBuildPhase;
114 | buildActionMask = 2147483647;
115 | files = (
116 | 39D1276E26D9255D007E64D1 /* HexFiend.framework in Frameworks */,
117 | );
118 | runOnlyForDeploymentPostprocessing = 0;
119 | };
120 | /* End PBXFrameworksBuildPhase section */
121 |
122 | /* Begin PBXGroup section */
123 | 393E182F207F6119002E6136 = {
124 | isa = PBXGroup;
125 | children = (
126 | 39D1276626D9254C007E64D1 /* HexFiend.xcodeproj */,
127 | 393E183B207F6119002E6136 /* LNPropertyListEditor */,
128 | 393E183A207F6119002E6136 /* Products */,
129 | 39D55F1926D829600013B105 /* Frameworks */,
130 | );
131 | sourceTree = "";
132 | };
133 | 393E183A207F6119002E6136 /* Products */ = {
134 | isa = PBXGroup;
135 | children = (
136 | 393E1839207F6119002E6136 /* LNPropertyListEditor.framework */,
137 | );
138 | name = Products;
139 | sourceTree = "";
140 | };
141 | 393E183B207F6119002E6136 /* LNPropertyListEditor */ = {
142 | isa = PBXGroup;
143 | children = (
144 | 391FF02A2084060000005D0F /* Assets.xcassets */,
145 | 3954022126150727005EEA38 /* Implementation */,
146 | 393E1877207F68B4002E6136 /* LNPropertyListNode.h */,
147 | 393E1873207F64A0002E6136 /* LNPropertyListEditor.h */,
148 | 393E183D207F6119002E6136 /* Info.plist */,
149 | );
150 | path = LNPropertyListEditor;
151 | sourceTree = "";
152 | };
153 | 3954022126150727005EEA38 /* Implementation */ = {
154 | isa = PBXGroup;
155 | children = (
156 | 39D152942328A9C4009124C8 /* _LNPropertyListDatePicker.h */,
157 | 39D152952328A9C4009124C8 /* _LNPropertyListDatePicker.m */,
158 | 39259138263C52B100AF78D3 /* LNPropertyListCellTextField.h */,
159 | 39259139263C52B100AF78D3 /* LNPropertyListCellTextField.m */,
160 | 393E1883207FAEC6002E6136 /* LNPropertyListCellView.h */,
161 | 393E1884207FAEC6002E6136 /* LNPropertyListCellView.m */,
162 | 3946906A20976ED300B4A457 /* LNPropertyListDatePicker.h */,
163 | 3946906B20976ED300B4A457 /* LNPropertyListDatePicker.m */,
164 | 3941486D2095E85900A21F96 /* LNPropertyListDatePickerCell.h */,
165 | 3941486E2095E85900A21F96 /* LNPropertyListDatePickerCell.mm */,
166 | 39D1528D23289668009124C8 /* LNPropertyListDatePickerPanel.h */,
167 | 39D1528E23289668009124C8 /* LNPropertyListDatePickerPanel.m */,
168 | 39DE8E9B2092214300ED16B4 /* LNPropertyListEditor-Private.h */,
169 | 393E1874207F64A0002E6136 /* LNPropertyListEditor.m */,
170 | 393E1871207F61C2002E6136 /* LNPropertyListEditorOutline.xib */,
171 | 393E1881207FAD26002E6136 /* LNPropertyListNode-Private.h */,
172 | 393E1878207F68B4002E6136 /* LNPropertyListNode.m */,
173 | 391FF0312084270400005D0F /* LNPropertyListOutlineView.h */,
174 | 391FF0322084270400005D0F /* LNPropertyListOutlineView.m */,
175 | 39DE8E922092030500ED16B4 /* LNPropertyListPopUpButtonCell.h */,
176 | 39DE8E932092030500ED16B4 /* LNPropertyListPopUpButtonCell.m */,
177 | 391FF02D208412CC00005D0F /* LNPropertyListRowView.h */,
178 | 391FF02E208412CC00005D0F /* LNPropertyListRowView.m */,
179 | 39F537F1264305AF00AB263A /* NSObject+LNPropertyListValueSorting.h */,
180 | 39F537F2264305AF00AB263A /* NSObject+LNPropertyListValueSorting.m */,
181 | 39D55F1E26D82C100013B105 /* LNPropertyListDataEditorPanel.h */,
182 | 39D55F1F26D82C100013B105 /* LNPropertyListDataEditorPanel.m */,
183 | );
184 | path = Implementation;
185 | sourceTree = "";
186 | };
187 | 39D1276726D9254C007E64D1 /* Products */ = {
188 | isa = PBXGroup;
189 | children = (
190 | 39D1276B26D9254C007E64D1 /* HexFiend.framework */,
191 | );
192 | name = Products;
193 | sourceTree = "";
194 | };
195 | 39D55F1926D829600013B105 /* Frameworks */ = {
196 | isa = PBXGroup;
197 | children = (
198 | );
199 | name = Frameworks;
200 | sourceTree = "";
201 | };
202 | /* End PBXGroup section */
203 |
204 | /* Begin PBXHeadersBuildPhase section */
205 | 393E1836207F6119002E6136 /* Headers */ = {
206 | isa = PBXHeadersBuildPhase;
207 | buildActionMask = 2147483647;
208 | files = (
209 | 393E1882207FAD26002E6136 /* LNPropertyListNode-Private.h in Headers */,
210 | 39D1528F23289668009124C8 /* LNPropertyListDatePickerPanel.h in Headers */,
211 | 391FF0332084270400005D0F /* LNPropertyListOutlineView.h in Headers */,
212 | 391FF02F208412CC00005D0F /* LNPropertyListRowView.h in Headers */,
213 | 393E1885207FAEC6002E6136 /* LNPropertyListCellView.h in Headers */,
214 | 39DE8E9C2092214400ED16B4 /* LNPropertyListEditor-Private.h in Headers */,
215 | 39DE8E942092030500ED16B4 /* LNPropertyListPopUpButtonCell.h in Headers */,
216 | 3946906C20976ED300B4A457 /* LNPropertyListDatePicker.h in Headers */,
217 | 3941486F2095E85900A21F96 /* LNPropertyListDatePickerCell.h in Headers */,
218 | 39F537F3264305AF00AB263A /* NSObject+LNPropertyListValueSorting.h in Headers */,
219 | 39D55F2026D82C100013B105 /* LNPropertyListDataEditorPanel.h in Headers */,
220 | 3925913A263C52B100AF78D3 /* LNPropertyListCellTextField.h in Headers */,
221 | 39D152962328A9C4009124C8 /* _LNPropertyListDatePicker.h in Headers */,
222 | 393E1875207F64A0002E6136 /* LNPropertyListEditor.h in Headers */,
223 | 393E1879207F68B4002E6136 /* LNPropertyListNode.h in Headers */,
224 | );
225 | runOnlyForDeploymentPostprocessing = 0;
226 | };
227 | /* End PBXHeadersBuildPhase section */
228 |
229 | /* Begin PBXNativeTarget section */
230 | 393E1838207F6119002E6136 /* LNPropertyListEditor */ = {
231 | isa = PBXNativeTarget;
232 | buildConfigurationList = 393E1841207F6119002E6136 /* Build configuration list for PBXNativeTarget "LNPropertyListEditor" */;
233 | buildPhases = (
234 | 393E1834207F6119002E6136 /* Sources */,
235 | 393E1835207F6119002E6136 /* Frameworks */,
236 | 393E1836207F6119002E6136 /* Headers */,
237 | 393E1837207F6119002E6136 /* Resources */,
238 | 39D55F1D26D829970013B105 /* Embed Frameworks */,
239 | );
240 | buildRules = (
241 | );
242 | dependencies = (
243 | 39D1276D26D92552007E64D1 /* PBXTargetDependency */,
244 | );
245 | name = LNPropertyListEditor;
246 | productName = LNPlistEditorView;
247 | productReference = 393E1839207F6119002E6136 /* LNPropertyListEditor.framework */;
248 | productType = "com.apple.product-type.framework";
249 | };
250 | /* End PBXNativeTarget section */
251 |
252 | /* Begin PBXProject section */
253 | 393E1830207F6119002E6136 /* Project object */ = {
254 | isa = PBXProject;
255 | attributes = {
256 | BuildIndependentTargetsInParallel = YES;
257 | LastUpgradeCheck = 1510;
258 | ORGANIZATIONNAME = "Leo Natan";
259 | TargetAttributes = {
260 | 393E1838207F6119002E6136 = {
261 | CreatedOnToolsVersion = 9.4;
262 | };
263 | };
264 | };
265 | buildConfigurationList = 393E1833207F6119002E6136 /* Build configuration list for PBXProject "LNPropertyListEditor" */;
266 | compatibilityVersion = "Xcode 9.3";
267 | developmentRegion = en;
268 | hasScannedForEncodings = 0;
269 | knownRegions = (
270 | en,
271 | Base,
272 | );
273 | mainGroup = 393E182F207F6119002E6136;
274 | productRefGroup = 393E183A207F6119002E6136 /* Products */;
275 | projectDirPath = "";
276 | projectReferences = (
277 | {
278 | ProductGroup = 39D1276726D9254C007E64D1 /* Products */;
279 | ProjectRef = 39D1276626D9254C007E64D1 /* HexFiend.xcodeproj */;
280 | },
281 | );
282 | projectRoot = "";
283 | targets = (
284 | 393E1838207F6119002E6136 /* LNPropertyListEditor */,
285 | );
286 | };
287 | /* End PBXProject section */
288 |
289 | /* Begin PBXReferenceProxy section */
290 | 39D1276B26D9254C007E64D1 /* HexFiend.framework */ = {
291 | isa = PBXReferenceProxy;
292 | fileType = wrapper.framework;
293 | path = HexFiend.framework;
294 | remoteRef = 39D1276A26D9254C007E64D1 /* PBXContainerItemProxy */;
295 | sourceTree = BUILT_PRODUCTS_DIR;
296 | };
297 | /* End PBXReferenceProxy section */
298 |
299 | /* Begin PBXResourcesBuildPhase section */
300 | 393E1837207F6119002E6136 /* Resources */ = {
301 | isa = PBXResourcesBuildPhase;
302 | buildActionMask = 2147483647;
303 | files = (
304 | 391FF02B2084060000005D0F /* Assets.xcassets in Resources */,
305 | 393E1872207F61C2002E6136 /* LNPropertyListEditorOutline.xib in Resources */,
306 | );
307 | runOnlyForDeploymentPostprocessing = 0;
308 | };
309 | /* End PBXResourcesBuildPhase section */
310 |
311 | /* Begin PBXSourcesBuildPhase section */
312 | 393E1834207F6119002E6136 /* Sources */ = {
313 | isa = PBXSourcesBuildPhase;
314 | buildActionMask = 2147483647;
315 | files = (
316 | 391FF030208412CC00005D0F /* LNPropertyListRowView.m in Sources */,
317 | 393E187A207F68B4002E6136 /* LNPropertyListNode.m in Sources */,
318 | 393E1886207FAEC6002E6136 /* LNPropertyListCellView.m in Sources */,
319 | 39D55F2126D82C100013B105 /* LNPropertyListDataEditorPanel.m in Sources */,
320 | 391FF0342084270400005D0F /* LNPropertyListOutlineView.m in Sources */,
321 | 39D152972328A9C4009124C8 /* _LNPropertyListDatePicker.m in Sources */,
322 | 3946906D20976ED300B4A457 /* LNPropertyListDatePicker.m in Sources */,
323 | 3925913B263C52B100AF78D3 /* LNPropertyListCellTextField.m in Sources */,
324 | 394148702095E85900A21F96 /* LNPropertyListDatePickerCell.mm in Sources */,
325 | 393E1876207F64A0002E6136 /* LNPropertyListEditor.m in Sources */,
326 | 39F537F4264305AF00AB263A /* NSObject+LNPropertyListValueSorting.m in Sources */,
327 | 39DE8E952092030500ED16B4 /* LNPropertyListPopUpButtonCell.m in Sources */,
328 | 39D1529023289668009124C8 /* LNPropertyListDatePickerPanel.m in Sources */,
329 | );
330 | runOnlyForDeploymentPostprocessing = 0;
331 | };
332 | /* End PBXSourcesBuildPhase section */
333 |
334 | /* Begin PBXTargetDependency section */
335 | 39D1276D26D92552007E64D1 /* PBXTargetDependency */ = {
336 | isa = PBXTargetDependency;
337 | name = HexFiend;
338 | targetProxy = 39D1276C26D92552007E64D1 /* PBXContainerItemProxy */;
339 | };
340 | /* End PBXTargetDependency section */
341 |
342 | /* Begin XCBuildConfiguration section */
343 | 393E183F207F6119002E6136 /* Debug */ = {
344 | isa = XCBuildConfiguration;
345 | buildSettings = {
346 | ALWAYS_SEARCH_USER_PATHS = NO;
347 | CLANG_ANALYZER_NONNULL = YES;
348 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
349 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
350 | CLANG_CXX_LIBRARY = "libc++";
351 | CLANG_ENABLE_MODULES = YES;
352 | CLANG_ENABLE_OBJC_ARC = YES;
353 | CLANG_ENABLE_OBJC_WEAK = YES;
354 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
355 | CLANG_WARN_BOOL_CONVERSION = YES;
356 | CLANG_WARN_COMMA = YES;
357 | CLANG_WARN_CONSTANT_CONVERSION = YES;
358 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
359 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
360 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
361 | CLANG_WARN_EMPTY_BODY = YES;
362 | CLANG_WARN_ENUM_CONVERSION = YES;
363 | CLANG_WARN_INFINITE_RECURSION = YES;
364 | CLANG_WARN_INT_CONVERSION = YES;
365 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
366 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
367 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
368 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
369 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
370 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
371 | CLANG_WARN_STRICT_PROTOTYPES = YES;
372 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
373 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
374 | CLANG_WARN_UNREACHABLE_CODE = YES;
375 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
376 | CODE_SIGN_IDENTITY = "-";
377 | COPY_PHASE_STRIP = NO;
378 | CURRENT_PROJECT_VERSION = 1;
379 | DEAD_CODE_STRIPPING = YES;
380 | DEBUG_INFORMATION_FORMAT = dwarf;
381 | ENABLE_STRICT_OBJC_MSGSEND = YES;
382 | ENABLE_TESTABILITY = YES;
383 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
384 | GCC_C_LANGUAGE_STANDARD = gnu11;
385 | GCC_DYNAMIC_NO_PIC = NO;
386 | GCC_NO_COMMON_BLOCKS = YES;
387 | GCC_OPTIMIZATION_LEVEL = 0;
388 | GCC_PREPROCESSOR_DEFINITIONS = (
389 | "DEBUG=1",
390 | "$(inherited)",
391 | );
392 | GCC_TREAT_WARNINGS_AS_ERRORS = YES;
393 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
394 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
395 | GCC_WARN_UNDECLARED_SELECTOR = YES;
396 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
397 | GCC_WARN_UNUSED_FUNCTION = YES;
398 | GCC_WARN_UNUSED_VARIABLE = YES;
399 | MACOSX_DEPLOYMENT_TARGET = 10.13;
400 | MTL_ENABLE_DEBUG_INFO = YES;
401 | ONLY_ACTIVE_ARCH = YES;
402 | SDKROOT = macosx;
403 | VERSIONING_SYSTEM = "apple-generic";
404 | VERSION_INFO_PREFIX = "";
405 | };
406 | name = Debug;
407 | };
408 | 393E1840207F6119002E6136 /* Release */ = {
409 | isa = XCBuildConfiguration;
410 | buildSettings = {
411 | ALWAYS_SEARCH_USER_PATHS = NO;
412 | CLANG_ANALYZER_NONNULL = YES;
413 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
414 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
415 | CLANG_CXX_LIBRARY = "libc++";
416 | CLANG_ENABLE_MODULES = YES;
417 | CLANG_ENABLE_OBJC_ARC = YES;
418 | CLANG_ENABLE_OBJC_WEAK = YES;
419 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
420 | CLANG_WARN_BOOL_CONVERSION = YES;
421 | CLANG_WARN_COMMA = YES;
422 | CLANG_WARN_CONSTANT_CONVERSION = YES;
423 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
424 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
425 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
426 | CLANG_WARN_EMPTY_BODY = YES;
427 | CLANG_WARN_ENUM_CONVERSION = YES;
428 | CLANG_WARN_INFINITE_RECURSION = YES;
429 | CLANG_WARN_INT_CONVERSION = YES;
430 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
431 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
432 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
433 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
434 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
435 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
436 | CLANG_WARN_STRICT_PROTOTYPES = YES;
437 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
438 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
439 | CLANG_WARN_UNREACHABLE_CODE = YES;
440 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
441 | CODE_SIGN_IDENTITY = "-";
442 | COPY_PHASE_STRIP = NO;
443 | CURRENT_PROJECT_VERSION = 1;
444 | DEAD_CODE_STRIPPING = YES;
445 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
446 | ENABLE_STRICT_OBJC_MSGSEND = YES;
447 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
448 | GCC_C_LANGUAGE_STANDARD = gnu11;
449 | GCC_NO_COMMON_BLOCKS = YES;
450 | GCC_TREAT_WARNINGS_AS_ERRORS = YES;
451 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
452 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
453 | GCC_WARN_UNDECLARED_SELECTOR = YES;
454 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
455 | GCC_WARN_UNUSED_FUNCTION = YES;
456 | GCC_WARN_UNUSED_VARIABLE = YES;
457 | MACOSX_DEPLOYMENT_TARGET = 10.13;
458 | MTL_ENABLE_DEBUG_INFO = NO;
459 | SDKROOT = macosx;
460 | VERSIONING_SYSTEM = "apple-generic";
461 | VERSION_INFO_PREFIX = "";
462 | };
463 | name = Release;
464 | };
465 | 393E1842207F6119002E6136 /* Debug */ = {
466 | isa = XCBuildConfiguration;
467 | buildSettings = {
468 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO;
469 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO;
470 | CODE_SIGN_IDENTITY = "";
471 | CODE_SIGN_STYLE = Automatic;
472 | COMBINE_HIDPI_IMAGES = YES;
473 | DEAD_CODE_STRIPPING = YES;
474 | DYLIB_COMPATIBILITY_VERSION = 1;
475 | DYLIB_CURRENT_VERSION = 1;
476 | DYLIB_INSTALL_NAME_BASE = "@rpath";
477 | ENABLE_MODULE_VERIFIER = YES;
478 | FRAMEWORK_VERSION = A;
479 | IBC_ERRORS = NO;
480 | IBC_NOTICES = NO;
481 | IBC_WARNINGS = NO;
482 | INFOPLIST_FILE = LNPropertyListEditor/Info.plist;
483 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
484 | LD_RUNPATH_SEARCH_PATHS = (
485 | "$(inherited)",
486 | "@executable_path/../Frameworks",
487 | "@loader_path/Frameworks",
488 | );
489 | MACOSX_DEPLOYMENT_TARGET = 10.14;
490 | MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
491 | MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++14";
492 | ONLY_ACTIVE_ARCH = NO;
493 | PRODUCT_BUNDLE_IDENTIFIER = com.leonatan.LNPropertyListEditor;
494 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
495 | SKIP_INSTALL = YES;
496 | WARNING_CFLAGS = "-Wno-incomplete-umbrella";
497 | };
498 | name = Debug;
499 | };
500 | 393E1843207F6119002E6136 /* Release */ = {
501 | isa = XCBuildConfiguration;
502 | buildSettings = {
503 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO;
504 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO;
505 | CODE_SIGN_IDENTITY = "";
506 | CODE_SIGN_STYLE = Automatic;
507 | COMBINE_HIDPI_IMAGES = YES;
508 | DEAD_CODE_STRIPPING = YES;
509 | DYLIB_COMPATIBILITY_VERSION = 1;
510 | DYLIB_CURRENT_VERSION = 1;
511 | DYLIB_INSTALL_NAME_BASE = "@rpath";
512 | ENABLE_MODULE_VERIFIER = YES;
513 | FRAMEWORK_VERSION = A;
514 | IBC_ERRORS = NO;
515 | IBC_NOTICES = NO;
516 | IBC_WARNINGS = NO;
517 | INFOPLIST_FILE = LNPropertyListEditor/Info.plist;
518 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
519 | LD_RUNPATH_SEARCH_PATHS = (
520 | "$(inherited)",
521 | "@executable_path/../Frameworks",
522 | "@loader_path/Frameworks",
523 | );
524 | MACOSX_DEPLOYMENT_TARGET = 10.14;
525 | MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
526 | MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++14";
527 | PRODUCT_BUNDLE_IDENTIFIER = com.leonatan.LNPropertyListEditor;
528 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
529 | SKIP_INSTALL = YES;
530 | WARNING_CFLAGS = "-Wno-incomplete-umbrella";
531 | };
532 | name = Release;
533 | };
534 | /* End XCBuildConfiguration section */
535 |
536 | /* Begin XCConfigurationList section */
537 | 393E1833207F6119002E6136 /* Build configuration list for PBXProject "LNPropertyListEditor" */ = {
538 | isa = XCConfigurationList;
539 | buildConfigurations = (
540 | 393E183F207F6119002E6136 /* Debug */,
541 | 393E1840207F6119002E6136 /* Release */,
542 | );
543 | defaultConfigurationIsVisible = 0;
544 | defaultConfigurationName = Release;
545 | };
546 | 393E1841207F6119002E6136 /* Build configuration list for PBXNativeTarget "LNPropertyListEditor" */ = {
547 | isa = XCConfigurationList;
548 | buildConfigurations = (
549 | 393E1842207F6119002E6136 /* Debug */,
550 | 393E1843207F6119002E6136 /* Release */,
551 | );
552 | defaultConfigurationIsVisible = 0;
553 | defaultConfigurationName = Release;
554 | };
555 | /* End XCConfigurationList section */
556 | };
557 | rootObject = 393E1830207F6119002E6136 /* Project object */;
558 | }
559 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor.xcodeproj/xcshareddata/xcschemes/LNPropertyListEditor.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
52 |
53 |
59 |
60 |
66 |
67 |
68 |
69 |
71 |
72 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Assets.xcassets/minus.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "filename" : "minus.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | },
12 | "properties" : {
13 | "template-rendering-intent" : "template"
14 | }
15 | }
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Assets.xcassets/minus.imageset/minus.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPropertyListEditor/7688237cb69ad68dd53ecf6f9f60f37a619b80e0/LNPropertyListEditor/LNPropertyListEditor/Assets.xcassets/minus.imageset/minus.pdf
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Assets.xcassets/plus.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "filename" : "plus.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | },
12 | "properties" : {
13 | "template-rendering-intent" : "template"
14 | }
15 | }
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Assets.xcassets/plus.imageset/plus.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPropertyListEditor/7688237cb69ad68dd53ecf6f9f60f37a619b80e0/LNPropertyListEditor/LNPropertyListEditor/Assets.xcassets/plus.imageset/plus.pdf
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListCellTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListCellTextField.h
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/30/21.
6 | // Copyright © 2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface LNPropertyListCellTextField : NSTextField
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListCellTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListCellTextField.m
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/30/21.
6 | // Copyright © 2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import "LNPropertyListCellTextField.h"
10 |
11 | @implementation LNPropertyListCellTextField
12 |
13 | - (NSView *)hitTest:(NSPoint)point
14 | {
15 | if((self.currentEditor == nil || self.window.firstResponder != self.currentEditor) &&
16 | (NSApp.currentEvent.type == NSEventTypeRightMouseDown || NSApp.currentEvent.type == NSEventTypeRightMouseUp))
17 | {
18 | return nil;
19 | }
20 |
21 | return [super hitTest:point];
22 | }
23 |
24 | - (BOOL)becomeFirstResponder
25 | {
26 | return [super becomeFirstResponder];
27 | }
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListCellView.h:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListCellView.h
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/12/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LNPropertyListDatePicker.h"
11 |
12 | @interface LNPropertyListCellView : NSTableCellView
13 |
14 | @property (nonatomic, strong) IBOutlet LNPropertyListDatePicker *datePicker;
15 | @property (nonatomic, strong) IBOutlet NSPopUpButton *typeButton;
16 | @property (nonatomic, strong) IBOutlet NSLayoutConstraint *typeButtonLeadingConstraint;
17 | @property (nonatomic, weak) IBOutlet NSButton *minusButton;
18 | @property (nonatomic, weak) IBOutlet NSButton *plusButton;
19 | @property (nonatomic, strong) IBOutlet NSLayoutConstraint *buttonsConstraint;
20 |
21 | @property (nonatomic, readonly) BOOL showsControlButtons;
22 | - (void)setShowsControlButtons:(BOOL)showsControlButtons addButtonEnabled:(BOOL)addButtonEnabled deleteButtonEnabled:(BOOL)deleteButtonEnabled;
23 |
24 | - (void)setControlWithString:(NSString*)str setToolTip:(BOOL)setToolTip;
25 | - (void)setControlWithBoolean:(BOOL)boolean;
26 | - (void)setControlWithDate:(NSDate*)date;
27 | - (void)setControlEditable:(BOOL)editable;
28 | - (void)flashError;
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListCellView.m:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListCellView.m
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/12/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import "LNPropertyListCellView.h"
10 | @import QuartzCore;
11 | @import ObjectiveC;
12 |
13 | @interface LNPropertyListCellView () @end
14 |
15 | @implementation LNPropertyListCellView
16 |
17 | - (void)awakeFromNib
18 | {
19 | [super awakeFromNib];
20 |
21 | objc_setAssociatedObject(self.typeButton.menu, "button", self.typeButton, OBJC_ASSOCIATION_ASSIGN);
22 |
23 | if(self.buttonsConstraint)
24 | {
25 | [NSLayoutConstraint deactivateConstraints:@[self.buttonsConstraint]];
26 | }
27 |
28 | if(@available(macOS 11.0, *))
29 | {
30 | _typeButtonLeadingConstraint.constant = -2;
31 | }
32 | }
33 |
34 | - (void)prepareForReuse
35 | {
36 | [super prepareForReuse];
37 |
38 | self.plusButton.hidden = self.minusButton.hidden = YES;
39 | if(self.buttonsConstraint)
40 | {
41 | [NSLayoutConstraint deactivateConstraints:@[self.buttonsConstraint]];
42 | }
43 | }
44 |
45 | - (void)setControlWithString:(NSString*)str setToolTip:(BOOL)setToolTip
46 | {
47 | if(self.typeButton)
48 | {
49 | [self.typeButton selectItemWithTitle:str];
50 | }
51 | else
52 | {
53 | self.textField.stringValue = str;
54 | }
55 |
56 | if(setToolTip)
57 | {
58 | self.toolTip = str;
59 | }
60 | }
61 |
62 | - (void)setControlWithBoolean:(BOOL)boolean
63 | {
64 | [self.typeButton selectItemAtIndex:(NSInteger)boolean];
65 | }
66 |
67 | - (void)setControlWithDate:(NSDate*)date
68 | {
69 | _datePicker.dateValue = date;
70 | }
71 |
72 | - (void)setBackgroundStyle:(NSBackgroundStyle)backgroundStyle
73 | {
74 | [super setBackgroundStyle:backgroundStyle];
75 |
76 | [_datePicker.cell setBackgroundStyle:backgroundStyle];
77 | }
78 |
79 | - (void)flashError
80 | {
81 | CABasicAnimation* flashAnimation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
82 | flashAnimation.fromValue = (__bridge id)NSColor.clearColor.CGColor;
83 | flashAnimation.toValue = (__bridge id)NSColor.systemRedColor.CGColor;
84 | flashAnimation.duration = 0.25;
85 | flashAnimation.autoreverses = YES;
86 | flashAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
87 | flashAnimation.fillMode = kCAFillModeForwards;
88 | flashAnimation.removedOnCompletion = YES;
89 |
90 | [self.layer addAnimation:flashAnimation forKey:@"backgroundColor"];
91 | }
92 |
93 | - (void)setShowsControlButtons:(BOOL)showsControlButtons addButtonEnabled:(BOOL)addButtonEnabled deleteButtonEnabled:(BOOL)deleteButtonEnabled
94 | {
95 | _showsControlButtons = showsControlButtons && (addButtonEnabled || deleteButtonEnabled);
96 |
97 | self.plusButton.hidden = self.minusButton.hidden = !_showsControlButtons;
98 | self.buttonsConstraint.active = _showsControlButtons;
99 |
100 | self.plusButton.enabled = addButtonEnabled;
101 | self.minusButton.enabled = deleteButtonEnabled;
102 | }
103 |
104 | - (void)setControlEditable:(BOOL)editable
105 | {
106 | self.textField.selectable = self.textField.editable = editable;
107 | _typeButton.enabled = editable;
108 | _datePicker.enabled = editable;
109 |
110 | NSColor* controlColor = editable ? NSColor.labelColor : NSColor.disabledControlTextColor;
111 |
112 | self.textField.textColor = controlColor;
113 | }
114 |
115 | @end
116 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListDataEditorPanel.h:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListDataEditorPanel.h
3 | // LNPropertyListDataEditorPanel
4 | //
5 | // Created by Leo Natan on 8/26/21.
6 | // Copyright © 2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface LNPropertyListDataEditorPanel : NSPanel
14 |
15 | @property (nonatomic, copy) NSData* data;
16 |
17 | - (void)beginSheetModalForWindow:(NSWindow *)window completionHandler:(void (^)(NSModalResponse result))handler;
18 |
19 | @end
20 |
21 | NS_ASSUME_NONNULL_END
22 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListDataEditorPanel.m:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListDataEditorPanel.m
3 | // LNPropertyListDataEditorPanel
4 | //
5 | // Created by Leo Natan on 8/26/21.
6 | // Copyright © 2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import "LNPropertyListDataEditorPanel.h"
10 | #import
11 |
12 | @interface _LNPropertyListDataEditorTextDividerRepresenter : HFRepresenter @end
13 |
14 | @implementation _LNPropertyListDataEditorTextDividerRepresenter
15 |
16 | - (NSView *)createView {
17 | NSBox* separator = [NSBox new];
18 | separator.boxType = NSBoxSeparator;
19 | separator.autoresizingMask = NSViewHeightSizable;
20 |
21 | return separator;
22 | }
23 |
24 | - (CGFloat)minimumViewWidthForBytesPerLine:(NSUInteger)bytesPerLine {
25 | USE(bytesPerLine);
26 | return 1;
27 | }
28 |
29 | + (NSPoint)defaultLayoutPosition {
30 | return NSMakePoint(2, 0);
31 | }
32 |
33 | @end
34 |
35 | @interface LNPropertyListDataEditorPanel ()
36 |
37 | @end
38 |
39 | @implementation LNPropertyListDataEditorPanel
40 | {
41 | HFTextView* _hexTextView;
42 | }
43 |
44 | - (void)setData:(NSData *)data
45 | {
46 | _data = [data copy];
47 |
48 | [self _reloadHexTextField];
49 | }
50 |
51 | - (void)_reloadHexTextField
52 | {
53 | _hexTextView.data = _data;
54 |
55 | [self _updateWindowSizeToContent];
56 |
57 | [_hexTextView.layoutRepresenter performLayout];
58 | [self.undoManager removeAllActions];
59 | }
60 |
61 | - (instancetype)init
62 | {
63 | self = [super init];
64 |
65 | if(self)
66 | {
67 | [self setFrame:NSMakeRect(0, 0, 900, 550) display:NO];
68 | [self center];
69 | self.styleMask |= NSWindowStyleMaskResizable;
70 | self.delegate = self;
71 | self.minSize = NSMakeSize(400, 300);
72 |
73 | _hexTextView = [[HFTextView alloc] initWithFrame:self.contentView.bounds];
74 | _hexTextView.controller.bytesPerColumn = 4;
75 | _hexTextView.delegate = self;
76 |
77 | HFLineCountingRepresenter* lineCountingRepresenter = [HFLineCountingRepresenter new];
78 | lineCountingRepresenter.lineNumberFormat = HFLineNumberFormatHexadecimal;
79 | // HFStatusBarRepresenter* statusBarRepresenter = [HFStatusBarRepresenter new];
80 | // statusBarRepresenter.statusMode = HFStatusModeDecimal;
81 | _LNPropertyListDataEditorTextDividerRepresenter* textDivider = [_LNPropertyListDataEditorTextDividerRepresenter new];
82 |
83 | _hexTextView.layoutRepresenter.maximizesBytesPerLine = YES;
84 | [_hexTextView.layoutRepresenter addRepresenter:lineCountingRepresenter];
85 | [_hexTextView.layoutRepresenter addRepresenter:textDivider];
86 | // [_hexTextView.layoutRepresenter addRepresenter:statusBarRepresenter];
87 | [_hexTextView.controller addRepresenter:lineCountingRepresenter];
88 | // [_hexTextView.controller addRepresenter:statusBarRepresenter];
89 | _hexTextView.controller.font = [NSFont userFixedPitchFontOfSize:0];
90 |
91 | _hexTextView.controller.undoManager = self.undoManager;
92 |
93 | _hexTextView.translatesAutoresizingMaskIntoConstraints = NO;
94 | [self.contentView addSubview:_hexTextView];
95 |
96 | NSButton* OKButton = [NSButton buttonWithTitle:@"Save" target:self action:@selector(_save:)];
97 | OKButton.keyEquivalent = [NSString stringWithFormat:@"\r"];
98 | NSButton* cancelButton = [NSButton buttonWithTitle:@"Cancel" target:self action:@selector(_cancel:)];
99 | cancelButton.keyEquivalent = [NSString stringWithFormat:@"%C", 0x1b];
100 |
101 | NSStackView* controlButtonsStackView = [NSStackView stackViewWithViews:@[cancelButton, OKButton]];
102 | controlButtonsStackView.translatesAutoresizingMaskIntoConstraints = NO;
103 |
104 | [self.contentView addSubview:controlButtonsStackView];
105 |
106 | NSBox* backgroundBox = [NSBox new];
107 | backgroundBox.translatesAutoresizingMaskIntoConstraints = NO;
108 | backgroundBox.boxType = NSBoxCustom;
109 | backgroundBox.borderColor = NSColor.clearColor;
110 | backgroundBox.fillColor = NSColor.windowBackgroundColor;
111 |
112 | NSBox* separator = [NSBox new];
113 | separator.translatesAutoresizingMaskIntoConstraints = NO;
114 | separator.boxType = NSBoxSeparator;
115 |
116 | [self.contentView addSubview:backgroundBox positioned:NSWindowBelow relativeTo:nil];
117 | [self.contentView addSubview:separator positioned:NSWindowAbove relativeTo:nil];
118 |
119 | [NSLayoutConstraint activateConstraints:@[
120 | [self.contentView.topAnchor constraintEqualToAnchor:_hexTextView.topAnchor],
121 | [self.contentView.leadingAnchor constraintEqualToAnchor:_hexTextView.leadingAnchor],
122 | [self.contentView.trailingAnchor constraintEqualToAnchor:_hexTextView.trailingAnchor],
123 | [_hexTextView.bottomAnchor constraintEqualToAnchor:controlButtonsStackView.topAnchor constant:-20],
124 |
125 | [self.contentView.trailingAnchor constraintEqualToAnchor:controlButtonsStackView.trailingAnchor constant:20],
126 | [self.contentView.bottomAnchor constraintEqualToAnchor:controlButtonsStackView.bottomAnchor constant:20],
127 |
128 | [OKButton.widthAnchor constraintEqualToAnchor:cancelButton.widthAnchor],
129 |
130 | [self.contentView.leadingAnchor constraintEqualToAnchor:backgroundBox.leadingAnchor],
131 | [self.contentView.trailingAnchor constraintEqualToAnchor:backgroundBox.trailingAnchor],
132 | [self.contentView.bottomAnchor constraintEqualToAnchor:backgroundBox.bottomAnchor],
133 | [controlButtonsStackView.topAnchor constraintEqualToAnchor:backgroundBox.topAnchor constant:20],
134 |
135 | [self.contentView.leadingAnchor constraintEqualToAnchor:separator.leadingAnchor],
136 | [self.contentView.trailingAnchor constraintEqualToAnchor:separator.trailingAnchor],
137 | [controlButtonsStackView.topAnchor constraintEqualToAnchor:separator.topAnchor constant:20],
138 | ]];
139 |
140 | [_hexTextView.layoutRepresenter performLayout];
141 |
142 | NSNotificationCenter *center = NSNotificationCenter.defaultCenter;
143 | [center addObserver:self selector:@selector(_updateWindowSizeToContent) name:HFLineCountingRepresenterMinimumViewWidthChanged object:lineCountingRepresenter];
144 | }
145 |
146 | return self;
147 | }
148 |
149 | - (void)_save:(id)sender
150 | {
151 | _data = [_hexTextView.data copy];
152 |
153 | [self.sheetParent endSheet:self returnCode:NSModalResponseOK];
154 | }
155 |
156 | - (void)_cancel:(id)sender
157 | {
158 | [self.sheetParent endSheet:self returnCode:NSModalResponseCancel];
159 | }
160 |
161 | - (void)beginSheetModalForWindow:(NSWindow *)window completionHandler:(void (^)(NSModalResponse))handler
162 | {
163 | // [self makeKeyAndOrderFront:nil];
164 |
165 | [window beginCriticalSheet:self completionHandler:^(NSModalResponse returnCode) {
166 | handler(returnCode);
167 | }];
168 | }
169 |
170 | - (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize
171 | {
172 | if(_hexTextView.layoutRepresenter == nil)
173 | {
174 | return frameSize;
175 | }
176 |
177 | return [self minimumWindowFrameSizeForProposedSize:frameSize];
178 | }
179 |
180 | - (NSSize)minimumWindowFrameSizeForProposedSize:(NSSize)frameSize
181 | {
182 | NSSize proposedSizeInLayoutCoordinates = [_hexTextView convertSize:frameSize fromView:nil];
183 | CGFloat resultingWidthInLayoutCoordinates = [_hexTextView.layoutRepresenter minimumViewWidthForLayoutInProposedWidth:proposedSizeInLayoutCoordinates.width];
184 | NSSize resultSize = [_hexTextView convertSize:NSMakeSize(resultingWidthInLayoutCoordinates, proposedSizeInLayoutCoordinates.height) toView:nil];
185 | return resultSize;
186 | }
187 |
188 | - (void)_updateWindowSizeToContent
189 | {
190 | NSRect windowFrame = self.frame;
191 | CGFloat minViewWidth = [_hexTextView.layoutRepresenter minimumViewWidthForBytesPerLine:_hexTextView.controller.bytesPerLine];
192 | CGFloat minWindowWidth = [_hexTextView convertSize:NSMakeSize(minViewWidth, 1) toView:nil].width;
193 | windowFrame.size.width = minWindowWidth;
194 | [self setFrame:windowFrame display:YES];
195 | }
196 |
197 | #pragma mark HFTextViewDelegate
198 |
199 | - (void)hexTextView:(HFTextView *)view didChangeProperties:(HFControllerPropertyBits)properties
200 | {
201 |
202 | }
203 |
204 | @end
205 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListDatePicker.h:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListDatePicker.h
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/30/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LNPropertyListDatePicker : NSControl
12 |
13 | @property (nonatomic, copy) NSDate *dateValue;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListDatePicker.m:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListDatePicker.m
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/30/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import "LNPropertyListDatePicker.h"
10 | #import "_LNPropertyListDatePicker.h"
11 | #import "LNPropertyListDatePickerCell.h"
12 |
13 | @interface _LNPropertyListDatePickerInnerCell : NSCell
14 |
15 | @property (nonatomic, copy) NSArray* childCells;
16 |
17 | @end
18 |
19 | @implementation _LNPropertyListDatePickerInnerCell
20 |
21 | - (void)setBackgroundStyle:(NSBackgroundStyle)backgroundStyle
22 | {
23 | [self.childCells enumerateObjectsUsingBlock:^(NSCell * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
24 | [obj setBackgroundStyle:backgroundStyle];
25 | }];
26 | }
27 |
28 | - (void)setHighlighted:(BOOL)highlighted
29 | {}
30 |
31 | @end
32 |
33 | IB_DESIGNABLE
34 | @implementation LNPropertyListDatePicker
35 | {
36 | _LNPropertyListDatePicker* _datePicker;
37 | }
38 |
39 | - (void)prepareForInterfaceBuilder
40 | {
41 | _datePicker.dateValue = [NSDate date];
42 | }
43 |
44 | - (void)setEnabled:(BOOL)enabled
45 | {
46 | [super setEnabled:enabled];
47 |
48 | [_datePicker setEnabled:enabled];
49 | }
50 |
51 | - (void)awakeFromNib
52 | {
53 | [super awakeFromNib];
54 |
55 | NSFont* font = [NSFont monospacedDigitSystemFontOfSize:NSFont.smallSystemFontSize weight:NSFontWeightRegular];
56 |
57 | _datePicker = [_LNPropertyListDatePicker new];
58 | _datePicker.cell = [LNPropertyListDatePickerCell new];
59 | _datePicker.font = font;
60 | _datePicker.datePickerStyle = NSDatePickerStyleTextField;
61 | _datePicker.datePickerElements = NSDatePickerElementFlagYearMonthDay | NSDatePickerElementFlagEra | NSDatePickerElementFlagHourMinuteSecond | NSDatePickerElementFlagTimeZone;
62 | _datePicker.bordered = NO;
63 | _datePicker.drawsBackground = NO;
64 | _datePicker.translatesAutoresizingMaskIntoConstraints = NO;
65 | _datePicker.target = self;
66 | _datePicker.action = @selector(_internalDatePickerValueChanged:);
67 |
68 | _LNPropertyListDatePickerInnerCell* cell = [_LNPropertyListDatePickerInnerCell new];
69 | cell.childCells = @[_datePicker.cell];
70 | cell.bordered = NO;
71 | self.cell = cell;
72 |
73 | [self addSubview:_datePicker];
74 |
75 | [_datePicker setContentHuggingPriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationHorizontal];
76 | [_datePicker setContentCompressionResistancePriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationHorizontal];
77 | [NSLayoutConstraint activateConstraints:@[
78 | [self.heightAnchor constraintEqualToAnchor:_datePicker.heightAnchor],
79 | [self.leadingAnchor constraintEqualToAnchor:_datePicker.leadingAnchor],
80 | [self.centerYAnchor constraintEqualToAnchor:_datePicker.centerYAnchor constant:-1.5],
81 | ]];
82 |
83 | [self setContentHuggingPriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationHorizontal];
84 | [self setContentCompressionResistancePriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationHorizontal];
85 |
86 | self.wantsLayer = YES;
87 | self.layer.masksToBounds = NO;
88 | }
89 |
90 | - (void)_setDateValue:(NSDate *)dateValue sendAction:(BOOL)sendAction
91 | {
92 | self.objectValue = dateValue;
93 |
94 | _datePicker.dateValue = self.dateValue;
95 | _datePicker.visualDatePicker.dateValue = self.dateValue;
96 | _datePicker.textDatePicker.dateValue = self.dateValue;
97 |
98 | if(sendAction)
99 | {
100 | [self sendAction:self.action to:self.target];
101 | }
102 | }
103 |
104 | - (NSDate *)dateValue
105 | {
106 | return self.objectValue;
107 | }
108 |
109 | - (void)setDateValue:(NSDate *)dateValue
110 | {
111 | [self _setDateValue:dateValue sendAction:NO];
112 | }
113 |
114 | - (IBAction)_internalDatePickerValueChanged:(id)sender
115 | {
116 | [self _setDateValue:[sender dateValue] sendAction:YES];
117 | }
118 |
119 | - (BOOL)resignFirstResponder
120 | {
121 | return [super resignFirstResponder];
122 | }
123 |
124 | @end
125 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListDatePickerCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListDatePickerCell.h
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/29/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSDatePickerCell ()
12 |
13 | - (BOOL)_textFieldWithStepperTrackMouse:(id)arg1 inRect:(NSRect)arg2 ofView:(id)arg3 untilMouseUp:(BOOL)arg4;
14 |
15 | @end
16 |
17 | @interface LNLeadingZerosDatePickerCell : NSDatePickerCell
18 |
19 | @property (nonatomic) BOOL drawsBackgroundOnFirstResponder;
20 |
21 | @end
22 |
23 | @interface LNPropertyListDatePickerCell : LNLeadingZerosDatePickerCell
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListDatePickerCell.mm:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListDatePickerCell.mm
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/29/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import "LNPropertyListDatePickerCell.h"
10 | #import
11 |
12 | static NSDatePickerCell* __strong __drawingDatePickerCell;
13 |
14 | @interface NSDatePickerCell ()
15 |
16 | - (void)_setForcesLeadingZeroes:(BOOL)arg1;
17 | - (NSColor*)_textColorBasedOnEnabledState;
18 |
19 | @end
20 |
21 | @interface NSBezierPath (LNPropertyListEditorDatePickerCustomization) @end
22 |
23 | @implementation NSBezierPath (LNPropertyListEditorDatePickerCustomization)
24 |
25 | + (void)load
26 | {
27 | static dispatch_once_t onceToken;
28 | dispatch_once(&onceToken, ^{
29 | Method m1 = class_getClassMethod(NSBezierPath.class, @selector(__ln_bezierPathWithRoundedRect:xRadius:yRadius:));
30 | Method m2 = class_getClassMethod(NSBezierPath.class, @selector(bezierPathWithRoundedRect:xRadius:yRadius:));
31 | method_exchangeImplementations(m1, m2);
32 | });
33 | }
34 |
35 | + (NSBezierPath *)__ln_bezierPathWithRoundedRect:(NSRect)rect xRadius:(CGFloat)xRadius yRadius:(CGFloat)yRadius
36 | {
37 | if(__drawingDatePickerCell != nil)
38 | {
39 | // [[__drawingDatePickerCell._textColorBasedOnEnabledState blendedColorWithFraction:0.6 ofColor:NSColor.alternateSelectedControlColor] set];
40 | }
41 |
42 | NSBezierPath* rv = [self __ln_bezierPathWithRoundedRect:rect xRadius:xRadius yRadius:yRadius];
43 |
44 | return rv;
45 | }
46 |
47 | @end
48 |
49 | @implementation LNLeadingZerosDatePickerCell
50 |
51 | - (instancetype)init
52 | {
53 | self = [super init];
54 |
55 | if(self)
56 | {
57 | [self _setForcesLeadingZeroes:YES];
58 | }
59 |
60 | return self;
61 | }
62 |
63 | @end
64 |
65 | @implementation LNPropertyListDatePickerCell
66 |
67 | - (BOOL)_ln_isFirstResponder
68 | {
69 | return self.controlView.window.firstResponder == self.controlView;
70 | }
71 |
72 | - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
73 | {
74 | __drawingDatePickerCell = self;
75 | if(self._ln_isFirstResponder && self.drawsBackgroundOnFirstResponder)
76 | {
77 | [NSColor.textBackgroundColor setFill];
78 | [[NSBezierPath bezierPathWithRect:cellFrame] fill];
79 | }
80 |
81 | [super drawWithFrame:cellFrame inView:controlView];
82 |
83 | __drawingDatePickerCell = nil;
84 | }
85 |
86 | //This is faster than setting the text color when the background color changes.
87 | - (NSColor*)_textColorBasedOnEnabledState
88 | {
89 | return self.isEnabled ? self.backgroundStyle == NSBackgroundStyleEmphasized ? self._ln_isFirstResponder ? NSColor.controlTextColor : NSColor.alternateSelectedControlTextColor : NSColor.controlTextColor : self.backgroundStyle == NSBackgroundStyleEmphasized ? [NSColor valueForKey:@"_alternateDisabledSelectedControlTextColor"] : NSColor.disabledControlTextColor;
90 | }
91 |
92 | - (BOOL)_shouldShowFocusRingInView:(id)arg1
93 | {
94 | return YES;
95 | }
96 |
97 | @end
98 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListDatePickerPanel.h:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListDatePickerPanel.h
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 9/11/19.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LNPropertyListDatePickerPanelBackgroundView : NSView
12 |
13 | @property (nonatomic, weak) NSView* textDatePicker;
14 | @property (nonatomic, weak) NSView* visualDatePicker;
15 |
16 | @end
17 |
18 | @class LNPropertyListDatePickerPanel;
19 |
20 | @protocol LNPropertyListDatePickerPanelDelegate
21 |
22 | - (void)propertyListDatePickerPanelDidClose:(LNPropertyListDatePickerPanel*)panel;
23 |
24 | @end
25 |
26 | @interface LNPropertyListDatePickerPanel : NSPanel
27 |
28 | @property (nonatomic, weak) id datePickerPanelDelegate;
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListDatePickerPanel.m:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListDatePickerPanel.m
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 9/11/19.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import "LNPropertyListDatePickerPanel.h"
10 |
11 | @implementation LNPropertyListDatePickerPanelBackgroundView
12 |
13 | - (CGPathRef)_pathAroundView
14 | {
15 | const CGFloat radius = 4;
16 |
17 | CGMutablePathRef path = CGPathCreateMutable();
18 | CGPathMoveToPoint(path, NULL, CGRectGetMinX(self.textDatePicker.frame), CGRectGetMaxY(self.textDatePicker.frame) - radius);
19 | CGPathAddArcToPoint(path, NULL, CGRectGetMinX(self.textDatePicker.frame), CGRectGetMaxY(self.textDatePicker.frame),
20 | CGRectGetMinX(self.textDatePicker.frame) + radius, CGRectGetMaxY(self.textDatePicker.frame), radius);
21 | CGPathAddLineToPoint(path, NULL, CGRectGetMaxX(self.textDatePicker.frame) - radius, CGRectGetMaxY(self.textDatePicker.frame));
22 | CGPathAddArcToPoint(path, NULL, CGRectGetMaxX(self.textDatePicker.frame), CGRectGetMaxY(self.textDatePicker.frame),
23 | CGRectGetMaxX(self.textDatePicker.frame), CGRectGetMaxY(self.textDatePicker.frame) - radius, radius);
24 | CGPathAddLineToPoint(path, NULL, CGRectGetMaxX(self.textDatePicker.frame), CGRectGetMaxY(self.visualDatePicker.frame) + radius);
25 | CGPathAddArcToPoint(path, NULL, CGRectGetMaxX(self.textDatePicker.frame), CGRectGetMaxY(self.visualDatePicker.frame),
26 | CGRectGetMaxX(self.textDatePicker.frame) + radius, CGRectGetMaxY(self.visualDatePicker.frame), radius);
27 | CGPathAddLineToPoint(path, NULL, CGRectGetMaxX(self.visualDatePicker.frame) - radius, CGRectGetMaxY(self.visualDatePicker.frame));
28 | CGPathAddArcToPoint(path, NULL, CGRectGetMaxX(self.visualDatePicker.frame), CGRectGetMaxY(self.visualDatePicker.frame),
29 | CGRectGetMaxX(self.visualDatePicker.frame), CGRectGetMaxY(self.visualDatePicker.frame) - radius, radius);
30 | CGPathAddLineToPoint(path, NULL, CGRectGetMaxX(self.visualDatePicker.frame), CGRectGetMinY(self.visualDatePicker.frame) + radius);
31 | CGPathAddArcToPoint(path, NULL, CGRectGetMaxX(self.visualDatePicker.frame), CGRectGetMinY(self.visualDatePicker.frame),
32 | CGRectGetMaxX(self.visualDatePicker.frame) - radius, CGRectGetMinY(self.visualDatePicker.frame), radius);
33 | CGPathAddLineToPoint(path, NULL, CGRectGetMinX(self.visualDatePicker.frame) + radius, CGRectGetMinY(self.visualDatePicker.frame));
34 | CGPathAddArcToPoint(path, NULL, CGRectGetMinX(self.visualDatePicker.frame), CGRectGetMinY(self.visualDatePicker.frame),
35 | CGRectGetMinX(self.visualDatePicker.frame), CGRectGetMinY(self.visualDatePicker.frame) + radius, radius);
36 | CGPathCloseSubpath(path);
37 |
38 | return path;
39 | }
40 |
41 | - (void)drawRect:(NSRect)dirtyRect
42 | {
43 | [NSColor.controlBackgroundColor setFill];
44 |
45 | CGContextRef ctx = NSGraphicsContext.currentContext.CGContext;
46 |
47 | CGContextAddPath(ctx, self._pathAroundView);
48 | CGContextFillPath(ctx);
49 | }
50 |
51 | @end
52 |
53 | @implementation LNPropertyListDatePickerPanel
54 |
55 | - (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSWindowStyleMask)style backing:(NSBackingStoreType)backingStoreType defer:(BOOL)flag
56 | {
57 | self = [super initWithContentRect:contentRect styleMask:NSWindowStyleMaskBorderless backing:backingStoreType defer:flag];
58 |
59 | if(self)
60 | {
61 | self.releasedWhenClosed = NO;
62 | self.opaque = NO;
63 | self.hasShadow = YES;
64 | self.backgroundColor = NSColor.clearColor;
65 | self.hidesOnDeactivate = NO;
66 | }
67 |
68 | return self;
69 | }
70 |
71 | - (BOOL)canBecomeKeyWindow
72 | {
73 | return YES;
74 | }
75 |
76 | - (void)resignKeyWindow
77 | {
78 | [self close];
79 | }
80 |
81 | - (void)close
82 | {
83 | if(self.isVisible == NO)
84 | {
85 | return;
86 | }
87 |
88 | [super close];
89 |
90 | [self.datePickerPanelDelegate propertyListDatePickerPanelDidClose:self];
91 | }
92 |
93 | - (void)setIsVisible:(BOOL)flag
94 | {
95 | if(self.isVisible == flag)
96 | {
97 | return;
98 | }
99 |
100 | [super setIsVisible:flag];
101 | }
102 |
103 | - (void)setParentWindow:(NSWindow *)parentWindow
104 | {
105 | [super setParentWindow:parentWindow];
106 | }
107 |
108 | - (void)dealloc
109 | {
110 |
111 | }
112 |
113 | @end
114 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListEditor-Private.h:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListEditor.h
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/12/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LNPropertyListEditor.h"
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | typedef struct {
15 | unsigned int delegate_willChangeNode : 1;
16 | unsigned int delegate_didChangeNode : 1;
17 | unsigned int delegate_canEditKeyOfNode : 1;
18 | unsigned int delegate_canEditTypeOfNode : 1;
19 | unsigned int delegate_canEditValueOfNode : 1;
20 | unsigned int delegate_canDeleteNode : 1;
21 | unsigned int delegate_canAddNewNodeInNode : 1;
22 | unsigned int delegate_canMoveNode : 1;
23 | unsigned int delegate_canPasteNode : 1;
24 | unsigned int delegate_canReorderChildrenOfNode : 1;
25 | unsigned int delegate_defaultPropertyListForAddingInNode : 1;
26 |
27 | unsigned int dataTransformer_displayNameForNode : 1;
28 | unsigned int dataTransformer_transformValueForDisplay : 1;
29 | unsigned int dataTransformer_transformValueForStorage : 1;
30 | } __LNPropertyListEditor_flags;
31 |
32 | @interface LNPropertyListEditor ()
33 |
34 | @property (nonatomic) __LNPropertyListEditor_flags flags;
35 | @property (nonatomic, weak) IBOutlet NSOutlineView* outlineView;
36 |
37 | /// The current sort descriptors of the underlying outline view.
38 | @property (nullable, nonatomic, copy) NSArray* outlineViewSortDescriptors;
39 |
40 | - (BOOL)canInsertAtNode:(LNPropertyListNode*)node;
41 | - (BOOL)canDeleteNode:(LNPropertyListNode*)node;
42 |
43 | @end
44 |
45 | NS_ASSUME_NONNULL_END
46 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListNode-Private.h:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListNode.h
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/12/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LNPropertyListNode.h"
11 |
12 | #import
13 |
14 | extern NSString* const LNPropertyListNodePasteboardType;
15 | extern NSString* const LNPropertyListNodeXcodeKeyType;
16 |
17 | @interface LNPropertyListNode ()
18 |
19 | @property (nonatomic, strong) id _cachedDisplayKey;
20 | @property (nonatomic, strong) id _cachedDisplayValue;
21 | @property (nonatomic, readonly) LNPropertyListNodeType _appropriateType;
22 |
23 | + (NSNumberFormatter*)_numberFormatter;
24 |
25 | + (LNPropertyListNodeType)_typeForObject:(id)obj;
26 | + (NSString*)stringForType:(LNPropertyListNodeType)type;
27 | + (LNPropertyListNodeType)typeForString:(NSString*)str;
28 | + (id)defaultValueForType:(LNPropertyListNodeType)type;
29 | + (id)convertString:(NSString*)str toObjectOfType:(LNPropertyListNodeType)type;
30 | + (NSString*)stringKeyOfNode:(LNPropertyListNode*)node;
31 | + (NSString*)stringValueOfNode:(LNPropertyListNode*)node;
32 |
33 | + (instancetype)_nodeFromPasteboard:(NSPasteboard*)pasteboard;
34 | + (void)_clearPasteboardMapping;
35 |
36 | - (void)_setObject:(id)object;
37 |
38 | - (void)_sortUsingDescriptors:(NSArray *)descriptors validator:(BOOL (^)(LNPropertyListNode*))validator callback:(void (^)(LNPropertyListNode*, BOOL))callback;
39 |
40 | - (id)pasteboardWriter;
41 |
42 | @end
43 |
44 | @interface LNPropertyListNodePasteboardWriter : NSObject
45 |
46 | - (instancetype)initWithNode:(LNPropertyListNode*)node;
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListNode.m:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListNode.m
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/12/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import "LNPropertyListNode-Private.h"
10 | #import
11 |
12 | #define NS(x) ((__bridge id)x)
13 |
14 | NSString* const LNPropertyListNodePasteboardType = @"com.LeoNatan.LNPropertyList.node";
15 | NSString* const LNPropertyListNodeXcodeKeyType = @"com.apple.xcode.plist.key";
16 | static NSMapTable* _pasteboardNodeMapping;
17 |
18 | @implementation LNPropertyListNode
19 |
20 | + (void)load
21 | {
22 | @autoreleasepool
23 | {
24 | _pasteboardNodeMapping = [NSMapTable strongToWeakObjectsMapTable];
25 | }
26 | }
27 |
28 | + (BOOL)supportsSecureCoding
29 | {
30 | return YES;
31 | }
32 |
33 | + (NSNumberFormatter*)_numberFormatter
34 | {
35 | static NSNumberFormatter* __numberFormatter;
36 | static dispatch_once_t onceToken;
37 | dispatch_once(&onceToken, ^{
38 | __numberFormatter = [NSNumberFormatter new];
39 | __numberFormatter.numberStyle = NSNumberFormatterNoStyle;
40 | });
41 | return __numberFormatter;
42 | }
43 |
44 | + (LNPropertyListNodeType)_typeForObject:(id)obj
45 | {
46 | if([obj isKindOfClass:[NSArray class]])
47 | {
48 | return LNPropertyListNodeTypeArray;
49 | }
50 | if([obj isKindOfClass:[NSDictionary class]])
51 | {
52 | return LNPropertyListNodeTypeDictionary;
53 | }
54 | if([obj isKindOfClass:[NSString class]])
55 | {
56 | return LNPropertyListNodeTypeString;
57 | }
58 | if([obj isKindOfClass:[NSDate class]])
59 | {
60 | return LNPropertyListNodeTypeDate;
61 | }
62 | if([obj isKindOfClass:[NSData class]])
63 | {
64 | return LNPropertyListNodeTypeData;
65 | }
66 | if([obj isKindOfClass:NSClassFromString(@"__NSCFBoolean")])
67 | {
68 | return LNPropertyListNodeTypeBoolean;
69 | }
70 | if([obj isKindOfClass:[NSNumber class]])
71 | {
72 | return LNPropertyListNodeTypeNumber;
73 | }
74 |
75 | return LNPropertyListNodeTypeUnknown;
76 | }
77 |
78 | + (NSString *)stringForType:(LNPropertyListNodeType)type
79 | {
80 | switch (type)
81 | {
82 | case LNPropertyListNodeTypeUnknown:
83 | return nil;
84 | case LNPropertyListNodeTypeArray:
85 | return @"Array";
86 | case LNPropertyListNodeTypeDictionary:
87 | return @"Dictionary";
88 | case LNPropertyListNodeTypeBoolean:
89 | return @"Boolean";
90 | case LNPropertyListNodeTypeDate:
91 | return @"Date";
92 | case LNPropertyListNodeTypeData:
93 | return @"Data";
94 | case LNPropertyListNodeTypeNumber:
95 | return @"Number";
96 | case LNPropertyListNodeTypeString:
97 | return @"String";
98 | }
99 | }
100 |
101 | + (LNPropertyListNodeType)typeForString:(NSString*)str
102 | {
103 | if([str isEqualToString:@"Array"])
104 | {
105 | return LNPropertyListNodeTypeArray;
106 | }
107 | if([str isEqualToString:@"Dictionary"])
108 | {
109 | return LNPropertyListNodeTypeDictionary;
110 | }
111 | if([str isEqualToString:@"String"])
112 | {
113 | return LNPropertyListNodeTypeString;
114 | }
115 | if([str isEqualToString:@"Date"])
116 | {
117 | return LNPropertyListNodeTypeDate;
118 | }
119 | if([str isEqualToString:@"Data"])
120 | {
121 | return LNPropertyListNodeTypeData;
122 | }
123 | if([str isEqualToString:@"Boolean"])
124 | {
125 | return LNPropertyListNodeTypeBoolean;
126 | }
127 | if([str isEqualToString:@"Number"])
128 | {
129 | return LNPropertyListNodeTypeNumber;
130 | }
131 |
132 | return LNPropertyListNodeTypeUnknown;
133 | }
134 |
135 | + (id)defaultValueForType:(LNPropertyListNodeType)type;
136 | {
137 | switch (type)
138 | {
139 | case LNPropertyListNodeTypeUnknown:
140 | return nil;
141 | case LNPropertyListNodeTypeArray:
142 | case LNPropertyListNodeTypeDictionary:
143 | return nil;
144 | case LNPropertyListNodeTypeBoolean:
145 | return @NO;
146 | case LNPropertyListNodeTypeDate:
147 | return [NSDate date];
148 | case LNPropertyListNodeTypeData:
149 | return [NSData data];
150 | case LNPropertyListNodeTypeNumber:
151 | return @0;
152 | case LNPropertyListNodeTypeString:
153 | return @"";
154 | }
155 | }
156 |
157 | + (id)convertString:(NSString*)str toObjectOfType:(LNPropertyListNodeType)type
158 | {
159 | switch (type)
160 | {
161 | case LNPropertyListNodeTypeUnknown:
162 | return nil;
163 | case LNPropertyListNodeTypeArray:
164 | return nil;
165 | case LNPropertyListNodeTypeDictionary:
166 | return nil;
167 | case LNPropertyListNodeTypeBoolean:
168 | return [str isEqualToString:@"YES"] ? @YES : @NO;
169 | case LNPropertyListNodeTypeDate:
170 | return nil;
171 | case LNPropertyListNodeTypeData:
172 | return nil;
173 | case LNPropertyListNodeTypeNumber:
174 | return [LNPropertyListNode._numberFormatter numberFromString:str];
175 | case LNPropertyListNodeTypeString:
176 | return str;
177 | }
178 | }
179 |
180 | + (NSString*)stringValueOfNode:(LNPropertyListNode*)node
181 | {
182 | id valueToTranslate = node._cachedDisplayValue ?: node.value;
183 | NSArray* childrenToTranslate = [node._cachedDisplayValue isKindOfClass:[NSArray class]] ? node._cachedDisplayValue : [node._cachedDisplayValue isKindOfClass:[NSDictionary class]] ? [node._cachedDisplayValue allKeys] : node.children;
184 | LNPropertyListNodeType typeToTranslate = node._cachedDisplayValue ? [self _typeForObject:node._cachedDisplayValue] : node.type;
185 |
186 | switch (typeToTranslate)
187 | {
188 | case LNPropertyListNodeTypeUnknown:
189 | return nil;
190 | case LNPropertyListNodeTypeArray:
191 | case LNPropertyListNodeTypeDictionary:
192 | return [NSString stringWithFormat:NSLocalizedString(@"(%lu items)", @""), childrenToTranslate.count];
193 | case LNPropertyListNodeTypeBoolean:
194 | return [valueToTranslate boolValue] ? @"YES" : @"NO";
195 | case LNPropertyListNodeTypeDate:
196 | return nil;
197 | case LNPropertyListNodeTypeData:
198 | return [NSByteCountFormatter stringFromByteCount:[valueToTranslate length] countStyle:NSByteCountFormatterCountStyleMemory];
199 | // return [valueToTranslate description];
200 | case LNPropertyListNodeTypeNumber:
201 | return [LNPropertyListNode._numberFormatter stringFromNumber:valueToTranslate];
202 | case LNPropertyListNodeTypeString:
203 | return valueToTranslate;
204 | }
205 | }
206 |
207 | + (NSString*)stringKeyOfNode:(LNPropertyListNode*)node
208 | {
209 | switch (node.parent.type)
210 | {
211 | case LNPropertyListNodeTypeArray:
212 | return [NSString stringWithFormat:NSLocalizedString(@"Item %lu", @""), [node.parent.children indexOfObject:node]];
213 | default:
214 | return node.key;
215 | }
216 | }
217 |
218 | - (instancetype)initWithCoder:(NSCoder *)aDecoder
219 | {
220 | self = [super init];
221 |
222 | if(self)
223 | {
224 | self.key = [aDecoder decodeObjectForKey:@"key"];
225 | self.type = [[aDecoder decodeObjectForKey:@"type"] unsignedIntegerValue];
226 | self.value = [aDecoder decodeObjectForKey:@"value"];
227 | self.children = [aDecoder decodeObjectForKey:@"children"];
228 |
229 | [self.children enumerateObjectsUsingBlock:^(LNPropertyListNode * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
230 | obj.parent = self;
231 | }];
232 | }
233 |
234 | return self;
235 | }
236 |
237 | - (instancetype)initWithDictionary:(NSDictionary*)dictionary
238 | {
239 | self = [super init];
240 |
241 | if(self)
242 | {
243 | [self _setAsDictionary:dictionary];
244 | }
245 |
246 | return self;
247 | }
248 |
249 | - (void)_setAsDictionary:(NSDictionary*)dictionary
250 | {
251 | self.type = LNPropertyListNodeTypeDictionary;
252 | self.children = [NSMutableArray new];
253 |
254 | [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
255 | LNPropertyListNode* childNode = [[LNPropertyListNode alloc] initWithObject:obj];
256 | childNode.key = key;
257 | childNode.parent = self;
258 | [self.children addObject:childNode];
259 | }];
260 | }
261 |
262 | - (instancetype)initWithArray:(NSArray*)array
263 | {
264 | self = [super init];
265 |
266 | if(self)
267 | {
268 | [self _setAsArray:array];
269 | }
270 |
271 | return self;
272 | }
273 |
274 | - (void)_setAsArray:(NSArray*)array
275 | {
276 | self.type = LNPropertyListNodeTypeArray;
277 | self.children = [NSMutableArray new];
278 |
279 | [array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
280 | LNPropertyListNode* childNode = [[LNPropertyListNode alloc] initWithObject:obj];
281 | childNode.parent = self;
282 | [self.children addObject:childNode];
283 | }];
284 | }
285 |
286 | - (instancetype)initWithObject:(id)obj
287 | {
288 | if(obj == nil)
289 | {
290 | return nil;
291 | }
292 |
293 | self = [super init];
294 |
295 | if(self)
296 | {
297 | [self _setObject:obj];
298 | }
299 |
300 | return self;
301 | }
302 |
303 | - (void)_setObject:(id)obj
304 | {
305 | if(obj == nil)
306 | {
307 | return;
308 | }
309 |
310 | LNPropertyListNodeType type = [LNPropertyListNode _typeForObject:obj];
311 |
312 | if(type == LNPropertyListNodeTypeDictionary)
313 | {
314 | [self _setAsDictionary:obj];
315 | }
316 | else if(type == LNPropertyListNodeTypeArray)
317 | {
318 | [self _setAsArray:obj];
319 | }
320 | else
321 | {
322 | self.type = type;
323 | self.value = obj;
324 | }
325 | }
326 |
327 | - (instancetype)initWithPropertyListObject:(id)obj
328 | {
329 | return [self initWithObject:obj];
330 | }
331 |
332 | - (void)encodeWithCoder:(NSCoder *)aCoder
333 | {
334 | [aCoder encodeObject:self.key forKey:@"key"];
335 | [aCoder encodeObject:@(self.type) forKey:@"type"];
336 | [aCoder encodeObject:self.value forKey:@"value"];
337 | [aCoder encodeObject:self.children forKey:@"children"];
338 | }
339 |
340 | - (LNPropertyListNodeType)_appropriateType
341 | {
342 | return self._cachedDisplayValue ? [LNPropertyListNode _typeForObject:self._cachedDisplayValue] : self.type;
343 | }
344 |
345 | - (NSString *)description
346 | {
347 | NSMutableString* builder = [NSMutableString stringWithFormat:@"<%@ %p", self.className, self];
348 |
349 | if(self.key != nil)
350 | {
351 | [builder appendFormat:@" key: “%@”", self.key];
352 | }
353 |
354 | [builder appendFormat:@" type: “%@”", [LNPropertyListNode stringForType:self.type]];
355 |
356 | if(self.type == LNPropertyListNodeTypeDictionary || self.type == LNPropertyListNodeTypeArray)
357 | {
358 | [builder appendFormat:@" children: “%lu items”", self.children.count];
359 | }
360 | else
361 | {
362 | [builder appendFormat:@" value: “%@”", [self.value description]];
363 | }
364 |
365 | [builder appendString:@">"];
366 |
367 | return builder;
368 | }
369 |
370 | - (NSDictionary*)_dictionaryObject
371 | {
372 | NSMutableDictionary* rv = [NSMutableDictionary new];
373 |
374 | [self.children enumerateObjectsUsingBlock:^(LNPropertyListNode * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
375 | rv[obj.key] = obj.propertyListObject;
376 | }];
377 |
378 | return rv.copy;
379 | }
380 |
381 | - (NSArray*)_arrayObject
382 | {
383 | NSMutableArray* rv = [NSMutableArray new];
384 |
385 | [self.children enumerateObjectsUsingBlock:^(LNPropertyListNode * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
386 | [rv addObject:obj.propertyListObject];
387 | }];
388 |
389 | return rv.copy;
390 | }
391 |
392 | - (id)propertyListObject
393 | {
394 | if(self.type == LNPropertyListNodeTypeDictionary)
395 | {
396 | return self._dictionaryObject;
397 | }
398 | if(self.type == LNPropertyListNodeTypeArray)
399 | {
400 | return self._arrayObject;
401 | }
402 |
403 | return self.value;
404 | }
405 |
406 | - (LNPropertyListNode*)childNodeContainingDescendantNode:(LNPropertyListNode*)descendantNode;
407 | {
408 | LNPropertyListNode* parent = descendantNode;
409 |
410 | while(parent != nil && [self.children containsObject:parent] == NO)
411 | {
412 | parent = parent.parent;
413 | }
414 |
415 | return parent;
416 | }
417 |
418 | - (LNPropertyListNode*)childNodeForKey:(NSString*)key
419 | {
420 | return [self.children filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"key == %@", key]].firstObject;
421 | }
422 |
423 | - (void)_sortUsingDescriptors:(NSArray *)descriptors validator:(BOOL (^)(LNPropertyListNode*))validator callback:(void (^)(LNPropertyListNode*, BOOL))callback
424 | {
425 | if(self.type != LNPropertyListNodeTypeDictionary && self.type != LNPropertyListNodeTypeArray)
426 | {
427 | return;
428 | }
429 |
430 | if(validator(self) == NO)
431 | {
432 | return;
433 | }
434 |
435 | callback(self, YES);
436 | [self.children sortUsingDescriptors:descriptors];
437 |
438 | [self.children enumerateObjectsUsingBlock:^(LNPropertyListNode * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
439 | [obj _sortUsingDescriptors:descriptors validator:validator callback:callback];
440 | }];
441 | callback(self, NO);
442 | }
443 |
444 | - (id)pasteboardWriter
445 | {
446 | return [[LNPropertyListNodePasteboardWriter alloc] initWithNode:self];
447 | }
448 |
449 | + (void)_clearPasteboardMapping
450 | {
451 | [_pasteboardNodeMapping removeAllObjects];
452 | }
453 |
454 | + (instancetype)_nodeFromPasteboard:(NSPasteboard *)pasteboard
455 | {
456 | NSPasteboardType type = LNPropertyListNodePasteboardType;
457 | NSData* data = [pasteboard dataForType:type];
458 | BOOL needsValueReading = NO;
459 | if(data == nil)
460 | {
461 | type = LNPropertyListNodeXcodeKeyType;
462 | data = [pasteboard dataForType:type];
463 | needsValueReading = YES;
464 | }
465 |
466 | LNPropertyListNode* rv = [[LNPropertyListNode alloc] initWithPasteboardPropertyList:data ofType:type];
467 |
468 | if(needsValueReading)
469 | {
470 | id obj = [NSPropertyListSerialization propertyListWithData:[pasteboard dataForType:NSPasteboardTypeString] options:0 format:nil error:NULL];
471 | [rv _setObject:obj];
472 | }
473 |
474 | return rv;
475 | }
476 |
477 | #pragma mark NSCopying
478 |
479 | - (id)copyWithZone:(NSZone *)zone
480 | {
481 | LNPropertyListNode* rv = [LNPropertyListNode new];
482 | rv.key = self.key;
483 | rv.type = self.type;
484 | rv.value = self.value;
485 | rv.children = self.children.mutableCopy;
486 |
487 | return rv;
488 | }
489 |
490 | #pragma mark NSPasteboardReading
491 |
492 | + (nonnull NSArray *)readableTypesForPasteboard:(nonnull NSPasteboard *)pasteboard
493 | {
494 | return @[LNPropertyListNodePasteboardType, LNPropertyListNodeXcodeKeyType];
495 | }
496 |
497 | - (nullable instancetype)initWithPasteboardPropertyList:(NSData*)propertyList ofType:(NSPasteboardType)type
498 | {
499 | LNPropertyListNode* rv = nil;
500 |
501 | if([type isEqualToString:LNPropertyListNodePasteboardType])
502 | {
503 | NSDictionary* info = [NSPropertyListSerialization propertyListWithData:propertyList options:0 format:nil error:NULL];
504 | NSString* UDIDString = info[@"UDID"];
505 | rv = [_pasteboardNodeMapping objectForKey:UDIDString];
506 |
507 | if(rv == nil)
508 | {
509 | NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:info[@"data"] error:NULL];
510 | unarchiver.requiresSecureCoding = NO;
511 |
512 | rv = [unarchiver decodeObjectForKey:NSKeyedArchiveRootObjectKey];
513 | }
514 | }
515 |
516 | if([type isEqualToString:LNPropertyListNodeXcodeKeyType])
517 | {
518 | rv = [LNPropertyListNode new];
519 | rv.key = [NSPropertyListSerialization propertyListWithData:propertyList options:0 format:nil error:NULL];
520 | }
521 |
522 | return rv;
523 | }
524 |
525 | @end
526 |
527 | #pragma mark NSPasteboardWriting
528 |
529 | @implementation LNPropertyListNodePasteboardWriter
530 | {
531 | LNPropertyListNode* _node;
532 | NSMutableArray* _UUIDs;
533 | }
534 |
535 | - (instancetype)initWithNode:(LNPropertyListNode*)node
536 | {
537 | self = [super init];
538 |
539 | if(self)
540 | {
541 | _UUIDs = [NSMutableArray new];
542 | _node = node;
543 | }
544 |
545 | return self;
546 | }
547 |
548 | - (NSArray *)writableTypesForPasteboard:(NSPasteboard *)pasteboard
549 | {
550 | return @[LNPropertyListNodePasteboardType, LNPropertyListNodeXcodeKeyType, NS(kUTTypeUTF8PlainText)];
551 | }
552 |
553 | - (id)pasteboardPropertyListForType:(NSPasteboardType)type
554 | {
555 | if([type isEqualToString:LNPropertyListNodePasteboardType])
556 | {
557 | NSString* UUIDString = NSUUID.UUID.UUIDString;
558 |
559 | [_UUIDs addObject:UUIDString];
560 | [_pasteboardNodeMapping setObject:_node forKey:UUIDString];
561 |
562 | return [NSPropertyListSerialization dataWithPropertyList:@{
563 | @"UDID": UUIDString,
564 | @"data": [NSKeyedArchiver archivedDataWithRootObject:_node requiringSecureCoding:NO error:NULL]
565 | } format:NSPropertyListXMLFormat_v1_0 options:0 error:NULL];
566 | }
567 |
568 | if([type isEqualToString:NS(kUTTypeUTF8PlainText)])
569 | {
570 | NSError* error = nil;
571 | return [NSPropertyListSerialization dataWithPropertyList:_node.propertyListObject format:NSPropertyListXMLFormat_v1_0 options:0 error:&error];
572 | }
573 |
574 | if([type isEqualToString:LNPropertyListNodeXcodeKeyType])
575 | {
576 | return [_node.key dataUsingEncoding:NSUTF8StringEncoding];
577 | }
578 |
579 | return nil;
580 | }
581 |
582 | @end
583 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListOutlineView.h:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListOutlineView.h
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/16/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LNPropertyListOutlineView : NSOutlineView
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListOutlineView.m:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListOutlineView.m
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/16/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import "LNPropertyListOutlineView.h"
10 |
11 | @implementation LNPropertyListOutlineView
12 |
13 | - (void)awakeFromNib
14 | {
15 | [super awakeFromNib];
16 |
17 | self.enclosingScrollView.wantsLayer = YES;
18 | self.enclosingScrollView.layerContentsRedrawPolicy = NSViewLayerContentsRedrawOnSetNeedsDisplay;
19 | }
20 |
21 | - (void)drawGridInClipRect:(NSRect)clipRect
22 | {
23 | NSRect lastRowRect = [self rectOfRow:[self numberOfRows] - 1];
24 | NSRect myClipRect = NSMakeRect(0, 0, lastRowRect.size.width, NSMaxY(lastRowRect));
25 | NSRect finalClipRect = NSIntersectionRect(clipRect, myClipRect);
26 | [super drawGridInClipRect:finalClipRect];
27 | }
28 |
29 | - (void)layout
30 | {
31 | [super layout];
32 |
33 | if((self.tableColumns.lastObject.resizingMask & NSTableColumnAutoresizingMask) == NSTableColumnAutoresizingMask)
34 | {
35 | [self sizeLastColumnToFit];
36 | }
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListPopUpButtonCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListPopUpButtonCell.h
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/26/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LNPropertyListPopUpButtonCell : NSPopUpButtonCell
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListPopUpButtonCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListPopUpButtonCell.m
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/26/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import "LNPropertyListPopUpButtonCell.h"
10 |
11 | static NSColor* __enabledTextColor;
12 | static NSColor* __enabledTextColorHighlight;
13 | static NSColor* __disabledTextColor;
14 | static NSColor* __disabledTextColorHighlight;
15 | static NSAppearance* __darkAppearanceCache;
16 |
17 | @implementation LNPropertyListPopUpButtonCell
18 |
19 | + (void)load
20 | {
21 | __enabledTextColor = NSColor.controlTextColor;
22 | __enabledTextColorHighlight = NSColor.alternateSelectedControlTextColor;
23 | __disabledTextColor = NSColor.disabledControlTextColor;
24 | __disabledTextColorHighlight = [NSColor valueForKey:@"_alternateDisabledSelectedControlTextColor"];
25 | __darkAppearanceCache = [NSAppearance appearanceNamed:NSAppearanceNameVibrantDark];
26 | }
27 |
28 | - (NSRect)drawTitle:(NSAttributedString *)title withFrame:(NSRect)frame inView:(NSView *)controlView
29 | {
30 | BOOL isHighlited = self.backgroundStyle == NSBackgroundStyleEmphasized;
31 | //All this to get the damn colors to match a text field. Ridiculous
32 | NSColor* controlColor = self.isEnabled ? (isHighlited ? __enabledTextColorHighlight : (controlView.effectiveAppearance == __darkAppearanceCache ? NSColor.whiteColor : __enabledTextColor)) : (isHighlited ? __disabledTextColorHighlight : __disabledTextColor);
33 | NSMutableAttributedString* attr = self.attributedTitle.mutableCopy;
34 | [attr addAttribute:NSForegroundColorAttributeName value:controlColor range:NSMakeRange(0, attr.length)];
35 |
36 | [attr drawInRect:frame];
37 |
38 | return frame;
39 | }
40 |
41 | - (BOOL)trackMouse:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)flag
42 | {
43 | if(NSProcessInfo.processInfo.operatingSystemVersion.majorVersion < 11)
44 | {
45 | [self.controlView.window makeFirstResponder:self.controlView.superview];
46 | }
47 |
48 | return [super trackMouse:event inRect:cellFrame ofView:controlView untilMouseUp:flag];
49 | }
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListRowView.h:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListRowView.h
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/16/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LNPropertyListEditor-Private.h"
11 | #import "LNPropertyListNode.h"
12 |
13 | @interface LNPropertyListRowView : NSTableRowView
14 |
15 | @property (nonatomic, weak) LNPropertyListEditor* editor;
16 | @property (nonatomic, strong) LNPropertyListNode* node;
17 |
18 | - (void)updateEditButtons;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/LNPropertyListRowView.m:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListRowView.m
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/16/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import "LNPropertyListRowView.h"
10 | #import "LNPropertyListCellView.h"
11 |
12 | @implementation LNPropertyListRowView
13 | {
14 | BOOL _mouseIn;
15 | NSTrackingArea* _trackingArea;
16 | }
17 |
18 | - (void)awakeFromNib
19 | {
20 | [super awakeFromNib];
21 |
22 | self.wantsLayer = YES;
23 | self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawOnSetNeedsDisplay;
24 | self.canDrawSubviewsIntoLayer = YES;
25 | self.layer.borderWidth = 2.0;
26 | self.layer.borderColor = NSColor.clearColor.CGColor;
27 | }
28 |
29 | - (void)updateEditButtons;
30 | {
31 | if(self.subviews.count > 0)
32 | {
33 | LNPropertyListCellView* cellView = [self viewAtColumn:0];
34 |
35 | BOOL addButtonEnabled = [self.editor canInsertAtNode:self.node];
36 | BOOL deleteButtonEnabled = [self.editor canDeleteNode:self.node];
37 |
38 | [cellView setShowsControlButtons:self.selected || _mouseIn addButtonEnabled:addButtonEnabled deleteButtonEnabled:deleteButtonEnabled];
39 | }
40 | }
41 |
42 | - (void)setSelected:(BOOL)selected
43 | {
44 | [super setSelected:selected];
45 |
46 | [self updateEditButtons];
47 | }
48 |
49 | - (void)ensureTrackingArea
50 | {
51 | if (_trackingArea == nil)
52 | {
53 | _trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect options:NSTrackingInVisibleRect | NSTrackingActiveAlways | NSTrackingMouseEnteredAndExited owner:self userInfo:nil];
54 | }
55 | }
56 |
57 | - (void)updateTrackingAreas
58 | {
59 | [super updateTrackingAreas];
60 | [self ensureTrackingArea];
61 |
62 | if ([[self trackingAreas] containsObject:_trackingArea] == NO)
63 | {
64 | [self addTrackingArea:_trackingArea];
65 | }
66 | }
67 |
68 | - (void)mouseEntered:(NSEvent *)event
69 | {
70 | _mouseIn = YES;
71 |
72 | [self updateEditButtons];
73 | }
74 |
75 | - (void)mouseExited:(NSEvent *)event
76 | {
77 | _mouseIn = NO;
78 |
79 | [self updateEditButtons];
80 | }
81 |
82 | @end
83 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/NSObject+LNPropertyListValueSorting.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+LNPropertyListValueSorting.h
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 5/5/21.
6 | // Copyright © 2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface NSObject (LNPropertyListValueSorting)
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/NSObject+LNPropertyListValueSorting.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+LNPropertyListValueSorting.m
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 5/5/21.
6 | // Copyright © 2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import "NSObject+LNPropertyListValueSorting.h"
10 | #import "LNPropertyListNode-Private.h"
11 |
12 | @implementation NSObject (LNPropertyListValueSorting)
13 |
14 | - (NSString*)_ln_stringValueForComparison
15 | {
16 | if([self isKindOfClass:NSString.class])
17 | {
18 | return (NSString*)self;
19 | }
20 | else if([self isKindOfClass:NSClassFromString(@"__NSCFBoolean")])
21 | {
22 | return [(NSNumber*)self boolValue] ? @"YES" : @"NO";
23 | }
24 | else if([self isKindOfClass:NSNumber.class])
25 | {
26 | return [LNPropertyListNode._numberFormatter stringFromNumber:(NSNumber*)self];
27 | }
28 | else if([self isKindOfClass:NSData.class])
29 | {
30 | return @"";
31 | }
32 | else if([self isKindOfClass:NSDate.class])
33 | {
34 | return [NSDateFormatter localizedStringFromDate:(NSDate*)self dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterShortStyle];
35 | }
36 |
37 | return @"";
38 | }
39 |
40 |
41 | - (NSComparisonResult)_ln_compareValue:(NSObject*)other
42 | {
43 | return [[self _ln_stringValueForComparison] localizedCaseInsensitiveCompare:[other _ln_stringValueForComparison]];
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/_LNPropertyListDatePicker.h:
--------------------------------------------------------------------------------
1 | //
2 | // _LNPropertyListDatePicker.h
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 9/11/19.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class LNPropertyListDatePickerPanel;
12 |
13 | @interface _LNPropertyListDatePicker : NSDatePicker
14 |
15 | @property (nonatomic, strong) NSDatePicker* visualDatePicker;
16 | @property (nonatomic, strong) NSDatePicker* textDatePicker;
17 | @property (nonatomic, strong) LNPropertyListDatePickerPanel* datePickerPanel;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Implementation/_LNPropertyListDatePicker.m:
--------------------------------------------------------------------------------
1 | //
2 | // _LNPropertyListDatePicker.m
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 9/11/19.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import "_LNPropertyListDatePicker.h"
10 | #import "LNPropertyListDatePickerCell.h"
11 | #import "LNPropertyListDatePickerPanel.h"
12 |
13 | @interface NSView ()
14 |
15 | - (void)geometryInWindowDidChange;
16 |
17 | @end
18 |
19 | @interface _LNForwardingDatePicker : NSDatePicker
20 | @property (nonatomic, weak) NSResponder* expectedNextResponder;
21 | @end
22 | @implementation _LNForwardingDatePicker
23 |
24 | - (NSResponder *)nextResponder
25 | {
26 | return _expectedNextResponder;
27 | }
28 |
29 | @end
30 |
31 | @interface _LNPropertyListDatePicker () @end
32 |
33 | @implementation _LNPropertyListDatePicker
34 |
35 | - (instancetype)init
36 | {
37 | self = [super init];
38 |
39 | if(self)
40 | {
41 | _visualDatePicker = [NSDatePicker new];
42 | _visualDatePicker.translatesAutoresizingMaskIntoConstraints = NO;
43 | _visualDatePicker.datePickerStyle = NSDatePickerStyleClockAndCalendar;
44 | _visualDatePicker.datePickerElements = NSDatePickerElementFlagTimeZone | NSDatePickerElementFlagHourMinuteSecond | NSDatePickerElementFlagYearMonthDay | NSDatePickerElementFlagEra;
45 | _visualDatePicker.bordered = NO;
46 |
47 | _LNForwardingDatePicker* forwardingPicker = [_LNForwardingDatePicker new];
48 | forwardingPicker.expectedNextResponder = self.nextResponder;
49 | _textDatePicker = forwardingPicker;
50 | _textDatePicker.translatesAutoresizingMaskIntoConstraints = NO;
51 | _textDatePicker.cell = [LNLeadingZerosDatePickerCell new];
52 | _textDatePicker.bordered = NO;
53 |
54 | NSViewController* vc = [NSViewController new];
55 | LNPropertyListDatePickerPanelBackgroundView* view = [LNPropertyListDatePickerPanelBackgroundView new];
56 | view.textDatePicker = _textDatePicker;
57 | view.visualDatePicker = _visualDatePicker;
58 | vc.view = view;
59 | [vc.view addSubview:_visualDatePicker];
60 | [vc.view addSubview:_textDatePicker];
61 |
62 | [NSLayoutConstraint activateConstraints:@[
63 | [vc.view.leadingAnchor constraintEqualToAnchor:_textDatePicker.leadingAnchor],
64 | [vc.view.topAnchor constraintEqualToAnchor:_textDatePicker.topAnchor],
65 | [_textDatePicker.bottomAnchor constraintEqualToAnchor:_visualDatePicker.topAnchor],
66 | [vc.view.leadingAnchor constraintEqualToAnchor:_visualDatePicker.leadingAnchor],
67 | [vc.view.trailingAnchor constraintEqualToAnchor:_visualDatePicker.trailingAnchor],
68 | [vc.view.bottomAnchor constraintEqualToAnchor:_visualDatePicker.bottomAnchor],
69 | ]];
70 |
71 | _datePickerPanel = [LNPropertyListDatePickerPanel new];
72 | _datePickerPanel.contentViewController = vc;
73 | _datePickerPanel.datePickerPanelDelegate = self;
74 | }
75 |
76 | return self;
77 | }
78 |
79 | - (BOOL)becomeFirstResponder
80 | {
81 | _visualDatePicker.dateValue = self.dateValue;
82 | _visualDatePicker.target = self.target;
83 | _visualDatePicker.action = self.action;
84 | [_visualDatePicker sizeToFit];
85 |
86 | _textDatePicker.font = self.font;
87 | _textDatePicker.datePickerStyle = self.datePickerStyle;
88 | _textDatePicker.datePickerElements = self.datePickerElements;
89 | _textDatePicker.dateValue = self.dateValue;
90 | _textDatePicker.target = self.target;
91 | _textDatePicker.action = self.action;
92 | [_textDatePicker sizeToFit];
93 |
94 | [self.window addChildWindow:_datePickerPanel ordered:NSWindowAbove];
95 | [self _repositionPanel];
96 |
97 | BOOL rv = [super becomeFirstResponder];
98 |
99 | [_datePickerPanel makeKeyWindow];
100 | [_textDatePicker becomeFirstResponder];
101 | if(NSApp.currentEvent.type == NSEventTypeLeftMouseDown || NSApp.currentEvent.type == NSEventTypeLeftMouseUp)
102 | {
103 | [_textDatePicker.cell _textFieldWithStepperTrackMouse:NSApp.currentEvent inRect:self.bounds ofView:self untilMouseUp:YES];
104 | }
105 |
106 | return rv;
107 | }
108 |
109 | - (void)_repositionPanel
110 | {
111 | if(_datePickerPanel == nil)
112 | {
113 | return;
114 | }
115 |
116 | NSScrollView* scrollView = self.enclosingScrollView;
117 | NSRect selfInScrollView = [scrollView convertRect:self.bounds fromView:self];
118 | if(selfInScrollView.origin.y < [scrollView.documentView headerView].frame.size.height ||
119 | selfInScrollView.origin.y + selfInScrollView.size.height > scrollView.frame.size.height)
120 | {
121 | [_datePickerPanel close];
122 | }
123 |
124 | NSRect positionInScreen = [self.window convertRectToScreen:[self convertRect:self.bounds toView:nil]];
125 | NSRect frame = _datePickerPanel.frame;
126 | frame.origin = NSMakePoint(positionInScreen.origin.x, positionInScreen.origin.y - frame.size.height + self.bounds.size.height);
127 | [_datePickerPanel setFrame:frame display:YES];
128 | }
129 |
130 | - (void)geometryInWindowDidChange
131 | {
132 | [super geometryInWindowDidChange];
133 |
134 | [self _repositionPanel];
135 | }
136 |
137 | - (BOOL)resignFirstResponder
138 | {
139 | [self.window removeChildWindow:_datePickerPanel];
140 | [_datePickerPanel close];
141 | return [super resignFirstResponder];
142 | }
143 |
144 | - (void)propertyListDatePickerPanelDidClose:(LNPropertyListDatePickerPanel*)panel
145 | {
146 | [self.window makeKeyWindow];
147 | [self.window makeFirstResponder:self.superview];
148 | }
149 |
150 | @end
151 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 2.1.5
19 | CFBundleVersion
20 | 1
21 | NSHumanReadableCopyright
22 | Copyright © 2018-2022 Leo Natan. All rights reserved.
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/LNPropertyListEditor.h:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListEditor.h
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/12/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | #define LN_DEPRECATED_API(x) __attribute__((deprecated(x)))
13 |
14 | typedef NS_ENUM(NSUInteger, LNPropertyListNodeChangeType) {
15 | /// Specifies that a node was inserted.
16 | LNPropertyListNodeChangeTypeInsert,
17 | /// Specifies that a node was deleted.
18 | LNPropertyListNodeChangeTypeDelete,
19 | /// Specifies that a node was moved.
20 | LNPropertyListNodeChangeTypeMove,
21 | /// Specifies that an object was updated.
22 | LNPropertyListNodeChangeTypeUpdate,
23 |
24 | LNPropertyListNodeChangeTypeReorderChildren LN_DEPRECATED_API("Use LNPropertyListNodeChangeType.update instead.") = LNPropertyListNodeChangeTypeUpdate,
25 | };
26 |
27 | NS_ASSUME_NONNULL_BEGIN
28 |
29 | @class LNPropertyListEditor;
30 |
31 | @protocol LNPropertyListEditorDelegate
32 |
33 | @optional
34 |
35 | /// Notifies the delegate that a node is about to change.
36 | /// @param editor The property list editor.
37 | /// @param node The node that will change.
38 | /// @param changeType The change type.
39 | /// @param previousKey The previous key, in case the key property has been updated.
40 | - (void)propertyListEditor:(LNPropertyListEditor *)editor willChangeNode:(LNPropertyListNode *)node changeType:(LNPropertyListNodeChangeType)changeType previousKey:(nullable NSString *)previousKey;
41 |
42 | /// Notifies the delegate that a node has changed.
43 | /// @param editor The property list editor.
44 | /// @param node The node that has changed.
45 | /// @param changeType The change type.
46 | /// @param previousKey The previous key, in case the key property has been updated.
47 | - (void)propertyListEditor:(LNPropertyListEditor *)editor didChangeNode:(LNPropertyListNode *)node changeType:(LNPropertyListNodeChangeType)changeType previousKey:(nullable NSString *)previousKey;
48 |
49 | /// Asks the delegate if the key of the specified node can be edited.
50 | /// @param editor The property list editor.
51 | /// @param node The current node.
52 | - (BOOL)propertyListEditor:(LNPropertyListEditor *)editor canEditKeyOfNode:(LNPropertyListNode*)node;
53 |
54 | /// Asks the delegate if the type of the specified node can be edited.
55 | /// @param editor The property list editor.
56 | /// @param node The current node.
57 | - (BOOL)propertyListEditor:(LNPropertyListEditor *)editor canEditTypeOfNode:(LNPropertyListNode*)node;
58 |
59 | /// Asks the delegate if the value of the specified node can be edited.
60 | /// @param editor The property list editor.
61 | /// @param node The current node.
62 | - (BOOL)propertyListEditor:(LNPropertyListEditor *)editor canEditValueOfNode:(LNPropertyListNode*)node;
63 |
64 | /// Asks the delegate if the specified node can be deleted.
65 | /// @param editor The property list editor.
66 | /// @param node The current node.
67 | - (BOOL)propertyListEditor:(LNPropertyListEditor *)editor canDeleteNode:(LNPropertyListNode*)node;
68 |
69 | /// Asks the delegate if it is possible to add a child node in the specified node.
70 | /// @param editor The property list editor.
71 | /// @param node The current node.
72 | - (BOOL)propertyListEditor:(LNPropertyListEditor *)editor canAddChildNodeInNode:(LNPropertyListNode*)node;
73 |
74 | /// Asks the delegate if it is possible to reorder the children of the specified node.
75 | /// @param editor The property list editor.
76 | /// @param node The current node.
77 | - (BOOL)propertyListEditor:(LNPropertyListEditor *)editor canReorderChildrenOfNode:(LNPropertyListNode*)node;
78 |
79 | /// Asks the delegate if the specified pasted node can be added as a child node of the specified node.
80 | /// @param editor The property list editor.
81 | /// @param pastedNode The pasted node.
82 | /// @param node The current node.
83 | - (BOOL)propertyListEditor:(LNPropertyListEditor *)editor canPasteNode:(LNPropertyListNode*)pastedNode asChildOfNode:(LNPropertyListNode*)node;
84 |
85 | /// Asks the delegate if the specified node can be moved as a child node of the specified node, at the specified index.
86 | /// @param editor The property list editor.
87 | /// @param movedNode The pasted node.
88 | /// @param parentNode The current node.
89 | /// @param index The index to paste at.
90 | - (BOOL)propertyListEditor:(LNPropertyListEditor *)editor canMoveNode:(LNPropertyListNode*)movedNode toParentNode:(LNPropertyListNode*)parentNode atIndex:(NSInteger)index;
91 |
92 | /// Asks the delegate for a default value for a child node in the specified node.
93 | /// @param editor The property list editor.
94 | /// @param node The current node.
95 | ///
96 | /// This can be either a valid property list or an LNPropertyListNode object.
97 | - (nullable id)propertyListEditor:(LNPropertyListEditor *)editor defaultPropertyListForChildInNode:(LNPropertyListNode*)node;
98 |
99 | @end
100 |
101 | @protocol LNPropertyListEditorDataTransformer
102 |
103 | @optional
104 |
105 | /// Provides a display name for the specified node.
106 | /// @param editor The property list editor.
107 | /// @param node The current node.
108 | - (nullable NSString*)propertyListEditor:(LNPropertyListEditor *)editor displayNameForNode:(LNPropertyListNode*)node;
109 |
110 | /// Provides a display value for the specified node.
111 | /// @param editor The property list editor.
112 | /// @param node The current node.
113 | ///
114 | /// This can be either a valid property list or an LNPropertyListNode object.
115 | - (nullable id)propertyListEditor:(LNPropertyListEditor *)editor displayValueForNode:(LNPropertyListNode*)node;
116 |
117 | /// Provides a storage value for the specified node and display value
118 | /// @param editor The property list editor.
119 | /// @param node The current node.
120 | /// @param displayValue The current display value of the specified node.
121 | - (nullable id)propertyListEditor:(LNPropertyListEditor *)editor storageValueForNode:(LNPropertyListNode*)node displayValue:(id)displayValue;
122 |
123 | @end
124 |
125 | IB_DESIGNABLE
126 | @interface LNPropertyListEditor : NSView
127 |
128 | /// The underlying edited property list object.
129 | ///
130 | /// Setting this property with @c allowsColumnSorting enabled will result in the model being sorted by keys on load.
131 | @property (nonatomic, copy) id propertyListObject;
132 |
133 | /// Sets the type column as hidden.
134 | @property (nonatomic, getter=isTypeColumnHidden) BOOL typeColumnHidden;
135 |
136 | /// Controls whether column sorting is enabled.
137 | ///
138 | /// Sorting a column by the user will result in nodes being sorted in the model.
139 | @property (nonatomic) BOOL allowsColumnSorting;
140 |
141 | /// The root node of the edited property list.
142 | @property (nonatomic, readonly) LNPropertyListNode* rootPropertyListNode;
143 |
144 | /// Reloads the specified node and, optionally, its children.
145 | /// @param node The node to reload, or @c nil to reload the root node.
146 | /// @param reloadChildren Pass @c true to reload the node's children as well.
147 | - (void)reloadNode:(nullable LNPropertyListNode*)node reloadChildren:(BOOL)reloadChildren;
148 | /// Expands the specified node and, optionally, its children.
149 | /// @param node The node to reload, or @c nil to expand the root node.
150 | /// @param expandChildren Pass @c true to reload the node's children as well.
151 | - (void)expandNode:(nullable LNPropertyListNode*)node expandChildren:(BOOL)expandChildren;
152 | /// Collapses the specified node and, optionally, its children.
153 | /// @param node The node to reload, or @c nil to collapse the root node.
154 | /// @param collapseChildren Pass @c true to reload the node's children as well.
155 | - (void)collapseNode:(nullable LNPropertyListNode*)node collapseChildren:(BOOL)collapseChildren;
156 |
157 | /// The currently selected node, if any.
158 | @property (nonatomic, strong, readonly, nullable) LNPropertyListNode* selectedNode;
159 |
160 | /// Selects the row for the specified node, if possible.
161 | /// @param node The node to select.
162 | - (void)selectRowForNode:(LNPropertyListNode*)node;
163 |
164 | /// Scrolls the property list editor so the specified node's row is visible.
165 | /// @param node The node whose row to scroll to
166 | - (void)scrollRowForNodeToVisible:(LNPropertyListNode*)node;
167 |
168 | /// The property list editor delegate.
169 | @property (nonatomic, weak, nullable) id delegate;
170 | /// The property list editor data transformer.
171 | @property (nonatomic, weak, nullable) id dataTransformer;
172 |
173 | /// The property list editor's undo manager.
174 | ///
175 | /// Use this property only for registering as an observer of various @c NSUndoManager notifications; do not make changes to the various properties.
176 | @property (nonatomic, strong, readonly) NSUndoManager* undoManager;
177 |
178 | /// Adds a new item.
179 | - (IBAction)add:(nullable id)sender;
180 | /// Cuts the selected item.
181 | ///
182 | /// Does nothing if there is no selection.
183 | - (IBAction)cut:(nullable id)sender;
184 | /// Copies the selected item.
185 | ///
186 | /// Does nothing if there is no selection.
187 | - (IBAction)copy:(nullable id)sender;
188 | /// Pastes an item.
189 | - (IBAction)paste:(nullable id)sender;
190 | /// Deletes the selected item.
191 | ///
192 | /// Does nothing if there is no selection.
193 | - (IBAction)delete:(nullable id)sender;
194 | /// Converts the selected item to boolean type.
195 | ///
196 | /// Does nothing if there is no selection.
197 | - (IBAction)boolean:(nullable id)sender;
198 | /// Converts the selected item to number type.
199 | ///
200 | /// Does nothing if there is no selection.
201 | - (IBAction)number:(nullable id)sender;
202 | /// Converts the selected item to string type.
203 | ///
204 | /// Does nothing if there is no selection.
205 | - (IBAction)string:(nullable id)sender;
206 | /// Converts the selected item to date type.
207 | ///
208 | /// Does nothing if there is no selection.
209 | - (IBAction)date:(nullable id)sender;
210 | /// Converts the selected item to data type.
211 | ///
212 | /// Does nothing if there is no selection.
213 | - (IBAction)data:(nullable id)sender;
214 | /// Converts the selected item to array type.
215 | ///
216 | /// Does nothing if there is no selection.
217 | - (IBAction)array:(nullable id)sender;
218 | /// Converts the selected item to dictionary type.
219 | ///
220 | /// Does nothing if there is no selection.
221 | - (IBAction)dictionary:(nullable id)sender;
222 |
223 | @end
224 |
225 | NS_ASSUME_NONNULL_END
226 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/LNPropertyListEditor/LNPropertyListNode.h:
--------------------------------------------------------------------------------
1 | //
2 | // LNPropertyListNode.h
3 | // LNPropertyListEditor
4 | //
5 | // Created by Leo Natan on 4/12/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 |
8 | //
9 |
10 | #import
11 |
12 | typedef NS_ENUM(NSUInteger, LNPropertyListNodeType) {
13 | LNPropertyListNodeTypeUnknown,
14 |
15 | LNPropertyListNodeTypeArray,
16 | LNPropertyListNodeTypeDictionary,
17 | LNPropertyListNodeTypeBoolean,
18 | LNPropertyListNodeTypeDate,
19 | LNPropertyListNodeTypeData,
20 | LNPropertyListNodeTypeNumber,
21 | LNPropertyListNodeTypeString,
22 | };
23 |
24 | NS_ASSUME_NONNULL_BEGIN
25 |
26 | @interface LNPropertyListNode : NSObject
27 |
28 | /// Returns a property list node representing the specified object.
29 | /// @param obj An object to be represented by the node.
30 | - (instancetype)initWithPropertyListObject:(id)obj;
31 |
32 | /// The key of the property list node.
33 | @property (nonatomic, strong, nullable) NSString* key;
34 | /// The type of the property list node.
35 | @property (nonatomic) LNPropertyListNodeType type;
36 | /// The value of the property list object.
37 | @property (nonatomic, strong) id value;
38 |
39 | /// The children of the property list node.
40 | @property (nonatomic, strong, nullable) NSMutableArray* children;
41 |
42 |
43 | /// Returns the child node containing the specified descendant node.
44 | /// @param descendantNode The descendant node to search for.
45 | - (nullable LNPropertyListNode*)childNodeContainingDescendantNode:(LNPropertyListNode*)descendantNode;
46 |
47 | /// Returns the child node with the specified key.
48 | /// @param key The key of the child node.
49 | - (nullable LNPropertyListNode*)childNodeForKey:(NSString*)key;
50 |
51 | /// The parent of the property list node.
52 | @property (nonatomic, weak, nullable) LNPropertyListNode* parent;
53 |
54 | /// The object, represented by the property list node.
55 | @property (nonatomic, strong, readonly) id propertyListObject;
56 |
57 | @end
58 |
59 | NS_ASSUME_NONNULL_END
60 |
--------------------------------------------------------------------------------
/LNPropertyListEditor/include/LNPropertyListEditor/LNPropertyListEditor.h:
--------------------------------------------------------------------------------
1 | ../../LNPropertyListEditor/LNPropertyListEditor.h
--------------------------------------------------------------------------------
/LNPropertyListEditor/include/LNPropertyListEditor/LNPropertyListNode.h:
--------------------------------------------------------------------------------
1 | ../../LNPropertyListEditor/LNPropertyListNode.h
--------------------------------------------------------------------------------
/LNPropertyListEditorExample/LNPropertyListEditorExample.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 39255390208444D7009C33A0 /* LNPropertyListEditor.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3925538F208444CE009C33A0 /* LNPropertyListEditor.framework */; };
11 | 39255391208444D7009C33A0 /* LNPropertyListEditor.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3925538F208444CE009C33A0 /* LNPropertyListEditor.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
12 | 393E1852207F6154002E6136 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 393E1851207F6154002E6136 /* AppDelegate.m */; };
13 | 393E1855207F6154002E6136 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 393E1854207F6154002E6136 /* ViewController.m */; };
14 | 393E1857207F6155002E6136 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 393E1856207F6155002E6136 /* Assets.xcassets */; };
15 | 393E185A207F6155002E6136 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 393E1858207F6155002E6136 /* Main.storyboard */; };
16 | 393E185D207F6155002E6136 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 393E185C207F6155002E6136 /* main.m */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXContainerItemProxy section */
20 | 3925538E208444CE009C33A0 /* PBXContainerItemProxy */ = {
21 | isa = PBXContainerItemProxy;
22 | containerPortal = 3925538A208444CE009C33A0 /* LNPropertyListEditor.xcodeproj */;
23 | proxyType = 2;
24 | remoteGlobalIDString = 393E1839207F6119002E6136;
25 | remoteInfo = LNPropertyListEditor;
26 | };
27 | 39255392208444D7009C33A0 /* PBXContainerItemProxy */ = {
28 | isa = PBXContainerItemProxy;
29 | containerPortal = 3925538A208444CE009C33A0 /* LNPropertyListEditor.xcodeproj */;
30 | proxyType = 1;
31 | remoteGlobalIDString = 393E1838207F6119002E6136;
32 | remoteInfo = LNPropertyListEditor;
33 | };
34 | /* End PBXContainerItemProxy section */
35 |
36 | /* Begin PBXCopyFilesBuildPhase section */
37 | 393E1870207F6170002E6136 /* Embed Frameworks */ = {
38 | isa = PBXCopyFilesBuildPhase;
39 | buildActionMask = 2147483647;
40 | dstPath = "";
41 | dstSubfolderSpec = 10;
42 | files = (
43 | 39255391208444D7009C33A0 /* LNPropertyListEditor.framework in Embed Frameworks */,
44 | );
45 | name = "Embed Frameworks";
46 | runOnlyForDeploymentPostprocessing = 0;
47 | };
48 | /* End PBXCopyFilesBuildPhase section */
49 |
50 | /* Begin PBXFileReference section */
51 | 3925538A208444CE009C33A0 /* LNPropertyListEditor.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = LNPropertyListEditor.xcodeproj; path = ../LNPropertyListEditor/LNPropertyListEditor.xcodeproj; sourceTree = ""; };
52 | 393E184D207F6154002E6136 /* LNPropertyListEditorExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LNPropertyListEditorExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
53 | 393E1850207F6154002E6136 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
54 | 393E1851207F6154002E6136 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
55 | 393E1853207F6154002E6136 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
56 | 393E1854207F6154002E6136 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
57 | 393E1856207F6155002E6136 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
58 | 393E1859207F6155002E6136 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
59 | 393E185B207F6155002E6136 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
60 | 393E185C207F6155002E6136 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
61 | /* End PBXFileReference section */
62 |
63 | /* Begin PBXFrameworksBuildPhase section */
64 | 393E184A207F6154002E6136 /* Frameworks */ = {
65 | isa = PBXFrameworksBuildPhase;
66 | buildActionMask = 2147483647;
67 | files = (
68 | 39255390208444D7009C33A0 /* LNPropertyListEditor.framework in Frameworks */,
69 | );
70 | runOnlyForDeploymentPostprocessing = 0;
71 | };
72 | /* End PBXFrameworksBuildPhase section */
73 |
74 | /* Begin PBXGroup section */
75 | 3925538B208444CE009C33A0 /* Products */ = {
76 | isa = PBXGroup;
77 | children = (
78 | 3925538F208444CE009C33A0 /* LNPropertyListEditor.framework */,
79 | );
80 | name = Products;
81 | sourceTree = "";
82 | };
83 | 393E1844207F6154002E6136 = {
84 | isa = PBXGroup;
85 | children = (
86 | 3925538A208444CE009C33A0 /* LNPropertyListEditor.xcodeproj */,
87 | 393E184F207F6154002E6136 /* LNPropertyListEditorExample */,
88 | 393E184E207F6154002E6136 /* Products */,
89 | );
90 | sourceTree = "";
91 | };
92 | 393E184E207F6154002E6136 /* Products */ = {
93 | isa = PBXGroup;
94 | children = (
95 | 393E184D207F6154002E6136 /* LNPropertyListEditorExample.app */,
96 | );
97 | name = Products;
98 | sourceTree = "";
99 | };
100 | 393E184F207F6154002E6136 /* LNPropertyListEditorExample */ = {
101 | isa = PBXGroup;
102 | children = (
103 | 393E1850207F6154002E6136 /* AppDelegate.h */,
104 | 393E1851207F6154002E6136 /* AppDelegate.m */,
105 | 393E1853207F6154002E6136 /* ViewController.h */,
106 | 393E1854207F6154002E6136 /* ViewController.m */,
107 | 393E1856207F6155002E6136 /* Assets.xcassets */,
108 | 393E1858207F6155002E6136 /* Main.storyboard */,
109 | 393E185B207F6155002E6136 /* Info.plist */,
110 | 393E185C207F6155002E6136 /* main.m */,
111 | );
112 | path = LNPropertyListEditorExample;
113 | sourceTree = "";
114 | };
115 | /* End PBXGroup section */
116 |
117 | /* Begin PBXNativeTarget section */
118 | 393E184C207F6154002E6136 /* LNPropertyListEditorExample */ = {
119 | isa = PBXNativeTarget;
120 | buildConfigurationList = 393E1861207F6155002E6136 /* Build configuration list for PBXNativeTarget "LNPropertyListEditorExample" */;
121 | buildPhases = (
122 | 393E1849207F6154002E6136 /* Sources */,
123 | 393E184A207F6154002E6136 /* Frameworks */,
124 | 393E184B207F6154002E6136 /* Resources */,
125 | 393E1870207F6170002E6136 /* Embed Frameworks */,
126 | );
127 | buildRules = (
128 | );
129 | dependencies = (
130 | 39255393208444D7009C33A0 /* PBXTargetDependency */,
131 | );
132 | name = LNPropertyListEditorExample;
133 | productName = LNPlistEditorViewExample;
134 | productReference = 393E184D207F6154002E6136 /* LNPropertyListEditorExample.app */;
135 | productType = "com.apple.product-type.application";
136 | };
137 | /* End PBXNativeTarget section */
138 |
139 | /* Begin PBXProject section */
140 | 393E1845207F6154002E6136 /* Project object */ = {
141 | isa = PBXProject;
142 | attributes = {
143 | LastUpgradeCheck = 1250;
144 | ORGANIZATIONNAME = "Leo Natan";
145 | TargetAttributes = {
146 | 393E184C207F6154002E6136 = {
147 | CreatedOnToolsVersion = 9.4;
148 | LastSwiftMigration = 1250;
149 | SystemCapabilities = {
150 | com.apple.Sandbox = {
151 | enabled = 0;
152 | };
153 | };
154 | };
155 | };
156 | };
157 | buildConfigurationList = 393E1848207F6154002E6136 /* Build configuration list for PBXProject "LNPropertyListEditorExample" */;
158 | compatibilityVersion = "Xcode 9.3";
159 | developmentRegion = en;
160 | hasScannedForEncodings = 0;
161 | knownRegions = (
162 | en,
163 | Base,
164 | );
165 | mainGroup = 393E1844207F6154002E6136;
166 | productRefGroup = 393E184E207F6154002E6136 /* Products */;
167 | projectDirPath = "";
168 | projectReferences = (
169 | {
170 | ProductGroup = 3925538B208444CE009C33A0 /* Products */;
171 | ProjectRef = 3925538A208444CE009C33A0 /* LNPropertyListEditor.xcodeproj */;
172 | },
173 | );
174 | projectRoot = "";
175 | targets = (
176 | 393E184C207F6154002E6136 /* LNPropertyListEditorExample */,
177 | );
178 | };
179 | /* End PBXProject section */
180 |
181 | /* Begin PBXReferenceProxy section */
182 | 3925538F208444CE009C33A0 /* LNPropertyListEditor.framework */ = {
183 | isa = PBXReferenceProxy;
184 | fileType = wrapper.framework;
185 | path = LNPropertyListEditor.framework;
186 | remoteRef = 3925538E208444CE009C33A0 /* PBXContainerItemProxy */;
187 | sourceTree = BUILT_PRODUCTS_DIR;
188 | };
189 | /* End PBXReferenceProxy section */
190 |
191 | /* Begin PBXResourcesBuildPhase section */
192 | 393E184B207F6154002E6136 /* Resources */ = {
193 | isa = PBXResourcesBuildPhase;
194 | buildActionMask = 2147483647;
195 | files = (
196 | 393E1857207F6155002E6136 /* Assets.xcassets in Resources */,
197 | 393E185A207F6155002E6136 /* Main.storyboard in Resources */,
198 | );
199 | runOnlyForDeploymentPostprocessing = 0;
200 | };
201 | /* End PBXResourcesBuildPhase section */
202 |
203 | /* Begin PBXSourcesBuildPhase section */
204 | 393E1849207F6154002E6136 /* Sources */ = {
205 | isa = PBXSourcesBuildPhase;
206 | buildActionMask = 2147483647;
207 | files = (
208 | 393E1855207F6154002E6136 /* ViewController.m in Sources */,
209 | 393E185D207F6155002E6136 /* main.m in Sources */,
210 | 393E1852207F6154002E6136 /* AppDelegate.m in Sources */,
211 | );
212 | runOnlyForDeploymentPostprocessing = 0;
213 | };
214 | /* End PBXSourcesBuildPhase section */
215 |
216 | /* Begin PBXTargetDependency section */
217 | 39255393208444D7009C33A0 /* PBXTargetDependency */ = {
218 | isa = PBXTargetDependency;
219 | name = LNPropertyListEditor;
220 | targetProxy = 39255392208444D7009C33A0 /* PBXContainerItemProxy */;
221 | };
222 | /* End PBXTargetDependency section */
223 |
224 | /* Begin PBXVariantGroup section */
225 | 393E1858207F6155002E6136 /* Main.storyboard */ = {
226 | isa = PBXVariantGroup;
227 | children = (
228 | 393E1859207F6155002E6136 /* Base */,
229 | );
230 | name = Main.storyboard;
231 | sourceTree = "";
232 | };
233 | /* End PBXVariantGroup section */
234 |
235 | /* Begin XCBuildConfiguration section */
236 | 393E185F207F6155002E6136 /* Debug */ = {
237 | isa = XCBuildConfiguration;
238 | buildSettings = {
239 | ALWAYS_SEARCH_USER_PATHS = NO;
240 | CLANG_ANALYZER_NONNULL = YES;
241 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
242 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
243 | CLANG_CXX_LIBRARY = "libc++";
244 | CLANG_ENABLE_MODULES = YES;
245 | CLANG_ENABLE_OBJC_ARC = YES;
246 | CLANG_ENABLE_OBJC_WEAK = YES;
247 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
248 | CLANG_WARN_BOOL_CONVERSION = YES;
249 | CLANG_WARN_COMMA = YES;
250 | CLANG_WARN_CONSTANT_CONVERSION = YES;
251 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
252 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
253 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
254 | CLANG_WARN_EMPTY_BODY = YES;
255 | CLANG_WARN_ENUM_CONVERSION = YES;
256 | CLANG_WARN_INFINITE_RECURSION = YES;
257 | CLANG_WARN_INT_CONVERSION = YES;
258 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
259 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
260 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
261 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
262 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
263 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
264 | CLANG_WARN_STRICT_PROTOTYPES = YES;
265 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
266 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
267 | CLANG_WARN_UNREACHABLE_CODE = YES;
268 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
269 | CODE_SIGN_IDENTITY = "-";
270 | COPY_PHASE_STRIP = NO;
271 | DEBUG_INFORMATION_FORMAT = dwarf;
272 | ENABLE_STRICT_OBJC_MSGSEND = YES;
273 | ENABLE_TESTABILITY = YES;
274 | GCC_C_LANGUAGE_STANDARD = gnu11;
275 | GCC_DYNAMIC_NO_PIC = NO;
276 | GCC_NO_COMMON_BLOCKS = YES;
277 | GCC_OPTIMIZATION_LEVEL = 0;
278 | GCC_PREPROCESSOR_DEFINITIONS = (
279 | "DEBUG=1",
280 | "$(inherited)",
281 | );
282 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
283 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
284 | GCC_WARN_UNDECLARED_SELECTOR = YES;
285 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
286 | GCC_WARN_UNUSED_FUNCTION = YES;
287 | GCC_WARN_UNUSED_VARIABLE = YES;
288 | MACOSX_DEPLOYMENT_TARGET = 10.13;
289 | MTL_ENABLE_DEBUG_INFO = YES;
290 | ONLY_ACTIVE_ARCH = YES;
291 | SDKROOT = macosx;
292 | };
293 | name = Debug;
294 | };
295 | 393E1860207F6155002E6136 /* Release */ = {
296 | isa = XCBuildConfiguration;
297 | buildSettings = {
298 | ALWAYS_SEARCH_USER_PATHS = NO;
299 | CLANG_ANALYZER_NONNULL = YES;
300 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
301 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
302 | CLANG_CXX_LIBRARY = "libc++";
303 | CLANG_ENABLE_MODULES = YES;
304 | CLANG_ENABLE_OBJC_ARC = YES;
305 | CLANG_ENABLE_OBJC_WEAK = YES;
306 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
307 | CLANG_WARN_BOOL_CONVERSION = YES;
308 | CLANG_WARN_COMMA = YES;
309 | CLANG_WARN_CONSTANT_CONVERSION = YES;
310 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
311 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
312 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
313 | CLANG_WARN_EMPTY_BODY = YES;
314 | CLANG_WARN_ENUM_CONVERSION = YES;
315 | CLANG_WARN_INFINITE_RECURSION = YES;
316 | CLANG_WARN_INT_CONVERSION = YES;
317 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
318 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
319 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
320 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
321 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
322 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
323 | CLANG_WARN_STRICT_PROTOTYPES = YES;
324 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
325 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
326 | CLANG_WARN_UNREACHABLE_CODE = YES;
327 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
328 | CODE_SIGN_IDENTITY = "-";
329 | COPY_PHASE_STRIP = NO;
330 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
331 | ENABLE_NS_ASSERTIONS = NO;
332 | ENABLE_STRICT_OBJC_MSGSEND = YES;
333 | GCC_C_LANGUAGE_STANDARD = gnu11;
334 | GCC_NO_COMMON_BLOCKS = YES;
335 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
336 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
337 | GCC_WARN_UNDECLARED_SELECTOR = YES;
338 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
339 | GCC_WARN_UNUSED_FUNCTION = YES;
340 | GCC_WARN_UNUSED_VARIABLE = YES;
341 | MACOSX_DEPLOYMENT_TARGET = 10.13;
342 | MTL_ENABLE_DEBUG_INFO = NO;
343 | SDKROOT = macosx;
344 | SWIFT_COMPILATION_MODE = wholemodule;
345 | };
346 | name = Release;
347 | };
348 | 393E1862207F6155002E6136 /* Debug */ = {
349 | isa = XCBuildConfiguration;
350 | buildSettings = {
351 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
352 | CLANG_ENABLE_MODULES = YES;
353 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO;
354 | CODE_SIGN_IDENTITY = "-";
355 | CODE_SIGN_STYLE = Automatic;
356 | COMBINE_HIDPI_IMAGES = YES;
357 | INFOPLIST_FILE = LNPropertyListEditorExample/Info.plist;
358 | LD_RUNPATH_SEARCH_PATHS = (
359 | "$(inherited)",
360 | "@executable_path/../Frameworks",
361 | );
362 | PRODUCT_BUNDLE_IDENTIFIER = com.leonatan.LNPropertyListEditorExample;
363 | PRODUCT_NAME = "$(TARGET_NAME)";
364 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
365 | SWIFT_VERSION = 5.0;
366 | };
367 | name = Debug;
368 | };
369 | 393E1863207F6155002E6136 /* Release */ = {
370 | isa = XCBuildConfiguration;
371 | buildSettings = {
372 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
373 | CLANG_ENABLE_MODULES = YES;
374 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO;
375 | CODE_SIGN_IDENTITY = "-";
376 | CODE_SIGN_STYLE = Automatic;
377 | COMBINE_HIDPI_IMAGES = YES;
378 | INFOPLIST_FILE = LNPropertyListEditorExample/Info.plist;
379 | LD_RUNPATH_SEARCH_PATHS = (
380 | "$(inherited)",
381 | "@executable_path/../Frameworks",
382 | );
383 | PRODUCT_BUNDLE_IDENTIFIER = com.leonatan.LNPropertyListEditorExample;
384 | PRODUCT_NAME = "$(TARGET_NAME)";
385 | SWIFT_VERSION = 5.0;
386 | };
387 | name = Release;
388 | };
389 | /* End XCBuildConfiguration section */
390 |
391 | /* Begin XCConfigurationList section */
392 | 393E1848207F6154002E6136 /* Build configuration list for PBXProject "LNPropertyListEditorExample" */ = {
393 | isa = XCConfigurationList;
394 | buildConfigurations = (
395 | 393E185F207F6155002E6136 /* Debug */,
396 | 393E1860207F6155002E6136 /* Release */,
397 | );
398 | defaultConfigurationIsVisible = 0;
399 | defaultConfigurationName = Release;
400 | };
401 | 393E1861207F6155002E6136 /* Build configuration list for PBXNativeTarget "LNPropertyListEditorExample" */ = {
402 | isa = XCConfigurationList;
403 | buildConfigurations = (
404 | 393E1862207F6155002E6136 /* Debug */,
405 | 393E1863207F6155002E6136 /* Release */,
406 | );
407 | defaultConfigurationIsVisible = 0;
408 | defaultConfigurationName = Release;
409 | };
410 | /* End XCConfigurationList section */
411 | };
412 | rootObject = 393E1845207F6154002E6136 /* Project object */;
413 | }
414 |
--------------------------------------------------------------------------------
/LNPropertyListEditorExample/LNPropertyListEditorExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/LNPropertyListEditorExample/LNPropertyListEditorExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/LNPropertyListEditorExample/LNPropertyListEditorExample.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/LNPropertyListEditorExample/LNPropertyListEditorExample.xcodeproj/xcshareddata/xcschemes/LNPropertyListEditorExample.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
52 |
54 |
60 |
61 |
62 |
63 |
69 |
71 |
77 |
78 |
79 |
80 |
82 |
83 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/LNPropertyListEditorExample/LNPropertyListEditorExample/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // LNPropertyListEditorExample
4 | //
5 | // Created by Leo Natan on 4/12/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : NSObject
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/LNPropertyListEditorExample/LNPropertyListEditorExample/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // LNPropertyListEditorExample
4 | //
5 | // Created by Leo Natan on 4/12/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
18 | // NSApp.windows.firstObject.appearance = [NSAppearance appearanceNamed:NSAppearanceNameVibrantDark];
19 | }
20 |
21 |
22 | - (void)applicationWillTerminate:(NSNotification *)aNotification {
23 | // Insert code here to tear down your application
24 | }
25 |
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/LNPropertyListEditorExample/LNPropertyListEditorExample/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "size" : "32x32",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "size" : "32x32",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "size" : "128x128",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "size" : "128x128",
31 | "scale" : "2x"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "size" : "256x256",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "size" : "256x256",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "size" : "512x512",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "size" : "512x512",
51 | "scale" : "2x"
52 | }
53 | ],
54 | "info" : {
55 | "version" : 1,
56 | "author" : "xcode"
57 | }
58 | }
--------------------------------------------------------------------------------
/LNPropertyListEditorExample/LNPropertyListEditorExample/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/LNPropertyListEditorExample/LNPropertyListEditorExample/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // LNPropertyListEditorExample
4 | //
5 | // Created by Leo Natan on 4/12/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : NSViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/LNPropertyListEditorExample/LNPropertyListEditorExample/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // LNPropertyListEditorExample
4 | //
5 | // Created by Leo Natan on 4/12/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import
11 |
12 | @interface ViewController () @end
13 |
14 | @implementation ViewController
15 | {
16 | IBOutlet LNPropertyListEditor* _plistEditor;
17 | }
18 |
19 | - (void)viewDidLoad {
20 | [super viewDidLoad];
21 |
22 | NSURL* propertyListURL = [[NSBundle mainBundle].bundleURL URLByAppendingPathComponent:@"Contents/Info.plist"];
23 | id obj = [NSPropertyListSerialization propertyListWithData:[NSData dataWithContentsOfURL:propertyListURL] options:0 format:nil error:NULL];
24 |
25 | _plistEditor.delegate = self;
26 | _plistEditor.dataTransformer = self;
27 |
28 | _plistEditor.propertyListObject = obj;
29 | _plistEditor.allowsColumnSorting = YES;
30 |
31 | // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
32 | // NSLog(@"Selected: %@", _plistEditor.selectedNode);
33 | // LNPropertyListNode* node = [_plistEditor.rootPropertyListNode.children filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"key == 'yHelloNumber'"]].firstObject;
34 | //
35 | // [_plistEditor selectRowForNode:node];
36 | // [_plistEditor scrollRowForNodeToVisible:node];
37 | // NSLog(@"Selected: %@", _plistEditor.selectedNode);
38 | // });
39 | }
40 |
41 | #pragma mark LNPropertyListEditorDelegate
42 |
43 | //- (BOOL)propertyListEditor:(LNPropertyListEditor *)editor canEditValueOfNode:(LNPropertyListNode*)node
44 | //{
45 | // return NO;
46 | //}
47 |
48 | - (void)propertyListEditor:(LNPropertyListEditor *)editor didChangeNode:(LNPropertyListNode *)node changeType:(LNPropertyListNodeChangeType)changeType previousKey:(NSString *)previousKey
49 | {
50 | switch(changeType)
51 | {
52 | case LNPropertyListNodeChangeTypeInsert:
53 | NSLog(@"🎉 Inserted %@", node);
54 | break;
55 | case LNPropertyListNodeChangeTypeDelete:
56 | NSLog(@"🗑 Deleted %@", node);
57 | break;
58 | case LNPropertyListNodeChangeTypeMove:
59 | NSLog(@"➡️ Moved %@", node);
60 | break;
61 | case LNPropertyListNodeChangeTypeUpdate:
62 | NSLog(@"🔄 Updated %@", node);
63 | break;
64 | }
65 | }
66 |
67 | #pragma mark LNPropertyListEditorDataTransformer
68 |
69 | //- (nullable id)propertyListEditor:(LNPropertyListEditor *)editor displayValueForNode:(LNPropertyListNode*)node
70 | //{
71 | // if(node.type == LNPropertyListNodeTypeData)
72 | // {
73 | // return @"Test";
74 | // }
75 | //
76 | // return nil;
77 | //}
78 | //
79 | //- (nullable id)propertyListEditor:(LNPropertyListEditor *)editor storageValueForNode:(LNPropertyListNode*)node displayValue:(id)displayValue
80 | //{
81 | // if(node.type == LNPropertyListNodeTypeData)
82 | // {
83 | // return [displayValue dataUsingEncoding:NSUTF8StringEncoding];
84 | // }
85 | //
86 | // return nil;
87 | //}
88 |
89 | @end
90 |
--------------------------------------------------------------------------------
/LNPropertyListEditorExample/LNPropertyListEditorExample/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // LNPropertyListEditorExample
4 | //
5 | // Created by Leo Natan on 4/12/18.
6 | // Copyright © 2018-2021 Leo Natan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | int main(int argc, const char * argv[]) {
12 | return NSApplicationMain(argc, argv);
13 | }
14 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.3
2 |
3 | import PackageDescription
4 |
5 | let package = Package(
6 | name: "LNPropertyListEditor",
7 | platforms: [
8 | .macOS(.v10_13)
9 | ],
10 | products: [
11 | .library(
12 | name: "LNPropertyListEditor",
13 | type: .dynamic,
14 | targets: ["LNPropertyListEditor"]),
15 | .library(
16 | name: "LNPropertyListEditor-Static",
17 | type: .static,
18 | targets: ["LNPropertyListEditor"]),
19 | ],
20 | dependencies: [],
21 | targets: [
22 | .target(
23 | name: "LNPropertyListEditor_HexFiend",
24 | dependencies: [],
25 | path: "HexFiendFramework",
26 | exclude: [
27 |
28 | ],
29 | resources: [],
30 | publicHeadersPath: "include",
31 | cSettings: [
32 | .unsafeFlags(["-w"]),
33 | .define("HF_NO_PRIVILEGED_FILE_OPERATIONS", to: "1"),
34 | .headerSearchPath("include"),
35 | .headerSearchPath("src"),
36 | ]),
37 | .target(
38 | name: "LNPropertyListEditor",
39 | dependencies: [
40 | "LNPropertyListEditor_HexFiend"
41 | ],
42 | path: "LNPropertyListEditor",
43 | exclude: [
44 | "LNPropertyListEditor/Info.plist"
45 | ],
46 | resources: [
47 | .process("LNPropertyListEditor/Assets.xcassets"),
48 | .process("LNPropertyListEditor/Implementation/LNPropertyListEditorOutline.xib")
49 | ],
50 | publicHeadersPath: "include",
51 | cSettings: [
52 | .headerSearchPath("."),
53 | .headerSearchPath("LNPropertyListEditor"),
54 | ]),
55 | ]
56 | )
57 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # LNPropertyListEditor
2 |
3 | A property list editor for macOS, similar to the one implemented in Xcode, but with several quality of life additions, such as a visual date/time picker and a full hex editor for data objects.
4 |
5 | The framework has full support for macOS light and dark appearance.
6 |
7 | By implementing the `LNPropertyListEditorDataTransformer` protocol, you can significantly augment the way property list data is presented in the editor and represented on-disk.
8 |
9 | 
10 |
11 | 
12 |
13 | ## Adding to Your Project
14 |
15 | ### Swift Package Manager
16 |
17 | Swift Package Manager is the recommended way to integrate LNPropertyListEditor in your project.
18 |
19 | LNPropertyListEditor supports SPM versions 5.1.0 and above. To use SPM, you should use Xcode 11 to open your project. Click `File` -> `Swift Packages` -> `Add Package Dependency`, enter `https://github.com/LeoNatan/LNPropertyListEditor`. Select the version you’d like to use.
20 |
21 | You can also manually add the package to your Package.swift file:
22 |
23 | ```swift
24 | .package(url: "https://github.com/LeoNatan/LNPropertyListEditor.git", from: "1.0")
25 | ```
26 |
27 | And the dependency in your target:
28 |
29 | ```swift
30 | .target(name: "BestExampleApp", dependencies: ["LNPropertyListEditor"]),
31 | ```
32 |
33 | ### Carthage
34 |
35 | Add the following to your Cartfile:
36 |
37 | ```github "LeoNatan/LNPropertyListEditor"```
38 |
39 | Make sure you follow the Carthage integration instructions [here](https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos).
40 |
41 | ### Manual
42 |
43 | Drag the `LNPropertyListEditor.xcodeproj` project to your project, and add `LNPropertyListEditor.framework` to **Embedded Binaries** in your project target's **General** tab. Xcode should sort everything else on its own.
44 |
45 | ### CocoaPods
46 |
47 | CocoaPods is not supported. There are many reasons for this. Instead of CocoaPods, use Carthage. You can continue using CocoaPods for for your other dependencies and Carthage for `LNPropertyListEditor`.
48 |
49 | ## Using the Framework
50 |
51 | ### Swift
52 |
53 | While the framework is written in Objective C, it uses modern Objective C syntax, so using the framework in Swift should be very easy and intuitive.
54 |
55 | ### Project Integration
56 |
57 | Import the module in your project:
58 |
59 | ```objective-c
60 | @import LNPropertyListEditor;
61 | ```
62 |
63 | ### Usage
64 |
65 | Either using Interface Builder or in code, add an `LNPropertyListEditor` view to your user interface.
66 |
67 | To set a represented object, set the `propertyList` property.
68 |
69 | ```swift
70 | guard let propertyListURL = Bundle.main.url(forResource: "Some", withExtension: "plist"),
71 | let propertyListData = try? Data(contentsOf: propertyListURL),
72 | let propertyListObject = try? PropertyListSerialization.propertyList(from: propertyListData, options: [], format: nil) as? [String: AnyObject] else {
73 | return
74 | }
75 |
76 | plistEditor.propertyListObject = propertyListObject
77 | ```
78 |
79 | Supported object types: Dictionaries, arrays, strings, dates, datas, booleans and numbers (dictionaries and arrays can contains nested children of the aforementioned types).
80 |
81 | #### Delegate
82 |
83 | Implement the `LNPropertyListEditorDelegate` protocol to listen to various events, or control what aspects of the property list can be edited.
84 |
85 | ```swift
86 | plistEditor.delegate = self
87 | //...
88 | func propertyListEditor(_ editor: LNPropertyListEditor, didChange node: LNPropertyListNode, changeType: LNPropertyListNodeChangeType, previousKey: String?) {
89 | switch changeType {
90 | case .insert:
91 | print("🎉")
92 | case .move:
93 | print("➡️")
94 | case .update:
95 | print("🔄")
96 | case .delete:
97 | print("🗑")
98 | @unknown default:
99 | fatalError()
100 | }
101 | }
102 | ```
103 |
104 | For full documentation, see the `LNPropertyListEditor.h` header.
105 |
106 | #### Data Transformer
107 |
108 | Implement the `LNPropertyListEditorDataTransformer` protocol to provide display and data transformations for your property list objects.
109 |
110 | ```swift
111 | plistEditor.dataTransformer = self
112 | //...
113 | func propertyListEditor(_ editor: LNPropertyListEditor, displayNameFor node: LNPropertyListNode) -> String? {
114 | // ...
115 | if let key = node.key,
116 | key == "CFBundleShortVersionString" {
117 | return "Bundle version string (short)"
118 | }
119 | //...
120 | }
121 | ```
122 |
123 | For full documentation, see the `LNPropertyListEditor.h` header.
124 |
125 | ## Acknowledgements
126 |
127 | The framework uses:
128 |
129 | * [HexFiend](https://github.com/HexFiend/HexFiend) © ridiculous_fish, 2011-2020
130 |
131 |
--------------------------------------------------------------------------------
/Supplements/Screenshot_1_Dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPropertyListEditor/7688237cb69ad68dd53ecf6f9f60f37a619b80e0/Supplements/Screenshot_1_Dark.png
--------------------------------------------------------------------------------
/Supplements/Screenshot_2_Dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeoNatan/LNPropertyListEditor/7688237cb69ad68dd53ecf6f9f60f37a619b80e0/Supplements/Screenshot_2_Dark.png
--------------------------------------------------------------------------------
/prepare_spm_support.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | require 'fileutils'
4 |
5 | shim_header_path = File.expand_path("HexFiendShims/include/")
6 | shim_src_path = File.expand_path("HexFiendShims/src/")
7 |
8 | include_path = File.expand_path("HexFiendFramework/include/")
9 | src_path = File.expand_path("HexFiendFramework/src/")
10 |
11 | #cleanup
12 | Dir.foreach(src_path) do |f|
13 | fn = File.join(src_path, f)
14 | FileUtils.rm_rf(fn) if f != '.' && f != '..'
15 | end
16 |
17 | Dir.foreach(include_path) do |f|
18 | fn = File.join(include_path, f)
19 | FileUtils.rm_rf(fn) if f != '.' && f != '..'
20 | end
21 |
22 | Dir.mkdir(File.join(include_path, "HexFiend"))
23 |
24 | require 'xcodeproj'
25 |
26 | input_project_path = 'HexFiend/HexFiend_2.xcodeproj'
27 | input_project = Xcodeproj::Project.open(input_project_path)
28 |
29 | input_target = input_project.targets.select do |target|
30 | target.name == "HexFiend_Framework"
31 | end.first
32 |
33 | output_project_path = Pathname(File.expand_path("HexFiendFramework"))
34 | output_project = Xcodeproj::Project.new(output_project_path.join("HexFiend.xcodeproj"))
35 | output_project.build_configurations.each do |config|
36 | config.build_settings['ONLY_ACTIVE_ARCH'] = 'NO'
37 | config.build_settings['GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS'] = 'NO'
38 | end
39 | output_target = output_project.new_target(:framework, 'HexFiend', :osx, '10.14')
40 |
41 | #headers
42 | output_headers_group = output_project.new_group("Headers")
43 |
44 | files = input_target.headers_build_phase.files.to_a.map do |pbx_header_file|
45 | pbx_header_file
46 | end.select do |pbx_header_file|
47 | not(pbx_header_file.file_ref.real_path.to_s.include?("PrivilegedHelper"))
48 | end.each do |pbx_header_file|
49 | file = pbx_header_file.file_ref.real_path
50 |
51 | output_file_reference = output_headers_group.new_file(file)
52 | output_build_file = output_target.headers_build_phase.add_file_reference(output_file_reference)
53 |
54 | file2 = file.relative_path_from(src_path)
55 | File.symlink(file2, File.join(src_path, File.basename(file)))
56 |
57 | file3 = file.relative_path_from(File.join(include_path, "HexFiend"))
58 | File.symlink(file3, File.join(File.join(include_path, "HexFiend"), File.basename(file)))
59 |
60 | if pbx_header_file.settings.nil?
61 | else
62 | output_build_file.settings = pbx_header_file.settings
63 | end
64 | end
65 |
66 | Dir.each_child(shim_header_path) do |shim_header_filename|
67 | file = Pathname(File.expand_path(shim_header_filename, shim_header_path))
68 |
69 | output_file_reference = output_headers_group.new_file(file)
70 | output_build_file = output_target.headers_build_phase.add_file_reference(output_file_reference)
71 |
72 | file2 = file.relative_path_from(src_path)
73 | File.symlink(file2, File.join(src_path, File.basename(file)))
74 |
75 | file3 = file.relative_path_from(File.join(include_path, "HexFiend"))
76 | File.symlink(file3, File.join(File.join(include_path, "HexFiend"), File.basename(file)))
77 | end
78 |
79 | #manual
80 | file = Pathname(File.expand_path("HexFiend/framework/tests/HFTest.h"))
81 |
82 | output_file_reference = output_headers_group.new_file(file)
83 | output_target.add_file_references([output_file_reference])
84 |
85 | file2 = file.relative_path_from(src_path)
86 | File.symlink(file2, File.join(src_path, File.basename(file)))
87 | file3 = file.relative_path_from(File.join(include_path, "HexFiend"))
88 | File.symlink(file3, File.join(File.join(include_path, "HexFiend"), File.basename(file)))
89 |
90 | #sources
91 | output_sources_group = output_project.new_group("Sources")
92 |
93 | files = input_target.source_build_phase.files.to_a.map do |pbx_build_file|
94 | pbx_build_file.file_ref.real_path
95 | end.select do |path|
96 | path.to_s.end_with?(".h", ".m", ".mm")
97 | end.select do |path|
98 | not(path.to_s.include?("PrivilegedHelper"))
99 | end.select do |path|
100 | File.exists?(path)
101 | end.each do |file|
102 | output_file_reference = output_sources_group.new_file(file)
103 | output_target.add_file_references([output_file_reference])
104 |
105 | file2 = file.relative_path_from(src_path)
106 | File.symlink(file2, File.join(src_path, File.basename(file)))
107 | end
108 |
109 | Dir.each_child(shim_src_path) do |shim_source_filename|
110 | file = Pathname(File.expand_path(shim_source_filename, shim_src_path))
111 |
112 | output_file_reference = output_sources_group.new_file(file)
113 | output_target.add_file_references([output_file_reference])
114 |
115 | file2 = file.relative_path_from(src_path)
116 | File.symlink(file2, File.join(src_path, File.basename(file)))
117 | end
118 |
119 | infoPlistFile = Pathname(File.expand_path("HexFiend/framework/HexFiend_Framework-Info.plist")).relative_path_from(output_project_path)
120 | infoPlistPreprocessFile = Pathname(File.expand_path("HexFiend/version.h")).relative_path_from(output_project_path)
121 | output_target.build_configurations.each do |config|
122 | config.build_settings["GCC_PREPROCESSOR_DEFINITIONS"] = ["HF_NO_PRIVILEGED_FILE_OPERATIONS=1"]
123 | config.build_settings["INFOPLIST_PREFIX_HEADER"] = infoPlistPreprocessFile.to_s
124 | config.build_settings["INFOPLIST_FILE"] = infoPlistFile.to_s
125 | config.build_settings["INFOPLIST_PREPROCESS"] = input_target.build_configurations.first.build_settings["INFOPLIST_PREPROCESS"]
126 | config.build_settings["PRODUCT_BUNDLE_IDENTIFIER"] = "com.ridiculousfish.HexFiend-Framework"
127 | config.build_settings["WARNING_CFLAGS"] = "-Wno-conditional-uninitialized"
128 | end
129 |
130 | output_project.save(output_project_path.join("HexFiend.xcodeproj"))
--------------------------------------------------------------------------------
/releaseVersion.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | if [[ -n $(git status --porcelain) ]]; then
5 | echo -e >&2 "\033[1;31mCannot release version because there are unstaged changes:\033[0m"
6 | git status --short
7 | exit -2
8 | fi
9 |
10 | if [[ -n $(git tag --contains $(git rev-parse --verify HEAD)) ]]; then
11 | echo -e >&2 "\033[1;31mThe latest commit is already contained in the following releases:\033[0m"
12 | git tag --contains $(git rev-parse --verify HEAD)
13 | exit -3
14 | fi
15 |
16 | # if [[ -n $(git log --branches --not --remotes) ]]; then
17 | # echo -e "\033[1;34mPushing pending commits to git\033[0m"
18 | # git push
19 | # fi
20 |
21 | CURRENT_VERSION=$(/usr/libexec/PlistBuddy LNPropertyListEditor/LNPropertyListEditor/Info.plist -c "Print CFBundleShortVersionString")
22 | NEXT_VERSION=$(echo "$CURRENT_VERSION" | perl -pe 's/^((\d+\.)*)(-?\d+)(.*)$/$1.($3+1).$4/e')
23 |
24 | echo -e "\033[1;34mUsing $NEXT_VERSION as release version\033[0m"
25 |
26 | echo -e "\033[1;34mCreating release notes\033[0m"
27 |
28 | RELEASE_NOTES_FILE=_tmp_release_notes.md
29 |
30 | touch "${RELEASE_NOTES_FILE}"
31 | open -Wn "${RELEASE_NOTES_FILE}"
32 |
33 | if ! [ -s "${RELEASE_NOTES_FILE}" ]; then
34 | echo >&2 "\033[1;31mNo release notes provided, aborting.\033[0m"
35 | rm -f "${RELEASE_NOTES_FILE}"
36 | exit -1
37 | fi
38 |
39 | echo -e "\033[1;34mUpdating framework version\033[0m"
40 |
41 | /usr/libexec/PlistBuddy LNPropertyListEditor/LNPropertyListEditor/Info.plist -c "Set CFBundleShortVersionString $NEXT_VERSION" -c "Set CFBundleVersion 1"
42 |
43 | echo -e "\033[1;34mCommitting all changes to Git for release $NEXT_VERSION\033[0m"
44 |
45 | git add -A
46 | git commit -m "$NEXT_VERSION"
47 | git tag "$NEXT_VERSION"
48 |
49 | git push
50 | git push --tags
51 |
52 | echo -e "\033[1;34mCreating a GitHub release\033[0m"
53 |
54 | gh release create --repo LeoNatan/LNPropertyListEditor "$NEXT_VERSION" --title "v$NEXT_VERSION" --notes-file "${RELEASE_NOTES_FILE}"
55 |
56 | rm -f "${RELEASE_NOTES_FILE}"
--------------------------------------------------------------------------------