Compare commits

...

17 커밋

작성자 SHA1 메시지 날짜
Andrew Senetar 6a03e1e399
Update URLs 2021-01-05 23:21:44 -06:00
Andrew Senetar ae51842007
Update README.md 2021-01-05 23:04:42 -06:00
Andrew Senetar ab6acd9e88
Merge pull request #733 from glubsy/dev
Increment version to 4.1.0
2021-01-05 22:48:21 -06:00
glubsy 5553414205 Fix updating QTableView on input
* When clicking on the test regex button or editing the test input field, the tableView doesn't update its data properly.
* Somehow QTableView.update() doesn't request the data from the model.
* The workaround is to call refresh on the model directly, which will in turn update its view.
2020-12-30 23:18:42 +01:00
glubsy b138dfad33 Fix exception when testing invalid regex
* If a regex in the table is invalid and failed to compile, its "compiled" property is None.
* Only test against the regex if its compilation worked.
2020-12-30 22:50:42 +01:00
glubsy 348ce95f83 Remove comment
* There is a bug with pyqt5<=5.14 where the table does not update after a call to update() and needs to receive a mouse click event in order to repaint as expected.
* This does not affect Windows only as this is a Qt5 bug.
* This seems to be fixed with pyqt5>=5.15.1.
2020-12-30 18:44:38 +01:00
glubsy 288023d03e Update changelog 2020-12-29 21:51:16 +01:00
glubsy 7740dfca0e Update Readme 2020-12-29 21:31:36 +01:00
glubsy c1d94d6771 Merge branch 'master' into dev 2020-12-29 20:10:42 +01:00
glubsy 6bc619055e Change version to 4.1.0 2020-12-06 20:13:03 +01:00
glubsy 32d66cd19b Move up to 4.0.5
* Initial push to 4.0.5 milestone
* Update changelog
2020-10-27 19:38:51 +01:00
glubsy 735ba2fd0e Update error dialog traceback message for users
* Incite users to look for already existing issues
* Also invite them to test the very latest version available first
2020-10-27 18:23:14 +01:00
glubsy b16b6ecf4d Fix error after merging branches 2020-10-27 18:15:15 +01:00
glubsy 2875448c71 Merge branch 'save_directories' into dev 2020-10-27 16:23:49 +01:00
glubsy 51b76385c0 Merge branch 'exclude_list' into dev 2020-10-27 16:23:43 +01:00
glubsy b9f8dd6ea0 Merge branch 'PR_ref_row_background_color' into dev 2020-10-27 16:23:35 +01:00
glubsy 6623b04403 Merge branch 'details_dialog_improvements' into dev 2020-10-27 16:23:23 +01:00
9개의 변경된 파일127개의 추가작업 그리고 57개의 파일을 삭제

파일 보기

@ -24,8 +24,8 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. Windows 10 / OSX 10.15 / Ubuntu 20.04]
- Version [e.g. 4.0.4]
- OS: [e.g. Windows 10 / OSX 10.15 / Ubuntu 20.04 / Arch Linux]
- Version [e.g. 4.1.0]
**Additional context**
Add any other context about the problem here. You may include the debug log although it is normally best to attach it as a file.

파일 보기

@ -1,19 +1,21 @@
# dupeGuru
[dupeGuru][dupeguru] is a cross-platform (Linux, OS X, Windows) GUI tool to find duplicate files in
a system. It's written mostly in Python 3 and has the peculiarity of using
a system. It is written mostly in Python 3 and has the peculiarity of using
[multiple GUI toolkits][cross-toolkit], all using the same core Python code. On OS X, the UI layer
is written in Objective-C and uses Cocoa. On Linux, it's written in Python and uses Qt5.
is written in Objective-C and uses Cocoa. On Linux, it is written in Python and uses Qt5.
The Cocoa UI of dupeGuru is hosted in a separate repo: https://github.com/hsoft/dupeguru-cocoa
The Cocoa UI of dupeGuru is hosted in a separate repo: https://github.com/arsenetar/dupeguru-cocoa
## Current status
Development has been slow this past year, however very close to getting all the different 4.0.4 releases posted. Most of the work this past year (2019) has been towards packaging the application and issues related to that.
2020: various bug fixes and small UI improvements have been added. Packaging for MacOS is still a problem.
Still looking for additional help especially with regards to:
- OSX maintenance (reproducing bugs & cocoa version)
- Linux maintenance (reproducing bugs)
* OSX maintenance: reproducing bugs & cocoa version, building package with Cocoa UI.
* Linux maintenance: reproducing bugs, maintaining PPA repository, Debian package.
* Translations: updating missing strings.
* Documentation: keeping it up-to-date.
## Contents of this folder
@ -31,26 +33,44 @@ This folder contains the source for dupeGuru. Its documentation is in `help`, bu
## How to build dupeGuru from source
### Windows
### Windows & macOS specific additional instructions
For windows instructions see the [Windows Instructions](Windows.md).
For macos instructions (qt version) see the [macOS Instructions](macos.md).
### Prerequisites
* [Python 3.5+][python]
* [Python 3.6+][python]
* PyQt5
### make
### Building with Make
dupeGuru comes with a makefile that can be used to build and run:
dupeGuru is built with "make":
$ make && make run
$ make
$ make run
### Building without Make
### Generate Debian/Ubuntu package
$ cd <dupeGuru directory>
$ python3 -m venv --system-site-packages .\env
$ source .\env\bin\activate
$ pip install -r requirements.txt
$ python build.py
$ python run.py
$ bash -c "python3 -m venv --system-site-packages env && source env/bin/activate && pip install -r requirements.txt && python3 build.py --clean && python3 package.py"
### Generating Debian/Ubuntu package
To generate packages the extra requirements in requirements-extra.txt must be installed, the
steps are as follows:
### Running tests
$ cd <dupeGuru directory>
$ python3 -m venv --system-site-packages .\env
$ source .\env\bin\activate
$ pip install -r requirements.txt -r requirements-extra.txt
$ python build.py --clean
$ python package.py
This can be made a one-liner (once in the directory) as:
$ bash -c "python3 -m venv --system-site-packages env && source env/bin/activate && pip install -r requirements.txt -r requirements-extra.txt && python build.py --clean && python package.py"
## Running tests
The complete test suite is run with [Tox 1.7+][tox]. If you have it installed system-wide, you
don't even need to set up a virtualenv. Just `cd` into the root project folder and run `tox`.

파일 보기

@ -1,2 +1,2 @@
__version__ = "4.0.4"
__version__ = "4.1.0"
__appname__ = "dupeGuru"

파일 보기

@ -55,7 +55,8 @@ class ExcludeListDialogCore:
"""Sets property on row to highlight if its regex matches test_string supplied."""
matched = False
for row in self.exclude_list_table.rows:
if self.exclude_list.get_compiled(row.regex).match(test_string):
compiled_regex = self.exclude_list.get_compiled(row.regex)
if compiled_regex and compiled_regex.match(test_string):
matched = True
row.highlight = True
else:

파일 보기

@ -1,3 +1,29 @@
=== 4.1.0 (2020-12-29)
* Use tabs instead of separate windows (#688)
* Show the shortcut for "mark selected" in results dialog (#656, #641)
* Add image comparison features to details dialog (#683)
* Add the ability to use regex based exclusion filters (#705)
* Change reference row background color, and allow user to adjust the color (#701)
* Save / Load directories as XML (#706)
* Workaround for EXIF IFD type mismatch in parsing function (#630, #698)
* Progress dialog stuck at "Verified X/X matches" (#693, #694)
* Fix word wrap in ignore list dialog (#687)
* Fix issue with result window action on creation (#685)
* Colorize details table differences, allow moving rows (#682)
* Fix loading Result of 'Scan Type: Folders' shows only '---' in every table cell (#677, #676)
* Fix issue with details and results dialog row trimming (#655, #654)
* Add option to enable/disable bold font (#646, #314)
* Use relative icon path for themes to override more easily (#746)
* Fix issues with Python 3.8 compatibility (#665)
* Fix flake8 issues (#672)
* Update to use newer pytest and expand flake8 checking, cleanup various Deprecation Warnings
* Add warnings to packaging script when files are not built (#691)
* Use relative icon path for themes to override more easily (#746)
* Update Packaging for Ubuntu (#593)
* Minor Build Updates (#627, #575, #628, #614)
* Update CI builds and add windows CI (#572, #669)
=== 4.0.4 (2019-05-13)
* Update qt/platform.py to support other Unix style OSes (#444)

파일 보기

@ -65,20 +65,25 @@ class DupeGuru(QObject):
self.recentResults.mustOpenItem.connect(self.model.load_from)
self.resultWindow = None
if self.use_tabs:
self.main_window = TabBarWindow(self) if not self.prefs.tabs_default_pos else TabWindow(self)
self.main_window = (
TabBarWindow(self)
if not self.prefs.tabs_default_pos
else TabWindow(self)
)
parent_window = self.main_window
self.directories_dialog = self.main_window.createPage("DirectoriesDialog", app=self)
self.directories_dialog = self.main_window.createPage(
"DirectoriesDialog", app=self
)
self.main_window.addTab(
self.directories_dialog, "Directories", switch=False)
self.directories_dialog, "Directories", switch=False
)
self.actionDirectoriesWindow.setEnabled(False)
else: # floating windows only
self.main_window = None
self.directories_dialog = DirectoriesDialog(self)
parent_window = self.directories_dialog
self.progress_window = ProgressWindow(
parent_window, self.model.progress_window
)
self.progress_window = ProgressWindow(parent_window, self.model.progress_window)
self.problemDialog = ProblemDialog(
parent=parent_window, model=self.model.problem_dialog
)
@ -86,22 +91,25 @@ class DupeGuru(QObject):
self.ignoreListDialog = self.main_window.createPage(
"IgnoreListDialog",
parent=self.main_window,
model=self.model.ignore_list_dialog)
model=self.model.ignore_list_dialog,
)
self.excludeListDialog = self.main_window.createPage(
"ExcludeListDialog",
app=self,
parent=self.main_window,
model=self.model.exclude_list_dialog)
model=self.model.exclude_list_dialog,
)
else:
self.ignoreListDialog = IgnoreListDialog(
parent=parent_window, model=self.model.ignore_list_dialog)
parent=parent_window, model=self.model.ignore_list_dialog
)
self.excludeDialog = ExcludeListDialog(
app=self, parent=parent_window, model=self.model.exclude_list_dialog)
app=self, parent=parent_window, model=self.model.exclude_list_dialog
)
self.deletionOptions = DeletionOptions(
parent=parent_window,
model=self.model.deletion_options
parent=parent_window, model=self.model.deletion_options
)
self.about_box = AboutBox(parent_window, self)
@ -129,7 +137,13 @@ class DupeGuru(QObject):
self.preferencesTriggered,
),
("actionIgnoreList", "", "", tr("Ignore List"), self.ignoreListTriggered),
("actionDirectoriesWindow", "", "", tr("Directories"), self.showDirectoriesWindow),
(
"actionDirectoriesWindow",
"",
"",
tr("Directories"),
self.showDirectoriesWindow,
),
(
"actionClearPictureCache",
"Ctrl+Shift+P",
@ -137,7 +151,13 @@ class DupeGuru(QObject):
tr("Clear Picture Cache"),
self.clearPictureCacheTriggered,
),
("actionExcludeList", "", "", tr("Exclusion Filters"), self.excludeListTriggered),
(
"actionExcludeList",
"",
"",
tr("Exclusion Filters"),
self.excludeListTriggered,
),
("actionShowHelp", "F1", "", tr("dupeGuru Help"), self.showHelpTriggered),
("actionAbout", "", "", tr("About dupeGuru"), self.showAboutBoxTriggered),
(
@ -232,8 +252,7 @@ class DupeGuru(QObject):
if self.resultWindow is not None:
if self.use_tabs:
if self.main_window.indexOfWidget(self.resultWindow) < 0:
self.main_window.addTab(
self.resultWindow, "Results", switch=True)
self.main_window.addTab(self.resultWindow, "Results", switch=True)
return
self.main_window.showTab(self.resultWindow)
else:
@ -265,9 +284,11 @@ class DupeGuru(QObject):
"scanning have accented letters, you'll probably get a crash. It is advised that "
"you set your system locale properly."
)
QMessageBox.warning(self.main_window if self.main_window
else self.directories_dialog,
"Wrong Locale", msg)
QMessageBox.warning(
self.main_window if self.main_window else self.directories_dialog,
"Wrong Locale",
msg,
)
def clearPictureCacheTriggered(self):
title = tr("Clear Picture Cache")
@ -293,7 +314,9 @@ class DupeGuru(QObject):
"""Add tab for dialog, name the tab with desc_string, then show it."""
index = self.main_window.indexOfWidget(dialog)
# Create the tab if it doesn't exist already
if index < 0: # or (not dialog.isVisible() and not self.main_window.isTabVisible(index)):
if (
index < 0
): # or (not dialog.isVisible() and not self.main_window.isTabVisible(index)):
index = self.main_window.addTab(dialog, desc_string, switch=True)
# Show the tab for that widget
self.main_window.setCurrentIndex(index)
@ -304,8 +327,7 @@ class DupeGuru(QObject):
def preferencesTriggered(self):
preferences_dialog = self._get_preferences_dialog_class()(
self.main_window if self.main_window else self.directories_dialog,
self
self.main_window if self.main_window else self.directories_dialog, self
)
preferences_dialog.load()
result = preferences_dialog.exec()
@ -333,7 +355,7 @@ class DupeGuru(QObject):
if op.exists(help_path):
url = QUrl.fromLocalFile(help_path)
else:
url = QUrl("https://www.hardcoded.net/dupeguru/help/en/")
url = QUrl("https://dupeguru.voltaicideas.net/help/en/")
QDesktopServices.openUrl(url)
def handleSIGTERM(self):
@ -354,8 +376,7 @@ class DupeGuru(QObject):
return self.confirm("", prompt)
def create_results_window(self):
"""Creates resultWindow and details_dialog depending on the selected ``app_mode``.
"""
"""Creates resultWindow and details_dialog depending on the selected ``app_mode``."""
if self.details_dialog is not None:
# The object is not deleted entirely, avoid saving its geometry in the future
# self.willSavePrefs.disconnect(self.details_dialog.appWillSavePrefs)
@ -367,10 +388,13 @@ class DupeGuru(QObject):
if self.resultWindow is not None:
self.resultWindow.close()
# This is better for tabs, as it takes care of duplicate items in menu bar
self.resultWindow.deleteLater() if self.use_tabs else self.resultWindow.setParent(None)
self.resultWindow.deleteLater() if self.use_tabs else self.resultWindow.setParent(
None
)
if self.use_tabs:
self.resultWindow = self.main_window.createPage(
"ResultWindow", parent=self.main_window, app=self)
"ResultWindow", parent=self.main_window, app=self
)
else: # We don't use a tab widget, regular floating QMainWindow
self.resultWindow = ResultWindow(self.directories_dialog, self)
self.directories_dialog._updateActionsState()

파일 보기

@ -118,9 +118,7 @@ class ExcludeListDialog(QDialog):
return
# if at least one row matched, we know whether table is highlighted or not
self._row_matched = self.model.test_string(input_text)
# FIXME There is a bug on Windows (7) where the table rows don't get
# repainted until the table receives a mouse click event.
self.tableView.update()
self.table.refresh()
input_regex = self.inputLine.text()
if not input_regex:
@ -148,7 +146,7 @@ class ExcludeListDialog(QDialog):
if self._row_matched:
self._row_matched = False
self.model.reset_rows_highlight()
self.tableView.update()
self.table.refresh()
def display_help_message(self):
self.app.show_message(tr("""\

파일 보기

@ -58,9 +58,10 @@ class ErrorReportDialog(QDialog):
self.verticalLayout.addWidget(self.errorTextEdit)
msg = tr(
"Error reports should be reported as Github issues. You can copy the error traceback "
"above and paste it in a new issue (bonus point if you run a search to make sure the "
"issue doesn't already exist). What usually really helps is if you add a description "
"of how you got the error. Thanks!"
"above and paste it in a new issue.\n\nPlease make sure to run a search for any already "
"existing issues beforehand. Also make sure to test the very latest version available from the repository, "
"since the bug you are experiencing might have already been patched.\n\n"
"What usually really helps is if you add a description of how you got the error. Thanks!"
"\n\n"
"Although the application should continue to run after this error, it may be in an "
"unstable state, so it is recommended that you restart the application."

파일 보기

@ -48,9 +48,9 @@ SetCompressor /SOLID lzma
!define APPLICENSE "LICENSE" ; License is not in build directory
!define APPICON "images\dgse_logo.ico" ; nor is the icon
!define DISTDIR "dist"
!define HELPURL "http://www.hardcoded.net/support/"
!define UPDATEURL "http://www.hardcoded.net/dupeguru/"
!define ABOUTURL "http://www.hardcoded.net/dupeguru/"
!define HELPURL "https://github.com/arsenetar/dupeguru/issues"
!define UPDATEURL "https://dupeguru.voltaicideas.net/"
!define ABOUTURL "https://dupeguru.voltaicideas.net/"
; Static Defines
!define UNINSTALLREGBASE "Software\Microsoft\Windows\CurrentVersion\Uninstall"