mirror of
https://github.com/arsenetar/dupeguru.git
synced 2024-11-16 12:19:03 +00:00
838f8ae352
--HG-- rename : base/cocoa/AppDelegate.h => cocoa/base/AppDelegate.h rename : base/cocoa/AppDelegate.m => cocoa/base/AppDelegate.m rename : base/cocoa/Consts.h => cocoa/base/Consts.h rename : base/cocoa/DetailsPanel.h => cocoa/base/DetailsPanel.h rename : base/cocoa/DetailsPanel.m => cocoa/base/DetailsPanel.m rename : base/cocoa/DirectoryPanel.h => cocoa/base/DirectoryPanel.h rename : base/cocoa/DirectoryPanel.m => cocoa/base/DirectoryPanel.m rename : base/cocoa/PyDupeGuru.h => cocoa/base/PyDupeGuru.h rename : base/cocoa/ResultWindow.h => cocoa/base/ResultWindow.h rename : base/cocoa/ResultWindow.m => cocoa/base/ResultWindow.m rename : base/cocoa/dsa_pub.pem => cocoa/base/dsa_pub.pem rename : base/cocoa/xib/DetailsPanel.xib => cocoa/base/xib/DetailsPanel.xib rename : base/cocoa/xib/DirectoryPanel.xib => cocoa/base/xib/DirectoryPanel.xib rename : base/cocoa/xib/MainMenu.xib => cocoa/base/xib/MainMenu.xib rename : me/cocoa/AppDelegate.h => cocoa/me/AppDelegate.h rename : me/cocoa/AppDelegate.m => cocoa/me/AppDelegate.m rename : me/cocoa/Consts.h => cocoa/me/Consts.h rename : me/cocoa/DetailsPanel.h => cocoa/me/DetailsPanel.h rename : me/cocoa/DetailsPanel.m => cocoa/me/DetailsPanel.m rename : me/cocoa/DirectoryPanel.h => cocoa/me/DirectoryPanel.h rename : me/cocoa/DirectoryPanel.m => cocoa/me/DirectoryPanel.m rename : me/cocoa/Info.plist => cocoa/me/Info.plist rename : me/cocoa/PyDupeGuru.h => cocoa/me/PyDupeGuru.h rename : me/cocoa/ResultWindow.h => cocoa/me/ResultWindow.h rename : me/cocoa/ResultWindow.m => cocoa/me/ResultWindow.m rename : me/cocoa/dupeguru.icns => cocoa/me/dupeguru.icns rename : me/cocoa/dupeguru.xcodeproj/project.pbxproj => cocoa/me/dupeguru.xcodeproj/project.pbxproj rename : me/cocoa/gen.py => cocoa/me/gen.py rename : me/cocoa/main.m => cocoa/me/main.m rename : me/cocoa/py/dg_cocoa.py => cocoa/me/py/dg_cocoa.py rename : me/cocoa/py/setup.py => cocoa/me/py/setup.py rename : me/cocoa/xib/Preferences.xib => cocoa/me/xib/Preferences.xib rename : pe/cocoa/AppDelegate.h => cocoa/pe/AppDelegate.h rename : pe/cocoa/AppDelegate.m => cocoa/pe/AppDelegate.m rename : pe/cocoa/Consts.h => cocoa/pe/Consts.h rename : pe/cocoa/DetailsPanel.h => cocoa/pe/DetailsPanel.h rename : pe/cocoa/DetailsPanel.m => cocoa/pe/DetailsPanel.m rename : pe/cocoa/DirectoryPanel.h => cocoa/pe/DirectoryPanel.h rename : pe/cocoa/DirectoryPanel.m => cocoa/pe/DirectoryPanel.m rename : pe/cocoa/Info.plist => cocoa/pe/Info.plist rename : pe/cocoa/PictureBlocks.h => cocoa/pe/PictureBlocks.h rename : pe/cocoa/PictureBlocks.m => cocoa/pe/PictureBlocks.m rename : pe/cocoa/PyDupeGuru.h => cocoa/pe/PyDupeGuru.h rename : pe/cocoa/ResultWindow.h => cocoa/pe/ResultWindow.h rename : pe/cocoa/ResultWindow.m => cocoa/pe/ResultWindow.m rename : pe/cocoa/dupeguru.icns => cocoa/pe/dupeguru.icns rename : pe/cocoa/dupeguru.xcodeproj/project.pbxproj => cocoa/pe/dupeguru.xcodeproj/project.pbxproj rename : pe/cocoa/gen.py => cocoa/pe/gen.py rename : pe/cocoa/main.m => cocoa/pe/main.m rename : pe/cocoa/py/dg_cocoa.py => cocoa/pe/py/dg_cocoa.py rename : pe/cocoa/py/setup.py => cocoa/pe/py/setup.py rename : pe/cocoa/xib/DetailsPanel.xib => cocoa/pe/xib/DetailsPanel.xib rename : pe/cocoa/xib/Preferences.xib => cocoa/pe/xib/Preferences.xib rename : se/cocoa/AppDelegate.h => cocoa/se/AppDelegate.h rename : se/cocoa/AppDelegate.m => cocoa/se/AppDelegate.m rename : se/cocoa/Consts.h => cocoa/se/Consts.h rename : se/cocoa/DetailsPanel.h => cocoa/se/DetailsPanel.h rename : se/cocoa/DetailsPanel.m => cocoa/se/DetailsPanel.m rename : se/cocoa/DirectoryPanel.h => cocoa/se/DirectoryPanel.h rename : se/cocoa/DirectoryPanel.m => cocoa/se/DirectoryPanel.m rename : se/cocoa/Info.plist => cocoa/se/Info.plist rename : se/cocoa/PyDupeGuru.h => cocoa/se/PyDupeGuru.h rename : se/cocoa/ResultWindow.h => cocoa/se/ResultWindow.h rename : se/cocoa/ResultWindow.m => cocoa/se/ResultWindow.m rename : se/cocoa/dupeguru.icns => cocoa/se/dupeguru.icns rename : se/cocoa/dupeguru.xcodeproj/project.pbxproj => cocoa/se/dupeguru.xcodeproj/project.pbxproj rename : se/cocoa/gen.py => cocoa/se/gen.py rename : se/cocoa/main.m => cocoa/se/main.m rename : se/cocoa/py/dg_cocoa.py => cocoa/se/py/dg_cocoa.py rename : se/cocoa/py/setup.py => cocoa/se/py/setup.py rename : se/cocoa/xib/Preferences.xib => cocoa/se/xib/Preferences.xib rename : base/core/LICENSE => core/LICENSE rename : base/core/__init__.py => core/__init__.py rename : base/core/app.py => core/app.py rename : base/core/app_cocoa.py => core/app_cocoa.py rename : base/core/data.py => core/data.py rename : base/core/directories.py => core/directories.py rename : base/core/engine.py => core/engine.py rename : base/core/export.py => core/export.py rename : base/core/fs.py => core/fs.py rename : base/core/ignore.py => core/ignore.py rename : base/core/results.py => core/results.py rename : base/core/scanner.py => core/scanner.py rename : base/core/tests/__init__.py => core/tests/__init__.py rename : base/core/tests/app_cocoa_test.py => core/tests/app_cocoa_test.py rename : base/core/tests/app_test.py => core/tests/app_test.py rename : base/core/tests/data.py => core/tests/data.py rename : base/core/tests/directories_test.py => core/tests/directories_test.py rename : base/core/tests/engine_test.py => core/tests/engine_test.py rename : base/core/tests/ignore_test.py => core/tests/ignore_test.py rename : base/core/tests/results_test.py => core/tests/results_test.py rename : base/core/tests/scanner_test.py => core/tests/scanner_test.py rename : me/core/__init__.py => core_me/__init__.py rename : me/core/app_cocoa.py => core_me/app_cocoa.py rename : me/core/data.py => core_me/data.py rename : me/core/fs.py => core_me/fs.py rename : me/core/scanner.py => core_me/scanner.py rename : me/core/tests/__init__.py => core_me/tests/__init__.py rename : me/core/tests/scanner_test.py => core_me/tests/scanner_test.py rename : pe/core/LICENSE => core_pe/LICENSE rename : pe/core/__init__.py => core_pe/__init__.py rename : pe/core/app_cocoa.py => core_pe/app_cocoa.py rename : pe/core/block.py => core_pe/block.py rename : pe/core/cache.py => core_pe/cache.py rename : pe/core/data.py => core_pe/data.py rename : pe/core/gen.py => core_pe/gen.py rename : pe/core/matchbase.py => core_pe/matchbase.py rename : pe/core/modules/block/block.pyx => core_pe/modules/block/block.pyx rename : pe/core/modules/block/setup.py => core_pe/modules/block/setup.py rename : pe/core/modules/cache/cache.pyx => core_pe/modules/cache/cache.pyx rename : pe/core/modules/cache/setup.py => core_pe/modules/cache/setup.py rename : pe/core/scanner.py => core_pe/scanner.py rename : pe/core/tests/__init__.py => core_pe/tests/__init__.py rename : pe/core/tests/block_test.py => core_pe/tests/block_test.py rename : pe/core/tests/cache_test.py => core_pe/tests/cache_test.py rename : se/core/LICENSE => core_se/LICENSE rename : se/core/__init__.py => core_se/__init__.py rename : se/core/app_cocoa.py => core_se/app_cocoa.py rename : se/core/data.py => core_se/data.py rename : se/core/fs.py => core_se/fs.py rename : se/core/tests/__init__.py => core_se/tests/__init__.py rename : se/core/tests/fs_test.py => core_se/tests/fs_test.py rename : me/help/LICENSE => help_me/LICENSE rename : me/help/__init__.py => help_me/__init__.py rename : me/help/changelog.yaml => help_me/changelog.yaml rename : me/help/gen.py => help_me/gen.py rename : me/help/skeleton/hardcoded.css => help_me/skeleton/hardcoded.css rename : me/help/skeleton/images/hs_title.png => help_me/skeleton/images/hs_title.png rename : me/help/templates/base_dg.mako => help_me/templates/base_dg.mako rename : me/help/templates/credits.mako => help_me/templates/credits.mako rename : me/help/templates/directories.mako => help_me/templates/directories.mako rename : me/help/templates/faq.mako => help_me/templates/faq.mako rename : me/help/templates/intro.mako => help_me/templates/intro.mako rename : me/help/templates/power_marker.mako => help_me/templates/power_marker.mako rename : me/help/templates/preferences.mako => help_me/templates/preferences.mako rename : me/help/templates/quick_start.mako => help_me/templates/quick_start.mako rename : me/help/templates/results.mako => help_me/templates/results.mako rename : me/help/templates/versions.mako => help_me/templates/versions.mako rename : pe/help/LICENSE => help_pe/LICENSE rename : pe/help/__init__.py => help_pe/__init__.py rename : pe/help/changelog.yaml => help_pe/changelog.yaml rename : pe/help/gen.py => help_pe/gen.py rename : pe/help/skeleton/hardcoded.css => help_pe/skeleton/hardcoded.css rename : pe/help/skeleton/images/hs_title.png => help_pe/skeleton/images/hs_title.png rename : pe/help/templates/base_dg.mako => help_pe/templates/base_dg.mako rename : pe/help/templates/credits.mako => help_pe/templates/credits.mako rename : pe/help/templates/directories.mako => help_pe/templates/directories.mako rename : pe/help/templates/faq.mako => help_pe/templates/faq.mako rename : pe/help/templates/intro.mako => help_pe/templates/intro.mako rename : pe/help/templates/power_marker.mako => help_pe/templates/power_marker.mako rename : pe/help/templates/preferences.mako => help_pe/templates/preferences.mako rename : pe/help/templates/quick_start.mako => help_pe/templates/quick_start.mako rename : pe/help/templates/results.mako => help_pe/templates/results.mako rename : pe/help/templates/versions.mako => help_pe/templates/versions.mako rename : se/help/LICENSE => help_se/LICENSE rename : se/help/changelog.yaml => help_se/changelog.yaml rename : se/help/gen.py => help_se/gen.py rename : se/help/skeleton/hardcoded.css => help_se/skeleton/hardcoded.css rename : se/help/skeleton/images/hs_title.png => help_se/skeleton/images/hs_title.png rename : se/help/templates/base_dg.mako => help_se/templates/base_dg.mako rename : se/help/templates/credits.mako => help_se/templates/credits.mako rename : se/help/templates/directories.mako => help_se/templates/directories.mako rename : se/help/templates/faq.mako => help_se/templates/faq.mako rename : se/help/templates/intro.mako => help_se/templates/intro.mako rename : se/help/templates/power_marker.mako => help_se/templates/power_marker.mako rename : se/help/templates/preferences.mako => help_se/templates/preferences.mako rename : se/help/templates/quick_start.mako => help_se/templates/quick_start.mako rename : se/help/templates/results.mako => help_se/templates/results.mako rename : se/help/templates/versions.mako => help_se/templates/versions.mako rename : base/qt/WARNING => qt/WARNING rename : base/qt/__init__.py => qt/base/__init__.py rename : base/qt/app.py => qt/base/app.py rename : base/qt/details_table.py => qt/base/details_table.py rename : base/qt/dg.qrc => qt/base/dg.qrc rename : base/qt/directories_dialog.py => qt/base/directories_dialog.py rename : base/qt/directories_dialog.ui => qt/base/directories_dialog.ui rename : base/qt/directories_model.py => qt/base/directories_model.py rename : base/qt/main_window.py => qt/base/main_window.py rename : base/qt/main_window.ui => qt/base/main_window.ui rename : base/qt/platform.py => qt/base/platform.py rename : base/qt/platform_osx.py => qt/base/platform_osx.py rename : base/qt/platform_win.py => qt/base/platform_win.py rename : base/qt/preferences.py => qt/base/preferences.py rename : base/qt/results_model.py => qt/base/results_model.py rename : me/qt/app.py => qt/me/app.py rename : me/qt/build.py => qt/me/build.py rename : me/qt/details_dialog.py => qt/me/details_dialog.py rename : me/qt/details_dialog.ui => qt/me/details_dialog.ui rename : me/qt/dgme.spec => qt/me/dgme.spec rename : me/qt/gen.py => qt/me/gen.py rename : me/qt/installer.aip => qt/me/installer.aip rename : me/qt/preferences.py => qt/me/preferences.py rename : me/qt/preferences_dialog.py => qt/me/preferences_dialog.py rename : me/qt/preferences_dialog.ui => qt/me/preferences_dialog.ui rename : me/qt/profile.py => qt/me/profile.py rename : me/qt/start.py => qt/me/start.py rename : me/qt/verinfo => qt/me/verinfo rename : pe/qt/app.py => qt/pe/app.py rename : pe/qt/block.py => qt/pe/block.py rename : pe/qt/build.py => qt/pe/build.py rename : pe/qt/details_dialog.py => qt/pe/details_dialog.py rename : pe/qt/details_dialog.ui => qt/pe/details_dialog.ui rename : pe/qt/dgpe.spec => qt/pe/dgpe.spec rename : pe/qt/gen.py => qt/pe/gen.py rename : pe/qt/installer.aip => qt/pe/installer.aip rename : pe/qt/main_window.py => qt/pe/main_window.py rename : pe/qt/modules/block/block.pyx => qt/pe/modules/block/block.pyx rename : pe/qt/modules/block/setup.py => qt/pe/modules/block/setup.py rename : pe/qt/preferences.py => qt/pe/preferences.py rename : pe/qt/preferences_dialog.py => qt/pe/preferences_dialog.py rename : pe/qt/preferences_dialog.ui => qt/pe/preferences_dialog.ui rename : pe/qt/profile.py => qt/pe/profile.py rename : pe/qt/start.py => qt/pe/start.py rename : pe/qt/verinfo => qt/pe/verinfo rename : se/qt/app.py => qt/se/app.py rename : se/qt/build.py => qt/se/build.py rename : se/qt/details_dialog.py => qt/se/details_dialog.py rename : se/qt/details_dialog.ui => qt/se/details_dialog.ui rename : se/qt/dgse.spec => qt/se/dgse.spec rename : se/qt/gen.py => qt/se/gen.py rename : se/qt/installer.aip => qt/se/installer.aip rename : se/qt/preferences.py => qt/se/preferences.py rename : se/qt/preferences_dialog.py => qt/se/preferences_dialog.py rename : se/qt/preferences_dialog.ui => qt/se/preferences_dialog.ui rename : se/qt/profile.py => qt/se/profile.py rename : se/qt/start.py => qt/se/start.py rename : se/qt/verinfo => qt/se/verinfo extra : convert_revision : svn%3Ac306627e-7827-47d3-bdf0-9a457c9553a1/trunk%40285
258 lines
9.3 KiB
Python
258 lines
9.3 KiB
Python
# Created By: Virgil Dupras
|
|
# Created On: 2009-04-25
|
|
# $Id$
|
|
# Copyright 2009 Hardcoded Software (http://www.hardcoded.net)
|
|
#
|
|
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
|
# which should be included with this package. The terms are also available at
|
|
# http://www.hardcoded.net/licenses/hs_license
|
|
|
|
from __future__ import unicode_literals
|
|
|
|
import logging
|
|
import os
|
|
import os.path as op
|
|
|
|
from PyQt4.QtCore import Qt, QTimer, QObject, QCoreApplication, QUrl, SIGNAL
|
|
from PyQt4.QtGui import QProgressDialog, QDesktopServices, QFileDialog, QDialog, QMessageBox
|
|
|
|
from hsutil import job
|
|
from hsutil.reg import RegistrationRequired
|
|
|
|
from core import fs
|
|
from core.app import DupeGuru as DupeGuruBase, JOB_SCAN, JOB_LOAD, JOB_MOVE, JOB_COPY, JOB_DELETE
|
|
|
|
from qtlib.about_box import AboutBox
|
|
from qtlib.progress import Progress
|
|
from qtlib.reg import Registration
|
|
|
|
from . import platform
|
|
|
|
from .main_window import MainWindow
|
|
from .directories_dialog import DirectoriesDialog
|
|
|
|
JOBID2TITLE = {
|
|
JOB_SCAN: "Scanning for duplicates",
|
|
JOB_LOAD: "Loading",
|
|
JOB_MOVE: "Moving",
|
|
JOB_COPY: "Copying",
|
|
JOB_DELETE: "Sending files to the recycle bin",
|
|
}
|
|
|
|
def demo_method(method):
|
|
def wrapper(self, *args, **kwargs):
|
|
try:
|
|
return method(self, *args, **kwargs)
|
|
except RegistrationRequired:
|
|
msg = "The demo version of dupeGuru only allows 10 actions (delete/move/copy) per session."
|
|
QMessageBox.information(self.main_window, 'Demo', msg)
|
|
|
|
return wrapper
|
|
|
|
class DupeGuru(DupeGuruBase, QObject):
|
|
LOGO_NAME = '<replace this>'
|
|
NAME = '<replace this>'
|
|
DELTA_COLUMNS = frozenset()
|
|
DEMO_LIMIT_DESC = "In the demo version, only 10 duplicates per session can be sent to the recycle bin, moved or copied."
|
|
|
|
def __init__(self, data_module, appid):
|
|
appdata = unicode(QDesktopServices.storageLocation(QDesktopServices.DataLocation))
|
|
if not op.exists(appdata):
|
|
os.makedirs(appdata)
|
|
# For basicConfig() to work, we have to be sure that no logging has taken place before this call.
|
|
logging.basicConfig(filename=op.join(appdata, 'debug.log'), level=logging.WARNING)
|
|
DupeGuruBase.__init__(self, data_module, appdata, appid)
|
|
QObject.__init__(self)
|
|
self._setup()
|
|
|
|
#--- Private
|
|
def _setup(self):
|
|
self.selected_dupe = None
|
|
self.prefs = self._create_preferences()
|
|
self.prefs.load()
|
|
self._update_options()
|
|
self.main_window = self._create_main_window()
|
|
self._progress = Progress(self.main_window)
|
|
self.directories_dialog = DirectoriesDialog(self.main_window, self)
|
|
self.details_dialog = self._create_details_dialog(self.main_window)
|
|
self.preferences_dialog = self._create_preferences_dialog(self.main_window)
|
|
self.about_box = AboutBox(self.main_window, self)
|
|
|
|
self.reg = Registration(self)
|
|
self.set_registration(self.prefs.registration_code, self.prefs.registration_email)
|
|
if not self.registered:
|
|
# The timer scheme is because if the nag is not shown before the application is
|
|
# completely initialized, the nag will be shown before the app shows up in the task bar
|
|
# In some circumstances, the nag is hidden by other window, which may make the user think
|
|
# that the application haven't launched.
|
|
self._nagTimer = QTimer()
|
|
self.connect(self._nagTimer, SIGNAL('timeout()'), self.mustShowNag)
|
|
self._nagTimer.start(0)
|
|
self.main_window.show()
|
|
self.load()
|
|
|
|
self.connect(QCoreApplication.instance(), SIGNAL('aboutToQuit()'), self.application_will_terminate)
|
|
self.connect(self._progress, SIGNAL('finished(QString)'), self.job_finished)
|
|
|
|
def _setup_as_registered(self):
|
|
self.prefs.registration_code = self.registration_code
|
|
self.prefs.registration_email = self.registration_email
|
|
self.main_window.actionRegister.setVisible(False)
|
|
self.about_box.registerButton.hide()
|
|
self.about_box.registeredEmailLabel.setText(self.prefs.registration_email)
|
|
|
|
def _update_options(self):
|
|
self.scanner.mix_file_kind = self.prefs.mix_file_kind
|
|
self.options['escape_filter_regexp'] = self.prefs.use_regexp
|
|
self.options['clean_empty_dirs'] = self.prefs.remove_empty_folders
|
|
|
|
#--- Virtual
|
|
def _create_details_dialog(self, parent):
|
|
raise NotImplementedError()
|
|
|
|
def _create_main_window(self):
|
|
return MainWindow(app=self)
|
|
|
|
def _create_preferences(self):
|
|
raise NotImplementedError()
|
|
|
|
def _create_preferences_dialog(self, parent):
|
|
raise NotImplementedError()
|
|
|
|
#--- Override
|
|
@staticmethod
|
|
def _recycle_dupe(dupe):
|
|
platform.recycle_file(dupe.path)
|
|
|
|
def _start_job(self, jobid, func):
|
|
title = JOBID2TITLE[jobid]
|
|
try:
|
|
j = self._progress.create_job()
|
|
self._progress.run(jobid, title, func, args=(j, ))
|
|
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."
|
|
QMessageBox.information(self.main_window, 'Action in progress', msg)
|
|
|
|
#--- Public
|
|
def add_dupes_to_ignore_list(self, duplicates):
|
|
for dupe in duplicates:
|
|
self.add_to_ignore_list(dupe)
|
|
self.remove_duplicates(duplicates)
|
|
|
|
def apply_filter(self, filter):
|
|
DupeGuruBase.apply_filter(self, filter)
|
|
self.emit(SIGNAL('resultsChanged()'))
|
|
|
|
def askForRegCode(self):
|
|
self.reg.ask_for_code()
|
|
|
|
@demo_method
|
|
def copy_or_move_marked(self, copy):
|
|
opname = 'copy' if copy else 'move'
|
|
title = "Select a directory to {0} marked files to".format(opname)
|
|
flags = QFileDialog.ShowDirsOnly
|
|
destination = unicode(QFileDialog.getExistingDirectory(self.main_window, title, '', flags))
|
|
if not destination:
|
|
return
|
|
recreate_path = self.prefs.destination_type
|
|
DupeGuruBase.copy_or_move_marked(self, copy, destination, recreate_path)
|
|
|
|
delete_marked = demo_method(DupeGuruBase.delete_marked)
|
|
|
|
def make_reference(self, duplicates):
|
|
DupeGuruBase.make_reference(self, duplicates)
|
|
self.emit(SIGNAL('resultsChanged()'))
|
|
|
|
def mark_all(self):
|
|
self.results.mark_all()
|
|
self.emit(SIGNAL('dupeMarkingChanged()'))
|
|
|
|
def mark_invert(self):
|
|
self.results.mark_invert()
|
|
self.emit(SIGNAL('dupeMarkingChanged()'))
|
|
|
|
def mark_none(self):
|
|
self.results.mark_none()
|
|
self.emit(SIGNAL('dupeMarkingChanged()'))
|
|
|
|
def openDebugLog(self):
|
|
debugLogPath = op.join(self.appdata, 'debug.log')
|
|
url = QUrl.fromLocalFile(debugLogPath)
|
|
QDesktopServices.openUrl(url)
|
|
|
|
def open_selected(self):
|
|
if self.selected_dupe is None:
|
|
return
|
|
url = QUrl.fromLocalFile(unicode(self.selected_dupe.path))
|
|
QDesktopServices.openUrl(url)
|
|
|
|
def remove_duplicates(self, duplicates):
|
|
self.results.remove_duplicates(duplicates)
|
|
self.emit(SIGNAL('resultsChanged()'))
|
|
|
|
def remove_marked_duplicates(self):
|
|
marked = [d for d in self.results.dupes if self.results.is_marked(d)]
|
|
self.remove_duplicates(marked)
|
|
|
|
def rename_dupe(self, dupe, newname):
|
|
try:
|
|
dupe.rename(newname)
|
|
return True
|
|
except (IndexError, fs.FSError) as e:
|
|
logging.warning("dupeGuru Warning: %s" % unicode(e))
|
|
return False
|
|
|
|
def reveal_selected(self):
|
|
if self.selected_dupe is None:
|
|
return
|
|
url = QUrl.fromLocalFile(unicode(self.selected_dupe.path[:-1]))
|
|
QDesktopServices.openUrl(url)
|
|
|
|
def select_duplicate(self, dupe):
|
|
self.selected_dupe = dupe
|
|
self.emit(SIGNAL('duplicateSelected()'))
|
|
|
|
def show_about_box(self):
|
|
self.about_box.show()
|
|
|
|
def show_details(self):
|
|
self.details_dialog.show()
|
|
|
|
def show_directories(self):
|
|
self.directories_dialog.show()
|
|
|
|
def show_help(self):
|
|
url = QUrl.fromLocalFile(op.abspath('help/intro.htm'))
|
|
QDesktopServices.openUrl(url)
|
|
|
|
def show_preferences(self):
|
|
self.preferences_dialog.load()
|
|
result = self.preferences_dialog.exec_()
|
|
if result == QDialog.Accepted:
|
|
self.preferences_dialog.save()
|
|
self.prefs.save()
|
|
self._update_options()
|
|
|
|
def toggle_marking_for_dupes(self, dupes):
|
|
for dupe in dupes:
|
|
self.results.mark_toggle(dupe)
|
|
self.emit(SIGNAL('dupeMarkingChanged()'))
|
|
|
|
#--- Events
|
|
def application_will_terminate(self):
|
|
self.save()
|
|
self.save_ignore_list()
|
|
|
|
def mustShowNag(self):
|
|
self._nagTimer.stop() # must be shown only once
|
|
self.reg.show_nag()
|
|
|
|
def job_finished(self, jobid):
|
|
self.emit(SIGNAL('resultsChanged()'))
|
|
if jobid == JOB_LOAD:
|
|
self.emit(SIGNAL('directoriesChanged()'))
|
|
if jobid in (JOB_MOVE, JOB_COPY, JOB_DELETE) and self.last_op_error_count > 0:
|
|
msg = "{0} files could not be processed.".format(self.results.mark_count)
|
|
QMessageBox.warning(self.main_window, 'Warning', msg)
|
|
|