1
0
mirror of https://github.com/arsenetar/dupeguru.git synced 2026-01-25 16:11:39 +00:00

Compare commits

..

94 Commits

Author SHA1 Message Date
Virgil Dupras
f72db8dd1d pe v2.0.0 2011-01-29 11:39:51 +01:00
Virgil Dupras
c5bf0f228a Changed error logging in core_pe.cache because it would sometimes result in huge logs of no value. Also, added debug logging during the analysis of pictures. 2011-01-29 11:31:17 +01:00
Virgil Dupras
e150b26cab Forgot a litteral --> constant conversion in the last commit. 2011-01-29 11:20:19 +01:00
Virgil Dupras
da41d07dae [#115 state:fixed] Re-factored the data columns (and delta columns) and made the Dimensions column a delta one. 2011-01-29 11:07:33 +01:00
Virgil Dupras
c885cb35d8 Added tag se3.0.1 for changeset 778876a8a978 2011-01-27 12:11:11 +01:00
Virgil Dupras
7c38217308 Fixed pref dialog UI for Linux. 2011-01-27 02:22:10 -08:00
Virgil Dupras
a88519b814 Fixed pref window UI on Windows. 2011-01-27 10:11:23 +00:00
Virgil Dupras
0aa91b170c se v3.0.1 2011-01-27 10:53:13 +01:00
Virgil Dupras
e9bb1c01f7 [#136 state:fixed] Add dropped folders to recent added folders list in the folder selection window. 2011-01-27 10:27:17 +01:00
Virgil Dupras
883875e88e [#135 state:fixed] Removed focus from cancel button in progress dialog. 2011-01-27 09:58:43 +01:00
Virgil Dupras
4cab6b0ad2 Added a 'More Info' button to the Qt Fairware pop up. 2011-01-26 17:15:15 +01:00
Virgil Dupras
91a2664830 Internationalized (and localized to french) column names under Qt, which I had forgot to do. 2011-01-26 13:06:54 +01:00
Virgil Dupras
6abbeaf987 [#132 state:fixed] Added a debug mode preference as well as extra debug loggings. 2011-01-26 12:50:44 +01:00
Virgil Dupras
21efef42f7 [#134 state:fixed] Removing all dupes from the results sets it in 'not modified' state. 2011-01-26 11:49:30 +01:00
Virgil Dupras
9d0e8d94ca Fixed dummy DupeGuru app so it implements get/set defaults methods (their lack made all tests fail). 2011-01-26 11:48:48 +01:00
Virgil Dupras
0f57ca698c [#133 state:fixed] Restored the context menu in the results window. 2011-01-26 11:34:47 +01:00
Virgil Dupras
69c572e875 Added tag se3.0.0 for changeset 8d12cab3b12b 2011-01-24 17:22:17 +01:00
Virgil Dupras
4083b60ff3 se v3.0.0 2011-01-24 15:40:01 +01:00
Virgil Dupras
41fbeb7ec9 Fixed changelog formatting (again). 2011-01-24 14:54:29 +01:00
Virgil Dupras
1162357b9b Fixed changelog formatting. 2011-01-24 14:48:45 +01:00
Virgil Dupras
a2a526866f Don't show bundles as subfolders in Folder Selection dialog. 2011-01-24 12:35:07 +01:00
Virgil Dupras
d3338b699e Added a short timeout to fairware unpaid hours fetching to avoid delaying the app's launch too much. 2011-01-24 11:40:41 +01:00
Virgil Dupras
6c60e76b55 Localized Fairware dialogs to french and made a few fixes here and there. 2011-01-24 11:30:45 +01:00
Virgil Dupras
8a0d31f612 Fixed linux-specific crashes and glitches. 2011-01-23 07:09:47 -08:00
Virgil Dupras
6fc7e5ace1 Fixed windows-specific crash in pref panel under Qt. 2011-01-23 14:49:59 +00:00
Virgil Dupras
8175762e74 Fixed auto update checks in Cocoa which were broken. 2011-01-23 12:47:21 +01:00
Virgil Dupras
f48e14af8a Removed appname duplication between dg_cocoa and core_*.__init__. 2011-01-23 12:20:44 +01:00
Virgil Dupras
cd2a61d926 Removed py2app import workarounds, they're not needed anymore. 2011-01-23 12:12:28 +01:00
Virgil Dupras
f45997afe4 Added prompt in folders dialog under Qt. 2011-01-23 11:24:33 +01:00
Virgil Dupras
b6f56721cb Changed sphinxgen's mechanism so that we don't have to copy the whole sphinx source dir every time we generate help.
--HG--
rename : help/en/changelog.rst => help/en/changelog.tmpl
rename : help/en/conf.py => help/en/conf.tmpl
rename : help/fr/changelog.rst => help/fr/changelog.tmpl
rename : help/fr/conf.py => help/fr/conf.tmpl
2011-01-22 17:06:04 +01:00
Virgil Dupras
f9e7e82772 Fixed a few bugs here and there. 2011-01-22 16:12:18 +01:00
Virgil Dupras
dbcd7b63d8 Tweaked FAQ in help file to use topic directives instead of section. This way it doesn't bug when using 'only' directives (and it kind of looks cute). 2011-01-22 13:17:45 +01:00
Virgil Dupras
bf807684dd [#32] Translated the help file in french. 2011-01-22 12:12:08 +01:00
Virgil Dupras
f02fcb5e4b Added a --only-help option to build.py 2011-01-21 14:39:33 +01:00
Virgil Dupras
2c127adf59 [#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).
2011-01-21 13:57:54 +01:00
Virgil Dupras
7f8a357019 (Cocoa) Converted .strings files from UTF-16 to UTF-8. 2011-01-21 13:49:39 +01:00
Virgil Dupras
99daf5b7b7 Added core translation to qt. 2011-01-19 09:47:00 +01:00
Virgil Dupras
42cff20710 [#32] Internationalized the core and localized it to french. 2011-01-18 17:33:33 +01:00
Virgil Dupras
04d7880a0c [#32] Internationalized the cocoa layer and localized it to french.
--HG--
rename : cocoa/base/xib/DetailsPanel.xib => cocoa/base/en.lproj/DetailsPanel.xib
rename : cocoa/base/xib/DirectoryPanel.xib => cocoa/base/en.lproj/DirectoryPanel.xib
rename : cocoa/base/xib/MainMenu.xib => cocoa/base/en.lproj/MainMenu.xib
rename : cocoa/base/xib/ProblemDialog.xib => cocoa/base/en.lproj/ProblemDialog.xib
rename : cocoa/base/xib/ResultWindow.xib => cocoa/base/en.lproj/ResultWindow.xib
rename : cocoa/me/xib/Preferences.xib => cocoa/me/en.lproj/Preferences.xib
rename : cocoa/pe/xib/DetailsPanel.xib => cocoa/pe/en.lproj/DetailsPanel.xib
rename : cocoa/pe/xib/Preferences.xib => cocoa/pe/en.lproj/Preferences.xib
rename : cocoa/se/xib/Preferences.xib => cocoa/se/en.lproj/Preferences.xib
2011-01-18 15:35:14 +01:00
Virgil Dupras
e7d26e3f82 Replaced 'Add' and 'Remove' by + and - icons in the directories dialog under Qt. 2011-01-18 11:07:56 +01:00
Virgil Dupras
19308bf686 Made a few wording fixes in the doc and in Qt. 2011-01-18 10:45:40 +01:00
Virgil Dupras
92970489c5 Straightened out actions pictures and keybindings, added a Recent Folders menu and a link to Recent Results menu in a dialog button. 2011-01-17 17:15:16 +01:00
Virgil Dupras
d51f5184d7 The directories dialog is now the main window. There's probably many glitches left to fix due to that change, but the basic functionalities are there.
--HG--
rename : qt/base/main_window.py => qt/base/result_window.py
rename : qt/pe/main_window.py => qt/pe/result_window.py
2011-01-15 16:29:35 +01:00
Virgil Dupras
30eb26af7d Fixed ambiguities in Directories/Folder vocabulary. 2011-01-15 14:14:30 +01:00
Virgil Dupras
3ea43f8213 Adapted help to recent UI changes.
--HG--
rename : help/en/directories.rst => help/en/folders.rst
2011-01-15 14:10:16 +01:00
Virgil Dupras
9833067ba7 Added a 'Load Results' button in the Directory window. 2011-01-15 12:08:10 +01:00
Virgil Dupras
ad3114c56b Cleaned ResultWindow's code up. 2011-01-15 11:38:59 +01:00
Virgil Dupras
9da9c269c1 Prettyfied the directories panel. 2011-01-14 15:51:19 +01:00
Virgil Dupras
0a22bb8469 Made a few UI fixes. Mostly, it's about main menu item not pointing the appropriate target. 2011-01-14 15:34:10 +01:00
Virgil Dupras
c9fd1b1a17 Don't consider results as modified if they're empty. 2011-01-14 15:12:02 +01:00
Virgil Dupras
19b40d45c0 Brought DirectoryPanel in ME and PE up to speed with latest developments and fixed ResultsWindow.awakeFromNib (in ME and PE also). 2011-01-14 15:07:11 +01:00
Virgil Dupras
90e2a1cda0 The main window of dupeGuru is now the directories window (and its Done button is replaced by a Start Scanning button). 2011-01-14 14:41:43 +01:00
Virgil Dupras
5e47b9f4a7 Transfered ownership of pref panel from result window to app delegate. 2011-01-14 14:06:54 +01:00
Virgil Dupras
50b6948250 Extracted ResultWindow.xib from MainMenu.xib. 2011-01-14 13:56:50 +01:00
Virgil Dupras
3ef118c9fa Results are not automatically saved/load anymore. There's a reminder on quitting if you haven't saved your results. Also, for easier re-loading, there's a 'open recent results' menu item. 2011-01-13 16:20:03 +01:00
Virgil Dupras
064707db43 Merged heads 2011-01-13 13:53:28 +01:00
Virgil Dupras
8f71a1318d [#129] Replaced details, power marker and delta values button by one segmented control on OS X. 2011-01-13 13:51:00 +01:00
Virgil Dupras
1b8ab35fdd Fixed debian packaging. 2011-01-13 03:23:21 -08:00
Virgil Dupras
4a1fe2f8ab Fixed packaging versioning and help building for Qt. 2011-01-13 10:56:46 +00:00
Virgil Dupras
e6e4e14781 Centralized version information in core_* package so that they only live at one place (instead of several).
--HG--
rename : cocoa/me/Info.plist => cocoa/me/InfoTemplate.plist
rename : cocoa/pe/Info.plist => cocoa/pe/InfoTemplate.plist
rename : cocoa/se/Info.plist => cocoa/se/InfoTemplate.plist
2011-01-13 11:29:01 +01:00
Virgil Dupras
d139157234 [#130 state:fixed] Converted help file to Sphinx.
--HG--
rename : help_me/CHANGELOG => help/changelog_me
rename : help_pe/CHANGELOG => help/changelog_pe
rename : help_se/CHANGELOG => help/changelog_se
2011-01-12 17:30:57 +01:00
Virgil Dupras
94104f4e03 Removed duplication among help files of the different editions.
--HG--
rename : help_se/en/credits.md => help_base/en/credits.md
rename : help_se/en/directories.md => help_base/en/directories.md
rename : help_se/en/power_marker.md => help_base/en/power_marker.md
rename : help_se/en/quick_start.md => help_base/en/quick_start.md
rename : help_se/en/results.md => help_base/en/results.md
rename : help_se/skeleton/hardcoded.css => help_base/skeleton/hardcoded.css
rename : help_se/skeleton/images/hs_title.png => help_base/skeleton/images/hs_title.png
2011-01-11 17:58:28 +01:00
Virgil Dupras
8bea978715 Removed dependencies for yaml everywhere except for the documentation generation (it's going to be converted to sphinx).
--HG--
rename : help_me/changelog.yaml => help_me/CHANGELOG
rename : help_pe/changelog.yaml => help_pe/CHANGELOG
2011-01-11 16:21:36 +01:00
Virgil Dupras
eefe464fba Replaced dependencies from hsutil to hscommon. 2011-01-11 13:36:05 +01:00
Virgil Dupras
33c0ba808c Changed references to what has already been moved from hsutil to hscommon (io, path, testutil). 2011-01-11 11:59:53 +01:00
Virgil Dupras
e0cc8ecda2 Stop using hsutil.testcase. 2011-01-05 11:11:21 +01:00
Virgil Dupras
2d423b2358 Added test skipping if os.link() is not available. 2011-01-01 16:22:38 +00:00
Virgil Dupras
b5b27b141c Modernized core_pe tests and added skipping when the modules haven't been compiled (rather than a hard crash). 2011-01-01 17:17:27 +01:00
Virgil Dupras
800a879927 Added tag se2.12.3 for changeset 0056293b0dad 2011-01-01 13:32:54 +01:00
Virgil Dupras
f6806e42db se v2.12.3 2011-01-01 12:45:39 +01:00
Virgil Dupras
3aae21b810 Added tag pe1.11.3 for changeset 3f71a8f5bf8f 2010-12-31 15:51:52 +01:00
Virgil Dupras
75239d6a64 pe v1.11.3 2010-12-31 14:43:00 +01:00
Virgil Dupras
09082955a3 [#125 state:fixed] Wrapped error message around a crash when the iPhoto app can't be found. 2010-12-31 12:10:44 +01:00
Virgil Dupras
6a6f2d51aa Added tag me5.10.4 for changeset 44f6ff67066c 2010-12-30 16:11:17 +01:00
Virgil Dupras
7b0d3ea8ac me v5.10.4 2010-12-30 14:55:13 +01:00
Virgil Dupras
1c88b6bb26 Tweaked the wording of the fairware pop up. 2010-12-30 13:07:04 +01:00
Virgil Dupras
e5e8e5d908 Replaced the about box with one that supports fairware registering. 2010-12-30 13:00:44 +01:00
Virgil Dupras
92fadd26b7 [#120 state:fixed] Fixed dangling bogus results after cancelled scan. 2010-12-30 10:24:37 +01:00
Virgil Dupras
45d783ac43 Removed CallLogger-related code in app_test. This code was duplicating the code that was recently added to hscommon.testutil. 2010-12-30 10:00:29 +01:00
Virgil Dupras
ea9e76e7ae Removed conftest.py modules in tests, which aren't required anymore with pytest v2.0 2010-12-30 09:47:22 +01:00
Virgil Dupras
28426c0e91 [#121 state:fixed] Catch HTTPException in Fairware fetching. 2010-12-30 09:35:45 +01:00
Virgil Dupras
3a9f51b600 [#122 state:fixed] Fixed crash on scanning when file is being deleted during the scan. 2010-12-29 15:41:12 +01:00
Virgil Dupras
f1b4db368e [#123 state:fixed] Updated codebase to use hsaudiotag v1.1.0 (which fixed the AIFF bug) and made it use the new auto.File wrapper. 2010-12-29 13:17:30 +01:00
Virgil Dupras
95efac187b Updated hscommon and adapted to changes in hscommon.gui.table.Table.refresh(). 2010-11-24 16:12:10 +01:00
Virgil Dupras
6770d22438 Updated hscommon subrepo. 2010-11-22 10:06:42 +01:00
Virgil Dupras
4ce97613c4 Added tag me5.10.3 for changeset ca93352ce351 2010-11-21 17:56:37 +01:00
Virgil Dupras
030eb8eb6e Fixed debian packaging 2010-11-21 07:49:38 -08:00
Virgil Dupras
c9da8e26e6 Fixed crash caused by outdated hsgui. Also, fixed app_test, which was also outdated. 2010-11-21 16:45:02 +01:00
Virgil Dupras
7ddf9772df v5.10.3 2010-11-21 16:25:16 +01:00
Virgil Dupras
0382ad1534 Adapted to the job-related code moving to the 'jobprogress' package. 2010-11-20 12:42:15 +01:00
Virgil Dupras
1b6e1369a0 Tranformed PyQt's license warning into a licensing note
--HG--
rename : qt/WARNING => qt/ABOUT_LICENSE
2010-11-13 14:37:20 +01:00
Virgil Dupras
835050c337 Added tag pe1.11.2 for changeset 154c8cb6f018 2010-10-07 12:44:04 +02:00
Virgil Dupras
ca6a42e6eb pe 1.11.2 2010-10-07 11:34:29 +02:00
Virgil Dupras
a2e4d893ac Added tag me5.10.2 for changeset f9cae82a0752 2010-10-06 12:44:43 +02:00
225 changed files with 31019 additions and 9478 deletions

View File

@@ -8,7 +8,7 @@ run.py
*.pbxuser *.pbxuser
*.tm_build_errors *.tm_build_errors
*.pyd *.pyd
conf.yaml conf.json
build build
dist dist
install install
@@ -17,6 +17,7 @@ cocoa/*/Info.plist
cocoa/*/build cocoa/*/build
cocoa/*/dg_cocoa.plugin cocoa/*/dg_cocoa.plugin
qt/base/*_rc.py qt/base/*_rc.py
help_se/dupeguru_help qt/lang/fr.qm
help_me/dupeguru_me_help qt/lang/en.qm
help_pe/dupeguru_pe_help help/*/conf.py
help/*/changelog.rst

View File

@@ -34,3 +34,11 @@ d3fe0d0dcda1e0bf1100d02f117503d3bf6baacf me5.10.0
b07ac1398703dd358912c1f3d20bd995633db9fe pe1.11.0 b07ac1398703dd358912c1f3d20bd995633db9fe pe1.11.0
96b6aee668398d663b04eafc8d5dae05e18500ee before-fairware 96b6aee668398d663b04eafc8d5dae05e18500ee before-fairware
22239f94589baf2a9fad2123045b8a718dbd68f5 se2.12.2 22239f94589baf2a9fad2123045b8a718dbd68f5 se2.12.2
f9cae82a0752191276b24ffb2cc4e4a8afb5d754 me5.10.2
154c8cb6f018d446d88fa099490c900906e86386 pe1.11.2
ca93352ce35184853ad9fcb881935a43a8b1e249 me5.10.3
44f6ff67066c083f79daa18a9d2f1ab909e0a62e me5.10.4
3f71a8f5bf8f6d0729748a27af9163e013723294 pe1.11.3
0056293b0dade8b8230f68c1fe6f0c2d1e0b74d8 se2.12.3
8d12cab3b12b723e3a86d02cf8002731a0f73f95 se3.0.0
778876a8a9787658aa6adf6944b53aebcb7faeea se3.0.1

28
README
View File

@@ -1,16 +1,18 @@
Contents Contents
===== =====
This package contains the source for dupeGuru. To learns how to build it, refer to the "Build dupeGuru" section. Below is the description of the various subfolders: This package contains the source for dupeGuru. To learn how to build it, refer to the "Build dupeGuru" section. Below is the description of the various subfolders:
- core: Contains the core logic code for dupeGuru. It's Python code written in TDD style. - core: Contains the core logic code for dupeGuru. It's Python code written in TDD style.
- core_*: Edition-specific-cross-toolkit code written in Python. - core_*: Edition-specific-cross-toolkit code written in Python.
- cocoa: UI code for the Cocoa toolkit. It's Objective-C code. - cocoa: UI code for the Cocoa toolkit. It's Objective-C code.
- qt: UI code for the Qt toolkit. It's written in Python and uses PyQt. Before redistributing changes in this part of the code, read the "qt/WARNING" file. - qt: UI code for the Qt toolkit. It's written in Python and uses PyQt.
- images: Images used by the different UI codebases. - images: Images used by the different UI codebases.
- debian_*: Skeleton files required to create a .deb package
- help: Help document, written for Sphinx.
There are also other sub-folder that comes from external repositories (automatically checked out There are also other sub-folder that comes from external repositories (automatically checked out
with svn:externals): with as mercurial subrepos):
- hscommon: A collection of helpers used across HS applications. - hscommon: A collection of helpers used across HS applications.
- cocoalib: A collection of helpers used across Cocoa UI codebases of HS applications. - cocoalib: A collection of helpers used across Cocoa UI codebases of HS applications.
@@ -25,20 +27,24 @@ General dependencies
----- -----
- Python 3.1 (http://www.python.org) - Python 3.1 (http://www.python.org)
- Send2Trash3k (http://hg.hardcoded.net/send2trash3k) - Send2Trash3k (http://hg.hardcoded.net/send2trash)
- hsutil3k (http://hg.hardcoded.net/hsutil3k) - hsaudiotag3k 1.1.0 (for ME) (http://hg.hardcoded.net/hsaudiotag)
- hsaudiotag3k (for ME) (http://hg.hardcoded.net/hsaudiotag3k) - jobprogress (http://hg.hardcoded.net/jobprogress)
- Markdown, to generate help files. (http://pypi.python.org/pypi/Markdown) - Sphinx 1.0.6 (http://sphinx.pocoo.org/)
- PyYaml, for help files and the build system. (http://pyyaml.org/) - pytest 2.0.0, to run unit tests. (http://pytest.org/)
- py.test, to run unit tests. (http://codespeak.net/py/dist/test/)
Note: Sphinx doesn't officially support Python 3.x yet, but it doesn't matter because it is invoked
by the build system through command line, so you can build dupeGuru even if Sphinx is installed in
your Python 2.x install.
OS X prerequisites OS X prerequisites
----- -----
- XCode 3.1 (http://developer.apple.com/TOOLS/xcode/) - XCode 3.1 (http://developer.apple.com/TOOLS/xcode/)
- Sparkle (http://sparkle.andymatuschak.org/) - Sparkle (http://sparkle.andymatuschak.org/)
- PyObjC 2.3. (http://pyobjc.sourceforge.net/) - PyObjC 2.3 (http://pyobjc.sourceforge.net/)
- py2app 0.5.4 (http://svn.pythonmac.org/py2app/py2app/trunk/doc/index.html) - py2app 0.5.4 (http://bitbucket.org/ronaldoussoren/py2app)
- appscript 0.22.0 for ME and PE (http://appscript.sourceforge.net/)
Windows prerequisites Windows prerequisites
--- ---

View File

@@ -7,27 +7,35 @@
# 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
import sys
import os import os
import os.path as op import os.path as op
from optparse import OptionParser
import shutil import shutil
import json
from setuptools import setup from setuptools import setup
from distutils.extension import Extension from distutils.extension import Extension
import yaml
from hscommon import helpgen from hscommon import sphinxgen
from hscommon.build import add_to_pythonpath, print_and_do, build_all_qt_ui, copy_packages from hscommon.build import (add_to_pythonpath, print_and_do, copy_packages,
filereplace, get_module_version, build_all_cocoa_locs, build_all_qt_locs)
def build_cocoa(edition, dev, help_destpath): def parse_args():
if not dev: usage = "usage: %prog [options]"
print("Building help index") parser = OptionParser(usage=usage)
os.system('open -a /Developer/Applications/Utilities/Help\\ Indexer.app {0}'.format(help_destpath)) parser.add_option('--clean', action='store_true', dest='clean',
help="Clean build folder before building")
parser.add_option('--only-help', action='store_true', dest='only_help',
help="Build only help file")
(options, args) = parser.parse_args()
return options
def build_cocoa(edition, dev):
build_all_cocoa_locs('cocoalib')
build_all_cocoa_locs(op.join('cocoa', 'base'))
build_all_cocoa_locs(op.join('cocoa', edition))
print("Building dg_cocoa.plugin") print("Building dg_cocoa.plugin")
if op.exists('build'):
shutil.rmtree('build')
os.mkdir('build')
if not dev: if not dev:
specific_packages = { specific_packages = {
'se': ['core_se'], 'se': ['core_se'],
@@ -55,6 +63,9 @@ def build_cocoa(edition, dev, help_destpath):
pthpath = op.join(pluginpath, 'Contents/Resources/dev.pth') pthpath = op.join(pluginpath, 'Contents/Resources/dev.pth')
open(pthpath, 'w').write(op.abspath('.')) open(pthpath, 'w').write(op.abspath('.'))
os.chdir(cocoa_project_path) os.chdir(cocoa_project_path)
print('Generating Info.plist')
app_version = get_module_version('core_{}'.format(edition))
filereplace('InfoTemplate.plist', 'Info.plist', version=app_version)
print("Building the XCode project") print("Building the XCode project")
args = [] args = []
if dev: if dev:
@@ -76,6 +87,8 @@ def build_cocoa(edition, dev, help_destpath):
open('run.py', 'wt').write(run_contents) open('run.py', 'wt').write(run_contents)
def build_qt(edition, dev): def build_qt(edition, dev):
print("Building .ts files")
build_all_qt_locs(op.join('qt', 'lang'), extradirs=[op.join('qtlib', 'lang')])
print("Building Qt stuff") print("Building Qt stuff")
print_and_do("pyrcc4 -py3 {0} > {1}".format(op.join('qt', 'base', 'dg.qrc'), op.join('qt', 'base', 'dg_rc.py'))) print_and_do("pyrcc4 -py3 {0} > {1}".format(op.join('qt', 'base', 'dg.qrc'), op.join('qt', 'base', 'dg_rc.py')))
print("Creating the run.py file") print("Creating the run.py file")
@@ -83,6 +96,18 @@ def build_qt(edition, dev):
run_contents = tmpl.replace('{{edition}}', edition) run_contents = tmpl.replace('{{edition}}', edition)
open('run.py', 'wt').write(run_contents) open('run.py', 'wt').write(run_contents)
def build_help(edition):
print("Generating Help")
current_path = op.abspath('.')
help_basepath = op.join(current_path, 'help', 'en')
help_destpath = op.join(current_path, 'build', 'help'.format(edition))
changelog_path = op.join(current_path, 'help', 'changelog_{}'.format(edition))
tixurl = "https://hardcoded.lighthouseapp.com/projects/31699-dupeguru/tickets/{0}"
appname = {'se': 'dupeGuru', 'me': 'dupeGuru Music Edition', 'pe': 'dupeGuru Picture Edition'}[edition]
homepage = 'http://www.hardcoded.net/dupeguru{}/'.format('_' + edition if edition != 'se' else '')
confrepl = {'edition': edition, 'appname': appname, 'homepage': homepage}
sphinxgen.gen(help_basepath, help_destpath, changelog_path, tixurl, confrepl)
def build_pe_modules(ui): def build_pe_modules(ui):
def move(src, dst): def move(src, dst):
if not op.exists(src): if not op.exists(src):
@@ -119,30 +144,35 @@ def build_pe_modules(ui):
move('_block_qt.so', op.join('qt', 'pe', '_block_qt.so')) move('_block_qt.so', op.join('qt', 'pe', '_block_qt.so'))
move('_block_qt.pyd', op.join('qt', 'pe', '_block_qt.pyd')) move('_block_qt.pyd', op.join('qt', 'pe', '_block_qt.pyd'))
def main(): def build_normal(edition, ui, dev):
conf = yaml.load(open('conf.yaml'))
edition = conf['edition']
ui = conf['ui']
dev = conf['dev']
print("Building dupeGuru {0} with UI {1}".format(edition.upper(), ui)) print("Building dupeGuru {0} with UI {1}".format(edition.upper(), ui))
if dev:
print("Building in Dev mode")
add_to_pythonpath('.') add_to_pythonpath('.')
print("Generating Help") build_help(edition)
windows = sys.platform == 'win32'
profile = 'win_en' if windows else 'osx_en'
help_dir = 'help_{0}'.format(edition)
dest_dir = 'dupeguru_{0}_help'.format(edition) if edition != 'se' else 'dupeguru_help'
help_basepath = op.abspath(help_dir)
help_destpath = op.abspath(op.join(help_dir, dest_dir))
helpgen.gen(help_basepath, help_destpath, profile=profile)
print("Building dupeGuru") print("Building dupeGuru")
if edition == 'pe': if edition == 'pe':
build_pe_modules(ui) build_pe_modules(ui)
if ui == 'cocoa': if ui == 'cocoa':
build_cocoa(edition, dev, help_destpath) build_cocoa(edition, dev)
elif ui == 'qt': elif ui == 'qt':
build_qt(edition, dev) build_qt(edition, dev)
def main():
options = parse_args()
conf = json.load(open('conf.json'))
edition = conf['edition']
ui = conf['ui']
dev = conf['dev']
if dev:
print("Building in Dev mode")
if options.clean:
if op.exists('build'):
shutil.rmtree('build')
if not op.exists('build'):
os.mkdir('build')
if options.only_help:
build_help(edition)
else:
build_normal(edition, ui, dev)
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@@ -7,25 +7,49 @@ http://www.hardcoded.net/licenses/bsd_license
*/ */
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import "RecentDirectories.h"
#import "PyDupeGuru.h" #import "PyDupeGuru.h"
#import "ResultWindow.h" #import "ResultWindow.h"
#import "DetailsPanel.h" #import "DetailsPanel.h"
#import "DirectoryPanel.h" #import "DirectoryPanel.h"
#import "HSAboutBox.h"
#import "HSRecentFiles.h"
@interface AppDelegateBase : NSObject @interface AppDelegateBase : NSObject
{ {
IBOutlet PyDupeGuruBase *py; IBOutlet PyDupeGuruBase *py;
IBOutlet RecentDirectories *recentDirectories; IBOutlet NSMenu *recentResultsMenu;
IBOutlet ResultWindowBase *result; IBOutlet NSMenu *actionsMenu;
IBOutlet NSMenu *columnsMenu;
ResultWindowBase *_resultWindow;
DirectoryPanel *_directoryPanel; DirectoryPanel *_directoryPanel;
DetailsPanel *_detailsPanel; DetailsPanel *_detailsPanel;
BOOL _savedResults; NSWindowController *_preferencesPanel;
HSAboutBox *_aboutBox;
HSRecentFiles *_recentResults;
} }
/* Virtual */
- (PyDupeGuruBase *)py; - (PyDupeGuruBase *)py;
- (RecentDirectories *)recentDirectories; - (ResultWindowBase *)createResultWindow;
- (DirectoryPanel *)createDirectoryPanel;
- (DetailsPanel *)createDetailsPanel;
- (NSString *)homepageURL;
/* Public */
- (ResultWindowBase *)resultWindow;
- (DirectoryPanel *)directoryPanel; - (DirectoryPanel *)directoryPanel;
- (DetailsPanel *)detailsPanel; - (DetailsPanel *)detailsPanel;
- (void)saveResults; - (HSRecentFiles *)recentResults;
- (NSMenu *)columnsMenu;
/* Actions */
- (IBAction)loadResults:(id)sender;
- (IBAction)openWebsite:(id)sender;
- (IBAction)openHelp:(id)sender;
- (IBAction)showAboutBox:(id)sender;
- (IBAction)showDirectoryWindow:(id)sender;
- (IBAction)showPreferencesPanel:(id)sender;
- (IBAction)showResultWindow:(id)sender;
- (IBAction)startScanning:(id)sender;
@end @end

View File

@@ -11,35 +11,140 @@ http://www.hardcoded.net/licenses/bsd_license
#import "HSFairwareReminder.h" #import "HSFairwareReminder.h"
#import "Utils.h" #import "Utils.h"
#import "Consts.h" #import "Consts.h"
#import "Dialogs.h"
#import <Sparkle/SUUpdater.h> #import <Sparkle/SUUpdater.h>
@implementation AppDelegateBase @implementation AppDelegateBase
- (void)awakeFromNib
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
/* Because the pref pane is lazily loaded, we have to manually do the update check if the
preference is set.
*/
if ([ud boolForKey:@"SUEnableAutomaticChecks"]) {
[[SUUpdater sharedUpdater] checkForUpdatesInBackground];
}
_recentResults = [[HSRecentFiles alloc] initWithName:@"recentResults" menu:recentResultsMenu];
[_recentResults setDelegate:self];
_resultWindow = [self createResultWindow];
_directoryPanel = [self createDirectoryPanel];
_detailsPanel = nil; // Lazily loaded
_aboutBox = nil; // Lazily loaded
_preferencesPanel = nil; // Lazily loaded
[[[self directoryPanel] window] makeKeyAndOrderFront:self];
}
/* Virtual */
- (PyDupeGuruBase *)py { return py; } - (PyDupeGuruBase *)py { return py; }
- (RecentDirectories *)recentDirectories { return recentDirectories; }
- (ResultWindowBase *)createResultWindow
{
return nil; // must be overriden by all editions
}
- (DirectoryPanel *)createDirectoryPanel
{
return [[DirectoryPanel alloc] initWithParentApp:self];
}
- (DetailsPanel *)createDetailsPanel
{
return [[DetailsPanel alloc] initWithPy:py];
}
- (NSString *)homepageURL
{
return @""; // must be overriden by all editions
}
/* Public */
- (ResultWindowBase *)resultWindow
{
return _resultWindow;
}
- (DirectoryPanel *)directoryPanel - (DirectoryPanel *)directoryPanel
{ {
if (!_directoryPanel)
_directoryPanel = [[DirectoryPanel alloc] initWithParentApp:self];
return _directoryPanel; return _directoryPanel;
} }
- (DetailsPanel *)detailsPanel - (DetailsPanel *)detailsPanel
{ {
if (!_detailsPanel) if (!_detailsPanel)
_detailsPanel = [[DetailsPanel alloc] initWithPy:py]; _detailsPanel = [self createDetailsPanel];
return _detailsPanel; return _detailsPanel;
} }
- (void)saveResults - (HSRecentFiles *)recentResults
{ {
if (_savedResults) { return _recentResults;
return;
}
[py saveIgnoreList];
[py saveResults];
_savedResults = YES;
} }
- (NSMenu *)columnsMenu { return columnsMenu; }
/* Actions */
- (IBAction)loadResults:(id)sender
{
NSOpenPanel *op = [NSOpenPanel openPanel];
[op setCanChooseFiles:YES];
[op setCanChooseDirectories:NO];
[op setCanCreateDirectories:NO];
[op setAllowsMultipleSelection:NO];
[op setAllowedFileTypes:[NSArray arrayWithObject:@"dupeguru"]];
[op setTitle:TR(@"SelectResultToLoadMsg")];
if ([op runModal] == NSOKButton) {
NSString *filename = [[op filenames] objectAtIndex:0];
[py loadResultsFrom:filename];
[[self recentResults] addFile:filename];
}
}
- (IBAction)openWebsite:(id)sender
{
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[self homepageURL]]];
}
- (IBAction)openHelp:(id)sender
{
NSBundle *b = [NSBundle mainBundle];
NSString *p = [b pathForResource:@"index" ofType:@"html" inDirectory:@"help"];
NSURL *u = [NSURL fileURLWithPath:p];
[[NSWorkspace sharedWorkspace] openURL:u];
}
- (IBAction)showAboutBox:(id)sender
{
if (_aboutBox == nil) {
_aboutBox = [[HSAboutBox alloc] initWithApp:py];
}
[[_aboutBox window] makeKeyAndOrderFront:sender];
}
- (IBAction)showDirectoryWindow:(id)sender
{
[[[self directoryPanel] window] makeKeyAndOrderFront:nil];
}
- (IBAction)showPreferencesPanel:(id)sender
{
if (_preferencesPanel == nil) {
_preferencesPanel = [[NSWindowController alloc] initWithWindowNibName:@"Preferences"];
}
[_preferencesPanel showWindow:sender];
}
- (IBAction)showResultWindow:(id)sender
{
[[[self resultWindow] window] makeKeyAndOrderFront:nil];
}
- (IBAction)startScanning:(id)sender
{
[[self resultWindow] startDuplicateScan:sender];
}
/* Delegate */ /* Delegate */
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{ {
@@ -49,54 +154,53 @@ http://www.hardcoded.net/licenses/bsd_license
NSArray *columnsOrder = [ud arrayForKey:@"columnsOrder"]; NSArray *columnsOrder = [ud arrayForKey:@"columnsOrder"];
NSDictionary *columnsWidth = [ud dictionaryForKey:@"columnsWidth"]; NSDictionary *columnsWidth = [ud dictionaryForKey:@"columnsWidth"];
if ([columnsOrder count]) if ([columnsOrder count])
[result restoreColumnsPosition:columnsOrder widths:columnsWidth]; [[self resultWindow] restoreColumnsPosition:columnsOrder widths:columnsWidth];
else else
[result resetColumnsToDefault:nil]; [[self resultWindow] resetColumnsToDefault:nil];
[HSFairwareReminder showNagWithApp:[self py]]; [HSFairwareReminder showNagWithApp:[self py]];
//Restore results [py loadSession];
[py loadIgnoreList];
[py loadResults];
_savedResults = NO;
} }
- (void)applicationWillBecomeActive:(NSNotification *)aNotification - (void)applicationWillBecomeActive:(NSNotification *)aNotification
{ {
if (![[result window] isVisible]) if (![[[self directoryPanel] window] isVisible]) {
[result showWindow:NSApp]; [[self directoryPanel] showWindow:NSApp];
}
}
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
if ([py resultsAreModified]) {
NSString *msg = TR(@"ReallyWantToQuitMsg");
if ([Dialogs askYesNo:msg] == NSAlertSecondButtonReturn) { // NO
return NSTerminateCancel;
}
}
return NSTerminateNow;
} }
- (void)applicationWillTerminate:(NSNotification *)aNotification - (void)applicationWillTerminate:(NSNotification *)aNotification
{ {
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
[ud setObject: [result getColumnsOrder] forKey:@"columnsOrder"]; [ud setObject: [[self resultWindow] getColumnsOrder] forKey:@"columnsOrder"];
[ud setObject: [result getColumnsWidth] forKey:@"columnsWidth"]; [ud setObject: [[self resultWindow] getColumnsWidth] forKey:@"columnsWidth"];
[self saveResults];
NSInteger sc = [ud integerForKey:@"sessionCountSinceLastIgnorePurge"]; NSInteger sc = [ud integerForKey:@"sessionCountSinceLastIgnorePurge"];
if (sc >= 10) if (sc >= 10) {
{
sc = -1; sc = -1;
[py purgeIgnoreList]; [py purgeIgnoreList];
} }
sc++; sc++;
[py saveSession];
[ud setInteger:sc forKey:@"sessionCountSinceLastIgnorePurge"]; [ud setInteger:sc forKey:@"sessionCountSinceLastIgnorePurge"];
// NSApplication does not release nib instances objects, we must do it manually // NSApplication does not release nib instances objects, we must do it manually
// Well, it isn't needed because the memory is freed anyway (we are quitting the application // Well, it isn't needed because the memory is freed anyway (we are quitting the application
// But I need to release RecentDirectories so it saves the user defaults // But I need to release HSRecentFiles so it saves the user defaults
[recentDirectories release]; [_directoryPanel release];
[_recentResults release];
} }
- (void)recentDirecoryClicked:(NSString *)directory - (void)recentFileClicked:(NSString *)path
{ {
[[self directoryPanel] addDirectory:directory]; [py loadResultsFrom:path];
}
/* SUUpdater delegate */
- (BOOL)updater:(SUUpdater *)updater shouldPostponeRelaunchForUpdate:(SUAppcastItem *)update untilInvoking:(NSInvocation *)invocation;
{
/* If results aren't saved now, we might get a weird utf-8 lookup error when saving later.
**/
[self saveResults];
return NO;
} }
@end @end

View File

@@ -15,4 +15,6 @@ http://www.hardcoded.net/licenses/bsd_license
#define jobScan @"job_scan" #define jobScan @"job_scan"
#define jobCopy @"job_copy" #define jobCopy @"job_copy"
#define jobMove @"job_move" #define jobMove @"job_move"
#define jobDelete @"job_delete" #define jobDelete @"job_delete"
#define TR(s) NSLocalizedString(s, @"")

View File

@@ -18,6 +18,7 @@ http://www.hardcoded.net/licenses/bsd_license
- (id)initWithPy:(PyApp *)aPy; - (id)initWithPy:(PyApp *)aPy;
- (PyDetailsPanel *)py; - (PyDetailsPanel *)py;
- (BOOL)isVisible;
- (void)toggleVisibility; - (void)toggleVisibility;
/* Python --> Cocoa */ /* Python --> Cocoa */

View File

@@ -34,9 +34,14 @@ http://www.hardcoded.net/licenses/bsd_license
[detailsTable reloadData]; [detailsTable reloadData];
} }
- (BOOL)isVisible
{
return [[self window] isVisible];
}
- (void)toggleVisibility - (void)toggleVisibility
{ {
if ([[self window] isVisible]) { if ([self isVisible]) {
[[self window] close]; [[self window] close];
} }
else { else {

View File

@@ -10,6 +10,8 @@ http://www.hardcoded.net/licenses/bsd_license
#import "HSOutline.h" #import "HSOutline.h"
#import "PyDirectoryOutline.h" #import "PyDirectoryOutline.h"
#define DGAddedFoldersNotification @"DGAddedFoldersNotification"
@interface DirectoryOutline : HSOutline {} @interface DirectoryOutline : HSOutline {}
- (id)initWithPyParent:(id)aPyParent view:(HSOutlineView *)aOutlineView; - (id)initWithPyParent:(id)aPyParent view:(HSOutlineView *)aOutlineView;
- (PyDirectoryOutline *)py; - (PyDirectoryOutline *)py;

View File

@@ -49,12 +49,15 @@ http://www.hardcoded.net/licenses/bsd_license
sourceDragMask = [info draggingSourceOperationMask]; sourceDragMask = [info draggingSourceOperationMask];
pboard = [info draggingPasteboard]; pboard = [info draggingPasteboard];
if ([[pboard types] containsObject:NSFilenamesPboardType]) { if ([[pboard types] containsObject:NSFilenamesPboardType]) {
NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType]; NSArray *foldernames = [pboard propertyListForType:NSFilenamesPboardType];
if (!(sourceDragMask & NSDragOperationLink)) if (!(sourceDragMask & NSDragOperationLink))
return NO; return NO;
for (NSString *filename in filenames) { for (NSString *foldername in foldernames) {
[[self py] addDirectory:filename]; [[self py] addDirectory:foldername];
} }
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:foldernames forKey:@"foldernames"];
[[NSNotificationCenter defaultCenter] postNotificationName:DGAddedFoldersNotification
object:self userInfo:userInfo];
} }
return YES; return YES;
} }

View File

@@ -7,27 +7,34 @@ http://www.hardcoded.net/licenses/bsd_license
*/ */
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import "RecentDirectories.h"
#import "HSOutlineView.h" #import "HSOutlineView.h"
#import "HSRecentFiles.h"
#import "DirectoryOutline.h" #import "DirectoryOutline.h"
#import "PyDupeGuru.h" #import "PyDupeGuru.h"
@class AppDelegateBase;
@interface DirectoryPanel : NSWindowController @interface DirectoryPanel : NSWindowController
{ {
IBOutlet NSPopUpButton *addButtonPopUp; IBOutlet NSPopUpButton *addButtonPopUp;
IBOutlet NSPopUpButton *loadRecentButtonPopUp;
IBOutlet HSOutlineView *outlineView; IBOutlet HSOutlineView *outlineView;
IBOutlet NSButton *removeButton; IBOutlet NSButton *removeButton;
AppDelegateBase *_app;
PyDupeGuruBase *_py; PyDupeGuruBase *_py;
RecentDirectories *_recentDirectories; HSRecentFiles *_recentDirectories;
DirectoryOutline *outline; DirectoryOutline *outline;
BOOL _alwaysShowPopUp;
} }
- (id)initWithParentApp:(id)aParentApp; - (id)initWithParentApp:(AppDelegateBase *)aParentApp;
- (void)fillPopUpMenu; // Virtual
- (IBAction)askForDirectory:(id)sender; - (IBAction)askForDirectory:(id)sender;
- (IBAction)popupAddDirectoryMenu:(id)sender; - (IBAction)popupAddDirectoryMenu:(id)sender;
- (IBAction)popupLoadRecentMenu:(id)sender;
- (IBAction)removeSelectedDirectory:(id)sender; - (IBAction)removeSelectedDirectory:(id)sender;
- (IBAction)toggleVisible:(id)sender;
- (void)addDirectory:(NSString *)directory; - (void)addDirectory:(NSString *)directory;
- (void)refreshRemoveButtonText; - (void)refreshRemoveButtonText;

View File

@@ -10,28 +10,45 @@ http://www.hardcoded.net/licenses/bsd_license
#import "Dialogs.h" #import "Dialogs.h"
#import "Utils.h" #import "Utils.h"
#import "AppDelegate.h" #import "AppDelegate.h"
#import "Consts.h"
@implementation DirectoryPanel @implementation DirectoryPanel
- (id)initWithParentApp:(id)aParentApp - (id)initWithParentApp:(AppDelegateBase *)aParentApp
{ {
self = [super initWithWindowNibName:@"DirectoryPanel"]; self = [super initWithWindowNibName:@"DirectoryPanel"];
[self window]; [self window];
AppDelegateBase *app = aParentApp; _app = aParentApp;
_py = [app py]; _py = [_app py];
_recentDirectories = [app recentDirectories]; _alwaysShowPopUp = NO;
[self fillPopUpMenu];
_recentDirectories = [[HSRecentFiles alloc] initWithName:@"recentDirectories" menu:[addButtonPopUp menu]];
[_recentDirectories setDelegate:self];
outline = [[DirectoryOutline alloc] initWithPyParent:_py view:outlineView]; outline = [[DirectoryOutline alloc] initWithPyParent:_py view:outlineView];
[self refreshRemoveButtonText]; [self refreshRemoveButtonText];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(directorySelectionChanged:) [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(directorySelectionChanged:)
name:NSOutlineViewSelectionDidChangeNotification object:outlineView]; name:NSOutlineViewSelectionDidChangeNotification object:outlineView];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(outlineAddedFolders:)
name:DGAddedFoldersNotification object:outline];
return self; return self;
} }
- (void)dealloc - (void)dealloc
{ {
[outline release]; [outline release];
[_recentDirectories release];
[super dealloc]; [super dealloc];
} }
/* Virtual */
- (void)fillPopUpMenu
{
NSMenu *m = [addButtonPopUp menu];
NSMenuItem *mi = [m addItemWithTitle:TR(@"Add New Folder...") action:@selector(askForDirectory:) keyEquivalent:@""];
[mi setTarget:self];
[m addItem:[NSMenuItem separatorItem]];
}
/* Actions */ /* Actions */
- (IBAction)askForDirectory:(id)sender - (IBAction)askForDirectory:(id)sender
@@ -40,7 +57,7 @@ http://www.hardcoded.net/licenses/bsd_license
[op setCanChooseFiles:YES]; [op setCanChooseFiles:YES];
[op setCanChooseDirectories:YES]; [op setCanChooseDirectories:YES];
[op setAllowsMultipleSelection:YES]; [op setAllowsMultipleSelection:YES];
[op setTitle:@"Select a directory to add to the scanning list"]; [op setTitle:TR(@"SelectFolderToAddMsg")];
[op setDelegate:self]; [op setDelegate:self];
if ([op runModal] == NSOKButton) { if ([op runModal] == NSOKButton) {
for (NSString *directory in [op filenames]) { for (NSString *directory in [op filenames]) {
@@ -51,20 +68,32 @@ http://www.hardcoded.net/licenses/bsd_license
- (IBAction)popupAddDirectoryMenu:(id)sender - (IBAction)popupAddDirectoryMenu:(id)sender
{ {
if ([[_recentDirectories directories] count] == 0) if ((!_alwaysShowPopUp) && ([[_recentDirectories filepaths] count] == 0)) {
{
[self askForDirectory:sender]; [self askForDirectory:sender];
return;
} }
NSMenu *m = [addButtonPopUp menu]; else {
while ([m numberOfItems] > 0) [addButtonPopUp selectItem:nil];
[m removeItemAtIndex:0]; [[addButtonPopUp cell] performClickWithFrame:[sender frame] inView:[sender superview]];
NSMenuItem *mi = [m addItemWithTitle:@"Add New Directory..." action:@selector(askForDirectory:) keyEquivalent:@""]; }
[mi setTarget:self]; }
[m addItem:[NSMenuItem separatorItem]];
[_recentDirectories fillMenu:m]; - (IBAction)popupLoadRecentMenu:(id)sender
[addButtonPopUp selectItem:nil]; {
[[addButtonPopUp cell] performClickWithFrame:[sender frame] inView:[sender superview]]; if ([[[_app recentResults] filepaths] count] > 0) {
NSMenu *m = [loadRecentButtonPopUp menu];
while ([m numberOfItems] > 0) {
[m removeItemAtIndex:0];
}
NSMenuItem *mi = [m addItemWithTitle:TR(@"Load from file...") action:@selector(loadResults:) keyEquivalent:@""];
[mi setTarget:_app];
[m addItem:[NSMenuItem separatorItem]];
[[_app recentResults] fillMenu:m];
[loadRecentButtonPopUp selectItem:nil];
[[loadRecentButtonPopUp cell] performClickWithFrame:[sender frame] inView:[sender superview]];
}
else {
[_app loadResults:nil];
}
} }
- (IBAction)removeSelectedDirectory:(id)sender - (IBAction)removeSelectedDirectory:(id)sender
@@ -85,11 +114,6 @@ http://www.hardcoded.net/licenses/bsd_license
[self refreshRemoveButtonText]; [self refreshRemoveButtonText];
} }
- (IBAction)toggleVisible:(id)sender
{
[[self window] makeKeyAndOrderFront:nil];
}
/* Public */ /* Public */
- (void)addDirectory:(NSString *)directory - (void)addDirectory:(NSString *)directory
{ {
@@ -97,14 +121,14 @@ http://www.hardcoded.net/licenses/bsd_license
if (r) { if (r) {
NSString *m = @""; NSString *m = @"";
if (r == 1) { if (r == 1) {
m = @"'%@' already is in the list."; m = TR(@"FolderAlreadyInListMsg");
} }
else if (r == 2) { else if (r == 2) {
m = @"'%@' does not exist."; m = TR(@"FolderDoesNotExistMsg");
} }
[Dialogs showMessage:[NSString stringWithFormat:m,directory]]; [Dialogs showMessage:[NSString stringWithFormat:m,directory]];
} }
[_recentDirectories addDirectory:directory]; [_recentDirectories addFile:directory];
[[self window] makeKeyAndOrderFront:nil]; [[self window] makeKeyAndOrderFront:nil];
} }
@@ -116,8 +140,8 @@ http://www.hardcoded.net/licenses/bsd_license
} }
[removeButton setEnabled:YES]; [removeButton setEnabled:YES];
NSInteger state = [outline intProperty:@"state" valueAtPath:[outline selectedIndexPath]]; NSInteger state = [outline intProperty:@"state" valueAtPath:[outline selectedIndexPath]];
NSString *buttonText = state == 2 ? @"Put Back" : @"Remove"; NSString *imgName = state == 2 ? @"NSGoLeftTemplate" : @"NSRemoveTemplate";
[removeButton setTitle:buttonText]; [removeButton setImage:[NSImage imageNamed:imgName]];
} }
/* Delegate */ /* Delegate */
@@ -128,6 +152,11 @@ http://www.hardcoded.net/licenses/bsd_license
return isdir; return isdir;
} }
- (void)recentFileClicked:(NSString *)path
{
[self addDirectory:path];
}
/* Notifications */ /* Notifications */
- (void)directorySelectionChanged:(NSNotification *)aNotification - (void)directorySelectionChanged:(NSNotification *)aNotification
@@ -135,4 +164,12 @@ http://www.hardcoded.net/licenses/bsd_license
[self refreshRemoveButtonText]; [self refreshRemoveButtonText];
} }
- (void)outlineAddedFolders:(NSNotification *)aNotification
{
NSArray *foldernames = [[aNotification userInfo] objectForKey:@"foldernames"];
for (NSString *foldername in foldernames) {
[_recentDirectories addFile:foldername];
}
}
@end @end

View File

@@ -13,12 +13,10 @@ http://www.hardcoded.net/licenses/bsd_license
//Actions //Actions
- (NSNumber *)addDirectory:(NSString *)name; - (NSNumber *)addDirectory:(NSString *)name;
- (void)removeDirectory:(NSNumber *)index; - (void)removeDirectory:(NSNumber *)index;
- (void)loadResults;
- (void)loadResultsFrom:(NSString *)filename; - (void)loadResultsFrom:(NSString *)filename;
- (void)saveResults;
- (void)saveResultsAs:(NSString *)filename; - (void)saveResultsAs:(NSString *)filename;
- (void)loadIgnoreList; - (void)loadSession;
- (void)saveIgnoreList; - (void)saveSession;
- (void)clearIgnoreList; - (void)clearIgnoreList;
- (void)purgeIgnoreList; - (void)purgeIgnoreList;
- (NSString *)exportToXHTMLwithColumns:(NSArray *)aColIds; - (NSString *)exportToXHTMLwithColumns:(NSArray *)aColIds;
@@ -46,6 +44,8 @@ http://www.hardcoded.net/licenses/bsd_license
- (NSNumber *)getIgnoreListCount; - (NSNumber *)getIgnoreListCount;
- (NSNumber *)getMarkCount; - (NSNumber *)getMarkCount;
- (BOOL)scanWasProblematic; - (BOOL)scanWasProblematic;
- (BOOL)resultsAreModified;
- (NSArray *)deltaColumns;
//Scanning options //Scanning options
- (void)setMinMatchPercentage:(NSNumber *)percentage; - (void)setMinMatchPercentage:(NSNumber *)percentage;

View File

@@ -68,7 +68,8 @@ http://www.hardcoded.net/licenses/bsd_license
NSInteger selectedDupeCount = [self selectedDupeCount]; NSInteger selectedDupeCount = [self selectedDupeCount];
if (!selectedDupeCount) if (!selectedDupeCount)
return; return;
NSString *msg = [NSString stringWithFormat:@"You are about to remove %d files from results. Continue?",selectedDupeCount]; NSString *msgFmt = TR(@"FileRemovalConfirmMsg");
NSString *msg = [NSString stringWithFormat:msgFmt,selectedDupeCount];
if ([Dialogs askYesNo:msg] == NSAlertSecondButtonReturn) // NO if ([Dialogs askYesNo:msg] == NSAlertSecondButtonReturn) // NO
return; return;
[[self py] removeSelected]; [[self py] removeSelected];
@@ -97,7 +98,7 @@ http://www.hardcoded.net/licenses/bsd_license
if (![newName isEqual:oldName]) { if (![newName isEqual:oldName]) {
BOOL renamed = [[self py] renameSelected:newName]; BOOL renamed = [[self py] renameSelected:newName];
if (!renamed) { if (!renamed) {
[Dialogs showMessage:[NSString stringWithFormat:@"The name '%@' already exists.", newName]]; [Dialogs showMessage:[NSString stringWithFormat:TR(@"FilenameAlreadyExistsMsg"), newName]];
} }
else { else {
[tableView setNeedsDisplay:YES]; [tableView setNeedsDisplay:YES];

View File

@@ -13,37 +13,43 @@ http://www.hardcoded.net/licenses/bsd_license
#import "HSTableView.h" #import "HSTableView.h"
#import "PyDupeGuru.h" #import "PyDupeGuru.h"
@class AppDelegateBase;
@interface ResultWindowBase : NSWindowController @interface ResultWindowBase : NSWindowController
{ {
@protected @protected
IBOutlet PyDupeGuruBase *py; IBOutlet NSSegmentedControl *optionsSwitch;
IBOutlet id app;
IBOutlet NSSegmentedControl *deltaSwitch;
IBOutlet HSTableView *matches; IBOutlet HSTableView *matches;
IBOutlet NSSegmentedControl *pmSwitch; IBOutlet NSTextField *stats;
IBOutlet NSTextField *stats; IBOutlet NSSearchField *filterField;
IBOutlet NSMenu *columnsMenu;
IBOutlet NSSearchField *filterField;
AppDelegateBase *app;
PyDupeGuruBase *py;
NSMenu *columnsMenu;
NSMutableArray *_resultColumns; NSMutableArray *_resultColumns;
NSWindowController *preferencesPanel;
ResultTable *table; ResultTable *table;
StatsLabel *statsLabel; StatsLabel *statsLabel;
ProblemDialog *problemDialog; ProblemDialog *problemDialog;
} }
- (id)initWithParentApp:(AppDelegateBase *)app;
/* Virtual */
- (void)initResultColumns;
- (void)setScanOptions;
- (NSString *)getScanErrorMessageForCode:(NSInteger)errorCode;
/* Helpers */ /* Helpers */
- (void)fillColumnsMenu; - (void)fillColumnsMenu;
- (NSTableColumn *)getColumnForIdentifier:(NSInteger)aIdentifier title:(NSString *)aTitle width:(NSInteger)aWidth refCol:(NSTableColumn *)aColumn; - (NSTableColumn *)getColumnForIdentifier:(NSInteger)aIdentifier title:(NSString *)aTitle width:(NSInteger)aWidth refCol:(NSTableColumn *)aColumn;
- (NSArray *)getColumnsOrder; - (NSArray *)getColumnsOrder;
- (NSDictionary *)getColumnsWidth; - (NSDictionary *)getColumnsWidth;
- (void)initResultColumns;
- (void)restoreColumnsPosition:(NSArray *)aColumnsOrder widths:(NSDictionary *)aColumnsWidth; - (void)restoreColumnsPosition:(NSArray *)aColumnsOrder widths:(NSDictionary *)aColumnsWidth;
- (void)sendMarkedToTrash:(BOOL)hardlinkDeleted; - (void)sendMarkedToTrash:(BOOL)hardlinkDeleted;
- (void)updateOptionSegments;
/* Actions */ /* Actions */
- (IBAction)clearIgnoreList:(id)sender; - (IBAction)clearIgnoreList:(id)sender;
- (IBAction)changeDelta:(id)sender; - (IBAction)changeOptions:(id)sender;
- (IBAction)changePowerMarker:(id)sender;
- (IBAction)copyMarked:(id)sender; - (IBAction)copyMarked:(id)sender;
- (IBAction)deleteMarked:(id)sender; - (IBAction)deleteMarked:(id)sender;
- (IBAction)hardlinkMarked:(id)sender; - (IBAction)hardlinkMarked:(id)sender;
@@ -51,7 +57,6 @@ http://www.hardcoded.net/licenses/bsd_license
- (IBAction)filter:(id)sender; - (IBAction)filter:(id)sender;
- (IBAction)ignoreSelected:(id)sender; - (IBAction)ignoreSelected:(id)sender;
- (IBAction)invokeCustomCommand:(id)sender; - (IBAction)invokeCustomCommand:(id)sender;
- (IBAction)loadResults:(id)sender;
- (IBAction)markAll:(id)sender; - (IBAction)markAll:(id)sender;
- (IBAction)markInvert:(id)sender; - (IBAction)markInvert:(id)sender;
- (IBAction)markNone:(id)sender; - (IBAction)markNone:(id)sender;
@@ -65,7 +70,6 @@ http://www.hardcoded.net/licenses/bsd_license
- (IBAction)resetColumnsToDefault:(id)sender; - (IBAction)resetColumnsToDefault:(id)sender;
- (IBAction)revealSelected:(id)sender; - (IBAction)revealSelected:(id)sender;
- (IBAction)saveResults:(id)sender; - (IBAction)saveResults:(id)sender;
- (IBAction)showPreferencesPanel:(id)sender;
- (IBAction)startDuplicateScan:(id)sender; - (IBAction)startDuplicateScan:(id)sender;
- (IBAction)switchSelected:(id)sender; - (IBAction)switchSelected:(id)sender;
- (IBAction)toggleColumn:(id)sender; - (IBAction)toggleColumn:(id)sender;

View File

@@ -14,36 +14,57 @@ http://www.hardcoded.net/licenses/bsd_license
#import "Consts.h" #import "Consts.h"
@implementation ResultWindowBase @implementation ResultWindowBase
- (void)awakeFromNib - (id)initWithParentApp:(AppDelegateBase *)aApp;
{ {
[self window]; self = [super initWithWindowNibName:@"ResultWindow"];
app = aApp;
py = [app py];
columnsMenu = [app columnsMenu];
/* Put a cute iTunes-like bottom bar */ /* Put a cute iTunes-like bottom bar */
[[self window] setContentBorderThickness:28 forEdge:NSMinYEdge]; [[self window] setContentBorderThickness:28 forEdge:NSMinYEdge];
preferencesPanel = [[NSWindowController alloc] initWithWindowNibName:@"Preferences"];
table = [[ResultTable alloc] initWithPyParent:py view:matches]; table = [[ResultTable alloc] initWithPyParent:py view:matches];
statsLabel = [[StatsLabel alloc] initWithPyParent:py labelView:stats]; statsLabel = [[StatsLabel alloc] initWithPyParent:py labelView:stats];
problemDialog = [[ProblemDialog alloc] initWithPy:py]; problemDialog = [[ProblemDialog alloc] initWithPy:py];
[self initResultColumns]; [self initResultColumns];
[self fillColumnsMenu]; [self fillColumnsMenu];
[deltaSwitch setSelectedSegment:0];
[pmSwitch setSelectedSegment:0];
[matches setTarget:self]; [matches setTarget:self];
[matches setDoubleAction:@selector(openClicked:)]; [matches setDoubleAction:@selector(openClicked:)];
[table setDeltaColumns:[Utils array2IndexSet:[py deltaColumns]]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(jobCompleted:) name:JobCompletedNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(jobCompleted:) name:JobCompletedNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(jobStarted:) name:JobStarted object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(jobStarted:) name:JobStarted object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(jobInProgress:) name:JobInProgress object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(jobInProgress:) name:JobInProgress object:nil];
return self;
} }
- (void)dealloc - (void)dealloc
{ {
[table release]; [table release];
[preferencesPanel release];
[statsLabel release]; [statsLabel release];
[problemDialog release]; [problemDialog release];
[super dealloc]; [super dealloc];
} }
/* Virtual */
- (void)initResultColumns
{
}
- (void)setScanOptions
{
}
- (NSString *)getScanErrorMessageForCode:(NSInteger)errorCode
{
if (errorCode == 0) {
return nil;
}
if (errorCode == 3) {
return TR(@"NoScannableFileMsg");
}
return TR(@"UnknownErrorMsg");
}
/* Helpers */ /* Helpers */
- (void)fillColumnsMenu - (void)fillColumnsMenu
{ {
@@ -57,7 +78,8 @@ http://www.hardcoded.net/licenses/bsd_license
[mi setState:NSOnState]; [mi setState:NSOnState];
} }
[columnsMenu addItem:[NSMenuItem separatorItem]]; [columnsMenu addItem:[NSMenuItem separatorItem]];
NSMenuItem *mi = [columnsMenu addItemWithTitle:@"Reset to Default" action:@selector(resetColumnsToDefault:) keyEquivalent:@""]; NSMenuItem *mi = [columnsMenu addItemWithTitle:TR(@"Reset to Default")
action:@selector(resetColumnsToDefault:) keyEquivalent:@""];
[mi setTarget:self]; [mi setTarget:self];
} }
@@ -96,11 +118,6 @@ http://www.hardcoded.net/licenses/bsd_license
return result; return result;
} }
- (void)initResultColumns
{
// Virtual
}
- (void)restoreColumnsPosition:(NSArray *)aColumnsOrder widths:(NSDictionary *)aColumnsWidth - (void)restoreColumnsPosition:(NSArray *)aColumnsOrder widths:(NSDictionary *)aColumnsWidth
{ {
for (NSMenuItem *mi in [columnsMenu itemArray]) { for (NSMenuItem *mi in [columnsMenu itemArray]) {
@@ -130,9 +147,9 @@ http://www.hardcoded.net/licenses/bsd_license
if (!mark_count) { if (!mark_count) {
return; return;
} }
NSString *msg = @"You are about to send %d files to Trash. Continue?"; NSString *msg = TR(@"SendToTrashConfirmMsg");
if (hardlinkDeleted) { if (hardlinkDeleted) {
msg = @"You are about to send %d files to Trash (and hardlink them afterwards). Continue?"; msg = TR(@"HardlinkConfirmMsg");
} }
if ([Dialogs askYesNo:[NSString stringWithFormat:msg,mark_count]] == NSAlertSecondButtonReturn) { // NO if ([Dialogs askYesNo:[NSString stringWithFormat:msg,mark_count]] == NSAlertSecondButtonReturn) { // NO
return; return;
@@ -147,25 +164,37 @@ http://www.hardcoded.net/licenses/bsd_license
} }
} }
- (void)updateOptionSegments
{
[optionsSwitch setSelected:[[app detailsPanel] isVisible] forSegment:0];
[optionsSwitch setSelected:[table powerMarkerMode] forSegment:1];
[optionsSwitch setSelected:[table deltaValuesMode] forSegment:2];
}
/* Actions */ /* Actions */
- (IBAction)clearIgnoreList:(id)sender - (IBAction)clearIgnoreList:(id)sender
{ {
NSInteger i = n2i([py getIgnoreListCount]); NSInteger i = n2i([py getIgnoreListCount]);
if (!i) if (!i)
return; return;
if ([Dialogs askYesNo:[NSString stringWithFormat:@"Do you really want to remove all %d items from the ignore list?",i]] == NSAlertSecondButtonReturn) // NO NSString *msg = [NSString stringWithFormat:TR(@"ClearIgnoreListConfirmMsg"),i];
if ([Dialogs askYesNo:msg] == NSAlertSecondButtonReturn) // NO
return; return;
[py clearIgnoreList]; [py clearIgnoreList];
} }
- (IBAction)changeDelta:(id)sender - (IBAction)changeOptions:(id)sender
{ {
[table setDeltaValuesMode:[deltaSwitch selectedSegment] == 1]; NSInteger seg = [optionsSwitch selectedSegment];
} if (seg == 0) {
[self toggleDetailsPanel:sender];
- (IBAction)changePowerMarker:(id)sender }
{ else if (seg == 1) {
[table setPowerMarkerMode:[pmSwitch selectedSegment] == 1]; [self togglePowerMarker:sender];
}
else if (seg == 2) {
[self toggleDelta:sender];
}
} }
- (IBAction)copyMarked:(id)sender - (IBAction)copyMarked:(id)sender
@@ -178,9 +207,8 @@ http://www.hardcoded.net/licenses/bsd_license
[op setCanChooseDirectories:YES]; [op setCanChooseDirectories:YES];
[op setCanCreateDirectories:YES]; [op setCanCreateDirectories:YES];
[op setAllowsMultipleSelection:NO]; [op setAllowsMultipleSelection:NO];
[op setTitle:@"Select a directory to copy marked files to"]; [op setTitle:TR(@"SelectCopyDestinationMsg")];
if ([op runModalForTypes:nil] == NSOKButton) if ([op runModal] == NSOKButton) {
{
NSString *directory = [[op filenames] objectAtIndex:0]; NSString *directory = [[op filenames] objectAtIndex:0];
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
[py copyOrMove:b2n(YES) markedTo:directory recreatePath:[ud objectForKey:@"recreatePathType"]]; [py copyOrMove:b2n(YES) markedTo:directory recreatePath:[ud objectForKey:@"recreatePathType"]];
@@ -215,7 +243,7 @@ http://www.hardcoded.net/licenses/bsd_license
NSInteger selectedDupeCount = [table selectedDupeCount]; NSInteger selectedDupeCount = [table selectedDupeCount];
if (!selectedDupeCount) if (!selectedDupeCount)
return; return;
NSString *msg = [NSString stringWithFormat:@"All selected %d matches are going to be ignored in all subsequent scans. Continue?",selectedDupeCount]; NSString *msg = [NSString stringWithFormat:TR(@"IgnoreConfirmMsg"),selectedDupeCount];
if ([Dialogs askYesNo:msg] == NSAlertSecondButtonReturn) // NO if ([Dialogs askYesNo:msg] == NSAlertSecondButtonReturn) // NO
return; return;
[py addSelectedToIgnoreList]; [py addSelectedToIgnoreList];
@@ -229,22 +257,7 @@ http://www.hardcoded.net/licenses/bsd_license
[py invokeCommand:cmd]; [py invokeCommand:cmd];
} }
else { else {
[Dialogs showMessage:@"You have no custom command set up. Set it up in your preferences."]; [Dialogs showMessage:TR(@"NoCustomCommandMsg")];
}
}
- (IBAction)loadResults:(id)sender
{
NSOpenPanel *op = [NSOpenPanel openPanel];
[op setCanChooseFiles:YES];
[op setCanChooseDirectories:NO];
[op setCanCreateDirectories:NO];
[op setAllowsMultipleSelection:NO];
[op setAllowedFileTypes:[NSArray arrayWithObject:@"dupeguru"]];
[op setTitle:@"Select a results file to load"];
if ([op runModal] == NSOKButton) {
NSString *filename = [[op filenames] objectAtIndex:0];
[py loadResultsFrom:filename];
} }
} }
@@ -278,9 +291,8 @@ http://www.hardcoded.net/licenses/bsd_license
[op setCanChooseDirectories:YES]; [op setCanChooseDirectories:YES];
[op setCanCreateDirectories:YES]; [op setCanCreateDirectories:YES];
[op setAllowsMultipleSelection:NO]; [op setAllowsMultipleSelection:NO];
[op setTitle:@"Select a directory to move marked files to"]; [op setTitle:TR(@"SelectMoveDestinationMsg")];
if ([op runModalForTypes:nil] == NSOKButton) if ([op runModal] == NSOKButton) {
{
NSString *directory = [[op filenames] objectAtIndex:0]; NSString *directory = [[op filenames] objectAtIndex:0];
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
[py setRemoveEmptyFolders:n2b([ud objectForKey:@"removeEmptyFolders"])]; [py setRemoveEmptyFolders:n2b([ud objectForKey:@"removeEmptyFolders"])];
@@ -307,7 +319,8 @@ http://www.hardcoded.net/licenses/bsd_license
int mark_count = [[py getMarkCount] intValue]; int mark_count = [[py getMarkCount] intValue];
if (!mark_count) if (!mark_count)
return; return;
if ([Dialogs askYesNo:[NSString stringWithFormat:@"You are about to remove %d files from results. Continue?",mark_count]] == NSAlertSecondButtonReturn) // NO NSString *msg = [NSString stringWithFormat:@"You are about to remove %d files from results. Continue?",mark_count];
if ([Dialogs askYesNo:msg] == NSAlertSecondButtonReturn) // NO
return; return;
[py removeMarked]; [py removeMarked];
} }
@@ -334,25 +347,31 @@ http://www.hardcoded.net/licenses/bsd_license
[py revealSelected]; [py revealSelected];
} }
- (IBAction)showPreferencesPanel:(id)sender
{
[preferencesPanel showWindow:sender];
}
- (IBAction)saveResults:(id)sender - (IBAction)saveResults:(id)sender
{ {
NSSavePanel *sp = [NSSavePanel savePanel]; NSSavePanel *sp = [NSSavePanel savePanel];
[sp setCanCreateDirectories:YES]; [sp setCanCreateDirectories:YES];
[sp setAllowedFileTypes:[NSArray arrayWithObject:@"dupeguru"]]; [sp setAllowedFileTypes:[NSArray arrayWithObject:@"dupeguru"]];
[sp setTitle:@"Select a file to save your results to"]; [sp setTitle:TR(@"SelectResultToSaveMsg")];
if ([sp runModal] == NSOKButton) { if ([sp runModal] == NSOKButton) {
[py saveResultsAs:[sp filename]]; [py saveResultsAs:[sp filename]];
[[app recentResults] addFile:[sp filename]];
} }
} }
- (IBAction)startDuplicateScan:(id)sender - (IBAction)startDuplicateScan:(id)sender
{ {
// Virtual if ([py resultsAreModified]) {
if ([Dialogs askYesNo:TR(@"ReallyWantToContinueMsg")] == NSAlertSecondButtonReturn) // NO
return;
}
[self setScanOptions];
NSInteger r = n2i([py doScan]);
NSString *errorMsg = [self getScanErrorMessageForCode:r];
if (errorMsg != nil) {
[[ProgressController mainProgressController] hide];
[Dialogs showMessage:errorMsg];
}
} }
- (IBAction)switchSelected:(id)sender - (IBAction)switchSelected:(id)sender
@@ -365,50 +384,38 @@ http://www.hardcoded.net/licenses/bsd_license
NSMenuItem *mi = sender; NSMenuItem *mi = sender;
NSString *colId = [NSString stringWithFormat:@"%d",[mi tag]]; NSString *colId = [NSString stringWithFormat:@"%d",[mi tag]];
NSTableColumn *col = [matches tableColumnWithIdentifier:colId]; NSTableColumn *col = [matches tableColumnWithIdentifier:colId];
if (col == nil) if (col == nil) {
{
//Add Column //Add Column
col = [_resultColumns objectAtIndex:[mi tag]]; col = [_resultColumns objectAtIndex:[mi tag]];
[matches addTableColumn:col]; [matches addTableColumn:col];
[mi setState:NSOnState]; [mi setState:NSOnState];
} }
else else {
{
//Remove column //Remove column
[matches removeTableColumn:col]; [matches removeTableColumn:col];
[mi setState:NSOffState]; [mi setState:NSOffState];
} }
} }
- (IBAction)toggleDelta:(id)sender
{
if ([deltaSwitch selectedSegment] == 1)
[deltaSwitch setSelectedSegment:0];
else
[deltaSwitch setSelectedSegment:1];
[self changeDelta:sender];
}
- (IBAction)toggleDetailsPanel:(id)sender - (IBAction)toggleDetailsPanel:(id)sender
{ {
[[(AppDelegateBase *)app detailsPanel] toggleVisibility]; [[app detailsPanel] toggleVisibility];
[self updateOptionSegments];
}
- (IBAction)toggleDelta:(id)sender
{
[table setDeltaValuesMode:![table deltaValuesMode]];
[self updateOptionSegments];
} }
- (IBAction)togglePowerMarker:(id)sender - (IBAction)togglePowerMarker:(id)sender
{ {
if ([pmSwitch selectedSegment] == 1) [table setPowerMarkerMode:![table powerMarkerMode]];
[pmSwitch setSelectedSegment:0]; [self updateOptionSegments];
else
[pmSwitch setSelectedSegment:1];
[self changePowerMarker:sender];
} }
/* Notifications */ /* Notifications */
- (void)windowWillClose:(NSNotification *)aNotification
{
[NSApp hide:NSApp];
}
- (void)jobCompleted:(NSNotification *)aNotification - (void)jobCompleted:(NSNotification *)aNotification
{ {
id lastAction = [[ProgressController mainProgressController] jobId]; id lastAction = [[ProgressController mainProgressController] jobId];
@@ -417,7 +424,7 @@ http://www.hardcoded.net/licenses/bsd_license
[problemDialog showWindow:self]; [problemDialog showWindow:self];
} }
else { else {
[Dialogs showMessage:@"All marked files were copied sucessfully."]; [Dialogs showMessage:TR(@"CopySuccessMsg")];
} }
} }
else if ([lastAction isEqualTo:jobMove]) { else if ([lastAction isEqualTo:jobMove]) {
@@ -425,7 +432,7 @@ http://www.hardcoded.net/licenses/bsd_license
[problemDialog showWindow:self]; [problemDialog showWindow:self];
} }
else { else {
[Dialogs showMessage:@"All marked files were moved sucessfully."]; [Dialogs showMessage:TR(@"MoveSuccessMsg")];
} }
} }
else if ([lastAction isEqualTo:jobDelete]) { else if ([lastAction isEqualTo:jobDelete]) {
@@ -433,27 +440,25 @@ http://www.hardcoded.net/licenses/bsd_license
[problemDialog showWindow:self]; [problemDialog showWindow:self];
} }
else { else {
[Dialogs showMessage:@"All marked files were sucessfully sent to Trash."]; [Dialogs showMessage:TR(@"SendToTrashSuccessMsg")];
} }
} }
else if ([lastAction isEqualTo:jobScan]) { else if ([lastAction isEqualTo:jobScan]) {
NSInteger rowCount = [[table py] numberOfRows]; NSInteger rowCount = [[table py] numberOfRows];
if (rowCount == 0) if (rowCount == 0) {
[Dialogs showMessage:@"No duplicates found."]; [Dialogs showMessage:TR(@"NoDuplicateFoundMsg")];
}
} }
// Re-activate toolbar items right after the progress bar stops showing instead of waiting until
// a mouse-over is performed
[[[self window] toolbar] validateVisibleItems];
} }
- (void)jobInProgress:(NSNotification *)aNotification - (void)jobInProgress:(NSNotification *)aNotification
{ {
[Dialogs showMessage:@"A previous action is still hanging in there. You can't start a new one yet. Wait a few seconds, then try again."]; [Dialogs showMessage:TR(@"TaskHangingMsg")];
} }
- (void)jobStarted:(NSNotification *)aNotification - (void)jobStarted:(NSNotification *)aNotification
{ {
[[self window] makeKeyAndOrderFront:nil];
NSDictionary *ui = [aNotification userInfo]; NSDictionary *ui = [aNotification userInfo];
NSString *desc = [ui valueForKey:@"desc"]; NSString *desc = [ui valueForKey:@"desc"];
[[ProgressController mainProgressController] setJobDesc:desc]; [[ProgressController mainProgressController] setJobDesc:desc];

View File

@@ -0,0 +1,12 @@
/* Class = "NSPanel"; title = "Details of Selected File"; ObjectID = "5"; */
"5.title" = "Details of Selected File";
/* Class = "NSTableColumn"; headerCell.title = "Selected"; ObjectID = "9"; */
"9.headerCell.title" = "Selected";
/* Class = "NSTableColumn"; headerCell.title = "Reference"; ObjectID = "10"; */
"10.headerCell.title" = "Reference";
/* Class = "NSTableColumn"; headerCell.title = "Attribute"; ObjectID = "11"; */
"11.headerCell.title" = "Attribute";

View File

@@ -0,0 +1,23 @@
/* Class = "NSTableColumn"; headerCell.title = "State"; ObjectID = "13"; */
"13.headerCell.title" = "State";
/* Class = "NSTableColumn"; headerCell.title = "Name"; ObjectID = "15"; */
"15.headerCell.title" = "Name";
/* Class = "NSButtonCell"; title = "Scan"; ObjectID = "48"; */
"48.title" = "Scan";
/* Class = "NSMenuItem"; title = "Normal"; ObjectID = "55"; */
"55.title" = "Normal";
/* Class = "NSMenuItem"; title = "Reference"; ObjectID = "56"; */
"56.title" = "Reference";
/* Class = "NSMenuItem"; title = "Excluded"; ObjectID = "57"; */
"57.title" = "Excluded";
/* Class = "NSTextFieldCell"; title = "Select folders to scan and press \"Scan\"."; ObjectID = "71"; */
"71.title" = "Select folders to scan and press \"Scan\".";
/* Class = "NSButtonCell"; title = "Load Results"; ObjectID = "73"; */
"73.title" = "Load Results";

View File

@@ -0,0 +1,63 @@
"Add New Folder..." = "Add New Folder...";
"Load from file..." = "Load from file...";
"Reset to Default" = "Reset to Default";
"Add iTunes Directory" = "Add iTunes Directory";
"Remove Dead Tracks in iTunes" = "Remove Dead Tracks in iTunes";
"Add iPhoto Library" = "Add iPhoto Library";
"Clear Picture Cache" = "Clear Picture Cache";
/* Columns */
"Folder" = "Folder";
"Size (KB)" = "Size (KB)";
"Size (MB)" = "Size (MB)";
"Kind" = "Kind";
"Modification" = "Modification";
"Match %" = "Match %";
"Words Used" = "Words Used";
"Dupe Count" = "Dupe Count";
"Time" = "Time";
"Bitrate" = "Bitrate";
"Sample Rate" = "Sample Rate";
"Title" = "Title";
"Artist" = "Artist";
"Album" = "Album";
"Genre" = "Genre";
"Year" = "Year";
"Track Number" = "Track Number";
"Comment" = "Comment";
"Dimensions" = "Dimensions";
/* Messages */
"SelectResultToLoadMsg" = "Select a results file to load";
"SelectCopyDestinationMsg" = "Select a directory to copy marked files to";
"SelectMoveDestinationMsg" = "Select a directory to move marked files to";
"SelectResultToSaveMsg" = "Select a file to save your results to";
"SelectFolderToAddMsg" = "Select a folder to add to the scanning list";
"ReallyWantToQuitMsg" = "You have unsaved results, do you really want to quit?";
"ReallyWantToContinueMsg" = "You have unsaved results, do you really want to continue?";
"FolderAlreadyInListMsg" = "'%@' already is in the list.";
"FolderDoesNotExistMsg" = "'%@' does not exist.";
"FileRemovalConfirmMsg" = "You are about to remove %d files from results. Continue?";
"FilenameAlreadyExistsMsg" = "The name '%@' already exists.";
"NoScannableFileMsg" = "The selected directories contain no scannable file.";
"UnknownErrorMsg" = "Unknown Error.";
"SendToTrashConfirmMsg" = "You are about to send %d files to Trash. Continue?";
"HardlinkConfirmMsg" = "You are about to send %d files to Trash (and hardlink them afterwards). Continue?";
"ClearIgnoreListConfirmMsg" = "Do you really want to remove all %d items from the ignore list?";
"IgnoreConfirmMsg" = "All selected %d matches are going to be ignored in all subsequent scans. Continue?";
"NoCustomCommandMsg" = "You have no custom command set up. Set it up in your preferences.";
"CopySuccessMsg" = "All marked files were copied sucessfully.";
"MoveSuccessMsg" = "All marked files were moved sucessfully.";
"SendToTrashSuccessMsg" = "All marked files were sucessfully sent to Trash.";
"NoDuplicateFoundMsg" = "No duplicates found.";
"TaskHangingMsg" = "A previous action is still hanging in there. You can't start a new one yet. Wait a few seconds, then try again.";
"RemoveDeadTracksConfirmMsg" = "Your iTunes Library contains %d dead tracks ready to be removed. Continue?";
"NoDeadTrackMsg" = "You have no dead tracks in your iTunes Library";
"IPhotoAppNotFoundMsg" = "The iPhoto application couldn't be found.";
"ClearPictureCacheConfirmMsg" = "Do you really want to remove all your cached picture analysis?";

View File

@@ -0,0 +1,174 @@
/* Class = "NSMenuItem"; title = "Bring All to Front"; ObjectID = "5"; */
"5.title" = "Bring All to Front";
/* Class = "NSMenuItem"; title = "Window"; ObjectID = "19"; */
"19.title" = "Window";
/* Class = "NSMenuItem"; title = "Minimize"; ObjectID = "23"; */
"23.title" = "Minimize";
/* Class = "NSMenu"; title = "Window"; ObjectID = "24"; */
"24.title" = "Window";
/* Class = "NSMenuItem"; title = "About dupeGuru"; ObjectID = "58"; */
"58.title" = "About dupeGuru";
/* Class = "NSMenuItem"; title = "Help"; ObjectID = "103"; */
"103.title" = "Help";
/* Class = "NSMenu"; title = "Help"; ObjectID = "106"; */
"106.title" = "Help";
/* Class = "NSMenuItem"; title = "dupeGuru Help"; ObjectID = "111"; */
"111.title" = "dupeGuru Help";
/* Class = "NSMenuItem"; title = "Hide dupeGuru"; ObjectID = "134"; */
"134.title" = "Hide dupeGuru";
/* Class = "NSMenuItem"; title = "Quit dupeGuru"; ObjectID = "136"; */
"136.title" = "Quit dupeGuru";
/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "145"; */
"145.title" = "Hide Others";
/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "150"; */
"150.title" = "Show All";
/* Class = "NSMenuItem"; title = "Zoom"; ObjectID = "197"; */
"197.title" = "Zoom";
/* Class = "NSMenuItem"; title = "Details Panel"; ObjectID = "398"; */
"398.title" = "Details Panel";
/* Class = "NSMenuItem"; title = "Preferences..."; ObjectID = "541"; */
"541.title" = "Preferences...";
/* Class = "NSMenuItem"; title = "Folder Selection Window"; ObjectID = "579"; */
"579.title" = "Folder Selection Window";
/* Class = "NSMenuItem"; title = "Actions"; ObjectID = "597"; */
"597.title" = "Actions";
/* Class = "NSMenu"; title = "Actions"; ObjectID = "598"; */
"598.title" = "Actions";
/* Class = "NSMenuItem"; title = "Send Marked to Trash"; ObjectID = "599"; */
"599.title" = "Send Marked to Trash";
/* Class = "NSMenuItem"; title = "Move Marked to..."; ObjectID = "600"; */
"600.title" = "Move Marked to...";
/* Class = "NSMenuItem"; title = "Copy Marked to..."; ObjectID = "601"; */
"601.title" = "Copy Marked to...";
/* Class = "NSMenuItem"; title = "Make Selected Reference"; ObjectID = "602"; */
"602.title" = "Make Selected Reference";
/* Class = "NSMenuItem"; title = "Remove Marked from Results"; ObjectID = "603"; */
"603.title" = "Remove Marked from Results";
/* Class = "NSMenuItem"; title = "Remove Selected from Results"; ObjectID = "605"; */
"605.title" = "Remove Selected from Results";
/* Class = "NSMenuItem"; title = "Columns"; ObjectID = "618"; */
"618.title" = "Columns";
/* Class = "NSMenu"; title = "Columns"; ObjectID = "619"; */
"619.title" = "Columns";
/* Class = "NSMenuItem"; title = "Open Selected with Default Application"; ObjectID = "708"; */
"708.title" = "Open Selected with Default Application";
/* Class = "NSMenuItem"; title = "Reveal Selected in Finder"; ObjectID = "710"; */
"710.title" = "Reveal Selected in Finder";
/* Class = "NSMenuItem"; title = "Add Selected to Ignore List"; ObjectID = "922"; */
"922.title" = "Add Selected to Ignore List";
/* Class = "NSMenuItem"; title = "Close Window"; ObjectID = "924"; */
"924.title" = "Close Window";
/* Class = "NSMenuItem"; title = "Start Duplicate Scan"; ObjectID = "926"; */
"926.title" = "Start Duplicate Scan";
/* Class = "NSMenuItem"; title = "Clear Ignore List"; ObjectID = "927"; */
"927.title" = "Clear Ignore List";
/* Class = "NSMenuItem"; title = "Rename Selected"; ObjectID = "933"; */
"933.title" = "Rename Selected";
/* Class = "NSMenuItem"; title = "Export Results to XHTML"; ObjectID = "947"; */
"947.title" = "Export Results to XHTML";
/* Class = "NSMenuItem"; title = "Check for update..."; ObjectID = "950"; */
"950.title" = "Check for update...";
/* Class = "NSMenuItem"; title = "Mode"; ObjectID = "959"; */
"959.title" = "Mode";
/* Class = "NSMenu"; title = "Mode"; ObjectID = "960"; */
"960.title" = "Mode";
/* Class = "NSMenuItem"; title = "Show Dupes Only"; ObjectID = "961"; */
"961.title" = "Show Dupes Only";
/* Class = "NSMenuItem"; title = "Show Delta Values"; ObjectID = "962"; */
"962.title" = "Show Delta Values";
/* Class = "NSMenuItem"; title = "Edit"; ObjectID = "965"; */
"965.title" = "Edit";
/* Class = "NSMenu"; title = "Edit"; ObjectID = "966"; */
"966.title" = "Edit";
/* Class = "NSMenuItem"; title = "Cut"; ObjectID = "985"; */
"985.title" = "Cut";
/* Class = "NSMenuItem"; title = "Copy"; ObjectID = "986"; */
"986.title" = "Copy";
/* Class = "NSMenuItem"; title = "Paste"; ObjectID = "991"; */
"991.title" = "Paste";
/* Class = "NSMenuItem"; title = "Mark All"; ObjectID = "1011"; */
"1011.title" = "Mark All";
/* Class = "NSMenuItem"; title = "Mark None"; ObjectID = "1012"; */
"1012.title" = "Mark None";
/* Class = "NSMenuItem"; title = "Invert Marking"; ObjectID = "1013"; */
"1013.title" = "Invert Marking";
/* Class = "NSMenuItem"; title = "Mark Selected"; ObjectID = "1014"; */
"1014.title" = "Mark Selected";
/* Class = "NSMenuItem"; title = "dupeGuru Website"; ObjectID = "1023"; */
"1023.title" = "dupeGuru Website";
/* Class = "NSMenuItem"; title = "Invoke Custom Command"; ObjectID = "1177"; */
"1177.title" = "Invoke Custom Command";
/* Class = "NSMenuItem"; title = "File"; ObjectID = "1203"; */
"1203.title" = "File";
/* Class = "NSMenu"; title = "File"; ObjectID = "1204"; */
"1204.title" = "File";
/* Class = "NSMenuItem"; title = "Load Results..."; ObjectID = "1205"; */
"1205.title" = "Load Results...";
/* Class = "NSMenuItem"; title = "Save Results..."; ObjectID = "1206"; */
"1206.title" = "Save Results...";
/* Class = "NSMenuItem"; title = "Delete Marked and Replace with Hardlinks"; ObjectID = "1227"; */
"1227.title" = "Delete Marked and Replace with Hardlinks";
/* Class = "NSMenuItem"; title = "Load Recent Results"; ObjectID = "1239"; */
"1239.title" = "Load Recent Results";
/* Class = "NSMenu"; title = "Load Recent Results"; ObjectID = "1240"; */
"1240.title" = "Load Recent Results";
/* Class = "NSMenuItem"; title = "Results Window"; ObjectID = "1272"; */
"1272.title" = "Results Window";

View File

@@ -0,0 +1,18 @@
/* Class = "NSWindow"; title = "Problems!"; ObjectID = "1"; */
"1.title" = "Problems!";
/* Class = "NSTextFieldCell"; title = "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."; ObjectID = "4"; */
"4.title" = "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.";
/* Class = "NSTableColumn"; headerCell.title = "File Path"; ObjectID = "10"; */
"10.headerCell.title" = "File Path";
/* Class = "NSTableColumn"; headerCell.title = "Error Message"; ObjectID = "11"; */
"11.headerCell.title" = "Error Message";
/* Class = "NSButtonCell"; title = "Close"; ObjectID = "19"; */
"19.title" = "Close";
/* Class = "NSButtonCell"; title = "Reveal Selected"; ObjectID = "21"; */
"21.title" = "Reveal Selected";

View File

@@ -0,0 +1,99 @@
/* Class = "NSWindow"; title = "dupeGuru Results"; ObjectID = "1"; */
"1.title" = "dupeGuru Results";
/* Class = "NSTextFieldCell"; title = "Marked: 0 files, 0 B. Total: 0 files, 0 B."; ObjectID = "6"; */
"6.title" = "Marked: 0 files, 0 B. Total: 0 files, 0 B.";
/* Class = "NSTableColumn"; headerCell.title = "Name"; ObjectID = "11"; */
"11.headerCell.title" = "Name";
/* Class = "NSToolbarItem"; label = "Options"; ObjectID = "15"; */
"15.label" = "Options";
/* Class = "NSToolbarItem"; paletteLabel = "Options"; ObjectID = "15"; */
"15.paletteLabel" = "Options";
/* Class = "NSToolbarItem"; label = "Filter"; ObjectID = "16"; */
"16.label" = "Filter";
/* Class = "NSToolbarItem"; paletteLabel = "Filter"; ObjectID = "16"; */
"16.paletteLabel" = "Filter";
/* Class = "NSToolbarItem"; label = "Action"; ObjectID = "17"; */
"17.label" = "Action";
/* Class = "NSToolbarItem"; paletteLabel = "Action"; ObjectID = "17"; */
"17.paletteLabel" = "Action";
/* Class = "NSToolbarItem"; label = "Directories"; ObjectID = "19"; */
"19.label" = "Directories";
/* Class = "NSToolbarItem"; paletteLabel = "Directories"; ObjectID = "19"; */
"19.paletteLabel" = "Directories";
/* Class = "NSMenuItem"; title = "Delete Marked and Replace with Hardlinks"; ObjectID = "27"; */
"27.title" = "Delete Marked and Replace with Hardlinks";
/* Class = "NSMenuItem"; title = "Send Marked to Trash"; ObjectID = "29"; */
"29.title" = "Send Marked to Trash";
/* Class = "NSMenuItem"; title = "Move Marked to..."; ObjectID = "30"; */
"30.title" = "Move Marked to...";
/* Class = "NSMenuItem"; title = "Copy Marked to..."; ObjectID = "31"; */
"31.title" = "Copy Marked to...";
/* Class = "NSMenuItem"; title = "Remove Marked from Results"; ObjectID = "32"; */
"32.title" = "Remove Marked from Results";
/* Class = "NSMenuItem"; title = "Remove Selected from Results"; ObjectID = "34"; */
"34.title" = "Remove Selected from Results";
/* Class = "NSMenuItem"; title = "Add Selected to Ignore List"; ObjectID = "35"; */
"35.title" = "Add Selected to Ignore List";
/* Class = "NSMenuItem"; title = "Make Selected Reference"; ObjectID = "36"; */
"36.title" = "Make Selected Reference";
/* Class = "NSMenuItem"; title = "Open Selected with Default Application"; ObjectID = "38"; */
"38.title" = "Open Selected with Default Application";
/* Class = "NSMenuItem"; title = "Reveal Selected in Finder"; ObjectID = "39"; */
"39.title" = "Reveal Selected in Finder";
/* Class = "NSMenuItem"; title = "Rename Selected"; ObjectID = "40"; */
"40.title" = "Rename Selected";
/* Class = "NSSearchFieldCell"; placeholderString = "Filter"; ObjectID = "42"; */
"42.placeholderString" = "Filter";
/* Class = "NSSegmentedCell"; 44.labels[0] = "Details"; ObjectID = "44"; */
"44.labels[0]" = "Details";
/* Class = "NSSegmentedCell"; 44.labels[1] = "Dupes Only"; ObjectID = "44"; */
"44.labels[1]" = "Dupes Only";
/* Class = "NSSegmentedCell"; 44.labels[2] = "Delta"; ObjectID = "44"; */
"44.labels[2]" = "Delta";
/* Class = "NSMenu"; title = "Menu"; ObjectID = "67"; */
"67.title" = "Menu";
/* Class = "NSMenuItem"; title = "Add Selected to Ignore List"; ObjectID = "68"; */
"68.title" = "Add Selected to Ignore List";
/* Class = "NSMenuItem"; title = "Rename Selected"; ObjectID = "70"; */
"70.title" = "Rename Selected";
/* Class = "NSMenuItem"; title = "Remove Selected from Results"; ObjectID = "71"; */
"71.title" = "Remove Selected from Results";
/* Class = "NSMenuItem"; title = "Make Selected Reference"; ObjectID = "72"; */
"72.title" = "Make Selected Reference";
/* Class = "NSMenuItem"; title = "Reveal Selected in Finder"; ObjectID = "73"; */
"73.title" = "Reveal Selected in Finder";
/* Class = "NSMenuItem"; title = "Open Selected with Default Application"; ObjectID = "74"; */
"74.title" = "Open Selected with Default Application";

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
"Collecting files to scan" = "Collecting files to scan";
"%s (%d discarded)" = "%s (%d discarded)";
"Scanning for duplicates" = "Scanning for duplicates";
"Loading" = "Loading";
"Moving" = "Moving";
"Copying" = "Copying";
"Sending to Trash" = "Sending to Trash";
"0 matches found" = "0 matches found";
"%d matches found" = "%d matches found";
"Read size of %d/%d files" = "Read size of %d/%d files";
"Grouped %d/%d matches" = "Grouped %d/%d matches";
"%d / %d (%s / %s) duplicates marked." = "%d / %d (%s / %s) duplicates marked.";
" filter: %s" = " filter: %s";
"Read size of %d/%d files" = "Read size of %d/%d files";
"Read metadata of %d/%d files" = "Read metadata of %d/%d files";
"Removing false matches" = "Removing false matches";
"Processed %d/%d matches against the ignore list" = "Processed %d/%d matches against the ignore list";
"Doing group prioritization" = "Doing group prioritization";
"Analyzed %d/%d pictures" = "Analyzed %d/%d pictures";
"Preparing for matching" = "Preparing for matching";
"Matched %d/%d pictures" = "Matched %d/%d pictures";
"Verified %d/%d matches" = "Verified %d/%d matches";
"Removing dead tracks from your iTunes Library" = "Removing dead tracks from your iTunes Library";
"Scanning the iTunes Library" = "Scanning the iTunes Library";
"Probing iPhoto. Don't touch it during the operation!" = "Probing iPhoto. Don't touch it during the operation!";
"Sending dupes to the Trash" = "Sending dupes to the Trash";

View File

@@ -0,0 +1,12 @@
/* Class = "NSPanel"; title = "Details of Selected File"; ObjectID = "5"; */
"5.title" = "Détails du fichier sélectionné";
/* Class = "NSTableColumn"; headerCell.title = "Selected"; ObjectID = "9"; */
"9.headerCell.title" = "Sélectionné";
/* Class = "NSTableColumn"; headerCell.title = "Reference"; ObjectID = "10"; */
"10.headerCell.title" = "Référence";
/* Class = "NSTableColumn"; headerCell.title = "Attribute"; ObjectID = "11"; */
"11.headerCell.title" = "Attribut";

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,23 @@
/* Class = "NSTableColumn"; headerCell.title = "State"; ObjectID = "13"; */
"13.headerCell.title" = "Type";
/* Class = "NSTableColumn"; headerCell.title = "Name"; ObjectID = "15"; */
"15.headerCell.title" = "Nom";
/* Class = "NSButtonCell"; title = "Scan"; ObjectID = "48"; */
"48.title" = "Scan";
/* Class = "NSMenuItem"; title = "Normal"; ObjectID = "55"; */
"55.title" = "Normal";
/* Class = "NSMenuItem"; title = "Reference"; ObjectID = "56"; */
"56.title" = "Référence";
/* Class = "NSMenuItem"; title = "Excluded"; ObjectID = "57"; */
"57.title" = "Exclus";
/* Class = "NSTextFieldCell"; title = "Select folders to scan and press \"Scan\"."; ObjectID = "71"; */
"71.title" = "Sélectionnez les dossiers à scanner et cliquez sur Scan.";
/* Class = "NSButtonCell"; title = "Load Results"; ObjectID = "73"; */
"73.title" = "Charger";

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,63 @@
"Add New Folder..." = "Ajouter dossier...";
"Load from file..." = "Charger un fichier...";
"Reset to Default" = "Colonnes par défault";
"Add iTunes Directory" = "Ajouter librairie iTunes";
"Remove Dead Tracks in iTunes" = "Retirer les tracks mortes dans iTunes";
"Add iPhoto Library" = "Ajouter librairie iPhoto";
"Clear Picture Cache" = "Vider la cache d'images";
/* Columns */
"Folder" = "Dossier";
"Size (KB)" = "Taille (KB)";
"Size (MB)" = "Taille (MB)";
"Kind" = "Type";
"Modification" = "Modification";
"Match %" = "Match %";
"Words Used" = "Mots";
"Dupe Count" = "# Doublons";
"Time" = "Temps";
"Bitrate" = "Bitrate";
"Sample Rate" = "Sample Rate";
"Title" = "Titre";
"Artist" = "Artiste";
"Album" = "Album";
"Genre" = "Genre";
"Year" = "Année";
"Track Number" = "Track";
"Comment" = "Commentaire";
"Dimensions" = "Dimensions";
/* Messages */
"SelectResultToLoadMsg" = "Sélectionnez un fichier résultats à charger";
"SelectCopyDestinationMsg" = "Sélectionnez un dossier vers lequel copier les fichiers";
"SelectMoveDestinationMsg" = "Sélectionnez un dossier vers lequel déplacer les fichiers";
"SelectResultToSaveMsg" = "Sélectionnez un fichier résultats dans lequel sauvegarder";
"SelectFolderToAddMsg" = "Sélectionnez un dossier à ajouter à la liste";
"ReallyWantToQuitMsg" = "Vos résultats ne sont pas sauvegardés. Voulez-vous vraiment quitter?";
"ReallyWantToContinueMsg" = "Vos résultats ne sont pas sauvegardés. Voulez-vous vraiment continuer?";
"FolderAlreadyInListMsg" = "'%@' est déjà dans la liste.";
"FolderDoesNotExistMsg" = "'%@' n'existe pas.";
"FileRemovalConfirmMsg" = "%d fichiers seront retirés des résultats. Continuer?";
"FilenameAlreadyExistsMsg" = "Le nom '%@' existe déjà.";
"NoScannableFileMsg" = "Les dossiers sélectionnés ne continnent pas de fichiers valides.";
"UnknownErrorMsg" = "Erreur inconnue.";
"SendToTrashConfirmMsg" = "%d fichiers seront envoyés à la corbeille. Continuer?";
"HardlinkConfirmMsg" = "%d fichiers seront envoyés à la corbeille (puis 'hardlinkés'). Continuer?";
"ClearIgnoreListConfirmMsg" = "Voulez-vous vider la liste de fichiers ignorés des %d items qu'elle contient?";
"IgnoreConfirmMsg" = "%d fichiers seront ignorés des prochains scans. Continuer?";
"NoCustomCommandMsg" = "Vous n'avez pas de commande personnalisée. Ajoutez-la dans vos préférences.";
"CopySuccessMsg" = "Tous les fichiers marqués ont été copiés correctement.";
"MoveSuccessMsg" = "Tous les fichiers déplacés ont été copiés correctement.";
"SendToTrashSuccessMsg" = "Tous les fichiers marqués ont été correctement envoyés à la corbeille.";
"NoDuplicateFoundMsg" = "Aucun doublon trouvé.";
"TaskHangingMsg" = "Une action précédente est encore en cours. Attendez quelques secondes avant d'en repartir une nouvelle.";
"RemoveDeadTracksConfirmMsg" = "Votre librairie iTunes contient %d tracks mortes qui seront retirées. Continuer?";
"NoDeadTrackMsg" = "Votre librairie iTunes ne contient aucune track morte.";
"IPhotoAppNotFoundMsg" = "iPhoto n'a pas pu être trouvée dans vos applications.";
"ClearPictureCacheConfirmMsg" = "Voulez-vous vraiment vider la cache de vos analyses précédentes?";

View File

@@ -0,0 +1,174 @@
/* Class = "NSMenuItem"; title = "Bring All to Front"; ObjectID = "5"; */
"5.title" = "Tout ramener au premier plan";
/* Class = "NSMenuItem"; title = "Window"; ObjectID = "19"; */
"19.title" = "Fenêtre";
/* Class = "NSMenuItem"; title = "Minimize"; ObjectID = "23"; */
"23.title" = "Placer dans le Dock";
/* Class = "NSMenu"; title = "Window"; ObjectID = "24"; */
"24.title" = "Fenêtre";
/* Class = "NSMenuItem"; title = "About dupeGuru"; ObjectID = "58"; */
"58.title" = "À propos de dupeGuru";
/* Class = "NSMenuItem"; title = "Help"; ObjectID = "103"; */
"103.title" = "Aide";
/* Class = "NSMenu"; title = "Help"; ObjectID = "106"; */
"106.title" = "Aide";
/* Class = "NSMenuItem"; title = "dupeGuru Help"; ObjectID = "111"; */
"111.title" = "Aide dupeGuru";
/* Class = "NSMenuItem"; title = "Hide dupeGuru"; ObjectID = "134"; */
"134.title" = "Masquer dupeGuru";
/* Class = "NSMenuItem"; title = "Quit dupeGuru"; ObjectID = "136"; */
"136.title" = "Quitter dupeGuru";
/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "145"; */
"145.title" = "Masquer les autres";
/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "150"; */
"150.title" = "Tout afficher";
/* Class = "NSMenuItem"; title = "Zoom"; ObjectID = "197"; */
"197.title" = "Réduire/agrandir";
/* Class = "NSMenuItem"; title = "Details Panel"; ObjectID = "398"; */
"398.title" = "Fenêtre de détails";
/* Class = "NSMenuItem"; title = "Preferences..."; ObjectID = "541"; */
"541.title" = "Préférences...";
/* Class = "NSMenuItem"; title = "Folder Selection Window"; ObjectID = "579"; */
"579.title" = "Fenêtre de sélection de dossiers";
/* Class = "NSMenuItem"; title = "Actions"; ObjectID = "597"; */
"597.title" = "Actions";
/* Class = "NSMenu"; title = "Actions"; ObjectID = "598"; */
"598.title" = "Actions";
/* Class = "NSMenuItem"; title = "Send Marked to Trash"; ObjectID = "599"; */
"599.title" = "Envoyer marqués à la corbeille";
/* Class = "NSMenuItem"; title = "Move Marked to..."; ObjectID = "600"; */
"600.title" = "Déplacer marqués vers...";
/* Class = "NSMenuItem"; title = "Copy Marked to..."; ObjectID = "601"; */
"601.title" = "Copier marqués vers...";
/* Class = "NSMenuItem"; title = "Make Selected Reference"; ObjectID = "602"; */
"602.title" = "Transformer sélectionnés en références";
/* Class = "NSMenuItem"; title = "Remove Marked from Results"; ObjectID = "603"; */
"603.title" = "Retirer marqués des résultats";
/* Class = "NSMenuItem"; title = "Remove Selected from Results"; ObjectID = "605"; */
"605.title" = "Retirer sélectionnés des résultats";
/* Class = "NSMenuItem"; title = "Columns"; ObjectID = "618"; */
"618.title" = "Colonnes";
/* Class = "NSMenu"; title = "Columns"; ObjectID = "619"; */
"619.title" = "Colonnes";
/* Class = "NSMenuItem"; title = "Open Selected with Default Application"; ObjectID = "708"; */
"708.title" = "Ouvrir sélectionné avec l'application par défaut";
/* Class = "NSMenuItem"; title = "Reveal Selected in Finder"; ObjectID = "710"; */
"710.title" = "Révéler sélectionné dans Finder";
/* Class = "NSMenuItem"; title = "Add Selected to Ignore List"; ObjectID = "922"; */
"922.title" = "Ajouter sélectionnés à la liste de fichiers ignorés";
/* Class = "NSMenuItem"; title = "Close Window"; ObjectID = "924"; */
"924.title" = "Fermer";
/* Class = "NSMenuItem"; title = "Start Duplicate Scan"; ObjectID = "926"; */
"926.title" = "Commencer à scanner";
/* Class = "NSMenuItem"; title = "Clear Ignore List"; ObjectID = "927"; */
"927.title" = "Vider la liste de fichiers ignorés";
/* Class = "NSMenuItem"; title = "Rename Selected"; ObjectID = "933"; */
"933.title" = "Renommer sélectionné";
/* Class = "NSMenuItem"; title = "Export Results to XHTML"; ObjectID = "947"; */
"947.title" = "Exporter les résultats vers HTML";
/* Class = "NSMenuItem"; title = "Check for update..."; ObjectID = "950"; */
"950.title" = "Mise à jour...";
/* Class = "NSMenuItem"; title = "Mode"; ObjectID = "959"; */
"959.title" = "Mode";
/* Class = "NSMenu"; title = "Mode"; ObjectID = "960"; */
"960.title" = "Mode";
/* Class = "NSMenuItem"; title = "Show Dupes Only"; ObjectID = "961"; */
"961.title" = "Ne pas montrer les références";
/* Class = "NSMenuItem"; title = "Show Delta Values"; ObjectID = "962"; */
"962.title" = "Montrer les valeurs en tant que delta";
/* Class = "NSMenuItem"; title = "Edit"; ObjectID = "965"; */
"965.title" = "Édition";
/* Class = "NSMenu"; title = "Edit"; ObjectID = "966"; */
"966.title" = "Édition";
/* Class = "NSMenuItem"; title = "Cut"; ObjectID = "985"; */
"985.title" = "Couper";
/* Class = "NSMenuItem"; title = "Copy"; ObjectID = "986"; */
"986.title" = "Copier";
/* Class = "NSMenuItem"; title = "Paste"; ObjectID = "991"; */
"991.title" = "Coller";
/* Class = "NSMenuItem"; title = "Mark All"; ObjectID = "1011"; */
"1011.title" = "Tout marquer";
/* Class = "NSMenuItem"; title = "Mark None"; ObjectID = "1012"; */
"1012.title" = "Tout démarquer";
/* Class = "NSMenuItem"; title = "Invert Marking"; ObjectID = "1013"; */
"1013.title" = "Inverser le marquage";
/* Class = "NSMenuItem"; title = "Mark Selected"; ObjectID = "1014"; */
"1014.title" = "Marquer sélectionnés";
/* Class = "NSMenuItem"; title = "dupeGuru Website"; ObjectID = "1023"; */
"1023.title" = "Site web de dupeGuru";
/* Class = "NSMenuItem"; title = "Invoke Custom Command"; ObjectID = "1177"; */
"1177.title" = "Invoquer commande personnalisée";
/* Class = "NSMenuItem"; title = "File"; ObjectID = "1203"; */
"1203.title" = "Fichier";
/* Class = "NSMenu"; title = "File"; ObjectID = "1204"; */
"1204.title" = "Fichier";
/* Class = "NSMenuItem"; title = "Load Results..."; ObjectID = "1205"; */
"1205.title" = "Charger résultats...";
/* Class = "NSMenuItem"; title = "Save Results..."; ObjectID = "1206"; */
"1206.title" = "Sauvegarder résultats...";
/* Class = "NSMenuItem"; title = "Delete Marked and Replace with Hardlinks"; ObjectID = "1227"; */
"1227.title" = "Remplacer marqués par des hardlinks";
/* Class = "NSMenuItem"; title = "Load Recent Results"; ObjectID = "1239"; */
"1239.title" = "Charger résultats récents";
/* Class = "NSMenu"; title = "Load Recent Results"; ObjectID = "1240"; */
"1240.title" = "Charger résultats récents";
/* Class = "NSMenuItem"; title = "Results Window"; ObjectID = "1272"; */
"1272.title" = "Fenêtre de résultats";

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,19 @@
/* Class = "NSWindow"; title = "Problems!"; ObjectID = "1"; */
"1.title" = "Problèmes!";
/* Class = "NSTextFieldCell"; title = "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."; ObjectID = "4"; */
"4.title" = "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.";
"4.title" = "Il y a eu des problèmes lors du traitement de certain (ou tous) fichiers. La cause de ces problèmes est décrite ci-dessous. Ces fichiers n'ont pas été enlevés des résultats.";
/* Class = "NSTableColumn"; headerCell.title = "File Path"; ObjectID = "10"; */
"10.headerCell.title" = "Chemin du fichier";
/* Class = "NSTableColumn"; headerCell.title = "Error Message"; ObjectID = "11"; */
"11.headerCell.title" = "Message d'erreur";
/* Class = "NSButtonCell"; title = "Close"; ObjectID = "19"; */
"19.title" = "Fermer";
/* Class = "NSButtonCell"; title = "Reveal Selected"; ObjectID = "21"; */
"21.title" = "Révéler Fichier";

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,96 @@
/* Class = "NSWindow"; title = "dupeGuru Results"; ObjectID = "1"; */
"1.title" = "dupeGuru (Résultats)";
/* Class = "NSTextFieldCell"; title = "Marked: 0 files, 0 B. Total: 0 files, 0 B."; ObjectID = "6"; */
"6.title" = "Marqués: 0 fichiers, 0 B. Total: 0 fichiers, 0 B.";
/* Class = "NSTableColumn"; headerCell.title = "Name"; ObjectID = "11"; */
"11.headerCell.title" = "Nom";
/* Class = "NSToolbarItem"; label = "Options"; ObjectID = "15"; */
"15.label" = "Options";
/* Class = "NSToolbarItem"; paletteLabel = "Options"; ObjectID = "15"; */
"15.paletteLabel" = "Options";
/* Class = "NSToolbarItem"; label = "Filter"; ObjectID = "16"; */
"16.label" = "Filtre";
/* Class = "NSToolbarItem"; paletteLabel = "Filter"; ObjectID = "16"; */
"16.paletteLabel" = "Filtre";
/* Class = "NSToolbarItem"; label = "Action"; ObjectID = "17"; */
"17.label" = "Action";
/* Class = "NSToolbarItem"; paletteLabel = "Action"; ObjectID = "17"; */
"17.paletteLabel" = "Action";
/* Class = "NSToolbarItem"; label = "Directories"; ObjectID = "19"; */
"19.label" = "Dossiers";
/* Class = "NSToolbarItem"; paletteLabel = "Directories"; ObjectID = "19"; */
"19.paletteLabel" = "Dossiers";
/* Class = "NSMenuItem"; title = "Delete Marked and Replace with Hardlinks"; ObjectID = "27"; */
"27.title" = "Remplacer marqués par des hardlinks";
/* Class = "NSMenuItem"; title = "Send Marked to Trash"; ObjectID = "29"; */
"29.title" = "Envoyer marqués à la corbeille";
/* Class = "NSMenuItem"; title = "Move Marked to..."; ObjectID = "30"; */
"30.title" = "Déplacer marqués vers...";
/* Class = "NSMenuItem"; title = "Copy Marked to..."; ObjectID = "31"; */
"31.title" = "Copier marqués vers...";
/* Class = "NSMenuItem"; title = "Remove Marked from Results"; ObjectID = "32"; */
"32.title" = "Retirer marqués des résultats";
/* Class = "NSMenuItem"; title = "Remove Selected from Results"; ObjectID = "34"; */
"34.title" = "Retirer sélectionnés des résultats";
/* Class = "NSMenuItem"; title = "Add Selected to Ignore List"; ObjectID = "35"; */
"35.title" = "Ajouter sélectionnés à la liste de fichiers ignorés";
/* Class = "NSMenuItem"; title = "Make Selected Reference"; ObjectID = "36"; */
"36.title" = "Transformer sélectionnés en références";
/* Class = "NSMenuItem"; title = "Open Selected with Default Application"; ObjectID = "38"; */
"38.title" = "Ouvrir sélectionné avec l'application par défaut";
/* Class = "NSMenuItem"; title = "Reveal Selected in Finder"; ObjectID = "39"; */
"39.title" = "Révéler sélectionné dans Finder";
/* Class = "NSMenuItem"; title = "Rename Selected"; ObjectID = "40"; */
"40.title" = "Renommer sélectionné";
/* Class = "NSSearchFieldCell"; placeholderString = "Filter"; ObjectID = "42"; */
"42.placeholderString" = "Filtre";
/* Class = "NSSegmentedCell"; 44.labels[0] = "Details"; ObjectID = "44"; */
"44.labels[0]" = "Détails";
/* Class = "NSSegmentedCell"; 44.labels[1] = "Dupes Only"; ObjectID = "44"; */
"44.labels[1]" = "Sans réf.";
/* Class = "NSSegmentedCell"; 44.labels[2] = "Delta"; ObjectID = "44"; */
"44.labels[2]" = "Delta";
/* Class = "NSMenuItem"; title = "Add Selected to Ignore List"; ObjectID = "68"; */
"68.title" = "Ajouter sélectionnés à la liste de fichiers ignorés";
/* Class = "NSMenuItem"; title = "Rename Selected"; ObjectID = "70"; */
"70.title" = "Renommer sélectionné";
/* Class = "NSMenuItem"; title = "Remove Selected from Results"; ObjectID = "71"; */
"71.title" = "Retirer sélectionnés des résultats";
/* Class = "NSMenuItem"; title = "Make Selected Reference"; ObjectID = "72"; */
"72.title" = "Transformer sélectionnés en références";
/* Class = "NSMenuItem"; title = "Reveal Selected in Finder"; ObjectID = "73"; */
"73.title" = "Révéler sélectionné dans Finder";
/* Class = "NSMenuItem"; title = "Open Selected with Default Application"; ObjectID = "74"; */
"74.title" = "Ouvrir sélectionné avec l'application par défaut";

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,28 @@
"Collecting files to scan" = "Collecte des fichiers à scanner";
"%s (%d discarded)" = "%s (%d hors-groupe)";
"Scanning for duplicates" = "Scan de doublons en cours";
"Loading" = "Chargement en cours";
"Moving" = "Déplacement en cours";
"Copying" = "Copie en cours";
"Sending to Trash" = "Envoi vers corbeille";
"0 matches found" = "0 paires trouvées";
"%d matches found" = "%d paires trouvées";
"Read size of %d/%d files" = "Lu la taille de %d/%d fichiers";
"Grouped %d/%d matches" = "%d/%d paires groupées";
"%d / %d (%s / %s) duplicates marked." = "%d / %d (%s / %s) doublons marqués.";
" filter: %s" = " filtre: %s";
"Read metadata of %d/%d files" = "Lu les métadonnées de %d/%d fichiers";
"Removing false matches" = "Retrait des paires invalides";
"Processed %d/%d matches against the ignore list" = "Vérification de %d/%d paires dans la ignore list";
"Doing group prioritization" = "Prioritization des groupes";
"Analyzed %d/%d pictures" = "Analyzé %d/%d images";
"Preparing for matching" = "Préparation pour la comparaison";
"Matched %d/%d pictures" = "Comparé %d/%d images";
"Verified %d/%d matches" = "Vérifié %d/%d paires";
"Removing dead tracks from your iTunes Library" = "Retrait des tracks mortes de votre librairie iTunes";
"Scanning the iTunes Library" = "Scan de la librairie iTunes en cours";
"Probing iPhoto. Don't touch it during the operation!" = "Communication avec iPhoto en cours. N'y touchez pas!";
"Sending dupes to the Trash" = "Envoi de doublons à la corbeille en cours";

View File

@@ -12,8 +12,5 @@ http://www.hardcoded.net/licenses/bsd_license
#import "PyDupeGuru.h" #import "PyDupeGuru.h"
@interface AppDelegate : AppDelegateBase {} @interface AppDelegate : AppDelegateBase {}
- (IBAction)openWebsite:(id)sender;
- (IBAction)toggleDirectories:(id)sender;
- (PyDupeGuru *)py; - (PyDupeGuru *)py;
@end @end

View File

@@ -7,12 +7,13 @@ http://www.hardcoded.net/licenses/bsd_license
*/ */
#import "AppDelegate.h" #import "AppDelegate.h"
#import "../../cocoalib/ProgressController.h" #import "ProgressController.h"
#import "../../cocoalib/Utils.h" #import "Utils.h"
#import "../../cocoalib/ValueTransformers.h" #import "ValueTransformers.h"
#import "../../cocoalib/Dialogs.h" #import "Dialogs.h"
#import "DetailsPanel.h" #import "DetailsPanel.h"
#import "DirectoryPanel.h" #import "DirectoryPanel.h"
#import "ResultWindow.h"
#import "Consts.h" #import "Consts.h"
@implementation AppDelegate @implementation AppDelegate
@@ -56,32 +57,30 @@ http://www.hardcoded.net/licenses/bsd_license
return self; return self;
} }
- (IBAction)openWebsite:(id)sender - (NSString *)homepageURL
{ {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://www.hardcoded.net/dupeguru_me"]]; return @"http://www.hardcoded.net/dupeguru_me/";
} }
- (IBAction)toggleDirectories:(id)sender - (ResultWindowBase *)createResultWindow
{ {
[[self directoryPanel] toggleVisible:sender]; return [[ResultWindow alloc] initWithParentApp:self];
} }
- (DirectoryPanel *)directoryPanel - (DirectoryPanel *)createDirectoryPanel
{ {
if (!_directoryPanel) return [[DirectoryPanelME alloc] initWithParentApp:self];
_directoryPanel = [[DirectoryPanelME alloc] initWithParentApp:self];
return _directoryPanel;
} }
- (PyDupeGuru *)py { return (PyDupeGuru *)py; } - (PyDupeGuru *)py { return (PyDupeGuru *)py; }
//Delegate //Delegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{ {
NSMenu *actionsMenu = [[[NSApp mainMenu] itemWithTitle:@"Actions"] submenu];
// index 3 is just after "Export Results to XHTML" // index 3 is just after "Export Results to XHTML"
NSMenuItem *mi = [actionsMenu insertItemWithTitle:@"Remove Dead Tracks in iTunes" NSMenuItem *mi = [actionsMenu insertItemWithTitle:TR(@"Remove Dead Tracks in iTunes")
action:@selector(removeDeadTracks:) keyEquivalent:@"" atIndex:3]; action:@selector(removeDeadTracks:) keyEquivalent:@"" atIndex:3];
[mi setTarget:result]; [mi setTarget:[self resultWindow]];
[super applicationDidFinishLaunching:aNotification]; [super applicationDidFinishLaunching:aNotification];
} }
@end @end

View File

@@ -7,25 +7,28 @@ http://www.hardcoded.net/licenses/bsd_license
*/ */
#import "DirectoryPanel.h" #import "DirectoryPanel.h"
#import "Consts.h"
@implementation DirectoryPanelME @implementation DirectoryPanelME
- (id)initWithParentApp:(id)aParentApp
{
self = [super initWithParentApp:aParentApp];
[[self window] setTitle:@"dupeGuru Music Edition"];
_alwaysShowPopUp = YES;
return self;
}
- (void)fillPopUpMenu
{
[super fillPopUpMenu];
NSMenu *m = [addButtonPopUp menu];
NSMenuItem *mi = [m insertItemWithTitle:TR(@"Add iTunes Directory") action:@selector(addiTunes:)
keyEquivalent:@"" atIndex:1];
[mi setTarget:self];
}
- (IBAction)addiTunes:(id)sender - (IBAction)addiTunes:(id)sender
{ {
[self addDirectory:[@"~/Music/iTunes/iTunes Music" stringByExpandingTildeInPath]]; [self addDirectory:[@"~/Music/iTunes/iTunes Music" stringByExpandingTildeInPath]];
} }
- (IBAction)popupAddDirectoryMenu:(id)sender
{
NSMenu *m = [addButtonPopUp menu];
while ([m numberOfItems] > 0)
[m removeItemAtIndex:0];
NSMenuItem *mi = [m addItemWithTitle:@"Add New Directory..." action:@selector(askForDirectory:) keyEquivalent:@""];
[mi setTarget:self];
mi = [m addItemWithTitle:@"Add iTunes Directory" action:@selector(addiTunes:) keyEquivalent:@""];
[mi setTarget:self];
[m addItem:[NSMenuItem separatorItem]];
[_recentDirectories fillMenu:m];
[addButtonPopUp selectItem: nil];
[[addButtonPopUp cell] performClickWithFrame:[sender frame] inView:[sender superview]];
}
@end @end

View File

@@ -23,7 +23,7 @@
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>hsft</string> <string>hsft</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>5.10.2</string> <string>{version}</string>
<key>NSMainNibFile</key> <key>NSMainNibFile</key>
<string>MainMenu</string> <string>MainMenu</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>

View File

@@ -8,7 +8,6 @@ http://www.hardcoded.net/licenses/bsd_license
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import "../base/ResultWindow.h" #import "../base/ResultWindow.h"
#import "DirectoryPanel.h"
@interface ResultWindow : ResultWindowBase {} @interface ResultWindow : ResultWindowBase {}
- (IBAction)removeDeadTracks:(id)sender; - (IBAction)removeDeadTracks:(id)sender;

View File

@@ -7,21 +7,59 @@ http://www.hardcoded.net/licenses/bsd_license
*/ */
#import "ResultWindow.h" #import "ResultWindow.h"
#import "../../cocoalib/Dialogs.h" #import "Dialogs.h"
#import "../../cocoalib/ProgressController.h" #import "Utils.h"
#import "../../cocoalib/Utils.h" #import "PyDupeGuru.h"
#import "AppDelegate.h"
#import "Consts.h" #import "Consts.h"
@implementation ResultWindow @implementation ResultWindow
/* Override */ /* Override */
- (void)awakeFromNib - (void)setScanOptions
{ {
[super awakeFromNib]; NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
[[self window] setTitle:@"dupeGuru Music Edition"]; PyDupeGuru *_py = (PyDupeGuru *)py;
NSMutableIndexSet *deltaColumns = [NSMutableIndexSet indexSetWithIndexesInRange:NSMakeRange(2,6)]; [_py setScanType:[ud objectForKey:@"scanType"]];
[deltaColumns removeIndex:6]; [_py enable:[ud objectForKey:@"scanTagTrack"] scanForTag:@"track"];
[table setDeltaColumns:deltaColumns]; [_py enable:[ud objectForKey:@"scanTagArtist"] scanForTag:@"artist"];
[_py enable:[ud objectForKey:@"scanTagAlbum"] scanForTag:@"album"];
[_py enable:[ud objectForKey:@"scanTagTitle"] scanForTag:@"title"];
[_py enable:[ud objectForKey:@"scanTagGenre"] scanForTag:@"genre"];
[_py enable:[ud objectForKey:@"scanTagYear"] scanForTag:@"year"];
[_py setMinMatchPercentage:[ud objectForKey:@"minMatchPercentage"]];
[_py setWordWeighting:[ud objectForKey:@"wordWeighting"]];
[_py setMixFileKind:n2b([ud objectForKey:@"mixFileKind"])];
[_py setIgnoreHardlinkMatches:n2b([ud objectForKey:@"ignoreHardlinkMatches"])];
[_py setMatchSimilarWords:[ud objectForKey:@"matchSimilarWords"]];
}
- (void)initResultColumns
{
NSTableColumn *refCol = [matches tableColumnWithIdentifier:@"0"];
_resultColumns = [[NSMutableArray alloc] init];
[_resultColumns addObject:[matches tableColumnWithIdentifier:@"0"]]; // File Name
[_resultColumns addObject:[self getColumnForIdentifier:1 title:TR(@"Folder") width:120 refCol:refCol]];
NSTableColumn *sizeCol = [self getColumnForIdentifier:2 title:TR(@"Size (MB)") width:63 refCol:refCol];
[[sizeCol dataCell] setAlignment:NSRightTextAlignment];
[_resultColumns addObject:sizeCol];
NSTableColumn *timeCol = [self getColumnForIdentifier:3 title:TR(@"Time") width:50 refCol:refCol];
[[timeCol dataCell] setAlignment:NSRightTextAlignment];
[_resultColumns addObject:timeCol];
NSTableColumn *brCol = [self getColumnForIdentifier:4 title:TR(@"Bitrate") width:50 refCol:refCol];
[[brCol dataCell] setAlignment:NSRightTextAlignment];
[_resultColumns addObject:brCol];
[_resultColumns addObject:[self getColumnForIdentifier:5 title:TR(@"Sample Rate") width:60 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:6 title:TR(@"Kind") width:40 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:7 title:TR(@"Modification") width:120 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:8 title:TR(@"Title") width:120 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:9 title:TR(@"Artist") width:120 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:10 title:TR(@"Album") width:120 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:11 title:TR(@"Genre") width:80 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:12 title:TR(@"Year") width:40 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:13 title:TR(@"Track Number") width:40 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:14 title:TR(@"Comment") width:120 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:15 title:TR(@"Match %") width:57 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:16 title:TR(@"Words Used") width:120 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:17 title:TR(@"Dupe Count") width:80 refCol:refCol]];
} }
/* Actions */ /* Actions */
@@ -49,83 +87,20 @@ http://www.hardcoded.net/licenses/bsd_license
[self restoreColumnsPosition:columnsOrder widths:columnsWidth]; [self restoreColumnsPosition:columnsOrder widths:columnsWidth];
} }
- (IBAction)startDuplicateScan:(id)sender
{
if ([matches numberOfRows] > 0)
{
if ([Dialogs askYesNo:@"Are you sure you want to start a new duplicate scan?"] == NSAlertSecondButtonReturn) // NO
return;
}
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
PyDupeGuru *_py = (PyDupeGuru *)py;
[_py setScanType:[ud objectForKey:@"scanType"]];
[_py enable:[ud objectForKey:@"scanTagTrack"] scanForTag:@"track"];
[_py enable:[ud objectForKey:@"scanTagArtist"] scanForTag:@"artist"];
[_py enable:[ud objectForKey:@"scanTagAlbum"] scanForTag:@"album"];
[_py enable:[ud objectForKey:@"scanTagTitle"] scanForTag:@"title"];
[_py enable:[ud objectForKey:@"scanTagGenre"] scanForTag:@"genre"];
[_py enable:[ud objectForKey:@"scanTagYear"] scanForTag:@"year"];
[_py setMinMatchPercentage:[ud objectForKey:@"minMatchPercentage"]];
[_py setWordWeighting:[ud objectForKey:@"wordWeighting"]];
[_py setMixFileKind:n2b([ud objectForKey:@"mixFileKind"])];
[_py setIgnoreHardlinkMatches:n2b([ud objectForKey:@"ignoreHardlinkMatches"])];
[_py setMatchSimilarWords:[ud objectForKey:@"matchSimilarWords"]];
NSInteger r = n2i([py doScan]);
if (r == 3)
{
[Dialogs showMessage:@"The selected directories contain no scannable file."];
[app toggleDirectories:nil];
}
}
/* Public */
- (void)initResultColumns
{
NSTableColumn *refCol = [matches tableColumnWithIdentifier:@"0"];
_resultColumns = [[NSMutableArray alloc] init];
[_resultColumns addObject:[matches tableColumnWithIdentifier:@"0"]]; // File Name
[_resultColumns addObject:[self getColumnForIdentifier:1 title:@"Directory" width:120 refCol:refCol]];
NSTableColumn *sizeCol = [self getColumnForIdentifier:2 title:@"Size (MB)" width:63 refCol:refCol];
[[sizeCol dataCell] setAlignment:NSRightTextAlignment];
[_resultColumns addObject:sizeCol];
NSTableColumn *timeCol = [self getColumnForIdentifier:3 title:@"Time" width:50 refCol:refCol];
[[timeCol dataCell] setAlignment:NSRightTextAlignment];
[_resultColumns addObject:timeCol];
NSTableColumn *brCol = [self getColumnForIdentifier:4 title:@"Bitrate" width:50 refCol:refCol];
[[brCol dataCell] setAlignment:NSRightTextAlignment];
[_resultColumns addObject:brCol];
[_resultColumns addObject:[self getColumnForIdentifier:5 title:@"Sample Rate" width:60 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:6 title:@"Kind" width:40 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:7 title:@"Modification" width:120 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:8 title:@"Title" width:120 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:9 title:@"Artist" width:120 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:10 title:@"Album" width:120 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:11 title:@"Genre" width:80 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:12 title:@"Year" width:40 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:13 title:@"Track Number" width:40 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:14 title:@"Comment" width:120 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:15 title:@"Match %" width:57 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:16 title:@"Words Used" width:120 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:17 title:@"Dupe Count" width:80 refCol:refCol]];
}
/* Notifications */ /* Notifications */
- (void)jobCompleted:(NSNotification *)aNotification - (void)jobCompleted:(NSNotification *)aNotification
{ {
[super jobCompleted:aNotification]; [super jobCompleted:aNotification];
id lastAction = [[ProgressController mainProgressController] jobId]; id lastAction = [[ProgressController mainProgressController] jobId];
if ([lastAction isEqualTo:jobScanDeadTracks]) if ([lastAction isEqualTo:jobScanDeadTracks]) {
{
NSInteger deadTrackCount = [(PyDupeGuru *)py deadTrackCount]; NSInteger deadTrackCount = [(PyDupeGuru *)py deadTrackCount];
if (deadTrackCount > 0) if (deadTrackCount > 0) {
{ NSString *msg = TR(@"RemoveDeadTracksConfirmMsg");
NSString *msg = @"Your iTunes Library contains %d dead tracks ready to be removed. Continue?";
if ([Dialogs askYesNo:[NSString stringWithFormat:msg,deadTrackCount]] == NSAlertFirstButtonReturn) if ([Dialogs askYesNo:[NSString stringWithFormat:msg,deadTrackCount]] == NSAlertFirstButtonReturn)
[(PyDupeGuru *)py removeDeadTracks]; [(PyDupeGuru *)py removeDeadTracks];
} }
else else {
{ [Dialogs showMessage:TR(@"NoDeadTrackMsg")];
[Dialogs showMessage:@"You have no dead tracks in your iTunes Library"];
} }
} }
} }

View File

@@ -4,24 +4,16 @@
# 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 install_cocoa_trans
install_cocoa_trans()
from hscommon.cocoa import signature from hscommon.cocoa import signature
from core.app_cocoa_inter import PyDupeGuruBase, PyDetailsPanel from core.app_cocoa_inter import PyDupeGuruBase, PyDetailsPanel
from core_me.app_cocoa import DupeGuruME from core_me.app_cocoa import DupeGuruME
from core_me import __appname__
from core.scanner import ScanType from core.scanner import ScanType
# Fix py2app imports which chokes on relative imports and other stuff
import core_me.app_cocoa, core_me.data, core_me.fs, core_me.scanner
import hsaudiotag.aiff, hsaudiotag.flac, hsaudiotag.genres, hsaudiotag.id3v1,\
hsaudiotag.id3v2, hsaudiotag.mp4, hsaudiotag.mpeg, hsaudiotag.ogg, hsaudiotag.wma
from hsaudiotag import aiff, flac, genres, id3v1, id3v2, mp4, mpeg, ogg, wma
import hsutil.conflict
import core.engine, core.fs, core.app
import xml.etree.ElementPath
import gzip
import aem.kae
import appscript.defaultterminology
class PyDupeGuru(PyDupeGuruBase): class PyDupeGuru(PyDupeGuruBase):
def init(self): def init(self):
self = super(PyDupeGuru,self).init() self = super(PyDupeGuru,self).init()
@@ -70,5 +62,5 @@ class PyDupeGuru(PyDupeGuruBase):
#---Registration #---Registration
def appName(self): def appName(self):
return "dupeGuru Music Edition" return __appname__

View File

@@ -29,24 +29,31 @@
CE003CCB11242D00004B0AA7 /* NSIndexPathAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE003CC311242D00004B0AA7 /* NSIndexPathAdditions.m */; }; CE003CCB11242D00004B0AA7 /* NSIndexPathAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE003CC311242D00004B0AA7 /* NSIndexPathAdditions.m */; };
CE003CCC11242D00004B0AA7 /* NSTableViewAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE003CC511242D00004B0AA7 /* NSTableViewAdditions.m */; }; CE003CCC11242D00004B0AA7 /* NSTableViewAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE003CC511242D00004B0AA7 /* NSTableViewAdditions.m */; };
CE003CD011242D2C004B0AA7 /* DirectoryOutline.m in Sources */ = {isa = PBXBuildFile; fileRef = CE003CCE11242D2C004B0AA7 /* DirectoryOutline.m */; }; CE003CD011242D2C004B0AA7 /* DirectoryOutline.m in Sources */ = {isa = PBXBuildFile; fileRef = CE003CCE11242D2C004B0AA7 /* DirectoryOutline.m */; };
CE073F6309CAE1A3005C1D2F /* dupeguru_me_help in Resources */ = {isa = PBXBuildFile; fileRef = CE073F5409CAE1A3005C1D2F /* dupeguru_me_help */; }; CE05331712E5D3ED0029EF25 /* DetailsPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE05330D12E5D3ED0029EF25 /* DetailsPanel.xib */; };
CE05331812E5D3ED0029EF25 /* DirectoryPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE05330F12E5D3ED0029EF25 /* DirectoryPanel.xib */; };
CE05331912E5D3ED0029EF25 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE05331112E5D3ED0029EF25 /* MainMenu.xib */; };
CE05331A12E5D3ED0029EF25 /* ProblemDialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE05331312E5D3ED0029EF25 /* ProblemDialog.xib */; };
CE05331B12E5D3ED0029EF25 /* ResultWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE05331512E5D3ED0029EF25 /* ResultWindow.xib */; };
CE05332312E5D4100029EF25 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE05332112E5D4100029EF25 /* Preferences.xib */; };
CE05332F12E5D6100029EF25 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = CE05332D12E5D6100029EF25 /* Localizable.strings */; };
CE073F6309CAE1A3005C1D2F /* help in Resources */ = {isa = PBXBuildFile; fileRef = CE073F5409CAE1A3005C1D2F /* help */; };
CE0A0C001175A1C000DCA3C6 /* HSTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0A0BFF1175A1C000DCA3C6 /* HSTable.m */; }; CE0A0C001175A1C000DCA3C6 /* HSTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0A0BFF1175A1C000DCA3C6 /* HSTable.m */; };
CE0A0C041175A1DE00DCA3C6 /* ProblemDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0A0C021175A1DE00DCA3C6 /* ProblemDialog.m */; }; CE0A0C041175A1DE00DCA3C6 /* ProblemDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0A0C021175A1DE00DCA3C6 /* ProblemDialog.m */; };
CE0A0C061175A24800DCA3C6 /* ProblemDialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE0A0C051175A24800DCA3C6 /* ProblemDialog.xib */; };
CE1425890AFB718500BD5167 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE1425880AFB718500BD5167 /* Sparkle.framework */; }; CE1425890AFB718500BD5167 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE1425880AFB718500BD5167 /* Sparkle.framework */; };
CE14259F0AFB719300BD5167 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE1425880AFB718500BD5167 /* Sparkle.framework */; }; CE14259F0AFB719300BD5167 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE1425880AFB718500BD5167 /* Sparkle.framework */; };
CE1EAA0A12DF3E81009BA949 /* HSRecentFiles.m in Sources */ = {isa = PBXBuildFile; fileRef = CE1EAA0912DF3E81009BA949 /* HSRecentFiles.m */; };
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; }; CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; };
CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9A09914ADF003581CE /* ResultWindow.m */; }; CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9A09914ADF003581CE /* ResultWindow.m */; };
CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */ = {isa = PBXBuildFile; fileRef = CE381CF509915304003581CE /* dg_cocoa.plugin */; }; CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */ = {isa = PBXBuildFile; fileRef = CE381CF509915304003581CE /* dg_cocoa.plugin */; };
CE3FBDD31094637800B72D77 /* DetailsPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE3FBDD11094637800B72D77 /* DetailsPanel.xib */; }; CE45274F12E5F62D00005A15 /* core.strings in Resources */ = {isa = PBXBuildFile; fileRef = CE45274D12E5F62D00005A15 /* core.strings */; };
CE3FBDD41094637800B72D77 /* DirectoryPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE3FBDD21094637800B72D77 /* DirectoryPanel.xib */; };
CE49DEF60FDFEB810098617B /* BRSingleLineFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = CE49DEF30FDFEB810098617B /* BRSingleLineFormatter.m */; }; CE49DEF60FDFEB810098617B /* BRSingleLineFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = CE49DEF30FDFEB810098617B /* BRSingleLineFormatter.m */; };
CE4B59C81119919700C06C9E /* ErrorReportWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE4B59C51119919700C06C9E /* ErrorReportWindow.xib */; }; CE4B59C81119919700C06C9E /* ErrorReportWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE4B59C51119919700C06C9E /* ErrorReportWindow.xib */; };
CE4B59C91119919700C06C9E /* progress.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE4B59C61119919700C06C9E /* progress.xib */; }; CE4B59C91119919700C06C9E /* progress.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE4B59C61119919700C06C9E /* progress.xib */; };
CE4F934612CCA9470067A3AE /* about.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE4F934512CCA9470067A3AE /* about.xib */; };
CE4F934912CCA96C0067A3AE /* HSAboutBox.m in Sources */ = {isa = PBXBuildFile; fileRef = CE4F934812CCA96C0067A3AE /* HSAboutBox.m */; };
CE515DF30FC6C12E00EC695D /* Dialogs.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DE10FC6C12E00EC695D /* Dialogs.m */; }; CE515DF30FC6C12E00EC695D /* Dialogs.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DE10FC6C12E00EC695D /* Dialogs.m */; };
CE515DF40FC6C12E00EC695D /* HSErrorReportWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DE30FC6C12E00EC695D /* HSErrorReportWindow.m */; }; CE515DF40FC6C12E00EC695D /* HSErrorReportWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DE30FC6C12E00EC695D /* HSErrorReportWindow.m */; };
CE515DF60FC6C12E00EC695D /* ProgressController.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DE70FC6C12E00EC695D /* ProgressController.m */; }; CE515DF60FC6C12E00EC695D /* ProgressController.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DE70FC6C12E00EC695D /* ProgressController.m */; };
CE515DF70FC6C12E00EC695D /* RecentDirectories.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DEA0FC6C12E00EC695D /* RecentDirectories.m */; };
CE515DFA0FC6C12E00EC695D /* Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DF00FC6C12E00EC695D /* Utils.m */; }; CE515DFA0FC6C12E00EC695D /* Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DF00FC6C12E00EC695D /* Utils.m */; };
CE515DFB0FC6C12E00EC695D /* ValueTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DF20FC6C12E00EC695D /* ValueTransformers.m */; }; CE515DFB0FC6C12E00EC695D /* ValueTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DF20FC6C12E00EC695D /* ValueTransformers.m */; };
CE515E1D0FC6C19300EC695D /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515E160FC6C19300EC695D /* AppDelegate.m */; }; CE515E1D0FC6C19300EC695D /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515E160FC6C19300EC695D /* AppDelegate.m */; };
@@ -59,14 +66,10 @@
CE74A12412537F06008A8DF0 /* HSFairwareReminder.m in Sources */ = {isa = PBXBuildFile; fileRef = CE74A12212537F06008A8DF0 /* HSFairwareReminder.m */; }; CE74A12412537F06008A8DF0 /* HSFairwareReminder.m in Sources */ = {isa = PBXBuildFile; fileRef = CE74A12212537F06008A8DF0 /* HSFairwareReminder.m */; };
CE74A12712537F2E008A8DF0 /* FairwareReminder.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE74A12512537F2E008A8DF0 /* FairwareReminder.xib */; }; CE74A12712537F2E008A8DF0 /* FairwareReminder.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE74A12512537F2E008A8DF0 /* FairwareReminder.xib */; };
CE848A1909DD85810004CB44 /* Consts.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE848A1809DD85810004CB44 /* Consts.h */; }; CE848A1909DD85810004CB44 /* Consts.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE848A1809DD85810004CB44 /* Consts.h */; };
CE900AD2109B238600754048 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE900AD1109B238600754048 /* Preferences.xib */; };
CE900AD7109B2A9B00754048 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE900AD6109B2A9B00754048 /* MainMenu.xib */; };
CEB14D29124DFC2800FA7481 /* ResultTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CEB14D28124DFC2800FA7481 /* ResultTable.m */; }; CEB14D29124DFC2800FA7481 /* ResultTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CEB14D28124DFC2800FA7481 /* ResultTable.m */; };
CEDF07A3112493B200EE5BC0 /* StatsLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = CEDF07A2112493B200EE5BC0 /* StatsLabel.m */; }; CEDF07A3112493B200EE5BC0 /* StatsLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = CEDF07A2112493B200EE5BC0 /* StatsLabel.m */; };
CEEB135209C837A2004D2330 /* dupeguru.icns in Resources */ = {isa = PBXBuildFile; fileRef = CEEB135109C837A2004D2330 /* dupeguru.icns */; }; CEEB135209C837A2004D2330 /* dupeguru.icns in Resources */ = {isa = PBXBuildFile; fileRef = CEEB135109C837A2004D2330 /* dupeguru.icns */; };
CEFC294609C89E3D00D9F998 /* folder32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC294509C89E3D00D9F998 /* folder32.png */; }; CEFC294609C89E3D00D9F998 /* folder32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC294509C89E3D00D9F998 /* folder32.png */; };
CEFC295509C89FF200D9F998 /* details32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC295309C89FF200D9F998 /* details32.png */; };
CEFC295609C89FF200D9F998 /* preferences32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC295409C89FF200D9F998 /* preferences32.png */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
@@ -86,7 +89,7 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; }; 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; }; 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = SOURCE_ROOT; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; }; 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; }; 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; };
@@ -110,26 +113,45 @@
CE003CCD11242D2C004B0AA7 /* DirectoryOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DirectoryOutline.h; path = ../base/DirectoryOutline.h; sourceTree = SOURCE_ROOT; }; CE003CCD11242D2C004B0AA7 /* DirectoryOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DirectoryOutline.h; path = ../base/DirectoryOutline.h; sourceTree = SOURCE_ROOT; };
CE003CCE11242D2C004B0AA7 /* DirectoryOutline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DirectoryOutline.m; path = ../base/DirectoryOutline.m; sourceTree = SOURCE_ROOT; }; CE003CCE11242D2C004B0AA7 /* DirectoryOutline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DirectoryOutline.m; path = ../base/DirectoryOutline.m; sourceTree = SOURCE_ROOT; };
CE003CCF11242D2C004B0AA7 /* PyDirectoryOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyDirectoryOutline.h; path = ../base/PyDirectoryOutline.h; sourceTree = SOURCE_ROOT; }; CE003CCF11242D2C004B0AA7 /* PyDirectoryOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyDirectoryOutline.h; path = ../base/PyDirectoryOutline.h; sourceTree = SOURCE_ROOT; };
CE073F5409CAE1A3005C1D2F /* dupeguru_me_help */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dupeguru_me_help; path = ../../help_me/dupeguru_me_help; sourceTree = "<group>"; }; CE05330E12E5D3ED0029EF25 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../base/en.lproj/DetailsPanel.xib; sourceTree = SOURCE_ROOT; };
CE05331012E5D3ED0029EF25 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../base/en.lproj/DirectoryPanel.xib; sourceTree = SOURCE_ROOT; };
CE05331212E5D3ED0029EF25 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../base/en.lproj/MainMenu.xib; sourceTree = SOURCE_ROOT; };
CE05331412E5D3ED0029EF25 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../base/en.lproj/ProblemDialog.xib; sourceTree = SOURCE_ROOT; };
CE05331612E5D3ED0029EF25 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../base/en.lproj/ResultWindow.xib; sourceTree = SOURCE_ROOT; };
CE05331C12E5D4010029EF25 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../base/fr.lproj/DetailsPanel.xib; sourceTree = SOURCE_ROOT; };
CE05331D12E5D4010029EF25 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../base/fr.lproj/DirectoryPanel.xib; sourceTree = SOURCE_ROOT; };
CE05331E12E5D4010029EF25 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../base/fr.lproj/MainMenu.xib; sourceTree = SOURCE_ROOT; };
CE05331F12E5D4010029EF25 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../base/fr.lproj/ProblemDialog.xib; sourceTree = SOURCE_ROOT; };
CE05332012E5D4010029EF25 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../base/fr.lproj/ResultWindow.xib; sourceTree = SOURCE_ROOT; };
CE05332212E5D4100029EF25 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/Preferences.xib; sourceTree = "<group>"; };
CE05332912E5D4460029EF25 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = fr.lproj/Preferences.xib; sourceTree = "<group>"; };
CE05332E12E5D6100029EF25 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = ../base/en.lproj/Localizable.strings; sourceTree = SOURCE_ROOT; };
CE05333312E5D6370029EF25 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = ../base/fr.lproj/Localizable.strings; sourceTree = SOURCE_ROOT; };
CE05347712E5DC420029EF25 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../../cocoalib/fr.lproj/FairwareReminder.xib; sourceTree = SOURCE_ROOT; };
CE073F5409CAE1A3005C1D2F /* help */ = {isa = PBXFileReference; lastKnownFileType = folder; name = help; path = ../../build/help; sourceTree = "<group>"; };
CE0A0BFE1175A1C000DCA3C6 /* HSTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HSTable.h; sourceTree = "<group>"; }; CE0A0BFE1175A1C000DCA3C6 /* HSTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HSTable.h; sourceTree = "<group>"; };
CE0A0BFF1175A1C000DCA3C6 /* HSTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSTable.m; sourceTree = "<group>"; }; CE0A0BFF1175A1C000DCA3C6 /* HSTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSTable.m; sourceTree = "<group>"; };
CE0A0C011175A1DE00DCA3C6 /* ProblemDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProblemDialog.h; path = ../base/ProblemDialog.h; sourceTree = SOURCE_ROOT; }; CE0A0C011175A1DE00DCA3C6 /* ProblemDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProblemDialog.h; path = ../base/ProblemDialog.h; sourceTree = SOURCE_ROOT; };
CE0A0C021175A1DE00DCA3C6 /* ProblemDialog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProblemDialog.m; path = ../base/ProblemDialog.m; sourceTree = SOURCE_ROOT; }; CE0A0C021175A1DE00DCA3C6 /* ProblemDialog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProblemDialog.m; path = ../base/ProblemDialog.m; sourceTree = SOURCE_ROOT; };
CE0A0C031175A1DE00DCA3C6 /* PyProblemDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyProblemDialog.h; path = ../base/PyProblemDialog.h; sourceTree = SOURCE_ROOT; }; CE0A0C031175A1DE00DCA3C6 /* PyProblemDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyProblemDialog.h; path = ../base/PyProblemDialog.h; sourceTree = SOURCE_ROOT; };
CE0A0C051175A24800DCA3C6 /* ProblemDialog.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ProblemDialog.xib; path = ../base/xib/ProblemDialog.xib; sourceTree = SOURCE_ROOT; };
CE0A0C131175A28100DCA3C6 /* PyTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PyTable.h; sourceTree = "<group>"; }; CE0A0C131175A28100DCA3C6 /* PyTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PyTable.h; sourceTree = "<group>"; };
CE1425880AFB718500BD5167 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = /Library/Frameworks/Sparkle.framework; sourceTree = "<absolute>"; }; CE1425880AFB718500BD5167 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = /Library/Frameworks/Sparkle.framework; sourceTree = "<absolute>"; };
CE1EAA0812DF3E81009BA949 /* HSRecentFiles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSRecentFiles.h; path = ../../cocoalib/HSRecentFiles.h; sourceTree = SOURCE_ROOT; };
CE1EAA0912DF3E81009BA949 /* HSRecentFiles.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSRecentFiles.m; path = ../../cocoalib/HSRecentFiles.m; sourceTree = SOURCE_ROOT; };
CE381C9409914ACE003581CE /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; }; CE381C9409914ACE003581CE /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; };
CE381C9509914ACE003581CE /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; }; CE381C9509914ACE003581CE /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; };
CE381C9A09914ADF003581CE /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = ResultWindow.m; sourceTree = SOURCE_ROOT; }; CE381C9A09914ADF003581CE /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = ResultWindow.m; sourceTree = SOURCE_ROOT; };
CE381C9B09914ADF003581CE /* ResultWindow.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = ResultWindow.h; sourceTree = SOURCE_ROOT; }; CE381C9B09914ADF003581CE /* ResultWindow.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = ResultWindow.h; sourceTree = SOURCE_ROOT; };
CE381CF509915304003581CE /* dg_cocoa.plugin */ = {isa = PBXFileReference; lastKnownFileType = folder; path = dg_cocoa.plugin; sourceTree = SOURCE_ROOT; }; CE381CF509915304003581CE /* dg_cocoa.plugin */ = {isa = PBXFileReference; lastKnownFileType = folder; path = dg_cocoa.plugin; sourceTree = SOURCE_ROOT; };
CE3FBDD11094637800B72D77 /* DetailsPanel.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = DetailsPanel.xib; path = ../../base/xib/DetailsPanel.xib; sourceTree = "<group>"; }; CE45274E12E5F62D00005A15 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = ../base/en.lproj/core.strings; sourceTree = SOURCE_ROOT; };
CE3FBDD21094637800B72D77 /* DirectoryPanel.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = DirectoryPanel.xib; path = ../../base/xib/DirectoryPanel.xib; sourceTree = "<group>"; }; CE45275012E5F63900005A15 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = ../base/fr.lproj/core.strings; sourceTree = SOURCE_ROOT; };
CE49DEF20FDFEB810098617B /* BRSingleLineFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BRSingleLineFormatter.h; path = ../../cocoalib/brsinglelineformatter/BRSingleLineFormatter.h; sourceTree = SOURCE_ROOT; }; CE49DEF20FDFEB810098617B /* BRSingleLineFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BRSingleLineFormatter.h; path = ../../cocoalib/brsinglelineformatter/BRSingleLineFormatter.h; sourceTree = SOURCE_ROOT; };
CE49DEF30FDFEB810098617B /* BRSingleLineFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BRSingleLineFormatter.m; path = ../../cocoalib/brsinglelineformatter/BRSingleLineFormatter.m; sourceTree = SOURCE_ROOT; }; CE49DEF30FDFEB810098617B /* BRSingleLineFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BRSingleLineFormatter.m; path = ../../cocoalib/brsinglelineformatter/BRSingleLineFormatter.m; sourceTree = SOURCE_ROOT; };
CE4B59C51119919700C06C9E /* ErrorReportWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ErrorReportWindow.xib; sourceTree = "<group>"; }; CE4B59C51119919700C06C9E /* ErrorReportWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ErrorReportWindow.xib; sourceTree = "<group>"; };
CE4B59C61119919700C06C9E /* progress.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = progress.xib; sourceTree = "<group>"; }; CE4B59C61119919700C06C9E /* progress.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = progress.xib; sourceTree = "<group>"; };
CE4F934512CCA9470067A3AE /* about.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = about.xib; path = ../../cocoalib/xib/about.xib; sourceTree = SOURCE_ROOT; };
CE4F934712CCA96C0067A3AE /* HSAboutBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSAboutBox.h; path = ../../cocoalib/HSAboutBox.h; sourceTree = SOURCE_ROOT; };
CE4F934812CCA96C0067A3AE /* HSAboutBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSAboutBox.m; path = ../../cocoalib/HSAboutBox.m; sourceTree = SOURCE_ROOT; };
CE515DE00FC6C12E00EC695D /* Dialogs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Dialogs.h; path = ../../cocoalib/Dialogs.h; sourceTree = SOURCE_ROOT; }; CE515DE00FC6C12E00EC695D /* Dialogs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Dialogs.h; path = ../../cocoalib/Dialogs.h; sourceTree = SOURCE_ROOT; };
CE515DE10FC6C12E00EC695D /* Dialogs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Dialogs.m; path = ../../cocoalib/Dialogs.m; sourceTree = SOURCE_ROOT; }; CE515DE10FC6C12E00EC695D /* Dialogs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Dialogs.m; path = ../../cocoalib/Dialogs.m; sourceTree = SOURCE_ROOT; };
CE515DE20FC6C12E00EC695D /* HSErrorReportWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSErrorReportWindow.h; path = ../../cocoalib/HSErrorReportWindow.h; sourceTree = SOURCE_ROOT; }; CE515DE20FC6C12E00EC695D /* HSErrorReportWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSErrorReportWindow.h; path = ../../cocoalib/HSErrorReportWindow.h; sourceTree = SOURCE_ROOT; };
@@ -137,8 +159,6 @@
CE515DE60FC6C12E00EC695D /* ProgressController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProgressController.h; path = ../../cocoalib/ProgressController.h; sourceTree = SOURCE_ROOT; }; CE515DE60FC6C12E00EC695D /* ProgressController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProgressController.h; path = ../../cocoalib/ProgressController.h; sourceTree = SOURCE_ROOT; };
CE515DE70FC6C12E00EC695D /* ProgressController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProgressController.m; path = ../../cocoalib/ProgressController.m; sourceTree = SOURCE_ROOT; }; CE515DE70FC6C12E00EC695D /* ProgressController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProgressController.m; path = ../../cocoalib/ProgressController.m; sourceTree = SOURCE_ROOT; };
CE515DE80FC6C12E00EC695D /* PyApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyApp.h; path = ../../cocoalib/PyApp.h; sourceTree = SOURCE_ROOT; }; CE515DE80FC6C12E00EC695D /* PyApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyApp.h; path = ../../cocoalib/PyApp.h; sourceTree = SOURCE_ROOT; };
CE515DE90FC6C12E00EC695D /* RecentDirectories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RecentDirectories.h; path = ../../cocoalib/RecentDirectories.h; sourceTree = SOURCE_ROOT; };
CE515DEA0FC6C12E00EC695D /* RecentDirectories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RecentDirectories.m; path = ../../cocoalib/RecentDirectories.m; sourceTree = SOURCE_ROOT; };
CE515DEF0FC6C12E00EC695D /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Utils.h; path = ../../cocoalib/Utils.h; sourceTree = SOURCE_ROOT; }; CE515DEF0FC6C12E00EC695D /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Utils.h; path = ../../cocoalib/Utils.h; sourceTree = SOURCE_ROOT; };
CE515DF00FC6C12E00EC695D /* Utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Utils.m; path = ../../cocoalib/Utils.m; sourceTree = SOURCE_ROOT; }; CE515DF00FC6C12E00EC695D /* Utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Utils.m; path = ../../cocoalib/Utils.m; sourceTree = SOURCE_ROOT; };
CE515DF10FC6C12E00EC695D /* ValueTransformers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueTransformers.h; path = ../../cocoalib/ValueTransformers.h; sourceTree = SOURCE_ROOT; }; CE515DF10FC6C12E00EC695D /* ValueTransformers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueTransformers.h; path = ../../cocoalib/ValueTransformers.h; sourceTree = SOURCE_ROOT; };
@@ -163,8 +183,6 @@
CE74A12312537F06008A8DF0 /* PyFairware.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyFairware.h; path = ../../cocoalib/PyFairware.h; sourceTree = SOURCE_ROOT; }; CE74A12312537F06008A8DF0 /* PyFairware.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyFairware.h; path = ../../cocoalib/PyFairware.h; sourceTree = SOURCE_ROOT; };
CE74A12612537F2E008A8DF0 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../../cocoalib/en.lproj/FairwareReminder.xib; sourceTree = SOURCE_ROOT; }; CE74A12612537F2E008A8DF0 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../../cocoalib/en.lproj/FairwareReminder.xib; sourceTree = SOURCE_ROOT; };
CE848A1809DD85810004CB44 /* Consts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Consts.h; sourceTree = "<group>"; }; CE848A1809DD85810004CB44 /* Consts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Consts.h; sourceTree = "<group>"; };
CE900AD1109B238600754048 /* Preferences.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = Preferences.xib; sourceTree = "<group>"; };
CE900AD6109B2A9B00754048 /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MainMenu.xib; path = ../../base/xib/MainMenu.xib; sourceTree = "<group>"; };
CEB14D26124DFC2800FA7481 /* PyResultTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyResultTable.h; path = ../base/PyResultTable.h; sourceTree = SOURCE_ROOT; }; CEB14D26124DFC2800FA7481 /* PyResultTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyResultTable.h; path = ../base/PyResultTable.h; sourceTree = SOURCE_ROOT; };
CEB14D27124DFC2800FA7481 /* ResultTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ResultTable.h; path = ../base/ResultTable.h; sourceTree = SOURCE_ROOT; }; CEB14D27124DFC2800FA7481 /* ResultTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ResultTable.h; path = ../base/ResultTable.h; sourceTree = SOURCE_ROOT; };
CEB14D28124DFC2800FA7481 /* ResultTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ResultTable.m; path = ../base/ResultTable.m; sourceTree = SOURCE_ROOT; }; CEB14D28124DFC2800FA7481 /* ResultTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ResultTable.m; path = ../base/ResultTable.m; sourceTree = SOURCE_ROOT; };
@@ -174,8 +192,6 @@
CEDF07A2112493B200EE5BC0 /* StatsLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = StatsLabel.m; path = ../base/StatsLabel.m; sourceTree = SOURCE_ROOT; }; CEDF07A2112493B200EE5BC0 /* StatsLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = StatsLabel.m; path = ../base/StatsLabel.m; sourceTree = SOURCE_ROOT; };
CEEB135109C837A2004D2330 /* dupeguru.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = dupeguru.icns; sourceTree = "<group>"; }; CEEB135109C837A2004D2330 /* dupeguru.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = dupeguru.icns; sourceTree = "<group>"; };
CEFC294509C89E3D00D9F998 /* folder32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = folder32.png; path = ../../images/folder32.png; sourceTree = SOURCE_ROOT; }; CEFC294509C89E3D00D9F998 /* folder32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = folder32.png; path = ../../images/folder32.png; sourceTree = SOURCE_ROOT; };
CEFC295309C89FF200D9F998 /* details32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = details32.png; path = ../../images/details32.png; sourceTree = SOURCE_ROOT; };
CEFC295409C89FF200D9F998 /* preferences32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = preferences32.png; path = ../../images/preferences32.png; sourceTree = SOURCE_ROOT; };
CEFF18A009A4D387005E6321 /* PyDupeGuru.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = PyDupeGuru.h; sourceTree = SOURCE_ROOT; }; CEFF18A009A4D387005E6321 /* PyDupeGuru.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = PyDupeGuru.h; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@@ -195,6 +211,7 @@
080E96DDFE201D6D7F000001 /* DGME */ = { 080E96DDFE201D6D7F000001 /* DGME */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
29B97316FDCFA39411CA2CEA /* main.m */,
CE381C9509914ACE003581CE /* AppDelegate.h */, CE381C9509914ACE003581CE /* AppDelegate.h */,
CE381C9409914ACE003581CE /* AppDelegate.m */, CE381C9409914ACE003581CE /* AppDelegate.m */,
CE848A1809DD85810004CB44 /* Consts.h */, CE848A1809DD85810004CB44 /* Consts.h */,
@@ -240,7 +257,6 @@
080E96DDFE201D6D7F000001 /* DGME */, 080E96DDFE201D6D7F000001 /* DGME */,
CE515E140FC6C17900EC695D /* dgbase */, CE515E140FC6C17900EC695D /* dgbase */,
CE515DDD0FC6C09400EC695D /* cocoalib */, CE515DDD0FC6C09400EC695D /* cocoalib */,
29B97315FDCFA39411CA2CEA /* Other Sources */,
29B97317FDCFA39411CA2CEA /* Resources */, 29B97317FDCFA39411CA2CEA /* Resources */,
29B97323FDCFA39411CA2CEA /* Frameworks */, 29B97323FDCFA39411CA2CEA /* Frameworks */,
19C28FACFE9D520D11CA2CBB /* Products */, 19C28FACFE9D520D11CA2CBB /* Products */,
@@ -248,22 +264,16 @@
name = dupeguru; name = dupeguru;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
29B97315FDCFA39411CA2CEA /* Other Sources */ = {
isa = PBXGroup;
children = (
29B97316FDCFA39411CA2CEA /* main.m */,
);
name = "Other Sources";
sourceTree = "<group>";
};
29B97317FDCFA39411CA2CEA /* Resources */ = { 29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CE3FBDD01094637800B72D77 /* xib */, CE073F5409CAE1A3005C1D2F /* help */,
CE073F5409CAE1A3005C1D2F /* dupeguru_me_help */,
CE381CF509915304003581CE /* dg_cocoa.plugin */, CE381CF509915304003581CE /* dg_cocoa.plugin */,
CEFC294309C89E0000D9F998 /* images */, CEFC294309C89E0000D9F998 /* images */,
CE05330C12E5D3D70029EF25 /* xib */,
CEEB135109C837A2004D2330 /* dupeguru.icns */, CEEB135109C837A2004D2330 /* dupeguru.icns */,
CE05332D12E5D6100029EF25 /* Localizable.strings */,
CE45274D12E5F62D00005A15 /* core.strings */,
8D1107310486CEB800E47090 /* Info.plist */, 8D1107310486CEB800E47090 /* Info.plist */,
CE6E0E9E1054EB97008D9390 /* dsa_pub.pem */, CE6E0E9E1054EB97008D9390 /* dsa_pub.pem */,
); );
@@ -322,16 +332,17 @@
path = ../../cocoalib/views; path = ../../cocoalib/views;
sourceTree = SOURCE_ROOT; sourceTree = SOURCE_ROOT;
}; };
CE3FBDD01094637800B72D77 /* xib */ = { CE05330C12E5D3D70029EF25 /* xib */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CE900AD6109B2A9B00754048 /* MainMenu.xib */, CE05330D12E5D3ED0029EF25 /* DetailsPanel.xib */,
CE3FBDD11094637800B72D77 /* DetailsPanel.xib */, CE05330F12E5D3ED0029EF25 /* DirectoryPanel.xib */,
CE3FBDD21094637800B72D77 /* DirectoryPanel.xib */, CE05331112E5D3ED0029EF25 /* MainMenu.xib */,
CE900AD1109B238600754048 /* Preferences.xib */, CE05331312E5D3ED0029EF25 /* ProblemDialog.xib */,
CE0A0C051175A24800DCA3C6 /* ProblemDialog.xib */, CE05331512E5D3ED0029EF25 /* ResultWindow.xib */,
CE05332112E5D4100029EF25 /* Preferences.xib */,
); );
path = xib; name = xib;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
CE49DEF10FDFEB810098617B /* brsinglelineformatter */ = { CE49DEF10FDFEB810098617B /* brsinglelineformatter */ = {
@@ -347,6 +358,7 @@
CE4B59C41119919700C06C9E /* xib */ = { CE4B59C41119919700C06C9E /* xib */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CE4F934512CCA9470067A3AE /* about.xib */,
CE74A12512537F2E008A8DF0 /* FairwareReminder.xib */, CE74A12512537F2E008A8DF0 /* FairwareReminder.xib */,
CE4B59C51119919700C06C9E /* ErrorReportWindow.xib */, CE4B59C51119919700C06C9E /* ErrorReportWindow.xib */,
CE4B59C61119919700C06C9E /* progress.xib */, CE4B59C61119919700C06C9E /* progress.xib */,
@@ -370,13 +382,15 @@
CE74A12112537F06008A8DF0 /* HSFairwareReminder.h */, CE74A12112537F06008A8DF0 /* HSFairwareReminder.h */,
CE74A12212537F06008A8DF0 /* HSFairwareReminder.m */, CE74A12212537F06008A8DF0 /* HSFairwareReminder.m */,
CE74A12312537F06008A8DF0 /* PyFairware.h */, CE74A12312537F06008A8DF0 /* PyFairware.h */,
CE4F934712CCA96C0067A3AE /* HSAboutBox.h */,
CE4F934812CCA96C0067A3AE /* HSAboutBox.m */,
CE1EAA0812DF3E81009BA949 /* HSRecentFiles.h */,
CE1EAA0912DF3E81009BA949 /* HSRecentFiles.m */,
CE003CB911242D00004B0AA7 /* NSEventAdditions.h */, CE003CB911242D00004B0AA7 /* NSEventAdditions.h */,
CE003CBA11242D00004B0AA7 /* NSEventAdditions.m */, CE003CBA11242D00004B0AA7 /* NSEventAdditions.m */,
CE515DE60FC6C12E00EC695D /* ProgressController.h */, CE515DE60FC6C12E00EC695D /* ProgressController.h */,
CE515DE70FC6C12E00EC695D /* ProgressController.m */, CE515DE70FC6C12E00EC695D /* ProgressController.m */,
CE515DE80FC6C12E00EC695D /* PyApp.h */, CE515DE80FC6C12E00EC695D /* PyApp.h */,
CE515DE90FC6C12E00EC695D /* RecentDirectories.h */,
CE515DEA0FC6C12E00EC695D /* RecentDirectories.m */,
CE515DEF0FC6C12E00EC695D /* Utils.h */, CE515DEF0FC6C12E00EC695D /* Utils.h */,
CE515DF00FC6C12E00EC695D /* Utils.m */, CE515DF00FC6C12E00EC695D /* Utils.m */,
CE515DF10FC6C12E00EC695D /* ValueTransformers.h */, CE515DF10FC6C12E00EC695D /* ValueTransformers.h */,
@@ -418,8 +432,6 @@
CEFC294309C89E0000D9F998 /* images */ = { CEFC294309C89E0000D9F998 /* images */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CEFC295309C89FF200D9F998 /* details32.png */,
CEFC295409C89FF200D9F998 /* preferences32.png */,
CEFC294509C89E3D00D9F998 /* folder32.png */, CEFC294509C89E3D00D9F998 /* folder32.png */,
); );
name = images; name = images;
@@ -455,6 +467,7 @@
isa = PBXProject; isa = PBXProject;
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */;
compatibilityVersion = "Xcode 3.0"; compatibilityVersion = "Xcode 3.0";
developmentRegion = English;
hasScannedForEncodings = 1; hasScannedForEncodings = 1;
knownRegions = ( knownRegions = (
English, English,
@@ -462,6 +475,7 @@
French, French,
German, German,
en, en,
fr,
); );
mainGroup = 29B97314FDCFA39411CA2CEA /* dupeguru */; mainGroup = 29B97314FDCFA39411CA2CEA /* dupeguru */;
projectDirPath = ""; projectDirPath = "";
@@ -478,20 +492,22 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */, CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */,
CE073F6309CAE1A3005C1D2F /* dupeguru_me_help in Resources */, CE073F6309CAE1A3005C1D2F /* help in Resources */,
CEEB135209C837A2004D2330 /* dupeguru.icns in Resources */, CEEB135209C837A2004D2330 /* dupeguru.icns in Resources */,
CEFC294609C89E3D00D9F998 /* folder32.png in Resources */, CEFC294609C89E3D00D9F998 /* folder32.png in Resources */,
CEFC295509C89FF200D9F998 /* details32.png in Resources */,
CEFC295609C89FF200D9F998 /* preferences32.png in Resources */,
CE6E0E9F1054EB97008D9390 /* dsa_pub.pem in Resources */, CE6E0E9F1054EB97008D9390 /* dsa_pub.pem in Resources */,
CE3FBDD31094637800B72D77 /* DetailsPanel.xib in Resources */,
CE3FBDD41094637800B72D77 /* DirectoryPanel.xib in Resources */,
CE900AD2109B238600754048 /* Preferences.xib in Resources */,
CE900AD7109B2A9B00754048 /* MainMenu.xib in Resources */,
CE4B59C81119919700C06C9E /* ErrorReportWindow.xib in Resources */, CE4B59C81119919700C06C9E /* ErrorReportWindow.xib in Resources */,
CE4B59C91119919700C06C9E /* progress.xib in Resources */, CE4B59C91119919700C06C9E /* progress.xib in Resources */,
CE0A0C061175A24800DCA3C6 /* ProblemDialog.xib in Resources */,
CE74A12712537F2E008A8DF0 /* FairwareReminder.xib in Resources */, CE74A12712537F2E008A8DF0 /* FairwareReminder.xib in Resources */,
CE4F934612CCA9470067A3AE /* about.xib in Resources */,
CE05331712E5D3ED0029EF25 /* DetailsPanel.xib in Resources */,
CE05331812E5D3ED0029EF25 /* DirectoryPanel.xib in Resources */,
CE05331912E5D3ED0029EF25 /* MainMenu.xib in Resources */,
CE05331A12E5D3ED0029EF25 /* ProblemDialog.xib in Resources */,
CE05331B12E5D3ED0029EF25 /* ResultWindow.xib in Resources */,
CE05332312E5D4100029EF25 /* Preferences.xib in Resources */,
CE05332F12E5D6100029EF25 /* Localizable.strings in Resources */,
CE45274F12E5F62D00005A15 /* core.strings in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -509,7 +525,6 @@
CE515DF30FC6C12E00EC695D /* Dialogs.m in Sources */, CE515DF30FC6C12E00EC695D /* Dialogs.m in Sources */,
CE515DF40FC6C12E00EC695D /* HSErrorReportWindow.m in Sources */, CE515DF40FC6C12E00EC695D /* HSErrorReportWindow.m in Sources */,
CE515DF60FC6C12E00EC695D /* ProgressController.m in Sources */, CE515DF60FC6C12E00EC695D /* ProgressController.m in Sources */,
CE515DF70FC6C12E00EC695D /* RecentDirectories.m in Sources */,
CE515DFA0FC6C12E00EC695D /* Utils.m in Sources */, CE515DFA0FC6C12E00EC695D /* Utils.m in Sources */,
CE515DFB0FC6C12E00EC695D /* ValueTransformers.m in Sources */, CE515DFB0FC6C12E00EC695D /* ValueTransformers.m in Sources */,
CE515E1D0FC6C19300EC695D /* AppDelegate.m in Sources */, CE515E1D0FC6C19300EC695D /* AppDelegate.m in Sources */,
@@ -531,16 +546,91 @@
CEB14D29124DFC2800FA7481 /* ResultTable.m in Sources */, CEB14D29124DFC2800FA7481 /* ResultTable.m in Sources */,
CE578303124DFC660004769C /* HSTableView.m in Sources */, CE578303124DFC660004769C /* HSTableView.m in Sources */,
CE74A12412537F06008A8DF0 /* HSFairwareReminder.m in Sources */, CE74A12412537F06008A8DF0 /* HSFairwareReminder.m in Sources */,
CE4F934912CCA96C0067A3AE /* HSAboutBox.m in Sources */,
CE1EAA0A12DF3E81009BA949 /* HSRecentFiles.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
/* End PBXSourcesBuildPhase section */ /* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */ /* Begin PBXVariantGroup section */
CE05330D12E5D3ED0029EF25 /* DetailsPanel.xib */ = {
isa = PBXVariantGroup;
children = (
CE05330E12E5D3ED0029EF25 /* en */,
CE05331C12E5D4010029EF25 /* fr */,
);
name = DetailsPanel.xib;
sourceTree = SOURCE_ROOT;
};
CE05330F12E5D3ED0029EF25 /* DirectoryPanel.xib */ = {
isa = PBXVariantGroup;
children = (
CE05331012E5D3ED0029EF25 /* en */,
CE05331D12E5D4010029EF25 /* fr */,
);
name = DirectoryPanel.xib;
sourceTree = SOURCE_ROOT;
};
CE05331112E5D3ED0029EF25 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
CE05331212E5D3ED0029EF25 /* en */,
CE05331E12E5D4010029EF25 /* fr */,
);
name = MainMenu.xib;
sourceTree = SOURCE_ROOT;
};
CE05331312E5D3ED0029EF25 /* ProblemDialog.xib */ = {
isa = PBXVariantGroup;
children = (
CE05331412E5D3ED0029EF25 /* en */,
CE05331F12E5D4010029EF25 /* fr */,
);
name = ProblemDialog.xib;
sourceTree = SOURCE_ROOT;
};
CE05331512E5D3ED0029EF25 /* ResultWindow.xib */ = {
isa = PBXVariantGroup;
children = (
CE05331612E5D3ED0029EF25 /* en */,
CE05332012E5D4010029EF25 /* fr */,
);
name = ResultWindow.xib;
sourceTree = SOURCE_ROOT;
};
CE05332112E5D4100029EF25 /* Preferences.xib */ = {
isa = PBXVariantGroup;
children = (
CE05332212E5D4100029EF25 /* en */,
CE05332912E5D4460029EF25 /* fr */,
);
name = Preferences.xib;
sourceTree = SOURCE_ROOT;
};
CE05332D12E5D6100029EF25 /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
CE05332E12E5D6100029EF25 /* en */,
CE05333312E5D6370029EF25 /* fr */,
);
name = Localizable.strings;
sourceTree = "<group>";
};
CE45274D12E5F62D00005A15 /* core.strings */ = {
isa = PBXVariantGroup;
children = (
CE45274E12E5F62D00005A15 /* en */,
CE45275012E5F63900005A15 /* fr */,
);
name = core.strings;
sourceTree = SOURCE_ROOT;
};
CE74A12512537F2E008A8DF0 /* FairwareReminder.xib */ = { CE74A12512537F2E008A8DF0 /* FairwareReminder.xib */ = {
isa = PBXVariantGroup; isa = PBXVariantGroup;
children = ( children = (
CE74A12612537F2E008A8DF0 /* en */, CE74A12612537F2E008A8DF0 /* en */,
CE05347712E5DC420029EF25 /* fr */,
); );
name = FairwareReminder.xib; name = FairwareReminder.xib;
path = ../../cocoalib/xib; path = ../../cocoalib/xib;

Binary file not shown.

View File

@@ -2,13 +2,13 @@
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10"> <archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
<data> <data>
<int key="IBDocument.SystemTarget">1050</int> <int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">10F569</string> <string key="IBDocument.SystemVersion">10J567</string>
<string key="IBDocument.InterfaceBuilderVersion">788</string> <string key="IBDocument.InterfaceBuilderVersion">823</string>
<string key="IBDocument.AppKitVersion">1038.29</string> <string key="IBDocument.AppKitVersion">1038.35</string>
<string key="IBDocument.HIToolboxVersion">461.00</string> <string key="IBDocument.HIToolboxVersion">462.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions"> <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">788</string> <string key="NS.object.0">823</string>
</object> </object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs"> <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
@@ -19,13 +19,8 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object> </object>
<object class="NSMutableDictionary" key="IBDocument.Metadata"> <object class="NSMutableDictionary" key="IBDocument.Metadata">
<bool key="EncodedWithXMLCoder">YES</bool> <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<object class="NSArray" key="dict.sortedKeys" id="0"> <integer value="1" key="NS.object.0"/>
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object> </object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000"> <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
@@ -41,14 +36,14 @@
<object class="NSUserDefaultsController" id="579641073"> <object class="NSUserDefaultsController" id="579641073">
<object class="NSMutableArray" key="NSDeclaredKeys"> <object class="NSMutableArray" key="NSDeclaredKeys">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
<string>ignoreHardlinkMatches</string> <string>DebugMode</string>
</object> </object>
<bool key="NSSharedInstance">YES</bool> <bool key="NSSharedInstance">YES</bool>
</object> </object>
<object class="NSWindowTemplate" id="793317856"> <object class="NSWindowTemplate" id="793317856">
<int key="NSWindowStyleMask">3</int> <int key="NSWindowStyleMask">3</int>
<int key="NSWindowBacking">2</int> <int key="NSWindowBacking">2</int>
<string key="NSWindowRect">{{92, 276}, {406, 326}}</string> <string key="NSWindowRect">{{92, 259}, {406, 343}}</string>
<int key="NSWTFlags">1886912512</int> <int key="NSWTFlags">1886912512</int>
<string key="NSWindowTitle">dupeGuru ME Preferences</string> <string key="NSWindowTitle">dupeGuru ME Preferences</string>
<object class="NSMutableString" key="NSWindowClass"> <object class="NSMutableString" key="NSWindowClass">
@@ -94,7 +89,7 @@
<object class="NSTabView" id="1019752720"> <object class="NSTabView" id="1019752720">
<reference key="NSNextResponder" ref="986069316"/> <reference key="NSNextResponder" ref="986069316"/>
<int key="NSvFlags">12</int> <int key="NSvFlags">12</int>
<string key="NSFrame">{{13, 40}, {380, 280}}</string> <string key="NSFrame">{{13, 40}, {380, 297}}</string>
<reference key="NSSuperview" ref="986069316"/> <reference key="NSSuperview" ref="986069316"/>
<object class="NSMutableArray" key="NSTabViewItems"> <object class="NSMutableArray" key="NSTabViewItems">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
@@ -108,7 +103,7 @@
<object class="NSSlider" id="810949831"> <object class="NSSlider" id="810949831">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{117, 172}, {190, 21}}</string> <string key="NSFrame">{{117, 189}, {190, 21}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSSliderCell" key="NSCell" id="735486969"> <object class="NSSliderCell" key="NSCell" id="735486969">
@@ -136,7 +131,7 @@
<object class="NSTextField" id="595766735"> <object class="NSTextField" id="595766735">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{119, 155}, {80, 13}}</string> <string key="NSFrame">{{119, 172}, {80, 13}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="274051075"> <object class="NSTextFieldCell" key="NSCell" id="274051075">
@@ -172,7 +167,7 @@
<object class="NSTextField" id="735544762"> <object class="NSTextField" id="735544762">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">289</int> <int key="NSvFlags">289</int>
<string key="NSFrame">{{225, 155}, {80, 13}}</string> <string key="NSFrame">{{225, 172}, {80, 13}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="602722407"> <object class="NSTextFieldCell" key="NSCell" id="602722407">
@@ -188,7 +183,7 @@
<object class="NSTextField" id="152034108"> <object class="NSTextField" id="152034108">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{14, 177}, {100, 14}}</string> <string key="NSFrame">{{14, 194}, {100, 14}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="368410553"> <object class="NSTextFieldCell" key="NSCell" id="368410553">
@@ -208,7 +203,7 @@
<object class="NSTextField" id="531187173"> <object class="NSTextField" id="531187173">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{17, 218}, {85, 13}}</string> <string key="NSFrame">{{17, 235}, {85, 13}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="511697312"> <object class="NSTextFieldCell" key="NSCell" id="511697312">
@@ -224,7 +219,7 @@
<object class="NSPopUpButton" id="353791762"> <object class="NSPopUpButton" id="353791762">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{110, 207}, {231, 26}}</string> <string key="NSFrame">{{110, 224}, {231, 26}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSPopUpButtonCell" key="NSCell" id="1039743040"> <object class="NSPopUpButtonCell" key="NSCell" id="1039743040">
@@ -334,7 +329,7 @@
<object class="NSButton" id="102571342"> <object class="NSButton" id="102571342">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 91}, {214, 18}}</string> <string key="NSFrame">{{15, 90}, {330, 18}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="455609515"> <object class="NSButtonCell" key="NSCell" id="455609515">
@@ -357,7 +352,7 @@
<object class="NSButton" id="527948380"> <object class="NSButton" id="527948380">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 51}, {214, 18}}</string> <string key="NSFrame">{{15, 50}, {325, 18}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="812282968"> <object class="NSButtonCell" key="NSCell" id="812282968">
@@ -378,7 +373,7 @@
<object class="NSTextField" id="746186689"> <object class="NSTextField" id="746186689">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{313, 177}, {31, 14}}</string> <string key="NSFrame">{{313, 194}, {31, 14}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="661671041"> <object class="NSTextFieldCell" key="NSCell" id="661671041">
@@ -405,9 +400,11 @@
<boolean value="YES"/> <boolean value="YES"/>
<object class="NSAttributedString" id="145123224"> <object class="NSAttributedString" id="145123224">
<string key="NSString">0</string> <string key="NSString">0</string>
<object class="NSDictionary" key="NSAttributes" id="589681839"> <object class="NSDictionary" key="NSAttributes" id="601001826">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/> <object class="NSArray" key="dict.sortedKeys" id="0">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values"> <object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
</object> </object>
@@ -431,7 +428,7 @@
</object> </object>
<object class="NSAttributedString" key="NS.nan"> <object class="NSAttributedString" key="NS.nan">
<string key="NSString">NaN</string> <string key="NSString">NaN</string>
<reference key="NSAttributes" ref="589681839"/> <reference key="NSAttributes" ref="601001826"/>
</object> </object>
<object class="NSDecimalNumberPlaceholder" key="NS.min" id="417544583"> <object class="NSDecimalNumberPlaceholder" key="NS.min" id="417544583">
<int key="NS.exponent">0</int> <int key="NS.exponent">0</int>
@@ -457,7 +454,7 @@
<object class="NSButton" id="996173927"> <object class="NSButton" id="996173927">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 71}, {214, 18}}</string> <string key="NSFrame">{{15, 70}, {330, 18}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="839484037"> <object class="NSButtonCell" key="NSCell" id="839484037">
@@ -478,7 +475,7 @@
<object class="NSButton" id="147113892"> <object class="NSButton" id="147113892">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 9}, {283, 18}}</string> <string key="NSFrame">{{15, 10}, {330, 18}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="58676792"> <object class="NSButtonCell" key="NSCell" id="58676792">
@@ -499,7 +496,7 @@
<object class="NSButton" id="367077416"> <object class="NSButton" id="367077416">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 31}, {262, 18}}</string> <string key="NSFrame">{{15, 30}, {330, 18}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="469745366"> <object class="NSButtonCell" key="NSCell" id="469745366">
@@ -520,7 +517,7 @@
<object class="NSTextField" id="742879627"> <object class="NSTextField" id="742879627">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{14, 133}, {100, 17}}</string> <string key="NSFrame">{{14, 150}, {100, 17}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="714876031"> <object class="NSTextFieldCell" key="NSCell" id="714876031">
@@ -536,7 +533,7 @@
<object class="NSButton" id="24386232"> <object class="NSButton" id="24386232">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{24, 113}, {55, 18}}</string> <string key="NSFrame">{{24, 130}, {66, 18}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="771292699"> <object class="NSButtonCell" key="NSCell" id="771292699">
@@ -557,7 +554,7 @@
<object class="NSButton" id="28878355"> <object class="NSButton" id="28878355">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{77, 113}, {55, 18}}</string> <string key="NSFrame">{{94, 130}, {66, 18}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="324625140"> <object class="NSButtonCell" key="NSCell" id="324625140">
@@ -578,7 +575,7 @@
<object class="NSButton" id="964877114"> <object class="NSButton" id="964877114">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{129, 113}, {60, 18}}</string> <string key="NSFrame">{{164, 130}, {66, 18}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="564429548"> <object class="NSButtonCell" key="NSCell" id="564429548">
@@ -599,7 +596,7 @@
<object class="NSButton" id="144566514"> <object class="NSButton" id="144566514">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{187, 113}, {51, 18}}</string> <string key="NSFrame">{{24, 110}, {66, 18}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="243345318"> <object class="NSButtonCell" key="NSCell" id="243345318">
@@ -620,7 +617,7 @@
<object class="NSButton" id="180911463"> <object class="NSButton" id="180911463">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{235, 113}, {54, 18}}</string> <string key="NSFrame">{{94, 110}, {66, 18}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="222054797"> <object class="NSButtonCell" key="NSCell" id="222054797">
@@ -641,7 +638,7 @@
<object class="NSButton" id="422320464"> <object class="NSButton" id="422320464">
<reference key="NSNextResponder" ref="92401176"/> <reference key="NSNextResponder" ref="92401176"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{292, 113}, {54, 18}}</string> <string key="NSFrame">{{164, 110}, {66, 18}}</string>
<reference key="NSSuperview" ref="92401176"/> <reference key="NSSuperview" ref="92401176"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="464356494"> <object class="NSButtonCell" key="NSCell" id="464356494">
@@ -660,7 +657,7 @@
</object> </object>
</object> </object>
</object> </object>
<string key="NSFrame">{{10, 33}, {360, 234}}</string> <string key="NSFrame">{{10, 33}, {360, 251}}</string>
<reference key="NSSuperview" ref="1019752720"/> <reference key="NSSuperview" ref="1019752720"/>
</object> </object>
<string key="NSLabel">Basic</string> <string key="NSLabel">Basic</string>
@@ -677,7 +674,7 @@
<object class="NSButton" id="836095588"> <object class="NSButton" id="836095588">
<reference key="NSNextResponder" ref="76055040"/> <reference key="NSNextResponder" ref="76055040"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 215}, {262, 18}}</string> <string key="NSFrame">{{15, 232}, {262, 18}}</string>
<reference key="NSSuperview" ref="76055040"/> <reference key="NSSuperview" ref="76055040"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="287230715"> <object class="NSButtonCell" key="NSCell" id="287230715">
@@ -698,7 +695,7 @@
<object class="NSTextField" id="519483808"> <object class="NSTextField" id="519483808">
<reference key="NSNextResponder" ref="76055040"/> <reference key="NSNextResponder" ref="76055040"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{14, 172}, {85, 13}}</string> <string key="NSFrame">{{14, 126}, {332, 13}}</string>
<reference key="NSSuperview" ref="76055040"/> <reference key="NSSuperview" ref="76055040"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="142188233"> <object class="NSTextFieldCell" key="NSCell" id="142188233">
@@ -714,7 +711,7 @@
<object class="NSTextField" id="839713145"> <object class="NSTextField" id="839713145">
<reference key="NSNextResponder" ref="76055040"/> <reference key="NSNextResponder" ref="76055040"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{14, 144}, {324, 17}}</string> <string key="NSFrame">{{14, 169}, {332, 17}}</string>
<reference key="NSSuperview" ref="76055040"/> <reference key="NSSuperview" ref="76055040"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="380716547"> <object class="NSTextFieldCell" key="NSCell" id="380716547">
@@ -730,7 +727,7 @@
<object class="NSPopUpButton" id="1046542754"> <object class="NSPopUpButton" id="1046542754">
<reference key="NSNextResponder" ref="76055040"/> <reference key="NSNextResponder" ref="76055040"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{104, 165}, {234, 26}}</string> <string key="NSFrame">{{14, 94}, {256, 26}}</string>
<reference key="NSSuperview" ref="76055040"/> <reference key="NSSuperview" ref="76055040"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSPopUpButtonCell" key="NSCell" id="923770094"> <object class="NSPopUpButtonCell" key="NSCell" id="923770094">
@@ -800,7 +797,7 @@
<object class="NSTextField" id="330569030"> <object class="NSTextField" id="330569030">
<reference key="NSNextResponder" ref="76055040"/> <reference key="NSNextResponder" ref="76055040"/>
<int key="NSvFlags">266</int> <int key="NSvFlags">266</int>
<string key="NSFrame">{{17, 122}, {326, 22}}</string> <string key="NSFrame">{{17, 147}, {326, 22}}</string>
<reference key="NSSuperview" ref="76055040"/> <reference key="NSSuperview" ref="76055040"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="573680954"> <object class="NSTextFieldCell" key="NSCell" id="573680954">
@@ -830,7 +827,7 @@
<object class="NSButton" id="1065764374"> <object class="NSButton" id="1065764374">
<reference key="NSNextResponder" ref="76055040"/> <reference key="NSNextResponder" ref="76055040"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 195}, {265, 18}}</string> <string key="NSFrame">{{15, 212}, {265, 18}}</string>
<reference key="NSSuperview" ref="76055040"/> <reference key="NSSuperview" ref="76055040"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="621426332"> <object class="NSButtonCell" key="NSCell" id="621426332">
@@ -848,8 +845,29 @@
<int key="NSPeriodicInterval">25</int> <int key="NSPeriodicInterval">25</int>
</object> </object>
</object> </object>
<object class="NSButton" id="476462426">
<reference key="NSNextResponder" ref="76055040"/>
<int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 192}, {265, 18}}</string>
<reference key="NSSuperview" ref="76055040"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="29064087">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">0</int>
<string key="NSContents">Debug mode (restart required)</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSControlView" ref="476462426"/>
<int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int>
<reference key="NSAlternateImage" ref="150447483"/>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
<int key="NSPeriodicDelay">200</int>
<int key="NSPeriodicInterval">25</int>
</object>
</object>
</object> </object>
<string key="NSFrame">{{10, 33}, {360, 234}}</string> <string key="NSFrame">{{10, 33}, {360, 251}}</string>
</object> </object>
<string key="NSLabel">Advanced</string> <string key="NSLabel">Advanced</string>
<reference key="NSColor" ref="221998487"/> <reference key="NSColor" ref="221998487"/>
@@ -867,7 +885,7 @@
</object> </object>
</object> </object>
</object> </object>
<string key="NSFrameSize">{406, 326}</string> <string key="NSFrameSize">{406, 343}</string>
<reference key="NSSuperview"/> <reference key="NSSuperview"/>
</object> </object>
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string> <string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
@@ -1498,6 +1516,22 @@
</object> </object>
<int key="connectionID">128</int> <int key="connectionID">128</int>
</object> </object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">value: values.DebugMode</string>
<reference key="source" ref="476462426"/>
<reference key="destination" ref="579641073"/>
<object class="NSNibBindingConnector" key="connector">
<reference key="NSSource" ref="476462426"/>
<reference key="NSDestination" ref="579641073"/>
<string key="NSLabel">value: values.DebugMode</string>
<string key="NSBinding">value</string>
<string key="NSKeyPath">values.DebugMode</string>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">132</int>
</object>
</object> </object>
<object class="IBMutableOrderedSet" key="objectRecords"> <object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects"> <object class="NSArray" key="orderedObjects">
@@ -1547,8 +1581,8 @@
<reference key="object" ref="986069316"/> <reference key="object" ref="986069316"/>
<object class="NSMutableArray" key="children"> <object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="552254322"/>
<reference ref="1019752720"/> <reference ref="1019752720"/>
<reference ref="552254322"/>
</object> </object>
<reference key="parent" ref="793317856"/> <reference key="parent" ref="793317856"/>
</object> </object>
@@ -1601,6 +1635,7 @@
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="836095588"/> <reference ref="836095588"/>
<reference ref="1065764374"/> <reference ref="1065764374"/>
<reference ref="476462426"/>
<reference ref="519483808"/> <reference ref="519483808"/>
<reference ref="839713145"/> <reference ref="839713145"/>
<reference ref="1046542754"/> <reference ref="1046542754"/>
@@ -1613,25 +1648,25 @@
<reference key="object" ref="92401176"/> <reference key="object" ref="92401176"/>
<object class="NSMutableArray" key="children"> <object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="422320464"/>
<reference ref="180911463"/>
<reference ref="144566514"/>
<reference ref="964877114"/>
<reference ref="28878355"/>
<reference ref="24386232"/> <reference ref="24386232"/>
<reference ref="742879627"/> <reference ref="742879627"/>
<reference ref="996173927"/>
<reference ref="746186689"/> <reference ref="746186689"/>
<reference ref="527948380"/>
<reference ref="102571342"/>
<reference ref="353791762"/> <reference ref="353791762"/>
<reference ref="531187173"/> <reference ref="531187173"/>
<reference ref="152034108"/> <reference ref="152034108"/>
<reference ref="735544762"/> <reference ref="735544762"/>
<reference ref="595766735"/> <reference ref="595766735"/>
<reference ref="810949831"/> <reference ref="810949831"/>
<reference ref="147113892"/> <reference ref="144566514"/>
<reference ref="28878355"/>
<reference ref="180911463"/>
<reference ref="964877114"/>
<reference ref="422320464"/>
<reference ref="102571342"/>
<reference ref="527948380"/>
<reference ref="996173927"/>
<reference ref="367077416"/> <reference ref="367077416"/>
<reference ref="147113892"/>
</object> </object>
<reference key="parent" ref="443899983"/> <reference key="parent" ref="443899983"/>
</object> </object>
@@ -2072,6 +2107,20 @@
<reference key="object" ref="621426332"/> <reference key="object" ref="621426332"/>
<reference key="parent" ref="1065764374"/> <reference key="parent" ref="1065764374"/>
</object> </object>
<object class="IBObjectRecord">
<int key="objectID">129</int>
<reference key="object" ref="476462426"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="29064087"/>
</object>
<reference key="parent" ref="76055040"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">130</int>
<reference key="object" ref="29064087"/>
<reference key="parent" ref="476462426"/>
</object>
</object> </object>
</object> </object>
<object class="NSMutableDictionary" key="flattenedProperties"> <object class="NSMutableDictionary" key="flattenedProperties">
@@ -2084,6 +2133,7 @@
<string>10.IBPluginDependency</string> <string>10.IBPluginDependency</string>
<string>10.ImportedFromIB2</string> <string>10.ImportedFromIB2</string>
<string>11.IBPluginDependency</string> <string>11.IBPluginDependency</string>
<string>11.IBViewBoundsToFrameTransform</string>
<string>11.ImportedFromIB2</string> <string>11.ImportedFromIB2</string>
<string>115.IBPluginDependency</string> <string>115.IBPluginDependency</string>
<string>116.IBPluginDependency</string> <string>116.IBPluginDependency</string>
@@ -2093,22 +2143,34 @@
<string>12.IBPluginDependency</string> <string>12.IBPluginDependency</string>
<string>12.ImportedFromIB2</string> <string>12.ImportedFromIB2</string>
<string>120.IBPluginDependency</string> <string>120.IBPluginDependency</string>
<string>120.IBViewBoundsToFrameTransform</string>
<string>120.ImportedFromIB2</string> <string>120.ImportedFromIB2</string>
<string>121.IBPluginDependency</string> <string>121.IBPluginDependency</string>
<string>122.IBPluginDependency</string> <string>122.IBPluginDependency</string>
<string>122.IBViewBoundsToFrameTransform</string>
<string>123.IBPluginDependency</string> <string>123.IBPluginDependency</string>
<string>125.IBPluginDependency</string> <string>125.IBPluginDependency</string>
<string>125.IBViewBoundsToFrameTransform</string>
<string>125.ImportedFromIB2</string> <string>125.ImportedFromIB2</string>
<string>126.IBPluginDependency</string> <string>126.IBPluginDependency</string>
<string>129.IBPluginDependency</string>
<string>129.IBViewBoundsToFrameTransform</string>
<string>129.ImportedFromIB2</string>
<string>13.IBPluginDependency</string> <string>13.IBPluginDependency</string>
<string>13.IBViewBoundsToFrameTransform</string>
<string>13.ImportedFromIB2</string> <string>13.ImportedFromIB2</string>
<string>130.IBPluginDependency</string>
<string>14.IBPluginDependency</string> <string>14.IBPluginDependency</string>
<string>14.IBViewBoundsToFrameTransform</string>
<string>14.ImportedFromIB2</string> <string>14.ImportedFromIB2</string>
<string>15.IBPluginDependency</string> <string>15.IBPluginDependency</string>
<string>15.IBViewBoundsToFrameTransform</string>
<string>15.ImportedFromIB2</string> <string>15.ImportedFromIB2</string>
<string>17.IBPluginDependency</string> <string>17.IBPluginDependency</string>
<string>17.IBViewBoundsToFrameTransform</string>
<string>17.ImportedFromIB2</string> <string>17.ImportedFromIB2</string>
<string>18.IBPluginDependency</string> <string>18.IBPluginDependency</string>
<string>18.IBViewBoundsToFrameTransform</string>
<string>18.ImportedFromIB2</string> <string>18.ImportedFromIB2</string>
<string>19.IBPluginDependency</string> <string>19.IBPluginDependency</string>
<string>19.ImportedFromIB2</string> <string>19.ImportedFromIB2</string>
@@ -2119,8 +2181,10 @@
<string>2.windowTemplate.hasMinSize</string> <string>2.windowTemplate.hasMinSize</string>
<string>2.windowTemplate.minSize</string> <string>2.windowTemplate.minSize</string>
<string>20.IBPluginDependency</string> <string>20.IBPluginDependency</string>
<string>20.IBViewBoundsToFrameTransform</string>
<string>20.ImportedFromIB2</string> <string>20.ImportedFromIB2</string>
<string>21.IBPluginDependency</string> <string>21.IBPluginDependency</string>
<string>21.IBViewBoundsToFrameTransform</string>
<string>21.ImportedFromIB2</string> <string>21.ImportedFromIB2</string>
<string>22.IBPluginDependency</string> <string>22.IBPluginDependency</string>
<string>22.ImportedFromIB2</string> <string>22.ImportedFromIB2</string>
@@ -2155,6 +2219,7 @@
<string>39.IBPluginDependency</string> <string>39.IBPluginDependency</string>
<string>39.ImportedFromIB2</string> <string>39.ImportedFromIB2</string>
<string>4.IBPluginDependency</string> <string>4.IBPluginDependency</string>
<string>4.IBViewBoundsToFrameTransform</string>
<string>4.ImportedFromIB2</string> <string>4.ImportedFromIB2</string>
<string>40.IBPluginDependency</string> <string>40.IBPluginDependency</string>
<string>40.ImportedFromIB2</string> <string>40.ImportedFromIB2</string>
@@ -2166,6 +2231,7 @@
<string>45.IBPluginDependency</string> <string>45.IBPluginDependency</string>
<string>46.IBPluginDependency</string> <string>46.IBPluginDependency</string>
<string>5.IBPluginDependency</string> <string>5.IBPluginDependency</string>
<string>5.IBViewBoundsToFrameTransform</string>
<string>5.ImportedFromIB2</string> <string>5.ImportedFromIB2</string>
<string>54.IBPluginDependency</string> <string>54.IBPluginDependency</string>
<string>55.IBPluginDependency</string> <string>55.IBPluginDependency</string>
@@ -2178,6 +2244,7 @@
<string>59.IBPluginDependency</string> <string>59.IBPluginDependency</string>
<string>59.ImportedFromIB2</string> <string>59.ImportedFromIB2</string>
<string>6.IBPluginDependency</string> <string>6.IBPluginDependency</string>
<string>6.IBViewBoundsToFrameTransform</string>
<string>6.ImportedFromIB2</string> <string>6.ImportedFromIB2</string>
<string>60.IBPluginDependency</string> <string>60.IBPluginDependency</string>
<string>61.IBPluginDependency</string> <string>61.IBPluginDependency</string>
@@ -2190,8 +2257,10 @@
<string>68.IBPluginDependency</string> <string>68.IBPluginDependency</string>
<string>69.IBPluginDependency</string> <string>69.IBPluginDependency</string>
<string>7.IBPluginDependency</string> <string>7.IBPluginDependency</string>
<string>7.IBViewBoundsToFrameTransform</string>
<string>7.ImportedFromIB2</string> <string>7.ImportedFromIB2</string>
<string>8.IBPluginDependency</string> <string>8.IBPluginDependency</string>
<string>8.IBViewBoundsToFrameTransform</string>
<string>8.ImportedFromIB2</string> <string>8.ImportedFromIB2</string>
<string>9.IBPluginDependency</string> <string>9.IBPluginDependency</string>
<string>9.ImportedFromIB2</string> <string>9.ImportedFromIB2</string>
@@ -2204,6 +2273,9 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBcAAAwlQAAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -2213,34 +2285,70 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBYAAAwzQAAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBiAAAwyMAAA</bytes>
</object>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBcAAAw2QAAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBoAAAw18AAA</bytes>
</object>
<boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBcAAAwggAAA</bytes>
</object>
<boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBYAAAwuQAAA</bytes>
</object>
<boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBYAAAwwUAAA</bytes>
</object>
<boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBcAAAwroAAA</bytes>
</object>
<boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABDdAAAwigAAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
<string>{{555, 254}, {406, 343}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <string>{{555, 254}, {406, 343}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/>
<string>{{555, 271}, {406, 326}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{555, 271}, {406, 326}}</string>
<boolean value="YES"/> <boolean value="YES"/>
<boolean value="YES"/> <boolean value="YES"/>
<string>{213, 107}</string> <string>{213, 107}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBcAAAwpIAAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBcAAAwuIAAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
@@ -2275,6 +2383,9 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABDJAAAwwgAAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
@@ -2286,6 +2397,9 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABCtAAAwwgAAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -2298,6 +2412,9 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABDOwAAwxwAAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -2310,8 +2427,14 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABDJAAAwxwAAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABCtAAAwxwAAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
@@ -2333,7 +2456,7 @@
</object> </object>
</object> </object>
<nil key="sourceID"/> <nil key="sourceID"/>
<int key="maxID">128</int> <int key="maxID">132</int>
</object> </object>
<object class="IBClassDescriber" key="IBDocument.Classes"> <object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions"> <object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -2345,6 +2468,13 @@
<string key="minorKey">../views/HSOutlineView.h</string> <string key="minorKey">../views/HSOutlineView.h</string>
</object> </object>
</object> </object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">../views/HSTableView.h</string>
</object>
</object>
<object class="IBPartialClassDescription"> <object class="IBPartialClassDescription">
<string key="className">NSObject</string> <string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier"> <object class="IBClassDescriptionSource" key="sourceIdentifier">

View File

@@ -0,0 +1,102 @@
/* Class = "NSWindow"; title = "dupeGuru ME Preferences"; ObjectID = "2"; */
"2.title" = "Préférences de dupeGuru ME";
/* Class = "NSTextFieldCell"; title = "More results"; ObjectID = "29"; */
"29.title" = "+ de doubles";
/* Class = "NSTextFieldCell"; title = "Fewer results"; ObjectID = "30"; */
"30.title" = "- de doubles";
/* Class = "NSTextFieldCell"; title = "Filter hardness:"; ObjectID = "31"; */
"31.title" = "Seuil du filtre:";
/* Class = "NSTextFieldCell"; title = "Scan type:"; ObjectID = "32"; */
"32.title" = "Type de scan:";
/* Class = "NSMenuItem"; title = "Content"; ObjectID = "35"; */
"35.title" = "Contenu";
/* Class = "NSMenuItem"; title = "Filename"; ObjectID = "36"; */
"36.title" = "Nom de fichier";
/* Class = "NSMenuItem"; title = "Filename - Fields"; ObjectID = "37"; */
"37.title" = "Nom de fichier (Champs)";
/* Class = "NSMenuItem"; title = "Tags"; ObjectID = "38"; */
"38.title" = "Tags";
/* Class = "NSMenuItem"; title = "Audio Content"; ObjectID = "39"; */
"39.title" = "Contenu Audio";
/* Class = "NSMenuItem"; title = "Filename - Fields (No Order)"; ObjectID = "40"; */
"40.title" = "Nom de fichier (Champs sans ordre)";
/* Class = "NSButtonCell"; title = "Word weighting"; ObjectID = "41"; */
"41.title" = "Proportionalité des mots";
/* Class = "NSButtonCell"; title = "Can mix file kind"; ObjectID = "42"; */
"42.title" = "Comparer les fichiers de différents types";
/* Class = "NSButtonCell"; title = "Reset to Defaults"; ObjectID = "45"; */
"45.title" = "Options par défaut";
/* Class = "NSButtonCell"; title = "Match similar words"; ObjectID = "46"; */
"46.title" = "Comparer les mots similaires";
/* Class = "NSTextFieldCell"; title = "Copy and Move:"; ObjectID = "54"; */
"54.title" = "Déplacements de fichiers:";
/* Class = "NSMenuItem"; title = "Recreate relative path"; ObjectID = "57"; */
"57.title" = "Re-créer chemins relatifs";
/* Class = "NSMenuItem"; title = "Recreate absolute path"; ObjectID = "58"; */
"58.title" = "Re-créer chemins absolus";
/* Class = "NSMenuItem"; title = "Right in destination"; ObjectID = "59"; */
"59.title" = "Directement à la destination";
/* Class = "NSButtonCell"; title = "Automatically check for updates"; ObjectID = "60"; */
"60.title" = "Vérifier automatiquement les mises à jour";
/* Class = "NSButtonCell"; title = "Use regular expressions when filtering"; ObjectID = "61"; */
"61.title" = "Utiliser les expressions régulières pour les filtres";
/* Class = "NSButtonCell"; title = "Remove empty folders after delete and move"; ObjectID = "62"; */
"62.title" = "Effacer les dossiers vides après un déplacement";
/* Class = "NSTextFieldCell"; title = "Tags to scan:"; ObjectID = "63"; */
"63.title" = "Tags à scanner:";
/* Class = "NSButtonCell"; title = "Track"; ObjectID = "64"; */
"64.title" = "Track";
/* Class = "NSButtonCell"; title = "Artist"; ObjectID = "65"; */
"65.title" = "Artiste";
/* Class = "NSButtonCell"; title = "Album"; ObjectID = "66"; */
"66.title" = "Album";
/* Class = "NSButtonCell"; title = "Title"; ObjectID = "67"; */
"67.title" = "Titre";
/* Class = "NSButtonCell"; title = "Genre"; ObjectID = "68"; */
"68.title" = "Genre";
/* Class = "NSButtonCell"; title = "Year"; ObjectID = "69"; */
"69.title" = "Année";
/* Class = "NSTabViewItem"; label = "Basic"; ObjectID = "116"; */
"116.label" = "Simple";
/* Class = "NSTabViewItem"; label = "Advanced"; ObjectID = "117"; */
"117.label" = "Avancé";
/* Class = "NSTextFieldCell"; title = "Custom Command (arguments: %d for dupe, %r for ref):"; ObjectID = "121"; */
"121.title" = "Commande perso. (arguments: %d pour doublon, %r pour réf):";
/* Class = "NSButtonCell"; title = "Ignore duplicates hardlinking to the same file"; ObjectID = "126"; */
"126.title" = "Ignorer doublons avec hardlink vers le même fichier";
/* Class = "NSButtonCell"; title = "Debug mode (restart required)"; ObjectID = "130"; */
"130.title" = "Mode de déboguage (redémarrage requis)";

File diff suppressed because it is too large Load Diff

View File

@@ -11,8 +11,5 @@ http://www.hardcoded.net/licenses/bsd_license
#import "PyDupeGuru.h" #import "PyDupeGuru.h"
@interface AppDelegate : AppDelegateBase {} @interface AppDelegate : AppDelegateBase {}
- (IBAction)openWebsite:(id)sender;
- (IBAction)toggleDirectories:(id)sender;
- (PyDupeGuru *)py; - (PyDupeGuru *)py;
@end @end

View File

@@ -13,6 +13,7 @@ http://www.hardcoded.net/licenses/bsd_license
#import "Consts.h" #import "Consts.h"
#import "DetailsPanel.h" #import "DetailsPanel.h"
#import "DirectoryPanel.h" #import "DirectoryPanel.h"
#import "ResultWindow.h"
@implementation AppDelegate @implementation AppDelegate
+ (void)initialize + (void)initialize
@@ -34,45 +35,35 @@ http://www.hardcoded.net/licenses/bsd_license
[ud registerDefaults:d]; [ud registerDefaults:d];
} }
- (id)init - (NSString *)homepageURL
{ {
self = [super init]; return @"http://www.hardcoded.net/dupeguru_pe/";
_directoryPanel = nil;
return self;
} }
- (DetailsPanel *)detailsPanel - (ResultWindowBase *)createResultWindow
{ {
if (!_detailsPanel) return [[ResultWindow alloc] initWithParentApp:self];
_detailsPanel = [[DetailsPanelPE alloc] initWithPy:py];
return _detailsPanel;
} }
- (IBAction)openWebsite:(id)sender - (DirectoryPanel *)createDirectoryPanel
{ {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://www.hardcoded.net/dupeguru_pe"]]; return [[DirectoryPanelPE alloc] initWithParentApp:self];
} }
- (IBAction)toggleDirectories:(id)sender - (DetailsPanel *)createDetailsPanel
{ {
[[self directoryPanel] toggleVisible:sender]; return [[DetailsPanelPE alloc] initWithPy:py];
} }
- (DirectoryPanel *)directoryPanel
{
if (!_directoryPanel)
_directoryPanel = [[DirectoryPanelPE alloc] initWithParentApp:self];
return _directoryPanel;
}
- (PyDupeGuru *)py { return (PyDupeGuru *)py; } - (PyDupeGuru *)py { return (PyDupeGuru *)py; }
//Delegate //Delegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{ {
NSMenu *actionsMenu = [[[NSApp mainMenu] itemWithTitle:@"Actions"] submenu];
// index 2 is just after "Clear Ingore List" // index 2 is just after "Clear Ingore List"
NSMenuItem *mi = [actionsMenu insertItemWithTitle:@"Clear Picture Cache" action:@selector(clearPictureCache:) keyEquivalent:@"P" atIndex:2]; NSMenuItem *mi = [actionsMenu insertItemWithTitle:TR(@"Clear Picture Cache")
[mi setTarget:result]; action:@selector(clearPictureCache:) keyEquivalent:@"P" atIndex:2];
[mi setTarget:[self resultWindow]];
[mi setKeyEquivalentModifierMask:NSCommandKeyMask|NSShiftKeyMask]; [mi setKeyEquivalentModifierMask:NSCommandKeyMask|NSShiftKeyMask];
[super applicationDidFinishLaunching:aNotification]; [super applicationDidFinishLaunching:aNotification];
} }

View File

@@ -7,45 +7,28 @@ http://www.hardcoded.net/licenses/bsd_license
*/ */
#import "DirectoryPanel.h" #import "DirectoryPanel.h"
#import "ProgressController.h" #import "Consts.h"
static NSString* jobAddIPhoto = @"jobAddIPhoto";
@implementation DirectoryPanelPE @implementation DirectoryPanelPE
- (id)initWithParentApp:(id)aParentApp - (id)initWithParentApp:(id)aParentApp
{ {
self = [super initWithParentApp:aParentApp]; self = [super initWithParentApp:aParentApp];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(jobCompleted:) name:JobCompletedNotification object:nil]; [[self window] setTitle:@"dupeGuru Picture Edition"];
_alwaysShowPopUp = YES;
return self; return self;
} }
- (void)fillPopUpMenu
{
[super fillPopUpMenu];
NSMenu *m = [addButtonPopUp menu];
NSMenuItem *mi = [m insertItemWithTitle:TR(@"Add iPhoto Library") action:@selector(addiPhoto:)
keyEquivalent:@"" atIndex:1];
[mi setTarget:self];
}
- (IBAction)addiPhoto:(id)sender - (IBAction)addiPhoto:(id)sender
{ {
[[ProgressController mainProgressController] setJobDesc:@"Adding iPhoto Library..."];
[[ProgressController mainProgressController] setJobId:jobAddIPhoto];
[[ProgressController mainProgressController] showSheetForParent:[self window]];
[self addDirectory:@"iPhoto Library"]; [self addDirectory:@"iPhoto Library"];
} }
- (IBAction)popupAddDirectoryMenu:(id)sender
{
NSMenu *m = [addButtonPopUp menu];
while ([m numberOfItems] > 0)
[m removeItemAtIndex:0];
NSMenuItem *mi = [m addItemWithTitle:@"Add New Directory..." action:@selector(askForDirectory:) keyEquivalent:@""];
[mi setTarget:self];
mi = [m addItemWithTitle:@"Add iPhoto Directory" action:@selector(addiPhoto:) keyEquivalent:@""];
[mi setTarget:self];
[m addItem:[NSMenuItem separatorItem]];
[_recentDirectories fillMenu:m];
[addButtonPopUp selectItem:nil];
[[addButtonPopUp cell] performClickWithFrame:[sender frame] inView:[sender superview]];
}
- (void)jobCompleted:(NSNotification *)aNotification
{
if ([[ProgressController mainProgressController] jobId] == jobAddIPhoto) {
[outlineView reloadData];
}
}
@end @end

View File

@@ -23,7 +23,7 @@
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>hsft</string> <string>hsft</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.11.1</string> <string>{version}</string>
<key>NSMainNibFile</key> <key>NSMainNibFile</key>
<string>MainMenu</string> <string>MainMenu</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>

View File

@@ -11,6 +11,4 @@ http://www.hardcoded.net/licenses/bsd_license
@interface ResultWindow : ResultWindowBase {} @interface ResultWindow : ResultWindowBase {}
- (IBAction)clearPictureCache:(id)sender; - (IBAction)clearPictureCache:(id)sender;
- (IBAction)startDuplicateScan:(id)sender;
- (IBAction)toggleDirectories:(id)sender;
@end @end

View File

@@ -8,26 +8,51 @@ http://www.hardcoded.net/licenses/bsd_license
#import "ResultWindow.h" #import "ResultWindow.h"
#import "Dialogs.h" #import "Dialogs.h"
#import "ProgressController.h"
#import "Utils.h" #import "Utils.h"
#import "AppDelegate.h"
#import "Consts.h" #import "Consts.h"
#import "PyDupeGuru.h"
@implementation ResultWindow @implementation ResultWindow
/* Override */ /* Override */
- (void)awakeFromNib - (void)initResultColumns
{ {
[super awakeFromNib]; NSTableColumn *refCol = [matches tableColumnWithIdentifier:@"0"];
[[self window] setTitle:@"dupeGuru Picture Edition"]; _resultColumns = [[NSMutableArray alloc] init];
NSMutableIndexSet *deltaColumns = [NSMutableIndexSet indexSetWithIndex:2]; [_resultColumns addObject:[matches tableColumnWithIdentifier:@"0"]]; // File Name
[deltaColumns addIndex:5]; [_resultColumns addObject:[self getColumnForIdentifier:1 title:TR(@"Folder") width:120 refCol:refCol]];
[table setDeltaColumns:deltaColumns]; NSTableColumn *sizeCol = [self getColumnForIdentifier:2 title:TR(@"Size (KB)") width:63 refCol:refCol];
[[sizeCol dataCell] setAlignment:NSRightTextAlignment];
[_resultColumns addObject:sizeCol];
[_resultColumns addObject:[self getColumnForIdentifier:3 title:TR(@"Kind") width:40 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:4 title:TR(@"Dimensions") width:80 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:5 title:TR(@"Modification") width:120 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:6 title:TR(@"Match %") width:58 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:7 title:TR(@"Dupe Count") width:80 refCol:refCol]];
}
- (void)setScanOptions
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
PyDupeGuru *_py = (PyDupeGuru *)py;
[_py setMinMatchPercentage:[ud objectForKey:@"minMatchPercentage"]];
[_py setMixFileKind:n2b([ud objectForKey:@"mixFileKind"])];
[_py setIgnoreHardlinkMatches:n2b([ud objectForKey:@"ignoreHardlinkMatches"])];
[_py setMatchScaled:[ud objectForKey:@"matchScaled"]];
}
- (NSString *)getScanErrorMessageForCode:(NSInteger)errorCode
{
if (errorCode == 4) {
return TR(@"IPhotoAppNotFoundMsg");
}
return [super getScanErrorMessageForCode:errorCode];
} }
/* Actions */ /* Actions */
- (IBAction)clearPictureCache:(id)sender - (IBAction)clearPictureCache:(id)sender
{ {
if ([Dialogs askYesNo:@"Do you really want to remove all your cached picture analysis?"] == NSAlertSecondButtonReturn) // NO NSString *msg = TR(@"ClearPictureCacheConfirmMsg");
if ([Dialogs askYesNo:msg] == NSAlertSecondButtonReturn) // NO
return; return;
[(PyDupeGuru *)py clearPictureCache]; [(PyDupeGuru *)py clearPictureCache];
} }
@@ -48,49 +73,4 @@ http://www.hardcoded.net/licenses/bsd_license
[columnsWidth setObject:i2n(58) forKey:@"6"]; [columnsWidth setObject:i2n(58) forKey:@"6"];
[self restoreColumnsPosition:columnsOrder widths:columnsWidth]; [self restoreColumnsPosition:columnsOrder widths:columnsWidth];
} }
- (IBAction)startDuplicateScan:(id)sender
{
if ([matches numberOfRows] > 0)
{
if ([Dialogs askYesNo:@"Are you sure you want to start a new duplicate scan?"] == NSAlertSecondButtonReturn) // NO
return;
}
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
PyDupeGuru *_py = (PyDupeGuru *)py;
[_py setMinMatchPercentage:[ud objectForKey:@"minMatchPercentage"]];
[_py setMixFileKind:n2b([ud objectForKey:@"mixFileKind"])];
[_py setIgnoreHardlinkMatches:n2b([ud objectForKey:@"ignoreHardlinkMatches"])];
[_py setMatchScaled:[ud objectForKey:@"matchScaled"]];
int r = n2i([py doScan]);
if (r != 0)
[[ProgressController mainProgressController] hide];
if (r == 3)
{
[Dialogs showMessage:@"The selected directories contain no scannable file."];
[app toggleDirectories:nil];
}
}
- (IBAction)toggleDirectories:(id)sender
{
[(AppDelegate *)app toggleDirectories:sender];
}
/* Public */
- (void)initResultColumns
{
NSTableColumn *refCol = [matches tableColumnWithIdentifier:@"0"];
_resultColumns = [[NSMutableArray alloc] init];
[_resultColumns addObject:[matches tableColumnWithIdentifier:@"0"]]; // File Name
[_resultColumns addObject:[self getColumnForIdentifier:1 title:@"Directory" width:120 refCol:refCol]];
NSTableColumn *sizeCol = [self getColumnForIdentifier:2 title:@"Size (KB)" width:63 refCol:refCol];
[[sizeCol dataCell] setAlignment:NSRightTextAlignment];
[_resultColumns addObject:sizeCol];
[_resultColumns addObject:[self getColumnForIdentifier:3 title:@"Kind" width:40 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:4 title:@"Dimensions" width:80 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:5 title:@"Modification" width:120 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:6 title:@"Match %" width:58 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:7 title:@"Dupe Count" width:80 refCol:refCol]];
}
@end @end

View File

@@ -4,17 +4,11 @@
# 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.app_cocoa_inter import PyDupeGuruBase, PyDetailsPanel from hscommon.trans import install_cocoa_trans
from core_pe import app_cocoa as app_pe_cocoa install_cocoa_trans()
# Fix py2app imports which chokes on relative imports and other stuff from core.app_cocoa_inter import PyDupeGuruBase, PyDetailsPanel
import hsutil.conflict from core_pe import app_cocoa as app_pe_cocoa, __appname__
import core.engine, core.fs, core.app
import core_pe.block, core_pe.cache, core_pe.matchbase, core_pe.data, core_pe._block_osx
import xml.etree.ElementPath
import gzip
import aem.kae
import appscript.defaultterminology
class PyDupeGuru(PyDupeGuruBase): class PyDupeGuru(PyDupeGuruBase):
def init(self): def init(self):
@@ -41,5 +35,5 @@ class PyDupeGuru(PyDupeGuruBase):
#---Registration #---Registration
def appName(self): def appName(self):
return "dupeGuru Picture Edition" return __appname__

View File

@@ -9,12 +9,16 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
CE031751109B340A00517EE6 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE031750109B340A00517EE6 /* Preferences.xib */; }; CE05339B12E5DA350029EF25 /* DirectoryPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE05339312E5DA350029EF25 /* DirectoryPanel.xib */; };
CE031754109B345200517EE6 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE031753109B345200517EE6 /* MainMenu.xib */; }; CE05339C12E5DA350029EF25 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE05339512E5DA350029EF25 /* MainMenu.xib */; };
CE073F6309CAE1A3005C1D2F /* dupeguru_pe_help in Resources */ = {isa = PBXBuildFile; fileRef = CE073F5409CAE1A3005C1D2F /* dupeguru_pe_help */; }; CE05339D12E5DA350029EF25 /* ProblemDialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE05339712E5DA350029EF25 /* ProblemDialog.xib */; };
CE05339E12E5DA350029EF25 /* ResultWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE05339912E5DA350029EF25 /* ResultWindow.xib */; };
CE0533A712E5DA4D0029EF25 /* DetailsPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE0533A312E5DA4D0029EF25 /* DetailsPanel.xib */; };
CE0533A812E5DA4D0029EF25 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE0533A512E5DA4D0029EF25 /* Preferences.xib */; };
CE0533AB12E5DA6A0029EF25 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = CE0533A912E5DA6A0029EF25 /* Localizable.strings */; };
CE073F6309CAE1A3005C1D2F /* help in Resources */ = {isa = PBXBuildFile; fileRef = CE073F5409CAE1A3005C1D2F /* help */; };
CE0C2AB61177011000BC749F /* HSTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0C2AB51177011000BC749F /* HSTable.m */; }; CE0C2AB61177011000BC749F /* HSTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0C2AB51177011000BC749F /* HSTable.m */; };
CE0C2ABD1177014200BC749F /* ProblemDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0C2ABB1177014200BC749F /* ProblemDialog.m */; }; CE0C2ABD1177014200BC749F /* ProblemDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0C2ABB1177014200BC749F /* ProblemDialog.m */; };
CE0C2AC81177021600BC749F /* ProblemDialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE0C2AC71177021600BC749F /* ProblemDialog.xib */; };
CE15C8A80ADEB8B50061D4A5 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE15C8A70ADEB8B50061D4A5 /* Sparkle.framework */; }; CE15C8A80ADEB8B50061D4A5 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE15C8A70ADEB8B50061D4A5 /* Sparkle.framework */; };
CE15C8C00ADEB8D40061D4A5 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE15C8A70ADEB8B50061D4A5 /* Sparkle.framework */; }; CE15C8C00ADEB8D40061D4A5 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE15C8A70ADEB8B50061D4A5 /* Sparkle.framework */; };
CE1EB5FE12537F9D0034AABB /* HSFairwareReminder.m in Sources */ = {isa = PBXBuildFile; fileRef = CE1EB5FC12537F9D0034AABB /* HSFairwareReminder.m */; }; CE1EB5FE12537F9D0034AABB /* HSFairwareReminder.m in Sources */ = {isa = PBXBuildFile; fileRef = CE1EB5FC12537F9D0034AABB /* HSFairwareReminder.m */; };
@@ -22,17 +26,16 @@
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; }; CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; };
CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9A09914ADF003581CE /* ResultWindow.m */; }; CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9A09914ADF003581CE /* ResultWindow.m */; };
CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */ = {isa = PBXBuildFile; fileRef = CE381CF509915304003581CE /* dg_cocoa.plugin */; }; CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */ = {isa = PBXBuildFile; fileRef = CE381CF509915304003581CE /* dg_cocoa.plugin */; };
CE4527AC12E5F6E700005A15 /* core.strings in Resources */ = {isa = PBXBuildFile; fileRef = CE4527AA12E5F6E700005A15 /* core.strings */; };
CE60180812DF3EA900236FDC /* HSRecentFiles.m in Sources */ = {isa = PBXBuildFile; fileRef = CE60180712DF3EA900236FDC /* HSRecentFiles.m */; };
CE6044EC0FE6796200B71262 /* DetailsPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE6044EB0FE6796200B71262 /* DetailsPanel.m */; }; CE6044EC0FE6796200B71262 /* DetailsPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE6044EB0FE6796200B71262 /* DetailsPanel.m */; };
CE68EE6809ABC48000971085 /* DirectoryPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE68EE6609ABC48000971085 /* DirectoryPanel.m */; }; CE68EE6809ABC48000971085 /* DirectoryPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE68EE6609ABC48000971085 /* DirectoryPanel.m */; };
CE6E0F3D1054EC62008D9390 /* dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = CE6E0F3C1054EC62008D9390 /* dsa_pub.pem */; }; CE6E0F3D1054EC62008D9390 /* dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = CE6E0F3C1054EC62008D9390 /* dsa_pub.pem */; };
CE77C89E10946C6D0078B0DB /* DirectoryPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE77C89C10946C6D0078B0DB /* DirectoryPanel.xib */; };
CE77C8A810946CE20078B0DB /* DetailsPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE77C8A710946CE20078B0DB /* DetailsPanel.xib */; };
CE7AC9181119911200D02F6C /* ErrorReportWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE7AC9151119911200D02F6C /* ErrorReportWindow.xib */; }; CE7AC9181119911200D02F6C /* ErrorReportWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE7AC9151119911200D02F6C /* ErrorReportWindow.xib */; };
CE7AC9191119911200D02F6C /* progress.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE7AC9161119911200D02F6C /* progress.xib */; }; CE7AC9191119911200D02F6C /* progress.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE7AC9161119911200D02F6C /* progress.xib */; };
CE80DB2E0FC192D60086DCA6 /* Dialogs.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB1C0FC192D60086DCA6 /* Dialogs.m */; }; CE80DB2E0FC192D60086DCA6 /* Dialogs.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB1C0FC192D60086DCA6 /* Dialogs.m */; };
CE80DB2F0FC192D60086DCA6 /* HSErrorReportWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB1E0FC192D60086DCA6 /* HSErrorReportWindow.m */; }; CE80DB2F0FC192D60086DCA6 /* HSErrorReportWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB1E0FC192D60086DCA6 /* HSErrorReportWindow.m */; };
CE80DB310FC192D60086DCA6 /* ProgressController.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB220FC192D60086DCA6 /* ProgressController.m */; }; CE80DB310FC192D60086DCA6 /* ProgressController.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB220FC192D60086DCA6 /* ProgressController.m */; };
CE80DB320FC192D60086DCA6 /* RecentDirectories.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB250FC192D60086DCA6 /* RecentDirectories.m */; };
CE80DB350FC192D60086DCA6 /* Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB2B0FC192D60086DCA6 /* Utils.m */; }; CE80DB350FC192D60086DCA6 /* Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB2B0FC192D60086DCA6 /* Utils.m */; };
CE80DB360FC192D60086DCA6 /* ValueTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB2D0FC192D60086DCA6 /* ValueTransformers.m */; }; CE80DB360FC192D60086DCA6 /* ValueTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB2D0FC192D60086DCA6 /* ValueTransformers.m */; };
CE80DB470FC193650086DCA6 /* NSNotificationAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB460FC193650086DCA6 /* NSNotificationAdditions.m */; }; CE80DB470FC193650086DCA6 /* NSNotificationAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB460FC193650086DCA6 /* NSNotificationAdditions.m */; };
@@ -51,15 +54,14 @@
CE9EA75C1122C96C008CD2BC /* NSTableViewAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE9EA7551122C96C008CD2BC /* NSTableViewAdditions.m */; }; CE9EA75C1122C96C008CD2BC /* NSTableViewAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE9EA7551122C96C008CD2BC /* NSTableViewAdditions.m */; };
CE9EA7721122CA0B008CD2BC /* DirectoryOutline.m in Sources */ = {isa = PBXBuildFile; fileRef = CE9EA7701122CA0B008CD2BC /* DirectoryOutline.m */; }; CE9EA7721122CA0B008CD2BC /* DirectoryOutline.m in Sources */ = {isa = PBXBuildFile; fileRef = CE9EA7701122CA0B008CD2BC /* DirectoryOutline.m */; };
CEBAE4270FDA97E000B7887D /* BRSingleLineFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = CEBAE4240FDA97E000B7887D /* BRSingleLineFormatter.m */; }; CEBAE4270FDA97E000B7887D /* BRSingleLineFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = CEBAE4240FDA97E000B7887D /* BRSingleLineFormatter.m */; };
CEC9DB4712CCAA6B003102F0 /* about.xib in Resources */ = {isa = PBXBuildFile; fileRef = CEC9DB4612CCAA6B003102F0 /* about.xib */; };
CEC9DB4C12CCAA7D003102F0 /* HSAboutBox.m in Sources */ = {isa = PBXBuildFile; fileRef = CEC9DB4B12CCAA7D003102F0 /* HSAboutBox.m */; };
CECA899C09DB132E00A3D774 /* DetailsPanel.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CECA899A09DB132E00A3D774 /* DetailsPanel.h */; }; CECA899C09DB132E00A3D774 /* DetailsPanel.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CECA899A09DB132E00A3D774 /* DetailsPanel.h */; };
CECA899D09DB132E00A3D774 /* DetailsPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CECA899B09DB132E00A3D774 /* DetailsPanel.m */; }; CECA899D09DB132E00A3D774 /* DetailsPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CECA899B09DB132E00A3D774 /* DetailsPanel.m */; };
CEEB135209C837A2004D2330 /* dupeguru.icns in Resources */ = {isa = PBXBuildFile; fileRef = CEEB135109C837A2004D2330 /* dupeguru.icns */; }; CEEB135209C837A2004D2330 /* dupeguru.icns in Resources */ = {isa = PBXBuildFile; fileRef = CEEB135109C837A2004D2330 /* dupeguru.icns */; };
CEF12A7E124DFD400087B51D /* HSTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = CEF12A7D124DFD400087B51D /* HSTableView.m */; }; CEF12A7E124DFD400087B51D /* HSTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = CEF12A7D124DFD400087B51D /* HSTableView.m */; };
CEF12A84124DFD620087B51D /* ResultTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CEF12A83124DFD620087B51D /* ResultTable.m */; }; CEF12A84124DFD620087B51D /* ResultTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CEF12A83124DFD620087B51D /* ResultTable.m */; };
CEFC294609C89E3D00D9F998 /* folder32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC294509C89E3D00D9F998 /* folder32.png */; }; CEFC294609C89E3D00D9F998 /* folder32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC294509C89E3D00D9F998 /* folder32.png */; };
CEFC295509C89FF200D9F998 /* details32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC295309C89FF200D9F998 /* details32.png */; };
CEFC295609C89FF200D9F998 /* preferences32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC295409C89FF200D9F998 /* preferences32.png */; };
CEFCDE2D0AB0418600C33A93 /* dgpe_logo_32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFCDE2C0AB0418600C33A93 /* dgpe_logo_32.png */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
@@ -80,21 +82,33 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; }; 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; }; 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = SOURCE_ROOT; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; }; 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; }; 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; };
8D1107320486CEB800E47090 /* dupeGuru PE.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "dupeGuru PE.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 8D1107320486CEB800E47090 /* dupeGuru PE.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "dupeGuru PE.app"; sourceTree = BUILT_PRODUCTS_DIR; };
CE031750109B340A00517EE6 /* Preferences.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = Preferences.xib; sourceTree = "<group>"; }; CE05339412E5DA350029EF25 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../base/en.lproj/DirectoryPanel.xib; sourceTree = SOURCE_ROOT; };
CE031753109B345200517EE6 /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MainMenu.xib; path = ../../base/xib/MainMenu.xib; sourceTree = "<group>"; }; CE05339612E5DA350029EF25 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../base/en.lproj/MainMenu.xib; sourceTree = SOURCE_ROOT; };
CE073F5409CAE1A3005C1D2F /* dupeguru_pe_help */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dupeguru_pe_help; path = ../../help_pe/dupeguru_pe_help; sourceTree = SOURCE_ROOT; }; CE05339812E5DA350029EF25 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../base/en.lproj/ProblemDialog.xib; sourceTree = SOURCE_ROOT; };
CE05339A12E5DA350029EF25 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../base/en.lproj/ResultWindow.xib; sourceTree = SOURCE_ROOT; };
CE05339F12E5DA420029EF25 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../base/fr.lproj/DirectoryPanel.xib; sourceTree = SOURCE_ROOT; };
CE0533A012E5DA420029EF25 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../base/fr.lproj/MainMenu.xib; sourceTree = SOURCE_ROOT; };
CE0533A112E5DA420029EF25 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../base/fr.lproj/ProblemDialog.xib; sourceTree = SOURCE_ROOT; };
CE0533A212E5DA420029EF25 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../base/fr.lproj/ResultWindow.xib; sourceTree = SOURCE_ROOT; };
CE0533A412E5DA4D0029EF25 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/DetailsPanel.xib; sourceTree = "<group>"; };
CE0533A612E5DA4D0029EF25 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/Preferences.xib; sourceTree = "<group>"; };
CE0533AA12E5DA6A0029EF25 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = ../base/en.lproj/Localizable.strings; sourceTree = SOURCE_ROOT; };
CE0533AC12E5DA790029EF25 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = ../base/fr.lproj/Localizable.strings; sourceTree = SOURCE_ROOT; };
CE0533AD12E5DAAD0029EF25 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = fr.lproj/DetailsPanel.xib; sourceTree = "<group>"; };
CE0533AE12E5DAAD0029EF25 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = fr.lproj/Preferences.xib; sourceTree = "<group>"; };
CE0533B712E5DC040029EF25 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../../cocoalib/fr.lproj/FairwareReminder.xib; sourceTree = SOURCE_ROOT; };
CE073F5409CAE1A3005C1D2F /* help */ = {isa = PBXFileReference; lastKnownFileType = folder; name = help; path = ../../build/help; sourceTree = SOURCE_ROOT; };
CE0C2AAA117700E700BC749F /* PyTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PyTable.h; sourceTree = "<group>"; }; CE0C2AAA117700E700BC749F /* PyTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PyTable.h; sourceTree = "<group>"; };
CE0C2AB41177011000BC749F /* HSTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HSTable.h; sourceTree = "<group>"; }; CE0C2AB41177011000BC749F /* HSTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HSTable.h; sourceTree = "<group>"; };
CE0C2AB51177011000BC749F /* HSTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSTable.m; sourceTree = "<group>"; }; CE0C2AB51177011000BC749F /* HSTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSTable.m; sourceTree = "<group>"; };
CE0C2ABA1177014200BC749F /* ProblemDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProblemDialog.h; path = ../base/ProblemDialog.h; sourceTree = SOURCE_ROOT; }; CE0C2ABA1177014200BC749F /* ProblemDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProblemDialog.h; path = ../base/ProblemDialog.h; sourceTree = SOURCE_ROOT; };
CE0C2ABB1177014200BC749F /* ProblemDialog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProblemDialog.m; path = ../base/ProblemDialog.m; sourceTree = SOURCE_ROOT; }; CE0C2ABB1177014200BC749F /* ProblemDialog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProblemDialog.m; path = ../base/ProblemDialog.m; sourceTree = SOURCE_ROOT; };
CE0C2ABC1177014200BC749F /* PyProblemDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyProblemDialog.h; path = ../base/PyProblemDialog.h; sourceTree = SOURCE_ROOT; }; CE0C2ABC1177014200BC749F /* PyProblemDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyProblemDialog.h; path = ../base/PyProblemDialog.h; sourceTree = SOURCE_ROOT; };
CE0C2AC71177021600BC749F /* ProblemDialog.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ProblemDialog.xib; path = ../base/xib/ProblemDialog.xib; sourceTree = SOURCE_ROOT; };
CE15C8A70ADEB8B50061D4A5 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = /Library/Frameworks/Sparkle.framework; sourceTree = "<absolute>"; }; CE15C8A70ADEB8B50061D4A5 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = /Library/Frameworks/Sparkle.framework; sourceTree = "<absolute>"; };
CE18126F111C9D5100E49FCE /* PyDetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyDetailsPanel.h; path = ../base/PyDetailsPanel.h; sourceTree = SOURCE_ROOT; }; CE18126F111C9D5100E49FCE /* PyDetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyDetailsPanel.h; path = ../base/PyDetailsPanel.h; sourceTree = SOURCE_ROOT; };
CE1EB5FB12537F9D0034AABB /* HSFairwareReminder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSFairwareReminder.h; path = ../../cocoalib/HSFairwareReminder.h; sourceTree = SOURCE_ROOT; }; CE1EB5FB12537F9D0034AABB /* HSFairwareReminder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSFairwareReminder.h; path = ../../cocoalib/HSFairwareReminder.h; sourceTree = SOURCE_ROOT; };
@@ -106,13 +120,15 @@
CE381C9A09914ADF003581CE /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = ResultWindow.m; sourceTree = SOURCE_ROOT; }; CE381C9A09914ADF003581CE /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = ResultWindow.m; sourceTree = SOURCE_ROOT; };
CE381C9B09914ADF003581CE /* ResultWindow.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = ResultWindow.h; sourceTree = SOURCE_ROOT; }; CE381C9B09914ADF003581CE /* ResultWindow.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = ResultWindow.h; sourceTree = SOURCE_ROOT; };
CE381CF509915304003581CE /* dg_cocoa.plugin */ = {isa = PBXFileReference; lastKnownFileType = folder; path = dg_cocoa.plugin; sourceTree = SOURCE_ROOT; }; CE381CF509915304003581CE /* dg_cocoa.plugin */ = {isa = PBXFileReference; lastKnownFileType = folder; path = dg_cocoa.plugin; sourceTree = SOURCE_ROOT; };
CE4527AB12E5F6E700005A15 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = ../base/en.lproj/core.strings; sourceTree = SOURCE_ROOT; };
CE4527B012E5F72600005A15 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = ../base/fr.lproj/core.strings; sourceTree = SOURCE_ROOT; };
CE60180612DF3EA900236FDC /* HSRecentFiles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSRecentFiles.h; path = ../../cocoalib/HSRecentFiles.h; sourceTree = SOURCE_ROOT; };
CE60180712DF3EA900236FDC /* HSRecentFiles.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSRecentFiles.m; path = ../../cocoalib/HSRecentFiles.m; sourceTree = SOURCE_ROOT; };
CE6044EA0FE6796200B71262 /* DetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DetailsPanel.h; path = ../base/DetailsPanel.h; sourceTree = SOURCE_ROOT; }; CE6044EA0FE6796200B71262 /* DetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DetailsPanel.h; path = ../base/DetailsPanel.h; sourceTree = SOURCE_ROOT; };
CE6044EB0FE6796200B71262 /* DetailsPanel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DetailsPanel.m; path = ../base/DetailsPanel.m; sourceTree = SOURCE_ROOT; }; CE6044EB0FE6796200B71262 /* DetailsPanel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DetailsPanel.m; path = ../base/DetailsPanel.m; sourceTree = SOURCE_ROOT; };
CE68EE6509ABC48000971085 /* DirectoryPanel.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = DirectoryPanel.h; sourceTree = SOURCE_ROOT; }; CE68EE6509ABC48000971085 /* DirectoryPanel.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = DirectoryPanel.h; sourceTree = SOURCE_ROOT; };
CE68EE6609ABC48000971085 /* DirectoryPanel.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = DirectoryPanel.m; sourceTree = SOURCE_ROOT; }; CE68EE6609ABC48000971085 /* DirectoryPanel.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = DirectoryPanel.m; sourceTree = SOURCE_ROOT; };
CE6E0F3C1054EC62008D9390 /* dsa_pub.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = dsa_pub.pem; path = ../base/dsa_pub.pem; sourceTree = "<group>"; }; CE6E0F3C1054EC62008D9390 /* dsa_pub.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = dsa_pub.pem; path = ../base/dsa_pub.pem; sourceTree = "<group>"; };
CE77C89C10946C6D0078B0DB /* DirectoryPanel.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = DirectoryPanel.xib; path = ../../base/xib/DirectoryPanel.xib; sourceTree = "<group>"; };
CE77C8A710946CE20078B0DB /* DetailsPanel.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DetailsPanel.xib; sourceTree = "<group>"; };
CE7AC9151119911200D02F6C /* ErrorReportWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ErrorReportWindow.xib; sourceTree = "<group>"; }; CE7AC9151119911200D02F6C /* ErrorReportWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ErrorReportWindow.xib; sourceTree = "<group>"; };
CE7AC9161119911200D02F6C /* progress.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = progress.xib; sourceTree = "<group>"; }; CE7AC9161119911200D02F6C /* progress.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = progress.xib; sourceTree = "<group>"; };
CE80DB1B0FC192D60086DCA6 /* Dialogs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Dialogs.h; path = ../../cocoalib/Dialogs.h; sourceTree = SOURCE_ROOT; }; CE80DB1B0FC192D60086DCA6 /* Dialogs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Dialogs.h; path = ../../cocoalib/Dialogs.h; sourceTree = SOURCE_ROOT; };
@@ -122,8 +138,6 @@
CE80DB210FC192D60086DCA6 /* ProgressController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProgressController.h; path = ../../cocoalib/ProgressController.h; sourceTree = SOURCE_ROOT; }; CE80DB210FC192D60086DCA6 /* ProgressController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProgressController.h; path = ../../cocoalib/ProgressController.h; sourceTree = SOURCE_ROOT; };
CE80DB220FC192D60086DCA6 /* ProgressController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProgressController.m; path = ../../cocoalib/ProgressController.m; sourceTree = SOURCE_ROOT; }; CE80DB220FC192D60086DCA6 /* ProgressController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProgressController.m; path = ../../cocoalib/ProgressController.m; sourceTree = SOURCE_ROOT; };
CE80DB230FC192D60086DCA6 /* PyApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyApp.h; path = ../../cocoalib/PyApp.h; sourceTree = SOURCE_ROOT; }; CE80DB230FC192D60086DCA6 /* PyApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyApp.h; path = ../../cocoalib/PyApp.h; sourceTree = SOURCE_ROOT; };
CE80DB240FC192D60086DCA6 /* RecentDirectories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RecentDirectories.h; path = ../../cocoalib/RecentDirectories.h; sourceTree = SOURCE_ROOT; };
CE80DB250FC192D60086DCA6 /* RecentDirectories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RecentDirectories.m; path = ../../cocoalib/RecentDirectories.m; sourceTree = SOURCE_ROOT; };
CE80DB2A0FC192D60086DCA6 /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Utils.h; path = ../../cocoalib/Utils.h; sourceTree = SOURCE_ROOT; }; CE80DB2A0FC192D60086DCA6 /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Utils.h; path = ../../cocoalib/Utils.h; sourceTree = SOURCE_ROOT; };
CE80DB2B0FC192D60086DCA6 /* Utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Utils.m; path = ../../cocoalib/Utils.m; sourceTree = SOURCE_ROOT; }; CE80DB2B0FC192D60086DCA6 /* Utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Utils.m; path = ../../cocoalib/Utils.m; sourceTree = SOURCE_ROOT; };
CE80DB2C0FC192D60086DCA6 /* ValueTransformers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueTransformers.h; path = ../../cocoalib/ValueTransformers.h; sourceTree = SOURCE_ROOT; }; CE80DB2C0FC192D60086DCA6 /* ValueTransformers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueTransformers.h; path = ../../cocoalib/ValueTransformers.h; sourceTree = SOURCE_ROOT; };
@@ -165,6 +179,9 @@
CE9EA7711122CA0B008CD2BC /* PyDirectoryOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyDirectoryOutline.h; path = ../base/PyDirectoryOutline.h; sourceTree = SOURCE_ROOT; }; CE9EA7711122CA0B008CD2BC /* PyDirectoryOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyDirectoryOutline.h; path = ../base/PyDirectoryOutline.h; sourceTree = SOURCE_ROOT; };
CEBAE4230FDA97E000B7887D /* BRSingleLineFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BRSingleLineFormatter.h; path = ../../cocoalib/brsinglelineformatter/BRSingleLineFormatter.h; sourceTree = SOURCE_ROOT; }; CEBAE4230FDA97E000B7887D /* BRSingleLineFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BRSingleLineFormatter.h; path = ../../cocoalib/brsinglelineformatter/BRSingleLineFormatter.h; sourceTree = SOURCE_ROOT; };
CEBAE4240FDA97E000B7887D /* BRSingleLineFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BRSingleLineFormatter.m; path = ../../cocoalib/brsinglelineformatter/BRSingleLineFormatter.m; sourceTree = SOURCE_ROOT; }; CEBAE4240FDA97E000B7887D /* BRSingleLineFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BRSingleLineFormatter.m; path = ../../cocoalib/brsinglelineformatter/BRSingleLineFormatter.m; sourceTree = SOURCE_ROOT; };
CEC9DB4612CCAA6B003102F0 /* about.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = about.xib; path = ../../cocoalib/xib/about.xib; sourceTree = SOURCE_ROOT; };
CEC9DB4A12CCAA7D003102F0 /* HSAboutBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSAboutBox.h; path = ../../cocoalib/HSAboutBox.h; sourceTree = SOURCE_ROOT; };
CEC9DB4B12CCAA7D003102F0 /* HSAboutBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSAboutBox.m; path = ../../cocoalib/HSAboutBox.m; sourceTree = SOURCE_ROOT; };
CECA899A09DB132E00A3D774 /* DetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = DetailsPanel.h; sourceTree = "<group>"; }; CECA899A09DB132E00A3D774 /* DetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = DetailsPanel.h; sourceTree = "<group>"; };
CECA899B09DB132E00A3D774 /* DetailsPanel.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = DetailsPanel.m; sourceTree = "<group>"; }; CECA899B09DB132E00A3D774 /* DetailsPanel.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = DetailsPanel.m; sourceTree = "<group>"; };
CEEB135109C837A2004D2330 /* dupeguru.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = dupeguru.icns; sourceTree = "<group>"; }; CEEB135109C837A2004D2330 /* dupeguru.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = dupeguru.icns; sourceTree = "<group>"; };
@@ -174,9 +191,6 @@
CEF12A82124DFD620087B51D /* ResultTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ResultTable.h; path = ../base/ResultTable.h; sourceTree = SOURCE_ROOT; }; CEF12A82124DFD620087B51D /* ResultTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ResultTable.h; path = ../base/ResultTable.h; sourceTree = SOURCE_ROOT; };
CEF12A83124DFD620087B51D /* ResultTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ResultTable.m; path = ../base/ResultTable.m; sourceTree = SOURCE_ROOT; }; CEF12A83124DFD620087B51D /* ResultTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ResultTable.m; path = ../base/ResultTable.m; sourceTree = SOURCE_ROOT; };
CEFC294509C89E3D00D9F998 /* folder32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = folder32.png; path = ../../images/folder32.png; sourceTree = SOURCE_ROOT; }; CEFC294509C89E3D00D9F998 /* folder32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = folder32.png; path = ../../images/folder32.png; sourceTree = SOURCE_ROOT; };
CEFC295309C89FF200D9F998 /* details32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = details32.png; path = ../../images/details32.png; sourceTree = SOURCE_ROOT; };
CEFC295409C89FF200D9F998 /* preferences32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = preferences32.png; path = ../../images/preferences32.png; sourceTree = SOURCE_ROOT; };
CEFCDE2C0AB0418600C33A93 /* dgpe_logo_32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dgpe_logo_32.png; path = ../../images/dgpe_logo_32.png; sourceTree = SOURCE_ROOT; };
CEFF18A009A4D387005E6321 /* PyDupeGuru.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = PyDupeGuru.h; sourceTree = SOURCE_ROOT; }; CEFF18A009A4D387005E6321 /* PyDupeGuru.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = PyDupeGuru.h; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@@ -196,6 +210,7 @@
080E96DDFE201D6D7F000001 /* DGPE */ = { 080E96DDFE201D6D7F000001 /* DGPE */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
29B97316FDCFA39411CA2CEA /* main.m */,
CE381C9509914ACE003581CE /* AppDelegate.h */, CE381C9509914ACE003581CE /* AppDelegate.h */,
CE381C9409914ACE003581CE /* AppDelegate.m */, CE381C9409914ACE003581CE /* AppDelegate.m */,
CE848A1809DD85810004CB44 /* Consts.h */, CE848A1809DD85810004CB44 /* Consts.h */,
@@ -243,7 +258,6 @@
080E96DDFE201D6D7F000001 /* DGPE */, 080E96DDFE201D6D7F000001 /* DGPE */,
CE80DB1A0FC192AB0086DCA6 /* cocoalib */, CE80DB1A0FC192AB0086DCA6 /* cocoalib */,
CE80DB810FC194BD0086DCA6 /* dgbase */, CE80DB810FC194BD0086DCA6 /* dgbase */,
29B97315FDCFA39411CA2CEA /* Other Sources */,
29B97317FDCFA39411CA2CEA /* Resources */, 29B97317FDCFA39411CA2CEA /* Resources */,
29B97323FDCFA39411CA2CEA /* Frameworks */, 29B97323FDCFA39411CA2CEA /* Frameworks */,
19C28FACFE9D520D11CA2CBB /* Products */, 19C28FACFE9D520D11CA2CBB /* Products */,
@@ -251,23 +265,17 @@
name = dupeguru; name = dupeguru;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
29B97315FDCFA39411CA2CEA /* Other Sources */ = {
isa = PBXGroup;
children = (
29B97316FDCFA39411CA2CEA /* main.m */,
);
name = "Other Sources";
sourceTree = "<group>";
};
29B97317FDCFA39411CA2CEA /* Resources */ = { 29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CE77C89A10946C6D0078B0DB /* xib */, CE073F5409CAE1A3005C1D2F /* help */,
CE073F5409CAE1A3005C1D2F /* dupeguru_pe_help */,
CE381CF509915304003581CE /* dg_cocoa.plugin */, CE381CF509915304003581CE /* dg_cocoa.plugin */,
CEFC294309C89E0000D9F998 /* images */, CEFC294309C89E0000D9F998 /* images */,
CE05339212E5DA1D0029EF25 /* xib */,
CEEB135109C837A2004D2330 /* dupeguru.icns */, CEEB135109C837A2004D2330 /* dupeguru.icns */,
8D1107310486CEB800E47090 /* Info.plist */, 8D1107310486CEB800E47090 /* Info.plist */,
CE0533A912E5DA6A0029EF25 /* Localizable.strings */,
CE4527AA12E5F6E700005A15 /* core.strings */,
CE6E0F3C1054EC62008D9390 /* dsa_pub.pem */, CE6E0F3C1054EC62008D9390 /* dsa_pub.pem */,
); );
name = Resources; name = Resources;
@@ -282,21 +290,23 @@
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
CE77C89A10946C6D0078B0DB /* xib */ = { CE05339212E5DA1D0029EF25 /* xib */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CE031753109B345200517EE6 /* MainMenu.xib */, CE05339312E5DA350029EF25 /* DirectoryPanel.xib */,
CE77C8A710946CE20078B0DB /* DetailsPanel.xib */, CE05339512E5DA350029EF25 /* MainMenu.xib */,
CE77C89C10946C6D0078B0DB /* DirectoryPanel.xib */, CE05339712E5DA350029EF25 /* ProblemDialog.xib */,
CE031750109B340A00517EE6 /* Preferences.xib */, CE05339912E5DA350029EF25 /* ResultWindow.xib */,
CE0C2AC71177021600BC749F /* ProblemDialog.xib */, CE0533A312E5DA4D0029EF25 /* DetailsPanel.xib */,
CE0533A512E5DA4D0029EF25 /* Preferences.xib */,
); );
path = xib; name = xib;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
CE7AC9141119911200D02F6C /* xib */ = { CE7AC9141119911200D02F6C /* xib */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CEC9DB4612CCAA6B003102F0 /* about.xib */,
CE1EB5FF12537FB90034AABB /* FairwareReminder.xib */, CE1EB5FF12537FB90034AABB /* FairwareReminder.xib */,
CE7AC9151119911200D02F6C /* ErrorReportWindow.xib */, CE7AC9151119911200D02F6C /* ErrorReportWindow.xib */,
CE7AC9161119911200D02F6C /* progress.xib */, CE7AC9161119911200D02F6C /* progress.xib */,
@@ -326,11 +336,13 @@
CE1EB5FB12537F9D0034AABB /* HSFairwareReminder.h */, CE1EB5FB12537F9D0034AABB /* HSFairwareReminder.h */,
CE1EB5FC12537F9D0034AABB /* HSFairwareReminder.m */, CE1EB5FC12537F9D0034AABB /* HSFairwareReminder.m */,
CE1EB5FD12537F9D0034AABB /* PyFairware.h */, CE1EB5FD12537F9D0034AABB /* PyFairware.h */,
CEC9DB4A12CCAA7D003102F0 /* HSAboutBox.h */,
CEC9DB4B12CCAA7D003102F0 /* HSAboutBox.m */,
CE60180612DF3EA900236FDC /* HSRecentFiles.h */,
CE60180712DF3EA900236FDC /* HSRecentFiles.m */,
CE80DB210FC192D60086DCA6 /* ProgressController.h */, CE80DB210FC192D60086DCA6 /* ProgressController.h */,
CE80DB220FC192D60086DCA6 /* ProgressController.m */, CE80DB220FC192D60086DCA6 /* ProgressController.m */,
CE80DB230FC192D60086DCA6 /* PyApp.h */, CE80DB230FC192D60086DCA6 /* PyApp.h */,
CE80DB240FC192D60086DCA6 /* RecentDirectories.h */,
CE80DB250FC192D60086DCA6 /* RecentDirectories.m */,
CE80DB2A0FC192D60086DCA6 /* Utils.h */, CE80DB2A0FC192D60086DCA6 /* Utils.h */,
CE80DB2B0FC192D60086DCA6 /* Utils.m */, CE80DB2B0FC192D60086DCA6 /* Utils.m */,
CE80DB2C0FC192D60086DCA6 /* ValueTransformers.h */, CE80DB2C0FC192D60086DCA6 /* ValueTransformers.h */,
@@ -425,9 +437,6 @@
CEFC294309C89E0000D9F998 /* images */ = { CEFC294309C89E0000D9F998 /* images */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CEFCDE2C0AB0418600C33A93 /* dgpe_logo_32.png */,
CEFC295309C89FF200D9F998 /* details32.png */,
CEFC295409C89FF200D9F998 /* preferences32.png */,
CEFC294509C89E3D00D9F998 /* folder32.png */, CEFC294509C89E3D00D9F998 /* folder32.png */,
); );
name = images; name = images;
@@ -462,6 +471,7 @@
isa = PBXProject; isa = PBXProject;
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */;
compatibilityVersion = "Xcode 3.0"; compatibilityVersion = "Xcode 3.0";
developmentRegion = English;
hasScannedForEncodings = 1; hasScannedForEncodings = 1;
knownRegions = ( knownRegions = (
English, English,
@@ -469,6 +479,7 @@
French, French,
German, German,
en, en,
fr,
); );
mainGroup = 29B97314FDCFA39411CA2CEA /* dupeguru */; mainGroup = 29B97314FDCFA39411CA2CEA /* dupeguru */;
projectDirPath = ""; projectDirPath = "";
@@ -485,21 +496,22 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */, CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */,
CE073F6309CAE1A3005C1D2F /* dupeguru_pe_help in Resources */, CE073F6309CAE1A3005C1D2F /* help in Resources */,
CEEB135209C837A2004D2330 /* dupeguru.icns in Resources */, CEEB135209C837A2004D2330 /* dupeguru.icns in Resources */,
CEFC294609C89E3D00D9F998 /* folder32.png in Resources */, CEFC294609C89E3D00D9F998 /* folder32.png in Resources */,
CEFC295509C89FF200D9F998 /* details32.png in Resources */,
CEFC295609C89FF200D9F998 /* preferences32.png in Resources */,
CEFCDE2D0AB0418600C33A93 /* dgpe_logo_32.png in Resources */,
CE6E0F3D1054EC62008D9390 /* dsa_pub.pem in Resources */, CE6E0F3D1054EC62008D9390 /* dsa_pub.pem in Resources */,
CE77C89E10946C6D0078B0DB /* DirectoryPanel.xib in Resources */,
CE77C8A810946CE20078B0DB /* DetailsPanel.xib in Resources */,
CE031751109B340A00517EE6 /* Preferences.xib in Resources */,
CE031754109B345200517EE6 /* MainMenu.xib in Resources */,
CE7AC9181119911200D02F6C /* ErrorReportWindow.xib in Resources */, CE7AC9181119911200D02F6C /* ErrorReportWindow.xib in Resources */,
CE7AC9191119911200D02F6C /* progress.xib in Resources */, CE7AC9191119911200D02F6C /* progress.xib in Resources */,
CE0C2AC81177021600BC749F /* ProblemDialog.xib in Resources */,
CE1EB60112537FB90034AABB /* FairwareReminder.xib in Resources */, CE1EB60112537FB90034AABB /* FairwareReminder.xib in Resources */,
CEC9DB4712CCAA6B003102F0 /* about.xib in Resources */,
CE05339B12E5DA350029EF25 /* DirectoryPanel.xib in Resources */,
CE05339C12E5DA350029EF25 /* MainMenu.xib in Resources */,
CE05339D12E5DA350029EF25 /* ProblemDialog.xib in Resources */,
CE05339E12E5DA350029EF25 /* ResultWindow.xib in Resources */,
CE0533A712E5DA4D0029EF25 /* DetailsPanel.xib in Resources */,
CE0533A812E5DA4D0029EF25 /* Preferences.xib in Resources */,
CE0533AB12E5DA6A0029EF25 /* Localizable.strings in Resources */,
CE4527AC12E5F6E700005A15 /* core.strings in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -518,7 +530,6 @@
CE80DB2E0FC192D60086DCA6 /* Dialogs.m in Sources */, CE80DB2E0FC192D60086DCA6 /* Dialogs.m in Sources */,
CE80DB2F0FC192D60086DCA6 /* HSErrorReportWindow.m in Sources */, CE80DB2F0FC192D60086DCA6 /* HSErrorReportWindow.m in Sources */,
CE80DB310FC192D60086DCA6 /* ProgressController.m in Sources */, CE80DB310FC192D60086DCA6 /* ProgressController.m in Sources */,
CE80DB320FC192D60086DCA6 /* RecentDirectories.m in Sources */,
CE80DB350FC192D60086DCA6 /* Utils.m in Sources */, CE80DB350FC192D60086DCA6 /* Utils.m in Sources */,
CE80DB360FC192D60086DCA6 /* ValueTransformers.m in Sources */, CE80DB360FC192D60086DCA6 /* ValueTransformers.m in Sources */,
CE80DB470FC193650086DCA6 /* NSNotificationAdditions.m in Sources */, CE80DB470FC193650086DCA6 /* NSNotificationAdditions.m in Sources */,
@@ -542,21 +553,96 @@
CEF12A7E124DFD400087B51D /* HSTableView.m in Sources */, CEF12A7E124DFD400087B51D /* HSTableView.m in Sources */,
CEF12A84124DFD620087B51D /* ResultTable.m in Sources */, CEF12A84124DFD620087B51D /* ResultTable.m in Sources */,
CE1EB5FE12537F9D0034AABB /* HSFairwareReminder.m in Sources */, CE1EB5FE12537F9D0034AABB /* HSFairwareReminder.m in Sources */,
CEC9DB4C12CCAA7D003102F0 /* HSAboutBox.m in Sources */,
CE60180812DF3EA900236FDC /* HSRecentFiles.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
/* End PBXSourcesBuildPhase section */ /* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */ /* Begin PBXVariantGroup section */
CE05339312E5DA350029EF25 /* DirectoryPanel.xib */ = {
isa = PBXVariantGroup;
children = (
CE05339412E5DA350029EF25 /* en */,
CE05339F12E5DA420029EF25 /* fr */,
);
name = DirectoryPanel.xib;
sourceTree = SOURCE_ROOT;
};
CE05339512E5DA350029EF25 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
CE05339612E5DA350029EF25 /* en */,
CE0533A012E5DA420029EF25 /* fr */,
);
name = MainMenu.xib;
sourceTree = SOURCE_ROOT;
};
CE05339712E5DA350029EF25 /* ProblemDialog.xib */ = {
isa = PBXVariantGroup;
children = (
CE05339812E5DA350029EF25 /* en */,
CE0533A112E5DA420029EF25 /* fr */,
);
name = ProblemDialog.xib;
sourceTree = SOURCE_ROOT;
};
CE05339912E5DA350029EF25 /* ResultWindow.xib */ = {
isa = PBXVariantGroup;
children = (
CE05339A12E5DA350029EF25 /* en */,
CE0533A212E5DA420029EF25 /* fr */,
);
name = ResultWindow.xib;
sourceTree = SOURCE_ROOT;
};
CE0533A312E5DA4D0029EF25 /* DetailsPanel.xib */ = {
isa = PBXVariantGroup;
children = (
CE0533A412E5DA4D0029EF25 /* en */,
CE0533AD12E5DAAD0029EF25 /* fr */,
);
name = DetailsPanel.xib;
sourceTree = SOURCE_ROOT;
};
CE0533A512E5DA4D0029EF25 /* Preferences.xib */ = {
isa = PBXVariantGroup;
children = (
CE0533A612E5DA4D0029EF25 /* en */,
CE0533AE12E5DAAD0029EF25 /* fr */,
);
name = Preferences.xib;
sourceTree = SOURCE_ROOT;
};
CE0533A912E5DA6A0029EF25 /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
CE0533AA12E5DA6A0029EF25 /* en */,
CE0533AC12E5DA790029EF25 /* fr */,
);
name = Localizable.strings;
sourceTree = SOURCE_ROOT;
};
CE1EB5FF12537FB90034AABB /* FairwareReminder.xib */ = { CE1EB5FF12537FB90034AABB /* FairwareReminder.xib */ = {
isa = PBXVariantGroup; isa = PBXVariantGroup;
children = ( children = (
CE1EB60012537FB90034AABB /* en */, CE1EB60012537FB90034AABB /* en */,
CE0533B712E5DC040029EF25 /* fr */,
); );
name = FairwareReminder.xib; name = FairwareReminder.xib;
path = ../../cocoalib/xib; path = ../../cocoalib/xib;
sourceTree = SOURCE_ROOT; sourceTree = SOURCE_ROOT;
}; };
CE4527AA12E5F6E700005A15 /* core.strings */ = {
isa = PBXVariantGroup;
children = (
CE4527AB12E5F6E700005A15 /* en */,
CE4527B012E5F72600005A15 /* fr */,
);
name = core.strings;
sourceTree = SOURCE_ROOT;
};
/* End PBXVariantGroup section */ /* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */

View File

@@ -0,0 +1,18 @@
/* Class = "NSPanel"; title = "Details of Selected File"; ObjectID = "5"; */
"5.title" = "Details of Selected File";
/* Class = "NSTableColumn"; headerCell.title = "Selected"; ObjectID = "9"; */
"9.headerCell.title" = "Selected";
/* Class = "NSTableColumn"; headerCell.title = "Reference"; ObjectID = "10"; */
"10.headerCell.title" = "Reference";
/* Class = "NSTableColumn"; headerCell.title = "Attribute"; ObjectID = "11"; */
"11.headerCell.title" = "Attribute";
/* Class = "NSTextFieldCell"; title = "Selected"; ObjectID = "33"; */
"33.title" = "Selected";
/* Class = "NSTextFieldCell"; title = "Reference"; ObjectID = "35"; */
"35.title" = "Reference";

Binary file not shown.

View File

@@ -2,13 +2,13 @@
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10"> <archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
<data> <data>
<int key="IBDocument.SystemTarget">1050</int> <int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">10F569</string> <string key="IBDocument.SystemVersion">10J567</string>
<string key="IBDocument.InterfaceBuilderVersion">788</string> <string key="IBDocument.InterfaceBuilderVersion">823</string>
<string key="IBDocument.AppKitVersion">1038.29</string> <string key="IBDocument.AppKitVersion">1038.35</string>
<string key="IBDocument.HIToolboxVersion">461.00</string> <string key="IBDocument.HIToolboxVersion">462.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions"> <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">788</string> <string key="NS.object.0">823</string>
</object> </object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs"> <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
@@ -19,13 +19,8 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object> </object>
<object class="NSMutableDictionary" key="IBDocument.Metadata"> <object class="NSMutableDictionary" key="IBDocument.Metadata">
<bool key="EncodedWithXMLCoder">YES</bool> <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<object class="NSArray" key="dict.sortedKeys" id="0"> <integer value="1" key="NS.object.0"/>
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object> </object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000"> <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
@@ -41,14 +36,14 @@
<object class="NSUserDefaultsController" id="455472712"> <object class="NSUserDefaultsController" id="455472712">
<object class="NSMutableArray" key="NSDeclaredKeys"> <object class="NSMutableArray" key="NSDeclaredKeys">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
<string>ignoreHardlinkMatches</string> <string>DebugMode</string>
</object> </object>
<bool key="NSSharedInstance">YES</bool> <bool key="NSSharedInstance">YES</bool>
</object> </object>
<object class="NSWindowTemplate" id="809668081"> <object class="NSWindowTemplate" id="809668081">
<int key="NSWindowStyleMask">3</int> <int key="NSWindowStyleMask">3</int>
<int key="NSWindowBacking">2</int> <int key="NSWindowBacking">2</int>
<string key="NSWindowRect">{{92, 371}, {392, 231}}</string> <string key="NSWindowRect">{{92, 348}, {392, 254}}</string>
<int key="NSWTFlags">1886912512</int> <int key="NSWTFlags">1886912512</int>
<string key="NSWindowTitle">dupeGuru PE Preferences</string> <string key="NSWindowTitle">dupeGuru PE Preferences</string>
<object class="NSMutableString" key="NSWindowClass"> <object class="NSMutableString" key="NSWindowClass">
@@ -94,7 +89,7 @@
<object class="NSTabView" id="211771207"> <object class="NSTabView" id="211771207">
<reference key="NSNextResponder" ref="905655072"/> <reference key="NSNextResponder" ref="905655072"/>
<int key="NSvFlags">12</int> <int key="NSvFlags">12</int>
<string key="NSFrame">{{13, 40}, {366, 185}}</string> <string key="NSFrame">{{13, 40}, {366, 208}}</string>
<reference key="NSSuperview" ref="905655072"/> <reference key="NSSuperview" ref="905655072"/>
<object class="NSMutableArray" key="NSTabViewItems"> <object class="NSMutableArray" key="NSTabViewItems">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
@@ -108,7 +103,7 @@
<object class="NSSlider" id="266372855"> <object class="NSSlider" id="266372855">
<reference key="NSNextResponder" ref="1073354031"/> <reference key="NSNextResponder" ref="1073354031"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{117, 117}, {181, 21}}</string> <string key="NSFrame">{{117, 140}, {181, 21}}</string>
<reference key="NSSuperview" ref="1073354031"/> <reference key="NSSuperview" ref="1073354031"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSSliderCell" key="NSCell" id="453640282"> <object class="NSSliderCell" key="NSCell" id="453640282">
@@ -136,7 +131,7 @@
<object class="NSTextField" id="869007847"> <object class="NSTextField" id="869007847">
<reference key="NSNextResponder" ref="1073354031"/> <reference key="NSNextResponder" ref="1073354031"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{119, 100}, {80, 13}}</string> <string key="NSFrame">{{119, 123}, {80, 13}}</string>
<reference key="NSSuperview" ref="1073354031"/> <reference key="NSSuperview" ref="1073354031"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="106025161"> <object class="NSTextFieldCell" key="NSCell" id="106025161">
@@ -172,7 +167,7 @@
<object class="NSTextField" id="171701149"> <object class="NSTextField" id="171701149">
<reference key="NSNextResponder" ref="1073354031"/> <reference key="NSNextResponder" ref="1073354031"/>
<int key="NSvFlags">289</int> <int key="NSvFlags">289</int>
<string key="NSFrame">{{216, 100}, {80, 13}}</string> <string key="NSFrame">{{216, 123}, {80, 13}}</string>
<reference key="NSSuperview" ref="1073354031"/> <reference key="NSSuperview" ref="1073354031"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="397705219"> <object class="NSTextFieldCell" key="NSCell" id="397705219">
@@ -188,7 +183,7 @@
<object class="NSTextField" id="638371207"> <object class="NSTextField" id="638371207">
<reference key="NSNextResponder" ref="1073354031"/> <reference key="NSNextResponder" ref="1073354031"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{14, 122}, {100, 14}}</string> <string key="NSFrame">{{14, 145}, {100, 14}}</string>
<reference key="NSSuperview" ref="1073354031"/> <reference key="NSSuperview" ref="1073354031"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="812365472"> <object class="NSTextFieldCell" key="NSCell" id="812365472">
@@ -208,7 +203,7 @@
<object class="NSButton" id="488256664"> <object class="NSButton" id="488256664">
<reference key="NSNextResponder" ref="1073354031"/> <reference key="NSNextResponder" ref="1073354031"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 56}, {214, 18}}</string> <string key="NSFrame">{{15, 79}, {316, 18}}</string>
<reference key="NSSuperview" ref="1073354031"/> <reference key="NSSuperview" ref="1073354031"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="401283671"> <object class="NSButtonCell" key="NSCell" id="401283671">
@@ -231,7 +226,7 @@
<object class="NSButton" id="722670516"> <object class="NSButton" id="722670516">
<reference key="NSNextResponder" ref="1073354031"/> <reference key="NSNextResponder" ref="1073354031"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 76}, {214, 18}}</string> <string key="NSFrame">{{15, 99}, {316, 18}}</string>
<reference key="NSSuperview" ref="1073354031"/> <reference key="NSSuperview" ref="1073354031"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="911281323"> <object class="NSButtonCell" key="NSCell" id="911281323">
@@ -252,7 +247,7 @@
<object class="NSButton" id="472028782"> <object class="NSButton" id="472028782">
<reference key="NSNextResponder" ref="1073354031"/> <reference key="NSNextResponder" ref="1073354031"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 14}, {283, 18}}</string> <string key="NSFrame">{{15, 39}, {316, 18}}</string>
<reference key="NSSuperview" ref="1073354031"/> <reference key="NSSuperview" ref="1073354031"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="2297113"> <object class="NSButtonCell" key="NSCell" id="2297113">
@@ -273,7 +268,7 @@
<object class="NSButton" id="279087998"> <object class="NSButton" id="279087998">
<reference key="NSNextResponder" ref="1073354031"/> <reference key="NSNextResponder" ref="1073354031"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 36}, {242, 18}}</string> <string key="NSFrame">{{15, 59}, {316, 18}}</string>
<reference key="NSSuperview" ref="1073354031"/> <reference key="NSSuperview" ref="1073354031"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="287383961"> <object class="NSButtonCell" key="NSCell" id="287383961">
@@ -294,7 +289,7 @@
<object class="NSTextField" id="403531548"> <object class="NSTextField" id="403531548">
<reference key="NSNextResponder" ref="1073354031"/> <reference key="NSNextResponder" ref="1073354031"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{301, 122}, {31, 14}}</string> <string key="NSFrame">{{301, 145}, {31, 14}}</string>
<reference key="NSSuperview" ref="1073354031"/> <reference key="NSSuperview" ref="1073354031"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="983190380"> <object class="NSTextFieldCell" key="NSCell" id="983190380">
@@ -321,9 +316,11 @@
<boolean value="YES"/> <boolean value="YES"/>
<object class="NSAttributedString" id="778485313"> <object class="NSAttributedString" id="778485313">
<string key="NSString">0</string> <string key="NSString">0</string>
<object class="NSDictionary" key="NSAttributes" id="715018633"> <object class="NSDictionary" key="NSAttributes" id="808787112">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/> <object class="NSArray" key="dict.sortedKeys" id="0">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values"> <object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
</object> </object>
@@ -347,7 +344,7 @@
</object> </object>
<object class="NSAttributedString" key="NS.nan"> <object class="NSAttributedString" key="NS.nan">
<string key="NSString">NaN</string> <string key="NSString">NaN</string>
<reference key="NSAttributes" ref="715018633"/> <reference key="NSAttributes" ref="808787112"/>
</object> </object>
<object class="NSDecimalNumberPlaceholder" key="NS.min" id="737238985"> <object class="NSDecimalNumberPlaceholder" key="NS.min" id="737238985">
<int key="NS.exponent">0</int> <int key="NS.exponent">0</int>
@@ -371,7 +368,7 @@
</object> </object>
</object> </object>
</object> </object>
<string key="NSFrame">{{10, 33}, {346, 139}}</string> <string key="NSFrame">{{10, 33}, {346, 162}}</string>
<reference key="NSSuperview" ref="211771207"/> <reference key="NSSuperview" ref="211771207"/>
</object> </object>
<string key="NSLabel">Basic</string> <string key="NSLabel">Basic</string>
@@ -388,7 +385,7 @@
<object class="NSButton" id="1018598123"> <object class="NSButton" id="1018598123">
<reference key="NSNextResponder" ref="581039403"/> <reference key="NSNextResponder" ref="581039403"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 120}, {228, 18}}</string> <string key="NSFrame">{{15, 143}, {316, 18}}</string>
<reference key="NSSuperview" ref="581039403"/> <reference key="NSSuperview" ref="581039403"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="42276474"> <object class="NSButtonCell" key="NSCell" id="42276474">
@@ -409,7 +406,7 @@
<object class="NSButton" id="519470955"> <object class="NSButton" id="519470955">
<reference key="NSNextResponder" ref="581039403"/> <reference key="NSNextResponder" ref="581039403"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 100}, {265, 18}}</string> <string key="NSFrame">{{15, 123}, {316, 18}}</string>
<reference key="NSSuperview" ref="581039403"/> <reference key="NSSuperview" ref="581039403"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="595497720"> <object class="NSButtonCell" key="NSCell" id="595497720">
@@ -427,10 +424,31 @@
<int key="NSPeriodicInterval">25</int> <int key="NSPeriodicInterval">25</int>
</object> </object>
</object> </object>
<object class="NSButton" id="606836304">
<reference key="NSNextResponder" ref="581039403"/>
<int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 103}, {316, 18}}</string>
<reference key="NSSuperview" ref="581039403"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="100803310">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">0</int>
<string key="NSContents">Debug mode (restart required)</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSControlView" ref="606836304"/>
<int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int>
<reference key="NSAlternateImage" ref="990345653"/>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
<int key="NSPeriodicDelay">200</int>
<int key="NSPeriodicInterval">25</int>
</object>
</object>
<object class="NSTextField" id="748076392"> <object class="NSTextField" id="748076392">
<reference key="NSNextResponder" ref="581039403"/> <reference key="NSNextResponder" ref="581039403"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{14, 77}, {85, 13}}</string> <string key="NSFrame">{{14, 37}, {318, 13}}</string>
<reference key="NSSuperview" ref="581039403"/> <reference key="NSSuperview" ref="581039403"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="936873031"> <object class="NSTextFieldCell" key="NSCell" id="936873031">
@@ -446,7 +464,7 @@
<object class="NSTextField" id="526155835"> <object class="NSTextField" id="526155835">
<reference key="NSNextResponder" ref="581039403"/> <reference key="NSNextResponder" ref="581039403"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{14, 49}, {306, 17}}</string> <string key="NSFrame">{{14, 80}, {318, 17}}</string>
<reference key="NSSuperview" ref="581039403"/> <reference key="NSSuperview" ref="581039403"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="765798142"> <object class="NSTextFieldCell" key="NSCell" id="765798142">
@@ -462,7 +480,7 @@
<object class="NSPopUpButton" id="724953200"> <object class="NSPopUpButton" id="724953200">
<reference key="NSNextResponder" ref="581039403"/> <reference key="NSNextResponder" ref="581039403"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{104, 70}, {216, 26}}</string> <string key="NSFrame">{{14, 5}, {216, 26}}</string>
<reference key="NSSuperview" ref="581039403"/> <reference key="NSSuperview" ref="581039403"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSPopUpButtonCell" key="NSCell" id="601288025"> <object class="NSPopUpButtonCell" key="NSCell" id="601288025">
@@ -538,7 +556,7 @@
<object class="NSTextField" id="590530357"> <object class="NSTextField" id="590530357">
<reference key="NSNextResponder" ref="581039403"/> <reference key="NSNextResponder" ref="581039403"/>
<int key="NSvFlags">266</int> <int key="NSvFlags">266</int>
<string key="NSFrame">{{17, 27}, {312, 22}}</string> <string key="NSFrame">{{17, 58}, {312, 22}}</string>
<reference key="NSSuperview" ref="581039403"/> <reference key="NSSuperview" ref="581039403"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="922246764"> <object class="NSTextFieldCell" key="NSCell" id="922246764">
@@ -566,7 +584,7 @@
</object> </object>
</object> </object>
</object> </object>
<string key="NSFrame">{{10, 33}, {346, 139}}</string> <string key="NSFrame">{{10, 33}, {346, 162}}</string>
</object> </object>
<string key="NSLabel">Advanced</string> <string key="NSLabel">Advanced</string>
<reference key="NSColor" ref="71910056"/> <reference key="NSColor" ref="71910056"/>
@@ -584,7 +602,7 @@
</object> </object>
</object> </object>
</object> </object>
<string key="NSFrameSize">{392, 231}</string> <string key="NSFrameSize">{392, 254}</string>
<reference key="NSSuperview"/> <reference key="NSSuperview"/>
</object> </object>
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string> <string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
@@ -835,6 +853,30 @@
</object> </object>
<int key="connectionID">73</int> <int key="connectionID">73</int>
</object> </object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">nextKeyView</string>
<reference key="source" ref="606836304"/>
<reference key="destination" ref="279087998"/>
</object>
<int key="connectionID">77</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">value: values.DebugMode</string>
<reference key="source" ref="606836304"/>
<reference key="destination" ref="455472712"/>
<object class="NSNibBindingConnector" key="connector">
<reference key="NSSource" ref="606836304"/>
<reference key="NSDestination" ref="455472712"/>
<string key="NSLabel">value: values.DebugMode</string>
<string key="NSBinding">value</string>
<string key="NSKeyPath">values.DebugMode</string>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">78</int>
</object>
</object> </object>
<object class="IBMutableOrderedSet" key="objectRecords"> <object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects"> <object class="NSArray" key="orderedObjects">
@@ -942,6 +984,7 @@
<reference ref="526155835"/> <reference ref="526155835"/>
<reference ref="724953200"/> <reference ref="724953200"/>
<reference ref="590530357"/> <reference ref="590530357"/>
<reference ref="606836304"/>
</object> </object>
<reference key="parent" ref="1045400351"/> <reference key="parent" ref="1045400351"/>
</object> </object>
@@ -956,9 +999,9 @@
<reference ref="171701149"/> <reference ref="171701149"/>
<reference ref="869007847"/> <reference ref="869007847"/>
<reference ref="266372855"/> <reference ref="266372855"/>
<reference ref="472028782"/>
<reference ref="279087998"/> <reference ref="279087998"/>
<reference ref="403531548"/> <reference ref="403531548"/>
<reference ref="472028782"/>
</object> </object>
<reference key="parent" ref="700068878"/> <reference key="parent" ref="700068878"/>
</object> </object>
@@ -1211,6 +1254,20 @@
<reference key="object" ref="595497720"/> <reference key="object" ref="595497720"/>
<reference key="parent" ref="519470955"/> <reference key="parent" ref="519470955"/>
</object> </object>
<object class="IBObjectRecord">
<int key="objectID">74</int>
<reference key="object" ref="606836304"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="100803310"/>
</object>
<reference key="parent" ref="581039403"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">75</int>
<reference key="object" ref="100803310"/>
<reference key="parent" ref="606836304"/>
</object>
</object> </object>
</object> </object>
<object class="NSMutableDictionary" key="flattenedProperties"> <object class="NSMutableDictionary" key="flattenedProperties">
@@ -1221,6 +1278,7 @@
<string>1.IBPluginDependency</string> <string>1.IBPluginDependency</string>
<string>1.ImportedFromIB2</string> <string>1.ImportedFromIB2</string>
<string>10.IBPluginDependency</string> <string>10.IBPluginDependency</string>
<string>10.IBViewBoundsToFrameTransform</string>
<string>10.ImportedFromIB2</string> <string>10.ImportedFromIB2</string>
<string>11.IBPluginDependency</string> <string>11.IBPluginDependency</string>
<string>11.ImportedFromIB2</string> <string>11.ImportedFromIB2</string>
@@ -1271,24 +1329,34 @@
<string>5.ImportedFromIB2</string> <string>5.ImportedFromIB2</string>
<string>59.IBPluginDependency</string> <string>59.IBPluginDependency</string>
<string>6.IBPluginDependency</string> <string>6.IBPluginDependency</string>
<string>6.IBViewBoundsToFrameTransform</string>
<string>6.ImportedFromIB2</string> <string>6.ImportedFromIB2</string>
<string>60.IBPluginDependency</string> <string>60.IBPluginDependency</string>
<string>61.IBPluginDependency</string> <string>61.IBPluginDependency</string>
<string>62.IBPluginDependency</string> <string>62.IBPluginDependency</string>
<string>63.IBPluginDependency</string> <string>63.IBPluginDependency</string>
<string>64.IBPluginDependency</string> <string>64.IBPluginDependency</string>
<string>64.IBViewBoundsToFrameTransform</string>
<string>64.ImportedFromIB2</string> <string>64.ImportedFromIB2</string>
<string>65.IBPluginDependency</string> <string>65.IBPluginDependency</string>
<string>66.IBPluginDependency</string> <string>66.IBPluginDependency</string>
<string>66.IBViewBoundsToFrameTransform</string>
<string>67.IBPluginDependency</string> <string>67.IBPluginDependency</string>
<string>69.IBPluginDependency</string> <string>69.IBPluginDependency</string>
<string>69.IBViewBoundsToFrameTransform</string>
<string>69.ImportedFromIB2</string> <string>69.ImportedFromIB2</string>
<string>7.IBPluginDependency</string> <string>7.IBPluginDependency</string>
<string>7.ImportedFromIB2</string> <string>7.ImportedFromIB2</string>
<string>70.IBPluginDependency</string> <string>70.IBPluginDependency</string>
<string>74.IBPluginDependency</string>
<string>74.IBViewBoundsToFrameTransform</string>
<string>74.ImportedFromIB2</string>
<string>75.IBPluginDependency</string>
<string>8.IBPluginDependency</string> <string>8.IBPluginDependency</string>
<string>8.IBViewBoundsToFrameTransform</string>
<string>8.ImportedFromIB2</string> <string>8.ImportedFromIB2</string>
<string>9.IBPluginDependency</string> <string>9.IBPluginDependency</string>
<string>9.IBViewBoundsToFrameTransform</string>
<string>9.ImportedFromIB2</string> <string>9.ImportedFromIB2</string>
</object> </object>
<object class="NSMutableArray" key="dict.values"> <object class="NSMutableArray" key="dict.values">
@@ -1297,6 +1365,9 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABDZgAAwoIAAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
@@ -1313,9 +1384,9 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{88, 614}, {392, 231}}</string> <string>{{88, 591}, {392, 254}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{88, 614}, {392, 231}}</string> <string>{{88, 591}, {392, 254}}</string>
<boolean value="YES"/> <boolean value="YES"/>
<boolean value="YES"/> <boolean value="YES"/>
<string>{213, 107}</string> <string>{213, 107}</string>
@@ -1347,24 +1418,48 @@
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBcAAAwfAAAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBYAAAwrwAAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBiAAAwpoAAA</bytes>
</object>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBcAAAwwsAAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBcAAAwu4AAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBYAAAweAAAA</bytes>
</object>
<boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBYAAAwjwAAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
</object> </object>
</object> </object>
@@ -1384,7 +1479,7 @@
</object> </object>
</object> </object>
<nil key="sourceID"/> <nil key="sourceID"/>
<int key="maxID">73</int> <int key="maxID">78</int>
</object> </object>
<object class="IBClassDescriber" key="IBDocument.Classes"> <object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions"> <object class="NSMutableArray" key="referencedPartialClassDescriptions">

View File

@@ -0,0 +1,18 @@
/* Class = "NSPanel"; title = "Details of Selected File"; ObjectID = "5"; */
"5.title" = "Détails du fichier sélectionné";
/* Class = "NSTableColumn"; headerCell.title = "Selected"; ObjectID = "9"; */
"9.headerCell.title" = "Sélectionné";
/* Class = "NSTableColumn"; headerCell.title = "Reference"; ObjectID = "10"; */
"10.headerCell.title" = "Référence";
/* Class = "NSTableColumn"; headerCell.title = "Attribute"; ObjectID = "11"; */
"11.headerCell.title" = "Attribut";
/* Class = "NSTextFieldCell"; title = "Selected"; ObjectID = "33"; */
"33.title" = "Sélectionné";
/* Class = "NSTextFieldCell"; title = "Reference"; ObjectID = "35"; */
"35.title" = "Référence";

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,57 @@
/* Class = "NSWindow"; title = "dupeGuru PE Preferences"; ObjectID = "2"; */
"2.title" = "Préférences de dupeGuru PE";
/* Class = "NSTextFieldCell"; title = "More results"; ObjectID = "18"; */
"18.title" = "+ de doubles";
/* Class = "NSTextFieldCell"; title = "Fewer results"; ObjectID = "19"; */
"19.title" = "- de doubles";
/* Class = "NSTextFieldCell"; title = "Filter hardness:"; ObjectID = "20"; */
"20.title" = "Seuil du filtre:";
/* Class = "NSButtonCell"; title = "Can mix file kind"; ObjectID = "21"; */
"21.title" = "Comparer les fichiers de différents types";
/* Class = "NSButtonCell"; title = "Reset to Defaults"; ObjectID = "24"; */
"24.title" = "Options par défaut";
/* Class = "NSTextFieldCell"; title = "Copy and Move:"; ObjectID = "25"; */
"25.title" = "Déplacements de fichiers:";
/* Class = "NSMenuItem"; title = "Recreate relative path"; ObjectID = "28"; */
"28.title" = "Re-créer chemins relatifs";
/* Class = "NSMenuItem"; title = "Recreate absolute path"; ObjectID = "29"; */
"29.title" = "Re-créer chemins absolus";
/* Class = "NSMenuItem"; title = "Right in destination"; ObjectID = "30"; */
"30.title" = "Directement à la destination";
/* Class = "NSButtonCell"; title = "Match scaled pictures together"; ObjectID = "31"; */
"31.title" = "Comparer les images de tailles différentes";
/* Class = "NSButtonCell"; title = "Automatically check for updates"; ObjectID = "32"; */
"32.title" = "Vérifier automatiquement les mises à jour";
/* Class = "NSButtonCell"; title = "Remove empty folders on delete or move"; ObjectID = "33"; */
"33.title" = "Effacer les dossiers vides après un déplacement";
/* Class = "NSButtonCell"; title = "Use regular expressions when filtering"; ObjectID = "34"; */
"34.title" = "Utiliser les expressions régulières pour les filtres";
/* Class = "NSTabViewItem"; label = "Basic"; ObjectID = "60"; */
"60.label" = "Simple";
/* Class = "NSTabViewItem"; label = "Advanced"; ObjectID = "61"; */
"61.label" = "Avancé";
/* Class = "NSTextFieldCell"; title = "Custom Command (arguments: %d for dupe, %r for ref):"; ObjectID = "65"; */
"65.title" = "Commande perso. (arguments: %d pour doublon, %r pour réf):";
/* Class = "NSButtonCell"; title = "Ignore duplicates hardlinking to the same file"; ObjectID = "70"; */
"70.title" = "Ignorer doublons avec hardlink vers le même fichier";
/* Class = "NSButtonCell"; title = "Debug mode (restart required)"; ObjectID = "75"; */
"75.title" = "Mode de déboguage (redémarrage requis)";

File diff suppressed because it is too large Load Diff

View File

@@ -11,8 +11,5 @@ http://www.hardcoded.net/licenses/bsd_license
#import "PyDupeGuru.h" #import "PyDupeGuru.h"
@interface AppDelegate : AppDelegateBase {} @interface AppDelegate : AppDelegateBase {}
- (IBAction)openWebsite:(id)sender;
- (IBAction)toggleDirectories:(id)sender;
- (PyDupeGuru *)py; - (PyDupeGuru *)py;
@end @end

View File

@@ -12,6 +12,7 @@ http://www.hardcoded.net/licenses/bsd_license
#import "../../cocoalib/ValueTransformers.h" #import "../../cocoalib/ValueTransformers.h"
#import "DetailsPanel.h" #import "DetailsPanel.h"
#import "DirectoryPanel.h" #import "DirectoryPanel.h"
#import "ResultWindow.h"
#import "Consts.h" #import "Consts.h"
@implementation AppDelegate @implementation AppDelegate
@@ -47,14 +48,14 @@ http://www.hardcoded.net/licenses/bsd_license
return self; return self;
} }
- (IBAction)openWebsite:(id)sender - (NSString *)homepageURL
{ {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://www.hardcoded.net/dupeguru"]]; return @"http://www.hardcoded.net/dupeguru/";
} }
- (IBAction)toggleDirectories:(id)sender - (ResultWindowBase *)createResultWindow
{ {
[[self directoryPanel] toggleVisible:sender]; return [[ResultWindow alloc] initWithParentApp:self];
} }
- (PyDupeGuru *)py { return (PyDupeGuru *)py; } - (PyDupeGuru *)py { return (PyDupeGuru *)py; }

View File

@@ -23,7 +23,7 @@
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>hsft</string> <string>hsft</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>2.12.2</string> <string>{version}</string>
<key>NSMainNibFile</key> <key>NSMainNibFile</key>
<string>MainMenu</string> <string>MainMenu</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>

View File

@@ -8,12 +8,6 @@ http://www.hardcoded.net/licenses/bsd_license
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import "../base/ResultWindow.h" #import "../base/ResultWindow.h"
#import "DirectoryPanel.h"
@interface ResultWindow : ResultWindowBase @interface ResultWindow : ResultWindowBase {}
{
NSString *_lastAction;
}
- (IBAction)resetColumnsToDefault:(id)sender;
- (IBAction)startDuplicateScan:(id)sender;
@end @end

View File

@@ -7,20 +7,41 @@ http://www.hardcoded.net/licenses/bsd_license
*/ */
#import "ResultWindow.h" #import "ResultWindow.h"
#import "../../cocoalib/Dialogs.h" #import "Utils.h"
#import "../../cocoalib/ProgressController.h"
#import "../../cocoalib/Utils.h"
#import "AppDelegate.h"
#import "Consts.h" #import "Consts.h"
#import "PyDupeGuru.h"
@implementation ResultWindow @implementation ResultWindow
/* Override */ /* Override */
- (void)awakeFromNib - (void)initResultColumns
{ {
[super awakeFromNib]; NSTableColumn *refCol = [matches tableColumnWithIdentifier:@"0"];
NSMutableIndexSet *deltaColumns = [NSMutableIndexSet indexSetWithIndex:2]; _resultColumns = [[NSMutableArray alloc] init];
[deltaColumns addIndex:4]; [_resultColumns addObject:[matches tableColumnWithIdentifier:@"0"]]; // File Name
[table setDeltaColumns:deltaColumns]; [_resultColumns addObject:[self getColumnForIdentifier:1 title:TR(@"Folder") width:120 refCol:refCol]];
NSTableColumn *sizeCol = [self getColumnForIdentifier:2 title:TR(@"Size (KB)") width:63 refCol:refCol];
[[sizeCol dataCell] setAlignment:NSRightTextAlignment];
[_resultColumns addObject:sizeCol];
[_resultColumns addObject:[self getColumnForIdentifier:3 title:TR(@"Kind") width:40 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:4 title:TR(@"Modification") width:120 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:5 title:TR(@"Match %") width:60 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:6 title:TR(@"Words Used") width:120 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:7 title:TR(@"Dupe Count") width:80 refCol:refCol]];
}
- (void)setScanOptions
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
PyDupeGuru *_py = (PyDupeGuru *)py;
[_py setScanType:[ud objectForKey:@"scanType"]];
[_py setMinMatchPercentage:[ud objectForKey:@"minMatchPercentage"]];
[_py setWordWeighting:[ud objectForKey:@"wordWeighting"]];
[_py setMixFileKind:n2b([ud objectForKey:@"mixFileKind"])];
[_py setIgnoreHardlinkMatches:n2b([ud objectForKey:@"ignoreHardlinkMatches"])];
[_py setMatchSimilarWords:[ud objectForKey:@"matchSimilarWords"]];
int smallFileThreshold = [ud integerForKey:@"smallFileThreshold"]; // In KB
int sizeThreshold = [ud boolForKey:@"ignoreSmallFiles"] ? smallFileThreshold * 1024 : 0; // The py side wants bytes
[_py setSizeThreshold:sizeThreshold];
} }
/* Actions */ /* Actions */
@@ -38,50 +59,4 @@ http://www.hardcoded.net/licenses/bsd_license
[columnsWidth setObject:i2n(60) forKey:@"5"]; [columnsWidth setObject:i2n(60) forKey:@"5"];
[self restoreColumnsPosition:columnsOrder widths:columnsWidth]; [self restoreColumnsPosition:columnsOrder widths:columnsWidth];
} }
- (IBAction)startDuplicateScan:(id)sender
{
if ([matches numberOfRows] > 0)
{
if ([Dialogs askYesNo:@"Are you sure you want to start a new duplicate scan?"] == NSAlertSecondButtonReturn) // NO
return;
}
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
PyDupeGuru *_py = (PyDupeGuru *)py;
[_py setScanType:[ud objectForKey:@"scanType"]];
[_py setMinMatchPercentage:[ud objectForKey:@"minMatchPercentage"]];
[_py setWordWeighting:[ud objectForKey:@"wordWeighting"]];
[_py setMixFileKind:n2b([ud objectForKey:@"mixFileKind"])];
[_py setIgnoreHardlinkMatches:n2b([ud objectForKey:@"ignoreHardlinkMatches"])];
[_py setMatchSimilarWords:[ud objectForKey:@"matchSimilarWords"]];
int smallFileThreshold = [ud integerForKey:@"smallFileThreshold"]; // In KB
int sizeThreshold = [ud boolForKey:@"ignoreSmallFiles"] ? smallFileThreshold * 1024 : 0; // The py side wants bytes
[_py setSizeThreshold:sizeThreshold];
int r = n2i([py doScan]);
if (r != 0)
[[ProgressController mainProgressController] hide];
if (r == 3)
{
[Dialogs showMessage:@"The selected directories contain no scannable file."];
[app toggleDirectories:nil];
}
}
/* Public */
- (void)initResultColumns
{
NSTableColumn *refCol = [matches tableColumnWithIdentifier:@"0"];
_resultColumns = [[NSMutableArray alloc] init];
[_resultColumns addObject:[matches tableColumnWithIdentifier:@"0"]]; // File Name
[_resultColumns addObject:[self getColumnForIdentifier:1 title:@"Directory" width:120 refCol:refCol]];
NSTableColumn *sizeCol = [self getColumnForIdentifier:2 title:@"Size (KB)" width:63 refCol:refCol];
[[sizeCol dataCell] setAlignment:NSRightTextAlignment];
[_resultColumns addObject:sizeCol];
[_resultColumns addObject:[self getColumnForIdentifier:3 title:@"Kind" width:40 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:4 title:@"Modification" width:120 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:5 title:@"Match %" width:60 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:6 title:@"Words Used" width:120 refCol:refCol]];
[_resultColumns addObject:[self getColumnForIdentifier:7 title:@"Dupe Count" width:80 refCol:refCol]];
}
@end @end

View File

@@ -4,18 +4,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 install_cocoa_trans
install_cocoa_trans()
from hscommon.cocoa import signature from hscommon.cocoa import signature
from core.scanner import ScanType from core.scanner import ScanType
from core.app_cocoa_inter import PyDupeGuruBase, PyDetailsPanel from core.app_cocoa_inter import PyDupeGuruBase, PyDetailsPanel
from core_se.app_cocoa import DupeGuru from core_se.app_cocoa import DupeGuru
from core_se import __appname__
# Fix py2app imports with chokes on relative imports and other stuff
import hsutil.conflict
import core.engine, core.fs, core.app
import core_se.fs, core_se.data
import xml.etree.ElementPath
import gzip
class PyDupeGuru(PyDupeGuruBase): class PyDupeGuru(PyDupeGuruBase):
def init(self): def init(self):
@@ -48,5 +45,5 @@ class PyDupeGuru(PyDupeGuruBase):
#---Registration #---Registration
def appName(self): def appName(self):
return "dupeGuru" return __appname__

View File

@@ -9,17 +9,18 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
CE073F6309CAE1A3005C1D2F /* dupeguru_help in Resources */ = {isa = PBXBuildFile; fileRef = CE073F5409CAE1A3005C1D2F /* dupeguru_help */; }; CE073F6309CAE1A3005C1D2F /* help in Resources */ = {isa = PBXBuildFile; fileRef = CE073F5409CAE1A3005C1D2F /* help */; };
CE19BC6311199231007CCEB0 /* ErrorReportWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE19BC6011199231007CCEB0 /* ErrorReportWindow.xib */; }; CE19BC6311199231007CCEB0 /* ErrorReportWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE19BC6011199231007CCEB0 /* ErrorReportWindow.xib */; };
CE19BC6411199231007CCEB0 /* progress.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE19BC6111199231007CCEB0 /* progress.xib */; }; CE19BC6411199231007CCEB0 /* progress.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE19BC6111199231007CCEB0 /* progress.xib */; };
CE27D3C112CCA42500859E67 /* about.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE27D3C012CCA42500859E67 /* about.xib */; };
CE27D3C412CCA43800859E67 /* HSAboutBox.m in Sources */ = {isa = PBXBuildFile; fileRef = CE27D3C312CCA43800859E67 /* HSAboutBox.m */; };
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; }; CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; };
CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9A09914ADF003581CE /* ResultWindow.m */; }; CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9A09914ADF003581CE /* ResultWindow.m */; };
CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */ = {isa = PBXBuildFile; fileRef = CE381CF509915304003581CE /* dg_cocoa.plugin */; }; CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */ = {isa = PBXBuildFile; fileRef = CE381CF509915304003581CE /* dg_cocoa.plugin */; };
CE3A46FA109B212E002ABFD5 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE3A46F9109B212E002ABFD5 /* MainMenu.xib */; }; CE4526F212E5F55F00005A15 /* core.strings in Resources */ = {isa = PBXBuildFile; fileRef = CE4526F012E5F55F00005A15 /* core.strings */; };
CE45579B0AE3BC2B005A9546 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE45579A0AE3BC2B005A9546 /* Sparkle.framework */; }; CE45579B0AE3BC2B005A9546 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE45579A0AE3BC2B005A9546 /* Sparkle.framework */; };
CE4557B40AE3BC50005A9546 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE45579A0AE3BC2B005A9546 /* Sparkle.framework */; }; CE4557B40AE3BC50005A9546 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE45579A0AE3BC2B005A9546 /* Sparkle.framework */; };
CE647E571173024A006D28BA /* ProblemDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = CE647E551173024A006D28BA /* ProblemDialog.m */; }; CE647E571173024A006D28BA /* ProblemDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = CE647E551173024A006D28BA /* ProblemDialog.m */; };
CE647E591173026F006D28BA /* ProblemDialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE647E581173026F006D28BA /* ProblemDialog.xib */; };
CE6DD4E7124CA3070089A48D /* ResultTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CE6DD4E6124CA3070089A48D /* ResultTable.m */; }; CE6DD4E7124CA3070089A48D /* ResultTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CE6DD4E6124CA3070089A48D /* ResultTable.m */; };
CE6DD547124CAF1F0089A48D /* HSTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = CE6DD546124CAF1F0089A48D /* HSTableView.m */; }; CE6DD547124CAF1F0089A48D /* HSTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = CE6DD546124CAF1F0089A48D /* HSTableView.m */; };
CE6E0DFE1054E9EF008D9390 /* dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = CE6E0DFD1054E9EF008D9390 /* dsa_pub.pem */; }; CE6E0DFE1054E9EF008D9390 /* dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = CE6E0DFD1054E9EF008D9390 /* dsa_pub.pem */; };
@@ -32,22 +33,24 @@
CE76FDF7111EE561006618EA /* NSEventAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE76FDF6111EE561006618EA /* NSEventAdditions.m */; }; CE76FDF7111EE561006618EA /* NSEventAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE76FDF6111EE561006618EA /* NSEventAdditions.m */; };
CE79638612536C94008D405B /* FairwareReminder.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE79638412536C94008D405B /* FairwareReminder.xib */; }; CE79638612536C94008D405B /* FairwareReminder.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE79638412536C94008D405B /* FairwareReminder.xib */; };
CE79638C12536F4E008D405B /* HSFairwareReminder.m in Sources */ = {isa = PBXBuildFile; fileRef = CE79638B12536F4E008D405B /* HSFairwareReminder.m */; }; CE79638C12536F4E008D405B /* HSFairwareReminder.m in Sources */ = {isa = PBXBuildFile; fileRef = CE79638B12536F4E008D405B /* HSFairwareReminder.m */; };
CE81134C12E5CE4D00A36C80 /* DetailsPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE81134212E5CE4D00A36C80 /* DetailsPanel.xib */; };
CE81134D12E5CE4D00A36C80 /* DirectoryPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE81134412E5CE4D00A36C80 /* DirectoryPanel.xib */; };
CE81134E12E5CE4D00A36C80 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE81134612E5CE4D00A36C80 /* MainMenu.xib */; };
CE81134F12E5CE4D00A36C80 /* ProblemDialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE81134812E5CE4D00A36C80 /* ProblemDialog.xib */; };
CE81135012E5CE4D00A36C80 /* ResultWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE81134A12E5CE4D00A36C80 /* ResultWindow.xib */; };
CE81135812E5CE6D00A36C80 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE81135612E5CE6D00A36C80 /* Preferences.xib */; };
CE8113EB12E5CE9A00A36C80 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = CE8113E912E5CE9A00A36C80 /* Localizable.strings */; };
CE8C53BC117324CE0011B41F /* HSTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CE8C53BB117324CE0011B41F /* HSTable.m */; }; CE8C53BC117324CE0011B41F /* HSTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CE8C53BB117324CE0011B41F /* HSTable.m */; };
CE91F216113BC22D0010360B /* StatsLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE91F214113BC22D0010360B /* StatsLabel.m */; }; CE91F216113BC22D0010360B /* StatsLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE91F214113BC22D0010360B /* StatsLabel.m */; };
CEAC6811109B0B7E00B43C85 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = CEAC6810109B0B7E00B43C85 /* Preferences.xib */; };
CEBE4D74111F0EE1009AAC6D /* HSWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CEBE4D73111F0EE1009AAC6D /* HSWindowController.m */; }; CEBE4D74111F0EE1009AAC6D /* HSWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CEBE4D73111F0EE1009AAC6D /* HSWindowController.m */; };
CEDD92DA0FDD01640031C7B7 /* BRSingleLineFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = CEDD92D70FDD01640031C7B7 /* BRSingleLineFormatter.m */; }; CEDD92DA0FDD01640031C7B7 /* BRSingleLineFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = CEDD92D70FDD01640031C7B7 /* BRSingleLineFormatter.m */; };
CEE7EA130FE675C80004E467 /* DetailsPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CEE7EA120FE675C80004E467 /* DetailsPanel.m */; }; CEE7EA130FE675C80004E467 /* DetailsPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CEE7EA120FE675C80004E467 /* DetailsPanel.m */; };
CEEB135209C837A2004D2330 /* dupeguru.icns in Resources */ = {isa = PBXBuildFile; fileRef = CEEB135109C837A2004D2330 /* dupeguru.icns */; }; CEEB135209C837A2004D2330 /* dupeguru.icns in Resources */ = {isa = PBXBuildFile; fileRef = CEEB135109C837A2004D2330 /* dupeguru.icns */; };
CEEFC0F810945D9F001F3A39 /* DirectoryPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = CEEFC0F710945D9F001F3A39 /* DirectoryPanel.xib */; }; CEF0ACCE12DF3C2000B32F7E /* HSRecentFiles.m in Sources */ = {isa = PBXBuildFile; fileRef = CEF0ACCD12DF3C2000B32F7E /* HSRecentFiles.m */; };
CEEFC0FB10945E37001F3A39 /* DetailsPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = CEEFC0FA10945E37001F3A39 /* DetailsPanel.xib */; };
CEFC294609C89E3D00D9F998 /* folder32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC294509C89E3D00D9F998 /* folder32.png */; }; CEFC294609C89E3D00D9F998 /* folder32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC294509C89E3D00D9F998 /* folder32.png */; };
CEFC295509C89FF200D9F998 /* details32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC295309C89FF200D9F998 /* details32.png */; };
CEFC295609C89FF200D9F998 /* preferences32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC295409C89FF200D9F998 /* preferences32.png */; };
CEFC7F9E0FC9517500CD5728 /* Dialogs.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7F8B0FC9517500CD5728 /* Dialogs.m */; }; CEFC7F9E0FC9517500CD5728 /* Dialogs.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7F8B0FC9517500CD5728 /* Dialogs.m */; };
CEFC7F9F0FC9517500CD5728 /* HSErrorReportWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7F8D0FC9517500CD5728 /* HSErrorReportWindow.m */; }; CEFC7F9F0FC9517500CD5728 /* HSErrorReportWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7F8D0FC9517500CD5728 /* HSErrorReportWindow.m */; };
CEFC7FA10FC9517500CD5728 /* ProgressController.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7F910FC9517500CD5728 /* ProgressController.m */; }; CEFC7FA10FC9517500CD5728 /* ProgressController.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7F910FC9517500CD5728 /* ProgressController.m */; };
CEFC7FA20FC9517500CD5728 /* RecentDirectories.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7F950FC9517500CD5728 /* RecentDirectories.m */; };
CEFC7FA50FC9517500CD5728 /* Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7F9B0FC9517500CD5728 /* Utils.m */; }; CEFC7FA50FC9517500CD5728 /* Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7F9B0FC9517500CD5728 /* Utils.m */; };
CEFC7FA60FC9517500CD5728 /* ValueTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7F9D0FC9517500CD5728 /* ValueTransformers.m */; }; CEFC7FA60FC9517500CD5728 /* ValueTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7F9D0FC9517500CD5728 /* ValueTransformers.m */; };
CEFC7FB90FC951A700CD5728 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7FB20FC951A700CD5728 /* AppDelegate.m */; }; CEFC7FB90FC951A700CD5728 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7FB20FC951A700CD5728 /* AppDelegate.m */; };
@@ -76,20 +79,24 @@
29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; }; 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; };
8D1107320486CEB800E47090 /* dupeGuru.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = dupeGuru.app; sourceTree = BUILT_PRODUCTS_DIR; }; 8D1107320486CEB800E47090 /* dupeGuru.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = dupeGuru.app; sourceTree = BUILT_PRODUCTS_DIR; };
CE073F5409CAE1A3005C1D2F /* dupeguru_help */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dupeguru_help; path = ../../help_se/dupeguru_help; sourceTree = "<group>"; }; CE05341312E5DC260029EF25 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../../cocoalib/fr.lproj/FairwareReminder.xib; sourceTree = SOURCE_ROOT; };
CE073F5409CAE1A3005C1D2F /* help */ = {isa = PBXFileReference; lastKnownFileType = folder; name = help; path = ../../build/help; sourceTree = "<group>"; };
CE19BC6011199231007CCEB0 /* ErrorReportWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ErrorReportWindow.xib; sourceTree = "<group>"; }; CE19BC6011199231007CCEB0 /* ErrorReportWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ErrorReportWindow.xib; sourceTree = "<group>"; };
CE19BC6111199231007CCEB0 /* progress.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = progress.xib; sourceTree = "<group>"; }; CE19BC6111199231007CCEB0 /* progress.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = progress.xib; sourceTree = "<group>"; };
CE27D3C012CCA42500859E67 /* about.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = about.xib; path = ../../cocoalib/xib/about.xib; sourceTree = SOURCE_ROOT; };
CE27D3C212CCA43800859E67 /* HSAboutBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSAboutBox.h; path = ../../cocoalib/HSAboutBox.h; sourceTree = SOURCE_ROOT; };
CE27D3C312CCA43800859E67 /* HSAboutBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSAboutBox.m; path = ../../cocoalib/HSAboutBox.m; sourceTree = SOURCE_ROOT; };
CE381C9409914ACE003581CE /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; }; CE381C9409914ACE003581CE /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; };
CE381C9509914ACE003581CE /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; }; CE381C9509914ACE003581CE /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; };
CE381C9A09914ADF003581CE /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = ResultWindow.m; sourceTree = SOURCE_ROOT; }; CE381C9A09914ADF003581CE /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = ResultWindow.m; sourceTree = SOURCE_ROOT; };
CE381C9B09914ADF003581CE /* ResultWindow.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = ResultWindow.h; sourceTree = SOURCE_ROOT; }; CE381C9B09914ADF003581CE /* ResultWindow.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = ResultWindow.h; sourceTree = SOURCE_ROOT; };
CE381CF509915304003581CE /* dg_cocoa.plugin */ = {isa = PBXFileReference; lastKnownFileType = folder; path = dg_cocoa.plugin; sourceTree = SOURCE_ROOT; }; CE381CF509915304003581CE /* dg_cocoa.plugin */ = {isa = PBXFileReference; lastKnownFileType = folder; path = dg_cocoa.plugin; sourceTree = SOURCE_ROOT; };
CE3A46F9109B212E002ABFD5 /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MainMenu.xib; path = ../base/xib/MainMenu.xib; sourceTree = "<group>"; }; CE4526F112E5F55F00005A15 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = ../base/en.lproj/core.strings; sourceTree = SOURCE_ROOT; };
CE4526F312E5F57000005A15 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = ../base/fr.lproj/core.strings; sourceTree = SOURCE_ROOT; };
CE45579A0AE3BC2B005A9546 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = /Library/Frameworks/Sparkle.framework; sourceTree = "<absolute>"; }; CE45579A0AE3BC2B005A9546 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = /Library/Frameworks/Sparkle.framework; sourceTree = "<absolute>"; };
CE647E541173024A006D28BA /* ProblemDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProblemDialog.h; path = ../base/ProblemDialog.h; sourceTree = SOURCE_ROOT; }; CE647E541173024A006D28BA /* ProblemDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProblemDialog.h; path = ../base/ProblemDialog.h; sourceTree = SOURCE_ROOT; };
CE647E551173024A006D28BA /* ProblemDialog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProblemDialog.m; path = ../base/ProblemDialog.m; sourceTree = SOURCE_ROOT; }; CE647E551173024A006D28BA /* ProblemDialog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProblemDialog.m; path = ../base/ProblemDialog.m; sourceTree = SOURCE_ROOT; };
CE647E561173024A006D28BA /* PyProblemDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyProblemDialog.h; path = ../base/PyProblemDialog.h; sourceTree = SOURCE_ROOT; }; CE647E561173024A006D28BA /* PyProblemDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyProblemDialog.h; path = ../base/PyProblemDialog.h; sourceTree = SOURCE_ROOT; };
CE647E581173026F006D28BA /* ProblemDialog.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ProblemDialog.xib; path = ../base/xib/ProblemDialog.xib; sourceTree = SOURCE_ROOT; };
CE6DD4E4124CA3070089A48D /* PyResultTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyResultTable.h; path = ../base/PyResultTable.h; sourceTree = SOURCE_ROOT; }; CE6DD4E4124CA3070089A48D /* PyResultTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyResultTable.h; path = ../base/PyResultTable.h; sourceTree = SOURCE_ROOT; };
CE6DD4E5124CA3070089A48D /* ResultTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ResultTable.h; path = ../base/ResultTable.h; sourceTree = SOURCE_ROOT; }; CE6DD4E5124CA3070089A48D /* ResultTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ResultTable.h; path = ../base/ResultTable.h; sourceTree = SOURCE_ROOT; };
CE6DD4E6124CA3070089A48D /* ResultTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ResultTable.m; path = ../base/ResultTable.m; sourceTree = SOURCE_ROOT; }; CE6DD4E6124CA3070089A48D /* ResultTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ResultTable.m; path = ../base/ResultTable.m; sourceTree = SOURCE_ROOT; };
@@ -118,12 +125,25 @@
CE79638512536C94008D405B /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../../cocoalib/en.lproj/FairwareReminder.xib; sourceTree = SOURCE_ROOT; }; CE79638512536C94008D405B /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../../cocoalib/en.lproj/FairwareReminder.xib; sourceTree = SOURCE_ROOT; };
CE79638A12536F4E008D405B /* HSFairwareReminder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSFairwareReminder.h; path = ../../cocoalib/HSFairwareReminder.h; sourceTree = SOURCE_ROOT; }; CE79638A12536F4E008D405B /* HSFairwareReminder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSFairwareReminder.h; path = ../../cocoalib/HSFairwareReminder.h; sourceTree = SOURCE_ROOT; };
CE79638B12536F4E008D405B /* HSFairwareReminder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSFairwareReminder.m; path = ../../cocoalib/HSFairwareReminder.m; sourceTree = SOURCE_ROOT; }; CE79638B12536F4E008D405B /* HSFairwareReminder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSFairwareReminder.m; path = ../../cocoalib/HSFairwareReminder.m; sourceTree = SOURCE_ROOT; };
CE81134312E5CE4D00A36C80 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../base/en.lproj/DetailsPanel.xib; sourceTree = SOURCE_ROOT; };
CE81134512E5CE4D00A36C80 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../base/en.lproj/DirectoryPanel.xib; sourceTree = SOURCE_ROOT; };
CE81134712E5CE4D00A36C80 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../base/en.lproj/MainMenu.xib; sourceTree = SOURCE_ROOT; };
CE81134912E5CE4D00A36C80 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../base/en.lproj/ProblemDialog.xib; sourceTree = SOURCE_ROOT; };
CE81134B12E5CE4D00A36C80 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../base/en.lproj/ResultWindow.xib; sourceTree = SOURCE_ROOT; };
CE81135112E5CE6100A36C80 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../base/fr.lproj/DetailsPanel.xib; sourceTree = SOURCE_ROOT; };
CE81135212E5CE6100A36C80 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../base/fr.lproj/DirectoryPanel.xib; sourceTree = SOURCE_ROOT; };
CE81135312E5CE6100A36C80 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../base/fr.lproj/MainMenu.xib; sourceTree = SOURCE_ROOT; };
CE81135412E5CE6100A36C80 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../base/fr.lproj/ProblemDialog.xib; sourceTree = SOURCE_ROOT; };
CE81135512E5CE6100A36C80 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../base/fr.lproj/ResultWindow.xib; sourceTree = SOURCE_ROOT; };
CE81135712E5CE6D00A36C80 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/Preferences.xib; sourceTree = "<group>"; };
CE81135912E5CE7B00A36C80 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = fr.lproj/Preferences.xib; sourceTree = "<group>"; };
CE8113EA12E5CE9A00A36C80 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = ../base/en.lproj/Localizable.strings; sourceTree = SOURCE_ROOT; };
CE8113EC12E5CEA800A36C80 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = ../base/fr.lproj/Localizable.strings; sourceTree = SOURCE_ROOT; };
CE8C53B61173248F0011B41F /* PyTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PyTable.h; sourceTree = "<group>"; }; CE8C53B61173248F0011B41F /* PyTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PyTable.h; sourceTree = "<group>"; };
CE8C53BB117324CE0011B41F /* HSTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSTable.m; sourceTree = "<group>"; }; CE8C53BB117324CE0011B41F /* HSTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSTable.m; sourceTree = "<group>"; };
CE91F210113BC22D0010360B /* PyStatsLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyStatsLabel.h; path = ../base/PyStatsLabel.h; sourceTree = SOURCE_ROOT; }; CE91F210113BC22D0010360B /* PyStatsLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyStatsLabel.h; path = ../base/PyStatsLabel.h; sourceTree = SOURCE_ROOT; };
CE91F213113BC22D0010360B /* StatsLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StatsLabel.h; path = ../base/StatsLabel.h; sourceTree = SOURCE_ROOT; }; CE91F213113BC22D0010360B /* StatsLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StatsLabel.h; path = ../base/StatsLabel.h; sourceTree = SOURCE_ROOT; };
CE91F214113BC22D0010360B /* StatsLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = StatsLabel.m; path = ../base/StatsLabel.m; sourceTree = SOURCE_ROOT; }; CE91F214113BC22D0010360B /* StatsLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = StatsLabel.m; path = ../base/StatsLabel.m; sourceTree = SOURCE_ROOT; };
CEAC6810109B0B7E00B43C85 /* Preferences.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Preferences.xib; path = xib/Preferences.xib; sourceTree = "<group>"; };
CEBE4D72111F0EE1009AAC6D /* HSWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HSWindowController.h; sourceTree = "<group>"; }; CEBE4D72111F0EE1009AAC6D /* HSWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HSWindowController.h; sourceTree = "<group>"; };
CEBE4D73111F0EE1009AAC6D /* HSWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSWindowController.m; sourceTree = "<group>"; }; CEBE4D73111F0EE1009AAC6D /* HSWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSWindowController.m; sourceTree = "<group>"; };
CEDD92D60FDD01640031C7B7 /* BRSingleLineFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BRSingleLineFormatter.h; path = ../../cocoalib/brsinglelineformatter/BRSingleLineFormatter.h; sourceTree = SOURCE_ROOT; }; CEDD92D60FDD01640031C7B7 /* BRSingleLineFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BRSingleLineFormatter.h; path = ../../cocoalib/brsinglelineformatter/BRSingleLineFormatter.h; sourceTree = SOURCE_ROOT; };
@@ -131,11 +151,9 @@
CEE7EA110FE675C80004E467 /* DetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DetailsPanel.h; path = ../base/DetailsPanel.h; sourceTree = SOURCE_ROOT; }; CEE7EA110FE675C80004E467 /* DetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DetailsPanel.h; path = ../base/DetailsPanel.h; sourceTree = SOURCE_ROOT; };
CEE7EA120FE675C80004E467 /* DetailsPanel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DetailsPanel.m; path = ../base/DetailsPanel.m; sourceTree = SOURCE_ROOT; }; CEE7EA120FE675C80004E467 /* DetailsPanel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DetailsPanel.m; path = ../base/DetailsPanel.m; sourceTree = SOURCE_ROOT; };
CEEB135109C837A2004D2330 /* dupeguru.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = dupeguru.icns; sourceTree = "<group>"; }; CEEB135109C837A2004D2330 /* dupeguru.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = dupeguru.icns; sourceTree = "<group>"; };
CEEFC0F710945D9F001F3A39 /* DirectoryPanel.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = DirectoryPanel.xib; path = ../base/xib/DirectoryPanel.xib; sourceTree = "<group>"; }; CEF0ACCC12DF3C2000B32F7E /* HSRecentFiles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSRecentFiles.h; path = ../../cocoalib/HSRecentFiles.h; sourceTree = SOURCE_ROOT; };
CEEFC0FA10945E37001F3A39 /* DetailsPanel.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = DetailsPanel.xib; path = ../base/xib/DetailsPanel.xib; sourceTree = "<group>"; }; CEF0ACCD12DF3C2000B32F7E /* HSRecentFiles.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSRecentFiles.m; path = ../../cocoalib/HSRecentFiles.m; sourceTree = SOURCE_ROOT; };
CEFC294509C89E3D00D9F998 /* folder32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = folder32.png; path = ../../images/folder32.png; sourceTree = SOURCE_ROOT; }; CEFC294509C89E3D00D9F998 /* folder32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = folder32.png; path = ../../images/folder32.png; sourceTree = SOURCE_ROOT; };
CEFC295309C89FF200D9F998 /* details32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = details32.png; path = ../../images/details32.png; sourceTree = SOURCE_ROOT; };
CEFC295409C89FF200D9F998 /* preferences32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = preferences32.png; path = ../../images/preferences32.png; sourceTree = SOURCE_ROOT; };
CEFC7F8A0FC9517500CD5728 /* Dialogs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Dialogs.h; path = ../../cocoalib/Dialogs.h; sourceTree = SOURCE_ROOT; }; CEFC7F8A0FC9517500CD5728 /* Dialogs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Dialogs.h; path = ../../cocoalib/Dialogs.h; sourceTree = SOURCE_ROOT; };
CEFC7F8B0FC9517500CD5728 /* Dialogs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Dialogs.m; path = ../../cocoalib/Dialogs.m; sourceTree = SOURCE_ROOT; }; CEFC7F8B0FC9517500CD5728 /* Dialogs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Dialogs.m; path = ../../cocoalib/Dialogs.m; sourceTree = SOURCE_ROOT; };
CEFC7F8C0FC9517500CD5728 /* HSErrorReportWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSErrorReportWindow.h; path = ../../cocoalib/HSErrorReportWindow.h; sourceTree = SOURCE_ROOT; }; CEFC7F8C0FC9517500CD5728 /* HSErrorReportWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSErrorReportWindow.h; path = ../../cocoalib/HSErrorReportWindow.h; sourceTree = SOURCE_ROOT; };
@@ -143,8 +161,6 @@
CEFC7F900FC9517500CD5728 /* ProgressController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProgressController.h; path = ../../cocoalib/ProgressController.h; sourceTree = SOURCE_ROOT; }; CEFC7F900FC9517500CD5728 /* ProgressController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProgressController.h; path = ../../cocoalib/ProgressController.h; sourceTree = SOURCE_ROOT; };
CEFC7F910FC9517500CD5728 /* ProgressController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProgressController.m; path = ../../cocoalib/ProgressController.m; sourceTree = SOURCE_ROOT; }; CEFC7F910FC9517500CD5728 /* ProgressController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProgressController.m; path = ../../cocoalib/ProgressController.m; sourceTree = SOURCE_ROOT; };
CEFC7F920FC9517500CD5728 /* PyApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyApp.h; path = ../../cocoalib/PyApp.h; sourceTree = SOURCE_ROOT; }; CEFC7F920FC9517500CD5728 /* PyApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyApp.h; path = ../../cocoalib/PyApp.h; sourceTree = SOURCE_ROOT; };
CEFC7F940FC9517500CD5728 /* RecentDirectories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RecentDirectories.h; path = ../../cocoalib/RecentDirectories.h; sourceTree = SOURCE_ROOT; };
CEFC7F950FC9517500CD5728 /* RecentDirectories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RecentDirectories.m; path = ../../cocoalib/RecentDirectories.m; sourceTree = SOURCE_ROOT; };
CEFC7F9A0FC9517500CD5728 /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Utils.h; path = ../../cocoalib/Utils.h; sourceTree = SOURCE_ROOT; }; CEFC7F9A0FC9517500CD5728 /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Utils.h; path = ../../cocoalib/Utils.h; sourceTree = SOURCE_ROOT; };
CEFC7F9B0FC9517500CD5728 /* Utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Utils.m; path = ../../cocoalib/Utils.m; sourceTree = SOURCE_ROOT; }; CEFC7F9B0FC9517500CD5728 /* Utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Utils.m; path = ../../cocoalib/Utils.m; sourceTree = SOURCE_ROOT; };
CEFC7F9C0FC9517500CD5728 /* ValueTransformers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueTransformers.h; path = ../../cocoalib/ValueTransformers.h; sourceTree = SOURCE_ROOT; }; CEFC7F9C0FC9517500CD5728 /* ValueTransformers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueTransformers.h; path = ../../cocoalib/ValueTransformers.h; sourceTree = SOURCE_ROOT; };
@@ -229,12 +245,14 @@
29B97317FDCFA39411CA2CEA /* Resources */ = { 29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CE073F5409CAE1A3005C1D2F /* dupeguru_help */, CE073F5409CAE1A3005C1D2F /* help */,
CE381CF509915304003581CE /* dg_cocoa.plugin */, CE381CF509915304003581CE /* dg_cocoa.plugin */,
CEFC294309C89E0000D9F998 /* images */, CEFC294309C89E0000D9F998 /* images */,
CEEFC0CA10943849001F3A39 /* xib */, CEEFC0CA10943849001F3A39 /* xib */,
CEEB135109C837A2004D2330 /* dupeguru.icns */, CEEB135109C837A2004D2330 /* dupeguru.icns */,
8D1107310486CEB800E47090 /* Info.plist */, 8D1107310486CEB800E47090 /* Info.plist */,
CE8113E912E5CE9A00A36C80 /* Localizable.strings */,
CE4526F012E5F55F00005A15 /* core.strings */,
CE6E0DFD1054E9EF008D9390 /* dsa_pub.pem */, CE6E0DFD1054E9EF008D9390 /* dsa_pub.pem */,
); );
name = Resources; name = Resources;
@@ -252,6 +270,7 @@
CE19BC5F11199231007CCEB0 /* xib */ = { CE19BC5F11199231007CCEB0 /* xib */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CE27D3C012CCA42500859E67 /* about.xib */,
CE79638412536C94008D405B /* FairwareReminder.xib */, CE79638412536C94008D405B /* FairwareReminder.xib */,
CE19BC6011199231007CCEB0 /* ErrorReportWindow.xib */, CE19BC6011199231007CCEB0 /* ErrorReportWindow.xib */,
CE19BC6111199231007CCEB0 /* progress.xib */, CE19BC6111199231007CCEB0 /* progress.xib */,
@@ -315,11 +334,12 @@
CEEFC0CA10943849001F3A39 /* xib */ = { CEEFC0CA10943849001F3A39 /* xib */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CE647E581173026F006D28BA /* ProblemDialog.xib */, CE81134212E5CE4D00A36C80 /* DetailsPanel.xib */,
CE3A46F9109B212E002ABFD5 /* MainMenu.xib */, CE81134412E5CE4D00A36C80 /* DirectoryPanel.xib */,
CEAC6810109B0B7E00B43C85 /* Preferences.xib */, CE81134612E5CE4D00A36C80 /* MainMenu.xib */,
CEEFC0F710945D9F001F3A39 /* DirectoryPanel.xib */, CE81134812E5CE4D00A36C80 /* ProblemDialog.xib */,
CEEFC0FA10945E37001F3A39 /* DetailsPanel.xib */, CE81134A12E5CE4D00A36C80 /* ResultWindow.xib */,
CE81135612E5CE6D00A36C80 /* Preferences.xib */,
); );
name = xib; name = xib;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -327,8 +347,6 @@
CEFC294309C89E0000D9F998 /* images */ = { CEFC294309C89E0000D9F998 /* images */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CEFC295309C89FF200D9F998 /* details32.png */,
CEFC295409C89FF200D9F998 /* preferences32.png */,
CEFC294509C89E3D00D9F998 /* folder32.png */, CEFC294509C89E3D00D9F998 /* folder32.png */,
); );
name = images; name = images;
@@ -351,11 +369,13 @@
CE79638A12536F4E008D405B /* HSFairwareReminder.h */, CE79638A12536F4E008D405B /* HSFairwareReminder.h */,
CE79638B12536F4E008D405B /* HSFairwareReminder.m */, CE79638B12536F4E008D405B /* HSFairwareReminder.m */,
CE79638212536C6E008D405B /* PyFairware.h */, CE79638212536C6E008D405B /* PyFairware.h */,
CE27D3C212CCA43800859E67 /* HSAboutBox.h */,
CE27D3C312CCA43800859E67 /* HSAboutBox.m */,
CEF0ACCC12DF3C2000B32F7E /* HSRecentFiles.h */,
CEF0ACCD12DF3C2000B32F7E /* HSRecentFiles.m */,
CEFC7F900FC9517500CD5728 /* ProgressController.h */, CEFC7F900FC9517500CD5728 /* ProgressController.h */,
CEFC7F910FC9517500CD5728 /* ProgressController.m */, CEFC7F910FC9517500CD5728 /* ProgressController.m */,
CEFC7F920FC9517500CD5728 /* PyApp.h */, CEFC7F920FC9517500CD5728 /* PyApp.h */,
CEFC7F940FC9517500CD5728 /* RecentDirectories.h */,
CEFC7F950FC9517500CD5728 /* RecentDirectories.m */,
CEFC7F9A0FC9517500CD5728 /* Utils.h */, CEFC7F9A0FC9517500CD5728 /* Utils.h */,
CEFC7F9B0FC9517500CD5728 /* Utils.m */, CEFC7F9B0FC9517500CD5728 /* Utils.m */,
CEFC7F9C0FC9517500CD5728 /* ValueTransformers.h */, CEFC7F9C0FC9517500CD5728 /* ValueTransformers.h */,
@@ -426,6 +446,7 @@
}; };
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */;
compatibilityVersion = "Xcode 3.0"; compatibilityVersion = "Xcode 3.0";
developmentRegion = English;
hasScannedForEncodings = 1; hasScannedForEncodings = 1;
knownRegions = ( knownRegions = (
English, English,
@@ -433,6 +454,7 @@
French, French,
German, German,
en, en,
fr,
); );
mainGroup = 29B97314FDCFA39411CA2CEA /* dupeguru */; mainGroup = 29B97314FDCFA39411CA2CEA /* dupeguru */;
projectDirPath = ""; projectDirPath = "";
@@ -449,20 +471,22 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */, CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */,
CE073F6309CAE1A3005C1D2F /* dupeguru_help in Resources */, CE073F6309CAE1A3005C1D2F /* help in Resources */,
CEEB135209C837A2004D2330 /* dupeguru.icns in Resources */, CEEB135209C837A2004D2330 /* dupeguru.icns in Resources */,
CEFC294609C89E3D00D9F998 /* folder32.png in Resources */, CEFC294609C89E3D00D9F998 /* folder32.png in Resources */,
CEFC295509C89FF200D9F998 /* details32.png in Resources */,
CEFC295609C89FF200D9F998 /* preferences32.png in Resources */,
CE6E0DFE1054E9EF008D9390 /* dsa_pub.pem in Resources */, CE6E0DFE1054E9EF008D9390 /* dsa_pub.pem in Resources */,
CEEFC0F810945D9F001F3A39 /* DirectoryPanel.xib in Resources */,
CEEFC0FB10945E37001F3A39 /* DetailsPanel.xib in Resources */,
CEAC6811109B0B7E00B43C85 /* Preferences.xib in Resources */,
CE3A46FA109B212E002ABFD5 /* MainMenu.xib in Resources */,
CE19BC6311199231007CCEB0 /* ErrorReportWindow.xib in Resources */, CE19BC6311199231007CCEB0 /* ErrorReportWindow.xib in Resources */,
CE19BC6411199231007CCEB0 /* progress.xib in Resources */, CE19BC6411199231007CCEB0 /* progress.xib in Resources */,
CE647E591173026F006D28BA /* ProblemDialog.xib in Resources */,
CE79638612536C94008D405B /* FairwareReminder.xib in Resources */, CE79638612536C94008D405B /* FairwareReminder.xib in Resources */,
CE27D3C112CCA42500859E67 /* about.xib in Resources */,
CE81134C12E5CE4D00A36C80 /* DetailsPanel.xib in Resources */,
CE81134D12E5CE4D00A36C80 /* DirectoryPanel.xib in Resources */,
CE81134E12E5CE4D00A36C80 /* MainMenu.xib in Resources */,
CE81134F12E5CE4D00A36C80 /* ProblemDialog.xib in Resources */,
CE81135012E5CE4D00A36C80 /* ResultWindow.xib in Resources */,
CE81135812E5CE6D00A36C80 /* Preferences.xib in Resources */,
CE8113EB12E5CE9A00A36C80 /* Localizable.strings in Resources */,
CE4526F212E5F55F00005A15 /* core.strings in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -479,7 +503,6 @@
CEFC7F9E0FC9517500CD5728 /* Dialogs.m in Sources */, CEFC7F9E0FC9517500CD5728 /* Dialogs.m in Sources */,
CEFC7F9F0FC9517500CD5728 /* HSErrorReportWindow.m in Sources */, CEFC7F9F0FC9517500CD5728 /* HSErrorReportWindow.m in Sources */,
CEFC7FA10FC9517500CD5728 /* ProgressController.m in Sources */, CEFC7FA10FC9517500CD5728 /* ProgressController.m in Sources */,
CEFC7FA20FC9517500CD5728 /* RecentDirectories.m in Sources */,
CEFC7FA50FC9517500CD5728 /* Utils.m in Sources */, CEFC7FA50FC9517500CD5728 /* Utils.m in Sources */,
CEFC7FA60FC9517500CD5728 /* ValueTransformers.m in Sources */, CEFC7FA60FC9517500CD5728 /* ValueTransformers.m in Sources */,
CEFC7FB90FC951A700CD5728 /* AppDelegate.m in Sources */, CEFC7FB90FC951A700CD5728 /* AppDelegate.m in Sources */,
@@ -501,21 +524,96 @@
CE6DD4E7124CA3070089A48D /* ResultTable.m in Sources */, CE6DD4E7124CA3070089A48D /* ResultTable.m in Sources */,
CE6DD547124CAF1F0089A48D /* HSTableView.m in Sources */, CE6DD547124CAF1F0089A48D /* HSTableView.m in Sources */,
CE79638C12536F4E008D405B /* HSFairwareReminder.m in Sources */, CE79638C12536F4E008D405B /* HSFairwareReminder.m in Sources */,
CE27D3C412CCA43800859E67 /* HSAboutBox.m in Sources */,
CEF0ACCE12DF3C2000B32F7E /* HSRecentFiles.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
/* End PBXSourcesBuildPhase section */ /* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */ /* Begin PBXVariantGroup section */
CE4526F012E5F55F00005A15 /* core.strings */ = {
isa = PBXVariantGroup;
children = (
CE4526F112E5F55F00005A15 /* en */,
CE4526F312E5F57000005A15 /* fr */,
);
name = core.strings;
sourceTree = SOURCE_ROOT;
};
CE79638412536C94008D405B /* FairwareReminder.xib */ = { CE79638412536C94008D405B /* FairwareReminder.xib */ = {
isa = PBXVariantGroup; isa = PBXVariantGroup;
children = ( children = (
CE79638512536C94008D405B /* en */, CE79638512536C94008D405B /* en */,
CE05341312E5DC260029EF25 /* fr */,
); );
name = FairwareReminder.xib; name = FairwareReminder.xib;
path = ../../cocoalib/xib; path = ../../cocoalib/xib;
sourceTree = SOURCE_ROOT; sourceTree = SOURCE_ROOT;
}; };
CE81134212E5CE4D00A36C80 /* DetailsPanel.xib */ = {
isa = PBXVariantGroup;
children = (
CE81134312E5CE4D00A36C80 /* en */,
CE81135112E5CE6100A36C80 /* fr */,
);
name = DetailsPanel.xib;
sourceTree = SOURCE_ROOT;
};
CE81134412E5CE4D00A36C80 /* DirectoryPanel.xib */ = {
isa = PBXVariantGroup;
children = (
CE81134512E5CE4D00A36C80 /* en */,
CE81135212E5CE6100A36C80 /* fr */,
);
name = DirectoryPanel.xib;
sourceTree = SOURCE_ROOT;
};
CE81134612E5CE4D00A36C80 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
CE81134712E5CE4D00A36C80 /* en */,
CE81135312E5CE6100A36C80 /* fr */,
);
name = MainMenu.xib;
sourceTree = SOURCE_ROOT;
};
CE81134812E5CE4D00A36C80 /* ProblemDialog.xib */ = {
isa = PBXVariantGroup;
children = (
CE81134912E5CE4D00A36C80 /* en */,
CE81135412E5CE6100A36C80 /* fr */,
);
name = ProblemDialog.xib;
sourceTree = SOURCE_ROOT;
};
CE81134A12E5CE4D00A36C80 /* ResultWindow.xib */ = {
isa = PBXVariantGroup;
children = (
CE81134B12E5CE4D00A36C80 /* en */,
CE81135512E5CE6100A36C80 /* fr */,
);
name = ResultWindow.xib;
sourceTree = SOURCE_ROOT;
};
CE81135612E5CE6D00A36C80 /* Preferences.xib */ = {
isa = PBXVariantGroup;
children = (
CE81135712E5CE6D00A36C80 /* en */,
CE81135912E5CE7B00A36C80 /* fr */,
);
name = Preferences.xib;
sourceTree = SOURCE_ROOT;
};
CE8113E912E5CE9A00A36C80 /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
CE8113EA12E5CE9A00A36C80 /* en */,
CE8113EC12E5CEA800A36C80 /* fr */,
);
name = Localizable.strings;
sourceTree = SOURCE_ROOT;
};
/* End PBXVariantGroup section */ /* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */

Binary file not shown.

View File

@@ -2,13 +2,13 @@
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10"> <archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
<data> <data>
<int key="IBDocument.SystemTarget">1050</int> <int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">10F569</string> <string key="IBDocument.SystemVersion">10J567</string>
<string key="IBDocument.InterfaceBuilderVersion">788</string> <string key="IBDocument.InterfaceBuilderVersion">823</string>
<string key="IBDocument.AppKitVersion">1038.29</string> <string key="IBDocument.AppKitVersion">1038.35</string>
<string key="IBDocument.HIToolboxVersion">461.00</string> <string key="IBDocument.HIToolboxVersion">462.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions"> <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">788</string> <string key="NS.object.0">823</string>
</object> </object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs"> <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
@@ -19,13 +19,8 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object> </object>
<object class="NSMutableDictionary" key="IBDocument.Metadata"> <object class="NSMutableDictionary" key="IBDocument.Metadata">
<bool key="EncodedWithXMLCoder">YES</bool> <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<object class="NSArray" key="dict.sortedKeys" id="0"> <integer value="1" key="NS.object.0"/>
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object> </object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000"> <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
@@ -39,12 +34,16 @@
<string key="NSClassName">NSApplication</string> <string key="NSClassName">NSApplication</string>
</object> </object>
<object class="NSUserDefaultsController" id="75941798"> <object class="NSUserDefaultsController" id="75941798">
<object class="NSMutableArray" key="NSDeclaredKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>DebugMode</string>
</object>
<bool key="NSSharedInstance">YES</bool> <bool key="NSSharedInstance">YES</bool>
</object> </object>
<object class="NSWindowTemplate" id="489014306"> <object class="NSWindowTemplate" id="489014306">
<int key="NSWindowStyleMask">3</int> <int key="NSWindowStyleMask">3</int>
<int key="NSWindowBacking">2</int> <int key="NSWindowBacking">2</int>
<string key="NSWindowRect">{{92, 300}, {389, 302}}</string> <string key="NSWindowRect">{{92, 277}, {389, 325}}</string>
<int key="NSWTFlags">1886912512</int> <int key="NSWTFlags">1886912512</int>
<string key="NSWindowTitle">dupeGuru Preferences</string> <string key="NSWindowTitle">dupeGuru Preferences</string>
<object class="NSMutableString" key="NSWindowClass"> <object class="NSMutableString" key="NSWindowClass">
@@ -90,7 +89,7 @@
<object class="NSTabView" id="712448818"> <object class="NSTabView" id="712448818">
<reference key="NSNextResponder" ref="642300710"/> <reference key="NSNextResponder" ref="642300710"/>
<int key="NSvFlags">12</int> <int key="NSvFlags">12</int>
<string key="NSFrame">{{13, 40}, {363, 256}}</string> <string key="NSFrame">{{13, 40}, {363, 279}}</string>
<reference key="NSSuperview" ref="642300710"/> <reference key="NSSuperview" ref="642300710"/>
<object class="NSMutableArray" key="NSTabViewItems"> <object class="NSMutableArray" key="NSTabViewItems">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
@@ -104,7 +103,7 @@
<object class="NSSlider" id="111002126"> <object class="NSSlider" id="111002126">
<reference key="NSNextResponder" ref="889257400"/> <reference key="NSNextResponder" ref="889257400"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{117, 148}, {181, 21}}</string> <string key="NSFrame">{{117, 171}, {181, 21}}</string>
<reference key="NSSuperview" ref="889257400"/> <reference key="NSSuperview" ref="889257400"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSSliderCell" key="NSCell" id="4139314"> <object class="NSSliderCell" key="NSCell" id="4139314">
@@ -132,7 +131,7 @@
<object class="NSTextField" id="950195532"> <object class="NSTextField" id="950195532">
<reference key="NSNextResponder" ref="889257400"/> <reference key="NSNextResponder" ref="889257400"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{119, 131}, {80, 13}}</string> <string key="NSFrame">{{119, 154}, {80, 13}}</string>
<reference key="NSSuperview" ref="889257400"/> <reference key="NSSuperview" ref="889257400"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="117548381"> <object class="NSTextFieldCell" key="NSCell" id="117548381">
@@ -168,7 +167,7 @@
<object class="NSTextField" id="1008577648"> <object class="NSTextField" id="1008577648">
<reference key="NSNextResponder" ref="889257400"/> <reference key="NSNextResponder" ref="889257400"/>
<int key="NSvFlags">289</int> <int key="NSvFlags">289</int>
<string key="NSFrame">{{216, 131}, {80, 13}}</string> <string key="NSFrame">{{216, 154}, {80, 13}}</string>
<reference key="NSSuperview" ref="889257400"/> <reference key="NSSuperview" ref="889257400"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="569479200"> <object class="NSTextFieldCell" key="NSCell" id="569479200">
@@ -184,7 +183,7 @@
<object class="NSTextField" id="1006361062"> <object class="NSTextField" id="1006361062">
<reference key="NSNextResponder" ref="889257400"/> <reference key="NSNextResponder" ref="889257400"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{14, 153}, {100, 14}}</string> <string key="NSFrame">{{14, 176}, {100, 14}}</string>
<reference key="NSSuperview" ref="889257400"/> <reference key="NSSuperview" ref="889257400"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="566839293"> <object class="NSTextFieldCell" key="NSCell" id="566839293">
@@ -204,7 +203,7 @@
<object class="NSTextField" id="511073890"> <object class="NSTextField" id="511073890">
<reference key="NSNextResponder" ref="889257400"/> <reference key="NSNextResponder" ref="889257400"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{17, 194}, {85, 13}}</string> <string key="NSFrame">{{17, 217}, {85, 13}}</string>
<reference key="NSSuperview" ref="889257400"/> <reference key="NSSuperview" ref="889257400"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="901283318"> <object class="NSTextFieldCell" key="NSCell" id="901283318">
@@ -220,7 +219,7 @@
<object class="NSPopUpButton" id="413464883"> <object class="NSPopUpButton" id="413464883">
<reference key="NSNextResponder" ref="889257400"/> <reference key="NSNextResponder" ref="889257400"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{116, 183}, {216, 26}}</string> <string key="NSFrame">{{116, 206}, {216, 26}}</string>
<reference key="NSSuperview" ref="889257400"/> <reference key="NSSuperview" ref="889257400"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSPopUpButtonCell" key="NSCell" id="63752222"> <object class="NSPopUpButtonCell" key="NSCell" id="63752222">
@@ -285,7 +284,7 @@
<object class="NSButton" id="637819333"> <object class="NSButton" id="637819333">
<reference key="NSNextResponder" ref="889257400"/> <reference key="NSNextResponder" ref="889257400"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 107}, {214, 18}}</string> <string key="NSFrame">{{15, 130}, {313, 18}}</string>
<reference key="NSSuperview" ref="889257400"/> <reference key="NSSuperview" ref="889257400"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="369089279"> <object class="NSButtonCell" key="NSCell" id="369089279">
@@ -308,7 +307,7 @@
<object class="NSButton" id="1067721243"> <object class="NSButton" id="1067721243">
<reference key="NSNextResponder" ref="889257400"/> <reference key="NSNextResponder" ref="889257400"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 67}, {214, 18}}</string> <string key="NSFrame">{{15, 90}, {313, 18}}</string>
<reference key="NSSuperview" ref="889257400"/> <reference key="NSSuperview" ref="889257400"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="304300476"> <object class="NSButtonCell" key="NSCell" id="304300476">
@@ -329,7 +328,7 @@
<object class="NSButton" id="290008886"> <object class="NSButton" id="290008886">
<reference key="NSNextResponder" ref="889257400"/> <reference key="NSNextResponder" ref="889257400"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 87}, {214, 18}}</string> <string key="NSFrame">{{15, 110}, {313, 18}}</string>
<reference key="NSSuperview" ref="889257400"/> <reference key="NSSuperview" ref="889257400"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="949112651"> <object class="NSButtonCell" key="NSCell" id="949112651">
@@ -350,7 +349,7 @@
<object class="NSButton" id="551239185"> <object class="NSButton" id="551239185">
<reference key="NSNextResponder" ref="889257400"/> <reference key="NSNextResponder" ref="889257400"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 5}, {283, 18}}</string> <string key="NSFrame">{{15, 7}, {313, 18}}</string>
<reference key="NSSuperview" ref="889257400"/> <reference key="NSSuperview" ref="889257400"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="456303302"> <object class="NSButtonCell" key="NSCell" id="456303302">
@@ -371,7 +370,7 @@
<object class="NSButton" id="208488736"> <object class="NSButton" id="208488736">
<reference key="NSNextResponder" ref="889257400"/> <reference key="NSNextResponder" ref="889257400"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 45}, {242, 18}}</string> <string key="NSFrame">{{15, 70}, {313, 18}}</string>
<reference key="NSSuperview" ref="889257400"/> <reference key="NSSuperview" ref="889257400"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="275918454"> <object class="NSButtonCell" key="NSCell" id="275918454">
@@ -392,13 +391,13 @@
<object class="NSButton" id="427690895"> <object class="NSButton" id="427690895">
<reference key="NSNextResponder" ref="889257400"/> <reference key="NSNextResponder" ref="889257400"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 25}, {152, 18}}</string> <string key="NSFrame">{{15, 48}, {313, 18}}</string>
<reference key="NSSuperview" ref="889257400"/> <reference key="NSSuperview" ref="889257400"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="527567105"> <object class="NSButtonCell" key="NSCell" id="527567105">
<int key="NSCellFlags">67239424</int> <int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">0</int> <int key="NSCellFlags2">0</int>
<string key="NSContents">Ignore files smaller than</string> <string key="NSContents">Ignore files smaller than:</string>
<reference key="NSSupport" ref="26"/> <reference key="NSSupport" ref="26"/>
<reference key="NSControlView" ref="427690895"/> <reference key="NSControlView" ref="427690895"/>
<int key="NSButtonFlags">1211912703</int> <int key="NSButtonFlags">1211912703</int>
@@ -413,7 +412,7 @@
<object class="NSTextField" id="880304924"> <object class="NSTextField" id="880304924">
<reference key="NSNextResponder" ref="889257400"/> <reference key="NSNextResponder" ref="889257400"/>
<int key="NSvFlags">268</int> <int key="NSvFlags">268</int>
<string key="NSFrame">{{173, 23}, {59, 22}}</string> <string key="NSFrame">{{40, 26}, {59, 22}}</string>
<reference key="NSSuperview" ref="889257400"/> <reference key="NSSuperview" ref="889257400"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="210024698"> <object class="NSTextFieldCell" key="NSCell" id="210024698">
@@ -457,9 +456,11 @@
<nil key="NS.nil"/> <nil key="NS.nil"/>
<object class="NSAttributedString" key="NS.nan"> <object class="NSAttributedString" key="NS.nan">
<string key="NSString">NaN</string> <string key="NSString">NaN</string>
<object class="NSDictionary" key="NSAttributes" id="781126459"> <object class="NSDictionary" key="NSAttributes" id="755311072">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/> <object class="NSArray" key="dict.sortedKeys" id="0">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values"> <object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
</object> </object>
@@ -508,7 +509,7 @@
<object class="NSTextField" id="1051684239"> <object class="NSTextField" id="1051684239">
<reference key="NSNextResponder" ref="889257400"/> <reference key="NSNextResponder" ref="889257400"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{240, 25}, {23, 17}}</string> <string key="NSFrame">{{104, 25}, {23, 17}}</string>
<reference key="NSSuperview" ref="889257400"/> <reference key="NSSuperview" ref="889257400"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="212167232"> <object class="NSTextFieldCell" key="NSCell" id="212167232">
@@ -524,7 +525,7 @@
<object class="NSTextField" id="262539816"> <object class="NSTextField" id="262539816">
<reference key="NSNextResponder" ref="889257400"/> <reference key="NSNextResponder" ref="889257400"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{301, 153}, {31, 14}}</string> <string key="NSFrame">{{301, 176}, {31, 14}}</string>
<reference key="NSSuperview" ref="889257400"/> <reference key="NSSuperview" ref="889257400"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="186096546"> <object class="NSTextFieldCell" key="NSCell" id="186096546">
@@ -551,7 +552,7 @@
<boolean value="YES"/> <boolean value="YES"/>
<object class="NSAttributedString" id="428931648"> <object class="NSAttributedString" id="428931648">
<string key="NSString">0</string> <string key="NSString">0</string>
<reference key="NSAttributes" ref="781126459"/> <reference key="NSAttributes" ref="755311072"/>
</object> </object>
<string>.</string> <string>.</string>
<integer value="1000"/> <integer value="1000"/>
@@ -571,7 +572,7 @@
</object> </object>
<object class="NSAttributedString" key="NS.nan"> <object class="NSAttributedString" key="NS.nan">
<string key="NSString">NaN</string> <string key="NSString">NaN</string>
<reference key="NSAttributes" ref="781126459"/> <reference key="NSAttributes" ref="755311072"/>
</object> </object>
<reference key="NS.min" ref="643632001"/> <reference key="NS.min" ref="643632001"/>
<reference key="NS.max" ref="643632001"/> <reference key="NS.max" ref="643632001"/>
@@ -588,7 +589,7 @@
</object> </object>
</object> </object>
</object> </object>
<string key="NSFrame">{{10, 33}, {343, 210}}</string> <string key="NSFrame">{{10, 33}, {343, 233}}</string>
<reference key="NSSuperview" ref="712448818"/> <reference key="NSSuperview" ref="712448818"/>
</object> </object>
<string key="NSLabel">Basic</string> <string key="NSLabel">Basic</string>
@@ -605,7 +606,7 @@
<object class="NSButton" id="724127338"> <object class="NSButton" id="724127338">
<reference key="NSNextResponder" ref="448252432"/> <reference key="NSNextResponder" ref="448252432"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 191}, {228, 18}}</string> <string key="NSFrame">{{15, 214}, {313, 18}}</string>
<reference key="NSSuperview" ref="448252432"/> <reference key="NSSuperview" ref="448252432"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="360294640"> <object class="NSButtonCell" key="NSCell" id="360294640">
@@ -626,7 +627,7 @@
<object class="NSButton" id="647216699"> <object class="NSButton" id="647216699">
<reference key="NSNextResponder" ref="448252432"/> <reference key="NSNextResponder" ref="448252432"/>
<int key="NSvFlags">256</int> <int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 171}, {265, 18}}</string> <string key="NSFrame">{{15, 194}, {313, 18}}</string>
<reference key="NSSuperview" ref="448252432"/> <reference key="NSSuperview" ref="448252432"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="118836063"> <object class="NSButtonCell" key="NSCell" id="118836063">
@@ -644,10 +645,31 @@
<int key="NSPeriodicInterval">25</int> <int key="NSPeriodicInterval">25</int>
</object> </object>
</object> </object>
<object class="NSButton" id="727223254">
<reference key="NSNextResponder" ref="448252432"/>
<int key="NSvFlags">256</int>
<string key="NSFrame">{{15, 174}, {313, 18}}</string>
<reference key="NSSuperview" ref="448252432"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="236967908">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">0</int>
<string key="NSContents">Debug mode (restart required)</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSControlView" ref="727223254"/>
<int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int>
<reference key="NSAlternateImage" ref="589920880"/>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
<int key="NSPeriodicDelay">200</int>
<int key="NSPeriodicInterval">25</int>
</object>
</object>
<object class="NSTextField" id="962804407"> <object class="NSTextField" id="962804407">
<reference key="NSNextResponder" ref="448252432"/> <reference key="NSNextResponder" ref="448252432"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{14, 148}, {315, 17}}</string> <string key="NSFrame">{{14, 151}, {315, 17}}</string>
<reference key="NSSuperview" ref="448252432"/> <reference key="NSSuperview" ref="448252432"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="111092399"> <object class="NSTextFieldCell" key="NSCell" id="111092399">
@@ -663,7 +685,7 @@
<object class="NSTextField" id="873032174"> <object class="NSTextField" id="873032174">
<reference key="NSNextResponder" ref="448252432"/> <reference key="NSNextResponder" ref="448252432"/>
<int key="NSvFlags">266</int> <int key="NSvFlags">266</int>
<string key="NSFrame">{{17, 118}, {309, 22}}</string> <string key="NSFrame">{{17, 121}, {309, 22}}</string>
<reference key="NSSuperview" ref="448252432"/> <reference key="NSSuperview" ref="448252432"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="249250691"> <object class="NSTextFieldCell" key="NSCell" id="249250691">
@@ -680,7 +702,7 @@
<object class="NSTextField" id="511043844"> <object class="NSTextField" id="511043844">
<reference key="NSNextResponder" ref="448252432"/> <reference key="NSNextResponder" ref="448252432"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{14, 97}, {85, 13}}</string> <string key="NSFrame">{{14, 100}, {315, 13}}</string>
<reference key="NSSuperview" ref="448252432"/> <reference key="NSSuperview" ref="448252432"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="669919489"> <object class="NSTextFieldCell" key="NSCell" id="669919489">
@@ -696,7 +718,7 @@
<object class="NSPopUpButton" id="857082145"> <object class="NSPopUpButton" id="857082145">
<reference key="NSNextResponder" ref="448252432"/> <reference key="NSNextResponder" ref="448252432"/>
<int key="NSvFlags">292</int> <int key="NSvFlags">292</int>
<string key="NSFrame">{{101, 86}, {216, 26}}</string> <string key="NSFrame">{{14, 68}, {234, 26}}</string>
<reference key="NSSuperview" ref="448252432"/> <reference key="NSSuperview" ref="448252432"/>
<bool key="NSEnabled">YES</bool> <bool key="NSEnabled">YES</bool>
<object class="NSPopUpButtonCell" key="NSCell" id="307074513"> <object class="NSPopUpButtonCell" key="NSCell" id="307074513">
@@ -764,7 +786,7 @@
</object> </object>
</object> </object>
</object> </object>
<string key="NSFrame">{{10, 33}, {343, 210}}</string> <string key="NSFrame">{{10, 33}, {343, 233}}</string>
</object> </object>
<string key="NSLabel">Advanced</string> <string key="NSLabel">Advanced</string>
<reference key="NSColor" ref="623994344"/> <reference key="NSColor" ref="623994344"/>
@@ -782,7 +804,7 @@
</object> </object>
</object> </object>
</object> </object>
<string key="NSFrameSize">{389, 302}</string> <string key="NSFrameSize">{389, 325}</string>
<reference key="NSSuperview"/> <reference key="NSSuperview"/>
</object> </object>
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string> <string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
@@ -1105,6 +1127,22 @@
</object> </object>
<int key="connectionID">144</int> <int key="connectionID">144</int>
</object> </object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">value: values.DebugMode</string>
<reference key="source" ref="727223254"/>
<reference key="destination" ref="75941798"/>
<object class="NSNibBindingConnector" key="connector">
<reference key="NSSource" ref="727223254"/>
<reference key="NSDestination" ref="75941798"/>
<string key="NSLabel">value: values.DebugMode</string>
<string key="NSBinding">value</string>
<string key="NSKeyPath">values.DebugMode</string>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">148</int>
</object>
</object> </object>
<object class="IBMutableOrderedSet" key="objectRecords"> <object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects"> <object class="NSArray" key="orderedObjects">
@@ -1208,6 +1246,7 @@
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="724127338"/> <reference ref="724127338"/>
<reference ref="647216699"/> <reference ref="647216699"/>
<reference ref="727223254"/>
<reference ref="962804407"/> <reference ref="962804407"/>
<reference ref="873032174"/> <reference ref="873032174"/>
<reference ref="511043844"/> <reference ref="511043844"/>
@@ -1229,12 +1268,12 @@
<reference ref="1008577648"/> <reference ref="1008577648"/>
<reference ref="950195532"/> <reference ref="950195532"/>
<reference ref="111002126"/> <reference ref="111002126"/>
<reference ref="551239185"/>
<reference ref="208488736"/>
<reference ref="427690895"/> <reference ref="427690895"/>
<reference ref="262539816"/>
<reference ref="208488736"/>
<reference ref="880304924"/> <reference ref="880304924"/>
<reference ref="1051684239"/> <reference ref="1051684239"/>
<reference ref="262539816"/> <reference ref="551239185"/>
</object> </object>
<reference key="parent" ref="562140942"/> <reference key="parent" ref="562140942"/>
</object> </object>
@@ -1604,6 +1643,20 @@
<reference key="object" ref="118836063"/> <reference key="object" ref="118836063"/>
<reference key="parent" ref="647216699"/> <reference key="parent" ref="647216699"/>
</object> </object>
<object class="IBObjectRecord">
<int key="objectID">145</int>
<reference key="object" ref="727223254"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="236967908"/>
</object>
<reference key="parent" ref="448252432"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">146</int>
<reference key="object" ref="236967908"/>
<reference key="parent" ref="727223254"/>
</object>
</object> </object>
</object> </object>
<object class="NSMutableDictionary" key="flattenedProperties"> <object class="NSMutableDictionary" key="flattenedProperties">
@@ -1621,13 +1674,20 @@
<string>128.ImportedFromIB2</string> <string>128.ImportedFromIB2</string>
<string>129.IBPluginDependency</string> <string>129.IBPluginDependency</string>
<string>133.IBPluginDependency</string> <string>133.IBPluginDependency</string>
<string>133.IBViewBoundsToFrameTransform</string>
<string>133.ImportedFromIB2</string> <string>133.ImportedFromIB2</string>
<string>134.IBPluginDependency</string> <string>134.IBPluginDependency</string>
<string>138.IBPluginDependency</string> <string>138.IBPluginDependency</string>
<string>138.IBViewBoundsToFrameTransform</string>
<string>139.IBPluginDependency</string> <string>139.IBPluginDependency</string>
<string>141.IBPluginDependency</string> <string>141.IBPluginDependency</string>
<string>141.IBViewBoundsToFrameTransform</string>
<string>141.ImportedFromIB2</string> <string>141.ImportedFromIB2</string>
<string>142.IBPluginDependency</string> <string>142.IBPluginDependency</string>
<string>145.IBPluginDependency</string>
<string>145.IBViewBoundsToFrameTransform</string>
<string>145.ImportedFromIB2</string>
<string>146.IBPluginDependency</string>
<string>51.IBPluginDependency</string> <string>51.IBPluginDependency</string>
<string>51.ImportedFromIB2</string> <string>51.ImportedFromIB2</string>
<string>52.IBEditorWindowLastContentRect</string> <string>52.IBEditorWindowLastContentRect</string>
@@ -1639,22 +1699,29 @@
<string>53.IBPluginDependency</string> <string>53.IBPluginDependency</string>
<string>53.ImportedFromIB2</string> <string>53.ImportedFromIB2</string>
<string>54.IBPluginDependency</string> <string>54.IBPluginDependency</string>
<string>54.IBViewBoundsToFrameTransform</string>
<string>54.ImportedFromIB2</string> <string>54.ImportedFromIB2</string>
<string>55.IBPluginDependency</string> <string>55.IBPluginDependency</string>
<string>55.IBViewBoundsToFrameTransform</string>
<string>55.ImportedFromIB2</string> <string>55.ImportedFromIB2</string>
<string>56.IBPluginDependency</string> <string>56.IBPluginDependency</string>
<string>56.ImportedFromIB2</string> <string>56.ImportedFromIB2</string>
<string>57.IBPluginDependency</string> <string>57.IBPluginDependency</string>
<string>57.IBViewBoundsToFrameTransform</string>
<string>57.ImportedFromIB2</string> <string>57.ImportedFromIB2</string>
<string>59.IBPluginDependency</string> <string>59.IBPluginDependency</string>
<string>59.IBViewBoundsToFrameTransform</string>
<string>59.ImportedFromIB2</string> <string>59.ImportedFromIB2</string>
<string>60.IBPluginDependency</string> <string>60.IBPluginDependency</string>
<string>60.IBViewBoundsToFrameTransform</string>
<string>60.ImportedFromIB2</string> <string>60.ImportedFromIB2</string>
<string>61.IBPluginDependency</string> <string>61.IBPluginDependency</string>
<string>61.IBViewBoundsToFrameTransform</string>
<string>61.ImportedFromIB2</string> <string>61.ImportedFromIB2</string>
<string>62.IBPluginDependency</string> <string>62.IBPluginDependency</string>
<string>62.ImportedFromIB2</string> <string>62.ImportedFromIB2</string>
<string>63.IBPluginDependency</string> <string>63.IBPluginDependency</string>
<string>63.IBViewBoundsToFrameTransform</string>
<string>63.ImportedFromIB2</string> <string>63.ImportedFromIB2</string>
<string>64.IBPluginDependency</string> <string>64.IBPluginDependency</string>
<string>64.ImportedFromIB2</string> <string>64.ImportedFromIB2</string>
@@ -1695,6 +1762,7 @@
<string>87.IBPluginDependency</string> <string>87.IBPluginDependency</string>
<string>88.IBPluginDependency</string> <string>88.IBPluginDependency</string>
<string>89.IBPluginDependency</string> <string>89.IBPluginDependency</string>
<string>90.IBEditorWindowLastContentRect</string>
<string>90.IBPluginDependency</string> <string>90.IBPluginDependency</string>
<string>90.ImportedFromIB2</string> <string>90.ImportedFromIB2</string>
<string>91.IBPluginDependency</string> <string>91.IBPluginDependency</string>
@@ -1724,40 +1792,76 @@
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBYAAAwyYAAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBiAAAww0AAA</bytes>
</object>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBcAAAw1IAAA</bytes>
</object>
<boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBoAAAw00AAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
<string>{{88, 543}, {389, 302}}</string> <string>{{88, 520}, {389, 325}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{88, 543}, {389, 302}}</string> <string>{{88, 520}, {389, 325}}</string>
<boolean value="YES"/> <boolean value="YES"/>
<boolean value="YES"/> <boolean value="YES"/>
<string>{213, 107}</string> <string>{213, 107}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABDcAAAwqIAAA</bytes>
</object>
<boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABCUAAAwoAAAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBcAAAwnQAAA</bytes>
</object>
<boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBcAAAwhAAAA</bytes>
</object>
<boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBYAAAwrgAAA</bytes>
</object>
<boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBYAAAwt4AAA</bytes>
</object>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <object class="NSAffineTransform">
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <bytes key="NSTransformStruct">P4AAAL+AAABDYwAAwigAAA</bytes>
<boolean value="YES"/> </object>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
@@ -1798,6 +1902,7 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{114, 624}, {234, 63}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -1831,7 +1936,7 @@
</object> </object>
</object> </object>
<nil key="sourceID"/> <nil key="sourceID"/>
<int key="maxID">144</int> <int key="maxID">148</int>
</object> </object>
<object class="IBClassDescriber" key="IBDocument.Classes"> <object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions"> <object class="NSMutableArray" key="referencedPartialClassDescriptions">

View File

@@ -0,0 +1,75 @@
/* Class = "NSWindow"; title = "dupeGuru Preferences"; ObjectID = "52"; */
"52.title" = "Préférences de dupeGuru";
/* Class = "NSTextFieldCell"; title = "More results"; ObjectID = "74"; */
"74.title" = "+ de doubles";
/* Class = "NSTextFieldCell"; title = "Fewer results"; ObjectID = "75"; */
"75.title" = "- de doubles";
/* Class = "NSTextFieldCell"; title = "Filter hardness:"; ObjectID = "76"; */
"76.title" = "Seuil du filtre:";
/* Class = "NSTextFieldCell"; title = "Scan type:"; ObjectID = "77"; */
"77.title" = "Type de scan:";
/* Class = "NSMenuItem"; title = "Content"; ObjectID = "80"; */
"80.title" = "Contenu";
/* Class = "NSMenuItem"; title = "Filename"; ObjectID = "81"; */
"81.title" = "Nom de fichier";
/* Class = "NSButtonCell"; title = "Word weighting"; ObjectID = "82"; */
"82.title" = "Proportionalité des mots";
/* Class = "NSButtonCell"; title = "Can mix file kind"; ObjectID = "83"; */
"83.title" = "Comparer les fichiers de différents types";
/* Class = "NSButtonCell"; title = "Reset to Defaults"; ObjectID = "86"; */
"86.title" = "Options par défaut";
/* Class = "NSButtonCell"; title = "Match similar words"; ObjectID = "87"; */
"87.title" = "Comparer les mots similaires";
/* Class = "NSTextFieldCell"; title = "Copy and Move:"; ObjectID = "88"; */
"88.title" = "Déplacements de fichiers:";
/* Class = "NSMenuItem"; title = "Recreate relative path"; ObjectID = "91"; */
"91.title" = "Re-créer chemins relatifs";
/* Class = "NSMenuItem"; title = "Recreate absolute path"; ObjectID = "92"; */
"92.title" = "Re-créer chemins absolus";
/* Class = "NSMenuItem"; title = "Right in destination"; ObjectID = "93"; */
"93.title" = "Directement à la destination";
/* Class = "NSButtonCell"; title = "Automatically check for updates"; ObjectID = "94"; */
"94.title" = "Vérifier automatiquement les mises à jour";
/* Class = "NSButtonCell"; title = "Remove empty folders on delete or move"; ObjectID = "96"; */
"96.title" = "Effacer les dossiers vides après un déplacement";
/* Class = "NSButtonCell"; title = "Ignore files smaller than"; ObjectID = "97"; */
"97.title" = "Ignorer les fichiers plus petits que:";
/* Class = "NSTextFieldCell"; title = "KB"; ObjectID = "100"; */
"100.title" = "KB";
/* Class = "NSTabViewItem"; label = "Basic"; ObjectID = "124"; */
"124.label" = "Simple";
/* Class = "NSTabViewItem"; label = "Advanced"; ObjectID = "125"; */
"125.label" = "Avancé";
/* Class = "NSButtonCell"; title = "Use regular expressions when filtering"; ObjectID = "129"; */
"129.title" = "Utiliser les expressions régulières pour les filtres";
/* Class = "NSTextFieldCell"; title = "Custom command (arguments: %d for dupe, %r for ref):"; ObjectID = "134"; */
"134.title" = "Commande perso. (arguments: %d pour doublon, %r pour réf):";
/* Class = "NSButtonCell"; title = "Ignore duplicates hardlinking to the same file"; ObjectID = "142"; */
"142.title" = "Ignorer doublons avec hardlink vers le même fichier";
/* Class = "NSButtonCell"; title = "Debug mode (restart required)"; ObjectID = "146"; */
"146.title" = "Mode de déboguage (redémarrage requis)";

File diff suppressed because it is too large Load Diff

View File

@@ -9,8 +9,7 @@
import sys import sys
from optparse import OptionParser from optparse import OptionParser
import json
import yaml
def main(edition, ui, dev): def main(edition, ui, dev):
if edition not in ('se', 'me', 'pe'): if edition not in ('se', 'me', 'pe'):
@@ -24,7 +23,7 @@ def main(edition, ui, dev):
'ui': ui, 'ui': ui,
'dev': dev, 'dev': dev,
} }
yaml.dump(conf, open('conf.yaml', 'w')) json.dump(conf, open('conf.json', 'w'))
if __name__ == '__main__': if __name__ == '__main__':
usage = "usage: %prog [options]" usage = "usage: %prog [options]"

View File

@@ -13,12 +13,13 @@ import subprocess
import re import re
from send2trash import send2trash from send2trash import send2trash
from hscommon import io
from hscommon.reg import RegistrableApplication from hscommon.reg import RegistrableApplication
from hscommon.notify import Broadcaster from hscommon.notify import Broadcaster
from hsutil import io, files from hscommon.path import Path
from hsutil.path import Path from hscommon.conflict import smart_move, smart_copy
from hsutil.misc import flatten, first from hscommon.util import delete_if_empty, first, escape, nonone
from hsutil.str import escape from hscommon.trans import tr
from . import directories, results, scanner, export, fs from . import directories, results, scanner, export, fs
@@ -28,13 +29,22 @@ JOB_MOVE = 'job_move'
JOB_COPY = 'job_copy' JOB_COPY = 'job_copy'
JOB_DELETE = 'job_delete' JOB_DELETE = 'job_delete'
HAD_FIRST_LAUNCH_PREFERENCE = 'HadFirstLaunch'
DEBUG_MODE_PREFERENCE = 'DebugMode'
class NoScannableFileError(Exception): class NoScannableFileError(Exception):
pass pass
class DupeGuru(RegistrableApplication, Broadcaster): class DupeGuru(RegistrableApplication, Broadcaster):
def __init__(self, data_module, appdata): def __init__(self, data_module, appdata):
if self.get_default(DEBUG_MODE_PREFERENCE, False):
logging.getLogger().setLevel(logging.DEBUG)
logging.debug("Debug mode enabled")
RegistrableApplication.__init__(self, appid=1) RegistrableApplication.__init__(self, appid=1)
Broadcaster.__init__(self) Broadcaster.__init__(self)
self.is_first_run = not self.get_default(HAD_FIRST_LAUNCH_PREFERENCE, False)
if self.is_first_run:
self.set_default(HAD_FIRST_LAUNCH_PREFERENCE, True)
self.appdata = appdata self.appdata = appdata
if not op.exists(self.appdata): if not op.exists(self.appdata):
os.makedirs(self.appdata) os.makedirs(self.appdata)
@@ -49,6 +59,7 @@ class DupeGuru(RegistrableApplication, Broadcaster):
} }
self.selected_dupes = [] self.selected_dupes = []
#--- Private
def _do_delete(self, j, replace_with_hardlinks): def _do_delete(self, j, replace_with_hardlinks):
def op(dupe): def op(dupe):
j.add_progress() j.add_progress()
@@ -67,11 +78,6 @@ class DupeGuru(RegistrableApplication, Broadcaster):
os.link(str(ref.path), str(dupe.path)) os.link(str(ref.path), str(dupe.path))
self.clean_empty_dirs(dupe.path[:-1]) self.clean_empty_dirs(dupe.path[:-1])
def _do_load(self, j):
self.directories.load_from_file(op.join(self.appdata, 'last_directories.xml'))
self.notify('directories_changed')
self.results.load_from_xml(op.join(self.appdata, 'last_results.xml'), self._get_file, j)
def _get_display_info(self, dupe, group, delta=False): def _get_display_info(self, dupe, group, delta=False):
if (dupe is None) or (group is None): if (dupe is None) or (group is None):
return ['---'] * len(self.data.COLUMNS) return ['---'] * len(self.data.COLUMNS)
@@ -113,7 +119,11 @@ class DupeGuru(RegistrableApplication, Broadcaster):
seen_inodes = set() seen_inodes = set()
result = [] result = []
for file in files: for file in files:
inode = io.stat(file.path).st_ino try:
inode = io.stat(file.path).st_ino
except OSError:
# The file was probably deleted or something
continue
if inode not in seen_inodes: if inode not in seen_inodes:
seen_inodes.add(inode) seen_inodes.add(inode)
result.append(file) result.append(file)
@@ -129,6 +139,13 @@ class DupeGuru(RegistrableApplication, Broadcaster):
# func(j, *args) # func(j, *args)
raise NotImplementedError() raise NotImplementedError()
def _get_default(self, key_name, fallback_value=None):
raise NotImplementedError()
def _set_default(self, key_name, value):
raise NotImplementedError()
#--- Public
def add_directory(self, d): def add_directory(self, d):
try: try:
self.directories.add_path(Path(d)) self.directories.add_path(Path(d))
@@ -151,14 +168,14 @@ class DupeGuru(RegistrableApplication, Broadcaster):
def apply_filter(self, filter): def apply_filter(self, filter):
self.results.apply_filter(None) self.results.apply_filter(None)
if self.options['escape_filter_regexp']: if self.options['escape_filter_regexp']:
filter = escape(filter, '()[]\\.|+?^') filter = escape(filter, set('()[]\\.|+?^'))
filter = escape(filter, '*', '.') filter = escape(filter, '*', '.')
self.results.apply_filter(filter) self.results.apply_filter(filter)
self.notify('results_changed') self.notify('results_changed')
def clean_empty_dirs(self, path): def clean_empty_dirs(self, path):
if self.options['clean_empty_dirs']: if self.options['clean_empty_dirs']:
while files.delete_if_empty(path, ['.DS_Store']): while delete_if_empty(path, ['.DS_Store']):
path = path[:-1] path = path[:-1]
def copy_or_move(self, dupe, copy, destination, dest_type): def copy_or_move(self, dupe, copy, destination, dest_type):
@@ -180,9 +197,9 @@ class DupeGuru(RegistrableApplication, Broadcaster):
io.makedirs(dest_path) io.makedirs(dest_path)
# Raises an EnvironmentError if there's a problem # Raises an EnvironmentError if there's a problem
if copy: if copy:
files.copy(source_path, dest_path) smart_copy(source_path, dest_path)
else: else:
files.move(source_path, dest_path) smart_move(source_path, dest_path)
self.clean_empty_dirs(source_path[:-1]) self.clean_empty_dirs(source_path[:-1])
def copy_or_move_marked(self, copy, destination, recreate_path): def copy_or_move_marked(self, copy, destination, recreate_path):
@@ -204,7 +221,7 @@ class DupeGuru(RegistrableApplication, Broadcaster):
column_ids = [colid for colid in column_ids if colid.isdigit()] column_ids = [colid for colid in column_ids if colid.isdigit()]
column_ids = list(map(int, column_ids)) column_ids = list(map(int, column_ids))
column_ids.sort() column_ids.sort()
colnames = [col['display'] for i, col in enumerate(self.data.COLUMNS) if i in column_ids] colnames = [col.display for i, col in enumerate(self.data.COLUMNS) if i in column_ids]
rows = [] rows = []
for group in self.results.groups: for group in self.results.groups:
for dupe in group: for dupe in group:
@@ -240,18 +257,16 @@ class DupeGuru(RegistrableApplication, Broadcaster):
subprocess.Popen(cmd, shell=True) subprocess.Popen(cmd, shell=True)
def load(self): def load(self):
self._start_job(JOB_LOAD, self._do_load) self.directories.load_from_file(op.join(self.appdata, 'last_directories.xml'))
self.load_ignore_list() self.notify('directories_changed')
p = op.join(self.appdata, 'ignore_list.xml')
self.scanner.ignore_list.load_from_xml(p)
def load_from(self, filename): def load_from(self, filename):
def do(j): def do(j):
self.results.load_from_xml(filename, self._get_file, j) self.results.load_from_xml(filename, self._get_file, j)
self._start_job(JOB_LOAD, do) self._start_job(JOB_LOAD, do)
def load_ignore_list(self):
p = op.join(self.appdata, 'ignore_list.xml')
self.scanner.ignore_list.load_from_xml(p)
def make_selected_reference(self): def make_selected_reference(self):
dupes = self.without_ref(self.selected_dupes) dupes = self.without_ref(self.selected_dupes)
changed_groups = set() changed_groups = set()
@@ -323,23 +338,15 @@ class DupeGuru(RegistrableApplication, Broadcaster):
if not op.exists(self.appdata): if not op.exists(self.appdata):
os.makedirs(self.appdata) os.makedirs(self.appdata)
self.directories.save_to_file(op.join(self.appdata, 'last_directories.xml')) self.directories.save_to_file(op.join(self.appdata, 'last_directories.xml'))
if self.results.is_modified:
self.results.save_to_xml(op.join(self.appdata, 'last_results.xml'))
def save_as(self, filename):
self.results.save_to_xml(filename)
# It's not because we saved it here that we don't want to save it in appdata when we quit
self.results.is_modified = True
def save_ignore_list(self):
if not op.exists(self.appdata):
os.makedirs(self.appdata)
p = op.join(self.appdata, 'ignore_list.xml') p = op.join(self.appdata, 'ignore_list.xml')
self.scanner.ignore_list.save_to_xml(p) self.scanner.ignore_list.save_to_xml(p)
def save_as(self, filename):
self.results.save_to_xml(filename)
def start_scanning(self): def start_scanning(self):
def do(j): def do(j):
j.set_progress(0, 'Collecting files to scan') j.set_progress(0, tr("Collecting files to scan"))
files = list(self.directories.get_files()) files = list(self.directories.get_files())
if self.options['ignore_hardlink_matches']: if self.options['ignore_hardlink_matches']:
files = self._remove_hardlink_dupes(files) files = self._remove_hardlink_dupes(files)
@@ -349,6 +356,7 @@ class DupeGuru(RegistrableApplication, Broadcaster):
if not self.directories.has_any_file(): if not self.directories.has_any_file():
raise NoScannableFileError() raise NoScannableFileError()
self.results.groups = [] self.results.groups = []
self.notify('results_changed')
self._start_job(JOB_SCAN, do) self._start_job(JOB_SCAN, do)
def toggle_selected_mark_state(self): def toggle_selected_mark_state(self):
@@ -359,11 +367,24 @@ class DupeGuru(RegistrableApplication, Broadcaster):
def without_ref(self, dupes): def without_ref(self, dupes):
return [dupe for dupe in dupes if self.results.get_group_of_duplicate(dupe).ref is not dupe] return [dupe for dupe in dupes if self.results.get_group_of_duplicate(dupe).ref is not dupe]
def get_default(self, key, fallback_value=None):
result = nonone(self._get_default(key), fallback_value)
if fallback_value is not None and not isinstance(result, type(fallback_value)):
# we don't want to end up with garbage values from the prefs
try:
result = type(fallback_value)(result)
except Exception:
result = fallback_value
return result
def set_default(self, key, value):
self._set_default(key, value)
#--- Properties #--- Properties
@property @property
def stat_line(self): def stat_line(self):
result = self.results.stat_line result = self.results.stat_line
if self.scanner.discarded_file_count: if self.scanner.discarded_file_count:
result = '%s (%d discarded)' % (result, self.scanner.discarded_file_count) result = tr("%s (%d discarded)") % (result, self.scanner.discarded_file_count)
return result return result

View File

@@ -9,27 +9,27 @@
import logging import logging
import os.path as op import os.path as op
from hscommon import cocoa, job from jobprogress import job
from hscommon.cocoa import install_exception_hook from hscommon import cocoa
from hscommon.cocoa import install_exception_hook, pythonify
from hscommon.cocoa.objcmin import (NSNotificationCenter, NSUserDefaults, from hscommon.cocoa.objcmin import (NSNotificationCenter, NSUserDefaults,
NSSearchPathForDirectoriesInDomains, NSApplicationSupportDirectory, NSUserDomainMask, NSSearchPathForDirectoriesInDomains, NSApplicationSupportDirectory, NSUserDomainMask,
NSWorkspace) NSWorkspace)
from hscommon.trans import tr
from . import app from . import app
JOBID2TITLE = { JOBID2TITLE = {
app.JOB_SCAN: "Scanning for duplicates", app.JOB_SCAN: tr("Scanning for duplicates"),
app.JOB_LOAD: "Loading", app.JOB_LOAD: tr("Loading"),
app.JOB_MOVE: "Moving", app.JOB_MOVE: tr("Moving"),
app.JOB_COPY: "Copying", app.JOB_COPY: tr("Copying"),
app.JOB_DELETE: "Sending to Trash", app.JOB_DELETE: tr("Sending to Trash"),
} }
class DupeGuru(app.DupeGuru): class DupeGuru(app.DupeGuru):
def __init__(self, data_module, appdata_subdir): def __init__(self, data_module, appdata_subdir):
LOGGING_LEVEL = logging.DEBUG if NSUserDefaults.standardUserDefaults().boolForKey_('debug') else logging.WARNING logging.basicConfig(level=logging.WARNING, format='%(levelname)s %(message)s')
logging.basicConfig(level=LOGGING_LEVEL, format='%(levelname)s %(message)s')
logging.debug('started in debug mode')
install_exception_hook() install_exception_hook()
appsupport = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, True)[0] appsupport = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, True)[0]
appdata = op.join(appsupport, appdata_subdir) appdata = op.join(appsupport, appdata_subdir)
@@ -56,7 +56,15 @@ class DupeGuru(app.DupeGuru):
ud = {'desc': JOBID2TITLE[jobid], 'jobid':jobid} ud = {'desc': JOBID2TITLE[jobid], 'jobid':jobid}
NSNotificationCenter.defaultCenter().postNotificationName_object_userInfo_('JobStarted', self, ud) NSNotificationCenter.defaultCenter().postNotificationName_object_userInfo_('JobStarted', self, ud)
#---Public def _get_default(self, key_name):
raw = NSUserDefaults.standardUserDefaults().objectForKey_(key_name)
result = pythonify(raw)
return result
def _set_default(self, key_name, value):
NSUserDefaults.standardUserDefaults().setObject_forKey_(value, key_name)
#--- Public
def start_scanning(self): def start_scanning(self):
self._select_dupes([]) self._select_dupes([])
try: try:

View File

@@ -18,10 +18,6 @@ from .gui.problem_table import ProblemTable
from .gui.result_table import ResultTable from .gui.result_table import ResultTable
from .gui.stats_label import StatsLabel from .gui.stats_label import StatsLabel
# Fix py2app's problems on relative imports
from core import app, app_cocoa, data, directories, engine, export, ignore, results, fs, scanner
from hsutil import conflict
class PyDupeGuruBase(PyFairware): class PyDupeGuruBase(PyFairware):
#---Directories #---Directories
def addDirectory_(self, directory): def addDirectory_(self, directory):
@@ -40,10 +36,7 @@ class PyDupeGuruBase(PyFairware):
def exportToXHTMLwithColumns_(self, column_ids): def exportToXHTMLwithColumns_(self, column_ids):
return self.py.export_to_xhtml(column_ids) return self.py.export_to_xhtml(column_ids)
def loadIgnoreList(self): def loadSession(self):
self.py.load_ignore_list()
def loadResults(self):
self.py.load() self.py.load()
def loadResultsFrom_(self, filename): def loadResultsFrom_(self, filename):
@@ -64,10 +57,7 @@ class PyDupeGuruBase(PyFairware):
def toggleSelectedMark(self): def toggleSelectedMark(self):
self.py.toggle_selected_mark_state() self.py.toggle_selected_mark_state()
def saveIgnoreList(self): def saveSession(self):
self.py.save_ignore_list()
def saveResults(self):
self.py.save() self.py.save()
def saveResultsAs_(self, filename): def saveResultsAs_(self, filename):
@@ -118,6 +108,13 @@ class PyDupeGuruBase(PyFairware):
def scanWasProblematic(self): def scanWasProblematic(self):
return bool(self.py.results.problems) return bool(self.py.results.problems)
@signature('i@:')
def resultsAreModified(self):
return self.py.results.is_modified
def deltaColumns(self):
return list(self.py.data.DELTA_COLUMNS)
#---Properties #---Properties
@signature('v@:c') @signature('v@:c')
def setMixFileKind_(self, mix_file_kind): def setMixFileKind_(self, mix_file_kind):

View File

@@ -6,16 +6,20 @@
# 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 hsutil.str import format_time, FT_DECIMAL, format_size from collections import namedtuple
from hscommon.util import format_time_decimal, format_size
import time import time
Column = namedtuple('Column', 'attr display')
def format_path(p): def format_path(p):
return str(p[:-1]) return str(p[:-1])
def format_timestamp(t, delta): def format_timestamp(t, delta):
if delta: if delta:
return format_time(t, FT_DECIMAL) return format_time_decimal(t)
else: else:
if t > 0: if t > 0:
return time.strftime('%Y/%m/%d %H:%M:%S', time.localtime(t)) return time.strftime('%Y/%m/%d %H:%M:%S', time.localtime(t))

View File

@@ -7,10 +7,11 @@
# http://www.hardcoded.net/licenses/bsd_license # http://www.hardcoded.net/licenses/bsd_license
from xml.etree import ElementTree as ET from xml.etree import ElementTree as ET
import logging
from hsutil import io from hscommon import io
from hsutil.files import FileOrPath from hscommon.path import Path
from hsutil.path import Path from hscommon.util import FileOrPath
from . import fs from . import fs
@@ -24,7 +25,7 @@ class AlreadyThereError(Exception):
class InvalidPathError(Exception): class InvalidPathError(Exception):
"""The path being added is invalid""" """The path being added is invalid"""
class Directories(object): class Directories:
#---Override #---Override
def __init__(self, fileclasses=[fs.File]): def __init__(self, fileclasses=[fs.File]):
self._dirs = [] self._dirs = []
@@ -63,7 +64,9 @@ class Directories(object):
try: try:
filepaths = set() filepaths = set()
if state != STATE_EXCLUDED: if state != STATE_EXCLUDED:
for file in fs.get_files(from_path, fileclasses=self.fileclasses): found_files = fs.get_files(from_path, fileclasses=self.fileclasses)
logging.debug("Collected {} files in folder {}".format(len(found_files), str(from_path)))
for file in found_files:
file.is_ref = state == STATE_REFERENCE file.is_ref = state == STATE_REFERENCE
filepaths.add(file.path) filepaths.add(file.path)
yield file yield file

View File

@@ -6,7 +6,6 @@
# 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
import difflib import difflib
import itertools import itertools
import logging import logging
@@ -14,9 +13,9 @@ import string
from collections import defaultdict, namedtuple from collections import defaultdict, namedtuple
from unicodedata import normalize from unicodedata import normalize
from hsutil.misc import flatten from hscommon.util import flatten, multi_replace
from hsutil.str import multi_replace from hscommon.trans import tr
from hscommon import job from jobprogress import job
(WEIGHT_WORDS, (WEIGHT_WORDS,
MATCH_SIMILAR_WORDS, MATCH_SIMILAR_WORDS,
@@ -25,8 +24,8 @@ NO_FIELD_ORDER) = range(3)
JOB_REFRESH_RATE = 100 JOB_REFRESH_RATE = 100
def getwords(s): def getwords(s):
if isinstance(s, str): # We decompose the string so that ascii letters with accents can be part of the word.
s = normalize('NFD', s) s = normalize('NFD', s)
s = multi_replace(s, "-_&+():;\\[]{}.,<>/?~!@#$*", ' ').lower() s = multi_replace(s, "-_&+():;\\[]{}.,<>/?~!@#$*", ' ').lower()
s = ''.join(c for c in s if c in string.ascii_letters + string.digits + string.whitespace) s = ''.join(c for c in s if c in string.ascii_letters + string.digits + string.whitespace)
return [_f for _f in s.split(' ') if _f] # remove empty elements return [_f for _f in s.split(' ') if _f] # remove empty elements
@@ -176,7 +175,7 @@ def getmatches(objects, min_match_percentage=0, match_similar_words=False, weigh
match_flags.append(MATCH_SIMILAR_WORDS) match_flags.append(MATCH_SIMILAR_WORDS)
if no_field_order: if no_field_order:
match_flags.append(NO_FIELD_ORDER) match_flags.append(NO_FIELD_ORDER)
j.start_job(len(word_dict), '0 matches found') j.start_job(len(word_dict), tr("0 matches found"))
compared = defaultdict(set) compared = defaultdict(set)
result = [] result = []
try: try:
@@ -194,7 +193,7 @@ def getmatches(objects, min_match_percentage=0, match_similar_words=False, weigh
result.append(m) result.append(m)
if len(result) >= LIMIT: if len(result) >= LIMIT:
return result return result
j.add_progress(desc='%d matches found' % len(result)) j.add_progress(desc=tr("%d matches found") % len(result))
except MemoryError: except MemoryError:
# This is the place where the memory usage is at its peak during the scan. # This is the place where the memory usage is at its peak during the scan.
# Just continue the process with an incomplete list of matches. # Just continue the process with an incomplete list of matches.
@@ -206,14 +205,14 @@ def getmatches(objects, min_match_percentage=0, match_similar_words=False, weigh
def getmatches_by_contents(files, sizeattr='size', partial=False, j=job.nulljob): def getmatches_by_contents(files, sizeattr='size', partial=False, j=job.nulljob):
j = j.start_subjob([2, 8]) j = j.start_subjob([2, 8])
size2files = defaultdict(set) size2files = defaultdict(set)
for file in j.iter_with_progress(files, 'Read size of %d/%d files'): for file in j.iter_with_progress(files, tr("Read size of %d/%d files")):
filesize = getattr(file, sizeattr) filesize = getattr(file, sizeattr)
if filesize: if filesize:
size2files[filesize].add(file) size2files[filesize].add(file)
possible_matches = [files for files in size2files.values() if len(files) > 1] possible_matches = [files for files in size2files.values() if len(files) > 1]
del size2files del size2files
result = [] result = []
j.start_job(len(possible_matches), '0 matches found') j.start_job(len(possible_matches), tr("0 matches found"))
for group in possible_matches: for group in possible_matches:
for first, second in itertools.combinations(group, 2): for first, second in itertools.combinations(group, 2):
if first.is_ref and second.is_ref: if first.is_ref and second.is_ref:
@@ -221,7 +220,7 @@ def getmatches_by_contents(files, sizeattr='size', partial=False, j=job.nulljob)
if first.md5partial == second.md5partial: if first.md5partial == second.md5partial:
if partial or first.md5 == second.md5: if partial or first.md5 == second.md5:
result.append(Match(first, second, 100)) result.append(Match(first, second, 100))
j.add_progress(desc='%d matches found' % len(result)) j.add_progress(desc=tr("%d matches found") % len(result))
return result return result
class Group(object): class Group(object):
@@ -350,7 +349,7 @@ def get_groups(matches, j=job.nulljob):
dupe2group = {} dupe2group = {}
groups = [] groups = []
try: try:
for match in j.iter_with_progress(matches, 'Grouped %d/%d matches', JOB_REFRESH_RATE): for match in j.iter_with_progress(matches, tr("Grouped %d/%d matches"), JOB_REFRESH_RATE):
first, second, _ = match first, second, _ = match
first_group = dupe2group.get(first) first_group = dupe2group.get(first)
second_group = dupe2group.get(second) second_group = dupe2group.get(second)

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2009-10-22 # Created On: 2009-10-22
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
@@ -12,14 +11,11 @@
# resulting needless complexity and memory usage. It's been a while since I wanted to do that fork, # resulting needless complexity and memory usage. It's been a while since I wanted to do that fork,
# and I'm doing it now. # and I'm doing it now.
import hashlib import hashlib
import logging import logging
from hsutil import io from hscommon import io
from hsutil.misc import nonone, flatten from hscommon.util import nonone, flatten, get_file_ext
from hsutil.str import get_file_ext
class FSError(Exception): class FSError(Exception):
cls_message = "An error has occured on '{name}' in '{parent}'" cls_message = "An error has occured on '{name}' in '{parent}'"
@@ -52,7 +48,7 @@ class OperationError(FSError):
operation shows that it didn't work.""" operation shows that it didn't work."""
cls_message = "Operation on '{name}' failed." cls_message = "Operation on '{name}' failed."
class File(object): class File:
INITIAL_INFO = { INITIAL_INFO = {
'size': 0, 'size': 0,
'mtime': 0, 'mtime': 0,

View File

@@ -31,7 +31,7 @@ class DetailsPanel(GUIObject):
# we don't want the two sides of the table to display the stats for the same file # we don't want the two sides of the table to display the stats for the same file
ref = group.ref if group is not None and group.ref is not dupe else None ref = group.ref if group is not None and group.ref is not dupe else None
l2 = self.app._get_display_info(ref, group, False) l2 = self.app._get_display_info(ref, group, False)
names = [c['display'] for c in self.app.data.COLUMNS] names = [c.display for c in self.app.data.COLUMNS]
self._table = list(zip(names, l1, l2)) self._table = list(zip(names, l1, l2))
#--- Public #--- Public

View File

@@ -7,7 +7,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 hsgui.tree import Tree, Node from hscommon.gui.tree import Tree, Node
from ..directories import STATE_NORMAL, STATE_REFERENCE, STATE_EXCLUDED from ..directories import STATE_NORMAL, STATE_REFERENCE, STATE_EXCLUDED
from .base import GUIObject from .base import GUIObject

View File

@@ -8,7 +8,7 @@
# http://www.hardcoded.net/licenses/bsd_license # http://www.hardcoded.net/licenses/bsd_license
from hscommon.notify import Listener from hscommon.notify import Listener
from hsgui.table import GUITable, Row from hscommon.gui.table import GUITable, Row
class ProblemTable(GUITable, Listener): class ProblemTable(GUITable, Listener):
def __init__(self, view, problem_dialog): def __init__(self, view, problem_dialog):
@@ -31,7 +31,6 @@ class ProblemTable(GUITable, Listener):
#--- Event handlers #--- Event handlers
def problems_changed(self): def problems_changed(self):
self.refresh() self.refresh()
self.view.refresh()
class ProblemRow(Row): class ProblemRow(Row):

View File

@@ -9,7 +9,7 @@
from operator import attrgetter from operator import attrgetter
from hsgui.table import GUITable, Row from hscommon.gui.table import GUITable, Row
from .base import GUIObject from .base import GUIObject
@@ -87,7 +87,6 @@ class ResultTable(GUIObject, GUITable):
def _refresh_with_view(self): def _refresh_with_view(self):
self.refresh() self.refresh()
self.view.refresh()
self.view.show_selected_row() self.view.show_selected_row()
#--- Public #--- Public
@@ -139,7 +138,6 @@ class ResultTable(GUIObject, GUITable):
return return
self._delta_values = value self._delta_values = value
self.refresh() self.refresh()
self.view.refresh()
@property @property
def selected_dupe_count(self): def selected_dupe_count(self):
@@ -156,7 +154,7 @@ class ResultTable(GUIObject, GUITable):
# What we want to to here is that instead of restoring selected *dupes* after refresh, we # What we want to to here is that instead of restoring selected *dupes* after refresh, we
# restore selected *paths*. # restore selected *paths*.
indexes = self.selected_indexes indexes = self.selected_indexes
self.refresh() self.refresh(refresh_view=False)
self.select(indexes) self.select(indexes)
self.view.refresh() self.view.refresh()

View File

@@ -8,9 +8,9 @@
from xml.etree import ElementTree as ET from xml.etree import ElementTree as ET
from hsutil.files import FileOrPath from hscommon.util import FileOrPath
class IgnoreList(object): class IgnoreList:
"""An ignore list implementation that is iterable, filterable and exportable to XML. """An ignore list implementation that is iterable, filterable and exportable to XML.
Call Ignore to add an ignore list entry, and AreIgnore to check if 2 items are in the list. Call Ignore to add an ignore list entry, and AreIgnore to check if 2 items are in the list.

View File

@@ -11,11 +11,10 @@ import re
from xml.etree import ElementTree as ET from xml.etree import ElementTree as ET
from . import engine from . import engine
from hscommon.job import nulljob from jobprogress.job import nulljob
from hscommon.markable import Markable from hscommon.markable import Markable
from hsutil.misc import flatten, nonone from hscommon.util import flatten, nonone, FileOrPath, format_size
from hsutil.str import format_size from hscommon.trans import tr
from hsutil.files import FileOrPath
class Results(Markable): class Results(Markable):
#---Override #---Override
@@ -89,14 +88,14 @@ class Results(Markable):
total_size = sum(dupe.size for dupe in self.__filtered_dupes if self.is_markable(dupe)) total_size = sum(dupe.size for dupe in self.__filtered_dupes if self.is_markable(dupe))
if self.mark_inverted: if self.mark_inverted:
marked_size = self.__total_size - marked_size marked_size = self.__total_size - marked_size
result = '%d / %d (%s / %s) duplicates marked.' % ( result = tr("%d / %d (%s / %s) duplicates marked.") % (
mark_count, mark_count,
total_count, total_count,
format_size(marked_size, 2), format_size(marked_size, 2),
format_size(total_size, 2), format_size(total_size, 2),
) )
if self.__filters: if self.__filters:
result += ' filter: %s' % ' --> '.join(self.__filters) result += tr(" filter: %s") % ' --> '.join(self.__filters)
return result return result
def __recalculate_stats(self): def __recalculate_stats(self):
@@ -116,7 +115,7 @@ class Results(Markable):
self.__group_of_duplicate[dupe] = g self.__group_of_duplicate[dupe] = g
if not hasattr(dupe, 'is_ref'): if not hasattr(dupe, 'is_ref'):
dupe.is_ref = False dupe.is_ref = False
self.is_modified = True self.is_modified = bool(self.__groups)
old_filters = nonone(self.__filters, []) old_filters = nonone(self.__filters, [])
self.apply_filter(None) self.apply_filter(None)
for filter_str in old_filters: for filter_str in old_filters:
@@ -273,7 +272,7 @@ class Results(Markable):
for group in affected_groups: for group in affected_groups:
group.discard_matches() group.discard_matches()
self.__dupes = None self.__dupes = None
self.is_modified = True self.is_modified = bool(self.__groups)
def save_to_xml(self, outfile): def save_to_xml(self, outfile):
self.apply_filter(None) self.apply_filter(None)

View File

@@ -9,10 +9,10 @@
import logging import logging
import re import re
from hscommon import job from jobprogress import job
from hsutil import io from hscommon import io
from hsutil.misc import dedupe from hscommon.util import dedupe, rem_file_ext, get_file_ext
from hsutil.str import get_file_ext, rem_file_ext from hscommon.trans import tr
from . import engine from . import engine
from .ignore import IgnoreList from .ignore import IgnoreList
@@ -37,7 +37,7 @@ def is_same_with_digit(name, refname):
end = name[len(refname):].strip() end = name[len(refname):].strip()
return RE_DIGIT_ENDING.match(end) is not None return RE_DIGIT_ENDING.match(end) is not None
class Scanner(object): class Scanner:
def __init__(self): def __init__(self):
self.ignore_list = IgnoreList() self.ignore_list = IgnoreList()
self.discarded_file_count = 0 self.discarded_file_count = 0
@@ -45,7 +45,7 @@ class Scanner(object):
def _getmatches(self, files, j): def _getmatches(self, files, j):
if self.size_threshold: if self.size_threshold:
j = j.start_subjob([2, 8]) j = j.start_subjob([2, 8])
for f in j.iter_with_progress(files, 'Read size of %d/%d files'): for f in j.iter_with_progress(files, tr("Read size of %d/%d files")):
f.size # pre-read, makes a smoother progress if read here (especially for bundles) f.size # pre-read, makes a smoother progress if read here (especially for bundles)
files = [f for f in files if f.size >= self.size_threshold] files = [f for f in files if f.size >= self.size_threshold]
if self.scan_type in (ScanType.Contents, ScanType.ContentsAudio): if self.scan_type in (ScanType.Contents, ScanType.ContentsAudio):
@@ -65,7 +65,8 @@ class Scanner(object):
ScanType.Fields: lambda f: engine.getfields(rem_file_ext(f.name)), ScanType.Fields: lambda f: engine.getfields(rem_file_ext(f.name)),
ScanType.Tag: lambda f: [engine.getwords(str(getattr(f, attrname))) for attrname in SCANNABLE_TAGS if attrname in self.scanned_tags], ScanType.Tag: lambda f: [engine.getwords(str(getattr(f, attrname))) for attrname in SCANNABLE_TAGS if attrname in self.scanned_tags],
}[self.scan_type] }[self.scan_type]
for f in j.iter_with_progress(files, 'Read metadata of %d/%d files'): for f in j.iter_with_progress(files, tr("Read metadata of %d/%d files")):
logging.debug("Reading metadata of {}".format(str(f.path)))
f.words = func(f) f.words = func(f)
return engine.getmatches(files, j=j, **kw) return engine.getmatches(files, j=j, **kw)
@@ -94,13 +95,13 @@ class Scanner(object):
logging.info('Getting matches') logging.info('Getting matches')
matches = self._getmatches(files, j) matches = self._getmatches(files, j)
logging.info('Found %d matches' % len(matches)) logging.info('Found %d matches' % len(matches))
j.set_progress(100, 'Removing false matches') j.set_progress(100, tr("Removing false matches"))
if not self.mix_file_kind: if not self.mix_file_kind:
matches = [m for m in matches if get_file_ext(m.first.name) == get_file_ext(m.second.name)] matches = [m for m in matches if get_file_ext(m.first.name) == get_file_ext(m.second.name)]
matches = [m for m in matches if io.exists(m.first.path) and io.exists(m.second.path)] matches = [m for m in matches if io.exists(m.first.path) and io.exists(m.second.path)]
if self.ignore_list: if self.ignore_list:
j = j.start_subjob(2) j = j.start_subjob(2)
iter_matches = j.iter_with_progress(matches, 'Processed %d/%d matches against the ignore list') iter_matches = j.iter_with_progress(matches, tr("Processed %d/%d matches against the ignore list"))
matches = [m for m in iter_matches matches = [m for m in iter_matches
if not self.ignore_list.AreIgnored(str(m.first.path), str(m.second.path))] if not self.ignore_list.AreIgnored(str(m.first.path), str(m.second.path))]
logging.info('Grouping matches') logging.info('Grouping matches')
@@ -109,7 +110,7 @@ class Scanner(object):
self.discarded_file_count = len(matched_files) - sum(len(g) for g in groups) self.discarded_file_count = len(matched_files) - sum(len(g) for g in groups)
groups = [g for g in groups if any(not f.is_ref for f in g)] groups = [g for g in groups if any(not f.is_ref for f in g)]
logging.info('Created %d groups' % len(groups)) logging.info('Created %d groups' % len(groups))
j.set_progress(100, 'Doing group prioritization') j.set_progress(100, tr("Doing group prioritization"))
for g in groups: for g in groups:
g.prioritize(self._key_func, self._tie_breaker) g.prioritize(self._key_func, self._tie_breaker)
return groups return groups

View File

@@ -7,15 +7,16 @@
# http://www.hardcoded.net/licenses/bsd_license # http://www.hardcoded.net/licenses/bsd_license
import os import os
import os.path as op
import logging import logging
from hsutil.testutil import eq_ from pytest import mark
from hsutil.testcase import TestCase from hscommon import io
from hsutil import io from hscommon.path import Path
from hsutil.path import Path import hscommon.conflict
from hsutil.decorators import log_calls import hscommon.util
import hsutil.files from hscommon.testutil import CallLogger, eq_, log_calls
from hscommon.job import nulljob from jobprogress.job import nulljob, Job, JobCancelled
from . import data from . import data
from .results_test import GetTestGroups from .results_test import GetTestGroups
@@ -27,86 +28,85 @@ from ..gui.result_table import ResultTable
from ..scanner import ScanType from ..scanner import ScanType
class DupeGuru(DupeGuruBase): class DupeGuru(DupeGuruBase):
JOB = nulljob
def __init__(self): def __init__(self):
DupeGuruBase.__init__(self, data, '/tmp', appid=4) DupeGuruBase.__init__(self, data, '/tmp')
def _start_job(self, jobid, func, *args): def _start_job(self, jobid, func, *args):
func(nulljob, *args) try:
func(self.JOB, *args)
except JobCancelled:
return
def _get_default(self, key_name):
return None
def _set_default(self, key_name, value):
pass
class CallLogger(object): def add_fake_files_to_directories(directories, files):
"""This is a dummy object that logs all calls made to it. directories.get_files = lambda: iter(files)
directories._dirs.append('this is just so Scan() doesnt return 3')
It is used to simulate the GUI layer.
"""
def __init__(self):
self.calls = []
def __getattr__(self, func_name):
def func(*args, **kw):
self.calls.append(func_name)
return func
def clear_calls(self):
del self.calls[:]
class TCDupeGuru(TestCase): class TestCaseDupeGuru:
cls_tested_module = app def test_apply_filter_calls_results_apply_filter(self, monkeypatch):
def test_apply_filter_calls_results_apply_filter(self): dgapp = DupeGuru()
app = DupeGuru() monkeypatch.setattr(dgapp.results, 'apply_filter', log_calls(dgapp.results.apply_filter))
self.mock(app.results, 'apply_filter', log_calls(app.results.apply_filter)) dgapp.apply_filter('foo')
app.apply_filter('foo') eq_(2, len(dgapp.results.apply_filter.calls))
self.assertEqual(2, len(app.results.apply_filter.calls)) call = dgapp.results.apply_filter.calls[0]
call = app.results.apply_filter.calls[0] assert call['filter_str'] is None
self.assert_(call['filter_str'] is None) call = dgapp.results.apply_filter.calls[1]
call = app.results.apply_filter.calls[1] eq_('foo', call['filter_str'])
self.assertEqual('foo', call['filter_str'])
def test_apply_filter_escapes_regexp(self): def test_apply_filter_escapes_regexp(self, monkeypatch):
app = DupeGuru() dgapp = DupeGuru()
self.mock(app.results, 'apply_filter', log_calls(app.results.apply_filter)) monkeypatch.setattr(dgapp.results, 'apply_filter', log_calls(dgapp.results.apply_filter))
app.apply_filter('()[]\\.|+?^abc') dgapp.apply_filter('()[]\\.|+?^abc')
call = app.results.apply_filter.calls[1] call = dgapp.results.apply_filter.calls[1]
self.assertEqual('\\(\\)\\[\\]\\\\\\.\\|\\+\\?\\^abc', call['filter_str']) eq_('\\(\\)\\[\\]\\\\\\.\\|\\+\\?\\^abc', call['filter_str'])
app.apply_filter('(*)') # In "simple mode", we want the * to behave as a wilcard dgapp.apply_filter('(*)') # In "simple mode", we want the * to behave as a wilcard
call = app.results.apply_filter.calls[3] call = dgapp.results.apply_filter.calls[3]
self.assertEqual('\(.*\)', call['filter_str']) eq_('\(.*\)', call['filter_str'])
app.options['escape_filter_regexp'] = False dgapp.options['escape_filter_regexp'] = False
app.apply_filter('(abc)') dgapp.apply_filter('(abc)')
call = app.results.apply_filter.calls[5] call = dgapp.results.apply_filter.calls[5]
self.assertEqual('(abc)', call['filter_str']) eq_('(abc)', call['filter_str'])
def test_copy_or_move(self): def test_copy_or_move(self, tmpdir, monkeypatch):
# The goal here is just to have a test for a previous blowup I had. I know my test coverage # The goal here is just to have a test for a previous blowup I had. I know my test coverage
# for this unit is pathetic. What's done is done. My approach now is to add tests for # for this unit is pathetic. What's done is done. My approach now is to add tests for
# every change I want to make. The blowup was caused by a missing import. # every change I want to make. The blowup was caused by a missing import.
p = self.tmppath() p = Path(str(tmpdir))
io.open(p + 'foo', 'w').close() io.open(p + 'foo', 'w').close()
self.mock(hsutil.files, 'copy', log_calls(lambda source_path, dest_path: None)) monkeypatch.setattr(hscommon.conflict, 'smart_copy', log_calls(lambda source_path, dest_path: None))
self.mock(os, 'makedirs', lambda path: None) # We don't want the test to create that fake directory # XXX This monkeypatch is temporary. will be fixed in a better monkeypatcher.
app = DupeGuru() monkeypatch.setattr(app, 'smart_copy', hscommon.conflict.smart_copy)
app.directories.add_path(p) monkeypatch.setattr(os, 'makedirs', lambda path: None) # We don't want the test to create that fake directory
[f] = app.directories.get_files() dgapp = DupeGuru()
app.copy_or_move(f, True, 'some_destination', 0) dgapp.directories.add_path(p)
self.assertEqual(1, len(hsutil.files.copy.calls)) [f] = dgapp.directories.get_files()
call = hsutil.files.copy.calls[0] dgapp.copy_or_move(f, True, 'some_destination', 0)
self.assertEqual('some_destination', call['dest_path']) eq_(1, len(hscommon.conflict.smart_copy.calls))
self.assertEqual(f.path, call['source_path']) call = hscommon.conflict.smart_copy.calls[0]
eq_('some_destination', call['dest_path'])
eq_(f.path, call['source_path'])
def test_copy_or_move_clean_empty_dirs(self): def test_copy_or_move_clean_empty_dirs(self, tmpdir, monkeypatch):
tmppath = Path(self.tmpdir()) tmppath = Path(str(tmpdir))
sourcepath = tmppath + 'source' sourcepath = tmppath + 'source'
io.mkdir(sourcepath) io.mkdir(sourcepath)
io.open(sourcepath + 'myfile', 'w') io.open(sourcepath + 'myfile', 'w')
app = DupeGuru() app = DupeGuru()
app.directories.add_path(tmppath) app.directories.add_path(tmppath)
[myfile] = app.directories.get_files() [myfile] = app.directories.get_files()
self.mock(app, 'clean_empty_dirs', log_calls(lambda path: None)) monkeypatch.setattr(app, 'clean_empty_dirs', log_calls(lambda path: None))
app.copy_or_move(myfile, False, tmppath + 'dest', 0) app.copy_or_move(myfile, False, tmppath + 'dest', 0)
calls = app.clean_empty_dirs.calls calls = app.clean_empty_dirs.calls
self.assertEqual(1, len(calls)) eq_(1, len(calls))
self.assertEqual(sourcepath, calls[0]['path']) eq_(sourcepath, calls[0]['path'])
def test_Scan_with_objects_evaluating_to_false(self): def test_Scan_with_objects_evaluating_to_false(self):
class FakeFile(fs.File): class FakeFile(fs.File):
@@ -119,14 +119,14 @@ class TCDupeGuru(TestCase):
f1, f2 = [FakeFile('foo') for i in range(2)] f1, f2 = [FakeFile('foo') for i in range(2)]
f1.is_ref, f2.is_ref = (False, False) f1.is_ref, f2.is_ref = (False, False)
assert not (bool(f1) and bool(f2)) assert not (bool(f1) and bool(f2))
app.directories.get_files = lambda: iter([f1, f2]) add_fake_files_to_directories(app.directories, [f1, f2])
app.directories._dirs.append('this is just so Scan() doesnt return 3')
app.start_scanning() # no exception app.start_scanning() # no exception
def test_ignore_hardlink_matches(self): @mark.skipif("not hasattr(os, 'link')")
def test_ignore_hardlink_matches(self, tmpdir):
# If the ignore_hardlink_matches option is set, don't match files hardlinking to the same # If the ignore_hardlink_matches option is set, don't match files hardlinking to the same
# inode. # inode.
tmppath = Path(self.tmpdir()) tmppath = Path(str(tmpdir))
io.open(tmppath + 'myfile', 'w').write('foo') io.open(tmppath + 'myfile', 'w').write('foo')
os.link(str(tmppath + 'myfile'), str(tmppath + 'hardlink')) os.link(str(tmppath + 'myfile'), str(tmppath + 'hardlink'))
app = DupeGuru() app = DupeGuru()
@@ -137,42 +137,46 @@ class TCDupeGuru(TestCase):
eq_(len(app.results.groups), 0) eq_(len(app.results.groups), 0)
class TCDupeGuru_clean_empty_dirs(TestCase): class TestCaseDupeGuru_clean_empty_dirs:
cls_tested_module = app def pytest_funcarg__do_setup(self, request):
def setUp(self): monkeypatch = request.getfuncargvalue('monkeypatch')
self.mock(hsutil.files, 'delete_if_empty', log_calls(lambda path, files_to_delete=[]: None)) monkeypatch.setattr(hscommon.util, 'delete_if_empty', log_calls(lambda path, files_to_delete=[]: None))
# XXX This monkeypatch is temporary. will be fixed in a better monkeypatcher.
monkeypatch.setattr(app, 'delete_if_empty', hscommon.util.delete_if_empty)
self.app = DupeGuru() self.app = DupeGuru()
def test_option_off(self): def test_option_off(self, do_setup):
self.app.clean_empty_dirs(Path('/foo/bar')) self.app.clean_empty_dirs(Path('/foo/bar'))
self.assertEqual(0, len(hsutil.files.delete_if_empty.calls)) eq_(0, len(hscommon.util.delete_if_empty.calls))
def test_option_on(self): def test_option_on(self, do_setup):
self.app.options['clean_empty_dirs'] = True self.app.options['clean_empty_dirs'] = True
self.app.clean_empty_dirs(Path('/foo/bar')) self.app.clean_empty_dirs(Path('/foo/bar'))
calls = hsutil.files.delete_if_empty.calls calls = hscommon.util.delete_if_empty.calls
self.assertEqual(1, len(calls)) eq_(1, len(calls))
self.assertEqual(Path('/foo/bar'), calls[0]['path']) eq_(Path('/foo/bar'), calls[0]['path'])
self.assertEqual(['.DS_Store'], calls[0]['files_to_delete']) eq_(['.DS_Store'], calls[0]['files_to_delete'])
def test_recurse_up(self): def test_recurse_up(self, do_setup, monkeypatch):
# delete_if_empty must be recursively called up in the path until it returns False # delete_if_empty must be recursively called up in the path until it returns False
@log_calls @log_calls
def mock_delete_if_empty(path, files_to_delete=[]): def mock_delete_if_empty(path, files_to_delete=[]):
return len(path) > 1 return len(path) > 1
self.mock(hsutil.files, 'delete_if_empty', mock_delete_if_empty) monkeypatch.setattr(hscommon.util, 'delete_if_empty', mock_delete_if_empty)
# XXX This monkeypatch is temporary. will be fixed in a better monkeypatcher.
monkeypatch.setattr(app, 'delete_if_empty', mock_delete_if_empty)
self.app.options['clean_empty_dirs'] = True self.app.options['clean_empty_dirs'] = True
self.app.clean_empty_dirs(Path('not-empty/empty/empty')) self.app.clean_empty_dirs(Path('not-empty/empty/empty'))
calls = hsutil.files.delete_if_empty.calls calls = hscommon.util.delete_if_empty.calls
self.assertEqual(3, len(calls)) eq_(3, len(calls))
self.assertEqual(Path('not-empty/empty/empty'), calls[0]['path']) eq_(Path('not-empty/empty/empty'), calls[0]['path'])
self.assertEqual(Path('not-empty/empty'), calls[1]['path']) eq_(Path('not-empty/empty'), calls[1]['path'])
self.assertEqual(Path('not-empty'), calls[2]['path']) eq_(Path('not-empty'), calls[2]['path'])
class TCDupeGuruWithResults(TestCase): class TestCaseDupeGuruWithResults:
def setUp(self): def pytest_funcarg__do_setup(self, request):
self.app = DupeGuru() self.app = DupeGuru()
self.objects,self.matches,self.groups = GetTestGroups() self.objects,self.matches,self.groups = GetTestGroups()
self.app.results.groups = self.groups self.app.results.groups = self.groups
@@ -185,50 +189,13 @@ class TCDupeGuruWithResults(TestCase):
self.dpanel.connect() self.dpanel.connect()
self.dtree.connect() self.dtree.connect()
self.rtable.connect() self.rtable.connect()
tmppath = self.tmppath() tmpdir = request.getfuncargvalue('tmpdir')
tmppath = Path(str(tmpdir))
io.mkdir(tmppath + 'foo') io.mkdir(tmppath + 'foo')
io.mkdir(tmppath + 'bar') io.mkdir(tmppath + 'bar')
self.app.directories.add_path(tmppath) self.app.directories.add_path(tmppath)
def check_gui_calls(self, gui, expected, verify_order=False): def test_GetObjects(self, do_setup):
"""Checks that the expected calls have been made to 'gui', then clears the log.
`expected` is an iterable of strings representing method names.
If `verify_order` is True, the order of the calls matters.
"""
if verify_order:
eq_(gui.calls, expected)
else:
eq_(set(gui.calls), set(expected))
gui.clear_calls()
def check_gui_calls_partial(self, gui, expected=None, not_expected=None):
"""Checks that the expected calls have been made to 'gui', then clears the log.
`expected` is an iterable of strings representing method names. Order doesn't matter.
Moreover, if calls have been made that are not in expected, no failure occur.
`not_expected` can be used for a more explicit check (rather than calling `check_gui_calls`
with an empty `expected`) to assert that calls have *not* been made.
"""
calls = set(gui.calls)
if expected is not None:
expected = set(expected)
not_called = expected - calls
assert not not_called, "These calls haven't been made: {0}".format(not_called)
if not_expected is not None:
not_expected = set(not_expected)
called = not_expected & calls
assert not called, "These calls shouldn't have been made: {0}".format(called)
gui.clear_calls()
def clear_gui_calls(self):
for attr in dir(self):
if attr.endswith('_gui'):
gui = getattr(self, attr)
if hasattr(gui, 'calls'): # We might have test methods ending with '_gui'
gui.clear_calls()
def test_GetObjects(self):
objects = self.objects objects = self.objects
groups = self.groups groups = self.groups
r = self.rtable[0] r = self.rtable[0]
@@ -241,7 +208,7 @@ class TCDupeGuruWithResults(TestCase):
assert r._group is groups[1] assert r._group is groups[1]
assert r._dupe is objects[4] assert r._dupe is objects[4]
def test_GetObjects_after_sort(self): def test_GetObjects_after_sort(self, do_setup):
objects = self.objects objects = self.objects
groups = self.groups[:] # we need an un-sorted reference groups = self.groups[:] # we need an un-sorted reference
self.rtable.sort(0, False) #0 = Filename self.rtable.sort(0, False) #0 = Filename
@@ -249,14 +216,14 @@ class TCDupeGuruWithResults(TestCase):
assert r._group is groups[1] assert r._group is groups[1]
assert r._dupe is objects[4] assert r._dupe is objects[4]
def test_selected_result_node_paths_after_deletion(self): def test_selected_result_node_paths_after_deletion(self, do_setup):
# cases where the selected dupes aren't there are correctly handled # cases where the selected dupes aren't there are correctly handled
self.rtable.select([1, 2, 3]) self.rtable.select([1, 2, 3])
self.app.remove_selected() self.app.remove_selected()
# The first 2 dupes have been removed. The 3rd one is a ref. it stays there, in first pos. # The first 2 dupes have been removed. The 3rd one is a ref. it stays there, in first pos.
eq_(self.rtable.selected_indexes, [1]) # no exception eq_(self.rtable.selected_indexes, [1]) # no exception
def test_selectResultNodePaths(self): def test_selectResultNodePaths(self, do_setup):
app = self.app app = self.app
objects = self.objects objects = self.objects
self.rtable.select([1, 2]) self.rtable.select([1, 2])
@@ -264,7 +231,7 @@ class TCDupeGuruWithResults(TestCase):
assert app.selected_dupes[0] is objects[1] assert app.selected_dupes[0] is objects[1]
assert app.selected_dupes[1] is objects[2] assert app.selected_dupes[1] is objects[2]
def test_selectResultNodePaths_with_ref(self): def test_selectResultNodePaths_with_ref(self, do_setup):
app = self.app app = self.app
objects = self.objects objects = self.objects
self.rtable.select([1, 2, 3]) self.rtable.select([1, 2, 3])
@@ -273,7 +240,7 @@ class TCDupeGuruWithResults(TestCase):
assert app.selected_dupes[1] is objects[2] assert app.selected_dupes[1] is objects[2]
assert app.selected_dupes[2] is self.groups[1].ref assert app.selected_dupes[2] is self.groups[1].ref
def test_selectResultNodePaths_after_sort(self): def test_selectResultNodePaths_after_sort(self, do_setup):
app = self.app app = self.app
objects = self.objects objects = self.objects
groups = self.groups[:] #To keep the old order in memory groups = self.groups[:] #To keep the old order in memory
@@ -285,25 +252,22 @@ class TCDupeGuruWithResults(TestCase):
assert app.selected_dupes[1] is groups[0].ref assert app.selected_dupes[1] is groups[0].ref
assert app.selected_dupes[2] is objects[1] assert app.selected_dupes[2] is objects[1]
def test_selected_powermarker_node_paths(self): def test_selected_powermarker_node_paths(self, do_setup):
# app.selected_dupes is correctly converted into paths # app.selected_dupes is correctly converted into paths
app = self.app
objects = self.objects
self.rtable.power_marker = True self.rtable.power_marker = True
self.rtable.select([0, 1, 2]) self.rtable.select([0, 1, 2])
self.rtable.power_marker = False self.rtable.power_marker = False
eq_(self.rtable.selected_indexes, [1, 2, 4]) eq_(self.rtable.selected_indexes, [1, 2, 4])
def test_selected_powermarker_node_paths_after_deletion(self): def test_selected_powermarker_node_paths_after_deletion(self, do_setup):
# cases where the selected dupes aren't there are correctly handled # cases where the selected dupes aren't there are correctly handled
app = self.app app = self.app
objects = self.objects
self.rtable.power_marker = True self.rtable.power_marker = True
self.rtable.select([0, 1, 2]) self.rtable.select([0, 1, 2])
app.remove_selected() app.remove_selected()
eq_(self.rtable.selected_indexes, []) # no exception eq_(self.rtable.selected_indexes, []) # no exception
def test_selectPowerMarkerRows_after_sort(self): def test_selectPowerMarkerRows_after_sort(self, do_setup):
app = self.app app = self.app
objects = self.objects objects = self.objects
self.rtable.power_marker = True self.rtable.power_marker = True
@@ -314,7 +278,7 @@ class TCDupeGuruWithResults(TestCase):
assert app.selected_dupes[1] is objects[2] assert app.selected_dupes[1] is objects[2]
assert app.selected_dupes[2] is objects[1] assert app.selected_dupes[2] is objects[1]
def test_toggleSelectedMark(self): def test_toggleSelectedMark(self, do_setup):
app = self.app app = self.app
objects = self.objects objects = self.objects
app.toggle_selected_mark_state() app.toggle_selected_mark_state()
@@ -328,15 +292,15 @@ class TCDupeGuruWithResults(TestCase):
assert not app.results.is_marked(objects[3]) assert not app.results.is_marked(objects[3])
assert app.results.is_marked(objects[4]) assert app.results.is_marked(objects[4])
def test_refreshDetailsWithSelected(self): def test_refreshDetailsWithSelected(self, do_setup):
self.rtable.select([1, 4]) self.rtable.select([1, 4])
eq_(self.dpanel.row(0), ('Filename', 'bar bleh', 'foo bar')) eq_(self.dpanel.row(0), ('Filename', 'bar bleh', 'foo bar'))
self.check_gui_calls(self.dpanel_gui, ['refresh']) self.dpanel_gui.check_gui_calls(['refresh'])
self.rtable.select([]) self.rtable.select([])
eq_(self.dpanel.row(0), ('Filename', '---', '---')) eq_(self.dpanel.row(0), ('Filename', '---', '---'))
self.check_gui_calls(self.dpanel_gui, ['refresh']) self.dpanel_gui.check_gui_calls(['refresh'])
def test_makeSelectedReference(self): def test_makeSelectedReference(self, do_setup):
app = self.app app = self.app
objects = self.objects objects = self.objects
groups = self.groups groups = self.groups
@@ -345,7 +309,7 @@ class TCDupeGuruWithResults(TestCase):
assert groups[0].ref is objects[1] assert groups[0].ref is objects[1]
assert groups[1].ref is objects[4] assert groups[1].ref is objects[4]
def test_makeSelectedReference_by_selecting_two_dupes_in_the_same_group(self): def test_makeSelectedReference_by_selecting_two_dupes_in_the_same_group(self, do_setup):
app = self.app app = self.app
objects = self.objects objects = self.objects
groups = self.groups groups = self.groups
@@ -355,7 +319,7 @@ class TCDupeGuruWithResults(TestCase):
assert groups[0].ref is objects[1] assert groups[0].ref is objects[1]
assert groups[1].ref is objects[4] assert groups[1].ref is objects[4]
def test_removeSelected(self): def test_removeSelected(self, do_setup):
app = self.app app = self.app
self.rtable.select([1, 4]) self.rtable.select([1, 4])
app.remove_selected() app.remove_selected()
@@ -363,22 +327,25 @@ class TCDupeGuruWithResults(TestCase):
app.remove_selected() app.remove_selected()
eq_(len(app.results.dupes), 0) eq_(len(app.results.dupes), 0)
def test_addDirectory_simple(self): def test_addDirectory_simple(self, do_setup):
# There's already a directory in self.app, so adding another once makes 2 of em # There's already a directory in self.app, so adding another once makes 2 of em
app = self.app app = self.app
eq_(app.add_directory(self.datadirpath()), 0) # any other path that isn't a parent or child of the already added path
otherpath = Path(op.dirname(__file__))
eq_(app.add_directory(otherpath), 0)
eq_(len(app.directories), 2) eq_(len(app.directories), 2)
def test_addDirectory_already_there(self): def test_addDirectory_already_there(self, do_setup):
app = self.app app = self.app
self.assertEqual(0,app.add_directory(self.datadirpath())) otherpath = Path(op.dirname(__file__))
self.assertEqual(1,app.add_directory(self.datadirpath())) eq_(app.add_directory(otherpath), 0)
eq_(app.add_directory(otherpath), 1)
def test_addDirectory_does_not_exist(self): def test_addDirectory_does_not_exist(self, do_setup):
app = self.app app = self.app
self.assertEqual(2,app.add_directory('/does_not_exist')) eq_(2,app.add_directory('/does_not_exist'))
def test_ignore(self): def test_ignore(self, do_setup):
app = self.app app = self.app
self.rtable.select([4]) #The dupe of the second, 2 sized group self.rtable.select([4]) #The dupe of the second, 2 sized group
app.add_selected_to_ignore_list() app.add_selected_to_ignore_list()
@@ -388,20 +355,22 @@ class TCDupeGuruWithResults(TestCase):
#BOTH the ref and the other dupe should have been added #BOTH the ref and the other dupe should have been added
eq_(len(app.scanner.ignore_list), 3) eq_(len(app.scanner.ignore_list), 3)
def test_purgeIgnoreList(self): def test_purgeIgnoreList(self, do_setup, tmpdir):
app = self.app app = self.app
p1 = self.filepath('zerofile') p1 = str(tmpdir.join('file1'))
p2 = self.filepath('zerofill') p2 = str(tmpdir.join('file2'))
open(p1, 'w').close()
open(p2, 'w').close()
dne = '/does_not_exist' dne = '/does_not_exist'
app.scanner.ignore_list.Ignore(dne,p1) app.scanner.ignore_list.Ignore(dne,p1)
app.scanner.ignore_list.Ignore(p2,dne) app.scanner.ignore_list.Ignore(p2,dne)
app.scanner.ignore_list.Ignore(p1,p2) app.scanner.ignore_list.Ignore(p1,p2)
app.purge_ignore_list() app.purge_ignore_list()
self.assertEqual(1,len(app.scanner.ignore_list)) eq_(1,len(app.scanner.ignore_list))
self.assert_(app.scanner.ignore_list.AreIgnored(p1,p2)) assert app.scanner.ignore_list.AreIgnored(p1,p2)
self.assert_(not app.scanner.ignore_list.AreIgnored(dne,p1)) assert not app.scanner.ignore_list.AreIgnored(dne,p1)
def test_only_unicode_is_added_to_ignore_list(self): def test_only_unicode_is_added_to_ignore_list(self, do_setup):
def FakeIgnore(first,second): def FakeIgnore(first,second):
if not isinstance(first,str): if not isinstance(first,str):
self.fail() self.fail()
@@ -413,10 +382,19 @@ class TCDupeGuruWithResults(TestCase):
self.rtable.select([4]) self.rtable.select([4])
app.add_selected_to_ignore_list() app.add_selected_to_ignore_list()
def test_cancel_scan_with_previous_results(self, do_setup):
# When doing a scan with results being present prior to the scan, correctly invalidate the
# results table.
app = self.app
app.JOB = Job(1, lambda *args, **kw: False) # Cancels the task
add_fake_files_to_directories(app.directories, self.objects) # We want the scan to at least start
app.start_scanning() # will be cancelled immediately
eq_(len(self.rtable), 0)
class TCDupeGuru_renameSelected(TestCase): class TestCaseDupeGuru_renameSelected:
def setUp(self): def pytest_funcarg__do_setup(self, request):
p = self.tmppath() tmpdir = request.getfuncargvalue('tmpdir')
p = Path(str(tmpdir))
fp = open(str(p + 'foo bar 1'),mode='w') fp = open(str(p + 'foo bar 1'),mode='w')
fp.close() fp.close()
fp = open(str(p + 'foo bar 2'),mode='w') fp = open(str(p + 'foo bar 2'),mode='w')
@@ -438,7 +416,7 @@ class TCDupeGuru_renameSelected(TestCase):
self.rtable = ResultTable(self.rtable_gui, self.app) self.rtable = ResultTable(self.rtable_gui, self.app)
self.rtable.connect() self.rtable.connect()
def test_simple(self): def test_simple(self, do_setup):
app = self.app app = self.app
g = self.groups[0] g = self.groups[0]
self.rtable.select([1]) self.rtable.select([1])
@@ -448,11 +426,11 @@ class TCDupeGuru_renameSelected(TestCase):
assert 'foo bar 2' not in names assert 'foo bar 2' not in names
eq_(g.dupes[0].name, 'renamed') eq_(g.dupes[0].name, 'renamed')
def test_none_selected(self): def test_none_selected(self, do_setup, monkeypatch):
app = self.app app = self.app
g = self.groups[0] g = self.groups[0]
self.rtable.select([]) self.rtable.select([])
self.mock(logging, 'warning', log_calls(lambda msg: None)) monkeypatch.setattr(logging, 'warning', log_calls(lambda msg: None))
assert not app.rename_selected('renamed') assert not app.rename_selected('renamed')
msg = logging.warning.calls[0]['msg'] msg = logging.warning.calls[0]['msg']
eq_('dupeGuru Warning: list index out of range', msg) eq_('dupeGuru Warning: list index out of range', msg)
@@ -461,11 +439,11 @@ class TCDupeGuru_renameSelected(TestCase):
assert 'foo bar 2' in names assert 'foo bar 2' in names
eq_(g.dupes[0].name, 'foo bar 2') eq_(g.dupes[0].name, 'foo bar 2')
def test_name_already_exists(self): def test_name_already_exists(self, do_setup, monkeypatch):
app = self.app app = self.app
g = self.groups[0] g = self.groups[0]
self.rtable.select([1]) self.rtable.select([1])
self.mock(logging, 'warning', log_calls(lambda msg: None)) monkeypatch.setattr(logging, 'warning', log_calls(lambda msg: None))
assert not app.rename_selected('foo bar 1') assert not app.rename_selected('foo bar 1')
msg = logging.warning.calls[0]['msg'] msg = logging.warning.calls[0]['msg']
assert msg.startswith('dupeGuru Warning: \'foo bar 1\' already exists in') assert msg.startswith('dupeGuru Warning: \'foo bar 1\' already exists in')

View File

@@ -1,28 +0,0 @@
# -*- coding: utf-8 -*-
# Created By: Virgil Dupras
# Created On: 2010-07-11
# Copyright 2010 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
# This unit is required to make tests work with py.test. When running
import py
def get_testunit(item):
if hasattr(item, 'obj'):
testunit = py.builtin._getimself(item.obj)
if hasattr(testunit, 'global_setup'):
return testunit
def pytest_runtest_setup(item):
testunit = get_testunit(item)
if testunit is not None:
testunit.global_setup()
def pytest_runtest_teardown(item):
testunit = get_testunit(item)
if testunit is not None:
testunit.global_teardown()

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2009-10-23 # Created On: 2009-10-23
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
@@ -9,17 +8,18 @@
# data module for tests # data module for tests
from hsutil.str import format_size from hscommon.util import format_size
from ..data import format_path, cmp_value from ..data import format_path, cmp_value, Column
COLUMNS = [ COLUMNS = [
{'attr':'name','display':'Filename'}, Column('name', 'Filename'),
{'attr':'path','display':'Directory'}, Column('path', 'Directory'),
{'attr':'size','display':'Size (KB)'}, Column('size', 'Size (KB)'),
{'attr':'extension','display':'Kind'}, Column('extension', 'Kind'),
] ]
METADATA_TO_READ = ['size'] METADATA_TO_READ = ['size']
DELTA_COLUMNS = {2,}
def GetDisplayInfo(dupe, group, delta): def GetDisplayInfo(dupe, group, delta):
size = dupe.size size = dupe.size
@@ -35,10 +35,10 @@ def GetDisplayInfo(dupe, group, delta):
] ]
def GetDupeSortKey(dupe, get_group, key, delta): def GetDupeSortKey(dupe, get_group, key, delta):
r = cmp_value(getattr(dupe, COLUMNS[key]['attr'])) r = cmp_value(getattr(dupe, COLUMNS[key].attr))
if delta and (key == 2): if delta and (key in DELTA_COLUMNS):
r -= cmp_value(getattr(get_group().ref, COLUMNS[key]['attr'])) r -= cmp_value(getattr(get_group().ref, COLUMNS[key].attr))
return r return r
def GetGroupSortKey(group, key): def GetGroupSortKey(group, key):
return cmp_value(getattr(group.ref, COLUMNS[key]['attr'])) return cmp_value(getattr(group.ref, COLUMNS[key].attr))

View File

@@ -6,20 +6,20 @@
# 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
import os.path as op
import os import os
import time import time
import tempfile
import shutil
from hsutil import io from pytest import raises
from hsutil.path import Path from hscommon import io
from hsutil.testutil import eq_ from hscommon.path import Path
from hsutil.testcase import TestCase from hscommon.testutil import eq_
from ..directories import * from ..directories import *
testpath = Path(TestCase.datadirpath())
def create_fake_fs(rootpath): def create_fake_fs(rootpath):
# We have it as a separate function because other units are using it.
rootpath = rootpath + 'fs' rootpath = rootpath + 'fs'
io.mkdir(rootpath) io.mkdir(rootpath)
io.mkdir(rootpath + 'dir1') io.mkdir(rootpath + 'dir1')
@@ -45,233 +45,253 @@ def create_fake_fs(rootpath):
fp.close() fp.close()
return rootpath return rootpath
class TCDirectories(TestCase): def setup_module(module):
def test_empty(self): # In this unit, we have tests depending on two directory structure. One with only one file in it
d = Directories() # and another with a more complex structure.
self.assertEqual(0,len(d)) testpath = Path(tempfile.mkdtemp())
self.assert_('foobar' not in d) module.testpath = testpath
rootpath = testpath + 'onefile'
def test_add_path(self): io.mkdir(rootpath)
d = Directories() fp = io.open(rootpath + 'test.txt', 'w')
p = testpath + 'utils' fp.write('test_data')
fp.close()
create_fake_fs(testpath)
def teardown_module(module):
shutil.rmtree(str(module.testpath))
def test_empty():
d = Directories()
eq_(len(d), 0)
assert 'foobar' not in d
def test_add_path():
d = Directories()
p = testpath + 'onefile'
d.add_path(p)
eq_(1,len(d))
assert p in d
assert (p + 'foobar') in d
assert p[:-1] not in d
p = testpath + 'fs'
d.add_path(p)
eq_(2,len(d))
assert p in d
def test_AddPath_when_path_is_already_there():
d = Directories()
p = testpath + 'onefile'
d.add_path(p)
with raises(AlreadyThereError):
d.add_path(p) d.add_path(p)
self.assertEqual(1,len(d)) with raises(AlreadyThereError):
self.assert_(p in d) d.add_path(p + 'foobar')
self.assert_((p + 'foobar') in d) eq_(1, len(d))
self.assert_(p[:-1] not in d)
p = self.tmppath() def test_add_path_containing_paths_already_there():
d.add_path(p) d = Directories()
self.assertEqual(2,len(d)) d.add_path(testpath + 'onefile')
self.assert_(p in d) eq_(1, len(d))
d.add_path(testpath)
def test_AddPath_when_path_is_already_there(self): eq_(len(d), 1)
d = Directories() eq_(d[0], testpath)
p = testpath + 'utils'
d.add_path(p) def test_AddPath_non_latin(tmpdir):
self.assertRaises(AlreadyThereError, d.add_path, p) p = Path(str(tmpdir))
self.assertRaises(AlreadyThereError, d.add_path, p + 'foobar') to_add = p + 'unicode\u201a'
self.assertEqual(1, len(d)) os.mkdir(str(to_add))
d = Directories()
def test_add_path_containing_paths_already_there(self): try:
d = Directories() d.add_path(to_add)
d.add_path(testpath + 'utils') except UnicodeDecodeError:
self.assertEqual(1, len(d)) assert False
d.add_path(testpath)
eq_(len(d), 1) def test_del():
eq_(d[0], testpath) d = Directories()
d.add_path(testpath + 'onefile')
def test_AddPath_non_latin(self): try:
p = Path(self.tmpdir())
to_add = p + 'unicode\u201a'
os.mkdir(str(to_add))
d = Directories()
try:
d.add_path(to_add)
except UnicodeDecodeError:
self.fail()
def test_del(self):
d = Directories()
d.add_path(testpath + 'utils')
try:
del d[1]
self.fail()
except IndexError:
pass
d.add_path(self.tmppath())
del d[1] del d[1]
self.assertEqual(1, len(d)) assert False
except IndexError:
def test_states(self): pass
d = Directories() d.add_path(testpath + 'fs')
p = testpath + 'utils' del d[1]
eq_(1, len(d))
def test_states():
d = Directories()
p = testpath + 'onefile'
d.add_path(p)
eq_(STATE_NORMAL,d.get_state(p))
d.set_state(p,STATE_REFERENCE)
eq_(STATE_REFERENCE,d.get_state(p))
eq_(STATE_REFERENCE,d.get_state(p + 'dir1'))
eq_(1,len(d.states))
eq_(p,list(d.states.keys())[0])
eq_(STATE_REFERENCE,d.states[p])
def test_get_state_with_path_not_there():
# When the path's not there, just return STATE_NORMAL
d = Directories()
d.add_path(testpath + 'onefile')
eq_(d.get_state(testpath), STATE_NORMAL)
def test_states_remain_when_larger_directory_eat_smaller_ones():
d = Directories()
p = testpath + 'onefile'
d.add_path(p)
d.set_state(p,STATE_EXCLUDED)
d.add_path(testpath)
d.set_state(testpath,STATE_REFERENCE)
eq_(STATE_EXCLUDED,d.get_state(p))
eq_(STATE_EXCLUDED,d.get_state(p + 'dir1'))
eq_(STATE_REFERENCE,d.get_state(testpath))
def test_set_state_keep_state_dict_size_to_minimum():
d = Directories()
p = testpath + 'fs'
d.add_path(p)
d.set_state(p,STATE_REFERENCE)
d.set_state(p + 'dir1',STATE_REFERENCE)
eq_(1,len(d.states))
eq_(STATE_REFERENCE,d.get_state(p + 'dir1'))
d.set_state(p + 'dir1',STATE_NORMAL)
eq_(2,len(d.states))
eq_(STATE_NORMAL,d.get_state(p + 'dir1'))
d.set_state(p + 'dir1',STATE_REFERENCE)
eq_(1,len(d.states))
eq_(STATE_REFERENCE,d.get_state(p + 'dir1'))
def test_get_files():
d = Directories()
p = testpath + 'fs'
d.add_path(p)
d.set_state(p + 'dir1',STATE_REFERENCE)
d.set_state(p + 'dir2',STATE_EXCLUDED)
files = list(d.get_files())
eq_(5, len(files))
for f in files:
if f.path[:-1] == p + 'dir1':
assert f.is_ref
else:
assert not f.is_ref
def test_get_files_with_inherited_exclusion():
d = Directories()
p = testpath + 'onefile'
d.add_path(p)
d.set_state(p,STATE_EXCLUDED)
eq_([], list(d.get_files()))
def test_save_and_load(tmpdir):
d1 = Directories()
d2 = Directories()
p1 = Path(str(tmpdir.join('p1')))
io.mkdir(p1)
p2 = Path(str(tmpdir.join('p2')))
io.mkdir(p2)
d1.add_path(p1)
d1.add_path(p2)
d1.set_state(p1, STATE_REFERENCE)
d1.set_state(p1 + 'dir1',STATE_EXCLUDED)
tmpxml = str(tmpdir.join('directories_testunit.xml'))
d1.save_to_file(tmpxml)
d2.load_from_file(tmpxml)
eq_(2, len(d2))
eq_(STATE_REFERENCE,d2.get_state(p1))
eq_(STATE_EXCLUDED,d2.get_state(p1 + 'dir1'))
def test_invalid_path():
d = Directories()
p = Path('does_not_exist')
with raises(InvalidPathError):
d.add_path(p) d.add_path(p)
self.assertEqual(STATE_NORMAL,d.get_state(p)) eq_(0, len(d))
d.set_state(p,STATE_REFERENCE)
self.assertEqual(STATE_REFERENCE,d.get_state(p)) def test_set_state_on_invalid_path():
self.assertEqual(STATE_REFERENCE,d.get_state(p + 'dir1')) d = Directories()
self.assertEqual(1,len(d.states)) try:
self.assertEqual(p,list(d.states.keys())[0]) d.set_state(Path('foobar',),STATE_NORMAL)
self.assertEqual(STATE_REFERENCE,d.states[p]) except LookupError:
assert False
def test_get_state_with_path_not_there(self):
# When the path's not there, just return STATE_NORMAL def test_load_from_file_with_invalid_path(tmpdir):
d = Directories() #This test simulates a load from file resulting in a
d.add_path(testpath + 'utils') #InvalidPath raise. Other directories must be loaded.
eq_(d.get_state(testpath), STATE_NORMAL) d1 = Directories()
d1.add_path(testpath + 'onefile')
def test_states_remain_when_larger_directory_eat_smaller_ones(self): #Will raise InvalidPath upon loading
d = Directories() p = Path(str(tmpdir.join('toremove')))
p = testpath + 'utils' io.mkdir(p)
d.add_path(p) d1.add_path(p)
d.set_state(p,STATE_EXCLUDED) io.rmdir(p)
d.add_path(testpath) tmpxml = str(tmpdir.join('directories_testunit.xml'))
d.set_state(testpath,STATE_REFERENCE) d1.save_to_file(tmpxml)
self.assertEqual(STATE_EXCLUDED,d.get_state(p)) d2 = Directories()
self.assertEqual(STATE_EXCLUDED,d.get_state(p + 'dir1')) d2.load_from_file(tmpxml)
self.assertEqual(STATE_REFERENCE,d.get_state(testpath)) eq_(1, len(d2))
def test_set_state_keep_state_dict_size_to_minimum(self): def test_unicode_save(tmpdir):
d = Directories() d = Directories()
p = create_fake_fs(self.tmppath()) p1 = Path(str(tmpdir)) + 'hello\xe9'
d.add_path(p) io.mkdir(p1)
d.set_state(p,STATE_REFERENCE) io.mkdir(p1 + 'foo\xe9')
d.set_state(p + 'dir1',STATE_REFERENCE) d.add_path(p1)
self.assertEqual(1,len(d.states)) d.set_state(p1 + 'foo\xe9', STATE_EXCLUDED)
self.assertEqual(STATE_REFERENCE,d.get_state(p + 'dir1')) tmpxml = str(tmpdir.join('directories_testunit.xml'))
d.set_state(p + 'dir1',STATE_NORMAL) try:
self.assertEqual(2,len(d.states)) d.save_to_file(tmpxml)
self.assertEqual(STATE_NORMAL,d.get_state(p + 'dir1')) except UnicodeDecodeError:
d.set_state(p + 'dir1',STATE_REFERENCE) assert False
self.assertEqual(1,len(d.states))
self.assertEqual(STATE_REFERENCE,d.get_state(p + 'dir1')) def test_get_files_refreshes_its_directories():
d = Directories()
def test_get_files(self): p = testpath + 'fs'
d = Directories() d.add_path(p)
p = create_fake_fs(self.tmppath()) files = d.get_files()
d.add_path(p) eq_(6, len(list(files)))
d.set_state(p + 'dir1',STATE_REFERENCE) time.sleep(1)
d.set_state(p + 'dir2',STATE_EXCLUDED) os.remove(str(p + ('dir1','file1.test')))
files = list(d.get_files()) files = d.get_files()
self.assertEqual(5, len(files)) eq_(5, len(list(files)))
for f in files:
if f.path[:-1] == p + 'dir1': def test_get_files_does_not_choke_on_non_existing_directories(tmpdir):
assert f.is_ref d = Directories()
else: p = Path(str(tmpdir))
assert not f.is_ref d.add_path(p)
io.rmtree(p)
def test_get_files_with_inherited_exclusion(self): eq_([], list(d.get_files()))
d = Directories()
p = testpath + 'utils' def test_get_state_returns_excluded_by_default_for_hidden_directories(tmpdir):
d.add_path(p) d = Directories()
d.set_state(p,STATE_EXCLUDED) p = Path(str(tmpdir))
self.assertEqual([], list(d.get_files())) hidden_dir_path = p + '.foo'
io.mkdir(p + '.foo')
def test_save_and_load(self): d.add_path(p)
d1 = Directories() eq_(d.get_state(hidden_dir_path), STATE_EXCLUDED)
d2 = Directories() # But it can be overriden
p1 = self.tmppath() d.set_state(hidden_dir_path, STATE_NORMAL)
p2 = self.tmppath() eq_(d.get_state(hidden_dir_path), STATE_NORMAL)
d1.add_path(p1)
d1.add_path(p2) def test_default_path_state_override(tmpdir):
d1.set_state(p1, STATE_REFERENCE) # It's possible for a subclass to override the default state of a path
d1.set_state(p1 + 'dir1',STATE_EXCLUDED) class MyDirectories(Directories):
tmpxml = op.join(self.tmpdir(), 'directories_testunit.xml') def _default_state_for_path(self, path):
d1.save_to_file(tmpxml) if 'foobar' in path:
d2.load_from_file(tmpxml) return STATE_EXCLUDED
self.assertEqual(2, len(d2))
self.assertEqual(STATE_REFERENCE,d2.get_state(p1))
self.assertEqual(STATE_EXCLUDED,d2.get_state(p1 + 'dir1'))
def test_invalid_path(self):
d = Directories()
p = Path('does_not_exist')
self.assertRaises(InvalidPathError, d.add_path, p)
self.assertEqual(0, len(d))
def test_set_state_on_invalid_path(self):
d = Directories()
try:
d.set_state(Path('foobar',),STATE_NORMAL)
except LookupError:
self.fail()
def test_load_from_file_with_invalid_path(self):
#This test simulates a load from file resulting in a
#InvalidPath raise. Other directories must be loaded.
d1 = Directories()
d1.add_path(testpath + 'utils')
#Will raise InvalidPath upon loading
p = self.tmppath()
d1.add_path(p)
io.rmdir(p)
tmpxml = op.join(self.tmpdir(), 'directories_testunit.xml')
d1.save_to_file(tmpxml)
d2 = Directories()
d2.load_from_file(tmpxml)
self.assertEqual(1, len(d2))
def test_unicode_save(self):
d = Directories()
p1 = self.tmppath() + 'hello\xe9'
io.mkdir(p1)
io.mkdir(p1 + 'foo\xe9')
d.add_path(p1)
d.set_state(p1 + 'foo\xe9', STATE_EXCLUDED)
tmpxml = op.join(self.tmpdir(), 'directories_testunit.xml')
try:
d.save_to_file(tmpxml)
except UnicodeDecodeError:
self.fail()
def test_get_files_refreshes_its_directories(self):
d = Directories()
p = create_fake_fs(self.tmppath())
d.add_path(p)
files = d.get_files()
self.assertEqual(6, len(list(files)))
time.sleep(1)
os.remove(str(p + ('dir1','file1.test')))
files = d.get_files()
self.assertEqual(5, len(list(files)))
def test_get_files_does_not_choke_on_non_existing_directories(self):
d = Directories()
p = Path(self.tmpdir())
d.add_path(p)
io.rmtree(p)
self.assertEqual([], list(d.get_files()))
def test_get_state_returns_excluded_by_default_for_hidden_directories(self):
d = Directories()
p = Path(self.tmpdir())
hidden_dir_path = p + '.foo'
io.mkdir(p + '.foo')
d.add_path(p)
self.assertEqual(d.get_state(hidden_dir_path), STATE_EXCLUDED)
# But it can be overriden
d.set_state(hidden_dir_path, STATE_NORMAL)
self.assertEqual(d.get_state(hidden_dir_path), STATE_NORMAL)
def test_default_path_state_override(self):
# It's possible for a subclass to override the default state of a path
class MyDirectories(Directories):
def _default_state_for_path(self, path):
if 'foobar' in path:
return STATE_EXCLUDED
d = MyDirectories()
p1 = self.tmppath()
io.mkdir(p1 + 'foobar')
io.open(p1 + 'foobar/somefile', 'w').close()
io.mkdir(p1 + 'foobaz')
io.open(p1 + 'foobaz/somefile', 'w').close()
d.add_path(p1)
eq_(d.get_state(p1 + 'foobaz'), STATE_NORMAL)
eq_(d.get_state(p1 + 'foobar'), STATE_EXCLUDED)
eq_(len(list(d.get_files())), 1) # only the 'foobaz' file is there
# However, the default state can be changed
d.set_state(p1 + 'foobar', STATE_NORMAL)
eq_(d.get_state(p1 + 'foobar'), STATE_NORMAL)
eq_(len(list(d.get_files())), 2)
d = MyDirectories()
p1 = Path(str(tmpdir))
io.mkdir(p1 + 'foobar')
io.open(p1 + 'foobar/somefile', 'w').close()
io.mkdir(p1 + 'foobaz')
io.open(p1 + 'foobaz/somefile', 'w').close()
d.add_path(p1)
eq_(d.get_state(p1 + 'foobaz'), STATE_NORMAL)
eq_(d.get_state(p1 + 'foobar'), STATE_EXCLUDED)
eq_(len(list(d.get_files())), 1) # only the 'foobaz' file is there
# However, the default state can be changed
d.set_state(p1 + 'foobar', STATE_NORMAL)
eq_(d.get_state(p1 + 'foobar'), STATE_NORMAL)
eq_(len(list(d.get_files())), 2)

View File

@@ -8,16 +8,14 @@
import sys import sys
from hscommon import job from jobprogress import job
from hsutil.decorators import log_calls from hscommon.util import first
from hsutil.misc import first from hscommon.testutil import eq_, log_calls
from hsutil.testutil import eq_
from hsutil.testcase import TestCase
from .. import engine from .. import engine
from ..engine import * from ..engine import *
class NamedObject(object): class NamedObject:
def __init__(self, name="foobar", with_words=False, size=1): def __init__(self, name="foobar", with_words=False, size=1):
self.name = name self.name = name
self.size = size self.size = size
@@ -55,179 +53,179 @@ def assert_match(m, name1, name2):
eq_(m.first.name, name2) eq_(m.first.name, name2)
eq_(m.second.name, name1) eq_(m.second.name, name1)
class TCgetwords(TestCase): class TestCasegetwords:
def test_spaces(self): def test_spaces(self):
self.assertEqual(['a', 'b', 'c', 'd'], getwords("a b c d")) eq_(['a', 'b', 'c', 'd'], getwords("a b c d"))
self.assertEqual(['a', 'b', 'c', 'd'], getwords(" a b c d ")) eq_(['a', 'b', 'c', 'd'], getwords(" a b c d "))
def test_splitter_chars(self): def test_splitter_chars(self):
self.assertEqual( eq_(
[chr(i) for i in range(ord('a'),ord('z')+1)], [chr(i) for i in range(ord('a'),ord('z')+1)],
getwords("a-b_c&d+e(f)g;h\\i[j]k{l}m:n.o,p<q>r/s?t~u!v@w#x$y*z") getwords("a-b_c&d+e(f)g;h\\i[j]k{l}m:n.o,p<q>r/s?t~u!v@w#x$y*z")
) )
def test_joiner_chars(self): def test_joiner_chars(self):
self.assertEqual(["aec"], getwords("a'e\u0301c")) eq_(["aec"], getwords("a'e\u0301c"))
def test_empty(self): def test_empty(self):
self.assertEqual([], getwords('')) eq_([], getwords(''))
def test_returns_lowercase(self): def test_returns_lowercase(self):
self.assertEqual(['foo', 'bar'], getwords('FOO BAR')) eq_(['foo', 'bar'], getwords('FOO BAR'))
def test_decompose_unicode(self): def test_decompose_unicode(self):
self.assertEqual(getwords('foo\xe9bar'), ['fooebar']) eq_(getwords('foo\xe9bar'), ['fooebar'])
class TCgetfields(TestCase): class TestCasegetfields:
def test_simple(self): def test_simple(self):
self.assertEqual([['a', 'b'], ['c', 'd', 'e']], getfields('a b - c d e')) eq_([['a', 'b'], ['c', 'd', 'e']], getfields('a b - c d e'))
def test_empty(self): def test_empty(self):
self.assertEqual([], getfields('')) eq_([], getfields(''))
def test_cleans_empty_fields(self): def test_cleans_empty_fields(self):
expected = [['a', 'bc', 'def']] expected = [['a', 'bc', 'def']]
actual = getfields(' - a bc def') actual = getfields(' - a bc def')
self.assertEqual(expected, actual) eq_(expected, actual)
expected = [['bc', 'def']] expected = [['bc', 'def']]
class TCunpack_fields(TestCase): class TestCaseunpack_fields:
def test_with_fields(self): def test_with_fields(self):
expected = ['a', 'b', 'c', 'd', 'e', 'f'] expected = ['a', 'b', 'c', 'd', 'e', 'f']
actual = unpack_fields([['a'], ['b', 'c'], ['d', 'e', 'f']]) actual = unpack_fields([['a'], ['b', 'c'], ['d', 'e', 'f']])
self.assertEqual(expected, actual) eq_(expected, actual)
def test_without_fields(self): def test_without_fields(self):
expected = ['a', 'b', 'c', 'd', 'e', 'f'] expected = ['a', 'b', 'c', 'd', 'e', 'f']
actual = unpack_fields(['a', 'b', 'c', 'd', 'e', 'f']) actual = unpack_fields(['a', 'b', 'c', 'd', 'e', 'f'])
self.assertEqual(expected, actual) eq_(expected, actual)
def test_empty(self): def test_empty(self):
self.assertEqual([], unpack_fields([])) eq_([], unpack_fields([]))
class TCWordCompare(TestCase): class TestCaseWordCompare:
def test_list(self): def test_list(self):
self.assertEqual(100, compare(['a', 'b', 'c', 'd'],['a', 'b', 'c', 'd'])) eq_(100, compare(['a', 'b', 'c', 'd'],['a', 'b', 'c', 'd']))
self.assertEqual(86, compare(['a', 'b', 'c', 'd'],['a', 'b', 'c'])) eq_(86, compare(['a', 'b', 'c', 'd'],['a', 'b', 'c']))
def test_unordered(self): def test_unordered(self):
#Sometimes, users don't want fuzzy matching too much When they set the slider #Sometimes, users don't want fuzzy matching too much When they set the slider
#to 100, they don't expect a filename with the same words, but not the same order, to match. #to 100, they don't expect a filename with the same words, but not the same order, to match.
#Thus, we want to return 99 in that case. #Thus, we want to return 99 in that case.
self.assertEqual(99, compare(['a', 'b', 'c', 'd'], ['d', 'b', 'c', 'a'])) eq_(99, compare(['a', 'b', 'c', 'd'], ['d', 'b', 'c', 'a']))
def test_word_occurs_twice(self): def test_word_occurs_twice(self):
#if a word occurs twice in first, but once in second, we want the word to be only counted once #if a word occurs twice in first, but once in second, we want the word to be only counted once
self.assertEqual(89, compare(['a', 'b', 'c', 'd', 'a'], ['d', 'b', 'c', 'a'])) eq_(89, compare(['a', 'b', 'c', 'd', 'a'], ['d', 'b', 'c', 'a']))
def test_uses_copy_of_lists(self): def test_uses_copy_of_lists(self):
first = ['foo', 'bar'] first = ['foo', 'bar']
second = ['bar', 'bleh'] second = ['bar', 'bleh']
compare(first, second) compare(first, second)
self.assertEqual(['foo', 'bar'], first) eq_(['foo', 'bar'], first)
self.assertEqual(['bar', 'bleh'], second) eq_(['bar', 'bleh'], second)
def test_word_weight(self): def test_word_weight(self):
self.assertEqual(int((6.0 / 13.0) * 100), compare(['foo', 'bar'], ['bar', 'bleh'], (WEIGHT_WORDS, ))) eq_(int((6.0 / 13.0) * 100), compare(['foo', 'bar'], ['bar', 'bleh'], (WEIGHT_WORDS, )))
def test_similar_words(self): def test_similar_words(self):
self.assertEqual(100, compare(['the', 'white', 'stripes'],['the', 'whites', 'stripe'], (MATCH_SIMILAR_WORDS, ))) eq_(100, compare(['the', 'white', 'stripes'],['the', 'whites', 'stripe'], (MATCH_SIMILAR_WORDS, )))
def test_empty(self): def test_empty(self):
self.assertEqual(0, compare([], [])) eq_(0, compare([], []))
def test_with_fields(self): def test_with_fields(self):
self.assertEqual(67, compare([['a', 'b'], ['c', 'd', 'e']], [['a', 'b'], ['c', 'd', 'f']])) eq_(67, compare([['a', 'b'], ['c', 'd', 'e']], [['a', 'b'], ['c', 'd', 'f']]))
def test_propagate_flags_with_fields(self): def test_propagate_flags_with_fields(self, monkeypatch):
def mock_compare(first, second, flags): def mock_compare(first, second, flags):
self.assertEqual((0, 1, 2, 3, 5), flags) eq_((0, 1, 2, 3, 5), flags)
self.mock(engine, 'compare_fields', mock_compare) monkeypatch.setattr(engine, 'compare_fields', mock_compare)
compare([['a']], [['a']], (0, 1, 2, 3, 5)) compare([['a']], [['a']], (0, 1, 2, 3, 5))
class TCWordCompareWithFields(TestCase): class TestCaseWordCompareWithFields:
def test_simple(self): def test_simple(self):
self.assertEqual(67, compare_fields([['a', 'b'], ['c', 'd', 'e']], [['a', 'b'], ['c', 'd', 'f']])) eq_(67, compare_fields([['a', 'b'], ['c', 'd', 'e']], [['a', 'b'], ['c', 'd', 'f']]))
def test_empty(self): def test_empty(self):
self.assertEqual(0, compare_fields([], [])) eq_(0, compare_fields([], []))
def test_different_length(self): def test_different_length(self):
self.assertEqual(0, compare_fields([['a'], ['b']], [['a'], ['b'], ['c']])) eq_(0, compare_fields([['a'], ['b']], [['a'], ['b'], ['c']]))
def test_propagates_flags(self): def test_propagates_flags(self, monkeypatch):
def mock_compare(first, second, flags): def mock_compare(first, second, flags):
self.assertEqual((0, 1, 2, 3, 5), flags) eq_((0, 1, 2, 3, 5), flags)
self.mock(engine, 'compare_fields', mock_compare) monkeypatch.setattr(engine, 'compare_fields', mock_compare)
compare_fields([['a']], [['a']],(0, 1, 2, 3, 5)) compare_fields([['a']], [['a']],(0, 1, 2, 3, 5))
def test_order(self): def test_order(self):
first = [['a', 'b'], ['c', 'd', 'e']] first = [['a', 'b'], ['c', 'd', 'e']]
second = [['c', 'd', 'f'], ['a', 'b']] second = [['c', 'd', 'f'], ['a', 'b']]
self.assertEqual(0, compare_fields(first, second)) eq_(0, compare_fields(first, second))
def test_no_order(self): def test_no_order(self):
first = [['a','b'],['c','d','e']] first = [['a','b'],['c','d','e']]
second = [['c','d','f'],['a','b']] second = [['c','d','f'],['a','b']]
self.assertEqual(67, compare_fields(first, second, (NO_FIELD_ORDER, ))) eq_(67, compare_fields(first, second, (NO_FIELD_ORDER, )))
first = [['a','b'],['a','b']] #a field can only be matched once. first = [['a','b'],['a','b']] #a field can only be matched once.
second = [['c','d','f'],['a','b']] second = [['c','d','f'],['a','b']]
self.assertEqual(0, compare_fields(first, second, (NO_FIELD_ORDER, ))) eq_(0, compare_fields(first, second, (NO_FIELD_ORDER, )))
first = [['a','b'],['a','b','c']] first = [['a','b'],['a','b','c']]
second = [['c','d','f'],['a','b']] second = [['c','d','f'],['a','b']]
self.assertEqual(33, compare_fields(first, second, (NO_FIELD_ORDER, ))) eq_(33, compare_fields(first, second, (NO_FIELD_ORDER, )))
def test_compare_fields_without_order_doesnt_alter_fields(self): def test_compare_fields_without_order_doesnt_alter_fields(self):
#The NO_ORDER comp type altered the fields! #The NO_ORDER comp type altered the fields!
first = [['a','b'],['c','d','e']] first = [['a','b'],['c','d','e']]
second = [['c','d','f'],['a','b']] second = [['c','d','f'],['a','b']]
self.assertEqual(67, compare_fields(first, second, (NO_FIELD_ORDER, ))) eq_(67, compare_fields(first, second, (NO_FIELD_ORDER, )))
self.assertEqual([['a','b'],['c','d','e']],first) eq_([['a','b'],['c','d','e']],first)
self.assertEqual([['c','d','f'],['a','b']],second) eq_([['c','d','f'],['a','b']],second)
class TCbuild_word_dict(TestCase): class TestCasebuild_word_dict:
def test_with_standard_words(self): def test_with_standard_words(self):
l = [NamedObject('foo bar',True)] l = [NamedObject('foo bar',True)]
l.append(NamedObject('bar baz',True)) l.append(NamedObject('bar baz',True))
l.append(NamedObject('baz bleh foo',True)) l.append(NamedObject('baz bleh foo',True))
d = build_word_dict(l) d = build_word_dict(l)
self.assertEqual(4,len(d)) eq_(4,len(d))
self.assertEqual(2,len(d['foo'])) eq_(2,len(d['foo']))
self.assert_(l[0] in d['foo']) assert l[0] in d['foo']
self.assert_(l[2] in d['foo']) assert l[2] in d['foo']
self.assertEqual(2,len(d['bar'])) eq_(2,len(d['bar']))
self.assert_(l[0] in d['bar']) assert l[0] in d['bar']
self.assert_(l[1] in d['bar']) assert l[1] in d['bar']
self.assertEqual(2,len(d['baz'])) eq_(2,len(d['baz']))
self.assert_(l[1] in d['baz']) assert l[1] in d['baz']
self.assert_(l[2] in d['baz']) assert l[2] in d['baz']
self.assertEqual(1,len(d['bleh'])) eq_(1,len(d['bleh']))
self.assert_(l[2] in d['bleh']) assert l[2] in d['bleh']
def test_unpack_fields(self): def test_unpack_fields(self):
o = NamedObject('') o = NamedObject('')
o.words = [['foo','bar'],['baz']] o.words = [['foo','bar'],['baz']]
d = build_word_dict([o]) d = build_word_dict([o])
self.assertEqual(3,len(d)) eq_(3,len(d))
self.assertEqual(1,len(d['foo'])) eq_(1,len(d['foo']))
def test_words_are_unaltered(self): def test_words_are_unaltered(self):
o = NamedObject('') o = NamedObject('')
o.words = [['foo','bar'],['baz']] o.words = [['foo','bar'],['baz']]
d = build_word_dict([o]) build_word_dict([o])
self.assertEqual([['foo','bar'],['baz']],o.words) eq_([['foo','bar'],['baz']],o.words)
def test_object_instances_can_only_be_once_in_words_object_list(self): def test_object_instances_can_only_be_once_in_words_object_list(self):
o = NamedObject('foo foo',True) o = NamedObject('foo foo',True)
d = build_word_dict([o]) d = build_word_dict([o])
self.assertEqual(1,len(d['foo'])) eq_(1,len(d['foo']))
def test_job(self): def test_job(self):
def do_progress(p,d=''): def do_progress(p,d=''):
@@ -239,11 +237,11 @@ class TCbuild_word_dict(TestCase):
s = "foo bar" s = "foo bar"
build_word_dict([NamedObject(s, True), NamedObject(s, True), NamedObject(s, True)], j) build_word_dict([NamedObject(s, True), NamedObject(s, True), NamedObject(s, True)], j)
# We don't have intermediate log because iter_with_progress is called with every > 1 # We don't have intermediate log because iter_with_progress is called with every > 1
self.assertEqual(0,self.log[0]) eq_(0,self.log[0])
self.assertEqual(100,self.log[1]) eq_(100,self.log[1])
class TCmerge_similar_words(TestCase): class TestCasemerge_similar_words:
def test_some_similar_words(self): def test_some_similar_words(self):
d = { d = {
'foobar':set([1]), 'foobar':set([1]),
@@ -251,20 +249,20 @@ class TCmerge_similar_words(TestCase):
'foobar2':set([3]), 'foobar2':set([3]),
} }
merge_similar_words(d) merge_similar_words(d)
self.assertEqual(1,len(d)) eq_(1,len(d))
self.assertEqual(3,len(d['foobar'])) eq_(3,len(d['foobar']))
class TCreduce_common_words(TestCase): class TestCasereduce_common_words:
def test_typical(self): def test_typical(self):
d = { d = {
'foo': set([NamedObject('foo bar',True) for i in range(50)]), 'foo': set([NamedObject('foo bar',True) for i in range(50)]),
'bar': set([NamedObject('foo bar',True) for i in range(49)]) 'bar': set([NamedObject('foo bar',True) for i in range(49)])
} }
reduce_common_words(d, 50) reduce_common_words(d, 50)
self.assert_('foo' not in d) assert 'foo' not in d
self.assertEqual(49,len(d['bar'])) eq_(49,len(d['bar']))
def test_dont_remove_objects_with_only_common_words(self): def test_dont_remove_objects_with_only_common_words(self):
d = { d = {
@@ -272,8 +270,8 @@ class TCreduce_common_words(TestCase):
'uncommon': set([NamedObject("common uncommon",True)]) 'uncommon': set([NamedObject("common uncommon",True)])
} }
reduce_common_words(d, 50) reduce_common_words(d, 50)
self.assertEqual(1,len(d['common'])) eq_(1,len(d['common']))
self.assertEqual(1,len(d['uncommon'])) eq_(1,len(d['uncommon']))
def test_values_still_are_set_instances(self): def test_values_still_are_set_instances(self):
d = { d = {
@@ -281,8 +279,8 @@ class TCreduce_common_words(TestCase):
'uncommon': set([NamedObject("common uncommon",True)]) 'uncommon': set([NamedObject("common uncommon",True)])
} }
reduce_common_words(d, 50) reduce_common_words(d, 50)
self.assert_(isinstance(d['common'],set)) assert isinstance(d['common'],set)
self.assert_(isinstance(d['uncommon'],set)) assert isinstance(d['uncommon'],set)
def test_dont_raise_KeyError_when_a_word_has_been_removed(self): def test_dont_raise_KeyError_when_a_word_has_been_removed(self):
#If a word has been removed by the reduce, an object in a subsequent common word that #If a word has been removed by the reduce, an object in a subsequent common word that
@@ -324,42 +322,42 @@ class TCreduce_common_words(TestCase):
'baz': set([NamedObject('foo bar baz',True) for i in range(49)]) 'baz': set([NamedObject('foo bar baz',True) for i in range(49)])
} }
reduce_common_words(d, 50) reduce_common_words(d, 50)
self.assertEqual(1,len(d['foo'])) eq_(1,len(d['foo']))
self.assertEqual(1,len(d['bar'])) eq_(1,len(d['bar']))
self.assertEqual(49,len(d['baz'])) eq_(49,len(d['baz']))
class TCget_match(TestCase): class TestCaseget_match:
def test_simple(self): def test_simple(self):
o1 = NamedObject("foo bar",True) o1 = NamedObject("foo bar",True)
o2 = NamedObject("bar bleh",True) o2 = NamedObject("bar bleh",True)
m = get_match(o1,o2) m = get_match(o1,o2)
self.assertEqual(50,m.percentage) eq_(50,m.percentage)
self.assertEqual(['foo','bar'],m.first.words) eq_(['foo','bar'],m.first.words)
self.assertEqual(['bar','bleh'],m.second.words) eq_(['bar','bleh'],m.second.words)
self.assert_(m.first is o1) assert m.first is o1
self.assert_(m.second is o2) assert m.second is o2
def test_in(self): def test_in(self):
o1 = NamedObject("foo",True) o1 = NamedObject("foo",True)
o2 = NamedObject("bar",True) o2 = NamedObject("bar",True)
m = get_match(o1,o2) m = get_match(o1,o2)
self.assert_(o1 in m) assert o1 in m
self.assert_(o2 in m) assert o2 in m
self.assert_(object() not in m) assert object() not in m
def test_word_weight(self): def test_word_weight(self):
self.assertEqual(int((6.0 / 13.0) * 100),get_match(NamedObject("foo bar",True),NamedObject("bar bleh",True),(WEIGHT_WORDS,)).percentage) eq_(int((6.0 / 13.0) * 100),get_match(NamedObject("foo bar",True),NamedObject("bar bleh",True),(WEIGHT_WORDS,)).percentage)
class GetMatches(TestCase): class TestCaseGetMatches:
def test_empty(self): def test_empty(self):
eq_(getmatches([]), []) eq_(getmatches([]), [])
def test_simple(self): def test_simple(self):
l = [NamedObject("foo bar"),NamedObject("bar bleh"),NamedObject("a b c foo")] l = [NamedObject("foo bar"),NamedObject("bar bleh"),NamedObject("a b c foo")]
r = getmatches(l) r = getmatches(l)
self.assertEqual(2,len(r)) eq_(2,len(r))
m = first(m for m in r if m.percentage == 50) #"foo bar" and "bar bleh" m = first(m for m in r if m.percentage == 50) #"foo bar" and "bar bleh"
assert_match(m, 'foo bar', 'bar bleh') assert_match(m, 'foo bar', 'bar bleh')
m = first(m for m in r if m.percentage == 33) #"foo bar" and "a b c foo" m = first(m for m in r if m.percentage == 33) #"foo bar" and "a b c foo"
@@ -376,17 +374,17 @@ class GetMatches(TestCase):
def test_twice_the_same_word(self): def test_twice_the_same_word(self):
l = [NamedObject("foo foo bar"),NamedObject("bar bleh")] l = [NamedObject("foo foo bar"),NamedObject("bar bleh")]
r = getmatches(l) r = getmatches(l)
self.assertEqual(1,len(r)) eq_(1,len(r))
def test_twice_the_same_word_when_preworded(self): def test_twice_the_same_word_when_preworded(self):
l = [NamedObject("foo foo bar",True),NamedObject("bar bleh",True)] l = [NamedObject("foo foo bar",True),NamedObject("bar bleh",True)]
r = getmatches(l) r = getmatches(l)
self.assertEqual(1,len(r)) eq_(1,len(r))
def test_two_words_match(self): def test_two_words_match(self):
l = [NamedObject("foo bar"),NamedObject("foo bar bleh")] l = [NamedObject("foo bar"),NamedObject("foo bar bleh")]
r = getmatches(l) r = getmatches(l)
self.assertEqual(1,len(r)) eq_(1,len(r))
def test_match_files_with_only_common_words(self): def test_match_files_with_only_common_words(self):
#If a word occurs more than 50 times, it is excluded from the matching process #If a word occurs more than 50 times, it is excluded from the matching process
@@ -395,7 +393,7 @@ class GetMatches(TestCase):
# This test assumes that the common word threashold const is 50 # This test assumes that the common word threashold const is 50
l = [NamedObject("foo") for i in range(50)] l = [NamedObject("foo") for i in range(50)]
r = getmatches(l) r = getmatches(l)
self.assertEqual(1225,len(r)) eq_(1225,len(r))
def test_use_words_already_there_if_there(self): def test_use_words_already_there_if_there(self):
o1 = NamedObject('foo') o1 = NamedObject('foo')
@@ -412,14 +410,14 @@ class GetMatches(TestCase):
self.log = [] self.log = []
s = "foo bar" s = "foo bar"
getmatches([NamedObject(s), NamedObject(s), NamedObject(s)], j=j) getmatches([NamedObject(s), NamedObject(s), NamedObject(s)], j=j)
self.assert_(len(self.log) > 2) assert len(self.log) > 2
self.assertEqual(0,self.log[0]) eq_(0,self.log[0])
self.assertEqual(100,self.log[-1]) eq_(100,self.log[-1])
def test_weight_words(self): def test_weight_words(self):
l = [NamedObject("foo bar"),NamedObject("bar bleh")] l = [NamedObject("foo bar"),NamedObject("bar bleh")]
m = getmatches(l, weight_words=True)[0] m = getmatches(l, weight_words=True)[0]
self.assertEqual(int((6.0 / 13.0) * 100),m.percentage) eq_(int((6.0 / 13.0) * 100),m.percentage)
def test_similar_word(self): def test_similar_word(self):
l = [NamedObject("foobar"),NamedObject("foobars")] l = [NamedObject("foobar"),NamedObject("foobars")]
@@ -439,7 +437,7 @@ class GetMatches(TestCase):
def test_double_words_get_counted_only_once(self): def test_double_words_get_counted_only_once(self):
l = [NamedObject("foo bar foo bleh"),NamedObject("foo bar bleh bar")] l = [NamedObject("foo bar foo bleh"),NamedObject("foo bar bleh bar")]
m = getmatches(l)[0] m = getmatches(l)[0]
self.assertEqual(75,m.percentage) eq_(75,m.percentage)
def test_with_fields(self): def test_with_fields(self):
o1 = NamedObject("foo bar - foo bleh") o1 = NamedObject("foo bar - foo bleh")
@@ -447,7 +445,7 @@ class GetMatches(TestCase):
o1.words = getfields(o1.name) o1.words = getfields(o1.name)
o2.words = getfields(o2.name) o2.words = getfields(o2.name)
m = getmatches([o1, o2])[0] m = getmatches([o1, o2])[0]
self.assertEqual(50, m.percentage) eq_(50, m.percentage)
def test_with_fields_no_order(self): def test_with_fields_no_order(self):
o1 = NamedObject("foo bar - foo bleh") o1 = NamedObject("foo bar - foo bleh")
@@ -475,9 +473,9 @@ class GetMatches(TestCase):
def test_min_match_percentage(self): def test_min_match_percentage(self):
l = [NamedObject("foo bar"),NamedObject("bar bleh"),NamedObject("a b c foo")] l = [NamedObject("foo bar"),NamedObject("bar bleh"),NamedObject("a b c foo")]
r = getmatches(l, min_match_percentage=50) r = getmatches(l, min_match_percentage=50)
self.assertEqual(1,len(r)) #Only "foo bar" / "bar bleh" should match eq_(1,len(r)) #Only "foo bar" / "bar bleh" should match
def test_MemoryError(self): def test_MemoryError(self, monkeypatch):
@log_calls @log_calls
def mocked_match(first, second, flags): def mocked_match(first, second, flags):
if len(mocked_match.calls) > 42: if len(mocked_match.calls) > 42:
@@ -485,35 +483,35 @@ class GetMatches(TestCase):
return Match(first, second, 0) return Match(first, second, 0)
objects = [NamedObject() for i in range(10)] # results in 45 matches objects = [NamedObject() for i in range(10)] # results in 45 matches
self.mock(engine, 'get_match', mocked_match) monkeypatch.setattr(engine, 'get_match', mocked_match)
try: try:
r = getmatches(objects) r = getmatches(objects)
except MemoryError: except MemoryError:
self.fail('MemorryError must be handled') self.fail('MemorryError must be handled')
self.assertEqual(42, len(r)) eq_(42, len(r))
class GetMatchesByContents(TestCase): class TestCaseGetMatchesByContents:
def test_dont_compare_empty_files(self): def test_dont_compare_empty_files(self):
o1, o2 = no(size=0), no(size=0) o1, o2 = no(size=0), no(size=0)
assert not getmatches_by_contents([o1, o2]) assert not getmatches_by_contents([o1, o2])
class TCGroup(TestCase): class TestCaseGroup:
def test_empy(self): def test_empy(self):
g = Group() g = Group()
self.assertEqual(None,g.ref) eq_(None,g.ref)
self.assertEqual([],g.dupes) eq_([],g.dupes)
self.assertEqual(0,len(g.matches)) eq_(0,len(g.matches))
def test_add_match(self): def test_add_match(self):
g = Group() g = Group()
m = get_match(NamedObject("foo",True),NamedObject("bar",True)) m = get_match(NamedObject("foo",True),NamedObject("bar",True))
g.add_match(m) g.add_match(m)
self.assert_(g.ref is m.first) assert g.ref is m.first
self.assertEqual([m.second],g.dupes) eq_([m.second],g.dupes)
self.assertEqual(1,len(g.matches)) eq_(1,len(g.matches))
self.assert_(m in g.matches) assert m in g.matches
def test_multiple_add_match(self): def test_multiple_add_match(self):
g = Group() g = Group()
@@ -522,49 +520,49 @@ class TCGroup(TestCase):
o3 = NamedObject("c",True) o3 = NamedObject("c",True)
o4 = NamedObject("d",True) o4 = NamedObject("d",True)
g.add_match(get_match(o1,o2)) g.add_match(get_match(o1,o2))
self.assert_(g.ref is o1) assert g.ref is o1
self.assertEqual([o2],g.dupes) eq_([o2],g.dupes)
self.assertEqual(1,len(g.matches)) eq_(1,len(g.matches))
g.add_match(get_match(o1,o3)) g.add_match(get_match(o1,o3))
self.assertEqual([o2],g.dupes) eq_([o2],g.dupes)
self.assertEqual(2,len(g.matches)) eq_(2,len(g.matches))
g.add_match(get_match(o2,o3)) g.add_match(get_match(o2,o3))
self.assertEqual([o2,o3],g.dupes) eq_([o2,o3],g.dupes)
self.assertEqual(3,len(g.matches)) eq_(3,len(g.matches))
g.add_match(get_match(o1,o4)) g.add_match(get_match(o1,o4))
self.assertEqual([o2,o3],g.dupes) eq_([o2,o3],g.dupes)
self.assertEqual(4,len(g.matches)) eq_(4,len(g.matches))
g.add_match(get_match(o2,o4)) g.add_match(get_match(o2,o4))
self.assertEqual([o2,o3],g.dupes) eq_([o2,o3],g.dupes)
self.assertEqual(5,len(g.matches)) eq_(5,len(g.matches))
g.add_match(get_match(o3,o4)) g.add_match(get_match(o3,o4))
self.assertEqual([o2,o3,o4],g.dupes) eq_([o2,o3,o4],g.dupes)
self.assertEqual(6,len(g.matches)) eq_(6,len(g.matches))
def test_len(self): def test_len(self):
g = Group() g = Group()
self.assertEqual(0,len(g)) eq_(0,len(g))
g.add_match(get_match(NamedObject("foo",True),NamedObject("bar",True))) g.add_match(get_match(NamedObject("foo",True),NamedObject("bar",True)))
self.assertEqual(2,len(g)) eq_(2,len(g))
def test_add_same_match_twice(self): def test_add_same_match_twice(self):
g = Group() g = Group()
m = get_match(NamedObject("foo",True),NamedObject("foo",True)) m = get_match(NamedObject("foo",True),NamedObject("foo",True))
g.add_match(m) g.add_match(m)
self.assertEqual(2,len(g)) eq_(2,len(g))
self.assertEqual(1,len(g.matches)) eq_(1,len(g.matches))
g.add_match(m) g.add_match(m)
self.assertEqual(2,len(g)) eq_(2,len(g))
self.assertEqual(1,len(g.matches)) eq_(1,len(g.matches))
def test_in(self): def test_in(self):
g = Group() g = Group()
o1 = NamedObject("foo",True) o1 = NamedObject("foo",True)
o2 = NamedObject("bar",True) o2 = NamedObject("bar",True)
self.assert_(o1 not in g) assert o1 not in g
g.add_match(get_match(o1,o2)) g.add_match(get_match(o1,o2))
self.assert_(o1 in g) assert o1 in g
self.assert_(o2 in g) assert o2 in g
def test_remove(self): def test_remove(self):
g = Group() g = Group()
@@ -574,14 +572,14 @@ class TCGroup(TestCase):
g.add_match(get_match(o1,o2)) g.add_match(get_match(o1,o2))
g.add_match(get_match(o1,o3)) g.add_match(get_match(o1,o3))
g.add_match(get_match(o2,o3)) g.add_match(get_match(o2,o3))
self.assertEqual(3,len(g.matches)) eq_(3,len(g.matches))
self.assertEqual(3,len(g)) eq_(3,len(g))
g.remove_dupe(o3) g.remove_dupe(o3)
self.assertEqual(1,len(g.matches)) eq_(1,len(g.matches))
self.assertEqual(2,len(g)) eq_(2,len(g))
g.remove_dupe(o1) g.remove_dupe(o1)
self.assertEqual(0,len(g.matches)) eq_(0,len(g.matches))
self.assertEqual(0,len(g)) eq_(0,len(g))
def test_remove_with_ref_dupes(self): def test_remove_with_ref_dupes(self):
g = Group() g = Group()
@@ -594,21 +592,21 @@ class TCGroup(TestCase):
o1.is_ref = True o1.is_ref = True
o2.is_ref = True o2.is_ref = True
g.remove_dupe(o3) g.remove_dupe(o3)
self.assertEqual(0,len(g)) eq_(0,len(g))
def test_switch_ref(self): def test_switch_ref(self):
o1 = NamedObject(with_words=True) o1 = NamedObject(with_words=True)
o2 = NamedObject(with_words=True) o2 = NamedObject(with_words=True)
g = Group() g = Group()
g.add_match(get_match(o1,o2)) g.add_match(get_match(o1,o2))
self.assert_(o1 is g.ref) assert o1 is g.ref
g.switch_ref(o2) g.switch_ref(o2)
self.assert_(o2 is g.ref) assert o2 is g.ref
self.assertEqual([o1],g.dupes) eq_([o1],g.dupes)
g.switch_ref(o2) g.switch_ref(o2)
self.assert_(o2 is g.ref) assert o2 is g.ref
g.switch_ref(NamedObject('',True)) g.switch_ref(NamedObject('',True))
self.assert_(o2 is g.ref) assert o2 is g.ref
def test_get_match_of(self): def test_get_match_of(self):
g = Group() g = Group()
@@ -616,10 +614,10 @@ class TCGroup(TestCase):
g.add_match(m) g.add_match(m)
o = g.dupes[0] o = g.dupes[0]
m = g.get_match_of(o) m = g.get_match_of(o)
self.assert_(g.ref in m) assert g.ref in m
self.assert_(o in m) assert o in m
self.assert_(g.get_match_of(NamedObject('',True)) is None) assert g.get_match_of(NamedObject('',True)) is None
self.assert_(g.get_match_of(g.ref) is None) assert g.get_match_of(g.ref) is None
def test_percentage(self): def test_percentage(self):
#percentage should return the avg percentage in relation to the ref #percentage should return the avg percentage in relation to the ref
@@ -631,18 +629,18 @@ class TCGroup(TestCase):
g.add_match(m1) g.add_match(m1)
g.add_match(m2) g.add_match(m2)
g.add_match(m3) g.add_match(m3)
self.assertEqual(75,g.percentage) eq_(75,g.percentage)
g.switch_ref(g.dupes[0]) g.switch_ref(g.dupes[0])
self.assertEqual(66,g.percentage) eq_(66,g.percentage)
g.remove_dupe(g.dupes[0]) g.remove_dupe(g.dupes[0])
self.assertEqual(33,g.percentage) eq_(33,g.percentage)
g.add_match(m1) g.add_match(m1)
g.add_match(m2) g.add_match(m2)
self.assertEqual(66,g.percentage) eq_(66,g.percentage)
def test_percentage_on_empty_group(self): def test_percentage_on_empty_group(self):
g = Group() g = Group()
self.assertEqual(0,g.percentage) eq_(0,g.percentage)
def test_prioritize(self): def test_prioritize(self):
m1,m2,m3 = get_match_triangle() m1,m2,m3 = get_match_triangle()
@@ -656,9 +654,9 @@ class TCGroup(TestCase):
g.add_match(m1) g.add_match(m1)
g.add_match(m2) g.add_match(m2)
g.add_match(m3) g.add_match(m3)
self.assert_(o1 is g.ref) assert o1 is g.ref
g.prioritize(lambda x:x.name) g.prioritize(lambda x:x.name)
self.assert_(o3 is g.ref) assert o3 is g.ref
def test_prioritize_with_tie_breaker(self): def test_prioritize_with_tie_breaker(self):
# if the ref has the same key as one or more of the dupe, run the tie_breaker func among them # if the ref has the same key as one or more of the dupe, run the tie_breaker func among them
@@ -666,7 +664,7 @@ class TCGroup(TestCase):
o1, o2, o3 = g.ordered o1, o2, o3 = g.ordered
tie_breaker = lambda ref, dupe: dupe is o3 tie_breaker = lambda ref, dupe: dupe is o3
g.prioritize(lambda x:0, tie_breaker) g.prioritize(lambda x:0, tie_breaker)
self.assertTrue(g.ref is o3) assert g.ref is o3
def test_prioritize_with_tie_breaker_runs_on_all_dupes(self): def test_prioritize_with_tie_breaker_runs_on_all_dupes(self):
# Even if a dupe is chosen to switch with ref with a tie breaker, we still run the tie breaker # Even if a dupe is chosen to switch with ref with a tie breaker, we still run the tie breaker
@@ -678,7 +676,7 @@ class TCGroup(TestCase):
o3.foo = 3 o3.foo = 3
tie_breaker = lambda ref, dupe: dupe.foo > ref.foo tie_breaker = lambda ref, dupe: dupe.foo > ref.foo
g.prioritize(lambda x:0, tie_breaker) g.prioritize(lambda x:0, tie_breaker)
self.assertTrue(g.ref is o3) assert g.ref is o3
def test_prioritize_with_tie_breaker_runs_only_on_tie_dupes(self): def test_prioritize_with_tie_breaker_runs_only_on_tie_dupes(self):
# The tie breaker only runs on dupes that had the same value for the key_func # The tie breaker only runs on dupes that had the same value for the key_func
@@ -693,14 +691,14 @@ class TCGroup(TestCase):
key_func = lambda x: -x.foo key_func = lambda x: -x.foo
tie_breaker = lambda ref, dupe: dupe.bar > ref.bar tie_breaker = lambda ref, dupe: dupe.bar > ref.bar
g.prioritize(key_func, tie_breaker) g.prioritize(key_func, tie_breaker)
self.assertTrue(g.ref is o2) assert g.ref is o2
def test_list_like(self): def test_list_like(self):
g = Group() g = Group()
o1,o2 = (NamedObject("foo",True),NamedObject("bar",True)) o1,o2 = (NamedObject("foo",True),NamedObject("bar",True))
g.add_match(get_match(o1,o2)) g.add_match(get_match(o1,o2))
self.assert_(g[0] is o1) assert g[0] is o1
self.assert_(g[1] is o2) assert g[1] is o2
def test_discard_matches(self): def test_discard_matches(self):
g = Group() g = Group()
@@ -708,33 +706,33 @@ class TCGroup(TestCase):
g.add_match(get_match(o1,o2)) g.add_match(get_match(o1,o2))
g.add_match(get_match(o1,o3)) g.add_match(get_match(o1,o3))
g.discard_matches() g.discard_matches()
self.assertEqual(1,len(g.matches)) eq_(1,len(g.matches))
self.assertEqual(0,len(g.candidates)) eq_(0,len(g.candidates))
class TCget_groups(TestCase): class TestCaseget_groups:
def test_empty(self): def test_empty(self):
r = get_groups([]) r = get_groups([])
self.assertEqual([],r) eq_([],r)
def test_simple(self): def test_simple(self):
l = [NamedObject("foo bar"),NamedObject("bar bleh")] l = [NamedObject("foo bar"),NamedObject("bar bleh")]
matches = getmatches(l) matches = getmatches(l)
m = matches[0] m = matches[0]
r = get_groups(matches) r = get_groups(matches)
self.assertEqual(1,len(r)) eq_(1,len(r))
g = r[0] g = r[0]
self.assert_(g.ref is m.first) assert g.ref is m.first
self.assertEqual([m.second],g.dupes) eq_([m.second],g.dupes)
def test_group_with_multiple_matches(self): def test_group_with_multiple_matches(self):
#This results in 3 matches #This results in 3 matches
l = [NamedObject("foo"),NamedObject("foo"),NamedObject("foo")] l = [NamedObject("foo"),NamedObject("foo"),NamedObject("foo")]
matches = getmatches(l) matches = getmatches(l)
r = get_groups(matches) r = get_groups(matches)
self.assertEqual(1,len(r)) eq_(1,len(r))
g = r[0] g = r[0]
self.assertEqual(3,len(g)) eq_(3,len(g))
def test_must_choose_a_group(self): def test_must_choose_a_group(self):
l = [NamedObject("a b"),NamedObject("a b"),NamedObject("b c"),NamedObject("c d"),NamedObject("c d")] l = [NamedObject("a b"),NamedObject("a b"),NamedObject("b c"),NamedObject("c d"),NamedObject("c d")]
@@ -742,8 +740,8 @@ class TCget_groups(TestCase):
#"b c" can go either of them, but not both. #"b c" can go either of them, but not both.
matches = getmatches(l) matches = getmatches(l)
r = get_groups(matches) r = get_groups(matches)
self.assertEqual(2,len(r)) eq_(2,len(r))
self.assertEqual(5,len(r[0])+len(r[1])) eq_(5,len(r[0])+len(r[1]))
def test_should_all_go_in_the_same_group(self): def test_should_all_go_in_the_same_group(self):
l = [NamedObject("a b"),NamedObject("a b"),NamedObject("a b"),NamedObject("a b")] l = [NamedObject("a b"),NamedObject("a b"),NamedObject("a b"),NamedObject("a b")]
@@ -751,7 +749,7 @@ class TCget_groups(TestCase):
#"b c" can fit in both, but it must be in only one of them #"b c" can fit in both, but it must be in only one of them
matches = getmatches(l) matches = getmatches(l)
r = get_groups(matches) r = get_groups(matches)
self.assertEqual(1,len(r)) eq_(1,len(r))
def test_give_priority_to_matches_with_higher_percentage(self): def test_give_priority_to_matches_with_higher_percentage(self):
o1 = NamedObject(with_words=True) o1 = NamedObject(with_words=True)
@@ -760,19 +758,19 @@ class TCget_groups(TestCase):
m1 = Match(o1, o2, 1) m1 = Match(o1, o2, 1)
m2 = Match(o2, o3, 2) m2 = Match(o2, o3, 2)
r = get_groups([m1,m2]) r = get_groups([m1,m2])
self.assertEqual(1,len(r)) eq_(1,len(r))
g = r[0] g = r[0]
self.assertEqual(2,len(g)) eq_(2,len(g))
self.assert_(o1 not in g) assert o1 not in g
self.assert_(o2 in g) assert o2 in g
self.assert_(o3 in g) assert o3 in g
def test_four_sized_group(self): def test_four_sized_group(self):
l = [NamedObject("foobar") for i in range(4)] l = [NamedObject("foobar") for i in range(4)]
m = getmatches(l) m = getmatches(l)
r = get_groups(m) r = get_groups(m)
self.assertEqual(1,len(r)) eq_(1,len(r))
self.assertEqual(4,len(r[0])) eq_(4,len(r[0]))
def test_referenced_by_ref2(self): def test_referenced_by_ref2(self):
o1 = NamedObject(with_words=True) o1 = NamedObject(with_words=True)
@@ -782,7 +780,7 @@ class TCget_groups(TestCase):
m2 = get_match(o3,o1) m2 = get_match(o3,o1)
m3 = get_match(o3,o2) m3 = get_match(o3,o2)
r = get_groups([m1,m2,m3]) r = get_groups([m1,m2,m3])
self.assertEqual(3,len(r[0])) eq_(3,len(r[0]))
def test_job(self): def test_job(self):
def do_progress(p,d=''): def do_progress(p,d=''):
@@ -795,8 +793,8 @@ class TCget_groups(TestCase):
#101%: To make sure it is processed first so the job test works correctly #101%: To make sure it is processed first so the job test works correctly
m4 = Match(NamedObject('a',True), NamedObject('a',True), 101) m4 = Match(NamedObject('a',True), NamedObject('a',True), 101)
get_groups([m1,m2,m3,m4],j) get_groups([m1,m2,m3,m4],j)
self.assertEqual(0,self.log[0]) eq_(0,self.log[0])
self.assertEqual(100,self.log[-1]) eq_(100,self.log[-1])
def test_group_admissible_discarded_dupes(self): def test_group_admissible_discarded_dupes(self):
# If, with a (A, B, C, D) set, all match with A, but C and D don't match with B and that the # If, with a (A, B, C, D) set, all match with A, but C and D don't match with B and that the

Some files were not shown because too many files have changed in this diff Show More