dupeguru-cocoa/cocoa/ResultWindow.m

415 lines
12 KiB
Mathematica
Raw Permalink Normal View History

2017-03-11 19:18:27 -06:00
/*
2017-04-03 22:04:01 -05:00
Copyright 2017 Virgil Dupras
2017-03-11 19:18:27 -06:00
This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at
http://www.gnu.org/licenses/gpl-3.0.html
*/
#import "ResultWindow.h"
#import "Dialogs.h"
#import "ProgressController.h"
#import "Utils.h"
#import "AppDelegate.h"
#import "Consts.h"
#import "PrioritizeDialog.h"
@implementation ResultWindow
@synthesize optionsSwitch;
@synthesize optionsToolbarItem;
@synthesize matches;
@synthesize stats;
@synthesize filterField;
- (id)initWithParentApp:(AppDelegate *)aApp;
{
2017-04-03 22:04:01 -05:00
self = [super initWithWindowNibName:@"ResultWindow"];
[self window];
2017-03-11 19:18:27 -06:00
app = aApp;
model = [app model];
/* Put a cute iTunes-like bottom bar */
[[self window] setContentBorderThickness:28 forEdge:NSMinYEdge];
table = [[ResultTable alloc] initWithPyRef:[model resultTable] view:matches];
statsLabel = [[StatsLabel alloc] initWithPyRef:[model statsLabel] view:stats];
[self initResultColumns:table];
[[table columns] setColumnsAsReadOnly];
[self fillColumnsMenu];
[matches setTarget:self];
2017-04-03 22:40:48 -05:00
[matches setDoubleAction:@selector(openClicked:)];
2017-03-11 19:18:27 -06:00
[self adjustUIToLocalization];
return self;
}
- (void)dealloc
{
[table release];
[statsLabel release];
[super dealloc];
}
/* Helpers */
- (void)fillColumnsMenu
{
[[app columnsMenu] removeAllItems];
NSArray *menuItems = [[[table columns] model] menuItems];
for (NSInteger i=0; i < [menuItems count]; i++) {
NSArray *pair = [menuItems objectAtIndex:i];
NSString *display = [pair objectAtIndex:0];
BOOL marked = n2b([pair objectAtIndex:1]);
NSMenuItem *mi = [[app columnsMenu] addItemWithTitle:display action:@selector(toggleColumn:) keyEquivalent:@""];
[mi setTarget:self];
[mi setState:marked ? NSControlStateValueOn : NSControlStateValueOff];
2017-03-11 19:18:27 -06:00
[mi setTag:i];
}
[[app columnsMenu] addItem:[NSMenuItem separatorItem]];
NSMenuItem *mi = [[app columnsMenu] addItemWithTitle:NSLocalizedString(@"Reset to Default", @"")
2017-04-03 22:40:48 -05:00
action:@selector(resetColumnsToDefault:) keyEquivalent:@""];
2017-03-11 19:18:27 -06:00
[mi setTarget:self];
}
- (void)updateOptionSegments
{
[optionsSwitch setSelected:[[app detailsPanel] isVisible] forSegment:0];
[optionsSwitch setSelected:[table powerMarkerMode] forSegment:1];
[optionsSwitch setSelected:[table deltaValuesMode] forSegment:2];
}
- (void)adjustUIToLocalization
{
NSString *lang = [[NSBundle preferredLocalizationsFromArray:[[NSBundle mainBundle] localizations]] objectAtIndex:0];
NSInteger seg1delta = 0;
NSInteger seg2delta = 0;
if ([lang isEqual:@"ru"]) {
seg2delta = 20;
}
else if ([lang isEqual:@"uk"]) {
seg2delta = 20;
}
else if ([lang isEqual:@"hy"]) {
seg1delta = 20;
}
if (seg1delta || seg2delta) {
[optionsSwitch setWidth:[optionsSwitch widthForSegment:0]+seg1delta forSegment:0];
[optionsSwitch setWidth:[optionsSwitch widthForSegment:1]+seg2delta forSegment:1];
NSSize s = [optionsToolbarItem maxSize];
s.width += seg1delta + seg2delta;
[optionsToolbarItem setMaxSize:s];
[optionsToolbarItem setMinSize:s];
}
}
- (void)initResultColumns:(ResultTable *)aTable
{
NSInteger appMode = [app getAppMode];
if (appMode == AppModePicture) {
HSColumnDef defs[] = {
{@"marked", 26, 26, 26, YES, [NSButtonCell class]},
{@"name", 162, 16, 0, YES, nil},
{@"folder_path", 142, 16, 0, YES, nil},
{@"size", 63, 16, 0, YES, nil},
{@"extension", 40, 16, 0, YES, nil},
{@"dimensions", 73, 16, 0, YES, nil},
{@"exif_timestamp", 120, 16, 0, YES, nil},
{@"mtime", 120, 16, 0, YES, nil},
{@"percentage", 58, 16, 0, YES, nil},
{@"dupe_count", 80, 16, 0, YES, nil},
nil
};
[[aTable columns] initializeColumns:defs];
NSTableColumn *c = [[aTable view] tableColumnWithIdentifier:@"marked"];
[[c dataCell] setButtonType:NSButtonTypeSwitch];
[[c dataCell] setControlSize:NSControlSizeSmall];
2017-03-11 19:18:27 -06:00
c = [[aTable view] tableColumnWithIdentifier:@"size"];
[[c dataCell] setAlignment:NSTextAlignmentRight];
2017-03-11 19:18:27 -06:00
}
else if (appMode == AppModeMusic) {
HSColumnDef defs[] = {
{@"marked", 26, 26, 26, YES, [NSButtonCell class]},
{@"name", 235, 16, 0, YES, nil},
{@"folder_path", 120, 16, 0, YES, nil},
{@"size", 63, 16, 0, YES, nil},
{@"duration", 50, 16, 0, YES, nil},
{@"bitrate", 50, 16, 0, YES, nil},
{@"samplerate", 60, 16, 0, YES, nil},
{@"extension", 40, 16, 0, YES, nil},
{@"mtime", 120, 16, 0, YES, nil},
{@"title", 120, 16, 0, YES, nil},
{@"artist", 120, 16, 0, YES, nil},
{@"album", 120, 16, 0, YES, nil},
{@"genre", 80, 16, 0, YES, nil},
{@"year", 40, 16, 0, YES, nil},
{@"track", 40, 16, 0, YES, nil},
{@"comment", 120, 16, 0, YES, nil},
{@"percentage", 57, 16, 0, YES, nil},
{@"words", 120, 16, 0, YES, nil},
{@"dupe_count", 80, 16, 0, YES, nil},
nil
};
[[aTable columns] initializeColumns:defs];
NSTableColumn *c = [[aTable view] tableColumnWithIdentifier:@"marked"];
[[c dataCell] setButtonType:NSButtonTypeSwitch];
[[c dataCell] setControlSize:NSControlSizeSmall];
2017-03-11 19:18:27 -06:00
c = [[aTable view] tableColumnWithIdentifier:@"size"];
[[c dataCell] setAlignment:NSTextAlignmentRight];
2017-03-11 19:18:27 -06:00
c = [[aTable view] tableColumnWithIdentifier:@"duration"];
[[c dataCell] setAlignment:NSTextAlignmentRight];
2017-03-11 19:18:27 -06:00
c = [[aTable view] tableColumnWithIdentifier:@"bitrate"];
[[c dataCell] setAlignment:NSTextAlignmentRight];
2017-03-11 19:18:27 -06:00
}
else {
HSColumnDef defs[] = {
{@"marked", 26, 26, 26, YES, [NSButtonCell class]},
{@"name", 195, 16, 0, YES, nil},
{@"folder_path", 183, 16, 0, YES, nil},
{@"size", 63, 16, 0, YES, nil},
{@"extension", 40, 16, 0, YES, nil},
{@"mtime", 120, 16, 0, YES, nil},
{@"percentage", 60, 16, 0, YES, nil},
{@"words", 120, 16, 0, YES, nil},
{@"dupe_count", 80, 16, 0, YES, nil},
nil
};
[[aTable columns] initializeColumns:defs];
NSTableColumn *c = [[aTable view] tableColumnWithIdentifier:@"marked"];
[[c dataCell] setButtonType:NSButtonTypeSwitch];
[[c dataCell] setControlSize:NSControlSizeSmall];
2017-03-11 19:18:27 -06:00
c = [[aTable view] tableColumnWithIdentifier:@"size"];
[[c dataCell] setAlignment:NSTextAlignmentRight];
2017-03-11 19:18:27 -06:00
}
[[aTable columns] restoreColumns];
}
/* Actions */
2017-04-03 22:04:01 -05:00
- (IBAction)changeOptions:(id)sender
2017-03-11 19:18:27 -06:00
{
NSInteger seg = [optionsSwitch selectedSegment];
if (seg == 0) {
2017-04-03 22:04:01 -05:00
[self toggleDetailsPanel:sender];
2017-03-11 19:18:27 -06:00
}
else if (seg == 1) {
2017-04-03 22:04:01 -05:00
[self togglePowerMarker:sender];
2017-03-11 19:18:27 -06:00
}
else if (seg == 2) {
2017-04-03 22:04:01 -05:00
[self toggleDelta:sender];
2017-03-11 19:18:27 -06:00
}
}
2017-04-03 22:04:01 -05:00
- (IBAction)copyMarked:(id)sender
2017-03-11 19:18:27 -06:00
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
[model setRemoveEmptyFolders:n2b([ud objectForKey:@"removeEmptyFolders"])];
[model setCopyMoveDestType:n2i([ud objectForKey:@"recreatePathType"])];
[model copyMarked];
}
2017-04-03 22:04:01 -05:00
- (IBAction)trashMarked:(id)sender
2017-03-11 19:18:27 -06:00
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
[model setRemoveEmptyFolders:n2b([ud objectForKey:@"removeEmptyFolders"])];
[model deleteMarked];
}
2017-04-03 22:40:48 -05:00
- (IBAction)exportToXHTML:(id)sender
{
[model exportToXHTML];
}
- (IBAction)exportToCSV:(id)sender
{
[model exportToCSV];
}
2017-04-03 22:04:01 -05:00
- (IBAction)filter:(id)sender
2017-03-11 19:18:27 -06:00
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
[model setEscapeFilterRegexp:!n2b([ud objectForKey:@"useRegexpFilter"])];
[model applyFilter:[filterField stringValue]];
}
2017-04-03 22:04:01 -05:00
- (IBAction)focusOnFilterField:(id)sender
2017-03-11 19:18:27 -06:00
{
[[self window] makeFirstResponder:filterField];
}
2017-04-03 22:04:01 -05:00
- (IBAction)ignoreSelected:(id)sender
2017-03-11 19:18:27 -06:00
{
[model addSelectedToIgnoreList];
}
2017-04-03 22:04:01 -05:00
- (IBAction)invokeCustomCommand:(id)sender
2017-03-11 19:18:27 -06:00
{
[model invokeCustomCommand];
}
2017-04-03 22:04:01 -05:00
- (IBAction)markAll:(id)sender
2017-03-11 19:18:27 -06:00
{
[model markAll];
}
2017-04-03 22:04:01 -05:00
- (IBAction)markInvert:(id)sender
2017-03-11 19:18:27 -06:00
{
[model markInvert];
}
2017-04-03 22:04:01 -05:00
- (IBAction)markNone:(id)sender
2017-03-11 19:18:27 -06:00
{
[model markNone];
}
2017-04-03 22:04:01 -05:00
- (IBAction)markSelected:(id)sender
2017-03-11 19:18:27 -06:00
{
[model toggleSelectedMark];
}
2017-04-03 22:04:01 -05:00
- (IBAction)moveMarked:(id)sender
2017-03-11 19:18:27 -06:00
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
[model setRemoveEmptyFolders:n2b([ud objectForKey:@"removeEmptyFolders"])];
[model setCopyMoveDestType:n2i([ud objectForKey:@"recreatePathType"])];
[model moveMarked];
}
2017-04-03 22:04:01 -05:00
- (IBAction)openClicked:(id)sender
2017-03-11 19:18:27 -06:00
{
if ([matches clickedRow] < 0) {
return;
}
[matches selectRowIndexes:[NSIndexSet indexSetWithIndex:[matches clickedRow]] byExtendingSelection:NO];
[model openSelected];
}
2017-04-03 22:04:01 -05:00
- (IBAction)openSelected:(id)sender
2017-03-11 19:18:27 -06:00
{
[model openSelected];
}
2017-04-03 22:04:01 -05:00
- (IBAction)removeMarked:(id)sender
2017-03-11 19:18:27 -06:00
{
[model removeMarked];
}
2017-04-03 22:04:01 -05:00
- (IBAction)removeSelected:(id)sender
2017-03-11 19:18:27 -06:00
{
[model removeSelected];
}
2017-04-03 22:04:01 -05:00
- (IBAction)renameSelected:(id)sender
2017-03-11 19:18:27 -06:00
{
NSInteger col = [matches columnWithIdentifier:@"name"];
NSInteger row = [matches selectedRow];
[matches editColumn:col row:row withEvent:[NSApp currentEvent] select:YES];
}
2017-04-03 22:04:01 -05:00
- (IBAction)reprioritizeResults:(id)sender
2017-03-11 19:18:27 -06:00
{
PrioritizeDialog *dlg = [[PrioritizeDialog alloc] initWithApp:model];
NSInteger result = [NSApp runModalForWindow:[dlg window]];
if (result == NSModalResponseStop ) {
2017-03-11 19:18:27 -06:00
[[dlg model] performReprioritization];
}
[dlg release];
[[self window] makeKeyAndOrderFront:nil];
}
2017-04-03 22:04:01 -05:00
- (IBAction)resetColumnsToDefault:(id)sender
2017-03-11 19:18:27 -06:00
{
[[[table columns] model] resetToDefaults];
[self fillColumnsMenu];
}
2017-04-03 22:04:01 -05:00
- (IBAction)revealSelected:(id)sender
2017-03-11 19:18:27 -06:00
{
[model revealSelected];
}
2017-04-03 22:04:01 -05:00
- (IBAction)saveResults:(id)sender
2017-03-11 19:18:27 -06:00
{
NSSavePanel *sp = [NSSavePanel savePanel];
[sp setCanCreateDirectories:YES];
[sp setAllowedFileTypes:[NSArray arrayWithObject:@"dupeguru"]];
[sp setTitle:NSLocalizedString(@"Select a file to save your results to", @"")];
if ([sp runModal] == NSModalResponseOK) {
2017-03-11 19:18:27 -06:00
[model saveResultsAs:[[sp URL] path]];
[[app recentResults] addFile:[[sp URL] path]];
}
}
2017-04-03 22:04:01 -05:00
- (IBAction)switchSelected:(id)sender
2017-03-11 19:18:27 -06:00
{
[model makeSelectedReference];
}
2017-04-03 22:04:01 -05:00
- (IBAction)toggleColumn:(id)sender
2017-03-11 19:18:27 -06:00
{
NSMenuItem *mi = sender;
BOOL checked = [[[table columns] model] toggleMenuItem:[mi tag]];
[mi setState:checked ? NSControlStateValueOn : NSControlStateValueOff];
2017-03-11 19:18:27 -06:00
}
2017-04-03 22:04:01 -05:00
- (IBAction)toggleDetailsPanel:(id)sender
2017-03-11 19:18:27 -06:00
{
[[app detailsPanel] toggleVisibility];
[self updateOptionSegments];
}
2017-04-03 22:04:01 -05:00
- (IBAction)toggleDelta:(id)sender
2017-03-11 19:18:27 -06:00
{
[table setDeltaValuesMode:![table deltaValuesMode]];
[self updateOptionSegments];
}
2017-04-03 22:04:01 -05:00
- (IBAction)togglePowerMarker:(id)sender
2017-03-11 19:18:27 -06:00
{
[table setPowerMarkerMode:![table powerMarkerMode]];
[self updateOptionSegments];
}
2017-04-03 22:04:01 -05:00
- (IBAction)toggleQuicklookPanel:(id)sender
2017-03-11 19:18:27 -06:00
{
if ([QLPreviewPanel sharedPreviewPanelExists] && [[QLPreviewPanel sharedPreviewPanel] isVisible]) {
[[QLPreviewPanel sharedPreviewPanel] orderOut:nil];
}
else {
[[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:nil];
}
}
/* Quicklook */
- (BOOL)acceptsPreviewPanelControl:(QLPreviewPanel *)panel;
{
return YES;
}
- (void)beginPreviewPanelControl:(QLPreviewPanel *)panel
{
// This document is now responsible of the preview panel
// It is allowed to set the delegate, data source and refresh panel.
previewPanel = [panel retain];
panel.delegate = table;
panel.dataSource = table;
}
- (void)endPreviewPanelControl:(QLPreviewPanel *)panel
{
// This document loses its responsisibility on the preview panel
// Until the next call to -beginPreviewPanelControl: it must not
// change the panel's delegate, data source or refresh it.
[previewPanel release];
previewPanel = nil;
}
- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem
{
return ![[ProgressController mainProgressController] isShown];
}
- (BOOL)validateMenuItem:(NSMenuItem *)item
{
if ([item action] == @selector(markAll)) {
[item setTitle:NSLocalizedString(@"Mark All", @"")];
}
return ![[ProgressController mainProgressController] isShown];
}
@end