Using new KeePassKit API, simple multi selection support

This commit is contained in:
michael starke
2016-02-25 18:41:50 +01:00
parent 06c5f4d740
commit eb6e6bcaa9
22 changed files with 213 additions and 247 deletions

View File

@@ -181,7 +181,6 @@
4C89F524182FB4740069C73C /* MPAutotypeCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C89F523182FB4740069C73C /* MPAutotypeCommand.m */; }; 4C89F524182FB4740069C73C /* MPAutotypeCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C89F523182FB4740069C73C /* MPAutotypeCommand.m */; };
4C8B36AB17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8B36AA17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m */; }; 4C8B36AB17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8B36AA17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m */; };
4C8DEAA21C314D2C00D24C32 /* MPTestAutotypeDelay.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8DEAA11C314D2C00D24C32 /* MPTestAutotypeDelay.m */; }; 4C8DEAA21C314D2C00D24C32 /* MPTestAutotypeDelay.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8DEAA11C314D2C00D24C32 /* MPTestAutotypeDelay.m */; };
4C94A0721938DDC20040ABAB /* MPDocument+EditingSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C94A0711938DDC20040ABAB /* MPDocument+EditingSession.m */; };
4C978E0D19AE54AB003067DF /* MPFlagsHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C978E0C19AE54AB003067DF /* MPFlagsHelper.m */; }; 4C978E0D19AE54AB003067DF /* MPFlagsHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C978E0C19AE54AB003067DF /* MPFlagsHelper.m */; };
4CA08DA017A831B200A6544B /* MPAddEntryContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CA08D9F17A831B200A6544B /* MPAddEntryContextMenuDelegate.m */; }; 4CA08DA017A831B200A6544B /* MPAddEntryContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CA08D9F17A831B200A6544B /* MPAddEntryContextMenuDelegate.m */; };
4CA0B2ED15BCADAC00654E32 /* SettingsWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4CA0B2EC15BCADAC00654E32 /* SettingsWindow.xib */; }; 4CA0B2ED15BCADAC00654E32 /* SettingsWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4CA0B2EC15BCADAC00654E32 /* SettingsWindow.xib */; };
@@ -563,7 +562,6 @@
4C8B36A917A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOutlineContextMenuDelegate.h; sourceTree = "<group>"; }; 4C8B36A917A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOutlineContextMenuDelegate.h; sourceTree = "<group>"; };
4C8B36AA17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOutlineContextMenuDelegate.m; sourceTree = "<group>"; }; 4C8B36AA17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOutlineContextMenuDelegate.m; sourceTree = "<group>"; };
4C8DEAA11C314D2C00D24C32 /* MPTestAutotypeDelay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTestAutotypeDelay.m; sourceTree = "<group>"; }; 4C8DEAA11C314D2C00D24C32 /* MPTestAutotypeDelay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTestAutotypeDelay.m; sourceTree = "<group>"; };
4C94A0711938DDC20040ABAB /* MPDocument+EditingSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPDocument+EditingSession.m"; sourceTree = "<group>"; };
4C978E0C19AE54AB003067DF /* MPFlagsHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPFlagsHelper.m; sourceTree = "<group>"; }; 4C978E0C19AE54AB003067DF /* MPFlagsHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPFlagsHelper.m; sourceTree = "<group>"; };
4CA08D9E17A831B200A6544B /* MPAddEntryContextMenuDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAddEntryContextMenuDelegate.h; sourceTree = "<group>"; }; 4CA08D9E17A831B200A6544B /* MPAddEntryContextMenuDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAddEntryContextMenuDelegate.h; sourceTree = "<group>"; };
4CA08D9F17A831B200A6544B /* MPAddEntryContextMenuDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAddEntryContextMenuDelegate.m; sourceTree = "<group>"; }; 4CA08D9F17A831B200A6544B /* MPAddEntryContextMenuDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAddEntryContextMenuDelegate.m; sourceTree = "<group>"; };
@@ -959,7 +957,6 @@
4C1FA07A18231900003A3F8C /* MPDocument+Autotype.m */, 4C1FA07A18231900003A3F8C /* MPDocument+Autotype.m */,
4C15B74518BCA3B1003F8008 /* MPDocument+Search.m */, 4C15B74518BCA3B1003F8008 /* MPDocument+Search.m */,
4C6B7C7C18BE7EB0001D5D77 /* MPDocument+HistoryBrowsing.m */, 4C6B7C7C18BE7EB0001D5D77 /* MPDocument+HistoryBrowsing.m */,
4C94A0711938DDC20040ABAB /* MPDocument+EditingSession.m */,
4C0AF62D195C1F2B009E658D /* MPEntrySearchContext.h */, 4C0AF62D195C1F2B009E658D /* MPEntrySearchContext.h */,
4C0AF62E195C1F2B009E658D /* MPEntrySearchContext.m */, 4C0AF62E195C1F2B009E658D /* MPEntrySearchContext.m */,
); );
@@ -1706,7 +1703,6 @@
4C7B63711C0CB51F00D7038C /* NSValueTransformer+TransformerKit.m in Sources */, 4C7B63711C0CB51F00D7038C /* NSValueTransformer+TransformerKit.m in Sources */,
4CD034AA1BFE113B003C002C /* MPPlugin.m in Sources */, 4CD034AA1BFE113B003C002C /* MPPlugin.m in Sources */,
4CA2335A176DBFE100F0B6AC /* MPLockDaemon.m in Sources */, 4CA2335A176DBFE100F0B6AC /* MPLockDaemon.m in Sources */,
4C94A0721938DDC20040ABAB /* MPDocument+EditingSession.m in Sources */,
4C77C84118E240E000D1C42B /* DDHotKey+MacPassAdditions.m in Sources */, 4C77C84118E240E000D1C42B /* DDHotKey+MacPassAdditions.m in Sources */,
4C89B71019B4B4A300DC0A6A /* MPTreeDelegate.m in Sources */, 4C89B71019B4B4A300DC0A6A /* MPTreeDelegate.m in Sources */,
4C88C66918D9F8D600F43852 /* MPTemporaryFileStorageCenter.m in Sources */, 4C88C66918D9F8D600F43852 /* MPTemporaryFileStorageCenter.m in Sources */,

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES"> <document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9532" systemVersion="15D21" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies> <dependencies>
<deployment identifier="macosx"/> <deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9060"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9532"/>
</dependencies> </dependencies>
<objects> <objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPInspectorViewController"> <customObject id="-2" userLabel="File's Owner" customClass="MPInspectorViewController">
@@ -27,10 +27,9 @@
<customView translatesAutoresizingMaskIntoConstraints="NO" id="2930" customClass="HNHUIGradientView"> <customView translatesAutoresizingMaskIntoConstraints="NO" id="2930" customClass="HNHUIGradientView">
<rect key="frame" x="0.0" y="0.0" width="278" height="30"/> <rect key="frame" x="0.0" y="0.0" width="278" height="30"/>
<subviews> <subviews>
<button hidden="YES" verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3109"> <button verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3109">
<rect key="frame" x="219" y="2" width="39" height="25"/> <rect key="frame" x="219" y="2" width="39" height="25"/>
<animations/> <buttonCell key="cell" type="roundTextured" title="Edit" bezelStyle="texturedRounded" imagePosition="left" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="3110">
<buttonCell key="cell" type="roundTextured" title="Edit" bezelStyle="texturedRounded" imagePosition="left" alignment="center" enabled="NO" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="3110">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
@@ -38,10 +37,9 @@
<action selector="beginEditingSelectedItem:" target="-1" id="DRJ-M6-PkP"/> <action selector="beginEditingSelectedItem:" target="-1" id="DRJ-M6-PkP"/>
</connections> </connections>
</button> </button>
<button hidden="YES" verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3126"> <button verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3126">
<rect key="frame" x="154" y="2" width="57" height="25"/> <rect key="frame" x="154" y="2" width="57" height="25"/>
<animations/> <buttonCell key="cell" type="roundTextured" title="Cancel" bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="3127">
<buttonCell key="cell" type="roundTextured" title="Cancel" bezelStyle="texturedRounded" alignment="center" enabled="NO" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="3127">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
@@ -51,7 +49,6 @@
</button> </button>
<button hidden="YES" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jBD-3D-knW"> <button hidden="YES" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jBD-3D-knW">
<rect key="frame" x="20" y="2" width="59" height="25"/> <rect key="frame" x="20" y="2" width="59" height="25"/>
<animations/>
<buttonCell key="cell" type="roundTextured" title="History" bezelStyle="texturedRounded" alignment="center" enabled="NO" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="w1z-1n-b0m"> <buttonCell key="cell" type="roundTextured" title="History" bezelStyle="texturedRounded" alignment="center" enabled="NO" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="w1z-1n-b0m">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -68,7 +65,6 @@
<constraint firstItem="3109" firstAttribute="centerY" secondItem="2930" secondAttribute="centerY" id="3139"/> <constraint firstItem="3109" firstAttribute="centerY" secondItem="2930" secondAttribute="centerY" id="3139"/>
<constraint firstItem="3109" firstAttribute="leading" secondItem="3126" secondAttribute="trailing" constant="8" symbolic="YES" id="3140"/> <constraint firstItem="3109" firstAttribute="leading" secondItem="3126" secondAttribute="trailing" constant="8" symbolic="YES" id="3140"/>
</constraints> </constraints>
<animations/>
</customView> </customView>
<imageView translatesAutoresizingMaskIntoConstraints="NO" id="2998" customClass="MPPopupImageView"> <imageView translatesAutoresizingMaskIntoConstraints="NO" id="2998" customClass="MPPopupImageView">
<rect key="frame" x="20" y="620" width="32" height="32"/> <rect key="frame" x="20" y="620" width="32" height="32"/>
@@ -76,7 +72,6 @@
<constraint firstAttribute="width" constant="32" id="3027"/> <constraint firstAttribute="width" constant="32" id="3027"/>
<constraint firstAttribute="height" constant="32" id="3028"/> <constraint firstAttribute="height" constant="32" id="3028"/>
</constraints> </constraints>
<animations/>
<imageCell key="cell" alignment="left" imageScaling="proportionallyUpOrDown" image="NSActionTemplate" id="2999"/> <imageCell key="cell" alignment="left" imageScaling="proportionallyUpOrDown" image="NSActionTemplate" id="2999"/>
<connections> <connections>
<action selector="pickIcon:" target="-2" id="6wh-Ka-Thl"/> <action selector="pickIcon:" target="-2" id="6wh-Ka-Thl"/>
@@ -84,7 +79,6 @@
</imageView> </imageView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="3013"> <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="3013">
<rect key="frame" x="58" y="628" width="202" height="17"/> <rect key="frame" x="58" y="628" width="202" height="17"/>
<animations/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" truncatesLastVisibleLine="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Label" usesSingleLineMode="YES" id="3014"> <textFieldCell key="cell" lineBreakMode="truncatingTail" truncatesLastVisibleLine="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Label" usesSingleLineMode="YES" id="3014">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -100,21 +94,18 @@
<subviews> <subviews>
<tabView type="noTabsNoBorder" initialItem="2896" translatesAutoresizingMaskIntoConstraints="NO" id="2895"> <tabView type="noTabsNoBorder" initialItem="2896" translatesAutoresizingMaskIntoConstraints="NO" id="2895">
<rect key="frame" x="0.0" y="0.0" width="278" height="370"/> <rect key="frame" x="0.0" y="0.0" width="278" height="370"/>
<animations/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<tabViewItems> <tabViewItems>
<tabViewItem label="Entry" identifier="2" id="2897"> <tabViewItem label="Entry" identifier="2" id="2897">
<view key="view" id="2898"> <view key="view" id="2898">
<rect key="frame" x="0.0" y="0.0" width="278" height="370"/> <rect key="frame" x="0.0" y="0.0" width="278" height="370"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<animations/>
</view> </view>
</tabViewItem> </tabViewItem>
<tabViewItem label="Group" identifier="1" id="2896"> <tabViewItem label="Group" identifier="1" id="2896">
<view key="view" id="2899"> <view key="view" id="2899">
<rect key="frame" x="0.0" y="0.0" width="278" height="370"/> <rect key="frame" x="0.0" y="0.0" width="278" height="370"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<animations/>
</view> </view>
</tabViewItem> </tabViewItem>
<tabViewItem label="NoSelection" identifier="" id="2974"> <tabViewItem label="NoSelection" identifier="" id="2974">
@@ -124,7 +115,6 @@
<subviews> <subviews>
<textField verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2985"> <textField verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2985">
<rect key="frame" x="80" y="194" width="119" height="24"/> <rect key="frame" x="80" y="194" width="119" height="24"/>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="No Selection" id="2986"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="No Selection" id="2986">
<font key="font" metaFont="system" size="20"/> <font key="font" metaFont="system" size="20"/>
<color key="textColor" name="controlShadowColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlShadowColor" catalog="System" colorSpace="catalog"/>
@@ -136,7 +126,6 @@
<constraint firstAttribute="centerY" secondItem="2985" secondAttribute="centerY" constant="20.5" id="TSQ-BR-XdP"/> <constraint firstAttribute="centerY" secondItem="2985" secondAttribute="centerY" constant="20.5" id="TSQ-BR-XdP"/>
<constraint firstAttribute="centerX" secondItem="2985" secondAttribute="centerX" constant="-0.5" id="UAO-rN-hO7"/> <constraint firstAttribute="centerX" secondItem="2985" secondAttribute="centerX" constant="-0.5" id="UAO-rN-hO7"/>
</constraints> </constraints>
<animations/>
</view> </view>
</tabViewItem> </tabViewItem>
</tabViewItems> </tabViewItems>
@@ -149,7 +138,6 @@
<constraint firstAttribute="bottom" secondItem="2895" secondAttribute="bottom" id="3165"/> <constraint firstAttribute="bottom" secondItem="2895" secondAttribute="bottom" id="3165"/>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="100" id="qtg-Fq-2nL"/> <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="100" id="qtg-Fq-2nL"/>
</constraints> </constraints>
<animations/>
</customView> </customView>
<customView id="3147"> <customView id="3147">
<rect key="frame" x="0.0" y="371" width="278" height="211"/> <rect key="frame" x="0.0" y="371" width="278" height="211"/>
@@ -157,7 +145,6 @@
<subviews> <subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="PzR-P9-3al"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="PzR-P9-3al">
<rect key="frame" x="18" y="192" width="36" height="14"/> <rect key="frame" x="18" y="192" width="36" height="14"/>
<animations/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Notes" id="hwn-UY-9Cr"> <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Notes" id="hwn-UY-9Cr">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
@@ -173,7 +160,6 @@
<textView importsGraphics="NO" richText="NO" allowsUndo="YES" verticallyResizable="YES" allowsNonContiguousLayout="YES" smartInsertDelete="YES" id="g24-gQ-foD"> <textView importsGraphics="NO" richText="NO" allowsUndo="YES" verticallyResizable="YES" allowsNonContiguousLayout="YES" smartInsertDelete="YES" id="g24-gQ-foD">
<rect key="frame" x="0.0" y="0.0" width="236" height="177"/> <rect key="frame" x="0.0" y="0.0" width="236" height="177"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<size key="minSize" width="236" height="177"/> <size key="minSize" width="236" height="177"/>
<size key="maxSize" width="463" height="10000000"/> <size key="maxSize" width="463" height="10000000"/>
@@ -182,19 +168,15 @@
<size key="maxSize" width="463" height="10000000"/> <size key="maxSize" width="463" height="10000000"/>
</textView> </textView>
</subviews> </subviews>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</clipView> </clipView>
<animations/>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="YES" id="ozT-Yy-2vu"> <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="YES" id="ozT-Yy-2vu">
<rect key="frame" x="-100" y="-100" width="87" height="18"/> <rect key="frame" x="-100" y="-100" width="87" height="18"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<animations/>
</scroller> </scroller>
<scroller key="verticalScroller" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="Dgu-8Y-sx3"> <scroller key="verticalScroller" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="Dgu-8Y-sx3">
<rect key="frame" x="221" y="1" width="16" height="177"/> <rect key="frame" x="221" y="1" width="16" height="177"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<animations/>
</scroller> </scroller>
</scrollView> </scrollView>
</subviews> </subviews>
@@ -207,10 +189,8 @@
<constraint firstAttribute="trailing" secondItem="0V7-UG-vEA" secondAttribute="trailing" constant="20" symbolic="YES" id="VyI-AI-Rmt"/> <constraint firstAttribute="trailing" secondItem="0V7-UG-vEA" secondAttribute="trailing" constant="20" symbolic="YES" id="VyI-AI-Rmt"/>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="100" id="gZ6-Vo-6rK"/> <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="100" id="gZ6-Vo-6rK"/>
</constraints> </constraints>
<animations/>
</customView> </customView>
</subviews> </subviews>
<animations/>
<holdingPriorities> <holdingPriorities>
<real value="251"/> <real value="251"/>
<real value="249"/> <real value="249"/>
@@ -233,7 +213,6 @@
<constraint firstAttribute="trailing" secondItem="3145" secondAttribute="trailing" id="3154"/> <constraint firstAttribute="trailing" secondItem="3145" secondAttribute="trailing" id="3154"/>
<constraint firstItem="3145" firstAttribute="leading" secondItem="2894" secondAttribute="leading" id="3155"/> <constraint firstItem="3145" firstAttribute="leading" secondItem="2894" secondAttribute="leading" id="3155"/>
</constraints> </constraints>
<animations/>
<point key="canvasLocation" x="268" y="-437"/> <point key="canvasLocation" x="268" y="-437"/>
</customView> </customView>
</objects> </objects>

View File

@@ -23,8 +23,8 @@
<rect key="frame" x="0.0" y="0.0" width="694" height="595"/> <rect key="frame" x="0.0" y="0.0" width="694" height="595"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" multipleSelection="NO" rowSizeStyle="automatic" headerView="676" viewBased="YES" id="55" customClass="MPTableView"> <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" typeSelect="NO" rowSizeStyle="automatic" headerView="676" viewBased="YES" id="55" customClass="MPTableView">
<rect key="frame" x="0.0" y="0.0" width="694" height="572"/> <rect key="frame" x="0.0" y="0.0" width="695" height="572"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/> <size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@@ -190,7 +190,7 @@
</tableCellView> </tableCellView>
</prototypeCellViews> </prototypeCellViews>
</tableColumn> </tableColumn>
<tableColumn width="198" minWidth="10" maxWidth="3.4028234663852886e+38" id="614"> <tableColumn width="199" minWidth="10" maxWidth="3.4028234663852886e+38" id="614">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left"> <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@@ -204,10 +204,10 @@
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/> <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews> <prototypeCellViews>
<tableCellView id="616"> <tableCellView id="616">
<rect key="frame" x="494" y="1" width="198" height="17"/> <rect key="frame" x="494" y="1" width="199" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="617"> <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="617">
<rect key="frame" x="1" y="0.0" width="196" height="17"/> <rect key="frame" x="1" y="0.0" width="196" height="17"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="618"> <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="618">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@@ -232,8 +232,8 @@
</subviews> </subviews>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</clipView> </clipView>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="56"> <scroller key="horizontalScroller" verticalHuggingPriority="750" horizontal="YES" id="56">
<rect key="frame" x="0.0" y="549" width="694" height="16"/> <rect key="frame" x="0.0" y="579" width="694" height="16"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</scroller> </scroller>
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="58"> <scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="58">
@@ -241,7 +241,7 @@
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</scroller> </scroller>
<tableHeaderView key="headerView" id="676"> <tableHeaderView key="headerView" id="676">
<rect key="frame" x="0.0" y="0.0" width="694" height="23"/> <rect key="frame" x="0.0" y="0.0" width="695" height="23"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</tableHeaderView> </tableHeaderView>
</scrollView> </scrollView>

View File

@@ -48,12 +48,11 @@
} }
- (BOOL)tableView:(NSTableView *)tableView acceptDrop:(id<NSDraggingInfo>)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)dropOperation { - (BOOL)tableView:(NSTableView *)tableView acceptDrop:(id<NSDraggingInfo>)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)dropOperation {
MPDocument *document = [[[tableView window] windowController] document]; MPDocument *document = tableView.window.windowController.document;
id entry = document.selectedEntry; KPKEntry *entry = document.selectedEntries.count == 1 ? document.selectedEntries.lastObject : nil;
NSPasteboard *draggingPasteBoard = [info draggingPasteboard]; NSPasteboard *draggingPasteBoard = [info draggingPasteboard];
NSArray *classArray = [NSArray arrayWithObject:[NSURL class]]; NSArray *arrayOfURLs = [draggingPasteBoard readObjectsForClasses:@[[NSArray class]] options:nil];
NSArray *arrayOfURLs = [draggingPasteBoard readObjectsForClasses:classArray options:nil];
for(NSURL *fileUrl in arrayOfURLs) { for(NSURL *fileUrl in arrayOfURLs) {
[document addAttachment:fileUrl toEntry:entry]; [document addAttachment:fileUrl toEntry:entry];

View File

@@ -33,16 +33,14 @@
@implementation MPAttachmentTableViewDelegate @implementation MPAttachmentTableViewDelegate
- (void)tableViewSelectionDidChange:(NSNotification *)notification { - (void)tableViewSelectionDidChange:(NSNotification *)notification {
NSTableView *tableView = [notification object]; NSTableView *tableView = notification.object;
MPDocument *document = [[[tableView window] windowController] document]; NSIndexSet *allColumns = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, tableView.numberOfColumns)];
NSIndexSet *allColumns = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [[tableView tableColumns] count])]; NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, tableView.numberOfRows )];
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [document.selectedEntry.binaries count] )];
[tableView reloadDataForRowIndexes:indexSet columnIndexes:allColumns]; [tableView reloadDataForRowIndexes:indexSet columnIndexes:allColumns];
} }
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
/* Decide what view to use */ /* Decide what view to use */
MPDocument *document = [[[tableView window] windowController] document];
NSIndexSet *selectedIndexes = [tableView selectedRowIndexes]; NSIndexSet *selectedIndexes = [tableView selectedRowIndexes];
NSTableCellView *view; NSTableCellView *view;
if([selectedIndexes containsIndex:row]) { if([selectedIndexes containsIndex:row]) {
@@ -54,11 +52,10 @@
view = [tableView makeViewWithIdentifier:@"NormalCell" owner:tableView]; view = [tableView makeViewWithIdentifier:@"NormalCell" owner:tableView];
} }
/* Bind view */ /* Bind view */
KPKEntry *entry = document.selectedEntry; KPKBinary *binary = view.objectValue;
NSAssert([entry.binaries count] > row, @"Indes needs to be valid for binaries"); NSString *nameKeyPath = [NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(objectValue)), NSStringFromSelector(@selector(name))];
KPKBinary *binary = entry.binaries[row]; [view.textField bind:NSValueBinding toObject:view withKeyPath:nameKeyPath options:nil];
[[view textField] bind:NSValueBinding toObject:binary withKeyPath:@"name" options:nil]; view.imageView.image = [[NSWorkspace sharedWorkspace] iconForFileType:binary.name.pathExtension];
[[view imageView] setImage:[[NSWorkspace sharedWorkspace] iconForFileType:[binary.name pathExtension]]];
return view; return view;
} }
@@ -73,18 +70,18 @@
NSMenu *menu = [[NSMenu alloc] init]; NSMenu *menu = [[NSMenu alloc] init];
/* Image for Popup button */ /* Image for Popup button */
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"" action:NULL keyEquivalent:@""]; NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"" action:NULL keyEquivalent:@""];
[item setImage:[NSImage imageNamed:NSImageNameActionTemplate]]; item.image = [NSImage imageNamed:NSImageNameActionTemplate];
[menu addItem:item]; [menu addItem:item];
/* Quicklook */ /* Quicklook */
[menu addItemWithTitle:NSLocalizedString(@"PREVIEW", "") action:@selector(toggleQuicklookPreview:) keyEquivalent:@""]; [menu addItemWithTitle:NSLocalizedString(@"PREVIEW", "") action:@selector(toggleQuicklookPreview:) keyEquivalent:@""];
/* Save */ /* Save */
item = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"SAVE", "") action:@selector(saveAttachment:) keyEquivalent:@""]; item = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"SAVE", "") action:@selector(saveAttachment:) keyEquivalent:@""];
[item setTarget:self.viewController]; item.target = self.viewController;
[menu addItem:item]; [menu addItem:item];
/* Remove */ /* Remove */
[menu addItem:[NSMenuItem separatorItem]]; [menu addItem:[NSMenuItem separatorItem]];
item = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"DELETE", "") action:@selector(removeAttachment:) keyEquivalent:@""]; item = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"DELETE", "") action:@selector(removeAttachment:) keyEquivalent:@""];
[item setTarget:self.viewController]; item.target = self.viewController;
[menu addItem:item]; [menu addItem:item];
return menu; return menu;

View File

@@ -116,7 +116,9 @@ typedef NS_ENUM(NSUInteger, MPContextTab) {
- (void)_didChangeCurrentItem:(NSNotification *)notification { - (void)_didChangeCurrentItem:(NSNotification *)notification {
MPDocument *document = [notification object]; MPDocument *document = [notification object];
BOOL showTrash = document.tree.metaData.useTrash && (document.selectedItem.isTrashed || document.selectedItem.isTrash); KPKNode *node = document.selectedNodes.count == 1 ? document.selectedNodes.firstObject : nil;
BOOL showTrash = document.tree.metaData.useTrash && (node.isTrashed || node.isTrash);
if(showTrash && ! document.hasSearch) { if(showTrash && ! document.hasSearch) {
self.activeTab = MPContextTabTrash; self.activeTab = MPContextTabTrash;
[self _updateBindings]; [self _updateBindings];

View File

@@ -1,55 +0,0 @@
//
// MPDocument+EditingSession.m
// MacPass
//
// Created by Michael Starke on 30/05/14.
// Copyright (c) 2014 HicknHack Software GmbH. All rights reserved.
//
#import "MPDocument.h"
#import "KeePassKit/KeePassKit.h"
NSString *const MPDocumentDidBeginEditingSelectedItem = @"com.hicknhack.macpass.MPDocumentDidBeginEditingSelectedItem";
NSString *const MPDocumentDidCancelChangesToSelectedItem = @"com.hicknhack.macpass.MPDocumentDidCancelChangesToSelectedItem";
NSString *const MPDocumentDidCommitChangesToSelectedItem = @"com.hicknhack.macpass.MPDocumentDidCommitChangesToSelectedItem";
@implementation MPDocument (EditingSession)
- (BOOL)hasActiveEditingSession {
return NO;
}
- (void)commitChangesToSelectedItem:(id)sender {
/* Force any lingering updates to be written */
/* FIXME explore potential usage of:
* NSObject(NSEditorRegistration)
* NSObject(NSEditor)
*/
[((NSWindowController *)self.windowControllers.firstObject).window makeFirstResponder:nil];
/* update the data */
[self.selectedItem commitEditing];
if(self.selectedItem.asEntry) {
[self.undoManager setActionName:NSLocalizedString(@"UPDATE_ENTRY", "")];
}
else if(self.selectedItem.asGroup) {
[self.undoManager setActionName:NSLocalizedString(@"UPDATE_GROUP", "")];
}
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidCommitChangesToSelectedItem object:self];
}
- (void)cancelChangesToSelectedItem:(id)sender {
[self.selectedItem cancelEditing];
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidCancelChangesToSelectedItem object:self];
}
- (void)beginEditingSelectedItem:(id)sender {
if(nil == self.selectedItem) {
return;
}
[self.selectedItem beginEditing];
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidBeginEditingSelectedItem object:self];
}
@end

View File

@@ -14,7 +14,6 @@ NSString *const MPDocumentDidExitHistoryNotification = @"MPDocumentDidExitHisto
@implementation MPDocument (HistoryBrowsing) @implementation MPDocument (HistoryBrowsing)
- (void)showHistory:(id)sender { - (void)showHistory:(id)sender {
NSAssert(self.selectedEntry && self.selectedItem == (id)self.selectedEntry, @"Entry needs to be selected for history browsing!");
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidEnterHistoryNotification object:self]; [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidEnterHistoryNotification object:self];
} }

View File

@@ -53,7 +53,6 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul
dispatch_async(backgroundQueue, ^{ dispatch_async(backgroundQueue, ^{
NSArray *results = [weakSelf _findEntriesMatchingCurrentSearch]; NSArray *results = [weakSelf _findEntriesMatchingCurrentSearch];
dispatch_sync(dispatch_get_main_queue(), ^{ dispatch_sync(dispatch_get_main_queue(), ^{
weakSelf.selectedEntry = nil;
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidChangeSearchResults object:weakSelf userInfo:@{ kMPDocumentSearchResultsKey: results }]; [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidChangeSearchResults object:weakSelf userInfo:@{ kMPDocumentSearchResultsKey: results }];
}); });
}); });

View File

@@ -56,7 +56,6 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey;
@class KPKAttribute; @class KPKAttribute;
@class KPKCompositeKey; @class KPKCompositeKey;
@class KPKNode; @class KPKNode;
@class KPKEditingSession;
@interface MPDocument : NSDocument <MPTargetNodeResolving> @interface MPDocument : NSDocument <MPTargetNodeResolving>
@@ -76,9 +75,15 @@ APPKIT_EXTERN NSString *const MPDocumentGroupKey;
/* /*
State (active group/entry) State (active group/entry)
*/ */
@property (nonatomic, weak) KPKEntry *selectedEntry; //@property (nonatomic, weak) KPKEntry *selectedEntry;
@property (nonatomic, weak) KPKGroup *selectedGroup; //@property (nonatomic, weak) KPKGroup *selectedGroup;
@property (nonatomic, weak) KPKNode *selectedItem; //@property (nonatomic, weak) KPKNode *selectedItem;
@property (nonatomic, copy, readonly) NSArray<KPKNode *> *selectedNodes;
@property (nonatomic, copy) NSArray<KPKGroup *> *selectedGroups;
@property (nonatomic, copy) NSArray<KPKEntry *> *selectedEntries;
/* /*
Search - see MPDocument+Search for further details Search - see MPDocument+Search for further details

View File

@@ -67,6 +67,8 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
@property (nonatomic, strong) NSData *encryptedData; @property (nonatomic, strong) NSData *encryptedData;
@property (nonatomic, strong) MPTreeDelegate *treeDelgate; @property (nonatomic, strong) MPTreeDelegate *treeDelgate;
@property (nonatomic, copy) NSArray<KPKNode *> *selectedNodes;
@property (assign) BOOL readOnly; @property (assign) BOOL readOnly;
@property (strong) NSURL *lockFileURL; @property (strong) NSURL *lockFileURL;
@@ -374,26 +376,6 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
self.tree.trash = trash; self.tree.trash = trash;
} }
- (void)setSelectedGroup:(KPKGroup *)selectedGroup {
if(_selectedGroup != selectedGroup) {
_selectedGroup = selectedGroup;
}
self.selectedItem = _selectedGroup;
}
- (void)setSelectedEntry:(KPKEntry *)selectedEntry {
if(_selectedEntry != selectedEntry) {
_selectedEntry = selectedEntry;
}
self.selectedItem = selectedEntry;
}
- (void)setSelectedItem:(KPKNode *)selectedItem {
if(_selectedItem != selectedItem) {
_selectedItem = selectedItem;
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentCurrentItemChangedNotification object:self];
}
}
- (void)setTree:(KPKTree *)tree { - (void)setTree:(KPKTree *)tree {
if(_tree != tree) { if(_tree != tree) {
_tree = tree; _tree = tree;
@@ -404,6 +386,28 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
} }
} }
#pragma mark -
- (void)setSelectedNodes:(NSArray<KPKNode *> *)selectedNodes {
if(![_selectedNodes isEqualToArray:selectedNodes]) {
_selectedNodes = [selectedNodes copy];
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentCurrentItemChangedNotification object:self];
}
}
- (void)setSelectedGroups:(NSArray<KPKGroup *> *)selectedGroups {
if(![self.selectedGroups isEqualToArray:selectedGroups]) {
_selectedGroups = [selectedGroups copy];
}
self.selectedNodes = self.selectedGroups;
}
- (void)setSelectedEntries:(NSArray<KPKEntry *> *)selectedEntries {
if(![self.selectedEntries isEqualToArray:selectedEntries]) {
_selectedEntries = [selectedEntries copy];
}
self.selectedNodes = self.selectedEntries;
}
#pragma mark Data Accesors #pragma mark Data Accesors
- (KPKEntry *)findEntry:(NSUUID *)uuid { - (KPKEntry *)findEntry:(NSUUID *)uuid {
@@ -451,8 +455,8 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
if(defaultPassword) { if(defaultPassword) {
newEntry.password = defaultPassword; newEntry.password = defaultPassword;
} }
[parent addEntry:newEntry]; [newEntry addToGroup:parent];
[parent.undoManager setActionName:NSLocalizedString(@"ADD_ENTRY", "")]; [newEntry.undoManager setActionName:NSLocalizedString(@"ADD_ENTRY", "")];
NSDictionary *userInfo = @{ MPDocumentEntryKey: newEntry }; NSDictionary *userInfo = @{ MPDocumentEntryKey: newEntry };
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidAddEntryNotification object:self userInfo:userInfo]; [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidAddEntryNotification object:self userInfo:userInfo];
return newEntry; return newEntry;
@@ -468,7 +472,8 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
KPKGroup *newGroup = [self.tree createGroup:parent]; KPKGroup *newGroup = [self.tree createGroup:parent];
newGroup.title = NSLocalizedString(@"DEFAULT_GROUP_NAME", @"Title for a newly created group"); newGroup.title = NSLocalizedString(@"DEFAULT_GROUP_NAME", @"Title for a newly created group");
newGroup.iconId = MPIconFolder; newGroup.iconId = MPIconFolder;
[parent addGroup:newGroup]; [newGroup addToGroup:parent];
[newGroup.undoManager setActionName:NSLocalizedString(@"ADD_GROUP", "")];
NSDictionary *userInfo = @{ MPDocumentGroupKey : newGroup }; NSDictionary *userInfo = @{ MPDocumentGroupKey : newGroup };
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidAddGroupNotification object:self userInfo:userInfo]; [[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidAddGroupNotification object:self userInfo:userInfo];
return newGroup; return newGroup;
@@ -491,19 +496,24 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
[self _presentTrashAlertForItem:node]; [self _presentTrashAlertForItem:node];
return; return;
} }
// if(node.asGroup == self.selectedGroup) {
// self.selectedGroup = node.asGroup;
// }
// if(node.asEntry == self.selectedEntry) {
// self.selectedEntry = node.asEntry;
// }
if(!self.tree.metaData.useTrash) {
/* Display warning about permanently removing items! */
}
[node trashOrRemove]; [node trashOrRemove];
BOOL permanent = (nil == self.trash); BOOL permanent = !node.isTrashed;
if(node.asGroup) { if(node.asGroup) {
[self.undoManager setActionName:permanent ? NSLocalizedString(@"DELETE_GROUP", "Delete Group") : NSLocalizedString(@"TRASH_GROUP", "Move Group to Trash")]; [self.undoManager setActionName:permanent ? NSLocalizedString(@"DELETE_GROUP", "Delete Group") : NSLocalizedString(@"TRASH_GROUP", "Move Group to Trash")];
if(self.selectedGroup == node) {
self.selectedGroup = nil;
}
} }
else if(node.asEntry) { else if(node.asEntry) {
[self.undoManager setActionName:permanent ? NSLocalizedString(@"DELETE_ENTRY", "") : NSLocalizedString(@"TRASH_ENTRY", "Move Entry to Trash")]; [self.undoManager setActionName:permanent ? NSLocalizedString(@"DELETE_ENTRY", "") : NSLocalizedString(@"TRASH_ENTRY", "Move Entry to Trash")];
if(self.selectedEntry == node) {
self.selectedEntry = nil;
}
} }
} }
@@ -554,7 +564,6 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
[node.undoManager removeAllActionsWithTarget:group]; [node.undoManager removeAllActionsWithTarget:group];
} }
[node remove]; [node remove];
[node.undoManager removeAllActionsWithTarget:node];
} }
} }
@@ -569,18 +578,21 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
NSUUID *entryUUID = [sender representedObject]; NSUUID *entryUUID = [sender representedObject];
if(entryUUID) { if(entryUUID) {
KPKEntry *templateEntry = [self findEntry:entryUUID]; KPKEntry *templateEntry = [self findEntry:entryUUID];
if(templateEntry && self.selectedGroup) { KPKGroup *group = self.selectedGroups.count == 1 ? self.selectedGroups.firstObject : nil;
if(templateEntry && group) {
KPKEntry *copy = [templateEntry copyWithTitle:templateEntry.title options:kKPKCopyOptionNone]; KPKEntry *copy = [templateEntry copyWithTitle:templateEntry.title options:kKPKCopyOptionNone];
[self.selectedGroup addEntry:copy]; [copy addToGroup:group];
[self.selectedGroup.undoManager setActionName:NSLocalizedString(@"ADD_TREMPLATE_ENTRY", "")]; [self.undoManager setActionName:NSLocalizedString(@"ADD_TREMPLATE_ENTRY", "")];
} }
} }
} }
- (void)duplicateEntry:(id)sender { - (void)duplicateEntry:(id)sender {
/*
KPKEntry *duplicate = [self.selectedEntry copyWithTitle:nil options:kKPKCopyOptionNone]; KPKEntry *duplicate = [self.selectedEntry copyWithTitle:nil options:kKPKCopyOptionNone];
[self.selectedEntry.parent addEntry:duplicate]; [duplicate addToGroup:self.selectedEntry.parent];
[self.undoManager setActionName:NSLocalizedString(@"DUPLICATE_ENTRY", "")]; [self.undoManager setActionName:NSLocalizedString(@"DUPLICATE_ENTRY", "")];
*/
} }
- (void)duplicateEntryWithOptions:(id)sender { - (void)duplicateEntryWithOptions:(id)sender {
@@ -715,11 +727,12 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
#pragma mark MPTargetNodeResolving #pragma mark MPTargetNodeResolving
- (KPKEntry *)currentTargetEntry { - (KPKEntry *)currentTargetEntry {
return self.selectedEntry; return self.selectedEntries.firstObject;
//return self.selectedEntry;
} }
- (KPKGroup *)currentTargetGroup { - (KPKGroup *)currentTargetGroup {
return self.selectedGroup; return self.selectedGroups.firstObject;
} }
@end @end

View File

@@ -82,10 +82,10 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
- (void)windowDidLoad { - (void)windowDidLoad {
[super windowDidLoad]; [super windowDidLoad];
[[self window] setDelegate:self.documentWindowDelegate]; self.window.delegate = self.documentWindowDelegate;
[[self window] registerForDraggedTypes:@[NSURLPboardType]]; [self.window registerForDraggedTypes:@[NSURLPboardType]];
MPDocument *document = [self document]; MPDocument *document = self.document;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didRevertDocument:) name:MPDocumentDidRevertNotifiation object:document]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didRevertDocument:) name:MPDocumentDidRevertNotifiation object:document];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didUnlockDatabase:) name:MPDocumentDidUnlockDatabaseNotification object:document]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didUnlockDatabase:) name:MPDocumentDidUnlockDatabaseNotification object:document];
@@ -104,7 +104,7 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
self.window.toolbar = self.toolbar; self.window.toolbar = self.toolbar;
self.toolbarDelegate.toolbar = self.toolbar; self.toolbarDelegate.toolbar = self.toolbar;
[self.splitView setTranslatesAutoresizingMaskIntoConstraints:NO]; self.splitView.translatesAutoresizingMaskIntoConstraints = NO;
NSView *outlineView = self.outlineViewController.view; NSView *outlineView = self.outlineViewController.view;
NSView *inspectorView = self.inspectorViewController.view; NSView *inspectorView = self.inspectorViewController.view;
@@ -128,7 +128,7 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
[self showEntries]; [self showEntries];
} }
[self.splitView setAutosaveName:@"SplitView"]; self.splitView.autosaveName = @"SplitView";
} }
- (NSSearchField *)searchField { - (NSSearchField *)searchField {

View File

@@ -63,7 +63,7 @@
} }
/* Currently not working, as the underlying operations do not get the unomanager */ /* Currently not working, as the underlying operations do not get the unomanager */
MPDocument *document = [[[sender draggingDestinationWindow] windowController] document]; MPDocument *document = [[[sender draggingDestinationWindow] windowController] document];
KPKGroup *parentGroup = document.selectedGroup ? document.selectedGroup : document.root; KPKGroup *parentGroup = document.selectedGroups.count == 1 ? document.selectedGroups.firstObject : document.root;
[document.undoManager beginUndoGrouping]; [document.undoManager beginUndoGrouping];
KPKEntry *entry = [document createEntry:parentGroup]; KPKEntry *entry = [document createEntry:parentGroup];
BOOL didOk = (entry != nil); BOOL didOk = (entry != nil);

View File

@@ -131,7 +131,8 @@ static NSString *kMPContentBindingString3 = @"content.%@.%@.%@";
} }
- (void)setupBindings:(MPDocument *)document { - (void)setupBindings:(MPDocument *)document {
[self.entryController bind:NSContentObjectBinding toObject:document withKeyPath:NSStringFromSelector(@selector(selectedEntry)) options:nil]; [self.entryController bind:NSContentObjectBinding toObject:self withKeyPath:NSStringFromSelector(@selector(representedObject)) options:nil];
// [self.entryController bind:NSContentObjectBinding toObject:document withKeyPath:NSStringFromSelector(@selector(selectedEntry)) options:nil];
} }
- (void)registerNotificationsForDocument:(MPDocument *)document { - (void)registerNotificationsForDocument:(MPDocument *)document {
@@ -247,7 +248,7 @@ static NSString *kMPContentBindingString3 = @"content.%@.%@.%@";
- (BOOL)acceptsPreviewPanelControl:(QLPreviewPanel *)panel { - (BOOL)acceptsPreviewPanelControl:(QLPreviewPanel *)panel {
if(self.activeTab == MPEntryTabFiles) { if(self.activeTab == MPEntryTabFiles) {
return ([self.attachmentTableView selectedRow] != -1); return (self.attachmentTableView.selectedRow != -1);
} }
return NO; return NO;
} }

View File

@@ -65,7 +65,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
BOOL _didUnlock; BOOL _didUnlock;
} }
@property (strong) NSArrayController *entryArrayController; //@property (strong) NSArrayController *entryArrayController;
@property (strong) MPContextBarViewController *contextBarViewController; @property (strong) MPContextBarViewController *contextBarViewController;
@property (strong) NSArray *filteredEntries; @property (strong) NSArray *filteredEntries;
@@ -94,6 +94,8 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
_dataSource.viewController = self; _dataSource.viewController = self;
_menuDelegate = [[MPEntryContextMenuDelegate alloc] init]; _menuDelegate = [[MPEntryContextMenuDelegate alloc] init];
_contextBarViewController = [[MPContextBarViewController alloc] init]; _contextBarViewController = [[MPContextBarViewController alloc] init];
NSString *entriesKeyPath = [NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(entries))];
[_entryArrayController bind:NSContentBinding toObject:self withKeyPath:entriesKeyPath options:nil];
} }
return self; return self;
} }
@@ -164,6 +166,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
[self.entryTable bind:NSContentBinding toObject:self.entryArrayController withKeyPath:NSStringFromSelector(@selector(arrangedObjects)) options:nil]; [self.entryTable bind:NSContentBinding toObject:self.entryArrayController withKeyPath:NSStringFromSelector(@selector(arrangedObjects)) options:nil];
[self.entryTable bind:NSSortDescriptorsBinding toObject:self.entryArrayController withKeyPath:NSStringFromSelector(@selector(sortDescriptors)) options:nil]; [self.entryTable bind:NSSortDescriptorsBinding toObject:self.entryArrayController withKeyPath:NSStringFromSelector(@selector(sortDescriptors)) options:nil];
[self.entryTable bind:NSSelectionIndexesBinding toObject:self.entryArrayController withKeyPath:NSStringFromSelector(@selector(selectionIndexes)) options:nil];
self.entryTable.dataSource = self.dataSource; self.entryTable.dataSource = self.dataSource;
// bind NSArrayController sorting so that sort order gets auto-saved // bind NSArrayController sorting so that sort order gets auto-saved
@@ -341,22 +344,17 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
return; // Not the right table view return; // Not the right table view
} }
MPDocument *document = self.windowController.document; MPDocument *document = self.windowController.document;
if(tableView.selectedRow < 0 || tableView.selectedRowIndexes.count > 1) { document.selectedEntries = self.entryArrayController.selectedObjects;
document.selectedEntry = nil;
}
else {
document.selectedEntry = self.entryArrayController.arrangedObjects[tableView.selectedRow];
}
} }
#pragma mark MPTargetItemResolving #pragma mark MPTargetItemResolving
- (KPKEntry *)currentTargetEntry { - (KPKEntry *)currentTargetEntry {
NSInteger activeRow = [self.entryTable clickedRow]; NSInteger activeRow = self.entryTable.clickedRow;
/* Fall back to selection e.g. for toolbar actions */ /* Fall back to selection e.g. for toolbar actions */
if(activeRow < 0 ) { if(activeRow < 0 ) {
activeRow = [self.entryTable selectedRow]; activeRow = self.entryTable.selectedRow;
} }
if(activeRow >= 0 && activeRow <= [[self.entryArrayController arrangedObjects] count]) { if(activeRow >= 0 && activeRow <= [self.entryArrayController.arrangedObjects count]) {
return [self.entryArrayController arrangedObjects][activeRow]; return [self.entryArrayController arrangedObjects][activeRow];
} }
return nil; return nil;
@@ -368,60 +366,55 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
return entry; return entry;
} }
MPDocument *document = self.windowController.document; MPDocument *document = self.windowController.document;
return document.selectedItem; return document.selectedNodes.firstObject;
} }
#pragma mark MPDocument Notifications #pragma mark MPDocument Notifications
- (void)_didChangeCurrentItem:(NSNotification *)notification { - (void)_didChangeCurrentItem:(NSNotification *)notification {
MPDocument *document = [notification object]; MPDocument *document = [notification object];
if(!document.selectedGroup && !document.hasSearch) { if(document.selectedGroups.count != 1 && !document.hasSearch) {
/* no group selection out of search is wrong */ /* no group selection out of search is wrong */
[self.entryArrayController unbind:NSContentArrayBinding]; self.representedObject = nil;
[self.entryArrayController setContent:nil];
return; return;
} }
/* /*
If a group is the current item, see if we already show that group If a group is the current item, see if we already show that group
also test if an element has been selected (issue #257) also test if an element has been selected (issue #257)
*/ */
if(document.selectedItem == document.selectedGroup && document.selectedItem != nil) { if(document.selectedNodes.firstObject == document.selectedGroups.firstObject && document.selectedNodes.count > 0) {
if(document.hasSearch) { if(document.hasSearch) {
/* If search was active, stop it and exit */ /* If search was active, stop it and exit */
[document exitSearch:self]; [document exitSearch:self];
} }
else if([[self.entryArrayController content] count] > 0) { else if([self.entryArrayController.content count] > 0) {
KPKEntry *entry = [[self.entryArrayController content] lastObject]; KPKEntry *entry = [self.entryArrayController.content lastObject];
if(entry.parent == document.selectedGroup) { if(entry.parent == document.selectedGroups.lastObject) {
return; // we are showing the correct object right now. return; // we are showing the correct object right now.
} }
} }
[self.entryArrayController unbind:NSContentArrayBinding]; self.representedObject = document.selectedGroups.count == 1 ? document.selectedGroups.firstObject : nil;
[self.entryArrayController bind:NSContentArrayBinding toObject:document.selectedGroup withKeyPath:NSStringFromSelector(@selector(entries)) options:nil];
} }
[self _updateContextBar]; [self _updateContextBar];
} }
- (void)_didBecomFirstResponder:(NSNotification *)notification { - (void)_didBecomFirstResponder:(NSNotification *)notification {
MPDocument *document = [[self windowController] document]; MPDocument *document = self.windowController.document;
document.selectedEntries = self.entryArrayController.selectedObjects;
/*
if(document.selectedEntry.parent == document.selectedGroup || document.hasSearch) { if(document.selectedEntry.parent == document.selectedGroup || document.hasSearch) {
document.selectedItem = document.selectedEntry; document.selectedItem = document.selectedEntry;
} }
else { else {
document.selectedEntry = nil; document.selectedEntry = nil;
} }
*/
} }
- (void)_didAddItem:(NSNotification *)notification { - (void)_didAddItem:(NSNotification *)notification {
MPDocument *document = [[self windowController] document]; NSDictionary *dict = notification.userInfo;
if(!document.selectedGroup) { KPKEntry *entry = dict[MPDocumentEntryKey];
/* TODO: show group? */
return; // No group selected
}
KPKEntry *entry = document.selectedGroup.entries.lastObject;
if(!entry) {
return; // No Entry found, nothing to select.
}
NSUInteger row = [self.entryArrayController.arrangedObjects indexOfObject:entry]; NSUInteger row = [self.entryArrayController.arrangedObjects indexOfObject:entry];
[self.entryTable scrollRowToVisible:row]; [self.entryTable scrollRowToVisible:row];
[self.entryTable selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO]; [self.entryTable selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
@@ -440,13 +433,13 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
- (void)_didExitSearch:(NSNotification *)notification { - (void)_didExitSearch:(NSNotification *)notification {
[[self.entryTable tableColumnWithIdentifier:MPEntryTableParentColumnIdentifier] setHidden:YES]; [[self.entryTable tableColumnWithIdentifier:MPEntryTableParentColumnIdentifier] setHidden:YES];
MPDocument *document = [[self windowController] document]; // MPDocument *document = [[self windowController] document];
document.selectedItem = document.selectedGroup; // document.selectedItem = document.selectedGroup;
// TODO: really necessary? // // TODO: really necessary?
if( nil == document.selectedItem && nil == document.selectedGroup ) { // if( nil == document.selectedItem && nil == document.selectedGroup ) {
[self.entryArrayController unbind:NSContentArrayBinding]; // [self.entryArrayController unbind:NSContentArrayBinding];
[self.entryArrayController setContent:nil]; // [self.entryArrayController setContent:nil];
} // }
[self _updateContextBar]; [self _updateContextBar];
} }
@@ -469,13 +462,13 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
[self _showContextBar]; [self _showContextBar];
/* TODO: Show modification date column if not present? */ /* TODO: Show modification date column if not present? */
MPDocument *document = [[self windowController] document]; MPDocument *document = [[self windowController] document];
[self.entryArrayController bind:NSContentArrayBinding toObject:document.selectedEntry withKeyPath:NSStringFromSelector(@selector(history)) options:nil]; //[self.entryArrayController bind:NSContentArrayBinding toObject:document.selectedEntry withKeyPath:NSStringFromSelector(@selector(history)) options:nil];
} }
- (void)_didExitHistory:(NSNotification *)notification { - (void)_didExitHistory:(NSNotification *)notification {
[self _hideContextBar]; [self _hideContextBar];
MPDocument *document = [[self windowController] document]; MPDocument *document = [[self windowController] document];
document.selectedItem = document.selectedEntry; //document.selectedItem = document.selectedEntry;
} }
@@ -483,7 +476,9 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
- (void)_updateContextBar { - (void)_updateContextBar {
MPDocument *document = [[self windowController] document]; MPDocument *document = [[self windowController] document];
if(!document.hasSearch) { if(!document.hasSearch) {
BOOL showTrash = document.tree.metaData.useTrash && (document.selectedGroup.isTrash || document.selectedItem.isTrashed); KPKGroup *group = self.representedObject;
KPKNode *node = document.selectedNodes.count == 1 ? document.selectedNodes.firstObject : nil;
BOOL showTrash = document.tree.metaData.useTrash && (group.isTrash || node.isTrashed);
if(showTrash) { if(showTrash) {
[self _showContextBar]; [self _showContextBar];
} }

View File

@@ -84,7 +84,8 @@
} }
- (void)setupBindings:(MPDocument *)document { - (void)setupBindings:(MPDocument *)document {
[self.groupController bind:NSContentObjectBinding toObject:document withKeyPath:NSStringFromSelector(@selector(selectedGroup)) options:nil]; [self.groupController bind:NSContentObjectBinding toObject:self withKeyPath:NSStringFromSelector(@selector(representedObject)) options:nil];
//[self.groupController bind:NSContentObjectBinding toObject:document withKeyPath:NSStringFromSelector(@selector(selectedGroup)) options:nil];
} }
- (void)_establishBindings { - (void)_establishBindings {

View File

@@ -190,9 +190,9 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
self.popover.behavior = NSPopoverBehaviorTransient; self.popover.behavior = NSPopoverBehaviorTransient;
MPDatePickingViewController *controller = [[MPDatePickingViewController alloc] init]; MPDatePickingViewController *controller = [[MPDatePickingViewController alloc] init];
controller.popover = self.popover; controller.popover = self.popover;
MPDocument *document = self.windowController.document; KPKNode *node = self.representedObject;
if(document.selectedItem.timeInfo.expirationDate) { if(node.timeInfo.expirationDate) {
controller.date = document.selectedItem.timeInfo.expirationDate; controller.date = node.timeInfo.expirationDate;
} }
self.popover.contentViewController = controller; self.popover.contentViewController = controller;
[self.popover showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSMinYEdge]; [self.popover showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSMinYEdge];
@@ -216,16 +216,19 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
} }
- (void)_setIcon:(NSInteger)iconId { - (void)_setIcon:(NSInteger)iconId {
MPDocument *document = [[self windowController] document];
BOOL useDefault = (iconId == -1); BOOL useDefault = (iconId == -1);
switch (self.activeTab) { switch (self.activeTab) {
case MPGroupTab: case MPGroupTab: {
document.selectedGroup.iconId = useDefault ? [KPKGroup defaultIcon] : iconId; KPKGroup *group = self.nodeController.content;
group.iconId = useDefault ? [KPKGroup defaultIcon] : iconId;
break; break;
}
case MPEntryTab: case MPEntryTab: {
document.selectedEntry.iconId = useDefault ? [KPKEntry defaultIcon]: iconId; KPKEntry *entry = self.nodeController.content;
entry.iconId = useDefault ? [KPKEntry defaultIcon]: iconId;
break; break;
}
default: default:
break; break;
@@ -233,8 +236,8 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
} }
- (void)_setExpiryDate:(NSDate *)date { - (void)_setExpiryDate:(NSDate *)date {
MPDocument *document = [[self windowController] document]; KPKNode *node = self.representedObject;
document.selectedItem.timeInfo.expirationDate = date; node.timeInfo.expirationDate = date;
} }
#pragma mark - #pragma mark -
@@ -268,18 +271,19 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
- (void)_didChangeCurrentItem:(NSNotification *)notification { - (void)_didChangeCurrentItem:(NSNotification *)notification {
MPDocument *document = notification.object; MPDocument *document = notification.object;
if(document.selectedItem.asGroup) { KPKNode *node = document.selectedNodes.count == 1 ? document.selectedNodes.firstObject : nil;
if(node.asGroup) {
self.activeTab = MPGroupTab; self.activeTab = MPGroupTab;
} }
else if(document.selectedItem.asEntry) { else if(node.asEntry) {
self.activeTab = MPEntryTab; self.activeTab = MPEntryTab;
} }
else { else {
self.activeTab = MPEmptyTab; self.activeTab = MPEmptyTab;
} }
self.nodeController.content = document.selectedItem; self.nodeController.content = node;
self.entryViewController.representedObject = document.selectedItem.asEntry; self.entryViewController.representedObject = node.asEntry;
self.groupViewController.representedObject = document.selectedItem.asGroup; self.groupViewController.representedObject = node.asGroup;
} }
- (IBAction)beginEditing:(id)sender { - (IBAction)beginEditing:(id)sender {

View File

@@ -140,8 +140,8 @@
if(draggedGroup) { if(draggedGroup) {
if(copyItem || (nil == self.localDraggedGroup) ) { if(copyItem || (nil == self.localDraggedGroup) ) {
draggedGroup = [draggedGroup copyWithTitle:nil options:kKPKCopyOptionNone]; draggedGroup = [draggedGroup copyWithTitle:nil options:kKPKCopyOptionNone];
[targetGroup addGroup:draggedGroup atIndex:index]; [draggedGroup addToGroup:targetGroup atIndex:index];
[targetGroup.undoManager setActionName:NSLocalizedString(@"COPY_GROUP", "")]; [draggedGroup.undoManager setActionName:NSLocalizedString(@"COPY_GROUP", "")];
return YES; return YES;
} }
else if(self.localDraggedGroup) { else if(self.localDraggedGroup) {
@@ -156,8 +156,8 @@
else if(draggedEntry) { else if(draggedEntry) {
if(copyItem || (nil == self.localDraggedEntry)) { if(copyItem || (nil == self.localDraggedEntry)) {
draggedEntry = [draggedEntry copyWithTitle:nil options:kKPKCopyOptionNone]; draggedEntry = [draggedEntry copyWithTitle:nil options:kKPKCopyOptionNone];
[targetGroup addEntry:draggedEntry]; [draggedEntry addToGroup:targetGroup];
[targetGroup.undoManager setActionName:NSLocalizedString(@"COPY_ENTRY", "")]; [draggedEntry.undoManager setActionName:NSLocalizedString(@"COPY_ENTRY", "")];
return YES; return YES;
} }
else if(self.localDraggedEntry) { else if(self.localDraggedEntry) {

View File

@@ -17,6 +17,18 @@
@implementation MPOutlineView @implementation MPOutlineView
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)viewDidMoveToSuperview {
[[NSNotificationCenter defaultCenter] removeObserver:self];
if(self.enclosingScrollView) {
[self _setupNotifications];
}
}
- (void)mouseDown:(NSEvent *)theEvent { - (void)mouseDown:(NSEvent *)theEvent {
[super mouseDown:theEvent]; [super mouseDown:theEvent];
if(_didBecomeFirstResponder) { if(_didBecomeFirstResponder) {
@@ -36,4 +48,15 @@
return [super resignFirstResponder]; return [super resignFirstResponder];
} }
- (void)_setupNotifications {
[[NSNotificationCenter defaultCenter] removeObserver:self];
if(self.enclosingScrollView.contentView) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didChangeFrame:) name:NSViewBoundsDidChangeNotification object:self.enclosingScrollView.contentView];
}
}
- (void)_didChangeFrame:(NSNotification *)notification {
NSLog(@"DidChangeFrame:%@", NSStringFromRect(self.bounds));
}
@end @end

View File

@@ -71,13 +71,14 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
} }
- (void)didLoadView { - (void)didLoadView {
self.outlineView.menu = [self _contextMenu];
self.outlineView.allowsEmptySelection = YES;
self.outlineView.floatsGroupRows = NO;
self.outlineView.doubleAction = @selector(_doubleClickedGroup:);
self.outlineView.allowsMultipleSelection = YES;
[self.outlineView setDelegate:self]; [self.outlineView setDelegate:self];
[self.outlineView setMenu:[self _contextMenu]];
[self.outlineView setAllowsEmptySelection:YES];
[self.outlineView setFloatsGroupRows:NO];
[self.outlineView registerForDraggedTypes:@[ KPKGroupUTI, KPKEntryUTI ]]; [self.outlineView registerForDraggedTypes:@[ KPKGroupUTI, KPKEntryUTI ]];
[self.outlineView setDraggingSourceOperationMask:NSDragOperationEvery forLocal:YES]; [self.outlineView setDraggingSourceOperationMask:NSDragOperationEvery forLocal:YES];
[self.outlineView setDoubleAction:@selector(_doubleClickedGroup:)];
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_didBecomeFirstResponder:) selector:@selector(_didBecomeFirstResponder:)
@@ -94,12 +95,13 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
- (void)showOutline { - (void)showOutline {
if(!_bindingEstablished) { if(!_bindingEstablished) {
MPDocument *document = [[self windowController] document]; MPDocument *document = self.windowController.document;
[_treeController setChildrenKeyPath:NSStringFromSelector(@selector(groups))]; self.treeController.childrenKeyPath = NSStringFromSelector(@selector(groups));
[_treeController bind:NSContentBinding toObject:document withKeyPath:NSStringFromSelector(@selector(tree)) options:nil]; [self.treeController bind:NSContentBinding toObject:document withKeyPath:NSStringFromSelector(@selector(tree)) options:nil];
[_outlineView bind:NSContentBinding toObject:_treeController withKeyPath:NSStringFromSelector(@selector(arrangedObjects)) options:nil]; [self.outlineView bind:NSContentBinding toObject:self.treeController withKeyPath:NSStringFromSelector(@selector(arrangedObjects)) options:nil];
[self.outlineView bind:NSSelectionIndexPathsBinding toObject:self.treeController withKeyPath:NSStringFromSelector(@selector(selectionIndexPaths)) options:nil];
[self bind:NSStringFromSelector(@selector(databaseNameWrapper)) toObject:document.tree.metaData withKeyPath:NSStringFromSelector(@selector(databaseName)) options:nil]; [self bind:NSStringFromSelector(@selector(databaseNameWrapper)) toObject:document.tree.metaData withKeyPath:NSStringFromSelector(@selector(databaseName)) options:nil];
[_outlineView setDataSource:self.datasource]; [self.outlineView setDataSource:self.datasource];
_bindingEstablished = YES; _bindingEstablished = YES;
} }
NSTreeNode *node = [_outlineView itemAtRow:0]; NSTreeNode *node = [_outlineView itemAtRow:0];
@@ -119,7 +121,7 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
[self.outlineView collapseItem:node]; [self.outlineView collapseItem:node];
} }
} }
for(NSTreeNode *child in [node childNodes]) { for(NSTreeNode *child in node.childNodes) {
[self _expandItems:child]; [self _expandItems:child];
} }
} }
@@ -133,9 +135,9 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
#pragma mark MPTargetNodeResolving #pragma mark MPTargetNodeResolving
- (KPKGroup *)currentTargetGroup { - (KPKGroup *)currentTargetGroup {
NSInteger row = [self.outlineView clickedRow]; NSInteger row = self.outlineView.clickedRow;
if( row < 0 ) { if( row < 0 ) {
row = [self.outlineView selectedRow]; row = self.outlineView.selectedRow;
} }
return [[self.outlineView itemAtRow:row] representedObject]; return [[self.outlineView itemAtRow:row] representedObject];
} }
@@ -145,8 +147,8 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
if(group) { if(group) {
return group; return group;
} }
MPDocument *document = [[self windowController] document]; MPDocument *document = self.windowController.document;
return document.selectedItem; return document.selectedNodes.firstObject;
} }
#pragma mark Notifications #pragma mark Notifications
@@ -165,7 +167,8 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
return; // Nothing we need to worry about return; // Nothing we need to worry about
} }
MPDocument *document = [[self windowController] document]; MPDocument *document = [[self windowController] document];
document.selectedItem = document.selectedGroup; document.selectedGroups = self.treeController.selectedObjects;
//document.selectedItem = document.selectedGroup;
} }
# pragma mark MPDocument Notifications # pragma mark MPDocument Notifications
@@ -229,10 +232,13 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
} }
- (void)outlineViewSelectionDidChange:(NSNotification *)notification { - (void)outlineViewSelectionDidChange:(NSNotification *)notification {
NSTreeNode *treeNode = [_outlineView itemAtRow:[_outlineView selectedRow]]; MPDocument *document = self.windowController.document;
KPKGroup *selectedGroup = [treeNode representedObject]; if(![self.treeController.selectedObjects.firstObject isKindOfClass:[KPKTree class]]) {
MPDocument *document = [[self windowController] document]; document.selectedGroups = self.treeController.selectedObjects;
document.selectedGroup = selectedGroup; }
else {
document.selectedGroups = nil;
}
} }
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldShowOutlineCellForItem:(id)item { - (BOOL)outlineView:(NSOutlineView *)outlineView shouldShowOutlineCellForItem:(id)item {

View File

@@ -19,11 +19,12 @@
} }
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
MPDocument *document = [[[tableView window] windowController] document];
NSTableCellView *view = [tableView makeViewWithIdentifier:@"WindowAssociationCell" owner:tableView]; NSTableCellView *view = [tableView makeViewWithIdentifier:@"WindowAssociationCell" owner:tableView];
KPKEntry *entry = document.selectedEntry; NSString *windowTitleKeyPath = [NSString stringWithFormat:@"%@.%@",
KPKWindowAssociation *association = entry.autotype.associations[row]; NSStringFromSelector(@selector(objectValue)),
[[view textField] bind:NSValueBinding toObject:association withKeyPath:@"windowTitle" options:nil]; NSStringFromSelector(@selector(windowTitle))];
[view.textField bind:NSValueBinding toObject:view withKeyPath:windowTitleKeyPath options:nil];
return view; return view;
} }

View File

@@ -23,7 +23,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" selectionHighlightStyle="sourceList" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" rowSizeStyle="automatic" viewBased="YES" indentationPerLevel="16" outlineTableColumn="231" id="228" customClass="MPOutlineView"> <outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" selectionHighlightStyle="sourceList" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" rowSizeStyle="automatic" viewBased="YES" indentationPerLevel="16" outlineTableColumn="231" id="228" customClass="MPOutlineView">
<rect key="frame" x="0.0" y="0.0" width="272" height="449"/> <rect key="frame" x="0.0" y="0.0" width="272" height="0.0"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="0.0"/> <size key="intercellSpacing" width="3" height="0.0"/>
<color key="backgroundColor" name="_sourceListBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="_sourceListBackgroundColor" catalog="System" colorSpace="catalog"/>
@@ -92,6 +92,7 @@
<constraint firstItem="241" firstAttribute="centerY" secondItem="240" secondAttribute="centerY" id="349"/> <constraint firstItem="241" firstAttribute="centerY" secondItem="240" secondAttribute="centerY" id="349"/>
<constraint firstItem="243" firstAttribute="bottom" secondItem="241" secondAttribute="bottom" id="388"/> <constraint firstItem="243" firstAttribute="bottom" secondItem="241" secondAttribute="bottom" id="388"/>
<constraint firstAttribute="trailing" secondItem="243" secondAttribute="trailing" constant="3" id="389"/> <constraint firstAttribute="trailing" secondItem="243" secondAttribute="trailing" constant="3" id="389"/>
<constraint firstAttribute="trailing" secondItem="243" secondAttribute="trailing" constant="3" id="4Vg-BQ-zVQ"/>
</constraints> </constraints>
<connections> <connections>
<outlet property="imageView" destination="241" id="247"/> <outlet property="imageView" destination="241" id="247"/>