Adapted the Qt codebase to the addition of core.gui.result_tree and core.gui.stats_label.

This commit is contained in:
Virgil Dupras 2010-02-12 15:39:29 +01:00
parent c3a972d39b
commit cab6d924aa
14 changed files with 142 additions and 208 deletions

View File

@ -14,9 +14,16 @@ http://www.hardcoded.net/licenses/hs_license
{ {
self = [super initWithNibName:@"DetailsPanel" pyClassName:@"PyDetailsPanel" pyParent:aPy]; self = [super initWithNibName:@"DetailsPanel" pyClassName:@"PyDetailsPanel" pyParent:aPy];
[self window]; //So the detailsTable is initialized. [self window]; //So the detailsTable is initialized.
[self connect];
return self; return self;
} }
- (void)dealloc
{
[self disconnect];
[super dealloc];
}
- (PyDetailsPanel *)py - (PyDetailsPanel *)py
{ {
return (PyDetailsPanel *)py; return (PyDetailsPanel *)py;

View File

@ -13,9 +13,16 @@ http://www.hardcoded.net/licenses/hs_license
{ {
self = [super initWithPyClassName:@"PyDirectoryOutline" pyParent:aPyParent view:aOutlineView]; self = [super initWithPyClassName:@"PyDirectoryOutline" pyParent:aPyParent view:aOutlineView];
[outlineView registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]]; [outlineView registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];
[self connect];
return self; return self;
} }
- (void)dealloc
{
[self disconnect];
[super dealloc];
}
- (PyDirectoryOutline *)py - (PyDirectoryOutline *)py
{ {
return (PyDirectoryOutline *)py; return (PyDirectoryOutline *)py;

View File

@ -16,11 +16,13 @@ http://www.hardcoded.net/licenses/hs_license
{ {
self = [super initWithPyClassName:@"PyResultOutline" pyParent:aPyParent view:aOutlineView]; self = [super initWithPyClassName:@"PyResultOutline" pyParent:aPyParent view:aOutlineView];
_rootChildrenCounts = nil; _rootChildrenCounts = nil;
[self connect];
return self; return self;
} }
- (void)dealloc - (void)dealloc
{ {
[self disconnect];
[_deltaColumns release]; [_deltaColumns release];
[super dealloc]; [super dealloc];
} }

View File

@ -14,11 +14,13 @@ http://www.hardcoded.net/licenses/hs_license
{ {
self = [super initWithPyClassName:@"PyStatsLabel" pyParent:aPyParent]; self = [super initWithPyClassName:@"PyStatsLabel" pyParent:aPyParent];
labelView = [aLabelView retain]; labelView = [aLabelView retain];
[self connect];
return self; return self;
} }
- (void)dealloc - (void)dealloc
{ {
[self disconnect];
[labelView release]; [labelView release];
[super dealloc]; [super dealloc];
} }

View File

@ -13,8 +13,11 @@ class DetailsPanel(GUIObject):
def __init__(self, view, app): def __init__(self, view, app):
GUIObject.__init__(self, view, app) GUIObject.__init__(self, view, app)
self._table = [] self._table = []
def connect(self):
GUIObject.connect(self)
self._refresh() self._refresh()
self.connect() self.view.refresh()
#--- Private #--- Private
def _refresh(self): def _refresh(self):

View File

@ -53,7 +53,9 @@ class DirectoryTree(GUIObject, Tree):
def __init__(self, view, app): def __init__(self, view, app):
GUIObject.__init__(self, view, app) GUIObject.__init__(self, view, app)
Tree.__init__(self) Tree.__init__(self)
self.connect()
def connect(self):
GUIObject.connect(self)
self._refresh() self._refresh()
self.view.refresh() self.view.refresh()

View File

@ -54,11 +54,13 @@ class ResultTree(GUIObject, Tree):
self._power_marker = False self._power_marker = False
self._delta_values = False self._delta_values = False
self._sort_descriptors = (0, True) self._sort_descriptors = (0, True)
self.connect()
#--- Override
def connect(self):
GUIObject.connect(self)
self._refresh() self._refresh()
self.view.refresh() self.view.refresh()
#--- Override
def _select_nodes(self, nodes): def _select_nodes(self, nodes):
Tree._select_nodes(self, nodes) Tree._select_nodes(self, nodes)
self.app._select_dupes(map(attrgetter('_dupe'), nodes)) self.app._select_dupes(map(attrgetter('_dupe'), nodes))

View File

@ -10,9 +10,8 @@
from .base import GUIObject from .base import GUIObject
class StatsLabel(GUIObject): class StatsLabel(GUIObject):
def __init__(self, view, app): def connect(self):
GUIObject.__init__(self, view, app) GUIObject.connect(self)
self.connect()
self.view.refresh() self.view.refresh()
@property @property

View File

@ -12,13 +12,12 @@ import logging
import os import os
import os.path as op import os.path as op
from PyQt4.QtCore import Qt, QTimer, QObject, QCoreApplication, QUrl, SIGNAL from PyQt4.QtCore import QTimer, QObject, QCoreApplication, QUrl, SIGNAL
from PyQt4.QtGui import QProgressDialog, QDesktopServices, QFileDialog, QDialog, QMessageBox from PyQt4.QtGui import QDesktopServices, QFileDialog, QDialog, QMessageBox
from hsutil import job from hsutil import job
from hsutil.reg import RegistrationRequired from hsutil.reg import RegistrationRequired
from core import fs
from core.app import DupeGuru as DupeGuruBase, JOB_SCAN, JOB_LOAD, JOB_MOVE, JOB_COPY, JOB_DELETE from core.app import DupeGuru as DupeGuruBase, JOB_SCAN, JOB_LOAD, JOB_MOVE, JOB_COPY, JOB_DELETE
from qtlib.about_box import AboutBox from qtlib.about_box import AboutBox
@ -148,10 +147,6 @@ class DupeGuru(DupeGuruBase, QObject):
if self.main_window._confirm(title, msg): if self.main_window._confirm(title, msg):
DupeGuruBase.add_selected_to_ignore_list(self) DupeGuruBase.add_selected_to_ignore_list(self)
def apply_filter(self, filter):
DupeGuruBase.apply_filter(self, filter)
self.emit(SIGNAL('resultsChanged()'))
@demo_method @demo_method
def copy_or_move_marked(self, copy): def copy_or_move_marked(self, copy):
opname = 'copy' if copy else 'move' opname = 'copy' if copy else 'move'
@ -165,14 +160,6 @@ class DupeGuru(DupeGuruBase, QObject):
delete_marked = demo_method(DupeGuruBase.delete_marked) delete_marked = demo_method(DupeGuruBase.delete_marked)
def make_selected_reference(self):
DupeGuruBase.make_selected_reference(self)
self.emit(SIGNAL('resultsChanged()'))
def remove_duplicates(self, duplicates):
DupeGuruBase.remove_duplicates(self, duplicates)
self.emit(SIGNAL('resultsChanged()'))
def remove_selected(self): def remove_selected(self):
dupes = self.without_ref(self.selected_dupes) dupes = self.without_ref(self.selected_dupes)
if not dupes: if not dupes:
@ -186,37 +173,10 @@ class DupeGuru(DupeGuruBase, QObject):
def askForRegCode(self): def askForRegCode(self):
self.reg.ask_for_code() self.reg.ask_for_code()
def mark_all(self):
self.results.mark_all()
self.emit(SIGNAL('dupeMarkingChanged()'))
def mark_invert(self):
self.results.mark_invert()
self.emit(SIGNAL('dupeMarkingChanged()'))
def mark_none(self):
self.results.mark_none()
self.emit(SIGNAL('dupeMarkingChanged()'))
def openDebugLog(self): def openDebugLog(self):
debugLogPath = op.join(self.appdata, 'debug.log') debugLogPath = op.join(self.appdata, 'debug.log')
self._open_path(debugLogPath) self._open_path(debugLogPath)
def remove_marked_duplicates(self):
marked = [d for d in self.results.dupes if self.results.is_marked(d)]
self.remove_duplicates(marked)
def rename_dupe(self, dupe, newname):
try:
dupe.rename(newname)
return True
except (IndexError, fs.FSError) as e:
logging.warning("dupeGuru Warning: %s" % unicode(e))
return False
def select_dupes(self, dupes):
self._select_dupes(dupes)
def show_about_box(self): def show_about_box(self):
self.about_box.show() self.about_box.show()
@ -238,11 +198,6 @@ class DupeGuru(DupeGuruBase, QObject):
self.prefs.save() self.prefs.save()
self._update_options() self._update_options()
def toggle_marking_for_dupes(self, dupes):
for dupe in dupes:
self.results.mark_toggle(dupe)
self.emit(SIGNAL('dupeMarkingChanged()'))
#--- Events #--- Events
def application_will_terminate(self): def application_will_terminate(self):
self.save() self.save()
@ -253,7 +208,7 @@ class DupeGuru(DupeGuruBase, QObject):
self.reg.show_nag() self.reg.show_nag()
def job_finished(self, jobid): def job_finished(self, jobid):
self.emit(SIGNAL('resultsChanged()')) self._job_completed(jobid)
if jobid in (JOB_MOVE, JOB_COPY, JOB_DELETE) and self.last_op_error_count > 0: if jobid in (JOB_MOVE, JOB_COPY, JOB_DELETE) and self.last_op_error_count > 0:
msg = "{0} files could not be processed.".format(self.results.mark_count) msg = "{0} files could not be processed.".format(self.results.mark_count)
QMessageBox.warning(self.main_window, 'Warning', msg) QMessageBox.warning(self.main_window, 'Warning', msg)

View File

@ -23,6 +23,7 @@ class DetailsDialog(QDialog):
self.tableModel = DetailsModel(self.model) self.tableModel = DetailsModel(self.model)
# tableView is defined in subclasses # tableView is defined in subclasses
self.tableView.setModel(self.tableModel) self.tableView.setModel(self.tableModel)
self.model.connect()
def _setupUi(self): # Virtual def _setupUi(self): # Virtual
pass pass

View File

@ -64,6 +64,7 @@ class DirectoriesModel(TreeModel):
def __init__(self, app): def __init__(self, app):
TreeModel.__init__(self) TreeModel.__init__(self)
self.model = DirectoryTree(self, app) self.model = DirectoryTree(self, app)
self.model.connect()
def _createNode(self, ref, row): def _createNode(self, ref, row):
return RefNode(self, None, ref, row) return RefNode(self, None, ref, row)

View File

@ -8,7 +8,7 @@
from PyQt4.QtCore import Qt, QCoreApplication, QProcess, SIGNAL, QUrl from PyQt4.QtCore import Qt, QCoreApplication, QProcess, SIGNAL, QUrl
from PyQt4.QtGui import (QMainWindow, QMenu, QPixmap, QIcon, QToolButton, QLabel, QHeaderView, from PyQt4.QtGui import (QMainWindow, QMenu, QPixmap, QIcon, QToolButton, QLabel, QHeaderView,
QMessageBox, QInputDialog, QLineEdit, QItemSelectionModel, QDesktopServices) QMessageBox, QInputDialog, QLineEdit, QDesktopServices)
from hsutil.misc import nonone from hsutil.misc import nonone
@ -16,7 +16,8 @@ from core.app import NoScannableFileError, AllFilesAreRefError
import dg_rc import dg_rc
from main_window_ui import Ui_MainWindow from main_window_ui import Ui_MainWindow
from results_model import ResultsDelegate, ResultsModel from results_model import ResultsModel
from stats_label import StatsLabel
class MainWindow(QMainWindow, Ui_MainWindow): class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self, app): def __init__(self, app):
@ -24,23 +25,16 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.app = app self.app = app
self._last_filter = None self._last_filter = None
self._setupUi() self._setupUi()
self.resultsDelegate = ResultsDelegate() self.resultsModel = ResultsModel(self.app, self.resultsView)
self.resultsModel = ResultsModel(self.app) self.stats = StatsLabel(app, self.statusLabel)
self.resultsView.setModel(self.resultsModel)
self.resultsView.setItemDelegate(self.resultsDelegate)
self._load_columns() self._load_columns()
self._update_column_actions_status() self._update_column_actions_status()
self.resultsView.expandAll()
self._update_status_line()
self.connect(self.app, SIGNAL('resultsChanged()'), self.resultsChanged)
self.connect(self.app, SIGNAL('dupeMarkingChanged()'), self.dupeMarkingChanged)
self.connect(self.actionQuit, SIGNAL('triggered()'), QCoreApplication.instance().quit) self.connect(self.actionQuit, SIGNAL('triggered()'), QCoreApplication.instance().quit)
self.connect(self.resultsView.selectionModel(), SIGNAL('selectionChanged(QItemSelection,QItemSelection)'), self.selectionChanged)
self.connect(self.menuColumns, SIGNAL('triggered(QAction*)'), self.columnToggled) self.connect(self.menuColumns, SIGNAL('triggered(QAction*)'), self.columnToggled)
self.connect(QCoreApplication.instance(), SIGNAL('aboutToQuit()'), self.application_will_terminate) self.connect(QCoreApplication.instance(), SIGNAL('aboutToQuit()'), self.application_will_terminate)
self.connect(self.resultsModel, SIGNAL('modelReset()'), self.resultsReset)
self.connect(self.resultsView, SIGNAL('doubleClicked()'), self.resultsDoubleClicked) self.connect(self.resultsView, SIGNAL('doubleClicked()'), self.resultsDoubleClicked)
self.connect(self.resultsView, SIGNAL('spacePressed()'), self.resultsSpacePressed)
def _setupUi(self): def _setupUi(self):
self.setupUi(self) self.setupUi(self)
@ -108,11 +102,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
h.setSectionHidden(index, not visible) h.setSectionHidden(index, not visible)
h.setResizeMode(0, QHeaderView.Stretch) h.setResizeMode(0, QHeaderView.Stretch)
def _redraw_results(self):
# HACK. this is the only way I found to update the widget without reseting everything
self.resultsView.scroll(0, 1)
self.resultsView.scroll(0, -1)
def _save_columns(self): def _save_columns(self):
h = self.resultsView.header() h = self.resultsView.header()
widths = [] widths = []
@ -131,9 +120,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
colid = action.column_index colid = action.column_index
action.setChecked(not h.isSectionHidden(colid)) action.setChecked(not h.isSectionHidden(colid))
def _update_status_line(self):
self.statusLabel.setText(self.app.stat_line)
#--- Actions #--- Actions
def aboutTriggered(self): def aboutTriggered(self):
self.app.show_about_box() self.app.show_about_box()
@ -185,8 +171,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.app.delete_marked() self.app.delete_marked()
def deltaTriggered(self): def deltaTriggered(self):
self.resultsModel.delta = self.actionDelta.isChecked() self.resultsModel.delta_values = self.actionDelta.isChecked()
self._redraw_results()
def detailsTriggered(self): def detailsTriggered(self):
self.app.show_details() self.app.show_details()
@ -217,8 +202,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.app.mark_none() self.app.mark_none()
def markSelectedTriggered(self): def markSelectedTriggered(self):
dupes = self.resultsView.selectedDupes() self.app.toggle_selected_mark_state()
self.app.toggle_marking_for_dupes(dupes)
def moveTriggered(self): def moveTriggered(self):
self.app.copy_or_move_marked(False) self.app.copy_or_move_marked(False)
@ -245,7 +229,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
title = "Remove duplicates" title = "Remove duplicates"
msg = "You are about to remove {0} files from results. Continue?".format(count) msg = "You are about to remove {0} files from results. Continue?".format(count)
if self._confirm(title, msg): if self._confirm(title, msg):
self.app.remove_marked_duplicates() self.app.remove_marked()
def removeSelectedTriggered(self): def removeSelectedTriggered(self):
self.app.remove_selected() self.app.remove_selected()
@ -292,25 +276,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def contextMenuEvent(self, event): def contextMenuEvent(self, event):
self.actionActions.menu().exec_(event.globalPos()) self.actionActions.menu().exec_(event.globalPos())
def dupeMarkingChanged(self):
self._redraw_results()
self._update_status_line()
def resultsChanged(self):
self.resultsView.model().reset()
def resultsDoubleClicked(self): def resultsDoubleClicked(self):
self.app.open_selected() self.app.open_selected()
def resultsReset(self): def resultsSpacePressed(self):
self.resultsView.expandAll() self.app.toggle_selected_mark_state()
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)
self._update_status_line()
def selectionChanged(self, selected, deselected):
self.app.select_dupes(self.resultsView.selectedDupes())

View File

@ -6,74 +6,62 @@
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
# http://www.hardcoded.net/licenses/hs_license # http://www.hardcoded.net/licenses/hs_license
from PyQt4.QtCore import SIGNAL, Qt, QAbstractItemModel, QModelIndex, QRect from PyQt4.QtCore import SIGNAL, Qt
from PyQt4.QtGui import QBrush, QStyledItemDelegate, QFont, QTreeView, QColor from PyQt4.QtGui import (QBrush, QStyledItemDelegate, QFont, QTreeView, QColor, QItemSelectionModel,
QItemSelection)
from qtlib.tree_model import TreeNode, TreeModel from qtlib.tree_model import TreeModel, RefNode
class ResultNode(TreeNode): from core.gui.result_tree import ResultTree as ResultTreeModel
def __init__(self, model, parent, row, dupe, group):
TreeNode.__init__(self, model, parent, row)
self.dupe = dupe
self.group = group
self._normalData = None
self._deltaData = None
def _createNode(self, ref, row):
return ResultNode(self.model, self, row, ref, self.group)
def _getChildren(self):
return self.group.dupes if self.dupe is self.group.ref else []
def invalidate(self):
self._normalData = None
self._deltaData = None
TreeNode.invalidate(self)
@property
def normalData(self):
if self._normalData is None:
self._normalData = self.model._app._get_display_info(self.dupe, self.group, delta=False)
return self._normalData
@property
def deltaData(self):
if self._deltaData is None:
self._deltaData = self.model._app._get_display_info(self.dupe, self.group, delta=True)
return self._deltaData
class ResultsDelegate(QStyledItemDelegate): class ResultsDelegate(QStyledItemDelegate):
def initStyleOption(self, option, index): def initStyleOption(self, option, index):
QStyledItemDelegate.initStyleOption(self, option, index) QStyledItemDelegate.initStyleOption(self, option, index)
node = index.internalPointer() node = index.internalPointer()
if node.group.ref is node.dupe: ref = node.ref
if ref._group.ref is ref._dupe:
newfont = QFont(option.font) newfont = QFont(option.font)
newfont.setBold(True) newfont.setBold(True)
option.font = newfont option.font = newfont
class ResultsModel(TreeModel): class ResultsModel(TreeModel):
def __init__(self, app): def __init__(self, app, view):
TreeModel.__init__(self)
self.view = view
self._app = app self._app = app
self._results = app.results
self._data = app.data self._data = app.data
self._delta_columns = app.DELTA_COLUMNS self._delta_columns = app.DELTA_COLUMNS
self.delta = False self.resultsDelegate = ResultsDelegate()
self._power_marker = False self.model = ResultTreeModel(self, app)
TreeModel.__init__(self) self.view.setItemDelegate(self.resultsDelegate)
self.view.setModel(self)
self.model.connect()
self.connect(self.view.selectionModel(), SIGNAL('selectionChanged(QItemSelection,QItemSelection)'), self.selectionChanged)
def _createNode(self, ref, row): def _createNode(self, ref, row):
if self.power_marker: return RefNode(self, None, ref, row)
# ref is a dupe
group = self._results.get_group_of_duplicate(ref)
return ResultNode(self, None, row, ref, group)
else:
# ref is a group
return ResultNode(self, None, row, ref.ref, ref)
def _getChildren(self): def _getChildren(self):
return self._results.dupes if self.power_marker else self._results.groups return list(self.model)
def _updateSelection(self):
selectedIndexes = []
for path in self.model.selected_paths:
modelIndex = self.findIndex(path)
if modelIndex.isValid():
selectedIndexes.append(modelIndex)
if selectedIndexes:
selection = QItemSelection()
for modelIndex in selectedIndexes:
selection.select(modelIndex, modelIndex)
flags = QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows
self.view.selectionModel().select(selection, flags)
flags = QItemSelectionModel.Rows
self.view.selectionModel().setCurrentIndex(selectedIndexes[0], flags)
else:
self.view.selectionModel().clear()
def columnCount(self, parent): def columnCount(self, parent):
return len(self._data.COLUMNS) return len(self._data.COLUMNS)
@ -82,51 +70,23 @@ class ResultsModel(TreeModel):
if not index.isValid(): if not index.isValid():
return None return None
node = index.internalPointer() node = index.internalPointer()
ref = node.ref
if role == Qt.DisplayRole: if role == Qt.DisplayRole:
data = node.deltaData if self.delta else node.normalData data = ref.data_delta if self.model.delta_values else ref.data
return data[index.column()] return data[index.column()]
elif role == Qt.CheckStateRole: elif role == Qt.CheckStateRole:
if index.column() == 0 and node.dupe is not node.group.ref: if index.column() == 0 and ref.markable:
state = Qt.Checked if self._results.is_marked(node.dupe) else Qt.Unchecked return Qt.Checked if ref.marked else Qt.Unchecked
return state
elif role == Qt.ForegroundRole: elif role == Qt.ForegroundRole:
if node.dupe is node.group.ref or node.dupe.is_ref: if ref._dupe is ref._group.ref or ref._dupe.is_ref:
return QBrush(Qt.blue) return QBrush(Qt.blue)
elif self.delta and index.column() in self._delta_columns: elif self.model.delta_values and index.column() in self._delta_columns:
return QBrush(QColor(255, 142, 40)) # orange return QBrush(QColor(255, 142, 40)) # orange
elif role == Qt.EditRole: elif role == Qt.EditRole:
if index.column() == 0: if index.column() == 0:
return node.normalData[index.column()] return ref.data[index.column()]
return None return None
def dupesForIndexes(self, indexes):
nodes = [index.internalPointer() for index in indexes]
return [node.dupe for node in nodes]
def indexesForDupes(self, dupes):
def index(dupe):
try:
if self.power_marker:
row = self._results.dupes.index(dupe)
node = self.subnodes[row]
assert node.dupe is dupe
return self.createIndex(row, 0, node)
else:
group = self._results.get_group_of_duplicate(dupe)
row = self._results.groups.index(group)
node = self.subnodes[row]
if dupe is group.ref:
assert node.dupe is dupe
return self.createIndex(row, 0, node)
subrow = group.dupes.index(dupe)
subnode = node.subnodes[subrow]
assert subnode.dupe is dupe
return self.createIndex(subrow, 0, subnode)
except ValueError: # the dupe is not there anymore
return QModelIndex()
return map(index, dupes)
def flags(self, index): def flags(self, index):
if not index.isValid(): if not index.isValid():
return Qt.ItemIsEnabled return Qt.ItemIsEnabled
@ -144,48 +104,61 @@ class ResultsModel(TreeModel):
if not index.isValid(): if not index.isValid():
return False return False
node = index.internalPointer() node = index.internalPointer()
ref = node.ref
if role == Qt.CheckStateRole: if role == Qt.CheckStateRole:
if index.column() == 0: if index.column() == 0:
self._app.toggle_marking_for_dupes([node.dupe]) self._app.mark_dupe(ref._dupe, value.toBool())
return True return True
if role == Qt.EditRole: if role == Qt.EditRole:
if index.column() == 0: if index.column() == 0:
value = unicode(value.toString()) value = unicode(value.toString())
if self._app.rename_dupe(node.dupe, value): return self.model.rename_selected(value)
node.invalidate()
return True
return False return False
def sort(self, column, order): def sort(self, column, order):
if self.power_marker: self.model.sort(column, order == Qt.AscendingOrder)
self._results.sort_dupes(column, order == Qt.AscendingOrder, self.delta)
else:
self._results.sort_groups(column, order == Qt.AscendingOrder)
self.reset()
def toggleMarked(self, indexes):
assert indexes
dupes = self.dupesForIndexes(indexes)
self._app.toggle_marking_for_dupes(dupes)
#--- Properties #--- Properties
@property @property
def power_marker(self): def power_marker(self):
return self._power_marker return self.model.power_marker
@power_marker.setter @power_marker.setter
def power_marker(self, value): def power_marker(self, value):
if value == self._power_marker: self.model.power_marker = value
return
self._power_marker = value @property
def delta_values(self):
return self.model.delta_values
@delta_values.setter
def delta_values(self, value):
self.model.delta_values = value
#--- Events
def selectionChanged(self, selected, deselected):
indexes = self.view.selectionModel().selectedRows()
nodes = [index.internalPointer() for index in indexes]
self.model.selected_nodes = [node.ref for node in nodes]
#--- model --> view
def refresh(self):
self.reset() self.reset()
self._updateSelection()
self.view.expandAll()
def invalidate_markings(self):
# redraw view
# HACK. this is the only way I found to update the widget without reseting everything
self.view.scroll(0, 1)
self.view.scroll(0, -1)
class ResultsView(QTreeView): class ResultsView(QTreeView):
#--- Override #--- Override
def keyPressEvent(self, event): def keyPressEvent(self, event):
if event.text() == ' ': if event.text() == ' ':
self.model().toggleMarked(self.selectionModel().selectedRows()) self.emit(SIGNAL('spacePressed()'))
return return
QTreeView.keyPressEvent(self, event) QTreeView.keyPressEvent(self, event)
@ -193,11 +166,3 @@ class ResultsView(QTreeView):
self.emit(SIGNAL('doubleClicked()')) self.emit(SIGNAL('doubleClicked()'))
# We don't call the superclass' method because the default behavior is to rename the cell. # We don't call the superclass' method because the default behavior is to rename the cell.
def setModel(self, model):
assert isinstance(model, ResultsModel)
QTreeView.setModel(self, model)
#--- Public
def selectedDupes(self):
return self.model().dupesForIndexes(self.selectionModel().selectedRows())

20
qt/base/stats_label.py Normal file
View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Created By: Virgil Dupras
# Created On: 2010-02-12
# 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 core.gui.stats_label import StatsLabel as StatsLabelModel
class StatsLabel(object):
def __init__(self, app, view):
self.view = view
self.model = StatsLabelModel(self, app)
self.model.connect()
def refresh(self):
self.view.setText(self.model.display)