From 9a25670552a55d6291b1046eede03250a18fa817 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Tue, 31 May 2016 21:22:50 -0400 Subject: [PATCH] qt: merge se.app into base.app --- qt/base/app.py | 71 +++++++++++++++++++------ qt/base/preferences.py | 50 ++++++++++++------ qt/base/preferences_dialog.py | 9 ++-- qt/base/result_window.py | 12 ++++- qt/me/preferences_dialog.py | 4 -- qt/pe/preferences_dialog.py | 4 -- qt/run_template.py | 2 +- qt/se/app.py | 98 ----------------------------------- qt/se/preferences.py | 51 ------------------ qt/se/preferences_dialog.py | 4 -- 10 files changed, 106 insertions(+), 199 deletions(-) delete mode 100644 qt/se/app.py delete mode 100644 qt/se/preferences.py diff --git a/qt/base/app.py b/qt/base/app.py index 23697593..bc6bd73d 100644 --- a/qt/base/app.py +++ b/qt/base/app.py @@ -1,6 +1,4 @@ -# Created By: Virgil Dupras -# Created On: 2009-04-25 -# Copyright 2015 Hardcoded Software (http://www.hardcoded.net) +# Copyright 2016 Hardcoded Software (http://www.hardcoded.net) # # 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 @@ -21,34 +19,40 @@ from qtlib.recent import Recent from qtlib.util import createActions from qtlib.progress_window import ProgressWindow +from core.app import AppMode +from core_se.app import DupeGuru as DupeGuruModel +import core_pe.photo from . import platform +from .preferences import Preferences from .result_window import ResultWindow from .directories_dialog import DirectoriesDialog from .problem_dialog import ProblemDialog from .ignore_list_dialog import IgnoreListDialog from .deletion_options import DeletionOptions +from ..se.details_dialog import DetailsDialog as DetailsDialogStandard +from ..me.details_dialog import DetailsDialog as DetailsDialogMusic +from ..pe.details_dialog import DetailsDialog as DetailsDialogPicture +from ..se.preferences_dialog import PreferencesDialog as PreferencesDialogStandard +from ..me.preferences_dialog import PreferencesDialog as PreferencesDialogMusic +from ..pe.preferences_dialog import PreferencesDialog as PreferencesDialogPicture +from ..pe.photo import File as PlatSpecificPhoto tr = trget('ui') class DupeGuru(QObject): - MODELCLASS = None - LOGO_NAME = '' - NAME = '' - - DETAILS_DIALOG_CLASS = None - RESULT_MODEL_CLASS = None - PREFERENCES_CLASS = None - PREFERENCES_DIALOG_CLASS = None + LOGO_NAME = 'logo_se' + NAME = 'dupeGuru' def __init__(self, **kwargs): super().__init__(**kwargs) - self.prefs = self.PREFERENCES_CLASS() + self.prefs = Preferences() self.prefs.load() - self.model = self.MODELCLASS(view=self) + self.model = DupeGuruModel(view=self) self._setup() #--- Private def _setup(self): + core_pe.photo.PLAT_SPECIFIC_PHOTO_CLASS = PlatSpecificPhoto self._setupActions() self._update_options() self.recentResults = Recent(self, 'recentResults') @@ -93,6 +97,43 @@ class DupeGuru(QObject): self.model.options['ignore_hardlink_matches'] = self.prefs.ignore_hardlink_matches self.model.options['copymove_dest_type'] = self.prefs.destination_type self.model.options['scan_type'] = self.prefs.get_scan_type(self.model.app_mode) + self.model.options['min_match_percentage'] = self.prefs.filter_hardness + self.model.options['word_weighting'] = self.prefs.word_weighting + self.model.options['match_similar_words'] = self.prefs.match_similar + threshold = self.prefs.small_file_threshold if self.prefs.ignore_small_files else 0 + self.model.options['size_threshold'] = threshold * 1024 # threshold is in KB. the scanner wants bytes + scanned_tags = set() + if self.prefs.scan_tag_track: + scanned_tags.add('track') + if self.prefs.scan_tag_artist: + scanned_tags.add('artist') + if self.prefs.scan_tag_album: + scanned_tags.add('album') + if self.prefs.scan_tag_title: + scanned_tags.add('title') + if self.prefs.scan_tag_genre: + scanned_tags.add('genre') + if self.prefs.scan_tag_year: + scanned_tags.add('year') + self.model.options['scanned_tags'] = scanned_tags + self.model.options['match_scaled'] = self.prefs.match_scaled + + #--- Private + def _get_details_dialog_class(self): + if self.model.app_mode == AppMode.Picture: + return DetailsDialogPicture + elif self.model.app_mode == AppMode.Music: + return DetailsDialogMusic + else: + return DetailsDialogStandard + + def _get_preferences_dialog_class(self): + if self.model.app_mode == AppMode.Picture: + return PreferencesDialogPicture + elif self.model.app_mode == AppMode.Music: + return PreferencesDialogMusic + else: + return PreferencesDialogStandard #--- Public def add_selected_to_ignore_list(self): @@ -151,7 +192,7 @@ class DupeGuru(QObject): desktop.open_path(debugLogPath) def preferencesTriggered(self): - preferences_dialog = self.PREFERENCES_DIALOG_CLASS(self.directories_dialog, self) + preferences_dialog = self._get_preferences_dialog_class()(self.directories_dialog, self) preferences_dialog.load() result = preferences_dialog.exec() if result == QDialog.Accepted: @@ -195,7 +236,7 @@ class DupeGuru(QObject): self.resultWindow.close() self.resultWindow.setParent(None) self.resultWindow = ResultWindow(self.directories_dialog, self) - self.details_dialog = self.DETAILS_DIALOG_CLASS(self.resultWindow, self) + self.details_dialog = self._get_details_dialog_class()(self.resultWindow, self) def show_results_window(self): self.showResultsWindow() diff --git a/qt/base/preferences.py b/qt/base/preferences.py index 24fc5dc2..78357597 100644 --- a/qt/base/preferences.py +++ b/qt/base/preferences.py @@ -12,12 +12,6 @@ from core.scanner import ScanType from qtlib.preferences import Preferences as PreferencesBase class Preferences(PreferencesBase): - DEFAULT_SCAN_TYPE = None # edition-specific - - def _load_specific(self, settings): - # load prefs specific to the dg edition - pass - def _load_values(self, settings): get = self.get_value self.filter_hardness = get('FilterHardness', self.filter_hardness) @@ -39,11 +33,17 @@ class Preferences(PreferencesBase): self.recentResults = get('RecentResults', self.recentResults) self.recentFolders = get('RecentFolders', self.recentFolders) - self._load_specific(settings) - - def _reset_specific(self): - # reset prefs specific to the dg edition - pass + self.word_weighting = get('WordWeighting', self.word_weighting) + self.match_similar = get('MatchSimilar', self.match_similar) + self.ignore_small_files = get('IgnoreSmallFiles', self.ignore_small_files) + self.small_file_threshold = get('SmallFileThreshold', self.small_file_threshold) + self.scan_tag_track = get('ScanTagTrack', self.scan_tag_track) + self.scan_tag_artist = get('ScanTagArtist', self.scan_tag_artist) + self.scan_tag_album = get('ScanTagAlbum', self.scan_tag_album) + self.scan_tag_title = get('ScanTagTitle', self.scan_tag_title) + self.scan_tag_genre = get('ScanTagGenre', self.scan_tag_genre) + self.scan_tag_year = get('ScanTagYear', self.scan_tag_year) + self.match_scaled = get('MatchScaled', self.match_scaled) def reset(self): self.filter_hardness = 95 @@ -63,11 +63,17 @@ class Preferences(PreferencesBase): self.recentResults = [] self.recentFolders = [] - self._reset_specific() - - def _save_specific(self, settings): - # save prefs specific to the dg edition - pass + self.word_weighting = True + self.match_similar = False + self.ignore_small_files = True + self.small_file_threshold = 10 # KB + self.scan_tag_track = False + self.scan_tag_artist = True + self.scan_tag_album = True + self.scan_tag_title = True + self.scan_tag_genre = False + self.scan_tag_year = False + self.match_scaled = False def _save_values(self, settings): set_ = self.set_value @@ -88,7 +94,17 @@ class Preferences(PreferencesBase): set_('RecentResults', self.recentResults) set_('RecentFolders', self.recentFolders) - self._save_specific(settings) + set_('WordWeighting', self.word_weighting) + set_('MatchSimilar', self.match_similar) + set_('IgnoreSmallFiles', self.ignore_small_files) + set_('SmallFileThreshold', self.small_file_threshold) + set_('ScanTagTrack', self.scan_tag_track) + set_('ScanTagArtist', self.scan_tag_artist) + set_('ScanTagAlbum', self.scan_tag_album) + set_('ScanTagTitle', self.scan_tag_title) + set_('ScanTagGenre', self.scan_tag_genre) + set_('ScanTagYear', self.scan_tag_year) + set_('MatchScaled', self.match_scaled) # scan_type is special because we save it immediately when we set it. def get_scan_type(self, app_mode): diff --git a/qt/base/preferences_dialog.py b/qt/base/preferences_dialog.py index d3b873ff..506ba977 100644 --- a/qt/base/preferences_dialog.py +++ b/qt/base/preferences_dialog.py @@ -10,11 +10,12 @@ from PyQt5.QtWidgets import ( QSlider, QSizePolicy, QSpacerItem, QCheckBox, QLineEdit, QMessageBox, QSpinBox ) -from hscommon.plat import ISOSX, ISLINUX from hscommon.trans import trget from qtlib.util import horizontalWrap from qtlib.preferences import get_langnames +from .preferences import Preferences + tr = trget('ui') SUPPORTED_LANGUAGES = [ @@ -123,9 +124,6 @@ class PreferencesDialogBase(QDialog): self.buttonBox = QDialogButtonBox(self) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok|QDialogButtonBox.RestoreDefaults) self.mainVLayout.addWidget(self.buttonBox) - if (not ISOSX) and (not ISLINUX): - self.mainVLayout.removeWidget(self.ignoreHardlinkMatches) - self.ignoreHardlinkMatches.setHidden(True) def _load(self, prefs, setchecked): # Edition-specific @@ -177,6 +175,9 @@ class PreferencesDialogBase(QDialog): self.app.prefs.language = lang self._save(prefs, ischecked) + def resetToDefaults(self): + self.load(Preferences()) + #--- Events def buttonClicked(self, button): role = self.buttonBox.buttonRole(button) diff --git a/qt/base/result_window.py b/qt/base/result_window.py index a3310f92..b496ed42 100644 --- a/qt/base/result_window.py +++ b/qt/base/result_window.py @@ -16,6 +16,10 @@ from hscommon.trans import trget from qtlib.util import moveToScreenCenter, horizontalWrap, createActions from qtlib.search_edit import SearchEdit +from core.app import AppMode +from ..se.results_model import ResultsModel as ResultsModelStandard +from ..me.results_model import ResultsModel as ResultsModelMusic +from ..pe.results_model import ResultsModel as ResultsModelPicture from .results_model import ResultsView from .stats_label import StatsLabel from .prioritize_dialog import PrioritizeDialog @@ -27,7 +31,13 @@ class ResultWindow(QMainWindow): super().__init__(parent, **kwargs) self.app = app self._setupUi() - self.resultsModel = app.RESULT_MODEL_CLASS(self.app, self.resultsView) + if app.model.app_mode == AppMode.Picture: + MODEL_CLASS = ResultsModelPicture + elif app.model.app_mode == AppMode.Music: + MODEL_CLASS = ResultsModelMusic + else: + MODEL_CLASS = ResultsModelStandard + self.resultsModel = MODEL_CLASS(self.app, self.resultsView) self.stats = StatsLabel(app.model.stats_label, self.statusLabel) self._update_column_actions_status() diff --git a/qt/me/preferences_dialog.py b/qt/me/preferences_dialog.py index 535b1d12..3b5caf0e 100644 --- a/qt/me/preferences_dialog.py +++ b/qt/me/preferences_dialog.py @@ -14,7 +14,6 @@ from core.app import AppMode from core.scanner import ScanType from ..base.preferences_dialog import PreferencesDialogBase -from ..se import preferences tr = trget('ui') @@ -101,6 +100,3 @@ class PreferencesDialog(PreferencesDialogBase): prefs.match_similar = ischecked(self.matchSimilarBox) prefs.word_weighting = ischecked(self.wordWeightingBox) - def resetToDefaults(self): - self.load(preferences.Preferences()) - diff --git a/qt/pe/preferences_dialog.py b/qt/pe/preferences_dialog.py index c8a18cd9..18ee9a80 100644 --- a/qt/pe/preferences_dialog.py +++ b/qt/pe/preferences_dialog.py @@ -9,7 +9,6 @@ from core.scanner import ScanType from core.app import AppMode from ..base.preferences_dialog import PreferencesDialogBase -from ..se import preferences tr = trget('ui') @@ -42,6 +41,3 @@ class PreferencesDialog(PreferencesDialogBase): def _save(self, prefs, ischecked): prefs.match_scaled = ischecked(self.matchScaledBox) - def resetToDefaults(self): - self.load(preferences.Preferences()) - diff --git a/qt/run_template.py b/qt/run_template.py index be86bded..7954d9c9 100644 --- a/qt/run_template.py +++ b/qt/run_template.py @@ -32,7 +32,7 @@ def main(): install_gettext_trans_under_qt(locale_folder, lang) # Many strings are translated at import time, so this is why we only import after the translator # has been installed - from qt.se.app import DupeGuru + from qt.base.app import DupeGuru app.setWindowIcon(QIcon(QPixmap(":/{0}".format(DupeGuru.LOGO_NAME)))) dgapp = DupeGuru() install_excepthook('https://github.com/hsoft/dupeguru/issues') diff --git a/qt/se/app.py b/qt/se/app.py deleted file mode 100644 index 72c2cf51..00000000 --- a/qt/se/app.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright 2016 Hardcoded Software (http://www.hardcoded.net) -# -# 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 - -from core_se import __appname__ -from core_se.app import DupeGuru as DupeGuruModel -from core.directories import Directories as DirectoriesBase, DirectoryState -from core.app import AppMode -import core_pe.photo - -from ..base.app import DupeGuru as DupeGuruBase -from .details_dialog import DetailsDialog as DetailsDialogStandard -from ..me.details_dialog import DetailsDialog as DetailsDialogMusic -from ..pe.details_dialog import DetailsDialog as DetailsDialogPicture -from .results_model import ResultsModel as ResultsModelStandard -from ..me.results_model import ResultsModel as ResultsModelMusic -from ..pe.results_model import ResultsModel as ResultsModelPicture -from .preferences import Preferences -from .preferences_dialog import PreferencesDialog as PreferencesDialogStandard -from ..me.preferences_dialog import PreferencesDialog as PreferencesDialogMusic -from ..pe.preferences_dialog import PreferencesDialog as PreferencesDialogPicture -from ..pe.photo import File as PlatSpecificPhoto - -class Directories(DirectoriesBase): - ROOT_PATH_TO_EXCLUDE = frozenset(['windows', 'program files']) - - def _default_state_for_path(self, path): - result = DirectoriesBase._default_state_for_path(self, path) - if result is not None: - return result - if len(path) == 2 and path[1].lower() in self.ROOT_PATH_TO_EXCLUDE: - return DirectoryState.Excluded - -class DupeGuru(DupeGuruBase): - MODELCLASS = DupeGuruModel - EDITION = 'se' - LOGO_NAME = 'logo_se' - NAME = __appname__ - - PREFERENCES_CLASS = Preferences - - def _setup(self): - self.directories = Directories() - DupeGuruBase._setup(self) - core_pe.photo.PLAT_SPECIFIC_PHOTO_CLASS = PlatSpecificPhoto - - def _update_options(self): - DupeGuruBase._update_options(self) - self.model.options['min_match_percentage'] = self.prefs.filter_hardness - self.model.options['word_weighting'] = self.prefs.word_weighting - self.model.options['match_similar_words'] = self.prefs.match_similar - threshold = self.prefs.small_file_threshold if self.prefs.ignore_small_files else 0 - self.model.options['size_threshold'] = threshold * 1024 # threshold is in KB. the scanner wants bytes - scanned_tags = set() - if self.prefs.scan_tag_track: - scanned_tags.add('track') - if self.prefs.scan_tag_artist: - scanned_tags.add('artist') - if self.prefs.scan_tag_album: - scanned_tags.add('album') - if self.prefs.scan_tag_title: - scanned_tags.add('title') - if self.prefs.scan_tag_genre: - scanned_tags.add('genre') - if self.prefs.scan_tag_year: - scanned_tags.add('year') - self.model.options['scanned_tags'] = scanned_tags - self.model.options['match_scaled'] = self.prefs.match_scaled - - @property - def DETAILS_DIALOG_CLASS(self): - if self.model.app_mode == AppMode.Picture: - return DetailsDialogPicture - elif self.model.app_mode == AppMode.Music: - return DetailsDialogMusic - else: - return DetailsDialogStandard - - @property - def RESULT_MODEL_CLASS(self): - if self.model.app_mode == AppMode.Picture: - return ResultsModelPicture - elif self.model.app_mode == AppMode.Music: - return ResultsModelMusic - else: - return ResultsModelStandard - - @property - def PREFERENCES_DIALOG_CLASS(self): - if self.model.app_mode == AppMode.Picture: - return PreferencesDialogPicture - elif self.model.app_mode == AppMode.Music: - return PreferencesDialogMusic - else: - return PreferencesDialogStandard - diff --git a/qt/se/preferences.py b/qt/se/preferences.py deleted file mode 100644 index 2b5d92d7..00000000 --- a/qt/se/preferences.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright 2016 Hardcoded Software (http://www.hardcoded.net) -# -# 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 - -from ..base.preferences import Preferences as PreferencesBase - -class Preferences(PreferencesBase): - def _load_specific(self, settings): - get = self.get_value - self.word_weighting = get('WordWeighting', self.word_weighting) - self.match_similar = get('MatchSimilar', self.match_similar) - self.ignore_small_files = get('IgnoreSmallFiles', self.ignore_small_files) - self.small_file_threshold = get('SmallFileThreshold', self.small_file_threshold) - self.scan_tag_track = get('ScanTagTrack', self.scan_tag_track) - self.scan_tag_artist = get('ScanTagArtist', self.scan_tag_artist) - self.scan_tag_album = get('ScanTagAlbum', self.scan_tag_album) - self.scan_tag_title = get('ScanTagTitle', self.scan_tag_title) - self.scan_tag_genre = get('ScanTagGenre', self.scan_tag_genre) - self.scan_tag_year = get('ScanTagYear', self.scan_tag_year) - self.match_scaled = get('MatchScaled', self.match_scaled) - - def _reset_specific(self): - self.filter_hardness = 95 - self.word_weighting = True - self.match_similar = False - self.ignore_small_files = True - self.small_file_threshold = 10 # KB - self.scan_tag_track = False - self.scan_tag_artist = True - self.scan_tag_album = True - self.scan_tag_title = True - self.scan_tag_genre = False - self.scan_tag_year = False - self.match_scaled = False - - def _save_specific(self, settings): - set_ = self.set_value - set_('WordWeighting', self.word_weighting) - set_('MatchSimilar', self.match_similar) - set_('IgnoreSmallFiles', self.ignore_small_files) - set_('SmallFileThreshold', self.small_file_threshold) - set_('ScanTagTrack', self.scan_tag_track) - set_('ScanTagArtist', self.scan_tag_artist) - set_('ScanTagAlbum', self.scan_tag_album) - set_('ScanTagTitle', self.scan_tag_title) - set_('ScanTagGenre', self.scan_tag_genre) - set_('ScanTagYear', self.scan_tag_year) - set_('MatchScaled', self.match_scaled) - diff --git a/qt/se/preferences_dialog.py b/qt/se/preferences_dialog.py index 01716011..9daf276e 100644 --- a/qt/se/preferences_dialog.py +++ b/qt/se/preferences_dialog.py @@ -17,7 +17,6 @@ from core.app import AppMode from core.scanner import ScanType from ..base.preferences_dialog import PreferencesDialogBase -from . import preferences tr = trget('ui') @@ -94,6 +93,3 @@ class PreferencesDialog(PreferencesDialogBase): prefs.ignore_small_files = ischecked(self.ignoreSmallFilesBox) prefs.small_file_threshold = tryint(self.sizeThresholdEdit.text()) - def resetToDefaults(self): - self.load(preferences.Preferences()) -