mirror of
https://github.com/arsenetar/dupeguru.git
synced 2026-01-25 08:01:39 +00:00
Compare commits
180 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2a55ffd31 | ||
|
|
793c2aa423 | ||
|
|
5daa332b6c | ||
|
|
d5511a857c | ||
|
|
7fecd21331 | ||
|
|
88b79e512f | ||
|
|
853bf63777 | ||
|
|
ff16fea54a | ||
|
|
a03e2a69d4 | ||
|
|
56a39df635 | ||
|
|
ac1593ff75 | ||
|
|
4d66b4667c | ||
|
|
fdde538b66 | ||
|
|
de1147219c | ||
|
|
371426a08e | ||
|
|
75eb005ba0 | ||
|
|
601b67145c | ||
|
|
c65afbc057 | ||
|
|
378589a473 | ||
|
|
fa264972a4 | ||
|
|
6b10e01c03 | ||
|
|
5a6d74ab37 | ||
|
|
73f1bb6968 | ||
|
|
d1a7f51859 | ||
|
|
2ae16396a6 | ||
|
|
ef090a5dc5 | ||
|
|
5c0799e82b | ||
|
|
fa2ee01d3f | ||
|
|
d6ba80bd3f | ||
|
|
ee96d5f88c | ||
|
|
e96a917bef | ||
|
|
769b816998 | ||
|
|
ff891c210c | ||
|
|
3ed5e1bf95 | ||
|
|
5bc8581389 | ||
|
|
7346b422d5 | ||
|
|
5c80ac1c74 | ||
|
|
699023992c | ||
|
|
454ce604ad | ||
|
|
1e0f6bfecb | ||
|
|
7f10aa3de2 | ||
|
|
f8764ab85e | ||
|
|
aa8544308e | ||
|
|
31fc70e0f8 | ||
|
|
a16af4560b | ||
|
|
0782ba0dab | ||
|
|
83725667a4 | ||
|
|
f4b3163b04 | ||
|
|
6cd745f429 | ||
|
|
6131f7f6bf | ||
|
|
dd4faa030f | ||
|
|
ab8691f5ac | ||
|
|
77ab073cdb | ||
|
|
87e0011525 | ||
|
|
7af3bb7226 | ||
|
|
5573352ce6 | ||
|
|
e6486e08ab | ||
|
|
48badaa927 | ||
|
|
2f13bf677e | ||
|
|
e63abc1b4b | ||
|
|
88334acdef | ||
|
|
0491aa9f6e | ||
|
|
5be76d7c0f | ||
|
|
3b510389fc | ||
|
|
32d88e9249 | ||
|
|
7b1a1ff4bb | ||
|
|
19beb919d0 | ||
|
|
ba09e8bf4d | ||
|
|
26dd2d0e8e | ||
|
|
69b15d58a2 | ||
|
|
ba68789fb9 | ||
|
|
47a6ceffbc | ||
|
|
b17ca66f73 | ||
|
|
93bc609026 | ||
|
|
3ea51c2e15 | ||
|
|
1d9897ea60 | ||
|
|
b6cb00bc79 | ||
|
|
6dd53c6bfd | ||
|
|
07df5126b3 | ||
|
|
47b38c7d45 | ||
|
|
0e97bec7b2 | ||
|
|
b182585d46 | ||
|
|
e8f92535d3 | ||
|
|
d62c3663e9 | ||
|
|
6b0bfda9fb | ||
|
|
7477330961 | ||
|
|
1f71157063 | ||
|
|
905988c592 | ||
|
|
310951bfa8 | ||
|
|
64c1087856 | ||
|
|
cab6d924aa | ||
|
|
c3a972d39b | ||
|
|
33d44d4d24 | ||
|
|
fd89cf2482 | ||
|
|
112ffb981f | ||
|
|
514426b980 | ||
|
|
a4bf1c8be6 | ||
|
|
9b82e1478f | ||
|
|
d5f145d57e | ||
|
|
bab891ee74 | ||
|
|
a65fd7d0d0 | ||
|
|
46836cc805 | ||
|
|
42559f13d8 | ||
|
|
87351b5920 | ||
|
|
e68dcf189c | ||
|
|
5d62b8389c | ||
|
|
c50aebe76d | ||
|
|
a610f3fde7 | ||
|
|
626391a1d9 | ||
|
|
1bedfe75ea | ||
|
|
86ecc8d4d5 | ||
|
|
9eca84efe1 | ||
|
|
8a6fb6dcba | ||
|
|
e3706fa923 | ||
|
|
8193bc5f60 | ||
|
|
504ecaee5e | ||
|
|
7c9e836572 | ||
|
|
5db0f09b43 | ||
|
|
195bc4ef21 | ||
|
|
6b190bc184 | ||
|
|
39f1cac2c8 | ||
|
|
d193eed519 | ||
|
|
2d80b0e12f | ||
|
|
b50d99be9c | ||
|
|
af41876a5e | ||
|
|
76d351d8be | ||
|
|
b5dd9651c3 | ||
|
|
3e34502014 | ||
|
|
5e57f9cbd6 | ||
|
|
8edb869fdc | ||
|
|
37238c7f57 | ||
|
|
9edee82fa1 | ||
|
|
f7aaea79af | ||
|
|
3c75d2f8b7 | ||
|
|
64c67e19d2 | ||
|
|
d4db8faad8 | ||
|
|
7957b73b4a | ||
|
|
69838c44af | ||
|
|
8e2953aef6 | ||
|
|
8dda616502 | ||
|
|
484512e35b | ||
|
|
c8cd05c07d | ||
|
|
7ffefe6259 | ||
|
|
cd9b7f2f11 | ||
|
|
b372974437 | ||
|
|
7464e0f799 | ||
|
|
25e12f1775 | ||
|
|
6416469f78 | ||
|
|
922ce5ae36 | ||
|
|
9ca8a199c0 | ||
|
|
a570406ac8 | ||
|
|
719edb6b6e | ||
|
|
d075218621 | ||
|
|
7509943938 | ||
|
|
774da9d2f8 | ||
|
|
978fd383e8 | ||
|
|
8551fc23fe | ||
|
|
fb711edeeb | ||
|
|
352a21acaa | ||
|
|
0b9d936317 | ||
|
|
dc500243e9 | ||
|
|
21203b8341 | ||
|
|
5b03447640 | ||
|
|
d34158db2c | ||
|
|
65a17390c7 | ||
|
|
0e96f0917c | ||
|
|
3d62a7e64a | ||
|
|
962805936e | ||
|
|
967aeecf5b | ||
|
|
348b039fa3 | ||
|
|
6e9b1f4fa3 | ||
|
|
f1d447d1aa | ||
|
|
a7c6f47dbe | ||
|
|
0446e89bfe | ||
|
|
e41457913f | ||
|
|
cea1ec7641 | ||
|
|
cc362deb87 | ||
|
|
7ec64e8a3d | ||
|
|
ff2461df9d | ||
|
|
192cd2733c |
@@ -6,17 +6,20 @@ syntax: glob
|
|||||||
*.mode1v3
|
*.mode1v3
|
||||||
*.pbxuser
|
*.pbxuser
|
||||||
*.tm_build_errors
|
*.tm_build_errors
|
||||||
|
*.pyd
|
||||||
conf.yaml
|
conf.yaml
|
||||||
build
|
build
|
||||||
core_pe/modules/block/block.c
|
|
||||||
core_pe/modules/cache/cache.c
|
|
||||||
cocoa/*/Info.plist
|
cocoa/*/Info.plist
|
||||||
cocoa/*/build
|
cocoa/*/build
|
||||||
cocoa/*/dg_cocoa.plugin
|
cocoa/*/dg_cocoa.plugin
|
||||||
qt/base/*_rc.py
|
qt/base/*_rc.py
|
||||||
qt/base/*_ui.py
|
qt/base/*_ui.py
|
||||||
qt/*/*_ui.py
|
qt/*/*_ui.py
|
||||||
qt/pe/modules/block/block.c
|
qt/*/build
|
||||||
|
qt/*/dist
|
||||||
|
qt/*/install
|
||||||
|
qt/*/logdict*.log
|
||||||
|
qt/*/warn*.txt
|
||||||
help_se/dupeguru_help
|
help_se/dupeguru_help
|
||||||
help_me/dupeguru_me_help
|
help_me/dupeguru_me_help
|
||||||
help_pe/dupeguru_pe_help
|
help_pe/dupeguru_pe_help
|
||||||
14
.hgtags
14
.hgtags
@@ -7,3 +7,17 @@ adc73ccd14b1386cb04dee773c53a2d126800e31 se2.9.0
|
|||||||
cbcf9c80fee4c908ef2efbf1c143c9e47676c9b2 pe1.8.0
|
cbcf9c80fee4c908ef2efbf1c143c9e47676c9b2 pe1.8.0
|
||||||
61c4101851bdea3cb37dfb76f0d404c78c7c594c se2.9.1
|
61c4101851bdea3cb37dfb76f0d404c78c7c594c se2.9.1
|
||||||
0e923897a3389331d4ab3debbc40b8dd616199d9 pe1.8.1
|
0e923897a3389331d4ab3debbc40b8dd616199d9 pe1.8.1
|
||||||
|
2c454eca9ebe93b6cf34916068f828a6a39e3eaf me5.7.1
|
||||||
|
19e40bab20521d4256acf325dba9b32e95e135c5 pe1.8.2
|
||||||
|
7b7c5a66ebee4e4b8125330d24fe9ce1a070ff25 se2.9.2
|
||||||
|
1cef6d39855f85d4be728646bc78b860e6d4e398 pe1.8.3
|
||||||
|
90ed56ee602666db2f267f73eac6f824347039b5 me5.7.2
|
||||||
|
4c3cb1e671a333eabde1151c7c6ffb3609cab025 pe1.8.4
|
||||||
|
0a71306434bca51bea9a5d5ae54fe1bf0e4900d8 pe1.8.5
|
||||||
|
556baf4a410779e9bbf43129de133e4c4b26d679 pe1.8.6
|
||||||
|
9149024283959a50fe9a47a5f175b905d1672c19 se2.10.0
|
||||||
|
388a7e5aef6385e515189f4a15b4c4fed3ae2fcf me5.8.0
|
||||||
|
27501167e3b9262ecb60c967941294f36d77eb25 pe1.9.0
|
||||||
|
cb0a860430bacd712820bce426bcf47a4135efe1 se2.10.1
|
||||||
|
cb0a860430bacd712820bce426bcf47a4135efe1 se2.10.1
|
||||||
|
f71d405e62badcfdc1b037facaac043cece40ee5 se2.10.1
|
||||||
|
|||||||
25
README
25
README
@@ -12,9 +12,8 @@ This package contains the source for dupeGuru. To learns how to build it, refer
|
|||||||
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 svn:externals):
|
||||||
|
|
||||||
- hsutil: A collection of helpers used across HS applications.
|
- hscommon: A collection of helpers used across HS applications.
|
||||||
- hsdocgen: An ad-hoc document generation used across HS project (used for help files)
|
- hsdocgen: An ad-hoc document generation used across HS project (used for help files)
|
||||||
- hsmedia: A library to read audio file metadata, used in dupeGuru ME.
|
|
||||||
- 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.
|
||||||
- qtlib: A collection of helpers used across Qt UI codebases of HS applications.
|
- qtlib: A collection of helpers used across Qt UI codebases of HS applications.
|
||||||
|
|
||||||
@@ -27,26 +26,29 @@ General dependencies
|
|||||||
-----
|
-----
|
||||||
|
|
||||||
- Python 2.6 (http://www.python.org)
|
- Python 2.6 (http://www.python.org)
|
||||||
|
- Send2Trash (http://hg.hardcoded.net/send2trash)
|
||||||
|
- hsutil (http://hg.hardcoded.net/hsutil)
|
||||||
|
- hsaudiotag (for ME) (http://hg.hardcoded.net/hsaudiotag)
|
||||||
|
- lxml, to read and write XML files. (http://codespeak.net/lxml/)
|
||||||
- Mako, to generate help files. (http://www.makotemplates.org/)
|
- Mako, to generate help files. (http://www.makotemplates.org/)
|
||||||
- PyYaml, for help files and the build system. (http://pyyaml.org/)
|
- PyYaml, for help files and the build system. (http://pyyaml.org/)
|
||||||
- Nose, to run unit tests. (http://somethingaboutorange.com/mrl/projects/nose/)
|
- py.test, to run unit tests. (http://codespeak.net/py/dist/test/)
|
||||||
- Cython to compile a few optimized bottlenecks. (http://www.cython.org/)
|
|
||||||
- Python Imaging Library for dupeGuru PE. (http://www.pythonware.com/products/pil/)
|
|
||||||
|
|
||||||
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. Although Tiger support has been dropped with dupeGuru 1.7, I still use PyObjC 1.4 because funky stuff happens with newer releases. However, it's mostly related to packaging with py2app. (http://pyobjc.sourceforge.net/)
|
- PyObjC 2.2. (http://pyobjc.sourceforge.net/)
|
||||||
- py2app (http://svn.pythonmac.org/py2app/py2app/trunk/doc/index.html)
|
- py2app (http://svn.pythonmac.org/py2app/py2app/trunk/doc/index.html)
|
||||||
|
|
||||||
Windows prerequisites
|
Windows prerequisites
|
||||||
---
|
---
|
||||||
|
|
||||||
- Visual Studio 2008 (Express is enough) is needed to build the Cython extensions. (http://www.microsoft.com/Express/)
|
- Visual Studio 2008 (Express is enough) is needed to build C extensions. (http://www.microsoft.com/Express/)
|
||||||
- PyQt 4.6 (http://www.riverbankcomputing.co.uk/news)
|
- PyQt 4.6 (http://www.riverbankcomputing.co.uk/news)
|
||||||
- PyInstaller, if you want to build a exe. You don't need it if you just want to run dupeGuru. (http://www.pyinstaller.org/)
|
- Python Imaging Library for dupeGuru PE. (http://www.pythonware.com/products/pil/)
|
||||||
|
- cx_Freeze, if you want to build a exe. You don't need it if you just want to run dupeGuru. (http://cx-freeze.sourceforge.net/)
|
||||||
- Advanced Installer, if you want to build the installer file. (http://www.advancedinstaller.com/)
|
- Advanced Installer, if you want to build the installer file. (http://www.advancedinstaller.com/)
|
||||||
|
|
||||||
Building dupeGuru
|
Building dupeGuru
|
||||||
@@ -56,7 +58,7 @@ First, make sure you meet the dependencies listed in the section above. Then you
|
|||||||
|
|
||||||
python configure.py
|
python configure.py
|
||||||
|
|
||||||
If you want, you can specify a UI to use with the `--ui` option. So, if you want to build dupeGuru with Qt on OS X, then you have to type `python configure.py --ui=qt`. You can also use the `--dev` flag to indicate a dev build (it will build `mg_cocoa.plugin` in alias mode).
|
If you want, you can specify a UI to use with the `--ui` option. So, if you want to build dupeGuru with Qt on OS X, then you have to type `python configure.py --ui=qt`. You can also use the `--dev` flag to indicate a dev build (it will build `dg_cocoa.plugin` in alias mode and use the "dev" config in XCode).
|
||||||
|
|
||||||
Then, just build the thing and then run it with:
|
Then, just build the thing and then run it with:
|
||||||
|
|
||||||
@@ -66,3 +68,8 @@ Then, just build the thing and then run it with:
|
|||||||
If you want to create ready-to-upload package, run:
|
If you want to create ready-to-upload package, run:
|
||||||
|
|
||||||
python package.py
|
python package.py
|
||||||
|
|
||||||
|
64-bit on OS X
|
||||||
|
---
|
||||||
|
|
||||||
|
The "release" configuration of dupeGuru's XCode project build with archs "i386 x86_64 ppc". However there are currently problems with py2app and 64 bit. If you want to correctly build 64-bit apps, refer to http://www.hardcoded.net/articles/building-64-bit-pyobjc-applications-with-py2app.htm .
|
||||||
115
build.py
115
build.py
@@ -15,82 +15,91 @@ import shutil
|
|||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from hsdocgen import generate_help, filters
|
from hscommon import helpgen
|
||||||
from hsutil.build import add_to_pythonpath, print_and_do, build_all_qt_ui, copy_packages
|
from hscommon.build import add_to_pythonpath, print_and_do, build_all_qt_ui, copy_packages
|
||||||
|
|
||||||
|
def build_cocoa(edition, dev, help_destpath):
|
||||||
|
if not dev:
|
||||||
|
print "Building help index"
|
||||||
|
os.system('open -a /Developer/Applications/Utilities/Help\\ Indexer.app {0}'.format(help_destpath))
|
||||||
|
|
||||||
|
print "Building dg_cocoa.plugin"
|
||||||
|
if op.exists('build'):
|
||||||
|
shutil.rmtree('build')
|
||||||
|
os.mkdir('build')
|
||||||
|
if not dev:
|
||||||
|
specific_packages = {
|
||||||
|
'se': ['core_se'],
|
||||||
|
'me': ['core_me'],
|
||||||
|
'pe': ['core_pe'],
|
||||||
|
}[edition]
|
||||||
|
copy_packages(['core', 'hscommon'] + specific_packages, 'build')
|
||||||
|
cocoa_project_path = 'cocoa/{0}'.format(edition)
|
||||||
|
shutil.copy(op.join(cocoa_project_path, 'dg_cocoa.py'), 'build')
|
||||||
|
os.chdir('build')
|
||||||
|
script_args = ['py2app', '-A'] if dev else ['py2app']
|
||||||
|
setup(
|
||||||
|
script_args = script_args,
|
||||||
|
plugin = ['dg_cocoa.py'],
|
||||||
|
setup_requires = ['py2app'],
|
||||||
|
)
|
||||||
|
os.chdir('..')
|
||||||
|
pluginpath = op.join(cocoa_project_path, 'dg_cocoa.plugin')
|
||||||
|
if op.exists(pluginpath):
|
||||||
|
shutil.rmtree(pluginpath)
|
||||||
|
shutil.move('build/dist/dg_cocoa.plugin', pluginpath)
|
||||||
|
if dev:
|
||||||
|
# In alias mode, the tweakings we do to the pythonpath aren't counted in. We have to
|
||||||
|
# manually put a .pth in the plugin
|
||||||
|
pthpath = op.join(pluginpath, 'Contents/Resources/dev.pth')
|
||||||
|
open(pthpath, 'w').write(op.abspath('.'))
|
||||||
|
os.chdir(cocoa_project_path)
|
||||||
|
print "Building the XCode project"
|
||||||
|
args = []
|
||||||
|
if dev:
|
||||||
|
args.append('-configuration dev')
|
||||||
|
else:
|
||||||
|
args.append('-configuration release')
|
||||||
|
args = ' '.join(args)
|
||||||
|
os.system('xcodebuild {0}'.format(args))
|
||||||
|
os.chdir('..')
|
||||||
|
|
||||||
|
def build_qt(edition, dev):
|
||||||
|
build_all_qt_ui(op.join('qtlib', 'ui'))
|
||||||
|
build_all_qt_ui(op.join('qt', 'base'))
|
||||||
|
build_all_qt_ui(op.join('qt', edition))
|
||||||
|
print_and_do("pyrcc4 {0} > {1}".format(op.join('qt', 'base', 'dg.qrc'), op.join('qt', 'base', 'dg_rc.py')))
|
||||||
|
if edition == 'pe':
|
||||||
|
os.chdir(op.join('qt', edition))
|
||||||
|
os.system('python gen.py')
|
||||||
|
os.chdir(op.join('..', '..'))
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
conf = yaml.load(open('conf.yaml'))
|
conf = yaml.load(open('conf.yaml'))
|
||||||
edition = conf['edition']
|
edition = conf['edition']
|
||||||
ui = conf['ui']
|
ui = conf['ui']
|
||||||
dev = conf['dev']
|
dev = conf['dev']
|
||||||
build64 = conf['build64']
|
|
||||||
print "Building dupeGuru {0} with UI {1}".format(edition.upper(), ui)
|
print "Building dupeGuru {0} with UI {1}".format(edition.upper(), ui)
|
||||||
if build64:
|
|
||||||
print "If possible, 64-bit builds will be made"
|
|
||||||
if dev:
|
if dev:
|
||||||
print "Building in Dev mode"
|
print "Building in Dev mode"
|
||||||
add_to_pythonpath('.')
|
add_to_pythonpath('.')
|
||||||
print "Generating Help"
|
print "Generating Help"
|
||||||
windows = sys.platform == 'win32'
|
windows = sys.platform == 'win32'
|
||||||
tix = filters.tixgen("https://hardcoded.lighthouseapp.com/projects/31699-dupeguru/tickets/{0}")
|
profile = 'win_en' if windows else 'osx_en'
|
||||||
help_dir = 'help_{0}'.format(edition)
|
help_dir = 'help_{0}'.format(edition)
|
||||||
dest_dir = 'dupeguru_{0}_help'.format(edition) if edition != 'se' else 'dupeguru_help'
|
dest_dir = 'dupeguru_{0}_help'.format(edition) if edition != 'se' else 'dupeguru_help'
|
||||||
help_basepath = op.abspath(help_dir)
|
help_basepath = op.abspath(help_dir)
|
||||||
help_destpath = op.abspath(op.join(help_dir, dest_dir))
|
help_destpath = op.abspath(op.join(help_dir, dest_dir))
|
||||||
generate_help.main(help_basepath, help_destpath, force_render=not dev, tix=tix, windows=windows)
|
helpgen.gen(help_basepath, help_destpath, profile=profile)
|
||||||
|
|
||||||
print "Building dupeGuru"
|
print "Building dupeGuru"
|
||||||
if edition == 'pe':
|
if edition == 'pe':
|
||||||
os.chdir('core_pe')
|
os.chdir('core_pe')
|
||||||
os.system('python gen.py')
|
os.system('python gen.py')
|
||||||
os.chdir('..')
|
os.chdir('..')
|
||||||
if ui == 'cocoa':
|
if ui == 'cocoa':
|
||||||
if not dev:
|
build_cocoa(edition, dev, help_destpath)
|
||||||
print "Building help index"
|
|
||||||
os.system('open -a /Developer/Applications/Utilities/Help\\ Indexer.app {0}'.format(help_destpath))
|
|
||||||
|
|
||||||
print "Building dg_cocoa.plugin"
|
|
||||||
if op.exists('build'):
|
|
||||||
shutil.rmtree('build')
|
|
||||||
os.mkdir('build')
|
|
||||||
if not dev:
|
|
||||||
specific_packages = {
|
|
||||||
'se': ['core_se'],
|
|
||||||
'me': ['core_me', 'hsmedia'],
|
|
||||||
'pe': ['core_pe'],
|
|
||||||
}[edition]
|
|
||||||
copy_packages(['core', 'hsutil'] + specific_packages, 'build')
|
|
||||||
cocoa_project_path = 'cocoa/{0}'.format(edition)
|
|
||||||
shutil.copy(op.join(cocoa_project_path, 'dg_cocoa.py'), 'build')
|
|
||||||
os.chdir('build')
|
|
||||||
script_args = ['py2app', '-A'] if dev else ['py2app']
|
|
||||||
setup(
|
|
||||||
script_args = script_args,
|
|
||||||
plugin = ['dg_cocoa.py'],
|
|
||||||
setup_requires = ['py2app'],
|
|
||||||
)
|
|
||||||
os.chdir('..')
|
|
||||||
pluginpath = op.join(cocoa_project_path, 'dg_cocoa.plugin')
|
|
||||||
if op.exists(pluginpath):
|
|
||||||
shutil.rmtree(pluginpath)
|
|
||||||
shutil.move('build/dist/dg_cocoa.plugin', pluginpath)
|
|
||||||
if dev:
|
|
||||||
# In alias mode, the tweakings we do to the pythonpath aren't counted in. We have to
|
|
||||||
# manually put a .pth in the plugin
|
|
||||||
pthpath = op.join(pluginpath, 'Contents/Resources/dev.pth')
|
|
||||||
open(pthpath, 'w').write(op.abspath('.'))
|
|
||||||
os.chdir(cocoa_project_path)
|
|
||||||
print "Building the XCode project"
|
|
||||||
args = []
|
|
||||||
if build64:
|
|
||||||
args.append('ARCHS="x86_64 i386 ppc"')
|
|
||||||
args = ' '.join(args)
|
|
||||||
os.system('xcodebuild {0}'.format(args))
|
|
||||||
os.chdir('..')
|
|
||||||
elif ui == 'qt':
|
elif ui == 'qt':
|
||||||
os.chdir(op.join('qt', edition))
|
build_qt(edition, dev)
|
||||||
os.system('python gen.py')
|
|
||||||
os.chdir(op.join('..', '..'))
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
#import "PyDupeGuru.h"
|
#import "PyDupeGuru.h"
|
||||||
#import "ResultWindow.h"
|
#import "ResultWindow.h"
|
||||||
#import "DetailsPanel.h"
|
#import "DetailsPanel.h"
|
||||||
|
#import "DirectoryPanel.h"
|
||||||
|
|
||||||
@interface AppDelegateBase : NSObject
|
@interface AppDelegateBase : NSObject
|
||||||
{
|
{
|
||||||
@@ -19,11 +20,15 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
IBOutlet NSMenuItem *unlockMenuItem;
|
IBOutlet NSMenuItem *unlockMenuItem;
|
||||||
IBOutlet ResultWindowBase *result;
|
IBOutlet ResultWindowBase *result;
|
||||||
|
|
||||||
DetailsPanelBase *_detailsPanel;
|
DirectoryPanel *_directoryPanel;
|
||||||
|
DetailsPanel *_detailsPanel;
|
||||||
|
BOOL _savedResults;
|
||||||
}
|
}
|
||||||
- (IBAction)unlockApp:(id)sender;
|
- (IBAction)unlockApp:(id)sender;
|
||||||
|
|
||||||
- (PyDupeGuruBase *)py;
|
- (PyDupeGuruBase *)py;
|
||||||
- (RecentDirectories *)recentDirectories;
|
- (RecentDirectories *)recentDirectories;
|
||||||
- (DetailsPanelBase *)detailsPanel; // Virtual
|
- (DirectoryPanel *)directoryPanel;
|
||||||
|
- (DetailsPanel *)detailsPanel;
|
||||||
|
- (void)saveResults;
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
#import "RegistrationInterface.h"
|
#import "RegistrationInterface.h"
|
||||||
#import "Utils.h"
|
#import "Utils.h"
|
||||||
#import "Consts.h"
|
#import "Consts.h"
|
||||||
|
#import <Sparkle/SUUpdater.h>
|
||||||
|
|
||||||
@implementation AppDelegateBase
|
@implementation AppDelegateBase
|
||||||
- (IBAction)unlockApp:(id)sender
|
- (IBAction)unlockApp:(id)sender
|
||||||
@@ -28,7 +29,29 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
|
|
||||||
- (PyDupeGuruBase *)py { return py; }
|
- (PyDupeGuruBase *)py { return py; }
|
||||||
- (RecentDirectories *)recentDirectories { return recentDirectories; }
|
- (RecentDirectories *)recentDirectories { return recentDirectories; }
|
||||||
- (DetailsPanelBase *)detailsPanel { return nil; } // Virtual
|
- (DirectoryPanel *)directoryPanel
|
||||||
|
{
|
||||||
|
if (!_directoryPanel)
|
||||||
|
_directoryPanel = [[DirectoryPanel alloc] initWithParentApp:self];
|
||||||
|
return _directoryPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (DetailsPanel *)detailsPanel
|
||||||
|
{
|
||||||
|
if (!_detailsPanel)
|
||||||
|
_detailsPanel = [[DetailsPanel alloc] initWithPy:py];
|
||||||
|
return _detailsPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)saveResults
|
||||||
|
{
|
||||||
|
if (_savedResults) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
[py saveIgnoreList];
|
||||||
|
[py saveResults];
|
||||||
|
_savedResults = YES;
|
||||||
|
}
|
||||||
|
|
||||||
/* Delegate */
|
/* Delegate */
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||||
@@ -48,5 +71,47 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
//Restore results
|
//Restore results
|
||||||
[py loadIgnoreList];
|
[py loadIgnoreList];
|
||||||
[py loadResults];
|
[py loadResults];
|
||||||
|
_savedResults = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)applicationWillBecomeActive:(NSNotification *)aNotification
|
||||||
|
{
|
||||||
|
if (![[result window] isVisible])
|
||||||
|
[result showWindow:NSApp];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)applicationWillTerminate:(NSNotification *)aNotification
|
||||||
|
{
|
||||||
|
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||||
|
[ud setObject: [result getColumnsOrder] forKey:@"columnsOrder"];
|
||||||
|
[ud setObject: [result getColumnsWidth] forKey:@"columnsWidth"];
|
||||||
|
[self saveResults];
|
||||||
|
NSInteger sc = [ud integerForKey:@"sessionCountSinceLastIgnorePurge"];
|
||||||
|
if (sc >= 10)
|
||||||
|
{
|
||||||
|
sc = -1;
|
||||||
|
[py purgeIgnoreList];
|
||||||
|
}
|
||||||
|
sc++;
|
||||||
|
[ud setInteger:sc forKey:@"sessionCountSinceLastIgnorePurge"];
|
||||||
|
// 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
|
||||||
|
// But I need to release RecentDirectories so it saves the user defaults
|
||||||
|
[recentDirectories release];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)recentDirecoryClicked:(NSString *)directory
|
||||||
|
{
|
||||||
|
[[self directoryPanel] addDirectory:directory];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|||||||
@@ -8,12 +8,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
#define DuplicateSelectionChangedNotification @"DuplicateSelectionChangedNotification"
|
|
||||||
/* ResultsChangedNotification happens on major changes, which requires a complete reload of the data*/
|
|
||||||
#define ResultsChangedNotification @"ResultsChangedNotification"
|
|
||||||
/* ResultsChangedNotification happens on minor changes, which requires buffer flush*/
|
|
||||||
#define ResultsUpdatedNotification @"ResultsUpdatedNotification"
|
|
||||||
#define ResultsMarkingChangedNotification @"ResultsMarkingChangedNotification"
|
|
||||||
#define RegistrationRequired @"RegistrationRequired"
|
#define RegistrationRequired @"RegistrationRequired"
|
||||||
#define JobStarted @"JobStarted"
|
#define JobStarted @"JobStarted"
|
||||||
#define JobInProgress @"JobInProgress"
|
#define JobInProgress @"JobInProgress"
|
||||||
@@ -22,6 +16,4 @@ http://www.hardcoded.net/licenses/hs_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 DEMO_MAX_ACTION_COUNT 10
|
|
||||||
@@ -7,19 +7,19 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import "HSWindowController.h"
|
||||||
#import "PyApp.h"
|
#import "PyApp.h"
|
||||||
#import "Table.h"
|
#import "PyDetailsPanel.h"
|
||||||
|
|
||||||
|
@interface DetailsPanel : HSWindowController
|
||||||
@interface DetailsPanelBase : NSWindowController
|
|
||||||
{
|
{
|
||||||
IBOutlet TableView *detailsTable;
|
IBOutlet NSTableView *detailsTable;
|
||||||
}
|
}
|
||||||
- (id)initWithPy:(PyApp *)aPy;
|
- (id)initWithPy:(PyApp *)aPy;
|
||||||
|
- (PyDetailsPanel *)py;
|
||||||
|
|
||||||
- (void)refresh;
|
|
||||||
- (void)toggleVisibility;
|
- (void)toggleVisibility;
|
||||||
|
|
||||||
/* Notifications */
|
/* Python --> Cocoa */
|
||||||
- (void)duplicateSelectionChanged:(NSNotification *)aNotification;
|
- (void)refresh;
|
||||||
@end
|
@end
|
||||||
@@ -7,38 +7,60 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import "DetailsPanel.h"
|
#import "DetailsPanel.h"
|
||||||
#import "Consts.h"
|
#import "Utils.h"
|
||||||
|
|
||||||
@implementation DetailsPanelBase
|
@implementation DetailsPanel
|
||||||
- (id)initWithPy:(PyApp *)aPy
|
- (id)initWithPy:(PyApp *)aPy
|
||||||
{
|
{
|
||||||
self = [super initWithWindowNibName:@"DetailsPanel"];
|
self = [super initWithNibName:@"DetailsPanel" pyClassName:@"PyDetailsPanel" pyParent:aPy];
|
||||||
[self window]; //So the detailsTable is initialized.
|
[self window]; //So the detailsTable is initialized.
|
||||||
[detailsTable setPy:aPy];
|
[self connect];
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(duplicateSelectionChanged:) name:DuplicateSelectionChangedNotification object:nil];
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)refresh
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
[self disconnect];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (PyDetailsPanel *)py
|
||||||
|
{
|
||||||
|
return (PyDetailsPanel *)py;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)refreshDetails
|
||||||
{
|
{
|
||||||
[detailsTable reloadData];
|
[detailsTable reloadData];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)toggleVisibility
|
- (void)toggleVisibility
|
||||||
{
|
{
|
||||||
if ([[self window] isVisible])
|
if ([[self window] isVisible]) {
|
||||||
[[self window] close];
|
[[self window] close];
|
||||||
else
|
}
|
||||||
{
|
else {
|
||||||
[self refresh]; // selection might have changed since last time
|
[self refreshDetails]; // selection might have changed since last time
|
||||||
[[self window] orderFront:nil];
|
[[self window] orderFront:nil];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Notifications */
|
/* NSTableView Delegate */
|
||||||
- (void)duplicateSelectionChanged:(NSNotification *)aNotification
|
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
|
||||||
{
|
{
|
||||||
if ([[self window] isVisible])
|
return [[self py] numberOfRows];
|
||||||
[self refresh];
|
}
|
||||||
|
|
||||||
|
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)column row:(NSInteger)row
|
||||||
|
{
|
||||||
|
return [[self py] valueForColumn:[column identifier] row:row];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Python --> Cocoa */
|
||||||
|
- (void)refresh
|
||||||
|
{
|
||||||
|
if ([[self window] isVisible]) {
|
||||||
|
[self refreshDetails];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|||||||
16
cocoa/base/DirectoryOutline.h
Normal file
16
cocoa/base/DirectoryOutline.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
|
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||||
|
which should be included with this package. The terms are also available at
|
||||||
|
http://www.hardcoded.net/licenses/hs_license
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import "HSOutline.h"
|
||||||
|
#import "PyDirectoryOutline.h"
|
||||||
|
|
||||||
|
@interface DirectoryOutline : HSOutline {}
|
||||||
|
- (id)initWithPyParent:(id)aPyParent view:(HSOutlineView *)aOutlineView;
|
||||||
|
- (PyDirectoryOutline *)py;
|
||||||
|
@end;
|
||||||
84
cocoa/base/DirectoryOutline.m
Normal file
84
cocoa/base/DirectoryOutline.m
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
|
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||||
|
which should be included with this package. The terms are also available at
|
||||||
|
http://www.hardcoded.net/licenses/hs_license
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "DirectoryOutline.h"
|
||||||
|
|
||||||
|
@implementation DirectoryOutline
|
||||||
|
- (id)initWithPyParent:(id)aPyParent view:(HSOutlineView *)aOutlineView
|
||||||
|
{
|
||||||
|
self = [super initWithPyClassName:@"PyDirectoryOutline" pyParent:aPyParent view:aOutlineView];
|
||||||
|
[outlineView registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];
|
||||||
|
[self connect];
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
[self disconnect];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (PyDirectoryOutline *)py
|
||||||
|
{
|
||||||
|
return (PyDirectoryOutline *)py;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delegate */
|
||||||
|
- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id < NSDraggingInfo >)info proposedItem:(id)item proposedChildIndex:(NSInteger)index
|
||||||
|
{
|
||||||
|
NSPasteboard *pboard;
|
||||||
|
NSDragOperation sourceDragMask;
|
||||||
|
sourceDragMask = [info draggingSourceOperationMask];
|
||||||
|
pboard = [info draggingPasteboard];
|
||||||
|
if ([[pboard types] containsObject:NSFilenamesPboardType]) {
|
||||||
|
if (sourceDragMask & NSDragOperationLink)
|
||||||
|
return NSDragOperationLink;
|
||||||
|
}
|
||||||
|
return NSDragOperationNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id < NSDraggingInfo >)info item:(id)item childIndex:(NSInteger)index
|
||||||
|
{
|
||||||
|
NSPasteboard *pboard;
|
||||||
|
NSDragOperation sourceDragMask;
|
||||||
|
sourceDragMask = [info draggingSourceOperationMask];
|
||||||
|
pboard = [info draggingPasteboard];
|
||||||
|
if ([[pboard types] containsObject:NSFilenamesPboardType]) {
|
||||||
|
NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType];
|
||||||
|
if (!(sourceDragMask & NSDragOperationLink))
|
||||||
|
return NO;
|
||||||
|
for (NSString *filename in filenames) {
|
||||||
|
[[self py] addDirectory:filename];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)outlineView:(NSOutlineView *)aOutlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
|
||||||
|
{
|
||||||
|
if ([cell isKindOfClass:[NSTextFieldCell class]]) {
|
||||||
|
NSTextFieldCell *textCell = cell;
|
||||||
|
NSIndexPath *path = item;
|
||||||
|
BOOL selected = [path isEqualTo:[outlineView selectedPath]];
|
||||||
|
if (selected) {
|
||||||
|
[textCell setTextColor:[NSColor blackColor]];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NSInteger state = [self intProperty:@"state" valueAtPath:path];
|
||||||
|
if (state == 1) {
|
||||||
|
[textCell setTextColor:[NSColor blueColor]];
|
||||||
|
}
|
||||||
|
else if (state == 2) {
|
||||||
|
[textCell setTextColor:[NSColor redColor]];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[textCell setTextColor:[NSColor blackColor]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@end
|
||||||
@@ -8,31 +8,23 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "RecentDirectories.h"
|
#import "RecentDirectories.h"
|
||||||
#import "Outline.h"
|
#import "HSOutlineView.h"
|
||||||
|
#import "DirectoryOutline.h"
|
||||||
#import "PyDupeGuru.h"
|
#import "PyDupeGuru.h"
|
||||||
|
|
||||||
@interface DirectoryOutline : OutlineView
|
@interface DirectoryPanel : NSWindowController
|
||||||
{
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
@protocol DirectoryOutlineDelegate
|
|
||||||
- (void)outlineView:(NSOutlineView *)outlineView addDirectory:(NSString *)directory;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface DirectoryPanelBase : NSWindowController
|
|
||||||
{
|
{
|
||||||
IBOutlet NSPopUpButton *addButtonPopUp;
|
IBOutlet NSPopUpButton *addButtonPopUp;
|
||||||
IBOutlet DirectoryOutline *directories;
|
IBOutlet HSOutlineView *outlineView;
|
||||||
IBOutlet NSButton *removeButton;
|
IBOutlet NSButton *removeButton;
|
||||||
|
|
||||||
PyDupeGuruBase *_py;
|
PyDupeGuruBase *_py;
|
||||||
RecentDirectories *_recentDirectories;
|
RecentDirectories *_recentDirectories;
|
||||||
|
DirectoryOutline *outline;
|
||||||
}
|
}
|
||||||
- (id)initWithParentApp:(id)aParentApp;
|
- (id)initWithParentApp:(id)aParentApp;
|
||||||
|
|
||||||
- (IBAction)askForDirectory:(id)sender;
|
- (IBAction)askForDirectory:(id)sender;
|
||||||
- (IBAction)changeDirectoryState:(id)sender;
|
|
||||||
- (IBAction)popupAddDirectoryMenu:(id)sender;
|
- (IBAction)popupAddDirectoryMenu:(id)sender;
|
||||||
- (IBAction)removeSelectedDirectory:(id)sender;
|
- (IBAction)removeSelectedDirectory:(id)sender;
|
||||||
- (IBAction)toggleVisible:(id)sender;
|
- (IBAction)toggleVisible:(id)sender;
|
||||||
|
|||||||
@@ -11,49 +11,7 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
#import "Utils.h"
|
#import "Utils.h"
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
|
|
||||||
@implementation DirectoryOutline
|
@implementation DirectoryPanel
|
||||||
- (void)doInit
|
|
||||||
{
|
|
||||||
[super doInit];
|
|
||||||
[self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id < NSDraggingInfo >)info proposedItem:(id)item proposedChildIndex:(NSInteger)index
|
|
||||||
{
|
|
||||||
NSPasteboard *pboard;
|
|
||||||
NSDragOperation sourceDragMask;
|
|
||||||
sourceDragMask = [info draggingSourceOperationMask];
|
|
||||||
pboard = [info draggingPasteboard];
|
|
||||||
if ([[pboard types] containsObject:NSFilenamesPboardType])
|
|
||||||
{
|
|
||||||
if (sourceDragMask & NSDragOperationLink)
|
|
||||||
return NSDragOperationLink;
|
|
||||||
}
|
|
||||||
return NSDragOperationNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id < NSDraggingInfo >)info item:(id)item childIndex:(NSInteger)index
|
|
||||||
{
|
|
||||||
NSPasteboard *pboard;
|
|
||||||
NSDragOperation sourceDragMask;
|
|
||||||
sourceDragMask = [info draggingSourceOperationMask];
|
|
||||||
pboard = [info draggingPasteboard];
|
|
||||||
if ( [[pboard types] containsObject:NSFilenamesPboardType] )
|
|
||||||
{
|
|
||||||
NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType];
|
|
||||||
if (!(sourceDragMask & NSDragOperationLink))
|
|
||||||
return NO;
|
|
||||||
if (([self delegate] == nil) || (![[self delegate] respondsToSelector:@selector(outlineView:addDirectory:)]))
|
|
||||||
return NO;
|
|
||||||
for (NSString *filename in filenames)
|
|
||||||
[[self delegate] outlineView:self addDirectory:filename];
|
|
||||||
}
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation DirectoryPanelBase
|
|
||||||
- (id)initWithParentApp:(id)aParentApp
|
- (id)initWithParentApp:(id)aParentApp
|
||||||
{
|
{
|
||||||
self = [super initWithWindowNibName:@"DirectoryPanel"];
|
self = [super initWithWindowNibName:@"DirectoryPanel"];
|
||||||
@@ -61,23 +19,19 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
AppDelegateBase *app = aParentApp;
|
AppDelegateBase *app = aParentApp;
|
||||||
_py = [app py];
|
_py = [app py];
|
||||||
_recentDirectories = [app recentDirectories];
|
_recentDirectories = [app recentDirectories];
|
||||||
[directories setPy:_py];
|
outline = [[DirectoryOutline alloc] initWithPyParent:_py view:outlineView];
|
||||||
NSPopUpButtonCell *cell = [[directories tableColumnWithIdentifier:@"1"] dataCell];
|
|
||||||
[cell addItemWithTitle:@"Normal"];
|
|
||||||
[cell addItemWithTitle:@"Reference"];
|
|
||||||
[cell addItemWithTitle:@"Excluded"];
|
|
||||||
for (NSInteger i=0;i<[[cell itemArray] count];i++)
|
|
||||||
{
|
|
||||||
NSMenuItem *mi = [[cell itemArray] objectAtIndex:i];
|
|
||||||
[mi setTarget:self];
|
|
||||||
[mi setAction:@selector(changeDirectoryState:)];
|
|
||||||
[mi setTag:i];
|
|
||||||
}
|
|
||||||
[self refreshRemoveButtonText];
|
[self refreshRemoveButtonText];
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(directorySelectionChanged:) name:NSOutlineViewSelectionDidChangeNotification object:directories];
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(directorySelectionChanged:)
|
||||||
|
name:NSOutlineViewSelectionDidChangeNotification object:outlineView];
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
[outline release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
/* Actions */
|
/* Actions */
|
||||||
|
|
||||||
- (IBAction)askForDirectory:(id)sender
|
- (IBAction)askForDirectory:(id)sender
|
||||||
@@ -95,15 +49,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)changeDirectoryState:(id)sender
|
|
||||||
{
|
|
||||||
OVNode *node = [directories itemAtRow:[directories clickedRow]];
|
|
||||||
[_py setDirectory:p2a([node indexPath]) state:i2n([sender tag])];
|
|
||||||
[node resetAllBuffers];
|
|
||||||
[directories reloadItem:node reloadChildren:YES];
|
|
||||||
[directories display];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)popupAddDirectoryMenu:(id)sender
|
- (IBAction)popupAddDirectoryMenu:(id)sender
|
||||||
{
|
{
|
||||||
if ([[_recentDirectories directories] count] == 0)
|
if ([[_recentDirectories directories] count] == 0)
|
||||||
@@ -125,21 +70,17 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
- (IBAction)removeSelectedDirectory:(id)sender
|
- (IBAction)removeSelectedDirectory:(id)sender
|
||||||
{
|
{
|
||||||
[[self window] makeKeyAndOrderFront:nil];
|
[[self window] makeKeyAndOrderFront:nil];
|
||||||
if ([directories selectedRow] < 0)
|
if ([outlineView selectedRow] < 0)
|
||||||
return;
|
return;
|
||||||
OVNode *node = [directories itemAtRow:[directories selectedRow]];
|
NSIndexPath *path = [outline selectedIndexPath];
|
||||||
if ([node level] == 1)
|
NSInteger state = [outline intProperty:@"state" valueAtPath:path];
|
||||||
{
|
if (([path length] == 1) && (state != 2)) {
|
||||||
[_py removeDirectory:i2n([node index])];
|
[_py removeDirectory:i2n([path indexAtPosition:0])];
|
||||||
[directories reloadData];
|
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
NSInteger state = n2i([[node buffer] objectAtIndex:1]);
|
|
||||||
NSInteger newState = state == 2 ? 0 : 2; // If excluded, put it back
|
NSInteger newState = state == 2 ? 0 : 2; // If excluded, put it back
|
||||||
[_py setDirectory:p2a([node indexPath]) state:i2n(newState)];
|
[outline setIntProperty:@"state" value:newState atPath:path];
|
||||||
[node resetAllBuffers];
|
[outlineView display];
|
||||||
[directories display];
|
|
||||||
}
|
}
|
||||||
[self refreshRemoveButtonText];
|
[self refreshRemoveButtonText];
|
||||||
}
|
}
|
||||||
@@ -150,70 +91,40 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Public */
|
/* Public */
|
||||||
|
|
||||||
- (void)addDirectory:(NSString *)directory
|
- (void)addDirectory:(NSString *)directory
|
||||||
{
|
{
|
||||||
NSInteger r = [[_py addDirectory:directory] intValue];
|
NSInteger r = [[_py addDirectory:directory] intValue];
|
||||||
if (r)
|
if (r) {
|
||||||
{
|
|
||||||
NSString *m;
|
NSString *m;
|
||||||
switch (r)
|
switch (r) {
|
||||||
{
|
case 1: {
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
m = @"This directory already is in the list.";
|
m = @"This directory already is in the list.";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2:
|
case 2: {
|
||||||
{
|
|
||||||
m = @"This directory does not exist.";
|
m = @"This directory does not exist.";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[Dialogs showMessage:m];
|
[Dialogs showMessage:m];
|
||||||
}
|
}
|
||||||
[directories reloadData];
|
|
||||||
[_recentDirectories addDirectory:directory];
|
[_recentDirectories addDirectory:directory];
|
||||||
[[self window] makeKeyAndOrderFront:nil];
|
[[self window] makeKeyAndOrderFront:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)refreshRemoveButtonText
|
- (void)refreshRemoveButtonText
|
||||||
{
|
{
|
||||||
if ([directories selectedRow] < 0)
|
if ([outlineView selectedRow] < 0) {
|
||||||
{
|
|
||||||
[removeButton setEnabled:NO];
|
[removeButton setEnabled:NO];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
[removeButton setEnabled:YES];
|
[removeButton setEnabled:YES];
|
||||||
OVNode *node = [directories itemAtRow:[directories selectedRow]];
|
NSInteger state = [outline intProperty:@"state" valueAtPath:[outline selectedIndexPath]];
|
||||||
NSInteger state = n2i([[node buffer] objectAtIndex:1]);
|
|
||||||
NSString *buttonText = state == 2 ? @"Put Back" : @"Remove";
|
NSString *buttonText = state == 2 ? @"Put Back" : @"Remove";
|
||||||
[removeButton setTitle:buttonText];
|
[removeButton setTitle:buttonText];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delegate */
|
/* Delegate */
|
||||||
|
|
||||||
- (void)outlineView:(NSOutlineView *)outlineView addDirectory:(NSString *)directory
|
|
||||||
{
|
|
||||||
[self addDirectory:directory];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
|
|
||||||
{
|
|
||||||
OVNode *node = item;
|
|
||||||
NSInteger state = n2i([[node buffer] objectAtIndex:1]);
|
|
||||||
if ([cell isKindOfClass:[NSTextFieldCell class]])
|
|
||||||
{
|
|
||||||
NSTextFieldCell *textCell = cell;
|
|
||||||
if (state == 1)
|
|
||||||
[textCell setTextColor:[NSColor blueColor]];
|
|
||||||
else if (state == 2)
|
|
||||||
[textCell setTextColor:[NSColor redColor]];
|
|
||||||
else
|
|
||||||
[textCell setTextColor:[NSColor blackColor]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)path
|
- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)path
|
||||||
{
|
{
|
||||||
BOOL isdir;
|
BOOL isdir;
|
||||||
|
|||||||
25
cocoa/base/ProblemDialog.h
Normal file
25
cocoa/base/ProblemDialog.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
|
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||||
|
which should be included with this package. The terms are also available at
|
||||||
|
http://www.hardcoded.net/licenses/hs_license
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import "HSWindowController.h"
|
||||||
|
#import "PyApp.h"
|
||||||
|
#import "PyProblemDialog.h"
|
||||||
|
#import "HSTable.h"
|
||||||
|
|
||||||
|
@interface ProblemDialog : HSWindowController
|
||||||
|
{
|
||||||
|
IBOutlet NSTableView *problemTableView;
|
||||||
|
|
||||||
|
HSTable *problemTable;
|
||||||
|
}
|
||||||
|
- (id)initWithPy:(PyApp *)aPy;
|
||||||
|
- (PyProblemDialog *)py;
|
||||||
|
|
||||||
|
- (IBAction)revealSelected:(id)sender;
|
||||||
|
@end
|
||||||
40
cocoa/base/ProblemDialog.m
Normal file
40
cocoa/base/ProblemDialog.m
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
|
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||||
|
which should be included with this package. The terms are also available at
|
||||||
|
http://www.hardcoded.net/licenses/hs_license
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "ProblemDialog.h"
|
||||||
|
#import "Utils.h"
|
||||||
|
|
||||||
|
@implementation ProblemDialog
|
||||||
|
- (id)initWithPy:(PyApp *)aPy
|
||||||
|
{
|
||||||
|
self = [super initWithNibName:@"ProblemDialog" pyClassName:@"PyProblemDialog" pyParent:aPy];
|
||||||
|
[self window]; //So the detailsTable is initialized.
|
||||||
|
problemTable = [[HSTable alloc] initWithPyClassName:@"PyProblemTable" pyParent:[self py] view:problemTableView];
|
||||||
|
[self connect];
|
||||||
|
[problemTable connect];
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
[problemTable disconnect];
|
||||||
|
[self disconnect];
|
||||||
|
[problemTable release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (PyProblemDialog *)py
|
||||||
|
{
|
||||||
|
return (PyProblemDialog *)py;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)revealSelected:(id)sender
|
||||||
|
{
|
||||||
|
[[self py] revealSelected];
|
||||||
|
}
|
||||||
|
@end
|
||||||
@@ -6,7 +6,10 @@ which should be included with this package. The terms are also available at
|
|||||||
http://www.hardcoded.net/licenses/hs_license
|
http://www.hardcoded.net/licenses/hs_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "DetailsPanel.h"
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import "PyGUI.h"
|
||||||
|
|
||||||
@implementation DetailsPanel
|
@interface PyDetailsPanel : PyGUI
|
||||||
@end
|
- (NSInteger)numberOfRows;
|
||||||
|
- (id)valueForColumn:(NSString *)column row:(NSInteger)row;
|
||||||
|
@end
|
||||||
@@ -7,9 +7,8 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "../base/DirectoryPanel.h"
|
#import "PyOutline.h"
|
||||||
|
|
||||||
@interface DirectoryPanel : DirectoryPanelBase
|
@interface PyDirectoryOutline : PyOutline
|
||||||
{
|
- (void)addDirectory:(NSString *)directoryPath;
|
||||||
}
|
@end
|
||||||
@end
|
|
||||||
@@ -13,7 +13,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
//Actions
|
//Actions
|
||||||
- (NSNumber *)addDirectory:(NSString *)name;
|
- (NSNumber *)addDirectory:(NSString *)name;
|
||||||
- (void)removeDirectory:(NSNumber *)index;
|
- (void)removeDirectory:(NSNumber *)index;
|
||||||
- (void)setDirectory:(NSArray *)indexPath state:(NSNumber *)state;
|
|
||||||
- (void)loadResults;
|
- (void)loadResults;
|
||||||
- (void)saveResults;
|
- (void)saveResults;
|
||||||
- (void)loadIgnoreList;
|
- (void)loadIgnoreList;
|
||||||
@@ -21,31 +20,21 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
- (void)clearIgnoreList;
|
- (void)clearIgnoreList;
|
||||||
- (void)purgeIgnoreList;
|
- (void)purgeIgnoreList;
|
||||||
- (NSString *)exportToXHTMLwithColumns:(NSArray *)aColIds;
|
- (NSString *)exportToXHTMLwithColumns:(NSArray *)aColIds;
|
||||||
|
- (void)invokeCommand:(NSString *)cmd;
|
||||||
|
|
||||||
- (NSNumber *)doScan;
|
- (NSNumber *)doScan;
|
||||||
|
|
||||||
- (NSArray *)selectedPowerMarkerNodePaths;
|
|
||||||
- (void)selectPowerMarkerNodePaths:(NSArray *)aIndexPaths;
|
|
||||||
- (NSArray *)selectedResultNodePaths;
|
|
||||||
- (void)selectResultNodePaths:(NSArray *)aIndexPaths;
|
|
||||||
|
|
||||||
- (void)toggleSelectedMark;
|
- (void)toggleSelectedMark;
|
||||||
- (void)markAll;
|
- (void)markAll;
|
||||||
- (void)markInvert;
|
- (void)markInvert;
|
||||||
- (void)markNone;
|
- (void)markNone;
|
||||||
|
|
||||||
- (void)addSelectedToIgnoreList;
|
- (void)addSelectedToIgnoreList;
|
||||||
- (void)refreshDetailsWithSelected;
|
|
||||||
- (void)removeSelected;
|
|
||||||
- (void)openSelected;
|
- (void)openSelected;
|
||||||
- (NSNumber *)renameSelected:(NSString *)aNewName;
|
|
||||||
- (void)revealSelected;
|
- (void)revealSelected;
|
||||||
- (void)makeSelectedReference;
|
- (void)makeSelectedReference;
|
||||||
- (void)applyFilter:(NSString *)filter;
|
- (void)applyFilter:(NSString *)filter;
|
||||||
|
|
||||||
- (void)sortGroupsBy:(NSNumber *)aIdentifier ascending:(NSNumber *)aAscending;
|
|
||||||
- (void)sortDupesBy:(NSNumber *)aIdentifier ascending:(NSNumber *)aAscending;
|
|
||||||
|
|
||||||
- (void)copyOrMove:(NSNumber *)aCopy markedTo:(NSString *)destination recreatePath:(NSNumber *)aRecreateType;
|
- (void)copyOrMove:(NSNumber *)aCopy markedTo:(NSString *)destination recreatePath:(NSNumber *)aRecreateType;
|
||||||
- (void)deleteMarked;
|
- (void)deleteMarked;
|
||||||
- (void)removeMarked;
|
- (void)removeMarked;
|
||||||
@@ -53,13 +42,11 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
//Data
|
//Data
|
||||||
- (NSNumber *)getIgnoreListCount;
|
- (NSNumber *)getIgnoreListCount;
|
||||||
- (NSNumber *)getMarkCount;
|
- (NSNumber *)getMarkCount;
|
||||||
- (NSString *)getStatLine;
|
- (BOOL)scanWasProblematic;
|
||||||
- (NSNumber *)getOperationalErrorCount;
|
|
||||||
|
|
||||||
//Scanning options
|
//Scanning options
|
||||||
- (void)setMinMatchPercentage:(NSNumber *)percentage;
|
- (void)setMinMatchPercentage:(NSNumber *)percentage;
|
||||||
- (void)setMixFileKind:(NSNumber *)mix_file_kind;
|
- (void)setMixFileKind:(NSNumber *)mix_file_kind;
|
||||||
- (void)setDisplayDeltaValues:(NSNumber *)display_delta_values;
|
|
||||||
- (void)setEscapeFilterRegexp:(NSNumber *)escape_filter_regexp;
|
- (void)setEscapeFilterRegexp:(NSNumber *)escape_filter_regexp;
|
||||||
- (void)setRemoveEmptyFolders:(NSNumber *)remove_empty_folders;
|
- (void)setRemoveEmptyFolders:(NSNumber *)remove_empty_folders;
|
||||||
- (void)setSizeThreshold:(NSInteger)size_threshold;
|
- (void)setSizeThreshold:(NSInteger)size_threshold;
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "../base/DetailsPanel.h"
|
#import "PyGUI.h"
|
||||||
|
|
||||||
|
@interface PyProblemDialog : PyGUI
|
||||||
@interface DetailsPanel : DetailsPanelBase
|
- (void)revealSelected;
|
||||||
@end
|
@end
|
||||||
24
cocoa/base/PyResultTree.h
Normal file
24
cocoa/base/PyResultTree.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
|
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||||
|
which should be included with this package. The terms are also available at
|
||||||
|
http://www.hardcoded.net/licenses/hs_license
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import "PyOutline.h"
|
||||||
|
|
||||||
|
@interface PyResultTree : PyOutline
|
||||||
|
- (BOOL)powerMarkerMode;
|
||||||
|
- (void)setPowerMarkerMode:(BOOL)aPowerMarkerMode;
|
||||||
|
- (BOOL)deltaValuesMode;
|
||||||
|
- (void)setDeltaValuesMode:(BOOL)aDeltaValuesMode;
|
||||||
|
|
||||||
|
- (NSString *)valueForPath:(NSArray *)aPath column:(NSInteger)aColumn;
|
||||||
|
- (BOOL)renameSelected:(NSString *)aNewName;
|
||||||
|
- (void)sortBy:(NSInteger)aIdentifier ascending:(BOOL)aAscending;
|
||||||
|
- (void)markSelected;
|
||||||
|
- (void)removeSelected;
|
||||||
|
- (NSArray *)rootChildrenCounts;
|
||||||
|
@end
|
||||||
@@ -7,7 +7,8 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "../base/DetailsPanel.h"
|
#import "PyGUI.h"
|
||||||
|
|
||||||
@interface DetailsPanel : DetailsPanelBase
|
@interface PyStatsLabel : PyGUI
|
||||||
|
- (NSString *)display;
|
||||||
@end
|
@end
|
||||||
26
cocoa/base/ResultOutline.h
Normal file
26
cocoa/base/ResultOutline.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
|
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||||
|
which should be included with this package. The terms are also available at
|
||||||
|
http://www.hardcoded.net/licenses/hs_license
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import "HSOutline.h"
|
||||||
|
#import "PyResultTree.h"
|
||||||
|
|
||||||
|
@interface ResultOutline : HSOutline
|
||||||
|
{
|
||||||
|
NSIndexSet *_deltaColumns;
|
||||||
|
NSArray *_rootChildrenCounts;
|
||||||
|
}
|
||||||
|
- (PyResultTree *)py;
|
||||||
|
- (BOOL)powerMarkerMode;
|
||||||
|
- (void)setPowerMarkerMode:(BOOL)aPowerMarkerMode;
|
||||||
|
- (BOOL)deltaValuesMode;
|
||||||
|
- (void)setDeltaValuesMode:(BOOL)aDeltaValuesMode;
|
||||||
|
- (void)setDeltaColumns:(NSIndexSet *)aDeltaColumns;
|
||||||
|
- (NSInteger)selectedDupeCount;
|
||||||
|
- (void)removeSelected;
|
||||||
|
@end;
|
||||||
207
cocoa/base/ResultOutline.m
Normal file
207
cocoa/base/ResultOutline.m
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
|
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||||
|
which should be included with this package. The terms are also available at
|
||||||
|
http://www.hardcoded.net/licenses/hs_license
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "ResultOutline.h"
|
||||||
|
#import "Dialogs.h"
|
||||||
|
#import "Utils.h"
|
||||||
|
#import "Consts.h"
|
||||||
|
|
||||||
|
@implementation ResultOutline
|
||||||
|
- (id)initWithPyParent:(id)aPyParent view:(HSOutlineView *)aOutlineView
|
||||||
|
{
|
||||||
|
self = [super initWithPyClassName:@"PyResultOutline" pyParent:aPyParent view:aOutlineView];
|
||||||
|
_rootChildrenCounts = nil;
|
||||||
|
[self connect];
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
[self disconnect];
|
||||||
|
[_deltaColumns release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (PyResultTree *)py
|
||||||
|
{
|
||||||
|
return (PyResultTree *)py;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Public */
|
||||||
|
- (BOOL)powerMarkerMode
|
||||||
|
{
|
||||||
|
return [[self py] powerMarkerMode];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setPowerMarkerMode:(BOOL)aPowerMarkerMode
|
||||||
|
{
|
||||||
|
[[self py] setPowerMarkerMode:aPowerMarkerMode];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)deltaValuesMode
|
||||||
|
{
|
||||||
|
return [[self py] deltaValuesMode];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setDeltaValuesMode:(BOOL)aDeltaValuesMode
|
||||||
|
{
|
||||||
|
[[self py] setDeltaValuesMode:aDeltaValuesMode];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setDeltaColumns:(NSIndexSet *)aDeltaColumns
|
||||||
|
{
|
||||||
|
[_deltaColumns release];
|
||||||
|
_deltaColumns = [aDeltaColumns retain];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)selectedDupeCount
|
||||||
|
{
|
||||||
|
NSArray *selected = [self selectedIndexPaths];
|
||||||
|
if ([self powerMarkerMode]) {
|
||||||
|
return [selected count];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
NSInteger r = 0;
|
||||||
|
for (NSIndexPath *path in selected) {
|
||||||
|
if ([path length] == 2) {
|
||||||
|
r++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)removeSelected
|
||||||
|
{
|
||||||
|
NSInteger selectedDupeCount = [self selectedDupeCount];
|
||||||
|
if (!selectedDupeCount)
|
||||||
|
return;
|
||||||
|
NSString *msg = [NSString stringWithFormat:@"You are about to remove %d files from results. Continue?",selectedDupeCount];
|
||||||
|
if ([Dialogs askYesNo:msg] == NSAlertSecondButtonReturn) // NO
|
||||||
|
return;
|
||||||
|
[[self py] removeSelected];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Datasource */
|
||||||
|
- (NSInteger)outlineView:(NSOutlineView *)aOutlineView numberOfChildrenOfItem:(id)item
|
||||||
|
{
|
||||||
|
NSIndexPath *path = item;
|
||||||
|
if ((path != nil) && ([path length] == 1)) {
|
||||||
|
if (_rootChildrenCounts == nil) {
|
||||||
|
_rootChildrenCounts = [[[self py] rootChildrenCounts] retain];
|
||||||
|
}
|
||||||
|
NSInteger index = [path indexAtPosition:0];
|
||||||
|
return n2i([_rootChildrenCounts objectAtIndex:index]);
|
||||||
|
}
|
||||||
|
return [super outlineView:aOutlineView numberOfChildrenOfItem:item];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)column byItem:(id)item
|
||||||
|
{
|
||||||
|
NSIndexPath *path = item;
|
||||||
|
NSString *identifier = [column identifier];
|
||||||
|
if ([identifier isEqual:@"marked"]) {
|
||||||
|
return b2n([self boolProperty:@"marked" valueAtPath:path]);
|
||||||
|
}
|
||||||
|
NSInteger columnId = [identifier integerValue];
|
||||||
|
return [[self py] valueForPath:p2a(path) column:columnId];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)outlineView:(NSOutlineView *)aOutlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
|
||||||
|
{
|
||||||
|
if ([[tableColumn identifier] isEqual:@"0"]) {
|
||||||
|
NSIndexPath *path = item;
|
||||||
|
NSString *oldName = [[self py] valueForPath:p2a(path) column:0];
|
||||||
|
NSString *newName = object;
|
||||||
|
if (![newName isEqual:oldName]) {
|
||||||
|
BOOL renamed = [[self py] renameSelected:newName];
|
||||||
|
if (!renamed) {
|
||||||
|
[Dialogs showMessage:[NSString stringWithFormat:@"The name '%@' already exists.", newName]];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[self refreshItemAtPath:path];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[super outlineView:aOutlineView setObjectValue:object forTableColumn:tableColumn byItem:item];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delegate */
|
||||||
|
- (void)outlineView:(NSOutlineView *)aOutlineView didClickTableColumn:(NSTableColumn *)tableColumn
|
||||||
|
{
|
||||||
|
if ([[outlineView sortDescriptors] count] < 1)
|
||||||
|
return;
|
||||||
|
NSSortDescriptor *sd = [[outlineView sortDescriptors] objectAtIndex:0];
|
||||||
|
[[self py] sortBy:[[sd key] integerValue] ascending:[sd ascending]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
|
||||||
|
{
|
||||||
|
NSIndexPath *path = item;
|
||||||
|
BOOL isMarkable = [self boolProperty:@"markable" valueAtPath:path];
|
||||||
|
if ([[tableColumn identifier] isEqual:@"marked"]) {
|
||||||
|
[cell setEnabled:isMarkable];
|
||||||
|
}
|
||||||
|
if ([cell isKindOfClass:[NSTextFieldCell class]]) {
|
||||||
|
// Determine if the text color will be blue due to directory being reference.
|
||||||
|
NSTextFieldCell *textCell = cell;
|
||||||
|
if (isMarkable) {
|
||||||
|
[textCell setTextColor:[NSColor blackColor]];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[textCell setTextColor:[NSColor blueColor]];
|
||||||
|
}
|
||||||
|
if (([self deltaValuesMode]) && ([self powerMarkerMode] || ([path length] > 1))) {
|
||||||
|
NSInteger i = [[tableColumn identifier] integerValue];
|
||||||
|
if ([_deltaColumns containsIndex:i]) {
|
||||||
|
[textCell setTextColor:[NSColor orangeColor]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)tableViewHadDeletePressed:(NSTableView *)tableView
|
||||||
|
{
|
||||||
|
[self removeSelected];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)tableViewHadSpacePressed:(NSTableView *)tableView
|
||||||
|
{
|
||||||
|
[[self py] markSelected];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* don't calls saveEdits and cancelEdits */
|
||||||
|
- (void)outlineViewDidEndEditing:(HSOutlineView *)outlineView
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)outlineViewCancelsEdition:(HSOutlineView *)outlineView
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Python --> Cocoa */
|
||||||
|
- (void)refresh /* Override */
|
||||||
|
{
|
||||||
|
[_rootChildrenCounts release];
|
||||||
|
_rootChildrenCounts = nil;
|
||||||
|
[super refresh];
|
||||||
|
[outlineView expandItem:nil expandChildren:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)invalidateMarkings
|
||||||
|
{
|
||||||
|
for (NSMutableDictionary *props in [itemData objectEnumerator]) {
|
||||||
|
[props removeObjectForKey:@"marked"];
|
||||||
|
}
|
||||||
|
[outlineView setNeedsDisplay:YES];
|
||||||
|
}
|
||||||
|
@end
|
||||||
@@ -7,54 +7,65 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "Outline.h"
|
#import "HSOutlineView.h"
|
||||||
|
#import "StatsLabel.h"
|
||||||
|
#import "ResultOutline.h"
|
||||||
|
#import "ProblemDialog.h"
|
||||||
#import "PyDupeGuru.h"
|
#import "PyDupeGuru.h"
|
||||||
|
|
||||||
@interface MatchesView : OutlineView
|
|
||||||
- (void)keyDown:(NSEvent *)theEvent;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface ResultWindowBase : NSWindowController
|
@interface ResultWindowBase : NSWindowController
|
||||||
{
|
{
|
||||||
@protected
|
@protected
|
||||||
IBOutlet PyDupeGuruBase *py;
|
IBOutlet PyDupeGuruBase *py;
|
||||||
IBOutlet id app;
|
IBOutlet id app;
|
||||||
IBOutlet NSSegmentedControl *deltaSwitch;
|
IBOutlet NSSegmentedControl *deltaSwitch;
|
||||||
IBOutlet MatchesView *matches;
|
IBOutlet HSOutlineView *matches;
|
||||||
IBOutlet NSSegmentedControl *pmSwitch;
|
IBOutlet NSSegmentedControl *pmSwitch;
|
||||||
IBOutlet NSTextField *stats;
|
IBOutlet NSTextField *stats;
|
||||||
IBOutlet NSMenu *columnsMenu;
|
IBOutlet NSMenu *columnsMenu;
|
||||||
|
IBOutlet NSSearchField *filterField;
|
||||||
|
|
||||||
BOOL _powerMode;
|
|
||||||
BOOL _displayDelta;
|
|
||||||
NSMutableArray *_resultColumns;
|
NSMutableArray *_resultColumns;
|
||||||
NSWindowController *preferencesPanel;
|
NSWindowController *preferencesPanel;
|
||||||
|
ResultOutline *outline;
|
||||||
|
StatsLabel *statsLabel;
|
||||||
|
ProblemDialog *problemDialog;
|
||||||
}
|
}
|
||||||
/* 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;
|
||||||
- (NSArray *)getSelected:(BOOL)aDupesOnly;
|
|
||||||
- (NSArray *)getSelectedPaths:(BOOL)aDupesOnly;
|
|
||||||
- (void)initResultColumns;
|
- (void)initResultColumns;
|
||||||
- (void)updatePySelection;
|
|
||||||
- (void)performPySelection:(NSArray *)aIndexPaths;
|
|
||||||
- (void)refreshStats;
|
|
||||||
- (void)restoreColumnsPosition:(NSArray *)aColumnsOrder widths:(NSDictionary *)aColumnsWidth;
|
- (void)restoreColumnsPosition:(NSArray *)aColumnsOrder widths:(NSDictionary *)aColumnsWidth;
|
||||||
|
|
||||||
/* Actions */
|
/* Actions */
|
||||||
|
- (IBAction)clearIgnoreList:(id)sender;
|
||||||
- (IBAction)changeDelta:(id)sender;
|
- (IBAction)changeDelta:(id)sender;
|
||||||
- (IBAction)changePowerMarker:(id)sender;
|
- (IBAction)changePowerMarker:(id)sender;
|
||||||
- (IBAction)copyMarked:(id)sender;
|
- (IBAction)copyMarked:(id)sender;
|
||||||
- (IBAction)deleteMarked:(id)sender;
|
- (IBAction)deleteMarked:(id)sender;
|
||||||
- (IBAction)expandAll:(id)sender;
|
|
||||||
- (IBAction)exportToXHTML:(id)sender;
|
- (IBAction)exportToXHTML:(id)sender;
|
||||||
|
- (IBAction)filter:(id)sender;
|
||||||
|
- (IBAction)ignoreSelected:(id)sender;
|
||||||
|
- (IBAction)invokeCustomCommand:(id)sender;
|
||||||
|
- (IBAction)markAll:(id)sender;
|
||||||
|
- (IBAction)markInvert:(id)sender;
|
||||||
|
- (IBAction)markNone:(id)sender;
|
||||||
|
- (IBAction)markSelected:(id)sender;
|
||||||
- (IBAction)moveMarked:(id)sender;
|
- (IBAction)moveMarked:(id)sender;
|
||||||
|
- (IBAction)openClicked:(id)sender;
|
||||||
|
- (IBAction)openSelected:(id)sender;
|
||||||
|
- (IBAction)removeMarked:(id)sender;
|
||||||
|
- (IBAction)removeSelected:(id)sender;
|
||||||
|
- (IBAction)renameSelected:(id)sender;
|
||||||
- (IBAction)resetColumnsToDefault:(id)sender;
|
- (IBAction)resetColumnsToDefault:(id)sender;
|
||||||
|
- (IBAction)revealSelected:(id)sender;
|
||||||
- (IBAction)showPreferencesPanel:(id)sender;
|
- (IBAction)showPreferencesPanel:(id)sender;
|
||||||
|
- (IBAction)startDuplicateScan:(id)sender;
|
||||||
- (IBAction)switchSelected:(id)sender;
|
- (IBAction)switchSelected:(id)sender;
|
||||||
- (IBAction)toggleColumn:(id)sender;
|
- (IBAction)toggleColumn:(id)sender;
|
||||||
|
- (IBAction)toggleDelta:(id)sender;
|
||||||
- (IBAction)toggleDetailsPanel:(id)sender;
|
- (IBAction)toggleDetailsPanel:(id)sender;
|
||||||
- (IBAction)togglePowerMarker:(id)sender;
|
- (IBAction)togglePowerMarker:(id)sender;
|
||||||
|
|
||||||
|
|||||||
@@ -14,57 +14,33 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
#import "Consts.h"
|
#import "Consts.h"
|
||||||
|
|
||||||
@implementation MatchesView
|
|
||||||
- (void)keyDown:(NSEvent *)theEvent
|
|
||||||
{
|
|
||||||
unichar key = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
|
|
||||||
// get flags and strip the lower 16 (device dependant) bits
|
|
||||||
NSUInteger flags = ( [theEvent modifierFlags] & 0x00FF );
|
|
||||||
if (((key == NSDeleteFunctionKey) || (key == NSDeleteCharacter)) && (flags == 0))
|
|
||||||
[self sendAction:@selector(removeSelected:) to:[self delegate]];
|
|
||||||
else
|
|
||||||
if ((key == 0x20) && (flags == 0)) // Space
|
|
||||||
[self sendAction:@selector(markSelected:) to:[self delegate]];
|
|
||||||
else
|
|
||||||
[super keyDown:theEvent];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
|
|
||||||
{
|
|
||||||
if (![[tableColumn identifier] isEqual:@"0"])
|
|
||||||
return; //We only want to cover renames.
|
|
||||||
OVNode *node = item;
|
|
||||||
NSString *oldName = [[node buffer] objectAtIndex:0];
|
|
||||||
NSString *newName = object;
|
|
||||||
if (![newName isEqual:oldName])
|
|
||||||
{
|
|
||||||
BOOL renamed = n2b([(PyDupeGuruBase *)py renameSelected:newName]);
|
|
||||||
if (renamed)
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self];
|
|
||||||
else
|
|
||||||
[Dialogs showMessage:[NSString stringWithFormat:@"The name '%@' already exists.",newName]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation ResultWindowBase
|
@implementation ResultWindowBase
|
||||||
- (void)awakeFromNib
|
- (void)awakeFromNib
|
||||||
{
|
{
|
||||||
[self window];
|
[self window];
|
||||||
preferencesPanel = [[NSWindowController alloc] initWithWindowNibName:@"Preferences"];
|
preferencesPanel = [[NSWindowController alloc] initWithWindowNibName:@"Preferences"];
|
||||||
|
outline = [[ResultOutline alloc] initWithPyParent:py view:matches];
|
||||||
|
statsLabel = [[StatsLabel alloc] initWithPyParent:py labelView:stats];
|
||||||
|
problemDialog = [[ProblemDialog alloc] initWithPy:py];
|
||||||
[self initResultColumns];
|
[self initResultColumns];
|
||||||
[self fillColumnsMenu];
|
[self fillColumnsMenu];
|
||||||
|
[deltaSwitch setSelectedSegment:0];
|
||||||
|
[pmSwitch setSelectedSegment:0];
|
||||||
|
[matches setTarget:self];
|
||||||
|
[matches setDoubleAction:@selector(openClicked:)];
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(registrationRequired:) name:RegistrationRequired object:nil];
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(registrationRequired:) name:RegistrationRequired object:nil];
|
||||||
[[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];
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resultsChanged:) name:ResultsChangedNotification object:nil];
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resultsUpdated:) name:ResultsUpdatedNotification object:nil];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
|
[outline release];
|
||||||
[preferencesPanel release];
|
[preferencesPanel release];
|
||||||
|
[statsLabel release];
|
||||||
|
[problemDialog release];
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,13 +77,9 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
//Returns an array of identifiers, in order.
|
//Returns an array of identifiers, in order.
|
||||||
- (NSArray *)getColumnsOrder
|
- (NSArray *)getColumnsOrder
|
||||||
{
|
{
|
||||||
NSTableColumn *col;
|
|
||||||
NSString *colId;
|
|
||||||
NSMutableArray *result = [NSMutableArray array];
|
NSMutableArray *result = [NSMutableArray array];
|
||||||
NSEnumerator *e = [[matches tableColumns] objectEnumerator];
|
for (NSTableColumn *col in [matches tableColumns]) {
|
||||||
while (col = [e nextObject])
|
NSString *colId = [col identifier];
|
||||||
{
|
|
||||||
colId = [col identifier];
|
|
||||||
[result addObject:colId];
|
[result addObject:colId];
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -116,48 +88,14 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
- (NSDictionary *)getColumnsWidth
|
- (NSDictionary *)getColumnsWidth
|
||||||
{
|
{
|
||||||
NSMutableDictionary *result = [NSMutableDictionary dictionary];
|
NSMutableDictionary *result = [NSMutableDictionary dictionary];
|
||||||
NSTableColumn *col;
|
for (NSTableColumn *col in [matches tableColumns]) {
|
||||||
NSString *colId;
|
NSString *colId = [col identifier];
|
||||||
NSNumber *width;
|
NSNumber *width = [NSNumber numberWithDouble:[col width]];
|
||||||
NSEnumerator *e = [[matches tableColumns] objectEnumerator];
|
|
||||||
while (col = [e nextObject])
|
|
||||||
{
|
|
||||||
colId = [col identifier];
|
|
||||||
width = [NSNumber numberWithDouble:[col width]];
|
|
||||||
[result setObject:width forKey:colId];
|
[result setObject:width forKey:colId];
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *)getSelected:(BOOL)aDupesOnly
|
|
||||||
{
|
|
||||||
if (_powerMode)
|
|
||||||
aDupesOnly = NO;
|
|
||||||
NSIndexSet *indexes = [matches selectedRowIndexes];
|
|
||||||
NSMutableArray *nodeList = [NSMutableArray array];
|
|
||||||
OVNode *node;
|
|
||||||
NSInteger i = [indexes firstIndex];
|
|
||||||
while (i != NSNotFound)
|
|
||||||
{
|
|
||||||
node = [matches itemAtRow:i];
|
|
||||||
if (!aDupesOnly || ([node level] > 1))
|
|
||||||
[nodeList addObject:node];
|
|
||||||
i = [indexes indexGreaterThanIndex:i];
|
|
||||||
}
|
|
||||||
return nodeList;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSArray *)getSelectedPaths:(BOOL)aDupesOnly
|
|
||||||
{
|
|
||||||
NSMutableArray *r = [NSMutableArray array];
|
|
||||||
NSArray *selected = [self getSelected:aDupesOnly];
|
|
||||||
NSEnumerator *e = [selected objectEnumerator];
|
|
||||||
OVNode *node;
|
|
||||||
while (node = [e nextObject])
|
|
||||||
[r addObject:p2a([node indexPath])];
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)initResultColumns
|
- (void)initResultColumns
|
||||||
{
|
{
|
||||||
// Virtual
|
// Virtual
|
||||||
@@ -165,75 +103,46 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
|
|
||||||
- (void)restoreColumnsPosition:(NSArray *)aColumnsOrder widths:(NSDictionary *)aColumnsWidth
|
- (void)restoreColumnsPosition:(NSArray *)aColumnsOrder widths:(NSDictionary *)aColumnsWidth
|
||||||
{
|
{
|
||||||
NSTableColumn *col;
|
for (NSMenuItem *mi in [columnsMenu itemArray]) {
|
||||||
NSString *colId;
|
if ([mi state] == NSOnState) {
|
||||||
NSNumber *width;
|
|
||||||
NSMenuItem *mi;
|
|
||||||
//Remove all columns
|
|
||||||
NSEnumerator *e = [[columnsMenu itemArray] objectEnumerator];
|
|
||||||
while (mi = [e nextObject])
|
|
||||||
{
|
|
||||||
if ([mi state] == NSOnState)
|
|
||||||
[self toggleColumn:mi];
|
|
||||||
}
|
|
||||||
//Add columns and set widths
|
|
||||||
e = [aColumnsOrder objectEnumerator];
|
|
||||||
while (colId = [e nextObject])
|
|
||||||
{
|
|
||||||
if (![colId isEqual:@"mark"])
|
|
||||||
{
|
|
||||||
col = [_resultColumns objectAtIndex:[colId intValue]];
|
|
||||||
width = [aColumnsWidth objectForKey:[col identifier]];
|
|
||||||
mi = [columnsMenu itemWithTag:[colId intValue]];
|
|
||||||
if (width)
|
|
||||||
[col setWidth:[width floatValue]];
|
|
||||||
[self toggleColumn:mi];
|
[self toggleColumn:mi];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
//Add columns and set widths
|
||||||
|
for (NSString *colId in aColumnsOrder) {
|
||||||
- (void)updatePySelection
|
NSInteger colIndex = [colId integerValue];
|
||||||
{
|
if ((colIndex == 0) && (![colId isEqual:@"0"])) {
|
||||||
NSArray *selection;
|
continue;
|
||||||
if (_powerMode)
|
}
|
||||||
selection = [py selectedPowerMarkerNodePaths];
|
NSTableColumn *col = [_resultColumns objectAtIndex:colIndex];
|
||||||
else
|
NSNumber *width = [aColumnsWidth objectForKey:[col identifier]];
|
||||||
selection = [py selectedResultNodePaths];
|
NSMenuItem *mi = [columnsMenu itemWithTag:colIndex];
|
||||||
[matches selectNodePaths:selection];
|
if (width) {
|
||||||
}
|
[col setWidth:[width floatValue]];
|
||||||
|
}
|
||||||
- (void)performPySelection:(NSArray *)aIndexPaths
|
[self toggleColumn:mi];
|
||||||
{
|
}
|
||||||
if (_powerMode)
|
|
||||||
[py selectPowerMarkerNodePaths:aIndexPaths];
|
|
||||||
else
|
|
||||||
[py selectResultNodePaths:aIndexPaths];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)refreshStats
|
|
||||||
{
|
|
||||||
[stats setStringValue:[py getStatLine]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Actions */
|
/* Actions */
|
||||||
|
- (IBAction)clearIgnoreList:(id)sender
|
||||||
|
{
|
||||||
|
NSInteger i = n2i([py getIgnoreListCount]);
|
||||||
|
if (!i)
|
||||||
|
return;
|
||||||
|
if ([Dialogs askYesNo:[NSString stringWithFormat:@"Do you really want to remove all %d items from the ignore list?",i]] == NSAlertSecondButtonReturn) // NO
|
||||||
|
return;
|
||||||
|
[py clearIgnoreList];
|
||||||
|
}
|
||||||
|
|
||||||
- (IBAction)changeDelta:(id)sender
|
- (IBAction)changeDelta:(id)sender
|
||||||
{
|
{
|
||||||
_displayDelta = [deltaSwitch selectedSegment] == 1;
|
[outline setDeltaValuesMode:[deltaSwitch selectedSegment] == 1];
|
||||||
[py setDisplayDeltaValues:b2n(_displayDelta)];
|
|
||||||
[matches reloadData];
|
|
||||||
[self expandAll:nil];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)changePowerMarker:(id)sender
|
- (IBAction)changePowerMarker:(id)sender
|
||||||
{
|
{
|
||||||
_powerMode = [pmSwitch selectedSegment] == 1;
|
[outline setPowerMarkerMode:[pmSwitch selectedSegment] == 1];
|
||||||
if (_powerMode)
|
|
||||||
[matches setTag:2];
|
|
||||||
else
|
|
||||||
[matches setTag:0];
|
|
||||||
[self expandAll:nil];
|
|
||||||
[self outlineView:matches didClickTableColumn:nil];
|
|
||||||
[self updatePySelection];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)copyMarked:(id)sender
|
- (IBAction)copyMarked:(id)sender
|
||||||
@@ -267,18 +176,62 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[py deleteMarked];
|
[py deleteMarked];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)expandAll:(id)sender
|
|
||||||
{
|
|
||||||
for (NSInteger i=0;i < [matches numberOfRows];i++)
|
|
||||||
[matches expandItem:[matches itemAtRow:i]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)exportToXHTML:(id)sender
|
- (IBAction)exportToXHTML:(id)sender
|
||||||
{
|
{
|
||||||
NSString *exported = [py exportToXHTMLwithColumns:[self getColumnsOrder]];
|
NSString *exported = [py exportToXHTMLwithColumns:[self getColumnsOrder]];
|
||||||
[[NSWorkspace sharedWorkspace] openFile:exported];
|
[[NSWorkspace sharedWorkspace] openFile:exported];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction)filter:(id)sender
|
||||||
|
{
|
||||||
|
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||||
|
[py setEscapeFilterRegexp:b2n(!n2b([ud objectForKey:@"useRegexpFilter"]))];
|
||||||
|
[py applyFilter:[filterField stringValue]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)ignoreSelected:(id)sender
|
||||||
|
{
|
||||||
|
NSInteger selectedDupeCount = [outline selectedDupeCount];
|
||||||
|
if (!selectedDupeCount)
|
||||||
|
return;
|
||||||
|
NSString *msg = [NSString stringWithFormat:@"All selected %d matches are going to be ignored in all subsequent scans. Continue?",selectedDupeCount];
|
||||||
|
if ([Dialogs askYesNo:msg] == NSAlertSecondButtonReturn) // NO
|
||||||
|
return;
|
||||||
|
[py addSelectedToIgnoreList];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)invokeCustomCommand:(id)sender
|
||||||
|
{
|
||||||
|
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||||
|
NSString *cmd = [ud stringForKey:@"CustomCommand"];
|
||||||
|
if ((cmd != nil) && ([cmd length] > 0)) {
|
||||||
|
[py invokeCommand:cmd];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[Dialogs showMessage:@"You have no custom command set up. Set it up in your preferences."];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)markAll:(id)sender
|
||||||
|
{
|
||||||
|
[py markAll];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)markInvert:(id)sender
|
||||||
|
{
|
||||||
|
[py markInvert];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)markNone:(id)sender
|
||||||
|
{
|
||||||
|
[py markNone];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)markSelected:(id)sender
|
||||||
|
{
|
||||||
|
[py toggleSelectedMark];
|
||||||
|
}
|
||||||
|
|
||||||
- (IBAction)moveMarked:(id)sender
|
- (IBAction)moveMarked:(id)sender
|
||||||
{
|
{
|
||||||
NSInteger mark_count = [[py getMarkCount] intValue];
|
NSInteger mark_count = [[py getMarkCount] intValue];
|
||||||
@@ -299,31 +252,65 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction)openClicked:(id)sender
|
||||||
|
{
|
||||||
|
if ([matches clickedRow] < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
[matches selectRowIndexes:[NSIndexSet indexSetWithIndex:[matches clickedRow]] byExtendingSelection:NO];
|
||||||
|
[py openSelected];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)openSelected:(id)sender
|
||||||
|
{
|
||||||
|
[py openSelected];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)removeMarked:(id)sender
|
||||||
|
{
|
||||||
|
int mark_count = [[py getMarkCount] intValue];
|
||||||
|
if (!mark_count)
|
||||||
|
return;
|
||||||
|
if ([Dialogs askYesNo:[NSString stringWithFormat:@"You are about to remove %d files from results. Continue?",mark_count]] == NSAlertSecondButtonReturn) // NO
|
||||||
|
return;
|
||||||
|
[py removeMarked];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)removeSelected:(id)sender
|
||||||
|
{
|
||||||
|
[outline removeSelected];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)renameSelected:(id)sender
|
||||||
|
{
|
||||||
|
NSInteger col = [matches columnWithIdentifier:@"0"];
|
||||||
|
NSInteger row = [matches selectedRow];
|
||||||
|
[matches editColumn:col row:row withEvent:[NSApp currentEvent] select:YES];
|
||||||
|
}
|
||||||
|
|
||||||
- (IBAction)resetColumnsToDefault:(id)sender
|
- (IBAction)resetColumnsToDefault:(id)sender
|
||||||
{
|
{
|
||||||
// Virtual
|
// Virtual
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction)revealSelected:(id)sender
|
||||||
|
{
|
||||||
|
[py revealSelected];
|
||||||
|
}
|
||||||
|
|
||||||
- (IBAction)showPreferencesPanel:(id)sender
|
- (IBAction)showPreferencesPanel:(id)sender
|
||||||
{
|
{
|
||||||
[preferencesPanel showWindow:sender];
|
[preferencesPanel showWindow:sender];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction)startDuplicateScan:(id)sender
|
||||||
|
{
|
||||||
|
// Virtual
|
||||||
|
}
|
||||||
|
|
||||||
- (IBAction)switchSelected:(id)sender
|
- (IBAction)switchSelected:(id)sender
|
||||||
{
|
{
|
||||||
// It might look like a complicated way to get the length of the current dupe list on the py side
|
|
||||||
// but after a lot of fussing around, believe it or not, it actually is.
|
|
||||||
NSInteger matchesTag = _powerMode ? 2 : 0;
|
|
||||||
NSInteger startLen = [[py getOutlineView:matchesTag childCountsForPath:[NSArray array]] count];
|
|
||||||
[self performPySelection:[self getSelectedPaths:YES]];
|
|
||||||
[py makeSelectedReference];
|
[py makeSelectedReference];
|
||||||
// In some cases (when in a filtered view in Power Marker mode, it's possible that the demoted
|
|
||||||
// ref is not a part of the filter, making the table smaller. In those cases, we want to do a
|
|
||||||
// complete reload of the table to avoid a crash.
|
|
||||||
if ([[py getOutlineView:matchesTag childCountsForPath:[NSArray array]] count] == startLen)
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsUpdatedNotification object:self];
|
|
||||||
else
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)toggleColumn:(id)sender
|
- (IBAction)toggleColumn:(id)sender
|
||||||
@@ -346,6 +333,15 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (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];
|
[[(AppDelegateBase *)app detailsPanel] toggleVisibility];
|
||||||
@@ -360,21 +356,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[self changePowerMarker:sender];
|
[self changePowerMarker:sender];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delegate */
|
|
||||||
|
|
||||||
- (void)outlineView:(NSOutlineView *)outlineView didClickTableColumn:(NSTableColumn *)tableColumn
|
|
||||||
{
|
|
||||||
if ([[outlineView sortDescriptors] count] < 1)
|
|
||||||
return;
|
|
||||||
NSSortDescriptor *sd = [[outlineView sortDescriptors] objectAtIndex:0];
|
|
||||||
if (_powerMode)
|
|
||||||
[py sortDupesBy:i2n([[sd key] intValue]) ascending:b2n([sd ascending])];
|
|
||||||
else
|
|
||||||
[py sortGroupsBy:i2n([[sd key] intValue]) ascending:b2n([sd ascending])];
|
|
||||||
[matches reloadData];
|
|
||||||
[self expandAll:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Notifications */
|
/* Notifications */
|
||||||
- (void)windowWillClose:(NSNotification *)aNotification
|
- (void)windowWillClose:(NSNotification *)aNotification
|
||||||
{
|
{
|
||||||
@@ -383,32 +364,33 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
|
|
||||||
- (void)jobCompleted:(NSNotification *)aNotification
|
- (void)jobCompleted:(NSNotification *)aNotification
|
||||||
{
|
{
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self];
|
|
||||||
NSInteger r = n2i([py getOperationalErrorCount]);
|
|
||||||
id lastAction = [[ProgressController mainProgressController] jobId];
|
id lastAction = [[ProgressController mainProgressController] jobId];
|
||||||
if ([lastAction isEqualTo:jobCopy]) {
|
if ([lastAction isEqualTo:jobCopy]) {
|
||||||
if (r > 0)
|
if ([py scanWasProblematic]) {
|
||||||
[Dialogs showMessage:[NSString stringWithFormat:@"%d file(s) couldn't be copied.",r]];
|
[problemDialog showWindow:self];
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
[Dialogs showMessage:@"All marked files were copied sucessfully."];
|
[Dialogs showMessage:@"All marked files were copied sucessfully."];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ([lastAction isEqualTo:jobMove]) {
|
else if ([lastAction isEqualTo:jobMove]) {
|
||||||
if (r > 0)
|
if ([py scanWasProblematic]) {
|
||||||
[Dialogs showMessage:[NSString stringWithFormat:@"%d file(s) couldn't be moved. They were kept in the results, and still are marked.",r]];
|
[problemDialog showWindow:self];
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
[Dialogs showMessage:@"All marked files were moved sucessfully."];
|
[Dialogs showMessage:@"All marked files were moved sucessfully."];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ([lastAction isEqualTo:jobDelete]) {
|
else if ([lastAction isEqualTo:jobDelete]) {
|
||||||
if (r > 0) {
|
if ([py scanWasProblematic]) {
|
||||||
NSString *msg = @"%d file(s) couldn't be sent to Trash. They were kept in the results, "\
|
[problemDialog showWindow:self];
|
||||||
"and still are marked. See the F.A.Q. section in the help file for details.";
|
|
||||||
[Dialogs showMessage:[NSString stringWithFormat:msg,r]];
|
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
[Dialogs showMessage:@"All marked files were sucessfully sent to Trash."];
|
[Dialogs showMessage:@"All marked files were sucessfully sent to Trash."];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ([lastAction isEqualTo:jobScan]) {
|
else if ([lastAction isEqualTo:jobScan]) {
|
||||||
NSInteger groupCount = [[py getOutlineView:0 childCountsForPath:[NSArray array]] count];
|
NSInteger groupCount = [outline intProperty:@"children_count" valueAtPath:nil];
|
||||||
if (groupCount == 0)
|
if (groupCount == 0)
|
||||||
[Dialogs showMessage:@"No duplicates found."];
|
[Dialogs showMessage:@"No duplicates found."];
|
||||||
}
|
}
|
||||||
@@ -429,7 +411,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
NSString *desc = [ui valueForKey:@"desc"];
|
NSString *desc = [ui valueForKey:@"desc"];
|
||||||
[[ProgressController mainProgressController] setJobDesc:desc];
|
[[ProgressController mainProgressController] setJobDesc:desc];
|
||||||
NSString *jobid = [ui valueForKey:@"jobid"];
|
NSString *jobid = [ui valueForKey:@"jobid"];
|
||||||
// NSLog(jobid);
|
|
||||||
[[ProgressController mainProgressController] setJobId:jobid];
|
[[ProgressController mainProgressController] setJobId:jobid];
|
||||||
[[ProgressController mainProgressController] showSheetForParent:[self window]];
|
[[ProgressController mainProgressController] showSheetForParent:[self window]];
|
||||||
}
|
}
|
||||||
@@ -440,20 +421,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[Dialogs showMessage:msg];
|
[Dialogs showMessage:msg];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)resultsChanged:(NSNotification *)aNotification
|
|
||||||
{
|
|
||||||
[matches reloadData];
|
|
||||||
[self expandAll:nil];
|
|
||||||
[self outlineViewSelectionDidChange:nil];
|
|
||||||
[self refreshStats];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)resultsUpdated:(NSNotification *)aNotification
|
|
||||||
{
|
|
||||||
[matches invalidateBuffers];
|
|
||||||
[matches invalidateMarkings];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem
|
- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem
|
||||||
{
|
{
|
||||||
return ![[ProgressController mainProgressController] isShown];
|
return ![[ProgressController mainProgressController] isShown];
|
||||||
|
|||||||
@@ -7,13 +7,13 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import "HSGUIController.h"
|
||||||
|
#import "PyStatsLabel.h"
|
||||||
|
|
||||||
|
@interface StatsLabel : HSGUIController
|
||||||
@interface PictureBlocks : NSObject {
|
{
|
||||||
|
NSTextField *labelView;
|
||||||
}
|
}
|
||||||
+ (NSString *)getBlocksFromImagePath:(NSString *)imagePath blockCount:(NSNumber *)blockCount;
|
- (id)initWithPyParent:(id)aPyParent labelView:(NSTextField *)aLabelView;
|
||||||
+ (NSSize)getImageSize:(NSString *)imagePath;
|
- (PyStatsLabel *)py;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
NSString* GetBlocks(NSString *filePath, int blockCount);
|
|
||||||
38
cocoa/base/StatsLabel.m
Normal file
38
cocoa/base/StatsLabel.m
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
|
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||||
|
which should be included with this package. The terms are also available at
|
||||||
|
http://www.hardcoded.net/licenses/hs_license
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "StatsLabel.h"
|
||||||
|
#import "Utils.h"
|
||||||
|
|
||||||
|
@implementation StatsLabel
|
||||||
|
- (id)initWithPyParent:(id)aPyParent labelView:(NSTextField *)aLabelView
|
||||||
|
{
|
||||||
|
self = [super initWithPyClassName:@"PyStatsLabel" pyParent:aPyParent];
|
||||||
|
labelView = [aLabelView retain];
|
||||||
|
[self connect];
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
[self disconnect];
|
||||||
|
[labelView release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (PyStatsLabel *)py
|
||||||
|
{
|
||||||
|
return (PyStatsLabel *)py;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Python --> Cocoa */
|
||||||
|
- (void)refresh
|
||||||
|
{
|
||||||
|
[labelView setStringValue:[[self py] display]];
|
||||||
|
}
|
||||||
|
@end
|
||||||
@@ -2,17 +2,17 @@
|
|||||||
<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">10B504</string>
|
<string key="IBDocument.SystemVersion">10C540</string>
|
||||||
<string key="IBDocument.InterfaceBuilderVersion">740</string>
|
<string key="IBDocument.InterfaceBuilderVersion">740</string>
|
||||||
<string key="IBDocument.AppKitVersion">1038.2</string>
|
<string key="IBDocument.AppKitVersion">1038.25</string>
|
||||||
<string key="IBDocument.HIToolboxVersion">437.00</string>
|
<string key="IBDocument.HIToolboxVersion">458.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">740</string>
|
<string key="NS.object.0">740</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>
|
||||||
<integer value="5"/>
|
<integer value="6"/>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSArray" key="IBDocument.PluginDependencies">
|
<object class="NSArray" key="IBDocument.PluginDependencies">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
@@ -297,13 +297,21 @@
|
|||||||
</object>
|
</object>
|
||||||
<int key="connectionID">12</int>
|
<int key="connectionID">12</int>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="IBConnectionRecord">
|
||||||
|
<object class="IBOutletConnection" key="connection">
|
||||||
|
<string key="label">dataSource</string>
|
||||||
|
<reference key="source" ref="251969872"/>
|
||||||
|
<reference key="destination" ref="449947658"/>
|
||||||
|
</object>
|
||||||
|
<int key="connectionID">21</int>
|
||||||
|
</object>
|
||||||
<object class="IBConnectionRecord">
|
<object class="IBConnectionRecord">
|
||||||
<object class="IBOutletConnection" key="connection">
|
<object class="IBOutletConnection" key="connection">
|
||||||
<string key="label">detailsTable</string>
|
<string key="label">detailsTable</string>
|
||||||
<reference key="source" ref="449947658"/>
|
<reference key="source" ref="449947658"/>
|
||||||
<reference key="destination" ref="251969872"/>
|
<reference key="destination" ref="251969872"/>
|
||||||
</object>
|
</object>
|
||||||
<int key="connectionID">13</int>
|
<int key="connectionID">22</int>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||||
@@ -438,15 +446,22 @@
|
|||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
<object class="NSArray" key="dict.sortedKeys">
|
<object class="NSArray" key="dict.sortedKeys">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
|
<string>-3.IBPluginDependency</string>
|
||||||
<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.ImportedFromIB2</string>
|
<string>11.ImportedFromIB2</string>
|
||||||
|
<string>15.IBPluginDependency</string>
|
||||||
<string>15.IBShouldRemoveOnLegacySave</string>
|
<string>15.IBShouldRemoveOnLegacySave</string>
|
||||||
|
<string>16.IBPluginDependency</string>
|
||||||
<string>16.IBShouldRemoveOnLegacySave</string>
|
<string>16.IBShouldRemoveOnLegacySave</string>
|
||||||
|
<string>17.IBPluginDependency</string>
|
||||||
<string>17.IBShouldRemoveOnLegacySave</string>
|
<string>17.IBShouldRemoveOnLegacySave</string>
|
||||||
|
<string>18.IBPluginDependency</string>
|
||||||
<string>18.IBShouldRemoveOnLegacySave</string>
|
<string>18.IBShouldRemoveOnLegacySave</string>
|
||||||
|
<string>19.IBPluginDependency</string>
|
||||||
<string>19.IBShouldRemoveOnLegacySave</string>
|
<string>19.IBShouldRemoveOnLegacySave</string>
|
||||||
|
<string>20.IBPluginDependency</string>
|
||||||
<string>20.IBShouldRemoveOnLegacySave</string>
|
<string>20.IBShouldRemoveOnLegacySave</string>
|
||||||
<string>5.IBEditorWindowLastContentRect</string>
|
<string>5.IBEditorWindowLastContentRect</string>
|
||||||
<string>5.IBPluginDependency</string>
|
<string>5.IBPluginDependency</string>
|
||||||
@@ -458,7 +473,6 @@
|
|||||||
<string>6.ImportedFromIB2</string>
|
<string>6.ImportedFromIB2</string>
|
||||||
<string>7.IBPluginDependency</string>
|
<string>7.IBPluginDependency</string>
|
||||||
<string>7.ImportedFromIB2</string>
|
<string>7.ImportedFromIB2</string>
|
||||||
<string>8.CustomClassName</string>
|
|
||||||
<string>8.IBPluginDependency</string>
|
<string>8.IBPluginDependency</string>
|
||||||
<string>8.ImportedFromIB2</string>
|
<string>8.ImportedFromIB2</string>
|
||||||
<string>9.IBPluginDependency</string>
|
<string>9.IBPluginDependency</string>
|
||||||
@@ -467,14 +481,21 @@
|
|||||||
<object class="NSMutableArray" key="dict.values">
|
<object class="NSMutableArray" key="dict.values">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
<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>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<boolean value="YES"/>
|
<boolean value="YES"/>
|
||||||
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<boolean value="YES"/>
|
<boolean value="YES"/>
|
||||||
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<boolean value="YES"/>
|
<boolean value="YES"/>
|
||||||
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<boolean value="YES"/>
|
<boolean value="YES"/>
|
||||||
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<boolean value="YES"/>
|
<boolean value="YES"/>
|
||||||
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<boolean value="YES"/>
|
<boolean value="YES"/>
|
||||||
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<boolean value="YES"/>
|
<boolean value="YES"/>
|
||||||
<string>{{109, 656}, {451, 161}}</string>
|
<string>{{109, 656}, {451, 161}}</string>
|
||||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
@@ -486,7 +507,6 @@
|
|||||||
<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>TableView</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>
|
||||||
@@ -509,81 +529,34 @@
|
|||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<nil key="sourceID"/>
|
<nil key="sourceID"/>
|
||||||
<int key="maxID">20</int>
|
<int key="maxID">22</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">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
<string key="className">DetailsPanel</string>
|
<string key="className">DetailsPanel</string>
|
||||||
<string key="superclassName">DetailsPanelBase</string>
|
<string key="superclassName">NSWindowController</string>
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBProjectSource</string>
|
|
||||||
<string key="minorKey">DetailsPanel.h</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBPartialClassDescription">
|
|
||||||
<string key="className">DetailsPanel</string>
|
|
||||||
<string key="superclassName">DetailsPanelBase</string>
|
|
||||||
<object class="NSMutableDictionary" key="outlets">
|
<object class="NSMutableDictionary" key="outlets">
|
||||||
<string key="NS.key.0">detailsTable</string>
|
<string key="NS.key.0">detailsTable</string>
|
||||||
<string key="NS.object.0">NSTableView</string>
|
<string key="NS.object.0">NSTableView</string>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
<string key="majorKey">IBUserSource</string>
|
<string key="majorKey">IBProjectSource</string>
|
||||||
<string key="minorKey"/>
|
<string key="minorKey">../base/DetailsPanel.h</string>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
<string key="className">DetailsPanelBase</string>
|
<string key="className">DetailsPanel</string>
|
||||||
<string key="superclassName">NSWindowController</string>
|
<string key="superclassName">NSWindowController</string>
|
||||||
<object class="NSMutableDictionary" key="outlets">
|
|
||||||
<string key="NS.key.0">detailsTable</string>
|
|
||||||
<string key="NS.object.0">TableView</string>
|
|
||||||
</object>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
<string key="majorKey">IBProjectSource</string>
|
<string key="majorKey">IBUserSource</string>
|
||||||
<string key="minorKey">dgbase/DetailsPanel.h</string>
|
<string key="minorKey"/>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
<string key="className">FirstResponder</string>
|
<string key="className">FirstResponder</string>
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBUserSource</string>
|
|
||||||
<string key="minorKey"/>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBPartialClassDescription">
|
|
||||||
<string key="className">PyApp</string>
|
|
||||||
<string key="superclassName">PyRegistrable</string>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBProjectSource</string>
|
|
||||||
<string key="minorKey">cocoalib/PyApp.h</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBPartialClassDescription">
|
|
||||||
<string key="className">PyRegistrable</string>
|
|
||||||
<string key="superclassName">NSObject</string>
|
<string key="superclassName">NSObject</string>
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBProjectSource</string>
|
|
||||||
<string key="minorKey">cocoalib/PyRegistrable.h</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBPartialClassDescription">
|
|
||||||
<string key="className">TableView</string>
|
|
||||||
<string key="superclassName">NSTableView</string>
|
|
||||||
<object class="NSMutableDictionary" key="outlets">
|
|
||||||
<string key="NS.key.0">py</string>
|
|
||||||
<string key="NS.object.0">PyApp</string>
|
|
||||||
</object>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBProjectSource</string>
|
|
||||||
<string key="minorKey">cocoalib/Table.h</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBPartialClassDescription">
|
|
||||||
<string key="className">TableView</string>
|
|
||||||
<string key="superclassName">NSTableView</string>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
<string key="majorKey">IBUserSource</string>
|
<string key="majorKey">IBUserSource</string>
|
||||||
<string key="minorKey"/>
|
<string key="minorKey"/>
|
||||||
|
|||||||
@@ -2,17 +2,17 @@
|
|||||||
<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">10B504</string>
|
<string key="IBDocument.SystemVersion">10C540</string>
|
||||||
<string key="IBDocument.InterfaceBuilderVersion">740</string>
|
<string key="IBDocument.InterfaceBuilderVersion">740</string>
|
||||||
<string key="IBDocument.AppKitVersion">1038.2</string>
|
<string key="IBDocument.AppKitVersion">1038.25</string>
|
||||||
<string key="IBDocument.HIToolboxVersion">437.00</string>
|
<string key="IBDocument.HIToolboxVersion">458.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">740</string>
|
<string key="NS.object.0">740</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>
|
||||||
<integer value="6"/>
|
<integer value="50"/>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSArray" key="IBDocument.PluginDependencies">
|
<object class="NSArray" key="IBDocument.PluginDependencies">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
@@ -70,7 +70,6 @@
|
|||||||
<int key="NSvFlags">256</int>
|
<int key="NSvFlags">256</int>
|
||||||
<string key="NSFrameSize">{327, 165}</string>
|
<string key="NSFrameSize">{327, 165}</string>
|
||||||
<reference key="NSSuperview" ref="514281221"/>
|
<reference key="NSSuperview" ref="514281221"/>
|
||||||
<int key="NSTag">1</int>
|
|
||||||
<bool key="NSEnabled">YES</bool>
|
<bool key="NSEnabled">YES</bool>
|
||||||
<object class="NSTableHeaderView" key="NSHeaderView" id="885660940">
|
<object class="NSTableHeaderView" key="NSHeaderView" id="885660940">
|
||||||
<reference key="NSNextResponder" ref="395832192"/>
|
<reference key="NSNextResponder" ref="395832192"/>
|
||||||
@@ -88,7 +87,7 @@
|
|||||||
<object class="NSMutableArray" key="NSTableColumns">
|
<object class="NSMutableArray" key="NSTableColumns">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
<object class="NSTableColumn" id="547470852">
|
<object class="NSTableColumn" id="547470852">
|
||||||
<string key="NSIdentifier">0</string>
|
<string key="NSIdentifier">name</string>
|
||||||
<double key="NSWidth">236</double>
|
<double key="NSWidth">236</double>
|
||||||
<double key="NSMinWidth">16</double>
|
<double key="NSMinWidth">16</double>
|
||||||
<double key="NSMaxWidth">1000</double>
|
<double key="NSMaxWidth">1000</double>
|
||||||
@@ -142,7 +141,7 @@
|
|||||||
<reference key="NSTableView" ref="10140319"/>
|
<reference key="NSTableView" ref="10140319"/>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSTableColumn" id="50798966">
|
<object class="NSTableColumn" id="50798966">
|
||||||
<string key="NSIdentifier">1</string>
|
<string key="NSIdentifier">state</string>
|
||||||
<double key="NSWidth">85.35595703125</double>
|
<double key="NSWidth">85.35595703125</double>
|
||||||
<double key="NSMinWidth">30.35595703125</double>
|
<double key="NSMinWidth">30.35595703125</double>
|
||||||
<double key="NSMaxWidth">1000</double>
|
<double key="NSMaxWidth">1000</double>
|
||||||
@@ -173,15 +172,41 @@
|
|||||||
<string key="NSKeyEquivalent"/>
|
<string key="NSKeyEquivalent"/>
|
||||||
<int key="NSPeriodicDelay">400</int>
|
<int key="NSPeriodicDelay">400</int>
|
||||||
<int key="NSPeriodicInterval">75</int>
|
<int key="NSPeriodicInterval">75</int>
|
||||||
<nil key="NSMenuItem"/>
|
<object class="NSMenuItem" key="NSMenuItem" id="71151438">
|
||||||
|
<reference key="NSMenu" ref="104112446"/>
|
||||||
|
<string key="NSTitle">Normal</string>
|
||||||
|
<string key="NSKeyEquiv"/>
|
||||||
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
|
<int key="NSState">1</int>
|
||||||
|
<string key="NSAction">_popUpItemAction:</string>
|
||||||
|
<reference key="NSTarget" ref="867721721"/>
|
||||||
|
</object>
|
||||||
<bool key="NSMenuItemRespectAlignment">YES</bool>
|
<bool key="NSMenuItemRespectAlignment">YES</bool>
|
||||||
<object class="NSMenu" key="NSMenu" id="104112446">
|
<object class="NSMenu" key="NSMenu" id="104112446">
|
||||||
<string key="NSTitle"/>
|
<string key="NSTitle">Normal</string>
|
||||||
<object class="NSMutableArray" key="NSMenuItems">
|
<object class="NSMutableArray" key="NSMenuItems">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
|
<reference ref="71151438"/>
|
||||||
|
<object class="NSMenuItem" id="828402206">
|
||||||
|
<reference key="NSMenu" ref="104112446"/>
|
||||||
|
<string key="NSTitle">Reference</string>
|
||||||
|
<string key="NSKeyEquiv"/>
|
||||||
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
|
<string key="NSAction">_popUpItemAction:</string>
|
||||||
|
<reference key="NSTarget" ref="867721721"/>
|
||||||
|
</object>
|
||||||
|
<object class="NSMenuItem" id="142495353">
|
||||||
|
<reference key="NSMenu" ref="104112446"/>
|
||||||
|
<string key="NSTitle">Excluded</string>
|
||||||
|
<string key="NSKeyEquiv"/>
|
||||||
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
|
<string key="NSAction">_popUpItemAction:</string>
|
||||||
|
<reference key="NSTarget" ref="867721721"/>
|
||||||
|
</object>
|
||||||
</object>
|
</object>
|
||||||
|
<bool key="NSNoAutoenable">YES</bool>
|
||||||
|
<bool key="NSMenuExcludeMarkColumn">YES</bool>
|
||||||
</object>
|
</object>
|
||||||
<int key="NSSelectedIndex">-1</int>
|
|
||||||
<int key="NSPreferredEdge">3</int>
|
<int key="NSPreferredEdge">3</int>
|
||||||
<bool key="NSUsesItemFromMenu">YES</bool>
|
<bool key="NSUsesItemFromMenu">YES</bool>
|
||||||
<bool key="NSAltersState">YES</bool>
|
<bool key="NSAltersState">YES</bool>
|
||||||
@@ -189,6 +214,7 @@
|
|||||||
</object>
|
</object>
|
||||||
<int key="NSResizingMask">2</int>
|
<int key="NSResizingMask">2</int>
|
||||||
<bool key="NSIsResizeable">YES</bool>
|
<bool key="NSIsResizeable">YES</bool>
|
||||||
|
<bool key="NSIsEditable">YES</bool>
|
||||||
<reference key="NSTableView" ref="10140319"/>
|
<reference key="NSTableView" ref="10140319"/>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
@@ -415,30 +441,6 @@
|
|||||||
</object>
|
</object>
|
||||||
<int key="connectionID">19</int>
|
<int key="connectionID">19</int>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBConnectionRecord">
|
|
||||||
<object class="IBOutletConnection" key="connection">
|
|
||||||
<string key="label">nextKeyView</string>
|
|
||||||
<reference key="source" ref="963602908"/>
|
|
||||||
<reference key="destination" ref="10140319"/>
|
|
||||||
</object>
|
|
||||||
<int key="connectionID">20</int>
|
|
||||||
</object>
|
|
||||||
<object class="IBConnectionRecord">
|
|
||||||
<object class="IBOutletConnection" key="connection">
|
|
||||||
<string key="label">nextKeyView</string>
|
|
||||||
<reference key="source" ref="10140319"/>
|
|
||||||
<reference key="destination" ref="630693842"/>
|
|
||||||
</object>
|
|
||||||
<int key="connectionID">21</int>
|
|
||||||
</object>
|
|
||||||
<object class="IBConnectionRecord">
|
|
||||||
<object class="IBOutletConnection" key="connection">
|
|
||||||
<string key="label">nextKeyView</string>
|
|
||||||
<reference key="source" ref="630693842"/>
|
|
||||||
<reference key="destination" ref="963602908"/>
|
|
||||||
</object>
|
|
||||||
<int key="connectionID">22</int>
|
|
||||||
</object>
|
|
||||||
<object class="IBConnectionRecord">
|
<object class="IBConnectionRecord">
|
||||||
<object class="IBActionConnection" key="connection">
|
<object class="IBActionConnection" key="connection">
|
||||||
<string key="label">popupAddDirectoryMenu:</string>
|
<string key="label">popupAddDirectoryMenu:</string>
|
||||||
@@ -471,22 +473,6 @@
|
|||||||
</object>
|
</object>
|
||||||
<int key="connectionID">26</int>
|
<int key="connectionID">26</int>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBConnectionRecord">
|
|
||||||
<object class="IBOutletConnection" key="connection">
|
|
||||||
<string key="label">directories</string>
|
|
||||||
<reference key="source" ref="566600593"/>
|
|
||||||
<reference key="destination" ref="10140319"/>
|
|
||||||
</object>
|
|
||||||
<int key="connectionID">27</int>
|
|
||||||
</object>
|
|
||||||
<object class="IBConnectionRecord">
|
|
||||||
<object class="IBOutletConnection" key="connection">
|
|
||||||
<string key="label">delegate</string>
|
|
||||||
<reference key="source" ref="10140319"/>
|
|
||||||
<reference key="destination" ref="566600593"/>
|
|
||||||
</object>
|
|
||||||
<int key="connectionID">29</int>
|
|
||||||
</object>
|
|
||||||
<object class="IBConnectionRecord">
|
<object class="IBConnectionRecord">
|
||||||
<object class="IBActionConnection" key="connection">
|
<object class="IBActionConnection" key="connection">
|
||||||
<string key="label">performClose:</string>
|
<string key="label">performClose:</string>
|
||||||
@@ -503,6 +489,14 @@
|
|||||||
</object>
|
</object>
|
||||||
<int key="connectionID">43</int>
|
<int key="connectionID">43</int>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="IBConnectionRecord">
|
||||||
|
<object class="IBOutletConnection" key="connection">
|
||||||
|
<string key="label">outlineView</string>
|
||||||
|
<reference key="source" ref="566600593"/>
|
||||||
|
<reference key="destination" ref="10140319"/>
|
||||||
|
</object>
|
||||||
|
<int key="connectionID">54</int>
|
||||||
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||||
<object class="NSArray" key="orderedObjects">
|
<object class="NSArray" key="orderedObjects">
|
||||||
@@ -685,6 +679,12 @@
|
|||||||
<object class="IBObjectRecord">
|
<object class="IBObjectRecord">
|
||||||
<int key="objectID">50</int>
|
<int key="objectID">50</int>
|
||||||
<reference key="object" ref="104112446"/>
|
<reference key="object" ref="104112446"/>
|
||||||
|
<object class="NSMutableArray" key="children">
|
||||||
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
|
<reference ref="71151438"/>
|
||||||
|
<reference ref="828402206"/>
|
||||||
|
<reference ref="142495353"/>
|
||||||
|
</object>
|
||||||
<reference key="parent" ref="867721721"/>
|
<reference key="parent" ref="867721721"/>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBObjectRecord">
|
<object class="IBObjectRecord">
|
||||||
@@ -702,6 +702,21 @@
|
|||||||
<reference key="object" ref="885660940"/>
|
<reference key="object" ref="885660940"/>
|
||||||
<reference key="parent" ref="242279311"/>
|
<reference key="parent" ref="242279311"/>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="IBObjectRecord">
|
||||||
|
<int key="objectID">55</int>
|
||||||
|
<reference key="object" ref="71151438"/>
|
||||||
|
<reference key="parent" ref="104112446"/>
|
||||||
|
</object>
|
||||||
|
<object class="IBObjectRecord">
|
||||||
|
<int key="objectID">56</int>
|
||||||
|
<reference key="object" ref="828402206"/>
|
||||||
|
<reference key="parent" ref="104112446"/>
|
||||||
|
</object>
|
||||||
|
<object class="IBObjectRecord">
|
||||||
|
<int key="objectID">57</int>
|
||||||
|
<reference key="object" ref="142495353"/>
|
||||||
|
<reference key="parent" ref="104112446"/>
|
||||||
|
</object>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSMutableDictionary" key="flattenedProperties">
|
<object class="NSMutableDictionary" key="flattenedProperties">
|
||||||
@@ -739,6 +754,7 @@
|
|||||||
<string>5.ImportedFromIB2</string>
|
<string>5.ImportedFromIB2</string>
|
||||||
<string>5.windowTemplate.hasMinSize</string>
|
<string>5.windowTemplate.hasMinSize</string>
|
||||||
<string>5.windowTemplate.minSize</string>
|
<string>5.windowTemplate.minSize</string>
|
||||||
|
<string>50.IBEditorWindowLastContentRect</string>
|
||||||
<string>50.IBPluginDependency</string>
|
<string>50.IBPluginDependency</string>
|
||||||
<string>51.IBPluginDependency</string>
|
<string>51.IBPluginDependency</string>
|
||||||
<string>51.IBShouldRemoveOnLegacySave</string>
|
<string>51.IBShouldRemoveOnLegacySave</string>
|
||||||
@@ -746,6 +762,9 @@
|
|||||||
<string>52.IBShouldRemoveOnLegacySave</string>
|
<string>52.IBShouldRemoveOnLegacySave</string>
|
||||||
<string>53.IBPluginDependency</string>
|
<string>53.IBPluginDependency</string>
|
||||||
<string>53.IBShouldRemoveOnLegacySave</string>
|
<string>53.IBShouldRemoveOnLegacySave</string>
|
||||||
|
<string>55.IBPluginDependency</string>
|
||||||
|
<string>56.IBPluginDependency</string>
|
||||||
|
<string>57.IBPluginDependency</string>
|
||||||
<string>6.IBPluginDependency</string>
|
<string>6.IBPluginDependency</string>
|
||||||
<string>6.ImportedFromIB2</string>
|
<string>6.ImportedFromIB2</string>
|
||||||
<string>7.IBPluginDependency</string>
|
<string>7.IBPluginDependency</string>
|
||||||
@@ -761,7 +780,7 @@
|
|||||||
<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>DirectoryOutline</string>
|
<string>HSOutlineView</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>
|
||||||
@@ -788,6 +807,7 @@
|
|||||||
<boolean value="YES"/>
|
<boolean value="YES"/>
|
||||||
<boolean value="YES"/>
|
<boolean value="YES"/>
|
||||||
<string>{369, 269}</string>
|
<string>{369, 269}</string>
|
||||||
|
<string>{{98, 740}, {327, 63}}</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>
|
||||||
<boolean value="YES"/>
|
<boolean value="YES"/>
|
||||||
@@ -796,6 +816,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>
|
||||||
|
<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>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<boolean value="YES"/>
|
<boolean value="YES"/>
|
||||||
@@ -821,78 +844,19 @@
|
|||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<nil key="sourceID"/>
|
<nil key="sourceID"/>
|
||||||
<int key="maxID">53</int>
|
<int key="maxID">57</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">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
<object class="IBPartialClassDescription">
|
|
||||||
<string key="className">DirectoryOutline</string>
|
|
||||||
<string key="superclassName">OutlineView</string>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="462913745">
|
|
||||||
<string key="majorKey">IBProjectSource</string>
|
|
||||||
<string key="minorKey">dgbase/DirectoryPanel.h</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
<string key="className">DirectoryPanel</string>
|
<string key="className">DirectoryPanel</string>
|
||||||
<string key="superclassName">DirectoryPanelBase</string>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBProjectSource</string>
|
|
||||||
<string key="minorKey">DirectoryPanel.h</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBPartialClassDescription">
|
|
||||||
<string key="className">DirectoryPanel</string>
|
|
||||||
<string key="superclassName">DirectoryPanelBase</string>
|
|
||||||
<object class="NSMutableDictionary" key="actions">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<object class="NSArray" key="dict.sortedKeys">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<string>askForDirectory:</string>
|
|
||||||
<string>changeDirectoryState:</string>
|
|
||||||
<string>popupAddDirectoryMenu:</string>
|
|
||||||
<string>removeSelectedDirectory:</string>
|
|
||||||
<string>toggleVisible:</string>
|
|
||||||
</object>
|
|
||||||
<object class="NSMutableArray" key="dict.values">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="NSMutableDictionary" key="outlets">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<object class="NSArray" key="dict.sortedKeys">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<string>addButtonPopUp</string>
|
|
||||||
<string>directories</string>
|
|
||||||
<string>removeButton</string>
|
|
||||||
</object>
|
|
||||||
<object class="NSMutableArray" key="dict.values">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<string>NSPopUpButton</string>
|
|
||||||
<string>NSOutlineView</string>
|
|
||||||
<string>NSButton</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBUserSource</string>
|
|
||||||
<string key="minorKey"/>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBPartialClassDescription">
|
|
||||||
<string key="className">DirectoryPanelBase</string>
|
|
||||||
<string key="superclassName">NSWindowController</string>
|
<string key="superclassName">NSWindowController</string>
|
||||||
<object class="NSMutableDictionary" key="actions">
|
<object class="NSMutableDictionary" key="actions">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
<object class="NSArray" key="dict.sortedKeys">
|
<object class="NSArray" key="dict.sortedKeys">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
<string>askForDirectory:</string>
|
<string>askForDirectory:</string>
|
||||||
<string>changeDirectoryState:</string>
|
|
||||||
<string>popupAddDirectoryMenu:</string>
|
<string>popupAddDirectoryMenu:</string>
|
||||||
<string>removeSelectedDirectory:</string>
|
<string>removeSelectedDirectory:</string>
|
||||||
<string>toggleVisible:</string>
|
<string>toggleVisible:</string>
|
||||||
@@ -903,7 +867,6 @@
|
|||||||
<string>id</string>
|
<string>id</string>
|
||||||
<string>id</string>
|
<string>id</string>
|
||||||
<string>id</string>
|
<string>id</string>
|
||||||
<string>id</string>
|
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSMutableDictionary" key="outlets">
|
<object class="NSMutableDictionary" key="outlets">
|
||||||
@@ -911,17 +874,28 @@
|
|||||||
<object class="NSArray" key="dict.sortedKeys">
|
<object class="NSArray" key="dict.sortedKeys">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
<string>addButtonPopUp</string>
|
<string>addButtonPopUp</string>
|
||||||
<string>directories</string>
|
<string>outlineView</string>
|
||||||
<string>removeButton</string>
|
<string>removeButton</string>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSMutableArray" key="dict.values">
|
<object class="NSMutableArray" key="dict.values">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
<string>NSPopUpButton</string>
|
<string>NSPopUpButton</string>
|
||||||
<string>DirectoryOutline</string>
|
<string>HSOutlineView</string>
|
||||||
<string>NSButton</string>
|
<string>NSButton</string>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<reference key="sourceIdentifier" ref="462913745"/>
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
|
<string key="majorKey">IBProjectSource</string>
|
||||||
|
<string key="minorKey">../base/DirectoryPanel.h</string>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="IBPartialClassDescription">
|
||||||
|
<string key="className">DirectoryPanel</string>
|
||||||
|
<string key="superclassName">NSWindowController</string>
|
||||||
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
|
<string key="majorKey">IBUserSource</string>
|
||||||
|
<string key="minorKey"/>
|
||||||
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
<string key="className">FirstResponder</string>
|
<string key="className">FirstResponder</string>
|
||||||
@@ -932,40 +906,27 @@
|
|||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
<string key="className">OutlineView</string>
|
<string key="className">HSOutlineView</string>
|
||||||
<string key="superclassName">NSOutlineView</string>
|
<string key="superclassName">NSOutlineView</string>
|
||||||
<object class="NSMutableDictionary" key="outlets">
|
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="53364925">
|
||||||
<string key="NS.key.0">py</string>
|
|
||||||
<string key="NS.object.0">PyApp</string>
|
|
||||||
</object>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBProjectSource</string>
|
<string key="majorKey">IBProjectSource</string>
|
||||||
<string key="minorKey">cocoalib/Outline.h</string>
|
<string key="minorKey">../views/HSOutlineView.h</string>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
<string key="className">OutlineView</string>
|
<string key="className">NSObject</string>
|
||||||
<string key="superclassName">NSOutlineView</string>
|
<reference key="sourceIdentifier" ref="53364925"/>
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
</object>
|
||||||
<string key="majorKey">IBUserSource</string>
|
<object class="IBPartialClassDescription">
|
||||||
<string key="minorKey"/>
|
<string key="className">NSObject</string>
|
||||||
|
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="42597526">
|
||||||
|
<string key="majorKey">IBProjectSource</string>
|
||||||
|
<string key="minorKey">../views/NSTableViewAdditions.h</string>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
<string key="className">PyApp</string>
|
<string key="className">NSTableView</string>
|
||||||
<string key="superclassName">PyRegistrable</string>
|
<reference key="sourceIdentifier" ref="42597526"/>
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBProjectSource</string>
|
|
||||||
<string key="minorKey">cocoalib/PyApp.h</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBPartialClassDescription">
|
|
||||||
<string key="className">PyRegistrable</string>
|
|
||||||
<string key="superclassName">NSObject</string>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBProjectSource</string>
|
|
||||||
<string key="minorKey">cocoalib/PyRegistrable.h</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
|
<object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
|
||||||
@@ -1497,7 +1458,7 @@
|
|||||||
<integer value="3000" key="NS.object.0"/>
|
<integer value="3000" key="NS.object.0"/>
|
||||||
</object>
|
</object>
|
||||||
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
||||||
<string key="IBDocument.LastKnownRelativeProjectPath">../../dupeguru.xcodeproj</string>
|
<string key="IBDocument.LastKnownRelativeProjectPath">../../se/dupeguru.xcodeproj</string>
|
||||||
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
||||||
</data>
|
</data>
|
||||||
</archive>
|
</archive>
|
||||||
|
|||||||
@@ -2,18 +2,18 @@
|
|||||||
<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">10B504</string>
|
<string key="IBDocument.SystemVersion">10D573</string>
|
||||||
<string key="IBDocument.InterfaceBuilderVersion">740</string>
|
<string key="IBDocument.InterfaceBuilderVersion">740</string>
|
||||||
<string key="IBDocument.AppKitVersion">1038.2</string>
|
<string key="IBDocument.AppKitVersion">1038.29</string>
|
||||||
<string key="IBDocument.HIToolboxVersion">437.00</string>
|
<string key="IBDocument.HIToolboxVersion">460.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">740</string>
|
<string key="NS.object.0">740</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>
|
||||||
<integer value="29"/>
|
<integer value="598"/>
|
||||||
<integer value="21"/>
|
<integer value="219"/>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSArray" key="IBDocument.PluginDependencies">
|
<object class="NSArray" key="IBDocument.PluginDependencies">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
@@ -83,11 +83,9 @@
|
|||||||
<string key="NSToolbarItemPaletteLabel">Power Marker</string>
|
<string key="NSToolbarItemPaletteLabel">Power Marker</string>
|
||||||
<nil key="NSToolbarItemToolTip"/>
|
<nil key="NSToolbarItemToolTip"/>
|
||||||
<object class="NSSegmentedControl" key="NSToolbarItemView" id="35398541">
|
<object class="NSSegmentedControl" key="NSToolbarItemView" id="35398541">
|
||||||
<reference key="NSNextResponder"/>
|
<nil key="NSNextResponder"/>
|
||||||
<int key="NSvFlags">256</int>
|
<int key="NSvFlags">256</int>
|
||||||
<string key="NSFrame">{{7, 14}, {67, 24}}</string>
|
<string key="NSFrame">{{7, 14}, {67, 24}}</string>
|
||||||
<reference key="NSSuperview"/>
|
|
||||||
<reference key="NSWindow"/>
|
|
||||||
<bool key="NSEnabled">YES</bool>
|
<bool key="NSEnabled">YES</bool>
|
||||||
<object class="NSSegmentedCell" key="NSCell" id="431579725">
|
<object class="NSSegmentedCell" key="NSCell" id="431579725">
|
||||||
<int key="NSCellFlags">67239424</int>
|
<int key="NSCellFlags">67239424</int>
|
||||||
@@ -178,11 +176,9 @@
|
|||||||
<string key="NSToolbarItemPaletteLabel">Filter</string>
|
<string key="NSToolbarItemPaletteLabel">Filter</string>
|
||||||
<nil key="NSToolbarItemToolTip"/>
|
<nil key="NSToolbarItemToolTip"/>
|
||||||
<object class="NSSearchField" key="NSToolbarItemView" id="1013657232">
|
<object class="NSSearchField" key="NSToolbarItemView" id="1013657232">
|
||||||
<reference key="NSNextResponder"/>
|
<nil key="NSNextResponder"/>
|
||||||
<int key="NSvFlags">258</int>
|
<int key="NSvFlags">258</int>
|
||||||
<string key="NSFrame">{{0, 14}, {81, 22}}</string>
|
<string key="NSFrame">{{0, 14}, {81, 22}}</string>
|
||||||
<reference key="NSSuperview"/>
|
|
||||||
<reference key="NSWindow"/>
|
|
||||||
<bool key="NSEnabled">YES</bool>
|
<bool key="NSEnabled">YES</bool>
|
||||||
<object class="NSSearchFieldCell" key="NSCell" id="484816507">
|
<object class="NSSearchFieldCell" key="NSCell" id="484816507">
|
||||||
<int key="NSCellFlags">343014976</int>
|
<int key="NSCellFlags">343014976</int>
|
||||||
@@ -324,11 +320,9 @@
|
|||||||
<string key="NSToolbarItemPaletteLabel">Action</string>
|
<string key="NSToolbarItemPaletteLabel">Action</string>
|
||||||
<nil key="NSToolbarItemToolTip"/>
|
<nil key="NSToolbarItemToolTip"/>
|
||||||
<object class="NSPopUpButton" key="NSToolbarItemView" id="165812138">
|
<object class="NSPopUpButton" key="NSToolbarItemView" id="165812138">
|
||||||
<reference key="NSNextResponder"/>
|
<nil key="NSNextResponder"/>
|
||||||
<int key="NSvFlags">256</int>
|
<int key="NSvFlags">256</int>
|
||||||
<string key="NSFrame">{{0, 14}, {58, 26}}</string>
|
<string key="NSFrame">{{0, 14}, {58, 26}}</string>
|
||||||
<reference key="NSSuperview"/>
|
|
||||||
<reference key="NSWindow"/>
|
|
||||||
<bool key="NSEnabled">YES</bool>
|
<bool key="NSEnabled">YES</bool>
|
||||||
<object class="NSPopUpButtonCell" key="NSCell" id="436420677">
|
<object class="NSPopUpButtonCell" key="NSCell" id="436420677">
|
||||||
<int key="NSCellFlags">-2076049856</int>
|
<int key="NSCellFlags">-2076049856</int>
|
||||||
@@ -531,11 +525,9 @@
|
|||||||
<string key="NSToolbarItemPaletteLabel">Delta Values</string>
|
<string key="NSToolbarItemPaletteLabel">Delta Values</string>
|
||||||
<nil key="NSToolbarItemToolTip"/>
|
<nil key="NSToolbarItemToolTip"/>
|
||||||
<object class="NSSegmentedControl" key="NSToolbarItemView" id="311230297">
|
<object class="NSSegmentedControl" key="NSToolbarItemView" id="311230297">
|
||||||
<reference key="NSNextResponder"/>
|
<nil key="NSNextResponder"/>
|
||||||
<int key="NSvFlags">256</int>
|
<int key="NSvFlags">256</int>
|
||||||
<string key="NSFrame">{{4, 14}, {67, 24}}</string>
|
<string key="NSFrame">{{4, 14}, {67, 24}}</string>
|
||||||
<reference key="NSSuperview"/>
|
|
||||||
<reference key="NSWindow"/>
|
|
||||||
<bool key="NSEnabled">YES</bool>
|
<bool key="NSEnabled">YES</bool>
|
||||||
<object class="NSSegmentedCell" key="NSCell" id="211272396">
|
<object class="NSSegmentedCell" key="NSCell" id="211272396">
|
||||||
<int key="NSCellFlags">67239424</int>
|
<int key="NSCellFlags">67239424</int>
|
||||||
@@ -718,7 +710,7 @@
|
|||||||
<object class="NSMutableArray" key="NSTableColumns">
|
<object class="NSMutableArray" key="NSTableColumns">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
<object class="NSTableColumn" id="430098394">
|
<object class="NSTableColumn" id="430098394">
|
||||||
<string key="NSIdentifier">mark</string>
|
<string key="NSIdentifier">marked</string>
|
||||||
<double key="NSWidth">47</double>
|
<double key="NSWidth">47</double>
|
||||||
<double key="NSMinWidth">16</double>
|
<double key="NSMinWidth">16</double>
|
||||||
<double key="NSMaxWidth">1000</double>
|
<double key="NSMaxWidth">1000</double>
|
||||||
@@ -760,6 +752,7 @@
|
|||||||
<int key="NSPeriodicDelay">400</int>
|
<int key="NSPeriodicDelay">400</int>
|
||||||
<int key="NSPeriodicInterval">75</int>
|
<int key="NSPeriodicInterval">75</int>
|
||||||
</object>
|
</object>
|
||||||
|
<bool key="NSIsEditable">YES</bool>
|
||||||
<reference key="NSTableView" ref="40047569"/>
|
<reference key="NSTableView" ref="40047569"/>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSTableColumn" id="932540235">
|
<object class="NSTableColumn" id="932540235">
|
||||||
@@ -1153,7 +1146,7 @@
|
|||||||
<object class="NSMenuItem" id="578499792">
|
<object class="NSMenuItem" id="578499792">
|
||||||
<reference key="NSMenu" ref="600111647"/>
|
<reference key="NSMenu" ref="600111647"/>
|
||||||
<string key="NSTitle">Clear Ignore List</string>
|
<string key="NSTitle">Clear Ignore List</string>
|
||||||
<string key="NSKeyEquiv">I</string>
|
<string key="NSKeyEquiv">G</string>
|
||||||
<int key="NSKeyEquivModMask">1048576</int>
|
<int key="NSKeyEquivModMask">1048576</int>
|
||||||
<int key="NSMnemonicLoc">2147483647</int>
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
<reference key="NSOnImage" ref="852972005"/>
|
<reference key="NSOnImage" ref="852972005"/>
|
||||||
@@ -1238,7 +1231,7 @@
|
|||||||
<object class="NSMenuItem" id="904423169">
|
<object class="NSMenuItem" id="904423169">
|
||||||
<reference key="NSMenu" ref="600111647"/>
|
<reference key="NSMenu" ref="600111647"/>
|
||||||
<string key="NSTitle">Add Selected to Ignore List</string>
|
<string key="NSTitle">Add Selected to Ignore List</string>
|
||||||
<string key="NSKeyEquiv">i</string>
|
<string key="NSKeyEquiv">g</string>
|
||||||
<int key="NSKeyEquivModMask">1048576</int>
|
<int key="NSKeyEquivModMask">1048576</int>
|
||||||
<int key="NSMnemonicLoc">2147483647</int>
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
<reference key="NSOnImage" ref="852972005"/>
|
<reference key="NSOnImage" ref="852972005"/>
|
||||||
@@ -1282,6 +1275,15 @@
|
|||||||
<reference key="NSOnImage" ref="852972005"/>
|
<reference key="NSOnImage" ref="852972005"/>
|
||||||
<reference key="NSMixedImage" ref="218295580"/>
|
<reference key="NSMixedImage" ref="218295580"/>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="NSMenuItem" id="517397504">
|
||||||
|
<reference key="NSMenu" ref="600111647"/>
|
||||||
|
<string key="NSTitle">Invoke Custom Command</string>
|
||||||
|
<string key="NSKeyEquiv">i</string>
|
||||||
|
<int key="NSKeyEquivModMask">1048576</int>
|
||||||
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
|
<reference key="NSOnImage" ref="852972005"/>
|
||||||
|
<reference key="NSMixedImage" ref="218295580"/>
|
||||||
|
</object>
|
||||||
<object class="NSMenuItem" id="564101661">
|
<object class="NSMenuItem" id="564101661">
|
||||||
<reference key="NSMenu" ref="600111647"/>
|
<reference key="NSMenu" ref="600111647"/>
|
||||||
<string key="NSTitle">Rename Selected</string>
|
<string key="NSTitle">Rename Selected</string>
|
||||||
@@ -1675,14 +1677,6 @@
|
|||||||
</object>
|
</object>
|
||||||
<int key="connectionID">212</int>
|
<int key="connectionID">212</int>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBConnectionRecord">
|
|
||||||
<object class="IBOutletConnection" key="connection">
|
|
||||||
<string key="label">matches</string>
|
|
||||||
<reference key="source" ref="339936126"/>
|
|
||||||
<reference key="destination" ref="40047569"/>
|
|
||||||
</object>
|
|
||||||
<int key="connectionID">245</int>
|
|
||||||
</object>
|
|
||||||
<object class="IBConnectionRecord">
|
<object class="IBConnectionRecord">
|
||||||
<object class="IBOutletConnection" key="connection">
|
<object class="IBOutletConnection" key="connection">
|
||||||
<string key="label">initialFirstResponder</string>
|
<string key="label">initialFirstResponder</string>
|
||||||
@@ -1691,22 +1685,6 @@
|
|||||||
</object>
|
</object>
|
||||||
<int key="connectionID">279</int>
|
<int key="connectionID">279</int>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBConnectionRecord">
|
|
||||||
<object class="IBOutletConnection" key="connection">
|
|
||||||
<string key="label">delegate</string>
|
|
||||||
<reference key="source" ref="40047569"/>
|
|
||||||
<reference key="destination" ref="339936126"/>
|
|
||||||
</object>
|
|
||||||
<int key="connectionID">410</int>
|
|
||||||
</object>
|
|
||||||
<object class="IBConnectionRecord">
|
|
||||||
<object class="IBActionConnection" key="connection">
|
|
||||||
<string key="label">markToggle:</string>
|
|
||||||
<reference key="source" ref="339936126"/>
|
|
||||||
<reference key="destination" ref="705360835"/>
|
|
||||||
</object>
|
|
||||||
<int key="connectionID">414</int>
|
|
||||||
</object>
|
|
||||||
<object class="IBConnectionRecord">
|
<object class="IBConnectionRecord">
|
||||||
<object class="IBOutletConnection" key="connection">
|
<object class="IBOutletConnection" key="connection">
|
||||||
<string key="label">stats</string>
|
<string key="label">stats</string>
|
||||||
@@ -1947,14 +1925,6 @@
|
|||||||
</object>
|
</object>
|
||||||
<int key="connectionID">758</int>
|
<int key="connectionID">758</int>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBConnectionRecord">
|
|
||||||
<object class="IBOutletConnection" key="connection">
|
|
||||||
<string key="label">py</string>
|
|
||||||
<reference key="source" ref="40047569"/>
|
|
||||||
<reference key="destination" ref="875360857"/>
|
|
||||||
</object>
|
|
||||||
<int key="connectionID">764</int>
|
|
||||||
</object>
|
|
||||||
<object class="IBConnectionRecord">
|
<object class="IBConnectionRecord">
|
||||||
<object class="IBActionConnection" key="connection">
|
<object class="IBActionConnection" key="connection">
|
||||||
<string key="label">removeSelected:</string>
|
<string key="label">removeSelected:</string>
|
||||||
@@ -2227,6 +2197,30 @@
|
|||||||
</object>
|
</object>
|
||||||
<int key="connectionID">1174</int>
|
<int key="connectionID">1174</int>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="IBConnectionRecord">
|
||||||
|
<object class="IBOutletConnection" key="connection">
|
||||||
|
<string key="label">delegate</string>
|
||||||
|
<reference key="source" ref="23220930"/>
|
||||||
|
<reference key="destination" ref="91622651"/>
|
||||||
|
</object>
|
||||||
|
<int key="connectionID">1175</int>
|
||||||
|
</object>
|
||||||
|
<object class="IBConnectionRecord">
|
||||||
|
<object class="IBOutletConnection" key="connection">
|
||||||
|
<string key="label">matches</string>
|
||||||
|
<reference key="source" ref="339936126"/>
|
||||||
|
<reference key="destination" ref="40047569"/>
|
||||||
|
</object>
|
||||||
|
<int key="connectionID">1176</int>
|
||||||
|
</object>
|
||||||
|
<object class="IBConnectionRecord">
|
||||||
|
<object class="IBActionConnection" key="connection">
|
||||||
|
<string key="label">invokeCustomCommand:</string>
|
||||||
|
<reference key="source" ref="339936126"/>
|
||||||
|
<reference key="destination" ref="517397504"/>
|
||||||
|
</object>
|
||||||
|
<int key="connectionID">1178</int>
|
||||||
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||||
<object class="NSArray" key="orderedObjects">
|
<object class="NSArray" key="orderedObjects">
|
||||||
@@ -2553,6 +2547,7 @@
|
|||||||
<reference ref="564101661"/>
|
<reference ref="564101661"/>
|
||||||
<reference ref="630362403"/>
|
<reference ref="630362403"/>
|
||||||
<reference ref="747820446"/>
|
<reference ref="747820446"/>
|
||||||
|
<reference ref="517397504"/>
|
||||||
</object>
|
</object>
|
||||||
<reference key="parent" ref="528113253"/>
|
<reference key="parent" ref="528113253"/>
|
||||||
</object>
|
</object>
|
||||||
@@ -3089,6 +3084,11 @@
|
|||||||
<reference key="object" ref="747820446"/>
|
<reference key="object" ref="747820446"/>
|
||||||
<reference key="parent" ref="600111647"/>
|
<reference key="parent" ref="600111647"/>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="IBObjectRecord">
|
||||||
|
<int key="objectID">1177</int>
|
||||||
|
<reference key="object" ref="517397504"/>
|
||||||
|
<reference key="parent" ref="600111647"/>
|
||||||
|
</object>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSMutableDictionary" key="flattenedProperties">
|
<object class="NSMutableDictionary" key="flattenedProperties">
|
||||||
@@ -3140,6 +3140,7 @@
|
|||||||
<string>1171.IBPluginDependency</string>
|
<string>1171.IBPluginDependency</string>
|
||||||
<string>1172.IBPluginDependency</string>
|
<string>1172.IBPluginDependency</string>
|
||||||
<string>1173.IBPluginDependency</string>
|
<string>1173.IBPluginDependency</string>
|
||||||
|
<string>1177.IBPluginDependency</string>
|
||||||
<string>134.IBPluginDependency</string>
|
<string>134.IBPluginDependency</string>
|
||||||
<string>134.ImportedFromIB2</string>
|
<string>134.ImportedFromIB2</string>
|
||||||
<string>136.IBPluginDependency</string>
|
<string>136.IBPluginDependency</string>
|
||||||
@@ -3378,6 +3379,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>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"/>
|
||||||
@@ -3397,16 +3399,16 @@
|
|||||||
<boolean value="YES"/>
|
<boolean value="YES"/>
|
||||||
<boolean value="YES"/>
|
<boolean value="YES"/>
|
||||||
<boolean value="YES"/>
|
<boolean value="YES"/>
|
||||||
<string>{{109, 366}, {557, 400}}</string>
|
<string>{{439, 345}, {557, 400}}</string>
|
||||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<string>{{109, 366}, {557, 400}}</string>
|
<string>{{439, 345}, {557, 400}}</string>
|
||||||
<boolean value="YES"/>
|
<boolean value="YES"/>
|
||||||
<boolean value="YES"/>
|
<boolean value="YES"/>
|
||||||
<boolean value="YES"/>
|
<boolean value="YES"/>
|
||||||
<string>{340, 340}</string>
|
<string>{340, 340}</string>
|
||||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<boolean value="YES"/>
|
<boolean value="YES"/>
|
||||||
<string>MatchesView</string>
|
<string>HSOutlineView</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>
|
||||||
@@ -3446,7 +3448,7 @@
|
|||||||
<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>{{286, 475}, {361, 293}}</string>
|
<string>{{286, 455}, {361, 313}}</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>
|
||||||
@@ -3584,7 +3586,7 @@
|
|||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<nil key="sourceID"/>
|
<nil key="sourceID"/>
|
||||||
<int key="maxID">1174</int>
|
<int key="maxID">1178</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">
|
||||||
@@ -3663,7 +3665,7 @@
|
|||||||
</object>
|
</object>
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
<string key="majorKey">IBProjectSource</string>
|
<string key="majorKey">IBProjectSource</string>
|
||||||
<string key="minorKey">dgbase/AppDelegate.h</string>
|
<string key="minorKey">../base/AppDelegate.h</string>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
@@ -3675,19 +3677,22 @@
|
|||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
<string key="className">MatchesView</string>
|
<string key="className">HSOutlineView</string>
|
||||||
<string key="superclassName">OutlineView</string>
|
<string key="superclassName">NSOutlineView</string>
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="417275989">
|
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="384069338">
|
||||||
<string key="majorKey">IBProjectSource</string>
|
<string key="majorKey">IBProjectSource</string>
|
||||||
<string key="minorKey">dgbase/ResultWindow.h</string>
|
<string key="minorKey">../views/HSOutlineView.h</string>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
<string key="className">MatchesView</string>
|
<string key="className">NSObject</string>
|
||||||
<string key="superclassName">OutlineView</string>
|
<reference key="sourceIdentifier" ref="384069338"/>
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
</object>
|
||||||
<string key="majorKey">IBUserSource</string>
|
<object class="IBPartialClassDescription">
|
||||||
<string key="minorKey"/>
|
<string key="className">NSObject</string>
|
||||||
|
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="653924221">
|
||||||
|
<string key="majorKey">IBProjectSource</string>
|
||||||
|
<string key="minorKey">../views/NSTableViewAdditions.h</string>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
@@ -3699,31 +3704,15 @@
|
|||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
<string key="className">OutlineView</string>
|
<string key="className">NSTableView</string>
|
||||||
<string key="superclassName">NSOutlineView</string>
|
<reference key="sourceIdentifier" ref="653924221"/>
|
||||||
<object class="NSMutableDictionary" key="outlets">
|
|
||||||
<string key="NS.key.0">py</string>
|
|
||||||
<string key="NS.object.0">PyApp</string>
|
|
||||||
</object>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBProjectSource</string>
|
|
||||||
<string key="minorKey">cocoalib/Outline.h</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBPartialClassDescription">
|
|
||||||
<string key="className">OutlineView</string>
|
|
||||||
<string key="superclassName">NSOutlineView</string>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBUserSource</string>
|
|
||||||
<string key="minorKey"/>
|
|
||||||
</object>
|
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
<string key="className">PyApp</string>
|
<string key="className">PyApp</string>
|
||||||
<string key="superclassName">PyRegistrable</string>
|
<string key="superclassName">PyRegistrable</string>
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
<string key="majorKey">IBProjectSource</string>
|
<string key="majorKey">IBProjectSource</string>
|
||||||
<string key="minorKey">cocoalib/PyApp.h</string>
|
<string key="minorKey">../PyApp.h</string>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
@@ -3755,7 +3744,7 @@
|
|||||||
<string key="superclassName">PyApp</string>
|
<string key="superclassName">PyApp</string>
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
<string key="majorKey">IBProjectSource</string>
|
<string key="majorKey">IBProjectSource</string>
|
||||||
<string key="minorKey">dgbase/PyDupeGuru.h</string>
|
<string key="minorKey">../base/PyDupeGuru.h</string>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
@@ -3763,7 +3752,7 @@
|
|||||||
<string key="superclassName">NSObject</string>
|
<string key="superclassName">NSObject</string>
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
<string key="majorKey">IBProjectSource</string>
|
<string key="majorKey">IBProjectSource</string>
|
||||||
<string key="minorKey">cocoalib/PyRegistrable.h</string>
|
<string key="minorKey">../PyRegistrable.h</string>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
@@ -3797,7 +3786,7 @@
|
|||||||
</object>
|
</object>
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
<string key="majorKey">IBProjectSource</string>
|
<string key="majorKey">IBProjectSource</string>
|
||||||
<string key="minorKey">cocoalib/RecentDirectories.h</string>
|
<string key="minorKey">../RecentDirectories.h</string>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
@@ -3815,120 +3804,20 @@
|
|||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
<object class="NSArray" key="dict.sortedKeys">
|
<object class="NSArray" key="dict.sortedKeys">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
<string>clearIgnoreList:</string>
|
|
||||||
<string>filter:</string>
|
|
||||||
<string>ignoreSelected:</string>
|
|
||||||
<string>markAll:</string>
|
|
||||||
<string>markInvert:</string>
|
|
||||||
<string>markNone:</string>
|
|
||||||
<string>markSelected:</string>
|
|
||||||
<string>markToggle:</string>
|
|
||||||
<string>openSelected:</string>
|
|
||||||
<string>refresh:</string>
|
|
||||||
<string>removeMarked:</string>
|
|
||||||
<string>removeSelected:</string>
|
|
||||||
<string>renameSelected:</string>
|
|
||||||
<string>resetColumnsToDefault:</string>
|
<string>resetColumnsToDefault:</string>
|
||||||
<string>revealSelected:</string>
|
|
||||||
<string>startDuplicateScan:</string>
|
<string>startDuplicateScan:</string>
|
||||||
<string>toggleDelta:</string>
|
|
||||||
</object>
|
</object>
|
||||||
<object class="NSMutableArray" key="dict.values">
|
<object class="NSMutableArray" key="dict.values">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
<string>id</string>
|
<string>id</string>
|
||||||
<string>id</string>
|
<string>id</string>
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSMutableDictionary" key="outlets">
|
|
||||||
<string key="NS.key.0">filterField</string>
|
|
||||||
<string key="NS.object.0">NSSearchField</string>
|
|
||||||
</object>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
<string key="majorKey">IBProjectSource</string>
|
<string key="majorKey">IBProjectSource</string>
|
||||||
<string key="minorKey">ResultWindow.h</string>
|
<string key="minorKey">ResultWindow.h</string>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
|
||||||
<string key="className">ResultWindow</string>
|
|
||||||
<string key="superclassName">ResultWindowBase</string>
|
|
||||||
<object class="NSMutableDictionary" key="actions">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<object class="NSArray" key="dict.sortedKeys">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<string>changeDelta:</string>
|
|
||||||
<string>changePowerMarker:</string>
|
|
||||||
<string>collapseAll:</string>
|
|
||||||
<string>copyMarked:</string>
|
|
||||||
<string>deleteMarked:</string>
|
|
||||||
<string>expandAll:</string>
|
|
||||||
<string>exportToXHTML:</string>
|
|
||||||
<string>moveMarked:</string>
|
|
||||||
<string>switchSelected:</string>
|
|
||||||
<string>togglePowerMarker:</string>
|
|
||||||
</object>
|
|
||||||
<object class="NSMutableArray" key="dict.values">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>id</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="NSMutableDictionary" key="outlets">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<object class="NSArray" key="dict.sortedKeys">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<string>actionMenuView</string>
|
|
||||||
<string>app</string>
|
|
||||||
<string>deltaSwitch</string>
|
|
||||||
<string>deltaSwitchView</string>
|
|
||||||
<string>filterFieldView</string>
|
|
||||||
<string>matches</string>
|
|
||||||
<string>pmSwitch</string>
|
|
||||||
<string>pmSwitchView</string>
|
|
||||||
<string>py</string>
|
|
||||||
<string>stats</string>
|
|
||||||
</object>
|
|
||||||
<object class="NSMutableArray" key="dict.values">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<string>NSView</string>
|
|
||||||
<string>id</string>
|
|
||||||
<string>NSSegmentedControl</string>
|
|
||||||
<string>NSView</string>
|
|
||||||
<string>NSView</string>
|
|
||||||
<string>MatchesView</string>
|
|
||||||
<string>NSSegmentedControl</string>
|
|
||||||
<string>NSView</string>
|
|
||||||
<string>PyDupeGuru</string>
|
|
||||||
<string>NSTextField</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBUserSource</string>
|
|
||||||
<string key="minorKey"/>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
<string key="className">ResultWindowBase</string>
|
<string key="className">ResultWindowBase</string>
|
||||||
<string key="superclassName">NSWindowController</string>
|
<string key="superclassName">NSWindowController</string>
|
||||||
@@ -3938,15 +3827,30 @@
|
|||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
<string>changeDelta:</string>
|
<string>changeDelta:</string>
|
||||||
<string>changePowerMarker:</string>
|
<string>changePowerMarker:</string>
|
||||||
|
<string>clearIgnoreList:</string>
|
||||||
<string>copyMarked:</string>
|
<string>copyMarked:</string>
|
||||||
<string>deleteMarked:</string>
|
<string>deleteMarked:</string>
|
||||||
<string>expandAll:</string>
|
|
||||||
<string>exportToXHTML:</string>
|
<string>exportToXHTML:</string>
|
||||||
|
<string>filter:</string>
|
||||||
|
<string>ignoreSelected:</string>
|
||||||
|
<string>invokeCustomCommand:</string>
|
||||||
|
<string>markAll:</string>
|
||||||
|
<string>markInvert:</string>
|
||||||
|
<string>markNone:</string>
|
||||||
|
<string>markSelected:</string>
|
||||||
<string>moveMarked:</string>
|
<string>moveMarked:</string>
|
||||||
|
<string>openClicked:</string>
|
||||||
|
<string>openSelected:</string>
|
||||||
|
<string>removeMarked:</string>
|
||||||
|
<string>removeSelected:</string>
|
||||||
|
<string>renameSelected:</string>
|
||||||
<string>resetColumnsToDefault:</string>
|
<string>resetColumnsToDefault:</string>
|
||||||
|
<string>revealSelected:</string>
|
||||||
<string>showPreferencesPanel:</string>
|
<string>showPreferencesPanel:</string>
|
||||||
|
<string>startDuplicateScan:</string>
|
||||||
<string>switchSelected:</string>
|
<string>switchSelected:</string>
|
||||||
<string>toggleColumn:</string>
|
<string>toggleColumn:</string>
|
||||||
|
<string>toggleDelta:</string>
|
||||||
<string>toggleDetailsPanel:</string>
|
<string>toggleDetailsPanel:</string>
|
||||||
<string>togglePowerMarker:</string>
|
<string>togglePowerMarker:</string>
|
||||||
</object>
|
</object>
|
||||||
@@ -3965,6 +3869,21 @@
|
|||||||
<string>id</string>
|
<string>id</string>
|
||||||
<string>id</string>
|
<string>id</string>
|
||||||
<string>id</string>
|
<string>id</string>
|
||||||
|
<string>id</string>
|
||||||
|
<string>id</string>
|
||||||
|
<string>id</string>
|
||||||
|
<string>id</string>
|
||||||
|
<string>id</string>
|
||||||
|
<string>id</string>
|
||||||
|
<string>id</string>
|
||||||
|
<string>id</string>
|
||||||
|
<string>id</string>
|
||||||
|
<string>id</string>
|
||||||
|
<string>id</string>
|
||||||
|
<string>id</string>
|
||||||
|
<string>id</string>
|
||||||
|
<string>id</string>
|
||||||
|
<string>id</string>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSMutableDictionary" key="outlets">
|
<object class="NSMutableDictionary" key="outlets">
|
||||||
@@ -3974,6 +3893,7 @@
|
|||||||
<string>app</string>
|
<string>app</string>
|
||||||
<string>columnsMenu</string>
|
<string>columnsMenu</string>
|
||||||
<string>deltaSwitch</string>
|
<string>deltaSwitch</string>
|
||||||
|
<string>filterField</string>
|
||||||
<string>matches</string>
|
<string>matches</string>
|
||||||
<string>pmSwitch</string>
|
<string>pmSwitch</string>
|
||||||
<string>py</string>
|
<string>py</string>
|
||||||
@@ -3984,13 +3904,17 @@
|
|||||||
<string>id</string>
|
<string>id</string>
|
||||||
<string>NSMenu</string>
|
<string>NSMenu</string>
|
||||||
<string>NSSegmentedControl</string>
|
<string>NSSegmentedControl</string>
|
||||||
<string>MatchesView</string>
|
<string>NSSearchField</string>
|
||||||
|
<string>HSOutlineView</string>
|
||||||
<string>NSSegmentedControl</string>
|
<string>NSSegmentedControl</string>
|
||||||
<string>PyDupeGuruBase</string>
|
<string>PyDupeGuruBase</string>
|
||||||
<string>NSTextField</string>
|
<string>NSTextField</string>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<reference key="sourceIdentifier" ref="417275989"/>
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
|
<string key="majorKey">IBProjectSource</string>
|
||||||
|
<string key="minorKey">../base/ResultWindow.h</string>
|
||||||
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
<string key="className">SUUpdater</string>
|
<string key="className">SUUpdater</string>
|
||||||
@@ -4612,7 +4536,7 @@
|
|||||||
<integer value="3000" key="NS.object.0"/>
|
<integer value="3000" key="NS.object.0"/>
|
||||||
</object>
|
</object>
|
||||||
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
||||||
<string key="IBDocument.LastKnownRelativeProjectPath">../../dupeguru.xcodeproj</string>
|
<string key="IBDocument.LastKnownRelativeProjectPath">../../se/dupeguru.xcodeproj</string>
|
||||||
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
||||||
</data>
|
</data>
|
||||||
</archive>
|
</archive>
|
||||||
|
|||||||
1142
cocoa/base/xib/ProblemDialog.xib
Normal file
1142
cocoa/base/xib/ProblemDialog.xib
Normal file
File diff suppressed because it is too large
Load Diff
@@ -9,16 +9,11 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "../base/AppDelegate.h"
|
#import "../base/AppDelegate.h"
|
||||||
#import "ResultWindow.h"
|
#import "ResultWindow.h"
|
||||||
#import "DirectoryPanel.h"
|
|
||||||
#import "PyDupeGuru.h"
|
#import "PyDupeGuru.h"
|
||||||
|
|
||||||
@interface AppDelegate : AppDelegateBase
|
@interface AppDelegate : AppDelegateBase {}
|
||||||
{
|
|
||||||
DirectoryPanel *_directoryPanel;
|
|
||||||
}
|
|
||||||
- (IBAction)openWebsite:(id)sender;
|
- (IBAction)openWebsite:(id)sender;
|
||||||
- (IBAction)toggleDirectories:(id)sender;
|
- (IBAction)toggleDirectories:(id)sender;
|
||||||
|
|
||||||
- (DirectoryPanel *)directoryPanel;
|
|
||||||
- (PyDupeGuru *)py;
|
- (PyDupeGuru *)py;
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
#import "../../cocoalib/ValueTransformers.h"
|
#import "../../cocoalib/ValueTransformers.h"
|
||||||
#import "../../cocoalib/Dialogs.h"
|
#import "../../cocoalib/Dialogs.h"
|
||||||
#import "DetailsPanel.h"
|
#import "DetailsPanel.h"
|
||||||
|
#import "DirectoryPanel.h"
|
||||||
#import "Consts.h"
|
#import "Consts.h"
|
||||||
|
|
||||||
@implementation AppDelegate
|
@implementation AppDelegate
|
||||||
@@ -65,18 +66,10 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[[self directoryPanel] toggleVisible:sender];
|
[[self directoryPanel] toggleVisible:sender];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (DetailsPanelBase *)detailsPanel
|
|
||||||
{
|
|
||||||
if (!_detailsPanel)
|
|
||||||
_detailsPanel = [[DetailsPanel alloc] initWithPy:py];
|
|
||||||
return _detailsPanel;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (DirectoryPanel *)directoryPanel
|
- (DirectoryPanel *)directoryPanel
|
||||||
{
|
{
|
||||||
if (!_directoryPanel)
|
if (!_directoryPanel)
|
||||||
_directoryPanel = [[DirectoryPanel alloc] initWithParentApp:self];
|
_directoryPanel = [[DirectoryPanelME alloc] initWithParentApp:self];
|
||||||
return _directoryPanel;
|
return _directoryPanel;
|
||||||
}
|
}
|
||||||
- (PyDupeGuru *)py { return (PyDupeGuru *)py; }
|
- (PyDupeGuru *)py { return (PyDupeGuru *)py; }
|
||||||
@@ -91,36 +84,4 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[mi setTarget:result];
|
[mi setTarget:result];
|
||||||
[super applicationDidFinishLaunching:aNotification];
|
[super applicationDidFinishLaunching:aNotification];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationWillBecomeActive:(NSNotification *)aNotification
|
|
||||||
{
|
|
||||||
if (![[result window] isVisible])
|
|
||||||
[result showWindow:NSApp];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)applicationWillTerminate:(NSNotification *)aNotification
|
|
||||||
{
|
|
||||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
|
||||||
[ud setObject: [result getColumnsOrder] forKey:@"columnsOrder"];
|
|
||||||
[ud setObject: [result getColumnsWidth] forKey:@"columnsWidth"];
|
|
||||||
[py saveIgnoreList];
|
|
||||||
[py saveResults];
|
|
||||||
NSInteger sc = [ud integerForKey:@"sessionCountSinceLastIgnorePurge"];
|
|
||||||
if (sc >= 10)
|
|
||||||
{
|
|
||||||
sc = -1;
|
|
||||||
[py purgeIgnoreList];
|
|
||||||
}
|
|
||||||
sc++;
|
|
||||||
[ud setInteger:sc forKey:@"sessionCountSinceLastIgnorePurge"];
|
|
||||||
// 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
|
|
||||||
// But I need to release RecentDirectories so it saves the user defaults
|
|
||||||
[recentDirectories release];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)recentDirecoryClicked:(NSString *)directory
|
|
||||||
{
|
|
||||||
[[self directoryPanel] addDirectory:directory];
|
|
||||||
}
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
|
||||||
which should be included with this package. The terms are also available at
|
|
||||||
http://www.hardcoded.net/licenses/hs_license
|
|
||||||
*/
|
|
||||||
|
|
||||||
#import "DetailsPanel.h"
|
|
||||||
|
|
||||||
@implementation DetailsPanel
|
|
||||||
@end
|
|
||||||
@@ -9,7 +9,7 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "../base/DirectoryPanel.h"
|
#import "../base/DirectoryPanel.h"
|
||||||
|
|
||||||
@interface DirectoryPanel : DirectoryPanelBase
|
@interface DirectoryPanelME : DirectoryPanel
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
- (IBAction)addiTunes:(id)sender;
|
- (IBAction)addiTunes:(id)sender;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
|
|
||||||
#import "DirectoryPanel.h"
|
#import "DirectoryPanel.h"
|
||||||
|
|
||||||
@implementation DirectoryPanel
|
@implementation DirectoryPanelME
|
||||||
- (IBAction)addiTunes:(id)sender
|
- (IBAction)addiTunes:(id)sender
|
||||||
{
|
{
|
||||||
[self addDirectory:[@"~/Music/iTunes/iTunes Music" stringByExpandingTildeInPath]];
|
[self addDirectory:[@"~/Music/iTunes/iTunes Music" stringByExpandingTildeInPath]];
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>hsft</string>
|
<string>hsft</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>5.7.1</string>
|
<string>5.8.1</string>
|
||||||
<key>NSMainNibFile</key>
|
<key>NSMainNibFile</key>
|
||||||
<string>MainMenu</string>
|
<string>MainMenu</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
|
|||||||
@@ -7,32 +7,9 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "../../cocoalib/Outline.h"
|
|
||||||
#import "../base/ResultWindow.h"
|
#import "../base/ResultWindow.h"
|
||||||
#import "DirectoryPanel.h"
|
#import "DirectoryPanel.h"
|
||||||
|
|
||||||
@interface ResultWindow : ResultWindowBase
|
@interface ResultWindow : ResultWindowBase {}
|
||||||
{
|
|
||||||
IBOutlet NSSearchField *filterField;
|
|
||||||
|
|
||||||
NSString *_lastAction;
|
|
||||||
NSMutableIndexSet *_deltaColumns;
|
|
||||||
}
|
|
||||||
- (IBAction)clearIgnoreList:(id)sender;
|
|
||||||
- (IBAction)filter:(id)sender;
|
|
||||||
- (IBAction)ignoreSelected:(id)sender;
|
|
||||||
- (IBAction)markAll:(id)sender;
|
|
||||||
- (IBAction)markInvert:(id)sender;
|
|
||||||
- (IBAction)markNone:(id)sender;
|
|
||||||
- (IBAction)markSelected:(id)sender;
|
|
||||||
- (IBAction)markToggle:(id)sender;
|
|
||||||
- (IBAction)openSelected:(id)sender;
|
|
||||||
- (IBAction)refresh:(id)sender;
|
|
||||||
- (IBAction)removeDeadTracks:(id)sender;
|
- (IBAction)removeDeadTracks:(id)sender;
|
||||||
- (IBAction)removeMarked:(id)sender;
|
|
||||||
- (IBAction)removeSelected:(id)sender;
|
|
||||||
- (IBAction)renameSelected:(id)sender;
|
|
||||||
- (IBAction)revealSelected:(id)sender;
|
|
||||||
- (IBAction)startDuplicateScan:(id)sender;
|
|
||||||
- (IBAction)toggleDelta:(id)sender;
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -20,130 +20,17 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
{
|
{
|
||||||
[super awakeFromNib];
|
[super awakeFromNib];
|
||||||
[[self window] setTitle:@"dupeGuru Music Edition"];
|
[[self window] setTitle:@"dupeGuru Music Edition"];
|
||||||
_displayDelta = NO;
|
NSMutableIndexSet *deltaColumns = [NSMutableIndexSet indexSetWithIndexesInRange:NSMakeRange(2,7)];
|
||||||
_powerMode = NO;
|
[deltaColumns removeIndex:6];
|
||||||
_deltaColumns = [[NSMutableIndexSet indexSetWithIndexesInRange:NSMakeRange(2,7)] retain];
|
[outline setDeltaColumns:deltaColumns];
|
||||||
[_deltaColumns removeIndex:6];
|
|
||||||
[deltaSwitch setSelectedSegment:0];
|
|
||||||
[pmSwitch setSelectedSegment:0];
|
|
||||||
[py setDisplayDeltaValues:b2n(_displayDelta)];
|
|
||||||
[matches setTarget:self];
|
|
||||||
[matches setDoubleAction:@selector(openSelected:)];
|
|
||||||
[self refreshStats];
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resultsMarkingChanged:) name:ResultsMarkingChangedNotification object:nil];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Actions */
|
/* Actions */
|
||||||
- (IBAction)clearIgnoreList:(id)sender
|
|
||||||
{
|
|
||||||
NSInteger i = n2i([py getIgnoreListCount]);
|
|
||||||
if (!i)
|
|
||||||
return;
|
|
||||||
if ([Dialogs askYesNo:[NSString stringWithFormat:@"Do you really want to remove all %d items from the ignore list?",i]] == NSAlertSecondButtonReturn) // NO
|
|
||||||
return;
|
|
||||||
[py clearIgnoreList];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)filter:(id)sender
|
|
||||||
{
|
|
||||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
|
||||||
[py setEscapeFilterRegexp:b2n(!n2b([ud objectForKey:@"useRegexpFilter"]))];
|
|
||||||
[py applyFilter:[filterField stringValue]];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)ignoreSelected:(id)sender
|
|
||||||
{
|
|
||||||
NSArray *nodeList = [self getSelected:YES];
|
|
||||||
if (![nodeList count])
|
|
||||||
return;
|
|
||||||
if ([Dialogs askYesNo:[NSString stringWithFormat:@"All selected %d matches are going to be ignored in all subsequent scans. Continue?",[nodeList count]]] == NSAlertSecondButtonReturn) // NO
|
|
||||||
return;
|
|
||||||
[self performPySelection:[self getSelectedPaths:YES]];
|
|
||||||
[py addSelectedToIgnoreList];
|
|
||||||
[py removeSelected];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)markAll:(id)sender
|
|
||||||
{
|
|
||||||
[py markAll];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)markInvert:(id)sender
|
|
||||||
{
|
|
||||||
[py markInvert];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)markNone:(id)sender
|
|
||||||
{
|
|
||||||
[py markNone];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)markSelected:(id)sender
|
|
||||||
{
|
|
||||||
[self performPySelection:[self getSelectedPaths:YES]];
|
|
||||||
[py toggleSelectedMark];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)markToggle:(id)sender
|
|
||||||
{
|
|
||||||
OVNode *node = [matches itemAtRow:[matches clickedRow]];
|
|
||||||
[self performPySelection:[NSArray arrayWithObject:p2a([node indexPath])]];
|
|
||||||
[py toggleSelectedMark];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)openSelected:(id)sender
|
|
||||||
{
|
|
||||||
[self performPySelection:[self getSelectedPaths:NO]];
|
|
||||||
[py openSelected];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)refresh:(id)sender
|
|
||||||
{
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)removeDeadTracks:(id)sender
|
- (IBAction)removeDeadTracks:(id)sender
|
||||||
{
|
{
|
||||||
[(PyDupeGuru *)py scanDeadTracks];
|
[(PyDupeGuru *)py scanDeadTracks];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)removeMarked:(id)sender
|
|
||||||
{
|
|
||||||
int mark_count = [[py getMarkCount] intValue];
|
|
||||||
if (!mark_count)
|
|
||||||
return;
|
|
||||||
if ([Dialogs askYesNo:[NSString stringWithFormat:@"You are about to remove %d files from results. Continue?",mark_count]] == NSAlertSecondButtonReturn) // NO
|
|
||||||
return;
|
|
||||||
[py removeMarked];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)removeSelected:(id)sender
|
|
||||||
{
|
|
||||||
NSArray *nodeList = [self getSelected:YES];
|
|
||||||
if (![nodeList count])
|
|
||||||
return;
|
|
||||||
if ([Dialogs askYesNo:[NSString stringWithFormat:@"You are about to remove %d files from results. Continue?",[nodeList count]]] == NSAlertSecondButtonReturn) // NO
|
|
||||||
return;
|
|
||||||
[self performPySelection:[self getSelectedPaths:YES]];
|
|
||||||
[py removeSelected];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)renameSelected:(id)sender
|
|
||||||
{
|
|
||||||
NSInteger col = [matches columnWithIdentifier:@"0"];
|
|
||||||
NSInteger row = [matches selectedRow];
|
|
||||||
[matches editColumn:col row:row withEvent:[NSApp currentEvent] select:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)resetColumnsToDefault:(id)sender
|
- (IBAction)resetColumnsToDefault:(id)sender
|
||||||
{
|
{
|
||||||
NSMutableArray *columnsOrder = [NSMutableArray array];
|
NSMutableArray *columnsOrder = [NSMutableArray array];
|
||||||
@@ -161,12 +48,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[self restoreColumnsPosition:columnsOrder widths:columnsWidth];
|
[self restoreColumnsPosition:columnsOrder widths:columnsWidth];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)revealSelected:(id)sender
|
|
||||||
{
|
|
||||||
[self performPySelection:[self getSelectedPaths:NO]];
|
|
||||||
[py revealSelected];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)startDuplicateScan:(id)sender
|
- (IBAction)startDuplicateScan:(id)sender
|
||||||
{
|
{
|
||||||
if ([matches numberOfRows] > 0)
|
if ([matches numberOfRows] > 0)
|
||||||
@@ -188,8 +69,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[_py setMixFileKind:[ud objectForKey:@"mixFileKind"]];
|
[_py setMixFileKind:[ud objectForKey:@"mixFileKind"]];
|
||||||
[_py setMatchSimilarWords:[ud objectForKey:@"matchSimilarWords"]];
|
[_py setMatchSimilarWords:[ud objectForKey:@"matchSimilarWords"]];
|
||||||
NSInteger r = n2i([py doScan]);
|
NSInteger r = n2i([py doScan]);
|
||||||
[matches reloadData];
|
|
||||||
[self refreshStats];
|
|
||||||
if (r == 1)
|
if (r == 1)
|
||||||
[Dialogs showMessage:@"You cannot make a duplicate scan with only reference directories."];
|
[Dialogs showMessage:@"You cannot make a duplicate scan with only reference directories."];
|
||||||
if (r == 3)
|
if (r == 3)
|
||||||
@@ -199,15 +78,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)toggleDelta:(id)sender
|
|
||||||
{
|
|
||||||
if ([deltaSwitch selectedSegment] == 1)
|
|
||||||
[deltaSwitch setSelectedSegment:0];
|
|
||||||
else
|
|
||||||
[deltaSwitch setSelectedSegment:1];
|
|
||||||
[self changeDelta:sender];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Public */
|
/* Public */
|
||||||
- (void)initResultColumns
|
- (void)initResultColumns
|
||||||
{
|
{
|
||||||
@@ -240,31 +110,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[_resultColumns addObject:[self getColumnForIdentifier:18 title:@"Dupe Count" width:80 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:18 title:@"Dupe Count" width:80 refCol:refCol]];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delegate */
|
|
||||||
- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
|
|
||||||
{
|
|
||||||
OVNode *node = item;
|
|
||||||
if ([[tableColumn identifier] isEqual:@"mark"])
|
|
||||||
{
|
|
||||||
[cell setEnabled: [node isMarkable]];
|
|
||||||
}
|
|
||||||
if ([cell isKindOfClass:[NSTextFieldCell class]])
|
|
||||||
{
|
|
||||||
// Determine if the text color will be blue due to directory being reference.
|
|
||||||
NSTextFieldCell *textCell = cell;
|
|
||||||
if ([node isMarkable])
|
|
||||||
[textCell setTextColor:[NSColor blackColor]];
|
|
||||||
else
|
|
||||||
[textCell setTextColor:[NSColor blueColor]];
|
|
||||||
if ((_displayDelta) && (_powerMode || ([node level] > 1)))
|
|
||||||
{
|
|
||||||
int i = [[tableColumn identifier] intValue];
|
|
||||||
if ([_deltaColumns containsIndex:i])
|
|
||||||
[textCell setTextColor:[NSColor orangeColor]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Notifications */
|
/* Notifications */
|
||||||
- (void)jobCompleted:(NSNotification *)aNotification
|
- (void)jobCompleted:(NSNotification *)aNotification
|
||||||
{
|
{
|
||||||
@@ -285,17 +130,4 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)outlineViewSelectionDidChange:(NSNotification *)notification
|
|
||||||
{
|
|
||||||
[self performPySelection:[self getSelectedPaths:NO]];
|
|
||||||
[py refreshDetailsWithSelected];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:DuplicateSelectionChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)resultsMarkingChanged:(NSNotification *)aNotification
|
|
||||||
{
|
|
||||||
[matches invalidateMarkings];
|
|
||||||
[self refreshStats];
|
|
||||||
}
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -4,184 +4,43 @@
|
|||||||
# 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/hs_license
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
import objc
|
from hscommon.cocoa import signature
|
||||||
from Foundation import NSObject
|
|
||||||
|
|
||||||
from hsutil.cocoa import signature
|
|
||||||
|
|
||||||
|
from core.app_cocoa_inter import PyDupeGuruBase, PyDetailsPanel
|
||||||
from core_me.app_cocoa import DupeGuruME
|
from core_me.app_cocoa import DupeGuruME
|
||||||
from core.scanner import (SCAN_TYPE_FILENAME, SCAN_TYPE_FIELDS, SCAN_TYPE_FIELDS_NO_ORDER,
|
from core.scanner import (SCAN_TYPE_FILENAME, SCAN_TYPE_FIELDS, SCAN_TYPE_FIELDS_NO_ORDER,
|
||||||
SCAN_TYPE_TAG, SCAN_TYPE_CONTENT, SCAN_TYPE_CONTENT_AUDIO)
|
SCAN_TYPE_TAG, SCAN_TYPE_CONTENT, SCAN_TYPE_CONTENT_AUDIO)
|
||||||
|
|
||||||
# Fix py2app imports which chokes on relative imports
|
# Fix py2app imports which chokes on relative imports and other stuff
|
||||||
from core_me import app_cocoa, data, fs, scanner
|
from core_me import app_cocoa, data, fs, scanner
|
||||||
from core import app, app_cocoa, data, directories, engine, export, ignore, results, scanner, fs
|
from hsaudiotag import aiff, flac, genres, id3v1, id3v2, mp4, mpeg, ogg, wma
|
||||||
from hsmedia import aiff, flac, genres, id3v1, id3v2, mp4, mpeg, ogg, wma
|
from lxml import etree, _elementpath
|
||||||
from hsutil import conflict
|
import gzip
|
||||||
|
|
||||||
class PyApp(NSObject):
|
class PyDupeGuru(PyDupeGuruBase):
|
||||||
pass #fake class
|
|
||||||
|
|
||||||
class PyDupeGuru(PyApp):
|
|
||||||
def init(self):
|
def init(self):
|
||||||
self = super(PyDupeGuru,self).init()
|
self = super(PyDupeGuru,self).init()
|
||||||
self.app = DupeGuruME()
|
self.py = DupeGuruME()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
#---Directories
|
|
||||||
def addDirectory_(self,directory):
|
|
||||||
return self.app.add_directory(directory)
|
|
||||||
|
|
||||||
def removeDirectory_(self,index):
|
|
||||||
self.app.RemoveDirectory(index)
|
|
||||||
|
|
||||||
def setDirectory_state_(self,node_path,state):
|
|
||||||
self.app.SetDirectoryState(node_path,state)
|
|
||||||
|
|
||||||
#---Results
|
|
||||||
def clearIgnoreList(self):
|
|
||||||
self.app.scanner.ignore_list.Clear()
|
|
||||||
|
|
||||||
def doScan(self):
|
|
||||||
return self.app.start_scanning()
|
|
||||||
|
|
||||||
def exportToXHTMLwithColumns_(self, column_ids):
|
|
||||||
return self.app.export_to_xhtml(column_ids)
|
|
||||||
|
|
||||||
def loadIgnoreList(self):
|
|
||||||
self.app.load_ignore_list()
|
|
||||||
|
|
||||||
def loadResults(self):
|
|
||||||
self.app.load()
|
|
||||||
|
|
||||||
def markAll(self):
|
|
||||||
self.app.results.mark_all()
|
|
||||||
|
|
||||||
def markNone(self):
|
|
||||||
self.app.results.mark_none()
|
|
||||||
|
|
||||||
def markInvert(self):
|
|
||||||
self.app.results.mark_invert()
|
|
||||||
|
|
||||||
def purgeIgnoreList(self):
|
|
||||||
self.app.PurgeIgnoreList()
|
|
||||||
|
|
||||||
def toggleSelectedMark(self):
|
|
||||||
self.app.ToggleSelectedMarkState()
|
|
||||||
|
|
||||||
def saveIgnoreList(self):
|
|
||||||
self.app.save_ignore_list()
|
|
||||||
|
|
||||||
def saveResults(self):
|
|
||||||
self.app.save()
|
|
||||||
|
|
||||||
def refreshDetailsWithSelected(self):
|
|
||||||
self.app.RefreshDetailsWithSelected()
|
|
||||||
|
|
||||||
def selectedResultNodePaths(self):
|
|
||||||
return self.app.selected_result_node_paths()
|
|
||||||
|
|
||||||
def selectResultNodePaths_(self,node_paths):
|
|
||||||
self.app.SelectResultNodePaths(node_paths)
|
|
||||||
|
|
||||||
def selectedPowerMarkerNodePaths(self):
|
|
||||||
return self.app.selected_powermarker_node_paths()
|
|
||||||
|
|
||||||
def selectPowerMarkerNodePaths_(self,node_paths):
|
|
||||||
self.app.SelectPowerMarkerNodePaths(node_paths)
|
|
||||||
|
|
||||||
#---Actions
|
|
||||||
def addSelectedToIgnoreList(self):
|
|
||||||
self.app.AddSelectedToIgnoreList()
|
|
||||||
|
|
||||||
def applyFilter_(self, filter):
|
|
||||||
self.app.apply_filter(filter)
|
|
||||||
|
|
||||||
def deleteMarked(self):
|
|
||||||
self.app.delete_marked()
|
|
||||||
|
|
||||||
def makeSelectedReference(self):
|
|
||||||
self.app.MakeSelectedReference()
|
|
||||||
|
|
||||||
def copyOrMove_markedTo_recreatePath_(self,copy,destination,recreate_path):
|
|
||||||
self.app.copy_or_move_marked(copy, destination, recreate_path)
|
|
||||||
|
|
||||||
def openSelected(self):
|
|
||||||
self.app.OpenSelected()
|
|
||||||
|
|
||||||
def removeDeadTracks(self):
|
def removeDeadTracks(self):
|
||||||
self.app.remove_dead_tracks()
|
self.py.remove_dead_tracks()
|
||||||
|
|
||||||
def removeMarked(self):
|
|
||||||
self.app.results.perform_on_marked(lambda x:True, True)
|
|
||||||
|
|
||||||
def removeSelected(self):
|
|
||||||
self.app.RemoveSelected()
|
|
||||||
|
|
||||||
def renameSelected_(self,newname):
|
|
||||||
return self.app.RenameSelected(newname)
|
|
||||||
|
|
||||||
def revealSelected(self):
|
|
||||||
self.app.RevealSelected()
|
|
||||||
|
|
||||||
def scanDeadTracks(self):
|
def scanDeadTracks(self):
|
||||||
self.app.scan_dead_tracks()
|
self.py.scan_dead_tracks()
|
||||||
|
|
||||||
#---Misc
|
|
||||||
def sortDupesBy_ascending_(self,key,asc):
|
|
||||||
self.app.sort_dupes(key,asc)
|
|
||||||
|
|
||||||
def sortGroupsBy_ascending_(self,key,asc):
|
|
||||||
self.app.sort_groups(key,asc)
|
|
||||||
|
|
||||||
#---Information
|
#---Information
|
||||||
@signature('i@:')
|
@signature('i@:')
|
||||||
def deadTrackCount(self):
|
def deadTrackCount(self):
|
||||||
return len(self.app.dead_tracks)
|
return len(self.py.dead_tracks)
|
||||||
|
|
||||||
def getIgnoreListCount(self):
|
|
||||||
return len(self.app.scanner.ignore_list)
|
|
||||||
|
|
||||||
def getMarkCount(self):
|
|
||||||
return self.app.results.mark_count
|
|
||||||
|
|
||||||
def getStatLine(self):
|
|
||||||
return self.app.stat_line
|
|
||||||
|
|
||||||
def getOperationalErrorCount(self):
|
|
||||||
return self.app.last_op_error_count
|
|
||||||
|
|
||||||
#---Data
|
|
||||||
@signature('i@:i')
|
|
||||||
def getOutlineViewMaxLevel_(self, tag):
|
|
||||||
return self.app.GetOutlineViewMaxLevel(tag)
|
|
||||||
|
|
||||||
@signature('@@:i@')
|
|
||||||
def getOutlineView_childCountsForPath_(self, tag, node_path):
|
|
||||||
return self.app.GetOutlineViewChildCounts(tag, node_path)
|
|
||||||
|
|
||||||
def getOutlineView_valuesForIndexes_(self,tag,node_path):
|
|
||||||
return self.app.GetOutlineViewValues(tag,node_path)
|
|
||||||
|
|
||||||
def getOutlineView_markedAtIndexes_(self,tag,node_path):
|
|
||||||
return self.app.GetOutlineViewMarked(tag,node_path)
|
|
||||||
|
|
||||||
def getTableViewCount_(self,tag):
|
|
||||||
return self.app.GetTableViewCount(tag)
|
|
||||||
|
|
||||||
def getTableViewMarkedIndexes_(self,tag):
|
|
||||||
return self.app.GetTableViewMarkedIndexes(tag)
|
|
||||||
|
|
||||||
def getTableView_valuesForRow_(self,tag,row):
|
|
||||||
return self.app.GetTableViewValues(tag,row)
|
|
||||||
|
|
||||||
#---Properties
|
#---Properties
|
||||||
def setMinMatchPercentage_(self, percentage):
|
def setMinMatchPercentage_(self, percentage):
|
||||||
self.app.scanner.min_match_percentage = int(percentage)
|
self.py.scanner.min_match_percentage = int(percentage)
|
||||||
|
|
||||||
def setScanType_(self, scan_type):
|
def setScanType_(self, scan_type):
|
||||||
try:
|
try:
|
||||||
self.app.scanner.scan_type = [
|
self.py.scanner.scan_type = [
|
||||||
SCAN_TYPE_FILENAME,
|
SCAN_TYPE_FILENAME,
|
||||||
SCAN_TYPE_FIELDS,
|
SCAN_TYPE_FIELDS,
|
||||||
SCAN_TYPE_FIELDS_NO_ORDER,
|
SCAN_TYPE_FIELDS_NO_ORDER,
|
||||||
@@ -193,54 +52,18 @@ class PyDupeGuru(PyApp):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def setWordWeighting_(self, words_are_weighted):
|
def setWordWeighting_(self, words_are_weighted):
|
||||||
self.app.scanner.word_weighting = words_are_weighted
|
self.py.scanner.word_weighting = words_are_weighted
|
||||||
|
|
||||||
def setMixFileKind_(self, mix_file_kind):
|
|
||||||
self.app.scanner.mix_file_kind = mix_file_kind
|
|
||||||
|
|
||||||
def setDisplayDeltaValues_(self, display_delta_values):
|
|
||||||
self.app.display_delta_values = display_delta_values
|
|
||||||
|
|
||||||
def setMatchSimilarWords_(self, match_similar_words):
|
def setMatchSimilarWords_(self, match_similar_words):
|
||||||
self.app.scanner.match_similar_words = match_similar_words
|
self.py.scanner.match_similar_words = match_similar_words
|
||||||
|
|
||||||
def setEscapeFilterRegexp_(self, escape_filter_regexp):
|
|
||||||
self.app.options['escape_filter_regexp'] = escape_filter_regexp
|
|
||||||
|
|
||||||
def setRemoveEmptyFolders_(self, remove_empty_folders):
|
|
||||||
self.app.options['clean_empty_dirs'] = remove_empty_folders
|
|
||||||
|
|
||||||
def enable_scanForTag_(self, enable, scan_tag):
|
def enable_scanForTag_(self, enable, scan_tag):
|
||||||
if enable:
|
if enable:
|
||||||
self.app.scanner.scanned_tags.add(scan_tag)
|
self.py.scanner.scanned_tags.add(scan_tag)
|
||||||
else:
|
else:
|
||||||
self.app.scanner.scanned_tags.discard(scan_tag)
|
self.py.scanner.scanned_tags.discard(scan_tag)
|
||||||
|
|
||||||
#---Worker
|
|
||||||
def getJobProgress(self):
|
|
||||||
return self.app.progress.last_progress
|
|
||||||
|
|
||||||
def getJobDesc(self):
|
|
||||||
return self.app.progress.last_desc
|
|
||||||
|
|
||||||
def cancelJob(self):
|
|
||||||
self.app.progress.job_cancelled = True
|
|
||||||
|
|
||||||
#---Registration
|
#---Registration
|
||||||
def appName(self):
|
def appName(self):
|
||||||
return "dupeGuru Music Edition"
|
return "dupeGuru Music Edition"
|
||||||
|
|
||||||
def demoLimitDescription(self):
|
|
||||||
return self.app.DEMO_LIMIT_DESC
|
|
||||||
|
|
||||||
@signature('i@:')
|
|
||||||
def isRegistered(self):
|
|
||||||
return self.app.registered
|
|
||||||
|
|
||||||
@signature('i@:@@')
|
|
||||||
def isCodeValid_withEmail_(self, code, email):
|
|
||||||
return self.app.is_code_valid(code, email)
|
|
||||||
|
|
||||||
def setRegisteredCode_andEmail_(self, code, email):
|
|
||||||
self.app.set_registration(code, email)
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,19 @@
|
|||||||
/* 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 */; };
|
||||||
|
CE003CC611242D00004B0AA7 /* HSGUIController.m in Sources */ = {isa = PBXBuildFile; fileRef = CE003CB411242D00004B0AA7 /* HSGUIController.m */; };
|
||||||
|
CE003CC711242D00004B0AA7 /* HSOutline.m in Sources */ = {isa = PBXBuildFile; fileRef = CE003CB611242D00004B0AA7 /* HSOutline.m */; };
|
||||||
|
CE003CC811242D00004B0AA7 /* HSWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CE003CB811242D00004B0AA7 /* HSWindowController.m */; };
|
||||||
|
CE003CC911242D00004B0AA7 /* NSEventAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE003CBA11242D00004B0AA7 /* NSEventAdditions.m */; };
|
||||||
|
CE003CCA11242D00004B0AA7 /* HSOutlineView.m in Sources */ = {isa = PBXBuildFile; fileRef = CE003CC111242D00004B0AA7 /* HSOutlineView.m */; };
|
||||||
|
CE003CCB11242D00004B0AA7 /* NSIndexPathAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE003CC311242D00004B0AA7 /* NSIndexPathAdditions.m */; };
|
||||||
|
CE003CCC11242D00004B0AA7 /* NSTableViewAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE003CC511242D00004B0AA7 /* NSTableViewAdditions.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 */; };
|
CE073F6309CAE1A3005C1D2F /* dupeguru_me_help in Resources */ = {isa = PBXBuildFile; fileRef = CE073F5409CAE1A3005C1D2F /* dupeguru_me_help */; };
|
||||||
|
CE0A0C001175A1C000DCA3C6 /* HSTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0A0BFF1175A1C000DCA3C6 /* HSTable.m */; };
|
||||||
|
CE0A0C041175A1DE00DCA3C6 /* ProblemDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0A0C021175A1DE00DCA3C6 /* ProblemDialog.m */; };
|
||||||
|
CE0A0C061175A24800DCA3C6 /* ProblemDialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE0A0C051175A24800DCA3C6 /* ProblemDialog.xib */; };
|
||||||
|
CE0B3D6711243F83009A7A30 /* ResultOutline.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0B3D6611243F83009A7A30 /* ResultOutline.m */; };
|
||||||
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 */; };
|
||||||
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; };
|
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; };
|
||||||
@@ -30,18 +42,16 @@
|
|||||||
CE3FBDD31094637800B72D77 /* DetailsPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE3FBDD11094637800B72D77 /* DetailsPanel.xib */; };
|
CE3FBDD31094637800B72D77 /* DetailsPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE3FBDD11094637800B72D77 /* DetailsPanel.xib */; };
|
||||||
CE3FBDD41094637800B72D77 /* DirectoryPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE3FBDD21094637800B72D77 /* DirectoryPanel.xib */; };
|
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 */; };
|
||||||
|
CE4B59C91119919700C06C9E /* progress.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE4B59C61119919700C06C9E /* progress.xib */; };
|
||||||
|
CE4B59CA1119919700C06C9E /* registration.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE4B59C71119919700C06C9E /* registration.xib */; };
|
||||||
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 */; };
|
||||||
CE515DF50FC6C12E00EC695D /* Outline.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DE50FC6C12E00EC695D /* Outline.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 */; };
|
CE515DF70FC6C12E00EC695D /* RecentDirectories.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DEA0FC6C12E00EC695D /* RecentDirectories.m */; };
|
||||||
CE515DF80FC6C12E00EC695D /* RegistrationInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DEC0FC6C12E00EC695D /* RegistrationInterface.m */; };
|
CE515DF80FC6C12E00EC695D /* RegistrationInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DEC0FC6C12E00EC695D /* RegistrationInterface.m */; };
|
||||||
CE515DF90FC6C12E00EC695D /* Table.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DEE0FC6C12E00EC695D /* Table.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 */; };
|
||||||
CE515E020FC6C13E00EC695D /* ErrorReportWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE515DFC0FC6C13E00EC695D /* ErrorReportWindow.xib */; };
|
|
||||||
CE515E030FC6C13E00EC695D /* progress.nib in Resources */ = {isa = PBXBuildFile; fileRef = CE515DFE0FC6C13E00EC695D /* progress.nib */; };
|
|
||||||
CE515E040FC6C13E00EC695D /* registration.nib in Resources */ = {isa = PBXBuildFile; fileRef = CE515E000FC6C13E00EC695D /* registration.nib */; };
|
|
||||||
CE515E1D0FC6C19300EC695D /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515E160FC6C19300EC695D /* AppDelegate.m */; };
|
CE515E1D0FC6C19300EC695D /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515E160FC6C19300EC695D /* AppDelegate.m */; };
|
||||||
CE515E1E0FC6C19300EC695D /* DirectoryPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515E190FC6C19300EC695D /* DirectoryPanel.m */; };
|
CE515E1E0FC6C19300EC695D /* DirectoryPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515E190FC6C19300EC695D /* DirectoryPanel.m */; };
|
||||||
CE515E1F0FC6C19300EC695D /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515E1C0FC6C19300EC695D /* ResultWindow.m */; };
|
CE515E1F0FC6C19300EC695D /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515E1C0FC6C19300EC695D /* ResultWindow.m */; };
|
||||||
@@ -51,8 +61,7 @@
|
|||||||
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 */; };
|
CE900AD2109B238600754048 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE900AD1109B238600754048 /* Preferences.xib */; };
|
||||||
CE900AD7109B2A9B00754048 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE900AD6109B2A9B00754048 /* MainMenu.xib */; };
|
CE900AD7109B2A9B00754048 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE900AD6109B2A9B00754048 /* MainMenu.xib */; };
|
||||||
CECA899C09DB132E00A3D774 /* DetailsPanel.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CECA899A09DB132E00A3D774 /* DetailsPanel.h */; };
|
CEDF07A3112493B200EE5BC0 /* StatsLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = CEDF07A2112493B200EE5BC0 /* StatsLabel.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 */; };
|
||||||
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 */; };
|
CEFC295509C89FF200D9F998 /* details32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC295309C89FF200D9F998 /* details32.png */; };
|
||||||
@@ -67,7 +76,6 @@
|
|||||||
dstSubfolderSpec = 10;
|
dstSubfolderSpec = 10;
|
||||||
files = (
|
files = (
|
||||||
CE14259F0AFB719300BD5167 /* Sparkle.framework in CopyFiles */,
|
CE14259F0AFB719300BD5167 /* Sparkle.framework in CopyFiles */,
|
||||||
CECA899C09DB132E00A3D774 /* DetailsPanel.h in CopyFiles */,
|
|
||||||
CE848A1909DD85810004CB44 /* Consts.h in CopyFiles */,
|
CE848A1909DD85810004CB44 /* Consts.h in CopyFiles */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
@@ -82,7 +90,37 @@
|
|||||||
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 ME.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "dupeGuru ME.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
8D1107320486CEB800E47090 /* dupeGuru ME.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "dupeGuru ME.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
CE003CB311242D00004B0AA7 /* HSGUIController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HSGUIController.h; sourceTree = "<group>"; };
|
||||||
|
CE003CB411242D00004B0AA7 /* HSGUIController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSGUIController.m; sourceTree = "<group>"; };
|
||||||
|
CE003CB511242D00004B0AA7 /* HSOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HSOutline.h; sourceTree = "<group>"; };
|
||||||
|
CE003CB611242D00004B0AA7 /* HSOutline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSOutline.m; sourceTree = "<group>"; };
|
||||||
|
CE003CB711242D00004B0AA7 /* HSWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HSWindowController.h; sourceTree = "<group>"; };
|
||||||
|
CE003CB811242D00004B0AA7 /* HSWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSWindowController.m; sourceTree = "<group>"; };
|
||||||
|
CE003CB911242D00004B0AA7 /* NSEventAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NSEventAdditions.h; path = ../../cocoalib/NSEventAdditions.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE003CBA11242D00004B0AA7 /* NSEventAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NSEventAdditions.m; path = ../../cocoalib/NSEventAdditions.m; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE003CBC11242D00004B0AA7 /* PyGUI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PyGUI.h; sourceTree = "<group>"; };
|
||||||
|
CE003CBD11242D00004B0AA7 /* PyOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PyOutline.h; sourceTree = "<group>"; };
|
||||||
|
CE003CBE11242D00004B0AA7 /* PyRegistrable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyRegistrable.h; path = ../../cocoalib/PyRegistrable.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE003CC011242D00004B0AA7 /* HSOutlineView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HSOutlineView.h; sourceTree = "<group>"; };
|
||||||
|
CE003CC111242D00004B0AA7 /* HSOutlineView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSOutlineView.m; sourceTree = "<group>"; };
|
||||||
|
CE003CC211242D00004B0AA7 /* NSIndexPathAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSIndexPathAdditions.h; sourceTree = "<group>"; };
|
||||||
|
CE003CC311242D00004B0AA7 /* NSIndexPathAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSIndexPathAdditions.m; sourceTree = "<group>"; };
|
||||||
|
CE003CC411242D00004B0AA7 /* NSTableViewAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSTableViewAdditions.h; sourceTree = "<group>"; };
|
||||||
|
CE003CC511242D00004B0AA7 /* NSTableViewAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSTableViewAdditions.m; sourceTree = "<group>"; };
|
||||||
|
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; };
|
||||||
|
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>"; };
|
CE073F5409CAE1A3005C1D2F /* dupeguru_me_help */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dupeguru_me_help; path = ../../help_me/dupeguru_me_help; 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>"; };
|
||||||
|
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; };
|
||||||
|
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>"; };
|
||||||
|
CE0B3D6411243F83009A7A30 /* PyResultTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyResultTree.h; path = ../base/PyResultTree.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE0B3D6511243F83009A7A30 /* ResultOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ResultOutline.h; path = ../base/ResultOutline.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE0B3D6611243F83009A7A30 /* ResultOutline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ResultOutline.m; path = ../base/ResultOutline.m; sourceTree = SOURCE_ROOT; };
|
||||||
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>"; };
|
||||||
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; };
|
||||||
@@ -93,12 +131,13 @@
|
|||||||
CE3FBDD21094637800B72D77 /* DirectoryPanel.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = DirectoryPanel.xib; path = ../../base/xib/DirectoryPanel.xib; sourceTree = "<group>"; };
|
CE3FBDD21094637800B72D77 /* DirectoryPanel.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = DirectoryPanel.xib; path = ../../base/xib/DirectoryPanel.xib; sourceTree = "<group>"; };
|
||||||
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>"; };
|
||||||
|
CE4B59C61119919700C06C9E /* progress.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = progress.xib; sourceTree = "<group>"; };
|
||||||
|
CE4B59C71119919700C06C9E /* registration.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = registration.xib; sourceTree = "<group>"; };
|
||||||
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; };
|
||||||
CE515DE30FC6C12E00EC695D /* HSErrorReportWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSErrorReportWindow.m; path = ../../cocoalib/HSErrorReportWindow.m; sourceTree = SOURCE_ROOT; };
|
CE515DE30FC6C12E00EC695D /* HSErrorReportWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSErrorReportWindow.m; path = ../../cocoalib/HSErrorReportWindow.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE515DE40FC6C12E00EC695D /* Outline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Outline.h; path = ../../cocoalib/Outline.h; sourceTree = SOURCE_ROOT; };
|
|
||||||
CE515DE50FC6C12E00EC695D /* Outline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Outline.m; path = ../../cocoalib/Outline.m; sourceTree = SOURCE_ROOT; };
|
|
||||||
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; };
|
||||||
@@ -106,15 +145,10 @@
|
|||||||
CE515DEA0FC6C12E00EC695D /* RecentDirectories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RecentDirectories.m; path = ../../cocoalib/RecentDirectories.m; sourceTree = SOURCE_ROOT; };
|
CE515DEA0FC6C12E00EC695D /* RecentDirectories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RecentDirectories.m; path = ../../cocoalib/RecentDirectories.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE515DEB0FC6C12E00EC695D /* RegistrationInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegistrationInterface.h; path = ../../cocoalib/RegistrationInterface.h; sourceTree = SOURCE_ROOT; };
|
CE515DEB0FC6C12E00EC695D /* RegistrationInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegistrationInterface.h; path = ../../cocoalib/RegistrationInterface.h; sourceTree = SOURCE_ROOT; };
|
||||||
CE515DEC0FC6C12E00EC695D /* RegistrationInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RegistrationInterface.m; path = ../../cocoalib/RegistrationInterface.m; sourceTree = SOURCE_ROOT; };
|
CE515DEC0FC6C12E00EC695D /* RegistrationInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RegistrationInterface.m; path = ../../cocoalib/RegistrationInterface.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE515DED0FC6C12E00EC695D /* Table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Table.h; path = ../../cocoalib/Table.h; sourceTree = SOURCE_ROOT; };
|
|
||||||
CE515DEE0FC6C12E00EC695D /* Table.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Table.m; path = ../../cocoalib/Table.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; };
|
||||||
CE515DF20FC6C12E00EC695D /* ValueTransformers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ValueTransformers.m; path = ../../cocoalib/ValueTransformers.m; sourceTree = SOURCE_ROOT; };
|
CE515DF20FC6C12E00EC695D /* ValueTransformers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ValueTransformers.m; path = ../../cocoalib/ValueTransformers.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE515DFD0FC6C13E00EC695D /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = ../../cocoalib/English.lproj/ErrorReportWindow.xib; sourceTree = "<group>"; };
|
|
||||||
CE515DFF0FC6C13E00EC695D /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = ../../cocoalib/English.lproj/progress.nib; sourceTree = "<group>"; };
|
|
||||||
CE515E010FC6C13E00EC695D /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = ../../cocoalib/English.lproj/registration.nib; sourceTree = "<group>"; };
|
|
||||||
CE515E150FC6C19300EC695D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = ../base/AppDelegate.h; sourceTree = SOURCE_ROOT; };
|
CE515E150FC6C19300EC695D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = ../base/AppDelegate.h; sourceTree = SOURCE_ROOT; };
|
||||||
CE515E160FC6C19300EC695D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = ../base/AppDelegate.m; sourceTree = SOURCE_ROOT; };
|
CE515E160FC6C19300EC695D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = ../base/AppDelegate.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE515E170FC6C19300EC695D /* Consts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Consts.h; path = ../base/Consts.h; sourceTree = SOURCE_ROOT; };
|
CE515E170FC6C19300EC695D /* Consts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Consts.h; path = ../base/Consts.h; sourceTree = SOURCE_ROOT; };
|
||||||
@@ -131,8 +165,10 @@
|
|||||||
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>"; };
|
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>"; };
|
CE900AD6109B2A9B00754048 /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MainMenu.xib; path = ../../base/xib/MainMenu.xib; sourceTree = "<group>"; };
|
||||||
CECA899A09DB132E00A3D774 /* DetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = DetailsPanel.h; sourceTree = "<group>"; };
|
CED0A591111C9FD10020AD7D /* PyDetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyDetailsPanel.h; path = ../base/PyDetailsPanel.h; sourceTree = SOURCE_ROOT; };
|
||||||
CECA899B09DB132E00A3D774 /* DetailsPanel.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = DetailsPanel.m; sourceTree = "<group>"; };
|
CEDF07A0112493B200EE5BC0 /* PyStatsLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyStatsLabel.h; path = ../base/PyStatsLabel.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CEDF07A1112493B200EE5BC0 /* StatsLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StatsLabel.h; path = ../base/StatsLabel.h; 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; };
|
CEFC295309C89FF200D9F998 /* details32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = details32.png; path = ../../images/details32.png; sourceTree = SOURCE_ROOT; };
|
||||||
@@ -153,21 +189,19 @@
|
|||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
080E96DDFE201D6D7F000001 /* Classes */ = {
|
080E96DDFE201D6D7F000001 /* DGME */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
CE381C9509914ACE003581CE /* AppDelegate.h */,
|
CE381C9509914ACE003581CE /* AppDelegate.h */,
|
||||||
CE381C9409914ACE003581CE /* AppDelegate.m */,
|
CE381C9409914ACE003581CE /* AppDelegate.m */,
|
||||||
CE848A1809DD85810004CB44 /* Consts.h */,
|
CE848A1809DD85810004CB44 /* Consts.h */,
|
||||||
CECA899A09DB132E00A3D774 /* DetailsPanel.h */,
|
|
||||||
CECA899B09DB132E00A3D774 /* DetailsPanel.m */,
|
|
||||||
CE68EE6509ABC48000971085 /* DirectoryPanel.h */,
|
CE68EE6509ABC48000971085 /* DirectoryPanel.h */,
|
||||||
CE68EE6609ABC48000971085 /* DirectoryPanel.m */,
|
CE68EE6609ABC48000971085 /* DirectoryPanel.m */,
|
||||||
CEFF18A009A4D387005E6321 /* PyDupeGuru.h */,
|
CEFF18A009A4D387005E6321 /* PyDupeGuru.h */,
|
||||||
CE381C9B09914ADF003581CE /* ResultWindow.h */,
|
CE381C9B09914ADF003581CE /* ResultWindow.h */,
|
||||||
CE381C9A09914ADF003581CE /* ResultWindow.m */,
|
CE381C9A09914ADF003581CE /* ResultWindow.m */,
|
||||||
);
|
);
|
||||||
name = Classes;
|
name = DGME;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
|
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
|
||||||
@@ -200,7 +234,7 @@
|
|||||||
29B97314FDCFA39411CA2CEA /* dupeguru */ = {
|
29B97314FDCFA39411CA2CEA /* dupeguru */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
080E96DDFE201D6D7F000001 /* Classes */,
|
080E96DDFE201D6D7F000001 /* DGME */,
|
||||||
CE515E140FC6C17900EC695D /* dgbase */,
|
CE515E140FC6C17900EC695D /* dgbase */,
|
||||||
CE515DDD0FC6C09400EC695D /* cocoalib */,
|
CE515DDD0FC6C09400EC695D /* cocoalib */,
|
||||||
29B97315FDCFA39411CA2CEA /* Other Sources */,
|
29B97315FDCFA39411CA2CEA /* Other Sources */,
|
||||||
@@ -242,6 +276,47 @@
|
|||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
CE003CB211242D00004B0AA7 /* controllers */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CE003CB311242D00004B0AA7 /* HSGUIController.h */,
|
||||||
|
CE003CB411242D00004B0AA7 /* HSGUIController.m */,
|
||||||
|
CE003CB511242D00004B0AA7 /* HSOutline.h */,
|
||||||
|
CE003CB611242D00004B0AA7 /* HSOutline.m */,
|
||||||
|
CE0A0BFE1175A1C000DCA3C6 /* HSTable.h */,
|
||||||
|
CE0A0BFF1175A1C000DCA3C6 /* HSTable.m */,
|
||||||
|
CE003CB711242D00004B0AA7 /* HSWindowController.h */,
|
||||||
|
CE003CB811242D00004B0AA7 /* HSWindowController.m */,
|
||||||
|
);
|
||||||
|
name = controllers;
|
||||||
|
path = ../../cocoalib/controllers;
|
||||||
|
sourceTree = SOURCE_ROOT;
|
||||||
|
};
|
||||||
|
CE003CBB11242D00004B0AA7 /* proxies */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CE003CBC11242D00004B0AA7 /* PyGUI.h */,
|
||||||
|
CE003CBD11242D00004B0AA7 /* PyOutline.h */,
|
||||||
|
CE0A0C131175A28100DCA3C6 /* PyTable.h */,
|
||||||
|
);
|
||||||
|
name = proxies;
|
||||||
|
path = ../../cocoalib/proxies;
|
||||||
|
sourceTree = SOURCE_ROOT;
|
||||||
|
};
|
||||||
|
CE003CBF11242D00004B0AA7 /* views */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CE003CC011242D00004B0AA7 /* HSOutlineView.h */,
|
||||||
|
CE003CC111242D00004B0AA7 /* HSOutlineView.m */,
|
||||||
|
CE003CC211242D00004B0AA7 /* NSIndexPathAdditions.h */,
|
||||||
|
CE003CC311242D00004B0AA7 /* NSIndexPathAdditions.m */,
|
||||||
|
CE003CC411242D00004B0AA7 /* NSTableViewAdditions.h */,
|
||||||
|
CE003CC511242D00004B0AA7 /* NSTableViewAdditions.m */,
|
||||||
|
);
|
||||||
|
name = views;
|
||||||
|
path = ../../cocoalib/views;
|
||||||
|
sourceTree = SOURCE_ROOT;
|
||||||
|
};
|
||||||
CE3FBDD01094637800B72D77 /* xib */ = {
|
CE3FBDD01094637800B72D77 /* xib */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -249,6 +324,7 @@
|
|||||||
CE3FBDD11094637800B72D77 /* DetailsPanel.xib */,
|
CE3FBDD11094637800B72D77 /* DetailsPanel.xib */,
|
||||||
CE3FBDD21094637800B72D77 /* DirectoryPanel.xib */,
|
CE3FBDD21094637800B72D77 /* DirectoryPanel.xib */,
|
||||||
CE900AD1109B238600754048 /* Preferences.xib */,
|
CE900AD1109B238600754048 /* Preferences.xib */,
|
||||||
|
CE0A0C051175A24800DCA3C6 /* ProblemDialog.xib */,
|
||||||
);
|
);
|
||||||
path = xib;
|
path = xib;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -263,28 +339,39 @@
|
|||||||
path = ../../cocoalib/brsinglelineformatter;
|
path = ../../cocoalib/brsinglelineformatter;
|
||||||
sourceTree = SOURCE_ROOT;
|
sourceTree = SOURCE_ROOT;
|
||||||
};
|
};
|
||||||
|
CE4B59C41119919700C06C9E /* xib */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CE4B59C51119919700C06C9E /* ErrorReportWindow.xib */,
|
||||||
|
CE4B59C61119919700C06C9E /* progress.xib */,
|
||||||
|
CE4B59C71119919700C06C9E /* registration.xib */,
|
||||||
|
);
|
||||||
|
name = xib;
|
||||||
|
path = ../../cocoalib/xib;
|
||||||
|
sourceTree = SOURCE_ROOT;
|
||||||
|
};
|
||||||
CE515DDD0FC6C09400EC695D /* cocoalib */ = {
|
CE515DDD0FC6C09400EC695D /* cocoalib */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
CE003CB211242D00004B0AA7 /* controllers */,
|
||||||
|
CE003CBB11242D00004B0AA7 /* proxies */,
|
||||||
|
CE003CBF11242D00004B0AA7 /* views */,
|
||||||
|
CE4B59C41119919700C06C9E /* xib */,
|
||||||
CE49DEF10FDFEB810098617B /* brsinglelineformatter */,
|
CE49DEF10FDFEB810098617B /* brsinglelineformatter */,
|
||||||
CE515DFC0FC6C13E00EC695D /* ErrorReportWindow.xib */,
|
|
||||||
CE515DFE0FC6C13E00EC695D /* progress.nib */,
|
|
||||||
CE515E000FC6C13E00EC695D /* registration.nib */,
|
|
||||||
CE515DE00FC6C12E00EC695D /* Dialogs.h */,
|
CE515DE00FC6C12E00EC695D /* Dialogs.h */,
|
||||||
CE515DE10FC6C12E00EC695D /* Dialogs.m */,
|
CE515DE10FC6C12E00EC695D /* Dialogs.m */,
|
||||||
CE515DE20FC6C12E00EC695D /* HSErrorReportWindow.h */,
|
CE515DE20FC6C12E00EC695D /* HSErrorReportWindow.h */,
|
||||||
CE515DE30FC6C12E00EC695D /* HSErrorReportWindow.m */,
|
CE515DE30FC6C12E00EC695D /* HSErrorReportWindow.m */,
|
||||||
CE515DE40FC6C12E00EC695D /* Outline.h */,
|
CE003CB911242D00004B0AA7 /* NSEventAdditions.h */,
|
||||||
CE515DE50FC6C12E00EC695D /* Outline.m */,
|
CE003CBA11242D00004B0AA7 /* NSEventAdditions.m */,
|
||||||
CE515DE60FC6C12E00EC695D /* ProgressController.h */,
|
CE515DE60FC6C12E00EC695D /* ProgressController.h */,
|
||||||
CE515DE70FC6C12E00EC695D /* ProgressController.m */,
|
CE515DE70FC6C12E00EC695D /* ProgressController.m */,
|
||||||
CE515DE80FC6C12E00EC695D /* PyApp.h */,
|
CE515DE80FC6C12E00EC695D /* PyApp.h */,
|
||||||
|
CE003CBE11242D00004B0AA7 /* PyRegistrable.h */,
|
||||||
CE515DE90FC6C12E00EC695D /* RecentDirectories.h */,
|
CE515DE90FC6C12E00EC695D /* RecentDirectories.h */,
|
||||||
CE515DEA0FC6C12E00EC695D /* RecentDirectories.m */,
|
CE515DEA0FC6C12E00EC695D /* RecentDirectories.m */,
|
||||||
CE515DEB0FC6C12E00EC695D /* RegistrationInterface.h */,
|
CE515DEB0FC6C12E00EC695D /* RegistrationInterface.h */,
|
||||||
CE515DEC0FC6C12E00EC695D /* RegistrationInterface.m */,
|
CE515DEC0FC6C12E00EC695D /* RegistrationInterface.m */,
|
||||||
CE515DED0FC6C12E00EC695D /* Table.h */,
|
|
||||||
CE515DEE0FC6C12E00EC695D /* Table.m */,
|
|
||||||
CE515DEF0FC6C12E00EC695D /* Utils.h */,
|
CE515DEF0FC6C12E00EC695D /* Utils.h */,
|
||||||
CE515DF00FC6C12E00EC695D /* Utils.m */,
|
CE515DF00FC6C12E00EC695D /* Utils.m */,
|
||||||
CE515DF10FC6C12E00EC695D /* ValueTransformers.h */,
|
CE515DF10FC6C12E00EC695D /* ValueTransformers.h */,
|
||||||
@@ -296,6 +383,9 @@
|
|||||||
CE515E140FC6C17900EC695D /* dgbase */ = {
|
CE515E140FC6C17900EC695D /* dgbase */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
CE003CCD11242D2C004B0AA7 /* DirectoryOutline.h */,
|
||||||
|
CE003CCE11242D2C004B0AA7 /* DirectoryOutline.m */,
|
||||||
|
CE003CCF11242D2C004B0AA7 /* PyDirectoryOutline.h */,
|
||||||
CE515E150FC6C19300EC695D /* AppDelegate.h */,
|
CE515E150FC6C19300EC695D /* AppDelegate.h */,
|
||||||
CE515E160FC6C19300EC695D /* AppDelegate.m */,
|
CE515E160FC6C19300EC695D /* AppDelegate.m */,
|
||||||
CE515E170FC6C19300EC695D /* Consts.h */,
|
CE515E170FC6C19300EC695D /* Consts.h */,
|
||||||
@@ -303,9 +393,19 @@
|
|||||||
CE6032BF0FE6784C007E33FF /* DetailsPanel.m */,
|
CE6032BF0FE6784C007E33FF /* DetailsPanel.m */,
|
||||||
CE515E180FC6C19300EC695D /* DirectoryPanel.h */,
|
CE515E180FC6C19300EC695D /* DirectoryPanel.h */,
|
||||||
CE515E190FC6C19300EC695D /* DirectoryPanel.m */,
|
CE515E190FC6C19300EC695D /* DirectoryPanel.m */,
|
||||||
CE515E1A0FC6C19300EC695D /* PyDupeGuru.h */,
|
CE0A0C011175A1DE00DCA3C6 /* ProblemDialog.h */,
|
||||||
|
CE0A0C021175A1DE00DCA3C6 /* ProblemDialog.m */,
|
||||||
CE515E1B0FC6C19300EC695D /* ResultWindow.h */,
|
CE515E1B0FC6C19300EC695D /* ResultWindow.h */,
|
||||||
CE515E1C0FC6C19300EC695D /* ResultWindow.m */,
|
CE515E1C0FC6C19300EC695D /* ResultWindow.m */,
|
||||||
|
CE0B3D6511243F83009A7A30 /* ResultOutline.h */,
|
||||||
|
CE0B3D6611243F83009A7A30 /* ResultOutline.m */,
|
||||||
|
CEDF07A1112493B200EE5BC0 /* StatsLabel.h */,
|
||||||
|
CEDF07A2112493B200EE5BC0 /* StatsLabel.m */,
|
||||||
|
CE515E1A0FC6C19300EC695D /* PyDupeGuru.h */,
|
||||||
|
CED0A591111C9FD10020AD7D /* PyDetailsPanel.h */,
|
||||||
|
CE0A0C031175A1DE00DCA3C6 /* PyProblemDialog.h */,
|
||||||
|
CE0B3D6411243F83009A7A30 /* PyResultTree.h */,
|
||||||
|
CEDF07A0112493B200EE5BC0 /* PyStatsLabel.h */,
|
||||||
);
|
);
|
||||||
name = dgbase;
|
name = dgbase;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -371,14 +471,15 @@
|
|||||||
CEFC294609C89E3D00D9F998 /* folder32.png in Resources */,
|
CEFC294609C89E3D00D9F998 /* folder32.png in Resources */,
|
||||||
CEFC295509C89FF200D9F998 /* details32.png in Resources */,
|
CEFC295509C89FF200D9F998 /* details32.png in Resources */,
|
||||||
CEFC295609C89FF200D9F998 /* preferences32.png in Resources */,
|
CEFC295609C89FF200D9F998 /* preferences32.png in Resources */,
|
||||||
CE515E020FC6C13E00EC695D /* ErrorReportWindow.xib in Resources */,
|
|
||||||
CE515E030FC6C13E00EC695D /* progress.nib in Resources */,
|
|
||||||
CE515E040FC6C13E00EC695D /* registration.nib in Resources */,
|
|
||||||
CE6E0E9F1054EB97008D9390 /* dsa_pub.pem in Resources */,
|
CE6E0E9F1054EB97008D9390 /* dsa_pub.pem in Resources */,
|
||||||
CE3FBDD31094637800B72D77 /* DetailsPanel.xib in Resources */,
|
CE3FBDD31094637800B72D77 /* DetailsPanel.xib in Resources */,
|
||||||
CE3FBDD41094637800B72D77 /* DirectoryPanel.xib in Resources */,
|
CE3FBDD41094637800B72D77 /* DirectoryPanel.xib in Resources */,
|
||||||
CE900AD2109B238600754048 /* Preferences.xib in Resources */,
|
CE900AD2109B238600754048 /* Preferences.xib in Resources */,
|
||||||
CE900AD7109B2A9B00754048 /* MainMenu.xib in Resources */,
|
CE900AD7109B2A9B00754048 /* MainMenu.xib in Resources */,
|
||||||
|
CE4B59C81119919700C06C9E /* ErrorReportWindow.xib in Resources */,
|
||||||
|
CE4B59C91119919700C06C9E /* progress.xib in Resources */,
|
||||||
|
CE4B59CA1119919700C06C9E /* registration.xib in Resources */,
|
||||||
|
CE0A0C061175A24800DCA3C6 /* ProblemDialog.xib in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -393,14 +494,11 @@
|
|||||||
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */,
|
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */,
|
||||||
CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */,
|
CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */,
|
||||||
CE68EE6809ABC48000971085 /* DirectoryPanel.m in Sources */,
|
CE68EE6809ABC48000971085 /* DirectoryPanel.m in Sources */,
|
||||||
CECA899D09DB132E00A3D774 /* DetailsPanel.m in Sources */,
|
|
||||||
CE515DF30FC6C12E00EC695D /* Dialogs.m in Sources */,
|
CE515DF30FC6C12E00EC695D /* Dialogs.m in Sources */,
|
||||||
CE515DF40FC6C12E00EC695D /* HSErrorReportWindow.m in Sources */,
|
CE515DF40FC6C12E00EC695D /* HSErrorReportWindow.m in Sources */,
|
||||||
CE515DF50FC6C12E00EC695D /* Outline.m in Sources */,
|
|
||||||
CE515DF60FC6C12E00EC695D /* ProgressController.m in Sources */,
|
CE515DF60FC6C12E00EC695D /* ProgressController.m in Sources */,
|
||||||
CE515DF70FC6C12E00EC695D /* RecentDirectories.m in Sources */,
|
CE515DF70FC6C12E00EC695D /* RecentDirectories.m in Sources */,
|
||||||
CE515DF80FC6C12E00EC695D /* RegistrationInterface.m in Sources */,
|
CE515DF80FC6C12E00EC695D /* RegistrationInterface.m in Sources */,
|
||||||
CE515DF90FC6C12E00EC695D /* Table.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 */,
|
||||||
@@ -408,64 +506,72 @@
|
|||||||
CE515E1F0FC6C19300EC695D /* ResultWindow.m in Sources */,
|
CE515E1F0FC6C19300EC695D /* ResultWindow.m in Sources */,
|
||||||
CE49DEF60FDFEB810098617B /* BRSingleLineFormatter.m in Sources */,
|
CE49DEF60FDFEB810098617B /* BRSingleLineFormatter.m in Sources */,
|
||||||
CE6032C00FE6784C007E33FF /* DetailsPanel.m in Sources */,
|
CE6032C00FE6784C007E33FF /* DetailsPanel.m in Sources */,
|
||||||
|
CE003CC611242D00004B0AA7 /* HSGUIController.m in Sources */,
|
||||||
|
CE003CC711242D00004B0AA7 /* HSOutline.m in Sources */,
|
||||||
|
CE003CC811242D00004B0AA7 /* HSWindowController.m in Sources */,
|
||||||
|
CE003CC911242D00004B0AA7 /* NSEventAdditions.m in Sources */,
|
||||||
|
CE003CCA11242D00004B0AA7 /* HSOutlineView.m in Sources */,
|
||||||
|
CE003CCB11242D00004B0AA7 /* NSIndexPathAdditions.m in Sources */,
|
||||||
|
CE003CCC11242D00004B0AA7 /* NSTableViewAdditions.m in Sources */,
|
||||||
|
CE003CD011242D2C004B0AA7 /* DirectoryOutline.m in Sources */,
|
||||||
|
CE0B3D6711243F83009A7A30 /* ResultOutline.m in Sources */,
|
||||||
|
CEDF07A3112493B200EE5BC0 /* StatsLabel.m in Sources */,
|
||||||
|
CE0A0C001175A1C000DCA3C6 /* HSTable.m in Sources */,
|
||||||
|
CE0A0C041175A1DE00DCA3C6 /* ProblemDialog.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
|
||||||
CE515DFC0FC6C13E00EC695D /* ErrorReportWindow.xib */ = {
|
|
||||||
isa = PBXVariantGroup;
|
|
||||||
children = (
|
|
||||||
CE515DFD0FC6C13E00EC695D /* English */,
|
|
||||||
);
|
|
||||||
name = ErrorReportWindow.xib;
|
|
||||||
sourceTree = SOURCE_ROOT;
|
|
||||||
};
|
|
||||||
CE515DFE0FC6C13E00EC695D /* progress.nib */ = {
|
|
||||||
isa = PBXVariantGroup;
|
|
||||||
children = (
|
|
||||||
CE515DFF0FC6C13E00EC695D /* English */,
|
|
||||||
);
|
|
||||||
name = progress.nib;
|
|
||||||
sourceTree = SOURCE_ROOT;
|
|
||||||
};
|
|
||||||
CE515E000FC6C13E00EC695D /* registration.nib */ = {
|
|
||||||
isa = PBXVariantGroup;
|
|
||||||
children = (
|
|
||||||
CE515E010FC6C13E00EC695D /* English */,
|
|
||||||
);
|
|
||||||
name = registration.nib;
|
|
||||||
sourceTree = SOURCE_ROOT;
|
|
||||||
};
|
|
||||||
/* End PBXVariantGroup section */
|
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
C01FCF4C08A954540054247B /* Release */ = {
|
C01FCF4C08A954540054247B /* release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||||
GCC_MODEL_TUNING = G5;
|
|
||||||
INFOPLIST_FILE = Info.plist;
|
INFOPLIST_FILE = Info.plist;
|
||||||
INSTALL_PATH = "$(HOME)/Applications";
|
INSTALL_PATH = "$(HOME)/Applications";
|
||||||
PRODUCT_NAME = "dupeGuru ME";
|
PRODUCT_NAME = "dupeGuru ME";
|
||||||
WRAPPER_EXTENSION = app;
|
WRAPPER_EXTENSION = app;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = release;
|
||||||
};
|
};
|
||||||
C01FCF5008A954540054247B /* Release */ = {
|
C01FCF5008A954540054247B /* release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ARCHS = "$(ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1)";
|
ARCHS = (
|
||||||
ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1 = x86_64;
|
i386,
|
||||||
|
x86_64,
|
||||||
|
ppc,
|
||||||
|
);
|
||||||
GCC_C_LANGUAGE_STANDARD = c99;
|
GCC_C_LANGUAGE_STANDARD = c99;
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.5;
|
MACOSX_DEPLOYMENT_TARGET = 10.5;
|
||||||
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
|
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = release;
|
||||||
|
};
|
||||||
|
CED596C5111AF56D00C0CF2B /* dev */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
|
||||||
|
GCC_C_LANGUAGE_STANDARD = c99;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.5;
|
||||||
|
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
|
||||||
|
};
|
||||||
|
name = dev;
|
||||||
|
};
|
||||||
|
CED596C6111AF56D00C0CF2B /* dev */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
INFOPLIST_FILE = Info.plist;
|
||||||
|
INSTALL_PATH = "$(HOME)/Applications";
|
||||||
|
PRODUCT_NAME = "dupeGuru ME";
|
||||||
|
WRAPPER_EXTENSION = app;
|
||||||
|
};
|
||||||
|
name = dev;
|
||||||
};
|
};
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
@@ -473,18 +579,20 @@
|
|||||||
C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "dupeguru" */ = {
|
C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "dupeguru" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
C01FCF4C08A954540054247B /* Release */,
|
C01FCF4C08A954540054247B /* release */,
|
||||||
|
CED596C6111AF56D00C0CF2B /* dev */,
|
||||||
);
|
);
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = release;
|
||||||
};
|
};
|
||||||
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */ = {
|
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
C01FCF5008A954540054247B /* Release */,
|
C01FCF5008A954540054247B /* release */,
|
||||||
|
CED596C5111AF56D00C0CF2B /* dev */,
|
||||||
);
|
);
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = release;
|
||||||
};
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,10 +7,12 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import "Utils.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
[Utils setPluginName:@"dg_cocoa"];
|
||||||
NSString *pluginPath = [[NSBundle mainBundle]
|
NSString *pluginPath = [[NSBundle mainBundle]
|
||||||
pathForResource:@"dg_cocoa"
|
pathForResource:@"dg_cocoa"
|
||||||
ofType:@"plugin"];
|
ofType:@"plugin"];
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -8,16 +8,11 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "../base/AppDelegate.h"
|
#import "../base/AppDelegate.h"
|
||||||
#import "DirectoryPanel.h"
|
|
||||||
#import "PyDupeGuru.h"
|
#import "PyDupeGuru.h"
|
||||||
|
|
||||||
@interface AppDelegate : AppDelegateBase
|
@interface AppDelegate : AppDelegateBase {}
|
||||||
{
|
|
||||||
DirectoryPanel *_directoryPanel;
|
|
||||||
}
|
|
||||||
- (IBAction)openWebsite:(id)sender;
|
- (IBAction)openWebsite:(id)sender;
|
||||||
- (IBAction)toggleDirectories:(id)sender;
|
- (IBAction)toggleDirectories:(id)sender;
|
||||||
|
|
||||||
- (DirectoryPanel *)directoryPanel;
|
|
||||||
- (PyDupeGuru *)py;
|
- (PyDupeGuru *)py;
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
#import "ValueTransformers.h"
|
#import "ValueTransformers.h"
|
||||||
#import "Consts.h"
|
#import "Consts.h"
|
||||||
#import "DetailsPanel.h"
|
#import "DetailsPanel.h"
|
||||||
|
#import "DirectoryPanel.h"
|
||||||
|
|
||||||
@implementation AppDelegate
|
@implementation AppDelegate
|
||||||
+ (void)initialize
|
+ (void)initialize
|
||||||
@@ -40,10 +41,10 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (DetailsPanelBase *)detailsPanel
|
- (DetailsPanel *)detailsPanel
|
||||||
{
|
{
|
||||||
if (!_detailsPanel)
|
if (!_detailsPanel)
|
||||||
_detailsPanel = [[DetailsPanel alloc] initWithPy:py];
|
_detailsPanel = [[DetailsPanelPE alloc] initWithPy:py];
|
||||||
return _detailsPanel;
|
return _detailsPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +61,7 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
- (DirectoryPanel *)directoryPanel
|
- (DirectoryPanel *)directoryPanel
|
||||||
{
|
{
|
||||||
if (!_directoryPanel)
|
if (!_directoryPanel)
|
||||||
_directoryPanel = [[DirectoryPanel alloc] initWithParentApp:self];
|
_directoryPanel = [[DirectoryPanelPE alloc] initWithParentApp:self];
|
||||||
return _directoryPanel;
|
return _directoryPanel;
|
||||||
}
|
}
|
||||||
- (PyDupeGuru *)py { return (PyDupeGuru *)py; }
|
- (PyDupeGuru *)py { return (PyDupeGuru *)py; }
|
||||||
@@ -75,36 +76,4 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[mi setKeyEquivalentModifierMask:NSCommandKeyMask|NSShiftKeyMask];
|
[mi setKeyEquivalentModifierMask:NSCommandKeyMask|NSShiftKeyMask];
|
||||||
[super applicationDidFinishLaunching:aNotification];
|
[super applicationDidFinishLaunching:aNotification];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationWillBecomeActive:(NSNotification *)aNotification
|
|
||||||
{
|
|
||||||
if (![[result window] isVisible])
|
|
||||||
[result showWindow:NSApp];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)applicationWillTerminate:(NSNotification *)aNotification
|
|
||||||
{
|
|
||||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
|
||||||
[ud setObject: [result getColumnsOrder] forKey:@"columnsOrder"];
|
|
||||||
[ud setObject: [result getColumnsWidth] forKey:@"columnsWidth"];
|
|
||||||
[py saveIgnoreList];
|
|
||||||
[py saveResults];
|
|
||||||
int sc = [ud integerForKey:@"sessionCountSinceLastIgnorePurge"];
|
|
||||||
if (sc >= 10)
|
|
||||||
{
|
|
||||||
sc = -1;
|
|
||||||
[py purgeIgnoreList];
|
|
||||||
}
|
|
||||||
sc++;
|
|
||||||
[ud setInteger:sc forKey:@"sessionCountSinceLastIgnorePurge"];
|
|
||||||
// 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
|
|
||||||
// But I need to release RecentDirectories so it saves the user defaults
|
|
||||||
[recentDirectories release];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)recentDirecoryClicked:(NSString *)directory
|
|
||||||
{
|
|
||||||
[[self directoryPanel] addDirectory:directory];
|
|
||||||
}
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "../base/DetailsPanel.h"
|
#import "../base/DetailsPanel.h"
|
||||||
|
|
||||||
@interface DetailsPanel : DetailsPanelBase
|
@interface DetailsPanelPE : DetailsPanel
|
||||||
{
|
{
|
||||||
IBOutlet NSImageView *dupeImage;
|
IBOutlet NSImageView *dupeImage;
|
||||||
IBOutlet NSProgressIndicator *dupeProgressIndicator;
|
IBOutlet NSProgressIndicator *dupeProgressIndicator;
|
||||||
IBOutlet NSImageView *refImage;
|
IBOutlet NSImageView *refImage;
|
||||||
IBOutlet NSProgressIndicator *refProgressIndicator;
|
IBOutlet NSProgressIndicator *refProgressIndicator;
|
||||||
|
|
||||||
PyApp *py;
|
PyApp *pyApp;
|
||||||
BOOL _needsRefresh;
|
BOOL _needsRefresh;
|
||||||
NSString *_dupePath;
|
NSString *_dupePath;
|
||||||
NSString *_refPath;
|
NSString *_refPath;
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
#import "DetailsPanel.h"
|
#import "DetailsPanel.h"
|
||||||
#import "Consts.h"
|
#import "Consts.h"
|
||||||
|
|
||||||
@implementation DetailsPanel
|
@implementation DetailsPanelPE
|
||||||
- (id)initWithPy:(PyApp *)aPy
|
- (id)initWithPy:(PyApp *)aPy
|
||||||
{
|
{
|
||||||
self = [super initWithPy:aPy];
|
self = [super initWithPy:aPy];
|
||||||
py = aPy;
|
pyApp = aPy;
|
||||||
_needsRefresh = YES;
|
_needsRefresh = YES;
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(imageLoaded:) name:ImageLoadedNotification object:self];
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(imageLoaded:) name:ImageLoadedNotification object:self];
|
||||||
return self;
|
return self;
|
||||||
@@ -36,18 +36,18 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[pool release];
|
[pool release];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)refresh
|
- (void)refreshDetails
|
||||||
{
|
{
|
||||||
if (!_needsRefresh)
|
if (!_needsRefresh)
|
||||||
return;
|
return;
|
||||||
[detailsTable reloadData];
|
[detailsTable reloadData];
|
||||||
|
|
||||||
NSString *refPath = [(PyDupeGuru *)py getSelectedDupeRefPath];
|
NSString *refPath = [(PyDupeGuru *)pyApp getSelectedDupeRefPath];
|
||||||
if (_refPath != nil)
|
if (_refPath != nil)
|
||||||
[_refPath autorelease];
|
[_refPath autorelease];
|
||||||
_refPath = [refPath retain];
|
_refPath = [refPath retain];
|
||||||
[NSThread detachNewThreadSelector:@selector(loadImageAsync:) toTarget:self withObject:refPath];
|
[NSThread detachNewThreadSelector:@selector(loadImageAsync:) toTarget:self withObject:refPath];
|
||||||
NSString *dupePath = [(PyDupeGuru *)py getSelectedDupePath];
|
NSString *dupePath = [(PyDupeGuru *)pyApp getSelectedDupePath];
|
||||||
if (_dupePath != nil)
|
if (_dupePath != nil)
|
||||||
[_dupePath autorelease];
|
[_dupePath autorelease];
|
||||||
_dupePath = [dupePath retain];
|
_dupePath = [dupePath retain];
|
||||||
@@ -59,12 +59,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Notifications */
|
/* Notifications */
|
||||||
- (void)duplicateSelectionChanged:(NSNotification *)aNotification
|
|
||||||
{
|
|
||||||
_needsRefresh = YES;
|
|
||||||
[super duplicateSelectionChanged:aNotification];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)imageLoaded:(NSNotification *)aNotification
|
- (void)imageLoaded:(NSNotification *)aNotification
|
||||||
{
|
{
|
||||||
NSString *imagePath = [[aNotification userInfo] valueForKey:@"imagePath"];
|
NSString *imagePath = [[aNotification userInfo] valueForKey:@"imagePath"];
|
||||||
@@ -80,4 +74,11 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[dupeProgressIndicator stopAnimation:nil];
|
[dupeProgressIndicator stopAnimation:nil];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Python --> Cocoa */
|
||||||
|
- (void)refresh
|
||||||
|
{
|
||||||
|
_needsRefresh = YES;
|
||||||
|
[super refresh];
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "../base/DirectoryPanel.h"
|
#import "../base/DirectoryPanel.h"
|
||||||
|
|
||||||
@interface DirectoryPanel : DirectoryPanelBase
|
@interface DirectoryPanelPE : DirectoryPanel
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
- (IBAction)addiPhoto:(id)sender;
|
- (IBAction)addiPhoto:(id)sender;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
|
|
||||||
static NSString* jobAddIPhoto = @"jobAddIPhoto";
|
static NSString* jobAddIPhoto = @"jobAddIPhoto";
|
||||||
|
|
||||||
@implementation DirectoryPanel
|
@implementation DirectoryPanelPE
|
||||||
- (id)initWithParentApp:(id)aParentApp
|
- (id)initWithParentApp:(id)aParentApp
|
||||||
{
|
{
|
||||||
self = [super initWithParentApp:aParentApp];
|
self = [super initWithParentApp:aParentApp];
|
||||||
@@ -44,9 +44,8 @@ static NSString* jobAddIPhoto = @"jobAddIPhoto";
|
|||||||
|
|
||||||
- (void)jobCompleted:(NSNotification *)aNotification
|
- (void)jobCompleted:(NSNotification *)aNotification
|
||||||
{
|
{
|
||||||
if ([[ProgressController mainProgressController] jobId] == jobAddIPhoto)
|
if ([[ProgressController mainProgressController] jobId] == jobAddIPhoto) {
|
||||||
{
|
[outlineView reloadData];
|
||||||
[directories reloadData];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>hsft</string>
|
<string>hsft</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.8.1</string>
|
<string>1.9.0</string>
|
||||||
<key>NSMainNibFile</key>
|
<key>NSMainNibFile</key>
|
||||||
<string>MainMenu</string>
|
<string>MainMenu</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
|
|||||||
@@ -1,146 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
|
||||||
which should be included with this package. The terms are also available at
|
|
||||||
http://www.hardcoded.net/licenses/hs_license
|
|
||||||
*/
|
|
||||||
|
|
||||||
#import "PictureBlocks.h"
|
|
||||||
#import "Utils.h"
|
|
||||||
|
|
||||||
@implementation PictureBlocks
|
|
||||||
+ (NSString *)getBlocksFromImagePath:(NSString *)imagePath blockCount:(NSNumber *)blockCount
|
|
||||||
{
|
|
||||||
return GetBlocks(imagePath, n2i(blockCount));
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (NSSize)getImageSize:(NSString *)imagePath
|
|
||||||
{
|
|
||||||
CFURLRef fileURL = CFURLCreateWithFileSystemPath(NULL, (CFStringRef)imagePath, kCFURLPOSIXPathStyle, FALSE);
|
|
||||||
CGImageSourceRef source = CGImageSourceCreateWithURL(fileURL, NULL);
|
|
||||||
if (source == NULL)
|
|
||||||
return NSMakeSize(0, 0);
|
|
||||||
CGImageRef image = CGImageSourceCreateImageAtIndex(source, 0, NULL);
|
|
||||||
if (image == NULL)
|
|
||||||
return NSMakeSize(0, 0);
|
|
||||||
size_t width = CGImageGetWidth(image);
|
|
||||||
size_t height = CGImageGetHeight(image);
|
|
||||||
CGImageRelease(image);
|
|
||||||
CFRelease(source);
|
|
||||||
CFRelease(fileURL);
|
|
||||||
return NSMakeSize(width, height);
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
CGContextRef MyCreateBitmapContext (int width, int height)
|
|
||||||
{
|
|
||||||
CGContextRef context = NULL;
|
|
||||||
CGColorSpaceRef colorSpace;
|
|
||||||
void * bitmapData;
|
|
||||||
int bitmapByteCount;
|
|
||||||
int bitmapBytesPerRow;
|
|
||||||
|
|
||||||
bitmapBytesPerRow = (width * 4);
|
|
||||||
bitmapByteCount = (bitmapBytesPerRow * height);
|
|
||||||
|
|
||||||
colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
|
|
||||||
|
|
||||||
// calloc() must be used to allocate bitmapData here because the buffer has to be zeroed.
|
|
||||||
// If it's not zeroes, when images with transparency are drawn in the context, this buffer
|
|
||||||
// will stay with undefined pixels, which means that two pictures with the same pixels will
|
|
||||||
// most likely have different blocks (which is not supposed to happen).
|
|
||||||
bitmapData = calloc(bitmapByteCount, 1);
|
|
||||||
if (bitmapData == NULL)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "Memory not allocated!");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
context = CGBitmapContextCreate (bitmapData,width,height,8,bitmapBytesPerRow,colorSpace,kCGImageAlphaNoneSkipLast);
|
|
||||||
if (context== NULL)
|
|
||||||
{
|
|
||||||
free (bitmapData);
|
|
||||||
fprintf (stderr, "Context not created!");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
CGColorSpaceRelease( colorSpace );
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns 0x00RRGGBB
|
|
||||||
int GetBlock(unsigned char *imageData, int imageWidth, int imageHeight, int boxX, int boxY, int boxW, int boxH)
|
|
||||||
{
|
|
||||||
int i,j;
|
|
||||||
int totalR = 0;
|
|
||||||
int totalG = 0;
|
|
||||||
int totalB = 0;
|
|
||||||
for(i = boxY; i < boxY + boxH; i++)
|
|
||||||
{
|
|
||||||
for(j = boxX; j < boxX + boxW; j++)
|
|
||||||
{
|
|
||||||
int offset = (i * imageWidth * 4) + (j * 4);
|
|
||||||
totalR += *(imageData + offset);
|
|
||||||
totalG += *(imageData + offset + 1);
|
|
||||||
totalB += *(imageData + offset + 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int pixelCount = boxH * boxW;
|
|
||||||
int result = 0;
|
|
||||||
result += (totalR / pixelCount) << 16;
|
|
||||||
result += (totalG / pixelCount) << 8;
|
|
||||||
result += (totalB / pixelCount);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSString* GetBlocks (NSString* filePath, int blockCount)
|
|
||||||
{
|
|
||||||
CFURLRef fileURL = CFURLCreateWithFileSystemPath(NULL, (CFStringRef)filePath, kCFURLPOSIXPathStyle, FALSE);
|
|
||||||
CGImageSourceRef source = CGImageSourceCreateWithURL(fileURL, NULL);
|
|
||||||
if (source == NULL)
|
|
||||||
return NULL;
|
|
||||||
CGImageRef image = CGImageSourceCreateImageAtIndex(source, 0, NULL);
|
|
||||||
if (image == NULL)
|
|
||||||
return NULL;
|
|
||||||
size_t width = CGImageGetWidth(image);
|
|
||||||
size_t height = CGImageGetHeight(image);
|
|
||||||
CGContextRef myContext = MyCreateBitmapContext(width, height);
|
|
||||||
CGRect myBoundingBox = CGRectMake (0, 0, width, height);
|
|
||||||
CGContextDrawImage(myContext, myBoundingBox, image);
|
|
||||||
unsigned char *bitmapData = CGBitmapContextGetData(myContext);
|
|
||||||
if (bitmapData == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
int blockHeight = height / blockCount;
|
|
||||||
if (blockHeight < 1)
|
|
||||||
blockHeight = 1;
|
|
||||||
int blockWidth = width / blockCount;
|
|
||||||
if (blockWidth < 1)
|
|
||||||
blockWidth = 1;
|
|
||||||
//blockCount might have changed
|
|
||||||
int blockXCount = (width / blockWidth);
|
|
||||||
int blockYCount = (height / blockHeight);
|
|
||||||
|
|
||||||
CFMutableArrayRef blocks = CFArrayCreateMutable(NULL, blockXCount * blockYCount, &kCFTypeArrayCallBacks);
|
|
||||||
int i,j;
|
|
||||||
for(i = 0; i < blockYCount; i++)
|
|
||||||
{
|
|
||||||
for(j = 0; j < blockXCount; j++)
|
|
||||||
{
|
|
||||||
int block = GetBlock(bitmapData, width, height, j * blockWidth, i * blockHeight, blockWidth, blockHeight);
|
|
||||||
CFStringRef strBlock = CFStringCreateWithFormat(NULL, NULL, CFSTR("%06x"), block);
|
|
||||||
CFArrayAppendValue(blocks, strBlock);
|
|
||||||
CFRelease(strBlock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CGContextRelease (myContext);
|
|
||||||
if (bitmapData) free(bitmapData);
|
|
||||||
CGImageRelease(image);
|
|
||||||
CFRelease(source);
|
|
||||||
CFRelease(fileURL);
|
|
||||||
|
|
||||||
CFStringRef result = CFStringCreateByCombiningStrings(NULL, blocks, CFSTR(""));
|
|
||||||
CFRelease(blocks);
|
|
||||||
return (NSString *)result;
|
|
||||||
}
|
|
||||||
@@ -7,31 +7,10 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "Outline.h"
|
|
||||||
#import "../base/ResultWindow.h"
|
#import "../base/ResultWindow.h"
|
||||||
|
|
||||||
@interface ResultWindow : ResultWindowBase
|
@interface ResultWindow : ResultWindowBase {}
|
||||||
{
|
|
||||||
IBOutlet NSSearchField *filterField;
|
|
||||||
|
|
||||||
NSMutableIndexSet *_deltaColumns;
|
|
||||||
}
|
|
||||||
- (IBAction)clearIgnoreList:(id)sender;
|
|
||||||
- (IBAction)clearPictureCache:(id)sender;
|
- (IBAction)clearPictureCache:(id)sender;
|
||||||
- (IBAction)filter:(id)sender;
|
|
||||||
- (IBAction)ignoreSelected:(id)sender;
|
|
||||||
- (IBAction)markAll:(id)sender;
|
|
||||||
- (IBAction)markInvert:(id)sender;
|
|
||||||
- (IBAction)markNone:(id)sender;
|
|
||||||
- (IBAction)markSelected:(id)sender;
|
|
||||||
- (IBAction)markToggle:(id)sender;
|
|
||||||
- (IBAction)openSelected:(id)sender;
|
|
||||||
- (IBAction)refresh:(id)sender;
|
|
||||||
- (IBAction)removeMarked:(id)sender;
|
|
||||||
- (IBAction)removeSelected:(id)sender;
|
|
||||||
- (IBAction)renameSelected:(id)sender;
|
|
||||||
- (IBAction)revealSelected:(id)sender;
|
|
||||||
- (IBAction)startDuplicateScan:(id)sender;
|
- (IBAction)startDuplicateScan:(id)sender;
|
||||||
- (IBAction)toggleDelta:(id)sender;
|
|
||||||
- (IBAction)toggleDirectories:(id)sender;
|
- (IBAction)toggleDirectories:(id)sender;
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -20,31 +20,13 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
{
|
{
|
||||||
[super awakeFromNib];
|
[super awakeFromNib];
|
||||||
[[self window] setTitle:@"dupeGuru Picture Edition"];
|
[[self window] setTitle:@"dupeGuru Picture Edition"];
|
||||||
_displayDelta = NO;
|
NSMutableIndexSet *deltaColumns = [NSMutableIndexSet indexSetWithIndexesInRange:NSMakeRange(2,5)];
|
||||||
_powerMode = NO;
|
[deltaColumns removeIndex:3];
|
||||||
_deltaColumns = [[NSMutableIndexSet indexSetWithIndexesInRange:NSMakeRange(2,5)] retain];
|
[deltaColumns removeIndex:4];
|
||||||
[_deltaColumns removeIndex:3];
|
[outline setDeltaColumns:deltaColumns];
|
||||||
[_deltaColumns removeIndex:4];
|
|
||||||
[deltaSwitch setSelectedSegment:0];
|
|
||||||
[pmSwitch setSelectedSegment:0];
|
|
||||||
[py setDisplayDeltaValues:b2n(_displayDelta)];
|
|
||||||
[matches setTarget:self];
|
|
||||||
[matches setDoubleAction:@selector(openSelected:)];
|
|
||||||
[self refreshStats];
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resultsMarkingChanged:) name:ResultsMarkingChangedNotification object:nil];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Actions */
|
/* Actions */
|
||||||
- (IBAction)clearIgnoreList:(id)sender
|
|
||||||
{
|
|
||||||
int i = n2i([py getIgnoreListCount]);
|
|
||||||
if (!i)
|
|
||||||
return;
|
|
||||||
if ([Dialogs askYesNo:[NSString stringWithFormat:@"Do you really want to remove all %d items from the ignore list?",i]] == NSAlertSecondButtonReturn) // NO
|
|
||||||
return;
|
|
||||||
[py clearIgnoreList];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)clearPictureCache:(id)sender
|
- (IBAction)clearPictureCache:(id)sender
|
||||||
{
|
{
|
||||||
if ([Dialogs askYesNo:@"Do you really want to remove all your cached picture analysis?"] == NSAlertSecondButtonReturn) // NO
|
if ([Dialogs askYesNo:@"Do you really want to remove all your cached picture analysis?"] == NSAlertSecondButtonReturn) // NO
|
||||||
@@ -52,101 +34,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[(PyDupeGuru *)py clearPictureCache];
|
[(PyDupeGuru *)py clearPictureCache];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)filter:(id)sender
|
|
||||||
{
|
|
||||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
|
||||||
[py setEscapeFilterRegexp:b2n(!n2b([ud objectForKey:@"useRegexpFilter"]))];
|
|
||||||
[py applyFilter:[filterField stringValue]];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)ignoreSelected:(id)sender
|
|
||||||
{
|
|
||||||
NSArray *nodeList = [self getSelected:YES];
|
|
||||||
if (![nodeList count])
|
|
||||||
return;
|
|
||||||
if ([Dialogs askYesNo:[NSString stringWithFormat:@"All selected %d matches are going to be ignored in all subsequent scans. Continue?",[nodeList count]]] == NSAlertSecondButtonReturn) // NO
|
|
||||||
return;
|
|
||||||
[self performPySelection:[self getSelectedPaths:YES]];
|
|
||||||
[py addSelectedToIgnoreList];
|
|
||||||
[py removeSelected];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)markAll:(id)sender
|
|
||||||
{
|
|
||||||
[py markAll];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)markInvert:(id)sender
|
|
||||||
{
|
|
||||||
[py markInvert];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)markNone:(id)sender
|
|
||||||
{
|
|
||||||
[py markNone];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)markSelected:(id)sender
|
|
||||||
{
|
|
||||||
[self performPySelection:[self getSelectedPaths:YES]];
|
|
||||||
[py toggleSelectedMark];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)markToggle:(id)sender
|
|
||||||
{
|
|
||||||
OVNode *node = [matches itemAtRow:[matches clickedRow]];
|
|
||||||
[self performPySelection:[NSArray arrayWithObject:p2a([node indexPath])]];
|
|
||||||
[py toggleSelectedMark];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)openSelected:(id)sender
|
|
||||||
{
|
|
||||||
[self performPySelection:[self getSelectedPaths:NO]];
|
|
||||||
[py openSelected];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)refresh:(id)sender
|
|
||||||
{
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)removeMarked:(id)sender
|
|
||||||
{
|
|
||||||
int mark_count = [[py getMarkCount] intValue];
|
|
||||||
if (!mark_count)
|
|
||||||
return;
|
|
||||||
if ([Dialogs askYesNo:[NSString stringWithFormat:@"You are about to remove %d files from results. Continue?",mark_count]] == NSAlertSecondButtonReturn) // NO
|
|
||||||
return;
|
|
||||||
[py removeMarked];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)removeSelected:(id)sender
|
|
||||||
{
|
|
||||||
NSArray *nodeList = [self getSelected:YES];
|
|
||||||
if (![nodeList count])
|
|
||||||
return;
|
|
||||||
if ([Dialogs askYesNo:[NSString stringWithFormat:@"You are about to remove %d files from results. Continue?",[nodeList count]]] == NSAlertSecondButtonReturn) // NO
|
|
||||||
return;
|
|
||||||
[self performPySelection:[self getSelectedPaths:YES]];
|
|
||||||
[py removeSelected];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)renameSelected:(id)sender
|
|
||||||
{
|
|
||||||
int col = [matches columnWithIdentifier:@"0"];
|
|
||||||
int row = [matches selectedRow];
|
|
||||||
[matches editColumn:col row:row withEvent:[NSApp currentEvent] select:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)resetColumnsToDefault:(id)sender
|
- (IBAction)resetColumnsToDefault:(id)sender
|
||||||
{
|
{
|
||||||
NSMutableArray *columnsOrder = [NSMutableArray array];
|
NSMutableArray *columnsOrder = [NSMutableArray array];
|
||||||
@@ -164,12 +51,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[self restoreColumnsPosition:columnsOrder widths:columnsWidth];
|
[self restoreColumnsPosition:columnsOrder widths:columnsWidth];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)revealSelected:(id)sender
|
|
||||||
{
|
|
||||||
[self performPySelection:[self getSelectedPaths:NO]];
|
|
||||||
[py revealSelected];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)startDuplicateScan:(id)sender
|
- (IBAction)startDuplicateScan:(id)sender
|
||||||
{
|
{
|
||||||
if ([matches numberOfRows] > 0)
|
if ([matches numberOfRows] > 0)
|
||||||
@@ -183,8 +64,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[_py setMixFileKind:[ud objectForKey:@"mixFileKind"]];
|
[_py setMixFileKind:[ud objectForKey:@"mixFileKind"]];
|
||||||
[_py setMatchScaled:[ud objectForKey:@"matchScaled"]];
|
[_py setMatchScaled:[ud objectForKey:@"matchScaled"]];
|
||||||
int r = n2i([py doScan]);
|
int r = n2i([py doScan]);
|
||||||
[matches reloadData];
|
|
||||||
[self refreshStats];
|
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
[[ProgressController mainProgressController] hide];
|
[[ProgressController mainProgressController] hide];
|
||||||
if (r == 1)
|
if (r == 1)
|
||||||
@@ -196,15 +75,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)toggleDelta:(id)sender
|
|
||||||
{
|
|
||||||
if ([deltaSwitch selectedSegment] == 1)
|
|
||||||
[deltaSwitch setSelectedSegment:0];
|
|
||||||
else
|
|
||||||
[deltaSwitch setSelectedSegment:1];
|
|
||||||
[self changeDelta:sender];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)toggleDirectories:(id)sender
|
- (IBAction)toggleDirectories:(id)sender
|
||||||
{
|
{
|
||||||
[(AppDelegate *)app toggleDirectories:sender];
|
[(AppDelegate *)app toggleDirectories:sender];
|
||||||
@@ -227,43 +97,4 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[_resultColumns addObject:[self getColumnForIdentifier:7 title:@"Match %" width:58 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:7 title:@"Match %" width:58 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:8 title:@"Dupe Count" width:80 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:8 title:@"Dupe Count" width:80 refCol:refCol]];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delegate */
|
|
||||||
- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
|
|
||||||
{
|
|
||||||
OVNode *node = item;
|
|
||||||
if ([[tableColumn identifier] isEqual:@"mark"])
|
|
||||||
{
|
|
||||||
[cell setEnabled: [node isMarkable]];
|
|
||||||
}
|
|
||||||
if ([cell isKindOfClass:[NSTextFieldCell class]])
|
|
||||||
{
|
|
||||||
// Determine if the text color will be blue due to directory being reference.
|
|
||||||
NSTextFieldCell *textCell = cell;
|
|
||||||
if ([node isMarkable])
|
|
||||||
[textCell setTextColor:[NSColor blackColor]];
|
|
||||||
else
|
|
||||||
[textCell setTextColor:[NSColor blueColor]];
|
|
||||||
if ((_displayDelta) && (_powerMode || ([node level] > 1)))
|
|
||||||
{
|
|
||||||
int i = [[tableColumn identifier] intValue];
|
|
||||||
if ([_deltaColumns containsIndex:i])
|
|
||||||
[textCell setTextColor:[NSColor orangeColor]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)outlineViewSelectionDidChange:(NSNotification *)notification
|
|
||||||
{
|
|
||||||
[self performPySelection:[self getSelectedPaths:NO]];
|
|
||||||
[py refreshDetailsWithSelected];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:DuplicateSelectionChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)resultsMarkingChanged:(NSNotification *)aNotification
|
|
||||||
{
|
|
||||||
[matches invalidateMarkings];
|
|
||||||
[self refreshStats];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -4,215 +4,38 @@
|
|||||||
# 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/hs_license
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
import objc
|
from core.app_cocoa_inter import PyDupeGuruBase, PyDetailsPanel
|
||||||
from Foundation import NSObject
|
|
||||||
|
|
||||||
from core_pe import app_cocoa as app_pe_cocoa
|
from core_pe import app_cocoa as app_pe_cocoa
|
||||||
|
|
||||||
# Fix py2app imports which chokes on relative imports
|
# Fix py2app imports which chokes on relative imports and other stuff
|
||||||
from core import app, app_cocoa, data, directories, engine, export, ignore, results, scanner
|
from core_pe import block, cache, matchbase, data, _block_osx
|
||||||
from core_pe import block, cache, matchbase, data
|
from lxml import etree, _elementpath
|
||||||
from hsutil import conflict
|
import gzip
|
||||||
|
|
||||||
class PyApp(NSObject):
|
class PyDupeGuru(PyDupeGuruBase):
|
||||||
pass #fake class
|
|
||||||
|
|
||||||
class PyDupeGuru(PyApp):
|
|
||||||
def init(self):
|
def init(self):
|
||||||
self = super(PyDupeGuru,self).init()
|
self = super(PyDupeGuru, self).init()
|
||||||
self.app = app_pe_cocoa.DupeGuruPE()
|
self.py = app_pe_cocoa.DupeGuruPE()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
#---Directories
|
|
||||||
def addDirectory_(self,directory):
|
|
||||||
return self.app.add_directory(directory)
|
|
||||||
|
|
||||||
def removeDirectory_(self,index):
|
|
||||||
self.app.RemoveDirectory(index)
|
|
||||||
|
|
||||||
def setDirectory_state_(self,node_path,state):
|
|
||||||
self.app.SetDirectoryState(node_path,state)
|
|
||||||
|
|
||||||
#---Results
|
|
||||||
def clearIgnoreList(self):
|
|
||||||
self.app.scanner.ignore_list.Clear()
|
|
||||||
|
|
||||||
def clearPictureCache(self):
|
def clearPictureCache(self):
|
||||||
self.app.scanner.clear_picture_cache()
|
self.py.scanner.clear_picture_cache()
|
||||||
|
|
||||||
def doScan(self):
|
|
||||||
return self.app.start_scanning()
|
|
||||||
|
|
||||||
def exportToXHTMLwithColumns_(self, column_ids):
|
|
||||||
return self.app.export_to_xhtml(column_ids)
|
|
||||||
|
|
||||||
def loadIgnoreList(self):
|
|
||||||
self.app.load_ignore_list()
|
|
||||||
|
|
||||||
def loadResults(self):
|
|
||||||
self.app.load()
|
|
||||||
|
|
||||||
def markAll(self):
|
|
||||||
self.app.results.mark_all()
|
|
||||||
|
|
||||||
def markNone(self):
|
|
||||||
self.app.results.mark_none()
|
|
||||||
|
|
||||||
def markInvert(self):
|
|
||||||
self.app.results.mark_invert()
|
|
||||||
|
|
||||||
def purgeIgnoreList(self):
|
|
||||||
self.app.PurgeIgnoreList()
|
|
||||||
|
|
||||||
def toggleSelectedMark(self):
|
|
||||||
self.app.ToggleSelectedMarkState()
|
|
||||||
|
|
||||||
def saveIgnoreList(self):
|
|
||||||
self.app.save_ignore_list()
|
|
||||||
|
|
||||||
def saveResults(self):
|
|
||||||
self.app.save()
|
|
||||||
|
|
||||||
def refreshDetailsWithSelected(self):
|
|
||||||
self.app.RefreshDetailsWithSelected()
|
|
||||||
|
|
||||||
def selectedResultNodePaths(self):
|
|
||||||
return self.app.selected_result_node_paths()
|
|
||||||
|
|
||||||
def selectResultNodePaths_(self,node_paths):
|
|
||||||
self.app.SelectResultNodePaths(node_paths)
|
|
||||||
|
|
||||||
def selectedPowerMarkerNodePaths(self):
|
|
||||||
return self.app.selected_powermarker_node_paths()
|
|
||||||
|
|
||||||
def selectPowerMarkerNodePaths_(self,node_paths):
|
|
||||||
self.app.SelectPowerMarkerNodePaths(node_paths)
|
|
||||||
|
|
||||||
#---Actions
|
|
||||||
def addSelectedToIgnoreList(self):
|
|
||||||
self.app.AddSelectedToIgnoreList()
|
|
||||||
|
|
||||||
def deleteMarked(self):
|
|
||||||
self.app.delete_marked()
|
|
||||||
|
|
||||||
def applyFilter_(self, filter):
|
|
||||||
self.app.apply_filter(filter)
|
|
||||||
|
|
||||||
def makeSelectedReference(self):
|
|
||||||
self.app.MakeSelectedReference()
|
|
||||||
|
|
||||||
def copyOrMove_markedTo_recreatePath_(self,copy,destination,recreate_path):
|
|
||||||
self.app.copy_or_move_marked(copy, destination, recreate_path)
|
|
||||||
|
|
||||||
def openSelected(self):
|
|
||||||
self.app.OpenSelected()
|
|
||||||
|
|
||||||
def removeMarked(self):
|
|
||||||
self.app.results.perform_on_marked(lambda x:True,True)
|
|
||||||
|
|
||||||
def removeSelected(self):
|
|
||||||
self.app.RemoveSelected()
|
|
||||||
|
|
||||||
def renameSelected_(self,newname):
|
|
||||||
return self.app.RenameSelected(newname)
|
|
||||||
|
|
||||||
def revealSelected(self):
|
|
||||||
self.app.RevealSelected()
|
|
||||||
|
|
||||||
#---Misc
|
|
||||||
def sortDupesBy_ascending_(self,key,asc):
|
|
||||||
self.app.sort_dupes(key,asc)
|
|
||||||
|
|
||||||
def sortGroupsBy_ascending_(self,key,asc):
|
|
||||||
self.app.sort_groups(key,asc)
|
|
||||||
|
|
||||||
#---Information
|
|
||||||
def getIgnoreListCount(self):
|
|
||||||
return len(self.app.scanner.ignore_list)
|
|
||||||
|
|
||||||
def getMarkCount(self):
|
|
||||||
return self.app.results.mark_count
|
|
||||||
|
|
||||||
def getStatLine(self):
|
|
||||||
return self.app.stat_line
|
|
||||||
|
|
||||||
def getOperationalErrorCount(self):
|
|
||||||
return self.app.last_op_error_count
|
|
||||||
|
|
||||||
|
#---Information
|
||||||
def getSelectedDupePath(self):
|
def getSelectedDupePath(self):
|
||||||
return unicode(self.app.selected_dupe_path())
|
return unicode(self.py.selected_dupe_path())
|
||||||
|
|
||||||
def getSelectedDupeRefPath(self):
|
def getSelectedDupeRefPath(self):
|
||||||
return unicode(self.app.selected_dupe_ref_path())
|
return unicode(self.py.selected_dupe_ref_path())
|
||||||
|
|
||||||
#---Data
|
|
||||||
@objc.signature('i@:i')
|
|
||||||
def getOutlineViewMaxLevel_(self, tag):
|
|
||||||
return self.app.GetOutlineViewMaxLevel(tag)
|
|
||||||
|
|
||||||
@objc.signature('@@:i@')
|
|
||||||
def getOutlineView_childCountsForPath_(self, tag, node_path):
|
|
||||||
return self.app.GetOutlineViewChildCounts(tag, node_path)
|
|
||||||
|
|
||||||
def getOutlineView_valuesForIndexes_(self,tag,node_path):
|
|
||||||
return self.app.GetOutlineViewValues(tag,node_path)
|
|
||||||
|
|
||||||
def getOutlineView_markedAtIndexes_(self,tag,node_path):
|
|
||||||
return self.app.GetOutlineViewMarked(tag,node_path)
|
|
||||||
|
|
||||||
def getTableViewCount_(self,tag):
|
|
||||||
return self.app.GetTableViewCount(tag)
|
|
||||||
|
|
||||||
def getTableViewMarkedIndexes_(self,tag):
|
|
||||||
return self.app.GetTableViewMarkedIndexes(tag)
|
|
||||||
|
|
||||||
def getTableView_valuesForRow_(self,tag,row):
|
|
||||||
return self.app.GetTableViewValues(tag,row)
|
|
||||||
|
|
||||||
#---Properties
|
#---Properties
|
||||||
def setMatchScaled_(self,match_scaled):
|
def setMatchScaled_(self,match_scaled):
|
||||||
self.app.scanner.match_scaled = match_scaled
|
self.py.scanner.match_scaled = match_scaled
|
||||||
|
|
||||||
def setMinMatchPercentage_(self,percentage):
|
def setMinMatchPercentage_(self,percentage):
|
||||||
self.app.scanner.threshold = int(percentage)
|
self.py.scanner.threshold = int(percentage)
|
||||||
|
|
||||||
def setMixFileKind_(self,mix_file_kind):
|
|
||||||
self.app.scanner.mix_file_kind = mix_file_kind
|
|
||||||
|
|
||||||
def setDisplayDeltaValues_(self,display_delta_values):
|
|
||||||
self.app.display_delta_values= display_delta_values
|
|
||||||
|
|
||||||
def setEscapeFilterRegexp_(self, escape_filter_regexp):
|
|
||||||
self.app.options['escape_filter_regexp'] = escape_filter_regexp
|
|
||||||
|
|
||||||
def setRemoveEmptyFolders_(self, remove_empty_folders):
|
|
||||||
self.app.options['clean_empty_dirs'] = remove_empty_folders
|
|
||||||
|
|
||||||
#---Worker
|
|
||||||
def getJobProgress(self):
|
|
||||||
return self.app.progress.last_progress
|
|
||||||
|
|
||||||
def getJobDesc(self):
|
|
||||||
return self.app.progress.last_desc
|
|
||||||
|
|
||||||
def cancelJob(self):
|
|
||||||
self.app.progress.job_cancelled = True
|
|
||||||
|
|
||||||
#---Registration
|
#---Registration
|
||||||
def appName(self):
|
def appName(self):
|
||||||
return "dupeGuru Picture Edition"
|
return "dupeGuru Picture Edition"
|
||||||
|
|
||||||
def demoLimitDescription(self):
|
|
||||||
return self.app.DEMO_LIMIT_DESC
|
|
||||||
|
|
||||||
@objc.signature('i@:')
|
|
||||||
def isRegistered(self):
|
|
||||||
return self.app.registered
|
|
||||||
|
|
||||||
@objc.signature('i@:@@')
|
|
||||||
def isCodeValid_withEmail_(self, code, email):
|
|
||||||
return self.app.is_code_valid(code, email)
|
|
||||||
|
|
||||||
def setRegisteredCode_andEmail_(self, code, email):
|
|
||||||
self.app.set_registration(code, email)
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,9 @@
|
|||||||
CE031751109B340A00517EE6 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE031750109B340A00517EE6 /* Preferences.xib */; };
|
CE031751109B340A00517EE6 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE031750109B340A00517EE6 /* Preferences.xib */; };
|
||||||
CE031754109B345200517EE6 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE031753109B345200517EE6 /* MainMenu.xib */; };
|
CE031754109B345200517EE6 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE031753109B345200517EE6 /* MainMenu.xib */; };
|
||||||
CE073F6309CAE1A3005C1D2F /* dupeguru_pe_help in Resources */ = {isa = PBXBuildFile; fileRef = CE073F5409CAE1A3005C1D2F /* dupeguru_pe_help */; };
|
CE073F6309CAE1A3005C1D2F /* dupeguru_pe_help in Resources */ = {isa = PBXBuildFile; fileRef = CE073F5409CAE1A3005C1D2F /* dupeguru_pe_help */; };
|
||||||
CE0C46AA0FA0647E000BE99B /* PictureBlocks.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0C46A90FA0647E000BE99B /* PictureBlocks.m */; };
|
CE0C2AB61177011000BC749F /* HSTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0C2AB51177011000BC749F /* HSTable.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 */; };
|
||||||
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; };
|
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; };
|
||||||
@@ -23,24 +25,32 @@
|
|||||||
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 */; };
|
CE77C89E10946C6D0078B0DB /* DirectoryPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE77C89C10946C6D0078B0DB /* DirectoryPanel.xib */; };
|
||||||
CE77C8A810946CE20078B0DB /* DetailsPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE77C8A710946CE20078B0DB /* DetailsPanel.xib */; };
|
CE77C8A810946CE20078B0DB /* DetailsPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE77C8A710946CE20078B0DB /* DetailsPanel.xib */; };
|
||||||
|
CE7AC9181119911200D02F6C /* ErrorReportWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE7AC9151119911200D02F6C /* ErrorReportWindow.xib */; };
|
||||||
|
CE7AC9191119911200D02F6C /* progress.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE7AC9161119911200D02F6C /* progress.xib */; };
|
||||||
|
CE7AC91A1119911200D02F6C /* registration.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE7AC9171119911200D02F6C /* registration.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 */; };
|
||||||
CE80DB300FC192D60086DCA6 /* Outline.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB200FC192D60086DCA6 /* Outline.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 */; };
|
CE80DB320FC192D60086DCA6 /* RecentDirectories.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB250FC192D60086DCA6 /* RecentDirectories.m */; };
|
||||||
CE80DB330FC192D60086DCA6 /* RegistrationInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB270FC192D60086DCA6 /* RegistrationInterface.m */; };
|
CE80DB330FC192D60086DCA6 /* RegistrationInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB270FC192D60086DCA6 /* RegistrationInterface.m */; };
|
||||||
CE80DB340FC192D60086DCA6 /* Table.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB290FC192D60086DCA6 /* Table.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 */; };
|
||||||
CE80DB4A0FC193770086DCA6 /* NSImageAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB490FC193770086DCA6 /* NSImageAdditions.m */; };
|
CE80DB4A0FC193770086DCA6 /* NSImageAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB490FC193770086DCA6 /* NSImageAdditions.m */; };
|
||||||
CE80DB760FC194760086DCA6 /* ErrorReportWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE80DB700FC194760086DCA6 /* ErrorReportWindow.xib */; };
|
|
||||||
CE80DB770FC194760086DCA6 /* progress.nib in Resources */ = {isa = PBXBuildFile; fileRef = CE80DB720FC194760086DCA6 /* progress.nib */; };
|
|
||||||
CE80DB780FC194760086DCA6 /* registration.nib in Resources */ = {isa = PBXBuildFile; fileRef = CE80DB740FC194760086DCA6 /* registration.nib */; };
|
|
||||||
CE80DB8A0FC1951C0086DCA6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB830FC1951C0086DCA6 /* AppDelegate.m */; };
|
CE80DB8A0FC1951C0086DCA6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB830FC1951C0086DCA6 /* AppDelegate.m */; };
|
||||||
CE80DB8B0FC1951C0086DCA6 /* DirectoryPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB860FC1951C0086DCA6 /* DirectoryPanel.m */; };
|
CE80DB8B0FC1951C0086DCA6 /* DirectoryPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB860FC1951C0086DCA6 /* DirectoryPanel.m */; };
|
||||||
CE80DB8C0FC1951C0086DCA6 /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB890FC1951C0086DCA6 /* ResultWindow.m */; };
|
CE80DB8C0FC1951C0086DCA6 /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE80DB890FC1951C0086DCA6 /* ResultWindow.m */; };
|
||||||
CE848A1909DD85810004CB44 /* Consts.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE848A1809DD85810004CB44 /* Consts.h */; };
|
CE848A1909DD85810004CB44 /* Consts.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE848A1809DD85810004CB44 /* Consts.h */; };
|
||||||
|
CE95865E112C516400F95FD2 /* ResultOutline.m in Sources */ = {isa = PBXBuildFile; fileRef = CE95865B112C516400F95FD2 /* ResultOutline.m */; };
|
||||||
|
CE95865F112C516400F95FD2 /* StatsLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE95865D112C516400F95FD2 /* StatsLabel.m */; };
|
||||||
|
CE9EA7561122C96C008CD2BC /* HSGUIController.m in Sources */ = {isa = PBXBuildFile; fileRef = CE9EA7441122C96C008CD2BC /* HSGUIController.m */; };
|
||||||
|
CE9EA7571122C96C008CD2BC /* HSOutline.m in Sources */ = {isa = PBXBuildFile; fileRef = CE9EA7461122C96C008CD2BC /* HSOutline.m */; };
|
||||||
|
CE9EA7581122C96C008CD2BC /* HSWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CE9EA7481122C96C008CD2BC /* HSWindowController.m */; };
|
||||||
|
CE9EA7591122C96C008CD2BC /* NSEventAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE9EA74A1122C96C008CD2BC /* NSEventAdditions.m */; };
|
||||||
|
CE9EA75A1122C96C008CD2BC /* HSOutlineView.m in Sources */ = {isa = PBXBuildFile; fileRef = CE9EA7511122C96C008CD2BC /* HSOutlineView.m */; };
|
||||||
|
CE9EA75B1122C96C008CD2BC /* NSIndexPathAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE9EA7531122C96C008CD2BC /* NSIndexPathAdditions.m */; };
|
||||||
|
CE9EA75C1122C96C008CD2BC /* NSTableViewAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE9EA7551122C96C008CD2BC /* NSTableViewAdditions.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 */; };
|
||||||
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 */; };
|
||||||
@@ -77,14 +87,20 @@
|
|||||||
CE031750109B340A00517EE6 /* Preferences.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = Preferences.xib; sourceTree = "<group>"; };
|
CE031750109B340A00517EE6 /* Preferences.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = Preferences.xib; sourceTree = "<group>"; };
|
||||||
CE031753109B345200517EE6 /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MainMenu.xib; path = ../../base/xib/MainMenu.xib; sourceTree = "<group>"; };
|
CE031753109B345200517EE6 /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MainMenu.xib; path = ../../base/xib/MainMenu.xib; sourceTree = "<group>"; };
|
||||||
CE073F5409CAE1A3005C1D2F /* dupeguru_pe_help */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dupeguru_pe_help; path = ../../help_pe/dupeguru_pe_help; sourceTree = SOURCE_ROOT; };
|
CE073F5409CAE1A3005C1D2F /* dupeguru_pe_help */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dupeguru_pe_help; path = ../../help_pe/dupeguru_pe_help; sourceTree = SOURCE_ROOT; };
|
||||||
CE0C46A80FA0647E000BE99B /* PictureBlocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PictureBlocks.h; sourceTree = "<group>"; };
|
CE0C2AAA117700E700BC749F /* PyTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PyTable.h; sourceTree = "<group>"; };
|
||||||
CE0C46A90FA0647E000BE99B /* PictureBlocks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PictureBlocks.m; 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>"; };
|
||||||
|
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; };
|
||||||
|
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; };
|
||||||
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; name = dg_cocoa.plugin; path = dg_cocoa.plugin; sourceTree = SOURCE_ROOT; };
|
CE381CF509915304003581CE /* dg_cocoa.plugin */ = {isa = PBXFileReference; lastKnownFileType = folder; path = dg_cocoa.plugin; 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; };
|
||||||
@@ -92,12 +108,13 @@
|
|||||||
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>"; };
|
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>"; };
|
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>"; };
|
||||||
|
CE7AC9161119911200D02F6C /* progress.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = progress.xib; sourceTree = "<group>"; };
|
||||||
|
CE7AC9171119911200D02F6C /* registration.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = registration.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; };
|
||||||
CE80DB1C0FC192D60086DCA6 /* Dialogs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Dialogs.m; path = ../../cocoalib/Dialogs.m; sourceTree = SOURCE_ROOT; };
|
CE80DB1C0FC192D60086DCA6 /* Dialogs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Dialogs.m; path = ../../cocoalib/Dialogs.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE80DB1D0FC192D60086DCA6 /* HSErrorReportWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSErrorReportWindow.h; path = ../../cocoalib/HSErrorReportWindow.h; sourceTree = SOURCE_ROOT; };
|
CE80DB1D0FC192D60086DCA6 /* HSErrorReportWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSErrorReportWindow.h; path = ../../cocoalib/HSErrorReportWindow.h; sourceTree = SOURCE_ROOT; };
|
||||||
CE80DB1E0FC192D60086DCA6 /* HSErrorReportWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSErrorReportWindow.m; path = ../../cocoalib/HSErrorReportWindow.m; sourceTree = SOURCE_ROOT; };
|
CE80DB1E0FC192D60086DCA6 /* HSErrorReportWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSErrorReportWindow.m; path = ../../cocoalib/HSErrorReportWindow.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE80DB1F0FC192D60086DCA6 /* Outline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Outline.h; path = ../../cocoalib/Outline.h; sourceTree = SOURCE_ROOT; };
|
|
||||||
CE80DB200FC192D60086DCA6 /* Outline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Outline.m; path = ../../cocoalib/Outline.m; sourceTree = SOURCE_ROOT; };
|
|
||||||
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; };
|
||||||
@@ -105,8 +122,6 @@
|
|||||||
CE80DB250FC192D60086DCA6 /* RecentDirectories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RecentDirectories.m; path = ../../cocoalib/RecentDirectories.m; sourceTree = SOURCE_ROOT; };
|
CE80DB250FC192D60086DCA6 /* RecentDirectories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RecentDirectories.m; path = ../../cocoalib/RecentDirectories.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE80DB260FC192D60086DCA6 /* RegistrationInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegistrationInterface.h; path = ../../cocoalib/RegistrationInterface.h; sourceTree = SOURCE_ROOT; };
|
CE80DB260FC192D60086DCA6 /* RegistrationInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegistrationInterface.h; path = ../../cocoalib/RegistrationInterface.h; sourceTree = SOURCE_ROOT; };
|
||||||
CE80DB270FC192D60086DCA6 /* RegistrationInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RegistrationInterface.m; path = ../../cocoalib/RegistrationInterface.m; sourceTree = SOURCE_ROOT; };
|
CE80DB270FC192D60086DCA6 /* RegistrationInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RegistrationInterface.m; path = ../../cocoalib/RegistrationInterface.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE80DB280FC192D60086DCA6 /* Table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Table.h; path = ../../cocoalib/Table.h; sourceTree = SOURCE_ROOT; };
|
|
||||||
CE80DB290FC192D60086DCA6 /* Table.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Table.m; path = ../../cocoalib/Table.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; };
|
||||||
@@ -115,9 +130,6 @@
|
|||||||
CE80DB460FC193650086DCA6 /* NSNotificationAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NSNotificationAdditions.m; path = ../../cocoalib/NSNotificationAdditions.m; sourceTree = SOURCE_ROOT; };
|
CE80DB460FC193650086DCA6 /* NSNotificationAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NSNotificationAdditions.m; path = ../../cocoalib/NSNotificationAdditions.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE80DB480FC193770086DCA6 /* NSImageAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NSImageAdditions.h; path = ../../cocoalib/NSImageAdditions.h; sourceTree = SOURCE_ROOT; };
|
CE80DB480FC193770086DCA6 /* NSImageAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NSImageAdditions.h; path = ../../cocoalib/NSImageAdditions.h; sourceTree = SOURCE_ROOT; };
|
||||||
CE80DB490FC193770086DCA6 /* NSImageAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NSImageAdditions.m; path = ../../cocoalib/NSImageAdditions.m; sourceTree = SOURCE_ROOT; };
|
CE80DB490FC193770086DCA6 /* NSImageAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NSImageAdditions.m; path = ../../cocoalib/NSImageAdditions.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE80DB710FC194760086DCA6 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = ../../cocoalib/English.lproj/ErrorReportWindow.xib; sourceTree = SOURCE_ROOT; };
|
|
||||||
CE80DB730FC194760086DCA6 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = ../../cocoalib/English.lproj/progress.nib; sourceTree = SOURCE_ROOT; };
|
|
||||||
CE80DB750FC194760086DCA6 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = ../../cocoalib/English.lproj/registration.nib; sourceTree = SOURCE_ROOT; };
|
|
||||||
CE80DB820FC1951C0086DCA6 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = ../base/AppDelegate.h; sourceTree = SOURCE_ROOT; };
|
CE80DB820FC1951C0086DCA6 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = ../base/AppDelegate.h; sourceTree = SOURCE_ROOT; };
|
||||||
CE80DB830FC1951C0086DCA6 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = ../base/AppDelegate.m; sourceTree = SOURCE_ROOT; };
|
CE80DB830FC1951C0086DCA6 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = ../base/AppDelegate.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE80DB840FC1951C0086DCA6 /* Consts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Consts.h; path = ../base/Consts.h; sourceTree = SOURCE_ROOT; };
|
CE80DB840FC1951C0086DCA6 /* Consts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Consts.h; path = ../base/Consts.h; sourceTree = SOURCE_ROOT; };
|
||||||
@@ -127,6 +139,32 @@
|
|||||||
CE80DB880FC1951C0086DCA6 /* ResultWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ResultWindow.h; path = ../base/ResultWindow.h; sourceTree = SOURCE_ROOT; };
|
CE80DB880FC1951C0086DCA6 /* ResultWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ResultWindow.h; path = ../base/ResultWindow.h; sourceTree = SOURCE_ROOT; };
|
||||||
CE80DB890FC1951C0086DCA6 /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ResultWindow.m; path = ../base/ResultWindow.m; sourceTree = SOURCE_ROOT; };
|
CE80DB890FC1951C0086DCA6 /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ResultWindow.m; path = ../base/ResultWindow.m; 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>"; };
|
||||||
|
CE958658112C516400F95FD2 /* PyResultTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyResultTree.h; path = ../base/PyResultTree.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE958659112C516400F95FD2 /* PyStatsLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyStatsLabel.h; path = ../base/PyStatsLabel.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE95865A112C516400F95FD2 /* ResultOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ResultOutline.h; path = ../base/ResultOutline.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE95865B112C516400F95FD2 /* ResultOutline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ResultOutline.m; path = ../base/ResultOutline.m; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE95865C112C516400F95FD2 /* StatsLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StatsLabel.h; path = ../base/StatsLabel.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE95865D112C516400F95FD2 /* StatsLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = StatsLabel.m; path = ../base/StatsLabel.m; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE9EA7431122C96C008CD2BC /* HSGUIController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HSGUIController.h; sourceTree = "<group>"; };
|
||||||
|
CE9EA7441122C96C008CD2BC /* HSGUIController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSGUIController.m; sourceTree = "<group>"; };
|
||||||
|
CE9EA7451122C96C008CD2BC /* HSOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HSOutline.h; sourceTree = "<group>"; };
|
||||||
|
CE9EA7461122C96C008CD2BC /* HSOutline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSOutline.m; sourceTree = "<group>"; };
|
||||||
|
CE9EA7471122C96C008CD2BC /* HSWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HSWindowController.h; sourceTree = "<group>"; };
|
||||||
|
CE9EA7481122C96C008CD2BC /* HSWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSWindowController.m; sourceTree = "<group>"; };
|
||||||
|
CE9EA7491122C96C008CD2BC /* NSEventAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NSEventAdditions.h; path = ../../cocoalib/NSEventAdditions.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE9EA74A1122C96C008CD2BC /* NSEventAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NSEventAdditions.m; path = ../../cocoalib/NSEventAdditions.m; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE9EA74C1122C96C008CD2BC /* PyGUI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PyGUI.h; sourceTree = "<group>"; };
|
||||||
|
CE9EA74D1122C96C008CD2BC /* PyOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PyOutline.h; sourceTree = "<group>"; };
|
||||||
|
CE9EA74E1122C96C008CD2BC /* PyRegistrable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyRegistrable.h; path = ../../cocoalib/PyRegistrable.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE9EA7501122C96C008CD2BC /* HSOutlineView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HSOutlineView.h; sourceTree = "<group>"; };
|
||||||
|
CE9EA7511122C96C008CD2BC /* HSOutlineView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSOutlineView.m; sourceTree = "<group>"; };
|
||||||
|
CE9EA7521122C96C008CD2BC /* NSIndexPathAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSIndexPathAdditions.h; sourceTree = "<group>"; };
|
||||||
|
CE9EA7531122C96C008CD2BC /* NSIndexPathAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSIndexPathAdditions.m; sourceTree = "<group>"; };
|
||||||
|
CE9EA7541122C96C008CD2BC /* NSTableViewAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSTableViewAdditions.h; sourceTree = "<group>"; };
|
||||||
|
CE9EA7551122C96C008CD2BC /* NSTableViewAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSTableViewAdditions.m; sourceTree = "<group>"; };
|
||||||
|
CE9EA76F1122CA0B008CD2BC /* DirectoryOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DirectoryOutline.h; path = ../base/DirectoryOutline.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE9EA7701122CA0B008CD2BC /* DirectoryOutline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DirectoryOutline.m; path = ../base/DirectoryOutline.m; 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; };
|
||||||
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>"; };
|
||||||
@@ -152,11 +190,9 @@
|
|||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
080E96DDFE201D6D7F000001 /* Classes */ = {
|
080E96DDFE201D6D7F000001 /* DGPE */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
CE0C46A80FA0647E000BE99B /* PictureBlocks.h */,
|
|
||||||
CE0C46A90FA0647E000BE99B /* PictureBlocks.m */,
|
|
||||||
CE381C9509914ACE003581CE /* AppDelegate.h */,
|
CE381C9509914ACE003581CE /* AppDelegate.h */,
|
||||||
CE381C9409914ACE003581CE /* AppDelegate.m */,
|
CE381C9409914ACE003581CE /* AppDelegate.m */,
|
||||||
CE848A1809DD85810004CB44 /* Consts.h */,
|
CE848A1809DD85810004CB44 /* Consts.h */,
|
||||||
@@ -168,7 +204,7 @@
|
|||||||
CE381C9B09914ADF003581CE /* ResultWindow.h */,
|
CE381C9B09914ADF003581CE /* ResultWindow.h */,
|
||||||
CE381C9A09914ADF003581CE /* ResultWindow.m */,
|
CE381C9A09914ADF003581CE /* ResultWindow.m */,
|
||||||
);
|
);
|
||||||
name = Classes;
|
name = DGPE;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
|
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
|
||||||
@@ -201,7 +237,7 @@
|
|||||||
29B97314FDCFA39411CA2CEA /* dupeguru */ = {
|
29B97314FDCFA39411CA2CEA /* dupeguru */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
080E96DDFE201D6D7F000001 /* Classes */,
|
080E96DDFE201D6D7F000001 /* DGPE */,
|
||||||
CE80DB1A0FC192AB0086DCA6 /* cocoalib */,
|
CE80DB1A0FC192AB0086DCA6 /* cocoalib */,
|
||||||
CE80DB810FC194BD0086DCA6 /* dgbase */,
|
CE80DB810FC194BD0086DCA6 /* dgbase */,
|
||||||
29B97315FDCFA39411CA2CEA /* Other Sources */,
|
29B97315FDCFA39411CA2CEA /* Other Sources */,
|
||||||
@@ -250,36 +286,48 @@
|
|||||||
CE77C8A710946CE20078B0DB /* DetailsPanel.xib */,
|
CE77C8A710946CE20078B0DB /* DetailsPanel.xib */,
|
||||||
CE77C89C10946C6D0078B0DB /* DirectoryPanel.xib */,
|
CE77C89C10946C6D0078B0DB /* DirectoryPanel.xib */,
|
||||||
CE031750109B340A00517EE6 /* Preferences.xib */,
|
CE031750109B340A00517EE6 /* Preferences.xib */,
|
||||||
|
CE0C2AC71177021600BC749F /* ProblemDialog.xib */,
|
||||||
);
|
);
|
||||||
path = xib;
|
path = xib;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
CE7AC9141119911200D02F6C /* xib */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CE7AC9151119911200D02F6C /* ErrorReportWindow.xib */,
|
||||||
|
CE7AC9161119911200D02F6C /* progress.xib */,
|
||||||
|
CE7AC9171119911200D02F6C /* registration.xib */,
|
||||||
|
);
|
||||||
|
name = xib;
|
||||||
|
path = ../../cocoalib/xib;
|
||||||
|
sourceTree = SOURCE_ROOT;
|
||||||
|
};
|
||||||
CE80DB1A0FC192AB0086DCA6 /* cocoalib */ = {
|
CE80DB1A0FC192AB0086DCA6 /* cocoalib */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
CE9EA7421122C96C008CD2BC /* controllers */,
|
||||||
|
CE9EA74B1122C96C008CD2BC /* proxies */,
|
||||||
|
CE9EA74F1122C96C008CD2BC /* views */,
|
||||||
|
CE7AC9141119911200D02F6C /* xib */,
|
||||||
CEBAE4220FDA97E000B7887D /* brsinglelineformatter */,
|
CEBAE4220FDA97E000B7887D /* brsinglelineformatter */,
|
||||||
CE80DB700FC194760086DCA6 /* ErrorReportWindow.xib */,
|
|
||||||
CE80DB720FC194760086DCA6 /* progress.nib */,
|
|
||||||
CE80DB740FC194760086DCA6 /* registration.nib */,
|
|
||||||
CE80DB480FC193770086DCA6 /* NSImageAdditions.h */,
|
CE80DB480FC193770086DCA6 /* NSImageAdditions.h */,
|
||||||
CE80DB490FC193770086DCA6 /* NSImageAdditions.m */,
|
CE80DB490FC193770086DCA6 /* NSImageAdditions.m */,
|
||||||
CE80DB450FC193650086DCA6 /* NSNotificationAdditions.h */,
|
CE80DB450FC193650086DCA6 /* NSNotificationAdditions.h */,
|
||||||
CE80DB460FC193650086DCA6 /* NSNotificationAdditions.m */,
|
CE80DB460FC193650086DCA6 /* NSNotificationAdditions.m */,
|
||||||
|
CE9EA7491122C96C008CD2BC /* NSEventAdditions.h */,
|
||||||
|
CE9EA74A1122C96C008CD2BC /* NSEventAdditions.m */,
|
||||||
CE80DB1B0FC192D60086DCA6 /* Dialogs.h */,
|
CE80DB1B0FC192D60086DCA6 /* Dialogs.h */,
|
||||||
CE80DB1C0FC192D60086DCA6 /* Dialogs.m */,
|
CE80DB1C0FC192D60086DCA6 /* Dialogs.m */,
|
||||||
CE80DB1D0FC192D60086DCA6 /* HSErrorReportWindow.h */,
|
CE80DB1D0FC192D60086DCA6 /* HSErrorReportWindow.h */,
|
||||||
CE80DB1E0FC192D60086DCA6 /* HSErrorReportWindow.m */,
|
CE80DB1E0FC192D60086DCA6 /* HSErrorReportWindow.m */,
|
||||||
CE80DB1F0FC192D60086DCA6 /* Outline.h */,
|
|
||||||
CE80DB200FC192D60086DCA6 /* Outline.m */,
|
|
||||||
CE80DB210FC192D60086DCA6 /* ProgressController.h */,
|
CE80DB210FC192D60086DCA6 /* ProgressController.h */,
|
||||||
CE80DB220FC192D60086DCA6 /* ProgressController.m */,
|
CE80DB220FC192D60086DCA6 /* ProgressController.m */,
|
||||||
CE80DB230FC192D60086DCA6 /* PyApp.h */,
|
CE80DB230FC192D60086DCA6 /* PyApp.h */,
|
||||||
|
CE9EA74E1122C96C008CD2BC /* PyRegistrable.h */,
|
||||||
CE80DB240FC192D60086DCA6 /* RecentDirectories.h */,
|
CE80DB240FC192D60086DCA6 /* RecentDirectories.h */,
|
||||||
CE80DB250FC192D60086DCA6 /* RecentDirectories.m */,
|
CE80DB250FC192D60086DCA6 /* RecentDirectories.m */,
|
||||||
CE80DB260FC192D60086DCA6 /* RegistrationInterface.h */,
|
CE80DB260FC192D60086DCA6 /* RegistrationInterface.h */,
|
||||||
CE80DB270FC192D60086DCA6 /* RegistrationInterface.m */,
|
CE80DB270FC192D60086DCA6 /* RegistrationInterface.m */,
|
||||||
CE80DB280FC192D60086DCA6 /* Table.h */,
|
|
||||||
CE80DB290FC192D60086DCA6 /* Table.m */,
|
|
||||||
CE80DB2A0FC192D60086DCA6 /* Utils.h */,
|
CE80DB2A0FC192D60086DCA6 /* Utils.h */,
|
||||||
CE80DB2B0FC192D60086DCA6 /* Utils.m */,
|
CE80DB2B0FC192D60086DCA6 /* Utils.m */,
|
||||||
CE80DB2C0FC192D60086DCA6 /* ValueTransformers.h */,
|
CE80DB2C0FC192D60086DCA6 /* ValueTransformers.h */,
|
||||||
@@ -298,13 +346,67 @@
|
|||||||
CE6044EB0FE6796200B71262 /* DetailsPanel.m */,
|
CE6044EB0FE6796200B71262 /* DetailsPanel.m */,
|
||||||
CE80DB850FC1951C0086DCA6 /* DirectoryPanel.h */,
|
CE80DB850FC1951C0086DCA6 /* DirectoryPanel.h */,
|
||||||
CE80DB860FC1951C0086DCA6 /* DirectoryPanel.m */,
|
CE80DB860FC1951C0086DCA6 /* DirectoryPanel.m */,
|
||||||
CE80DB870FC1951C0086DCA6 /* PyDupeGuru.h */,
|
CE9EA76F1122CA0B008CD2BC /* DirectoryOutline.h */,
|
||||||
|
CE9EA7701122CA0B008CD2BC /* DirectoryOutline.m */,
|
||||||
|
CE0C2ABA1177014200BC749F /* ProblemDialog.h */,
|
||||||
|
CE0C2ABB1177014200BC749F /* ProblemDialog.m */,
|
||||||
CE80DB880FC1951C0086DCA6 /* ResultWindow.h */,
|
CE80DB880FC1951C0086DCA6 /* ResultWindow.h */,
|
||||||
CE80DB890FC1951C0086DCA6 /* ResultWindow.m */,
|
CE80DB890FC1951C0086DCA6 /* ResultWindow.m */,
|
||||||
|
CE958658112C516400F95FD2 /* PyResultTree.h */,
|
||||||
|
CE95865A112C516400F95FD2 /* ResultOutline.h */,
|
||||||
|
CE95865B112C516400F95FD2 /* ResultOutline.m */,
|
||||||
|
CE95865C112C516400F95FD2 /* StatsLabel.h */,
|
||||||
|
CE95865D112C516400F95FD2 /* StatsLabel.m */,
|
||||||
|
CE80DB870FC1951C0086DCA6 /* PyDupeGuru.h */,
|
||||||
|
CE18126F111C9D5100E49FCE /* PyDetailsPanel.h */,
|
||||||
|
CE9EA7711122CA0B008CD2BC /* PyDirectoryOutline.h */,
|
||||||
|
CE0C2ABC1177014200BC749F /* PyProblemDialog.h */,
|
||||||
|
CE958659112C516400F95FD2 /* PyStatsLabel.h */,
|
||||||
);
|
);
|
||||||
name = dgbase;
|
name = dgbase;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
CE9EA7421122C96C008CD2BC /* controllers */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CE9EA7431122C96C008CD2BC /* HSGUIController.h */,
|
||||||
|
CE9EA7441122C96C008CD2BC /* HSGUIController.m */,
|
||||||
|
CE9EA7451122C96C008CD2BC /* HSOutline.h */,
|
||||||
|
CE9EA7461122C96C008CD2BC /* HSOutline.m */,
|
||||||
|
CE0C2AB41177011000BC749F /* HSTable.h */,
|
||||||
|
CE0C2AB51177011000BC749F /* HSTable.m */,
|
||||||
|
CE9EA7471122C96C008CD2BC /* HSWindowController.h */,
|
||||||
|
CE9EA7481122C96C008CD2BC /* HSWindowController.m */,
|
||||||
|
);
|
||||||
|
name = controllers;
|
||||||
|
path = ../../cocoalib/controllers;
|
||||||
|
sourceTree = SOURCE_ROOT;
|
||||||
|
};
|
||||||
|
CE9EA74B1122C96C008CD2BC /* proxies */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CE9EA74C1122C96C008CD2BC /* PyGUI.h */,
|
||||||
|
CE9EA74D1122C96C008CD2BC /* PyOutline.h */,
|
||||||
|
CE0C2AAA117700E700BC749F /* PyTable.h */,
|
||||||
|
);
|
||||||
|
name = proxies;
|
||||||
|
path = ../../cocoalib/proxies;
|
||||||
|
sourceTree = SOURCE_ROOT;
|
||||||
|
};
|
||||||
|
CE9EA74F1122C96C008CD2BC /* views */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CE9EA7501122C96C008CD2BC /* HSOutlineView.h */,
|
||||||
|
CE9EA7511122C96C008CD2BC /* HSOutlineView.m */,
|
||||||
|
CE9EA7521122C96C008CD2BC /* NSIndexPathAdditions.h */,
|
||||||
|
CE9EA7531122C96C008CD2BC /* NSIndexPathAdditions.m */,
|
||||||
|
CE9EA7541122C96C008CD2BC /* NSTableViewAdditions.h */,
|
||||||
|
CE9EA7551122C96C008CD2BC /* NSTableViewAdditions.m */,
|
||||||
|
);
|
||||||
|
name = views;
|
||||||
|
path = ../../cocoalib/views;
|
||||||
|
sourceTree = SOURCE_ROOT;
|
||||||
|
};
|
||||||
CEBAE4220FDA97E000B7887D /* brsinglelineformatter */ = {
|
CEBAE4220FDA97E000B7887D /* brsinglelineformatter */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -377,14 +479,15 @@
|
|||||||
CEFC295509C89FF200D9F998 /* details32.png in Resources */,
|
CEFC295509C89FF200D9F998 /* details32.png in Resources */,
|
||||||
CEFC295609C89FF200D9F998 /* preferences32.png in Resources */,
|
CEFC295609C89FF200D9F998 /* preferences32.png in Resources */,
|
||||||
CEFCDE2D0AB0418600C33A93 /* dgpe_logo_32.png in Resources */,
|
CEFCDE2D0AB0418600C33A93 /* dgpe_logo_32.png in Resources */,
|
||||||
CE80DB760FC194760086DCA6 /* ErrorReportWindow.xib in Resources */,
|
|
||||||
CE80DB770FC194760086DCA6 /* progress.nib in Resources */,
|
|
||||||
CE80DB780FC194760086DCA6 /* registration.nib in Resources */,
|
|
||||||
CE6E0F3D1054EC62008D9390 /* dsa_pub.pem in Resources */,
|
CE6E0F3D1054EC62008D9390 /* dsa_pub.pem in Resources */,
|
||||||
CE77C89E10946C6D0078B0DB /* DirectoryPanel.xib in Resources */,
|
CE77C89E10946C6D0078B0DB /* DirectoryPanel.xib in Resources */,
|
||||||
CE77C8A810946CE20078B0DB /* DetailsPanel.xib in Resources */,
|
CE77C8A810946CE20078B0DB /* DetailsPanel.xib in Resources */,
|
||||||
CE031751109B340A00517EE6 /* Preferences.xib in Resources */,
|
CE031751109B340A00517EE6 /* Preferences.xib in Resources */,
|
||||||
CE031754109B345200517EE6 /* MainMenu.xib in Resources */,
|
CE031754109B345200517EE6 /* MainMenu.xib in Resources */,
|
||||||
|
CE7AC9181119911200D02F6C /* ErrorReportWindow.xib in Resources */,
|
||||||
|
CE7AC9191119911200D02F6C /* progress.xib in Resources */,
|
||||||
|
CE7AC91A1119911200D02F6C /* registration.xib in Resources */,
|
||||||
|
CE0C2AC81177021600BC749F /* ProblemDialog.xib in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -400,14 +503,11 @@
|
|||||||
CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */,
|
CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */,
|
||||||
CE68EE6809ABC48000971085 /* DirectoryPanel.m in Sources */,
|
CE68EE6809ABC48000971085 /* DirectoryPanel.m in Sources */,
|
||||||
CECA899D09DB132E00A3D774 /* DetailsPanel.m in Sources */,
|
CECA899D09DB132E00A3D774 /* DetailsPanel.m in Sources */,
|
||||||
CE0C46AA0FA0647E000BE99B /* PictureBlocks.m in Sources */,
|
|
||||||
CE80DB2E0FC192D60086DCA6 /* Dialogs.m in Sources */,
|
CE80DB2E0FC192D60086DCA6 /* Dialogs.m in Sources */,
|
||||||
CE80DB2F0FC192D60086DCA6 /* HSErrorReportWindow.m in Sources */,
|
CE80DB2F0FC192D60086DCA6 /* HSErrorReportWindow.m in Sources */,
|
||||||
CE80DB300FC192D60086DCA6 /* Outline.m in Sources */,
|
|
||||||
CE80DB310FC192D60086DCA6 /* ProgressController.m in Sources */,
|
CE80DB310FC192D60086DCA6 /* ProgressController.m in Sources */,
|
||||||
CE80DB320FC192D60086DCA6 /* RecentDirectories.m in Sources */,
|
CE80DB320FC192D60086DCA6 /* RecentDirectories.m in Sources */,
|
||||||
CE80DB330FC192D60086DCA6 /* RegistrationInterface.m in Sources */,
|
CE80DB330FC192D60086DCA6 /* RegistrationInterface.m in Sources */,
|
||||||
CE80DB340FC192D60086DCA6 /* Table.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 */,
|
||||||
@@ -417,71 +517,72 @@
|
|||||||
CE80DB8C0FC1951C0086DCA6 /* ResultWindow.m in Sources */,
|
CE80DB8C0FC1951C0086DCA6 /* ResultWindow.m in Sources */,
|
||||||
CEBAE4270FDA97E000B7887D /* BRSingleLineFormatter.m in Sources */,
|
CEBAE4270FDA97E000B7887D /* BRSingleLineFormatter.m in Sources */,
|
||||||
CE6044EC0FE6796200B71262 /* DetailsPanel.m in Sources */,
|
CE6044EC0FE6796200B71262 /* DetailsPanel.m in Sources */,
|
||||||
|
CE9EA7561122C96C008CD2BC /* HSGUIController.m in Sources */,
|
||||||
|
CE9EA7571122C96C008CD2BC /* HSOutline.m in Sources */,
|
||||||
|
CE9EA7581122C96C008CD2BC /* HSWindowController.m in Sources */,
|
||||||
|
CE9EA7591122C96C008CD2BC /* NSEventAdditions.m in Sources */,
|
||||||
|
CE9EA75A1122C96C008CD2BC /* HSOutlineView.m in Sources */,
|
||||||
|
CE9EA75B1122C96C008CD2BC /* NSIndexPathAdditions.m in Sources */,
|
||||||
|
CE9EA75C1122C96C008CD2BC /* NSTableViewAdditions.m in Sources */,
|
||||||
|
CE9EA7721122CA0B008CD2BC /* DirectoryOutline.m in Sources */,
|
||||||
|
CE95865E112C516400F95FD2 /* ResultOutline.m in Sources */,
|
||||||
|
CE95865F112C516400F95FD2 /* StatsLabel.m in Sources */,
|
||||||
|
CE0C2AB61177011000BC749F /* HSTable.m in Sources */,
|
||||||
|
CE0C2ABD1177014200BC749F /* ProblemDialog.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
|
||||||
CE80DB700FC194760086DCA6 /* ErrorReportWindow.xib */ = {
|
|
||||||
isa = PBXVariantGroup;
|
|
||||||
children = (
|
|
||||||
CE80DB710FC194760086DCA6 /* English */,
|
|
||||||
);
|
|
||||||
name = ErrorReportWindow.xib;
|
|
||||||
sourceTree = SOURCE_ROOT;
|
|
||||||
};
|
|
||||||
CE80DB720FC194760086DCA6 /* progress.nib */ = {
|
|
||||||
isa = PBXVariantGroup;
|
|
||||||
children = (
|
|
||||||
CE80DB730FC194760086DCA6 /* English */,
|
|
||||||
);
|
|
||||||
name = progress.nib;
|
|
||||||
sourceTree = SOURCE_ROOT;
|
|
||||||
};
|
|
||||||
CE80DB740FC194760086DCA6 /* registration.nib */ = {
|
|
||||||
isa = PBXVariantGroup;
|
|
||||||
children = (
|
|
||||||
CE80DB750FC194760086DCA6 /* English */,
|
|
||||||
);
|
|
||||||
name = registration.nib;
|
|
||||||
sourceTree = SOURCE_ROOT;
|
|
||||||
};
|
|
||||||
/* End PBXVariantGroup section */
|
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
C01FCF4C08A954540054247B /* Release */ = {
|
C01FCF4C08A954540054247B /* release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ARCHS = (
|
|
||||||
ppc,
|
|
||||||
i386,
|
|
||||||
);
|
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
|
||||||
"$(FRAMEWORK_SEARCH_PATHS)",
|
|
||||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
|
|
||||||
);
|
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||||
GCC_MODEL_TUNING = G5;
|
|
||||||
INFOPLIST_FILE = Info.plist;
|
INFOPLIST_FILE = Info.plist;
|
||||||
INSTALL_PATH = "$(HOME)/Applications";
|
INSTALL_PATH = "$(HOME)/Applications";
|
||||||
PRODUCT_NAME = "dupeGuru PE";
|
PRODUCT_NAME = "dupeGuru PE";
|
||||||
WRAPPER_EXTENSION = app;
|
WRAPPER_EXTENSION = app;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = release;
|
||||||
};
|
};
|
||||||
C01FCF5008A954540054247B /* Release */ = {
|
C01FCF5008A954540054247B /* release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)";
|
ARCHS = (
|
||||||
ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386";
|
i386,
|
||||||
|
x86_64,
|
||||||
|
ppc,
|
||||||
|
);
|
||||||
GCC_C_LANGUAGE_STANDARD = c99;
|
GCC_C_LANGUAGE_STANDARD = c99;
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.5;
|
MACOSX_DEPLOYMENT_TARGET = 10.5;
|
||||||
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
|
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = release;
|
||||||
|
};
|
||||||
|
CEE00FF0111AF37400BC1A77 /* dev */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
|
||||||
|
GCC_C_LANGUAGE_STANDARD = c99;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.5;
|
||||||
|
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
|
||||||
|
};
|
||||||
|
name = dev;
|
||||||
|
};
|
||||||
|
CEE00FF1111AF37400BC1A77 /* dev */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
INFOPLIST_FILE = Info.plist;
|
||||||
|
INSTALL_PATH = "$(HOME)/Applications";
|
||||||
|
PRODUCT_NAME = "dupeGuru PE";
|
||||||
|
WRAPPER_EXTENSION = app;
|
||||||
|
};
|
||||||
|
name = dev;
|
||||||
};
|
};
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
@@ -489,18 +590,20 @@
|
|||||||
C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "dupeguru" */ = {
|
C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "dupeguru" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
C01FCF4C08A954540054247B /* Release */,
|
C01FCF4C08A954540054247B /* release */,
|
||||||
|
CEE00FF1111AF37400BC1A77 /* dev */,
|
||||||
);
|
);
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = release;
|
||||||
};
|
};
|
||||||
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */ = {
|
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
C01FCF5008A954540054247B /* Release */,
|
C01FCF5008A954540054247B /* release */,
|
||||||
|
CEE00FF0111AF37400BC1A77 /* dev */,
|
||||||
);
|
);
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = release;
|
||||||
};
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,10 +7,12 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import "Utils.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
[Utils setPluginName:@"dg_cocoa"];
|
||||||
NSString *pluginPath = [[NSBundle mainBundle]
|
NSString *pluginPath = [[NSBundle mainBundle]
|
||||||
pathForResource:@"dg_cocoa"
|
pathForResource:@"dg_cocoa"
|
||||||
ofType:@"plugin"];
|
ofType:@"plugin"];
|
||||||
|
|||||||
@@ -2,17 +2,17 @@
|
|||||||
<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">10B504</string>
|
<string key="IBDocument.SystemVersion">10C540</string>
|
||||||
<string key="IBDocument.InterfaceBuilderVersion">740</string>
|
<string key="IBDocument.InterfaceBuilderVersion">740</string>
|
||||||
<string key="IBDocument.AppKitVersion">1038.2</string>
|
<string key="IBDocument.AppKitVersion">1038.25</string>
|
||||||
<string key="IBDocument.HIToolboxVersion">437.00</string>
|
<string key="IBDocument.HIToolboxVersion">458.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">740</string>
|
<string key="NS.object.0">740</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>
|
||||||
<integer value="18"/>
|
<integer value="7"/>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSArray" key="IBDocument.PluginDependencies">
|
<object class="NSArray" key="IBDocument.PluginDependencies">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
<object class="NSMutableArray" key="IBDocument.RootObjects" id="433298071">
|
<object class="NSMutableArray" key="IBDocument.RootObjects" id="433298071">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
<object class="NSCustomObject" id="449950342">
|
<object class="NSCustomObject" id="449950342">
|
||||||
<string key="NSClassName">DetailsPanel</string>
|
<string key="NSClassName">DetailsPanelPE</string>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSCustomObject" id="175405098">
|
<object class="NSCustomObject" id="175405098">
|
||||||
<string key="NSClassName">FirstResponder</string>
|
<string key="NSClassName">FirstResponder</string>
|
||||||
@@ -487,6 +487,14 @@
|
|||||||
</object>
|
</object>
|
||||||
<int key="connectionID">31</int>
|
<int key="connectionID">31</int>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="IBConnectionRecord">
|
||||||
|
<object class="IBOutletConnection" key="connection">
|
||||||
|
<string key="label">dataSource</string>
|
||||||
|
<reference key="source" ref="1061505056"/>
|
||||||
|
<reference key="destination" ref="449950342"/>
|
||||||
|
</object>
|
||||||
|
<int key="connectionID">43</int>
|
||||||
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||||
<object class="NSArray" key="orderedObjects">
|
<object class="NSArray" key="orderedObjects">
|
||||||
@@ -768,7 +776,6 @@
|
|||||||
<string>6.ImportedFromIB2</string>
|
<string>6.ImportedFromIB2</string>
|
||||||
<string>7.IBPluginDependency</string>
|
<string>7.IBPluginDependency</string>
|
||||||
<string>7.ImportedFromIB2</string>
|
<string>7.ImportedFromIB2</string>
|
||||||
<string>8.CustomClassName</string>
|
|
||||||
<string>8.IBPluginDependency</string>
|
<string>8.IBPluginDependency</string>
|
||||||
<string>8.ImportedFromIB2</string>
|
<string>8.ImportedFromIB2</string>
|
||||||
<string>9.IBPluginDependency</string>
|
<string>9.IBPluginDependency</string>
|
||||||
@@ -825,7 +832,6 @@
|
|||||||
<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>TableView</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>
|
||||||
@@ -848,14 +854,26 @@
|
|||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<nil key="sourceID"/>
|
<nil key="sourceID"/>
|
||||||
<int key="maxID">42</int>
|
<int key="maxID">43</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">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
<string key="className">DetailsPanel</string>
|
<string key="className">DetailsPanel</string>
|
||||||
<string key="superclassName">DetailsPanelBase</string>
|
<string key="superclassName">NSWindowController</string>
|
||||||
|
<object class="NSMutableDictionary" key="outlets">
|
||||||
|
<string key="NS.key.0">detailsTable</string>
|
||||||
|
<string key="NS.object.0">NSTableView</string>
|
||||||
|
</object>
|
||||||
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
|
<string key="majorKey">IBProjectSource</string>
|
||||||
|
<string key="minorKey">../base/DetailsPanel.h</string>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="IBPartialClassDescription">
|
||||||
|
<string key="className">DetailsPanelPE</string>
|
||||||
|
<string key="superclassName">DetailsPanel</string>
|
||||||
<object class="NSMutableDictionary" key="outlets">
|
<object class="NSMutableDictionary" key="outlets">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
<object class="NSArray" key="dict.sortedKeys">
|
<object class="NSArray" key="dict.sortedKeys">
|
||||||
@@ -879,8 +897,8 @@
|
|||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
<string key="className">DetailsPanel</string>
|
<string key="className">DetailsPanelPE</string>
|
||||||
<string key="superclassName">DetailsPanelBase</string>
|
<string key="superclassName">DetailsPanel</string>
|
||||||
<object class="NSMutableDictionary" key="outlets">
|
<object class="NSMutableDictionary" key="outlets">
|
||||||
<string key="NS.key.0">detailsTable</string>
|
<string key="NS.key.0">detailsTable</string>
|
||||||
<string key="NS.object.0">NSTableView</string>
|
<string key="NS.object.0">NSTableView</string>
|
||||||
@@ -890,18 +908,6 @@
|
|||||||
<string key="minorKey"/>
|
<string key="minorKey"/>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
|
||||||
<string key="className">DetailsPanelBase</string>
|
|
||||||
<string key="superclassName">NSWindowController</string>
|
|
||||||
<object class="NSMutableDictionary" key="outlets">
|
|
||||||
<string key="NS.key.0">detailsTable</string>
|
|
||||||
<string key="NS.object.0">TableView</string>
|
|
||||||
</object>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBProjectSource</string>
|
|
||||||
<string key="minorKey">dgbase/DetailsPanel.h</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBPartialClassDescription">
|
<object class="IBPartialClassDescription">
|
||||||
<string key="className">FirstResponder</string>
|
<string key="className">FirstResponder</string>
|
||||||
<string key="superclassName">NSObject</string>
|
<string key="superclassName">NSObject</string>
|
||||||
@@ -910,34 +916,6 @@
|
|||||||
<string key="minorKey"/>
|
<string key="minorKey"/>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBPartialClassDescription">
|
|
||||||
<string key="className">PyApp</string>
|
|
||||||
<string key="superclassName">PyRegistrable</string>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBProjectSource</string>
|
|
||||||
<string key="minorKey">cocoalib/PyApp.h</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBPartialClassDescription">
|
|
||||||
<string key="className">TableView</string>
|
|
||||||
<string key="superclassName">NSTableView</string>
|
|
||||||
<object class="NSMutableDictionary" key="outlets">
|
|
||||||
<string key="NS.key.0">py</string>
|
|
||||||
<string key="NS.object.0">PyApp</string>
|
|
||||||
</object>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBProjectSource</string>
|
|
||||||
<string key="minorKey">cocoalib/Table.h</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBPartialClassDescription">
|
|
||||||
<string key="className">TableView</string>
|
|
||||||
<string key="superclassName">NSTableView</string>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBUserSource</string>
|
|
||||||
<string key="minorKey"/>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
</object>
|
</object>
|
||||||
<object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
|
<object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -8,16 +8,11 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "../base/AppDelegate.h"
|
#import "../base/AppDelegate.h"
|
||||||
#import "DirectoryPanel.h"
|
|
||||||
#import "PyDupeGuru.h"
|
#import "PyDupeGuru.h"
|
||||||
|
|
||||||
@interface AppDelegate : AppDelegateBase
|
@interface AppDelegate : AppDelegateBase {}
|
||||||
{
|
|
||||||
DirectoryPanel *_directoryPanel;
|
|
||||||
}
|
|
||||||
- (IBAction)openWebsite:(id)sender;
|
- (IBAction)openWebsite:(id)sender;
|
||||||
- (IBAction)toggleDirectories:(id)sender;
|
- (IBAction)toggleDirectories:(id)sender;
|
||||||
|
|
||||||
- (DirectoryPanel *)directoryPanel;
|
|
||||||
- (PyDupeGuru *)py;
|
- (PyDupeGuru *)py;
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
#import "../../cocoalib/Utils.h"
|
#import "../../cocoalib/Utils.h"
|
||||||
#import "../../cocoalib/ValueTransformers.h"
|
#import "../../cocoalib/ValueTransformers.h"
|
||||||
#import "DetailsPanel.h"
|
#import "DetailsPanel.h"
|
||||||
|
#import "DirectoryPanel.h"
|
||||||
#import "Consts.h"
|
#import "Consts.h"
|
||||||
|
|
||||||
@implementation AppDelegate
|
@implementation AppDelegate
|
||||||
@@ -56,52 +57,5 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[[self directoryPanel] toggleVisible:sender];
|
[[self directoryPanel] toggleVisible:sender];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (DirectoryPanel *)directoryPanel
|
|
||||||
{
|
|
||||||
if (!_directoryPanel)
|
|
||||||
_directoryPanel = [[DirectoryPanel alloc] initWithParentApp:self];
|
|
||||||
return _directoryPanel;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (DetailsPanelBase *)detailsPanel
|
|
||||||
{
|
|
||||||
if (!_detailsPanel)
|
|
||||||
_detailsPanel = [[DetailsPanel alloc] initWithPy:py];
|
|
||||||
return _detailsPanel;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (PyDupeGuru *)py { return (PyDupeGuru *)py; }
|
- (PyDupeGuru *)py { return (PyDupeGuru *)py; }
|
||||||
|
|
||||||
//Delegate
|
|
||||||
- (void)applicationWillBecomeActive:(NSNotification *)aNotification
|
|
||||||
{
|
|
||||||
if (![[result window] isVisible])
|
|
||||||
[result showWindow:NSApp];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)applicationWillTerminate:(NSNotification *)aNotification
|
|
||||||
{
|
|
||||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
|
||||||
[ud setObject: [result getColumnsOrder] forKey:@"columnsOrder"];
|
|
||||||
[ud setObject: [result getColumnsWidth] forKey:@"columnsWidth"];
|
|
||||||
[py saveResults];
|
|
||||||
int sc = [ud integerForKey:@"sessionCountSinceLastIgnorePurge"];
|
|
||||||
if (sc >= 10)
|
|
||||||
{
|
|
||||||
sc = -1;
|
|
||||||
[py purgeIgnoreList];
|
|
||||||
}
|
|
||||||
sc++;
|
|
||||||
[ud setInteger:sc forKey:@"sessionCountSinceLastIgnorePurge"];
|
|
||||||
[py saveIgnoreList];
|
|
||||||
// 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
|
|
||||||
// But I need to release RecentDirectories so it saves the user defaults
|
|
||||||
[recentDirectories release];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)recentDirecoryClicked:(NSString *)directory
|
|
||||||
{
|
|
||||||
[[self directoryPanel] addDirectory:directory];
|
|
||||||
}
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
|
||||||
which should be included with this package. The terms are also available at
|
|
||||||
http://www.hardcoded.net/licenses/hs_license
|
|
||||||
*/
|
|
||||||
|
|
||||||
#import "DirectoryPanel.h"
|
|
||||||
|
|
||||||
@implementation DirectoryPanel
|
|
||||||
@end
|
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>hsft</string>
|
<string>hsft</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>2.9.1</string>
|
<string>2.10.1</string>
|
||||||
<key>NSMainNibFile</key>
|
<key>NSMainNibFile</key>
|
||||||
<string>MainMenu</string>
|
<string>MainMenu</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
|
|||||||
@@ -7,32 +7,13 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "../../cocoalib/Outline.h"
|
|
||||||
#import "../base/ResultWindow.h"
|
#import "../base/ResultWindow.h"
|
||||||
#import "DirectoryPanel.h"
|
#import "DirectoryPanel.h"
|
||||||
|
|
||||||
@interface ResultWindow : ResultWindowBase
|
@interface ResultWindow : ResultWindowBase
|
||||||
{
|
{
|
||||||
IBOutlet NSSearchField *filterField;
|
|
||||||
|
|
||||||
NSString *_lastAction;
|
NSString *_lastAction;
|
||||||
NSMutableIndexSet *_deltaColumns;
|
|
||||||
}
|
}
|
||||||
- (IBAction)clearIgnoreList:(id)sender;
|
|
||||||
- (IBAction)filter:(id)sender;
|
|
||||||
- (IBAction)ignoreSelected:(id)sender;
|
|
||||||
- (IBAction)markAll:(id)sender;
|
|
||||||
- (IBAction)markInvert:(id)sender;
|
|
||||||
- (IBAction)markNone:(id)sender;
|
|
||||||
- (IBAction)markSelected:(id)sender;
|
|
||||||
- (IBAction)markToggle:(id)sender;
|
|
||||||
- (IBAction)openSelected:(id)sender;
|
|
||||||
- (IBAction)refresh:(id)sender;
|
|
||||||
- (IBAction)removeMarked:(id)sender;
|
|
||||||
- (IBAction)removeSelected:(id)sender;
|
|
||||||
- (IBAction)renameSelected:(id)sender;
|
|
||||||
- (IBAction)resetColumnsToDefault:(id)sender;
|
- (IBAction)resetColumnsToDefault:(id)sender;
|
||||||
- (IBAction)revealSelected:(id)sender;
|
|
||||||
- (IBAction)startDuplicateScan:(id)sender;
|
- (IBAction)startDuplicateScan:(id)sender;
|
||||||
- (IBAction)toggleDelta:(id)sender;
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -18,125 +18,12 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
- (void)awakeFromNib
|
- (void)awakeFromNib
|
||||||
{
|
{
|
||||||
[super awakeFromNib];
|
[super awakeFromNib];
|
||||||
_displayDelta = NO;
|
NSMutableIndexSet *deltaColumns = [NSMutableIndexSet indexSetWithIndexesInRange:NSMakeRange(2,4)];
|
||||||
_powerMode = NO;
|
[deltaColumns removeIndex:3];
|
||||||
_deltaColumns = [[NSMutableIndexSet indexSetWithIndexesInRange:NSMakeRange(2,4)] retain];
|
[outline setDeltaColumns:deltaColumns];
|
||||||
[_deltaColumns removeIndex:3];
|
|
||||||
[deltaSwitch setSelectedSegment:0];
|
|
||||||
[pmSwitch setSelectedSegment:0];
|
|
||||||
[py setDisplayDeltaValues:b2n(_displayDelta)];
|
|
||||||
[matches setTarget:self];
|
|
||||||
[matches setDoubleAction:@selector(openSelected:)];
|
|
||||||
[self refreshStats];
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resultsMarkingChanged:) name:ResultsMarkingChangedNotification object:nil];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Actions */
|
/* Actions */
|
||||||
- (IBAction)clearIgnoreList:(id)sender
|
|
||||||
{
|
|
||||||
int i = n2i([py getIgnoreListCount]);
|
|
||||||
if (!i)
|
|
||||||
return;
|
|
||||||
if ([Dialogs askYesNo:[NSString stringWithFormat:@"Do you really want to remove all %d items from the ignore list?",i]] == NSAlertSecondButtonReturn) // NO
|
|
||||||
return;
|
|
||||||
[py clearIgnoreList];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)filter:(id)sender
|
|
||||||
{
|
|
||||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
|
||||||
[py setEscapeFilterRegexp:b2n(!n2b([ud objectForKey:@"useRegexpFilter"]))];
|
|
||||||
[py applyFilter:[filterField stringValue]];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)ignoreSelected:(id)sender
|
|
||||||
{
|
|
||||||
NSArray *nodeList = [self getSelected:YES];
|
|
||||||
if (![nodeList count])
|
|
||||||
return;
|
|
||||||
if ([Dialogs askYesNo:[NSString stringWithFormat:@"All selected %d matches are going to be ignored in all subsequent scans. Continue?",[nodeList count]]] == NSAlertSecondButtonReturn) // NO
|
|
||||||
return;
|
|
||||||
[self performPySelection:[self getSelectedPaths:YES]];
|
|
||||||
[py addSelectedToIgnoreList];
|
|
||||||
[py removeSelected];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)markAll:(id)sender
|
|
||||||
{
|
|
||||||
[py markAll];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)markInvert:(id)sender
|
|
||||||
{
|
|
||||||
[py markInvert];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)markNone:(id)sender
|
|
||||||
{
|
|
||||||
[py markNone];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)markSelected:(id)sender
|
|
||||||
{
|
|
||||||
[self performPySelection:[self getSelectedPaths:YES]];
|
|
||||||
[py toggleSelectedMark];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)markToggle:(id)sender
|
|
||||||
{
|
|
||||||
OVNode *node = [matches itemAtRow:[matches clickedRow]];
|
|
||||||
[self performPySelection:[NSArray arrayWithObject:p2a([node indexPath])]];
|
|
||||||
[py toggleSelectedMark];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsMarkingChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)openSelected:(id)sender
|
|
||||||
{
|
|
||||||
[self performPySelection:[self getSelectedPaths:NO]];
|
|
||||||
[py openSelected];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)refresh:(id)sender
|
|
||||||
{
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)removeMarked:(id)sender
|
|
||||||
{
|
|
||||||
int mark_count = [[py getMarkCount] intValue];
|
|
||||||
if (!mark_count)
|
|
||||||
return;
|
|
||||||
if ([Dialogs askYesNo:[NSString stringWithFormat:@"You are about to remove %d files from results. Continue?",mark_count]] == NSAlertSecondButtonReturn) // NO
|
|
||||||
return;
|
|
||||||
[py removeMarked];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)removeSelected:(id)sender
|
|
||||||
{
|
|
||||||
NSArray *nodeList = [self getSelected:YES];
|
|
||||||
if (![nodeList count])
|
|
||||||
return;
|
|
||||||
if ([Dialogs askYesNo:[NSString stringWithFormat:@"You are about to remove %d files from results. Continue?",[nodeList count]]] == NSAlertSecondButtonReturn) // NO
|
|
||||||
return;
|
|
||||||
[self performPySelection:[self getSelectedPaths:YES]];
|
|
||||||
[py removeSelected];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:ResultsChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)renameSelected:(id)sender
|
|
||||||
{
|
|
||||||
int col = [matches columnWithIdentifier:@"0"];
|
|
||||||
int row = [matches selectedRow];
|
|
||||||
[matches editColumn:col row:row withEvent:[NSApp currentEvent] select:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)resetColumnsToDefault:(id)sender
|
- (IBAction)resetColumnsToDefault:(id)sender
|
||||||
{
|
{
|
||||||
NSMutableArray *columnsOrder = [NSMutableArray array];
|
NSMutableArray *columnsOrder = [NSMutableArray array];
|
||||||
@@ -152,12 +39,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[self restoreColumnsPosition:columnsOrder widths:columnsWidth];
|
[self restoreColumnsPosition:columnsOrder widths:columnsWidth];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)revealSelected:(id)sender
|
|
||||||
{
|
|
||||||
[self performPySelection:[self getSelectedPaths:NO]];
|
|
||||||
[py revealSelected];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)startDuplicateScan:(id)sender
|
- (IBAction)startDuplicateScan:(id)sender
|
||||||
{
|
{
|
||||||
if ([matches numberOfRows] > 0)
|
if ([matches numberOfRows] > 0)
|
||||||
@@ -176,8 +57,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
int sizeThreshold = [ud boolForKey:@"ignoreSmallFiles"] ? smallFileThreshold * 1024 : 0; // The py side wants bytes
|
int sizeThreshold = [ud boolForKey:@"ignoreSmallFiles"] ? smallFileThreshold * 1024 : 0; // The py side wants bytes
|
||||||
[_py setSizeThreshold:sizeThreshold];
|
[_py setSizeThreshold:sizeThreshold];
|
||||||
int r = n2i([py doScan]);
|
int r = n2i([py doScan]);
|
||||||
[matches reloadData];
|
|
||||||
[self refreshStats];
|
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
[[ProgressController mainProgressController] hide];
|
[[ProgressController mainProgressController] hide];
|
||||||
if (r == 1)
|
if (r == 1)
|
||||||
@@ -190,15 +69,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)toggleDelta:(id)sender
|
|
||||||
{
|
|
||||||
if ([deltaSwitch selectedSegment] == 1)
|
|
||||||
[deltaSwitch setSelectedSegment:0];
|
|
||||||
else
|
|
||||||
[deltaSwitch setSelectedSegment:1];
|
|
||||||
[self changeDelta:sender];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Public */
|
/* Public */
|
||||||
- (void)initResultColumns
|
- (void)initResultColumns
|
||||||
{
|
{
|
||||||
@@ -216,43 +86,4 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[_resultColumns addObject:[self getColumnForIdentifier:7 title:@"Words Used" width:120 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:7 title:@"Words Used" width:120 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:8 title:@"Dupe Count" width:80 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:8 title:@"Dupe Count" width:80 refCol:refCol]];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delegate */
|
|
||||||
- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
|
|
||||||
{
|
|
||||||
OVNode *node = item;
|
|
||||||
if ([[tableColumn identifier] isEqual:@"mark"])
|
|
||||||
{
|
|
||||||
[cell setEnabled: [node isMarkable]];
|
|
||||||
}
|
|
||||||
if ([cell isKindOfClass:[NSTextFieldCell class]])
|
|
||||||
{
|
|
||||||
// Determine if the text color will be blue due to directory being reference.
|
|
||||||
NSTextFieldCell *textCell = cell;
|
|
||||||
if ([node isMarkable])
|
|
||||||
[textCell setTextColor:[NSColor blackColor]];
|
|
||||||
else
|
|
||||||
[textCell setTextColor:[NSColor blueColor]];
|
|
||||||
if ((_displayDelta) && (_powerMode || ([node level] > 1)))
|
|
||||||
{
|
|
||||||
int i = [[tableColumn identifier] intValue];
|
|
||||||
if ([_deltaColumns containsIndex:i])
|
|
||||||
[textCell setTextColor:[NSColor orangeColor]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Notifications */
|
|
||||||
- (void)outlineViewSelectionDidChange:(NSNotification *)notification
|
|
||||||
{
|
|
||||||
[self performPySelection:[self getSelectedPaths:NO]];
|
|
||||||
[py refreshDetailsWithSelected];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:DuplicateSelectionChangedNotification object:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)resultsMarkingChanged:(NSNotification *)aNotification
|
|
||||||
{
|
|
||||||
[matches invalidateMarkings];
|
|
||||||
[self refreshStats];
|
|
||||||
}
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -4,170 +4,30 @@
|
|||||||
# 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/hs_license
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
import objc
|
from hscommon.cocoa import signature
|
||||||
from Foundation import NSObject
|
|
||||||
|
|
||||||
from core_se.app_cocoa import DupeGuru
|
|
||||||
from core import scanner
|
from core import scanner
|
||||||
|
from core.app_cocoa_inter import PyDupeGuruBase, PyDetailsPanel
|
||||||
|
from core_se.app_cocoa import DupeGuru
|
||||||
|
|
||||||
# Fix py2app imports with chokes on relative imports
|
# Fix py2app imports with chokes on relative imports and other stuff
|
||||||
from core_se import fs, data
|
from core_se import fs, data
|
||||||
from core import app, app_cocoa, data, directories, engine, export, ignore, results, fs
|
from lxml import etree, _elementpath
|
||||||
from hsutil import conflict
|
import gzip
|
||||||
|
|
||||||
class PyApp(NSObject):
|
class PyDupeGuru(PyDupeGuruBase):
|
||||||
pass #fake class
|
|
||||||
|
|
||||||
class PyDupeGuru(PyApp):
|
|
||||||
def init(self):
|
def init(self):
|
||||||
self = super(PyDupeGuru,self).init()
|
self = super(PyDupeGuru,self).init()
|
||||||
self.app = DupeGuru()
|
self.py = DupeGuru()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
#---Directories
|
|
||||||
def addDirectory_(self,directory):
|
|
||||||
return self.app.add_directory(directory)
|
|
||||||
|
|
||||||
def removeDirectory_(self,index):
|
|
||||||
self.app.RemoveDirectory(index)
|
|
||||||
|
|
||||||
def setDirectory_state_(self,node_path,state):
|
|
||||||
self.app.SetDirectoryState(node_path,state)
|
|
||||||
|
|
||||||
#---Results
|
|
||||||
def clearIgnoreList(self):
|
|
||||||
self.app.scanner.ignore_list.Clear()
|
|
||||||
|
|
||||||
def doScan(self):
|
|
||||||
return self.app.start_scanning()
|
|
||||||
|
|
||||||
def exportToXHTMLwithColumns_(self, column_ids):
|
|
||||||
return self.app.export_to_xhtml(column_ids)
|
|
||||||
|
|
||||||
def loadIgnoreList(self):
|
|
||||||
self.app.load_ignore_list()
|
|
||||||
|
|
||||||
def loadResults(self):
|
|
||||||
self.app.load()
|
|
||||||
|
|
||||||
def markAll(self):
|
|
||||||
self.app.results.mark_all()
|
|
||||||
|
|
||||||
def markNone(self):
|
|
||||||
self.app.results.mark_none()
|
|
||||||
|
|
||||||
def markInvert(self):
|
|
||||||
self.app.results.mark_invert()
|
|
||||||
|
|
||||||
def purgeIgnoreList(self):
|
|
||||||
self.app.PurgeIgnoreList()
|
|
||||||
|
|
||||||
def toggleSelectedMark(self):
|
|
||||||
self.app.ToggleSelectedMarkState()
|
|
||||||
|
|
||||||
def saveIgnoreList(self):
|
|
||||||
self.app.save_ignore_list()
|
|
||||||
|
|
||||||
def saveResults(self):
|
|
||||||
self.app.save()
|
|
||||||
|
|
||||||
def refreshDetailsWithSelected(self):
|
|
||||||
self.app.RefreshDetailsWithSelected()
|
|
||||||
|
|
||||||
def selectedResultNodePaths(self):
|
|
||||||
return self.app.selected_result_node_paths()
|
|
||||||
|
|
||||||
def selectResultNodePaths_(self,node_paths):
|
|
||||||
self.app.SelectResultNodePaths(node_paths)
|
|
||||||
|
|
||||||
def selectedPowerMarkerNodePaths(self):
|
|
||||||
return self.app.selected_powermarker_node_paths()
|
|
||||||
|
|
||||||
def selectPowerMarkerNodePaths_(self,node_paths):
|
|
||||||
self.app.SelectPowerMarkerNodePaths(node_paths)
|
|
||||||
|
|
||||||
#---Actions
|
|
||||||
def addSelectedToIgnoreList(self):
|
|
||||||
self.app.AddSelectedToIgnoreList()
|
|
||||||
|
|
||||||
def deleteMarked(self):
|
|
||||||
self.app.delete_marked()
|
|
||||||
|
|
||||||
def applyFilter_(self, filter):
|
|
||||||
self.app.apply_filter(filter)
|
|
||||||
|
|
||||||
def makeSelectedReference(self):
|
|
||||||
self.app.MakeSelectedReference()
|
|
||||||
|
|
||||||
def copyOrMove_markedTo_recreatePath_(self,copy,destination,recreate_path):
|
|
||||||
self.app.copy_or_move_marked(copy, destination, recreate_path)
|
|
||||||
|
|
||||||
def openSelected(self):
|
|
||||||
self.app.OpenSelected()
|
|
||||||
|
|
||||||
def removeMarked(self):
|
|
||||||
self.app.results.perform_on_marked(lambda x:True, True)
|
|
||||||
|
|
||||||
def removeSelected(self):
|
|
||||||
self.app.RemoveSelected()
|
|
||||||
|
|
||||||
def renameSelected_(self,newname):
|
|
||||||
return self.app.RenameSelected(newname)
|
|
||||||
|
|
||||||
def revealSelected(self):
|
|
||||||
self.app.RevealSelected()
|
|
||||||
|
|
||||||
#---Misc
|
|
||||||
def sortDupesBy_ascending_(self,key,asc):
|
|
||||||
self.app.sort_dupes(key,asc)
|
|
||||||
|
|
||||||
def sortGroupsBy_ascending_(self,key,asc):
|
|
||||||
self.app.sort_groups(key,asc)
|
|
||||||
|
|
||||||
#---Information
|
|
||||||
def getIgnoreListCount(self):
|
|
||||||
return len(self.app.scanner.ignore_list)
|
|
||||||
|
|
||||||
def getMarkCount(self):
|
|
||||||
return self.app.results.mark_count
|
|
||||||
|
|
||||||
def getStatLine(self):
|
|
||||||
return self.app.stat_line
|
|
||||||
|
|
||||||
def getOperationalErrorCount(self):
|
|
||||||
return self.app.last_op_error_count
|
|
||||||
|
|
||||||
#---Data
|
|
||||||
@objc.signature('i@:i')
|
|
||||||
def getOutlineViewMaxLevel_(self, tag):
|
|
||||||
return self.app.GetOutlineViewMaxLevel(tag)
|
|
||||||
|
|
||||||
@objc.signature('@@:i@')
|
|
||||||
def getOutlineView_childCountsForPath_(self, tag, node_path):
|
|
||||||
return self.app.GetOutlineViewChildCounts(tag, node_path)
|
|
||||||
|
|
||||||
def getOutlineView_valuesForIndexes_(self,tag,node_path):
|
|
||||||
return self.app.GetOutlineViewValues(tag,node_path)
|
|
||||||
|
|
||||||
def getOutlineView_markedAtIndexes_(self,tag,node_path):
|
|
||||||
return self.app.GetOutlineViewMarked(tag,node_path)
|
|
||||||
|
|
||||||
def getTableViewCount_(self,tag):
|
|
||||||
return self.app.GetTableViewCount(tag)
|
|
||||||
|
|
||||||
def getTableViewMarkedIndexes_(self,tag):
|
|
||||||
return self.app.GetTableViewMarkedIndexes(tag)
|
|
||||||
|
|
||||||
def getTableView_valuesForRow_(self,tag,row):
|
|
||||||
return self.app.GetTableViewValues(tag,row)
|
|
||||||
|
|
||||||
#---Properties
|
#---Properties
|
||||||
def setMinMatchPercentage_(self,percentage):
|
def setMinMatchPercentage_(self,percentage):
|
||||||
self.app.scanner.min_match_percentage = int(percentage)
|
self.py.scanner.min_match_percentage = int(percentage)
|
||||||
|
|
||||||
def setScanType_(self,scan_type):
|
def setScanType_(self,scan_type):
|
||||||
try:
|
try:
|
||||||
self.app.scanner.scan_type = [
|
self.py.scanner.scan_type = [
|
||||||
scanner.SCAN_TYPE_FILENAME,
|
scanner.SCAN_TYPE_FILENAME,
|
||||||
scanner.SCAN_TYPE_CONTENT
|
scanner.SCAN_TYPE_CONTENT
|
||||||
][scan_type]
|
][scan_type]
|
||||||
@@ -175,52 +35,16 @@ class PyDupeGuru(PyApp):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def setWordWeighting_(self,words_are_weighted):
|
def setWordWeighting_(self,words_are_weighted):
|
||||||
self.app.scanner.word_weighting = words_are_weighted
|
self.py.scanner.word_weighting = words_are_weighted
|
||||||
|
|
||||||
def setMixFileKind_(self,mix_file_kind):
|
|
||||||
self.app.scanner.mix_file_kind = mix_file_kind
|
|
||||||
|
|
||||||
def setDisplayDeltaValues_(self,display_delta_values):
|
|
||||||
self.app.display_delta_values= display_delta_values
|
|
||||||
|
|
||||||
def setMatchSimilarWords_(self,match_similar_words):
|
def setMatchSimilarWords_(self,match_similar_words):
|
||||||
self.app.scanner.match_similar_words = match_similar_words
|
self.py.scanner.match_similar_words = match_similar_words
|
||||||
|
|
||||||
def setEscapeFilterRegexp_(self, escape_filter_regexp):
|
@signature('v@:i')
|
||||||
self.app.options['escape_filter_regexp'] = escape_filter_regexp
|
|
||||||
|
|
||||||
def setRemoveEmptyFolders_(self, remove_empty_folders):
|
|
||||||
self.app.options['clean_empty_dirs'] = remove_empty_folders
|
|
||||||
|
|
||||||
@objc.signature('v@:i')
|
|
||||||
def setSizeThreshold_(self, size_threshold):
|
def setSizeThreshold_(self, size_threshold):
|
||||||
self.app.scanner.size_threshold = size_threshold
|
self.py.scanner.size_threshold = size_threshold
|
||||||
|
|
||||||
#---Worker
|
|
||||||
def getJobProgress(self):
|
|
||||||
return self.app.progress.last_progress
|
|
||||||
|
|
||||||
def getJobDesc(self):
|
|
||||||
return self.app.progress.last_desc
|
|
||||||
|
|
||||||
def cancelJob(self):
|
|
||||||
self.app.progress.job_cancelled = True
|
|
||||||
|
|
||||||
#---Registration
|
#---Registration
|
||||||
def appName(self):
|
def appName(self):
|
||||||
return "dupeGuru"
|
return "dupeGuru"
|
||||||
|
|
||||||
def demoLimitDescription(self):
|
|
||||||
return self.app.DEMO_LIMIT_DESC
|
|
||||||
|
|
||||||
@objc.signature('i@:')
|
|
||||||
def isRegistered(self):
|
|
||||||
return self.app.registered
|
|
||||||
|
|
||||||
@objc.signature('i@:@@')
|
|
||||||
def isCodeValid_withEmail_(self, code, email):
|
|
||||||
return self.app.is_code_valid(code, email)
|
|
||||||
|
|
||||||
def setRegisteredCode_andEmail_(self, code, email):
|
|
||||||
self.app.set_registration(code, email)
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,17 +10,30 @@
|
|||||||
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 /* dupeguru_help in Resources */ = {isa = PBXBuildFile; fileRef = CE073F5409CAE1A3005C1D2F /* dupeguru_help */; };
|
||||||
|
CE19BC6311199231007CCEB0 /* ErrorReportWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE19BC6011199231007CCEB0 /* ErrorReportWindow.xib */; };
|
||||||
|
CE19BC6411199231007CCEB0 /* progress.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE19BC6111199231007CCEB0 /* progress.xib */; };
|
||||||
|
CE19BC6511199231007CCEB0 /* registration.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE19BC6211199231007CCEB0 /* registration.xib */; };
|
||||||
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 */; };
|
CE3A46FA109B212E002ABFD5 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE3A46F9109B212E002ABFD5 /* MainMenu.xib */; };
|
||||||
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 */; };
|
||||||
CE68EE6809ABC48000971085 /* DirectoryPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE68EE6609ABC48000971085 /* DirectoryPanel.m */; };
|
CE647E571173024A006D28BA /* ProblemDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = CE647E551173024A006D28BA /* ProblemDialog.m */; };
|
||||||
|
CE647E591173026F006D28BA /* ProblemDialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE647E581173026F006D28BA /* ProblemDialog.xib */; };
|
||||||
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 */; };
|
||||||
|
CE76FDC4111EE37C006618EA /* HSOutlineView.m in Sources */ = {isa = PBXBuildFile; fileRef = CE76FDBF111EE37C006618EA /* HSOutlineView.m */; };
|
||||||
|
CE76FDC5111EE37C006618EA /* NSIndexPathAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE76FDC1111EE37C006618EA /* NSIndexPathAdditions.m */; };
|
||||||
|
CE76FDC6111EE37C006618EA /* NSTableViewAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE76FDC3111EE37C006618EA /* NSTableViewAdditions.m */; };
|
||||||
|
CE76FDCF111EE38E006618EA /* HSGUIController.m in Sources */ = {isa = PBXBuildFile; fileRef = CE76FDC9111EE38E006618EA /* HSGUIController.m */; };
|
||||||
|
CE76FDD4111EE3A7006618EA /* DirectoryOutline.m in Sources */ = {isa = PBXBuildFile; fileRef = CE76FDD2111EE3A7006618EA /* DirectoryOutline.m */; };
|
||||||
|
CE76FDDF111EE42F006618EA /* HSOutline.m in Sources */ = {isa = PBXBuildFile; fileRef = CE76FDDE111EE42F006618EA /* HSOutline.m */; };
|
||||||
|
CE76FDF7111EE561006618EA /* NSEventAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CE76FDF6111EE561006618EA /* NSEventAdditions.m */; };
|
||||||
|
CE8C53BC117324CE0011B41F /* HSTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CE8C53BB117324CE0011B41F /* HSTable.m */; };
|
||||||
|
CE91F215113BC22D0010360B /* ResultOutline.m in Sources */ = {isa = PBXBuildFile; fileRef = CE91F212113BC22D0010360B /* ResultOutline.m */; };
|
||||||
|
CE91F216113BC22D0010360B /* StatsLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE91F214113BC22D0010360B /* StatsLabel.m */; };
|
||||||
CEAC6811109B0B7E00B43C85 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = CEAC6810109B0B7E00B43C85 /* Preferences.xib */; };
|
CEAC6811109B0B7E00B43C85 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = CEAC6810109B0B7E00B43C85 /* Preferences.xib */; };
|
||||||
CECA899C09DB132E00A3D774 /* DetailsPanel.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CECA899A09DB132E00A3D774 /* DetailsPanel.h */; };
|
CEBE4D74111F0EE1009AAC6D /* HSWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CEBE4D73111F0EE1009AAC6D /* HSWindowController.m */; };
|
||||||
CECA899D09DB132E00A3D774 /* DetailsPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CECA899B09DB132E00A3D774 /* DetailsPanel.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 */; };
|
||||||
@@ -31,16 +44,11 @@
|
|||||||
CEFC295609C89FF200D9F998 /* preferences32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC295409C89FF200D9F998 /* preferences32.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 */; };
|
||||||
CEFC7FA00FC9517500CD5728 /* Outline.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7F8F0FC9517500CD5728 /* Outline.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 */; };
|
CEFC7FA20FC9517500CD5728 /* RecentDirectories.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7F950FC9517500CD5728 /* RecentDirectories.m */; };
|
||||||
CEFC7FA30FC9517500CD5728 /* RegistrationInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7F970FC9517500CD5728 /* RegistrationInterface.m */; };
|
CEFC7FA30FC9517500CD5728 /* RegistrationInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7F970FC9517500CD5728 /* RegistrationInterface.m */; };
|
||||||
CEFC7FA40FC9517500CD5728 /* Table.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7F990FC9517500CD5728 /* Table.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 */; };
|
||||||
CEFC7FAD0FC9518A00CD5728 /* ErrorReportWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CEFC7FA70FC9518A00CD5728 /* ErrorReportWindow.xib */; };
|
|
||||||
CEFC7FAE0FC9518A00CD5728 /* progress.nib in Resources */ = {isa = PBXBuildFile; fileRef = CEFC7FA90FC9518A00CD5728 /* progress.nib */; };
|
|
||||||
CEFC7FAF0FC9518A00CD5728 /* registration.nib in Resources */ = {isa = PBXBuildFile; fileRef = CEFC7FAB0FC9518A00CD5728 /* registration.nib */; };
|
|
||||||
CEFC7FB90FC951A700CD5728 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7FB20FC951A700CD5728 /* AppDelegate.m */; };
|
CEFC7FB90FC951A700CD5728 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7FB20FC951A700CD5728 /* AppDelegate.m */; };
|
||||||
CEFC7FBA0FC951A700CD5728 /* DirectoryPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7FB50FC951A700CD5728 /* DirectoryPanel.m */; };
|
CEFC7FBA0FC951A700CD5728 /* DirectoryPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7FB50FC951A700CD5728 /* DirectoryPanel.m */; };
|
||||||
CEFC7FBB0FC951A700CD5728 /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7FB80FC951A700CD5728 /* ResultWindow.m */; };
|
CEFC7FBB0FC951A700CD5728 /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFC7FB80FC951A700CD5728 /* ResultWindow.m */; };
|
||||||
@@ -54,7 +62,6 @@
|
|||||||
dstSubfolderSpec = 10;
|
dstSubfolderSpec = 10;
|
||||||
files = (
|
files = (
|
||||||
CE4557B40AE3BC50005A9546 /* Sparkle.framework in CopyFiles */,
|
CE4557B40AE3BC50005A9546 /* Sparkle.framework in CopyFiles */,
|
||||||
CECA899C09DB132E00A3D774 /* DetailsPanel.h in CopyFiles */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -69,6 +76,9 @@
|
|||||||
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>"; };
|
CE073F5409CAE1A3005C1D2F /* dupeguru_help */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dupeguru_help; path = ../../help_se/dupeguru_help; 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>"; };
|
||||||
|
CE19BC6211199231007CCEB0 /* registration.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = registration.xib; sourceTree = "<group>"; };
|
||||||
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; };
|
||||||
@@ -76,12 +86,40 @@
|
|||||||
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>"; };
|
CE3A46F9109B212E002ABFD5 /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MainMenu.xib; path = ../base/xib/MainMenu.xib; sourceTree = "<group>"; };
|
||||||
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>"; };
|
||||||
CE68EE6509ABC48000971085 /* DirectoryPanel.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = DirectoryPanel.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; };
|
||||||
CE68EE6609ABC48000971085 /* DirectoryPanel.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = DirectoryPanel.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; };
|
||||||
|
CE647E581173026F006D28BA /* ProblemDialog.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = ProblemDialog.xib; path = ../base/xib/ProblemDialog.xib; sourceTree = SOURCE_ROOT; };
|
||||||
CE6E0DFD1054E9EF008D9390 /* dsa_pub.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = dsa_pub.pem; path = ../base/dsa_pub.pem; sourceTree = "<group>"; };
|
CE6E0DFD1054E9EF008D9390 /* dsa_pub.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = dsa_pub.pem; path = ../base/dsa_pub.pem; sourceTree = "<group>"; };
|
||||||
|
CE6E7407111C997500C350E3 /* PyDetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyDetailsPanel.h; path = ../base/PyDetailsPanel.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE76FDBE111EE37C006618EA /* HSOutlineView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HSOutlineView.h; sourceTree = "<group>"; };
|
||||||
|
CE76FDBF111EE37C006618EA /* HSOutlineView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSOutlineView.m; sourceTree = "<group>"; };
|
||||||
|
CE76FDC0111EE37C006618EA /* NSIndexPathAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSIndexPathAdditions.h; sourceTree = "<group>"; };
|
||||||
|
CE76FDC1111EE37C006618EA /* NSIndexPathAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSIndexPathAdditions.m; sourceTree = "<group>"; };
|
||||||
|
CE76FDC2111EE37C006618EA /* NSTableViewAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSTableViewAdditions.h; sourceTree = "<group>"; };
|
||||||
|
CE76FDC3111EE37C006618EA /* NSTableViewAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSTableViewAdditions.m; sourceTree = "<group>"; };
|
||||||
|
CE76FDC8111EE38E006618EA /* HSGUIController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HSGUIController.h; sourceTree = "<group>"; };
|
||||||
|
CE76FDC9111EE38E006618EA /* HSGUIController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSGUIController.m; sourceTree = "<group>"; };
|
||||||
|
CE76FDCD111EE38E006618EA /* PyGUI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PyGUI.h; sourceTree = "<group>"; };
|
||||||
|
CE76FDCE111EE38E006618EA /* PyOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PyOutline.h; sourceTree = "<group>"; };
|
||||||
|
CE76FDD1111EE3A7006618EA /* DirectoryOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DirectoryOutline.h; path = ../base/DirectoryOutline.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE76FDD2111EE3A7006618EA /* DirectoryOutline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DirectoryOutline.m; path = ../base/DirectoryOutline.m; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE76FDD3111EE3A7006618EA /* PyDirectoryOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyDirectoryOutline.h; path = ../base/PyDirectoryOutline.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE76FDDD111EE42F006618EA /* HSOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HSOutline.h; sourceTree = "<group>"; };
|
||||||
|
CE76FDDE111EE42F006618EA /* HSOutline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HSOutline.m; sourceTree = "<group>"; };
|
||||||
|
CE76FDF5111EE561006618EA /* NSEventAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NSEventAdditions.h; path = ../../cocoalib/NSEventAdditions.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE76FDF6111EE561006618EA /* NSEventAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NSEventAdditions.m; path = ../../cocoalib/NSEventAdditions.m; sourceTree = SOURCE_ROOT; };
|
||||||
|
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>"; };
|
||||||
|
CE91F20F113BC22D0010360B /* PyResultTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyResultTree.h; path = ../base/PyResultTree.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; };
|
||||||
|
CE91F211113BC22D0010360B /* ResultOutline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ResultOutline.h; path = ../base/ResultOutline.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE91F212113BC22D0010360B /* ResultOutline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ResultOutline.m; path = ../base/ResultOutline.m; 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; };
|
||||||
CEAC6810109B0B7E00B43C85 /* Preferences.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Preferences.xib; path = xib/Preferences.xib; sourceTree = "<group>"; };
|
CEAC6810109B0B7E00B43C85 /* Preferences.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Preferences.xib; path = xib/Preferences.xib; sourceTree = "<group>"; };
|
||||||
CECA899A09DB132E00A3D774 /* DetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = DetailsPanel.h; sourceTree = "<group>"; };
|
CEBE4D72111F0EE1009AAC6D /* HSWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HSWindowController.h; sourceTree = "<group>"; };
|
||||||
CECA899B09DB132E00A3D774 /* DetailsPanel.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = DetailsPanel.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; };
|
||||||
CEDD92D70FDD01640031C7B7 /* BRSingleLineFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BRSingleLineFormatter.m; path = ../../cocoalib/brsinglelineformatter/BRSingleLineFormatter.m; sourceTree = SOURCE_ROOT; };
|
CEDD92D70FDD01640031C7B7 /* BRSingleLineFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BRSingleLineFormatter.m; path = ../../cocoalib/brsinglelineformatter/BRSingleLineFormatter.m; sourceTree = SOURCE_ROOT; };
|
||||||
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; };
|
||||||
@@ -96,8 +134,6 @@
|
|||||||
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; };
|
||||||
CEFC7F8D0FC9517500CD5728 /* HSErrorReportWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSErrorReportWindow.m; path = ../../cocoalib/HSErrorReportWindow.m; sourceTree = SOURCE_ROOT; };
|
CEFC7F8D0FC9517500CD5728 /* HSErrorReportWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSErrorReportWindow.m; path = ../../cocoalib/HSErrorReportWindow.m; sourceTree = SOURCE_ROOT; };
|
||||||
CEFC7F8E0FC9517500CD5728 /* Outline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Outline.h; path = ../../cocoalib/Outline.h; sourceTree = SOURCE_ROOT; };
|
|
||||||
CEFC7F8F0FC9517500CD5728 /* Outline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Outline.m; path = ../../cocoalib/Outline.m; sourceTree = SOURCE_ROOT; };
|
|
||||||
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; };
|
||||||
@@ -106,15 +142,10 @@
|
|||||||
CEFC7F950FC9517500CD5728 /* RecentDirectories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RecentDirectories.m; path = ../../cocoalib/RecentDirectories.m; sourceTree = SOURCE_ROOT; };
|
CEFC7F950FC9517500CD5728 /* RecentDirectories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RecentDirectories.m; path = ../../cocoalib/RecentDirectories.m; sourceTree = SOURCE_ROOT; };
|
||||||
CEFC7F960FC9517500CD5728 /* RegistrationInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegistrationInterface.h; path = ../../cocoalib/RegistrationInterface.h; sourceTree = SOURCE_ROOT; };
|
CEFC7F960FC9517500CD5728 /* RegistrationInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegistrationInterface.h; path = ../../cocoalib/RegistrationInterface.h; sourceTree = SOURCE_ROOT; };
|
||||||
CEFC7F970FC9517500CD5728 /* RegistrationInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RegistrationInterface.m; path = ../../cocoalib/RegistrationInterface.m; sourceTree = SOURCE_ROOT; };
|
CEFC7F970FC9517500CD5728 /* RegistrationInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RegistrationInterface.m; path = ../../cocoalib/RegistrationInterface.m; sourceTree = SOURCE_ROOT; };
|
||||||
CEFC7F980FC9517500CD5728 /* Table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Table.h; path = ../../cocoalib/Table.h; sourceTree = SOURCE_ROOT; };
|
|
||||||
CEFC7F990FC9517500CD5728 /* Table.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Table.m; path = ../../cocoalib/Table.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; };
|
||||||
CEFC7F9D0FC9517500CD5728 /* ValueTransformers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ValueTransformers.m; path = ../../cocoalib/ValueTransformers.m; sourceTree = SOURCE_ROOT; };
|
CEFC7F9D0FC9517500CD5728 /* ValueTransformers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ValueTransformers.m; path = ../../cocoalib/ValueTransformers.m; sourceTree = SOURCE_ROOT; };
|
||||||
CEFC7FA80FC9518A00CD5728 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = ../../cocoalib/English.lproj/ErrorReportWindow.xib; sourceTree = "<group>"; };
|
|
||||||
CEFC7FAA0FC9518A00CD5728 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = ../../cocoalib/English.lproj/progress.nib; sourceTree = "<group>"; };
|
|
||||||
CEFC7FAC0FC9518A00CD5728 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = ../../cocoalib/English.lproj/registration.nib; sourceTree = "<group>"; };
|
|
||||||
CEFC7FB10FC951A700CD5728 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = ../base/AppDelegate.h; sourceTree = SOURCE_ROOT; };
|
CEFC7FB10FC951A700CD5728 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = ../base/AppDelegate.h; sourceTree = SOURCE_ROOT; };
|
||||||
CEFC7FB20FC951A700CD5728 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = ../base/AppDelegate.m; sourceTree = SOURCE_ROOT; };
|
CEFC7FB20FC951A700CD5728 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = ../base/AppDelegate.m; sourceTree = SOURCE_ROOT; };
|
||||||
CEFC7FB30FC951A700CD5728 /* Consts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Consts.h; path = ../base/Consts.h; sourceTree = SOURCE_ROOT; };
|
CEFC7FB30FC951A700CD5728 /* Consts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Consts.h; path = ../base/Consts.h; sourceTree = SOURCE_ROOT; };
|
||||||
@@ -144,10 +175,6 @@
|
|||||||
children = (
|
children = (
|
||||||
CE381C9509914ACE003581CE /* AppDelegate.h */,
|
CE381C9509914ACE003581CE /* AppDelegate.h */,
|
||||||
CE381C9409914ACE003581CE /* AppDelegate.m */,
|
CE381C9409914ACE003581CE /* AppDelegate.m */,
|
||||||
CECA899A09DB132E00A3D774 /* DetailsPanel.h */,
|
|
||||||
CECA899B09DB132E00A3D774 /* DetailsPanel.m */,
|
|
||||||
CE68EE6509ABC48000971085 /* DirectoryPanel.h */,
|
|
||||||
CE68EE6609ABC48000971085 /* DirectoryPanel.m */,
|
|
||||||
CEFF18A009A4D387005E6321 /* PyDupeGuru.h */,
|
CEFF18A009A4D387005E6321 /* PyDupeGuru.h */,
|
||||||
CE381C9B09914ADF003581CE /* ResultWindow.h */,
|
CE381C9B09914ADF003581CE /* ResultWindow.h */,
|
||||||
CE381C9A09914ADF003581CE /* ResultWindow.m */,
|
CE381C9A09914ADF003581CE /* ResultWindow.m */,
|
||||||
@@ -219,6 +246,57 @@
|
|||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
CE19BC5F11199231007CCEB0 /* xib */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CE19BC6011199231007CCEB0 /* ErrorReportWindow.xib */,
|
||||||
|
CE19BC6111199231007CCEB0 /* progress.xib */,
|
||||||
|
CE19BC6211199231007CCEB0 /* registration.xib */,
|
||||||
|
);
|
||||||
|
name = xib;
|
||||||
|
path = ../../cocoalib/xib;
|
||||||
|
sourceTree = SOURCE_ROOT;
|
||||||
|
};
|
||||||
|
CE76FDBD111EE37C006618EA /* views */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CE76FDBE111EE37C006618EA /* HSOutlineView.h */,
|
||||||
|
CE76FDBF111EE37C006618EA /* HSOutlineView.m */,
|
||||||
|
CE76FDC0111EE37C006618EA /* NSIndexPathAdditions.h */,
|
||||||
|
CE76FDC1111EE37C006618EA /* NSIndexPathAdditions.m */,
|
||||||
|
CE76FDC2111EE37C006618EA /* NSTableViewAdditions.h */,
|
||||||
|
CE76FDC3111EE37C006618EA /* NSTableViewAdditions.m */,
|
||||||
|
);
|
||||||
|
name = views;
|
||||||
|
path = ../../cocoalib/views;
|
||||||
|
sourceTree = SOURCE_ROOT;
|
||||||
|
};
|
||||||
|
CE76FDC7111EE38E006618EA /* controllers */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CEBE4D72111F0EE1009AAC6D /* HSWindowController.h */,
|
||||||
|
CEBE4D73111F0EE1009AAC6D /* HSWindowController.m */,
|
||||||
|
CE76FDDD111EE42F006618EA /* HSOutline.h */,
|
||||||
|
CE76FDDE111EE42F006618EA /* HSOutline.m */,
|
||||||
|
CE76FDC8111EE38E006618EA /* HSGUIController.h */,
|
||||||
|
CE76FDC9111EE38E006618EA /* HSGUIController.m */,
|
||||||
|
CE8C53BB117324CE0011B41F /* HSTable.m */,
|
||||||
|
);
|
||||||
|
name = controllers;
|
||||||
|
path = ../../cocoalib/controllers;
|
||||||
|
sourceTree = SOURCE_ROOT;
|
||||||
|
};
|
||||||
|
CE76FDCC111EE38E006618EA /* proxies */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CE76FDCD111EE38E006618EA /* PyGUI.h */,
|
||||||
|
CE76FDCE111EE38E006618EA /* PyOutline.h */,
|
||||||
|
CE8C53B61173248F0011B41F /* PyTable.h */,
|
||||||
|
);
|
||||||
|
name = proxies;
|
||||||
|
path = ../../cocoalib/proxies;
|
||||||
|
sourceTree = SOURCE_ROOT;
|
||||||
|
};
|
||||||
CEDD92D50FDD01640031C7B7 /* brsinglelineformatter */ = {
|
CEDD92D50FDD01640031C7B7 /* brsinglelineformatter */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -232,6 +310,7 @@
|
|||||||
CEEFC0CA10943849001F3A39 /* xib */ = {
|
CEEFC0CA10943849001F3A39 /* xib */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
CE647E581173026F006D28BA /* ProblemDialog.xib */,
|
||||||
CE3A46F9109B212E002ABFD5 /* MainMenu.xib */,
|
CE3A46F9109B212E002ABFD5 /* MainMenu.xib */,
|
||||||
CEAC6810109B0B7E00B43C85 /* Preferences.xib */,
|
CEAC6810109B0B7E00B43C85 /* Preferences.xib */,
|
||||||
CEEFC0F710945D9F001F3A39 /* DirectoryPanel.xib */,
|
CEEFC0F710945D9F001F3A39 /* DirectoryPanel.xib */,
|
||||||
@@ -253,16 +332,17 @@
|
|||||||
CEFC7F890FC9513600CD5728 /* cocoalib */ = {
|
CEFC7F890FC9513600CD5728 /* cocoalib */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
CE76FDF5111EE561006618EA /* NSEventAdditions.h */,
|
||||||
|
CE76FDF6111EE561006618EA /* NSEventAdditions.m */,
|
||||||
|
CE76FDC7111EE38E006618EA /* controllers */,
|
||||||
|
CE76FDCC111EE38E006618EA /* proxies */,
|
||||||
|
CE76FDBD111EE37C006618EA /* views */,
|
||||||
|
CE19BC5F11199231007CCEB0 /* xib */,
|
||||||
CEDD92D50FDD01640031C7B7 /* brsinglelineformatter */,
|
CEDD92D50FDD01640031C7B7 /* brsinglelineformatter */,
|
||||||
CEFC7FA70FC9518A00CD5728 /* ErrorReportWindow.xib */,
|
|
||||||
CEFC7FA90FC9518A00CD5728 /* progress.nib */,
|
|
||||||
CEFC7FAB0FC9518A00CD5728 /* registration.nib */,
|
|
||||||
CEFC7F8A0FC9517500CD5728 /* Dialogs.h */,
|
CEFC7F8A0FC9517500CD5728 /* Dialogs.h */,
|
||||||
CEFC7F8B0FC9517500CD5728 /* Dialogs.m */,
|
CEFC7F8B0FC9517500CD5728 /* Dialogs.m */,
|
||||||
CEFC7F8C0FC9517500CD5728 /* HSErrorReportWindow.h */,
|
CEFC7F8C0FC9517500CD5728 /* HSErrorReportWindow.h */,
|
||||||
CEFC7F8D0FC9517500CD5728 /* HSErrorReportWindow.m */,
|
CEFC7F8D0FC9517500CD5728 /* HSErrorReportWindow.m */,
|
||||||
CEFC7F8E0FC9517500CD5728 /* Outline.h */,
|
|
||||||
CEFC7F8F0FC9517500CD5728 /* Outline.m */,
|
|
||||||
CEFC7F900FC9517500CD5728 /* ProgressController.h */,
|
CEFC7F900FC9517500CD5728 /* ProgressController.h */,
|
||||||
CEFC7F910FC9517500CD5728 /* ProgressController.m */,
|
CEFC7F910FC9517500CD5728 /* ProgressController.m */,
|
||||||
CEFC7F920FC9517500CD5728 /* PyApp.h */,
|
CEFC7F920FC9517500CD5728 /* PyApp.h */,
|
||||||
@@ -271,8 +351,6 @@
|
|||||||
CEFC7F950FC9517500CD5728 /* RecentDirectories.m */,
|
CEFC7F950FC9517500CD5728 /* RecentDirectories.m */,
|
||||||
CEFC7F960FC9517500CD5728 /* RegistrationInterface.h */,
|
CEFC7F960FC9517500CD5728 /* RegistrationInterface.h */,
|
||||||
CEFC7F970FC9517500CD5728 /* RegistrationInterface.m */,
|
CEFC7F970FC9517500CD5728 /* RegistrationInterface.m */,
|
||||||
CEFC7F980FC9517500CD5728 /* Table.h */,
|
|
||||||
CEFC7F990FC9517500CD5728 /* Table.m */,
|
|
||||||
CEFC7F9A0FC9517500CD5728 /* Utils.h */,
|
CEFC7F9A0FC9517500CD5728 /* Utils.h */,
|
||||||
CEFC7F9B0FC9517500CD5728 /* Utils.m */,
|
CEFC7F9B0FC9517500CD5728 /* Utils.m */,
|
||||||
CEFC7F9C0FC9517500CD5728 /* ValueTransformers.h */,
|
CEFC7F9C0FC9517500CD5728 /* ValueTransformers.h */,
|
||||||
@@ -284,6 +362,15 @@
|
|||||||
CEFC7FB00FC9518F00CD5728 /* dgbase */ = {
|
CEFC7FB00FC9518F00CD5728 /* dgbase */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
CE91F20F113BC22D0010360B /* PyResultTree.h */,
|
||||||
|
CE91F210113BC22D0010360B /* PyStatsLabel.h */,
|
||||||
|
CE91F211113BC22D0010360B /* ResultOutline.h */,
|
||||||
|
CE91F212113BC22D0010360B /* ResultOutline.m */,
|
||||||
|
CE91F213113BC22D0010360B /* StatsLabel.h */,
|
||||||
|
CE91F214113BC22D0010360B /* StatsLabel.m */,
|
||||||
|
CE76FDD1111EE3A7006618EA /* DirectoryOutline.h */,
|
||||||
|
CE76FDD2111EE3A7006618EA /* DirectoryOutline.m */,
|
||||||
|
CE76FDD3111EE3A7006618EA /* PyDirectoryOutline.h */,
|
||||||
CEFC7FB10FC951A700CD5728 /* AppDelegate.h */,
|
CEFC7FB10FC951A700CD5728 /* AppDelegate.h */,
|
||||||
CEFC7FB20FC951A700CD5728 /* AppDelegate.m */,
|
CEFC7FB20FC951A700CD5728 /* AppDelegate.m */,
|
||||||
CEFC7FB30FC951A700CD5728 /* Consts.h */,
|
CEFC7FB30FC951A700CD5728 /* Consts.h */,
|
||||||
@@ -292,8 +379,12 @@
|
|||||||
CEFC7FB40FC951A700CD5728 /* DirectoryPanel.h */,
|
CEFC7FB40FC951A700CD5728 /* DirectoryPanel.h */,
|
||||||
CEFC7FB50FC951A700CD5728 /* DirectoryPanel.m */,
|
CEFC7FB50FC951A700CD5728 /* DirectoryPanel.m */,
|
||||||
CEFC7FB60FC951A700CD5728 /* PyDupeGuru.h */,
|
CEFC7FB60FC951A700CD5728 /* PyDupeGuru.h */,
|
||||||
|
CE6E7407111C997500C350E3 /* PyDetailsPanel.h */,
|
||||||
CEFC7FB70FC951A700CD5728 /* ResultWindow.h */,
|
CEFC7FB70FC951A700CD5728 /* ResultWindow.h */,
|
||||||
CEFC7FB80FC951A700CD5728 /* ResultWindow.m */,
|
CEFC7FB80FC951A700CD5728 /* ResultWindow.m */,
|
||||||
|
CE647E541173024A006D28BA /* ProblemDialog.h */,
|
||||||
|
CE647E551173024A006D28BA /* ProblemDialog.m */,
|
||||||
|
CE647E561173024A006D28BA /* PyProblemDialog.h */,
|
||||||
);
|
);
|
||||||
name = dgbase;
|
name = dgbase;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -351,14 +442,15 @@
|
|||||||
CEFC294609C89E3D00D9F998 /* folder32.png in Resources */,
|
CEFC294609C89E3D00D9F998 /* folder32.png in Resources */,
|
||||||
CEFC295509C89FF200D9F998 /* details32.png in Resources */,
|
CEFC295509C89FF200D9F998 /* details32.png in Resources */,
|
||||||
CEFC295609C89FF200D9F998 /* preferences32.png in Resources */,
|
CEFC295609C89FF200D9F998 /* preferences32.png in Resources */,
|
||||||
CEFC7FAD0FC9518A00CD5728 /* ErrorReportWindow.xib in Resources */,
|
|
||||||
CEFC7FAE0FC9518A00CD5728 /* progress.nib in Resources */,
|
|
||||||
CEFC7FAF0FC9518A00CD5728 /* registration.nib in Resources */,
|
|
||||||
CE6E0DFE1054E9EF008D9390 /* dsa_pub.pem in Resources */,
|
CE6E0DFE1054E9EF008D9390 /* dsa_pub.pem in Resources */,
|
||||||
CEEFC0F810945D9F001F3A39 /* DirectoryPanel.xib in Resources */,
|
CEEFC0F810945D9F001F3A39 /* DirectoryPanel.xib in Resources */,
|
||||||
CEEFC0FB10945E37001F3A39 /* DetailsPanel.xib in Resources */,
|
CEEFC0FB10945E37001F3A39 /* DetailsPanel.xib in Resources */,
|
||||||
CEAC6811109B0B7E00B43C85 /* Preferences.xib in Resources */,
|
CEAC6811109B0B7E00B43C85 /* Preferences.xib in Resources */,
|
||||||
CE3A46FA109B212E002ABFD5 /* MainMenu.xib in Resources */,
|
CE3A46FA109B212E002ABFD5 /* MainMenu.xib in Resources */,
|
||||||
|
CE19BC6311199231007CCEB0 /* ErrorReportWindow.xib in Resources */,
|
||||||
|
CE19BC6411199231007CCEB0 /* progress.xib in Resources */,
|
||||||
|
CE19BC6511199231007CCEB0 /* registration.xib in Resources */,
|
||||||
|
CE647E591173026F006D28BA /* ProblemDialog.xib in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -372,15 +464,11 @@
|
|||||||
8D11072D0486CEB800E47090 /* main.m in Sources */,
|
8D11072D0486CEB800E47090 /* main.m in Sources */,
|
||||||
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */,
|
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */,
|
||||||
CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */,
|
CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */,
|
||||||
CE68EE6809ABC48000971085 /* DirectoryPanel.m in Sources */,
|
|
||||||
CECA899D09DB132E00A3D774 /* DetailsPanel.m in Sources */,
|
|
||||||
CEFC7F9E0FC9517500CD5728 /* Dialogs.m in Sources */,
|
CEFC7F9E0FC9517500CD5728 /* Dialogs.m in Sources */,
|
||||||
CEFC7F9F0FC9517500CD5728 /* HSErrorReportWindow.m in Sources */,
|
CEFC7F9F0FC9517500CD5728 /* HSErrorReportWindow.m in Sources */,
|
||||||
CEFC7FA00FC9517500CD5728 /* Outline.m in Sources */,
|
|
||||||
CEFC7FA10FC9517500CD5728 /* ProgressController.m in Sources */,
|
CEFC7FA10FC9517500CD5728 /* ProgressController.m in Sources */,
|
||||||
CEFC7FA20FC9517500CD5728 /* RecentDirectories.m in Sources */,
|
CEFC7FA20FC9517500CD5728 /* RecentDirectories.m in Sources */,
|
||||||
CEFC7FA30FC9517500CD5728 /* RegistrationInterface.m in Sources */,
|
CEFC7FA30FC9517500CD5728 /* RegistrationInterface.m in Sources */,
|
||||||
CEFC7FA40FC9517500CD5728 /* Table.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 */,
|
||||||
@@ -388,68 +476,72 @@
|
|||||||
CEFC7FBB0FC951A700CD5728 /* ResultWindow.m in Sources */,
|
CEFC7FBB0FC951A700CD5728 /* ResultWindow.m in Sources */,
|
||||||
CEDD92DA0FDD01640031C7B7 /* BRSingleLineFormatter.m in Sources */,
|
CEDD92DA0FDD01640031C7B7 /* BRSingleLineFormatter.m in Sources */,
|
||||||
CEE7EA130FE675C80004E467 /* DetailsPanel.m in Sources */,
|
CEE7EA130FE675C80004E467 /* DetailsPanel.m in Sources */,
|
||||||
|
CE76FDC4111EE37C006618EA /* HSOutlineView.m in Sources */,
|
||||||
|
CE76FDC5111EE37C006618EA /* NSIndexPathAdditions.m in Sources */,
|
||||||
|
CE76FDC6111EE37C006618EA /* NSTableViewAdditions.m in Sources */,
|
||||||
|
CE76FDCF111EE38E006618EA /* HSGUIController.m in Sources */,
|
||||||
|
CE76FDD4111EE3A7006618EA /* DirectoryOutline.m in Sources */,
|
||||||
|
CE76FDDF111EE42F006618EA /* HSOutline.m in Sources */,
|
||||||
|
CE76FDF7111EE561006618EA /* NSEventAdditions.m in Sources */,
|
||||||
|
CEBE4D74111F0EE1009AAC6D /* HSWindowController.m in Sources */,
|
||||||
|
CE91F215113BC22D0010360B /* ResultOutline.m in Sources */,
|
||||||
|
CE91F216113BC22D0010360B /* StatsLabel.m in Sources */,
|
||||||
|
CE647E571173024A006D28BA /* ProblemDialog.m in Sources */,
|
||||||
|
CE8C53BC117324CE0011B41F /* HSTable.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
|
||||||
CEFC7FA70FC9518A00CD5728 /* ErrorReportWindow.xib */ = {
|
|
||||||
isa = PBXVariantGroup;
|
|
||||||
children = (
|
|
||||||
CEFC7FA80FC9518A00CD5728 /* English */,
|
|
||||||
);
|
|
||||||
name = ErrorReportWindow.xib;
|
|
||||||
sourceTree = SOURCE_ROOT;
|
|
||||||
};
|
|
||||||
CEFC7FA90FC9518A00CD5728 /* progress.nib */ = {
|
|
||||||
isa = PBXVariantGroup;
|
|
||||||
children = (
|
|
||||||
CEFC7FAA0FC9518A00CD5728 /* English */,
|
|
||||||
);
|
|
||||||
name = progress.nib;
|
|
||||||
sourceTree = SOURCE_ROOT;
|
|
||||||
};
|
|
||||||
CEFC7FAB0FC9518A00CD5728 /* registration.nib */ = {
|
|
||||||
isa = PBXVariantGroup;
|
|
||||||
children = (
|
|
||||||
CEFC7FAC0FC9518A00CD5728 /* English */,
|
|
||||||
);
|
|
||||||
name = registration.nib;
|
|
||||||
sourceTree = SOURCE_ROOT;
|
|
||||||
};
|
|
||||||
/* End PBXVariantGroup section */
|
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
C01FCF4C08A954540054247B /* Release */ = {
|
C01FCF4C08A954540054247B /* release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ARCHS = (
|
|
||||||
ppc,
|
|
||||||
i386,
|
|
||||||
);
|
|
||||||
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../base/cocoa/build/Release\"";
|
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||||
GCC_MODEL_TUNING = G5;
|
|
||||||
INFOPLIST_FILE = Info.plist;
|
INFOPLIST_FILE = Info.plist;
|
||||||
INSTALL_PATH = "$(HOME)/Applications";
|
INSTALL_PATH = "$(HOME)/Applications";
|
||||||
PRODUCT_NAME = dupeGuru;
|
PRODUCT_NAME = dupeGuru;
|
||||||
WRAPPER_EXTENSION = app;
|
WRAPPER_EXTENSION = app;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = release;
|
||||||
};
|
};
|
||||||
C01FCF5008A954540054247B /* Release */ = {
|
C01FCF5008A954540054247B /* release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)";
|
ARCHS = (
|
||||||
ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386";
|
i386,
|
||||||
|
x86_64,
|
||||||
|
ppc,
|
||||||
|
);
|
||||||
GCC_C_LANGUAGE_STANDARD = c99;
|
GCC_C_LANGUAGE_STANDARD = c99;
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.5;
|
MACOSX_DEPLOYMENT_TARGET = 10.5;
|
||||||
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
|
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = release;
|
||||||
|
};
|
||||||
|
CE85E84F111AF63D00187B0D /* dev */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
|
||||||
|
GCC_C_LANGUAGE_STANDARD = c99;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.5;
|
||||||
|
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
|
||||||
|
};
|
||||||
|
name = dev;
|
||||||
|
};
|
||||||
|
CE85E850111AF63D00187B0D /* dev */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
INFOPLIST_FILE = Info.plist;
|
||||||
|
INSTALL_PATH = "$(HOME)/Applications";
|
||||||
|
PRODUCT_NAME = dupeGuru;
|
||||||
|
WRAPPER_EXTENSION = app;
|
||||||
|
};
|
||||||
|
name = dev;
|
||||||
};
|
};
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
@@ -457,18 +549,20 @@
|
|||||||
C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "dupeguru" */ = {
|
C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "dupeguru" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
C01FCF4C08A954540054247B /* Release */,
|
C01FCF4C08A954540054247B /* release */,
|
||||||
|
CE85E850111AF63D00187B0D /* dev */,
|
||||||
);
|
);
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = release;
|
||||||
};
|
};
|
||||||
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */ = {
|
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
C01FCF5008A954540054247B /* Release */,
|
C01FCF5008A954540054247B /* release */,
|
||||||
|
CE85E84F111AF63D00187B0D /* dev */,
|
||||||
);
|
);
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = release;
|
||||||
};
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,10 +7,12 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import "Utils.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
[Utils setPluginName:@"dg_cocoa"];
|
||||||
NSString *pluginPath = [[NSBundle mainBundle]
|
NSString *pluginPath = [[NSBundle mainBundle]
|
||||||
pathForResource:@"dg_cocoa"
|
pathForResource:@"dg_cocoa"
|
||||||
ofType:@"plugin"];
|
ofType:@"plugin"];
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -12,20 +12,17 @@ from optparse import OptionParser
|
|||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
def main(edition, ui, dev, build64):
|
def main(edition, ui, dev):
|
||||||
if edition not in ('se', 'me', 'pe'):
|
if edition not in ('se', 'me', 'pe'):
|
||||||
edition = 'se'
|
edition = 'se'
|
||||||
if ui not in ('cocoa', 'qt'):
|
if ui not in ('cocoa', 'qt'):
|
||||||
ui = 'cocoa' if sys.platform == 'darwin' else 'qt'
|
ui = 'cocoa' if sys.platform == 'darwin' else 'qt'
|
||||||
build_type = 'Dev' if dev else 'Release'
|
build_type = 'Dev' if dev else 'Release'
|
||||||
print "Configuring dupeGuru {0} for UI {1} ({2})".format(edition.upper(), ui, build_type)
|
print "Configuring dupeGuru {0} for UI {1} ({2})".format(edition.upper(), ui, build_type)
|
||||||
if build64:
|
|
||||||
print "If possible, 64-bit builds will be made"
|
|
||||||
conf = {
|
conf = {
|
||||||
'edition': edition,
|
'edition': edition,
|
||||||
'ui': ui,
|
'ui': ui,
|
||||||
'dev': dev,
|
'dev': dev,
|
||||||
'build64': build64,
|
|
||||||
}
|
}
|
||||||
yaml.dump(conf, open('conf.yaml', 'w'))
|
yaml.dump(conf, open('conf.yaml', 'w'))
|
||||||
|
|
||||||
@@ -38,7 +35,5 @@ if __name__ == '__main__':
|
|||||||
help="Type of UI to build. 'qt' or 'cocoa'. Default is determined by your system.")
|
help="Type of UI to build. 'qt' or 'cocoa'. Default is determined by your system.")
|
||||||
parser.add_option('--dev', action='store_true', dest='dev', default=False,
|
parser.add_option('--dev', action='store_true', dest='dev', default=False,
|
||||||
help="If this flag is set, will configure for dev builds.")
|
help="If this flag is set, will configure for dev builds.")
|
||||||
parser.add_option('--64bit', action='store_false', dest='build64', default=False,
|
|
||||||
help="Build 64-bit app if possible.")
|
|
||||||
(options, args) = parser.parse_args()
|
(options, args) = parser.parse_args()
|
||||||
main(options.edition, options.ui, options.dev, options.build64)
|
main(options.edition, options.ui, options.dev)
|
||||||
|
|||||||
200
core/app.py
200
core/app.py
@@ -1,4 +1,3 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2006/11/11
|
# Created On: 2006/11/11
|
||||||
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
@@ -12,10 +11,14 @@ from __future__ import unicode_literals
|
|||||||
import os
|
import os
|
||||||
import os.path as op
|
import os.path as op
|
||||||
import logging
|
import logging
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
|
||||||
|
from send2trash import send2trash
|
||||||
|
from hscommon.reg import RegistrableApplication, RegistrationRequired
|
||||||
|
from hscommon.notify import Broadcaster
|
||||||
from hsutil import io, files
|
from hsutil import io, files
|
||||||
from hsutil.path import Path
|
from hsutil.path import Path
|
||||||
from hsutil.reg import RegistrableApplication, RegistrationRequired
|
|
||||||
from hsutil.misc import flatten, first
|
from hsutil.misc import flatten, first
|
||||||
from hsutil.str import escape
|
from hsutil.str import escape
|
||||||
|
|
||||||
@@ -33,11 +36,12 @@ class NoScannableFileError(Exception):
|
|||||||
class AllFilesAreRefError(Exception):
|
class AllFilesAreRefError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class DupeGuru(RegistrableApplication):
|
class DupeGuru(RegistrableApplication, Broadcaster):
|
||||||
DEMO_LIMIT_DESC = "In the demo version, only 10 duplicates per session can be sent to the recycle bin, moved or copied."
|
DEMO_LIMIT_DESC = "In the demo version, only 10 duplicates per session can be sent to the recycle bin, moved or copied."
|
||||||
|
|
||||||
def __init__(self, data_module, appdata, appid):
|
def __init__(self, data_module, appdata, appid):
|
||||||
RegistrableApplication.__init__(self, appid)
|
RegistrableApplication.__init__(self, appid)
|
||||||
|
Broadcaster.__init__(self)
|
||||||
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)
|
||||||
@@ -46,11 +50,11 @@ class DupeGuru(RegistrableApplication):
|
|||||||
self.results = results.Results(data_module)
|
self.results = results.Results(data_module)
|
||||||
self.scanner = scanner.Scanner()
|
self.scanner = scanner.Scanner()
|
||||||
self.action_count = 0
|
self.action_count = 0
|
||||||
self.last_op_error_count = 0
|
|
||||||
self.options = {
|
self.options = {
|
||||||
'escape_filter_regexp': True,
|
'escape_filter_regexp': True,
|
||||||
'clean_empty_dirs': False,
|
'clean_empty_dirs': False,
|
||||||
}
|
}
|
||||||
|
self.selected_dupes = []
|
||||||
|
|
||||||
def _demo_check(self):
|
def _demo_check(self):
|
||||||
if self.registered:
|
if self.registered:
|
||||||
@@ -67,25 +71,28 @@ class DupeGuru(RegistrableApplication):
|
|||||||
return self._do_delete_dupe(dupe)
|
return self._do_delete_dupe(dupe)
|
||||||
|
|
||||||
j.start_job(self.results.mark_count)
|
j.start_job(self.results.mark_count)
|
||||||
self.last_op_error_count = self.results.perform_on_marked(op, True)
|
self.results.perform_on_marked(op, True)
|
||||||
|
|
||||||
def _do_delete_dupe(self, dupe):
|
def _do_delete_dupe(self, dupe):
|
||||||
if not io.exists(dupe.path):
|
if not io.exists(dupe.path):
|
||||||
return True
|
return
|
||||||
self._recycle_dupe(dupe)
|
send2trash(unicode(dupe.path)) # Raises OSError when there's a problem
|
||||||
self.clean_empty_dirs(dupe.path[:-1])
|
self.clean_empty_dirs(dupe.path[:-1])
|
||||||
if not io.exists(dupe.path):
|
|
||||||
return True
|
|
||||||
logging.warning("Could not send {0} to trash.".format(unicode(dupe.path)))
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _do_load(self, j):
|
def _do_load(self, j):
|
||||||
self.directories.load_from_file(op.join(self.appdata, 'last_directories.xml'))
|
self.directories.load_from_file(op.join(self.appdata, 'last_directories.xml'))
|
||||||
|
self.notify('directories_changed')
|
||||||
j = j.start_subjob([1, 9])
|
j = j.start_subjob([1, 9])
|
||||||
self.results.load_from_xml(op.join(self.appdata, 'last_results.xml'), self._get_file, j)
|
self.results.load_from_xml(op.join(self.appdata, 'last_results.xml'), self._get_file, j)
|
||||||
files = flatten(g[:] for g in self.results.groups)
|
files = flatten(g[:] for g in self.results.groups)
|
||||||
for file in j.iter_with_progress(files, 'Reading metadata %d/%d'):
|
try:
|
||||||
file._read_all_info(attrnames=self.data.METADATA_TO_READ)
|
for file in j.iter_with_progress(files, 'Reading metadata %d/%d'):
|
||||||
|
file._read_all_info(attrnames=self.data.METADATA_TO_READ)
|
||||||
|
except (OSError, IOError):
|
||||||
|
# If this error is raised, it means that a file was deleted while we were reading
|
||||||
|
# metadata. Proper handling of this rare occurrence is complex because there's no easy
|
||||||
|
# way to remove an arbitrary file from the Results. Thus, we simply clear them.
|
||||||
|
self.results.groups = []
|
||||||
|
|
||||||
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):
|
||||||
@@ -100,10 +107,28 @@ class DupeGuru(RegistrableApplication):
|
|||||||
path = Path(str_path)
|
path = Path(str_path)
|
||||||
return fs.get_file(path, self.directories.fileclasses)
|
return fs.get_file(path, self.directories.fileclasses)
|
||||||
|
|
||||||
|
def _job_completed(self, jobid):
|
||||||
|
# Must be called by subclasses when they detect that an async job is completed.
|
||||||
|
if jobid == JOB_SCAN:
|
||||||
|
self.notify('results_changed')
|
||||||
|
elif jobid in (JOB_LOAD, JOB_MOVE, JOB_DELETE):
|
||||||
|
self.notify('results_changed')
|
||||||
|
self.notify('problems_changed')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _recycle_dupe(dupe):
|
def _open_path(path):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _reveal_path(path):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def _select_dupes(self, dupes):
|
||||||
|
if dupes == self.selected_dupes:
|
||||||
|
return
|
||||||
|
self.selected_dupes = dupes
|
||||||
|
self.notify('dupes_selected')
|
||||||
|
|
||||||
def _start_job(self, jobid, func):
|
def _start_job(self, jobid, func):
|
||||||
# func(j)
|
# func(j)
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
@@ -111,17 +136,21 @@ class DupeGuru(RegistrableApplication):
|
|||||||
def add_directory(self, d):
|
def add_directory(self, d):
|
||||||
try:
|
try:
|
||||||
self.directories.add_path(Path(d))
|
self.directories.add_path(Path(d))
|
||||||
|
self.notify('directories_changed')
|
||||||
return 0
|
return 0
|
||||||
except directories.AlreadyThereError:
|
except directories.AlreadyThereError:
|
||||||
return 1
|
return 1
|
||||||
except directories.InvalidPathError:
|
except directories.InvalidPathError:
|
||||||
return 2
|
return 2
|
||||||
|
|
||||||
def add_to_ignore_list(self, dupe):
|
def add_selected_to_ignore_list(self):
|
||||||
g = self.results.get_group_of_duplicate(dupe)
|
dupes = self.without_ref(self.selected_dupes)
|
||||||
for other in g:
|
for dupe in dupes:
|
||||||
if other is not dupe:
|
g = self.results.get_group_of_duplicate(dupe)
|
||||||
self.scanner.ignore_list.Ignore(unicode(other.path), unicode(dupe.path))
|
for other in g:
|
||||||
|
if other is not dupe:
|
||||||
|
self.scanner.ignore_list.Ignore(unicode(other.path), unicode(dupe.path))
|
||||||
|
self.remove_duplicates(dupes)
|
||||||
|
|
||||||
def apply_filter(self, filter):
|
def apply_filter(self, filter):
|
||||||
self.results.apply_filter(None)
|
self.results.apply_filter(None)
|
||||||
@@ -129,6 +158,7 @@ class DupeGuru(RegistrableApplication):
|
|||||||
filter = escape(filter, '()[]\\.|+?^')
|
filter = escape(filter, '()[]\\.|+?^')
|
||||||
filter = escape(filter, '*', '.')
|
filter = escape(filter, '*', '.')
|
||||||
self.results.apply_filter(filter)
|
self.results.apply_filter(filter)
|
||||||
|
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']:
|
||||||
@@ -150,28 +180,23 @@ class DupeGuru(RegistrableApplication):
|
|||||||
dest_path = dest_path + source_path[1:-1] #Remove drive letter and filename
|
dest_path = dest_path + source_path[1:-1] #Remove drive letter and filename
|
||||||
elif dest_type == 1:
|
elif dest_type == 1:
|
||||||
dest_path = dest_path + source_path[location_path:-1]
|
dest_path = dest_path + source_path[location_path:-1]
|
||||||
try:
|
if not io.exists(dest_path):
|
||||||
if not io.exists(dest_path):
|
io.makedirs(dest_path)
|
||||||
io.makedirs(dest_path)
|
# Raises an EnvironmentError if there's a problem
|
||||||
if copy:
|
if copy:
|
||||||
files.copy(source_path, dest_path)
|
files.copy(source_path, dest_path)
|
||||||
else:
|
else:
|
||||||
files.move(source_path, dest_path)
|
files.move(source_path, dest_path)
|
||||||
self.clean_empty_dirs(source_path[:-1])
|
self.clean_empty_dirs(source_path[:-1])
|
||||||
except EnvironmentError as e:
|
|
||||||
operation = 'Copy' if copy else 'Move'
|
|
||||||
logging.warning('%s operation failed on %s. Error: %s' % (operation, unicode(dupe.path), unicode(e)))
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def copy_or_move_marked(self, copy, destination, recreate_path):
|
def copy_or_move_marked(self, copy, destination, recreate_path):
|
||||||
def do(j):
|
def do(j):
|
||||||
def op(dupe):
|
def op(dupe):
|
||||||
j.add_progress()
|
j.add_progress()
|
||||||
return self.copy_or_move(dupe, copy, destination, recreate_path)
|
self.copy_or_move(dupe, copy, destination, recreate_path)
|
||||||
|
|
||||||
j.start_job(self.results.mark_count)
|
j.start_job(self.results.mark_count)
|
||||||
self.last_op_error_count = self.results.perform_on_marked(op, not copy)
|
self.results.perform_on_marked(op, not copy)
|
||||||
|
|
||||||
self._demo_check()
|
self._demo_check()
|
||||||
jobid = JOB_COPY if copy else JOB_MOVE
|
jobid = JOB_COPY if copy else JOB_MOVE
|
||||||
@@ -195,6 +220,31 @@ class DupeGuru(RegistrableApplication):
|
|||||||
rows.append(row)
|
rows.append(row)
|
||||||
return export.export_to_xhtml(colnames, rows)
|
return export.export_to_xhtml(colnames, rows)
|
||||||
|
|
||||||
|
def invoke_command(self, cmd):
|
||||||
|
"""Calls command `cmd` with %d and %r placeholders replaced.
|
||||||
|
|
||||||
|
Using the current selection, %d is replaced with the currently selected dupe and %r is
|
||||||
|
replaced with that dupe's ref file. If there's no selection, the command is not invoked.
|
||||||
|
If the dupe is a ref, %d and %r will be the same.
|
||||||
|
"""
|
||||||
|
if not self.selected_dupes:
|
||||||
|
return
|
||||||
|
dupe = self.selected_dupes[0]
|
||||||
|
group = self.results.get_group_of_duplicate(dupe)
|
||||||
|
ref = group.ref
|
||||||
|
cmd = cmd.replace('%d', unicode(dupe.path))
|
||||||
|
cmd = cmd.replace('%r', unicode(ref.path))
|
||||||
|
match = re.match(r'"([^"]+)"(.*)', cmd)
|
||||||
|
if match is not None:
|
||||||
|
# This code here is because subprocess. Popen doesn't seem to accept, under Windows,
|
||||||
|
# executable paths with spaces in it, *even* when they're enclosed in "". So this is
|
||||||
|
# a workaround to make the damn thing work.
|
||||||
|
exepath, args = match.groups()
|
||||||
|
path, exename = op.split(exepath)
|
||||||
|
subprocess.Popen(exename + args, shell=True, cwd=path)
|
||||||
|
else:
|
||||||
|
subprocess.Popen(cmd, shell=True)
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
self._start_job(JOB_LOAD, self._do_load)
|
self._start_job(JOB_LOAD, self._do_load)
|
||||||
self.load_ignore_list()
|
self.load_ignore_list()
|
||||||
@@ -203,24 +253,82 @@ class DupeGuru(RegistrableApplication):
|
|||||||
p = op.join(self.appdata, 'ignore_list.xml')
|
p = op.join(self.appdata, 'ignore_list.xml')
|
||||||
self.scanner.ignore_list.load_from_xml(p)
|
self.scanner.ignore_list.load_from_xml(p)
|
||||||
|
|
||||||
def make_reference(self, duplicates):
|
def make_selected_reference(self):
|
||||||
|
dupes = self.without_ref(self.selected_dupes)
|
||||||
changed_groups = set()
|
changed_groups = set()
|
||||||
for dupe in duplicates:
|
for dupe in dupes:
|
||||||
g = self.results.get_group_of_duplicate(dupe)
|
g = self.results.get_group_of_duplicate(dupe)
|
||||||
if g not in changed_groups:
|
if g not in changed_groups:
|
||||||
self.results.make_ref(dupe)
|
self.results.make_ref(dupe)
|
||||||
changed_groups.add(g)
|
changed_groups.add(g)
|
||||||
|
self.notify('results_changed_but_keep_selection')
|
||||||
|
|
||||||
def save(self):
|
def mark_all(self):
|
||||||
|
self.results.mark_all()
|
||||||
|
self.notify('marking_changed')
|
||||||
|
|
||||||
|
def mark_none(self):
|
||||||
|
self.results.mark_none()
|
||||||
|
self.notify('marking_changed')
|
||||||
|
|
||||||
|
def mark_invert(self):
|
||||||
|
self.results.mark_invert()
|
||||||
|
self.notify('marking_changed')
|
||||||
|
|
||||||
|
def mark_dupe(self, dupe, marked):
|
||||||
|
if marked:
|
||||||
|
self.results.mark(dupe)
|
||||||
|
else:
|
||||||
|
self.results.unmark(dupe)
|
||||||
|
self.notify('marking_changed')
|
||||||
|
|
||||||
|
def open_selected(self):
|
||||||
|
if self.selected_dupes:
|
||||||
|
self._open_path(self.selected_dupes[0].path)
|
||||||
|
|
||||||
|
def purge_ignore_list(self):
|
||||||
|
self.scanner.ignore_list.Filter(lambda f,s:op.exists(f) and op.exists(s))
|
||||||
|
|
||||||
|
def remove_directory(self,index):
|
||||||
try:
|
try:
|
||||||
self.directories.save_to_file(op.join(self.appdata, 'last_directories.xml'))
|
del self.directories[index]
|
||||||
self.results.save_to_xml(op.join(self.appdata, 'last_results.xml'))
|
self.notify('directories_changed')
|
||||||
except LookupError:
|
except IndexError:
|
||||||
# This is that weird issue from #39 that sometimes happens when auto-updating with
|
|
||||||
# Sparkle. Just ignore it.
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def remove_duplicates(self, duplicates):
|
||||||
|
self.results.remove_duplicates(self.without_ref(duplicates))
|
||||||
|
self.notify('results_changed_but_keep_selection')
|
||||||
|
|
||||||
|
def remove_marked(self):
|
||||||
|
self.results.perform_on_marked(lambda x:None, True)
|
||||||
|
self.notify('results_changed')
|
||||||
|
|
||||||
|
def remove_selected(self):
|
||||||
|
self.remove_duplicates(self.selected_dupes)
|
||||||
|
|
||||||
|
def rename_selected(self, newname):
|
||||||
|
try:
|
||||||
|
d = self.selected_dupes[0]
|
||||||
|
d.rename(newname)
|
||||||
|
return True
|
||||||
|
except (IndexError, fs.FSError) as e:
|
||||||
|
logging.warning("dupeGuru Warning: %s" % unicode(e))
|
||||||
|
return False
|
||||||
|
|
||||||
|
def reveal_selected(self):
|
||||||
|
if self.selected_dupes:
|
||||||
|
self._reveal_path(self.selected_dupes[0].path)
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
if not op.exists(self.appdata):
|
||||||
|
os.makedirs(self.appdata)
|
||||||
|
self.directories.save_to_file(op.join(self.appdata, 'last_directories.xml'))
|
||||||
|
self.results.save_to_xml(op.join(self.appdata, 'last_results.xml'))
|
||||||
|
|
||||||
def save_ignore_list(self):
|
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)
|
||||||
|
|
||||||
@@ -240,6 +348,14 @@ class DupeGuru(RegistrableApplication):
|
|||||||
self.results.groups = []
|
self.results.groups = []
|
||||||
self._start_job(JOB_SCAN, do)
|
self._start_job(JOB_SCAN, do)
|
||||||
|
|
||||||
|
def toggle_selected_mark_state(self):
|
||||||
|
for dupe in self.selected_dupes:
|
||||||
|
self.results.mark_toggle(dupe)
|
||||||
|
self.notify('marking_changed')
|
||||||
|
|
||||||
|
def without_ref(self, dupes):
|
||||||
|
return [dupe for dupe in dupes if self.results.get_group_of_duplicate(dupe).ref is not dupe]
|
||||||
|
|
||||||
#--- Properties
|
#--- Properties
|
||||||
@property
|
@property
|
||||||
def stat_line(self):
|
def stat_line(self):
|
||||||
|
|||||||
@@ -6,18 +6,17 @@
|
|||||||
# 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/hs_license
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
import objc
|
|
||||||
from Foundation import (NSNotificationCenter, NSUserDefaults, NSSearchPathForDirectoriesInDomains,
|
|
||||||
NSApplicationSupportDirectory, NSUserDomainMask)
|
|
||||||
import logging
|
import logging
|
||||||
import os.path as op
|
import os.path as op
|
||||||
|
|
||||||
from hsutil import cocoa, job
|
from hscommon import cocoa, job
|
||||||
from hsutil.cocoa import install_exception_hook
|
from hscommon.cocoa import install_exception_hook
|
||||||
from hsutil.misc import stripnone
|
from hscommon.cocoa.objcmin import (NSNotificationCenter, NSUserDefaults,
|
||||||
from hsutil.reg import RegistrationRequired
|
NSSearchPathForDirectoriesInDomains, NSApplicationSupportDirectory, NSUserDomainMask,
|
||||||
|
NSWorkspace)
|
||||||
|
from hscommon.reg import RegistrationRequired
|
||||||
|
|
||||||
from . import app, fs
|
from . import app
|
||||||
|
|
||||||
JOBID2TITLE = {
|
JOBID2TITLE = {
|
||||||
app.JOB_SCAN: "Scanning for duplicates",
|
app.JOB_SCAN: "Scanning for duplicates",
|
||||||
@@ -46,23 +45,15 @@ class DupeGuru(app.DupeGuru):
|
|||||||
appdata = op.join(appsupport, appdata_subdir)
|
appdata = op.join(appsupport, appdata_subdir)
|
||||||
app.DupeGuru.__init__(self, data_module, appdata, appid)
|
app.DupeGuru.__init__(self, data_module, appdata, appid)
|
||||||
self.progress = cocoa.ThreadedJobPerformer()
|
self.progress = cocoa.ThreadedJobPerformer()
|
||||||
self.display_delta_values = False
|
|
||||||
self.selected_dupes = []
|
|
||||||
self.RefreshDetailsTable(None,None)
|
|
||||||
|
|
||||||
#--- Override
|
#--- Override
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _recycle_dupe(dupe):
|
def _open_path(path):
|
||||||
# local import because first appkit import takes a lot of memory. we want to avoid it.
|
NSWorkspace.sharedWorkspace().openFile_(unicode(path))
|
||||||
from AppKit import NSWorkspace, NSWorkspaceRecycleOperation
|
|
||||||
directory = unicode(dupe.path[:-1])
|
@staticmethod
|
||||||
filename = dupe.name
|
def _reveal_path(path):
|
||||||
if objc.__version__ == '1.4': # For a while, we have to support this.
|
NSWorkspace.sharedWorkspace().selectFile_inFileViewerRootedAtPath_(unicode(path), '')
|
||||||
result, tag = NSWorkspace.sharedWorkspace().performFileOperation_source_destination_files_tag_(
|
|
||||||
NSWorkspaceRecycleOperation, directory, '', [filename])
|
|
||||||
else:
|
|
||||||
result, tag = NSWorkspace.sharedWorkspace().performFileOperation_source_destination_files_tag_(
|
|
||||||
NSWorkspaceRecycleOperation, directory, '', [filename], None)
|
|
||||||
|
|
||||||
def _start_job(self, jobid, func):
|
def _start_job(self, jobid, func):
|
||||||
try:
|
try:
|
||||||
@@ -74,93 +65,12 @@ 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)
|
||||||
|
|
||||||
#---Helpers
|
|
||||||
def GetObjects(self,node_path):
|
|
||||||
#returns a tuple g,d
|
|
||||||
try:
|
|
||||||
g = self.results.groups[node_path[0]]
|
|
||||||
if len(node_path) == 2:
|
|
||||||
return (g,self.results.groups[node_path[0]].dupes[node_path[1]])
|
|
||||||
else:
|
|
||||||
return (g,None)
|
|
||||||
except IndexError:
|
|
||||||
return (None,None)
|
|
||||||
|
|
||||||
def get_folder_path(self, node_path, curr_path=None):
|
|
||||||
if not node_path:
|
|
||||||
return curr_path
|
|
||||||
current_index = node_path[0]
|
|
||||||
if curr_path is None:
|
|
||||||
curr_path = self.directories[current_index]
|
|
||||||
else:
|
|
||||||
curr_path = self.directories.get_subfolders(curr_path)[current_index]
|
|
||||||
return self.get_folder_path(node_path[1:], curr_path)
|
|
||||||
|
|
||||||
def RefreshDetailsTable(self,dupe,group):
|
|
||||||
l1 = self._get_display_info(dupe, group, False)
|
|
||||||
# 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
|
|
||||||
l2 = self._get_display_info(ref, group, False)
|
|
||||||
names = [c['display'] for c in self.data.COLUMNS]
|
|
||||||
self.details_table = zip(names,l1,l2)
|
|
||||||
|
|
||||||
#---Public
|
#---Public
|
||||||
def AddSelectedToIgnoreList(self):
|
|
||||||
for dupe in self.selected_dupes:
|
|
||||||
self.add_to_ignore_list(dupe)
|
|
||||||
|
|
||||||
copy_or_move_marked = demo_method(app.DupeGuru.copy_or_move_marked)
|
copy_or_move_marked = demo_method(app.DupeGuru.copy_or_move_marked)
|
||||||
delete_marked = demo_method(app.DupeGuru.delete_marked)
|
delete_marked = demo_method(app.DupeGuru.delete_marked)
|
||||||
|
|
||||||
def MakeSelectedReference(self):
|
|
||||||
self.make_reference(self.selected_dupes)
|
|
||||||
|
|
||||||
def OpenSelected(self):
|
|
||||||
# local import because first appkit import takes a lot of memory. we want to avoid it.
|
|
||||||
from AppKit import NSWorkspace
|
|
||||||
if self.selected_dupes:
|
|
||||||
path = unicode(self.selected_dupes[0].path)
|
|
||||||
NSWorkspace.sharedWorkspace().openFile_(path)
|
|
||||||
|
|
||||||
def PurgeIgnoreList(self):
|
|
||||||
self.scanner.ignore_list.Filter(lambda f,s:op.exists(f) and op.exists(s))
|
|
||||||
|
|
||||||
def RefreshDetailsWithSelected(self):
|
|
||||||
if self.selected_dupes:
|
|
||||||
self.RefreshDetailsTable(
|
|
||||||
self.selected_dupes[0],
|
|
||||||
self.results.get_group_of_duplicate(self.selected_dupes[0])
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.RefreshDetailsTable(None,None)
|
|
||||||
|
|
||||||
def RemoveDirectory(self,index):
|
|
||||||
try:
|
|
||||||
del self.directories[index]
|
|
||||||
except IndexError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def RemoveSelected(self):
|
|
||||||
self.results.remove_duplicates(self.selected_dupes)
|
|
||||||
|
|
||||||
def RenameSelected(self, newname):
|
|
||||||
try:
|
|
||||||
d = self.selected_dupes[0]
|
|
||||||
d.rename(newname)
|
|
||||||
return True
|
|
||||||
except (IndexError, fs.FSError) as e:
|
|
||||||
logging.warning("dupeGuru Warning: %s" % unicode(e))
|
|
||||||
return False
|
|
||||||
|
|
||||||
def RevealSelected(self):
|
|
||||||
# local import because first appkit import takes a lot of memory. we want to avoid it.
|
|
||||||
from AppKit import NSWorkspace
|
|
||||||
if self.selected_dupes:
|
|
||||||
path = unicode(self.selected_dupes[0].path)
|
|
||||||
NSWorkspace.sharedWorkspace().selectFile_inFileViewerRootedAtPath_(path,'')
|
|
||||||
|
|
||||||
def start_scanning(self):
|
def start_scanning(self):
|
||||||
self.RefreshDetailsTable(None, None)
|
self._select_dupes([])
|
||||||
try:
|
try:
|
||||||
app.DupeGuru.start_scanning(self)
|
app.DupeGuru.start_scanning(self)
|
||||||
return 0
|
return 0
|
||||||
@@ -169,144 +79,3 @@ class DupeGuru(app.DupeGuru):
|
|||||||
except app.AllFilesAreRefError:
|
except app.AllFilesAreRefError:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def selected_result_node_paths(self):
|
|
||||||
def get_path(dupe):
|
|
||||||
try:
|
|
||||||
group = self.results.get_group_of_duplicate(dupe)
|
|
||||||
groupindex = self.results.groups.index(group)
|
|
||||||
if dupe is group.ref:
|
|
||||||
return [groupindex]
|
|
||||||
dupeindex = group.dupes.index(dupe)
|
|
||||||
return [groupindex, dupeindex]
|
|
||||||
except ValueError: # dupe not in there
|
|
||||||
return None
|
|
||||||
|
|
||||||
dupes = self.selected_dupes
|
|
||||||
return stripnone(get_path(dupe) for dupe in dupes)
|
|
||||||
|
|
||||||
def selected_powermarker_node_paths(self):
|
|
||||||
def get_path(dupe):
|
|
||||||
try:
|
|
||||||
dupeindex = self.results.dupes.index(dupe)
|
|
||||||
return [dupeindex]
|
|
||||||
except ValueError: # dupe not in there
|
|
||||||
return None
|
|
||||||
|
|
||||||
dupes = self.selected_dupes
|
|
||||||
return stripnone(get_path(dupe) for dupe in dupes)
|
|
||||||
|
|
||||||
def SelectResultNodePaths(self,node_paths):
|
|
||||||
def extract_dupe(t):
|
|
||||||
g,d = t
|
|
||||||
if d is not None:
|
|
||||||
return d
|
|
||||||
else:
|
|
||||||
if g is not None:
|
|
||||||
return g.ref
|
|
||||||
|
|
||||||
selected = [extract_dupe(self.GetObjects(p)) for p in node_paths]
|
|
||||||
self.selected_dupes = [dupe for dupe in selected if dupe is not None]
|
|
||||||
|
|
||||||
def SelectPowerMarkerNodePaths(self,node_paths):
|
|
||||||
rows = [p[0] for p in node_paths]
|
|
||||||
self.selected_dupes = [
|
|
||||||
self.results.dupes[row] for row in rows if row in xrange(len(self.results.dupes))
|
|
||||||
]
|
|
||||||
|
|
||||||
def SetDirectoryState(self, node_path, state):
|
|
||||||
p = self.get_folder_path(node_path)
|
|
||||||
self.directories.set_state(p, state)
|
|
||||||
|
|
||||||
def sort_dupes(self,key,asc):
|
|
||||||
self.results.sort_dupes(key,asc,self.display_delta_values)
|
|
||||||
|
|
||||||
def sort_groups(self,key,asc):
|
|
||||||
self.results.sort_groups(key,asc)
|
|
||||||
|
|
||||||
def ToggleSelectedMarkState(self):
|
|
||||||
for dupe in self.selected_dupes:
|
|
||||||
self.results.mark_toggle(dupe)
|
|
||||||
|
|
||||||
#---Data
|
|
||||||
def GetOutlineViewMaxLevel(self, tag):
|
|
||||||
if tag == 0:
|
|
||||||
return 2
|
|
||||||
elif tag == 1:
|
|
||||||
return 0
|
|
||||||
elif tag == 2:
|
|
||||||
return 1
|
|
||||||
|
|
||||||
def GetOutlineViewChildCounts(self, tag, node_path):
|
|
||||||
if self.progress._job_running:
|
|
||||||
return []
|
|
||||||
if tag == 0: #Normal results
|
|
||||||
assert not node_path # no other value is possible
|
|
||||||
return [len(g.dupes) for g in self.results.groups]
|
|
||||||
elif tag == 1: #Directories
|
|
||||||
try:
|
|
||||||
if node_path:
|
|
||||||
path = self.get_folder_path(node_path)
|
|
||||||
subfolders = self.directories.get_subfolders(path)
|
|
||||||
else:
|
|
||||||
subfolders = self.directories
|
|
||||||
return [len(self.directories.get_subfolders(path)) for path in subfolders]
|
|
||||||
except IndexError: # node_path out of range
|
|
||||||
return []
|
|
||||||
else: #Power Marker
|
|
||||||
assert not node_path # no other value is possible
|
|
||||||
return [0 for d in self.results.dupes]
|
|
||||||
|
|
||||||
def GetOutlineViewValues(self, tag, node_path):
|
|
||||||
if self.progress._job_running:
|
|
||||||
return
|
|
||||||
if not node_path:
|
|
||||||
return
|
|
||||||
if tag in (0,2): #Normal results / Power Marker
|
|
||||||
if tag == 0:
|
|
||||||
g, d = self.GetObjects(node_path)
|
|
||||||
if d is None:
|
|
||||||
d = g.ref
|
|
||||||
else:
|
|
||||||
d = self.results.dupes[node_path[0]]
|
|
||||||
g = self.results.get_group_of_duplicate(d)
|
|
||||||
result = self._get_display_info(d, g, self.display_delta_values)
|
|
||||||
return result
|
|
||||||
elif tag == 1: #Directories
|
|
||||||
try:
|
|
||||||
path = self.get_folder_path(node_path)
|
|
||||||
name = unicode(path) if len(node_path) == 1 else path[-1]
|
|
||||||
return [name, self.directories.get_state(path)]
|
|
||||||
except IndexError: # node_path out of range
|
|
||||||
return []
|
|
||||||
|
|
||||||
def GetOutlineViewMarked(self, tag, node_path):
|
|
||||||
# 0=unmarked 1=marked 2=unmarkable
|
|
||||||
if self.progress._job_running:
|
|
||||||
return
|
|
||||||
if not node_path:
|
|
||||||
return 2
|
|
||||||
if tag == 1: #Directories
|
|
||||||
return 2
|
|
||||||
if tag == 0: #Normal results
|
|
||||||
g, d = self.GetObjects(node_path)
|
|
||||||
else: #Power Marker
|
|
||||||
d = self.results.dupes[node_path[0]]
|
|
||||||
if (d is None) or (not self.results.is_markable(d)):
|
|
||||||
return 2
|
|
||||||
elif self.results.is_marked(d):
|
|
||||||
return 1
|
|
||||||
else:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def GetTableViewCount(self, tag):
|
|
||||||
if self.progress._job_running:
|
|
||||||
return 0
|
|
||||||
return len(self.details_table)
|
|
||||||
|
|
||||||
def GetTableViewMarkedIndexes(self,tag):
|
|
||||||
return []
|
|
||||||
|
|
||||||
def GetTableViewValues(self,tag,row):
|
|
||||||
return self.details_table[row]
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
214
core/app_cocoa_inter.py
Normal file
214
core/app_cocoa_inter.py
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Created By: Virgil Dupras
|
||||||
|
# Created On: 2010-02-02
|
||||||
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
#
|
||||||
|
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||||
|
# which should be included with this package. The terms are also available at
|
||||||
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
|
# Common interface for all editions' dg_cocoa unit.
|
||||||
|
|
||||||
|
from hscommon.cocoa.inter import signature, PyTable, PyOutline, PyGUIObject, PyRegistrable
|
||||||
|
|
||||||
|
from .gui.details_panel import DetailsPanel
|
||||||
|
from .gui.directory_tree import DirectoryTree
|
||||||
|
from .gui.problem_dialog import ProblemDialog
|
||||||
|
from .gui.problem_table import ProblemTable
|
||||||
|
from .gui.result_tree import ResultTree
|
||||||
|
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(PyRegistrable):
|
||||||
|
#---Directories
|
||||||
|
def addDirectory_(self, directory):
|
||||||
|
return self.py.add_directory(directory)
|
||||||
|
|
||||||
|
def removeDirectory_(self, index):
|
||||||
|
self.py.remove_directory(index)
|
||||||
|
|
||||||
|
#---Results
|
||||||
|
def clearIgnoreList(self):
|
||||||
|
self.py.scanner.ignore_list.Clear()
|
||||||
|
|
||||||
|
def doScan(self):
|
||||||
|
return self.py.start_scanning()
|
||||||
|
|
||||||
|
def exportToXHTMLwithColumns_(self, column_ids):
|
||||||
|
return self.py.export_to_xhtml(column_ids)
|
||||||
|
|
||||||
|
def loadIgnoreList(self):
|
||||||
|
self.py.load_ignore_list()
|
||||||
|
|
||||||
|
def loadResults(self):
|
||||||
|
self.py.load()
|
||||||
|
|
||||||
|
def markAll(self):
|
||||||
|
self.py.mark_all()
|
||||||
|
|
||||||
|
def markNone(self):
|
||||||
|
self.py.mark_none()
|
||||||
|
|
||||||
|
def markInvert(self):
|
||||||
|
self.py.mark_invert()
|
||||||
|
|
||||||
|
def purgeIgnoreList(self):
|
||||||
|
self.py.purge_ignore_list()
|
||||||
|
|
||||||
|
def toggleSelectedMark(self):
|
||||||
|
self.py.toggle_selected_mark_state()
|
||||||
|
|
||||||
|
def saveIgnoreList(self):
|
||||||
|
self.py.save_ignore_list()
|
||||||
|
|
||||||
|
def saveResults(self):
|
||||||
|
self.py.save()
|
||||||
|
|
||||||
|
#---Actions
|
||||||
|
def addSelectedToIgnoreList(self):
|
||||||
|
self.py.add_selected_to_ignore_list()
|
||||||
|
|
||||||
|
def deleteMarked(self):
|
||||||
|
self.py.delete_marked()
|
||||||
|
|
||||||
|
def applyFilter_(self, filter):
|
||||||
|
self.py.apply_filter(filter)
|
||||||
|
|
||||||
|
def makeSelectedReference(self):
|
||||||
|
self.py.make_selected_reference()
|
||||||
|
|
||||||
|
def copyOrMove_markedTo_recreatePath_(self, copy, destination, recreate_path):
|
||||||
|
self.py.copy_or_move_marked(copy, destination, recreate_path)
|
||||||
|
|
||||||
|
def openSelected(self):
|
||||||
|
self.py.open_selected()
|
||||||
|
|
||||||
|
def removeMarked(self):
|
||||||
|
self.py.remove_marked()
|
||||||
|
|
||||||
|
def renameSelected_(self,newname):
|
||||||
|
return self.py.rename_selected(newname)
|
||||||
|
|
||||||
|
def revealSelected(self):
|
||||||
|
self.py.reveal_selected()
|
||||||
|
|
||||||
|
def invokeCommand_(self, cmd):
|
||||||
|
self.py.invoke_command(cmd)
|
||||||
|
|
||||||
|
#---Information
|
||||||
|
def getIgnoreListCount(self):
|
||||||
|
return len(self.py.scanner.ignore_list)
|
||||||
|
|
||||||
|
def getMarkCount(self):
|
||||||
|
return self.py.results.mark_count
|
||||||
|
|
||||||
|
@signature('i@:')
|
||||||
|
def scanWasProblematic(self):
|
||||||
|
return bool(self.py.results.problems)
|
||||||
|
|
||||||
|
#---Properties
|
||||||
|
def setMixFileKind_(self, mix_file_kind):
|
||||||
|
self.py.scanner.mix_file_kind = mix_file_kind
|
||||||
|
|
||||||
|
def setEscapeFilterRegexp_(self, escape_filter_regexp):
|
||||||
|
self.py.options['escape_filter_regexp'] = escape_filter_regexp
|
||||||
|
|
||||||
|
def setRemoveEmptyFolders_(self, remove_empty_folders):
|
||||||
|
self.py.options['clean_empty_dirs'] = remove_empty_folders
|
||||||
|
|
||||||
|
#---Worker
|
||||||
|
def getJobProgress(self):
|
||||||
|
return self.py.progress.last_progress
|
||||||
|
|
||||||
|
def getJobDesc(self):
|
||||||
|
return self.py.progress.last_desc
|
||||||
|
|
||||||
|
def cancelJob(self):
|
||||||
|
self.py.progress.job_cancelled = True
|
||||||
|
|
||||||
|
def jobCompleted_(self, jobid):
|
||||||
|
self.py._job_completed(jobid)
|
||||||
|
|
||||||
|
|
||||||
|
class PyDetailsPanel(PyGUIObject):
|
||||||
|
py_class = DetailsPanel
|
||||||
|
@signature('i@:')
|
||||||
|
def numberOfRows(self):
|
||||||
|
return self.py.row_count()
|
||||||
|
|
||||||
|
@signature('@@:@i')
|
||||||
|
def valueForColumn_row_(self, column, row):
|
||||||
|
return self.py.row(row)[int(column)]
|
||||||
|
|
||||||
|
|
||||||
|
class PyDirectoryOutline(PyOutline):
|
||||||
|
py_class = DirectoryTree
|
||||||
|
|
||||||
|
def addDirectory_(self, path):
|
||||||
|
self.py.add_directory(path)
|
||||||
|
|
||||||
|
|
||||||
|
class PyResultOutline(PyOutline):
|
||||||
|
py_class = ResultTree
|
||||||
|
|
||||||
|
@signature('c@:')
|
||||||
|
def powerMarkerMode(self):
|
||||||
|
return self.py.power_marker
|
||||||
|
|
||||||
|
@signature('v@:c')
|
||||||
|
def setPowerMarkerMode_(self, value):
|
||||||
|
self.py.power_marker = value
|
||||||
|
|
||||||
|
@signature('c@:')
|
||||||
|
def deltaValuesMode(self):
|
||||||
|
return self.py.delta_values
|
||||||
|
|
||||||
|
@signature('v@:c')
|
||||||
|
def setDeltaValuesMode_(self, value):
|
||||||
|
self.py.delta_values = value
|
||||||
|
|
||||||
|
@signature('@@:@i')
|
||||||
|
def valueForPath_column_(self, path, column):
|
||||||
|
return self.py.get_node_value(path, column)
|
||||||
|
|
||||||
|
@signature('c@:@')
|
||||||
|
def renameSelected_(self, newname):
|
||||||
|
return self.py.rename_selected(newname)
|
||||||
|
|
||||||
|
@signature('v@:ic')
|
||||||
|
def sortBy_ascending_(self, key, asc):
|
||||||
|
self.py.sort(key, asc)
|
||||||
|
|
||||||
|
def markSelected(self):
|
||||||
|
self.py.app.toggle_selected_mark_state()
|
||||||
|
|
||||||
|
def removeSelected(self):
|
||||||
|
self.py.app.remove_selected()
|
||||||
|
|
||||||
|
def rootChildrenCounts(self):
|
||||||
|
return self.py.root_children_counts()
|
||||||
|
|
||||||
|
# python --> cocoa
|
||||||
|
def invalidate_markings(self):
|
||||||
|
self.cocoa.invalidateMarkings()
|
||||||
|
|
||||||
|
|
||||||
|
class PyStatsLabel(PyGUIObject):
|
||||||
|
py_class = StatsLabel
|
||||||
|
|
||||||
|
def display(self):
|
||||||
|
return self.py.display
|
||||||
|
|
||||||
|
|
||||||
|
class PyProblemDialog(PyGUIObject):
|
||||||
|
py_class = ProblemDialog
|
||||||
|
|
||||||
|
def revealSelected(self):
|
||||||
|
self.py.reveal_selected_dupe()
|
||||||
|
|
||||||
|
|
||||||
|
class PyProblemTable(PyTable):
|
||||||
|
py_class = ProblemTable
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
# which should be included with this package. The terms are also available at
|
# which should be included with this package. The terms are also available at
|
||||||
# http://www.hardcoded.net/licenses/hs_license
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
import xml.dom.minidom
|
from lxml import etree
|
||||||
|
|
||||||
from hsutil import io
|
from hsutil import io
|
||||||
from hsutil.files import FileOrPath
|
from hsutil.files import FileOrPath
|
||||||
@@ -126,38 +126,38 @@ class Directories(object):
|
|||||||
|
|
||||||
def load_from_file(self, infile):
|
def load_from_file(self, infile):
|
||||||
try:
|
try:
|
||||||
doc = xml.dom.minidom.parse(infile)
|
root = etree.parse(infile).getroot()
|
||||||
except:
|
except:
|
||||||
return
|
return
|
||||||
root_path_nodes = doc.getElementsByTagName('root_directory')
|
for rdn in root.iterchildren('root_directory'):
|
||||||
for rdn in root_path_nodes:
|
attrib = rdn.attrib
|
||||||
if not rdn.getAttributeNode('path'):
|
if 'path' not in attrib:
|
||||||
continue
|
continue
|
||||||
path = rdn.getAttributeNode('path').nodeValue
|
path = attrib['path']
|
||||||
try:
|
try:
|
||||||
self.add_path(Path(path))
|
self.add_path(Path(path))
|
||||||
except (AlreadyThereError, InvalidPathError):
|
except (AlreadyThereError, InvalidPathError):
|
||||||
pass
|
pass
|
||||||
state_nodes = doc.getElementsByTagName('state')
|
for sn in root.iterchildren('state'):
|
||||||
for sn in state_nodes:
|
attrib = sn.attrib
|
||||||
if not (sn.getAttributeNode('path') and sn.getAttributeNode('value')):
|
if not ('path' in attrib and 'value' in attrib):
|
||||||
continue
|
continue
|
||||||
path = sn.getAttributeNode('path').nodeValue
|
path = attrib['path']
|
||||||
state = sn.getAttributeNode('value').nodeValue
|
state = attrib['value']
|
||||||
self.set_state(Path(path), int(state))
|
self.set_state(Path(path), int(state))
|
||||||
|
|
||||||
def save_to_file(self,outfile):
|
def save_to_file(self, outfile):
|
||||||
with FileOrPath(outfile, 'wb') as fp:
|
with FileOrPath(outfile, 'wb') as fp:
|
||||||
doc = xml.dom.minidom.Document()
|
root = etree.Element('directories')
|
||||||
root = doc.appendChild(doc.createElement('directories'))
|
|
||||||
for root_path in self:
|
for root_path in self:
|
||||||
root_path_node = root.appendChild(doc.createElement('root_directory'))
|
root_path_node = etree.SubElement(root, 'root_directory')
|
||||||
root_path_node.setAttribute('path', unicode(root_path).encode('utf-8'))
|
root_path_node.set('path', unicode(root_path))
|
||||||
for path, state in self.states.iteritems():
|
for path, state in self.states.iteritems():
|
||||||
state_node = root.appendChild(doc.createElement('state'))
|
state_node = etree.SubElement(root, 'state')
|
||||||
state_node.setAttribute('path', unicode(path).encode('utf-8'))
|
state_node.set('path', unicode(path))
|
||||||
state_node.setAttribute('value', str(state))
|
state_node.set('value', unicode(state))
|
||||||
doc.writexml(fp, '\t', '\t', '\n', encoding='utf-8')
|
tree = etree.ElementTree(root)
|
||||||
|
tree.write(fp, encoding='utf-8')
|
||||||
|
|
||||||
def set_state(self, path, state):
|
def set_state(self, path, state):
|
||||||
if self.get_state(path) == state:
|
if self.get_state(path) == state:
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ from unicodedata import normalize
|
|||||||
|
|
||||||
from hsutil.misc import flatten
|
from hsutil.misc import flatten
|
||||||
from hsutil.str import multi_replace
|
from hsutil.str import multi_replace
|
||||||
from hsutil import job
|
from hscommon import job
|
||||||
|
|
||||||
(WEIGHT_WORDS,
|
(WEIGHT_WORDS,
|
||||||
MATCH_SIMILAR_WORDS,
|
MATCH_SIMILAR_WORDS,
|
||||||
|
|||||||
10
core/fs.py
10
core/fs.py
@@ -160,8 +160,16 @@ def get_file(path, fileclasses=[File]):
|
|||||||
|
|
||||||
def get_files(path, fileclasses=[File]):
|
def get_files(path, fileclasses=[File]):
|
||||||
assert all(issubclass(fileclass, File) for fileclass in fileclasses)
|
assert all(issubclass(fileclass, File) for fileclass in fileclasses)
|
||||||
|
def combine_paths(p1, p2):
|
||||||
|
try:
|
||||||
|
return p1 + p2
|
||||||
|
except Exception:
|
||||||
|
# This is temporary debug logging for #84.
|
||||||
|
logging.warning("Failed to combine %r and %r.", p1, p2)
|
||||||
|
raise
|
||||||
|
|
||||||
try:
|
try:
|
||||||
paths = [path + name for name in io.listdir(path)]
|
paths = [combine_paths(path, name) for name in io.listdir(path)]
|
||||||
result = []
|
result = []
|
||||||
for path in paths:
|
for path in paths:
|
||||||
file = get_file(path, fileclasses=fileclasses)
|
file = get_file(path, fileclasses=fileclasses)
|
||||||
|
|||||||
0
core/gui/__init__.py
Normal file
0
core/gui/__init__.py
Normal file
35
core/gui/base.py
Normal file
35
core/gui/base.py
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Created By: Virgil Dupras
|
||||||
|
# Created On: 2010-02-06
|
||||||
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
#
|
||||||
|
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||||
|
# which should be included with this package. The terms are also available at
|
||||||
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
|
from hscommon.notify import Listener
|
||||||
|
|
||||||
|
class GUIObject(Listener):
|
||||||
|
def __init__(self, view, app):
|
||||||
|
Listener.__init__(self, app)
|
||||||
|
self.view = view
|
||||||
|
self.app = app
|
||||||
|
|
||||||
|
def directories_changed(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def dupes_selected(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def marking_changed(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def problems_changed(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def results_changed(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def results_changed_but_keep_selection(self):
|
||||||
|
pass
|
||||||
|
|
||||||
48
core/gui/details_panel.py
Normal file
48
core/gui/details_panel.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Created By: Virgil Dupras
|
||||||
|
# Created On: 2010-02-05
|
||||||
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
#
|
||||||
|
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||||
|
# which should be included with this package. The terms are also available at
|
||||||
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
|
from .base import GUIObject
|
||||||
|
|
||||||
|
class DetailsPanel(GUIObject):
|
||||||
|
def __init__(self, view, app):
|
||||||
|
GUIObject.__init__(self, view, app)
|
||||||
|
self._table = []
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
GUIObject.connect(self)
|
||||||
|
self._refresh()
|
||||||
|
self.view.refresh()
|
||||||
|
|
||||||
|
#--- Private
|
||||||
|
def _refresh(self):
|
||||||
|
if self.app.selected_dupes:
|
||||||
|
dupe = self.app.selected_dupes[0]
|
||||||
|
group = self.app.results.get_group_of_duplicate(dupe)
|
||||||
|
else:
|
||||||
|
dupe = None
|
||||||
|
group = None
|
||||||
|
l1 = self.app._get_display_info(dupe, group, False)
|
||||||
|
# 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
|
||||||
|
l2 = self.app._get_display_info(ref, group, False)
|
||||||
|
names = [c['display'] for c in self.app.data.COLUMNS]
|
||||||
|
self._table = zip(names, l1, l2)
|
||||||
|
|
||||||
|
#--- Public
|
||||||
|
def row_count(self):
|
||||||
|
return len(self._table)
|
||||||
|
|
||||||
|
def row(self, row_index):
|
||||||
|
return self._table[row_index]
|
||||||
|
|
||||||
|
#--- Event Handlers
|
||||||
|
def dupes_selected(self):
|
||||||
|
self._refresh()
|
||||||
|
self.view.refresh()
|
||||||
|
|
||||||
74
core/gui/directory_tree.py
Normal file
74
core/gui/directory_tree.py
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Created By: Virgil Dupras
|
||||||
|
# Created On: 2010-02-06
|
||||||
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
#
|
||||||
|
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||||
|
# which should be included with this package. The terms are also available at
|
||||||
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
|
from hsgui.tree import Tree, Node
|
||||||
|
|
||||||
|
from ..directories import STATE_NORMAL, STATE_REFERENCE, STATE_EXCLUDED
|
||||||
|
from .base import GUIObject
|
||||||
|
|
||||||
|
STATE_ORDER = [STATE_NORMAL, STATE_REFERENCE, STATE_EXCLUDED]
|
||||||
|
|
||||||
|
# Lazily loads children
|
||||||
|
class DirectoryNode(Node):
|
||||||
|
def __init__(self, app, path, name):
|
||||||
|
Node.__init__(self, name)
|
||||||
|
self._app = app
|
||||||
|
self._directory_path = path
|
||||||
|
self._loaded = False
|
||||||
|
self._state = STATE_ORDER.index(self._app.directories.get_state(path))
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
if not self._loaded:
|
||||||
|
self._load()
|
||||||
|
return Node.__len__(self)
|
||||||
|
|
||||||
|
def _load(self):
|
||||||
|
self.clear()
|
||||||
|
subpaths = self._app.directories.get_subfolders(self._directory_path)
|
||||||
|
for path in subpaths:
|
||||||
|
self.append(DirectoryNode(self._app, path, path[-1]))
|
||||||
|
self._loaded = True
|
||||||
|
|
||||||
|
# The state propery is an index to the combobox
|
||||||
|
@property
|
||||||
|
def state(self):
|
||||||
|
return self._state
|
||||||
|
|
||||||
|
@state.setter
|
||||||
|
def state(self, value):
|
||||||
|
if value == self._state:
|
||||||
|
return
|
||||||
|
self._state = value
|
||||||
|
state = STATE_ORDER[value]
|
||||||
|
self._app.directories.set_state(self._directory_path, state)
|
||||||
|
|
||||||
|
|
||||||
|
class DirectoryTree(GUIObject, Tree):
|
||||||
|
def __init__(self, view, app):
|
||||||
|
GUIObject.__init__(self, view, app)
|
||||||
|
Tree.__init__(self)
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
GUIObject.connect(self)
|
||||||
|
self._refresh()
|
||||||
|
self.view.refresh()
|
||||||
|
|
||||||
|
def _refresh(self):
|
||||||
|
self.clear()
|
||||||
|
for path in self.app.directories:
|
||||||
|
self.append(DirectoryNode(self.app, path, unicode(path)))
|
||||||
|
|
||||||
|
def add_directory(self, path):
|
||||||
|
self.app.add_directory(path)
|
||||||
|
|
||||||
|
#--- Event Handlers
|
||||||
|
def directories_changed(self):
|
||||||
|
self._refresh()
|
||||||
|
self.view.refresh()
|
||||||
|
|
||||||
31
core/gui/problem_dialog.py
Normal file
31
core/gui/problem_dialog.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Created By: Virgil Dupras
|
||||||
|
# Created On: 2010-04-12
|
||||||
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
#
|
||||||
|
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||||
|
# which should be included with this package. The terms are also available at
|
||||||
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
|
from hscommon.notify import Broadcaster
|
||||||
|
|
||||||
|
from .base import GUIObject
|
||||||
|
|
||||||
|
class ProblemDialog(GUIObject, Broadcaster):
|
||||||
|
def __init__(self, view, app):
|
||||||
|
GUIObject.__init__(self, view, app)
|
||||||
|
Broadcaster.__init__(self)
|
||||||
|
self._selected_dupe = None
|
||||||
|
|
||||||
|
def reveal_selected_dupe(self):
|
||||||
|
if self._selected_dupe is not None:
|
||||||
|
self.app._reveal_path(self._selected_dupe.path)
|
||||||
|
|
||||||
|
def select_dupe(self, dupe):
|
||||||
|
self._selected_dupe = dupe
|
||||||
|
|
||||||
|
#--- Event Handlers
|
||||||
|
def problems_changed(self):
|
||||||
|
self._selected_dupe = None
|
||||||
|
self.notify('problems_changed')
|
||||||
|
|
||||||
43
core/gui/problem_table.py
Normal file
43
core/gui/problem_table.py
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Created By: Virgil Dupras
|
||||||
|
# Created On: 2010-04-12
|
||||||
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
#
|
||||||
|
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||||
|
# which should be included with this package. The terms are also available at
|
||||||
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
|
from hscommon.notify import Listener
|
||||||
|
from hsgui.table import GUITable, Row
|
||||||
|
|
||||||
|
class ProblemTable(GUITable, Listener):
|
||||||
|
def __init__(self, view, problem_dialog):
|
||||||
|
GUITable.__init__(self)
|
||||||
|
Listener.__init__(self, problem_dialog)
|
||||||
|
self.view = view
|
||||||
|
self.dialog = problem_dialog
|
||||||
|
|
||||||
|
#--- Override
|
||||||
|
def _update_selection(self):
|
||||||
|
row = self.selected_row
|
||||||
|
dupe = row.dupe if row is not None else None
|
||||||
|
self.dialog.select_dupe(dupe)
|
||||||
|
|
||||||
|
def _fill(self):
|
||||||
|
problems = self.dialog.app.results.problems
|
||||||
|
for dupe, msg in problems:
|
||||||
|
self.append(ProblemRow(self, dupe, msg))
|
||||||
|
|
||||||
|
#--- Event handlers
|
||||||
|
def problems_changed(self):
|
||||||
|
self.refresh()
|
||||||
|
self.view.refresh()
|
||||||
|
|
||||||
|
|
||||||
|
class ProblemRow(Row):
|
||||||
|
def __init__(self, table, dupe, msg):
|
||||||
|
Row.__init__(self, table)
|
||||||
|
self.dupe = dupe
|
||||||
|
self.msg = msg
|
||||||
|
self.path = unicode(dupe.path)
|
||||||
|
|
||||||
159
core/gui/result_tree.py
Normal file
159
core/gui/result_tree.py
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Created By: Virgil Dupras
|
||||||
|
# Created On: 2010-02-11
|
||||||
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
#
|
||||||
|
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||||
|
# which should be included with this package. The terms are also available at
|
||||||
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
|
from operator import attrgetter
|
||||||
|
|
||||||
|
from hsgui.tree import Tree, Node
|
||||||
|
|
||||||
|
from .base import GUIObject
|
||||||
|
|
||||||
|
class DupeNode(Node):
|
||||||
|
def __init__(self, app, group, dupe):
|
||||||
|
Node.__init__(self, '')
|
||||||
|
self._app = app
|
||||||
|
self._group = group
|
||||||
|
self._dupe = dupe
|
||||||
|
self._data = None
|
||||||
|
self._data_delta = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def data(self):
|
||||||
|
if self._data is None:
|
||||||
|
self._data = self._app._get_display_info(self._dupe, self._group, False)
|
||||||
|
return self._data
|
||||||
|
|
||||||
|
@property
|
||||||
|
def data_delta(self):
|
||||||
|
if self._data_delta is None:
|
||||||
|
self._data_delta = self._app._get_display_info(self._dupe, self._group, True)
|
||||||
|
return self._data_delta
|
||||||
|
|
||||||
|
@property
|
||||||
|
def markable(self):
|
||||||
|
return self._app.results.is_markable(self._dupe)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def marked(self):
|
||||||
|
return self._app.results.is_marked(self._dupe)
|
||||||
|
|
||||||
|
@marked.setter
|
||||||
|
def marked(self, value):
|
||||||
|
self._app.mark_dupe(self._dupe, value)
|
||||||
|
|
||||||
|
|
||||||
|
class ResultTree(GUIObject, Tree):
|
||||||
|
def __init__(self, view, app):
|
||||||
|
GUIObject.__init__(self, view, app)
|
||||||
|
Tree.__init__(self)
|
||||||
|
self._power_marker = False
|
||||||
|
self._delta_values = False
|
||||||
|
self._sort_descriptors = (0, True)
|
||||||
|
|
||||||
|
#--- Override
|
||||||
|
def connect(self):
|
||||||
|
GUIObject.connect(self)
|
||||||
|
self._refresh()
|
||||||
|
self.view.refresh()
|
||||||
|
|
||||||
|
def _select_nodes(self, nodes):
|
||||||
|
Tree._select_nodes(self, nodes)
|
||||||
|
self.app._select_dupes(map(attrgetter('_dupe'), nodes))
|
||||||
|
|
||||||
|
#--- Private
|
||||||
|
def _refresh(self):
|
||||||
|
self.clear()
|
||||||
|
if not self.power_marker:
|
||||||
|
for group in self.app.results.groups:
|
||||||
|
group_node = DupeNode(self.app, group, group.ref)
|
||||||
|
self.append(group_node)
|
||||||
|
for dupe in group.dupes:
|
||||||
|
group_node.append(DupeNode(self.app, group, dupe))
|
||||||
|
else:
|
||||||
|
for dupe in self.app.results.dupes:
|
||||||
|
group = self.app.results.get_group_of_duplicate(dupe)
|
||||||
|
self.append(DupeNode(self.app, group, dupe))
|
||||||
|
if self.app.selected_dupes:
|
||||||
|
to_find = set(self.app.selected_dupes)
|
||||||
|
nodes = list(self.findall(lambda n: n is not self and n._dupe in to_find))
|
||||||
|
self.selected_nodes = nodes
|
||||||
|
|
||||||
|
#--- Public
|
||||||
|
def get_node_value(self, path, column):
|
||||||
|
try:
|
||||||
|
node = self.get_node(path)
|
||||||
|
except IndexError:
|
||||||
|
return '---'
|
||||||
|
if self.delta_values:
|
||||||
|
return node.data_delta[column]
|
||||||
|
else:
|
||||||
|
return node.data[column]
|
||||||
|
|
||||||
|
def rename_selected(self, newname):
|
||||||
|
node = self.selected_node
|
||||||
|
node._data = None
|
||||||
|
node._data_delta = None
|
||||||
|
return self.app.rename_selected(newname)
|
||||||
|
|
||||||
|
def root_children_counts(self):
|
||||||
|
# This is a speed optimization for cases where there's a lot of results so that there is
|
||||||
|
# not thousands of children_count queries when expandAll is called.
|
||||||
|
return [len(node) for node in self]
|
||||||
|
|
||||||
|
def sort(self, key, asc):
|
||||||
|
if self.power_marker:
|
||||||
|
self.app.results.sort_dupes(key, asc, self.delta_values)
|
||||||
|
else:
|
||||||
|
self.app.results.sort_groups(key, asc)
|
||||||
|
self._sort_descriptors = (key, asc)
|
||||||
|
self._refresh()
|
||||||
|
self.view.refresh()
|
||||||
|
|
||||||
|
#--- Properties
|
||||||
|
@property
|
||||||
|
def power_marker(self):
|
||||||
|
return self._power_marker
|
||||||
|
|
||||||
|
@power_marker.setter
|
||||||
|
def power_marker(self, value):
|
||||||
|
if value == self._power_marker:
|
||||||
|
return
|
||||||
|
self._power_marker = value
|
||||||
|
key, asc = self._sort_descriptors
|
||||||
|
self.sort(key, asc)
|
||||||
|
self._refresh()
|
||||||
|
self.view.refresh()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def delta_values(self):
|
||||||
|
return self._delta_values
|
||||||
|
|
||||||
|
@delta_values.setter
|
||||||
|
def delta_values(self, value):
|
||||||
|
if value == self._delta_values:
|
||||||
|
return
|
||||||
|
self._delta_values = value
|
||||||
|
self._refresh()
|
||||||
|
self.view.refresh()
|
||||||
|
|
||||||
|
#--- Event Handlers
|
||||||
|
def marking_changed(self):
|
||||||
|
self.view.invalidate_markings()
|
||||||
|
|
||||||
|
def results_changed(self):
|
||||||
|
self._refresh()
|
||||||
|
self.view.refresh()
|
||||||
|
|
||||||
|
def results_changed_but_keep_selection(self):
|
||||||
|
# What we want to to here is that instead of restoring selected *dupes* after refresh, we
|
||||||
|
# restore selected *paths*.
|
||||||
|
paths = self.selected_paths
|
||||||
|
self._refresh()
|
||||||
|
self.selected_paths = paths
|
||||||
|
self.view.refresh()
|
||||||
|
|
||||||
23
core/gui/stats_label.py
Normal file
23
core/gui/stats_label.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Created By: Virgil Dupras
|
||||||
|
# Created On: 2010-02-11
|
||||||
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
#
|
||||||
|
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||||
|
# which should be included with this package. The terms are also available at
|
||||||
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
|
from .base import GUIObject
|
||||||
|
|
||||||
|
class StatsLabel(GUIObject):
|
||||||
|
def connect(self):
|
||||||
|
GUIObject.connect(self)
|
||||||
|
self.view.refresh()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def display(self):
|
||||||
|
return self.app.stat_line
|
||||||
|
|
||||||
|
def results_changed(self):
|
||||||
|
self.view.refresh()
|
||||||
|
marking_changed = results_changed
|
||||||
@@ -6,9 +6,9 @@
|
|||||||
# 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/hs_license
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
from hsutil.files import FileOrPath
|
from lxml import etree
|
||||||
|
|
||||||
import xml.dom.minidom
|
from hsutil.files import FileOrPath
|
||||||
|
|
||||||
class IgnoreList(object):
|
class IgnoreList(object):
|
||||||
"""An ignore list implementation that is iterable, filterable and exportable to XML.
|
"""An ignore list implementation that is iterable, filterable and exportable to XML.
|
||||||
@@ -71,45 +71,38 @@ class IgnoreList(object):
|
|||||||
self._ignored[first] = matches
|
self._ignored[first] = matches
|
||||||
self._count += 1
|
self._count += 1
|
||||||
|
|
||||||
def load_from_xml(self,infile):
|
def load_from_xml(self, infile):
|
||||||
"""Loads the ignore list from a XML created with save_to_xml.
|
"""Loads the ignore list from a XML created with save_to_xml.
|
||||||
|
|
||||||
infile can be a file object or a filename.
|
infile can be a file object or a filename.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
doc = xml.dom.minidom.parse(infile)
|
root = etree.parse(infile).getroot()
|
||||||
except Exception:
|
except Exception:
|
||||||
return
|
return
|
||||||
file_nodes = doc.getElementsByTagName('file')
|
for fn in root.iterchildren('file'):
|
||||||
for fn in file_nodes:
|
file_path = fn.get('path')
|
||||||
if not fn.getAttributeNode('path'):
|
if not file_path:
|
||||||
continue
|
continue
|
||||||
file_path = fn.getAttributeNode('path').nodeValue
|
for sfn in fn.iterchildren('file'):
|
||||||
subfile_nodes = fn.getElementsByTagName('file')
|
subfile_path = sfn.get('path')
|
||||||
for sfn in subfile_nodes:
|
if subfile_path:
|
||||||
if not sfn.getAttributeNode('path'):
|
self.Ignore(file_path, subfile_path)
|
||||||
continue
|
|
||||||
subfile_path = sfn.getAttributeNode('path').nodeValue
|
|
||||||
self.Ignore(file_path,subfile_path)
|
|
||||||
|
|
||||||
def save_to_xml(self,outfile):
|
def save_to_xml(self, outfile):
|
||||||
"""Create a XML file that can be used by load_from_xml.
|
"""Create a XML file that can be used by load_from_xml.
|
||||||
|
|
||||||
outfile can be a file object or a filename.
|
outfile can be a file object or a filename.
|
||||||
"""
|
"""
|
||||||
doc = xml.dom.minidom.Document()
|
root = etree.Element('ignore_list')
|
||||||
root = doc.appendChild(doc.createElement('ignore_list'))
|
for filename, subfiles in self._ignored.items():
|
||||||
for file,subfiles in self._ignored.items():
|
file_node = etree.SubElement(root, 'file')
|
||||||
file_node = root.appendChild(doc.createElement('file'))
|
file_node.set('path', filename)
|
||||||
if isinstance(file,unicode):
|
for subfilename in subfiles:
|
||||||
file = file.encode('utf-8')
|
subfile_node = etree.SubElement(file_node, 'file')
|
||||||
file_node.setAttribute('path',file)
|
subfile_node.set('path', subfilename)
|
||||||
for subfile in subfiles:
|
tree = etree.ElementTree(root)
|
||||||
subfile_node = file_node.appendChild(doc.createElement('file'))
|
|
||||||
if isinstance(subfile,unicode):
|
|
||||||
subfile = subfile.encode('utf-8')
|
|
||||||
subfile_node.setAttribute('path',subfile)
|
|
||||||
with FileOrPath(outfile, 'wb') as fp:
|
with FileOrPath(outfile, 'wb') as fp:
|
||||||
doc.writexml(fp,'\t','\t','\n',encoding='utf-8')
|
tree.write(fp, encoding='utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
215
core/results.py
215
core/results.py
@@ -8,16 +8,14 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
from xml.sax import handler, make_parser, SAXException
|
from lxml import etree
|
||||||
from xml.sax.saxutils import XMLGenerator
|
|
||||||
from xml.sax.xmlreader import AttributesImpl
|
|
||||||
|
|
||||||
from . import engine
|
from . import engine
|
||||||
from hsutil.job import nulljob
|
from hscommon.job import nulljob
|
||||||
from hsutil.markable import Markable
|
from hscommon.markable import Markable
|
||||||
from hsutil.misc import flatten, cond, nonone
|
from hsutil.misc import flatten, nonone
|
||||||
from hsutil.str import format_size
|
from hsutil.str import format_size
|
||||||
from hsutil.files import open_if_filename
|
from hsutil.files import FileOrPath
|
||||||
|
|
||||||
class Results(Markable):
|
class Results(Markable):
|
||||||
#---Override
|
#---Override
|
||||||
@@ -34,6 +32,7 @@ class Results(Markable):
|
|||||||
self.__recalculate_stats()
|
self.__recalculate_stats()
|
||||||
self.__marked_size = 0
|
self.__marked_size = 0
|
||||||
self.data = data_module
|
self.data = data_module
|
||||||
|
self.problems = [] # (dupe, error_msg)
|
||||||
|
|
||||||
def _did_mark(self, dupe):
|
def _did_mark(self, dupe):
|
||||||
self.__marked_size += dupe.size
|
self.__marked_size += dupe.size
|
||||||
@@ -148,7 +147,7 @@ class Results(Markable):
|
|||||||
self.__filters.append(filter_str)
|
self.__filters.append(filter_str)
|
||||||
if self.__filtered_dupes is None:
|
if self.__filtered_dupes is None:
|
||||||
self.__filtered_dupes = flatten(g[:] for g in self.groups)
|
self.__filtered_dupes = flatten(g[:] for g in self.groups)
|
||||||
self.__filtered_dupes = set(dupe for dupe in self.__filtered_dupes if filter_re.search(dupe.name))
|
self.__filtered_dupes = set(dupe for dupe in self.__filtered_dupes if filter_re.search(unicode(dupe.path)))
|
||||||
filtered_groups = set()
|
filtered_groups = set()
|
||||||
for dupe in self.__filtered_dupes:
|
for dupe in self.__filtered_dupes:
|
||||||
filtered_groups.add(self.get_group_of_duplicate(dupe))
|
filtered_groups.add(self.get_group_of_duplicate(dupe))
|
||||||
@@ -168,42 +167,54 @@ class Results(Markable):
|
|||||||
is_markable = _is_markable
|
is_markable = _is_markable
|
||||||
|
|
||||||
def load_from_xml(self, infile, get_file, j=nulljob):
|
def load_from_xml(self, infile, get_file, j=nulljob):
|
||||||
|
def do_match(ref_file, other_files, group):
|
||||||
|
if not other_files:
|
||||||
|
return
|
||||||
|
for other_file in other_files:
|
||||||
|
group.add_match(engine.get_match(ref_file, other_file))
|
||||||
|
do_match(other_files[0], other_files[1:], group)
|
||||||
|
|
||||||
self.apply_filter(None)
|
self.apply_filter(None)
|
||||||
handler = _ResultsHandler(get_file)
|
|
||||||
try:
|
try:
|
||||||
parser = make_parser()
|
root = etree.parse(infile).getroot()
|
||||||
except Exception as e:
|
except Exception:
|
||||||
# This special handling is to try to figure out the cause of #47
|
|
||||||
# We don't silently return, because we want the user to send error report.
|
|
||||||
logging.exception(e)
|
|
||||||
try:
|
|
||||||
import xml.parsers.expat
|
|
||||||
logging.warning('importing xml.parsers.expat went ok, WTF?')
|
|
||||||
except Exception as e:
|
|
||||||
# This log should give a little more details about the cause of this all
|
|
||||||
logging.exception(e)
|
|
||||||
raise
|
|
||||||
raise
|
|
||||||
parser.setContentHandler(handler)
|
|
||||||
try:
|
|
||||||
infile, must_close = open_if_filename(infile)
|
|
||||||
except IOError:
|
|
||||||
return
|
return
|
||||||
BUFSIZE = 1024 * 1024 # 1mb buffer
|
group_elems = list(root.iterchildren('group'))
|
||||||
infile.seek(0, 2)
|
groups = []
|
||||||
j.start_job(infile.tell() // BUFSIZE)
|
marked = set()
|
||||||
infile.seek(0, 0)
|
for group_elem in j.iter_with_progress(group_elems, every=100):
|
||||||
try:
|
group = engine.Group()
|
||||||
while True:
|
dupes = []
|
||||||
data = infile.read(BUFSIZE)
|
for file_elem in group_elem.iterchildren('file'):
|
||||||
if not data:
|
path = file_elem.get('path')
|
||||||
break
|
words = file_elem.get('words', '')
|
||||||
parser.feed(data)
|
if not path:
|
||||||
j.add_progress()
|
continue
|
||||||
except SAXException:
|
file = get_file(path)
|
||||||
return
|
if file is None:
|
||||||
self.groups = handler.groups
|
continue
|
||||||
for dupe_file in handler.marked:
|
file.words = words.split(',')
|
||||||
|
file.is_ref = file_elem.get('is_ref') == 'y'
|
||||||
|
dupes.append(file)
|
||||||
|
if file_elem.get('marked') == 'y':
|
||||||
|
marked.add(file)
|
||||||
|
for match_elem in group_elem.iterchildren('match'):
|
||||||
|
try:
|
||||||
|
attrs = match_elem.attrib
|
||||||
|
first_file = dupes[int(attrs['first'])]
|
||||||
|
second_file = dupes[int(attrs['second'])]
|
||||||
|
percentage = int(attrs['percentage'])
|
||||||
|
group.add_match(engine.Match(first_file, second_file, percentage))
|
||||||
|
except (IndexError, KeyError, ValueError): # Covers missing attr, non-int values and indexes out of bounds
|
||||||
|
pass
|
||||||
|
if (not group.matches) and (len(dupes) >= 2):
|
||||||
|
do_match(dupes[0], dupes[1:], group)
|
||||||
|
group.prioritize(lambda x: dupes.index(x))
|
||||||
|
if len(group):
|
||||||
|
groups.append(group)
|
||||||
|
j.add_progress()
|
||||||
|
self.groups = groups
|
||||||
|
for dupe_file in marked:
|
||||||
self.mark(dupe_file)
|
self.mark(dupe_file)
|
||||||
|
|
||||||
def make_ref(self, dupe):
|
def make_ref(self, dupe):
|
||||||
@@ -220,17 +231,22 @@ class Results(Markable):
|
|||||||
self.__dupes = None
|
self.__dupes = None
|
||||||
|
|
||||||
def perform_on_marked(self, func, remove_from_results):
|
def perform_on_marked(self, func, remove_from_results):
|
||||||
problems = []
|
# Performs `func` on all marked dupes. If an EnvironmentError is raised during the call,
|
||||||
for d in self.dupes:
|
# the problematic dupe is added to self.problems.
|
||||||
if self.is_marked(d) and (not func(d)):
|
self.problems = []
|
||||||
problems.append(d)
|
to_remove = []
|
||||||
|
marked = (dupe for dupe in self.dupes if self.is_marked(dupe))
|
||||||
|
for dupe in marked:
|
||||||
|
try:
|
||||||
|
func(dupe)
|
||||||
|
to_remove.append(dupe)
|
||||||
|
except EnvironmentError as e:
|
||||||
|
self.problems.append((dupe, unicode(e)))
|
||||||
if remove_from_results:
|
if remove_from_results:
|
||||||
to_remove = [d for d in self.dupes if self.is_marked(d) and (d not in problems)]
|
|
||||||
self.remove_duplicates(to_remove)
|
self.remove_duplicates(to_remove)
|
||||||
self.mark_none()
|
self.mark_none()
|
||||||
for d in problems:
|
for dupe, _ in self.problems:
|
||||||
self.mark(d)
|
self.mark(dupe)
|
||||||
return len(problems)
|
|
||||||
|
|
||||||
def remove_duplicates(self, dupes):
|
def remove_duplicates(self, dupes):
|
||||||
'''Remove 'dupes' from their respective group, and remove the group is it ends up empty.
|
'''Remove 'dupes' from their respective group, and remove the group is it ends up empty.
|
||||||
@@ -256,13 +272,10 @@ class Results(Markable):
|
|||||||
|
|
||||||
def save_to_xml(self, outfile):
|
def save_to_xml(self, outfile):
|
||||||
self.apply_filter(None)
|
self.apply_filter(None)
|
||||||
outfile, must_close = open_if_filename(outfile, 'wb')
|
root = etree.Element('results')
|
||||||
writer = XMLGenerator(outfile, 'utf-8')
|
# writer = XMLGenerator(outfile, 'utf-8')
|
||||||
writer.startDocument()
|
|
||||||
empty_attrs = AttributesImpl({})
|
|
||||||
writer.startElement('results', empty_attrs)
|
|
||||||
for g in self.groups:
|
for g in self.groups:
|
||||||
writer.startElement('group', empty_attrs)
|
group_elem = etree.SubElement(root, 'group')
|
||||||
dupe2index = {}
|
dupe2index = {}
|
||||||
for index, d in enumerate(g):
|
for index, d in enumerate(g):
|
||||||
dupe2index[d] = index
|
dupe2index[d] = index
|
||||||
@@ -270,27 +283,22 @@ class Results(Markable):
|
|||||||
words = engine.unpack_fields(d.words)
|
words = engine.unpack_fields(d.words)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
words = ()
|
words = ()
|
||||||
attrs = AttributesImpl({
|
file_elem = etree.SubElement(group_elem, 'file')
|
||||||
'path': unicode(d.path),
|
try:
|
||||||
'is_ref': cond(d.is_ref, 'y', 'n'),
|
file_elem.set('path', unicode(d.path))
|
||||||
'words': ','.join(words),
|
file_elem.set('words', ','.join(words))
|
||||||
'marked': cond(self.is_marked(d), 'y', 'n')
|
except ValueError: # If there's an invalid character, just skip the file
|
||||||
})
|
file_elem.set('path', '')
|
||||||
writer.startElement('file', attrs)
|
file_elem.set('is_ref', ('y' if d.is_ref else 'n'))
|
||||||
writer.endElement('file')
|
file_elem.set('marked', ('y' if self.is_marked(d) else 'n'))
|
||||||
for match in g.matches:
|
for match in g.matches:
|
||||||
attrs = AttributesImpl({
|
match_elem = etree.SubElement(group_elem, 'match')
|
||||||
'first': str(dupe2index[match.first]),
|
match_elem.set('first', unicode(dupe2index[match.first]))
|
||||||
'second': str(dupe2index[match.second]),
|
match_elem.set('second', unicode(dupe2index[match.second]))
|
||||||
'percentage': str(int(match.percentage)),
|
match_elem.set('percentage', unicode(int(match.percentage)))
|
||||||
})
|
tree = etree.ElementTree(root)
|
||||||
writer.startElement('match', attrs)
|
with FileOrPath(outfile, 'wb') as fp:
|
||||||
writer.endElement('match')
|
tree.write(fp, encoding='utf-8')
|
||||||
writer.endElement('group')
|
|
||||||
writer.endElement('results')
|
|
||||||
writer.endDocument()
|
|
||||||
if must_close:
|
|
||||||
outfile.close()
|
|
||||||
|
|
||||||
def sort_dupes(self, key, asc=True, delta=False):
|
def sort_dupes(self, key, asc=True, delta=False):
|
||||||
if not self.__dupes:
|
if not self.__dupes:
|
||||||
@@ -310,60 +318,3 @@ class Results(Markable):
|
|||||||
dupes = property(__get_dupe_list)
|
dupes = property(__get_dupe_list)
|
||||||
groups = property(__get_groups, __set_groups)
|
groups = property(__get_groups, __set_groups)
|
||||||
stat_line = property(__get_stat_line)
|
stat_line = property(__get_stat_line)
|
||||||
|
|
||||||
class _ResultsHandler(handler.ContentHandler):
|
|
||||||
def __init__(self, get_file):
|
|
||||||
self.group = None
|
|
||||||
self.dupes = None
|
|
||||||
self.marked = set()
|
|
||||||
self.groups = []
|
|
||||||
self.get_file = get_file
|
|
||||||
|
|
||||||
def startElement(self, name, attrs):
|
|
||||||
if name == 'group':
|
|
||||||
self.group = engine.Group()
|
|
||||||
self.dupes = []
|
|
||||||
return
|
|
||||||
if (name == 'file') and (self.group is not None):
|
|
||||||
if not (('path' in attrs) and ('words' in attrs)):
|
|
||||||
return
|
|
||||||
path = attrs['path']
|
|
||||||
file = self.get_file(path)
|
|
||||||
if file is None:
|
|
||||||
return
|
|
||||||
file.words = attrs['words'].split(',')
|
|
||||||
file.is_ref = attrs.get('is_ref') == 'y'
|
|
||||||
self.dupes.append(file)
|
|
||||||
if attrs.get('marked') == 'y':
|
|
||||||
self.marked.add(file)
|
|
||||||
if (name == 'match') and (self.group is not None):
|
|
||||||
try:
|
|
||||||
first_file = self.dupes[int(attrs['first'])]
|
|
||||||
second_file = self.dupes[int(attrs['second'])]
|
|
||||||
percentage = int(attrs['percentage'])
|
|
||||||
self.group.add_match(engine.Match(first_file, second_file, percentage))
|
|
||||||
except (IndexError, KeyError, ValueError): # Covers missing attr, non-int values and indexes out of bounds
|
|
||||||
pass
|
|
||||||
|
|
||||||
def endElement(self, name):
|
|
||||||
def do_match(ref_file, other_files, group):
|
|
||||||
if not other_files:
|
|
||||||
return
|
|
||||||
for other_file in other_files:
|
|
||||||
group.add_match(engine.get_match(ref_file, other_file))
|
|
||||||
do_match(other_files[0], other_files[1:], group)
|
|
||||||
|
|
||||||
if name == 'group':
|
|
||||||
group = self.group
|
|
||||||
self.group = None
|
|
||||||
dupes = self.dupes
|
|
||||||
self.dupes = []
|
|
||||||
if group is None:
|
|
||||||
return
|
|
||||||
if len(dupes) < 2:
|
|
||||||
return
|
|
||||||
if not group.matches: # <match> elements not present, do it manually, without %
|
|
||||||
do_match(dupes[0], dupes[1:], group)
|
|
||||||
group.prioritize(lambda x: dupes.index(x))
|
|
||||||
self.groups.append(group)
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
|
||||||
from hsutil import job, io
|
from hscommon import job
|
||||||
|
from hsutil import io
|
||||||
from hsutil.misc import dedupe
|
from hsutil.misc import dedupe
|
||||||
from hsutil.str import get_file_ext, rem_file_ext
|
from hsutil.str import get_file_ext, rem_file_ext
|
||||||
|
|
||||||
|
|||||||
@@ -1,365 +0,0 @@
|
|||||||
# Created By: Virgil Dupras
|
|
||||||
# Created On: 2006/11/11
|
|
||||||
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
|
||||||
#
|
|
||||||
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
|
||||||
# which should be included with this package. The terms are also available at
|
|
||||||
# http://www.hardcoded.net/licenses/hs_license
|
|
||||||
|
|
||||||
import tempfile
|
|
||||||
import shutil
|
|
||||||
import logging
|
|
||||||
import os.path as op
|
|
||||||
|
|
||||||
from nose.tools import eq_
|
|
||||||
|
|
||||||
from hsutil.path import Path
|
|
||||||
from hsutil.testcase import TestCase
|
|
||||||
from hsutil.decorators import log_calls
|
|
||||||
from hsutil import io
|
|
||||||
|
|
||||||
from . import data
|
|
||||||
from .results_test import GetTestGroups
|
|
||||||
from .. import engine, fs
|
|
||||||
try:
|
|
||||||
from ..app_cocoa import DupeGuru as DupeGuruBase
|
|
||||||
except ImportError:
|
|
||||||
from nose.plugins.skip import SkipTest
|
|
||||||
raise SkipTest("These tests can only be run on OS X")
|
|
||||||
|
|
||||||
class DupeGuru(DupeGuruBase):
|
|
||||||
def __init__(self):
|
|
||||||
DupeGuruBase.__init__(self, data, '/tmp', appid=4)
|
|
||||||
|
|
||||||
def _start_job(self, jobid, func):
|
|
||||||
func(nulljob)
|
|
||||||
|
|
||||||
def r2np(rows):
|
|
||||||
#Transforms a list of rows [1,2,3] into a list of node paths [[1],[2],[3]]
|
|
||||||
return [[i] for i in rows]
|
|
||||||
|
|
||||||
class TCDupeGuru(TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
self.app = DupeGuru()
|
|
||||||
self.objects,self.matches,self.groups = GetTestGroups()
|
|
||||||
self.app.results.groups = self.groups
|
|
||||||
tmppath = self.tmppath()
|
|
||||||
io.mkdir(tmppath + 'foo')
|
|
||||||
io.mkdir(tmppath + 'bar')
|
|
||||||
self.app.directories.add_path(tmppath)
|
|
||||||
|
|
||||||
def test_GetObjects(self):
|
|
||||||
app = self.app
|
|
||||||
objects = self.objects
|
|
||||||
groups = self.groups
|
|
||||||
g,d = app.GetObjects([0])
|
|
||||||
self.assert_(g is groups[0])
|
|
||||||
self.assert_(d is None)
|
|
||||||
g,d = app.GetObjects([0,0])
|
|
||||||
self.assert_(g is groups[0])
|
|
||||||
self.assert_(d is objects[1])
|
|
||||||
g,d = app.GetObjects([1,0])
|
|
||||||
self.assert_(g is groups[1])
|
|
||||||
self.assert_(d is objects[4])
|
|
||||||
|
|
||||||
def test_GetObjects_after_sort(self):
|
|
||||||
app = self.app
|
|
||||||
objects = self.objects
|
|
||||||
groups = self.groups[:] #To keep the old order in memory
|
|
||||||
app.sort_groups(0,False) #0 = Filename
|
|
||||||
#Now, the group order is supposed to be reversed
|
|
||||||
g,d = app.GetObjects([0,0])
|
|
||||||
self.assert_(g is groups[1])
|
|
||||||
self.assert_(d is objects[4])
|
|
||||||
|
|
||||||
def test_GetObjects_out_of_range(self):
|
|
||||||
app = self.app
|
|
||||||
self.assertEqual((None,None),app.GetObjects([2]))
|
|
||||||
self.assertEqual((None,None),app.GetObjects([]))
|
|
||||||
self.assertEqual((None,None),app.GetObjects([1,2]))
|
|
||||||
|
|
||||||
def test_selected_result_node_paths(self):
|
|
||||||
# app.selected_dupes is correctly converted into node paths
|
|
||||||
app = self.app
|
|
||||||
objects = self.objects
|
|
||||||
paths = [[0, 0], [0, 1], [1]]
|
|
||||||
app.SelectResultNodePaths(paths)
|
|
||||||
eq_(app.selected_result_node_paths(), paths)
|
|
||||||
|
|
||||||
def test_selected_result_node_paths_after_deletion(self):
|
|
||||||
# cases where the selected dupes aren't there are correctly handled
|
|
||||||
app = self.app
|
|
||||||
objects = self.objects
|
|
||||||
paths = [[0, 0], [0, 1], [1]]
|
|
||||||
app.SelectResultNodePaths(paths)
|
|
||||||
app.RemoveSelected()
|
|
||||||
# The first 2 dupes have been removed. The 3rd one is a ref. it stays there, in first pos.
|
|
||||||
eq_(app.selected_result_node_paths(), [[0]]) # no exception
|
|
||||||
|
|
||||||
def test_selectResultNodePaths(self):
|
|
||||||
app = self.app
|
|
||||||
objects = self.objects
|
|
||||||
app.SelectResultNodePaths([[0,0],[0,1]])
|
|
||||||
self.assertEqual(2,len(app.selected_dupes))
|
|
||||||
self.assert_(app.selected_dupes[0] is objects[1])
|
|
||||||
self.assert_(app.selected_dupes[1] is objects[2])
|
|
||||||
|
|
||||||
def test_selectResultNodePaths_with_ref(self):
|
|
||||||
app = self.app
|
|
||||||
objects = self.objects
|
|
||||||
app.SelectResultNodePaths([[0,0],[0,1],[1]])
|
|
||||||
self.assertEqual(3,len(app.selected_dupes))
|
|
||||||
self.assert_(app.selected_dupes[0] is objects[1])
|
|
||||||
self.assert_(app.selected_dupes[1] is objects[2])
|
|
||||||
self.assert_(app.selected_dupes[2] is self.groups[1].ref)
|
|
||||||
|
|
||||||
def test_selectResultNodePaths_empty(self):
|
|
||||||
self.app.SelectResultNodePaths([])
|
|
||||||
self.assertEqual(0,len(self.app.selected_dupes))
|
|
||||||
|
|
||||||
def test_selectResultNodePaths_after_sort(self):
|
|
||||||
app = self.app
|
|
||||||
objects = self.objects
|
|
||||||
groups = self.groups[:] #To keep the old order in memory
|
|
||||||
app.sort_groups(0,False) #0 = Filename
|
|
||||||
#Now, the group order is supposed to be reversed
|
|
||||||
app.SelectResultNodePaths([[0,0],[1],[1,0]])
|
|
||||||
self.assertEqual(3,len(app.selected_dupes))
|
|
||||||
self.assert_(app.selected_dupes[0] is objects[4])
|
|
||||||
self.assert_(app.selected_dupes[1] is groups[0].ref)
|
|
||||||
self.assert_(app.selected_dupes[2] is objects[1])
|
|
||||||
|
|
||||||
def test_selectResultNodePaths_out_of_range(self):
|
|
||||||
app = self.app
|
|
||||||
app.SelectResultNodePaths([[0,0],[0,1],[1],[1,1],[2]])
|
|
||||||
self.assertEqual(3,len(app.selected_dupes))
|
|
||||||
|
|
||||||
def test_selected_powermarker_node_paths(self):
|
|
||||||
# app.selected_dupes is correctly converted into paths
|
|
||||||
app = self.app
|
|
||||||
objects = self.objects
|
|
||||||
paths = r2np([0, 1, 2])
|
|
||||||
app.SelectPowerMarkerNodePaths(paths)
|
|
||||||
eq_(app.selected_powermarker_node_paths(), paths)
|
|
||||||
|
|
||||||
def test_selected_powermarker_node_paths_after_deletion(self):
|
|
||||||
# cases where the selected dupes aren't there are correctly handled
|
|
||||||
app = self.app
|
|
||||||
objects = self.objects
|
|
||||||
paths = r2np([0, 1, 2])
|
|
||||||
app.SelectPowerMarkerNodePaths(paths)
|
|
||||||
app.RemoveSelected()
|
|
||||||
eq_(app.selected_powermarker_node_paths(), []) # no exception
|
|
||||||
|
|
||||||
def test_selectPowerMarkerRows(self):
|
|
||||||
app = self.app
|
|
||||||
objects = self.objects
|
|
||||||
app.SelectPowerMarkerNodePaths(r2np([0,1,2]))
|
|
||||||
self.assertEqual(3,len(app.selected_dupes))
|
|
||||||
self.assert_(app.selected_dupes[0] is objects[1])
|
|
||||||
self.assert_(app.selected_dupes[1] is objects[2])
|
|
||||||
self.assert_(app.selected_dupes[2] is objects[4])
|
|
||||||
|
|
||||||
def test_selectPowerMarkerRows_empty(self):
|
|
||||||
self.app.SelectPowerMarkerNodePaths([])
|
|
||||||
self.assertEqual(0,len(self.app.selected_dupes))
|
|
||||||
|
|
||||||
def test_selectPowerMarkerRows_after_sort(self):
|
|
||||||
app = self.app
|
|
||||||
objects = self.objects
|
|
||||||
app.sort_dupes(0,False) #0 = Filename
|
|
||||||
app.SelectPowerMarkerNodePaths(r2np([0,1,2]))
|
|
||||||
self.assertEqual(3,len(app.selected_dupes))
|
|
||||||
self.assert_(app.selected_dupes[0] is objects[4])
|
|
||||||
self.assert_(app.selected_dupes[1] is objects[2])
|
|
||||||
self.assert_(app.selected_dupes[2] is objects[1])
|
|
||||||
|
|
||||||
def test_selectPowerMarkerRows_out_of_range(self):
|
|
||||||
app = self.app
|
|
||||||
app.SelectPowerMarkerNodePaths(r2np([0,1,2,3]))
|
|
||||||
self.assertEqual(3,len(app.selected_dupes))
|
|
||||||
|
|
||||||
def test_toggleSelectedMark(self):
|
|
||||||
app = self.app
|
|
||||||
objects = self.objects
|
|
||||||
app.ToggleSelectedMarkState()
|
|
||||||
self.assertEqual(0,app.results.mark_count)
|
|
||||||
app.SelectPowerMarkerNodePaths(r2np([0,2]))
|
|
||||||
app.ToggleSelectedMarkState()
|
|
||||||
self.assertEqual(2,app.results.mark_count)
|
|
||||||
self.assert_(not app.results.is_marked(objects[0]))
|
|
||||||
self.assert_(app.results.is_marked(objects[1]))
|
|
||||||
self.assert_(not app.results.is_marked(objects[2]))
|
|
||||||
self.assert_(not app.results.is_marked(objects[3]))
|
|
||||||
self.assert_(app.results.is_marked(objects[4]))
|
|
||||||
|
|
||||||
def test_refreshDetailsWithSelected(self):
|
|
||||||
def mock_refresh(dupe,group):
|
|
||||||
self.called = True
|
|
||||||
if self.app.selected_dupes:
|
|
||||||
self.assert_(dupe is self.app.selected_dupes[0])
|
|
||||||
self.assert_(group is self.app.results.get_group_of_duplicate(dupe))
|
|
||||||
else:
|
|
||||||
self.assert_(dupe is None)
|
|
||||||
self.assert_(group is None)
|
|
||||||
|
|
||||||
self.app.RefreshDetailsTable = mock_refresh
|
|
||||||
self.called = False
|
|
||||||
self.app.SelectPowerMarkerNodePaths(r2np([0,2]))
|
|
||||||
self.app.RefreshDetailsWithSelected()
|
|
||||||
self.assert_(self.called)
|
|
||||||
self.called = False
|
|
||||||
self.app.SelectPowerMarkerNodePaths([])
|
|
||||||
self.app.RefreshDetailsWithSelected()
|
|
||||||
self.assert_(self.called)
|
|
||||||
|
|
||||||
def test_makeSelectedReference(self):
|
|
||||||
app = self.app
|
|
||||||
objects = self.objects
|
|
||||||
groups = self.groups
|
|
||||||
app.SelectPowerMarkerNodePaths(r2np([0,2]))
|
|
||||||
app.MakeSelectedReference()
|
|
||||||
self.assert_(groups[0].ref is objects[1])
|
|
||||||
self.assert_(groups[1].ref is objects[4])
|
|
||||||
|
|
||||||
def test_makeSelectedReference_by_selecting_two_dupes_in_the_same_group(self):
|
|
||||||
app = self.app
|
|
||||||
objects = self.objects
|
|
||||||
groups = self.groups
|
|
||||||
app.SelectPowerMarkerNodePaths(r2np([0,1,2]))
|
|
||||||
#Only 0 and 2 must go ref, not 1 because it is a part of the same group
|
|
||||||
app.MakeSelectedReference()
|
|
||||||
self.assert_(groups[0].ref is objects[1])
|
|
||||||
self.assert_(groups[1].ref is objects[4])
|
|
||||||
|
|
||||||
def test_removeSelected(self):
|
|
||||||
app = self.app
|
|
||||||
app.SelectPowerMarkerNodePaths(r2np([0,2]))
|
|
||||||
app.RemoveSelected()
|
|
||||||
self.assertEqual(1,len(app.results.dupes))
|
|
||||||
app.RemoveSelected()
|
|
||||||
self.assertEqual(1,len(app.results.dupes))
|
|
||||||
app.SelectPowerMarkerNodePaths(r2np([0,2]))
|
|
||||||
app.RemoveSelected()
|
|
||||||
self.assertEqual(0,len(app.results.dupes))
|
|
||||||
|
|
||||||
def test_addDirectory_simple(self):
|
|
||||||
# There's already a directory in self.app, so adding another once makes 2 of em
|
|
||||||
app = self.app
|
|
||||||
eq_(app.add_directory(self.datadirpath()), 0)
|
|
||||||
eq_(len(app.directories), 2)
|
|
||||||
|
|
||||||
def test_addDirectory_already_there(self):
|
|
||||||
app = self.app
|
|
||||||
self.assertEqual(0,app.add_directory(self.datadirpath()))
|
|
||||||
self.assertEqual(1,app.add_directory(self.datadirpath()))
|
|
||||||
|
|
||||||
def test_addDirectory_does_not_exist(self):
|
|
||||||
app = self.app
|
|
||||||
self.assertEqual(2,app.add_directory('/does_not_exist'))
|
|
||||||
|
|
||||||
def test_ignore(self):
|
|
||||||
app = self.app
|
|
||||||
app.SelectPowerMarkerNodePaths(r2np([2])) #The dupe of the second, 2 sized group
|
|
||||||
app.AddSelectedToIgnoreList()
|
|
||||||
self.assertEqual(1,len(app.scanner.ignore_list))
|
|
||||||
app.SelectPowerMarkerNodePaths(r2np([0])) #first dupe of the 3 dupes group
|
|
||||||
app.AddSelectedToIgnoreList()
|
|
||||||
#BOTH the ref and the other dupe should have been added
|
|
||||||
self.assertEqual(3,len(app.scanner.ignore_list))
|
|
||||||
|
|
||||||
def test_purgeIgnoreList(self):
|
|
||||||
app = self.app
|
|
||||||
p1 = self.filepath('zerofile')
|
|
||||||
p2 = self.filepath('zerofill')
|
|
||||||
dne = '/does_not_exist'
|
|
||||||
app.scanner.ignore_list.Ignore(dne,p1)
|
|
||||||
app.scanner.ignore_list.Ignore(p2,dne)
|
|
||||||
app.scanner.ignore_list.Ignore(p1,p2)
|
|
||||||
app.PurgeIgnoreList()
|
|
||||||
self.assertEqual(1,len(app.scanner.ignore_list))
|
|
||||||
self.assert_(app.scanner.ignore_list.AreIgnored(p1,p2))
|
|
||||||
self.assert_(not app.scanner.ignore_list.AreIgnored(dne,p1))
|
|
||||||
|
|
||||||
def test_only_unicode_is_added_to_ignore_list(self):
|
|
||||||
def FakeIgnore(first,second):
|
|
||||||
if not isinstance(first,unicode):
|
|
||||||
self.fail()
|
|
||||||
if not isinstance(second,unicode):
|
|
||||||
self.fail()
|
|
||||||
|
|
||||||
app = self.app
|
|
||||||
app.scanner.ignore_list.Ignore = FakeIgnore
|
|
||||||
app.SelectPowerMarkerNodePaths(r2np([2])) #The dupe of the second, 2 sized group
|
|
||||||
app.AddSelectedToIgnoreList()
|
|
||||||
|
|
||||||
def test_GetOutlineViewChildCounts_out_of_range(self):
|
|
||||||
# Out of range requests don't crash and return an empty value
|
|
||||||
app = self.app
|
|
||||||
# [0, 2] is out of range
|
|
||||||
eq_(app.GetOutlineViewChildCounts(1, [0, 2]), []) # no crash
|
|
||||||
|
|
||||||
def test_GetOutlineViewValues_out_of_range(self):
|
|
||||||
# Out of range requests don't crash and return an empty value
|
|
||||||
app = self.app
|
|
||||||
# [0, 2] is out of range
|
|
||||||
eq_(app.GetOutlineViewValues(1, [0, 2]), []) # no crash
|
|
||||||
|
|
||||||
|
|
||||||
class TCDupeGuru_renameSelected(TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
p = self.tmppath()
|
|
||||||
fp = open(unicode(p + 'foo bar 1'),mode='w')
|
|
||||||
fp.close()
|
|
||||||
fp = open(unicode(p + 'foo bar 2'),mode='w')
|
|
||||||
fp.close()
|
|
||||||
fp = open(unicode(p + 'foo bar 3'),mode='w')
|
|
||||||
fp.close()
|
|
||||||
files = fs.get_files(p)
|
|
||||||
matches = engine.getmatches(files)
|
|
||||||
groups = engine.get_groups(matches)
|
|
||||||
g = groups[0]
|
|
||||||
g.prioritize(lambda x:x.name)
|
|
||||||
app = DupeGuru()
|
|
||||||
app.results.groups = groups
|
|
||||||
self.app = app
|
|
||||||
self.groups = groups
|
|
||||||
self.p = p
|
|
||||||
self.files = files
|
|
||||||
|
|
||||||
def test_simple(self):
|
|
||||||
app = self.app
|
|
||||||
g = self.groups[0]
|
|
||||||
app.SelectPowerMarkerNodePaths(r2np([0]))
|
|
||||||
assert app.RenameSelected('renamed')
|
|
||||||
names = io.listdir(self.p)
|
|
||||||
assert 'renamed' in names
|
|
||||||
assert 'foo bar 2' not in names
|
|
||||||
eq_(g.dupes[0].name, 'renamed')
|
|
||||||
|
|
||||||
def test_none_selected(self):
|
|
||||||
app = self.app
|
|
||||||
g = self.groups[0]
|
|
||||||
app.SelectPowerMarkerNodePaths([])
|
|
||||||
self.mock(logging, 'warning', log_calls(lambda msg: None))
|
|
||||||
assert not app.RenameSelected('renamed')
|
|
||||||
msg = logging.warning.calls[0]['msg']
|
|
||||||
eq_('dupeGuru Warning: list index out of range', msg)
|
|
||||||
names = io.listdir(self.p)
|
|
||||||
assert 'renamed' not in names
|
|
||||||
assert 'foo bar 2' in names
|
|
||||||
eq_(g.dupes[0].name, 'foo bar 2')
|
|
||||||
|
|
||||||
def test_name_already_exists(self):
|
|
||||||
app = self.app
|
|
||||||
g = self.groups[0]
|
|
||||||
app.SelectPowerMarkerNodePaths(r2np([0]))
|
|
||||||
self.mock(logging, 'warning', log_calls(lambda msg: None))
|
|
||||||
assert not app.RenameSelected('foo bar 1')
|
|
||||||
msg = logging.warning.calls[0]['msg']
|
|
||||||
assert msg.startswith('dupeGuru Warning: \'foo bar 1\' already exists in')
|
|
||||||
names = io.listdir(self.p)
|
|
||||||
assert 'foo bar 1' in names
|
|
||||||
assert 'foo bar 2' in names
|
|
||||||
eq_(g.dupes[0].name, 'foo bar 2')
|
|
||||||
|
|
||||||
@@ -7,17 +7,23 @@
|
|||||||
# http://www.hardcoded.net/licenses/hs_license
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from hsutil.testutil import eq_
|
||||||
from hsutil.testcase import TestCase
|
from hsutil.testcase import TestCase
|
||||||
from hsutil import io
|
from hsutil import io
|
||||||
from hsutil.path import Path
|
from hsutil.path import Path
|
||||||
from hsutil.decorators import log_calls
|
from hsutil.decorators import log_calls
|
||||||
import hsutil.files
|
import hsutil.files
|
||||||
from hsutil.job import nulljob
|
from hscommon.job import nulljob
|
||||||
|
|
||||||
from . import data
|
from . import data
|
||||||
from .. import app, fs
|
from .results_test import GetTestGroups
|
||||||
|
from .. import app, fs, engine
|
||||||
from ..app import DupeGuru as DupeGuruBase
|
from ..app import DupeGuru as DupeGuruBase
|
||||||
|
from ..gui.details_panel import DetailsPanel
|
||||||
|
from ..gui.directory_tree import DirectoryTree
|
||||||
|
from ..gui.result_tree import ResultTree
|
||||||
|
|
||||||
class DupeGuru(DupeGuruBase):
|
class DupeGuru(DupeGuruBase):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -27,6 +33,23 @@ class DupeGuru(DupeGuruBase):
|
|||||||
func(nulljob)
|
func(nulljob)
|
||||||
|
|
||||||
|
|
||||||
|
class CallLogger(object):
|
||||||
|
"""This is a dummy object that logs all calls made to it.
|
||||||
|
|
||||||
|
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 TCDupeGuru(TestCase):
|
||||||
cls_tested_module = app
|
cls_tested_module = app
|
||||||
def test_apply_filter_calls_results_apply_filter(self):
|
def test_apply_filter_calls_results_apply_filter(self):
|
||||||
@@ -133,3 +156,327 @@ class TCDupeGuru_clean_empty_dirs(TestCase):
|
|||||||
self.assertEqual(Path('not-empty/empty'), calls[1]['path'])
|
self.assertEqual(Path('not-empty/empty'), calls[1]['path'])
|
||||||
self.assertEqual(Path('not-empty'), calls[2]['path'])
|
self.assertEqual(Path('not-empty'), calls[2]['path'])
|
||||||
|
|
||||||
|
|
||||||
|
class TCDupeGuruWithResults(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.app = DupeGuru()
|
||||||
|
self.objects,self.matches,self.groups = GetTestGroups()
|
||||||
|
self.app.results.groups = self.groups
|
||||||
|
self.dpanel_gui = CallLogger()
|
||||||
|
self.dpanel = DetailsPanel(self.dpanel_gui, self.app)
|
||||||
|
self.dtree_gui = CallLogger()
|
||||||
|
self.dtree = DirectoryTree(self.dtree_gui, self.app)
|
||||||
|
self.rtree_gui = CallLogger()
|
||||||
|
self.rtree = ResultTree(self.rtree_gui, self.app)
|
||||||
|
self.dpanel.connect()
|
||||||
|
self.dtree.connect()
|
||||||
|
self.rtree.connect()
|
||||||
|
tmppath = self.tmppath()
|
||||||
|
io.mkdir(tmppath + 'foo')
|
||||||
|
io.mkdir(tmppath + 'bar')
|
||||||
|
self.app.directories.add_path(tmppath)
|
||||||
|
|
||||||
|
def check_gui_calls(self, gui, expected, verify_order=False):
|
||||||
|
"""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, u"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, u"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
|
||||||
|
groups = self.groups
|
||||||
|
n = self.rtree.get_node([0])
|
||||||
|
assert n._group is groups[0]
|
||||||
|
assert n._dupe is objects[0]
|
||||||
|
n = self.rtree.get_node([0, 0])
|
||||||
|
assert n._group is groups[0]
|
||||||
|
assert n._dupe is objects[1]
|
||||||
|
n = self.rtree.get_node([1, 0])
|
||||||
|
assert n._group is groups[1]
|
||||||
|
assert n._dupe is objects[4]
|
||||||
|
|
||||||
|
def test_GetObjects_after_sort(self):
|
||||||
|
objects = self.objects
|
||||||
|
groups = self.groups[:] # we need an un-sorted reference
|
||||||
|
self.rtree.sort(0, False) #0 = Filename
|
||||||
|
n = self.rtree.get_node([0, 0])
|
||||||
|
assert n._group is groups[1]
|
||||||
|
assert n._dupe is objects[4]
|
||||||
|
|
||||||
|
def test_selected_result_node_paths(self):
|
||||||
|
# app.selected_dupes is correctly converted into node paths
|
||||||
|
paths = [[0, 0], [0, 1], [1]]
|
||||||
|
self.rtree.selected_paths = paths
|
||||||
|
eq_(self.rtree.selected_paths, paths)
|
||||||
|
|
||||||
|
def test_selected_result_node_paths_after_deletion(self):
|
||||||
|
# cases where the selected dupes aren't there are correctly handled
|
||||||
|
paths = [[0, 0], [0, 1], [1]]
|
||||||
|
self.rtree.selected_paths = paths
|
||||||
|
self.app.remove_selected()
|
||||||
|
# The first 2 dupes have been removed. The 3rd one is a ref. it stays there, in first pos.
|
||||||
|
eq_(self.rtree.selected_paths, [[0, 0]]) # no exception
|
||||||
|
|
||||||
|
def test_selectResultNodePaths(self):
|
||||||
|
app = self.app
|
||||||
|
objects = self.objects
|
||||||
|
self.rtree.selected_paths = [[0, 0], [0, 1]]
|
||||||
|
eq_(len(app.selected_dupes), 2)
|
||||||
|
assert app.selected_dupes[0] is objects[1]
|
||||||
|
assert app.selected_dupes[1] is objects[2]
|
||||||
|
|
||||||
|
def test_selectResultNodePaths_with_ref(self):
|
||||||
|
app = self.app
|
||||||
|
objects = self.objects
|
||||||
|
self.rtree.selected_paths = [[0, 0], [0, 1], [1]]
|
||||||
|
eq_(len(app.selected_dupes), 3)
|
||||||
|
assert app.selected_dupes[0] is objects[1]
|
||||||
|
assert app.selected_dupes[1] is objects[2]
|
||||||
|
assert app.selected_dupes[2] is self.groups[1].ref
|
||||||
|
|
||||||
|
def test_selectResultNodePaths_after_sort(self):
|
||||||
|
app = self.app
|
||||||
|
objects = self.objects
|
||||||
|
groups = self.groups[:] #To keep the old order in memory
|
||||||
|
self.rtree.sort(0, False) #0 = Filename
|
||||||
|
#Now, the group order is supposed to be reversed
|
||||||
|
self.rtree.selected_paths = [[0, 0], [1], [1, 0]]
|
||||||
|
eq_(len(app.selected_dupes), 3)
|
||||||
|
assert app.selected_dupes[0] is objects[4]
|
||||||
|
assert app.selected_dupes[1] is groups[0].ref
|
||||||
|
assert app.selected_dupes[2] is objects[1]
|
||||||
|
|
||||||
|
def test_selected_powermarker_node_paths(self):
|
||||||
|
# app.selected_dupes is correctly converted into paths
|
||||||
|
app = self.app
|
||||||
|
objects = self.objects
|
||||||
|
self.rtree.power_marker = True
|
||||||
|
self.rtree.selected_paths = [[0], [1], [2]]
|
||||||
|
self.rtree.power_marker = False
|
||||||
|
eq_(self.rtree.selected_paths, [[0, 0], [0, 1], [1, 0]])
|
||||||
|
|
||||||
|
def test_selected_powermarker_node_paths_after_deletion(self):
|
||||||
|
# cases where the selected dupes aren't there are correctly handled
|
||||||
|
app = self.app
|
||||||
|
objects = self.objects
|
||||||
|
self.rtree.power_marker = True
|
||||||
|
self.rtree.selected_paths = [[0], [1], [2]]
|
||||||
|
app.remove_selected()
|
||||||
|
eq_(self.rtree.selected_paths, []) # no exception
|
||||||
|
|
||||||
|
def test_selectPowerMarkerRows(self):
|
||||||
|
app = self.app
|
||||||
|
objects = self.objects
|
||||||
|
self.rtree.selected_paths = [[0, 0], [0, 1], [1, 0]]
|
||||||
|
eq_(len(app.selected_dupes), 3)
|
||||||
|
assert app.selected_dupes[0] is objects[1]
|
||||||
|
assert app.selected_dupes[1] is objects[2]
|
||||||
|
assert app.selected_dupes[2] is objects[4]
|
||||||
|
|
||||||
|
def test_selectPowerMarkerRows_empty(self):
|
||||||
|
self.rtree.selected_paths = []
|
||||||
|
eq_(len(self.app.selected_dupes), 0)
|
||||||
|
|
||||||
|
def test_selectPowerMarkerRows_after_sort(self):
|
||||||
|
app = self.app
|
||||||
|
objects = self.objects
|
||||||
|
self.rtree.power_marker = True
|
||||||
|
self.rtree.sort(0, False) #0 = Filename
|
||||||
|
self.rtree.selected_paths = [[0], [1], [2]]
|
||||||
|
eq_(len(app.selected_dupes), 3)
|
||||||
|
assert app.selected_dupes[0] is objects[4]
|
||||||
|
assert app.selected_dupes[1] is objects[2]
|
||||||
|
assert app.selected_dupes[2] is objects[1]
|
||||||
|
|
||||||
|
def test_toggleSelectedMark(self):
|
||||||
|
app = self.app
|
||||||
|
objects = self.objects
|
||||||
|
app.toggle_selected_mark_state()
|
||||||
|
eq_(app.results.mark_count, 0)
|
||||||
|
self.rtree.selected_paths = [[0, 0], [1, 0]]
|
||||||
|
app.toggle_selected_mark_state()
|
||||||
|
eq_(app.results.mark_count, 2)
|
||||||
|
assert not app.results.is_marked(objects[0])
|
||||||
|
assert app.results.is_marked(objects[1])
|
||||||
|
assert not app.results.is_marked(objects[2])
|
||||||
|
assert not app.results.is_marked(objects[3])
|
||||||
|
assert app.results.is_marked(objects[4])
|
||||||
|
|
||||||
|
def test_refreshDetailsWithSelected(self):
|
||||||
|
self.rtree.selected_paths = [[0, 0], [1, 0]]
|
||||||
|
eq_(self.dpanel.row(0), ('Filename', 'bar bleh', 'foo bar'))
|
||||||
|
self.check_gui_calls(self.dpanel_gui, ['refresh'])
|
||||||
|
self.rtree.selected_paths = []
|
||||||
|
eq_(self.dpanel.row(0), ('Filename', '---', '---'))
|
||||||
|
self.check_gui_calls(self.dpanel_gui, ['refresh'])
|
||||||
|
|
||||||
|
def test_makeSelectedReference(self):
|
||||||
|
app = self.app
|
||||||
|
objects = self.objects
|
||||||
|
groups = self.groups
|
||||||
|
self.rtree.selected_paths = [[0, 0], [1, 0]]
|
||||||
|
app.make_selected_reference()
|
||||||
|
assert groups[0].ref is objects[1]
|
||||||
|
assert groups[1].ref is objects[4]
|
||||||
|
|
||||||
|
def test_makeSelectedReference_by_selecting_two_dupes_in_the_same_group(self):
|
||||||
|
app = self.app
|
||||||
|
objects = self.objects
|
||||||
|
groups = self.groups
|
||||||
|
self.rtree.selected_paths = [[0, 0], [0, 1], [1, 0]]
|
||||||
|
#Only [0, 0] and [1, 0] must go ref, not [0, 1] because it is a part of the same group
|
||||||
|
app.make_selected_reference()
|
||||||
|
assert groups[0].ref is objects[1]
|
||||||
|
assert groups[1].ref is objects[4]
|
||||||
|
|
||||||
|
def test_removeSelected(self):
|
||||||
|
app = self.app
|
||||||
|
self.rtree.selected_paths = [[0, 0], [1, 0]]
|
||||||
|
app.remove_selected()
|
||||||
|
eq_(len(app.results.dupes), 1) # the first path is now selected
|
||||||
|
app.remove_selected()
|
||||||
|
eq_(len(app.results.dupes), 0)
|
||||||
|
|
||||||
|
def test_addDirectory_simple(self):
|
||||||
|
# There's already a directory in self.app, so adding another once makes 2 of em
|
||||||
|
app = self.app
|
||||||
|
eq_(app.add_directory(self.datadirpath()), 0)
|
||||||
|
eq_(len(app.directories), 2)
|
||||||
|
|
||||||
|
def test_addDirectory_already_there(self):
|
||||||
|
app = self.app
|
||||||
|
self.assertEqual(0,app.add_directory(self.datadirpath()))
|
||||||
|
self.assertEqual(1,app.add_directory(self.datadirpath()))
|
||||||
|
|
||||||
|
def test_addDirectory_does_not_exist(self):
|
||||||
|
app = self.app
|
||||||
|
self.assertEqual(2,app.add_directory('/does_not_exist'))
|
||||||
|
|
||||||
|
def test_ignore(self):
|
||||||
|
app = self.app
|
||||||
|
self.rtree.selected_path = [1, 0] #The dupe of the second, 2 sized group
|
||||||
|
app.add_selected_to_ignore_list()
|
||||||
|
eq_(len(app.scanner.ignore_list), 1)
|
||||||
|
self.rtree.selected_path = [0, 0] #first dupe of the 3 dupes group
|
||||||
|
app.add_selected_to_ignore_list()
|
||||||
|
#BOTH the ref and the other dupe should have been added
|
||||||
|
eq_(len(app.scanner.ignore_list), 3)
|
||||||
|
|
||||||
|
def test_purgeIgnoreList(self):
|
||||||
|
app = self.app
|
||||||
|
p1 = self.filepath('zerofile')
|
||||||
|
p2 = self.filepath('zerofill')
|
||||||
|
dne = '/does_not_exist'
|
||||||
|
app.scanner.ignore_list.Ignore(dne,p1)
|
||||||
|
app.scanner.ignore_list.Ignore(p2,dne)
|
||||||
|
app.scanner.ignore_list.Ignore(p1,p2)
|
||||||
|
app.purge_ignore_list()
|
||||||
|
self.assertEqual(1,len(app.scanner.ignore_list))
|
||||||
|
self.assert_(app.scanner.ignore_list.AreIgnored(p1,p2))
|
||||||
|
self.assert_(not app.scanner.ignore_list.AreIgnored(dne,p1))
|
||||||
|
|
||||||
|
def test_only_unicode_is_added_to_ignore_list(self):
|
||||||
|
def FakeIgnore(first,second):
|
||||||
|
if not isinstance(first,unicode):
|
||||||
|
self.fail()
|
||||||
|
if not isinstance(second,unicode):
|
||||||
|
self.fail()
|
||||||
|
|
||||||
|
app = self.app
|
||||||
|
app.scanner.ignore_list.Ignore = FakeIgnore
|
||||||
|
self.rtree.selected_path = [1, 0]
|
||||||
|
app.add_selected_to_ignore_list()
|
||||||
|
|
||||||
|
|
||||||
|
class TCDupeGuru_renameSelected(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
p = self.tmppath()
|
||||||
|
fp = open(unicode(p + 'foo bar 1'),mode='w')
|
||||||
|
fp.close()
|
||||||
|
fp = open(unicode(p + 'foo bar 2'),mode='w')
|
||||||
|
fp.close()
|
||||||
|
fp = open(unicode(p + 'foo bar 3'),mode='w')
|
||||||
|
fp.close()
|
||||||
|
files = fs.get_files(p)
|
||||||
|
matches = engine.getmatches(files)
|
||||||
|
groups = engine.get_groups(matches)
|
||||||
|
g = groups[0]
|
||||||
|
g.prioritize(lambda x:x.name)
|
||||||
|
app = DupeGuru()
|
||||||
|
app.results.groups = groups
|
||||||
|
self.app = app
|
||||||
|
self.groups = groups
|
||||||
|
self.p = p
|
||||||
|
self.files = files
|
||||||
|
self.rtree_gui = CallLogger()
|
||||||
|
self.rtree = ResultTree(self.rtree_gui, self.app)
|
||||||
|
self.rtree.connect()
|
||||||
|
|
||||||
|
def test_simple(self):
|
||||||
|
app = self.app
|
||||||
|
g = self.groups[0]
|
||||||
|
self.rtree.selected_path = [0, 0]
|
||||||
|
assert app.rename_selected('renamed')
|
||||||
|
names = io.listdir(self.p)
|
||||||
|
assert 'renamed' in names
|
||||||
|
assert 'foo bar 2' not in names
|
||||||
|
eq_(g.dupes[0].name, 'renamed')
|
||||||
|
|
||||||
|
def test_none_selected(self):
|
||||||
|
app = self.app
|
||||||
|
g = self.groups[0]
|
||||||
|
self.rtree.selected_paths = []
|
||||||
|
self.mock(logging, 'warning', log_calls(lambda msg: None))
|
||||||
|
assert not app.rename_selected('renamed')
|
||||||
|
msg = logging.warning.calls[0]['msg']
|
||||||
|
eq_('dupeGuru Warning: list index out of range', msg)
|
||||||
|
names = io.listdir(self.p)
|
||||||
|
assert 'renamed' not in names
|
||||||
|
assert 'foo bar 2' in names
|
||||||
|
eq_(g.dupes[0].name, 'foo bar 2')
|
||||||
|
|
||||||
|
def test_name_already_exists(self):
|
||||||
|
app = self.app
|
||||||
|
g = self.groups[0]
|
||||||
|
self.rtree.selected_path = [0, 0]
|
||||||
|
self.mock(logging, 'warning', log_calls(lambda msg: None))
|
||||||
|
assert not app.rename_selected('foo bar 1')
|
||||||
|
msg = logging.warning.calls[0]['msg']
|
||||||
|
assert msg.startswith('dupeGuru Warning: \'foo bar 1\' already exists in')
|
||||||
|
names = io.listdir(self.p)
|
||||||
|
assert 'foo bar 1' in names
|
||||||
|
assert 'foo bar 2' in names
|
||||||
|
eq_(g.dupes[0].name, 'foo bar 2')
|
||||||
|
|
||||||
|
|||||||
28
core/tests/conftest.py
Normal file
28
core/tests/conftest.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# -*- 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()
|
||||||
@@ -31,7 +31,7 @@ def GetDisplayInfo(dupe, group, delta):
|
|||||||
dupe.name,
|
dupe.name,
|
||||||
format_path(dupe.path),
|
format_path(dupe.path),
|
||||||
format_size(size, 0, 1, False),
|
format_size(size, 0, 1, False),
|
||||||
dupe.extension,
|
dupe.extension if hasattr(dupe, 'extension') else '---',
|
||||||
]
|
]
|
||||||
|
|
||||||
def GetDupeSortKey(dupe, get_group, key, delta):
|
def GetDupeSortKey(dupe, get_group, key, delta):
|
||||||
|
|||||||
@@ -10,10 +10,9 @@ import os.path as op
|
|||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from nose.tools import eq_
|
|
||||||
|
|
||||||
from hsutil import io
|
from hsutil import io
|
||||||
from hsutil.path import Path
|
from hsutil.path import Path
|
||||||
|
from hsutil.testutil import eq_
|
||||||
from hsutil.testcase import TestCase
|
from hsutil.testcase import TestCase
|
||||||
|
|
||||||
from ..directories import *
|
from ..directories import *
|
||||||
|
|||||||
@@ -8,13 +8,13 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from nose.tools import eq_
|
from hscommon import job
|
||||||
|
|
||||||
from hsutil import job
|
|
||||||
from hsutil.decorators import log_calls
|
from hsutil.decorators import log_calls
|
||||||
|
from hsutil.misc import first
|
||||||
|
from hsutil.testutil import eq_
|
||||||
from hsutil.testcase import TestCase
|
from hsutil.testcase import TestCase
|
||||||
|
|
||||||
from .. import engine, fs
|
from .. import engine
|
||||||
from ..engine import *
|
from ..engine import *
|
||||||
|
|
||||||
class NamedObject(object):
|
class NamedObject(object):
|
||||||
@@ -46,6 +46,15 @@ def get_test_group():
|
|||||||
result.add_match(m3)
|
result.add_match(m3)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def assert_match(m, name1, name2):
|
||||||
|
# When testing matches, whether objects are in first or second position very often doesn't
|
||||||
|
# matter. This function makes this test more convenient.
|
||||||
|
if m.first.name == name1:
|
||||||
|
eq_(m.second.name, name2)
|
||||||
|
else:
|
||||||
|
eq_(m.first.name, name2)
|
||||||
|
eq_(m.second.name, name1)
|
||||||
|
|
||||||
class TCgetwords(TestCase):
|
class TCgetwords(TestCase):
|
||||||
def test_spaces(self):
|
def test_spaces(self):
|
||||||
self.assertEqual(['a', 'b', 'c', 'd'], getwords("a b c d"))
|
self.assertEqual(['a', 'b', 'c', 'd'], getwords("a b c d"))
|
||||||
@@ -229,10 +238,9 @@ class TCbuild_word_dict(TestCase):
|
|||||||
self.log = []
|
self.log = []
|
||||||
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
|
||||||
self.assertEqual(0,self.log[0])
|
self.assertEqual(0,self.log[0])
|
||||||
self.assertEqual(33,self.log[1])
|
self.assertEqual(100,self.log[1])
|
||||||
self.assertEqual(66,self.log[2])
|
|
||||||
self.assertEqual(100,self.log[3])
|
|
||||||
|
|
||||||
|
|
||||||
class TCmerge_similar_words(TestCase):
|
class TCmerge_similar_words(TestCase):
|
||||||
@@ -352,23 +360,18 @@ class GetMatches(TestCase):
|
|||||||
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))
|
self.assertEqual(2,len(r))
|
||||||
seek = [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"
|
||||||
m = seek[0]
|
assert_match(m, 'foo bar', 'bar bleh')
|
||||||
self.assertEqual(['foo','bar'],m.first.words)
|
m = first(m for m in r if m.percentage == 33) #"foo bar" and "a b c foo"
|
||||||
self.assertEqual(['bar','bleh'],m.second.words)
|
assert_match(m, 'foo bar', 'a b c foo')
|
||||||
seek = [m for m in r if m.percentage == 33] #"foo bar" and "a b c foo"
|
|
||||||
m = seek[0]
|
|
||||||
self.assertEqual(['foo','bar'],m.first.words)
|
|
||||||
self.assertEqual(['a','b','c','foo'],m.second.words)
|
|
||||||
|
|
||||||
def test_null_and_unrelated_objects(self):
|
def test_null_and_unrelated_objects(self):
|
||||||
l = [NamedObject("foo bar"),NamedObject("bar bleh"),NamedObject(""),NamedObject("unrelated object")]
|
l = [NamedObject("foo bar"),NamedObject("bar bleh"),NamedObject(""),NamedObject("unrelated object")]
|
||||||
r = getmatches(l)
|
r = getmatches(l)
|
||||||
self.assertEqual(1,len(r))
|
eq_(len(r), 1)
|
||||||
m = r[0]
|
m = r[0]
|
||||||
self.assertEqual(50,m.percentage)
|
eq_(m.percentage, 50)
|
||||||
self.assertEqual(['foo','bar'],m.first.words)
|
assert_match(m, 'foo bar', 'bar bleh')
|
||||||
self.assertEqual(['bar','bleh'],m.second.words)
|
|
||||||
|
|
||||||
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")]
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
# http://www.hardcoded.net/licenses/hs_license
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
import cStringIO
|
import cStringIO
|
||||||
import xml.dom.minidom
|
from lxml import etree
|
||||||
|
|
||||||
from nose.tools import eq_
|
from hsutil.testutil import eq_
|
||||||
|
|
||||||
from ..ignore import *
|
from ..ignore import *
|
||||||
|
|
||||||
@@ -62,26 +62,25 @@ def test_save_to_xml():
|
|||||||
f = cStringIO.StringIO()
|
f = cStringIO.StringIO()
|
||||||
il.save_to_xml(f)
|
il.save_to_xml(f)
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
doc = xml.dom.minidom.parse(f)
|
doc = etree.parse(f)
|
||||||
root = doc.documentElement
|
root = doc.getroot()
|
||||||
eq_('ignore_list',root.nodeName)
|
eq_(root.tag, 'ignore_list')
|
||||||
children = [c for c in root.childNodes if c.localName]
|
eq_(len(root), 2)
|
||||||
eq_(2,len(children))
|
eq_(len([c for c in root if c.tag == 'file']), 2)
|
||||||
eq_(2,len([c for c in children if c.nodeName == 'file']))
|
f1, f2 = root[:]
|
||||||
f1,f2 = children
|
subchildren = [c for c in f1 if c.tag == 'file'] + [c for c in f2 if c.tag == 'file']
|
||||||
subchildren = [c for c in f1.childNodes if c.localName == 'file'] +\
|
eq_(len(subchildren), 3)
|
||||||
[c for c in f2.childNodes if c.localName == 'file']
|
|
||||||
eq_(3,len(subchildren))
|
|
||||||
|
|
||||||
def test_SaveThenLoad():
|
def test_SaveThenLoad():
|
||||||
il = IgnoreList()
|
il = IgnoreList()
|
||||||
il.Ignore('foo','bar')
|
il.Ignore('foo', 'bar')
|
||||||
il.Ignore('foo','bleh')
|
il.Ignore('foo', 'bleh')
|
||||||
il.Ignore('bleh','bar')
|
il.Ignore('bleh', 'bar')
|
||||||
il.Ignore(u'\u00e9','bar')
|
il.Ignore(u'\u00e9', 'bar')
|
||||||
f = cStringIO.StringIO()
|
f = cStringIO.StringIO()
|
||||||
il.save_to_xml(f)
|
il.save_to_xml(f)
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
|
f.seek(0)
|
||||||
il = IgnoreList()
|
il = IgnoreList()
|
||||||
il.load_from_xml(f)
|
il.load_from_xml(f)
|
||||||
eq_(4,len(il))
|
eq_(4,len(il))
|
||||||
@@ -129,9 +128,9 @@ def test_filter():
|
|||||||
assert not il.AreIgnored('foo','bar')
|
assert not il.AreIgnored('foo','bar')
|
||||||
assert il.AreIgnored('bar','baz')
|
assert il.AreIgnored('bar','baz')
|
||||||
|
|
||||||
def test_save_with_non_ascii_non_unicode_items():
|
def test_save_with_non_ascii_items():
|
||||||
il = IgnoreList()
|
il = IgnoreList()
|
||||||
il.Ignore('\xac','\xbf')
|
il.Ignore(u'\xac', u'\xbf')
|
||||||
f = cStringIO.StringIO()
|
f = cStringIO.StringIO()
|
||||||
try:
|
try:
|
||||||
il.save_to_xml(f)
|
il.save_to_xml(f)
|
||||||
|
|||||||
@@ -7,18 +7,19 @@
|
|||||||
# 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/hs_license
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
import unittest
|
|
||||||
import StringIO
|
import StringIO
|
||||||
import xml.dom.minidom
|
|
||||||
import os.path as op
|
import os.path as op
|
||||||
|
|
||||||
|
from lxml import etree
|
||||||
|
|
||||||
from hsutil.path import Path
|
from hsutil.path import Path
|
||||||
|
from hsutil.testutil import eq_
|
||||||
from hsutil.testcase import TestCase
|
from hsutil.testcase import TestCase
|
||||||
from hsutil.misc import first
|
from hsutil.misc import first
|
||||||
|
|
||||||
from . import engine_test, data
|
from . import engine_test, data
|
||||||
from .. import engine
|
from .. import engine
|
||||||
from ..results import *
|
from ..results import Results
|
||||||
|
|
||||||
class NamedObject(engine_test.NamedObject):
|
class NamedObject(engine_test.NamedObject):
|
||||||
path = property(lambda x:Path('basepath') + x.name)
|
path = property(lambda x:Path('basepath') + x.name)
|
||||||
@@ -65,9 +66,9 @@ class TCResultsEmpty(TestCase):
|
|||||||
f = StringIO.StringIO()
|
f = StringIO.StringIO()
|
||||||
self.results.save_to_xml(f)
|
self.results.save_to_xml(f)
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
doc = xml.dom.minidom.parse(f)
|
doc = etree.parse(f)
|
||||||
root = doc.documentElement
|
root = doc.getroot()
|
||||||
self.assertEqual('results',root.nodeName)
|
self.assertEqual('results', root.tag)
|
||||||
|
|
||||||
|
|
||||||
class TCResultsWithSomeGroups(TestCase):
|
class TCResultsWithSomeGroups(TestCase):
|
||||||
@@ -253,18 +254,23 @@ class TCResultsMarkings(TestCase):
|
|||||||
def test_perform_on_marked_with_problems(self):
|
def test_perform_on_marked_with_problems(self):
|
||||||
def log_object(o):
|
def log_object(o):
|
||||||
log.append(o)
|
log.append(o)
|
||||||
return o is not self.objects[1]
|
if o is self.objects[1]:
|
||||||
|
raise EnvironmentError('foobar')
|
||||||
|
|
||||||
log = []
|
log = []
|
||||||
self.results.mark_all()
|
self.results.mark_all()
|
||||||
self.assert_(self.results.is_marked(self.objects[1]))
|
assert self.results.is_marked(self.objects[1])
|
||||||
self.assertEqual(1,self.results.perform_on_marked(log_object, True))
|
self.results.perform_on_marked(log_object, True)
|
||||||
self.assertEqual(3,len(log))
|
eq_(len(log), 3)
|
||||||
self.assertEqual(1,len(self.results.groups))
|
eq_(len(self.results.groups), 1)
|
||||||
self.assertEqual(2,len(self.results.groups[0]))
|
eq_(len(self.results.groups[0]), 2)
|
||||||
self.assert_(self.objects[1] in self.results.groups[0])
|
assert self.objects[1] in self.results.groups[0]
|
||||||
self.assert_(not self.results.is_marked(self.objects[2]))
|
assert not self.results.is_marked(self.objects[2])
|
||||||
self.assert_(self.results.is_marked(self.objects[1]))
|
assert self.results.is_marked(self.objects[1])
|
||||||
|
eq_(len(self.results.problems), 1)
|
||||||
|
dupe, msg = self.results.problems[0]
|
||||||
|
assert dupe is self.objects[1]
|
||||||
|
eq_(msg, 'foobar')
|
||||||
|
|
||||||
def test_perform_on_marked_with_ref(self):
|
def test_perform_on_marked_with_ref(self):
|
||||||
def log_object(o):
|
def log_object(o):
|
||||||
@@ -321,16 +327,16 @@ class TCResultsMarkings(TestCase):
|
|||||||
f = StringIO.StringIO()
|
f = StringIO.StringIO()
|
||||||
self.results.save_to_xml(f)
|
self.results.save_to_xml(f)
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
doc = xml.dom.minidom.parse(f)
|
doc = etree.parse(f)
|
||||||
root = doc.documentElement
|
root = doc.getroot()
|
||||||
g1,g2 = root.getElementsByTagName('group')
|
g1, g2 = root.iterchildren('group')
|
||||||
d1,d2,d3 = g1.getElementsByTagName('file')
|
d1, d2, d3 = g1.iterchildren('file')
|
||||||
self.assertEqual('n',d1.getAttributeNode('marked').nodeValue)
|
self.assertEqual('n', d1.get('marked'))
|
||||||
self.assertEqual('n',d2.getAttributeNode('marked').nodeValue)
|
self.assertEqual('n', d2.get('marked'))
|
||||||
self.assertEqual('y',d3.getAttributeNode('marked').nodeValue)
|
self.assertEqual('y', d3.get('marked'))
|
||||||
d1,d2 = g2.getElementsByTagName('file')
|
d1, d2 = g2.iterchildren('file')
|
||||||
self.assertEqual('n',d1.getAttributeNode('marked').nodeValue)
|
self.assertEqual('n', d1.get('marked'))
|
||||||
self.assertEqual('y',d2.getAttributeNode('marked').nodeValue)
|
self.assertEqual('y', d2.get('marked'))
|
||||||
|
|
||||||
def test_LoadXML(self):
|
def test_LoadXML(self):
|
||||||
def get_file(path):
|
def get_file(path):
|
||||||
@@ -366,38 +372,35 @@ class TCResultsXML(TestCase):
|
|||||||
f = StringIO.StringIO()
|
f = StringIO.StringIO()
|
||||||
self.results.save_to_xml(f)
|
self.results.save_to_xml(f)
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
doc = xml.dom.minidom.parse(f)
|
doc = etree.parse(f)
|
||||||
root = doc.documentElement
|
root = doc.getroot()
|
||||||
self.assertEqual('results',root.nodeName)
|
self.assertEqual('results', root.tag)
|
||||||
children = [c for c in root.childNodes if c.localName]
|
self.assertEqual(2, len(root))
|
||||||
self.assertEqual(2,len(children))
|
self.assertEqual(2, len([c for c in root if c.tag == 'group']))
|
||||||
self.assertEqual(2,len([c for c in children if c.nodeName == 'group']))
|
g1, g2 = root
|
||||||
g1,g2 = children
|
self.assertEqual(6,len(g1))
|
||||||
children = [c for c in g1.childNodes if c.localName]
|
self.assertEqual(3,len([c for c in g1 if c.tag == 'file']))
|
||||||
self.assertEqual(6,len(children))
|
self.assertEqual(3,len([c for c in g1 if c.tag == 'match']))
|
||||||
self.assertEqual(3,len([c for c in children if c.nodeName == 'file']))
|
d1, d2, d3 = [c for c in g1 if c.tag == 'file']
|
||||||
self.assertEqual(3,len([c for c in children if c.nodeName == 'match']))
|
self.assertEqual(op.join('basepath','foo bar'),d1.get('path'))
|
||||||
d1,d2,d3 = [c for c in children if c.nodeName == 'file']
|
self.assertEqual(op.join('basepath','bar bleh'),d2.get('path'))
|
||||||
self.assertEqual(op.join('basepath','foo bar'),d1.getAttributeNode('path').nodeValue)
|
self.assertEqual(op.join('basepath','foo bleh'),d3.get('path'))
|
||||||
self.assertEqual(op.join('basepath','bar bleh'),d2.getAttributeNode('path').nodeValue)
|
self.assertEqual('y',d1.get('is_ref'))
|
||||||
self.assertEqual(op.join('basepath','foo bleh'),d3.getAttributeNode('path').nodeValue)
|
self.assertEqual('n',d2.get('is_ref'))
|
||||||
self.assertEqual('y',d1.getAttributeNode('is_ref').nodeValue)
|
self.assertEqual('n',d3.get('is_ref'))
|
||||||
self.assertEqual('n',d2.getAttributeNode('is_ref').nodeValue)
|
self.assertEqual('foo,bar',d1.get('words'))
|
||||||
self.assertEqual('n',d3.getAttributeNode('is_ref').nodeValue)
|
self.assertEqual('bar,bleh',d2.get('words'))
|
||||||
self.assertEqual('foo,bar',d1.getAttributeNode('words').nodeValue)
|
self.assertEqual('foo,bleh',d3.get('words'))
|
||||||
self.assertEqual('bar,bleh',d2.getAttributeNode('words').nodeValue)
|
self.assertEqual(3,len(g2))
|
||||||
self.assertEqual('foo,bleh',d3.getAttributeNode('words').nodeValue)
|
self.assertEqual(2,len([c for c in g2 if c.tag == 'file']))
|
||||||
children = [c for c in g2.childNodes if c.localName]
|
self.assertEqual(1,len([c for c in g2 if c.tag == 'match']))
|
||||||
self.assertEqual(3,len(children))
|
d1, d2 = [c for c in g2 if c.tag == 'file']
|
||||||
self.assertEqual(2,len([c for c in children if c.nodeName == 'file']))
|
self.assertEqual(op.join('basepath','ibabtu'),d1.get('path'))
|
||||||
self.assertEqual(1,len([c for c in children if c.nodeName == 'match']))
|
self.assertEqual(op.join('basepath','ibabtu'),d2.get('path'))
|
||||||
d1,d2 = [c for c in children if c.nodeName == 'file']
|
self.assertEqual('n',d1.get('is_ref'))
|
||||||
self.assertEqual(op.join('basepath','ibabtu'),d1.getAttributeNode('path').nodeValue)
|
self.assertEqual('n',d2.get('is_ref'))
|
||||||
self.assertEqual(op.join('basepath','ibabtu'),d2.getAttributeNode('path').nodeValue)
|
self.assertEqual('ibabtu',d1.get('words'))
|
||||||
self.assertEqual('n',d1.getAttributeNode('is_ref').nodeValue)
|
self.assertEqual('ibabtu',d2.get('words'))
|
||||||
self.assertEqual('n',d2.getAttributeNode('is_ref').nodeValue)
|
|
||||||
self.assertEqual('ibabtu',d1.getAttributeNode('words').nodeValue)
|
|
||||||
self.assertEqual('ibabtu',d2.getAttributeNode('words').nodeValue)
|
|
||||||
|
|
||||||
def test_LoadXML(self):
|
def test_LoadXML(self):
|
||||||
def get_file(path):
|
def get_file(path):
|
||||||
@@ -460,41 +463,41 @@ class TCResultsXML(TestCase):
|
|||||||
def get_file(path):
|
def get_file(path):
|
||||||
return [f for f in self.objects if str(f.path) == path][0]
|
return [f for f in self.objects if str(f.path) == path][0]
|
||||||
|
|
||||||
doc = xml.dom.minidom.Document()
|
root = etree.Element('foobar') #The root element shouldn't matter, really.
|
||||||
root = doc.appendChild(doc.createElement('foobar')) #The root element shouldn't matter, really.
|
group_node = etree.SubElement(root, 'group')
|
||||||
group_node = root.appendChild(doc.createElement('group'))
|
dupe_node = etree.SubElement(group_node, 'file') #Perfectly correct file
|
||||||
dupe_node = group_node.appendChild(doc.createElement('file')) #Perfectly correct file
|
dupe_node.set('path', op.join('basepath','foo bar'))
|
||||||
dupe_node.setAttribute('path',op.join('basepath','foo bar'))
|
dupe_node.set('is_ref', 'y')
|
||||||
dupe_node.setAttribute('is_ref','y')
|
dupe_node.set('words', 'foo,bar')
|
||||||
dupe_node.setAttribute('words','foo,bar')
|
dupe_node = etree.SubElement(group_node, 'file') #is_ref missing, default to 'n'
|
||||||
dupe_node = group_node.appendChild(doc.createElement('file')) #is_ref missing, default to 'n'
|
dupe_node.set('path',op.join('basepath','foo bleh'))
|
||||||
dupe_node.setAttribute('path',op.join('basepath','foo bleh'))
|
dupe_node.set('words','foo,bleh')
|
||||||
dupe_node.setAttribute('words','foo,bleh')
|
dupe_node = etree.SubElement(group_node, 'file') #words are missing, valid.
|
||||||
dupe_node = group_node.appendChild(doc.createElement('file')) #words are missing, invalid.
|
dupe_node.set('path',op.join('basepath','bar bleh'))
|
||||||
dupe_node.setAttribute('path',op.join('basepath','bar bleh'))
|
dupe_node = etree.SubElement(group_node, 'file') #path is missing, invalid.
|
||||||
dupe_node = group_node.appendChild(doc.createElement('file')) #path is missing, invalid.
|
dupe_node.set('words','foo,bleh')
|
||||||
dupe_node.setAttribute('words','foo,bleh')
|
dupe_node = etree.SubElement(group_node, 'foobar') #Invalid element name
|
||||||
dupe_node = group_node.appendChild(doc.createElement('foobar')) #Invalid element name
|
dupe_node.set('path',op.join('basepath','bar bleh'))
|
||||||
dupe_node.setAttribute('path',op.join('basepath','bar bleh'))
|
dupe_node.set('is_ref','y')
|
||||||
dupe_node.setAttribute('is_ref','y')
|
dupe_node.set('words','bar,bleh')
|
||||||
dupe_node.setAttribute('words','bar,bleh')
|
match_node = etree.SubElement(group_node, 'match') # match pointing to a bad index
|
||||||
match_node = group_node.appendChild(doc.createElement('match')) # match pointing to a bad index
|
match_node.set('first', '42')
|
||||||
match_node.setAttribute('first', '42')
|
match_node.set('second', '45')
|
||||||
match_node.setAttribute('second', '45')
|
match_node = etree.SubElement(group_node, 'match') # match with missing attrs
|
||||||
match_node = group_node.appendChild(doc.createElement('match')) # match with missing attrs
|
match_node = etree.SubElement(group_node, 'match') # match with non-int values
|
||||||
match_node = group_node.appendChild(doc.createElement('match')) # match with non-int values
|
match_node.set('first', 'foo')
|
||||||
match_node.setAttribute('first', 'foo')
|
match_node.set('second', 'bar')
|
||||||
match_node.setAttribute('second', 'bar')
|
match_node.set('percentage', 'baz')
|
||||||
match_node.setAttribute('percentage', 'baz')
|
group_node = etree.SubElement(root, 'foobar') #invalid group
|
||||||
group_node = root.appendChild(doc.createElement('foobar')) #invalid group
|
group_node = etree.SubElement(root, 'group') #empty group
|
||||||
group_node = root.appendChild(doc.createElement('group')) #empty group
|
|
||||||
f = StringIO.StringIO()
|
f = StringIO.StringIO()
|
||||||
doc.writexml(f,'\t','\t','\n',encoding='utf-8')
|
tree = etree.ElementTree(root)
|
||||||
|
tree.write(f, encoding='utf-8')
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
r = Results(data)
|
r = Results(data)
|
||||||
r.load_from_xml(f,get_file)
|
r.load_from_xml(f, get_file)
|
||||||
self.assertEqual(1,len(r.groups))
|
self.assertEqual(1,len(r.groups))
|
||||||
self.assertEqual(2,len(r.groups[0]))
|
self.assertEqual(3,len(r.groups[0]))
|
||||||
|
|
||||||
def test_xml_non_ascii(self):
|
def test_xml_non_ascii(self):
|
||||||
def get_file(path):
|
def get_file(path):
|
||||||
@@ -567,6 +570,16 @@ class TCResultsXML(TestCase):
|
|||||||
self.results.load_from_xml(f, self.get_file)
|
self.results.load_from_xml(f, self.get_file)
|
||||||
first(self.results.groups[0].matches).percentage
|
first(self.results.groups[0].matches).percentage
|
||||||
|
|
||||||
|
def test_apply_filter_works_on_paths(self):
|
||||||
|
# apply_filter() searches on the whole path, not just on the filename.
|
||||||
|
self.results.apply_filter(u'basepath')
|
||||||
|
eq_(len(self.results.groups), 2)
|
||||||
|
|
||||||
|
def test_save_xml_with_invalid_characters(self):
|
||||||
|
# Don't crash when saving files that have invalid xml characters in their path
|
||||||
|
self.objects[0].name = u'foo\x19'
|
||||||
|
self.results.save_to_xml(StringIO.StringIO()) # don't crash
|
||||||
|
|
||||||
|
|
||||||
class TCResultsFilter(TestCase):
|
class TCResultsFilter(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|||||||
@@ -6,10 +6,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/hs_license
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
from nose.tools import eq_
|
|
||||||
|
|
||||||
from hsutil import job, io
|
from hscommon import job
|
||||||
|
from hsutil import io
|
||||||
from hsutil.path import Path
|
from hsutil.path import Path
|
||||||
|
from hsutil.testutil import eq_
|
||||||
from hsutil.testcase import TestCase
|
from hsutil.testcase import TestCase
|
||||||
|
|
||||||
from .. import fs
|
from .. import fs
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import logging
|
|||||||
from appscript import app, k, CommandError
|
from appscript import app, k, CommandError
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from hsutil.cocoa import as_fetch
|
from hscommon.cocoa import as_fetch
|
||||||
|
|
||||||
from core.app_cocoa import JOBID2TITLE, DupeGuru as DupeGuruBase
|
from core.app_cocoa import JOBID2TITLE, DupeGuru as DupeGuruBase
|
||||||
|
|
||||||
|
|||||||
@@ -85,9 +85,9 @@ def GetDupeSortKey(dupe, get_group, key, delta):
|
|||||||
return m.percentage
|
return m.percentage
|
||||||
if key == 18:
|
if key == 18:
|
||||||
return 0
|
return 0
|
||||||
r = cmp_value(getattr(dupe, COLUMNS[key]['attr']))
|
r = cmp_value(getattr(dupe, COLUMNS[key]['attr'], ''))
|
||||||
if delta and (key in (2, 3, 4, 7, 8)):
|
if delta and (key in (2, 3, 4, 7, 8)):
|
||||||
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):
|
||||||
@@ -95,4 +95,4 @@ def GetGroupSortKey(group, key):
|
|||||||
return group.percentage
|
return group.percentage
|
||||||
if key == 18:
|
if key == 18:
|
||||||
return len(group)
|
return len(group)
|
||||||
return cmp_value(getattr(group.ref, COLUMNS[key]['attr']))
|
return cmp_value(getattr(group.ref, COLUMNS[key]['attr'], ''))
|
||||||
|
|||||||
@@ -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/hs_license
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
from hsmedia import mpeg, wma, mp4, ogg, flac, aiff
|
from hsaudiotag import mpeg, wma, mp4, ogg, flac, aiff
|
||||||
from hsutil.str import get_file_ext
|
from hsutil.str import get_file_ext
|
||||||
from core import fs
|
from core import fs
|
||||||
|
|
||||||
|
|||||||
28
core_me/tests/conftest.py
Normal file
28
core_me/tests/conftest.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# -*- 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()
|
||||||
@@ -7,28 +7,22 @@
|
|||||||
# http://www.hardcoded.net/licenses/hs_license
|
# http://www.hardcoded.net/licenses/hs_license
|
||||||
|
|
||||||
import os.path as op
|
import os.path as op
|
||||||
import logging
|
|
||||||
import plistlib
|
import plistlib
|
||||||
import re
|
|
||||||
|
|
||||||
from Foundation import NSBundle, NSUserDefaults, NSURL
|
from lxml import etree
|
||||||
from appscript import app, k, CommandError
|
from appscript import app, k, CommandError
|
||||||
|
|
||||||
from hsutil import io
|
from hsutil import io
|
||||||
from hsutil.str import get_file_ext
|
from hsutil.str import get_file_ext
|
||||||
from hsutil.path import Path
|
from hsutil.path import Path
|
||||||
from hsutil.cocoa import as_fetch
|
from hscommon.cocoa import as_fetch
|
||||||
|
from hscommon.cocoa.objcmin import NSUserDefaults, NSURL
|
||||||
|
|
||||||
from core import fs
|
from core import fs
|
||||||
from core import app_cocoa, directories
|
from core import app_cocoa, directories
|
||||||
from . import data
|
from . import data, _block_osx
|
||||||
from .cache import string_to_colors
|
|
||||||
from .scanner import ScannerPE
|
from .scanner import ScannerPE
|
||||||
|
|
||||||
mainBundle = NSBundle.mainBundle()
|
|
||||||
PictureBlocks = mainBundle.classNamed_('PictureBlocks')
|
|
||||||
assert PictureBlocks is not None
|
|
||||||
|
|
||||||
class Photo(fs.File):
|
class Photo(fs.File):
|
||||||
INITIAL_INFO = fs.File.INITIAL_INFO.copy()
|
INITIAL_INFO = fs.File.INITIAL_INFO.copy()
|
||||||
INITIAL_INFO.update({
|
INITIAL_INFO.update({
|
||||||
@@ -43,17 +37,16 @@ class Photo(fs.File):
|
|||||||
def _read_info(self, field):
|
def _read_info(self, field):
|
||||||
fs.File._read_info(self, field)
|
fs.File._read_info(self, field)
|
||||||
if field == 'dimensions':
|
if field == 'dimensions':
|
||||||
size = PictureBlocks.getImageSize_(unicode(self.path))
|
self.dimensions = _block_osx.get_image_size(unicode(self.path))
|
||||||
self.dimensions = (size.width, size.height)
|
|
||||||
|
|
||||||
def get_blocks(self, block_count_per_side):
|
def get_blocks(self, block_count_per_side):
|
||||||
try:
|
try:
|
||||||
blocks = PictureBlocks.getBlocksFromImagePath_blockCount_(unicode(self.path), block_count_per_side)
|
blocks = _block_osx.getblocks(unicode(self.path), block_count_per_side)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise IOError('The reading of "%s" failed with "%s"' % (unicode(self.path), unicode(e)))
|
raise IOError('The reading of "%s" failed with "%s"' % (unicode(self.path), unicode(e)))
|
||||||
if not blocks:
|
if not blocks:
|
||||||
raise IOError('The picture %s could not be read' % unicode(self.path))
|
raise IOError('The picture %s could not be read' % unicode(self.path))
|
||||||
return string_to_colors(blocks)
|
return blocks
|
||||||
|
|
||||||
|
|
||||||
class IPhoto(Photo):
|
class IPhoto(Photo):
|
||||||
@@ -74,15 +67,10 @@ def get_iphoto_database_path():
|
|||||||
def get_iphoto_pictures(plistpath):
|
def get_iphoto_pictures(plistpath):
|
||||||
if not io.exists(plistpath):
|
if not io.exists(plistpath):
|
||||||
return []
|
return []
|
||||||
s = io.open(plistpath).read()
|
# We make the xml go through lxml so that it can fix broken xml which iPhoto sometimes produces.
|
||||||
# There was a case where a guy had 0x10 chars in his plist, causing expat errors on loading
|
parser = etree.XMLParser(recover=True)
|
||||||
s = s.replace('\x10', '')
|
root = etree.parse(io.open(plistpath), parser=parser).getroot()
|
||||||
# It seems that iPhoto sometimes doesn't properly escape & chars. The regexp below is to find
|
s = etree.tostring(root)
|
||||||
# any & char that is not a &-based entity (&, ", etc.). based on TextMate's XML
|
|
||||||
# bundle's regexp
|
|
||||||
s, count = re.subn(r'&(?![a-zA-Z0-9_-]+|#[0-9]+|#x[0-9a-fA-F]+;)', '', s)
|
|
||||||
if count:
|
|
||||||
logging.warning("%d invalid XML entities replacement made", count)
|
|
||||||
plist = plistlib.readPlistFromString(s)
|
plist = plistlib.readPlistFromString(s)
|
||||||
result = []
|
result = []
|
||||||
for photo_data in plist['Master Image List'].values():
|
for photo_data in plist['Master Image List'].values():
|
||||||
@@ -158,7 +146,7 @@ class DupeGuruPE(app_cocoa.DupeGuru):
|
|||||||
except (CommandError, RuntimeError):
|
except (CommandError, RuntimeError):
|
||||||
pass
|
pass
|
||||||
j.start_job(self.results.mark_count, "Sending dupes to the Trash")
|
j.start_job(self.results.mark_count, "Sending dupes to the Trash")
|
||||||
self.last_op_error_count = self.results.perform_on_marked(op, True)
|
self.results.perform_on_marked(op, True)
|
||||||
del self.path2iphoto
|
del self.path2iphoto
|
||||||
|
|
||||||
def _do_delete_dupe(self, dupe):
|
def _do_delete_dupe(self, dupe):
|
||||||
@@ -168,14 +156,13 @@ class DupeGuruPE(app_cocoa.DupeGuru):
|
|||||||
try:
|
try:
|
||||||
a = app('iPhoto')
|
a = app('iPhoto')
|
||||||
a.remove(photo, timeout=0)
|
a.remove(photo, timeout=0)
|
||||||
return True
|
except (CommandError, RuntimeError) as e:
|
||||||
except (CommandError, RuntimeError):
|
raise EnvironmentError(unicode(e))
|
||||||
return False
|
|
||||||
else:
|
else:
|
||||||
logging.warning(u"Could not find photo %s in iPhoto Library", unicode(dupe.path))
|
msg = u"Could not find photo %s in iPhoto Library" % unicode(dupe.path)
|
||||||
return False
|
raise EnvironmentError(msg)
|
||||||
else:
|
else:
|
||||||
return app_cocoa.DupeGuru._do_delete_dupe(self, dupe)
|
app_cocoa.DupeGuru._do_delete_dupe(self, dupe)
|
||||||
|
|
||||||
def _do_load(self, j):
|
def _do_load(self, j):
|
||||||
self.directories.load_from_file(op.join(self.appdata, 'last_directories.xml'))
|
self.directories.load_from_file(op.join(self.appdata, 'last_directories.xml'))
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user