mirror of
https://github.com/arsenetar/dupeguru.git
synced 2025-03-10 05:34:36 +00:00
[#32] Internationalized the qt layer and localized it to French.
In the process of doing so, I also added a new preferences_dialog base class to reduce code duplication in the three pref dialogs (I didn't want to copy/paste the language combobox addition three times).
This commit is contained in:
parent
7f8a357019
commit
2c127adf59
@ -17,3 +17,5 @@ cocoa/*/Info.plist
|
|||||||
cocoa/*/build
|
cocoa/*/build
|
||||||
cocoa/*/dg_cocoa.plugin
|
cocoa/*/dg_cocoa.plugin
|
||||||
qt/base/*_rc.py
|
qt/base/*_rc.py
|
||||||
|
qt/lang/fr.qm
|
||||||
|
qt/lang/en.qm
|
@ -1 +1,2 @@
|
|||||||
__version__ = '5.10.4'
|
__version__ = '5.10.4'
|
||||||
|
__appname__ = 'dupeGuru Music Edition'
|
@ -1 +1,2 @@
|
|||||||
__version__ = '1.11.3'
|
__version__ = '1.11.3'
|
||||||
|
__appname__ = 'dupeGuru Picture Edition'
|
@ -1 +1,2 @@
|
|||||||
__version__ = '2.12.3'
|
__version__ = '2.12.3'
|
||||||
|
__appname__ = 'dupeGuru'
|
||||||
|
@ -15,6 +15,7 @@ from PyQt4.QtGui import QDesktopServices, QFileDialog, QDialog, QMessageBox, QAp
|
|||||||
|
|
||||||
from jobprogress import job
|
from jobprogress import job
|
||||||
from jobprogress.qt import Progress
|
from jobprogress.qt import Progress
|
||||||
|
from hscommon.trans import tr, trmsg
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
@ -29,11 +30,11 @@ from .problem_dialog import ProblemDialog
|
|||||||
from .util import createActions
|
from .util import createActions
|
||||||
|
|
||||||
JOBID2TITLE = {
|
JOBID2TITLE = {
|
||||||
JOB_SCAN: "Scanning for duplicates",
|
JOB_SCAN: tr("Scanning for duplicates"),
|
||||||
JOB_LOAD: "Loading",
|
JOB_LOAD: tr("Loading"),
|
||||||
JOB_MOVE: "Moving",
|
JOB_MOVE: tr("Moving"),
|
||||||
JOB_COPY: "Copying",
|
JOB_COPY: tr("Copying"),
|
||||||
JOB_DELETE: "Sending files to the recycle bin",
|
JOB_DELETE: tr("Sending files to the recycle bin"),
|
||||||
}
|
}
|
||||||
|
|
||||||
class DupeGuru(DupeGuruBase, QObject):
|
class DupeGuru(DupeGuruBase, QObject):
|
||||||
@ -86,13 +87,13 @@ class DupeGuru(DupeGuruBase, QObject):
|
|||||||
# Setup actions that are common to both the directory dialog and the results window.
|
# Setup actions that are common to both the directory dialog and the results window.
|
||||||
# (name, shortcut, icon, desc, func)
|
# (name, shortcut, icon, desc, func)
|
||||||
ACTIONS = [
|
ACTIONS = [
|
||||||
('actionQuit', 'Ctrl+Q', '', "Quit", self.quitTriggered),
|
('actionQuit', 'Ctrl+Q', '', tr("Quit"), self.quitTriggered),
|
||||||
('actionPreferences', 'Ctrl+P', '', "Preferences", self.preferencesTriggered),
|
('actionPreferences', 'Ctrl+P', '', tr("Preferences"), self.preferencesTriggered),
|
||||||
('actionShowHelp', 'F1', '', "dupeGuru Help", self.showHelpTriggered),
|
('actionShowHelp', 'F1', '', tr("dupeGuru Help"), self.showHelpTriggered),
|
||||||
('actionAbout', '', '', "About dupeGuru", self.showAboutBoxTriggered),
|
('actionAbout', '', '', tr("About dupeGuru"), self.showAboutBoxTriggered),
|
||||||
('actionRegister', '', '', "Register dupeGuru", self.registerTriggered),
|
('actionRegister', '', '', tr("Register dupeGuru"), self.registerTriggered),
|
||||||
('actionCheckForUpdate', '', '', "Check for Update", self.checkForUpdateTriggered),
|
('actionCheckForUpdate', '', '', tr("Check for Update"), self.checkForUpdateTriggered),
|
||||||
('actionOpenDebugLog', '', '', "Open Debug Log", self.openDebugLogTriggered),
|
('actionOpenDebugLog', '', '', tr("Open Debug Log"), self.openDebugLogTriggered),
|
||||||
]
|
]
|
||||||
createActions(ACTIONS, self)
|
createActions(ACTIONS, self)
|
||||||
|
|
||||||
@ -139,21 +140,21 @@ class DupeGuru(DupeGuruBase, QObject):
|
|||||||
args = tuple([j] + list(args))
|
args = tuple([j] + list(args))
|
||||||
self._progress.run(jobid, title, func, args=args)
|
self._progress.run(jobid, title, func, args=args)
|
||||||
except job.JobInProgressError:
|
except job.JobInProgressError:
|
||||||
msg = "A previous action is still hanging in there. You can't start a new one yet. Wait a few seconds, then try again."
|
msg = trmsg("TaskHangingMsg")
|
||||||
QMessageBox.information(self.resultWindow, 'Action in progress', msg)
|
QMessageBox.information(self.resultWindow, 'Action in progress', msg)
|
||||||
|
|
||||||
def add_selected_to_ignore_list(self):
|
def add_selected_to_ignore_list(self):
|
||||||
dupes = self.without_ref(self.selected_dupes)
|
dupes = self.without_ref(self.selected_dupes)
|
||||||
if not dupes:
|
if not dupes:
|
||||||
return
|
return
|
||||||
title = "Add to Ignore List"
|
title = tr("Add to Ignore List")
|
||||||
msg = "All selected {0} matches are going to be ignored in all subsequent scans. Continue?".format(len(dupes))
|
msg = trmsg("IgnoreConfirmMsg").format(len(dupes))
|
||||||
if self.confirm(title, msg):
|
if self.confirm(title, msg):
|
||||||
DupeGuruBase.add_selected_to_ignore_list(self)
|
DupeGuruBase.add_selected_to_ignore_list(self)
|
||||||
|
|
||||||
def copy_or_move_marked(self, copy):
|
def copy_or_move_marked(self, copy):
|
||||||
opname = 'copy' if copy else 'move'
|
opname = tr("copy") if copy else tr("move")
|
||||||
title = "Select a directory to {0} marked files to".format(opname)
|
title = trmsg("SelectCopyOrMoveDestinationMsg").format(opname)
|
||||||
flags = QFileDialog.ShowDirsOnly
|
flags = QFileDialog.ShowDirsOnly
|
||||||
destination = str(QFileDialog.getExistingDirectory(self.resultWindow, title, '', flags))
|
destination = str(QFileDialog.getExistingDirectory(self.resultWindow, title, '', flags))
|
||||||
if not destination:
|
if not destination:
|
||||||
@ -165,8 +166,8 @@ class DupeGuru(DupeGuruBase, QObject):
|
|||||||
dupes = self.without_ref(self.selected_dupes)
|
dupes = self.without_ref(self.selected_dupes)
|
||||||
if not dupes:
|
if not dupes:
|
||||||
return
|
return
|
||||||
title = "Remove duplicates"
|
title = tr("Remove duplicates")
|
||||||
msg = "You are about to remove {0} files from results. Continue?".format(len(dupes))
|
msg = trmsg("FileRemovalConfirmMsg").format(len(dupes))
|
||||||
if self.confirm(title, msg):
|
if self.confirm(title, msg):
|
||||||
DupeGuruBase.remove_selected(self)
|
DupeGuruBase.remove_selected(self)
|
||||||
|
|
||||||
@ -185,8 +186,8 @@ class DupeGuru(DupeGuruBase, QObject):
|
|||||||
if cmd:
|
if cmd:
|
||||||
self.invoke_command(cmd)
|
self.invoke_command(cmd)
|
||||||
else:
|
else:
|
||||||
msg = "You have no custom command set up. Please, set it up in your preferences."
|
msg = trmsg("NoCustomCommandMsg")
|
||||||
QMessageBox.warning(self.resultWindow, 'Custom Command', msg)
|
QMessageBox.warning(self.resultWindow, tr("Custom Command"), msg)
|
||||||
|
|
||||||
def show_details(self):
|
def show_details(self):
|
||||||
self.details_dialog.show()
|
self.details_dialog.show()
|
||||||
@ -212,12 +213,12 @@ class DupeGuru(DupeGuruBase, QObject):
|
|||||||
if self.results.problems:
|
if self.results.problems:
|
||||||
self.problemDialog.show()
|
self.problemDialog.show()
|
||||||
else:
|
else:
|
||||||
msg = "All files were processed successfully."
|
msg = trmsg("OperationSuccessMsg")
|
||||||
QMessageBox.information(self.resultWindow, 'Operation Complete', msg)
|
QMessageBox.information(self.resultWindow, tr("Operation Complete"), msg)
|
||||||
elif jobid == JOB_SCAN:
|
elif jobid == JOB_SCAN:
|
||||||
if not self.results.groups:
|
if not self.results.groups:
|
||||||
title = "Scan complete"
|
title = tr("Scan complete")
|
||||||
msg = "No duplicates found."
|
msg = trmsg("NoDuplicateFoundMsg")
|
||||||
QMessageBox.information(self.resultWindow, title, msg)
|
QMessageBox.information(self.resultWindow, title, msg)
|
||||||
else:
|
else:
|
||||||
self.showResultsWindow()
|
self.showResultsWindow()
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
from PyQt4.QtCore import Qt, SIGNAL, QAbstractTableModel
|
from PyQt4.QtCore import Qt, SIGNAL, QAbstractTableModel
|
||||||
from PyQt4.QtGui import QHeaderView, QTableView
|
from PyQt4.QtGui import QHeaderView, QTableView
|
||||||
|
|
||||||
HEADER = ['Attribute', 'Selected', 'Reference']
|
from hscommon.trans import tr
|
||||||
|
|
||||||
|
HEADER = [tr("Attribute"), tr("Selected"), tr("Reference")]
|
||||||
|
|
||||||
class DetailsModel(QAbstractTableModel):
|
class DetailsModel(QAbstractTableModel):
|
||||||
def __init__(self, model):
|
def __init__(self, model):
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<!DOCTYPE RCC><RCC version="1.0">
|
<!DOCTYPE RCC><RCC version="1.0">
|
||||||
<qresource>
|
<qresource>
|
||||||
|
<file alias="en.qm">../lang/en.qm</file>
|
||||||
<file alias="fr.qm">../lang/fr.qm</file>
|
<file alias="fr.qm">../lang/fr.qm</file>
|
||||||
<file alias="qt_fr.qm">../lang/qt_fr.qm</file>
|
<file alias="qt_fr.qm">../lang/qt_fr.qm</file>
|
||||||
<file alias="logo_pe">../../images/dgpe_logo_32.png</file>
|
<file alias="logo_pe">../../images/dgpe_logo_32.png</file>
|
||||||
|
@ -11,6 +11,7 @@ from PyQt4.QtGui import (QWidget, QFileDialog, QHeaderView, QVBoxLayout, QHBoxLa
|
|||||||
QAbstractItemView, QSpacerItem, QSizePolicy, QPushButton, QApplication, QMessageBox, QMainWindow,
|
QAbstractItemView, QSpacerItem, QSizePolicy, QPushButton, QApplication, QMessageBox, QMainWindow,
|
||||||
QMenuBar, QMenu, QIcon, QPixmap)
|
QMenuBar, QMenu, QIcon, QPixmap)
|
||||||
|
|
||||||
|
from hscommon.trans import tr, trmsg
|
||||||
from qtlib.recent import Recent
|
from qtlib.recent import Recent
|
||||||
from core.app import NoScannableFileError
|
from core.app import NoScannableFileError
|
||||||
|
|
||||||
@ -49,9 +50,9 @@ class DirectoriesDialog(QMainWindow):
|
|||||||
def _setupActions(self):
|
def _setupActions(self):
|
||||||
# (name, shortcut, icon, desc, func)
|
# (name, shortcut, icon, desc, func)
|
||||||
ACTIONS = [
|
ACTIONS = [
|
||||||
('actionLoadResults', 'Ctrl+L', '', "Load Results...", self.loadResultsTriggered),
|
('actionLoadResults', 'Ctrl+L', '', tr("Load Results..."), self.loadResultsTriggered),
|
||||||
('actionShowResultsWindow', '', '', "Results Window", self.app.showResultsWindow),
|
('actionShowResultsWindow', '', '', tr("Results Window"), self.app.showResultsWindow),
|
||||||
('actionAddFolder', '', '', "Add Folder...", self.addFolderTriggered),
|
('actionAddFolder', '', '', tr("Add Folder..."), self.addFolderTriggered),
|
||||||
]
|
]
|
||||||
createActions(ACTIONS, self)
|
createActions(ACTIONS, self)
|
||||||
|
|
||||||
@ -59,13 +60,13 @@ class DirectoriesDialog(QMainWindow):
|
|||||||
self.menubar = QMenuBar(self)
|
self.menubar = QMenuBar(self)
|
||||||
self.menubar.setGeometry(QRect(0, 0, 42, 22))
|
self.menubar.setGeometry(QRect(0, 0, 42, 22))
|
||||||
self.menuFile = QMenu(self.menubar)
|
self.menuFile = QMenu(self.menubar)
|
||||||
self.menuFile.setTitle("File")
|
self.menuFile.setTitle(tr("File"))
|
||||||
self.menuView = QMenu(self.menubar)
|
self.menuView = QMenu(self.menubar)
|
||||||
self.menuView.setTitle("View")
|
self.menuView.setTitle(tr("View"))
|
||||||
self.menuHelp = QMenu(self.menubar)
|
self.menuHelp = QMenu(self.menubar)
|
||||||
self.menuHelp.setTitle("Help")
|
self.menuHelp.setTitle(tr("Help"))
|
||||||
self.menuLoadRecent = QMenu(self.menuFile)
|
self.menuLoadRecent = QMenu(self.menuFile)
|
||||||
self.menuLoadRecent.setTitle("Load Recent Results")
|
self.menuLoadRecent.setTitle(tr("Load Recent Results"))
|
||||||
self.setMenuBar(self.menubar)
|
self.setMenuBar(self.menubar)
|
||||||
|
|
||||||
self.menuFile.addAction(self.actionLoadResults)
|
self.menuFile.addAction(self.actionLoadResults)
|
||||||
@ -126,10 +127,10 @@ class DirectoriesDialog(QMainWindow):
|
|||||||
spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
||||||
self.horizontalLayout.addItem(spacerItem1)
|
self.horizontalLayout.addItem(spacerItem1)
|
||||||
self.loadResultsButton = QPushButton(self.centralwidget)
|
self.loadResultsButton = QPushButton(self.centralwidget)
|
||||||
self.loadResultsButton.setText("Load Results")
|
self.loadResultsButton.setText(tr("Load Results"))
|
||||||
self.horizontalLayout.addWidget(self.loadResultsButton)
|
self.horizontalLayout.addWidget(self.loadResultsButton)
|
||||||
self.scanButton = QPushButton(self.centralwidget)
|
self.scanButton = QPushButton(self.centralwidget)
|
||||||
self.scanButton.setText("Scan")
|
self.scanButton.setText(tr("Scan"))
|
||||||
self.scanButton.setDefault(True)
|
self.scanButton.setDefault(True)
|
||||||
self.horizontalLayout.addWidget(self.scanButton)
|
self.horizontalLayout.addWidget(self.scanButton)
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||||
@ -167,8 +168,8 @@ class DirectoriesDialog(QMainWindow):
|
|||||||
def closeEvent(self, event):
|
def closeEvent(self, event):
|
||||||
event.accept()
|
event.accept()
|
||||||
if self.app.results.is_modified:
|
if self.app.results.is_modified:
|
||||||
title = "Unsaved results"
|
title = tr("Unsaved results")
|
||||||
msg = "You have unsaved results, do you really want to quit?"
|
msg = trmsg("ReallyWantToQuitMsg")
|
||||||
if not self.app.confirm(title, msg):
|
if not self.app.confirm(title, msg):
|
||||||
event.ignore()
|
event.ignore()
|
||||||
if event.isAccepted():
|
if event.isAccepted():
|
||||||
@ -176,7 +177,7 @@ class DirectoriesDialog(QMainWindow):
|
|||||||
|
|
||||||
#--- Events
|
#--- Events
|
||||||
def addFolderTriggered(self):
|
def addFolderTriggered(self):
|
||||||
title = "Select a directory to add to the scanning list"
|
title = trmsg("SelectFolderToAddMsg")
|
||||||
flags = QFileDialog.ShowDirsOnly
|
flags = QFileDialog.ShowDirsOnly
|
||||||
dirpath = str(QFileDialog.getExistingDirectory(self, title, self.lastAddedFolder, flags))
|
dirpath = str(QFileDialog.getExistingDirectory(self, title, self.lastAddedFolder, flags))
|
||||||
if not dirpath:
|
if not dirpath:
|
||||||
@ -189,8 +190,8 @@ class DirectoriesDialog(QMainWindow):
|
|||||||
self.app.prefs.directoriesWindowRect = self.geometry()
|
self.app.prefs.directoriesWindowRect = self.geometry()
|
||||||
|
|
||||||
def loadResultsTriggered(self):
|
def loadResultsTriggered(self):
|
||||||
title = "Select a results file to load"
|
title = trmsg("SelectResultToLoadMsg")
|
||||||
files = "dupeGuru Results (*.dupeguru)"
|
files = tr("dupeGuru Results (*.dupeguru)")
|
||||||
destination = QFileDialog.getOpenFileName(self, title, '', files)
|
destination = QFileDialog.getOpenFileName(self, title, '', files)
|
||||||
if destination:
|
if destination:
|
||||||
self.app.load_from(destination)
|
self.app.load_from(destination)
|
||||||
@ -207,15 +208,16 @@ class DirectoriesDialog(QMainWindow):
|
|||||||
self.app.remove_directory(row)
|
self.app.remove_directory(row)
|
||||||
|
|
||||||
def scanButtonClicked(self):
|
def scanButtonClicked(self):
|
||||||
title = "Start a new scan"
|
title = tr("Start a new scan")
|
||||||
|
# XXX must be triggered on unsaved results
|
||||||
if len(self.app.results.groups) > 0:
|
if len(self.app.results.groups) > 0:
|
||||||
msg = "Are you sure you want to start a new duplicate scan?"
|
msg = trmsg("ReallyWantToContinueMsg")
|
||||||
if not self.app.confirm(title, msg):
|
if not self.app.confirm(title, msg):
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
self.app.start_scanning()
|
self.app.start_scanning()
|
||||||
except NoScannableFileError:
|
except NoScannableFileError:
|
||||||
msg = "The selected directories contain no scannable file."
|
msg = trmsg("NoScannableFileMsg")
|
||||||
QMessageBox.warning(self, title, msg)
|
QMessageBox.warning(self, title, msg)
|
||||||
|
|
||||||
def selectionChanged(self, selected, deselected):
|
def selectionChanged(self, selected, deselected):
|
||||||
|
@ -12,12 +12,13 @@ from PyQt4.QtCore import QModelIndex, Qt, QRect, QEvent, QPoint, QUrl
|
|||||||
from PyQt4.QtGui import (QComboBox, QStyledItemDelegate, QMouseEvent, QApplication, QBrush, QStyle,
|
from PyQt4.QtGui import (QComboBox, QStyledItemDelegate, QMouseEvent, QApplication, QBrush, QStyle,
|
||||||
QStyleOptionComboBox, QStyleOptionViewItemV4)
|
QStyleOptionComboBox, QStyleOptionViewItemV4)
|
||||||
|
|
||||||
|
from hscommon.trans import tr
|
||||||
from qtlib.tree_model import RefNode, TreeModel
|
from qtlib.tree_model import RefNode, TreeModel
|
||||||
|
|
||||||
from core.gui.directory_tree import DirectoryTree
|
from core.gui.directory_tree import DirectoryTree
|
||||||
|
|
||||||
HEADERS = ['Name', 'State']
|
HEADERS = [tr("Name"), tr("State")]
|
||||||
STATES = ['Normal', 'Reference', 'Excluded']
|
STATES = [tr("Normal"), tr("Reference"), tr("Excluded")]
|
||||||
|
|
||||||
class DirectoriesDelegate(QStyledItemDelegate):
|
class DirectoriesDelegate(QStyledItemDelegate):
|
||||||
def createEditor(self, parent, option, index):
|
def createEditor(self, parent, option, index):
|
||||||
|
@ -29,6 +29,8 @@ class Preferences(PreferencesBase):
|
|||||||
self.remove_empty_folders = get('RemoveEmptyFolders', self.remove_empty_folders)
|
self.remove_empty_folders = get('RemoveEmptyFolders', self.remove_empty_folders)
|
||||||
self.destination_type = get('DestinationType', self.destination_type)
|
self.destination_type = get('DestinationType', self.destination_type)
|
||||||
self.custom_command = get('CustomCommand', self.custom_command)
|
self.custom_command = get('CustomCommand', self.custom_command)
|
||||||
|
self.language = get('Language', self.language)
|
||||||
|
|
||||||
widths = get('ColumnsWidth', self.columns_width)
|
widths = get('ColumnsWidth', self.columns_width)
|
||||||
# only set nonzero values
|
# only set nonzero values
|
||||||
for index, width in enumerate(widths[:len(self.columns_width)]):
|
for index, width in enumerate(widths[:len(self.columns_width)]):
|
||||||
@ -59,6 +61,7 @@ class Preferences(PreferencesBase):
|
|||||||
self.remove_empty_folders = False
|
self.remove_empty_folders = False
|
||||||
self.destination_type = 1
|
self.destination_type = 1
|
||||||
self.custom_command = ''
|
self.custom_command = ''
|
||||||
|
self.language = ''
|
||||||
|
|
||||||
self.resultWindowIsMaximized = False
|
self.resultWindowIsMaximized = False
|
||||||
self.resultWindowRect = None
|
self.resultWindowRect = None
|
||||||
@ -90,6 +93,7 @@ class Preferences(PreferencesBase):
|
|||||||
set_('CustomCommand', self.custom_command)
|
set_('CustomCommand', self.custom_command)
|
||||||
set_('ColumnsWidth', self.columns_width)
|
set_('ColumnsWidth', self.columns_width)
|
||||||
set_('ColumnsVisible', self.columns_visible)
|
set_('ColumnsVisible', self.columns_visible)
|
||||||
|
set_('Language', self.language)
|
||||||
|
|
||||||
set_('ResultWindowIsMaximized', self.resultWindowIsMaximized)
|
set_('ResultWindowIsMaximized', self.resultWindowIsMaximized)
|
||||||
self.set_rect('ResultWindowRect', self.resultWindowRect)
|
self.set_rect('ResultWindowRect', self.resultWindowRect)
|
||||||
|
164
qt/base/preferences_dialog.py
Normal file
164
qt/base/preferences_dialog.py
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
# Created By: Virgil Dupras
|
||||||
|
# Created On: 2011-01-21
|
||||||
|
# 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
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from PyQt4.QtCore import SIGNAL, Qt, QSize
|
||||||
|
from PyQt4.QtGui import (QDialog, QDialogButtonBox, QVBoxLayout, QHBoxLayout, QLabel, QComboBox,
|
||||||
|
QSlider, QSizePolicy, QSpacerItem, QCheckBox, QLineEdit, QMessageBox)
|
||||||
|
|
||||||
|
from hscommon.trans import tr, trmsg
|
||||||
|
|
||||||
|
class PreferencesDialogBase(QDialog):
|
||||||
|
def __init__(self, parent, app):
|
||||||
|
flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint
|
||||||
|
QDialog.__init__(self, parent, flags)
|
||||||
|
self.app = app
|
||||||
|
self._setupUi()
|
||||||
|
|
||||||
|
self.connect(self.filterHardnessSlider, SIGNAL("valueChanged(int)"), self.filterHardnessLabel.setNum)
|
||||||
|
self.connect(self.buttonBox, SIGNAL('clicked(QAbstractButton*)'), self.buttonClicked)
|
||||||
|
self.buttonBox.accepted.connect(self.accept)
|
||||||
|
self.buttonBox.rejected.connect(self.reject)
|
||||||
|
|
||||||
|
def _setupFilterHardnessBox(self):
|
||||||
|
self.filterHardnessHLayout = QHBoxLayout()
|
||||||
|
self.filterHardnessLabel = QLabel(self)
|
||||||
|
self.filterHardnessLabel.setText(tr("Filter Hardness:"))
|
||||||
|
self.filterHardnessLabel.setMinimumSize(QSize(0, 0))
|
||||||
|
self.filterHardnessHLayout.addWidget(self.filterHardnessLabel)
|
||||||
|
self.filterHardnessVLayout = QVBoxLayout()
|
||||||
|
self.filterHardnessVLayout.setSpacing(0)
|
||||||
|
self.filterHardnessHLayoutSub1 = QHBoxLayout()
|
||||||
|
self.filterHardnessHLayoutSub1.setSpacing(12)
|
||||||
|
self.filterHardnessSlider = QSlider(self)
|
||||||
|
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
sizePolicy.setHeightForWidth(self.filterHardnessSlider.sizePolicy().hasHeightForWidth())
|
||||||
|
self.filterHardnessSlider.setSizePolicy(sizePolicy)
|
||||||
|
self.filterHardnessSlider.setMinimum(1)
|
||||||
|
self.filterHardnessSlider.setMaximum(100)
|
||||||
|
self.filterHardnessSlider.setTracking(True)
|
||||||
|
self.filterHardnessSlider.setOrientation(Qt.Horizontal)
|
||||||
|
self.filterHardnessHLayoutSub1.addWidget(self.filterHardnessSlider)
|
||||||
|
self.filterHardnessLabel = QLabel(self)
|
||||||
|
self.filterHardnessLabel.setText("100")
|
||||||
|
self.filterHardnessLabel.setMinimumSize(QSize(21, 0))
|
||||||
|
self.filterHardnessHLayoutSub1.addWidget(self.filterHardnessLabel)
|
||||||
|
self.filterHardnessVLayout.addLayout(self.filterHardnessHLayoutSub1)
|
||||||
|
self.filterHardnessHLayoutSub2 = QHBoxLayout()
|
||||||
|
self.filterHardnessHLayoutSub2.setContentsMargins(-1, 0, -1, -1)
|
||||||
|
self.moreResultsLabel = QLabel(self)
|
||||||
|
self.moreResultsLabel.setText(tr("More Results"))
|
||||||
|
self.filterHardnessHLayoutSub2.addWidget(self.moreResultsLabel)
|
||||||
|
spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
||||||
|
self.filterHardnessHLayoutSub2.addItem(spacerItem)
|
||||||
|
self.fewerResultsLabel = QLabel(self)
|
||||||
|
self.fewerResultsLabel.setText(tr("Fewer Results"))
|
||||||
|
self.filterHardnessHLayoutSub2.addWidget(self.fewerResultsLabel)
|
||||||
|
self.filterHardnessVLayout.addLayout(self.filterHardnessHLayoutSub2)
|
||||||
|
self.filterHardnessHLayout.addLayout(self.filterHardnessVLayout)
|
||||||
|
|
||||||
|
def _setupBottomPart(self):
|
||||||
|
# The bottom part of the pref panel is always the same in all editions.
|
||||||
|
self.languageLabel = QLabel(tr("Language:"), self)
|
||||||
|
self.widgetsVLayout.addWidget(self.languageLabel)
|
||||||
|
self.languageComboBox = QComboBox(self)
|
||||||
|
self.languageComboBox.addItem(tr("English"))
|
||||||
|
self.languageComboBox.addItem(tr("French"))
|
||||||
|
self.widgetsVLayout.addWidget(self.languageComboBox)
|
||||||
|
self.copyMoveLabel = QLabel(self)
|
||||||
|
self.copyMoveLabel.setText(tr("Copy and Move:"))
|
||||||
|
self.widgetsVLayout.addWidget(self.copyMoveLabel)
|
||||||
|
self.copyMoveDestinationComboBox = QComboBox(self)
|
||||||
|
self.copyMoveDestinationComboBox.addItem(tr("Right in destination"))
|
||||||
|
self.copyMoveDestinationComboBox.addItem(tr("Recreate relative path"))
|
||||||
|
self.copyMoveDestinationComboBox.addItem(tr("Recreate absolute path"))
|
||||||
|
self.widgetsVLayout.addWidget(self.copyMoveDestinationComboBox)
|
||||||
|
self.customCommandLabel = QLabel(self)
|
||||||
|
self.customCommandLabel.setText(tr("Custom Command (arguments: %d for dupe, %r for ref):"))
|
||||||
|
self.widgetsVLayout.addWidget(self.customCommandLabel)
|
||||||
|
self.customCommandEdit = QLineEdit(self)
|
||||||
|
self.widgetsVLayout.addWidget(self.customCommandEdit)
|
||||||
|
|
||||||
|
def _setupAddCheckbox(self, name, label, parent=None):
|
||||||
|
if parent is None:
|
||||||
|
parent = self
|
||||||
|
cb = QCheckBox(parent)
|
||||||
|
cb.setText(label)
|
||||||
|
setattr(self, name, cb)
|
||||||
|
|
||||||
|
def _setupPreferenceWidgets(self):
|
||||||
|
# Edition-specific
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _setupUi(self):
|
||||||
|
self.setWindowTitle(tr("Preferences"))
|
||||||
|
self.resize(304, 263)
|
||||||
|
self.setSizeGripEnabled(False)
|
||||||
|
self.setModal(True)
|
||||||
|
self.mainVLayout = QVBoxLayout(self)
|
||||||
|
self.widgetsVLayout = QVBoxLayout()
|
||||||
|
self._setupPreferenceWidgets()
|
||||||
|
self.mainVLayout.addLayout(self.widgetsVLayout)
|
||||||
|
self.buttonBox = QDialogButtonBox(self)
|
||||||
|
self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok|QDialogButtonBox.RestoreDefaults)
|
||||||
|
self.mainVLayout.addWidget(self.buttonBox)
|
||||||
|
if sys.platform not in {'darwin', 'linux2'}:
|
||||||
|
self.verticalLayout.removeWidget(self.ignoreHardlinkMatches)
|
||||||
|
self.ignoreHardlinkMatches.setHidden(True)
|
||||||
|
|
||||||
|
def _load(self, prefs, setchecked):
|
||||||
|
# Edition-specific
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _save(self, prefs, ischecked):
|
||||||
|
# Edition-specific
|
||||||
|
pass
|
||||||
|
|
||||||
|
def load(self, prefs=None):
|
||||||
|
if prefs is None:
|
||||||
|
prefs = self.app.prefs
|
||||||
|
self.filterHardnessSlider.setValue(prefs.filter_hardness)
|
||||||
|
self.filterHardnessLabel.setNum(prefs.filter_hardness)
|
||||||
|
setchecked = lambda cb, b: cb.setCheckState(Qt.Checked if b else Qt.Unchecked)
|
||||||
|
setchecked(self.mixFileKindBox, prefs.mix_file_kind)
|
||||||
|
setchecked(self.useRegexpBox, prefs.use_regexp)
|
||||||
|
setchecked(self.removeEmptyFoldersBox, prefs.remove_empty_folders)
|
||||||
|
setchecked(self.ignoreHardlinkMatches, prefs.ignore_hardlink_matches)
|
||||||
|
self.copyMoveDestinationComboBox.setCurrentIndex(prefs.destination_type)
|
||||||
|
self.customCommandEdit.setText(prefs.custom_command)
|
||||||
|
langindex = {'fr': 1}.get(self.app.prefs.language, 0)
|
||||||
|
self.languageComboBox.setCurrentIndex(langindex)
|
||||||
|
self._load(prefs, setchecked)
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
prefs = self.app.prefs
|
||||||
|
prefs.filter_hardness = self.filterHardnessSlider.value()
|
||||||
|
ischecked = lambda cb: cb.checkState() == Qt.Checked
|
||||||
|
prefs.mix_file_kind = ischecked(self.mixFileKindBox)
|
||||||
|
prefs.use_regexp = ischecked(self.useRegexpBox)
|
||||||
|
prefs.remove_empty_folders = ischecked(self.removeEmptyFoldersBox)
|
||||||
|
prefs.ignore_hardlink_matches = ischecked(self.ignoreHardlinkMatches)
|
||||||
|
prefs.destination_type = self.copyMoveDestinationComboBox.currentIndex()
|
||||||
|
prefs.custom_command = str(self.customCommandEdit.text())
|
||||||
|
langs = ['en', 'fr']
|
||||||
|
lang = langs[self.languageComboBox.currentIndex()]
|
||||||
|
oldlang = self.app.prefs.language
|
||||||
|
if oldlang not in langs:
|
||||||
|
oldlang = 'en'
|
||||||
|
if lang != oldlang:
|
||||||
|
QMessageBox.information(self, "", trmsg("NeedsToRestartToApplyLangMsg"))
|
||||||
|
self.app.prefs.language = lang
|
||||||
|
self._save(prefs, ischecked)
|
||||||
|
|
||||||
|
#--- Events
|
||||||
|
def buttonClicked(self, button):
|
||||||
|
role = self.buttonBox.buttonRole(button)
|
||||||
|
if role == QDialogButtonBox.ResetRole:
|
||||||
|
self.resetToDefaults()
|
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2010-04-12
|
# Created On: 2010-04-12
|
||||||
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
@ -11,6 +10,7 @@ from PyQt4.QtCore import Qt
|
|||||||
from PyQt4.QtGui import (QDialog, QVBoxLayout, QHBoxLayout, QPushButton, QSpacerItem, QSizePolicy,
|
from PyQt4.QtGui import (QDialog, QVBoxLayout, QHBoxLayout, QPushButton, QSpacerItem, QSizePolicy,
|
||||||
QLabel, QTableView, QAbstractItemView, QApplication)
|
QLabel, QTableView, QAbstractItemView, QApplication)
|
||||||
|
|
||||||
|
from hscommon.trans import tr, trmsg
|
||||||
from core.gui.problem_dialog import ProblemDialog as ProblemDialogModel
|
from core.gui.problem_dialog import ProblemDialog as ProblemDialogModel
|
||||||
from .problem_table import ProblemTable
|
from .problem_table import ProblemTable
|
||||||
|
|
||||||
@ -29,11 +29,11 @@ class ProblemDialog(QDialog):
|
|||||||
self.closeButton.clicked.connect(self.accept)
|
self.closeButton.clicked.connect(self.accept)
|
||||||
|
|
||||||
def _setupUi(self):
|
def _setupUi(self):
|
||||||
self.setWindowTitle("Problems!")
|
self.setWindowTitle(tr("Problems!"))
|
||||||
self.resize(413, 323)
|
self.resize(413, 323)
|
||||||
self.verticalLayout = QVBoxLayout(self)
|
self.verticalLayout = QVBoxLayout(self)
|
||||||
self.label = QLabel(self)
|
self.label = QLabel(self)
|
||||||
self.label.setText("There were problems processing some (or all) of the files. The cause of these problems are described in the table below. Those files were not removed from your results.")
|
self.label.setText(trmsg("ProblemsDuringProcessingMsg"))
|
||||||
self.label.setWordWrap(True)
|
self.label.setWordWrap(True)
|
||||||
self.verticalLayout.addWidget(self.label)
|
self.verticalLayout.addWidget(self.label)
|
||||||
self.tableView = QTableView(self)
|
self.tableView = QTableView(self)
|
||||||
@ -47,12 +47,12 @@ class ProblemDialog(QDialog):
|
|||||||
self.verticalLayout.addWidget(self.tableView)
|
self.verticalLayout.addWidget(self.tableView)
|
||||||
self.horizontalLayout = QHBoxLayout()
|
self.horizontalLayout = QHBoxLayout()
|
||||||
self.revealButton = QPushButton(self)
|
self.revealButton = QPushButton(self)
|
||||||
self.revealButton.setText("Reveal Selected")
|
self.revealButton.setText(tr("Reveal Selected"))
|
||||||
self.horizontalLayout.addWidget(self.revealButton)
|
self.horizontalLayout.addWidget(self.revealButton)
|
||||||
spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
||||||
self.horizontalLayout.addItem(spacerItem)
|
self.horizontalLayout.addItem(spacerItem)
|
||||||
self.closeButton = QPushButton(self)
|
self.closeButton = QPushButton(self)
|
||||||
self.closeButton.setText("Close")
|
self.closeButton.setText(tr("Close"))
|
||||||
self.closeButton.setDefault(True)
|
self.closeButton.setDefault(True)
|
||||||
self.horizontalLayout.addWidget(self.closeButton)
|
self.horizontalLayout.addWidget(self.closeButton)
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||||
|
@ -7,14 +7,15 @@
|
|||||||
# 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/bsd_license
|
# http://www.hardcoded.net/licenses/bsd_license
|
||||||
|
|
||||||
|
from hscommon.trans import tr
|
||||||
from qtlib.column import Column
|
from qtlib.column import Column
|
||||||
from qtlib.table import Table
|
from qtlib.table import Table
|
||||||
from core.gui.problem_table import ProblemTable as ProblemTableModel
|
from core.gui.problem_table import ProblemTable as ProblemTableModel
|
||||||
|
|
||||||
class ProblemTable(Table):
|
class ProblemTable(Table):
|
||||||
COLUMNS = [
|
COLUMNS = [
|
||||||
Column('path', 'File Path', 150),
|
Column('path', tr("File Path"), 150),
|
||||||
Column('msg', 'Error Message', 150),
|
Column('msg', tr("Error Message"), 150),
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, problem_dialog, view):
|
def __init__(self, problem_dialog, view):
|
||||||
|
@ -9,10 +9,11 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from PyQt4.QtCore import Qt, SIGNAL, QUrl, QRect
|
from PyQt4.QtCore import Qt, SIGNAL, QUrl, QRect
|
||||||
from PyQt4.QtGui import (QMainWindow, QMenu, QPixmap, QIcon, QLabel, QHeaderView, QMessageBox,
|
from PyQt4.QtGui import (QMainWindow, QMenu, QLabel, QHeaderView, QMessageBox, QInputDialog,
|
||||||
QInputDialog, QLineEdit, QDesktopServices, QFileDialog, QMenuBar, QWidget, QVBoxLayout,
|
QLineEdit, QDesktopServices, QFileDialog, QMenuBar, QWidget, QVBoxLayout, QAbstractItemView,
|
||||||
QAbstractItemView, QStatusBar)
|
QStatusBar)
|
||||||
|
|
||||||
|
from hscommon.trans import tr, trmsg
|
||||||
from hscommon.util import nonone
|
from hscommon.util import nonone
|
||||||
|
|
||||||
from .results_model import ResultsModel, ResultsView
|
from .results_model import ResultsModel, ResultsView
|
||||||
@ -38,31 +39,31 @@ class ResultWindow(QMainWindow):
|
|||||||
def _setupActions(self):
|
def _setupActions(self):
|
||||||
# (name, shortcut, icon, desc, func)
|
# (name, shortcut, icon, desc, func)
|
||||||
ACTIONS = [
|
ACTIONS = [
|
||||||
('actionDetails', 'Ctrl+I', '', "Details", self.detailsTriggered),
|
('actionDetails', 'Ctrl+I', '', tr("Details"), self.detailsTriggered),
|
||||||
('actionActions', '', '', "Actions", self.actionsTriggered),
|
('actionActions', '', '', tr("Actions"), self.actionsTriggered),
|
||||||
('actionPowerMarker', 'Ctrl+1', '', "Show Dupes Only", self.powerMarkerTriggered),
|
('actionPowerMarker', 'Ctrl+1', '', tr("Show Dupes Only"), self.powerMarkerTriggered),
|
||||||
('actionDelta', 'Ctrl+2', '', "Show Delta Values", self.deltaTriggered),
|
('actionDelta', 'Ctrl+2', '', tr("Show Delta Values"), self.deltaTriggered),
|
||||||
('actionDeleteMarked', 'Ctrl+D', '', "Send Marked to Recycle Bin", self.deleteTriggered),
|
('actionDeleteMarked', 'Ctrl+D', '', tr("Send Marked to Recycle Bin"), self.deleteTriggered),
|
||||||
('actionHardlinkMarked', 'Ctrl+Shift+D', '', "Delete Marked and Replace with Hardlinks", self.hardlinkTriggered),
|
('actionHardlinkMarked', 'Ctrl+Shift+D', '', tr("Delete Marked and Replace with Hardlinks"), self.hardlinkTriggered),
|
||||||
('actionMoveMarked', 'Ctrl+M', '', "Move Marked to...", self.moveTriggered),
|
('actionMoveMarked', 'Ctrl+M', '', tr("Move Marked to..."), self.moveTriggered),
|
||||||
('actionCopyMarked', 'Ctrl+Shift+M', '', "Copy Marked to...", self.copyTriggered),
|
('actionCopyMarked', 'Ctrl+Shift+M', '', tr("Copy Marked to..."), self.copyTriggered),
|
||||||
('actionRemoveMarked', 'Ctrl+R', '', "Remove Marked from Results", self.removeMarkedTriggered),
|
('actionRemoveMarked', 'Ctrl+R', '', tr("Remove Marked from Results"), self.removeMarkedTriggered),
|
||||||
('actionRemoveSelected', 'Ctrl+Del', '', "Remove Selected from Results", self.removeSelectedTriggered),
|
('actionRemoveSelected', 'Ctrl+Del', '', tr("Remove Selected from Results"), self.removeSelectedTriggered),
|
||||||
('actionIgnoreSelected', 'Ctrl+Shift+Del', '', "Add Selected to Ignore List", self.addToIgnoreListTriggered),
|
('actionIgnoreSelected', 'Ctrl+Shift+Del', '', tr("Add Selected to Ignore List"), self.addToIgnoreListTriggered),
|
||||||
('actionMakeSelectedReference', 'Ctrl+Space', '', "Make Selected Reference", self.makeReferenceTriggered),
|
('actionMakeSelectedReference', 'Ctrl+Space', '', tr("Make Selected Reference"), self.makeReferenceTriggered),
|
||||||
('actionOpenSelected', 'Ctrl+O', '', "Open Selected with Default Application", self.openTriggered),
|
('actionOpenSelected', 'Ctrl+O', '', tr("Open Selected with Default Application"), self.openTriggered),
|
||||||
('actionRevealSelected', 'Ctrl+Shift+O', '', "Open Containing Folder of Selected", self.revealTriggered),
|
('actionRevealSelected', 'Ctrl+Shift+O', '', tr("Open Containing Folder of Selected"), self.revealTriggered),
|
||||||
('actionRenameSelected', 'F2', '', "Rename Selected", self.renameTriggered),
|
('actionRenameSelected', 'F2', '', tr("Rename Selected"), self.renameTriggered),
|
||||||
('actionMarkAll', 'Ctrl+A', '', "Mark All", self.markAllTriggered),
|
('actionMarkAll', 'Ctrl+A', '', tr("Mark All"), self.markAllTriggered),
|
||||||
('actionMarkNone', 'Ctrl+Shift+A', '', "Mark None", self.markNoneTriggered),
|
('actionMarkNone', 'Ctrl+Shift+A', '', tr("Mark None"), self.markNoneTriggered),
|
||||||
('actionInvertMarking', 'Ctrl+Alt+A', '', "Invert Marking", self.markInvertTriggered),
|
('actionInvertMarking', 'Ctrl+Alt+A', '', tr("Invert Marking"), self.markInvertTriggered),
|
||||||
('actionMarkSelected', '', '', "Mark Selected", self.markSelectedTriggered),
|
('actionMarkSelected', '', '', tr("Mark Selected"), self.markSelectedTriggered),
|
||||||
('actionClearIgnoreList', '', '', "Clear Ignore List", self.clearIgnoreListTriggered),
|
('actionClearIgnoreList', '', '', tr("Clear Ignore List"), self.clearIgnoreListTriggered),
|
||||||
('actionApplyFilter', 'Ctrl+F', '', "Apply Filter", self.applyFilterTriggered),
|
('actionApplyFilter', 'Ctrl+F', '', tr("Apply Filter"), self.applyFilterTriggered),
|
||||||
('actionCancelFilter', 'Ctrl+Shift+F', '', "Cancel Filter", self.cancelFilterTriggered),
|
('actionCancelFilter', 'Ctrl+Shift+F', '', tr("Cancel Filter"), self.cancelFilterTriggered),
|
||||||
('actionExport', '', '', "Export To HTML", self.exportTriggered),
|
('actionExport', '', '', tr("Export To HTML"), self.exportTriggered),
|
||||||
('actionSaveResults', 'Ctrl+S', '', "Save Results...", self.saveResultsTriggered),
|
('actionSaveResults', 'Ctrl+S', '', tr("Save Results..."), self.saveResultsTriggered),
|
||||||
('actionInvokeCustomCommand', 'Ctrl+Alt+I', '', "Invoke Custom Command", self.app.invokeCustomCommand),
|
('actionInvokeCustomCommand', 'Ctrl+Alt+I', '', tr("Invoke Custom Command"), self.app.invokeCustomCommand),
|
||||||
]
|
]
|
||||||
createActions(ACTIONS, self)
|
createActions(ACTIONS, self)
|
||||||
self.actionDelta.setCheckable(True)
|
self.actionDelta.setCheckable(True)
|
||||||
@ -72,17 +73,17 @@ class ResultWindow(QMainWindow):
|
|||||||
self.menubar = QMenuBar(self)
|
self.menubar = QMenuBar(self)
|
||||||
self.menubar.setGeometry(QRect(0, 0, 630, 22))
|
self.menubar.setGeometry(QRect(0, 0, 630, 22))
|
||||||
self.menuFile = QMenu(self.menubar)
|
self.menuFile = QMenu(self.menubar)
|
||||||
self.menuFile.setTitle("File")
|
self.menuFile.setTitle(tr("File"))
|
||||||
self.menuMark = QMenu(self.menubar)
|
self.menuMark = QMenu(self.menubar)
|
||||||
self.menuMark.setTitle("Mark")
|
self.menuMark.setTitle(tr("Mark"))
|
||||||
self.menuActions = QMenu(self.menubar)
|
self.menuActions = QMenu(self.menubar)
|
||||||
self.menuActions.setTitle("Actions")
|
self.menuActions.setTitle(tr("Actions"))
|
||||||
self.menuColumns = QMenu(self.menubar)
|
self.menuColumns = QMenu(self.menubar)
|
||||||
self.menuColumns.setTitle("Columns")
|
self.menuColumns.setTitle(tr("Columns"))
|
||||||
self.menuView = QMenu(self.menubar)
|
self.menuView = QMenu(self.menubar)
|
||||||
self.menuView.setTitle("View")
|
self.menuView.setTitle(tr("View"))
|
||||||
self.menuHelp = QMenu(self.menubar)
|
self.menuHelp = QMenu(self.menubar)
|
||||||
self.menuHelp.setTitle("Help")
|
self.menuHelp.setTitle(tr("Help"))
|
||||||
self.setMenuBar(self.menubar)
|
self.setMenuBar(self.menubar)
|
||||||
|
|
||||||
self.menuActions.addAction(self.actionDeleteMarked)
|
self.menuActions.addAction(self.actionDeleteMarked)
|
||||||
@ -138,11 +139,11 @@ class ResultWindow(QMainWindow):
|
|||||||
action.column_index = index
|
action.column_index = index
|
||||||
self._column_actions.append(action)
|
self._column_actions.append(action)
|
||||||
menu.addSeparator()
|
menu.addSeparator()
|
||||||
action = menu.addAction("Reset to Defaults")
|
action = menu.addAction(tr("Reset to Defaults"))
|
||||||
action.column_index = -1
|
action.column_index = -1
|
||||||
|
|
||||||
# Action menu
|
# Action menu
|
||||||
actionMenu = QMenu('Actions', self.menubar)
|
actionMenu = QMenu(tr("Actions"), self.menubar)
|
||||||
actionMenu.addAction(self.actionDeleteMarked)
|
actionMenu.addAction(self.actionDeleteMarked)
|
||||||
actionMenu.addAction(self.actionHardlinkMarked)
|
actionMenu.addAction(self.actionHardlinkMarked)
|
||||||
actionMenu.addAction(self.actionMoveMarked)
|
actionMenu.addAction(self.actionMoveMarked)
|
||||||
@ -160,7 +161,7 @@ class ResultWindow(QMainWindow):
|
|||||||
self.actionActions.setMenu(actionMenu)
|
self.actionActions.setMenu(actionMenu)
|
||||||
|
|
||||||
def _setupUi(self):
|
def _setupUi(self):
|
||||||
self.setWindowTitle("dupeGuru Results")
|
self.setWindowTitle(tr("dupeGuru Results"))
|
||||||
self.resize(630, 514)
|
self.resize(630, 514)
|
||||||
self.centralwidget = QWidget(self)
|
self.centralwidget = QWidget(self)
|
||||||
self.verticalLayout_2 = QVBoxLayout(self.centralwidget)
|
self.verticalLayout_2 = QVBoxLayout(self.centralwidget)
|
||||||
@ -222,8 +223,8 @@ class ResultWindow(QMainWindow):
|
|||||||
self.app.add_selected_to_ignore_list()
|
self.app.add_selected_to_ignore_list()
|
||||||
|
|
||||||
def applyFilterTriggered(self):
|
def applyFilterTriggered(self):
|
||||||
title = "Apply Filter"
|
title = tr("Apply Filter")
|
||||||
msg = "Type the filter you want to apply on your results. See help for details."
|
msg = trmsg("TypeFilterMsg")
|
||||||
text = nonone(self._last_filter, '[*]')
|
text = nonone(self._last_filter, '[*]')
|
||||||
answer, ok = QInputDialog.getText(self, title, msg, QLineEdit.Normal, text)
|
answer, ok = QInputDialog.getText(self, title, msg, QLineEdit.Normal, text)
|
||||||
if not ok:
|
if not ok:
|
||||||
@ -236,15 +237,15 @@ class ResultWindow(QMainWindow):
|
|||||||
self.app.apply_filter('')
|
self.app.apply_filter('')
|
||||||
|
|
||||||
def clearIgnoreListTriggered(self):
|
def clearIgnoreListTriggered(self):
|
||||||
title = "Clear Ignore List"
|
title = tr("Clear Ignore List")
|
||||||
count = len(self.app.scanner.ignore_list)
|
count = len(self.app.scanner.ignore_list)
|
||||||
if not count:
|
if not count:
|
||||||
QMessageBox.information(self, title, "Nothing to clear.")
|
QMessageBox.information(self, title, trmsg("NothingToClearMsg"))
|
||||||
return
|
return
|
||||||
msg = "Do you really want to remove all {0} items from the ignore list?".format(count)
|
msg = trmsg("ClearIgnoreListConfirmMsg").format(count)
|
||||||
if self.app.confirm(title, msg, QMessageBox.No):
|
if self.app.confirm(title, msg, QMessageBox.No):
|
||||||
self.app.scanner.ignore_list.Clear()
|
self.app.scanner.ignore_list.Clear()
|
||||||
QMessageBox.information(self, title, "Ignore list cleared.")
|
QMessageBox.information(self, title, trmsg("IgnoreListClearedMsg"))
|
||||||
|
|
||||||
def copyTriggered(self):
|
def copyTriggered(self):
|
||||||
self.app.copy_or_move_marked(True)
|
self.app.copy_or_move_marked(True)
|
||||||
@ -253,8 +254,8 @@ class ResultWindow(QMainWindow):
|
|||||||
count = self.app.results.mark_count
|
count = self.app.results.mark_count
|
||||||
if not count:
|
if not count:
|
||||||
return
|
return
|
||||||
title = "Delete duplicates"
|
title = tr("Delete duplicates")
|
||||||
msg = "You are about to send {0} files to the recycle bin. Continue?".format(count)
|
msg = trmsg("SendToTrashConfirmMsg").format(count)
|
||||||
if self.app.confirm(title, msg):
|
if self.app.confirm(title, msg):
|
||||||
self.app.delete_marked()
|
self.app.delete_marked()
|
||||||
|
|
||||||
@ -278,8 +279,8 @@ class ResultWindow(QMainWindow):
|
|||||||
count = self.app.results.mark_count
|
count = self.app.results.mark_count
|
||||||
if not count:
|
if not count:
|
||||||
return
|
return
|
||||||
title = "Delete and hardlink duplicates"
|
title = tr("Delete and hardlink duplicates")
|
||||||
msg = "You are about to send {0} files to the trash and hardlink them afterwards. Continue?".format(count)
|
msg = trmsg("HardlinkConfirmMsg").format(count)
|
||||||
if self.app.confirm(title, msg):
|
if self.app.confirm(title, msg):
|
||||||
self.app.delete_marked(replace_with_hardlinks=True)
|
self.app.delete_marked(replace_with_hardlinks=True)
|
||||||
|
|
||||||
@ -314,8 +315,8 @@ class ResultWindow(QMainWindow):
|
|||||||
count = self.app.results.mark_count
|
count = self.app.results.mark_count
|
||||||
if not count:
|
if not count:
|
||||||
return
|
return
|
||||||
title = "Remove duplicates"
|
title = tr("Remove duplicates")
|
||||||
msg = "You are about to remove {0} files from results. Continue?".format(count)
|
msg = trmsg("FileRemovalConfirmMsg").format(count)
|
||||||
if self.app.confirm(title, msg):
|
if self.app.confirm(title, msg):
|
||||||
self.app.remove_marked()
|
self.app.remove_marked()
|
||||||
|
|
||||||
@ -329,8 +330,8 @@ class ResultWindow(QMainWindow):
|
|||||||
self.app.reveal_selected()
|
self.app.reveal_selected()
|
||||||
|
|
||||||
def saveResultsTriggered(self):
|
def saveResultsTriggered(self):
|
||||||
title = "Select a file to save your results to"
|
title = trmsg("SelectResultToSaveMsg")
|
||||||
files = "dupeGuru Results (*.dupeguru)"
|
files = tr("dupeGuru Results (*.dupeguru)")
|
||||||
destination = QFileDialog.getSaveFileName(self, title, '', files)
|
destination = QFileDialog.getSaveFileName(self, title, '', files)
|
||||||
if destination:
|
if destination:
|
||||||
self.app.save_as(destination)
|
self.app.save_as(destination)
|
||||||
|
99
qt/lang/en.ts
Normal file
99
qt/lang/en.ts
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.0" language="en_US">
|
||||||
|
<context>
|
||||||
|
<name>message</name>
|
||||||
|
<message>
|
||||||
|
<source>TaskHangingMsg</source>
|
||||||
|
<translation>A previous action is still hanging in there. You can't start a new one yet. Wait a few seconds, then try again.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>IgnoreConfirmMsg</source>
|
||||||
|
<translation>All selected {} matches are going to be ignored in all subsequent scans. Continue?</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>SelectCopyOrMoveDestinationMsg</source>
|
||||||
|
<translation>Select a directory to {} marked files to</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>FileRemovalConfirmMsg</source>
|
||||||
|
<translation>You are about to remove {} files from results. Continue?</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>NoCustomCommandMsg</source>
|
||||||
|
<translation>You have no custom command set up. Please, set it up in your preferences.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>OperationSuccessMsg</source>
|
||||||
|
<translation>All files were processed successfully.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>NoDuplicateFoundMsg</source>
|
||||||
|
<translation>No duplicates found.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>ReallyWantToQuitMsg</source>
|
||||||
|
<translation>You have unsaved results, do you really want to quit?</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>SelectFolderToAddMsg</source>
|
||||||
|
<translation>Select a folder to add to the scanning list</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>SelectResultToLoadMsg</source>
|
||||||
|
<translation>Select a results file to load</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>ReallyWantToContinueMsg</source>
|
||||||
|
<translation>You have unsaved results, do you really want to continue?</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>NoScannableFileMsg</source>
|
||||||
|
<translation>The selected folders contain no scannable file.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>ProblemsDuringProcessingMsg</source>
|
||||||
|
<translation>There were problems processing some (or all) of the files. The cause of these problems are described in the table below. Those files were not removed from your results.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>TypeFilterMsg</source>
|
||||||
|
<translation>Type the filter you want to apply on your results. See help for details.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>NothingToClearMsg</source>
|
||||||
|
<translation>Nothing to clear.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>ClearIgnoreListConfirmMsg</source>
|
||||||
|
<translation>Do you really want to remove all {} items from the ignore list?</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>IgnoreListClearedMsg</source>
|
||||||
|
<translation>Ignore list cleared.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>SendToTrashConfirmMsg</source>
|
||||||
|
<translation>You are about to send {} files to the recycle bin. Continue?</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>HardlinkConfirmMsg</source>
|
||||||
|
<translation>You are about to send {} files to the trash and hardlink them afterwards. Continue?</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>SelectResultToSaveMsg</source>
|
||||||
|
<translation>Select a file to save your results to</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>NeedsToRestartToApplyLangMsg</source>
|
||||||
|
<translation>dupeGuru has to restart for language changes to take effect.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>ClearPictureCacheConfirmMsg</source>
|
||||||
|
<translation>Do you really want to remove all your cached picture analysis?</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>PictureCacheClearedMsg</source>
|
||||||
|
<translation>Picture cache cleared.</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
BIN
qt/lang/fr.qm
BIN
qt/lang/fr.qm
Binary file not shown.
524
qt/lang/fr.ts
524
qt/lang/fr.ts
@ -4,6 +4,7 @@
|
|||||||
<!-- ******** Core ******** -->
|
<!-- ******** Core ******** -->
|
||||||
<context>
|
<context>
|
||||||
<name>core</name>
|
<name>core</name>
|
||||||
|
<!-- core.* -->
|
||||||
<message>
|
<message>
|
||||||
<source>Collecting files to scan</source>
|
<source>Collecting files to scan</source>
|
||||||
<translation>Collecte des fichiers à scanner</translation>
|
<translation>Collecte des fichiers à scanner</translation>
|
||||||
@ -107,5 +108,528 @@
|
|||||||
<source>Sending dupes to the Trash</source>
|
<source>Sending dupes to the Trash</source>
|
||||||
<translation>Envoi de doublons à la corbeille en cours</translation>
|
<translation>Envoi de doublons à la corbeille en cours</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
||||||
|
<!-- qt.* -->
|
||||||
|
<message>
|
||||||
|
<source>Sending files to the recycle bin</source>
|
||||||
|
<translation>Envoi de fichiers à la corbeille</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Quit</source>
|
||||||
|
<translation>Quitter</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Preferences</source>
|
||||||
|
<translation>Préférences</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>dupeGuru Help</source>
|
||||||
|
<translation>Aide dupeGuru</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>About dupeGuru</source>
|
||||||
|
<translation>À propos de dupeGuru</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Register dupeGuru</source>
|
||||||
|
<translation>Enregistrer dupeGuru</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Check for Update</source>
|
||||||
|
<translation>Vérifier les mises à jour</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Open Debug Log</source>
|
||||||
|
<translation>Ouvrir logs de déboguage</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Add to Ignore List</source>
|
||||||
|
<translation>Ignorer ces doublons à l'avenir</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>copy</source>
|
||||||
|
<translation>copier</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>move</source>
|
||||||
|
<translation>déplacer</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Remove duplicates</source>
|
||||||
|
<translation>Retirer des doublons</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Custom Command</source>
|
||||||
|
<translation>Commande personnalisée</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Operation Complete</source>
|
||||||
|
<translation>Opération complétée</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Scan complete</source>
|
||||||
|
<translation>Scan complété</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Attribute</source>
|
||||||
|
<translation>Attribut</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Selected</source>
|
||||||
|
<translation>Sélectionné</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Reference</source>
|
||||||
|
<translation>Référence</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Load Results...</source>
|
||||||
|
<translation>Charger résultats...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Results Window</source>
|
||||||
|
<translation>Fenêtre de résultats</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Add Folder...</source>
|
||||||
|
<translation>Ajouter dossier...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>File</source>
|
||||||
|
<translation>Fichier</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>View</source>
|
||||||
|
<translation>Voir</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Help</source>
|
||||||
|
<translation>Aide</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Load Recent Results</source>
|
||||||
|
<translation>Charger résultats récents</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Load Results</source>
|
||||||
|
<translation>Charger</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Scan</source>
|
||||||
|
<translation>Scan</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unsaved results</source>
|
||||||
|
<translation>Résultats non sauvegardés</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>dupeGuru Results (*.dupeguru)</source>
|
||||||
|
<translation>Résultats dupeGuru (*.dupeguru)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Start a new scan</source>
|
||||||
|
<translation>Commencer un nouveau scan</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Name</source>
|
||||||
|
<translation>Nom</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>State</source>
|
||||||
|
<translation>Type</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Normal</source>
|
||||||
|
<translation>Normal</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Excluded</source>
|
||||||
|
<translation>Exclus</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Problems!</source>
|
||||||
|
<translation>Problèmes!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Reveal Selected</source>
|
||||||
|
<translation>Révéler Fichier</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Close</source>
|
||||||
|
<translation>Fermer</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>File Path</source>
|
||||||
|
<translation>Chemin du fichier</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Error Message</source>
|
||||||
|
<translation>Message d'erreur</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Details</source>
|
||||||
|
<translation>Détails</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Actions</source>
|
||||||
|
<translation>Actions</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Show Dupes Only</source>
|
||||||
|
<translation>Ne pas montrer les références</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Show Delta Values</source>
|
||||||
|
<translation>Montrer les valeurs en tant que delta</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Send Marked to Recycle Bin</source>
|
||||||
|
<translation>Envoyer marqués à la corbeille</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Delete Marked and Replace with Hardlinks</source>
|
||||||
|
<translation>Remplacer marqués par des hardlinks</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Move Marked to...</source>
|
||||||
|
<translation>Déplacer marqués vers...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Copy Marked to...</source>
|
||||||
|
<translation>Copier marqués vers...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Remove Marked from Results</source>
|
||||||
|
<translation>Retirer marqués des résultats</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Remove Selected from Results</source>
|
||||||
|
<translation>Retirer sélectionnés des résultats</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Add Selected to Ignore List</source>
|
||||||
|
<translation>Ajouter sélectionnés à la liste de fichiers ignorés</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Make Selected Reference</source>
|
||||||
|
<translation>Transformer sélectionnés en références</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Open Selected with Default Application</source>
|
||||||
|
<translation>Ouvrir sélectionné avec l'application par défaut</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Open Containing Folder of Selected</source>
|
||||||
|
<translation>Ouvrir le dossier contenant le fichier sélectionné</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Rename Selected</source>
|
||||||
|
<translation>Renommer sélectionné</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mark All</source>
|
||||||
|
<translation>Tout marquer</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mark None</source>
|
||||||
|
<translation>Tout démarquer</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Invert Marking</source>
|
||||||
|
<translation>Inverser le marquage</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mark Selected</source>
|
||||||
|
<translation>Marquer sélectionnés</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Clear Ignore List</source>
|
||||||
|
<translation>Vider la liste de fichiers ignorés</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Apply Filter</source>
|
||||||
|
<translation>Appliquer filtre</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Cancel Filter</source>
|
||||||
|
<translation>Annuler filtre</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Export To HTML</source>
|
||||||
|
<translation>Exporter vers HTML</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Save Results...</source>
|
||||||
|
<translation>Sauvegarder résultats...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Invoke Custom Command</source>
|
||||||
|
<translation>Invoquer commande personnalisée</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mark</source>
|
||||||
|
<translation>Marquer</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Columns</source>
|
||||||
|
<translation>Colonnes</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Reset to Defaults</source>
|
||||||
|
<translation>Réinitialiser</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>dupeGuru Results</source>
|
||||||
|
<translation>dupeGuru (Résultats)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Delete duplicates</source>
|
||||||
|
<translation>Effacement de doublons</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Delete and hardlink duplicates</source>
|
||||||
|
<translation>Hardlinking de doublons</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Scan Type:</source>
|
||||||
|
<translation>Type de scan:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filename</source>
|
||||||
|
<translation>Nom de fichier</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Contents</source>
|
||||||
|
<translation>Contenu</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filter Hardness:</source>
|
||||||
|
<translation>Seuil du filtre:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>More Results</source>
|
||||||
|
<translation>+ de doublons</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Fewer Results</source>
|
||||||
|
<translation>- de doublons</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Word weighting</source>
|
||||||
|
<translation>Proportionalité des mots</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Match similar words</source>
|
||||||
|
<translation>Comparer les mots similaires</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Can mix file kind</source>
|
||||||
|
<translation>Comparer les fichiers de différents types</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Use regular expressions when filtering</source>
|
||||||
|
<translation>Utiliser les expressions régulières pour les filtres</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Remove empty folders on delete or move</source>
|
||||||
|
<translation>Effacer les dossiers vides après un déplacement</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ignore files smaller than</source>
|
||||||
|
<translation>Ignorer les fichiers plus petits que:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>KB</source>
|
||||||
|
<translation>KB</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ignore duplicates hardlinking to the same file</source>
|
||||||
|
<translation>Ignorer doublons avec hardlink vers le même fichier</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Copy and Move:</source>
|
||||||
|
<translation>Déplacements de fichiers:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Right in destination</source>
|
||||||
|
<translation>Directement à la destination</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Recreate relative path</source>
|
||||||
|
<translation>Re-créer chemins relatifs</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Recreate absolute path</source>
|
||||||
|
<translation>Re-créer chemins absolus</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Custom Command (arguments: %d for dupe, %r for ref):</source>
|
||||||
|
<translation>Commande perso. (arguments: %d pour doublon, %r pour réf):</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filename - Fields</source>
|
||||||
|
<translation>Nom de fichier (Champs)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filename - Fields (No Order)</source>
|
||||||
|
<translation>Nom de fichier (Champs sans ordre)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Tags</source>
|
||||||
|
<translation>Tags</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Audio Contents</source>
|
||||||
|
<translation>Contenu Audio</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Tags to scan:</source>
|
||||||
|
<translation>Tags à scanner:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Track</source>
|
||||||
|
<translation>Track</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Artist</source>
|
||||||
|
<translation>Artiste</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Album</source>
|
||||||
|
<translation>Album</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Title</source>
|
||||||
|
<translation>Titre</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Genre</source>
|
||||||
|
<translation>Genre</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Year</source>
|
||||||
|
<translation>Année</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Match scaled pictures together</source>
|
||||||
|
<translation>Comparer les images de taille différente</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Clear Picture Cache</source>
|
||||||
|
<translation>Vider la cache d'images</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Clear List</source>
|
||||||
|
<translation>Vider la liste</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Language:</source>
|
||||||
|
<translation>Langue:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>English</source>
|
||||||
|
<translation>Anglais</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>French</source>
|
||||||
|
<translation>Français</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<!-- ******** Message ******** -->
|
||||||
|
<context>
|
||||||
|
<name>message</name>
|
||||||
|
<message>
|
||||||
|
<source>TaskHangingMsg</source>
|
||||||
|
<translation>Une action précédente est encore en cours. Attendez quelques secondes avant d'en repartir une nouvelle.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>IgnoreConfirmMsg</source>
|
||||||
|
<translation>%d fichiers seront ignorés des prochains scans. Continuer?</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>SelectCopyOrMoveDestinationMsg</source>
|
||||||
|
<translation>Sélectionnez un dossier vers lequel {} les fichiers marqués.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>FileRemovalConfirmMsg</source>
|
||||||
|
<translation>{} fichiers seront retirés des résultats. Continuer?</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>NoCustomCommandMsg</source>
|
||||||
|
<translation>Vous n'avez pas de commande personnalisée. Ajoutez-la dans vos préférences.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>OperationSuccessMsg</source>
|
||||||
|
<translation>Tous les fichiers ont été traités avec succès.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>NoDuplicateFoundMsg</source>
|
||||||
|
<translation>Aucun doublon trouvé.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>ReallyWantToQuitMsg</source>
|
||||||
|
<translation>Vos résultats ne sont pas sauvegardés. Voulez-vous vraiment quitter?</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>SelectFolderToAddMsg</source>
|
||||||
|
<translation>Sélectionnez un dossier à ajouter à la liste</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>SelectResultToLoadMsg</source>
|
||||||
|
<translation>Sélectionnez un fichier résultats à charger</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>ReallyWantToContinueMsg</source>
|
||||||
|
<translation>Vos résultats ne sont pas sauvegardés. Voulez-vous vraiment continuer?</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>NoScannableFileMsg</source>
|
||||||
|
<translation>Les dossiers sélectionnés ne continnent pas de fichiers valides.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>ProblemsDuringProcessingMsg</source>
|
||||||
|
<translation>Des problèmes ont été rencontrés lors du traitement de certains fichiers. La nature de ces problèmes est décrite dans la liste ci-dessous. Ces fichiers n'ont pas été retirés des résultats.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>TypeFilterMsg</source>
|
||||||
|
<translation>Entrer le filtre que vous voulez appliquer sur vos résultats.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>NothingToClearMsg</source>
|
||||||
|
<translation>Il n'y a rien à vider.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>ClearIgnoreListConfirmMsg</source>
|
||||||
|
<translation>Voulez-vous vider la liste de fichiers ignorés des {} items qu'elle contient?</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>IgnoreListClearedMsg</source>
|
||||||
|
<translation>La liste de doublons ignorés a été vidée.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>SendToTrashConfirmMsg</source>
|
||||||
|
<translation>{} fichiers seront envoyés à la corbeille. Continuer?</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>HardlinkConfirmMsg</source>
|
||||||
|
<translation>{} fichiers seront envoyés à la corbeille (puis 'hardlinkés'). Continuer?</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>SelectResultToSaveMsg</source>
|
||||||
|
<translation>Sélectionnez un fichier résultats dans lequel sauvegarder</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>NeedsToRestartToApplyLangMsg</source>
|
||||||
|
<translation>dupeGuru doit redémarrer pour appliquer le changement de langue.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>ClearPictureCacheConfirmMsg</source>
|
||||||
|
<translation>Voulez-vous vraiment vider la cache de vos analyses précédentes?</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>PictureCacheClearedMsg</source>
|
||||||
|
<translation>La cache des analyses précédentes a été vidée.</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
@ -6,7 +6,7 @@
|
|||||||
# 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/bsd_license
|
# http://www.hardcoded.net/licenses/bsd_license
|
||||||
|
|
||||||
from core_me import data, scanner, fs, __version__
|
from core_me import data, scanner, fs, __appname__
|
||||||
|
|
||||||
from ..base.app import DupeGuru as DupeGuruBase
|
from ..base.app import DupeGuru as DupeGuruBase
|
||||||
from .details_dialog import DetailsDialog
|
from .details_dialog import DetailsDialog
|
||||||
@ -16,8 +16,7 @@ from .preferences_dialog import PreferencesDialog
|
|||||||
class DupeGuru(DupeGuruBase):
|
class DupeGuru(DupeGuruBase):
|
||||||
EDITION = 'me'
|
EDITION = 'me'
|
||||||
LOGO_NAME = 'logo_me'
|
LOGO_NAME = 'logo_me'
|
||||||
NAME = 'dupeGuru Music Edition'
|
NAME = __appname__
|
||||||
VERSION = __version__
|
|
||||||
DELTA_COLUMNS = frozenset([2, 3, 4, 5, 7])
|
DELTA_COLUMNS = frozenset([2, 3, 4, 5, 7])
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -9,12 +9,13 @@
|
|||||||
from PyQt4.QtCore import QSize
|
from PyQt4.QtCore import QSize
|
||||||
from PyQt4.QtGui import QVBoxLayout, QAbstractItemView
|
from PyQt4.QtGui import QVBoxLayout, QAbstractItemView
|
||||||
|
|
||||||
|
from hscommon.trans import tr
|
||||||
from ..base.details_dialog import DetailsDialog as DetailsDialogBase
|
from ..base.details_dialog import DetailsDialog as DetailsDialogBase
|
||||||
from ..base.details_table import DetailsTable
|
from ..base.details_table import DetailsTable
|
||||||
|
|
||||||
class DetailsDialog(DetailsDialogBase):
|
class DetailsDialog(DetailsDialogBase):
|
||||||
def _setupUi(self):
|
def _setupUi(self):
|
||||||
self.setWindowTitle("Details")
|
self.setWindowTitle(tr("Details"))
|
||||||
self.resize(502, 295)
|
self.resize(502, 295)
|
||||||
self.setMinimumSize(QSize(250, 250))
|
self.setMinimumSize(QSize(250, 250))
|
||||||
self.verticalLayout = QVBoxLayout(self)
|
self.verticalLayout = QVBoxLayout(self)
|
||||||
|
@ -7,12 +7,14 @@
|
|||||||
# http://www.hardcoded.net/licenses/bsd_license
|
# http://www.hardcoded.net/licenses/bsd_license
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
from PyQt4.QtCore import SIGNAL, Qt, QSize
|
from PyQt4.QtCore import SIGNAL, QSize
|
||||||
from PyQt4.QtGui import (QDialog, QDialogButtonBox, QVBoxLayout, QHBoxLayout, QLabel, QComboBox,
|
from PyQt4.QtGui import (QVBoxLayout, QHBoxLayout, QLabel, QComboBox, QSizePolicy, QSpacerItem,
|
||||||
QSlider, QSizePolicy, QSpacerItem, QWidget, QCheckBox, QLineEdit, QDialogButtonBox, QApplication)
|
QWidget, QApplication)
|
||||||
|
|
||||||
|
from hscommon.trans import tr
|
||||||
from core.scanner import ScanType
|
from core.scanner import ScanType
|
||||||
|
|
||||||
|
from ..base.preferences_dialog import PreferencesDialogBase
|
||||||
from . import preferences
|
from . import preferences
|
||||||
|
|
||||||
SCAN_TYPE_ORDER = [
|
SCAN_TYPE_ORDER = [
|
||||||
@ -24,169 +26,73 @@ SCAN_TYPE_ORDER = [
|
|||||||
ScanType.ContentsAudio,
|
ScanType.ContentsAudio,
|
||||||
]
|
]
|
||||||
|
|
||||||
class PreferencesDialog(QDialog):
|
class PreferencesDialog(PreferencesDialogBase):
|
||||||
def __init__(self, parent, app):
|
def __init__(self, parent, app):
|
||||||
flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint
|
PreferencesDialogBase.__init__(self, parent, app)
|
||||||
QDialog.__init__(self, parent, flags)
|
|
||||||
self.app = app
|
|
||||||
self._setupUi()
|
|
||||||
|
|
||||||
self.connect(self.buttonBox, SIGNAL('clicked(QAbstractButton*)'), self.buttonClicked)
|
|
||||||
self.connect(self.scanTypeComboBox, SIGNAL('currentIndexChanged(int)'), self.scanTypeChanged)
|
self.connect(self.scanTypeComboBox, SIGNAL('currentIndexChanged(int)'), self.scanTypeChanged)
|
||||||
self.connect(self.filterHardnessSlider, SIGNAL("valueChanged(int)"), self.filterHardnessLabel.setNum)
|
|
||||||
self.buttonBox.accepted.connect(self.accept)
|
|
||||||
self.buttonBox.rejected.connect(self.reject)
|
|
||||||
|
|
||||||
def _setupUi(self):
|
def _setupPreferenceWidgets(self):
|
||||||
self.setWindowTitle("Preferences")
|
|
||||||
self.resize(325, 360)
|
|
||||||
self.setSizeGripEnabled(False)
|
|
||||||
self.setModal(True)
|
|
||||||
self.verticalLayout_2 = QVBoxLayout(self)
|
|
||||||
self.verticalLayout = QVBoxLayout()
|
|
||||||
self.horizontalLayout = QHBoxLayout()
|
self.horizontalLayout = QHBoxLayout()
|
||||||
self.label_2 = QLabel(self)
|
self.label_2 = QLabel(self)
|
||||||
self.label_2.setText("Scan Type:")
|
self.label_2.setText(tr("Scan Type:"))
|
||||||
self.label_2.setMinimumSize(QSize(100, 0))
|
self.label_2.setMinimumSize(QSize(100, 0))
|
||||||
self.label_2.setMaximumSize(QSize(100, 16777215))
|
self.label_2.setMaximumSize(QSize(100, 16777215))
|
||||||
self.horizontalLayout.addWidget(self.label_2)
|
self.horizontalLayout.addWidget(self.label_2)
|
||||||
self.scanTypeComboBox = QComboBox(self)
|
self.scanTypeComboBox = QComboBox(self)
|
||||||
self.scanTypeComboBox.addItem("Filename")
|
self.scanTypeComboBox.addItem(tr("Filename"))
|
||||||
self.scanTypeComboBox.addItem("Filename - Fields")
|
self.scanTypeComboBox.addItem(tr("Filename - Fields"))
|
||||||
self.scanTypeComboBox.addItem("Filename - Fields (No Order)")
|
self.scanTypeComboBox.addItem(tr("Filename - Fields (No Order)"))
|
||||||
self.scanTypeComboBox.addItem("Tags")
|
self.scanTypeComboBox.addItem(tr("Tags"))
|
||||||
self.scanTypeComboBox.addItem("Contents")
|
self.scanTypeComboBox.addItem(tr("Contents"))
|
||||||
self.scanTypeComboBox.addItem("Audio Contents")
|
self.scanTypeComboBox.addItem(tr("Audio Contents"))
|
||||||
self.horizontalLayout.addWidget(self.scanTypeComboBox)
|
self.horizontalLayout.addWidget(self.scanTypeComboBox)
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
self.widgetsVLayout.addLayout(self.horizontalLayout)
|
||||||
self.horizontalLayout_3 = QHBoxLayout()
|
self._setupFilterHardnessBox()
|
||||||
self.label = QLabel(self)
|
self.widgetsVLayout.addLayout(self.filterHardnessHLayout)
|
||||||
self.label.setText("Filter Hardness:")
|
|
||||||
self.label.setMinimumSize(QSize(100, 0))
|
|
||||||
self.label.setMaximumSize(QSize(100, 16777215))
|
|
||||||
self.horizontalLayout_3.addWidget(self.label)
|
|
||||||
self.verticalLayout_3 = QVBoxLayout()
|
|
||||||
self.verticalLayout_3.setSpacing(0)
|
|
||||||
self.horizontalLayout_6 = QHBoxLayout()
|
|
||||||
self.horizontalLayout_6.setSpacing(12)
|
|
||||||
self.filterHardnessSlider = QSlider(self)
|
|
||||||
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(self.filterHardnessSlider.sizePolicy().hasHeightForWidth())
|
|
||||||
self.filterHardnessSlider.setSizePolicy(sizePolicy)
|
|
||||||
self.filterHardnessSlider.setMinimum(1)
|
|
||||||
self.filterHardnessSlider.setMaximum(100)
|
|
||||||
self.filterHardnessSlider.setTracking(True)
|
|
||||||
self.filterHardnessSlider.setOrientation(Qt.Horizontal)
|
|
||||||
self.horizontalLayout_6.addWidget(self.filterHardnessSlider)
|
|
||||||
self.filterHardnessLabel = QLabel(self)
|
|
||||||
self.filterHardnessLabel.setText("100")
|
|
||||||
self.filterHardnessLabel.setMinimumSize(QSize(21, 0))
|
|
||||||
self.horizontalLayout_6.addWidget(self.filterHardnessLabel)
|
|
||||||
self.verticalLayout_3.addLayout(self.horizontalLayout_6)
|
|
||||||
self.horizontalLayout_5 = QHBoxLayout()
|
|
||||||
self.horizontalLayout_5.setContentsMargins(-1, 0, -1, -1)
|
|
||||||
self.label_4 = QLabel(self)
|
|
||||||
self.label_4.setText("More Results")
|
|
||||||
self.horizontalLayout_5.addWidget(self.label_4)
|
|
||||||
spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
||||||
self.horizontalLayout_5.addItem(spacerItem)
|
|
||||||
self.label_3 = QLabel(self)
|
|
||||||
self.label_3.setText("Fewer Results")
|
|
||||||
self.horizontalLayout_5.addWidget(self.label_3)
|
|
||||||
self.verticalLayout_3.addLayout(self.horizontalLayout_5)
|
|
||||||
self.horizontalLayout_3.addLayout(self.verticalLayout_3)
|
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout_3)
|
|
||||||
self.widget = QWidget(self)
|
self.widget = QWidget(self)
|
||||||
self.widget.setMinimumSize(QSize(0, 40))
|
self.widget.setMinimumSize(QSize(0, 40))
|
||||||
self.verticalLayout_4 = QVBoxLayout(self.widget)
|
self.verticalLayout_4 = QVBoxLayout(self.widget)
|
||||||
self.verticalLayout_4.setSpacing(0)
|
self.verticalLayout_4.setSpacing(0)
|
||||||
self.verticalLayout_4.setMargin(0)
|
self.verticalLayout_4.setMargin(0)
|
||||||
self.label_6 = QLabel(self.widget)
|
self.label_6 = QLabel(self.widget)
|
||||||
self.label_6.setText("Tags to scan:")
|
self.label_6.setText(tr("Tags to scan:"))
|
||||||
self.verticalLayout_4.addWidget(self.label_6)
|
self.verticalLayout_4.addWidget(self.label_6)
|
||||||
self.horizontalLayout_2 = QHBoxLayout()
|
self.horizontalLayout_2 = QHBoxLayout()
|
||||||
self.horizontalLayout_2.setSpacing(0)
|
self.horizontalLayout_2.setSpacing(0)
|
||||||
spacerItem1 = QSpacerItem(15, 20, QSizePolicy.Fixed, QSizePolicy.Minimum)
|
spacerItem1 = QSpacerItem(15, 20, QSizePolicy.Fixed, QSizePolicy.Minimum)
|
||||||
self.horizontalLayout_2.addItem(spacerItem1)
|
self.horizontalLayout_2.addItem(spacerItem1)
|
||||||
self.tagTrackBox = QCheckBox(self.widget)
|
self._setupAddCheckbox('tagTrackBox', tr("Track"), self.widget)
|
||||||
self.tagTrackBox.setText("Track")
|
|
||||||
self.horizontalLayout_2.addWidget(self.tagTrackBox)
|
self.horizontalLayout_2.addWidget(self.tagTrackBox)
|
||||||
self.tagArtistBox = QCheckBox(self.widget)
|
self._setupAddCheckbox('tagArtistBox', tr("Artist"), self.widget)
|
||||||
self.tagArtistBox.setText("Artist")
|
|
||||||
self.horizontalLayout_2.addWidget(self.tagArtistBox)
|
self.horizontalLayout_2.addWidget(self.tagArtistBox)
|
||||||
self.tagAlbumBox = QCheckBox(self.widget)
|
self._setupAddCheckbox('tagAlbumBox', tr("Album"), self.widget)
|
||||||
self.tagAlbumBox.setText("Album")
|
|
||||||
self.horizontalLayout_2.addWidget(self.tagAlbumBox)
|
self.horizontalLayout_2.addWidget(self.tagAlbumBox)
|
||||||
self.tagTitleBox = QCheckBox(self.widget)
|
self._setupAddCheckbox('tagTitleBox', tr("Title"), self.widget)
|
||||||
self.tagTitleBox.setText("Title")
|
|
||||||
self.horizontalLayout_2.addWidget(self.tagTitleBox)
|
self.horizontalLayout_2.addWidget(self.tagTitleBox)
|
||||||
self.tagGenreBox = QCheckBox(self.widget)
|
self._setupAddCheckbox('tagGenreBox', tr("Genre"), self.widget)
|
||||||
self.tagGenreBox.setText("Genre")
|
|
||||||
self.horizontalLayout_2.addWidget(self.tagGenreBox)
|
self.horizontalLayout_2.addWidget(self.tagGenreBox)
|
||||||
self.tagYearBox = QCheckBox(self.widget)
|
self._setupAddCheckbox('tagYearBox', tr("Year"), self.widget)
|
||||||
self.tagYearBox.setText("Year")
|
|
||||||
self.horizontalLayout_2.addWidget(self.tagYearBox)
|
self.horizontalLayout_2.addWidget(self.tagYearBox)
|
||||||
self.verticalLayout_4.addLayout(self.horizontalLayout_2)
|
self.verticalLayout_4.addLayout(self.horizontalLayout_2)
|
||||||
self.verticalLayout.addWidget(self.widget)
|
self.widgetsVLayout.addWidget(self.widget)
|
||||||
self.wordWeightingBox = QCheckBox(self)
|
self._setupAddCheckbox('wordWeightingBox', tr("Word weighting"))
|
||||||
self.wordWeightingBox.setText("Word weighting")
|
self.widgetsVLayout.addWidget(self.wordWeightingBox)
|
||||||
self.verticalLayout.addWidget(self.wordWeightingBox)
|
self._setupAddCheckbox('matchSimilarBox', tr("Match similar words"))
|
||||||
self.matchSimilarBox = QCheckBox(self)
|
self.widgetsVLayout.addWidget(self.matchSimilarBox)
|
||||||
self.matchSimilarBox.setText("Match similar words")
|
self._setupAddCheckbox('mixFileKindBox', tr("Can mix file kind"))
|
||||||
self.verticalLayout.addWidget(self.matchSimilarBox)
|
self.widgetsVLayout.addWidget(self.mixFileKindBox)
|
||||||
self.mixFileKindBox = QCheckBox(self)
|
self._setupAddCheckbox('useRegexpBox', tr("Use regular expressions when filtering"))
|
||||||
self.mixFileKindBox.setText("Can mix file kind")
|
self.widgetsVLayout.addWidget(self.useRegexpBox)
|
||||||
self.verticalLayout.addWidget(self.mixFileKindBox)
|
self._setupAddCheckbox('removeEmptyFoldersBox', tr("Remove empty folders on delete or move"))
|
||||||
self.useRegexpBox = QCheckBox(self)
|
self.widgetsVLayout.addWidget(self.removeEmptyFoldersBox)
|
||||||
self.useRegexpBox.setText("Use regular expressions when filtering")
|
self._setupAddCheckbox('ignoreHardlinkMatches', tr("Ignore duplicates hardlinking to the same file"))
|
||||||
self.verticalLayout.addWidget(self.useRegexpBox)
|
self.widgetsVLayout.addWidget(self.ignoreHardlinkMatches)
|
||||||
self.removeEmptyFoldersBox = QCheckBox(self)
|
self._setupBottomPart()
|
||||||
self.removeEmptyFoldersBox.setText("Remove empty folders on delete or move")
|
|
||||||
self.verticalLayout.addWidget(self.removeEmptyFoldersBox)
|
|
||||||
self.ignoreHardlinkMatches = QCheckBox(self)
|
|
||||||
self.ignoreHardlinkMatches.setText("Ignore duplicates hardlinking to the same file")
|
|
||||||
self.verticalLayout.addWidget(self.ignoreHardlinkMatches)
|
|
||||||
self.horizontalLayout_4 = QHBoxLayout()
|
|
||||||
self.label_5 = QLabel(self)
|
|
||||||
self.label_5.setText("Copy and Move:")
|
|
||||||
self.label_5.setMinimumSize(QSize(100, 0))
|
|
||||||
self.label_5.setMaximumSize(QSize(100, 16777215))
|
|
||||||
self.horizontalLayout_4.addWidget(self.label_5)
|
|
||||||
self.copyMoveDestinationComboBox = QComboBox(self)
|
|
||||||
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(self.copyMoveDestinationComboBox.sizePolicy().hasHeightForWidth())
|
|
||||||
self.copyMoveDestinationComboBox.setSizePolicy(sizePolicy)
|
|
||||||
self.copyMoveDestinationComboBox.addItem("Right in destination")
|
|
||||||
self.copyMoveDestinationComboBox.addItem("Recreate relative path")
|
|
||||||
self.copyMoveDestinationComboBox.addItem("Recreate absolute path")
|
|
||||||
self.horizontalLayout_4.addWidget(self.copyMoveDestinationComboBox)
|
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout_4)
|
|
||||||
self.label_7 = QLabel(self)
|
|
||||||
self.label_7.setText("Custom Command (arguments: %d for dupe, %r for ref):")
|
|
||||||
self.verticalLayout.addWidget(self.label_7)
|
|
||||||
self.customCommandEdit = QLineEdit(self)
|
|
||||||
self.verticalLayout.addWidget(self.customCommandEdit)
|
|
||||||
self.verticalLayout_2.addLayout(self.verticalLayout)
|
|
||||||
self.buttonBox = QDialogButtonBox(self)
|
|
||||||
self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok|QDialogButtonBox.RestoreDefaults)
|
|
||||||
self.verticalLayout_2.addWidget(self.buttonBox)
|
|
||||||
|
|
||||||
if sys.platform not in {'darwin', 'linux2'}:
|
def _load(self, prefs, setchecked):
|
||||||
self.verticalLayout.removeWidget(self.ignoreHardlinkMatches)
|
|
||||||
self.ignoreHardlinkMatches.setHidden(True)
|
|
||||||
|
|
||||||
def load(self, prefs=None):
|
|
||||||
if prefs is None:
|
|
||||||
prefs = self.app.prefs
|
|
||||||
self.filterHardnessSlider.setValue(prefs.filter_hardness)
|
|
||||||
self.filterHardnessLabel.setNum(prefs.filter_hardness)
|
|
||||||
scan_type_index = SCAN_TYPE_ORDER.index(prefs.scan_type)
|
scan_type_index = SCAN_TYPE_ORDER.index(prefs.scan_type)
|
||||||
self.scanTypeComboBox.setCurrentIndex(scan_type_index)
|
self.scanTypeComboBox.setCurrentIndex(scan_type_index)
|
||||||
setchecked = lambda cb, b: cb.setCheckState(Qt.Checked if b else Qt.Unchecked)
|
|
||||||
setchecked(self.tagTrackBox, prefs.scan_tag_track)
|
setchecked(self.tagTrackBox, prefs.scan_tag_track)
|
||||||
setchecked(self.tagArtistBox, prefs.scan_tag_artist)
|
setchecked(self.tagArtistBox, prefs.scan_tag_artist)
|
||||||
setchecked(self.tagAlbumBox, prefs.scan_tag_album)
|
setchecked(self.tagAlbumBox, prefs.scan_tag_album)
|
||||||
@ -195,18 +101,9 @@ class PreferencesDialog(QDialog):
|
|||||||
setchecked(self.tagYearBox, prefs.scan_tag_year)
|
setchecked(self.tagYearBox, prefs.scan_tag_year)
|
||||||
setchecked(self.matchSimilarBox, prefs.match_similar)
|
setchecked(self.matchSimilarBox, prefs.match_similar)
|
||||||
setchecked(self.wordWeightingBox, prefs.word_weighting)
|
setchecked(self.wordWeightingBox, prefs.word_weighting)
|
||||||
setchecked(self.mixFileKindBox, prefs.mix_file_kind)
|
|
||||||
setchecked(self.ignoreHardlinkMatches, prefs.ignore_hardlink_matches)
|
|
||||||
setchecked(self.useRegexpBox, prefs.use_regexp)
|
|
||||||
setchecked(self.removeEmptyFoldersBox, prefs.remove_empty_folders)
|
|
||||||
self.copyMoveDestinationComboBox.setCurrentIndex(prefs.destination_type)
|
|
||||||
self.customCommandEdit.setText(prefs.custom_command)
|
|
||||||
|
|
||||||
def save(self):
|
def _save(self, prefs, ischecked):
|
||||||
prefs = self.app.prefs
|
|
||||||
prefs.filter_hardness = self.filterHardnessSlider.value()
|
|
||||||
prefs.scan_type = SCAN_TYPE_ORDER[self.scanTypeComboBox.currentIndex()]
|
prefs.scan_type = SCAN_TYPE_ORDER[self.scanTypeComboBox.currentIndex()]
|
||||||
ischecked = lambda cb: cb.checkState() == Qt.Checked
|
|
||||||
prefs.scan_tag_track = ischecked(self.tagTrackBox)
|
prefs.scan_tag_track = ischecked(self.tagTrackBox)
|
||||||
prefs.scan_tag_artist = ischecked(self.tagArtistBox)
|
prefs.scan_tag_artist = ischecked(self.tagArtistBox)
|
||||||
prefs.scan_tag_album = ischecked(self.tagAlbumBox)
|
prefs.scan_tag_album = ischecked(self.tagAlbumBox)
|
||||||
@ -215,22 +112,11 @@ class PreferencesDialog(QDialog):
|
|||||||
prefs.scan_tag_year = ischecked(self.tagYearBox)
|
prefs.scan_tag_year = ischecked(self.tagYearBox)
|
||||||
prefs.match_similar = ischecked(self.matchSimilarBox)
|
prefs.match_similar = ischecked(self.matchSimilarBox)
|
||||||
prefs.word_weighting = ischecked(self.wordWeightingBox)
|
prefs.word_weighting = ischecked(self.wordWeightingBox)
|
||||||
prefs.mix_file_kind = ischecked(self.mixFileKindBox)
|
|
||||||
prefs.ignore_hardlink_matches = ischecked(self.ignoreHardlinkMatches)
|
|
||||||
prefs.use_regexp = ischecked(self.useRegexpBox)
|
|
||||||
prefs.remove_empty_folders = ischecked(self.removeEmptyFoldersBox)
|
|
||||||
prefs.destination_type = self.copyMoveDestinationComboBox.currentIndex()
|
|
||||||
prefs.custom_command = str(self.customCommandEdit.text())
|
|
||||||
|
|
||||||
def resetToDefaults(self):
|
def resetToDefaults(self):
|
||||||
self.load(preferences.Preferences())
|
self.load(preferences.Preferences())
|
||||||
|
|
||||||
#--- Events
|
#--- Events
|
||||||
def buttonClicked(self, button):
|
|
||||||
role = self.buttonBox.buttonRole(button)
|
|
||||||
if role == QDialogButtonBox.ResetRole:
|
|
||||||
self.resetToDefaults()
|
|
||||||
|
|
||||||
def scanTypeChanged(self, index):
|
def scanTypeChanged(self, index):
|
||||||
scan_type = SCAN_TYPE_ORDER[self.scanTypeComboBox.currentIndex()]
|
scan_type = SCAN_TYPE_ORDER[self.scanTypeComboBox.currentIndex()]
|
||||||
word_based = scan_type in (ScanType.Filename, ScanType.Fields, ScanType.FieldsNoOrder,
|
word_based = scan_type in (ScanType.Filename, ScanType.Fields, ScanType.FieldsNoOrder,
|
||||||
@ -248,7 +134,6 @@ class PreferencesDialog(QDialog):
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import sys
|
|
||||||
from ..testapp import TestApp
|
from ..testapp import TestApp
|
||||||
app = QApplication([])
|
app = QApplication([])
|
||||||
dgapp = TestApp()
|
dgapp = TestApp()
|
||||||
|
@ -14,7 +14,7 @@ from PyQt4.QtGui import QImage, QImageReader
|
|||||||
from hscommon.util import get_file_ext
|
from hscommon.util import get_file_ext
|
||||||
|
|
||||||
from core import fs
|
from core import fs
|
||||||
from core_pe import data as data_pe, __version__
|
from core_pe import data as data_pe, __appname__
|
||||||
from core_pe.scanner import ScannerPE
|
from core_pe.scanner import ScannerPE
|
||||||
|
|
||||||
from ..base.app import DupeGuru as DupeGuruBase
|
from ..base.app import DupeGuru as DupeGuruBase
|
||||||
@ -58,8 +58,7 @@ class File(fs.File):
|
|||||||
class DupeGuru(DupeGuruBase):
|
class DupeGuru(DupeGuruBase):
|
||||||
EDITION = 'pe'
|
EDITION = 'pe'
|
||||||
LOGO_NAME = 'logo_pe'
|
LOGO_NAME = 'logo_pe'
|
||||||
NAME = 'dupeGuru Picture Edition'
|
NAME = __appname__
|
||||||
VERSION = __version__
|
|
||||||
DELTA_COLUMNS = frozenset([2, 5])
|
DELTA_COLUMNS = frozenset([2, 5])
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
from PyQt4.QtCore import Qt, QSize
|
from PyQt4.QtCore import Qt, QSize
|
||||||
from PyQt4.QtGui import QVBoxLayout, QAbstractItemView, QHBoxLayout, QLabel, QSizePolicy, QPixmap
|
from PyQt4.QtGui import QVBoxLayout, QAbstractItemView, QHBoxLayout, QLabel, QSizePolicy, QPixmap
|
||||||
|
|
||||||
|
from hscommon.trans import tr
|
||||||
from ..base.details_dialog import DetailsDialog as DetailsDialogBase
|
from ..base.details_dialog import DetailsDialog as DetailsDialogBase
|
||||||
from ..base.details_table import DetailsTable
|
from ..base.details_table import DetailsTable
|
||||||
|
|
||||||
@ -19,7 +20,7 @@ class DetailsDialog(DetailsDialogBase):
|
|||||||
self.referencePixmap = None
|
self.referencePixmap = None
|
||||||
|
|
||||||
def _setupUi(self):
|
def _setupUi(self):
|
||||||
self.setWindowTitle("Details")
|
self.setWindowTitle(tr("Details"))
|
||||||
self.resize(502, 295)
|
self.resize(502, 295)
|
||||||
self.setMinimumSize(QSize(250, 250))
|
self.setMinimumSize(QSize(250, 250))
|
||||||
self.verticalLayout = QVBoxLayout(self)
|
self.verticalLayout = QVBoxLayout(self)
|
||||||
|
@ -7,148 +7,40 @@
|
|||||||
# http://www.hardcoded.net/licenses/bsd_license
|
# http://www.hardcoded.net/licenses/bsd_license
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
from PyQt4.QtCore import SIGNAL, Qt, QSize
|
from PyQt4.QtGui import QLabel, QApplication
|
||||||
from PyQt4.QtGui import (QDialog, QDialogButtonBox, QVBoxLayout, QHBoxLayout, QLabel, QComboBox,
|
|
||||||
QSlider, QSizePolicy, QSpacerItem, QWidget, QCheckBox, QLineEdit, QDialogButtonBox, QApplication)
|
|
||||||
|
|
||||||
|
from hscommon.trans import tr
|
||||||
|
|
||||||
|
from ..base.preferences_dialog import PreferencesDialogBase
|
||||||
from . import preferences
|
from . import preferences
|
||||||
|
|
||||||
class PreferencesDialog(QDialog):
|
class PreferencesDialog(PreferencesDialogBase):
|
||||||
def __init__(self, parent, app):
|
def _setupPreferenceWidgets(self):
|
||||||
flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint
|
self._setupFilterHardnessBox()
|
||||||
QDialog.__init__(self, parent, flags)
|
self.widgetsVLayout.addLayout(self.filterHardnessHLayout)
|
||||||
self.app = app
|
self._setupAddCheckbox('matchScaledBox', tr("Match scaled pictures together"))
|
||||||
self._setupUi()
|
self.widgetsVLayout.addWidget(self.matchScaledBox)
|
||||||
|
self._setupAddCheckbox('mixFileKindBox', tr("Can mix file kind"))
|
||||||
|
self.widgetsVLayout.addWidget(self.mixFileKindBox)
|
||||||
|
self._setupAddCheckbox('useRegexpBox', tr("Use regular expressions when filtering"))
|
||||||
|
self.widgetsVLayout.addWidget(self.useRegexpBox)
|
||||||
|
self._setupAddCheckbox('removeEmptyFoldersBox', tr("Remove empty folders on delete or move"))
|
||||||
|
self.widgetsVLayout.addWidget(self.removeEmptyFoldersBox)
|
||||||
|
self._setupAddCheckbox('ignoreHardlinkMatches', tr("Ignore duplicates hardlinking to the same file"))
|
||||||
|
self.widgetsVLayout.addWidget(self.ignoreHardlinkMatches)
|
||||||
|
self._setupBottomPart()
|
||||||
|
|
||||||
self.connect(self.buttonBox, SIGNAL('clicked(QAbstractButton*)'), self.buttonClicked)
|
def _load(self, prefs, setchecked):
|
||||||
self.connect(self.filterHardnessSlider, SIGNAL("valueChanged(int)"), self.filterHardnessLabel.setNum)
|
|
||||||
self.buttonBox.accepted.connect(self.accept)
|
|
||||||
self.buttonBox.rejected.connect(self.reject)
|
|
||||||
|
|
||||||
def _setupUi(self):
|
|
||||||
self.setWindowTitle("Preferences")
|
|
||||||
self.resize(304, 263)
|
|
||||||
self.setSizeGripEnabled(False)
|
|
||||||
self.setModal(True)
|
|
||||||
self.verticalLayout_2 = QVBoxLayout(self)
|
|
||||||
self.verticalLayout = QVBoxLayout()
|
|
||||||
self.horizontalLayout_3 = QHBoxLayout()
|
|
||||||
self.label = QLabel(self)
|
|
||||||
self.label.setText("Filter Hardness:")
|
|
||||||
self.label.setMinimumSize(QSize(0, 0))
|
|
||||||
self.horizontalLayout_3.addWidget(self.label)
|
|
||||||
self.verticalLayout_3 = QVBoxLayout()
|
|
||||||
self.verticalLayout_3.setSpacing(0)
|
|
||||||
self.horizontalLayout_6 = QHBoxLayout()
|
|
||||||
self.horizontalLayout_6.setSpacing(12)
|
|
||||||
self.filterHardnessSlider = QSlider(self)
|
|
||||||
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(self.filterHardnessSlider.sizePolicy().hasHeightForWidth())
|
|
||||||
self.filterHardnessSlider.setSizePolicy(sizePolicy)
|
|
||||||
self.filterHardnessSlider.setMinimum(1)
|
|
||||||
self.filterHardnessSlider.setMaximum(100)
|
|
||||||
self.filterHardnessSlider.setTracking(True)
|
|
||||||
self.filterHardnessSlider.setOrientation(Qt.Horizontal)
|
|
||||||
self.horizontalLayout_6.addWidget(self.filterHardnessSlider)
|
|
||||||
self.filterHardnessLabel = QLabel(self)
|
|
||||||
self.filterHardnessLabel.setText("100")
|
|
||||||
self.filterHardnessLabel.setMinimumSize(QSize(21, 0))
|
|
||||||
self.horizontalLayout_6.addWidget(self.filterHardnessLabel)
|
|
||||||
self.verticalLayout_3.addLayout(self.horizontalLayout_6)
|
|
||||||
self.horizontalLayout_5 = QHBoxLayout()
|
|
||||||
self.horizontalLayout_5.setContentsMargins(-1, 0, -1, -1)
|
|
||||||
self.label_4 = QLabel(self)
|
|
||||||
self.label_4.setText("More Results")
|
|
||||||
self.horizontalLayout_5.addWidget(self.label_4)
|
|
||||||
spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
||||||
self.horizontalLayout_5.addItem(spacerItem)
|
|
||||||
self.label_3 = QLabel(self)
|
|
||||||
self.label_3.setText("Fewer Results")
|
|
||||||
self.horizontalLayout_5.addWidget(self.label_3)
|
|
||||||
self.verticalLayout_3.addLayout(self.horizontalLayout_5)
|
|
||||||
self.horizontalLayout_3.addLayout(self.verticalLayout_3)
|
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout_3)
|
|
||||||
self.matchScaledBox = QCheckBox(self)
|
|
||||||
self.matchScaledBox.setText("Match scaled pictures together")
|
|
||||||
self.verticalLayout.addWidget(self.matchScaledBox)
|
|
||||||
self.mixFileKindBox = QCheckBox(self)
|
|
||||||
self.mixFileKindBox.setText("Can mix file kind")
|
|
||||||
self.verticalLayout.addWidget(self.mixFileKindBox)
|
|
||||||
self.useRegexpBox = QCheckBox(self)
|
|
||||||
self.useRegexpBox.setText("Use regular expressions when filtering")
|
|
||||||
self.verticalLayout.addWidget(self.useRegexpBox)
|
|
||||||
self.removeEmptyFoldersBox = QCheckBox(self)
|
|
||||||
self.removeEmptyFoldersBox.setText("Remove empty folders on delete or move")
|
|
||||||
self.verticalLayout.addWidget(self.removeEmptyFoldersBox)
|
|
||||||
self.ignoreHardlinkMatches = QCheckBox(self)
|
|
||||||
self.ignoreHardlinkMatches.setText("Ignore duplicates hardlinking to the same file")
|
|
||||||
self.verticalLayout.addWidget(self.ignoreHardlinkMatches)
|
|
||||||
self.horizontalLayout_4 = QHBoxLayout()
|
|
||||||
self.label_5 = QLabel(self)
|
|
||||||
self.label_5.setText("Copy and Move:")
|
|
||||||
self.label_5.setMinimumSize(QSize(0, 0))
|
|
||||||
self.horizontalLayout_4.addWidget(self.label_5)
|
|
||||||
self.copyMoveDestinationComboBox = QComboBox(self)
|
|
||||||
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(self.copyMoveDestinationComboBox.sizePolicy().hasHeightForWidth())
|
|
||||||
self.copyMoveDestinationComboBox.addItem("Right in destination")
|
|
||||||
self.copyMoveDestinationComboBox.addItem("Recreate relative path")
|
|
||||||
self.copyMoveDestinationComboBox.addItem("Recreate absolute path")
|
|
||||||
self.horizontalLayout_4.addWidget(self.copyMoveDestinationComboBox)
|
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout_4)
|
|
||||||
self.label_2 = QLabel(self)
|
|
||||||
self.label_2.setText("Custom Command (arguments: %d for dupe %r for ref):")
|
|
||||||
self.verticalLayout.addWidget(self.label_2)
|
|
||||||
self.customCommandEdit = QLineEdit(self)
|
|
||||||
self.verticalLayout.addWidget(self.customCommandEdit)
|
|
||||||
self.verticalLayout_2.addLayout(self.verticalLayout)
|
|
||||||
self.buttonBox = QDialogButtonBox(self)
|
|
||||||
self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok|QDialogButtonBox.RestoreDefaults)
|
|
||||||
self.verticalLayout_2.addWidget(self.buttonBox)
|
|
||||||
if sys.platform not in {'darwin', 'linux2'}:
|
|
||||||
self.verticalLayout.removeWidget(self.ignoreHardlinkMatches)
|
|
||||||
self.ignoreHardlinkMatches.setHidden(True)
|
|
||||||
|
|
||||||
def load(self, prefs=None):
|
|
||||||
if prefs is None:
|
|
||||||
prefs = self.app.prefs
|
|
||||||
self.filterHardnessSlider.setValue(prefs.filter_hardness)
|
|
||||||
self.filterHardnessLabel.setNum(prefs.filter_hardness)
|
|
||||||
setchecked = lambda cb, b: cb.setCheckState(Qt.Checked if b else Qt.Unchecked)
|
|
||||||
setchecked(self.matchScaledBox, prefs.match_scaled)
|
setchecked(self.matchScaledBox, prefs.match_scaled)
|
||||||
setchecked(self.mixFileKindBox, prefs.mix_file_kind)
|
|
||||||
setchecked(self.useRegexpBox, prefs.use_regexp)
|
|
||||||
setchecked(self.removeEmptyFoldersBox, prefs.remove_empty_folders)
|
|
||||||
self.copyMoveDestinationComboBox.setCurrentIndex(prefs.destination_type)
|
|
||||||
self.customCommandEdit.setText(prefs.custom_command)
|
|
||||||
|
|
||||||
def save(self):
|
def _save(self, prefs, ischecked):
|
||||||
prefs = self.app.prefs
|
|
||||||
prefs.filter_hardness = self.filterHardnessSlider.value()
|
|
||||||
ischecked = lambda cb: cb.checkState() == Qt.Checked
|
|
||||||
prefs.match_scaled = ischecked(self.matchScaledBox)
|
prefs.match_scaled = ischecked(self.matchScaledBox)
|
||||||
prefs.mix_file_kind = ischecked(self.mixFileKindBox)
|
|
||||||
prefs.use_regexp = ischecked(self.useRegexpBox)
|
|
||||||
prefs.remove_empty_folders = ischecked(self.removeEmptyFoldersBox)
|
|
||||||
prefs.destination_type = self.copyMoveDestinationComboBox.currentIndex()
|
|
||||||
prefs.custom_command = str(self.customCommandEdit.text())
|
|
||||||
|
|
||||||
def resetToDefaults(self):
|
def resetToDefaults(self):
|
||||||
self.load(preferences.Preferences())
|
self.load(preferences.Preferences())
|
||||||
|
|
||||||
#--- Events
|
|
||||||
def buttonClicked(self, button):
|
|
||||||
role = self.buttonBox.buttonRole(button)
|
|
||||||
if role == QDialogButtonBox.ResetRole:
|
|
||||||
self.resetToDefaults()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import sys
|
|
||||||
from ..testapp import TestApp
|
from ..testapp import TestApp
|
||||||
app = QApplication([])
|
app = QApplication([])
|
||||||
dgapp = TestApp()
|
dgapp = TestApp()
|
||||||
|
@ -9,19 +9,20 @@
|
|||||||
from PyQt4.QtCore import SIGNAL
|
from PyQt4.QtCore import SIGNAL
|
||||||
from PyQt4.QtGui import QMessageBox, QAction
|
from PyQt4.QtGui import QMessageBox, QAction
|
||||||
|
|
||||||
|
from hscommon.trans import tr, trmsg
|
||||||
from ..base.result_window import ResultWindow as ResultWindowBase
|
from ..base.result_window import ResultWindow as ResultWindowBase
|
||||||
|
|
||||||
class ResultWindow(ResultWindowBase):
|
class ResultWindow(ResultWindowBase):
|
||||||
def _setupUi(self):
|
def _setupUi(self):
|
||||||
ResultWindowBase._setupUi(self)
|
ResultWindowBase._setupUi(self)
|
||||||
self.actionClearPictureCache = QAction("Clear Picture Cache", self)
|
self.actionClearPictureCache = QAction(tr("Clear Picture Cache"), self)
|
||||||
self.menuFile.insertAction(self.actionClearIgnoreList, self.actionClearPictureCache)
|
self.menuFile.insertAction(self.actionClearIgnoreList, self.actionClearPictureCache)
|
||||||
self.connect(self.actionClearPictureCache, SIGNAL("triggered()"), self.clearPictureCacheTriggered)
|
self.connect(self.actionClearPictureCache, SIGNAL("triggered()"), self.clearPictureCacheTriggered)
|
||||||
|
|
||||||
def clearPictureCacheTriggered(self):
|
def clearPictureCacheTriggered(self):
|
||||||
title = "Clear Picture Cache"
|
title = tr("Clear Picture Cache")
|
||||||
msg = "Do you really want to remove all your cached picture analysis?"
|
msg = trmsg("ClearPictureCacheConfirmMsg")
|
||||||
if self.app.confirm(title, msg, QMessageBox.No):
|
if self.app.confirm(title, msg, QMessageBox.No):
|
||||||
self.app.scanner.clear_picture_cache()
|
self.app.scanner.clear_picture_cache()
|
||||||
QMessageBox.information(self, title, "Picture cache cleared.")
|
QMessageBox.information(self, title, trmsg("PictureCacheClearedMsg"))
|
||||||
|
|
@ -6,7 +6,7 @@
|
|||||||
# 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/bsd_license
|
# http://www.hardcoded.net/licenses/bsd_license
|
||||||
|
|
||||||
from core_se import data, __version__
|
from core_se import data, __appname__
|
||||||
from core.directories import Directories as DirectoriesBase, STATE_EXCLUDED
|
from core.directories import Directories as DirectoriesBase, STATE_EXCLUDED
|
||||||
|
|
||||||
from ..base.app import DupeGuru as DupeGuruBase
|
from ..base.app import DupeGuru as DupeGuruBase
|
||||||
@ -26,8 +26,7 @@ class Directories(DirectoriesBase):
|
|||||||
class DupeGuru(DupeGuruBase):
|
class DupeGuru(DupeGuruBase):
|
||||||
EDITION = 'se'
|
EDITION = 'se'
|
||||||
LOGO_NAME = 'logo_se'
|
LOGO_NAME = 'logo_se'
|
||||||
NAME = 'dupeGuru'
|
NAME = __appname__
|
||||||
VERSION = __version__
|
|
||||||
DELTA_COLUMNS = frozenset([2, 4])
|
DELTA_COLUMNS = frozenset([2, 4])
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -9,12 +9,13 @@
|
|||||||
from PyQt4.QtCore import QSize
|
from PyQt4.QtCore import QSize
|
||||||
from PyQt4.QtGui import QVBoxLayout, QAbstractItemView
|
from PyQt4.QtGui import QVBoxLayout, QAbstractItemView
|
||||||
|
|
||||||
|
from hscommon.trans import tr
|
||||||
from ..base.details_dialog import DetailsDialog as DetailsDialogBase
|
from ..base.details_dialog import DetailsDialog as DetailsDialogBase
|
||||||
from ..base.details_table import DetailsTable
|
from ..base.details_table import DetailsTable
|
||||||
|
|
||||||
class DetailsDialog(DetailsDialogBase):
|
class DetailsDialog(DetailsDialogBase):
|
||||||
def _setupUi(self):
|
def _setupUi(self):
|
||||||
self.setWindowTitle("Details")
|
self.setWindowTitle(tr("Details"))
|
||||||
self.resize(502, 186)
|
self.resize(502, 186)
|
||||||
self.setMinimumSize(QSize(200, 0))
|
self.setMinimumSize(QSize(200, 0))
|
||||||
self.verticalLayout = QVBoxLayout(self)
|
self.verticalLayout = QVBoxLayout(self)
|
||||||
|
@ -7,14 +7,16 @@
|
|||||||
# http://www.hardcoded.net/licenses/bsd_license
|
# http://www.hardcoded.net/licenses/bsd_license
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
from PyQt4.QtCore import SIGNAL, Qt, QSize
|
from PyQt4.QtCore import SIGNAL, QSize
|
||||||
from PyQt4.QtGui import (QDialog, QDialogButtonBox, QVBoxLayout, QHBoxLayout, QLabel, QComboBox,
|
from PyQt4.QtGui import (QVBoxLayout, QHBoxLayout, QLabel, QComboBox, QSizePolicy, QSpacerItem,
|
||||||
QSlider, QSizePolicy, QSpacerItem, QWidget, QCheckBox, QLineEdit, QDialogButtonBox, QApplication)
|
QWidget, QLineEdit, QApplication)
|
||||||
|
|
||||||
|
from hscommon.trans import tr
|
||||||
from hscommon.util import tryint
|
from hscommon.util import tryint
|
||||||
|
|
||||||
from core.scanner import ScanType
|
from core.scanner import ScanType
|
||||||
|
|
||||||
|
from ..base.preferences_dialog import PreferencesDialogBase
|
||||||
from . import preferences
|
from . import preferences
|
||||||
|
|
||||||
SCAN_TYPE_ORDER = [
|
SCAN_TYPE_ORDER = [
|
||||||
@ -22,97 +24,41 @@ SCAN_TYPE_ORDER = [
|
|||||||
ScanType.Contents,
|
ScanType.Contents,
|
||||||
]
|
]
|
||||||
|
|
||||||
class PreferencesDialog(QDialog):
|
class PreferencesDialog(PreferencesDialogBase):
|
||||||
def __init__(self, parent, app):
|
def __init__(self, parent, app):
|
||||||
flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint
|
PreferencesDialogBase.__init__(self, parent, app)
|
||||||
QDialog.__init__(self, parent, flags)
|
|
||||||
self.app = app
|
|
||||||
self._setupUi()
|
|
||||||
|
|
||||||
self.connect(self.buttonBox, SIGNAL('clicked(QAbstractButton*)'), self.buttonClicked)
|
|
||||||
self.connect(self.scanTypeComboBox, SIGNAL('currentIndexChanged(int)'), self.scanTypeChanged)
|
self.connect(self.scanTypeComboBox, SIGNAL('currentIndexChanged(int)'), self.scanTypeChanged)
|
||||||
self.connect(self.filterHardnessSlider, SIGNAL("valueChanged(int)"), self.filterHardnessLabel.setNum)
|
|
||||||
self.buttonBox.accepted.connect(self.accept)
|
|
||||||
self.buttonBox.rejected.connect(self.reject)
|
|
||||||
|
|
||||||
def _setupUi(self):
|
def _setupPreferenceWidgets(self):
|
||||||
self.setWindowTitle("Preferences")
|
|
||||||
self.resize(308, 361)
|
|
||||||
self.setSizeGripEnabled(False)
|
|
||||||
self.setModal(True)
|
|
||||||
self.verticalLayout_2 = QVBoxLayout(self)
|
|
||||||
self.verticalLayout = QVBoxLayout()
|
|
||||||
self.horizontalLayout = QHBoxLayout()
|
self.horizontalLayout = QHBoxLayout()
|
||||||
self.label_2 = QLabel(self)
|
self.label_2 = QLabel(self)
|
||||||
self.label_2.setText("Scan Type:")
|
self.label_2.setText(tr("Scan Type:"))
|
||||||
self.label_2.setMinimumSize(QSize(100, 0))
|
self.label_2.setMinimumSize(QSize(100, 0))
|
||||||
self.label_2.setMaximumSize(QSize(100, 16777215))
|
self.label_2.setMaximumSize(QSize(100, 16777215))
|
||||||
self.horizontalLayout.addWidget(self.label_2)
|
self.horizontalLayout.addWidget(self.label_2)
|
||||||
self.scanTypeComboBox = QComboBox(self)
|
self.scanTypeComboBox = QComboBox(self)
|
||||||
self.scanTypeComboBox.addItem("Filename")
|
self.scanTypeComboBox.addItem(tr("Filename"))
|
||||||
self.scanTypeComboBox.addItem("Contents")
|
self.scanTypeComboBox.addItem(tr("Contents"))
|
||||||
self.horizontalLayout.addWidget(self.scanTypeComboBox)
|
self.horizontalLayout.addWidget(self.scanTypeComboBox)
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
self.widgetsVLayout.addLayout(self.horizontalLayout)
|
||||||
self.horizontalLayout_3 = QHBoxLayout()
|
self._setupFilterHardnessBox()
|
||||||
self.label = QLabel(self)
|
self.widgetsVLayout.addLayout(self.filterHardnessHLayout)
|
||||||
self.label.setText("Filter Hardness:")
|
|
||||||
self.label.setMinimumSize(QSize(100, 0))
|
|
||||||
self.label.setMaximumSize(QSize(100, 16777215))
|
|
||||||
self.horizontalLayout_3.addWidget(self.label)
|
|
||||||
self.verticalLayout_3 = QVBoxLayout()
|
|
||||||
self.verticalLayout_3.setSpacing(0)
|
|
||||||
self.horizontalLayout_6 = QHBoxLayout()
|
|
||||||
self.horizontalLayout_6.setSpacing(12)
|
|
||||||
self.filterHardnessSlider = QSlider(self)
|
|
||||||
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(self.filterHardnessSlider.sizePolicy().hasHeightForWidth())
|
|
||||||
self.filterHardnessSlider.setSizePolicy(sizePolicy)
|
|
||||||
self.filterHardnessSlider.setMinimum(1)
|
|
||||||
self.filterHardnessSlider.setMaximum(100)
|
|
||||||
self.filterHardnessSlider.setTracking(True)
|
|
||||||
self.filterHardnessSlider.setOrientation(Qt.Horizontal)
|
|
||||||
self.horizontalLayout_6.addWidget(self.filterHardnessSlider)
|
|
||||||
self.filterHardnessLabel = QLabel(self)
|
|
||||||
self.filterHardnessLabel.setText("100")
|
|
||||||
self.filterHardnessLabel.setMinimumSize(QSize(21, 0))
|
|
||||||
self.horizontalLayout_6.addWidget(self.filterHardnessLabel)
|
|
||||||
self.verticalLayout_3.addLayout(self.horizontalLayout_6)
|
|
||||||
self.horizontalLayout_5 = QHBoxLayout()
|
|
||||||
self.horizontalLayout_5.setContentsMargins(-1, 0, -1, -1)
|
|
||||||
self.label_4 = QLabel(self)
|
|
||||||
self.label_4.setText("More Results")
|
|
||||||
self.horizontalLayout_5.addWidget(self.label_4)
|
|
||||||
spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
||||||
self.horizontalLayout_5.addItem(spacerItem)
|
|
||||||
self.label_3 = QLabel(self)
|
|
||||||
self.label_3.setText("Fewer Results")
|
|
||||||
self.horizontalLayout_5.addWidget(self.label_3)
|
|
||||||
self.verticalLayout_3.addLayout(self.horizontalLayout_5)
|
|
||||||
self.horizontalLayout_3.addLayout(self.verticalLayout_3)
|
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout_3)
|
|
||||||
self.widget = QWidget(self)
|
self.widget = QWidget(self)
|
||||||
self.widget.setMinimumSize(QSize(0, 136))
|
self.widget.setMinimumSize(QSize(0, 136))
|
||||||
self.verticalLayout_4 = QVBoxLayout(self.widget)
|
self.verticalLayout_4 = QVBoxLayout(self.widget)
|
||||||
self.wordWeightingBox = QCheckBox(self.widget)
|
self._setupAddCheckbox('wordWeightingBox', tr("Word weighting"), self.widget)
|
||||||
self.wordWeightingBox.setText("Word weighting")
|
|
||||||
self.verticalLayout_4.addWidget(self.wordWeightingBox)
|
self.verticalLayout_4.addWidget(self.wordWeightingBox)
|
||||||
self.matchSimilarBox = QCheckBox(self.widget)
|
self._setupAddCheckbox('matchSimilarBox', tr("Match similar words"), self.widget)
|
||||||
self.matchSimilarBox.setText("Match similar words")
|
|
||||||
self.verticalLayout_4.addWidget(self.matchSimilarBox)
|
self.verticalLayout_4.addWidget(self.matchSimilarBox)
|
||||||
self.mixFileKindBox = QCheckBox(self.widget)
|
self._setupAddCheckbox('mixFileKindBox', tr("Can mix file kind"), self.widget)
|
||||||
self.mixFileKindBox.setText("Can mix file kind")
|
|
||||||
self.verticalLayout_4.addWidget(self.mixFileKindBox)
|
self.verticalLayout_4.addWidget(self.mixFileKindBox)
|
||||||
self.useRegexpBox = QCheckBox(self.widget)
|
self._setupAddCheckbox('useRegexpBox', tr("Use regular expressions when filtering"), self.widget)
|
||||||
self.useRegexpBox.setText("Use regular expressions when filtering")
|
|
||||||
self.verticalLayout_4.addWidget(self.useRegexpBox)
|
self.verticalLayout_4.addWidget(self.useRegexpBox)
|
||||||
self.removeEmptyFoldersBox = QCheckBox(self.widget)
|
self._setupAddCheckbox('removeEmptyFoldersBox', tr("Remove empty folders on delete or move"), self.widget)
|
||||||
self.removeEmptyFoldersBox.setText("Remove empty folders on delete or move")
|
|
||||||
self.verticalLayout_4.addWidget(self.removeEmptyFoldersBox)
|
self.verticalLayout_4.addWidget(self.removeEmptyFoldersBox)
|
||||||
self.horizontalLayout_2 = QHBoxLayout()
|
self.horizontalLayout_2 = QHBoxLayout()
|
||||||
self.ignoreSmallFilesBox = QCheckBox(self.widget)
|
self._setupAddCheckbox('ignoreSmallFilesBox', tr("Ignore files smaller than"), self.widget)
|
||||||
self.ignoreSmallFilesBox.setText("Ignore files smaller than")
|
|
||||||
self.horizontalLayout_2.addWidget(self.ignoreSmallFilesBox)
|
self.horizontalLayout_2.addWidget(self.ignoreSmallFilesBox)
|
||||||
self.sizeThresholdEdit = QLineEdit(self.widget)
|
self.sizeThresholdEdit = QLineEdit(self.widget)
|
||||||
sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed)
|
sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed)
|
||||||
@ -123,94 +69,43 @@ class PreferencesDialog(QDialog):
|
|||||||
self.sizeThresholdEdit.setMaximumSize(QSize(50, 16777215))
|
self.sizeThresholdEdit.setMaximumSize(QSize(50, 16777215))
|
||||||
self.horizontalLayout_2.addWidget(self.sizeThresholdEdit)
|
self.horizontalLayout_2.addWidget(self.sizeThresholdEdit)
|
||||||
self.label_6 = QLabel(self.widget)
|
self.label_6 = QLabel(self.widget)
|
||||||
self.label_6.setText("KB")
|
self.label_6.setText(tr("KB"))
|
||||||
self.horizontalLayout_2.addWidget(self.label_6)
|
self.horizontalLayout_2.addWidget(self.label_6)
|
||||||
spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
||||||
self.horizontalLayout_2.addItem(spacerItem1)
|
self.horizontalLayout_2.addItem(spacerItem1)
|
||||||
self.verticalLayout_4.addLayout(self.horizontalLayout_2)
|
self.verticalLayout_4.addLayout(self.horizontalLayout_2)
|
||||||
self.ignoreHardlinkMatches = QCheckBox(self.widget)
|
self._setupAddCheckbox('ignoreHardlinkMatches', tr("Ignore duplicates hardlinking to the same file"), self.widget)
|
||||||
self.ignoreHardlinkMatches.setText("Ignore duplicates hardlinking to the same file")
|
|
||||||
self.verticalLayout_4.addWidget(self.ignoreHardlinkMatches)
|
self.verticalLayout_4.addWidget(self.ignoreHardlinkMatches)
|
||||||
self.verticalLayout.addWidget(self.widget)
|
self.widgetsVLayout.addWidget(self.widget)
|
||||||
self.horizontalLayout_4 = QHBoxLayout()
|
self._setupBottomPart()
|
||||||
self.label_5 = QLabel(self)
|
|
||||||
self.label_5.setText("Copy and Move:")
|
def _setupUi(self):
|
||||||
self.label_5.setMinimumSize(QSize(100, 0))
|
PreferencesDialogBase._setupUi(self)
|
||||||
self.label_5.setMaximumSize(QSize(100, 16777215))
|
|
||||||
self.horizontalLayout_4.addWidget(self.label_5)
|
|
||||||
self.copyMoveDestinationComboBox = QComboBox(self)
|
|
||||||
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(self.copyMoveDestinationComboBox.sizePolicy().hasHeightForWidth())
|
|
||||||
self.copyMoveDestinationComboBox.setSizePolicy(sizePolicy)
|
|
||||||
self.copyMoveDestinationComboBox.addItem("Right in destination")
|
|
||||||
self.copyMoveDestinationComboBox.addItem("Recreate relative path")
|
|
||||||
self.copyMoveDestinationComboBox.addItem("Recreate absolute path")
|
|
||||||
self.horizontalLayout_4.addWidget(self.copyMoveDestinationComboBox)
|
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout_4)
|
|
||||||
self.label_7 = QLabel(self)
|
|
||||||
self.label_7.setText("Custom Command (arguments: %d for dupe, %r for ref):")
|
|
||||||
self.verticalLayout.addWidget(self.label_7)
|
|
||||||
self.customCommandEdit = QLineEdit(self)
|
|
||||||
self.verticalLayout.addWidget(self.customCommandEdit)
|
|
||||||
self.verticalLayout_2.addLayout(self.verticalLayout)
|
|
||||||
self.buttonBox = QDialogButtonBox(self)
|
|
||||||
self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok|QDialogButtonBox.RestoreDefaults)
|
|
||||||
self.verticalLayout_2.addWidget(self.buttonBox)
|
|
||||||
|
|
||||||
if sys.platform not in {'darwin', 'linux2'}:
|
|
||||||
self.verticalLayout_4.removeWidget(self.ignoreHardlinkMatches)
|
|
||||||
self.ignoreHardlinkMatches.setHidden(True)
|
|
||||||
if sys.platform == 'linux2':
|
if sys.platform == 'linux2':
|
||||||
# Under linux, whether it's a Qt layout bug or something else, the size threshold text edit
|
# Under linux, whether it's a Qt layout bug or something else, the size threshold text edit
|
||||||
# doesn't have enough space, so we make the pref pane higher to compensate.
|
# doesn't have enough space, so we make the pref pane higher to compensate.
|
||||||
self.resize(self.width(), 400)
|
self.resize(self.width(), 400)
|
||||||
|
|
||||||
def load(self, prefs=None):
|
def _load(self, prefs, setchecked):
|
||||||
if prefs is None:
|
|
||||||
prefs = self.app.prefs
|
|
||||||
self.filterHardnessSlider.setValue(prefs.filter_hardness)
|
|
||||||
self.filterHardnessLabel.setNum(prefs.filter_hardness)
|
|
||||||
scan_type_index = SCAN_TYPE_ORDER.index(prefs.scan_type)
|
scan_type_index = SCAN_TYPE_ORDER.index(prefs.scan_type)
|
||||||
self.scanTypeComboBox.setCurrentIndex(scan_type_index)
|
self.scanTypeComboBox.setCurrentIndex(scan_type_index)
|
||||||
setchecked = lambda cb, b: cb.setCheckState(Qt.Checked if b else Qt.Unchecked)
|
|
||||||
setchecked(self.matchSimilarBox, prefs.match_similar)
|
setchecked(self.matchSimilarBox, prefs.match_similar)
|
||||||
setchecked(self.wordWeightingBox, prefs.word_weighting)
|
setchecked(self.wordWeightingBox, prefs.word_weighting)
|
||||||
setchecked(self.mixFileKindBox, prefs.mix_file_kind)
|
|
||||||
setchecked(self.ignoreHardlinkMatches, prefs.ignore_hardlink_matches)
|
|
||||||
setchecked(self.useRegexpBox, prefs.use_regexp)
|
|
||||||
setchecked(self.removeEmptyFoldersBox, prefs.remove_empty_folders)
|
|
||||||
setchecked(self.ignoreSmallFilesBox, prefs.ignore_small_files)
|
setchecked(self.ignoreSmallFilesBox, prefs.ignore_small_files)
|
||||||
self.sizeThresholdEdit.setText(str(prefs.small_file_threshold))
|
self.sizeThresholdEdit.setText(str(prefs.small_file_threshold))
|
||||||
self.copyMoveDestinationComboBox.setCurrentIndex(prefs.destination_type)
|
|
||||||
self.customCommandEdit.setText(prefs.custom_command)
|
|
||||||
|
|
||||||
def save(self):
|
def _save(self, prefs, ischecked):
|
||||||
prefs = self.app.prefs
|
|
||||||
prefs.filter_hardness = self.filterHardnessSlider.value()
|
|
||||||
prefs.scan_type = SCAN_TYPE_ORDER[self.scanTypeComboBox.currentIndex()]
|
prefs.scan_type = SCAN_TYPE_ORDER[self.scanTypeComboBox.currentIndex()]
|
||||||
ischecked = lambda cb: cb.checkState() == Qt.Checked
|
|
||||||
prefs.match_similar = ischecked(self.matchSimilarBox)
|
prefs.match_similar = ischecked(self.matchSimilarBox)
|
||||||
prefs.word_weighting = ischecked(self.wordWeightingBox)
|
prefs.word_weighting = ischecked(self.wordWeightingBox)
|
||||||
prefs.mix_file_kind = ischecked(self.mixFileKindBox)
|
|
||||||
prefs.ignore_hardlink_matches = ischecked(self.ignoreHardlinkMatches)
|
|
||||||
prefs.use_regexp = ischecked(self.useRegexpBox)
|
|
||||||
prefs.remove_empty_folders = ischecked(self.removeEmptyFoldersBox)
|
|
||||||
prefs.ignore_small_files = ischecked(self.ignoreSmallFilesBox)
|
prefs.ignore_small_files = ischecked(self.ignoreSmallFilesBox)
|
||||||
prefs.small_file_threshold = tryint(self.sizeThresholdEdit.text())
|
prefs.small_file_threshold = tryint(self.sizeThresholdEdit.text())
|
||||||
prefs.destination_type = self.copyMoveDestinationComboBox.currentIndex()
|
|
||||||
prefs.custom_command = str(self.customCommandEdit.text())
|
|
||||||
|
|
||||||
def resetToDefaults(self):
|
def resetToDefaults(self):
|
||||||
self.load(preferences.Preferences())
|
self.load(preferences.Preferences())
|
||||||
|
|
||||||
#--- Events
|
#--- Events
|
||||||
def buttonClicked(self, button):
|
|
||||||
role = self.buttonBox.buttonRole(button)
|
|
||||||
if role == QDialogButtonBox.ResetRole:
|
|
||||||
self.resetToDefaults()
|
|
||||||
|
|
||||||
def scanTypeChanged(self, index):
|
def scanTypeChanged(self, index):
|
||||||
scan_type = SCAN_TYPE_ORDER[self.scanTypeComboBox.currentIndex()]
|
scan_type = SCAN_TYPE_ORDER[self.scanTypeComboBox.currentIndex()]
|
||||||
word_based = scan_type == ScanType.Filename
|
word_based = scan_type == ScanType.Filename
|
||||||
|
@ -15,12 +15,16 @@ from PyQt4.QtGui import QApplication, QIcon, QPixmap
|
|||||||
from hscommon.trans import install_qt_trans
|
from hscommon.trans import install_qt_trans
|
||||||
from qtlib.error_report_dialog import install_excepthook
|
from qtlib.error_report_dialog import install_excepthook
|
||||||
from qt.base import dg_rc
|
from qt.base import dg_rc
|
||||||
|
from core_{{edition}} import __version__, __appname__
|
||||||
|
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
import qt.base.cxfreeze_fix
|
import qt.base.cxfreeze_fix
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
|
QCoreApplication.setOrganizationName('Hardcoded Software')
|
||||||
|
QCoreApplication.setApplicationName(__appname__)
|
||||||
|
QCoreApplication.setApplicationVersion(__version__)
|
||||||
settings = QSettings()
|
settings = QSettings()
|
||||||
lang = settings.value('Language').toString()
|
lang = settings.value('Language').toString()
|
||||||
install_qt_trans(lang)
|
install_qt_trans(lang)
|
||||||
@ -28,9 +32,6 @@ if __name__ == "__main__":
|
|||||||
# has been installed
|
# has been installed
|
||||||
from qt.{{edition}}.app import DupeGuru
|
from qt.{{edition}}.app import DupeGuru
|
||||||
app.setWindowIcon(QIcon(QPixmap(":/{0}".format(DupeGuru.LOGO_NAME))))
|
app.setWindowIcon(QIcon(QPixmap(":/{0}".format(DupeGuru.LOGO_NAME))))
|
||||||
QCoreApplication.setOrganizationName('Hardcoded Software')
|
|
||||||
QCoreApplication.setApplicationName(DupeGuru.NAME)
|
|
||||||
QCoreApplication.setApplicationVersion(DupeGuru.VERSION)
|
|
||||||
dgapp = DupeGuru()
|
dgapp = DupeGuru()
|
||||||
install_excepthook()
|
install_excepthook()
|
||||||
sys.exit(app.exec_())
|
sys.exit(app.exec_())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user