mirror of
https://github.com/arsenetar/dupeguru.git
synced 2025-03-10 05:34:36 +00:00
qt base: Adjusted codebase to the latest dev trends.
--HG-- extra : convert_revision : svn%3Ac306627e-7827-47d3-bdf0-9a457c9553a1/trunk%40142
This commit is contained in:
parent
657eca1bb8
commit
a508a86ce4
@ -9,8 +9,6 @@
|
||||
|
||||
import logging
|
||||
import os.path as op
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
from PyQt4.QtCore import Qt, QTimer, QObject, QCoreApplication, QUrl, SIGNAL
|
||||
from PyQt4.QtGui import QProgressDialog, QDesktopServices, QFileDialog, QDialog, QMessageBox
|
||||
@ -22,16 +20,14 @@ from hsutil.reg import RegistrationRequired
|
||||
from dupeguru.app import (DupeGuru as DupeGuruBase, JOB_SCAN, JOB_LOAD, JOB_MOVE, JOB_COPY,
|
||||
JOB_DELETE)
|
||||
|
||||
if sys.platform == 'win32':
|
||||
from .win import recycle_file
|
||||
else:
|
||||
logging.warning("Unsupported Platform!!!")
|
||||
from qtlib.progress import Progress
|
||||
|
||||
from main_window import MainWindow
|
||||
from directories_dialog import DirectoriesDialog
|
||||
from about_box import AboutBox
|
||||
from reg import Registration
|
||||
from error_report_dialog import ErrorReportDialog
|
||||
from . import platform
|
||||
|
||||
from .main_window import MainWindow
|
||||
from .directories_dialog import DirectoriesDialog
|
||||
from .about_box import AboutBox
|
||||
from .reg import Registration
|
||||
|
||||
JOBID2TITLE = {
|
||||
JOB_SCAN: "Scanning for duplicates",
|
||||
@ -41,47 +37,6 @@ JOBID2TITLE = {
|
||||
JOB_DELETE: "Sending files to the recycle bin",
|
||||
}
|
||||
|
||||
class Progress(QProgressDialog, job.ThreadedJobPerformer):
|
||||
def __init__(self, parent):
|
||||
flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint
|
||||
QProgressDialog.__init__(self, '', u"Cancel", 0, 100, parent, flags)
|
||||
self.setModal(True)
|
||||
self.setAutoReset(False)
|
||||
self.setAutoClose(False)
|
||||
self._timer = QTimer()
|
||||
self._jobid = ''
|
||||
self.connect(self._timer, SIGNAL('timeout()'), self.updateProgress)
|
||||
|
||||
def updateProgress(self):
|
||||
# the values might change before setValue happens
|
||||
last_progress = self.last_progress
|
||||
last_desc = self.last_desc
|
||||
if not self._job_running or last_progress is None:
|
||||
self._timer.stop()
|
||||
self.close()
|
||||
self.emit(SIGNAL('finished(QString)'), self._jobid)
|
||||
if self._last_error is not None:
|
||||
s = ''.join(traceback.format_exception(*self._last_error))
|
||||
dialog = ErrorReportDialog(self.parent(), s)
|
||||
dialog.exec_()
|
||||
return
|
||||
if self.wasCanceled():
|
||||
self.job_cancelled = True
|
||||
return
|
||||
if last_desc:
|
||||
self.setLabelText(last_desc)
|
||||
self.setValue(last_progress)
|
||||
|
||||
def run(self, jobid, title, target, args=()):
|
||||
self._jobid = jobid
|
||||
self.reset()
|
||||
self.setLabelText('')
|
||||
self.run_threaded(target, args)
|
||||
self.setWindowTitle(title)
|
||||
self.show()
|
||||
self._timer.start(500)
|
||||
|
||||
|
||||
def demo_method(method):
|
||||
def wrapper(self, *args, **kwargs):
|
||||
try:
|
||||
@ -154,7 +109,7 @@ class DupeGuru(DupeGuruBase, QObject):
|
||||
#--- Override
|
||||
@staticmethod
|
||||
def _recycle_dupe(dupe):
|
||||
recycle_file(dupe.path)
|
||||
platform.recycle_file(dupe.path)
|
||||
|
||||
def _start_job(self, jobid, func):
|
||||
title = JOBID2TITLE[jobid]
|
||||
|
@ -7,10 +7,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 QVariant, QModelIndex, Qt, QRect, QEvent, QPoint
|
||||
from PyQt4.QtCore import QModelIndex, Qt, QRect, QEvent, QPoint
|
||||
from PyQt4.QtGui import QComboBox, QStyledItemDelegate, QMouseEvent, QApplication, QBrush
|
||||
|
||||
from tree_model import TreeNode, TreeModel
|
||||
from qtlib.tree_model import TreeNode, TreeModel
|
||||
|
||||
HEADERS = ['Name', 'State']
|
||||
STATES = ['Normal', 'Reference', 'Excluded']
|
||||
@ -22,8 +22,7 @@ class DirectoriesDelegate(QStyledItemDelegate):
|
||||
return editor
|
||||
|
||||
def setEditorData(self, editor, index):
|
||||
value, ok = index.model().data(index, Qt.EditRole).toInt()
|
||||
assert ok
|
||||
value = index.model().data(index, Qt.EditRole)
|
||||
editor.setCurrentIndex(value);
|
||||
press = QMouseEvent(QEvent.MouseButtonPress, QPoint(0, 0), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier)
|
||||
release = QMouseEvent(QEvent.MouseButtonRelease, QPoint(0, 0), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier)
|
||||
@ -32,7 +31,7 @@ class DirectoriesDelegate(QStyledItemDelegate):
|
||||
# editor.showPopup() # this causes a weird glitch. the ugly workaround is above.
|
||||
|
||||
def setModelData(self, editor, model, index):
|
||||
value = QVariant(editor.currentIndex())
|
||||
value = editor.currentIndex()
|
||||
model.setData(index, value, Qt.EditRole)
|
||||
|
||||
def updateEditorGeometry(self, editor, option, index):
|
||||
@ -40,16 +39,15 @@ class DirectoriesDelegate(QStyledItemDelegate):
|
||||
|
||||
|
||||
class DirectoryNode(TreeNode):
|
||||
def __init__(self, parent, ref, row):
|
||||
TreeNode.__init__(self, parent, row)
|
||||
def __init__(self, model, parent, ref, row):
|
||||
TreeNode.__init__(self, model, parent, row)
|
||||
self.ref = ref
|
||||
|
||||
def _get_children(self):
|
||||
children = []
|
||||
for index, directory in enumerate(self.ref.dirs):
|
||||
node = DirectoryNode(self, directory, index)
|
||||
children.append(node)
|
||||
return children
|
||||
def _createNode(self, ref, row):
|
||||
return DirectoryNode(self.model, self, ref, row)
|
||||
|
||||
def _getChildren(self):
|
||||
return self.ref.dirs
|
||||
|
||||
|
||||
class DirectoriesModel(TreeModel):
|
||||
@ -57,33 +55,33 @@ class DirectoriesModel(TreeModel):
|
||||
self._dirs = app.directories
|
||||
TreeModel.__init__(self)
|
||||
|
||||
def _root_nodes(self):
|
||||
nodes = []
|
||||
for index, directory in enumerate(self._dirs):
|
||||
nodes.append(DirectoryNode(None, directory, index))
|
||||
return nodes
|
||||
def _createNode(self, ref, row):
|
||||
return DirectoryNode(self, None, ref, row)
|
||||
|
||||
def _getChildren(self):
|
||||
return self._dirs
|
||||
|
||||
def columnCount(self, parent):
|
||||
return 2
|
||||
|
||||
def data(self, index, role):
|
||||
if not index.isValid():
|
||||
return QVariant()
|
||||
return None
|
||||
node = index.internalPointer()
|
||||
if role == Qt.DisplayRole:
|
||||
if index.column() == 0:
|
||||
return QVariant(node.ref.name)
|
||||
return node.ref.name
|
||||
else:
|
||||
return QVariant(STATES[self._dirs.get_state(node.ref.path)])
|
||||
return STATES[self._dirs.get_state(node.ref.path)]
|
||||
elif role == Qt.EditRole and index.column() == 1:
|
||||
return QVariant(self._dirs.get_state(node.ref.path))
|
||||
return self._dirs.get_state(node.ref.path)
|
||||
elif role == Qt.ForegroundRole:
|
||||
state = self._dirs.get_state(node.ref.path)
|
||||
if state == 1:
|
||||
return QVariant(QBrush(Qt.blue))
|
||||
return QBrush(Qt.blue)
|
||||
elif state == 2:
|
||||
return QVariant(QBrush(Qt.red))
|
||||
return QVariant()
|
||||
return QBrush(Qt.red)
|
||||
return None
|
||||
|
||||
def flags(self, index):
|
||||
if not index.isValid():
|
||||
@ -96,15 +94,13 @@ class DirectoriesModel(TreeModel):
|
||||
def headerData(self, section, orientation, role):
|
||||
if orientation == Qt.Horizontal:
|
||||
if role == Qt.DisplayRole and section < len(HEADERS):
|
||||
return QVariant(HEADERS[section])
|
||||
return QVariant()
|
||||
return HEADERS[section]
|
||||
return None
|
||||
|
||||
def setData(self, index, value, role):
|
||||
if not index.isValid() or role != Qt.EditRole or index.column() != 1:
|
||||
return False
|
||||
node = index.internalPointer()
|
||||
state, ok = value.toInt()
|
||||
assert ok
|
||||
self._dirs.set_state(node.ref.path, state)
|
||||
self._dirs.set_state(node.ref.path, value)
|
||||
return True
|
||||
|
||||
|
@ -1,27 +0,0 @@
|
||||
# Created By: Virgil Dupras
|
||||
# Created On: 2009-05-23
|
||||
# $Id$
|
||||
# Copyright 2009 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, QUrl
|
||||
from PyQt4.QtGui import QDialog, QDesktopServices
|
||||
|
||||
from error_report_dialog_ui import Ui_ErrorReportDialog
|
||||
|
||||
class ErrorReportDialog(QDialog, Ui_ErrorReportDialog):
|
||||
def __init__(self, parent, error):
|
||||
flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint
|
||||
QDialog.__init__(self, parent, flags)
|
||||
self.setupUi(self)
|
||||
self.errorTextEdit.setPlainText(error)
|
||||
|
||||
def accept(self):
|
||||
text = self.errorTextEdit.toPlainText()
|
||||
url = QUrl("mailto:support@hardcoded.net?SUBJECT=Error Report&BODY=%s" % text)
|
||||
QDesktopServices.openUrl(url)
|
||||
QDialog.accept(self)
|
||||
|
@ -1,117 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ErrorReportDialog</class>
|
||||
<widget class="QDialog" name="ErrorReportDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>553</width>
|
||||
<height>349</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Error Report</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Something went wrong. Would you like to send the error report to Hardcoded Software?</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="errorTextEdit">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="dontSendButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>110</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Don't Send</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="sendButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>110</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Send</string>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>sendButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>ErrorReportDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>485</x>
|
||||
<y>320</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>276</x>
|
||||
<y>174</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>dontSendButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>ErrorReportDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>373</x>
|
||||
<y>320</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>276</x>
|
||||
<y>174</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
17
base/qt/platform.py
Normal file
17
base/qt/platform.py
Normal file
@ -0,0 +1,17 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Created By: Virgil Dupras
|
||||
# Created On: 2009-09-27
|
||||
# $Id$
|
||||
# Copyright 2009 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 logging
|
||||
import sys
|
||||
|
||||
if sys.platform == 'win32':
|
||||
from platform_win import *
|
||||
else:
|
||||
logging.warning("Unsupported Platform!!")
|
@ -7,30 +7,29 @@
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.hardcoded.net/licenses/hs_license
|
||||
|
||||
from PyQt4.QtCore import SIGNAL, Qt, QAbstractItemModel, QVariant, QModelIndex, QRect
|
||||
from PyQt4.QtCore import SIGNAL, Qt, QAbstractItemModel, QModelIndex, QRect
|
||||
from PyQt4.QtGui import QBrush, QStyledItemDelegate, QFont, QTreeView, QColor
|
||||
|
||||
from tree_model import TreeNode, TreeModel
|
||||
from qtlib.tree_model import TreeNode, TreeModel
|
||||
|
||||
class ResultNode(TreeNode):
|
||||
def __init__(self, model, parent, row, dupe, group):
|
||||
TreeNode.__init__(self, parent, row)
|
||||
self.model = model
|
||||
TreeNode.__init__(self, model, parent, row)
|
||||
self.dupe = dupe
|
||||
self.group = group
|
||||
self._normalData = None
|
||||
self._deltaData = None
|
||||
|
||||
def _get_children(self):
|
||||
children = []
|
||||
if self.dupe is self.group.ref:
|
||||
for index, dupe in enumerate(self.group.dupes):
|
||||
children.append(ResultNode(self.model, self, index, dupe, self.group))
|
||||
return children
|
||||
def _createNode(self, ref, row):
|
||||
return ResultNode(self.model, self, row, ref, self.group)
|
||||
|
||||
def reset(self):
|
||||
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):
|
||||
@ -65,40 +64,41 @@ class ResultsModel(TreeModel):
|
||||
self._power_marker = False
|
||||
TreeModel.__init__(self)
|
||||
|
||||
def _root_nodes(self):
|
||||
nodes = []
|
||||
def _createNode(self, ref, row):
|
||||
if self.power_marker:
|
||||
for index, dupe in enumerate(self._results.dupes):
|
||||
group = self._results.get_group_of_duplicate(dupe)
|
||||
nodes.append(ResultNode(self, None, index, dupe, group))
|
||||
# ref is a dupe
|
||||
group = self._results.get_group_of_duplicate(ref)
|
||||
return ResultNode(self, None, row, ref, group)
|
||||
else:
|
||||
for index, group in enumerate(self._results.groups):
|
||||
nodes.append(ResultNode(self, None, index, group.ref, group))
|
||||
return nodes
|
||||
# ref is a group
|
||||
return ResultNode(self, None, row, ref.ref, ref)
|
||||
|
||||
def _getChildren(self):
|
||||
return self._results.dupes if self.power_marker else self._results.groups
|
||||
|
||||
def columnCount(self, parent):
|
||||
return len(self._data.COLUMNS)
|
||||
|
||||
def data(self, index, role):
|
||||
if not index.isValid():
|
||||
return QVariant()
|
||||
return None
|
||||
node = index.internalPointer()
|
||||
if role == Qt.DisplayRole:
|
||||
data = node.deltaData if self.delta else node.normalData
|
||||
return QVariant(data[index.column()])
|
||||
return data[index.column()]
|
||||
elif role == Qt.CheckStateRole:
|
||||
if index.column() == 0 and node.dupe is not node.group.ref:
|
||||
state = Qt.Checked if self._results.is_marked(node.dupe) else Qt.Unchecked
|
||||
return QVariant(state)
|
||||
return state
|
||||
elif role == Qt.ForegroundRole:
|
||||
if node.dupe is node.group.ref or node.dupe.is_ref:
|
||||
return QVariant(QBrush(Qt.blue))
|
||||
return QBrush(Qt.blue)
|
||||
elif self.delta and index.column() in self._delta_columns:
|
||||
return QVariant(QBrush(QColor(255, 142, 40))) # orange
|
||||
return QBrush(QColor(255, 142, 40)) # orange
|
||||
elif role == Qt.EditRole:
|
||||
if index.column() == 0:
|
||||
return QVariant(node.normalData[index.column()])
|
||||
return QVariant()
|
||||
return node.normalData[index.column()]
|
||||
return None
|
||||
|
||||
def dupesForIndexes(self, indexes):
|
||||
nodes = [index.internalPointer() for index in indexes]
|
||||
@ -138,9 +138,8 @@ class ResultsModel(TreeModel):
|
||||
|
||||
def headerData(self, section, orientation, role):
|
||||
if orientation == Qt.Horizontal and role == Qt.DisplayRole and section < len(self._data.COLUMNS):
|
||||
return QVariant(self._data.COLUMNS[section]['display'])
|
||||
|
||||
return QVariant()
|
||||
return self._data.COLUMNS[section]['display']
|
||||
return None
|
||||
|
||||
def setData(self, index, value, role):
|
||||
if not index.isValid():
|
||||
|
@ -1,68 +0,0 @@
|
||||
# Created By: Virgil Dupras
|
||||
# Created On: 2009-05-04
|
||||
# $Id$
|
||||
# Copyright 2009 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, QAbstractItemModel, QVariant, QModelIndex
|
||||
|
||||
class TreeNode(object):
|
||||
def __init__(self, parent, row):
|
||||
self.parent = parent
|
||||
self.row = row
|
||||
self._children = None
|
||||
|
||||
def _get_children(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
def children(self):
|
||||
if self._children is None:
|
||||
self._children = self._get_children()
|
||||
return self._children
|
||||
|
||||
|
||||
class TreeModel(QAbstractItemModel):
|
||||
def __init__(self):
|
||||
QAbstractItemModel.__init__(self)
|
||||
self._nodes = None
|
||||
|
||||
def _root_nodes(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def index(self, row, column, parent):
|
||||
if not self.nodes:
|
||||
return QModelIndex()
|
||||
if not parent.isValid():
|
||||
return self.createIndex(row, column, self.nodes[row])
|
||||
node = parent.internalPointer()
|
||||
return self.createIndex(row, column, node.children[row])
|
||||
|
||||
def parent(self, index):
|
||||
if not index.isValid():
|
||||
return QModelIndex()
|
||||
node = index.internalPointer()
|
||||
if node.parent is None:
|
||||
return QModelIndex()
|
||||
else:
|
||||
return self.createIndex(node.parent.row, 0, node.parent)
|
||||
|
||||
def reset(self):
|
||||
self._nodes = None
|
||||
QAbstractItemModel.reset(self)
|
||||
|
||||
def rowCount(self, parent):
|
||||
if not parent.isValid():
|
||||
return len(self.nodes)
|
||||
node = parent.internalPointer()
|
||||
return len(node.children)
|
||||
|
||||
@property
|
||||
def nodes(self):
|
||||
if self._nodes is None:
|
||||
self._nodes = self._root_nodes()
|
||||
return self._nodes
|
||||
|
Loading…
x
Reference in New Issue
Block a user