diff --git a/cocoa/base/PyDupeGuru.h b/cocoa/base/PyDupeGuru.h index 28f830b0..7879caa9 100644 --- a/cocoa/base/PyDupeGuru.h +++ b/cocoa/base/PyDupeGuru.h @@ -20,6 +20,7 @@ http://www.hardcoded.net/licenses/hs_license - (void)clearIgnoreList; - (void)purgeIgnoreList; - (NSString *)exportToXHTMLwithColumns:(NSArray *)aColIds; +- (void)invokeCommand:(NSString *)cmd; - (NSNumber *)doScan; diff --git a/cocoa/base/ResultWindow.h b/cocoa/base/ResultWindow.h index 4bf6bd7f..3df5601c 100644 --- a/cocoa/base/ResultWindow.h +++ b/cocoa/base/ResultWindow.h @@ -48,6 +48,7 @@ http://www.hardcoded.net/licenses/hs_license - (IBAction)exportToXHTML:(id)sender; - (IBAction)filter:(id)sender; - (IBAction)ignoreSelected:(id)sender; +- (IBAction)invokeCustomCommand:(id)sender; - (IBAction)markAll:(id)sender; - (IBAction)markInvert:(id)sender; - (IBAction)markNone:(id)sender; diff --git a/cocoa/base/ResultWindow.m b/cocoa/base/ResultWindow.m index fa273c8e..4c60c20d 100644 --- a/cocoa/base/ResultWindow.m +++ b/cocoa/base/ResultWindow.m @@ -200,6 +200,13 @@ http://www.hardcoded.net/licenses/hs_license [py addSelectedToIgnoreList]; } +- (IBAction)invokeCustomCommand:(id)sender +{ + NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; + NSString *cmd = [ud stringForKey:@"CustomCommand"]; + [py invokeCommand:cmd]; +} + - (IBAction)markAll:(id)sender { [py markAll]; diff --git a/cocoa/base/xib/MainMenu.xib b/cocoa/base/xib/MainMenu.xib index 686991fa..ea7f76be 100644 --- a/cocoa/base/xib/MainMenu.xib +++ b/cocoa/base/xib/MainMenu.xib @@ -2,18 +2,18 @@ 1050 - 10C540 + 10D573 740 - 1038.25 - 458.00 + 1038.29 + 460.00 com.apple.InterfaceBuilder.CocoaPlugin 740 YES + - YES @@ -1146,7 +1146,7 @@ Clear Ignore List - I + G 1048576 2147483647 @@ -1231,7 +1231,7 @@ Add Selected to Ignore List - i + g 1048576 2147483647 @@ -1275,6 +1275,15 @@ + + + Invoke Custom Command + i + 1048576 + 2147483647 + + + Rename Selected @@ -2204,6 +2213,14 @@ 1176 + + + invokeCustomCommand: + + + + 1178 + @@ -2530,6 +2547,7 @@ + @@ -3066,6 +3084,11 @@ + + 1177 + + + @@ -3117,6 +3140,7 @@ 1171.IBPluginDependency 1172.IBPluginDependency 1173.IBPluginDependency + 1177.IBPluginDependency 134.IBPluginDependency 134.ImportedFromIB2 136.IBPluginDependency @@ -3355,6 +3379,7 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -3374,9 +3399,9 @@ - {{109, 366}, {557, 400}} + {{439, 345}, {557, 400}} com.apple.InterfaceBuilder.CocoaPlugin - {{109, 366}, {557, 400}} + {{439, 345}, {557, 400}} @@ -3423,7 +3448,7 @@ com.apple.InterfaceBuilder.CocoaPlugin - {{286, 475}, {361, 293}} + {{286, 455}, {361, 313}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -3561,7 +3586,7 @@ - 1176 + 1178 @@ -3776,8 +3801,17 @@ ResultWindow ResultWindowBase - removeDeadTracks: - id + YES + + YES + resetColumnsToDefault: + startDuplicateScan: + + + YES + id + id + IBProjectSource @@ -3799,6 +3833,7 @@ exportToXHTML: filter: ignoreSelected: + invokeCustomCommand: markAll: markInvert: markNone: @@ -3848,6 +3883,7 @@ id id id + id @@ -4500,7 +4536,7 @@ YES - ../../me/dupeguru.xcodeproj + ../../se/dupeguru.xcodeproj 3 diff --git a/cocoa/se/xib/Preferences.xib b/cocoa/se/xib/Preferences.xib index 53e8eca3..93686d93 100644 --- a/cocoa/se/xib/Preferences.xib +++ b/cocoa/se/xib/Preferences.xib @@ -2,10 +2,10 @@ 1050 - 10C540 + 10D573 740 - 1038.25 - 458.00 + 1038.29 + 460.00 com.apple.InterfaceBuilder.CocoaPlugin 740 @@ -39,16 +39,12 @@ NSApplication - - YES - SUEnableAutomaticChecks - YES 3 2 - {{92, 276}, {352, 326}} + {{92, 269}, {389, 333}} 1886912512 dupeGuru Preferences @@ -64,325 +60,21 @@ 256 YES - - - 292 - {{120, 247}, {181, 21}} - - YES - - 67239424 - 0 - - - - - Helvetica - 12 - 16 - - - 100 - 1 - 80 - 0.0 - 0 - 1 - NO - NO - - - - - 292 - {{122, 230}, {80, 13}} - - YES - - 67239424 - 272629760 - More results - - LucidaGrande - 10 - 2843 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - - - - 289 - {{219, 230}, {80, 13}} - - YES - - 67239424 - 71303168 - Fewer results - - - - - - - - - 292 - {{17, 252}, {100, 14}} - - YES - - 67239424 - 272629760 - Filter hardness: - - LucidaGrande - 11 - 3100 - - - - - - - - - 292 - {{20, 293}, {85, 13}} - - YES - - 67239424 - 272629760 - Scan type: - - - - - - - - - 292 - {{119, 282}, {216, 26}} - - YES - - -2076049856 - 2048 - - LucidaGrande - 13 - 1044 - - - 109199615 - 1 - - - - - - 400 - 75 - - - Filename - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - - - YES - - - OtherViews - - - YES - - - - Content - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - 3 - YES - YES - 1 - - - - - 256 - {{18, 206}, {214, 18}} - - YES - - 67239424 - 0 - Word weighting - - - 1211912703 - 2 - - NSSwitch - - - - 200 - 25 - - - - - 256 - {{18, 166}, {214, 18}} - - YES - - 67239424 - 0 - Can mix file kind - - - 1211912703 - 2 - - - - 200 - 25 - - - - - 256 - {{304, 252}, {31, 14}} - - YES - - 67239424 - -1874853888 - - - - - YES - - YES - allowsFloats - attributedStringForZero - decimalSeparator - formatterBehavior - groupingSeparator - negativeFormat - positiveFormat - usesGroupingSeparator - - - YES - - - 0 - - YES - - - YES - - - - . - - , - -0 - 0 - - - - 0 - -0 - - - - - - - - NaN - - - - 0 - 0 - YES - NO - 1 - AAAAAAAAAAAAAAAAAAAAAA - - - - . - , - NO - YES - YES - - - - - - 256 - {{190, 12}, {148, 32}} + {{227, 12}, {148, 32}} YES 67239424 134217728 Reset to Defaults - + + LucidaGrande + 13 + 1044 + -2038284033 1 @@ -395,297 +87,681 @@ 25 - + - 256 - {{18, 186}, {214, 18}} + 12 + {{13, 40}, {363, 287}} - YES - - 67239424 - 0 - Match similar words - - - 1211912703 - 2 - - - - 200 - 25 - - - - - 292 - {{20, 67}, {85, 13}} - - YES - - 67239424 - 272629760 - Copy and Move: - - - - - - - - - 292 - {{110, 56}, {216, 26}} - - YES - - -2076049856 - 2048 - - - 109199615 - 1 - - - - - - 400 - 75 - - - Right in destination - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - YES - - - - Recreate relative path - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - Recreate absolute path - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - 3 - YES - YES - 1 - - - - - 256 - {{18, 86}, {283, 18}} - - YES - - 67239424 - 0 - Automatically check for updates - - - 1211912703 - 2 - - - - 200 - 25 - - - - - 256 - {{18, 146}, {228, 18}} - - YES - - 67239424 - 0 - Use regular expressions when filtering - - - 1211912703 - 2 - - - - 200 - 25 - - - - - 256 - {{18, 126}, {242, 18}} - - YES - - 67239424 - 0 - Remove empty folders on delete or move - - - 1211912703 - 2 - - - - 200 - 25 - - - - - 256 - {{18, 106}, {152, 18}} - - YES - - 67239424 - 0 - Ignore files smaller than - - - 1211912703 - 2 - - - - 200 - 25 - - - - - 268 - {{176, 104}, {59, 22}} - - YES - - -1804468671 - -1874852864 - - - - - YES - + + YES + + 1 + + + 256 + YES - allowsFloats - formatterBehavior - locale - maximumFractionDigits - numberStyle - positiveFormat - roundingIncrement - usesGroupingSeparator - - - YES - - - - + + + 292 + {{117, 179}, {181, 21}} + + YES + + 67239424 + 0 + + + + + Helvetica + 12 + 16 + + + 100 + 1 + 80 + 0.0 + 0 + 1 + NO + NO + + + + + 292 + {{119, 162}, {80, 13}} + + YES + + 67239424 + 272629760 + More results + + LucidaGrande + 10 + 2843 + + + + 6 + System + controlColor + + 3 + MC42NjY2NjY2NjY3AA + + + + 6 + System + controlTextColor + + 3 + MAA + + + + + + + 289 + {{216, 162}, {80, 13}} + + YES + + 67239424 + 71303168 + Fewer results + + + + + + + + + 292 + {{14, 184}, {100, 14}} + + YES + + 67239424 + 272629760 + Filter hardness: + + LucidaGrande + 11 + 3100 + + + + + + + + + 292 + {{17, 225}, {85, 13}} + + YES + + 67239424 + 272629760 + Scan type: + + + + + + + + + 292 + {{116, 214}, {216, 26}} + + YES + + -2076049856 + 2048 + + + 109199615 + 1 + + + + + + 400 + 75 + + + Filename + + 1048576 + 2147483647 + 1 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + _popUpItemAction: + + + YES + + + OtherViews + + + YES + + + + Content + + 1048576 + 2147483647 + + + _popUpItemAction: + + + + + 3 + YES + YES + 1 + + + + + 256 + {{15, 138}, {214, 18}} + + YES + + 67239424 + 0 + Word weighting + + + 1211912703 + 2 + + NSSwitch + + + + 200 + 25 + + + + + 256 + {{15, 98}, {214, 18}} + + YES + + 67239424 + 0 + Can mix file kind + + + 1211912703 + 2 + + + + 200 + 25 + + + + + 256 + {{15, 118}, {214, 18}} + + YES + + 67239424 + 0 + Match similar words + + + 1211912703 + 2 + + + + 200 + 25 + + + + + 292 + {{17, 17}, {85, 13}} + + YES + + 67239424 + 272629760 + Copy and Move: + + + + + + + + + 292 + {{107, 6}, {216, 26}} + + YES + + -2076049856 + 2048 + + + 109199615 + 1 + + + + + + 400 + 75 + + + Right in destination + + 1048576 + 2147483647 + 1 + + + _popUpItemAction: + + + YES + + + OtherViews + + + YES + + + + Recreate relative path + + 1048576 + 2147483647 + + + _popUpItemAction: + + + + + Recreate absolute path + + 1048576 + 2147483647 + + + _popUpItemAction: + + + + + 3 + YES + YES + 1 + + + + + 256 + {{15, 36}, {283, 18}} + + YES + + 67239424 + 0 + Automatically check for updates + + + 1211912703 + 2 + + + + 200 + 25 + + + + + 256 + {{15, 76}, {242, 18}} + + YES + + 67239424 + 0 + Remove empty folders on delete or move + + + 1211912703 + 2 + + + + 200 + 25 + + + + + 256 + {{15, 56}, {152, 18}} + + YES + + 67239424 + 0 + Ignore files smaller than + + + 1211912703 + 2 + + + + 200 + 25 + + + + + 268 + {{173, 54}, {59, 22}} + + YES + + -1804468671 + -1874852864 + + + + + YES + + YES + allowsFloats + formatterBehavior + locale + maximumFractionDigits + numberStyle + positiveFormat + roundingIncrement + usesGroupingSeparator + + + YES + + + + + + + + #0 + + + + + #0 + #0 + + + + + + NaN + + YES + + + YES + + + + + 0 + 0 + YES + NO + 1 + AAAAAAAAAAAAAAAAAAAAAA + + + + 3 + YES + YES + YES + + . + , + NO + NO + NO + + + YES + + 6 + System + textBackgroundColor + + 3 + MQA + + + + 6 + System + textColor + + + + + + + 292 + {{240, 56}, {23, 17}} + + YES + + 67239424 + 272629760 + KB + + + + + + + + + 256 + {{301, 184}, {31, 14}} + + YES + + 67239424 + -1874853888 + + + + + YES + + YES + allowsFloats + attributedStringForZero + decimalSeparator + formatterBehavior + groupingSeparator + negativeFormat + positiveFormat + usesGroupingSeparator + + + YES + + + 0 + + + . + + , + -0 + 0 + + + + 0 + -0 + + + + + + + + NaN + + + + + + . + , + NO + YES + YES + + + + + - - - #0 - - + {{10, 33}, {343, 241}} + - #0 - #0 - - - - - - NaN - - - - - - 3 - YES - YES - YES - - . - , - NO - NO - NO + Basic + + - - YES - - 6 - System - textBackgroundColor - - 3 - MQA + + 2 + + + 256 + + YES + + + 256 + {{15, 222}, {228, 18}} + + YES + + 67239424 + 0 + Use regular expressions when filtering + + + 1211912703 + 2 + + + + 200 + 25 + + + + + 292 + {{14, 199}, {315, 17}} + + YES + + 67239424 + 272629760 + Custom command (arguments: %d for dupe, %r for ref): + + + + + + + + + 266 + {{17, 169}, {309, 22}} + + YES + + -1804468671 + 272630784 + + + + YES + + + + + + {{10, 33}, {343, 241}} - - - 6 - System - textColor - + Advanced + + - - - - 292 - {{243, 106}, {23, 17}} - - YES - - 67239424 - 272629760 - KB - - - - + + + 0 + YES + YES + + YES + - {352, 326} + {389, 333} {{0, 0}, {1440, 878}} @@ -864,22 +940,6 @@ 113 - - - value: values.useRegexpFilter - - - - - - value: values.useRegexpFilter - value - values.useRegexpFilter - 2 - - - 114 - selectedIndex: values.scanType @@ -976,6 +1036,38 @@ 122 + + + value: values.useRegexpFilter + + + + + + value: values.useRegexpFilter + value + values.useRegexpFilter + 2 + + + 130 + + + + value: values.CustomCommand + + + + + + value: values.CustomCommand + value + values.CustomCommand + 2 + + + 140 + @@ -1025,109 +1117,11 @@ YES - - - - - - - - - - - - - - - - - - + - - 54 - - - YES - - - - - - 55 - - - YES - - - - - - 56 - - - YES - - - - - - 57 - - - YES - - - - - - 58 - - - YES - - - - - - 59 - - - YES - - - - - - 60 - - - YES - - - - - - 61 - - - YES - - - - - - 62 - - - YES - - - - 63 @@ -1138,76 +1132,73 @@ - 64 - + 86 + + + + + 123 + YES - + + - 65 - + 124 + YES - + - + - 66 - + 125 + YES - + - + - 67 - + 126 + YES - + + + - + - 68 - + 127 + YES - + + + + + + + + + + + + + + + + + - - - - 69 - - - YES - - - - - - 70 - - - YES - - - - - - 71 - - - YES - - - + 72 @@ -1216,33 +1207,78 @@ YES - + 73 + + 71 + + + YES + + + + 74 + + 70 + + + YES + + + + 75 + + 69 + + + YES + + + + 76 + + 68 + + + YES + + + + 77 + + 67 + + + YES + + + + 78 @@ -1257,60 +1293,86 @@ YES - + - - 80 - - - 81 + + 80 + + + + + 66 + + + YES + + + + 82 + + 65 + + + YES + + + + 83 - 84 - + 62 + YES - + - - - - 85 - - - - - 86 - - + 87 + + 61 + + + YES + + + + 88 + + 60 + + + YES + + + + 89 @@ -1325,15 +1387,15 @@ YES - - + + - 91 - + 93 + @@ -1342,30 +1404,61 @@ - 93 - + 91 + + + 59 + + + YES + + + + 94 - 95 - - + 57 + + + YES + + + 96 + + 56 + + + YES + + + + 97 + + 55 + + + YES + + + + 98 @@ -1380,11 +1473,85 @@ + + 54 + + + YES + + + + 100 + + 128 + + + YES + + + + + + 129 + + + + + 133 + + + YES + + + + + + 134 + + + + + 138 + + + YES + + + + + + 139 + + + + + 64 + + + YES + + + + + + 84 + + + YES + + + + + + 85 + + + @@ -1393,6 +1560,19 @@ YES -3.IBPluginDependency 100.IBPluginDependency + 123.IBPluginDependency + 124.IBPluginDependency + 125.IBPluginDependency + 126.IBPluginDependency + 127.IBPluginDependency + 128.IBPluginDependency + 128.ImportedFromIB2 + 129.IBPluginDependency + 133.IBPluginDependency + 133.ImportedFromIB2 + 134.IBPluginDependency + 138.IBPluginDependency + 139.IBPluginDependency 51.IBPluginDependency 51.ImportedFromIB2 52.IBEditorWindowLastContentRect @@ -1411,8 +1591,6 @@ 56.ImportedFromIB2 57.IBPluginDependency 57.ImportedFromIB2 - 58.IBPluginDependency - 58.ImportedFromIB2 59.IBPluginDependency 59.ImportedFromIB2 60.IBPluginDependency @@ -1471,7 +1649,6 @@ 93.IBPluginDependency 93.ImportedFromIB2 94.IBPluginDependency - 95.IBPluginDependency 96.IBPluginDependency 97.IBPluginDependency 98.IBPluginDependency @@ -1484,10 +1661,23 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - - {{88, 519}, {352, 326}} com.apple.InterfaceBuilder.CocoaPlugin - {{88, 519}, {352, 326}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + {{88, 512}, {389, 333}} + com.apple.InterfaceBuilder.CocoaPlugin + {{88, 512}, {389, 333}} {213, 107} @@ -1530,8 +1720,6 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1564,7 +1752,6 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1586,7 +1773,7 @@ - 122 + 140 @@ -2044,6 +2231,22 @@ AppKit.framework/Headers/NSSliderCell.h + + NSTabView + NSView + + IBFrameworkSource + AppKit.framework/Headers/NSTabView.h + + + + NSTabViewItem + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSTabViewItem.h + + NSTextField NSControl diff --git a/core/app.py b/core/app.py index 296aaea3..00803338 100644 --- a/core/app.py +++ b/core/app.py @@ -11,6 +11,7 @@ from __future__ import unicode_literals import os import os.path as op import logging +import subprocess from send2trash import send2trash from hsutil import io, files @@ -218,6 +219,22 @@ class DupeGuru(RegistrableApplication, Broadcaster): rows.append(row) return export.export_to_xhtml(colnames, rows) + def invoke_command(self, cmd): + """Calls command `cmd` with %d and %r placeholders replaced. + + Using the current selection, %d is replaced with the currently selected dupe and %r is + replaced with that dupe's ref file. If there's no selection, the command is not invoked. + If the dupe is a ref, %d and %r will be the same. + """ + if not self.selected_dupes: + return + dupe = self.selected_dupes[0] + group = self.results.get_group_of_duplicate(dupe) + ref = group.ref + cmd = cmd.replace('%d', unicode(dupe.path)) + cmd = cmd.replace('%r', unicode(ref.path)) + subprocess.Popen(cmd, shell=True) + def load(self): self._start_job(JOB_LOAD, self._do_load) self.load_ignore_list() diff --git a/core/app_cocoa_inter.py b/core/app_cocoa_inter.py index 0a0a1d68..b5e166eb 100644 --- a/core/app_cocoa_inter.py +++ b/core/app_cocoa_inter.py @@ -95,6 +95,9 @@ class PyDupeGuruBase(PyRegistrable): def revealSelected(self): self.py.reveal_selected() + def invokeCommand_(self, cmd): + self.py.invoke_command(cmd) + #---Information def getIgnoreListCount(self): return len(self.py.scanner.ignore_list)