mirror of
https://github.com/arsenetar/dupeguru.git
synced 2025-03-10 05:34:36 +00:00
The Qt side now makes use of core.gui.details_panel.
This commit is contained in:
parent
484512e35b
commit
8dda616502
11
core/app.py
11
core/app.py
@ -17,6 +17,7 @@ from hsutil import io, files
|
||||
from hsutil.path import Path
|
||||
from hsutil.reg import RegistrableApplication, RegistrationRequired
|
||||
from hsutil.misc import flatten, first
|
||||
from hsutil.notify import Broadcaster
|
||||
from hsutil.str import escape
|
||||
|
||||
from . import directories, results, scanner, export, fs
|
||||
@ -33,11 +34,12 @@ class NoScannableFileError(Exception):
|
||||
class AllFilesAreRefError(Exception):
|
||||
pass
|
||||
|
||||
class DupeGuru(RegistrableApplication):
|
||||
class DupeGuru(RegistrableApplication, Broadcaster):
|
||||
DEMO_LIMIT_DESC = "In the demo version, only 10 duplicates per session can be sent to the recycle bin, moved or copied."
|
||||
|
||||
def __init__(self, data_module, appdata, appid):
|
||||
RegistrableApplication.__init__(self, appid)
|
||||
Broadcaster.__init__(self)
|
||||
self.appdata = appdata
|
||||
if not op.exists(self.appdata):
|
||||
os.makedirs(self.appdata)
|
||||
@ -51,6 +53,7 @@ class DupeGuru(RegistrableApplication):
|
||||
'escape_filter_regexp': True,
|
||||
'clean_empty_dirs': False,
|
||||
}
|
||||
self.selected_dupes = []
|
||||
|
||||
def _demo_check(self):
|
||||
if self.registered:
|
||||
@ -104,6 +107,12 @@ class DupeGuru(RegistrableApplication):
|
||||
def _recycle_dupe(dupe):
|
||||
raise NotImplementedError()
|
||||
|
||||
def _select_dupes(self, dupes):
|
||||
if dupes == self.selected_dupes:
|
||||
return
|
||||
self.selected_dupes = dupes
|
||||
self.notify('dupes_selected')
|
||||
|
||||
def _start_job(self, jobid, func):
|
||||
# func(j)
|
||||
raise NotImplementedError()
|
||||
|
@ -15,7 +15,6 @@ from hsutil.cocoa.objcmin import (NSNotificationCenter, NSUserDefaults,
|
||||
NSSearchPathForDirectoriesInDomains, NSApplicationSupportDirectory, NSUserDomainMask,
|
||||
NSWorkspace, NSWorkspaceRecycleOperation)
|
||||
from hsutil.misc import stripnone
|
||||
from hsutil.notify import Broadcaster
|
||||
from hsutil.reg import RegistrationRequired
|
||||
|
||||
from . import app, fs
|
||||
@ -37,9 +36,8 @@ def demo_method(method):
|
||||
|
||||
return wrapper
|
||||
|
||||
class DupeGuru(app.DupeGuru, Broadcaster):
|
||||
class DupeGuru(app.DupeGuru):
|
||||
def __init__(self, data_module, appdata_subdir, appid):
|
||||
Broadcaster.__init__(self)
|
||||
LOGGING_LEVEL = logging.DEBUG if NSUserDefaults.standardUserDefaults().boolForKey_('debug') else logging.WARNING
|
||||
logging.basicConfig(level=LOGGING_LEVEL, format='%(levelname)s %(message)s')
|
||||
logging.debug('started in debug mode')
|
||||
@ -49,7 +47,6 @@ class DupeGuru(app.DupeGuru, Broadcaster):
|
||||
app.DupeGuru.__init__(self, data_module, appdata, appid)
|
||||
self.progress = cocoa.ThreadedJobPerformer()
|
||||
self.display_delta_values = False
|
||||
self.selected_dupes = []
|
||||
|
||||
#--- Override
|
||||
@staticmethod
|
||||
@ -92,12 +89,6 @@ class DupeGuru(app.DupeGuru, Broadcaster):
|
||||
curr_path = self.directories.get_subfolders(curr_path)[current_index]
|
||||
return self.get_folder_path(node_path[1:], curr_path)
|
||||
|
||||
def _select_dupes(self, dupes):
|
||||
if dupes == self.selected_dupes:
|
||||
return
|
||||
self.selected_dupes = dupes
|
||||
self.notify('dupes_selected')
|
||||
|
||||
#---Public
|
||||
def AddSelectedToIgnoreList(self):
|
||||
for dupe in self.selected_dupes:
|
||||
|
@ -65,7 +65,6 @@ class DupeGuru(DupeGuruBase, QObject):
|
||||
|
||||
#--- Private
|
||||
def _setup(self):
|
||||
self.selected_dupe = None
|
||||
self.prefs = self._create_preferences()
|
||||
self.prefs.load()
|
||||
self._update_options()
|
||||
@ -179,9 +178,9 @@ class DupeGuru(DupeGuruBase, QObject):
|
||||
QDesktopServices.openUrl(url)
|
||||
|
||||
def open_selected(self):
|
||||
if self.selected_dupe is None:
|
||||
if not self.selected_dupes:
|
||||
return
|
||||
url = QUrl.fromLocalFile(unicode(self.selected_dupe.path))
|
||||
url = QUrl.fromLocalFile(unicode(self.selected_dupes[0].path))
|
||||
QDesktopServices.openUrl(url)
|
||||
|
||||
def remove_duplicates(self, duplicates):
|
||||
@ -201,14 +200,13 @@ class DupeGuru(DupeGuruBase, QObject):
|
||||
return False
|
||||
|
||||
def reveal_selected(self):
|
||||
if self.selected_dupe is None:
|
||||
if not self.selected_dupes:
|
||||
return
|
||||
url = QUrl.fromLocalFile(unicode(self.selected_dupe.path[:-1]))
|
||||
url = QUrl.fromLocalFile(unicode(self.selected_dupe[0].path[:-1]))
|
||||
QDesktopServices.openUrl(url)
|
||||
|
||||
def select_duplicate(self, dupe):
|
||||
self.selected_dupe = dupe
|
||||
self.emit(SIGNAL('duplicateSelected()'))
|
||||
self._select_dupes([dupe])
|
||||
|
||||
def show_about_box(self):
|
||||
self.about_box.show()
|
||||
|
33
qt/base/details_dialog.py
Normal file
33
qt/base/details_dialog.py
Normal file
@ -0,0 +1,33 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Created By: Virgil Dupras
|
||||
# Created On: 2010-02-05
|
||||
# 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 PyQt4.QtCore import Qt
|
||||
from PyQt4.QtGui import QDialog
|
||||
|
||||
from core.gui.details_panel import DetailsPanel
|
||||
|
||||
from .details_table import DetailsModel
|
||||
|
||||
class DetailsDialog(QDialog):
|
||||
def __init__(self, parent, app):
|
||||
QDialog.__init__(self, parent, Qt.Tool)
|
||||
self.app = app
|
||||
self.model = DetailsPanel(self, app)
|
||||
self._setupUi()
|
||||
self.tableModel = DetailsModel(self.model)
|
||||
# tableView is defined in subclasses
|
||||
self.tableView.setModel(self.tableModel)
|
||||
|
||||
def _setupUi(self): # Virtual
|
||||
pass
|
||||
|
||||
# model --> view
|
||||
def refresh(self):
|
||||
self.tableModel.reset()
|
||||
|
@ -6,57 +6,35 @@
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.hardcoded.net/licenses/hs_license
|
||||
|
||||
from PyQt4.QtCore import Qt, SIGNAL, QAbstractTableModel, QVariant
|
||||
from PyQt4.QtCore import Qt, SIGNAL, QAbstractTableModel
|
||||
from PyQt4.QtGui import QHeaderView, QTableView
|
||||
|
||||
HEADER = ['Attribute', 'Selected', 'Reference']
|
||||
|
||||
class DetailsModel(QAbstractTableModel):
|
||||
def __init__(self, app):
|
||||
def __init__(self, model):
|
||||
QAbstractTableModel.__init__(self)
|
||||
self._app = app
|
||||
self._dupe_data = None
|
||||
self._ref_data = None
|
||||
self.connect(app, SIGNAL('duplicateSelected()'), self.duplicateSelected)
|
||||
self.model = model
|
||||
|
||||
def columnCount(self, parent):
|
||||
return len(HEADER)
|
||||
|
||||
def data(self, index, role):
|
||||
if not index.isValid():
|
||||
return QVariant()
|
||||
return None
|
||||
if role != Qt.DisplayRole:
|
||||
return QVariant()
|
||||
return None
|
||||
column = index.column()
|
||||
row = index.row()
|
||||
if column == 0:
|
||||
return QVariant(self._app.data.COLUMNS[row]['display'])
|
||||
elif column == 1 and self._dupe_data:
|
||||
return QVariant(self._dupe_data[row])
|
||||
elif column == 2 and self._ref_data:
|
||||
return QVariant(self._ref_data[row])
|
||||
return QVariant()
|
||||
return self.model.row(row)[column]
|
||||
|
||||
def headerData(self, section, orientation, role):
|
||||
if orientation == Qt.Horizontal and role == Qt.DisplayRole and section < len(HEADER):
|
||||
return QVariant(HEADER[section])
|
||||
return QVariant()
|
||||
return HEADER[section]
|
||||
return None
|
||||
|
||||
def rowCount(self, parent):
|
||||
return len(self._app.data.COLUMNS)
|
||||
|
||||
#--- Events
|
||||
def duplicateSelected(self):
|
||||
dupe = self._app.selected_dupe
|
||||
if dupe is None:
|
||||
group = None
|
||||
ref = None
|
||||
else:
|
||||
group = self._app.results.get_group_of_duplicate(dupe)
|
||||
ref = group.ref if group.ref is not dupe else None
|
||||
self._dupe_data = self._app._get_display_info(dupe, group)
|
||||
self._ref_data = self._app._get_display_info(ref, group)
|
||||
self.reset()
|
||||
return self.model.row_count()
|
||||
|
||||
|
||||
class DetailsTable(QTableView):
|
||||
|
@ -316,9 +316,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
|
||||
def resultsReset(self):
|
||||
self.resultsView.expandAll()
|
||||
dupe = self.app.selected_dupe
|
||||
if dupe is not None:
|
||||
[modelIndex] = self.resultsModel.indexesForDupes([dupe])
|
||||
if self.app.selected_dupes:
|
||||
[modelIndex] = self.resultsModel.indexesForDupes(self.app.selected_dupes[:1])
|
||||
if modelIndex.isValid():
|
||||
flags = QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows
|
||||
self.resultsView.selectionModel().setCurrentIndex(modelIndex, flags)
|
||||
|
@ -6,16 +6,10 @@
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.hardcoded.net/licenses/hs_license
|
||||
|
||||
from PyQt4.QtCore import Qt
|
||||
from PyQt4.QtGui import QDialog
|
||||
|
||||
from base.details_table import DetailsModel
|
||||
from base.details_dialog import DetailsDialog as DetailsDialogBase
|
||||
from details_dialog_ui import Ui_DetailsDialog
|
||||
|
||||
class DetailsDialog(QDialog, Ui_DetailsDialog):
|
||||
def __init__(self, parent, app):
|
||||
QDialog.__init__(self, parent, Qt.Tool)
|
||||
self.app = app
|
||||
class DetailsDialog(DetailsDialogBase, Ui_DetailsDialog):
|
||||
def _setupUi(self):
|
||||
self.setupUi(self)
|
||||
self.model = DetailsModel(app)
|
||||
self.tableView.setModel(self.model)
|
||||
|
||||
|
@ -6,27 +6,25 @@
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.hardcoded.net/licenses/hs_license
|
||||
|
||||
from PyQt4.QtCore import Qt, SIGNAL, QAbstractTableModel, QVariant
|
||||
from PyQt4.QtGui import QDialog, QHeaderView, QPixmap
|
||||
from PyQt4.QtCore import Qt
|
||||
from PyQt4.QtGui import QPixmap
|
||||
|
||||
from base.details_table import DetailsModel
|
||||
from base.details_dialog import DetailsDialog as DetailsDialogBase
|
||||
from details_dialog_ui import Ui_DetailsDialog
|
||||
|
||||
class DetailsDialog(QDialog, Ui_DetailsDialog):
|
||||
class DetailsDialog(DetailsDialogBase, Ui_DetailsDialog):
|
||||
def __init__(self, parent, app):
|
||||
QDialog.__init__(self, parent, Qt.Tool)
|
||||
self.app = app
|
||||
DetailsDialogBase.__init__(self, parent, app)
|
||||
self.selectedPixmap = None
|
||||
self.referencePixmap = None
|
||||
|
||||
def _setupUi(self):
|
||||
self.setupUi(self)
|
||||
self.model = DetailsModel(app)
|
||||
self.tableView.setModel(self.model)
|
||||
self.connect(app, SIGNAL('duplicateSelected()'), self.duplicateSelected)
|
||||
|
||||
def _update(self):
|
||||
dupe = self.app.selected_dupe
|
||||
if dupe is None:
|
||||
if not self.app.selected_dupes:
|
||||
return
|
||||
dupe = self.app.selected_dupes[0]
|
||||
group = self.app.results.get_group_of_duplicate(dupe)
|
||||
ref = group.ref
|
||||
|
||||
@ -56,11 +54,12 @@ class DetailsDialog(QDialog, Ui_DetailsDialog):
|
||||
self._updateImages()
|
||||
|
||||
def show(self):
|
||||
QDialog.show(self)
|
||||
DetailsDialogBase.show(self)
|
||||
self._update()
|
||||
|
||||
#--- Events
|
||||
def duplicateSelected(self):
|
||||
# model --> view
|
||||
def refresh(self):
|
||||
DetailsDialogBase.refresh(self)
|
||||
if self.isVisible():
|
||||
self._update()
|
||||
|
||||
|
@ -6,16 +6,10 @@
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.hardcoded.net/licenses/hs_license
|
||||
|
||||
from PyQt4.QtCore import Qt
|
||||
from PyQt4.QtGui import QDialog
|
||||
|
||||
from base.details_table import DetailsModel
|
||||
from base.details_dialog import DetailsDialog as DetailsDialogBase
|
||||
from details_dialog_ui import Ui_DetailsDialog
|
||||
|
||||
class DetailsDialog(QDialog, Ui_DetailsDialog):
|
||||
def __init__(self, parent, app):
|
||||
QDialog.__init__(self, parent, Qt.Tool)
|
||||
self.app = app
|
||||
class DetailsDialog(DetailsDialogBase, Ui_DetailsDialog):
|
||||
def _setupUi(self):
|
||||
self.setupUi(self)
|
||||
self.model = DetailsModel(app)
|
||||
self.tableView.setModel(self.model)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user