diff --git a/cocoa/base/Consts.h b/cocoa/base/Consts.h index 0a9b8ee0..790e9704 100644 --- a/cocoa/base/Consts.h +++ b/cocoa/base/Consts.h @@ -8,9 +8,6 @@ http://www.hardcoded.net/licenses/hs_license #import -/* ResultsChangedNotification happens on major changes, which requires a complete reload of the data*/ -#define ResultsChangedNotification @"ResultsChangedNotification" -#define ResultsMarkingChangedNotification @"ResultsMarkingChangedNotification" #define RegistrationRequired @"RegistrationRequired" #define JobStarted @"JobStarted" #define JobInProgress @"JobInProgress" diff --git a/cocoa/base/PyStatsLabel.h b/cocoa/base/PyStatsLabel.h new file mode 100644 index 00000000..5e6a98c3 --- /dev/null +++ b/cocoa/base/PyStatsLabel.h @@ -0,0 +1,14 @@ +/* +Copyright 2010 Hardcoded Software (http://www.hardcoded.net) + +This software is licensed under the "HS" License as described in the "LICENSE" file, +which should be included with this package. The terms are also available at +http://www.hardcoded.net/licenses/hs_license +*/ + +#import +#import "PyGUI.h" + +@interface PyStatsLabel : PyGUI +- (NSString *)display; +@end \ No newline at end of file diff --git a/cocoa/base/ResultOutline.m b/cocoa/base/ResultOutline.m index c174f1bc..d0d3edb7 100644 --- a/cocoa/base/ResultOutline.m +++ b/cocoa/base/ResultOutline.m @@ -89,10 +89,7 @@ http://www.hardcoded.net/licenses/hs_license NSString *newName = object; if (![newName isEqual:oldName]) { BOOL renamed = [[self py] renameSelected:newName]; - if (renamed) { - [[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self]; - } - else { + if (!renamed) { [Dialogs showMessage:[NSString stringWithFormat:@"The name '%@' already exists.", newName]]; } } diff --git a/cocoa/base/ResultWindow.h b/cocoa/base/ResultWindow.h index 92bfb640..5586d8fd 100644 --- a/cocoa/base/ResultWindow.h +++ b/cocoa/base/ResultWindow.h @@ -8,6 +8,7 @@ http://www.hardcoded.net/licenses/hs_license #import #import "HSOutlineView.h" +#import "StatsLabel.h" #import "ResultOutline.h" #import "PyDupeGuru.h" @@ -30,6 +31,7 @@ http://www.hardcoded.net/licenses/hs_license NSMutableArray *_resultColumns; NSWindowController *preferencesPanel; ResultOutline *outline; + StatsLabel *statsLabel; } /* Helpers */ - (void)fillColumnsMenu; @@ -39,8 +41,6 @@ http://www.hardcoded.net/licenses/hs_license - (NSArray *)getSelectedPaths:(BOOL)aDupesOnly; - (void)initResultColumns; - (void)performPySelection:(NSArray *)aIndexPaths; -- (void)refreshStats; -- (void)reloadMatches; - (void)restoreColumnsPosition:(NSArray *)aColumnsOrder widths:(NSDictionary *)aColumnsWidth; /* Actions */ diff --git a/cocoa/base/ResultWindow.m b/cocoa/base/ResultWindow.m index e719cb14..dbe9750f 100644 --- a/cocoa/base/ResultWindow.m +++ b/cocoa/base/ResultWindow.m @@ -36,20 +36,18 @@ http://www.hardcoded.net/licenses/hs_license [self window]; preferencesPanel = [[NSWindowController alloc] initWithWindowNibName:@"Preferences"]; outline = [[ResultOutline alloc] initWithPyParent:py view:matches]; + statsLabel = [[StatsLabel alloc] initWithPyParent:py labelView:stats]; [self initResultColumns]; [self fillColumnsMenu]; [deltaSwitch setSelectedSegment:0]; [pmSwitch setSelectedSegment:0]; [matches setTarget:self]; [matches setDoubleAction:@selector(openClicked:)]; - [self refreshStats]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(registrationRequired:) name:RegistrationRequired object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(jobCompleted:) name:JobCompletedNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(jobStarted:) name:JobStarted object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(jobInProgress:) name:JobInProgress object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resultsMarkingChanged:) name:ResultsMarkingChangedNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resultsChanged:) name:ResultsChangedNotification object:nil]; } - (void)dealloc @@ -176,17 +174,6 @@ http://www.hardcoded.net/licenses/hs_license } } -- (void)refreshStats -{ - [stats setStringValue:[py getStatLine]]; -} - -/* Reload the matches outline and restore selection from py */ -- (void)reloadMatches -{ - [outline refresh]; -} - /* Actions */ - (IBAction)clearIgnoreList:(id)sender { @@ -251,7 +238,6 @@ http://www.hardcoded.net/licenses/hs_license NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; [py setEscapeFilterRegexp:b2n(!n2b([ud objectForKey:@"useRegexpFilter"]))]; [py applyFilter:[filterField stringValue]]; - [[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self]; } - (IBAction)ignoreSelected:(id)sender @@ -263,32 +249,27 @@ http://www.hardcoded.net/licenses/hs_license if ([Dialogs askYesNo:msg] == NSAlertSecondButtonReturn) // NO return; [py addSelectedToIgnoreList]; - [[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self]; } - (IBAction)markAll:(id)sender { [py markAll]; - [[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self]; } - (IBAction)markInvert:(id)sender { [py markInvert]; - [[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self]; } - (IBAction)markNone:(id)sender { [py markNone]; - [[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self]; } - (IBAction)markSelected:(id)sender { [self performPySelection:[self getSelectedPaths:YES]]; [py toggleSelectedMark]; - [[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self]; } - (IBAction)markToggle:(id)sender @@ -296,7 +277,6 @@ http://www.hardcoded.net/licenses/hs_license NSIndexPath *path = [matches itemAtRow:[matches clickedRow]]; [self performPySelection:[NSArray arrayWithObject:p2a(path)]]; [py toggleSelectedMark]; - [[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self]; } - (IBAction)moveMarked:(id)sender @@ -334,11 +314,6 @@ http://www.hardcoded.net/licenses/hs_license [py openSelected]; } -- (IBAction)refresh:(id)sender -{ - [[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self]; -} - - (IBAction)removeMarked:(id)sender { int mark_count = [[py getMarkCount] intValue]; @@ -347,7 +322,6 @@ http://www.hardcoded.net/licenses/hs_license if ([Dialogs askYesNo:[NSString stringWithFormat:@"You are about to remove %d files from results. Continue?",mark_count]] == NSAlertSecondButtonReturn) // NO return; [py removeMarked]; - [[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self]; } - (IBAction)removeSelected:(id)sender @@ -359,7 +333,6 @@ http://www.hardcoded.net/licenses/hs_license return; [self performPySelection:[self getSelectedPaths:YES]]; [py removeSelected]; - [[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self]; } - (IBAction)renameSelected:(id)sender @@ -501,16 +474,6 @@ http://www.hardcoded.net/licenses/hs_license [self performPySelection:[self getSelectedPaths:NO]]; } -- (void)resultsChanged:(NSNotification *)aNotification -{ - [self refreshStats]; -} - -- (void)resultsMarkingChanged:(NSNotification *)aNotification -{ - [self refreshStats]; -} - - (BOOL)validateToolbarItem:(NSToolbarItem *)theItem { return ![[ProgressController mainProgressController] isShown]; diff --git a/cocoa/base/StatsLabel.h b/cocoa/base/StatsLabel.h new file mode 100644 index 00000000..af2aaa35 --- /dev/null +++ b/cocoa/base/StatsLabel.h @@ -0,0 +1,19 @@ +/* +Copyright 2010 Hardcoded Software (http://www.hardcoded.net) + +This software is licensed under the "HS" License as described in the "LICENSE" file, +which should be included with this package. The terms are also available at +http://www.hardcoded.net/licenses/hs_license +*/ + +#import +#import "HSGUIController.h" +#import "PyStatsLabel.h" + +@interface StatsLabel : HSGUIController +{ + NSTextField *labelView; +} +- (id)initWithPyParent:(id)aPyParent labelView:(NSTextField *)aLabelView; +- (PyStatsLabel *)py; +@end \ No newline at end of file diff --git a/cocoa/base/StatsLabel.m b/cocoa/base/StatsLabel.m new file mode 100644 index 00000000..87a54015 --- /dev/null +++ b/cocoa/base/StatsLabel.m @@ -0,0 +1,36 @@ +/* +Copyright 2010 Hardcoded Software (http://www.hardcoded.net) + +This software is licensed under the "HS" License as described in the "LICENSE" file, +which should be included with this package. The terms are also available at +http://www.hardcoded.net/licenses/hs_license +*/ + +#import "StatsLabel.h" +#import "Utils.h" + +@implementation StatsLabel +- (id)initWithPyParent:(id)aPyParent labelView:(NSTextField *)aLabelView +{ + self = [super initWithPyClassName:@"PyStatsLabel" pyParent:aPyParent]; + labelView = [aLabelView retain]; + return self; +} + +- (void)dealloc +{ + [labelView release]; + [super dealloc]; +} + +- (PyStatsLabel *)py +{ + return (PyStatsLabel *)py; +} + +/* Python --> Cocoa */ +- (void)refresh +{ + [labelView setStringValue:[[self py] display]]; +} +@end diff --git a/cocoa/me/ResultWindow.m b/cocoa/me/ResultWindow.m index 66e7d3f4..8861bea4 100644 --- a/cocoa/me/ResultWindow.m +++ b/cocoa/me/ResultWindow.m @@ -69,8 +69,6 @@ http://www.hardcoded.net/licenses/hs_license [_py setMixFileKind:[ud objectForKey:@"mixFileKind"]]; [_py setMatchSimilarWords:[ud objectForKey:@"matchSimilarWords"]]; NSInteger r = n2i([py doScan]); - [matches reloadData]; - [self refreshStats]; if (r == 1) [Dialogs showMessage:@"You cannot make a duplicate scan with only reference directories."]; if (r == 3) diff --git a/cocoa/me/dupeguru.xcodeproj/project.pbxproj b/cocoa/me/dupeguru.xcodeproj/project.pbxproj index 24a7c58b..a282b573 100644 --- a/cocoa/me/dupeguru.xcodeproj/project.pbxproj +++ b/cocoa/me/dupeguru.xcodeproj/project.pbxproj @@ -58,6 +58,7 @@ CE848A1909DD85810004CB44 /* Consts.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE848A1809DD85810004CB44 /* Consts.h */; }; CE900AD2109B238600754048 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE900AD1109B238600754048 /* Preferences.xib */; }; CE900AD7109B2A9B00754048 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE900AD6109B2A9B00754048 /* MainMenu.xib */; }; + CEDF07A3112493B200EE5BC0 /* StatsLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = CEDF07A2112493B200EE5BC0 /* StatsLabel.m */; }; CEEB135209C837A2004D2330 /* dupeguru.icns in Resources */ = {isa = PBXBuildFile; fileRef = CEEB135109C837A2004D2330 /* dupeguru.icns */; }; CEFC294609C89E3D00D9F998 /* folder32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC294509C89E3D00D9F998 /* folder32.png */; }; CEFC295509C89FF200D9F998 /* details32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC295309C89FF200D9F998 /* details32.png */; }; @@ -157,6 +158,9 @@ CECA899A09DB132E00A3D774 /* DetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = DetailsPanel.h; sourceTree = ""; }; CECA899B09DB132E00A3D774 /* DetailsPanel.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = DetailsPanel.m; sourceTree = ""; }; CED0A591111C9FD10020AD7D /* PyDetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyDetailsPanel.h; path = ../base/PyDetailsPanel.h; sourceTree = SOURCE_ROOT; }; + CEDF07A0112493B200EE5BC0 /* PyStatsLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyStatsLabel.h; path = ../base/PyStatsLabel.h; sourceTree = SOURCE_ROOT; }; + CEDF07A1112493B200EE5BC0 /* StatsLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StatsLabel.h; path = ../base/StatsLabel.h; sourceTree = SOURCE_ROOT; }; + CEDF07A2112493B200EE5BC0 /* StatsLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = StatsLabel.m; path = ../base/StatsLabel.m; sourceTree = SOURCE_ROOT; }; CEEB135109C837A2004D2330 /* dupeguru.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = dupeguru.icns; sourceTree = ""; }; CEFC294509C89E3D00D9F998 /* folder32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = folder32.png; path = ../../images/folder32.png; sourceTree = SOURCE_ROOT; }; CEFC295309C89FF200D9F998 /* details32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = details32.png; path = ../../images/details32.png; sourceTree = SOURCE_ROOT; }; @@ -383,9 +387,12 @@ CE515E1C0FC6C19300EC695D /* ResultWindow.m */, CE0B3D6511243F83009A7A30 /* ResultOutline.h */, CE0B3D6611243F83009A7A30 /* ResultOutline.m */, + CEDF07A1112493B200EE5BC0 /* StatsLabel.h */, + CEDF07A2112493B200EE5BC0 /* StatsLabel.m */, CE515E1A0FC6C19300EC695D /* PyDupeGuru.h */, CED0A591111C9FD10020AD7D /* PyDetailsPanel.h */, CE0B3D6411243F83009A7A30 /* PyResultTree.h */, + CEDF07A0112493B200EE5BC0 /* PyStatsLabel.h */, ); name = dgbase; sourceTree = ""; @@ -494,6 +501,7 @@ CE003CCC11242D00004B0AA7 /* NSTableViewAdditions.m in Sources */, CE003CD011242D2C004B0AA7 /* DirectoryOutline.m in Sources */, CE0B3D6711243F83009A7A30 /* ResultOutline.m in Sources */, + CEDF07A3112493B200EE5BC0 /* StatsLabel.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/core/app_cocoa_inter.py b/core/app_cocoa_inter.py index 7fc38488..321518b7 100644 --- a/core/app_cocoa_inter.py +++ b/core/app_cocoa_inter.py @@ -14,6 +14,7 @@ from hsutil.cocoa.inter import signature, PyOutline, PyGUIObject, PyRegistrable from .gui.details_panel import DetailsPanel from .gui.directory_tree import DirectoryTree from .gui.result_tree import ResultTree +from .gui.stats_label import StatsLabel # Fix py2app's problems on relative imports from core import app, app_cocoa, data, directories, engine, export, ignore, results, fs, scanner @@ -202,3 +203,10 @@ class PyResultOutline(PyOutline): def markSelected(self): self.py.app.toggle_selected_mark_state() + +class PyStatsLabel(PyGUIObject): + py_class = StatsLabel + + def display(self): + return self.py.display + diff --git a/core/gui/stats_label.py b/core/gui/stats_label.py new file mode 100644 index 00000000..c7f0ceee --- /dev/null +++ b/core/gui/stats_label.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Created By: Virgil Dupras +# Created On: 2010-02-11 +# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) +# +# This software is licensed under the "HS" License as described in the "LICENSE" file, +# which should be included with this package. The terms are also available at +# http://www.hardcoded.net/licenses/hs_license + +from .base import GUIObject + +class StatsLabel(GUIObject): + def __init__(self, view, app): + GUIObject.__init__(self, view, app) + self.connect() + self.view.refresh() + + @property + def display(self): + return self.app.results.stat_line + + def results_changed(self): + self.view.refresh() +