You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

256 lines
7.3 KiB

  1. /*
  2. Copyright 2017 Virgil Dupras
  3. This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
  4. which should be included with this package. The terms are also available at
  5. http://www.gnu.org/licenses/gpl-3.0.html
  6. */
  7. #import "DirectoryPanel.h"
  8. #import "Dialogs.h"
  9. #import "Utils.h"
  10. #import "AppDelegate.h"
  11. #import "Consts.h"
  12. @implementation DirectoryPanel
  13. @synthesize appModeSelector;
  14. @synthesize scanTypePopup;
  15. @synthesize addButtonPopUp;
  16. @synthesize loadRecentButtonPopUp;
  17. @synthesize outlineView;
  18. @synthesize removeButton;
  19. @synthesize loadResultsButton;
  20. - (id)initWithParentApp:(AppDelegate *)aParentApp
  21. {
  22. self = [super initWithWindowNibName:@"DirectoryPanel"];
  23. [self window];
  24. _app = aParentApp;
  25. model = [_app model];
  26. [[self window] setTitle:[model appName]];
  27. self.appModeSelector.selectedSegment = 0;
  28. [self fillScanTypeMenu];
  29. _alwaysShowPopUp = NO;
  30. [self fillPopUpMenu];
  31. _recentDirectories = [[HSRecentFiles alloc] initWithName:@"recentDirectories" menu:[addButtonPopUp menu]];
  32. [_recentDirectories setDelegate:self];
  33. outline = [[DirectoryOutline alloc] initWithPyRef:[model directoryTree] outlineView:outlineView];
  34. [self refreshRemoveButtonText];
  35. [self adjustUIToLocalization];
  36. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(directorySelectionChanged:)
  37. name:NSOutlineViewSelectionDidChangeNotification object:outlineView];
  38. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(outlineAddedFolders:)
  39. name:DGAddedFoldersNotification object:outline];
  40. return self;
  41. }
  42. - (void)dealloc
  43. {
  44. [outline release];
  45. [_recentDirectories release];
  46. [super dealloc];
  47. }
  48. /* Private */
  49. - (void)fillPopUpMenu
  50. {
  51. NSMenu *m = [addButtonPopUp menu];
  52. NSMenuItem *mi = [m addItemWithTitle:NSLocalizedString(@"Add New Folder...", @"") action:@selector(askForDirectory) keyEquivalent:@""];
  53. [mi setTarget:self];
  54. [m addItem:[NSMenuItem separatorItem]];
  55. }
  56. - (void)fillScanTypeMenu
  57. {
  58. [[self scanTypePopup] unbind:@"selectedIndex"];
  59. [[self scanTypePopup] removeAllItems];
  60. [[self scanTypePopup] addItemsWithTitles:[[_app model] getScanOptions]];
  61. NSString *keypath;
  62. NSInteger appMode = [_app getAppMode];
  63. if (appMode == AppModePicture) {
  64. keypath = @"values.scanTypePicture";
  65. }
  66. else if (appMode == AppModeMusic) {
  67. keypath = @"values.scanTypeMusic";
  68. }
  69. else {
  70. keypath = @"values.scanTypeStandard";
  71. }
  72. [[self scanTypePopup] bind:@"selectedIndex" toObject:[NSUserDefaultsController sharedUserDefaultsController] withKeyPath:keypath options:nil];
  73. }
  74. - (void)adjustUIToLocalization
  75. {
  76. NSString *lang = [[NSBundle preferredLocalizationsFromArray:[[NSBundle mainBundle] localizations]] objectAtIndex:0];
  77. NSInteger loadResultsWidthDelta = 0;
  78. if ([lang isEqual:@"ru"]) {
  79. loadResultsWidthDelta = 50;
  80. }
  81. else if ([lang isEqual:@"uk"]) {
  82. loadResultsWidthDelta = 70;
  83. }
  84. else if ([lang isEqual:@"hy"]) {
  85. loadResultsWidthDelta = 30;
  86. }
  87. if (loadResultsWidthDelta) {
  88. NSRect r = [loadResultsButton frame];
  89. r.size.width += loadResultsWidthDelta;
  90. r.origin.x -= loadResultsWidthDelta;
  91. [loadResultsButton setFrame:r];
  92. }
  93. }
  94. /* Actions */
  95. - (void)askForDirectory
  96. {
  97. NSOpenPanel *op = [NSOpenPanel openPanel];
  98. [op setCanChooseFiles:YES];
  99. [op setCanChooseDirectories:YES];
  100. [op setAllowsMultipleSelection:YES];
  101. [op setTitle:NSLocalizedString(@"Select a folder to add to the scanning list", @"")];
  102. [op setDelegate:self];
  103. if ([op runModal] == NSModalResponseOK) {
  104. for (NSURL *directoryURL in [op URLs]) {
  105. [self addDirectory:[directoryURL path]];
  106. }
  107. }
  108. }
  109. - (IBAction)changeAppMode:(id)sender
  110. {
  111. NSInteger appMode;
  112. NSUInteger selectedSegment = self.appModeSelector.selectedSegment;
  113. if (selectedSegment == 2) {
  114. appMode = AppModePicture;
  115. }
  116. else if (selectedSegment == 1) {
  117. appMode = AppModeMusic;
  118. }
  119. else {
  120. appMode = AppModeStandard;
  121. }
  122. [_app setAppMode:appMode];
  123. [self fillScanTypeMenu];
  124. }
  125. - (IBAction)popupAddDirectoryMenu:(id)sender
  126. {
  127. if ((!_alwaysShowPopUp) && ([[_recentDirectories filepaths] count] == 0)) {
  128. [self askForDirectory];
  129. }
  130. else {
  131. [addButtonPopUp selectItem:nil];
  132. [[addButtonPopUp cell] performClickWithFrame:[sender frame] inView:[sender superview]];
  133. }
  134. }
  135. - (IBAction)popupLoadRecentMenu:(id)sender
  136. {
  137. if ([[[_app recentResults] filepaths] count] > 0) {
  138. NSMenu *m = [loadRecentButtonPopUp menu];
  139. while ([m numberOfItems] > 0) {
  140. [m removeItemAtIndex:0];
  141. }
  142. NSMenuItem *mi = [m addItemWithTitle:NSLocalizedString(@"Load from file...", @"") action:@selector(loadResults:) keyEquivalent:@""];
  143. [mi setTarget:_app];
  144. [m addItem:[NSMenuItem separatorItem]];
  145. [[_app recentResults] fillMenu:m];
  146. [loadRecentButtonPopUp selectItem:nil];
  147. [[loadRecentButtonPopUp cell] performClickWithFrame:[sender frame] inView:[sender superview]];
  148. }
  149. else {
  150. [_app loadResults:sender];
  151. }
  152. }
  153. - (IBAction)removeSelectedDirectory:(id)sender
  154. {
  155. [[self window] makeKeyAndOrderFront:nil];
  156. [[outline model] removeSelectedDirectory];
  157. [self refreshRemoveButtonText];
  158. }
  159. - (IBAction)startDuplicateScan:(id)sender
  160. {
  161. if ([model resultsAreModified]) {
  162. if ([Dialogs askYesNo:NSLocalizedString(@"You have unsaved results, do you really want to continue?", @"")] == NSAlertSecondButtonReturn) // NO
  163. return;
  164. }
  165. [_app setScanOptions];
  166. [model doScan];
  167. }
  168. /* Public */
  169. - (void)addDirectory:(NSString *)directory
  170. {
  171. [model addDirectory:directory];
  172. [_recentDirectories addFile:directory];
  173. [[self window] makeKeyAndOrderFront:nil];
  174. }
  175. - (void)refreshRemoveButtonText
  176. {
  177. if ([outlineView selectedRow] < 0) {
  178. [removeButton setEnabled:NO];
  179. return;
  180. }
  181. [removeButton setEnabled:YES];
  182. NSIndexPath *path = [outline selectedIndexPath];
  183. if (path != nil) {
  184. NSInteger state = [outline intProperty:@"state" valueAtPath:path];
  185. BOOL shouldDisplayArrow = ([path length] > 1) && (state == 2);
  186. NSString *imgName = shouldDisplayArrow ? @"NSGoLeftTemplate" : @"NSRemoveTemplate";
  187. [removeButton setImage:[NSImage imageNamed:imgName]];
  188. }
  189. }
  190. - (void)markAll
  191. {
  192. /* markAll isn't very descriptive of what we do, but since we re-use the Mark All button from
  193. the result window, we don't have much choice.
  194. */
  195. [outline selectAll];
  196. }
  197. /* Delegate */
  198. - (BOOL)panel:(id)sender shouldShowFilename:(NSString *)path
  199. {
  200. BOOL isdir;
  201. [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isdir];
  202. return isdir;
  203. }
  204. - (void)recentFileClicked:(NSString *)path
  205. {
  206. [self addDirectory:path];
  207. }
  208. - (BOOL)validateMenuItem:(NSMenuItem *)item
  209. {
  210. if ([item action] == @selector(markAll)) {
  211. [item setTitle:NSLocalizedString(@"Select All", @"")];
  212. }
  213. return YES;
  214. }
  215. /* Notifications */
  216. - (void)directorySelectionChanged:(NSNotification *)aNotification
  217. {
  218. [self refreshRemoveButtonText];
  219. }
  220. - (void)outlineAddedFolders:(NSNotification *)aNotification
  221. {
  222. NSArray *foldernames = [[aNotification userInfo] objectForKey:@"foldernames"];
  223. for (NSString *foldername in foldernames) {
  224. [_recentDirectories addFile:foldername];
  225. }
  226. }
  227. @end