From 7e95404903f5a4778ad06ba780c5b424a32b53bd Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Sun, 27 Nov 2011 12:47:00 -0500 Subject: [PATCH] Moved column information in new edition-specific core result_table units. --- cocoa/base/PyDupeGuru.h | 2 ++ cocoa/base/PyResultTable.h | 2 +- cocoa/base/ResultTable.h | 2 +- cocoa/base/ResultTable.m | 6 ++--- cocoa/base/ResultWindow.m | 2 +- cocoa/inter/app.py | 5 ++++- cocoa/inter/result_table.py | 6 +---- core/app.py | 15 ++++++++----- core/gui/base.py | 3 ++- core/gui/details_panel.py | 8 +++---- core/gui/result_table.py | 7 +++--- core_me/app.py | 45 +++++++++---------------------------- core_me/result_table.py | 36 +++++++++++++++++++++++++++++ core_pe/app.py | 38 +++++++++---------------------- core_pe/result_table.py | 26 +++++++++++++++++++++ core_se/app.py | 33 ++++++++------------------- core_se/result_table.py | 26 +++++++++++++++++++++ 17 files changed, 149 insertions(+), 113 deletions(-) create mode 100644 core_me/result_table.py create mode 100644 core_pe/result_table.py create mode 100644 core_se/result_table.py diff --git a/cocoa/base/PyDupeGuru.h b/cocoa/base/PyDupeGuru.h index ac11d50d..de664420 100644 --- a/cocoa/base/PyDupeGuru.h +++ b/cocoa/base/PyDupeGuru.h @@ -7,10 +7,12 @@ http://www.hardcoded.net/licenses/bsd_license */ #import +#import "PyResultTable.h" #import "PyApp.h" @interface PyDupeGuruBase : PyApp - (void)bindCocoa:(id)cocoa; +- (PyResultTable *)resultTable; //Actions - (NSNumber *)addDirectory:(NSString *)name; - (void)removeDirectory:(NSNumber *)index; diff --git a/cocoa/base/PyResultTable.h b/cocoa/base/PyResultTable.h index 84d5ebca..3ebc125d 100644 --- a/cocoa/base/PyResultTable.h +++ b/cocoa/base/PyResultTable.h @@ -17,7 +17,7 @@ http://www.hardcoded.net/licenses/bsd_license - (NSString *)valueForRow:(NSInteger)rowIndex column:(NSString *)aColumn; - (BOOL)renameSelected:(NSString *)aNewName; -- (void)sortBy:(NSInteger)aIdentifier ascending:(BOOL)aAscending; +- (void)sortBy:(NSString *)aIdentifier ascending:(BOOL)aAscending; - (void)markSelected; - (void)removeSelected; - (NSInteger)selectedDupeCount; diff --git a/cocoa/base/ResultTable.h b/cocoa/base/ResultTable.h index eca0c840..d05a4526 100644 --- a/cocoa/base/ResultTable.h +++ b/cocoa/base/ResultTable.h @@ -17,7 +17,7 @@ http://www.hardcoded.net/licenses/bsd_license NSIndexSet *_deltaColumns; HSColumns *columns; } -- (id)initWithPyParent:(id)aPyParent view:(NSTableView *)aTableView; +- (id)initWithPy:(id)aPy view:(NSTableView *)aTableView; - (PyResultTable *)py; - (HSColumns *)columns; - (BOOL)powerMarkerMode; diff --git a/cocoa/base/ResultTable.m b/cocoa/base/ResultTable.m index 953fcec2..53e4e79d 100644 --- a/cocoa/base/ResultTable.m +++ b/cocoa/base/ResultTable.m @@ -18,9 +18,9 @@ http://www.hardcoded.net/licenses/bsd_license @end @implementation ResultTable -- (id)initWithPyParent:(id)aPyParent view:(NSTableView *)aTableView +- (id)initWithPy:(id)aPy view:(NSTableView *)aTableView { - self = [super initWithPyClassName:@"PyResultTable" pyParent:aPyParent view:aTableView]; + self = [super initWithPy:aPy view:aTableView]; columns = [[HSColumns alloc] initWithPy:[[self py] columns] tableView:aTableView]; [self connect]; return self; @@ -145,7 +145,7 @@ http://www.hardcoded.net/licenses/bsd_license if ([[tableView sortDescriptors] count] < 1) return; NSSortDescriptor *sd = [[tableView sortDescriptors] objectAtIndex:0]; - [[self py] sortBy:[[sd key] integerValue] ascending:[sd ascending]]; + [[self py] sortBy:[sd key] ascending:[sd ascending]]; } - (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)column row:(NSInteger)row diff --git a/cocoa/base/ResultWindow.m b/cocoa/base/ResultWindow.m index 2417fafc..2fe8ca62 100644 --- a/cocoa/base/ResultWindow.m +++ b/cocoa/base/ResultWindow.m @@ -24,7 +24,7 @@ http://www.hardcoded.net/licenses/bsd_license columnsMenu = [app columnsMenu]; /* Put a cute iTunes-like bottom bar */ [[self window] setContentBorderThickness:28 forEdge:NSMinYEdge]; - table = [[ResultTable alloc] initWithPyParent:py view:matches]; + table = [[ResultTable alloc] initWithPy:[py resultTable] view:matches]; statsLabel = [[StatsLabel alloc] initWithPyParent:py labelView:stats]; problemDialog = [[ProblemDialog alloc] initWithPy:py]; [self initResultColumns]; diff --git a/cocoa/inter/app.py b/cocoa/inter/app.py index 82f843dd..94ab4f4d 100644 --- a/cocoa/inter/app.py +++ b/cocoa/inter/app.py @@ -3,12 +3,13 @@ import logging from jobprogress import job from hscommon import cocoa from hscommon.cocoa import install_exception_hook -from hscommon.cocoa.inter import signature, PyFairware +from hscommon.cocoa.inter import signature, subproxy, PyFairware from hscommon.cocoa.objcmin import (NSNotificationCenter, NSSearchPathForDirectoriesInDomains, NSApplicationSupportDirectory, NSUserDomainMask, NSWorkspace) from hscommon.trans import trget from core.app import JobType +from .result_table import PyResultTable tr = trget('ui') @@ -31,6 +32,8 @@ class PyDupeGuruBase(PyFairware): def bindCocoa_(self, cocoa): self.cocoa = cocoa + resultTable = subproxy('resultTable', 'result_table', PyResultTable) + #---Directories def addDirectory_(self, directory): return self.py.add_directory(directory) diff --git a/cocoa/inter/result_table.py b/cocoa/inter/result_table.py index 6cc4c75c..85aabf3c 100644 --- a/cocoa/inter/result_table.py +++ b/cocoa/inter/result_table.py @@ -1,10 +1,6 @@ from hscommon.cocoa.inter import signature, PyTable -from core.gui.result_table import ResultTable - class PyResultTable(PyTable): - py_class = ResultTable - @signature('c@:') def powerMarkerMode(self): return self.py.power_marker @@ -29,7 +25,7 @@ class PyResultTable(PyTable): def renameSelected_(self, newname): return self.py.rename_selected(newname) - @signature('v@:ic') + @signature('v@:@c') def sortBy_ascending_(self, key, asc): self.py.sort(key, asc) diff --git a/core/app.py b/core/app.py index b2387933..3f5443e5 100644 --- a/core/app.py +++ b/core/app.py @@ -65,11 +65,11 @@ def format_perc(p): def format_dupe_count(c): return str(c) if c else '---' -def cmp_value(dupe, column): - if column.name == 'name': +def cmp_value(dupe, attrname): + if attrname == 'name': value = rem_file_ext(dupe.name) else: - value = getattr(dupe, column.name, '') + value = getattr(dupe, attrname, '') return value.lower() if isinstance(value, str) else value class DupeGuru(RegistrableApplication, Broadcaster): @@ -101,6 +101,7 @@ class DupeGuru(RegistrableApplication, Broadcaster): 'ignore_hardlink_matches': False, } self.selected_dupes = [] + # subclasses must create self.result_table #--- Virtual def _get_display_info(self, dupe, group, delta): @@ -276,7 +277,7 @@ class DupeGuru(RegistrableApplication, Broadcaster): column_ids = [colid for colid in column_ids if colid.isdigit()] column_ids = list(map(int, column_ids)) column_ids.sort() - colnames = [col.display for i, col in enumerate(self.COLUMNS) if i in column_ids] + colnames = [col.display for i, col in enumerate(self.result_table.COLUMNS) if i in column_ids] rows = [] for group in self.results.groups: for dupe in group: @@ -287,13 +288,15 @@ class DupeGuru(RegistrableApplication, Broadcaster): return export.export_to_xhtml(colnames, rows) def get_display_info(self, dupe, group, delta=False): + def empty_data(): + return {c.name: '---' for c in self.result_table.COLUMNS[1:]} if (dupe is None) or (group is None): - return ['---'] * len(self.COLUMNS) + return empty_data() try: return self._get_display_info(dupe, group, delta) except Exception as e: logging.warning("Exception on GetDisplayInfo for %s: %s", str(dupe.path), str(e)) - return ['---'] * len(self.COLUMNS) + return empty_data() def invoke_command(self, cmd): """Calls command `cmd` with %d and %r placeholders replaced. diff --git a/core/gui/base.py b/core/gui/base.py index 87e8557b..d7a4d592 100644 --- a/core/gui/base.py +++ b/core/gui/base.py @@ -12,7 +12,8 @@ from hscommon.notify import Listener class GUIObject(Listener): def __init__(self, view, app): Listener.__init__(self, app) - self.view = view + if view is not None: + self.view = view self.app = app def directories_changed(self): diff --git a/core/gui/details_panel.py b/core/gui/details_panel.py index 8fcea194..3f418aa6 100644 --- a/core/gui/details_panel.py +++ b/core/gui/details_panel.py @@ -26,12 +26,12 @@ class DetailsPanel(GUIObject): else: dupe = None group = None - l1 = self.app.get_display_info(dupe, group, False) + data1 = self.app.get_display_info(dupe, group, False) # we don't want the two sides of the table to display the stats for the same file ref = group.ref if group is not None and group.ref is not dupe else None - l2 = self.app.get_display_info(ref, group, False) - names = [c.display for c in self.app.COLUMNS] - self._table = list(zip(names, l1, l2)) + data2 = self.app.get_display_info(ref, group, False) + columns = self.app.result_table.COLUMNS[1:] # first column is the 'marked' column + self._table = [(c.display, data1[c.name], data2[c.name]) for c in columns] #--- Public def row_count(self): diff --git a/core/gui/result_table.py b/core/gui/result_table.py index 026de188..5c4a8286 100644 --- a/core/gui/result_table.py +++ b/core/gui/result_table.py @@ -52,14 +52,13 @@ class DupeRow(Row): class ResultTable(GUIObject, GUITable): - def __init__(self, view, app): - GUIObject.__init__(self, view, app) + def __init__(self, app): + GUIObject.__init__(self, None, app) GUITable.__init__(self) - self.COLUMNS = app.COLUMNS self.columns = Columns(self, prefaccess=app, savename='ResultTable') self._power_marker = False self._delta_values = False - self._sort_descriptors = (0, True) + self._sort_descriptors = ('name', True) #--- Override def connect(self): diff --git a/core_me/app.py b/core_me/app.py index 94fd6532..d797c3bd 100644 --- a/core_me/app.py +++ b/core_me/app.py @@ -5,51 +5,26 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from hscommon.trans import trget from hscommon.util import format_size, format_time -from hscommon.gui.column import Column from core.app import (DupeGuru as DupeGuruBase, format_timestamp, format_perc, format_words, format_dupe_count, cmp_value) from . import prioritize from . import __appname__ from . import scanner, fs - -coltr = trget('columns') +from .result_table import ResultTable class DupeGuru(DupeGuruBase): NAME = __appname__ - COLUMNS = [ - Column('marked', ''), - Column('name', coltr("Filename")), - Column('folder_path', coltr("Folder"), visible=False, optional=True), - Column('size', coltr("Size (MB)"), optional=True), - Column('duration', coltr("Time"), optional=True), - Column('bitrate', coltr("Bitrate"), optional=True), - Column('samplerate', coltr("Sample Rate"), visible=False, optional=True), - Column('extension', coltr("Kind"), optional=True), - Column('mtime', coltr("Modification"), visible=False, optional=True), - Column('title', coltr("Title"), visible=False, optional=True), - Column('artist', coltr("Artist"), visible=False, optional=True), - Column('album', coltr("Album"), visible=False, optional=True), - Column('genre', coltr("Genre"), visible=False, optional=True), - Column('year', coltr("Year"), visible=False, optional=True), - Column('track', coltr("Track Number"), visible=False, optional=True), - Column('comment', coltr("Comment"), visible=False, optional=True), - Column('percentage', coltr("Match %"), optional=True), - Column('words', coltr("Words Used"), visible=False, optional=True), - Column('dupe_count', coltr("Dupe Count"), visible=False, optional=True), - ] DELTA_COLUMNS = {2, 3, 4, 5, 7} METADATA_TO_READ = ['size', 'mtime', 'duration', 'bitrate', 'samplerate', 'title', 'artist', 'album', 'genre', 'year', 'track', 'comment'] - MATCHPERC_COL = 15 - DUPECOUNT_COL = 17 - + def __init__(self, view, appdata): DupeGuruBase.__init__(self, view, appdata) self.scanner = scanner.ScannerME() self.directories.fileclasses = [fs.MusicFile] + self.result_table = ResultTable(self) def _get_display_info(self, dupe, group, delta): size = dupe.size @@ -93,22 +68,22 @@ class DupeGuru(DupeGuruBase): } def _get_dupe_sort_key(self, dupe, get_group, key, delta): - if key == self.MATCHPERC_COL: + if key == 'percentage': m = get_group().get_match_of(dupe) return m.percentage - if key == self.DUPECOUNT_COL: + if key == 'dupe_count': return 0 - r = cmp_value(dupe, self.COLUMNS[key]) + r = cmp_value(dupe, key) if delta and (key in self.DELTA_COLUMNS): - r -= cmp_value(get_group().ref, self.COLUMNS[key]) + r -= cmp_value(get_group().ref, key) return r def _get_group_sort_key(self, group, key): - if key == self.MATCHPERC_COL: + if key == 'percentage': return group.percentage - if key == self.DUPECOUNT_COL: + if key == 'dupe_count': return len(group) - return cmp_value(group.ref, self.COLUMNS[key]) + return cmp_value(group.ref, key) def _prioritization_categories(self): return prioritize.all_categories() diff --git a/core_me/result_table.py b/core_me/result_table.py new file mode 100644 index 00000000..6eb24ede --- /dev/null +++ b/core_me/result_table.py @@ -0,0 +1,36 @@ +# Created On: 2011-11-27 +# Copyright 2011 Hardcoded Software (http://www.hardcoded.net) +# +# This software is licensed under the "BSD" 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/bsd_license + +from hscommon.gui.column import Column +from hscommon.trans import trget + +from core.gui.result_table import ResultTable as ResultTableBase + +coltr = trget('columns') + +class ResultTable(ResultTableBase): + COLUMNS = [ + Column('marked', ''), + Column('name', coltr("Filename")), + Column('folder_path', coltr("Folder"), visible=False, optional=True), + Column('size', coltr("Size (MB)"), optional=True), + Column('duration', coltr("Time"), optional=True), + Column('bitrate', coltr("Bitrate"), optional=True), + Column('samplerate', coltr("Sample Rate"), visible=False, optional=True), + Column('extension', coltr("Kind"), optional=True), + Column('mtime', coltr("Modification"), visible=False, optional=True), + Column('title', coltr("Title"), visible=False, optional=True), + Column('artist', coltr("Artist"), visible=False, optional=True), + Column('album', coltr("Album"), visible=False, optional=True), + Column('genre', coltr("Genre"), visible=False, optional=True), + Column('year', coltr("Year"), visible=False, optional=True), + Column('track', coltr("Track Number"), visible=False, optional=True), + Column('comment', coltr("Comment"), visible=False, optional=True), + Column('percentage', coltr("Match %"), optional=True), + Column('words', coltr("Words Used"), visible=False, optional=True), + Column('dupe_count', coltr("Dupe Count"), visible=False, optional=True), + ] diff --git a/core_pe/app.py b/core_pe/app.py index 1e6fd844..48afe427 100644 --- a/core_pe/app.py +++ b/core_pe/app.py @@ -7,17 +7,14 @@ import os.path as op -from hscommon.trans import trget from hscommon.util import format_size -from hscommon.gui.column import Column from core.app import (DupeGuru as DupeGuruBase, format_timestamp, format_perc, format_dupe_count, cmp_value) from .scanner import ScannerPE from . import prioritize from . import __appname__ - -coltr = trget('columns') +from .result_table import ResultTable def format_dimensions(dimensions): return '%d x %d' % (dimensions[0], dimensions[1]) @@ -27,27 +24,14 @@ def get_delta_dimensions(value, ref_value): class DupeGuru(DupeGuruBase): NAME = __appname__ - COLUMNS = [ - Column('marked', ''), - Column('name', coltr("Filename")), - Column('folder_path', coltr("Folder"), optional=True), - Column('size', coltr("Size (KB)"), optional=True), - Column('extension', coltr("Kind"), visible=False, optional=True), - Column('dimensions', coltr("Dimensions"), optional=True), - Column('mtime', coltr("Modification"), visible=False, optional=True), - Column('percentage', coltr("Match %"), optional=True), - Column('dupe_count', coltr("Dupe Count"), visible=False, optional=True), - ] DELTA_COLUMNS = {2, 4, 5} METADATA_TO_READ = ['size', 'mtime', 'dimensions'] - FOLDER_COL = 1 - MATCHPERC_COL = 6 - DUPECOUNT_COL = 7 def __init__(self, view, appdata): DupeGuruBase.__init__(self, view, appdata) self.scanner = ScannerPE() self.scanner.cache_path = op.join(self.appdata, 'cached_pictures.db') + self.result_table = ResultTable(self) def _get_display_info(self, dupe, group, delta): size = dupe.size @@ -78,17 +62,17 @@ class DupeGuru(DupeGuruBase): } def _get_dupe_sort_key(self, dupe, get_group, key, delta): - if key == self.MATCHPERC_COL: + if key == 'percentage': m = get_group().get_match_of(dupe) return m.percentage - if key == self.DUPECOUNT_COL: + if key == 'dupe_count': return 0 - if key == self.FOLDER_COL: + if key == 'folder_path': dupe_folder_path = getattr(dupe, 'display_folder_path', dupe.folder_path) return str(dupe_folder_path).lower() - r = cmp_value(dupe, self.COLUMNS[key]) + r = cmp_value(dupe, key) if delta and (key in self.DELTA_COLUMNS): - ref_value = cmp_value(get_group().ref, self.COLUMNS[key]) + ref_value = cmp_value(get_group().ref, key) if key == 4: # dimensions r = get_delta_dimensions(r, ref_value) else: @@ -96,14 +80,14 @@ class DupeGuru(DupeGuruBase): return r def _get_group_sort_key(self, group, key): - if key == self.MATCHPERC_COL: + if key == 'percentage': return group.percentage - if key == self.DUPECOUNT_COL: + if key == 'dupe_count': return len(group) - if key == self.FOLDER_COL: + if key == 'folder_path': dupe_folder_path = getattr(group.ref, 'display_folder_path', group.ref.folder_path) return str(dupe_folder_path).lower() - return cmp_value(group.ref, self.COLUMNS[key]) + return cmp_value(group.ref, key) def _prioritization_categories(self): return prioritize.all_categories() diff --git a/core_pe/result_table.py b/core_pe/result_table.py new file mode 100644 index 00000000..b6be5a1a --- /dev/null +++ b/core_pe/result_table.py @@ -0,0 +1,26 @@ +# Created On: 2011-11-27 +# Copyright 2011 Hardcoded Software (http://www.hardcoded.net) +# +# This software is licensed under the "BSD" 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/bsd_license + +from hscommon.gui.column import Column +from hscommon.trans import trget + +from core.gui.result_table import ResultTable as ResultTableBase + +coltr = trget('columns') + +class ResultTable(ResultTableBase): + COLUMNS = [ + Column('marked', ''), + Column('name', coltr("Filename")), + Column('folder_path', coltr("Folder"), optional=True), + Column('size', coltr("Size (KB)"), optional=True), + Column('extension', coltr("Kind"), visible=False, optional=True), + Column('dimensions', coltr("Dimensions"), optional=True), + Column('mtime', coltr("Modification"), visible=False, optional=True), + Column('percentage', coltr("Match %"), optional=True), + Column('dupe_count', coltr("Dupe Count"), visible=False, optional=True), + ] diff --git a/core_se/app.py b/core_se/app.py index ee57aca7..8c0d37fd 100644 --- a/core_se/app.py +++ b/core_se/app.py @@ -5,37 +5,22 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from hscommon.trans import trget from hscommon.util import format_size -from hscommon.gui.column import Column from core.app import (DupeGuru as DupeGuruBase, format_timestamp, format_perc, format_words, format_dupe_count, cmp_value) from core import prioritize from . import __appname__ - -coltr = trget('columns') +from .result_table import ResultTable class DupeGuru(DupeGuruBase): NAME = __appname__ - COLUMNS = [ - Column('marked', ''), - Column('name', coltr("Filename")), - Column('folder_path', coltr("Folder"), optional=True), - Column('size', coltr("Size (KB)"), optional=True), - Column('extension', coltr("Kind"), visible=False, optional=True), - Column('mtime', coltr("Modification"), visible=False, optional=True), - Column('percentage', coltr("Match %"), optional=True), - Column('words', coltr("Words Used"), visible=False, optional=True), - Column('dupe_count', coltr("Dupe Count"), visible=False, optional=True), - ] DELTA_COLUMNS = {2, 4} METADATA_TO_READ = ['size', 'mtime'] - MATCHPERC_COL = 5 - DUPECOUNT_COL = 7 def __init__(self, view, appdata): DupeGuruBase.__init__(self, view, appdata) + self.result_table = ResultTable(self) def _get_display_info(self, dupe, group, delta): size = dupe.size @@ -63,22 +48,22 @@ class DupeGuru(DupeGuruBase): } def _get_dupe_sort_key(self, dupe, get_group, key, delta): - if key == self.MATCHPERC_COL: + if key == 'percentage': m = get_group().get_match_of(dupe) return m.percentage - if key == self.DUPECOUNT_COL: + if key == 'dupe_count': return 0 - r = cmp_value(dupe, self.COLUMNS[key]) + r = cmp_value(dupe, key) if delta and (key in self.DELTA_COLUMNS): - r -= cmp_value(get_group().ref, self.COLUMNS[key]) + r -= cmp_value(get_group().ref, key) return r def _get_group_sort_key(self, group, key): - if key == self.MATCHPERC_COL: + if key == 'percentage': return group.percentage - if key == self.DUPECOUNT_COL: + if key == 'dupe_count': return len(group) - return cmp_value(group.ref, self.COLUMNS[key]) + return cmp_value(group.ref, key) def _prioritization_categories(self): return prioritize.all_categories() diff --git a/core_se/result_table.py b/core_se/result_table.py new file mode 100644 index 00000000..3358099c --- /dev/null +++ b/core_se/result_table.py @@ -0,0 +1,26 @@ +# Created On: 2011-11-27 +# Copyright 2011 Hardcoded Software (http://www.hardcoded.net) +# +# This software is licensed under the "BSD" 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/bsd_license + +from hscommon.gui.column import Column +from hscommon.trans import trget + +from core.gui.result_table import ResultTable as ResultTableBase + +coltr = trget('columns') + +class ResultTable(ResultTableBase): + COLUMNS = [ + Column('marked', ''), + Column('name', coltr("Filename")), + Column('folder_path', coltr("Folder"), optional=True), + Column('size', coltr("Size (KB)"), optional=True), + Column('extension', coltr("Kind"), visible=False, optional=True), + Column('mtime', coltr("Modification"), visible=False, optional=True), + Column('percentage', coltr("Match %"), optional=True), + Column('words', coltr("Words Used"), visible=False, optional=True), + Column('dupe_count', coltr("Dupe Count"), visible=False, optional=True), + ]