mirror of
https://github.com/MacPass/MacPass.git
synced 2025-12-14 15:12:21 +00:00
Fixed problem with tab order when another tab was displayed in the context bar
Began reworking filter selection in context bar
This commit is contained in:
@@ -195,6 +195,7 @@
|
|||||||
4C8A173D1790AA41008B5C17 /* NSData+Keyfile.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8A173C1790AA41008B5C17 /* NSData+Keyfile.m */; };
|
4C8A173D1790AA41008B5C17 /* NSData+Keyfile.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8A173C1790AA41008B5C17 /* NSData+Keyfile.m */; };
|
||||||
4C8B36AB17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8B36AA17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m */; };
|
4C8B36AB17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8B36AA17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m */; };
|
||||||
4C8FECC816D57E3200BF26CF /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8FECC716D57E3200BF26CF /* QuartzCore.framework */; };
|
4C8FECC816D57E3200BF26CF /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8FECC716D57E3200BF26CF /* QuartzCore.framework */; };
|
||||||
|
4C94DFCB1892860400F42F18 /* MPEntryFilterHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C94DFCA1892860400F42F18 /* MPEntryFilterHelper.m */; };
|
||||||
4C96D15417A12E4F00D931FA /* 99_CreatedTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C96D15317A12E4F00D931FA /* 99_CreatedTemplate.pdf */; };
|
4C96D15417A12E4F00D931FA /* 99_CreatedTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C96D15317A12E4F00D931FA /* 99_CreatedTemplate.pdf */; };
|
||||||
4C9D6AA917615199001C660C /* HNHRoundedSecureTextFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C9D6AA817615199001C660C /* HNHRoundedSecureTextFieldCell.m */; };
|
4C9D6AA917615199001C660C /* HNHRoundedSecureTextFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C9D6AA817615199001C660C /* HNHRoundedSecureTextFieldCell.m */; };
|
||||||
4CA08DA017A831B200A6544B /* MPAddEntryContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CA08D9F17A831B200A6544B /* MPAddEntryContextMenuDelegate.m */; };
|
4CA08DA017A831B200A6544B /* MPAddEntryContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CA08D9F17A831B200A6544B /* MPAddEntryContextMenuDelegate.m */; };
|
||||||
@@ -630,6 +631,8 @@
|
|||||||
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>"; };
|
||||||
4C8FECC716D57E3200BF26CF /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
4C8FECC716D57E3200BF26CF /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||||
|
4C94DFC91892860400F42F18 /* MPEntryFilterHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPEntryFilterHelper.h; sourceTree = "<group>"; };
|
||||||
|
4C94DFCA1892860400F42F18 /* MPEntryFilterHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPEntryFilterHelper.m; sourceTree = "<group>"; };
|
||||||
4C96D15317A12E4F00D931FA /* 99_CreatedTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = 99_CreatedTemplate.pdf; path = Icons/99_CreatedTemplate.pdf; sourceTree = "<group>"; };
|
4C96D15317A12E4F00D931FA /* 99_CreatedTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = 99_CreatedTemplate.pdf; path = Icons/99_CreatedTemplate.pdf; sourceTree = "<group>"; };
|
||||||
4C9D6AA717615199001C660C /* HNHRoundedSecureTextFieldCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHRoundedSecureTextFieldCell.h; sourceTree = "<group>"; };
|
4C9D6AA717615199001C660C /* HNHRoundedSecureTextFieldCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHRoundedSecureTextFieldCell.h; sourceTree = "<group>"; };
|
||||||
4C9D6AA817615199001C660C /* HNHRoundedSecureTextFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHRoundedSecureTextFieldCell.m; sourceTree = "<group>"; };
|
4C9D6AA817615199001C660C /* HNHRoundedSecureTextFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHRoundedSecureTextFieldCell.m; sourceTree = "<group>"; };
|
||||||
@@ -667,6 +670,7 @@
|
|||||||
4CAF62FA1763604000CD7084 /* HNHBadgedTextFieldCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHBadgedTextFieldCell.h; sourceTree = "<group>"; };
|
4CAF62FA1763604000CD7084 /* HNHBadgedTextFieldCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HNHBadgedTextFieldCell.h; sourceTree = "<group>"; };
|
||||||
4CAF62FB1763604000CD7084 /* HNHBadgedTextFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHBadgedTextFieldCell.m; sourceTree = "<group>"; };
|
4CAF62FB1763604000CD7084 /* HNHBadgedTextFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HNHBadgedTextFieldCell.m; sourceTree = "<group>"; };
|
||||||
4CB4AA0C17C2274200454CAD /* KeePass1_native_test.kdb */ = {isa = PBXFileReference; lastKnownFileType = file; name = KeePass1_native_test.kdb; path = Databases/KeePass1_native_test.kdb; sourceTree = "<group>"; };
|
4CB4AA0C17C2274200454CAD /* KeePass1_native_test.kdb */ = {isa = PBXFileReference; lastKnownFileType = file; name = KeePass1_native_test.kdb; path = Databases/KeePass1_native_test.kdb; sourceTree = "<group>"; };
|
||||||
|
4CB63A6018986530002DEC4C /* MPFlagsHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPFlagsHelper.h; sourceTree = "<group>"; };
|
||||||
4CB9339816D3A0DD00A13B5D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
|
4CB9339816D3A0DD00A13B5D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
|
||||||
4CBA2AB617074B59006D8139 /* MPSettingsHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSettingsHelper.h; sourceTree = "<group>"; };
|
4CBA2AB617074B59006D8139 /* MPSettingsHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSettingsHelper.h; sourceTree = "<group>"; };
|
||||||
4CBA2AB917074C07006D8139 /* MPSettingsHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSettingsHelper.m; sourceTree = "<group>"; };
|
4CBA2AB917074C07006D8139 /* MPSettingsHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSettingsHelper.m; sourceTree = "<group>"; };
|
||||||
@@ -1093,6 +1097,9 @@
|
|||||||
4C4B7EF717A4B335000234C7 /* MPUniqueCharactersFormatter.m */,
|
4C4B7EF717A4B335000234C7 /* MPUniqueCharactersFormatter.m */,
|
||||||
4C224B4017DFCB2300FF6AEE /* MPNumericalInputFormatter.h */,
|
4C224B4017DFCB2300FF6AEE /* MPNumericalInputFormatter.h */,
|
||||||
4C224B4117DFCB2400FF6AEE /* MPNumericalInputFormatter.m */,
|
4C224B4117DFCB2400FF6AEE /* MPNumericalInputFormatter.m */,
|
||||||
|
4C94DFC91892860400F42F18 /* MPEntryFilterHelper.h */,
|
||||||
|
4C94DFCA1892860400F42F18 /* MPEntryFilterHelper.m */,
|
||||||
|
4CB63A6018986530002DEC4C /* MPFlagsHelper.h */,
|
||||||
);
|
);
|
||||||
name = Helper;
|
name = Helper;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -2096,6 +2103,7 @@
|
|||||||
4CC6DB7A17D23719002C6091 /* KPKNode+IconImage.m in Sources */,
|
4CC6DB7A17D23719002C6091 /* KPKNode+IconImage.m in Sources */,
|
||||||
4CC6DB7D17D23DCE002C6091 /* KPKUTIs.m in Sources */,
|
4CC6DB7D17D23DCE002C6091 /* KPKUTIs.m in Sources */,
|
||||||
4CEED1C617D7BD0E007180F1 /* NSError+Messages.m in Sources */,
|
4CEED1C617D7BD0E007180F1 /* NSError+Messages.m in Sources */,
|
||||||
|
4C94DFCB1892860400F42F18 /* MPEntryFilterHelper.m in Sources */,
|
||||||
4C00E33817D8FA3500F37192 /* DDHotKeyCenter.m in Sources */,
|
4C00E33817D8FA3500F37192 /* DDHotKeyCenter.m in Sources */,
|
||||||
4C224B4217DFCB2400FF6AEE /* MPNumericalInputFormatter.m in Sources */,
|
4C224B4217DFCB2400FF6AEE /* MPNumericalInputFormatter.m in Sources */,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,11 +11,8 @@
|
|||||||
<outlet property="exitHistoryButton" destination="pqx-su-vAh" id="JmV-vC-F48"/>
|
<outlet property="exitHistoryButton" destination="pqx-su-vAh" id="JmV-vC-F48"/>
|
||||||
<outlet property="filterDoneButton" destination="61" id="o8k-20-QUA"/>
|
<outlet property="filterDoneButton" destination="61" id="o8k-20-QUA"/>
|
||||||
<outlet property="filterLabelTextField" destination="6" id="60"/>
|
<outlet property="filterLabelTextField" destination="6" id="60"/>
|
||||||
<outlet property="filterPasswordButton" destination="96" id="101"/>
|
|
||||||
<outlet property="filterSearchField" destination="80" id="95"/>
|
<outlet property="filterSearchField" destination="80" id="95"/>
|
||||||
<outlet property="filterTitleButton" destination="2" id="57"/>
|
<outlet property="filterTypePopupButton" destination="9ZN-yB-Aiq" id="7Af-Dn-e05"/>
|
||||||
<outlet property="filterURLButton" destination="40" id="59"/>
|
|
||||||
<outlet property="filterUsernameButton" destination="35" id="58"/>
|
|
||||||
<outlet property="historyBar" destination="S8L-rB-h0h" id="6yZ-El-fVs"/>
|
<outlet property="historyBar" destination="S8L-rB-h0h" id="6yZ-El-fVs"/>
|
||||||
<outlet property="historyLabel" destination="gGR-f0-dcr" id="slx-9D-8k8"/>
|
<outlet property="historyLabel" destination="gGR-f0-dcr" id="slx-9D-8k8"/>
|
||||||
<outlet property="trashBar" destination="DXf-SC-gVG" id="3aZ-Xc-VDk"/>
|
<outlet property="trashBar" destination="DXf-SC-gVG" id="3aZ-Xc-VDk"/>
|
||||||
@@ -38,18 +35,7 @@
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="576" height="30"/>
|
<rect key="frame" x="0.0" y="0.0" width="576" height="30"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2">
|
<textField verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6">
|
||||||
<rect key="frame" x="57" y="5" width="42" height="19"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<buttonCell key="cell" type="recessed" title="Title" bezelStyle="recessed" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="3">
|
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
|
|
||||||
<font key="font" metaFont="systemBold" size="12"/>
|
|
||||||
</buttonCell>
|
|
||||||
<connections>
|
|
||||||
<action selector="toggleFilterSpace:" target="-2" id="5tf-b0-MfH"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6">
|
|
||||||
<rect key="frame" x="6" y="7" width="45" height="14"/>
|
<rect key="frame" x="6" y="7" width="45" height="14"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Search:" id="7">
|
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Search:" id="7">
|
||||||
@@ -58,28 +44,6 @@
|
|||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="35">
|
|
||||||
<rect key="frame" x="107" y="6" width="77" height="17"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<buttonCell key="cell" type="recessed" title="Username" bezelStyle="recessed" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="36">
|
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
|
|
||||||
<font key="font" metaFont="systemBold" size="12"/>
|
|
||||||
</buttonCell>
|
|
||||||
<connections>
|
|
||||||
<action selector="toggleFilterSpace:" target="-2" id="eVq-ir-2ZF"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="40">
|
|
||||||
<rect key="frame" x="192" y="6" width="38" height="17"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<buttonCell key="cell" type="recessed" title="URL" bezelStyle="recessed" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="41">
|
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
|
|
||||||
<font key="font" metaFont="systemBold" size="12"/>
|
|
||||||
</buttonCell>
|
|
||||||
<connections>
|
|
||||||
<action selector="toggleFilterSpace:" target="-2" id="XEz-fj-0wx"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="61">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="61">
|
||||||
<rect key="frame" x="526" y="6" width="42" height="17"/>
|
<rect key="frame" x="526" y="6" width="42" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
@@ -87,6 +51,9 @@
|
|||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="smallSystem"/>
|
<font key="font" metaFont="smallSystem"/>
|
||||||
</buttonCell>
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="exitFilter:" target="-2" id="cip-Yr-YZx"/>
|
||||||
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<searchField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="80">
|
<searchField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="80">
|
||||||
<rect key="frame" x="418" y="5" width="100" height="19"/>
|
<rect key="frame" x="418" y="5" width="100" height="19"/>
|
||||||
@@ -103,36 +70,22 @@
|
|||||||
<outlet property="delegate" destination="-2" id="Y78-7K-e9c"/>
|
<outlet property="delegate" destination="-2" id="Y78-7K-e9c"/>
|
||||||
</connections>
|
</connections>
|
||||||
</searchField>
|
</searchField>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="96">
|
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9ZN-yB-Aiq">
|
||||||
<rect key="frame" x="238" y="6" width="74" height="17"/>
|
<rect key="frame" x="57" y="6" width="70" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<buttonCell key="cell" type="recessed" title="Password" bezelStyle="recessed" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="97">
|
<popUpButtonCell key="cell" type="roundRect" bezelStyle="roundedRect" alignment="center" controlSize="small" lineBreakMode="truncatingTail" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="oir-UN-bNS">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="systemBold" size="12"/>
|
<font key="font" metaFont="smallSystem"/>
|
||||||
</buttonCell>
|
<menu key="menu" title="OtherViews" id="el3-on-vmi"/>
|
||||||
<connections>
|
</popUpButtonCell>
|
||||||
<action selector="toggleFilterSpace:" target="-2" id="Dwh-vl-UhN"/>
|
</popUpButton>
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
</subviews>
|
</subviews>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="6" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="8" id="30"/>
|
<constraint firstItem="6" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="8" id="30"/>
|
||||||
<constraint firstItem="2" firstAttribute="leading" secondItem="6" secondAttribute="trailing" constant="8" symbolic="YES" id="32"/>
|
|
||||||
<constraint firstItem="6" firstAttribute="baseline" secondItem="2" secondAttribute="baseline" id="34"/>
|
|
||||||
<constraint firstItem="35" firstAttribute="leading" secondItem="2" secondAttribute="trailing" constant="8" symbolic="YES" id="38"/>
|
|
||||||
<constraint firstItem="40" firstAttribute="leading" secondItem="35" secondAttribute="trailing" constant="8" symbolic="YES" id="43"/>
|
|
||||||
<constraint firstAttribute="centerY" secondItem="40" secondAttribute="centerY" id="54"/>
|
|
||||||
<constraint firstAttribute="centerY" secondItem="2" secondAttribute="centerY" id="55"/>
|
|
||||||
<constraint firstAttribute="centerY" secondItem="35" secondAttribute="centerY" id="56"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="61" secondAttribute="trailing" constant="8" id="63"/>
|
<constraint firstAttribute="trailing" secondItem="61" secondAttribute="trailing" constant="8" id="63"/>
|
||||||
<constraint firstItem="6" firstAttribute="bottom" secondItem="35" secondAttribute="bottom" id="66"/>
|
|
||||||
<constraint firstAttribute="centerY" secondItem="61" secondAttribute="centerY" id="69"/>
|
<constraint firstAttribute="centerY" secondItem="61" secondAttribute="centerY" id="69"/>
|
||||||
<constraint firstItem="35" firstAttribute="baseline" secondItem="40" secondAttribute="baseline" id="73"/>
|
|
||||||
<constraint firstItem="61" firstAttribute="leading" secondItem="80" secondAttribute="trailing" constant="8" symbolic="YES" id="83"/>
|
<constraint firstItem="61" firstAttribute="leading" secondItem="80" secondAttribute="trailing" constant="8" symbolic="YES" id="83"/>
|
||||||
<constraint firstAttribute="centerY" secondItem="80" secondAttribute="centerY" id="86"/>
|
<constraint firstAttribute="centerY" secondItem="80" secondAttribute="centerY" id="86"/>
|
||||||
<constraint firstItem="96" firstAttribute="baseline" secondItem="40" secondAttribute="baseline" id="98"/>
|
|
||||||
<constraint firstItem="96" firstAttribute="leading" secondItem="40" secondAttribute="trailing" constant="8" symbolic="YES" id="99"/>
|
|
||||||
<constraint firstItem="80" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="96" secondAttribute="trailing" constant="8" symbolic="YES" id="100"/>
|
|
||||||
</constraints>
|
</constraints>
|
||||||
</customView>
|
</customView>
|
||||||
</subviews>
|
</subviews>
|
||||||
@@ -143,6 +96,9 @@
|
|||||||
<constraint firstItem="1" firstAttribute="top" secondItem="caQ-XO-RkM" secondAttribute="top" id="oAv-6v-o9d"/>
|
<constraint firstItem="1" firstAttribute="top" secondItem="caQ-XO-RkM" secondAttribute="top" id="oAv-6v-o9d"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
|
<connections>
|
||||||
|
<outlet property="initialFirstResponder" destination="80" id="tDw-Su-DU1"/>
|
||||||
|
</connections>
|
||||||
</tabViewItem>
|
</tabViewItem>
|
||||||
<tabViewItem label="Trash" identifier="2" id="na6-h9-r9q">
|
<tabViewItem label="Trash" identifier="2" id="na6-h9-r9q">
|
||||||
<view key="view" id="F6S-GS-AwI">
|
<view key="view" id="F6S-GS-AwI">
|
||||||
@@ -179,6 +135,9 @@
|
|||||||
<constraint firstAttribute="trailing" secondItem="DXf-SC-gVG" secondAttribute="trailing" id="wap-ZJ-5Rw"/>
|
<constraint firstAttribute="trailing" secondItem="DXf-SC-gVG" secondAttribute="trailing" id="wap-ZJ-5Rw"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
|
<connections>
|
||||||
|
<outlet property="initialFirstResponder" destination="szx-Hx-OrV" id="Cqa-Po-xMe"/>
|
||||||
|
</connections>
|
||||||
</tabViewItem>
|
</tabViewItem>
|
||||||
<tabViewItem label="History" identifier="3" id="z4I-cp-nhf">
|
<tabViewItem label="History" identifier="3" id="z4I-cp-nhf">
|
||||||
<view key="view" id="iPb-SZ-Lfm">
|
<view key="view" id="iPb-SZ-Lfm">
|
||||||
@@ -224,6 +183,9 @@
|
|||||||
<constraint firstItem="S8L-rB-h0h" firstAttribute="top" secondItem="iPb-SZ-Lfm" secondAttribute="top" id="mW1-xp-CdF"/>
|
<constraint firstItem="S8L-rB-h0h" firstAttribute="top" secondItem="iPb-SZ-Lfm" secondAttribute="top" id="mW1-xp-CdF"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
|
<connections>
|
||||||
|
<outlet property="initialFirstResponder" destination="pqx-su-vAh" id="bi5-CA-b4P"/>
|
||||||
|
</connections>
|
||||||
</tabViewItem>
|
</tabViewItem>
|
||||||
</tabViewItems>
|
</tabViewItems>
|
||||||
</tabView>
|
</tabView>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import "MPViewController.h"
|
#import "MPViewController.h"
|
||||||
|
#import "MPEntryFilterHelper.h"
|
||||||
|
|
||||||
@protocol MPContextBarDelegate <NSObject>
|
@protocol MPContextBarDelegate <NSObject>
|
||||||
|
|
||||||
@@ -17,33 +18,24 @@
|
|||||||
- (void)contextBarShouldEmptyTrash;
|
- (void)contextBarShouldEmptyTrash;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
typedef NS_OPTIONS(NSUInteger, MPFilterModeType) {
|
|
||||||
MPFilterNone = 0,
|
|
||||||
MPFilterUrls = (1<<0),
|
|
||||||
MPFilterUsernames = (1<<1),
|
|
||||||
MPFilterTitles = (1<<2),
|
|
||||||
MPFilterPasswords = (1<<3),
|
|
||||||
};
|
|
||||||
|
|
||||||
@class HNHGradientView;
|
@class HNHGradientView;
|
||||||
|
|
||||||
@interface MPContextBarViewController : MPViewController
|
@interface MPContextBarViewController : MPViewController
|
||||||
|
|
||||||
@property (nonatomic, assign) MPFilterModeType filterMode;
|
@property (nonatomic, assign) MPFilterMode filterMode;
|
||||||
@property (nonatomic, readonly) BOOL hasFilter;
|
@property (nonatomic, readonly) BOOL hasFilter;
|
||||||
@property (nonatomic, weak) id<MPContextBarDelegate> delegate;
|
@property (nonatomic, weak) id<MPContextBarDelegate> delegate;
|
||||||
@property (weak) NSView *nextKeyView;
|
@property (weak) NSView *nextKeyView;
|
||||||
|
|
||||||
- (NSString *)filterString;
|
- (NSString *)filterString;
|
||||||
- (NSArray *)filterPredicates;
|
|
||||||
|
|
||||||
- (IBAction)toggleFilterSpace:(id)sender;
|
- (IBAction)toggleFilterSpace:(id)sender;
|
||||||
|
- (IBAction)exitFilter:(id)sender;
|
||||||
|
|
||||||
- (BOOL)showsFilter;
|
- (BOOL)showsFilter;
|
||||||
- (BOOL)showsHistory;
|
- (BOOL)showsHistory;
|
||||||
- (BOOL)showsTrash;
|
- (BOOL)showsTrash;
|
||||||
|
|
||||||
- (void)exitFilter;
|
|
||||||
- (void)showFilter;
|
- (void)showFilter;
|
||||||
|
|
||||||
- (void)showHistory;
|
- (void)showHistory;
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#import "MPContextBarViewController.h"
|
#import "MPContextBarViewController.h"
|
||||||
#import "HNHGradientView.h"
|
#import "HNHGradientView.h"
|
||||||
|
#import "KPKEntry.h"
|
||||||
|
#import "MPEntryFilterHelper.h"
|
||||||
|
|
||||||
typedef NS_ENUM(NSUInteger, MPContextTab) {
|
typedef NS_ENUM(NSUInteger, MPContextTab) {
|
||||||
MPContextTabFilter,
|
MPContextTabFilter,
|
||||||
@@ -27,11 +29,8 @@ typedef NS_ENUM(NSUInteger, MPContextTab) {
|
|||||||
@property (nonatomic, assign) BOOL hasFilter;
|
@property (nonatomic, assign) BOOL hasFilter;
|
||||||
|
|
||||||
/* Filter */
|
/* Filter */
|
||||||
|
@property (weak) IBOutlet NSPopUpButton *filterTypePopupButton;
|
||||||
@property (weak) IBOutlet NSButton *filterDoneButton;
|
@property (weak) IBOutlet NSButton *filterDoneButton;
|
||||||
@property (weak) IBOutlet NSButton *filterTitleButton;
|
|
||||||
@property (weak) IBOutlet NSButton *filterUsernameButton;
|
|
||||||
@property (weak) IBOutlet NSButton *filterURLButton;
|
|
||||||
@property (weak) IBOutlet NSButton *filterPasswordButton;
|
|
||||||
@property (weak) IBOutlet NSTextField *filterLabelTextField;
|
@property (weak) IBOutlet NSTextField *filterLabelTextField;
|
||||||
@property (weak) IBOutlet NSSearchField *filterSearchField;
|
@property (weak) IBOutlet NSSearchField *filterSearchField;
|
||||||
/* History */
|
/* History */
|
||||||
@@ -65,13 +64,9 @@ typedef NS_ENUM(NSUInteger, MPContextTab) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)didLoadView {
|
- (void)didLoadView {
|
||||||
[self.filterURLButton setTag:MPFilterUrls];
|
|
||||||
[self.filterUsernameButton setTag:MPFilterUsernames];
|
|
||||||
[self.filterTitleButton setTag:MPFilterTitles];
|
|
||||||
[self.filterPasswordButton setTag:MPFilterPasswords];
|
|
||||||
[[self.filterLabelTextField cell] setBackgroundStyle:NSBackgroundStyleRaised];
|
[[self.filterLabelTextField cell] setBackgroundStyle:NSBackgroundStyleRaised];
|
||||||
[self.filterDoneButton setAction:@selector(exitFilter)];
|
[self.filterTypePopupButton setMenu:[self _allocFilterMenu]];
|
||||||
[self.filterDoneButton setTarget:self];
|
|
||||||
|
|
||||||
[self.filterSearchField setAction:@selector(_didChangeFilter)];
|
[self.filterSearchField setAction:@selector(_didChangeFilter)];
|
||||||
[[self.filterSearchField cell] setSendsSearchStringImmediately:NO];
|
[[self.filterSearchField cell] setSendsSearchStringImmediately:NO];
|
||||||
@@ -97,13 +92,13 @@ typedef NS_ENUM(NSUInteger, MPContextTab) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark Properties
|
#pragma mark Properties
|
||||||
- (void)setFilterMode:(MPFilterModeType)newFilterMode {
|
- (void)setFilterMode:(MPFilterMode)newFilterMode {
|
||||||
if(_filterMode != newFilterMode) {
|
if(_filterMode != newFilterMode) {
|
||||||
if(newFilterMode == MPFilterNone) {
|
if(newFilterMode == MPFilterNone) {
|
||||||
newFilterMode = MPFilterTitles;
|
newFilterMode = MPFilterTitles;
|
||||||
}
|
}
|
||||||
_filterMode = newFilterMode;
|
_filterMode = newFilterMode;
|
||||||
[self _updateFilterButtons];
|
[self _updateFilterMenu];
|
||||||
[self _didChangeFilter];
|
[self _didChangeFilter];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,33 +136,13 @@ typedef NS_ENUM(NSUInteger, MPContextTab) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *)filterPredicates {
|
#pragma mark Actions
|
||||||
if(![self hasFilter]) {
|
- (void)toggleFilterSpace:(id)sender {
|
||||||
return nil;
|
if(![sender isKindOfClass:[NSMenuItem class]]) {
|
||||||
}
|
|
||||||
NSMutableArray *prediactes = [[NSMutableArray alloc] initWithCapacity:4];
|
|
||||||
if([self _shouldFilterTitles]) {
|
|
||||||
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.title CONTAINS[cd] %@", [self filterString]]];
|
|
||||||
}
|
|
||||||
if([self _shouldFilterUsernames]) {
|
|
||||||
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.username CONTAINS[cd] %@", [self filterString]]];
|
|
||||||
}
|
|
||||||
if([self _shouldFilterURLs]) {
|
|
||||||
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.url CONTAINS[cd] %@", [self filterString]]];
|
|
||||||
}
|
|
||||||
if([self _shouldFilterPasswords]) {
|
|
||||||
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.password CONTAINS[cd] %@", [self filterString]]];
|
|
||||||
}
|
|
||||||
return prediactes;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)toggleFilterSpace:(id)sender {
|
|
||||||
if(![sender isKindOfClass:[NSButton class]]) {
|
|
||||||
return; // Wrong sender
|
return; // Wrong sender
|
||||||
}
|
}
|
||||||
NSButton *button = sender;
|
MPFilterMode toggledMode = [sender tag];
|
||||||
MPFilterModeType toggledMode = [button tag];
|
switch ([sender state]) {
|
||||||
switch ([button state]) {
|
|
||||||
case NSOnState:
|
case NSOnState:
|
||||||
self.filterMode |= toggledMode;
|
self.filterMode |= toggledMode;
|
||||||
break;
|
break;
|
||||||
@@ -181,6 +156,20 @@ typedef NS_ENUM(NSUInteger, MPContextTab) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)exitFilter:(id)sender {
|
||||||
|
if(!self.hasFilter) {
|
||||||
|
return; // Nothing to do;
|
||||||
|
}
|
||||||
|
if(![self showsFilter]) {
|
||||||
|
return; // We arent displaying the filter view
|
||||||
|
}
|
||||||
|
self.hasFilter = NO;
|
||||||
|
[self.filterSearchField setStringValue:@""];
|
||||||
|
if(_delegateRespondsToDidExitFilter) {
|
||||||
|
[self.delegate contextBarDidExitFilter];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)showFilter {
|
- (void)showFilter {
|
||||||
self.hasFilter = YES;
|
self.hasFilter = YES;
|
||||||
/* Select text if already visible */
|
/* Select text if already visible */
|
||||||
@@ -188,17 +177,17 @@ typedef NS_ENUM(NSUInteger, MPContextTab) {
|
|||||||
[self.filterSearchField selectText:self];
|
[self.filterSearchField selectText:self];
|
||||||
}
|
}
|
||||||
self.activeTab = MPContextTabFilter;
|
self.activeTab = MPContextTabFilter;
|
||||||
[self _updateFilterButtons];
|
[self _updateFilterMenu];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)showHistory {
|
- (void)showHistory {
|
||||||
[self exitFilter];
|
[self exitFilter:self];
|
||||||
self.activeTab = MPContextTabHistory;
|
self.activeTab = MPContextTabHistory;
|
||||||
[self _updateBindings];
|
[self _updateBindings];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)showTrash {
|
- (void)showTrash {
|
||||||
[self exitFilter];
|
[self exitFilter:self];
|
||||||
self.activeTab = MPContextTabTrash;
|
self.activeTab = MPContextTabTrash;
|
||||||
[self _updateBindings];
|
[self _updateBindings];
|
||||||
}
|
}
|
||||||
@@ -226,52 +215,68 @@ typedef NS_ENUM(NSUInteger, MPContextTab) {
|
|||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)exitFilter {
|
|
||||||
if(!self.hasFilter) {
|
|
||||||
return; // Nothing to do;
|
|
||||||
}
|
|
||||||
if(![self showsFilter]) {
|
|
||||||
return; // We arent displaying the filter view
|
|
||||||
}
|
|
||||||
self.hasFilter = NO;
|
|
||||||
[self.filterSearchField setStringValue:@""];
|
|
||||||
if(_delegateRespondsToDidExitFilter) {
|
|
||||||
[self.delegate contextBarDidExitFilter];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_didChangeFilter {
|
- (void)_didChangeFilter {
|
||||||
if(_delegateRespondsToDidChangeFilter) {
|
if(_delegateRespondsToDidChangeFilter) {
|
||||||
[self.delegate contextBarDidChangeFilter];
|
[self.delegate contextBarDidChangeFilter];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark UI Helper
|
||||||
- (void)_updateBindings {
|
- (void)_updateBindings {
|
||||||
// only the entry view has to be bound, the rest not
|
// only the entry view has to be bound, the rest not
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_updateFilterButtons {
|
- (NSMenu *)_allocFilterMenu {
|
||||||
[self.filterTitleButton setState:[self _shouldFilterTitles] ? NSOnState : NSOffState];
|
NSMenu *searchMenu = [[NSMenu alloc] init];
|
||||||
[self.filterURLButton setState:[self _shouldFilterURLs] ? NSOnState : NSOffState ];
|
|
||||||
[self.filterUsernameButton setState:[self _shouldFilterUsernames] ? NSOnState : NSOffState];
|
NSArray *titles = @[NSLocalizedString(@"TITLE", ""),
|
||||||
[self.filterPasswordButton setState:[self _shouldFilterPasswords] ? NSOnState : NSOffState];
|
NSLocalizedString(@"PASSWORD", ""),
|
||||||
|
NSLocalizedString(@"URL", ""),
|
||||||
|
NSLocalizedString(@"USERNAME", "")
|
||||||
|
];
|
||||||
|
NSArray *tags = @[ @(MPFilterTitles),
|
||||||
|
@(MPFilterPasswords),
|
||||||
|
@(MPFilterUrls),
|
||||||
|
@(MPFilterUsernames) ];
|
||||||
|
/* Attributes */
|
||||||
|
for(NSUInteger index = 0; index < [tags count]; index++) {
|
||||||
|
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:titles[index] action:@selector(toggleFilterSpace:) keyEquivalent:@""];
|
||||||
|
[item setTag:[tags[index] integerValue]];
|
||||||
|
[item setTarget:self];
|
||||||
|
[searchMenu addItem:item];
|
||||||
|
}
|
||||||
|
[searchMenu addItem:[NSMenuItem separatorItem]];
|
||||||
|
/* Special Search */
|
||||||
|
NSMenuItem *doublePasswordsItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"", "") action:NULL keyEquivalent:@""];
|
||||||
|
[doublePasswordsItem setTag:MPFilterDoublePasswords];
|
||||||
|
|
||||||
|
[searchMenu addItem:doublePasswordsItem];
|
||||||
|
|
||||||
|
return searchMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)_shouldFilterTitles {
|
- (void)_updateFilterMenu {
|
||||||
return (MPFilterNone != (self.filterMode & MPFilterTitles));
|
NSMenu *menu = [self.filterTypePopupButton menu];
|
||||||
|
NSArray *allItems = [menu itemArray];
|
||||||
|
NSArray *enabledItems = [self _filterItemsForMode:self.filterMode];
|
||||||
|
for(NSMenuItem *item in allItems) {
|
||||||
|
BOOL isEnabeld = [enabledItems containsObject:item];
|
||||||
|
[item setEnabled:isEnabeld];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)_shouldFilterURLs {
|
- (NSArray *)_filterItemsForMode:(MPFilterMode)mode {
|
||||||
return (MPFilterNone != (self.filterMode & MPFilterUrls));
|
NSArray *options = [MPEntryFilterHelper optionsEnabledInMode:mode];
|
||||||
|
NSMenu *menu = [self.filterTypePopupButton menu];
|
||||||
|
NSMutableArray *menuItems = [[NSMutableArray alloc] initWithCapacity:[[menu itemArray] count]];
|
||||||
|
for(NSNumber *number in options) {
|
||||||
|
MPFilterMode flag = [number integerValue];
|
||||||
|
NSMenuItem *flagItem = [menu itemWithTag:flag];
|
||||||
|
if(flagItem) {
|
||||||
|
[menuItems addObject:flagItem];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)_shouldFilterUsernames {
|
|
||||||
return (MPFilterNone != (self.filterMode & MPFilterUsernames));
|
|
||||||
}
|
}
|
||||||
|
return menuItems;
|
||||||
- (BOOL)_shouldFilterPasswords {
|
|
||||||
return (MPFilterNone != (self.filterMode & MPFilterPasswords));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
27
MacPass/MPEntryFilterHelper.h
Normal file
27
MacPass/MPEntryFilterHelper.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// MPSearchHelper.h
|
||||||
|
// MacPass
|
||||||
|
//
|
||||||
|
// Created by Michael Starke on 24/01/14.
|
||||||
|
// Copyright (c) 2014 HicknHack Software GmbH. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
@class MPDocument;
|
||||||
|
|
||||||
|
typedef NS_OPTIONS(NSUInteger, MPFilterMode) {
|
||||||
|
MPFilterNone = 0,
|
||||||
|
MPFilterUrls = (1<<0),
|
||||||
|
MPFilterUsernames = (1<<1),
|
||||||
|
MPFilterTitles = (1<<2),
|
||||||
|
MPFilterPasswords = (1<<3),
|
||||||
|
MPFilterNotes = (1<<4),
|
||||||
|
MPFilterDoublePasswords = (1<<5)
|
||||||
|
};
|
||||||
|
|
||||||
|
@interface MPEntryFilterHelper : NSObject
|
||||||
|
|
||||||
|
+ (NSArray *)entriesInDocument:(MPDocument *)document matching:(NSString *)filter usingFilterMode:(MPFilterMode)mode;
|
||||||
|
+ (NSArray *)optionsEnabledInMode:(MPFilterMode)mode;
|
||||||
|
@end
|
||||||
86
MacPass/MPEntryFilterHelper.m
Normal file
86
MacPass/MPEntryFilterHelper.m
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
//
|
||||||
|
// MPSearchHelper.m
|
||||||
|
// MacPass
|
||||||
|
//
|
||||||
|
// Created by Michael Starke on 24/01/14.
|
||||||
|
// Copyright (c) 2014 HicknHack Software GmbH. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPEntryFilterHelper.h"
|
||||||
|
#import "MPDocument.h"
|
||||||
|
#import "KPKGroup.h"
|
||||||
|
#import "KPKEntry.h"
|
||||||
|
#import "MPFlagsHelper.h"
|
||||||
|
|
||||||
|
@implementation MPEntryFilterHelper
|
||||||
|
|
||||||
|
+ (NSArray *)entriesInDocument:(MPDocument *)document matching:(NSString *)filter usingFilterMode:(MPFilterMode)mode {
|
||||||
|
/* Filter double passwords */
|
||||||
|
if(MPTestFlagInOptions(MPFilterDoublePasswords, mode)) {
|
||||||
|
__block NSMutableDictionary *passwordToEntryMap;
|
||||||
|
/* Build up a usage map */
|
||||||
|
[[document.root childEntries] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
||||||
|
KPKEntry *entry = obj;
|
||||||
|
NSMutableSet *entrySet = passwordToEntryMap[entry.password];
|
||||||
|
if(entrySet) {
|
||||||
|
[entrySet addObject:entry];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
passwordToEntryMap[entry.password] = [NSMutableSet setWithObject:entry];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
/* check for usage count */
|
||||||
|
__block NSMutableArray *doublePasswords = [[NSMutableArray alloc] init];
|
||||||
|
[[passwordToEntryMap allKeys] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
||||||
|
NSSet *entrySet = passwordToEntryMap[obj];
|
||||||
|
KPKEntry *entry = [entrySet anyObject];
|
||||||
|
if(entry) {
|
||||||
|
[doublePasswords addObject:entry];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
return doublePasswords;
|
||||||
|
}
|
||||||
|
/* Filter using predicates */
|
||||||
|
NSArray *predicates = [self _filterPredicatesForMode:mode withFilter:filter];
|
||||||
|
if(predicates) {
|
||||||
|
NSPredicate *fullFilter = [NSCompoundPredicate orPredicateWithSubpredicates:predicates];
|
||||||
|
return [[document.root childEntries] filteredArrayUsingPredicate:fullFilter];
|
||||||
|
}
|
||||||
|
/* No filter, just return everything */
|
||||||
|
return [document.root childEntries];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSArray *)optionsEnabledInMode:(MPFilterMode)mode {
|
||||||
|
NSArray *allOptions = @[ @(MPFilterUrls), @(MPFilterUsernames),
|
||||||
|
@(MPFilterTitles), @(MPFilterPasswords) ,
|
||||||
|
@(MPFilterNotes), @(MPFilterDoublePasswords) ];
|
||||||
|
|
||||||
|
NSIndexSet *indexes = [allOptions indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
|
||||||
|
MPFilterMode flag = [obj integerValue];
|
||||||
|
return MPTestFlagInOptions(flag, mode);
|
||||||
|
}];
|
||||||
|
return [allOptions objectsAtIndexes:indexes];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSArray *)_filterPredicatesForMode:(MPFilterMode)mode withFilter:(NSString *)filter{
|
||||||
|
NSMutableArray *prediactes = [[NSMutableArray alloc] initWithCapacity:4];
|
||||||
|
|
||||||
|
if(MPTestFlagInOptions(MPFilterTitles, mode)) {
|
||||||
|
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.title CONTAINS[cd] %@", filter]];
|
||||||
|
}
|
||||||
|
if(MPTestFlagInOptions(MPFilterUsernames, mode)) {
|
||||||
|
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.username CONTAINS[cd] %@", filter]];
|
||||||
|
}
|
||||||
|
if(MPTestFlagInOptions(MPFilterUrls, mode)) {
|
||||||
|
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.url CONTAINS[cd] %@", filter]];
|
||||||
|
}
|
||||||
|
if(MPTestFlagInOptions(MPFilterPasswords, mode)) {
|
||||||
|
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.password CONTAINS[cd] %@", filter]];
|
||||||
|
}
|
||||||
|
if(MPTestFlagInOptions(MPFilterNotes, mode)) {
|
||||||
|
[prediactes addObject:[NSPredicate predicateWithFormat:@"SELF.notes CONTAINS[cd] %@", filter]];
|
||||||
|
}
|
||||||
|
return prediactes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
#import "MPPasteBoardController.h"
|
#import "MPPasteBoardController.h"
|
||||||
#import "MPOverlayWindowController.h"
|
#import "MPOverlayWindowController.h"
|
||||||
#import "MPContextBarViewController.h"
|
#import "MPContextBarViewController.h"
|
||||||
|
#import "MPEntryFilterHelper.h"
|
||||||
|
|
||||||
#import "MPContextMenuHelper.h"
|
#import "MPContextMenuHelper.h"
|
||||||
#import "MPActionHelper.h"
|
#import "MPActionHelper.h"
|
||||||
@@ -299,7 +300,7 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
|
|||||||
if(document.selectedItem == document.selectedGroup) {
|
if(document.selectedItem == document.selectedGroup) {
|
||||||
/* If we change to a group selection, we should clear the filter */
|
/* If we change to a group selection, we should clear the filter */
|
||||||
if(_isDisplayingContextBar) {
|
if(_isDisplayingContextBar) {
|
||||||
[self.contextBarViewController exitFilter];
|
[self.contextBarViewController exitFilter: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];
|
||||||
@@ -333,14 +334,10 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
|
|||||||
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
|
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
|
||||||
dispatch_async(backgroundQueue, ^{
|
dispatch_async(backgroundQueue, ^{
|
||||||
MPDocument *document = [[self windowController] document];
|
MPDocument *document = [[self windowController] document];
|
||||||
NSArray *predicates = [self.contextBarViewController filterPredicates];
|
|
||||||
if(predicates) {
|
self.filteredEntries = [MPEntryFilterHelper entriesInDocument:document
|
||||||
NSPredicate *fullFilter = [NSCompoundPredicate orPredicateWithSubpredicates:predicates];
|
matching:self.contextBarViewController.filterString
|
||||||
self.filteredEntries = [[document.root childEntries] filteredArrayUsingPredicate:fullFilter];
|
usingFilterMode:self.contextBarViewController.filterMode];
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.filteredEntries = [document.root childEntries];
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
document.selectedEntry = nil;
|
document.selectedEntry = nil;
|
||||||
|
|||||||
27
MacPass/MPFlagsHelper.h
Normal file
27
MacPass/MPFlagsHelper.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// MPFlagsHelper.h
|
||||||
|
// MacPass
|
||||||
|
//
|
||||||
|
// Created by Michael Starke on 28/01/14.
|
||||||
|
// Copyright (c) 2014 HicknHack Software GmbH. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef MacPass_MPFlagsHelper_h
|
||||||
|
#define MacPass_MPFlagsHelper_h
|
||||||
|
|
||||||
|
#include <Foundation/Foundation.h>
|
||||||
|
/**
|
||||||
|
* Tests if the given flag is set in the mode options.
|
||||||
|
* The test operatats on bit flag leve. Hence it will return YES
|
||||||
|
* if only one single bit is common in both parameters!
|
||||||
|
*
|
||||||
|
* @param options single flag to test for
|
||||||
|
* @param flag options to test for flag
|
||||||
|
*
|
||||||
|
* @return YES if any bit of flag is set in mode
|
||||||
|
*/
|
||||||
|
static BOOL MPTestFlagInOptions(const NSUInteger flag, const NSUInteger options ) {
|
||||||
|
return (0 != (options & flag));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user