Migrate CommandSnippetsView to SwiftUI

This commit is contained in:
1024jp 2024-05-09 19:14:44 +09:00
parent b7d1496193
commit a76ace8a4d
9 changed files with 262 additions and 2293 deletions

View File

@ -17,7 +17,7 @@
- Remove Solarized themes from the bundle.
- Update all the bundled themes to have a 70% opacity in the current line highlight.
- [trivial] Make names of code contributes in the About window selectable.
- [dev] Migrate the navigation bar to SwiftUI.
- [dev] Migrate the navigation bar and the Snippets settings view to SwiftUI.

View File

@ -272,8 +272,6 @@
2A4E638120ADC45F0033CE63 /* NSBezierPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A4E637F20ADC45F0033CE63 /* NSBezierPath.swift */; };
2A505C052988D44E002080AA /* ShortcutFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A505C042988D44E002080AA /* ShortcutFormatter.swift */; };
2A505C062988D44E002080AA /* ShortcutFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A505C042988D44E002080AA /* ShortcutFormatter.swift */; };
2A505C09298A88DD002080AA /* SnippetsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A505C08298A88DD002080AA /* SnippetsViewController.swift */; };
2A505C0A298A88DD002080AA /* SnippetsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A505C08298A88DD002080AA /* SnippetsViewController.swift */; };
2A50AA62204D513500D10A10 /* DocumentFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A50AA61204D513500D10A10 /* DocumentFile.swift */; };
2A50AA63204D513500D10A10 /* DocumentFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A50AA61204D513500D10A10 /* DocumentFile.swift */; };
2A53F56727585A0E00ED16DF /* RegularExpressionReferenceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A53F56627585A0E00ED16DF /* RegularExpressionReferenceView.swift */; };
@ -711,7 +709,6 @@
2ACDC0A61D17350A009B72D6 /* InspectorTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ACDC0A51D17350A009B72D6 /* InspectorTabView.swift */; };
2ACDC0A71D17350A009B72D6 /* InspectorTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ACDC0A51D17350A009B72D6 /* InspectorTabView.swift */; };
2ACDE28D2406B9C000FC31EC /* ThemeListView.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2A10D1261E714D230027192A /* ThemeListView.storyboard */; };
2ACDE2992406B9C000FC31EC /* SnippetsView.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2ADF3BFF1E6D7345009125BB /* SnippetsView.storyboard */; };
2ACDE29A2406B9C000FC31EC /* FindPanelFieldView.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2A5D13401D1FE34F00D38E6A /* FindPanelFieldView.storyboard */; };
2ACDE29C2406B9C000FC31EC /* SyntaxListView.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2A10D1361E715E5B0027192A /* SyntaxListView.storyboard */; };
2ACDE2A22406B9C000FC31EC /* KeyBindingTreeView.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2A10D1081E708CDF0027192A /* KeyBindingTreeView.storyboard */; };
@ -746,7 +743,6 @@
2ADBC91621C9F30000B884FF /* Atomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ADBC91421C9F30000B884FF /* Atomic.swift */; };
2ADD0AD8217A967200F78732 /* NSTextView+LineNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ADD0AD7217A967200F78732 /* NSTextView+LineNumber.swift */; };
2ADD0AD9217A967200F78732 /* NSTextView+LineNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ADD0AD7217A967200F78732 /* NSTextView+LineNumber.swift */; };
2ADF3C011E6D7345009125BB /* SnippetsView.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2ADF3BFF1E6D7345009125BB /* SnippetsView.storyboard */; };
2AE12DFB1E7DB47000681F72 /* Collection+String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE12DFA1E7DB47000681F72 /* Collection+String.swift */; };
2AE12DFC1E7DB47000681F72 /* Collection+String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE12DFA1E7DB47000681F72 /* Collection+String.swift */; };
2AE12DFE1E7DB7D200681F72 /* StringCollectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE12DFD1E7DB7D200681F72 /* StringCollectionTests.swift */; };
@ -1032,7 +1028,6 @@
2A4D69261D3FF61C00FBBD0B /* String+Encoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Encoding.swift"; sourceTree = "<group>"; };
2A4E637F20ADC45F0033CE63 /* NSBezierPath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSBezierPath.swift; sourceTree = "<group>"; };
2A505C042988D44E002080AA /* ShortcutFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutFormatter.swift; sourceTree = "<group>"; };
2A505C08298A88DD002080AA /* SnippetsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnippetsViewController.swift; sourceTree = "<group>"; };
2A50AA61204D513500D10A10 /* DocumentFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentFile.swift; sourceTree = "<group>"; };
2A51CF402BB45940001896F1 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/UnicodeBlock.strings; sourceTree = "<group>"; };
2A53F56627585A0E00ED16DF /* RegularExpressionReferenceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegularExpressionReferenceView.swift; sourceTree = "<group>"; };
@ -1291,7 +1286,6 @@
2ADB04AB2A89F14D00C4F562 /* AddRemoveButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddRemoveButton.swift; sourceTree = "<group>"; };
2ADBC91421C9F30000B884FF /* Atomic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Atomic.swift; sourceTree = "<group>"; };
2ADD0AD7217A967200F78732 /* NSTextView+LineNumber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSTextView+LineNumber.swift"; sourceTree = "<group>"; };
2ADF3C001E6D7345009125BB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/SnippetsView.storyboard; sourceTree = "<group>"; };
2AE12DFA1E7DB47000681F72 /* Collection+String.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Collection+String.swift"; sourceTree = "<group>"; };
2AE12DFD1E7DB7D200681F72 /* StringCollectionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringCollectionTests.swift; sourceTree = "<group>"; };
2AE12DFF1E7DDB1B00681F72 /* EditorTextView+SurroundSelection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "EditorTextView+SurroundSelection.swift"; sourceTree = "<group>"; };
@ -1331,7 +1325,6 @@
2AF1229E2B7A3D50004BA1FF /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/ThemeListView.xcstrings; sourceTree = "<group>"; };
2AF1229F2B7A3D50004BA1FF /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/KeyBindingTreeView.xcstrings; sourceTree = "<group>"; };
2AF122A22B7A3D50004BA1FF /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/SyntaxListView.xcstrings; sourceTree = "<group>"; };
2AF122A42B7A3D50004BA1FF /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/SnippetsView.xcstrings; sourceTree = "<group>"; };
2AF1D85721B8D9250060BC04 /* NSRegularExpression+Additions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSRegularExpression+Additions.swift"; sourceTree = "<group>"; };
2AF29EC32882EE7700DF31D2 /* AdvancedCharacterCounter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedCharacterCounter.swift; sourceTree = "<group>"; };
2AF45E1D1E6C0D920030CD60 /* EditorCounter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditorCounter.swift; sourceTree = "<group>"; };
@ -1441,7 +1434,6 @@
children = (
2A10D1261E714D230027192A /* ThemeListView.storyboard */,
2A10D1361E715E5B0027192A /* SyntaxListView.storyboard */,
2ADF3BFF1E6D7345009125BB /* SnippetsView.storyboard */,
2A10D1081E708CDF0027192A /* KeyBindingTreeView.storyboard */,
);
name = Settings;
@ -2103,7 +2095,6 @@
2A2792971D1E57DA00F3FC5D /* SyntaxListViewController.swift */,
2A5DCE881D18FFDB00D5D74C /* EncodingListView.swift */,
2A5DCE851D1888D800D5D74C /* SyntaxMappingConflictView.swift */,
2A505C08298A88DD002080AA /* SnippetsViewController.swift */,
);
name = "Other Views";
sourceTree = "<group>";
@ -2692,7 +2683,6 @@
2ACDE2A32406B9C000FC31EC /* MultipleReplaceView.storyboard in Resources */,
2A7F4DFF2871F46D0029CE66 /* PrintPanelAccessory.storyboard in Resources */,
2ACDE28D2406B9C000FC31EC /* ThemeListView.storyboard in Resources */,
2ACDE2992406B9C000FC31EC /* SnippetsView.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2783,7 +2773,6 @@
2A3D63FB1E769DDF00F538E1 /* MultipleReplaceView.storyboard in Resources */,
2A7F4E002871F46D0029CE66 /* PrintPanelAccessory.storyboard in Resources */,
2A10D1281E714D230027192A /* ThemeListView.storyboard in Resources */,
2ADF3C011E6D7345009125BB /* SnippetsView.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3133,7 +3122,6 @@
2AEC48341E641E4F00FB0F89 /* Snippet.swift in Sources */,
2A64F2461D259E49001B229F /* SnippetManager.swift in Sources */,
2ACDA2532B813FA500B2EBA8 /* SnippetsSettingsView.swift in Sources */,
2A505C09298A88DD002080AA /* SnippetsViewController.swift in Sources */,
2AD551EB20D8206C007279B1 /* StatableMenuToolbarItem.swift in Sources */,
2A5D13261D1F9D4100D38E6A /* StatableToolbarItem.swift in Sources */,
2AD21FCD1D2E3BE80018C8D1 /* StatusBar.swift in Sources */,
@ -3501,7 +3489,6 @@
2AEC48331E641E4F00FB0F89 /* Snippet.swift in Sources */,
2A64F2451D259E49001B229F /* SnippetManager.swift in Sources */,
2ACDA2542B813FA500B2EBA8 /* SnippetsSettingsView.swift in Sources */,
2A505C0A298A88DD002080AA /* SnippetsViewController.swift in Sources */,
2AD551EA20D8206C007279B1 /* StatableMenuToolbarItem.swift in Sources */,
2A5D13251D1F9D4100D38E6A /* StatableToolbarItem.swift in Sources */,
2AD21FCC1D2E3BE80018C8D1 /* StatusBar.swift in Sources */,
@ -3690,15 +3677,6 @@
name = MultipleReplaceListView.storyboard;
sourceTree = "<group>";
};
2ADF3BFF1E6D7345009125BB /* SnippetsView.storyboard */ = {
isa = PBXVariantGroup;
children = (
2ADF3C001E6D7345009125BB /* Base */,
2AF122A42B7A3D50004BA1FF /* mul */,
);
name = SnippetsView.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */

View File

@ -1,980 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="Jku-3h-OhR">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22689"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Command-->
<scene sceneID="08h-d7-riI">
<objects>
<viewController title="Command" id="Jku-3h-OhR" customClass="SnippetsViewController" customModule="CotEditor" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="cRl-JP-UAb">
<rect key="frame" x="0.0" y="0.0" width="534" height="320"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<scrollView autohidesScrollers="YES" horizontalLineScroll="24" horizontalPageScroll="10" verticalLineScroll="24" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7ds-uj-8Oj">
<rect key="frame" x="0.0" y="172" width="534" height="148"/>
<clipView key="contentView" id="57f-vc-YkM">
<rect key="frame" x="1" y="1" width="532" height="146"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="firstColumnOnly" columnReordering="NO" columnResizing="NO" emptySelection="NO" autosaveColumns="NO" rowHeight="24" rowSizeStyle="systemDefault" headerView="974-uz-WFB" viewBased="YES" id="dsG-7b-UG0">
<rect key="frame" x="0.0" y="0.0" width="532" height="118"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="8" height="0.0"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<tableViewGridLines key="gridStyleMask" horizontal="YES"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn identifier="scope" width="104" minWidth="40" maxWidth="1000" headerToolTip="" id="pbJ-4Q-CE2">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Syntax">
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" id="q2i-OB-HQc">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView id="SdO-OQ-HSL">
<rect key="frame" x="4" y="0.0" width="106" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<popUpButton id="68U-sn-0cP">
<rect key="frame" x="-3" y="1" width="109" height="20"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<popUpButtonCell key="cell" type="bevel" title="All" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" imageScaling="proportionallyDown" inset="2" selectedItem="vXM-oG-cI7" id="N04-oz-sU5">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="C83-Em-4tE">
<items>
<menuItem title="All" state="on" id="vXM-oG-cI7">
<attributedString key="attributedTitle">
<fragment content="All">
<attributes>
<color key="NSColor" name="placeholderTextColor" catalog="System" colorSpace="catalog"/>
<font key="NSFont" metaFont="menu"/>
<paragraphStyle key="NSParagraphStyle" alignment="natural" lineBreakMode="wordWrapping" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
</attributes>
</fragment>
</attributedString>
</menuItem>
<menuItem isSeparatorItem="YES" id="lzH-e5-3FM"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<action selector="didSelectSyntax:" target="Jku-3h-OhR" id="d5s-GX-2Kf"/>
<binding destination="SdO-OQ-HSL" name="selectedObject" keyPath="objectValue" id="ISd-z5-emj"/>
</connections>
</popUpButton>
</subviews>
</tableCellView>
</prototypeCellViews>
</tableColumn>
<tableColumn identifier="name" editable="NO" width="304" minWidth="16" maxWidth="1000" id="cMF-G3-bl6">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Name">
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.33333299" alpha="1" colorSpace="calibratedWhite"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" alignment="left" id="muD-7X-atL">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES"/>
<prototypeCellViews>
<tableCellView id="WTC-7C-m9U">
<rect key="frame" x="118" y="0.0" width="304" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zxQ-hR-j2t">
<rect key="frame" x="0.0" y="3" width="304" height="16"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" id="4d2-ZY-6Rc">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<action selector="didEditName:" target="Jku-3h-OhR" id="h0w-qj-58G"/>
<binding destination="WTC-7C-m9U" name="value" keyPath="objectValue" id="Tbm-8r-CNX"/>
</connections>
</textField>
</subviews>
<connections>
<outlet property="textField" destination="zxQ-hR-j2t" id="mvr-2v-RPy"/>
</connections>
</tableCellView>
</prototypeCellViews>
</tableColumn>
<tableColumn identifier="key" editable="NO" width="72" minWidth="72" maxWidth="72" id="wer-OB-X46">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Key">
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.33333299" alpha="1" colorSpace="calibratedWhite"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" id="Vp7-uB-dGW">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<prototypeCellViews>
<tableCellView id="YN5-88-L3R">
<rect key="frame" x="430" y="0.0" width="74" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" textCompletion="NO" id="7e5-Al-qqJ" customClass="ShortcutField" customModule="CotEditor" customModuleProvider="target">
<rect key="frame" x="0.0" y="3" width="64" height="16"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" alignment="right" id="gro-YE-m3e">
<customFormatter key="formatter" id="6BR-Gb-CrL" customClass="ShortcutFormatter" customModule="CotEditor" customModuleProvider="target"/>
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<allowedInputSourceLocales>
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
</allowedInputSourceLocales>
</textFieldCell>
<connections>
<action selector="didEditShortcut:" target="Jku-3h-OhR" id="xGK-2E-G76"/>
<binding destination="YN5-88-L3R" name="value" keyPath="objectValue" id="oQt-9f-v7S"/>
</connections>
</textField>
</subviews>
<connections>
<outlet property="textField" destination="7e5-Al-qqJ" id="CyT-9a-tb3"/>
</connections>
</tableCellView>
</prototypeCellViews>
</tableColumn>
</tableColumns>
<connections>
<outlet property="dataSource" destination="Jku-3h-OhR" id="RXI-N6-7wE"/>
<outlet property="delegate" destination="Jku-3h-OhR" id="uhb-13-lpw"/>
</connections>
</tableView>
</subviews>
</clipView>
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="09H-dK-VID">
<rect key="frame" x="1" y="109" width="532" height="16"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="dcy-AX-VPZ">
<rect key="frame" x="414" y="17" width="15" height="130"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<tableHeaderView key="headerView" wantsLayer="YES" id="974-uz-WFB">
<rect key="frame" x="0.0" y="0.0" width="532" height="28"/>
<autoresizingMask key="autoresizingMask"/>
</tableHeaderView>
</scrollView>
<segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="zir-3g-sBb">
<rect key="frame" x="-3" y="142" width="55" height="24"/>
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="momentary" id="t2r-oN-Xpf">
<font key="font" metaFont="system"/>
<segments>
<segment toolTip="Add" image="NSAddTemplate" width="24"/>
<segment toolTip="Delete" image="NSRemoveTemplate" width="24" enabled="NO" tag="1"/>
</segments>
</segmentedCell>
<connections>
<action selector="addRemove:" target="Jku-3h-OhR" id="3Wy-4X-3Bg"/>
</connections>
</segmentedControl>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="K7g-Vp-Prr">
<rect key="frame" x="359" y="150" width="177" height="14"/>
<textFieldCell key="cell" controlSize="small" sendsActionOnEndEditing="YES" alignment="left" title="SHORTCUT WARNING MESSAGE" id="rUw-Mw-hR2">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="systemRedColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="Jku-3h-OhR" name="value" keyPath="warningMessage" id="icx-80-xfY"/>
</connections>
</textField>
<textField horizontalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6IG-gg-VIP">
<rect key="frame" x="-2" y="108" width="105" height="16"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Insertion format:" usesSingleLineMode="YES" id="PaR-eN-FFs">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MiJ-hw-gnc">
<rect key="frame" x="430" y="104" width="108" height="22"/>
<popUpButtonCell key="cell" type="push" title="Insert Variable" bezelStyle="rounded" alignment="left" controlSize="small" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" pullsDown="YES" preferredEdge="maxY" selectedItem="vOg-Tt-3ZZ" id="vaY-AY-tye">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="smallSystem"/>
<menu key="menu" showsStateColumn="NO" id="btm-95-vZA">
<items>
<menuItem title="Insert Variable" state="on" hidden="YES" id="vOg-Tt-3ZZ"/>
</items>
</menu>
</popUpButtonCell>
</popUpButton>
<scrollView autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uil-3J-Loj">
<rect key="frame" x="0.0" y="0.0" width="534" height="100"/>
<clipView key="contentView" id="Aal-ZX-ppq">
<rect key="frame" x="1" y="1" width="532" height="98"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView importsGraphics="NO" richText="NO" verticallyResizable="YES" allowsUndo="YES" smartInsertDelete="YES" layoutManager="textKit1" id="Fbn-Oh-pop" customClass="TokenTextView" customModule="CotEditor" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="532" height="86"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<size key="minSize" width="532" height="86"/>
<size key="maxSize" width="552" height="10000000"/>
<color key="insertionPointColor" name="textColor" catalog="System" colorSpace="catalog"/>
<allowedInputSourceLocales>
<string>eu</string>
<string>hr_BA</string>
<string>en_CM</string>
<string>rw_RW</string>
<string>en_SZ</string>
<string>tk_Latn</string>
<string>uz_Arab</string>
<string>he_IL</string>
<string>ar</string>
<string>en_PN</string>
<string>as</string>
<string>en_NF</string>
<string>rwk_TZ</string>
<string>zh_Hant_TW</string>
<string>gsw_LI</string>
<string>th_TH</string>
<string>ta_IN</string>
<string>es_EA</string>
<string>fr_GF</string>
<string>ar_001</string>
<string>en_RW</string>
<string>tr_TR</string>
<string>de_CH</string>
<string>ee_TG</string>
<string>en_NG</string>
<string>fr_TG</string>
<string>az</string>
<string>fr_SC</string>
<string>es_HN</string>
<string>en_AG</string>
<string>ru_KZ</string>
<string>gsw</string>
<string>dyo</string>
<string>so_ET</string>
<string>zh_Hant_MO</string>
<string>de_BE</string>
<string>km_KH</string>
<string>my_MM</string>
<string>mgh_MZ</string>
<string>ee_GH</string>
<string>es_EC</string>
<string>kw_GB</string>
<string>rm_CH</string>
<string>en_ME</string>
<string>nyn</string>
<string>mk_MK</string>
<string>bs_Cyrl_BA</string>
<string>ar_MR</string>
<string>en_BM</string>
<string>ms_Arab</string>
<string>en_AI</string>
<string>gl_ES</string>
<string>en_PR</string>
<string>ha_Latn_GH</string>
<string>ne_IN</string>
<string>or_IN</string>
<string>khq_ML</string>
<string>en_MG</string>
<string>pt_TL</string>
<string>en_LC</string>
<string>ta_SG</string>
<string>jmc_TZ</string>
<string>om_ET</string>
<string>lv_LV</string>
<string>es_US</string>
<string>en_PT</string>
<string>vai_Latn_LR</string>
<string>to_TO</string>
<string>en_NL</string>
<string>cgg_UG</string>
<string>ta</string>
<string>en_MH</string>
<string>iu_Cans_CA</string>
<string>zu_ZA</string>
<string>shi_Latn_MA</string>
<string>brx_IN</string>
<string>ar_KM</string>
<string>en_AL</string>
<string>te</string>
<string>chr_US</string>
<string>yo_BJ</string>
<string>fr_VU</string>
<string>pa</string>
<string>tg</string>
<string>ks_Arab</string>
<string>kea</string>
<string>te_IN</string>
<string>th</string>
<string>fr_RE</string>
<string>ur_IN</string>
<string>yo_NG</string>
<string>ti</string>
<string>guz_KE</string>
<string>tk</string>
<string>kl_GL</string>
<string>ksf_CM</string>
<string>mua_CM</string>
<string>lag_TZ</string>
<string>fr_TN</string>
<string>es_PA</string>
<string>pl_PL</string>
<string>to</string>
<string>hi_IN</string>
<string>dje_NE</string>
<string>es_GQ</string>
<string>kok_IN</string>
<string>pl</string>
<string>tr</string>
<string>bem</string>
<string>ha</string>
<string>ckb</string>
<string>lg</string>
<string>fr_GN</string>
<string>en_PW</string>
<string>en_NO</string>
<string>nyn_UG</string>
<string>sr_Latn_RS</string>
<string>pa_Guru</string>
<string>he</string>
<string>swc_CD</string>
<string>ug_Arab</string>
<string>lu_CD</string>
<string>mgo_CM</string>
<string>sn_ZW</string>
<string>en_BS</string>
<string>ps_AF</string>
<string>da</string>
<string>ms_Latn_SG</string>
<string>ps</string>
<string>ln</string>
<string>pt</string>
<string>iu_Cans</string>
<string>hi</string>
<string>lo</string>
<string>ebu</string>
<string>de</string>
<string>gu_IN</string>
<string>seh</string>
<string>en_CX</string>
<string>en_ZM</string>
<string>tzm_Latn_MA</string>
<string>fr_HT</string>
<string>fr_GP</string>
<string>lt</string>
<string>lu</string>
<string>ln_CD</string>
<string>vai_Latn</string>
<string>el_GR</string>
<string>lv</string>
<string>en_KE</string>
<string>sbp</string>
<string>hr</string>
<string>en_CY</string>
<string>es_GT</string>
<string>twq_NE</string>
<string>zh_Hant_HK</string>
<string>kln_KE</string>
<string>fr_GQ</string>
<string>chr</string>
<string>hu</string>
<string>es_UY</string>
<string>fr_CA</string>
<string>en_NR</string>
<string>mer</string>
<string>shi</string>
<string>es_PE</string>
<string>fr_SN</string>
<string>bez</string>
<string>sw_TZ</string>
<string>kkj</string>
<string>hy</string>
<string>kk_Cyrl_KZ</string>
<string>en_CZ</string>
<string>teo_KE</string>
<string>teo</string>
<string>dz_BT</string>
<string>ar_JO</string>
<string>mer_KE</string>
<string>khq</string>
<string>ln_CF</string>
<string>nn_NO</string>
<string>en_MO</string>
<string>ar_TD</string>
<string>dz</string>
<string>ses</string>
<string>en_BW</string>
<string>en_AS</string>
<string>ar_IL</string>
<string>ms_Latn_BN</string>
<string>bo_CN</string>
<string>nnh</string>
<string>teo_UG</string>
<string>hy_AM</string>
<string>ln_CG</string>
<string>sr_Latn_BA</string>
<string>en_MP</string>
<string>ksb_TZ</string>
<string>ar_SA</string>
<string>ar_LY</string>
<string>en_AT</string>
<string>so_KE</string>
<string>fr_CD</string>
<string>af_NA</string>
<string>en_NU</string>
<string>es_PH</string>
<string>en_KI</string>
<string>en_JE</string>
<string>lkt</string>
<string>en_AU</string>
<string>fa_IR</string>
<string>uz_Latn_UZ</string>
<string>ky_Cyrl</string>
<string>zh_Hans_CN</string>
<string>ewo_CM</string>
<string>fr_PF</string>
<string>ca_IT</string>
<string>en_BZ</string>
<string>ar_KW</string>
<string>pt_GW</string>
<string>fr_FR</string>
<string>am_ET</string>
<string>en_VC</string>
<string>fr_DJ</string>
<string>fr_CF</string>
<string>es_SV</string>
<string>en_MS</string>
<string>pt_ST</string>
<string>ar_SD</string>
<string>luy_KE</string>
<string>swc</string>
<string>de_LI</string>
<string>fr_CG</string>
<string>zh_Hans_SG</string>
<string>en_MT</string>
<string>ewo</string>
<string>af_ZA</string>
<string>om_KE</string>
<string>nl_SR</string>
<string>es_ES</string>
<string>es_DO</string>
<string>ar_IQ</string>
<string>fr_CH</string>
<string>nnh_CM</string>
<string>es_419</string>
<string>en_MU</string>
<string>en_US_POSIX</string>
<string>yav_CM</string>
<string>luo_KE</string>
<string>dua_CM</string>
<string>et_EE</string>
<string>en_IE</string>
<string>ak_GH</string>
<string>rwk</string>
<string>es_CL</string>
<string>kea_CV</string>
<string>fr_CI</string>
<string>fr_BE</string>
<string>en_NZ</string>
<string>ky_Cyrl_KG</string>
<string>en_LR</string>
<string>en_KN</string>
<string>nb_SJ</string>
<string>sg</string>
<string>sr_Cyrl_RS</string>
<string>ru_RU</string>
<string>en_ZW</string>
<string>sv_AX</string>
<string>si</string>
<string>ga_IE</string>
<string>en_VG</string>
<string>sk</string>
<string>agq_CM</string>
<string>fr_BF</string>
<string>naq_NA</string>
<string>sl</string>
<string>en_MW</string>
<string>mr_IN</string>
<string>az_Latn</string>
<string>en_LS</string>
<string>de_AT</string>
<string>ka</string>
<string>sn</string>
<string>sr_Latn_ME</string>
<string>fr_NC</string>
<string>so</string>
<string>is_IS</string>
<string>twq</string>
<string>ig_NG</string>
<string>sq</string>
<string>fo_FO</string>
<string>sr</string>
<string>tzm</string>
<string>ga</string>
<string>om</string>
<string>en_LT</string>
<string>bas_CM</string>
<string>ki</string>
<string>nl_BE</string>
<string>ar_QA</string>
<string>sv</string>
<string>kk</string>
<string>sw</string>
<string>es_CO</string>
<string>az_Latn_AZ</string>
<string>rn_BI</string>
<string>or</string>
<string>kl</string>
<string>ca</string>
<string>en_VI</string>
<string>km</string>
<string>kn</string>
<string>en_LU</string>
<string>fr_SY</string>
<string>ar_TN</string>
<string>en_JM</string>
<string>fr_PM</string>
<string>ko</string>
<string>fr_NE</string>
<string>fr_MA</string>
<string>gl</string>
<string>ru_MD</string>
<string>saq_KE</string>
<string>ks</string>
<string>fr_CM</string>
<string>gv_IM</string>
<string>fr_BI</string>
<string>en_LV</string>
<string>ks_Arab_IN</string>
<string>es_NI</string>
<string>en_GB</string>
<string>kw</string>
<string>nl_SX</string>
<string>dav_KE</string>
<string>tr_CY</string>
<string>ky</string>
<string>en_UG</string>
<string>tzm_Latn</string>
<string>en_TC</string>
<string>nus_SD</string>
<string>ar_EG</string>
<string>fr_BJ</string>
<string>gu</string>
<string>es_PR</string>
<string>fr_RW</string>
<string>sr_Cyrl_BA</string>
<string>gv</string>
<string>fr_MC</string>
<string>cs</string>
<string>bez_TZ</string>
<string>es_CR</string>
<string>asa_TZ</string>
<string>ar_EH</string>
<string>ms_Arab_BN</string>
<string>mn_Cyrl</string>
<string>sbp_TZ</string>
<string>ha_Latn_NE</string>
<string>lt_LT</string>
<string>mfe</string>
<string>en_GD</string>
<string>cy</string>
<string>ca_FR</string>
<string>es_BO</string>
<string>fr_BL</string>
<string>bn_IN</string>
<string>uz_Cyrl_UZ</string>
<string>az_Cyrl</string>
<string>en_IM</string>
<string>sw_KE</string>
<string>en_SB</string>
<string>ur_PK</string>
<string>pa_Arab</string>
<string>haw_US</string>
<string>ar_SO</string>
<string>en_IN</string>
<string>ha_Latn</string>
<string>fil</string>
<string>fr_MF</string>
<string>en_WS</string>
<string>es_CU</string>
<string>ja_JP</string>
<string>en_SC</string>
<string>en_IO</string>
<string>pt_PT</string>
<string>en_HK</string>
<string>en_GG</string>
<string>fr_MG</string>
<string>de_LU</string>
<string>ms_Latn_MY</string>
<string>tg_Cyrl</string>
<string>en_SD</string>
<string>shi_Tfng</string>
<string>ln_AO</string>
<string>ug_Arab_CN</string>
<string>as_IN</string>
<string>en_GH</string>
<string>ro_RO</string>
<string>jgo_CM</string>
<string>dua</string>
<string>en_UM</string>
<string>en_SE</string>
<string>kn_IN</string>
<string>en_KY</string>
<string>vun_TZ</string>
<string>kln</string>
<string>en_GI</string>
<string>ca_ES</string>
<string>rof</string>
<string>pt_CV</string>
<string>kok</string>
<string>pt_BR</string>
<string>ar_DJ</string>
<string>zh</string>
<string>fi_FI</string>
<string>tg_Cyrl_TJ</string>
<string>es_PY</string>
<string>ar_SS</string>
<string>mua</string>
<string>sr_Cyrl_ME</string>
<string>vai_Vaii_LR</string>
<string>en_001</string>
<string>xog_UG</string>
<string>en_TK</string>
<string>si_LK</string>
<string>en_SG</string>
<string>nl_NL</string>
<string>vi</string>
<string>sv_SE</string>
<string>pt_AO</string>
<string>fr_DZ</string>
<string>ca_AD</string>
<string>xog</string>
<string>en_IS</string>
<string>nb</string>
<string>seh_MZ</string>
<string>es_AR</string>
<string>sk_SK</string>
<string>en_SH</string>
<string>ti_ER</string>
<string>nd</string>
<string>az_Cyrl_AZ</string>
<string>zu</string>
<string>ne</string>
<string>nd_ZW</string>
<string>el_CY</string>
<string>en_IT</string>
<string>nl_BQ</string>
<string>da_GL</string>
<string>ja</string>
<string>rm</string>
<string>fr_ML</string>
<string>rn</string>
<string>en_VU</string>
<string>rof_TZ</string>
<string>ro</string>
<string>ebu_KE</string>
<string>ru_KG</string>
<string>en_SI</string>
<string>sg_CF</string>
<string>mfe_MU</string>
<string>nl</string>
<string>brx</string>
<string>bs_Latn</string>
<string>fa</string>
<string>zgh_MA</string>
<string>en_GM</string>
<string>shi_Latn</string>
<string>en_FI</string>
<string>nn</string>
<string>en_EE</string>
<string>ru</string>
<string>kam_KE</string>
<string>vai_Vaii</string>
<string>ar_ER</string>
<string>ti_ET</string>
<string>rw</string>
<string>ff</string>
<string>luo</string>
<string>fa_AF</string>
<string>ha_Latn_NG</string>
<string>nl_CW</string>
<string>en_HR</string>
<string>en_FJ</string>
<string>fi</string>
<string>pt_MO</string>
<string>be</string>
<string>en_US</string>
<string>en_TO</string>
<string>en_SK</string>
<string>bg</string>
<string>ru_BY</string>
<string>it_IT</string>
<string>ml_IN</string>
<string>gsw_CH</string>
<string>fo</string>
<string>sv_FI</string>
<string>en_FK</string>
<string>nus</string>
<string>ta_LK</string>
<string>vun</string>
<string>sr_Latn</string>
<string>fr</string>
<string>en_SL</string>
<string>bm</string>
<string>ar_BH</string>
<string>guz</string>
<string>bn</string>
<string>bo</string>
<string>ar_SY</string>
<string>lo_LA</string>
<string>ne_NP</string>
<string>uz_Latn</string>
<string>be_BY</string>
<string>es_IC</string>
<string>sr_Latn_XK</string>
<string>ar_MA</string>
<string>pa_Guru_IN</string>
<string>br</string>
<string>luy</string>
<string>kde_TZ</string>
<string>bs</string>
<string>hu_HU</string>
<string>ar_AE</string>
<string>en_HU</string>
<string>zh_Hans</string>
<string>en_FM</string>
<string>sq_AL</string>
<string>ko_KP</string>
<string>en_150</string>
<string>en_DE</string>
<string>fr_MQ</string>
<string>en_CA</string>
<string>en_TR</string>
<string>ro_MD</string>
<string>es_VE</string>
<string>fr_WF</string>
<string>mt_MT</string>
<string>kab</string>
<string>nmg_CM</string>
<string>ru_UA</string>
<string>fr_MR</string>
<string>tk_Latn_TM</string>
<string>zh_Hans_MO</string>
<string>mn_Cyrl_MN</string>
<string>bs_Cyrl</string>
<string>sw_UG</string>
<string>ko_KR</string>
<string>en_DG</string>
<string>bo_IN</string>
<string>en_CC</string>
<string>shi_Tfng_MA</string>
<string>lag</string>
<string>it_SM</string>
<string>en_TT</string>
<string>ms_Arab_MY</string>
<string>sq_MK</string>
<string>ms_Latn</string>
<string>bem_ZM</string>
<string>kde</string>
<string>ar_OM</string>
<string>cgg</string>
<string>bas</string>
<string>kam</string>
<string>zh_Hant</string>
<string>es_MX</string>
<string>en_GU</string>
<string>fr_MU</string>
<string>fr_KM</string>
<string>ar_LB</string>
<string>en_BA</string>
<string>en_TV</string>
<string>sr_Cyrl</string>
<string>dje</string>
<string>kab_DZ</string>
<string>fil_PH</string>
<string>vai</string>
<string>hr_HR</string>
<string>bs_Latn_BA</string>
<string>nl_AW</string>
<string>dav</string>
<string>so_SO</string>
<string>ar_PS</string>
<string>en_FR</string>
<string>uz_Cyrl</string>
<string>ff_SN</string>
<string>en_BB</string>
<string>ki_KE</string>
<string>naq</string>
<string>en_SS</string>
<string>mg_MG</string>
<string>mas_KE</string>
<string>en_RO</string>
<string>en_PG</string>
<string>mgh</string>
<string>dyo_SN</string>
<string>mas</string>
<string>agq</string>
<string>bn_BD</string>
<string>haw</string>
<string>nb_NO</string>
<string>da_DK</string>
<string>en_DK</string>
<string>saq</string>
<string>ug</string>
<string>cy_GB</string>
<string>fr_YT</string>
<string>jmc</string>
<string>ses_ML</string>
<string>en_PH</string>
<string>de_DE</string>
<string>ar_YE</string>
<string>bm_ML</string>
<string>yo</string>
<string>lkt_US</string>
<string>uz_Arab_AF</string>
<string>jgo</string>
<string>uk</string>
<string>sl_SI</string>
<string>en_CH</string>
<string>asa</string>
<string>lg_UG</string>
<string>mgo</string>
<string>id_ID</string>
<string>en_NA</string>
<string>en_GY</string>
<string>zgh</string>
<string>pt_MZ</string>
<string>fr_LU</string>
<string>kk_Cyrl</string>
<string>mas_TZ</string>
<string>ur</string>
<string>en_DM</string>
<string>ta_MY</string>
<string>en_BE</string>
<string>mg</string>
<string>fr_GA</string>
<string>ka_GE</string>
<string>nmg</string>
<string>en_TZ</string>
<string>eu_ES</string>
<string>ar_DZ</string>
<string>id</string>
<string>so_DJ</string>
<string>yav</string>
<string>mk</string>
<string>pa_Arab_PK</string>
<string>ml</string>
<string>en_ER</string>
<string>ig</string>
<string>mn</string>
<string>ksb</string>
<string>uz</string>
<string>vi_VN</string>
<string>ii</string>
<string>en_PK</string>
<string>ee</string>
<string>mr</string>
<string>ms</string>
<string>en_ES</string>
<string>sq_XK</string>
<string>it_CH</string>
<string>mt</string>
<string>en_CK</string>
<string>br_FR</string>
<string>sr_Cyrl_XK</string>
<string>ksf</string>
<string>en_SX</string>
<string>bg_BG</string>
<string>en_PL</string>
<string>af</string>
<string>el</string>
<string>cs_CZ</string>
<string>fr_TD</string>
<string>zh_Hans_HK</string>
<string>is</string>
<string>my</string>
<string>en</string>
<string>it</string>
<string>ii_CN</string>
<string>eo</string>
<string>iu</string>
<string>en_ZA</string>
<string>en_AD</string>
<string>ak</string>
<string>en_RU</string>
<string>kkj_CM</string>
<string>am</string>
<string>es</string>
<string>et</string>
<string>uk_UA</string>
</allowedInputSourceLocales>
<connections>
<accessibilityConnection property="title" destination="6IG-gg-VIP" id="mTh-yr-rjn"/>
<outlet property="delegate" destination="Jku-3h-OhR" id="PJt-a1-j9B"/>
</connections>
</textView>
</subviews>
<edgeInsets key="contentInsets" left="0.0" right="0.0" top="6" bottom="6"/>
</clipView>
<constraints>
<constraint firstAttribute="height" constant="100" id="gA0-oF-WUh"/>
</constraints>
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" controlSize="small" horizontal="YES" id="sU0-Fi-Pyv">
<rect key="frame" x="-100" y="-100" width="87" height="18"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" controlSize="small" horizontal="NO" id="IKs-Tg-JFh">
<rect key="frame" x="489" y="1" width="14" height="58"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="uil-3J-Loj" secondAttribute="trailing" id="2bN-Ds-oXj"/>
<constraint firstItem="zir-3g-sBb" firstAttribute="top" secondItem="7ds-uj-8Oj" secondAttribute="bottom" constant="8" symbolic="YES" id="7UM-XW-eM2"/>
<constraint firstAttribute="trailing" secondItem="7ds-uj-8Oj" secondAttribute="trailing" id="BRn-TL-1Y0"/>
<constraint firstItem="6IG-gg-VIP" firstAttribute="top" secondItem="zir-3g-sBb" secondAttribute="bottom" constant="20" id="D3C-tE-nK1"/>
<constraint firstItem="7ds-uj-8Oj" firstAttribute="top" secondItem="cRl-JP-UAb" secondAttribute="top" id="KJL-mI-WLL"/>
<constraint firstAttribute="trailing" secondItem="K7g-Vp-Prr" secondAttribute="trailing" id="Rc5-nB-GqI"/>
<constraint firstItem="uil-3J-Loj" firstAttribute="top" secondItem="6IG-gg-VIP" secondAttribute="bottom" constant="8" symbolic="YES" id="Slp-1l-h4D"/>
<constraint firstItem="K7g-Vp-Prr" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="zir-3g-sBb" secondAttribute="trailing" constant="8" symbolic="YES" id="UMf-Gh-vCO"/>
<constraint firstItem="7ds-uj-8Oj" firstAttribute="leading" secondItem="cRl-JP-UAb" secondAttribute="leading" id="eBc-zU-BRk"/>
<constraint firstItem="MiJ-hw-gnc" firstAttribute="trailing" secondItem="uil-3J-Loj" secondAttribute="trailing" id="fv0-Ed-MlE"/>
<constraint firstItem="MiJ-hw-gnc" firstAttribute="centerY" secondItem="6IG-gg-VIP" secondAttribute="centerY" id="gOh-1q-A7h"/>
<constraint firstItem="zir-3g-sBb" firstAttribute="leading" secondItem="cRl-JP-UAb" secondAttribute="leading" id="gwc-qh-Hrc"/>
<constraint firstAttribute="bottom" secondItem="uil-3J-Loj" secondAttribute="bottom" id="ikz-ET-z6i"/>
<constraint firstItem="6IG-gg-VIP" firstAttribute="leading" secondItem="cRl-JP-UAb" secondAttribute="leading" id="nI9-ak-j3i"/>
<constraint firstItem="K7g-Vp-Prr" firstAttribute="top" secondItem="7ds-uj-8Oj" secondAttribute="bottom" constant="8" symbolic="YES" id="uhY-uQ-Xef"/>
<constraint firstItem="MiJ-hw-gnc" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="6IG-gg-VIP" secondAttribute="trailing" constant="8" symbolic="YES" id="xqQ-Mn-0Ny"/>
<constraint firstItem="uil-3J-Loj" firstAttribute="leading" secondItem="cRl-JP-UAb" secondAttribute="leading" id="zOl-gw-MNw"/>
</constraints>
</view>
<connections>
<outlet property="addRemoveButton" destination="zir-3g-sBb" id="HUl-xN-SwB"/>
<outlet property="formatTextView" destination="Fbn-Oh-pop" id="Ygp-uw-3yH"/>
<outlet property="tableView" destination="dsG-7b-UG0" id="Pk7-qM-KSe"/>
<outlet property="variableInsertionMenu" destination="MiJ-hw-gnc" id="YFW-aj-ydK"/>
</connections>
</viewController>
<customObject id="3nJ-L4-Stp" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="251" y="527"/>
</scene>
</scenes>
<resources>
<image name="NSAddTemplate" width="18" height="17"/>
<image name="NSRemoveTemplate" width="18" height="5"/>
</resources>
</document>

View File

@ -615,9 +615,92 @@
}
}
},
"Key" : {
"comment" : "table column header",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zkratka"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Taste"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Key"
}
},
"en-GB" : {
"stringUnit" : {
"state" : "translated",
"value" : "Key"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Teclas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Raccourci"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tasto"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "キー"
}
},
"nl" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sleutel"
}
},
"pt" : {
"stringUnit" : {
"state" : "translated",
"value" : "Teclas"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Düğme"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "按键"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "按鍵"
}
}
}
},
"Multiple items selected" : {
"comment" : "placeholder",
"localizations" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
@ -691,11 +774,93 @@
}
}
}
},
"Name" : {
"comment" : "table column header",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Název"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Name"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Name"
}
},
"en-GB" : {
"stringUnit" : {
"state" : "translated",
"value" : "Name"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nombre"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nom"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nome"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "名前"
}
},
"nl" : {
"stringUnit" : {
"state" : "translated",
"value" : "Naam"
}
},
"pt" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nome"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ad"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "名字"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "名稱"
}
}
}
},
"No item selected" : {
"comment" : "placeholder",
"localizations" : {
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
@ -769,7 +934,6 @@
}
}
}
},
"Restore Defaults" : {
"comment" : "button label",
@ -850,6 +1014,7 @@
},
"Select a snippet to edit." : {
"comment" : "placeholder for insertion format field",
"extractionState" : "stale",
"localizations" : {
"cs" : {
"stringUnit" : {

View File

@ -25,7 +25,7 @@
import Foundation.NSString
struct Snippet: Identifiable {
struct Snippet: Equatable, Identifiable {
let id = UUID()

View File

@ -34,13 +34,9 @@ struct SnippetsSettingsView: View {
VStack {
TabView {
VStack(alignment: .leading) {
Text("Text to be inserted by a command in the menu or by keyboard shortcut:", tableName: "SnippetsSettings")
SnippetsView()
}
.padding(self.insets)
.tabItem { Text("Command", tableName: "SnippetsSettings", comment: "tab label") }
CommandSnippetsView()
.padding(self.insets)
.tabItem { Text("Command", tableName: "SnippetsSettings", comment: "tab label") }
FileDropView()
.padding(self.insets)
.tabItem { Text("File Drop", tableName: "SnippetsSettings", comment: "tab label") }
@ -58,18 +54,98 @@ struct SnippetsSettingsView: View {
}
private struct SnippetsView: NSViewControllerRepresentable {
private struct CommandSnippetsView: View {
typealias NSViewControllerType = NSViewController
private typealias Item = Snippet
func makeNSViewController(context: Context) -> NSViewController {
NSStoryboard(name: "SnippetsView", bundle: nil).instantiateInitialController()!
}
func updateNSViewController(_ nsViewController: NSViewController, context: Context) {
@State private var items: [Item] = []
@State private var selection: Set<Item.ID> = []
@State private var error: (any Error)?
@State private var format: String?
var body: some View {
VStack(alignment: .leading) {
Text("Text to be inserted by a command in the menu or by keyboard shortcut:", tableName: "SnippetsSettings")
Table(of: Item.self, selection: $selection) {
TableColumn(String(localized: "Syntax", table: "SnippetsSettings", comment: "table column header")) { wrappedItem in
let item = $items[id: wrappedItem.id]!
SyntaxPicker(selection: item.scope)
.buttonStyle(.borderless)
.help(String(localized: "Syntax in which this file drop setting is used.", table: "SnippetsSettings", comment: "tooltip"))
}.width(min: 40, ideal: 64)
TableColumn(String(localized: "Name", table: "SnippetsSettings", comment: "table column header")) { wrappedItem in
let item = $items[id: wrappedItem.id]!
TextField(text: item.name, label: EmptyView.init)
}.width(min: 40, ideal: 64)
TableColumn(String(localized: "Key", table: "SnippetsSettings", comment: "table column header")) { wrappedItem in
let item = $items[id: wrappedItem.id]!
ShortcutField(value: item.shortcut, error: $error)
}
} rows: {
ForEach(self.items) { item in
TableRow(item)
.itemProvider { [id = item.id] in id.itemProvider }
}
.onInsert(of: [.uuid]) { (index, providers) in
// `onInsert(of:perform:)` shows a plus badge which should be avoided
// on just moving items in the identical table,
// but `onMove()` is not provided yet for DynamicTableRowContent yet.
// (2024-05, macOS 14)
Task {
let indexes = try await providers
.asyncMap { try await $0.load(type: UUID.self) }
.compactMap { uuid in self.items.firstIndex(where: { $0.id == uuid }) }
withAnimation {
self.items.move(fromOffsets: IndexSet(indexes), toOffset: index)
}
}
}
}
.onChange(of: self.selection, initial: true) { (_, newValue) in
self.format = if newValue.count == 1, let id = newValue.first {
self.items[id: id]?.format
} else {
nil
}
}
.tableStyle(.bordered)
.border(Color(nsColor: .gridColor))
HStack(alignment: .firstTextBaseline) {
AddRemoveButton($items, selection: $selection) {
SnippetManager.shared.createUntitledSetting()
}
Spacer()
if let error {
Text(error.localizedDescription)
.foregroundStyle(.red)
.controlSize(.small)
}
}
.padding(.bottom)
InsertionFormatView(text: $format, count: self.selection.count, insertionVariables: Snippet.Variable.allCases, tokenizer: Snippet.Variable.tokenizer)
}
.onAppear {
self.items = SnippetManager.shared.snippets
if let item = self.items.first {
self.selection = [item.id]
}
}
.onChange(of: self.items) { (_, newValue) in
SnippetManager.shared.save(newValue)
}
}
}

View File

@ -1,397 +0,0 @@
//
// SnippetsViewController.swift
//
// CotEditor
// https://coteditor.com
//
// Created by 1024jp on 2023-02-01.
//
// ---------------------------------------------------------------------------
//
// © 2023-2024 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import AppKit
/// Column identifiers for table view.
private extension NSUserInterfaceItemIdentifier {
static let scope = NSUserInterfaceItemIdentifier("scope")
static let name = NSUserInterfaceItemIdentifier("name")
static let key = NSUserInterfaceItemIdentifier("key")
}
private extension NSPasteboard.PasteboardType {
static let rows = NSPasteboard.PasteboardType("rows")
}
final class SnippetsViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate, NSTextViewDelegate {
// MARK: Private Properties
private var snippets: [Snippet] = []
@objc private dynamic var warningMessage: String? // for binding
@IBOutlet private weak var tableView: NSTableView?
@IBOutlet private weak var addRemoveButton: NSSegmentedControl?
@IBOutlet private weak var formatTextView: TokenTextView?
@IBOutlet private weak var variableInsertionMenu: NSPopUpButton?
// MARK: View Controller Methods
override func viewDidLoad() {
super.viewDidLoad()
// setup variable menu
self.variableInsertionMenu!.menu!.items += Snippet.Variable.allCases
.map { $0.insertionMenuItem(target: self.formatTextView) }
// set tokenizer for format text view
self.formatTextView!.tokenizer = Snippet.Variable.tokenizer
}
override func viewWillAppear() {
super.viewWillAppear()
self.snippets = SnippetManager.shared.snippets
self.tableView?.reloadData()
self.selectionDidChange()
self.warningMessage = nil
}
override func viewWillDisappear() {
super.viewWillDisappear()
self.endEditing()
self.saveSetting()
}
// MARK: Table View Data Source
func numberOfRows(in tableView: NSTableView) -> Int {
self.snippets.count
}
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
guard let identifier = tableColumn?.identifier else { return nil }
let snippet = self.snippets[row]
switch identifier {
case .scope:
return snippet.scope
case .name:
return snippet.name
case .key:
return snippet.shortcut
default:
preconditionFailure()
}
}
/// Starts dragging.
func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool {
// register dragged type
tableView.registerForDraggedTypes([.rows])
pboard.declareTypes([.rows], owner: self)
// store row index info to pasteboard
guard let rows = try? NSKeyedArchiver.archivedData(withRootObject: rowIndexes, requiringSecureCoding: true) else { return false }
pboard.setData(rows, forType: .rows)
return true
}
/// Validates when dragged items come into tableView.
func tableView(_ tableView: NSTableView, validateDrop info: any NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
// accept only self drag-and-drop
guard info.draggingSource as? NSTableView == tableView else { return [] }
if dropOperation == .on {
tableView.setDropRow(row, dropOperation: .above)
}
return .move
}
/// Checks acceptability of dragged items and insert them to table.
func tableView(_ tableView: NSTableView, acceptDrop info: any NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
// accept only self drag-and-drop
guard info.draggingSource as? NSTableView == tableView else { return false }
// obtain original rows from paste board
guard
let data = info.draggingPasteboard.data(forType: .rows),
let sourceRows = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSIndexSet.self, from: data) as IndexSet?
else { return false }
// move
self.snippets.move(fromOffsets: sourceRows, toOffset: row)
tableView.moveRows(at: sourceRows, to: row)
self.saveSetting()
return true
}
// MARK: Table View Delegate
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
guard
let identifier = tableColumn?.identifier,
let cellView = tableView.makeView(withIdentifier: identifier, owner: self) as? NSTableCellView
else { return nil }
let snippet = self.snippets[row]
switch identifier {
case .scope:
guard let menu = cellView.subviews.first as? NSPopUpButton else { assertionFailure(); return nil }
// reset attributed string for "All" item
// -> Otherwise, the title isn't localized.
let allItem = menu.itemArray.first!
allItem.attributedTitle = NSAttributedString(string: allItem.title, attributes: allItem.attributedTitle!.attributes(at: 0, effectiveRange: nil))
// add syntaxes
for settingName in SyntaxManager.shared.settingNames {
menu.addItem(withTitle: settingName)
menu.lastItem!.representedObject = settingName
}
// select item
if let scope = snippet.scope {
menu.selectItem(withTitle: scope)
} else {
if let emptyItem = menu.itemArray.first(where: { !$0.isSeparatorItem && $0.title.isEmpty }) {
menu.menu?.removeItem(emptyItem)
}
menu.selectItem(at: 0)
}
default:
break
}
return cellView
}
/// Invoked when the selection in the table did change.
func tableViewSelectionDidChange(_ notification: Notification) {
self.selectionDidChange()
}
// MARK: Text View Delegate (format text view)
/// Invoked when the insertion text did update.
func textDidEndEditing(_ notification: Notification) {
guard
let textView = notification.object as? NSTextView,
let tableView = self.tableView,
tableView.selectedRowIndexes.count == 1
else { return }
self.snippets[tableView.selectedRow].format = textView.string
self.saveSetting()
}
// MARK: Actions
@IBAction func addRemove(_ sender: NSSegmentedControl) {
self.endEditing()
guard let rows = self.tableView?.selectedRowIndexes else { return }
switch sender.selectedSegment {
case 0: // add
let snippet = SnippetManager.shared.createUntitledSetting()
let row = rows.last.flatMap { $0 + 1 } ?? self.snippets.endIndex
self.snippets.insert(snippet, at: row)
self.tableView?.insertRows(at: [row], withAnimation: .effectGap)
case 1: // remove
guard !rows.isEmpty else { return }
self.snippets.remove(in: rows)
self.tableView?.removeRows(at: rows, withAnimation: [.slideUp, .effectFade])
default:
preconditionFailure()
}
self.saveSetting()
}
@IBAction func didSelectSyntax(_ sender: NSPopUpButton) {
guard let tableView = self.tableView else { return assertionFailure() }
let row = tableView.row(for: sender)
let column = tableView.column(for: sender)
guard row >= 0, column >= 0 else { return }
self.snippets[row].scope = sender.selectedItem?.representedObject as? String
self.saveSetting()
tableView.reloadData(forRowIndexes: [row], columnIndexes: [column])
}
@IBAction func didEditName(_ sender: NSTextField) {
guard let tableView = self.tableView else { return assertionFailure() }
let row = tableView.row(for: sender)
let column = tableView.column(for: sender)
guard row >= 0, column >= 0 else { return }
// successfully update data
self.snippets[row].name = sender.stringValue
self.saveSetting()
tableView.reloadData(forRowIndexes: [row], columnIndexes: [column])
}
/// Validates and applies the new shortcut key input.
@IBAction func didEditShortcut(_ sender: ShortcutTextField) {
guard let tableView = self.tableView else { return assertionFailure() }
let row = tableView.row(for: sender)
let column = tableView.column(for: sender)
let oldShortcut = self.snippets[row].shortcut
let shortcut = sender.objectValue as? Shortcut
// reset once warning
self.warningMessage = nil
// not edited
guard shortcut != oldShortcut else { return }
if let shortcut {
do {
try shortcut.checkCustomizationAvailability()
} catch {
self.warningMessage = error.localizedDescription
sender.objectValue = oldShortcut // reset text field
NSSound.beep()
// make text field edit mode again
Task {
tableView.editColumn(column, row: row, with: nil, select: true)
}
return
}
}
// successfully update data
self.snippets[row].shortcut = shortcut
self.saveSetting()
tableView.reloadData(forRowIndexes: [row], columnIndexes: [column])
}
// MARK: Private Methods
/// Saves current setting.
private func saveSetting() {
SnippetManager.shared.save(self.snippets)
}
/// Updates controls according to the state of selection in the table view.
private func selectionDidChange() {
guard
let tableView = self.tableView,
let textView = self.formatTextView
else { return assertionFailure() }
if tableView.selectedRowIndexes.count == 1 {
textView.isEditable = true
textView.textColor = .textColor
textView.string = self.snippets[tableView.selectedRow].format
} else {
textView.isEditable = false
textView.textColor = .disabledControlTextColor
textView.string = String(localized: "Select a snippet to edit.", table: "SnippetsSettings", comment: "placeholder for insertion format field")
}
self.addRemoveButton?.setEnabled(!tableView.selectedRowIndexes.isEmpty, forSegment: 1)
}
}
private extension NSTableView {
/// Moves the specified rows to the new row location using animation.
///
/// - Parameters:
/// - oldIndexes: Initial row indexes.
/// - newIndex: Row index to insert all specified rows.
func moveRows(at oldIndexes: IndexSet, to newIndex: Int) {
var oldOffset = 0
var newOffset = 0
self.beginUpdates()
for oldIndex in oldIndexes {
if oldIndex < newIndex {
self.moveRow(at: oldIndex + oldOffset, to: newIndex - 1)
oldOffset -= 1
} else {
self.moveRow(at: oldIndex, to: newIndex + newOffset)
newOffset += 1
}
}
self.endUpdates()
}
}

View File

@ -223,33 +223,6 @@ final class TokenTextView: NSTextView {
extension TokenRepresentable {
/// Returns a menu item to insert variable to TokenTextView.
///
/// - Parameter target: The action target.
/// - Returns: A menu item.
func insertionMenuItem(target: TokenTextView? = nil) -> NSMenuItem {
let font = NSFont.menuFont(ofSize: NSFont.systemFontSize(for: .small))
let token = NSAttributedString(string: self.token, attributes: [.font: font])
let description = NSAttributedString(string: self.localizedDescription,
attributes: [.font: font,
.foregroundColor: NSColor.secondaryLabelColor])
let item = NSMenuItem()
item.target = target
item.action = #selector(TokenTextView.insertVariable)
item.attributedTitle = [token, description].joined(separator: "\n")
item.representedObject = self.token
return item
}
}
private extension NSColor {
static let tokenTextColor = NSColor(name: nil) { appearance in

View File

@ -1,846 +0,0 @@
{
"sourceLanguage" : "en",
"strings" : {
"cMF-G3-bl6.headerCell.title" : {
"comment" : "Class = \"NSTableColumn\"; headerCell.title = \"Name\"; ObjectID = \"cMF-G3-bl6\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Název"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Name"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Name"
}
},
"en-GB" : {
"stringUnit" : {
"state" : "translated",
"value" : "Name"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nombre"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nom"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nome"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "名前"
}
},
"nl" : {
"stringUnit" : {
"state" : "translated",
"value" : "Naam"
}
},
"pt" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nome"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ad"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "名字"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "名稱"
}
}
}
},
"Jku-3h-OhR.title" : {
"comment" : "Class = \"NSViewController\"; title = \"Command\"; ObjectID = \"Jku-3h-OhR\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Příkaz"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Befehl"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Command"
}
},
"en-GB" : {
"stringUnit" : {
"state" : "translated",
"value" : "Command"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Comando"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commande"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Comando"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "コマンド"
}
},
"nl" : {
"stringUnit" : {
"state" : "translated",
"value" : "Commando"
}
},
"pt" : {
"stringUnit" : {
"state" : "translated",
"value" : "Comando"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Komut"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "命令"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "指令"
}
}
}
},
"PaR-eN-FFs.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"Insertion format:\"; ObjectID = \"PaR-eN-FFs\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formát vložení:"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Format des einzufügenden Textes:"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Insertion format:"
}
},
"en-GB" : {
"stringUnit" : {
"state" : "translated",
"value" : "Insertion format:"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Insertar formato:"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Texte à insérer :"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato di inserimento:"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "挿入フォーマット:"
}
},
"nl" : {
"stringUnit" : {
"state" : "translated",
"value" : "Invoegformaat:"
}
},
"pt" : {
"stringUnit" : {
"state" : "translated",
"value" : "Formato da inserção:"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ekleme biçimi:"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "按格式插入:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "按格式插入:"
}
}
}
},
"pbJ-4Q-CE2.headerCell.title" : {
"comment" : "Class = \"NSTableColumn\"; headerCell.title = \"Syntax\"; ObjectID = \"pbJ-4Q-CE2\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Syntaxe"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Syntax"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Syntax"
}
},
"en-GB" : {
"stringUnit" : {
"state" : "translated",
"value" : "Syntax"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sintaxis"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Syntaxe"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sintassi"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "シンタックス"
}
},
"nl" : {
"stringUnit" : {
"state" : "translated",
"value" : "Syntaxis"
}
},
"pt" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sintaxe"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sözdizim"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "语法"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "文法定義"
}
}
}
},
"rUw-Mw-hR2.title" : {
"comment" : "Class = \"NSTextFieldCell\"; title = \"SHORTCUT WARNING MESSAGE\"; ObjectID = \"rUw-Mw-hR2\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "SHORTCUT WARNING MESSAGE"
}
},
"en-GB" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"nl" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"pt" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
}
}
},
"t2r-oN-Xpf.ibShadowedToolTips[0]" : {
"comment" : "Class = \"NSSegmentedCell\"; t2r-oN-Xpf.ibShadowedToolTips[0] = \"Add\"; ObjectID = \"t2r-oN-Xpf\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Přidat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hinzufügen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Add"
}
},
"en-GB" : {
"stringUnit" : {
"state" : "translated",
"value" : "Add"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Añadir"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nouveau"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Aggiungi"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "追加"
}
},
"nl" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voeg toe"
}
},
"pt" : {
"stringUnit" : {
"state" : "translated",
"value" : "Adicione"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ekle"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "添加"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "新增"
}
}
}
},
"t2r-oN-Xpf.ibShadowedToolTips[1]" : {
"comment" : "Class = \"NSSegmentedCell\"; t2r-oN-Xpf.ibShadowedToolTips[1] = \"Delete\"; ObjectID = \"t2r-oN-Xpf\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Odebrat"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Löschen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Delete"
}
},
"en-GB" : {
"stringUnit" : {
"state" : "translated",
"value" : "Delete"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Borrar"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Supprimer"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rimuovi"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "削除"
}
},
"nl" : {
"stringUnit" : {
"state" : "translated",
"value" : "Verwijder"
}
},
"pt" : {
"stringUnit" : {
"state" : "translated",
"value" : "Apague"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sil"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "删除"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "刪除"
}
}
}
},
"vOg-Tt-3ZZ.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"Insert Variable\"; ObjectID = \"vOg-Tt-3ZZ\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vložit proměnnou"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Variable hinzufügen"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Insert Variable"
}
},
"en-GB" : {
"stringUnit" : {
"state" : "translated",
"value" : "Insert Variable"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Insertar variable"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Insérer une variable"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inserisci Variabile"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "変数を挿入"
}
},
"nl" : {
"stringUnit" : {
"state" : "translated",
"value" : "Voeg variabele in"
}
},
"pt" : {
"stringUnit" : {
"state" : "translated",
"value" : "Inserir Variável"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Değişken Ekle"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "插入变量"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "插入變數"
}
}
}
},
"vXM-oG-cI7.title" : {
"comment" : "Class = \"NSMenuItem\"; title = \"All\"; ObjectID = \"vXM-oG-cI7\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vše"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alle"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "All"
}
},
"en-GB" : {
"stringUnit" : {
"state" : "translated",
"value" : "All"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Todo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Toutes"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tutti"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "すべて"
}
},
"nl" : {
"stringUnit" : {
"state" : "translated",
"value" : "Alles"
}
},
"pt" : {
"stringUnit" : {
"state" : "translated",
"value" : "Todas"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tümü"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "全部"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "全部"
}
}
}
},
"wer-OB-X46.headerCell.title" : {
"comment" : "Class = \"NSTableColumn\"; headerCell.title = \"Key\"; ObjectID = \"wer-OB-X46\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"cs" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zkratka"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Taste"
}
},
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Key"
}
},
"en-GB" : {
"stringUnit" : {
"state" : "translated",
"value" : "Key"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Teclas"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Raccourci"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tasto"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "キー"
}
},
"nl" : {
"stringUnit" : {
"state" : "translated",
"value" : "Sleutel"
}
},
"pt" : {
"stringUnit" : {
"state" : "translated",
"value" : "Teclas"
}
},
"tr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Düğme"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "按键"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "按鍵"
}
}
}
}
},
"version" : "1.0"
}