mirror of
https://github.com/arsenetar/dupeguru.git
synced 2026-01-25 16:11:39 +00:00
Compare commits
295 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75239d6a64 | ||
|
|
09082955a3 | ||
|
|
6a6f2d51aa | ||
|
|
7b0d3ea8ac | ||
|
|
1c88b6bb26 | ||
|
|
e5e8e5d908 | ||
|
|
92fadd26b7 | ||
|
|
45d783ac43 | ||
|
|
ea9e76e7ae | ||
|
|
28426c0e91 | ||
|
|
3a9f51b600 | ||
|
|
f1b4db368e | ||
|
|
95efac187b | ||
|
|
6770d22438 | ||
|
|
4ce97613c4 | ||
|
|
030eb8eb6e | ||
|
|
c9da8e26e6 | ||
|
|
7ddf9772df | ||
|
|
0382ad1534 | ||
|
|
1b6e1369a0 | ||
|
|
835050c337 | ||
|
|
ca6a42e6eb | ||
|
|
a2e4d893ac | ||
|
|
657520b0b3 | ||
|
|
ea4b87895c | ||
|
|
19db500a19 | ||
|
|
1366cfd478 | ||
|
|
56a6df1f68 | ||
|
|
a1b35a8abf | ||
|
|
8a8a181186 | ||
|
|
463a551f7d | ||
|
|
fc613fb325 | ||
|
|
4517bea664 | ||
|
|
81dcfbe6ae | ||
|
|
fa8e64d04a | ||
|
|
562123b219 | ||
|
|
b217309618 | ||
|
|
357a02c74b | ||
|
|
508eeffa6e | ||
|
|
31555aa473 | ||
|
|
d2f968def7 | ||
|
|
d574bc611b | ||
|
|
a50a3b0123 | ||
|
|
5b6891dd45 | ||
|
|
4886982d43 | ||
|
|
7360f57beb | ||
|
|
491279b7a8 | ||
|
|
05b79f81af | ||
|
|
96ef2f2dd3 | ||
|
|
2542af17b6 | ||
|
|
c86bc649ff | ||
|
|
4b8e48ed88 | ||
|
|
a1addfd416 | ||
|
|
a1a57d8933 | ||
|
|
864970b860 | ||
|
|
a056be0842 | ||
|
|
c672e75739 | ||
|
|
7b5dd3f964 | ||
|
|
a6072f608b | ||
|
|
06462c65a5 | ||
|
|
359f9c0680 | ||
|
|
01db7c4948 | ||
|
|
f67f14a78d | ||
|
|
0a64d653e1 | ||
|
|
456a835285 | ||
|
|
0d8ed92a68 | ||
|
|
9bd093a03c | ||
|
|
361d4698a9 | ||
|
|
b342b15011 | ||
|
|
95638a3a80 | ||
|
|
2204fe3355 | ||
|
|
abcd774c9d | ||
|
|
ee209f8f88 | ||
|
|
b1f2e1c191 | ||
|
|
33f372f6c6 | ||
|
|
8e5c2a8875 | ||
|
|
36f3638ae4 | ||
|
|
d10210011f | ||
|
|
e867840d81 | ||
|
|
fb7e3189a8 | ||
|
|
5733c0143b | ||
|
|
ac4881f231 | ||
|
|
939efd7dab | ||
|
|
a93d96d742 | ||
|
|
f21804c769 | ||
|
|
4bc05a8d46 | ||
|
|
eebe2b0e80 | ||
|
|
250a496a78 | ||
|
|
29163ed053 | ||
|
|
cc05661f9e | ||
|
|
89409c22d1 | ||
|
|
e2f240ebc9 | ||
|
|
8d56f4c33b | ||
|
|
36eccb7122 | ||
|
|
c8827769b4 | ||
|
|
12e6c400b9 | ||
|
|
4c273a7910 | ||
|
|
58da335b17 | ||
|
|
5b2d506462 | ||
|
|
531430d44a | ||
|
|
7450eec7eb | ||
|
|
3a5802435f | ||
|
|
1b6b058097 | ||
|
|
a5797a2350 | ||
|
|
e81a5147c5 | ||
|
|
565c990687 | ||
|
|
0ccdfe0e26 | ||
|
|
f8a558e3a7 | ||
|
|
c5fa195cc6 | ||
|
|
3a821edd45 | ||
|
|
854d194f88 | ||
|
|
fb79daad6a | ||
|
|
b2ae0e8759 | ||
|
|
09f73988b3 | ||
|
|
9e6f289319 | ||
|
|
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 |
10
.hgignore
10
.hgignore
@@ -1,22 +1,22 @@
|
|||||||
syntax: glob
|
syntax: glob
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
run.py
|
||||||
*.pyc
|
*.pyc
|
||||||
*.so
|
*.so
|
||||||
*.mode1v3
|
*.mode1v3
|
||||||
*.pbxuser
|
*.pbxuser
|
||||||
*.tm_build_errors
|
*.tm_build_errors
|
||||||
|
*.pyd
|
||||||
conf.yaml
|
conf.yaml
|
||||||
build
|
build
|
||||||
core_pe/modules/block/block.c
|
dist
|
||||||
core_pe/modules/cache/cache.c
|
install
|
||||||
|
installer_tmp-cache
|
||||||
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/*/*_ui.py
|
|
||||||
qt/pe/modules/block/block.c
|
|
||||||
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
|
||||||
31
.hgtags
31
.hgtags
@@ -7,3 +7,34 @@ 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
|
||||||
|
3742e83edd9eadf44e1a501859f5e2462b1ef6fd me5.8.1
|
||||||
|
724ff565dd785fb739774588c6ee652cfc0612d5 pe1.9.1
|
||||||
|
634b66415c6529f46ae4f837318027cc9d70c3b5 before-py3k
|
||||||
|
2b67955db2b0580a8b0854dc918b6ab0d1fa3b88 se2.11.0
|
||||||
|
b56fe4dd8c95bca270b078a09e86848df77e2b2d me5.9.0
|
||||||
|
618a7365457d56fdc6920c70843a244762e2ea00 pe1.10.0
|
||||||
|
95b3a4b564c6222b414f2b40182dde2bd6d0e8a4 me5.9.1
|
||||||
|
9735a5218d2b5b3b1e1dfe17f2f874177cf8f61c se2.11.1
|
||||||
|
dbfee3ee2fa5cbb9e7ab36570659c17cd5b8561f se2.12.0
|
||||||
|
d3fe0d0dcda1e0bf1100d02f117503d3bf6baacf me5.10.0
|
||||||
|
b07ac1398703dd358912c1f3d20bd995633db9fe pe1.11.0
|
||||||
|
96b6aee668398d663b04eafc8d5dae05e18500ee before-fairware
|
||||||
|
22239f94589baf2a9fad2123045b8a718dbd68f5 se2.12.2
|
||||||
|
f9cae82a0752191276b24ffb2cc4e4a8afb5d754 me5.10.2
|
||||||
|
154c8cb6f018d446d88fa099490c900906e86386 pe1.11.2
|
||||||
|
ca93352ce35184853ad9fcb881935a43a8b1e249 me5.10.3
|
||||||
|
44f6ff67066c083f79daa18a9d2f1ab909e0a62e me5.10.4
|
||||||
|
|||||||
1
LICENSE
1
LICENSE
@@ -6,6 +6,5 @@ Redistribution and use in source and binary forms, with or without modification,
|
|||||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
* Neither the name of Hardcoded Software Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
* Neither the name of Hardcoded Software Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
* If the source code has been published less than two years ago, any redistribution, in whole or in part, must retain full licensing functionality, without any attempt to change, obscure or in other ways circumvent its intent.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
28
README
28
README
@@ -12,9 +12,7 @@ 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)
|
|
||||||
- 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.
|
||||||
|
|
||||||
@@ -26,27 +24,29 @@ Before being able to build dupeGuru, a few dependencies have to be installed:
|
|||||||
General dependencies
|
General dependencies
|
||||||
-----
|
-----
|
||||||
|
|
||||||
- Python 2.6 (http://www.python.org)
|
- Python 3.1 (http://www.python.org)
|
||||||
- Mako, to generate help files. (http://www.makotemplates.org/)
|
- Send2Trash3k (http://hg.hardcoded.net/send2trash)
|
||||||
|
- hsutil3k (http://hg.hardcoded.net/hsutil)
|
||||||
|
- hsaudiotag3k 1.1.0 (for ME) (http://hg.hardcoded.net/hsaudiotag)
|
||||||
|
- jobprogress (http://hg.hardcoded.net/jobprogress)
|
||||||
|
- Markdown, to generate help files. (http://pypi.python.org/pypi/Markdown)
|
||||||
- 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/)
|
- pytest 2.0.0, to run unit tests. (http://pytest.org/)
|
||||||
- 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.3. (http://pyobjc.sourceforge.net/)
|
||||||
- py2app (http://svn.pythonmac.org/py2app/py2app/trunk/doc/index.html)
|
- py2app 0.5.4 (http://bitbucket.org/ronaldoussoren/py2app)
|
||||||
|
|
||||||
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.7.5 (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/)
|
- 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 +56,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:
|
||||||
|
|
||||||
|
|||||||
176
build.py
176
build.py
@@ -3,9 +3,9 @@
|
|||||||
# Created On: 2009-12-30
|
# Created On: 2009-12-30
|
||||||
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
#
|
#
|
||||||
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
# 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
|
# 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/bsd_license
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
@@ -13,84 +13,136 @@ import os.path as op
|
|||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
|
from distutils.extension import Extension
|
||||||
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('../..')
|
||||||
|
print("Creating the run.py file")
|
||||||
|
subfolder = 'dev' if dev else 'release'
|
||||||
|
app_path = {
|
||||||
|
'se': 'cocoa/se/build/{0}/dupeGuru.app',
|
||||||
|
'me': 'cocoa/me/build/{0}/dupeGuru\\ ME.app',
|
||||||
|
'pe': 'cocoa/pe/build/{0}/dupeGuru\\ PE.app',
|
||||||
|
}[edition].format(subfolder)
|
||||||
|
tmpl = open('run_template_cocoa.py', 'rt').read()
|
||||||
|
run_contents = tmpl.replace('{{app_path}}', app_path)
|
||||||
|
open('run.py', 'wt').write(run_contents)
|
||||||
|
|
||||||
|
def build_qt(edition, dev):
|
||||||
|
print("Building Qt stuff")
|
||||||
|
print_and_do("pyrcc4 -py3 {0} > {1}".format(op.join('qt', 'base', 'dg.qrc'), op.join('qt', 'base', 'dg_rc.py')))
|
||||||
|
print("Creating the run.py file")
|
||||||
|
tmpl = open('run_template_qt.py', 'rt').read()
|
||||||
|
run_contents = tmpl.replace('{{edition}}', edition)
|
||||||
|
open('run.py', 'wt').write(run_contents)
|
||||||
|
|
||||||
|
def build_pe_modules(ui):
|
||||||
|
def move(src, dst):
|
||||||
|
if not op.exists(src):
|
||||||
|
return
|
||||||
|
if op.exists(dst):
|
||||||
|
os.remove(dst)
|
||||||
|
print('Moving %s --> %s' % (src, dst))
|
||||||
|
os.rename(src, dst)
|
||||||
|
|
||||||
|
print("Building PE Modules")
|
||||||
|
exts = [
|
||||||
|
Extension("_block", [op.join('core_pe', 'modules', 'block.c'), op.join('core_pe', 'modules', 'common.c')]),
|
||||||
|
Extension("_cache", [op.join('core_pe', 'modules', 'cache.c'), op.join('core_pe', 'modules', 'common.c')]),
|
||||||
|
]
|
||||||
|
if ui == 'qt':
|
||||||
|
exts.append(Extension("_block_qt", [op.join('qt', 'pe', 'modules', 'block.c')]))
|
||||||
|
elif ui == 'cocoa':
|
||||||
|
exts.append(Extension(
|
||||||
|
"_block_osx", [op.join('core_pe', 'modules', 'block_osx.m'), op.join('core_pe', 'modules', 'common.c')],
|
||||||
|
extra_link_args=[
|
||||||
|
"-framework", "CoreFoundation",
|
||||||
|
"-framework", "Foundation",
|
||||||
|
"-framework", "ApplicationServices",]
|
||||||
|
))
|
||||||
|
setup(
|
||||||
|
script_args = ['build_ext', '--inplace'],
|
||||||
|
ext_modules = exts,
|
||||||
|
)
|
||||||
|
move('_block.so', op.join('core_pe', '_block.so'))
|
||||||
|
move('_block.pyd', op.join('core_pe', '_block.pyd'))
|
||||||
|
move('_block_osx.so', op.join('core_pe', '_block_osx.so'))
|
||||||
|
move('_cache.so', op.join('core_pe', '_cache.so'))
|
||||||
|
move('_cache.pyd', op.join('core_pe', '_cache.pyd'))
|
||||||
|
move('_block_qt.so', op.join('qt', 'pe', '_block_qt.so'))
|
||||||
|
move('_block_qt.pyd', op.join('qt', 'pe', '_block_qt.pyd'))
|
||||||
|
|
||||||
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')
|
build_pe_modules(ui)
|
||||||
os.system('python gen.py')
|
|
||||||
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()
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
@@ -11,19 +11,25 @@ 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"
|
||||||
|
#import "HSAboutBox.h"
|
||||||
|
|
||||||
@interface AppDelegateBase : NSObject
|
@interface AppDelegateBase : NSObject
|
||||||
{
|
{
|
||||||
IBOutlet PyDupeGuruBase *py;
|
IBOutlet PyDupeGuruBase *py;
|
||||||
IBOutlet RecentDirectories *recentDirectories;
|
IBOutlet RecentDirectories *recentDirectories;
|
||||||
IBOutlet NSMenuItem *unlockMenuItem;
|
|
||||||
IBOutlet ResultWindowBase *result;
|
IBOutlet ResultWindowBase *result;
|
||||||
|
|
||||||
DetailsPanelBase *_detailsPanel;
|
DirectoryPanel *_directoryPanel;
|
||||||
|
DetailsPanel *_detailsPanel;
|
||||||
|
HSAboutBox *_aboutBox;
|
||||||
|
BOOL _savedResults;
|
||||||
}
|
}
|
||||||
- (IBAction)unlockApp:(id)sender;
|
|
||||||
|
|
||||||
- (PyDupeGuruBase *)py;
|
- (PyDupeGuruBase *)py;
|
||||||
- (RecentDirectories *)recentDirectories;
|
- (RecentDirectories *)recentDirectories;
|
||||||
- (DetailsPanelBase *)detailsPanel; // Virtual
|
- (DirectoryPanel *)directoryPanel;
|
||||||
|
- (DetailsPanel *)detailsPanel;
|
||||||
|
- (void)saveResults;
|
||||||
|
|
||||||
|
- (IBAction)showAboutBox:(id)sender;
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -1,34 +1,52 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
#import "ProgressController.h"
|
#import "ProgressController.h"
|
||||||
#import "RegistrationInterface.h"
|
#import "HSFairwareReminder.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
|
|
||||||
{
|
|
||||||
if ([[self py] isRegistered])
|
|
||||||
return;
|
|
||||||
RegistrationInterface *ri = [[RegistrationInterface alloc] initWithApp:[self py]];
|
|
||||||
if ([ri enterCode] == NSOKButton)
|
|
||||||
{
|
|
||||||
NSString *menuTitle = [NSString stringWithFormat:@"Thanks for buying %@!",[py appName]];
|
|
||||||
[unlockMenuItem setTitle:menuTitle];
|
|
||||||
}
|
|
||||||
[ri release];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (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;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)showAboutBox:(id)sender
|
||||||
|
{
|
||||||
|
if (_aboutBox == nil) {
|
||||||
|
_aboutBox = [[HSAboutBox alloc] initWithApp:py];
|
||||||
|
}
|
||||||
|
[[_aboutBox window] makeKeyAndOrderFront:sender];
|
||||||
|
}
|
||||||
|
|
||||||
/* Delegate */
|
/* Delegate */
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||||
@@ -42,11 +60,51 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[result restoreColumnsPosition:columnsOrder widths:columnsWidth];
|
[result restoreColumnsPosition:columnsOrder widths:columnsWidth];
|
||||||
else
|
else
|
||||||
[result resetColumnsToDefault:nil];
|
[result resetColumnsToDefault:nil];
|
||||||
//Reg stuff
|
[HSFairwareReminder showNagWithApp:[self py]];
|
||||||
if ([RegistrationInterface showNagWithApp:[self py]])
|
|
||||||
[unlockMenuItem setTitle:[NSString stringWithFormat:@"Thanks for buying %@!",[py appName]]];
|
|
||||||
//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
|
||||||
|
|||||||
@@ -1,20 +1,13 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_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 JobStarted @"JobStarted"
|
#define JobStarted @"JobStarted"
|
||||||
#define JobInProgress @"JobInProgress"
|
#define JobInProgress @"JobInProgress"
|
||||||
|
|
||||||
@@ -22,6 +15,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
|
|
||||||
@@ -1,25 +1,25 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_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
|
||||||
@@ -1,44 +1,66 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_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 "BSD" License as described in the "LICENSE" file,
|
||||||
|
which should be included with this package. The terms are also available at
|
||||||
|
http://www.hardcoded.net/licenses/bsd_license
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <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 "BSD" License as described in the "LICENSE" file,
|
||||||
|
which should be included with this package. The terms are also available at
|
||||||
|
http://www.hardcoded.net/licenses/bsd_license
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "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
|
||||||
@@ -1,38 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_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;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "DirectoryPanel.h"
|
#import "DirectoryPanel.h"
|
||||||
@@ -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
|
||||||
@@ -85,25 +39,16 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
NSOpenPanel *op = [NSOpenPanel openPanel];
|
NSOpenPanel *op = [NSOpenPanel openPanel];
|
||||||
[op setCanChooseFiles:YES];
|
[op setCanChooseFiles:YES];
|
||||||
[op setCanChooseDirectories:YES];
|
[op setCanChooseDirectories:YES];
|
||||||
[op setAllowsMultipleSelection:NO];
|
[op setAllowsMultipleSelection:YES];
|
||||||
[op setTitle:@"Select a directory to add to the scanning list"];
|
[op setTitle:@"Select a directory to add to the scanning list"];
|
||||||
[op setDelegate:self];
|
[op setDelegate:self];
|
||||||
if ([op runModalForTypes:nil] == NSOKButton)
|
if ([op runModal] == NSOKButton) {
|
||||||
{
|
for (NSString *directory in [op filenames]) {
|
||||||
NSString *directory = [[op filenames] objectAtIndex:0];
|
[self addDirectory:directory];
|
||||||
[self addDirectory:directory];
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (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,36 @@ 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;
|
if (r == 1) {
|
||||||
switch (r)
|
m = @"'%@' already is in the list.";
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
m = @"This directory already is in the list.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
m = @"This directory does not exist.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
[Dialogs showMessage:m];
|
else if (r == 2) {
|
||||||
|
m = @"'%@' does not exist.";
|
||||||
|
}
|
||||||
|
[Dialogs showMessage:[NSString stringWithFormat:m,directory]];
|
||||||
}
|
}
|
||||||
[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 "BSD" License as described in the "LICENSE" file,
|
||||||
|
which should be included with this package. The terms are also available at
|
||||||
|
http://www.hardcoded.net/licenses/bsd_license
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <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 "BSD" License as described in the "LICENSE" file,
|
||||||
|
which should be included with this package. The terms are also available at
|
||||||
|
http://www.hardcoded.net/licenses/bsd_license
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "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
|
||||||
15
cocoa/base/PyDetailsPanel.h
Normal file
15
cocoa/base/PyDetailsPanel.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import "PyGUI.h"
|
||||||
|
|
||||||
|
@interface PyDetailsPanel : PyGUI
|
||||||
|
- (NSInteger)numberOfRows;
|
||||||
|
- (id)valueForColumn:(NSString *)column row:(NSInteger)row;
|
||||||
|
@end
|
||||||
14
cocoa/base/PyDirectoryOutline.h
Normal file
14
cocoa/base/PyDirectoryOutline.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import "PyOutline.h"
|
||||||
|
|
||||||
|
@interface PyDirectoryOutline : PyOutline
|
||||||
|
- (void)addDirectory:(NSString *)directoryPath;
|
||||||
|
@end
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
@@ -13,54 +13,45 @@ 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)loadResultsFrom:(NSString *)filename;
|
||||||
- (void)saveResults;
|
- (void)saveResults;
|
||||||
|
- (void)saveResultsAs:(NSString *)filename;
|
||||||
- (void)loadIgnoreList;
|
- (void)loadIgnoreList;
|
||||||
- (void)saveIgnoreList;
|
- (void)saveIgnoreList;
|
||||||
- (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)hardlinkMarked;
|
||||||
- (void)removeMarked;
|
- (void)removeMarked;
|
||||||
|
|
||||||
//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:(BOOL)mix_file_kind;
|
||||||
- (void)setDisplayDeltaValues:(NSNumber *)display_delta_values;
|
- (void)setEscapeFilterRegexp:(BOOL)escape_filter_regexp;
|
||||||
- (void)setEscapeFilterRegexp:(NSNumber *)escape_filter_regexp;
|
- (void)setRemoveEmptyFolders:(BOOL)remove_empty_folders;
|
||||||
- (void)setRemoveEmptyFolders:(NSNumber *)remove_empty_folders;
|
- (void)setIgnoreHardlinkMatches:(BOOL)ignore_hardlink_matches;
|
||||||
- (void)setSizeThreshold:(NSInteger)size_threshold;
|
- (void)setSizeThreshold:(NSInteger)size_threshold;
|
||||||
@end
|
@end
|
||||||
|
|||||||
14
cocoa/base/PyProblemDialog.h
Normal file
14
cocoa/base/PyProblemDialog.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import "PyGUI.h"
|
||||||
|
|
||||||
|
@interface PyProblemDialog : PyGUI
|
||||||
|
- (void)revealSelected;
|
||||||
|
@end
|
||||||
24
cocoa/base/PyResultTable.h
Normal file
24
cocoa/base/PyResultTable.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import "PyTable.h"
|
||||||
|
|
||||||
|
@interface PyResultTable : PyTable
|
||||||
|
- (BOOL)powerMarkerMode;
|
||||||
|
- (void)setPowerMarkerMode:(BOOL)aPowerMarkerMode;
|
||||||
|
- (BOOL)deltaValuesMode;
|
||||||
|
- (void)setDeltaValuesMode:(BOOL)aDeltaValuesMode;
|
||||||
|
|
||||||
|
- (NSString *)valueForRow:(NSInteger)rowIndex column:(NSInteger)aColumn;
|
||||||
|
- (BOOL)renameSelected:(NSString *)aNewName;
|
||||||
|
- (void)sortBy:(NSInteger)aIdentifier ascending:(BOOL)aAscending;
|
||||||
|
- (void)markSelected;
|
||||||
|
- (void)removeSelected;
|
||||||
|
- (NSInteger)selectedDupeCount;
|
||||||
|
@end
|
||||||
14
cocoa/base/PyStatsLabel.h
Normal file
14
cocoa/base/PyStatsLabel.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import "PyGUI.h"
|
||||||
|
|
||||||
|
@interface PyStatsLabel : PyGUI
|
||||||
|
- (NSString *)display;
|
||||||
|
@end
|
||||||
26
cocoa/base/ResultTable.h
Normal file
26
cocoa/base/ResultTable.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import "HSTable.h"
|
||||||
|
#import "PyResultTable.h"
|
||||||
|
|
||||||
|
@interface ResultTable : HSTable
|
||||||
|
{
|
||||||
|
NSIndexSet *_deltaColumns;
|
||||||
|
}
|
||||||
|
- (id)initWithPyParent:(id)aPyParent view:(NSTableView *)aTableView;
|
||||||
|
- (PyResultTable *)py;
|
||||||
|
- (BOOL)powerMarkerMode;
|
||||||
|
- (void)setPowerMarkerMode:(BOOL)aPowerMarkerMode;
|
||||||
|
- (BOOL)deltaValuesMode;
|
||||||
|
- (void)setDeltaValuesMode:(BOOL)aDeltaValuesMode;
|
||||||
|
- (void)setDeltaColumns:(NSIndexSet *)aDeltaColumns;
|
||||||
|
- (NSInteger)selectedDupeCount;
|
||||||
|
- (void)removeSelected;
|
||||||
|
@end;
|
||||||
162
cocoa/base/ResultTable.m
Normal file
162
cocoa/base/ResultTable.m
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "ResultTable.h"
|
||||||
|
#import "Dialogs.h"
|
||||||
|
#import "Utils.h"
|
||||||
|
#import "Consts.h"
|
||||||
|
|
||||||
|
@implementation ResultTable
|
||||||
|
- (id)initWithPyParent:(id)aPyParent view:(NSTableView *)aTableView
|
||||||
|
{
|
||||||
|
self = [super initWithPyClassName:@"PyResultTable" pyParent:aPyParent view:aTableView];
|
||||||
|
[self connect];
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
[self disconnect];
|
||||||
|
[_deltaColumns release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (PyResultTable *)py
|
||||||
|
{
|
||||||
|
return (PyResultTable *)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
|
||||||
|
{
|
||||||
|
return [[self py] selectedDupeCount];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (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 */
|
||||||
|
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)column row:(NSInteger)row
|
||||||
|
{
|
||||||
|
NSString *identifier = [column identifier];
|
||||||
|
if ([identifier isEqual:@"marked"]) {
|
||||||
|
return [[self py] valueForColumn:@"marked" row:row];
|
||||||
|
}
|
||||||
|
NSInteger columnId = [identifier integerValue];
|
||||||
|
return [[self py] valueForRow:row column:columnId];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)column row:(NSInteger)row
|
||||||
|
{
|
||||||
|
NSString *identifier = [column identifier];
|
||||||
|
if ([identifier isEqual:@"marked"]) {
|
||||||
|
[[self py] setValue:object forColumn:identifier row:row];
|
||||||
|
}
|
||||||
|
else if ([identifier isEqual:@"0"]) {
|
||||||
|
NSString *oldName = [[self py] valueForRow:row 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 {
|
||||||
|
[tableView setNeedsDisplay:YES];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delegate */
|
||||||
|
- (void)tableView:(NSTableView *)aTableView didClickTableColumn:(NSTableColumn *)tableColumn
|
||||||
|
{
|
||||||
|
if ([[tableView sortDescriptors] count] < 1)
|
||||||
|
return;
|
||||||
|
NSSortDescriptor *sd = [[tableView sortDescriptors] objectAtIndex:0];
|
||||||
|
[[self py] sortBy:[[sd key] integerValue] ascending:[sd ascending]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)column row:(NSInteger)row
|
||||||
|
{
|
||||||
|
BOOL isMarkable = n2b([[self py] valueForColumn:@"markable" row:row]);
|
||||||
|
if ([[column identifier] isEqual:@"marked"]) {
|
||||||
|
[cell setEnabled:isMarkable];
|
||||||
|
// Low-tech solution, for indentation, but it works...
|
||||||
|
NSCellImagePosition pos = isMarkable ? NSImageRight : NSImageLeft;
|
||||||
|
[cell setImagePosition:pos];
|
||||||
|
}
|
||||||
|
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]];
|
||||||
|
if ([self deltaValuesMode]) {
|
||||||
|
NSInteger i = [[column identifier] integerValue];
|
||||||
|
if ([_deltaColumns containsIndex:i]) {
|
||||||
|
[textCell setTextColor:[NSColor orangeColor]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[textCell setTextColor:[NSColor blueColor]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)tableViewHadDeletePressed:(NSTableView *)tableView
|
||||||
|
{
|
||||||
|
[self removeSelected];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)tableViewHadSpacePressed:(NSTableView *)tableView
|
||||||
|
{
|
||||||
|
[[self py] markSelected];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Python --> Cocoa */
|
||||||
|
- (void)invalidateMarkings
|
||||||
|
{
|
||||||
|
[tableView setNeedsDisplay:YES];
|
||||||
|
}
|
||||||
|
@end
|
||||||
@@ -1,60 +1,75 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "Outline.h"
|
#import "StatsLabel.h"
|
||||||
|
#import "ResultTable.h"
|
||||||
|
#import "ProblemDialog.h"
|
||||||
|
#import "HSTableView.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 HSTableView *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;
|
||||||
|
ResultTable *table;
|
||||||
|
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;
|
||||||
|
- (void)sendMarkedToTrash:(BOOL)hardlinkDeleted;
|
||||||
|
|
||||||
/* 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)hardlinkMarked:(id)sender;
|
||||||
- (IBAction)exportToXHTML:(id)sender;
|
- (IBAction)exportToXHTML:(id)sender;
|
||||||
|
- (IBAction)filter:(id)sender;
|
||||||
|
- (IBAction)ignoreSelected:(id)sender;
|
||||||
|
- (IBAction)invokeCustomCommand:(id)sender;
|
||||||
|
- (IBAction)loadResults:(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)saveResults:(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;
|
||||||
|
|
||||||
|
|||||||
@@ -1,70 +1,46 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "ResultWindow.h"
|
#import "ResultWindow.h"
|
||||||
#import "Dialogs.h"
|
#import "Dialogs.h"
|
||||||
#import "ProgressController.h"
|
#import "ProgressController.h"
|
||||||
#import "Utils.h"
|
#import "Utils.h"
|
||||||
#import "RegistrationInterface.h"
|
|
||||||
#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];
|
||||||
|
/* Put a cute iTunes-like bottom bar */
|
||||||
|
[[self window] setContentBorderThickness:28 forEdge:NSMinYEdge];
|
||||||
preferencesPanel = [[NSWindowController alloc] initWithWindowNibName:@"Preferences"];
|
preferencesPanel = [[NSWindowController alloc] initWithWindowNibName:@"Preferences"];
|
||||||
|
table = [[ResultTable 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];
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(registrationRequired:) name:RegistrationRequired object:nil];
|
[deltaSwitch setSelectedSegment:0];
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(jobCompleted:) name:JobCompletedNotification object:nil];
|
[pmSwitch setSelectedSegment:0];
|
||||||
|
[matches setTarget:self];
|
||||||
|
[matches setDoubleAction:@selector(openClicked:)];
|
||||||
|
|
||||||
|
[[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
|
||||||
{
|
{
|
||||||
|
[table 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,69 @@ 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) {
|
||||||
|
NSInteger colIndex = [colId integerValue];
|
||||||
|
if ((colIndex == 0) && (![colId isEqual:@"0"])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
NSTableColumn *col = [_resultColumns objectAtIndex:colIndex];
|
||||||
|
NSNumber *width = [aColumnsWidth objectForKey:[col identifier]];
|
||||||
|
NSMenuItem *mi = [columnsMenu itemWithTag:colIndex];
|
||||||
|
if (width) {
|
||||||
|
[col setWidth:[width floatValue]];
|
||||||
|
}
|
||||||
|
[self toggleColumn:mi];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updatePySelection
|
- (void)sendMarkedToTrash:(BOOL)hardlinkDeleted
|
||||||
{
|
{
|
||||||
NSArray *selection;
|
NSInteger mark_count = [[py getMarkCount] intValue];
|
||||||
if (_powerMode)
|
if (!mark_count) {
|
||||||
selection = [py selectedPowerMarkerNodePaths];
|
return;
|
||||||
else
|
}
|
||||||
selection = [py selectedResultNodePaths];
|
NSString *msg = @"You are about to send %d files to Trash. Continue?";
|
||||||
[matches selectNodePaths:selection];
|
if (hardlinkDeleted) {
|
||||||
}
|
msg = @"You are about to send %d files to Trash (and hardlink them afterwards). Continue?";
|
||||||
|
}
|
||||||
- (void)performPySelection:(NSArray *)aIndexPaths
|
if ([Dialogs askYesNo:[NSString stringWithFormat:msg,mark_count]] == NSAlertSecondButtonReturn) { // NO
|
||||||
{
|
return;
|
||||||
if (_powerMode)
|
}
|
||||||
[py selectPowerMarkerNodePaths:aIndexPaths];
|
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||||
else
|
[py setRemoveEmptyFolders:n2b([ud objectForKey:@"removeEmptyFolders"])];
|
||||||
[py selectResultNodePaths:aIndexPaths];
|
if (hardlinkDeleted) {
|
||||||
}
|
[py hardlinkMarked];
|
||||||
|
}
|
||||||
- (void)refreshStats
|
else {
|
||||||
{
|
[py deleteMarked];
|
||||||
[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;
|
[table 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;
|
[table 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
|
||||||
@@ -257,20 +189,12 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
|
|
||||||
- (IBAction)deleteMarked:(id)sender
|
- (IBAction)deleteMarked:(id)sender
|
||||||
{
|
{
|
||||||
NSInteger mark_count = [[py getMarkCount] intValue];
|
[self sendMarkedToTrash:NO];
|
||||||
if (!mark_count)
|
|
||||||
return;
|
|
||||||
if ([Dialogs askYesNo:[NSString stringWithFormat:@"You are about to send %d files to Trash. Continue?",mark_count]] == NSAlertSecondButtonReturn) // NO
|
|
||||||
return;
|
|
||||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
|
||||||
[py setRemoveEmptyFolders:[ud objectForKey:@"removeEmptyFolders"]];
|
|
||||||
[py deleteMarked];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)expandAll:(id)sender
|
- (IBAction)hardlinkMarked:(id)sender
|
||||||
{
|
{
|
||||||
for (NSInteger i=0;i < [matches numberOfRows];i++)
|
[self sendMarkedToTrash:YES];
|
||||||
[matches expandItem:[matches itemAtRow:i]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)exportToXHTML:(id)sender
|
- (IBAction)exportToXHTML:(id)sender
|
||||||
@@ -279,6 +203,71 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[[NSWorkspace sharedWorkspace] openFile:exported];
|
[[NSWorkspace sharedWorkspace] openFile:exported];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction)filter:(id)sender
|
||||||
|
{
|
||||||
|
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||||
|
[py setEscapeFilterRegexp:!n2b([ud objectForKey:@"useRegexpFilter"])];
|
||||||
|
[py applyFilter:[filterField stringValue]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)ignoreSelected:(id)sender
|
||||||
|
{
|
||||||
|
NSInteger selectedDupeCount = [table 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)loadResults:(id)sender
|
||||||
|
{
|
||||||
|
NSOpenPanel *op = [NSOpenPanel openPanel];
|
||||||
|
[op setCanChooseFiles:YES];
|
||||||
|
[op setCanChooseDirectories:NO];
|
||||||
|
[op setCanCreateDirectories:NO];
|
||||||
|
[op setAllowsMultipleSelection:NO];
|
||||||
|
[op setAllowedFileTypes:[NSArray arrayWithObject:@"dupeguru"]];
|
||||||
|
[op setTitle:@"Select a results file to load"];
|
||||||
|
if ([op runModal] == NSOKButton) {
|
||||||
|
NSString *filename = [[op filenames] objectAtIndex:0];
|
||||||
|
[py loadResultsFrom:filename];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (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];
|
||||||
@@ -294,36 +283,81 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
{
|
{
|
||||||
NSString *directory = [[op filenames] objectAtIndex:0];
|
NSString *directory = [[op filenames] objectAtIndex:0];
|
||||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||||
[py setRemoveEmptyFolders:[ud objectForKey:@"removeEmptyFolders"]];
|
[py setRemoveEmptyFolders:n2b([ud objectForKey:@"removeEmptyFolders"])];
|
||||||
[py copyOrMove:b2n(NO) markedTo:directory recreatePath:[ud objectForKey:@"recreatePathType"]];
|
[py copyOrMove:b2n(NO) markedTo:directory recreatePath:[ud objectForKey:@"recreatePathType"]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (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
|
||||||
|
{
|
||||||
|
[table 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)saveResults:(id)sender
|
||||||
|
{
|
||||||
|
NSSavePanel *sp = [NSSavePanel savePanel];
|
||||||
|
[sp setCanCreateDirectories:YES];
|
||||||
|
[sp setAllowedFileTypes:[NSArray arrayWithObject:@"dupeguru"]];
|
||||||
|
[sp setTitle:@"Select a file to save your results to"];
|
||||||
|
if ([sp runModal] == NSOKButton) {
|
||||||
|
[py saveResultsAs:[sp filename]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (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 +380,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 +403,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,33 +411,34 @@ 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 rowCount = [[table py] numberOfRows];
|
||||||
if (groupCount == 0)
|
if (rowCount == 0)
|
||||||
[Dialogs showMessage:@"No duplicates found."];
|
[Dialogs showMessage:@"No duplicates found."];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,31 +458,10 @@ 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]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)registrationRequired:(NSNotification *)aNotification
|
|
||||||
{
|
|
||||||
NSString *msg = @"This is a demo version, which only allows you 10 delete/copy/move actions per session. You cannot continue.";
|
|
||||||
[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];
|
||||||
|
|||||||
19
cocoa/base/StatsLabel.h
Normal file
19
cocoa/base/StatsLabel.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import "HSGUIController.h"
|
||||||
|
#import "PyStatsLabel.h"
|
||||||
|
|
||||||
|
@interface StatsLabel : HSGUIController
|
||||||
|
{
|
||||||
|
NSTextField *labelView;
|
||||||
|
}
|
||||||
|
- (id)initWithPyParent:(id)aPyParent labelView:(NSTextField *)aLabelView;
|
||||||
|
- (PyStatsLabel *)py;
|
||||||
|
@end
|
||||||
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 "BSD" License as described in the "LICENSE" file,
|
||||||
|
which should be included with this package. The terms are also available at
|
||||||
|
http://www.hardcoded.net/licenses/bsd_license
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "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">10F569</string>
|
||||||
<string key="IBDocument.InterfaceBuilderVersion">740</string>
|
<string key="IBDocument.InterfaceBuilderVersion">788</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">461.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">788</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>
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<object class="NSWindowTemplate" id="476890502">
|
<object class="NSWindowTemplate" id="476890502">
|
||||||
<int key="NSWindowStyleMask">155</int>
|
<int key="NSWindowStyleMask">155</int>
|
||||||
<int key="NSWindowBacking">2</int>
|
<int key="NSWindowBacking">2</int>
|
||||||
<string key="NSWindowRect">{{33, 261}, {451, 161}}</string>
|
<string key="NSWindowRect">{{33, 261}, {451, 146}}</string>
|
||||||
<int key="NSWTFlags">-260571136</int>
|
<int key="NSWTFlags">-260571136</int>
|
||||||
<string key="NSWindowTitle">Details of Selected File</string>
|
<string key="NSWindowTitle">Details of Selected File</string>
|
||||||
<object class="NSMutableString" key="NSWindowClass">
|
<object class="NSMutableString" key="NSWindowClass">
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
<characters key="NS.bytes">View</characters>
|
<characters key="NS.bytes">View</characters>
|
||||||
</object>
|
</object>
|
||||||
<string key="NSWindowContentMaxSize">{1.79769e+308, 1.79769e+308}</string>
|
<string key="NSWindowContentMaxSize">{1.79769e+308, 1.79769e+308}</string>
|
||||||
<string key="NSWindowContentMinSize">{451, 161}</string>
|
<string key="NSWindowContentMinSize">{451, 146}</string>
|
||||||
<object class="NSView" key="NSWindowView" id="1027711962">
|
<object class="NSView" key="NSWindowView" id="1027711962">
|
||||||
<reference key="NSNextResponder"/>
|
<reference key="NSNextResponder"/>
|
||||||
<int key="NSvFlags">256</int>
|
<int key="NSvFlags">256</int>
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
<object class="NSTableView" id="251969872">
|
<object class="NSTableView" id="251969872">
|
||||||
<reference key="NSNextResponder" ref="488480549"/>
|
<reference key="NSNextResponder" ref="488480549"/>
|
||||||
<int key="NSvFlags">256</int>
|
<int key="NSvFlags">256</int>
|
||||||
<string key="NSFrameSize">{449, 143}</string>
|
<string key="NSFrameSize">{449, 128}</string>
|
||||||
<reference key="NSSuperview" ref="488480549"/>
|
<reference key="NSSuperview" ref="488480549"/>
|
||||||
<int key="NSTag">2</int>
|
<int key="NSTag">2</int>
|
||||||
<bool key="NSEnabled">YES</bool>
|
<bool key="NSEnabled">YES</bool>
|
||||||
@@ -224,7 +224,7 @@
|
|||||||
<int key="NSTableViewDraggingDestinationStyle">0</int>
|
<int key="NSTableViewDraggingDestinationStyle">0</int>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<string key="NSFrame">{{1, 17}, {449, 143}}</string>
|
<string key="NSFrame">{{1, 17}, {449, 128}}</string>
|
||||||
<reference key="NSSuperview" ref="362108788"/>
|
<reference key="NSSuperview" ref="362108788"/>
|
||||||
<reference key="NSNextKeyView" ref="251969872"/>
|
<reference key="NSNextKeyView" ref="251969872"/>
|
||||||
<reference key="NSDocView" ref="251969872"/>
|
<reference key="NSDocView" ref="251969872"/>
|
||||||
@@ -266,7 +266,7 @@
|
|||||||
</object>
|
</object>
|
||||||
<reference ref="717380566"/>
|
<reference ref="717380566"/>
|
||||||
</object>
|
</object>
|
||||||
<string key="NSFrameSize">{451, 161}</string>
|
<string key="NSFrameSize">{451, 146}</string>
|
||||||
<reference key="NSSuperview" ref="1027711962"/>
|
<reference key="NSSuperview" ref="1027711962"/>
|
||||||
<reference key="NSNextKeyView" ref="488480549"/>
|
<reference key="NSNextKeyView" ref="488480549"/>
|
||||||
<int key="NSsFlags">530</int>
|
<int key="NSsFlags">530</int>
|
||||||
@@ -278,12 +278,13 @@
|
|||||||
<bytes key="NSScrollAmts">QSAAAEEgAABBgAAAQYAAAA</bytes>
|
<bytes key="NSScrollAmts">QSAAAEEgAABBgAAAQYAAAA</bytes>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<string key="NSFrameSize">{451, 161}</string>
|
<string key="NSFrameSize">{451, 146}</string>
|
||||||
<reference key="NSSuperview"/>
|
<reference key="NSSuperview"/>
|
||||||
</object>
|
</object>
|
||||||
<string key="NSScreenRect">{{0, 0}, {1024, 746}}</string>
|
<string key="NSScreenRect">{{0, 0}, {1024, 746}}</string>
|
||||||
<string key="NSMinSize">{451, 177}</string>
|
<string key="NSMinSize">{451, 162}</string>
|
||||||
<string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
|
<string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
|
||||||
|
<string key="NSFrameAutosaveName">DetailsPanel</string>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBObjectContainer" key="IBDocument.Objects">
|
<object class="IBObjectContainer" key="IBDocument.Objects">
|
||||||
@@ -297,13 +298,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 +447,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 +474,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,26 +482,32 @@
|
|||||||
<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>
|
||||||
<boolean value="YES"/>
|
|
||||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
|
||||||
<boolean value="YES"/>
|
|
||||||
<boolean value="YES"/>
|
|
||||||
<boolean value="YES"/>
|
|
||||||
<boolean value="YES"/>
|
|
||||||
<boolean value="YES"/>
|
|
||||||
<boolean value="YES"/>
|
|
||||||
<boolean value="YES"/>
|
|
||||||
<string>{{109, 656}, {451, 161}}</string>
|
|
||||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
|
||||||
<string>{{109, 656}, {451, 161}}</string>
|
|
||||||
<boolean value="YES"/>
|
|
||||||
<boolean value="YES"/>
|
|
||||||
<string>{451, 161}</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>TableView</string>
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
|
<boolean value="YES"/>
|
||||||
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
|
<boolean value="YES"/>
|
||||||
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
|
<boolean value="YES"/>
|
||||||
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
|
<boolean value="YES"/>
|
||||||
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
|
<boolean value="YES"/>
|
||||||
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
|
<boolean value="YES"/>
|
||||||
|
<string>{{109, 671}, {451, 146}}</string>
|
||||||
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
|
<string>{{109, 671}, {451, 146}}</string>
|
||||||
|
<boolean value="YES"/>
|
||||||
|
<boolean value="YES"/>
|
||||||
|
<string>{451, 146}</string>
|
||||||
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
|
<boolean value="YES"/>
|
||||||
|
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
|
<boolean value="YES"/>
|
||||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<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,86 +530,72 @@
|
|||||||
</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">HSWindowController</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="NSMutableDictionary" key="toOneOutletInfosByName">
|
||||||
<string key="majorKey">IBUserSource</string>
|
|
||||||
<string key="minorKey"/>
|
|
||||||
</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.key.0">detailsTable</string>
|
||||||
<string key="NS.object.0">TableView</string>
|
<object class="IBToOneOutletInfo" key="NS.object.0">
|
||||||
|
<string key="name">detailsTable</string>
|
||||||
|
<string key="candidateClassName">NSTableView</string>
|
||||||
|
</object>
|
||||||
</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/DetailsPanel.h</string>
|
<string key="minorKey">../base/DetailsPanel.h</string>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="IBPartialClassDescription">
|
||||||
|
<string key="className">DetailsPanel</string>
|
||||||
|
<string key="superclassName">HSWindowController</string>
|
||||||
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
|
<string key="majorKey">IBUserSource</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"/>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="IBPartialClassDescription">
|
||||||
|
<string key="className">HSWindowController</string>
|
||||||
|
<string key="superclassName">NSWindowController</string>
|
||||||
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
|
<string key="majorKey">IBProjectSource</string>
|
||||||
|
<string key="minorKey">../controllers/HSWindowController.h</string>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="IBPartialClassDescription">
|
||||||
|
<string key="className">NSObject</string>
|
||||||
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
|
<string key="majorKey">IBProjectSource</string>
|
||||||
|
<string key="minorKey">../views/HSOutlineView.h</string>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="IBPartialClassDescription">
|
||||||
|
<string key="className">NSObject</string>
|
||||||
|
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="111130406">
|
||||||
|
<string key="majorKey">IBProjectSource</string>
|
||||||
|
<string key="minorKey">../views/NSTableViewAdditions.h</string>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<object class="IBPartialClassDescription">
|
||||||
|
<string key="className">NSTableView</string>
|
||||||
|
<reference key="sourceIdentifier" ref="111130406"/>
|
||||||
|
</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>
|
||||||
@@ -1056,6 +1063,13 @@
|
|||||||
<string key="NS.key.0">showWindow:</string>
|
<string key="NS.key.0">showWindow:</string>
|
||||||
<string key="NS.object.0">id</string>
|
<string key="NS.object.0">id</string>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="NSMutableDictionary" key="actionInfosByName">
|
||||||
|
<string key="NS.key.0">showWindow:</string>
|
||||||
|
<object class="IBActionInfo" key="NS.object.0">
|
||||||
|
<string key="name">showWindow:</string>
|
||||||
|
<string key="candidateClassName">id</string>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
<string key="majorKey">IBFrameworkSource</string>
|
<string key="majorKey">IBFrameworkSource</string>
|
||||||
<string key="minorKey">AppKit.framework/Headers/NSWindowController.h</string>
|
<string key="minorKey">AppKit.framework/Headers/NSWindowController.h</string>
|
||||||
@@ -1064,6 +1078,7 @@
|
|||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<int key="IBDocument.localizationMode">0</int>
|
<int key="IBDocument.localizationMode">0</int>
|
||||||
|
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
|
||||||
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
|
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
|
||||||
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
|
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
|
||||||
<integer value="1050" key="NS.object.0"/>
|
<integer value="1050" key="NS.object.0"/>
|
||||||
|
|||||||
@@ -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">10F569</string>
|
||||||
<string key="IBDocument.InterfaceBuilderVersion">740</string>
|
<string key="IBDocument.InterfaceBuilderVersion">788</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">461.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">788</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>
|
||||||
@@ -402,6 +428,7 @@
|
|||||||
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
|
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
|
||||||
<string key="NSMinSize">{369, 291}</string>
|
<string key="NSMinSize">{369, 291}</string>
|
||||||
<string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
|
<string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
|
||||||
|
<string key="NSFrameAutosaveName">DirectoryPanel</string>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBObjectContainer" key="IBDocument.Objects">
|
<object class="IBObjectContainer" key="IBDocument.Objects">
|
||||||
@@ -415,30 +442,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 +474,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 +490,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 +680,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 +703,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 +755,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 +763,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 +781,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 +808,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 +817,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 +845,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 +868,35 @@
|
|||||||
<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="actionInfosByName">
|
||||||
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
|
<object class="NSArray" key="dict.sortedKeys">
|
||||||
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
|
<string>askForDirectory:</string>
|
||||||
|
<string>popupAddDirectoryMenu:</string>
|
||||||
|
<string>removeSelectedDirectory:</string>
|
||||||
|
<string>toggleVisible:</string>
|
||||||
|
</object>
|
||||||
|
<object class="NSMutableArray" key="dict.values">
|
||||||
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
|
<object class="IBActionInfo">
|
||||||
|
<string key="name">askForDirectory:</string>
|
||||||
|
<string key="candidateClassName">id</string>
|
||||||
|
</object>
|
||||||
|
<object class="IBActionInfo">
|
||||||
|
<string key="name">popupAddDirectoryMenu:</string>
|
||||||
|
<string key="candidateClassName">id</string>
|
||||||
|
</object>
|
||||||
|
<object class="IBActionInfo">
|
||||||
|
<string key="name">removeSelectedDirectory:</string>
|
||||||
|
<string key="candidateClassName">id</string>
|
||||||
|
</object>
|
||||||
|
<object class="IBActionInfo">
|
||||||
|
<string key="name">toggleVisible:</string>
|
||||||
|
<string key="candidateClassName">id</string>
|
||||||
|
</object>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="NSMutableDictionary" key="outlets">
|
<object class="NSMutableDictionary" key="outlets">
|
||||||
@@ -911,17 +904,52 @@
|
|||||||
<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="NSMutableDictionary" key="toOneOutletInfosByName">
|
||||||
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
|
<object class="NSArray" key="dict.sortedKeys">
|
||||||
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
|
<string>addButtonPopUp</string>
|
||||||
|
<string>outlineView</string>
|
||||||
|
<string>removeButton</string>
|
||||||
|
</object>
|
||||||
|
<object class="NSMutableArray" key="dict.values">
|
||||||
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
|
<object class="IBToOneOutletInfo">
|
||||||
|
<string key="name">addButtonPopUp</string>
|
||||||
|
<string key="candidateClassName">NSPopUpButton</string>
|
||||||
|
</object>
|
||||||
|
<object class="IBToOneOutletInfo">
|
||||||
|
<string key="name">outlineView</string>
|
||||||
|
<string key="candidateClassName">HSOutlineView</string>
|
||||||
|
</object>
|
||||||
|
<object class="IBToOneOutletInfo">
|
||||||
|
<string key="name">removeButton</string>
|
||||||
|
<string key="candidateClassName">NSButton</string>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
|
<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 +960,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+">
|
||||||
@@ -1476,6 +1491,13 @@
|
|||||||
<string key="NS.key.0">showWindow:</string>
|
<string key="NS.key.0">showWindow:</string>
|
||||||
<string key="NS.object.0">id</string>
|
<string key="NS.object.0">id</string>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="NSMutableDictionary" key="actionInfosByName">
|
||||||
|
<string key="NS.key.0">showWindow:</string>
|
||||||
|
<object class="IBActionInfo" key="NS.object.0">
|
||||||
|
<string key="name">showWindow:</string>
|
||||||
|
<string key="candidateClassName">id</string>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
<string key="majorKey">IBFrameworkSource</string>
|
<string key="majorKey">IBFrameworkSource</string>
|
||||||
<string key="minorKey">AppKit.framework/Headers/NSWindowController.h</string>
|
<string key="minorKey">AppKit.framework/Headers/NSWindowController.h</string>
|
||||||
@@ -1484,6 +1506,7 @@
|
|||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<int key="IBDocument.localizationMode">0</int>
|
<int key="IBDocument.localizationMode">0</int>
|
||||||
|
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
|
||||||
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
|
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
|
||||||
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
|
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
|
||||||
<integer value="1050" key="NS.object.0"/>
|
<integer value="1050" key="NS.object.0"/>
|
||||||
@@ -1497,7 +1520,20 @@
|
|||||||
<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>
|
||||||
|
<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
|
||||||
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
|
<object class="NSArray" key="dict.sortedKeys">
|
||||||
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
|
<string>NSMenuCheckmark</string>
|
||||||
|
<string>NSMenuMixedState</string>
|
||||||
|
</object>
|
||||||
|
<object class="NSMutableArray" key="dict.values">
|
||||||
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
|
<string>{9, 8}</string>
|
||||||
|
<string>{7, 2}</string>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
</data>
|
</data>
|
||||||
</archive>
|
</archive>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
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
@@ -1,24 +1,19 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_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
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
#import "../../cocoalib/ProgressController.h"
|
#import "../../cocoalib/ProgressController.h"
|
||||||
#import "../../cocoalib/RegistrationInterface.h"
|
|
||||||
#import "../../cocoalib/Utils.h"
|
#import "../../cocoalib/Utils.h"
|
||||||
#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
|
||||||
@@ -27,6 +27,7 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[d setObject:b2n(NO) forKey:@"matchSimilarWords"];
|
[d setObject:b2n(NO) forKey:@"matchSimilarWords"];
|
||||||
[d setObject:b2n(YES) forKey:@"mixFileKind"];
|
[d setObject:b2n(YES) forKey:@"mixFileKind"];
|
||||||
[d setObject:b2n(NO) forKey:@"useRegexpFilter"];
|
[d setObject:b2n(NO) forKey:@"useRegexpFilter"];
|
||||||
|
[d setObject:b2n(NO) forKey:@"ignoreHardlinkMatches"];
|
||||||
[d setObject:b2n(NO) forKey:@"removeEmptyFolders"];
|
[d setObject:b2n(NO) forKey:@"removeEmptyFolders"];
|
||||||
[d setObject:b2n(NO) forKey:@"debug"];
|
[d setObject:b2n(NO) forKey:@"debug"];
|
||||||
[d setObject:b2n(NO) forKey:@"scanTagTrack"];
|
[d setObject:b2n(NO) forKey:@"scanTagTrack"];
|
||||||
@@ -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,9 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "../base/Consts.h"
|
#import "../base/Consts.h"
|
||||||
|
|||||||
@@ -1,14 +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 <Cocoa/Cocoa.h>
|
|
||||||
#import "../base/DetailsPanel.h"
|
|
||||||
|
|
||||||
|
|
||||||
@interface DetailsPanel : DetailsPanelBase
|
|
||||||
@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
|
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_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;
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_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.10.4</string>
|
||||||
<key>NSMainNibFile</key>
|
<key>NSMainNibFile</key>
|
||||||
<string>MainMenu</string>
|
<string>MainMenu</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|||||||
@@ -1,38 +1,15 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_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
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "ResultWindow.h"
|
#import "ResultWindow.h"
|
||||||
#import "../../cocoalib/Dialogs.h"
|
#import "../../cocoalib/Dialogs.h"
|
||||||
#import "../../cocoalib/ProgressController.h"
|
#import "../../cocoalib/ProgressController.h"
|
||||||
#import "../../cocoalib/RegistrationInterface.h"
|
|
||||||
#import "../../cocoalib/Utils.h"
|
#import "../../cocoalib/Utils.h"
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
#import "Consts.h"
|
#import "Consts.h"
|
||||||
@@ -20,130 +19,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,6)];
|
||||||
_powerMode = NO;
|
[deltaColumns removeIndex:6];
|
||||||
_deltaColumns = [[NSMutableIndexSet indexSetWithIndexesInRange:NSMakeRange(2,7)] retain];
|
[table 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];
|
||||||
@@ -151,22 +37,18 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[columnsOrder addObject:@"2"];
|
[columnsOrder addObject:@"2"];
|
||||||
[columnsOrder addObject:@"3"];
|
[columnsOrder addObject:@"3"];
|
||||||
[columnsOrder addObject:@"4"];
|
[columnsOrder addObject:@"4"];
|
||||||
[columnsOrder addObject:@"16"];
|
[columnsOrder addObject:@"6"];
|
||||||
|
[columnsOrder addObject:@"15"];
|
||||||
NSMutableDictionary *columnsWidth = [NSMutableDictionary dictionary];
|
NSMutableDictionary *columnsWidth = [NSMutableDictionary dictionary];
|
||||||
[columnsWidth setObject:i2n(214) forKey:@"0"];
|
[columnsWidth setObject:i2n(235) forKey:@"0"];
|
||||||
[columnsWidth setObject:i2n(63) forKey:@"2"];
|
[columnsWidth setObject:i2n(63) forKey:@"2"];
|
||||||
[columnsWidth setObject:i2n(50) forKey:@"3"];
|
[columnsWidth setObject:i2n(50) forKey:@"3"];
|
||||||
[columnsWidth setObject:i2n(50) forKey:@"4"];
|
[columnsWidth setObject:i2n(50) forKey:@"4"];
|
||||||
[columnsWidth setObject:i2n(57) forKey:@"16"];
|
[columnsWidth setObject:i2n(40) forKey:@"6"];
|
||||||
|
[columnsWidth setObject:i2n(57) forKey:@"15"];
|
||||||
[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)
|
||||||
@@ -185,13 +67,10 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[_py enable:[ud objectForKey:@"scanTagYear"] scanForTag:@"year"];
|
[_py enable:[ud objectForKey:@"scanTagYear"] scanForTag:@"year"];
|
||||||
[_py setMinMatchPercentage:[ud objectForKey:@"minMatchPercentage"]];
|
[_py setMinMatchPercentage:[ud objectForKey:@"minMatchPercentage"]];
|
||||||
[_py setWordWeighting:[ud objectForKey:@"wordWeighting"]];
|
[_py setWordWeighting:[ud objectForKey:@"wordWeighting"]];
|
||||||
[_py setMixFileKind:[ud objectForKey:@"mixFileKind"]];
|
[_py setMixFileKind:n2b([ud objectForKey:@"mixFileKind"])];
|
||||||
|
[_py setIgnoreHardlinkMatches:n2b([ud objectForKey:@"ignoreHardlinkMatches"])];
|
||||||
[_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)
|
|
||||||
[Dialogs showMessage:@"You cannot make a duplicate scan with only reference directories."];
|
|
||||||
if (r == 3)
|
if (r == 3)
|
||||||
{
|
{
|
||||||
[Dialogs showMessage:@"The selected directories contain no scannable file."];
|
[Dialogs showMessage:@"The selected directories contain no scannable file."];
|
||||||
@@ -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
|
||||||
{
|
{
|
||||||
@@ -226,43 +96,17 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[_resultColumns addObject:brCol];
|
[_resultColumns addObject:brCol];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:5 title:@"Sample Rate" width:60 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:5 title:@"Sample Rate" width:60 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:6 title:@"Kind" width:40 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:6 title:@"Kind" width:40 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:7 title:@"Creation" width:120 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:7 title:@"Modification" width:120 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:8 title:@"Modification" width:120 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:8 title:@"Title" width:120 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:9 title:@"Title" width:120 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:9 title:@"Artist" width:120 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:10 title:@"Artist" width:120 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:10 title:@"Album" width:120 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:11 title:@"Album" width:120 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:11 title:@"Genre" width:80 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:12 title:@"Genre" width:80 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:12 title:@"Year" width:40 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:13 title:@"Year" width:40 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:13 title:@"Track Number" width:40 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:14 title:@"Track Number" width:40 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:14 title:@"Comment" width:120 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:15 title:@"Comment" width:120 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:15 title:@"Match %" width:57 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:16 title:@"Match %" width:57 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:16 title:@"Words Used" width:120 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:17 title:@"Words Used" width:120 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:17 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 */
|
||||||
@@ -285,17 +129,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
|
||||||
|
|||||||
@@ -1,246 +1,74 @@
|
|||||||
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
#
|
#
|
||||||
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
# 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
|
# 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/bsd_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 ScanType
|
||||||
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
|
import core_me.app_cocoa, core_me.data, core_me.fs, core_me.scanner
|
||||||
from core import app, app_cocoa, data, directories, engine, export, ignore, results, scanner, fs
|
import hsaudiotag.aiff, hsaudiotag.flac, hsaudiotag.genres, hsaudiotag.id3v1,\
|
||||||
from hsmedia import aiff, flac, genres, id3v1, id3v2, mp4, mpeg, ogg, wma
|
hsaudiotag.id3v2, hsaudiotag.mp4, hsaudiotag.mpeg, hsaudiotag.ogg, hsaudiotag.wma
|
||||||
from hsutil import conflict
|
from hsaudiotag import aiff, flac, genres, id3v1, id3v2, mp4, mpeg, ogg, wma
|
||||||
|
import hsutil.conflict
|
||||||
|
import core.engine, core.fs, core.app
|
||||||
|
import xml.etree.ElementPath
|
||||||
|
import gzip
|
||||||
|
import aem.kae
|
||||||
|
import appscript.defaultterminology
|
||||||
|
|
||||||
class 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,
|
ScanType.Filename,
|
||||||
SCAN_TYPE_FIELDS,
|
ScanType.Fields,
|
||||||
SCAN_TYPE_FIELDS_NO_ORDER,
|
ScanType.FieldsNoOrder,
|
||||||
SCAN_TYPE_TAG,
|
ScanType.Tag,
|
||||||
SCAN_TYPE_CONTENT,
|
ScanType.Contents,
|
||||||
SCAN_TYPE_CONTENT_AUDIO
|
ScanType.ContentsAudio,
|
||||||
][scan_type]
|
][scan_type]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
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,18 @@
|
|||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
|
8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
|
||||||
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
|
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
|
||||||
|
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 */; };
|
||||||
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,29 +41,30 @@
|
|||||||
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 */; };
|
||||||
|
CE4F934612CCA9470067A3AE /* about.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE4F934512CCA9470067A3AE /* about.xib */; };
|
||||||
|
CE4F934912CCA96C0067A3AE /* HSAboutBox.m in Sources */ = {isa = PBXBuildFile; fileRef = CE4F934812CCA96C0067A3AE /* HSAboutBox.m */; };
|
||||||
CE515DF30FC6C12E00EC695D /* Dialogs.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DE10FC6C12E00EC695D /* Dialogs.m */; };
|
CE515DF30FC6C12E00EC695D /* Dialogs.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DE10FC6C12E00EC695D /* Dialogs.m */; };
|
||||||
CE515DF40FC6C12E00EC695D /* HSErrorReportWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DE30FC6C12E00EC695D /* HSErrorReportWindow.m */; };
|
CE515DF40FC6C12E00EC695D /* HSErrorReportWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE515DE30FC6C12E00EC695D /* HSErrorReportWindow.m */; };
|
||||||
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 */; };
|
|
||||||
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 */; };
|
||||||
|
CE578303124DFC660004769C /* HSTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = CE578302124DFC660004769C /* HSTableView.m */; };
|
||||||
CE6032C00FE6784C007E33FF /* DetailsPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE6032BF0FE6784C007E33FF /* DetailsPanel.m */; };
|
CE6032C00FE6784C007E33FF /* DetailsPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE6032BF0FE6784C007E33FF /* DetailsPanel.m */; };
|
||||||
CE68EE6809ABC48000971085 /* DirectoryPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE68EE6609ABC48000971085 /* DirectoryPanel.m */; };
|
CE68EE6809ABC48000971085 /* DirectoryPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE68EE6609ABC48000971085 /* DirectoryPanel.m */; };
|
||||||
CE6E0E9F1054EB97008D9390 /* dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = CE6E0E9E1054EB97008D9390 /* dsa_pub.pem */; };
|
CE6E0E9F1054EB97008D9390 /* dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = CE6E0E9E1054EB97008D9390 /* dsa_pub.pem */; };
|
||||||
|
CE74A12412537F06008A8DF0 /* HSFairwareReminder.m in Sources */ = {isa = PBXBuildFile; fileRef = CE74A12212537F06008A8DF0 /* HSFairwareReminder.m */; };
|
||||||
|
CE74A12712537F2E008A8DF0 /* FairwareReminder.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE74A12512537F2E008A8DF0 /* FairwareReminder.xib */; };
|
||||||
CE848A1909DD85810004CB44 /* Consts.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE848A1809DD85810004CB44 /* Consts.h */; };
|
CE848A1909DD85810004CB44 /* Consts.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE848A1809DD85810004CB44 /* Consts.h */; };
|
||||||
CE900AD2109B238600754048 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE900AD1109B238600754048 /* Preferences.xib */; };
|
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 */; };
|
CEB14D29124DFC2800FA7481 /* ResultTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CEB14D28124DFC2800FA7481 /* ResultTable.m */; };
|
||||||
CECA899D09DB132E00A3D774 /* DetailsPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CECA899B09DB132E00A3D774 /* DetailsPanel.m */; };
|
CEDF07A3112493B200EE5BC0 /* StatsLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = CEDF07A2112493B200EE5BC0 /* StatsLabel.m */; };
|
||||||
CEEB135209C837A2004D2330 /* dupeguru.icns in Resources */ = {isa = PBXBuildFile; fileRef = CEEB135109C837A2004D2330 /* dupeguru.icns */; };
|
CEEB135209C837A2004D2330 /* dupeguru.icns in Resources */ = {isa = PBXBuildFile; fileRef = CEEB135109C837A2004D2330 /* dupeguru.icns */; };
|
||||||
CEFC294609C89E3D00D9F998 /* folder32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC294509C89E3D00D9F998 /* folder32.png */; };
|
CEFC294609C89E3D00D9F998 /* folder32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC294509C89E3D00D9F998 /* folder32.png */; };
|
||||||
CEFC295509C89FF200D9F998 /* details32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC295309C89FF200D9F998 /* details32.png */; };
|
CEFC295509C89FF200D9F998 /* details32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC295309C89FF200D9F998 /* details32.png */; };
|
||||||
@@ -67,7 +79,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 +93,33 @@
|
|||||||
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>"; };
|
||||||
|
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>"; };
|
||||||
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,28 +130,24 @@
|
|||||||
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>"; };
|
||||||
|
CE4F934512CCA9470067A3AE /* about.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = about.xib; path = ../../cocoalib/xib/about.xib; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE4F934712CCA96C0067A3AE /* HSAboutBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSAboutBox.h; path = ../../cocoalib/HSAboutBox.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE4F934812CCA96C0067A3AE /* HSAboutBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSAboutBox.m; path = ../../cocoalib/HSAboutBox.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE515DE00FC6C12E00EC695D /* Dialogs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Dialogs.h; path = ../../cocoalib/Dialogs.h; sourceTree = SOURCE_ROOT; };
|
CE515DE00FC6C12E00EC695D /* Dialogs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Dialogs.h; path = ../../cocoalib/Dialogs.h; sourceTree = SOURCE_ROOT; };
|
||||||
CE515DE10FC6C12E00EC695D /* Dialogs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Dialogs.m; path = ../../cocoalib/Dialogs.m; sourceTree = SOURCE_ROOT; };
|
CE515DE10FC6C12E00EC695D /* Dialogs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Dialogs.m; path = ../../cocoalib/Dialogs.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE515DE20FC6C12E00EC695D /* HSErrorReportWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSErrorReportWindow.h; path = ../../cocoalib/HSErrorReportWindow.h; sourceTree = SOURCE_ROOT; };
|
CE515DE20FC6C12E00EC695D /* HSErrorReportWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSErrorReportWindow.h; path = ../../cocoalib/HSErrorReportWindow.h; sourceTree = SOURCE_ROOT; };
|
||||||
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; };
|
||||||
CE515DE90FC6C12E00EC695D /* RecentDirectories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RecentDirectories.h; path = ../../cocoalib/RecentDirectories.h; sourceTree = SOURCE_ROOT; };
|
CE515DE90FC6C12E00EC695D /* RecentDirectories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RecentDirectories.h; path = ../../cocoalib/RecentDirectories.h; sourceTree = SOURCE_ROOT; };
|
||||||
CE515DEA0FC6C12E00EC695D /* RecentDirectories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RecentDirectories.m; path = ../../cocoalib/RecentDirectories.m; sourceTree = SOURCE_ROOT; };
|
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; };
|
|
||||||
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; };
|
||||||
@@ -123,16 +156,27 @@
|
|||||||
CE515E1A0FC6C19300EC695D /* PyDupeGuru.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyDupeGuru.h; path = ../base/PyDupeGuru.h; sourceTree = SOURCE_ROOT; };
|
CE515E1A0FC6C19300EC695D /* PyDupeGuru.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyDupeGuru.h; path = ../base/PyDupeGuru.h; sourceTree = SOURCE_ROOT; };
|
||||||
CE515E1B0FC6C19300EC695D /* ResultWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ResultWindow.h; path = ../base/ResultWindow.h; sourceTree = SOURCE_ROOT; };
|
CE515E1B0FC6C19300EC695D /* ResultWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ResultWindow.h; path = ../base/ResultWindow.h; sourceTree = SOURCE_ROOT; };
|
||||||
CE515E1C0FC6C19300EC695D /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ResultWindow.m; path = ../base/ResultWindow.m; sourceTree = SOURCE_ROOT; };
|
CE515E1C0FC6C19300EC695D /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ResultWindow.m; path = ../base/ResultWindow.m; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE578301124DFC660004769C /* HSTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSTableView.h; path = ../../cocoalib/views/HSTableView.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE578302124DFC660004769C /* HSTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSTableView.m; path = ../../cocoalib/views/HSTableView.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE6032BE0FE6784C007E33FF /* DetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DetailsPanel.h; path = ../base/DetailsPanel.h; sourceTree = SOURCE_ROOT; };
|
CE6032BE0FE6784C007E33FF /* DetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DetailsPanel.h; path = ../base/DetailsPanel.h; sourceTree = SOURCE_ROOT; };
|
||||||
CE6032BF0FE6784C007E33FF /* DetailsPanel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DetailsPanel.m; path = ../base/DetailsPanel.m; sourceTree = SOURCE_ROOT; };
|
CE6032BF0FE6784C007E33FF /* DetailsPanel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DetailsPanel.m; path = ../base/DetailsPanel.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE68EE6509ABC48000971085 /* DirectoryPanel.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = DirectoryPanel.h; sourceTree = SOURCE_ROOT; };
|
CE68EE6509ABC48000971085 /* DirectoryPanel.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = DirectoryPanel.h; sourceTree = SOURCE_ROOT; };
|
||||||
CE68EE6609ABC48000971085 /* DirectoryPanel.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = DirectoryPanel.m; sourceTree = SOURCE_ROOT; };
|
CE68EE6609ABC48000971085 /* DirectoryPanel.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = DirectoryPanel.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE6E0E9E1054EB97008D9390 /* dsa_pub.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = dsa_pub.pem; path = ../base/dsa_pub.pem; sourceTree = "<group>"; };
|
CE6E0E9E1054EB97008D9390 /* dsa_pub.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = dsa_pub.pem; path = ../base/dsa_pub.pem; sourceTree = "<group>"; };
|
||||||
|
CE74A12112537F06008A8DF0 /* HSFairwareReminder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSFairwareReminder.h; path = ../../cocoalib/HSFairwareReminder.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE74A12212537F06008A8DF0 /* HSFairwareReminder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSFairwareReminder.m; path = ../../cocoalib/HSFairwareReminder.m; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE74A12312537F06008A8DF0 /* PyFairware.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyFairware.h; path = ../../cocoalib/PyFairware.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE74A12612537F2E008A8DF0 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../../cocoalib/en.lproj/FairwareReminder.xib; sourceTree = SOURCE_ROOT; };
|
||||||
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>"; };
|
CEB14D26124DFC2800FA7481 /* PyResultTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyResultTable.h; path = ../base/PyResultTable.h; sourceTree = SOURCE_ROOT; };
|
||||||
CECA899B09DB132E00A3D774 /* DetailsPanel.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = DetailsPanel.m; sourceTree = "<group>"; };
|
CEB14D27124DFC2800FA7481 /* ResultTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ResultTable.h; path = ../base/ResultTable.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CEB14D28124DFC2800FA7481 /* ResultTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ResultTable.m; path = ../base/ResultTable.m; sourceTree = SOURCE_ROOT; };
|
||||||
|
CED0A591111C9FD10020AD7D /* PyDetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyDetailsPanel.h; path = ../base/PyDetailsPanel.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
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 +197,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 +242,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 +284,49 @@
|
|||||||
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 = (
|
||||||
|
CE578301124DFC660004769C /* HSTableView.h */,
|
||||||
|
CE578302124DFC660004769C /* HSTableView.m */,
|
||||||
|
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 +334,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 +349,42 @@
|
|||||||
path = ../../cocoalib/brsinglelineformatter;
|
path = ../../cocoalib/brsinglelineformatter;
|
||||||
sourceTree = SOURCE_ROOT;
|
sourceTree = SOURCE_ROOT;
|
||||||
};
|
};
|
||||||
|
CE4B59C41119919700C06C9E /* xib */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CE4F934512CCA9470067A3AE /* about.xib */,
|
||||||
|
CE74A12512537F2E008A8DF0 /* FairwareReminder.xib */,
|
||||||
|
CE4B59C51119919700C06C9E /* ErrorReportWindow.xib */,
|
||||||
|
CE4B59C61119919700C06C9E /* progress.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 */,
|
CE74A12112537F06008A8DF0 /* HSFairwareReminder.h */,
|
||||||
CE515DE50FC6C12E00EC695D /* Outline.m */,
|
CE74A12212537F06008A8DF0 /* HSFairwareReminder.m */,
|
||||||
|
CE74A12312537F06008A8DF0 /* PyFairware.h */,
|
||||||
|
CE4F934712CCA96C0067A3AE /* HSAboutBox.h */,
|
||||||
|
CE4F934812CCA96C0067A3AE /* HSAboutBox.m */,
|
||||||
|
CE003CB911242D00004B0AA7 /* NSEventAdditions.h */,
|
||||||
|
CE003CBA11242D00004B0AA7 /* NSEventAdditions.m */,
|
||||||
CE515DE60FC6C12E00EC695D /* ProgressController.h */,
|
CE515DE60FC6C12E00EC695D /* ProgressController.h */,
|
||||||
CE515DE70FC6C12E00EC695D /* ProgressController.m */,
|
CE515DE70FC6C12E00EC695D /* ProgressController.m */,
|
||||||
CE515DE80FC6C12E00EC695D /* PyApp.h */,
|
CE515DE80FC6C12E00EC695D /* PyApp.h */,
|
||||||
CE515DE90FC6C12E00EC695D /* RecentDirectories.h */,
|
CE515DE90FC6C12E00EC695D /* RecentDirectories.h */,
|
||||||
CE515DEA0FC6C12E00EC695D /* RecentDirectories.m */,
|
CE515DEA0FC6C12E00EC695D /* RecentDirectories.m */,
|
||||||
CE515DEB0FC6C12E00EC695D /* RegistrationInterface.h */,
|
|
||||||
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 +396,12 @@
|
|||||||
CE515E140FC6C17900EC695D /* dgbase */ = {
|
CE515E140FC6C17900EC695D /* dgbase */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
CEB14D26124DFC2800FA7481 /* PyResultTable.h */,
|
||||||
|
CEB14D27124DFC2800FA7481 /* ResultTable.h */,
|
||||||
|
CEB14D28124DFC2800FA7481 /* ResultTable.m */,
|
||||||
|
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 +409,16 @@
|
|||||||
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 */,
|
||||||
|
CEDF07A1112493B200EE5BC0 /* StatsLabel.h */,
|
||||||
|
CEDF07A2112493B200EE5BC0 /* StatsLabel.m */,
|
||||||
|
CE515E1A0FC6C19300EC695D /* PyDupeGuru.h */,
|
||||||
|
CED0A591111C9FD10020AD7D /* PyDetailsPanel.h */,
|
||||||
|
CE0A0C031175A1DE00DCA3C6 /* PyProblemDialog.h */,
|
||||||
|
CEDF07A0112493B200EE5BC0 /* PyStatsLabel.h */,
|
||||||
);
|
);
|
||||||
name = dgbase;
|
name = dgbase;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -350,7 +463,15 @@
|
|||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */;
|
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */;
|
||||||
compatibilityVersion = "Xcode 3.0";
|
compatibilityVersion = "Xcode 3.0";
|
||||||
|
developmentRegion = English;
|
||||||
hasScannedForEncodings = 1;
|
hasScannedForEncodings = 1;
|
||||||
|
knownRegions = (
|
||||||
|
English,
|
||||||
|
Japanese,
|
||||||
|
French,
|
||||||
|
German,
|
||||||
|
en,
|
||||||
|
);
|
||||||
mainGroup = 29B97314FDCFA39411CA2CEA /* dupeguru */;
|
mainGroup = 29B97314FDCFA39411CA2CEA /* dupeguru */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
@@ -371,14 +492,16 @@
|
|||||||
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 */,
|
||||||
|
CE0A0C061175A24800DCA3C6 /* ProblemDialog.xib in Resources */,
|
||||||
|
CE74A12712537F2E008A8DF0 /* FairwareReminder.xib in Resources */,
|
||||||
|
CE4F934612CCA9470067A3AE /* about.xib in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -393,14 +516,10 @@
|
|||||||
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 */,
|
|
||||||
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 +527,87 @@
|
|||||||
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 */,
|
||||||
|
CEDF07A3112493B200EE5BC0 /* StatsLabel.m in Sources */,
|
||||||
|
CE0A0C001175A1C000DCA3C6 /* HSTable.m in Sources */,
|
||||||
|
CE0A0C041175A1DE00DCA3C6 /* ProblemDialog.m in Sources */,
|
||||||
|
CEB14D29124DFC2800FA7481 /* ResultTable.m in Sources */,
|
||||||
|
CE578303124DFC660004769C /* HSTableView.m in Sources */,
|
||||||
|
CE74A12412537F06008A8DF0 /* HSFairwareReminder.m in Sources */,
|
||||||
|
CE4F934912CCA96C0067A3AE /* HSAboutBox.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
/* Begin PBXVariantGroup section */
|
||||||
CE515DFC0FC6C13E00EC695D /* ErrorReportWindow.xib */ = {
|
CE74A12512537F2E008A8DF0 /* FairwareReminder.xib */ = {
|
||||||
isa = PBXVariantGroup;
|
isa = PBXVariantGroup;
|
||||||
children = (
|
children = (
|
||||||
CE515DFD0FC6C13E00EC695D /* English */,
|
CE74A12612537F2E008A8DF0 /* en */,
|
||||||
);
|
);
|
||||||
name = ErrorReportWindow.xib;
|
name = FairwareReminder.xib;
|
||||||
sourceTree = SOURCE_ROOT;
|
path = ../../cocoalib/xib;
|
||||||
};
|
|
||||||
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;
|
sourceTree = SOURCE_ROOT;
|
||||||
};
|
};
|
||||||
/* End PBXVariantGroup section */
|
/* 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 +615,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 */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_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
@@ -1,23 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_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
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
#import "ProgressController.h"
|
#import "ProgressController.h"
|
||||||
#import "RegistrationInterface.h"
|
|
||||||
#import "Utils.h"
|
#import "Utils.h"
|
||||||
#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
|
||||||
@@ -24,6 +24,7 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[d setObject:[NSNumber numberWithBool:NO] forKey:@"matchScaled"];
|
[d setObject:[NSNumber numberWithBool:NO] forKey:@"matchScaled"];
|
||||||
[d setObject:[NSNumber numberWithBool:YES] forKey:@"mixFileKind"];
|
[d setObject:[NSNumber numberWithBool:YES] forKey:@"mixFileKind"];
|
||||||
[d setObject:[NSNumber numberWithBool:NO] forKey:@"useRegexpFilter"];
|
[d setObject:[NSNumber numberWithBool:NO] forKey:@"useRegexpFilter"];
|
||||||
|
[d setObject:[NSNumber numberWithBool:NO] forKey:@"ignoreHardlinkMatches"];
|
||||||
[d setObject:[NSNumber numberWithBool:NO] forKey:@"removeEmptyFolders"];
|
[d setObject:[NSNumber numberWithBool:NO] forKey:@"removeEmptyFolders"];
|
||||||
[d setObject:[NSNumber numberWithBool:NO] forKey:@"debug"];
|
[d setObject:[NSNumber numberWithBool:NO] forKey:@"debug"];
|
||||||
[d setObject:[NSArray array] forKey:@"recentDirectories"];
|
[d setObject:[NSArray array] forKey:@"recentDirectories"];
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "../base/Consts.h"
|
#import "../base/Consts.h"
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_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;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "Utils.h"
|
#import "Utils.h"
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_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;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "DirectoryPanel.h"
|
#import "DirectoryPanel.h"
|
||||||
@@ -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.11.3</string>
|
||||||
<key>NSMainNibFile</key>
|
<key>NSMainNibFile</key>
|
||||||
<string>MainMenu</string>
|
<string>MainMenu</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
|
|||||||
@@ -1,19 +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 <Cocoa/Cocoa.h>
|
|
||||||
|
|
||||||
|
|
||||||
@interface PictureBlocks : NSObject {
|
|
||||||
}
|
|
||||||
+ (NSString *)getBlocksFromImagePath:(NSString *)imagePath blockCount:(NSNumber *)blockCount;
|
|
||||||
+ (NSSize)getImageSize:(NSString *)imagePath;
|
|
||||||
@end
|
|
||||||
|
|
||||||
|
|
||||||
NSString* GetBlocks(NSString *filePath, int blockCount);
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|||||||
@@ -1,37 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_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
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "ResultWindow.h"
|
#import "ResultWindow.h"
|
||||||
#import "Dialogs.h"
|
#import "Dialogs.h"
|
||||||
#import "ProgressController.h"
|
#import "ProgressController.h"
|
||||||
#import "RegistrationInterface.h"
|
|
||||||
#import "Utils.h"
|
#import "Utils.h"
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
#import "Consts.h"
|
#import "Consts.h"
|
||||||
@@ -20,31 +19,12 @@ 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 indexSetWithIndex:2];
|
||||||
_powerMode = NO;
|
[deltaColumns addIndex:5];
|
||||||
_deltaColumns = [[NSMutableIndexSet indexSetWithIndexesInRange:NSMakeRange(2,5)] retain];
|
[table setDeltaColumns:deltaColumns];
|
||||||
[_deltaColumns removeIndex:3];
|
|
||||||
[_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 +32,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];
|
||||||
@@ -154,22 +39,16 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[columnsOrder addObject:@"1"];
|
[columnsOrder addObject:@"1"];
|
||||||
[columnsOrder addObject:@"2"];
|
[columnsOrder addObject:@"2"];
|
||||||
[columnsOrder addObject:@"4"];
|
[columnsOrder addObject:@"4"];
|
||||||
[columnsOrder addObject:@"7"];
|
[columnsOrder addObject:@"6"];
|
||||||
NSMutableDictionary *columnsWidth = [NSMutableDictionary dictionary];
|
NSMutableDictionary *columnsWidth = [NSMutableDictionary dictionary];
|
||||||
[columnsWidth setObject:i2n(121) forKey:@"0"];
|
[columnsWidth setObject:i2n(162) forKey:@"0"];
|
||||||
[columnsWidth setObject:i2n(120) forKey:@"1"];
|
[columnsWidth setObject:i2n(142) forKey:@"1"];
|
||||||
[columnsWidth setObject:i2n(63) forKey:@"2"];
|
[columnsWidth setObject:i2n(63) forKey:@"2"];
|
||||||
[columnsWidth setObject:i2n(73) forKey:@"4"];
|
[columnsWidth setObject:i2n(73) forKey:@"4"];
|
||||||
[columnsWidth setObject:i2n(58) forKey:@"7"];
|
[columnsWidth setObject:i2n(58) forKey:@"6"];
|
||||||
[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)
|
||||||
@@ -180,29 +59,20 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||||
PyDupeGuru *_py = (PyDupeGuru *)py;
|
PyDupeGuru *_py = (PyDupeGuru *)py;
|
||||||
[_py setMinMatchPercentage:[ud objectForKey:@"minMatchPercentage"]];
|
[_py setMinMatchPercentage:[ud objectForKey:@"minMatchPercentage"]];
|
||||||
[_py setMixFileKind:[ud objectForKey:@"mixFileKind"]];
|
[_py setMixFileKind:n2b([ud objectForKey:@"mixFileKind"])];
|
||||||
|
[_py setIgnoreHardlinkMatches:n2b([ud objectForKey:@"ignoreHardlinkMatches"])];
|
||||||
[_py setMatchScaled:[ud objectForKey:@"matchScaled"]];
|
[_py setMatchScaled:[ud objectForKey:@"matchScaled"]];
|
||||||
int r = n2i([py doScan]);
|
int r = n2i([py doScan]);
|
||||||
[matches reloadData];
|
if (r != 0) {
|
||||||
[self refreshStats];
|
|
||||||
if (r != 0)
|
|
||||||
[[ProgressController mainProgressController] hide];
|
[[ProgressController mainProgressController] hide];
|
||||||
if (r == 1)
|
}
|
||||||
[Dialogs showMessage:@"You cannot make a duplicate scan with only reference directories."];
|
if (r == 3) {
|
||||||
if (r == 3)
|
|
||||||
{
|
|
||||||
[Dialogs showMessage:@"The selected directories contain no scannable file."];
|
[Dialogs showMessage:@"The selected directories contain no scannable file."];
|
||||||
[app toggleDirectories:nil];
|
[app toggleDirectories:nil];
|
||||||
}
|
}
|
||||||
}
|
if (r == 4) {
|
||||||
|
[Dialogs showMessage:@"The iPhoto application couldn't be found."];
|
||||||
- (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
|
||||||
@@ -222,48 +92,8 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[_resultColumns addObject:sizeCol];
|
[_resultColumns addObject:sizeCol];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:3 title:@"Kind" width:40 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:3 title:@"Kind" width:40 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:4 title:@"Dimensions" width:80 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:4 title:@"Dimensions" width:80 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:5 title:@"Creation" width:120 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:5 title:@"Modification" width:120 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:6 title:@"Modification" width:120 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:6 title:@"Match %" width:58 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:7 title:@"Match %" width:58 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:7 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
|
||||||
@@ -1,218 +1,45 @@
|
|||||||
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
#
|
#
|
||||||
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
# 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
|
# 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/bsd_license
|
||||||
|
|
||||||
import objc
|
|
||||||
from Foundation import NSObject
|
|
||||||
|
|
||||||
|
from core.app_cocoa_inter import PyDupeGuruBase, PyDetailsPanel
|
||||||
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
|
import hsutil.conflict
|
||||||
from core_pe import block, cache, matchbase, data
|
import core.engine, core.fs, core.app
|
||||||
from hsutil import conflict
|
import core_pe.block, core_pe.cache, core_pe.matchbase, core_pe.data, core_pe._block_osx
|
||||||
|
import xml.etree.ElementPath
|
||||||
|
import gzip
|
||||||
|
import aem.kae
|
||||||
|
import appscript.defaultterminology
|
||||||
|
|
||||||
class 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 str(self.py.selected_dupe_path())
|
||||||
|
|
||||||
def getSelectedDupeRefPath(self):
|
def getSelectedDupeRefPath(self):
|
||||||
return unicode(self.app.selected_dupe_ref_path())
|
return str(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,9 +12,13 @@
|
|||||||
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 */; };
|
||||||
|
CE1EB5FE12537F9D0034AABB /* HSFairwareReminder.m in Sources */ = {isa = PBXBuildFile; fileRef = CE1EB5FC12537F9D0034AABB /* HSFairwareReminder.m */; };
|
||||||
|
CE1EB60112537FB90034AABB /* FairwareReminder.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE1EB5FF12537FB90034AABB /* FairwareReminder.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 */; };
|
||||||
@@ -23,28 +27,37 @@
|
|||||||
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 */; };
|
||||||
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 */; };
|
|
||||||
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 */; };
|
||||||
|
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 */; };
|
||||||
|
CEC9DB4712CCAA6B003102F0 /* about.xib in Resources */ = {isa = PBXBuildFile; fileRef = CEC9DB4612CCAA6B003102F0 /* about.xib */; };
|
||||||
|
CEC9DB4C12CCAA7D003102F0 /* HSAboutBox.m in Sources */ = {isa = PBXBuildFile; fileRef = CEC9DB4B12CCAA7D003102F0 /* HSAboutBox.m */; };
|
||||||
CECA899C09DB132E00A3D774 /* DetailsPanel.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CECA899A09DB132E00A3D774 /* DetailsPanel.h */; };
|
CECA899C09DB132E00A3D774 /* DetailsPanel.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CECA899A09DB132E00A3D774 /* DetailsPanel.h */; };
|
||||||
CECA899D09DB132E00A3D774 /* DetailsPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CECA899B09DB132E00A3D774 /* DetailsPanel.m */; };
|
CECA899D09DB132E00A3D774 /* DetailsPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = CECA899B09DB132E00A3D774 /* DetailsPanel.m */; };
|
||||||
CEEB135209C837A2004D2330 /* dupeguru.icns in Resources */ = {isa = PBXBuildFile; fileRef = CEEB135109C837A2004D2330 /* dupeguru.icns */; };
|
CEEB135209C837A2004D2330 /* dupeguru.icns in Resources */ = {isa = PBXBuildFile; fileRef = CEEB135109C837A2004D2330 /* dupeguru.icns */; };
|
||||||
|
CEF12A7E124DFD400087B51D /* HSTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = CEF12A7D124DFD400087B51D /* HSTableView.m */; };
|
||||||
|
CEF12A84124DFD620087B51D /* ResultTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CEF12A83124DFD620087B51D /* ResultTable.m */; };
|
||||||
CEFC294609C89E3D00D9F998 /* folder32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC294509C89E3D00D9F998 /* folder32.png */; };
|
CEFC294609C89E3D00D9F998 /* folder32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC294509C89E3D00D9F998 /* folder32.png */; };
|
||||||
CEFC295509C89FF200D9F998 /* details32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC295309C89FF200D9F998 /* details32.png */; };
|
CEFC295509C89FF200D9F998 /* details32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC295309C89FF200D9F998 /* details32.png */; };
|
||||||
CEFC295609C89FF200D9F998 /* preferences32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC295409C89FF200D9F998 /* preferences32.png */; };
|
CEFC295609C89FF200D9F998 /* preferences32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC295409C89FF200D9F998 /* preferences32.png */; };
|
||||||
@@ -77,14 +90,24 @@
|
|||||||
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; };
|
||||||
|
CE1EB5FB12537F9D0034AABB /* HSFairwareReminder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSFairwareReminder.h; path = ../../cocoalib/HSFairwareReminder.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE1EB5FC12537F9D0034AABB /* HSFairwareReminder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSFairwareReminder.m; path = ../../cocoalib/HSFairwareReminder.m; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE1EB5FD12537F9D0034AABB /* PyFairware.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyFairware.h; path = ../../cocoalib/PyFairware.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE1EB60012537FB90034AABB /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../../cocoalib/en.lproj/FairwareReminder.xib; 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,21 +115,17 @@
|
|||||||
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>"; };
|
||||||
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; };
|
||||||
CE80DB240FC192D60086DCA6 /* RecentDirectories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RecentDirectories.h; path = ../../cocoalib/RecentDirectories.h; sourceTree = SOURCE_ROOT; };
|
CE80DB240FC192D60086DCA6 /* RecentDirectories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RecentDirectories.h; path = ../../cocoalib/RecentDirectories.h; sourceTree = SOURCE_ROOT; };
|
||||||
CE80DB250FC192D60086DCA6 /* RecentDirectories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RecentDirectories.m; path = ../../cocoalib/RecentDirectories.m; sourceTree = SOURCE_ROOT; };
|
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; };
|
|
||||||
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 +134,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,11 +143,41 @@
|
|||||||
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>"; };
|
||||||
|
CE958659112C516400F95FD2 /* PyStatsLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyStatsLabel.h; path = ../base/PyStatsLabel.h; 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>"; };
|
||||||
|
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; };
|
||||||
|
CEC9DB4612CCAA6B003102F0 /* about.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = about.xib; path = ../../cocoalib/xib/about.xib; sourceTree = SOURCE_ROOT; };
|
||||||
|
CEC9DB4A12CCAA7D003102F0 /* HSAboutBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSAboutBox.h; path = ../../cocoalib/HSAboutBox.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CEC9DB4B12CCAA7D003102F0 /* HSAboutBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSAboutBox.m; path = ../../cocoalib/HSAboutBox.m; sourceTree = SOURCE_ROOT; };
|
||||||
CECA899A09DB132E00A3D774 /* DetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = DetailsPanel.h; sourceTree = "<group>"; };
|
CECA899A09DB132E00A3D774 /* DetailsPanel.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = DetailsPanel.h; sourceTree = "<group>"; };
|
||||||
CECA899B09DB132E00A3D774 /* DetailsPanel.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = DetailsPanel.m; sourceTree = "<group>"; };
|
CECA899B09DB132E00A3D774 /* DetailsPanel.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = DetailsPanel.m; sourceTree = "<group>"; };
|
||||||
CEEB135109C837A2004D2330 /* dupeguru.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = dupeguru.icns; sourceTree = "<group>"; };
|
CEEB135109C837A2004D2330 /* dupeguru.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = dupeguru.icns; sourceTree = "<group>"; };
|
||||||
|
CEF12A7C124DFD400087B51D /* HSTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSTableView.h; path = ../../cocoalib/views/HSTableView.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CEF12A7D124DFD400087B51D /* HSTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSTableView.m; path = ../../cocoalib/views/HSTableView.m; sourceTree = SOURCE_ROOT; };
|
||||||
|
CEF12A81124DFD620087B51D /* PyResultTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyResultTable.h; path = ../base/PyResultTable.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CEF12A82124DFD620087B51D /* ResultTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ResultTable.h; path = ../base/ResultTable.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CEF12A83124DFD620087B51D /* ResultTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ResultTable.m; path = ../base/ResultTable.m; sourceTree = SOURCE_ROOT; };
|
||||||
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; };
|
||||||
CEFC295409C89FF200D9F998 /* preferences32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = preferences32.png; path = ../../images/preferences32.png; sourceTree = SOURCE_ROOT; };
|
CEFC295409C89FF200D9F998 /* preferences32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = preferences32.png; path = ../../images/preferences32.png; sourceTree = SOURCE_ROOT; };
|
||||||
@@ -152,11 +198,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 +212,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 +245,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 +294,51 @@
|
|||||||
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 = (
|
||||||
|
CEC9DB4612CCAA6B003102F0 /* about.xib */,
|
||||||
|
CE1EB5FF12537FB90034AABB /* FairwareReminder.xib */,
|
||||||
|
CE7AC9151119911200D02F6C /* ErrorReportWindow.xib */,
|
||||||
|
CE7AC9161119911200D02F6C /* progress.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 */,
|
CE1EB5FB12537F9D0034AABB /* HSFairwareReminder.h */,
|
||||||
CE80DB200FC192D60086DCA6 /* Outline.m */,
|
CE1EB5FC12537F9D0034AABB /* HSFairwareReminder.m */,
|
||||||
|
CE1EB5FD12537F9D0034AABB /* PyFairware.h */,
|
||||||
|
CEC9DB4A12CCAA7D003102F0 /* HSAboutBox.h */,
|
||||||
|
CEC9DB4B12CCAA7D003102F0 /* HSAboutBox.m */,
|
||||||
CE80DB210FC192D60086DCA6 /* ProgressController.h */,
|
CE80DB210FC192D60086DCA6 /* ProgressController.h */,
|
||||||
CE80DB220FC192D60086DCA6 /* ProgressController.m */,
|
CE80DB220FC192D60086DCA6 /* ProgressController.m */,
|
||||||
CE80DB230FC192D60086DCA6 /* PyApp.h */,
|
CE80DB230FC192D60086DCA6 /* PyApp.h */,
|
||||||
CE80DB240FC192D60086DCA6 /* RecentDirectories.h */,
|
CE80DB240FC192D60086DCA6 /* RecentDirectories.h */,
|
||||||
CE80DB250FC192D60086DCA6 /* RecentDirectories.m */,
|
CE80DB250FC192D60086DCA6 /* RecentDirectories.m */,
|
||||||
CE80DB260FC192D60086DCA6 /* RegistrationInterface.h */,
|
|
||||||
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 */,
|
||||||
@@ -291,6 +350,9 @@
|
|||||||
CE80DB810FC194BD0086DCA6 /* dgbase */ = {
|
CE80DB810FC194BD0086DCA6 /* dgbase */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
CEF12A81124DFD620087B51D /* PyResultTable.h */,
|
||||||
|
CEF12A82124DFD620087B51D /* ResultTable.h */,
|
||||||
|
CEF12A83124DFD620087B51D /* ResultTable.m */,
|
||||||
CE80DB820FC1951C0086DCA6 /* AppDelegate.h */,
|
CE80DB820FC1951C0086DCA6 /* AppDelegate.h */,
|
||||||
CE80DB830FC1951C0086DCA6 /* AppDelegate.m */,
|
CE80DB830FC1951C0086DCA6 /* AppDelegate.m */,
|
||||||
CE80DB840FC1951C0086DCA6 /* Consts.h */,
|
CE80DB840FC1951C0086DCA6 /* Consts.h */,
|
||||||
@@ -298,13 +360,66 @@
|
|||||||
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 */,
|
||||||
|
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 = (
|
||||||
|
CEF12A7C124DFD400087B51D /* HSTableView.h */,
|
||||||
|
CEF12A7D124DFD400087B51D /* HSTableView.m */,
|
||||||
|
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 = (
|
||||||
@@ -355,7 +470,15 @@
|
|||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */;
|
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */;
|
||||||
compatibilityVersion = "Xcode 3.0";
|
compatibilityVersion = "Xcode 3.0";
|
||||||
|
developmentRegion = English;
|
||||||
hasScannedForEncodings = 1;
|
hasScannedForEncodings = 1;
|
||||||
|
knownRegions = (
|
||||||
|
English,
|
||||||
|
Japanese,
|
||||||
|
French,
|
||||||
|
German,
|
||||||
|
en,
|
||||||
|
);
|
||||||
mainGroup = 29B97314FDCFA39411CA2CEA /* dupeguru */;
|
mainGroup = 29B97314FDCFA39411CA2CEA /* dupeguru */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
@@ -377,14 +500,16 @@
|
|||||||
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 */,
|
||||||
|
CE0C2AC81177021600BC749F /* ProblemDialog.xib in Resources */,
|
||||||
|
CE1EB60112537FB90034AABB /* FairwareReminder.xib in Resources */,
|
||||||
|
CEC9DB4712CCAA6B003102F0 /* about.xib in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -400,14 +525,10 @@
|
|||||||
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 */,
|
|
||||||
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 +538,87 @@
|
|||||||
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 */,
|
||||||
|
CE95865F112C516400F95FD2 /* StatsLabel.m in Sources */,
|
||||||
|
CE0C2AB61177011000BC749F /* HSTable.m in Sources */,
|
||||||
|
CE0C2ABD1177014200BC749F /* ProblemDialog.m in Sources */,
|
||||||
|
CEF12A7E124DFD400087B51D /* HSTableView.m in Sources */,
|
||||||
|
CEF12A84124DFD620087B51D /* ResultTable.m in Sources */,
|
||||||
|
CE1EB5FE12537F9D0034AABB /* HSFairwareReminder.m in Sources */,
|
||||||
|
CEC9DB4C12CCAA7D003102F0 /* HSAboutBox.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
/* Begin PBXVariantGroup section */
|
||||||
CE80DB700FC194760086DCA6 /* ErrorReportWindow.xib */ = {
|
CE1EB5FF12537FB90034AABB /* FairwareReminder.xib */ = {
|
||||||
isa = PBXVariantGroup;
|
isa = PBXVariantGroup;
|
||||||
children = (
|
children = (
|
||||||
CE80DB710FC194760086DCA6 /* English */,
|
CE1EB60012537FB90034AABB /* en */,
|
||||||
);
|
);
|
||||||
name = ErrorReportWindow.xib;
|
name = FairwareReminder.xib;
|
||||||
sourceTree = SOURCE_ROOT;
|
path = ../../cocoalib/xib;
|
||||||
};
|
|
||||||
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;
|
sourceTree = SOURCE_ROOT;
|
||||||
};
|
};
|
||||||
/* End PBXVariantGroup section */
|
/* 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 +626,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 */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_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">10F569</string>
|
||||||
<string key="IBDocument.InterfaceBuilderVersion">740</string>
|
<string key="IBDocument.InterfaceBuilderVersion">788</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">461.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">788</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>
|
||||||
@@ -434,6 +434,7 @@
|
|||||||
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
|
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
|
||||||
<string key="NSMinSize">{451, 177}</string>
|
<string key="NSMinSize">{451, 177}</string>
|
||||||
<string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
|
<string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
|
||||||
|
<string key="NSFrameAutosaveName">DetailsPanel</string>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="IBObjectContainer" key="IBDocument.Objects">
|
<object class="IBObjectContainer" key="IBDocument.Objects">
|
||||||
@@ -487,6 +488,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 +777,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 +833,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 +855,33 @@
|
|||||||
</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="NSMutableDictionary" key="toOneOutletInfosByName">
|
||||||
|
<string key="NS.key.0">detailsTable</string>
|
||||||
|
<object class="IBToOneOutletInfo" key="NS.object.0">
|
||||||
|
<string key="name">detailsTable</string>
|
||||||
|
<string key="candidateClassName">NSTableView</string>
|
||||||
|
</object>
|
||||||
|
</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">
|
||||||
@@ -873,35 +899,59 @@
|
|||||||
<string>NSProgressIndicator</string>
|
<string>NSProgressIndicator</string>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
|
||||||
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
|
<object class="NSArray" key="dict.sortedKeys">
|
||||||
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
|
<string>dupeImage</string>
|
||||||
|
<string>dupeProgressIndicator</string>
|
||||||
|
<string>refImage</string>
|
||||||
|
<string>refProgressIndicator</string>
|
||||||
|
</object>
|
||||||
|
<object class="NSMutableArray" key="dict.values">
|
||||||
|
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||||
|
<object class="IBToOneOutletInfo">
|
||||||
|
<string key="name">dupeImage</string>
|
||||||
|
<string key="candidateClassName">NSImageView</string>
|
||||||
|
</object>
|
||||||
|
<object class="IBToOneOutletInfo">
|
||||||
|
<string key="name">dupeProgressIndicator</string>
|
||||||
|
<string key="candidateClassName">NSProgressIndicator</string>
|
||||||
|
</object>
|
||||||
|
<object class="IBToOneOutletInfo">
|
||||||
|
<string key="name">refImage</string>
|
||||||
|
<string key="candidateClassName">NSImageView</string>
|
||||||
|
</object>
|
||||||
|
<object class="IBToOneOutletInfo">
|
||||||
|
<string key="name">refProgressIndicator</string>
|
||||||
|
<string key="candidateClassName">NSProgressIndicator</string>
|
||||||
|
</object>
|
||||||
|
</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">DetailsPanel.h</string>
|
<string key="minorKey">DetailsPanel.h</string>
|
||||||
</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>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
|
||||||
|
<string key="NS.key.0">detailsTable</string>
|
||||||
|
<object class="IBToOneOutletInfo" key="NS.object.0">
|
||||||
|
<string key="name">detailsTable</string>
|
||||||
|
<string key="candidateClassName">NSTableView</string>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
<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"/>
|
||||||
</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 +960,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>
|
||||||
@@ -1445,6 +1467,13 @@
|
|||||||
<string key="NS.key.0">showWindow:</string>
|
<string key="NS.key.0">showWindow:</string>
|
||||||
<string key="NS.object.0">id</string>
|
<string key="NS.object.0">id</string>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="NSMutableDictionary" key="actionInfosByName">
|
||||||
|
<string key="NS.key.0">showWindow:</string>
|
||||||
|
<object class="IBActionInfo" key="NS.object.0">
|
||||||
|
<string key="name">showWindow:</string>
|
||||||
|
<string key="candidateClassName">id</string>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||||
<string key="majorKey">IBFrameworkSource</string>
|
<string key="majorKey">IBFrameworkSource</string>
|
||||||
<string key="minorKey">AppKit.framework/Headers/NSWindowController.h</string>
|
<string key="minorKey">AppKit.framework/Headers/NSWindowController.h</string>
|
||||||
@@ -1453,6 +1482,7 @@
|
|||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<int key="IBDocument.localizationMode">0</int>
|
<int key="IBDocument.localizationMode">0</int>
|
||||||
|
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
|
||||||
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
|
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
|
||||||
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
|
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
|
||||||
<integer value="1050" key="NS.object.0"/>
|
<integer value="1050" key="NS.object.0"/>
|
||||||
@@ -1468,5 +1498,9 @@
|
|||||||
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
||||||
<nil key="IBDocument.LastKnownRelativeProjectPath"/>
|
<nil key="IBDocument.LastKnownRelativeProjectPath"/>
|
||||||
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
||||||
|
<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
|
||||||
|
<string key="NS.key.0">NSApplicationIcon</string>
|
||||||
|
<string key="NS.object.0">{128, 128}</string>
|
||||||
|
</object>
|
||||||
</data>
|
</data>
|
||||||
</archive>
|
</archive>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,23 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_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
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
#import "../../cocoalib/ProgressController.h"
|
#import "../../cocoalib/ProgressController.h"
|
||||||
#import "../../cocoalib/RegistrationInterface.h"
|
|
||||||
#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
|
||||||
@@ -27,6 +27,7 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[d setObject:b2n(NO) forKey:@"matchSimilarWords"];
|
[d setObject:b2n(NO) forKey:@"matchSimilarWords"];
|
||||||
[d setObject:b2n(YES) forKey:@"mixFileKind"];
|
[d setObject:b2n(YES) forKey:@"mixFileKind"];
|
||||||
[d setObject:b2n(NO) forKey:@"useRegexpFilter"];
|
[d setObject:b2n(NO) forKey:@"useRegexpFilter"];
|
||||||
|
[d setObject:b2n(NO) forKey:@"ignoreHardlinkMatches"];
|
||||||
[d setObject:b2n(NO) forKey:@"removeEmptyFolders"];
|
[d setObject:b2n(NO) forKey:@"removeEmptyFolders"];
|
||||||
[d setObject:b2n(YES) forKey:@"ignoreSmallFiles"];
|
[d setObject:b2n(YES) forKey:@"ignoreSmallFiles"];
|
||||||
[d setObject:b2n(NO) forKey:@"debug"];
|
[d setObject:b2n(NO) forKey:@"debug"];
|
||||||
@@ -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,13 +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 <Cocoa/Cocoa.h>
|
|
||||||
#import "../base/DetailsPanel.h"
|
|
||||||
|
|
||||||
@interface DetailsPanel : DetailsPanelBase
|
|
||||||
@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
|
|
||||||
@@ -1,15 +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 <Cocoa/Cocoa.h>
|
|
||||||
#import "../base/DirectoryPanel.h"
|
|
||||||
|
|
||||||
@interface DirectoryPanel : DirectoryPanelBase
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@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.12.2</string>
|
||||||
<key>NSMainNibFile</key>
|
<key>NSMainNibFile</key>
|
||||||
<string>MainMenu</string>
|
<string>MainMenu</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|||||||
@@ -1,38 +1,19 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_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
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "ResultWindow.h"
|
#import "ResultWindow.h"
|
||||||
@@ -18,146 +18,27 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
- (void)awakeFromNib
|
- (void)awakeFromNib
|
||||||
{
|
{
|
||||||
[super awakeFromNib];
|
[super awakeFromNib];
|
||||||
_displayDelta = NO;
|
NSMutableIndexSet *deltaColumns = [NSMutableIndexSet indexSetWithIndex:2];
|
||||||
_powerMode = NO;
|
[deltaColumns addIndex:4];
|
||||||
_deltaColumns = [[NSMutableIndexSet indexSetWithIndexesInRange:NSMakeRange(2,4)] retain];
|
[table 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];
|
||||||
[columnsOrder addObject:@"0"];
|
[columnsOrder addObject:@"0"];
|
||||||
[columnsOrder addObject:@"1"];
|
[columnsOrder addObject:@"1"];
|
||||||
[columnsOrder addObject:@"2"];
|
[columnsOrder addObject:@"2"];
|
||||||
[columnsOrder addObject:@"6"];
|
[columnsOrder addObject:@"5"];
|
||||||
NSMutableDictionary *columnsWidth = [NSMutableDictionary dictionary];
|
NSMutableDictionary *columnsWidth = [NSMutableDictionary dictionary];
|
||||||
[columnsWidth setObject:i2n(195) forKey:@"0"];
|
[columnsWidth setObject:i2n(195) forKey:@"0"];
|
||||||
[columnsWidth setObject:i2n(120) forKey:@"1"];
|
[columnsWidth setObject:i2n(183) forKey:@"1"];
|
||||||
[columnsWidth setObject:i2n(63) forKey:@"2"];
|
[columnsWidth setObject:i2n(63) forKey:@"2"];
|
||||||
[columnsWidth setObject:i2n(60) forKey:@"6"];
|
[columnsWidth setObject:i2n(60) forKey:@"5"];
|
||||||
[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)
|
||||||
@@ -170,18 +51,15 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[_py setScanType:[ud objectForKey:@"scanType"]];
|
[_py setScanType:[ud objectForKey:@"scanType"]];
|
||||||
[_py setMinMatchPercentage:[ud objectForKey:@"minMatchPercentage"]];
|
[_py setMinMatchPercentage:[ud objectForKey:@"minMatchPercentage"]];
|
||||||
[_py setWordWeighting:[ud objectForKey:@"wordWeighting"]];
|
[_py setWordWeighting:[ud objectForKey:@"wordWeighting"]];
|
||||||
[_py setMixFileKind:[ud objectForKey:@"mixFileKind"]];
|
[_py setMixFileKind:n2b([ud objectForKey:@"mixFileKind"])];
|
||||||
|
[_py setIgnoreHardlinkMatches:n2b([ud objectForKey:@"ignoreHardlinkMatches"])];
|
||||||
[_py setMatchSimilarWords:[ud objectForKey:@"matchSimilarWords"]];
|
[_py setMatchSimilarWords:[ud objectForKey:@"matchSimilarWords"]];
|
||||||
int smallFileThreshold = [ud integerForKey:@"smallFileThreshold"]; // In KB
|
int smallFileThreshold = [ud integerForKey:@"smallFileThreshold"]; // In KB
|
||||||
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)
|
|
||||||
[Dialogs showMessage:@"You cannot make a duplicate scan with only reference directories."];
|
|
||||||
if (r == 3)
|
if (r == 3)
|
||||||
{
|
{
|
||||||
[Dialogs showMessage:@"The selected directories contain no scannable file."];
|
[Dialogs showMessage:@"The selected directories contain no scannable file."];
|
||||||
@@ -190,15 +68,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
|
||||||
{
|
{
|
||||||
@@ -210,49 +79,9 @@ http://www.hardcoded.net/licenses/hs_license
|
|||||||
[[sizeCol dataCell] setAlignment:NSRightTextAlignment];
|
[[sizeCol dataCell] setAlignment:NSRightTextAlignment];
|
||||||
[_resultColumns addObject:sizeCol];
|
[_resultColumns addObject:sizeCol];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:3 title:@"Kind" width:40 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:3 title:@"Kind" width:40 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:4 title:@"Creation" width:120 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:4 title:@"Modification" width:120 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:5 title:@"Modification" width:120 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:5 title:@"Match %" width:60 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:6 title:@"Match %" width:60 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:6 title:@"Words Used" width:120 refCol:refCol]];
|
||||||
[_resultColumns addObject:[self getColumnForIdentifier:7 title:@"Words Used" width:120 refCol:refCol]];
|
[_resultColumns addObject:[self getColumnForIdentifier:7 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
|
||||||
|
|||||||
@@ -1,226 +1,52 @@
|
|||||||
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
#
|
#
|
||||||
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
# 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
|
# 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/bsd_license
|
||||||
|
|
||||||
import objc
|
from hscommon.cocoa import signature
|
||||||
from Foundation import NSObject
|
|
||||||
|
|
||||||
|
from core.scanner import ScanType
|
||||||
|
from core.app_cocoa_inter import PyDupeGuruBase, PyDetailsPanel
|
||||||
from core_se.app_cocoa import DupeGuru
|
from core_se.app_cocoa import DupeGuru
|
||||||
from core import scanner
|
|
||||||
|
|
||||||
# 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
|
import hsutil.conflict
|
||||||
from core import app, app_cocoa, data, directories, engine, export, ignore, results, fs
|
import core.engine, core.fs, core.app
|
||||||
from hsutil import conflict
|
import core_se.fs, core_se.data
|
||||||
|
import xml.etree.ElementPath
|
||||||
|
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,
|
ScanType.Filename,
|
||||||
scanner.SCAN_TYPE_CONTENT
|
ScanType.Contents,
|
||||||
][scan_type]
|
][scan_type]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
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,34 @@
|
|||||||
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 */; };
|
||||||
|
CE27D3C112CCA42500859E67 /* about.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE27D3C012CCA42500859E67 /* about.xib */; };
|
||||||
|
CE27D3C412CCA43800859E67 /* HSAboutBox.m in Sources */ = {isa = PBXBuildFile; fileRef = CE27D3C312CCA43800859E67 /* HSAboutBox.m */; };
|
||||||
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; };
|
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; };
|
||||||
CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9A09914ADF003581CE /* ResultWindow.m */; };
|
CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9A09914ADF003581CE /* ResultWindow.m */; };
|
||||||
CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */ = {isa = PBXBuildFile; fileRef = CE381CF509915304003581CE /* dg_cocoa.plugin */; };
|
CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */ = {isa = PBXBuildFile; fileRef = CE381CF509915304003581CE /* dg_cocoa.plugin */; };
|
||||||
CE3A46FA109B212E002ABFD5 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE3A46F9109B212E002ABFD5 /* MainMenu.xib */; };
|
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 */; };
|
||||||
|
CE6DD4E7124CA3070089A48D /* ResultTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CE6DD4E6124CA3070089A48D /* ResultTable.m */; };
|
||||||
|
CE6DD547124CAF1F0089A48D /* HSTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = CE6DD546124CAF1F0089A48D /* HSTableView.m */; };
|
||||||
CE6E0DFE1054E9EF008D9390 /* dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = CE6E0DFD1054E9EF008D9390 /* dsa_pub.pem */; };
|
CE6E0DFE1054E9EF008D9390 /* dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = CE6E0DFD1054E9EF008D9390 /* dsa_pub.pem */; };
|
||||||
|
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 */; };
|
||||||
|
CE79638612536C94008D405B /* FairwareReminder.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE79638412536C94008D405B /* FairwareReminder.xib */; };
|
||||||
|
CE79638C12536F4E008D405B /* HSFairwareReminder.m in Sources */ = {isa = PBXBuildFile; fileRef = CE79638B12536F4E008D405B /* HSFairwareReminder.m */; };
|
||||||
|
CE8C53BC117324CE0011B41F /* HSTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CE8C53BB117324CE0011B41F /* HSTable.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 +48,10 @@
|
|||||||
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 */; };
|
|
||||||
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 +65,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 +79,11 @@
|
|||||||
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>"; };
|
||||||
|
CE27D3C012CCA42500859E67 /* about.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = about.xib; path = ../../cocoalib/xib/about.xib; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE27D3C212CCA43800859E67 /* HSAboutBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSAboutBox.h; path = ../../cocoalib/HSAboutBox.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE27D3C312CCA43800859E67 /* HSAboutBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSAboutBox.m; path = ../../cocoalib/HSAboutBox.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE381C9409914ACE003581CE /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; };
|
CE381C9409914ACE003581CE /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; };
|
||||||
CE381C9509914ACE003581CE /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; };
|
CE381C9509914ACE003581CE /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; };
|
||||||
CE381C9A09914ADF003581CE /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = ResultWindow.m; sourceTree = SOURCE_ROOT; };
|
CE381C9A09914ADF003581CE /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = ResultWindow.m; sourceTree = SOURCE_ROOT; };
|
||||||
@@ -76,12 +91,46 @@
|
|||||||
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; };
|
||||||
|
CE6DD4E4124CA3070089A48D /* PyResultTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyResultTable.h; path = ../base/PyResultTable.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE6DD4E5124CA3070089A48D /* ResultTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ResultTable.h; path = ../base/ResultTable.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE6DD4E6124CA3070089A48D /* ResultTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ResultTable.m; path = ../base/ResultTable.m; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE6DD545124CAF1F0089A48D /* HSTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSTableView.h; path = ../../cocoalib/views/HSTableView.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE6DD546124CAF1F0089A48D /* HSTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSTableView.m; path = ../../cocoalib/views/HSTableView.m; 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; };
|
||||||
|
CE79638212536C6E008D405B /* PyFairware.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyFairware.h; path = ../../cocoalib/PyFairware.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE79638512536C94008D405B /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../../cocoalib/en.lproj/FairwareReminder.xib; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE79638A12536F4E008D405B /* HSFairwareReminder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HSFairwareReminder.h; path = ../../cocoalib/HSFairwareReminder.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE79638B12536F4E008D405B /* HSFairwareReminder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HSFairwareReminder.m; path = ../../cocoalib/HSFairwareReminder.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>"; };
|
||||||
|
CE91F210113BC22D0010360B /* PyStatsLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyStatsLabel.h; path = ../base/PyStatsLabel.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
CE91F213113BC22D0010360B /* StatsLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StatsLabel.h; path = ../base/StatsLabel.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
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,25 +145,15 @@
|
|||||||
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; };
|
||||||
CEFC7F930FC9517500CD5728 /* PyRegistrable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyRegistrable.h; path = ../../cocoalib/PyRegistrable.h; sourceTree = SOURCE_ROOT; };
|
|
||||||
CEFC7F940FC9517500CD5728 /* RecentDirectories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RecentDirectories.h; path = ../../cocoalib/RecentDirectories.h; sourceTree = SOURCE_ROOT; };
|
CEFC7F940FC9517500CD5728 /* RecentDirectories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RecentDirectories.h; path = ../../cocoalib/RecentDirectories.h; sourceTree = SOURCE_ROOT; };
|
||||||
CEFC7F950FC9517500CD5728 /* RecentDirectories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RecentDirectories.m; path = ../../cocoalib/RecentDirectories.m; sourceTree = SOURCE_ROOT; };
|
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; };
|
|
||||||
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 +183,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 +254,60 @@
|
|||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
CE19BC5F11199231007CCEB0 /* xib */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CE27D3C012CCA42500859E67 /* about.xib */,
|
||||||
|
CE79638412536C94008D405B /* FairwareReminder.xib */,
|
||||||
|
CE19BC6011199231007CCEB0 /* ErrorReportWindow.xib */,
|
||||||
|
CE19BC6111199231007CCEB0 /* progress.xib */,
|
||||||
|
);
|
||||||
|
name = xib;
|
||||||
|
path = ../../cocoalib/xib;
|
||||||
|
sourceTree = SOURCE_ROOT;
|
||||||
|
};
|
||||||
|
CE76FDBD111EE37C006618EA /* views */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CE6DD545124CAF1F0089A48D /* HSTableView.h */,
|
||||||
|
CE6DD546124CAF1F0089A48D /* HSTableView.m */,
|
||||||
|
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 +321,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,26 +343,27 @@
|
|||||||
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 */,
|
CE79638A12536F4E008D405B /* HSFairwareReminder.h */,
|
||||||
CEFC7F8F0FC9517500CD5728 /* Outline.m */,
|
CE79638B12536F4E008D405B /* HSFairwareReminder.m */,
|
||||||
|
CE79638212536C6E008D405B /* PyFairware.h */,
|
||||||
|
CE27D3C212CCA43800859E67 /* HSAboutBox.h */,
|
||||||
|
CE27D3C312CCA43800859E67 /* HSAboutBox.m */,
|
||||||
CEFC7F900FC9517500CD5728 /* ProgressController.h */,
|
CEFC7F900FC9517500CD5728 /* ProgressController.h */,
|
||||||
CEFC7F910FC9517500CD5728 /* ProgressController.m */,
|
CEFC7F910FC9517500CD5728 /* ProgressController.m */,
|
||||||
CEFC7F920FC9517500CD5728 /* PyApp.h */,
|
CEFC7F920FC9517500CD5728 /* PyApp.h */,
|
||||||
CEFC7F930FC9517500CD5728 /* PyRegistrable.h */,
|
|
||||||
CEFC7F940FC9517500CD5728 /* RecentDirectories.h */,
|
CEFC7F940FC9517500CD5728 /* RecentDirectories.h */,
|
||||||
CEFC7F950FC9517500CD5728 /* RecentDirectories.m */,
|
CEFC7F950FC9517500CD5728 /* RecentDirectories.m */,
|
||||||
CEFC7F960FC9517500CD5728 /* RegistrationInterface.h */,
|
|
||||||
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 +375,15 @@
|
|||||||
CEFC7FB00FC9518F00CD5728 /* dgbase */ = {
|
CEFC7FB00FC9518F00CD5728 /* dgbase */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
CE6DD4E4124CA3070089A48D /* PyResultTable.h */,
|
||||||
|
CE6DD4E5124CA3070089A48D /* ResultTable.h */,
|
||||||
|
CE6DD4E6124CA3070089A48D /* ResultTable.m */,
|
||||||
|
CE91F210113BC22D0010360B /* PyStatsLabel.h */,
|
||||||
|
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 +392,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>";
|
||||||
@@ -330,7 +434,15 @@
|
|||||||
};
|
};
|
||||||
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */;
|
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */;
|
||||||
compatibilityVersion = "Xcode 3.0";
|
compatibilityVersion = "Xcode 3.0";
|
||||||
|
developmentRegion = English;
|
||||||
hasScannedForEncodings = 1;
|
hasScannedForEncodings = 1;
|
||||||
|
knownRegions = (
|
||||||
|
English,
|
||||||
|
Japanese,
|
||||||
|
French,
|
||||||
|
German,
|
||||||
|
en,
|
||||||
|
);
|
||||||
mainGroup = 29B97314FDCFA39411CA2CEA /* dupeguru */;
|
mainGroup = 29B97314FDCFA39411CA2CEA /* dupeguru */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
@@ -351,14 +463,16 @@
|
|||||||
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 */,
|
||||||
|
CE647E591173026F006D28BA /* ProblemDialog.xib in Resources */,
|
||||||
|
CE79638612536C94008D405B /* FairwareReminder.xib in Resources */,
|
||||||
|
CE27D3C112CCA42500859E67 /* about.xib in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -372,15 +486,10 @@
|
|||||||
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 */,
|
|
||||||
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 +497,87 @@
|
|||||||
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 */,
|
||||||
|
CE91F216113BC22D0010360B /* StatsLabel.m in Sources */,
|
||||||
|
CE647E571173024A006D28BA /* ProblemDialog.m in Sources */,
|
||||||
|
CE8C53BC117324CE0011B41F /* HSTable.m in Sources */,
|
||||||
|
CE6DD4E7124CA3070089A48D /* ResultTable.m in Sources */,
|
||||||
|
CE6DD547124CAF1F0089A48D /* HSTableView.m in Sources */,
|
||||||
|
CE79638C12536F4E008D405B /* HSFairwareReminder.m in Sources */,
|
||||||
|
CE27D3C412CCA43800859E67 /* HSAboutBox.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
/* Begin PBXVariantGroup section */
|
||||||
CEFC7FA70FC9518A00CD5728 /* ErrorReportWindow.xib */ = {
|
CE79638412536C94008D405B /* FairwareReminder.xib */ = {
|
||||||
isa = PBXVariantGroup;
|
isa = PBXVariantGroup;
|
||||||
children = (
|
children = (
|
||||||
CEFC7FA80FC9518A00CD5728 /* English */,
|
CE79638512536C94008D405B /* en */,
|
||||||
);
|
);
|
||||||
name = ErrorReportWindow.xib;
|
name = FairwareReminder.xib;
|
||||||
sourceTree = SOURCE_ROOT;
|
path = ../../cocoalib/xib;
|
||||||
};
|
|
||||||
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;
|
sourceTree = SOURCE_ROOT;
|
||||||
};
|
};
|
||||||
/* End PBXVariantGroup section */
|
/* 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 +585,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 */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
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
|
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/bsd_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
15
configure.py
15
configure.py
@@ -3,29 +3,26 @@
|
|||||||
# Created On: 2009-12-30
|
# Created On: 2009-12-30
|
||||||
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
#
|
#
|
||||||
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
# 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
|
# 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/bsd_license
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
from optparse import OptionParser
|
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)
|
||||||
|
|||||||
288
core/app.py
288
core/app.py
@@ -1,21 +1,22 @@
|
|||||||
#!/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)
|
||||||
#
|
#
|
||||||
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
# 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
|
# 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/bsd_license
|
||||||
|
|
||||||
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
|
||||||
|
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
|
||||||
|
|
||||||
@@ -30,14 +31,10 @@ JOB_DELETE = 'job_delete'
|
|||||||
class NoScannableFileError(Exception):
|
class NoScannableFileError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class AllFilesAreRefError(Exception):
|
class DupeGuru(RegistrableApplication, Broadcaster):
|
||||||
pass
|
def __init__(self, data_module, appdata):
|
||||||
|
RegistrableApplication.__init__(self, appid=1)
|
||||||
class DupeGuru(RegistrableApplication):
|
Broadcaster.__init__(self)
|
||||||
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):
|
|
||||||
RegistrableApplication.__init__(self, appid)
|
|
||||||
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)
|
||||||
@@ -45,47 +42,35 @@ class DupeGuru(RegistrableApplication):
|
|||||||
self.directories = directories.Directories()
|
self.directories = directories.Directories()
|
||||||
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.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,
|
||||||
|
'ignore_hardlink_matches': False,
|
||||||
}
|
}
|
||||||
|
self.selected_dupes = []
|
||||||
|
|
||||||
def _demo_check(self):
|
def _do_delete(self, j, replace_with_hardlinks):
|
||||||
if self.registered:
|
|
||||||
return
|
|
||||||
count = self.results.mark_count
|
|
||||||
if count + self.action_count > 10:
|
|
||||||
raise RegistrationRequired()
|
|
||||||
else:
|
|
||||||
self.action_count += count
|
|
||||||
|
|
||||||
def _do_delete(self, j):
|
|
||||||
def op(dupe):
|
def op(dupe):
|
||||||
j.add_progress()
|
j.add_progress()
|
||||||
return self._do_delete_dupe(dupe)
|
return self._do_delete_dupe(dupe, replace_with_hardlinks)
|
||||||
|
|
||||||
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, replace_with_hardlinks):
|
||||||
if not io.exists(dupe.path):
|
if not io.exists(dupe.path):
|
||||||
return True
|
return
|
||||||
self._recycle_dupe(dupe)
|
send2trash(str(dupe.path)) # Raises OSError when there's a problem
|
||||||
|
if replace_with_hardlinks:
|
||||||
|
group = self.results.get_group_of_duplicate(dupe)
|
||||||
|
ref = group.ref
|
||||||
|
os.link(str(ref.path), str(dupe.path))
|
||||||
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'))
|
||||||
j = j.start_subjob([1, 9])
|
self.notify('directories_changed')
|
||||||
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)
|
|
||||||
for file in j.iter_with_progress(files, 'Reading metadata %d/%d'):
|
|
||||||
file._read_all_info(attrnames=self.data.METADATA_TO_READ)
|
|
||||||
|
|
||||||
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):
|
||||||
@@ -93,35 +78,79 @@ class DupeGuru(RegistrableApplication):
|
|||||||
try:
|
try:
|
||||||
return self.data.GetDisplayInfo(dupe, group, delta)
|
return self.data.GetDisplayInfo(dupe, group, delta)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.warning("Exception on GetDisplayInfo for %s: %s", unicode(dupe.path), unicode(e))
|
logging.warning("Exception on GetDisplayInfo for %s: %s", str(dupe.path), str(e))
|
||||||
return ['---'] * len(self.data.COLUMNS)
|
return ['---'] * len(self.data.COLUMNS)
|
||||||
|
|
||||||
def _get_file(self, str_path):
|
def _get_file(self, str_path):
|
||||||
path = Path(str_path)
|
path = Path(str_path)
|
||||||
return fs.get_file(path, self.directories.fileclasses)
|
f = fs.get_file(path, self.directories.fileclasses)
|
||||||
|
if f is None:
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
f._read_all_info(attrnames=self.data.METADATA_TO_READ)
|
||||||
|
return f
|
||||||
|
except EnvironmentError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
def _start_job(self, jobid, func):
|
@staticmethod
|
||||||
# func(j)
|
def _reveal_path(path):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _remove_hardlink_dupes(files):
|
||||||
|
seen_inodes = set()
|
||||||
|
result = []
|
||||||
|
for file in files:
|
||||||
|
try:
|
||||||
|
inode = io.stat(file.path).st_ino
|
||||||
|
except OSError:
|
||||||
|
# The file was probably deleted or something
|
||||||
|
continue
|
||||||
|
if inode not in seen_inodes:
|
||||||
|
seen_inodes.add(inode)
|
||||||
|
result.append(file)
|
||||||
|
return result
|
||||||
|
|
||||||
|
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, *args):
|
||||||
|
# func(j, *args)
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
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(str(other.path), str(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,40 +180,33 @@ 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()
|
|
||||||
jobid = JOB_COPY if copy else JOB_MOVE
|
jobid = JOB_COPY if copy else JOB_MOVE
|
||||||
self._start_job(jobid, do)
|
self._start_job(jobid, do)
|
||||||
|
|
||||||
def delete_marked(self):
|
def delete_marked(self, replace_with_hardlinks=False):
|
||||||
self._demo_check()
|
self._start_job(JOB_DELETE, self._do_delete, replace_with_hardlinks)
|
||||||
self._start_job(JOB_DELETE, self._do_delete)
|
|
||||||
|
|
||||||
def export_to_xhtml(self, column_ids):
|
def export_to_xhtml(self, column_ids):
|
||||||
column_ids = [colid for colid in column_ids if colid.isdigit()]
|
column_ids = [colid for colid in column_ids if colid.isdigit()]
|
||||||
column_ids = map(int, column_ids)
|
column_ids = list(map(int, column_ids))
|
||||||
column_ids.sort()
|
column_ids.sort()
|
||||||
colnames = [col['display'] for i, col in enumerate(self.data.COLUMNS) if i in column_ids]
|
colnames = [col['display'] for i, col in enumerate(self.data.COLUMNS) if i in column_ids]
|
||||||
rows = []
|
rows = []
|
||||||
@@ -195,32 +218,126 @@ 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', str(dupe.path))
|
||||||
|
cmd = cmd.replace('%r', str(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()
|
||||||
|
|
||||||
|
def load_from(self, filename):
|
||||||
|
def do(j):
|
||||||
|
self.results.load_from_xml(filename, self._get_file, j)
|
||||||
|
self._start_job(JOB_LOAD, do)
|
||||||
|
|
||||||
def load_ignore_list(self):
|
def load_ignore_list(self):
|
||||||
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" % str(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'))
|
||||||
|
if self.results.is_modified:
|
||||||
|
self.results.save_to_xml(op.join(self.appdata, 'last_results.xml'))
|
||||||
|
|
||||||
|
def save_as(self, filename):
|
||||||
|
self.results.save_to_xml(filename)
|
||||||
|
# It's not because we saved it here that we don't want to save it in appdata when we quit
|
||||||
|
self.results.is_modified = True
|
||||||
|
|
||||||
def save_ignore_list(self):
|
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)
|
||||||
|
|
||||||
@@ -228,18 +345,25 @@ class DupeGuru(RegistrableApplication):
|
|||||||
def do(j):
|
def do(j):
|
||||||
j.set_progress(0, 'Collecting files to scan')
|
j.set_progress(0, 'Collecting files to scan')
|
||||||
files = list(self.directories.get_files())
|
files = list(self.directories.get_files())
|
||||||
|
if self.options['ignore_hardlink_matches']:
|
||||||
|
files = self._remove_hardlink_dupes(files)
|
||||||
logging.info('Scanning %d files' % len(files))
|
logging.info('Scanning %d files' % len(files))
|
||||||
self.results.groups = self.scanner.GetDupeGroups(files, j)
|
self.results.groups = self.scanner.GetDupeGroups(files, j)
|
||||||
|
|
||||||
files = self.directories.get_files()
|
if not self.directories.has_any_file():
|
||||||
first_file = first(files)
|
|
||||||
if first_file is None:
|
|
||||||
raise NoScannableFileError()
|
raise NoScannableFileError()
|
||||||
if first_file.is_ref and all(f.is_ref for f in files):
|
|
||||||
raise AllFilesAreRefError()
|
|
||||||
self.results.groups = []
|
self.results.groups = []
|
||||||
|
self.notify('results_changed')
|
||||||
self._start_job(JOB_SCAN, do)
|
self._start_job(JOB_SCAN, do)
|
||||||
|
|
||||||
|
def toggle_selected_mark_state(self):
|
||||||
|
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):
|
||||||
|
|||||||
@@ -2,22 +2,21 @@
|
|||||||
# 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)
|
||||||
#
|
#
|
||||||
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
# 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
|
# 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/bsd_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 jobprogress import job
|
||||||
from hsutil.cocoa import install_exception_hook
|
from hscommon import cocoa
|
||||||
from hsutil.misc import stripnone
|
from hscommon.cocoa import install_exception_hook
|
||||||
from hsutil.reg import RegistrationRequired
|
from hscommon.cocoa.objcmin import (NSNotificationCenter, NSUserDefaults,
|
||||||
|
NSSearchPathForDirectoriesInDomains, NSApplicationSupportDirectory, NSUserDomainMask,
|
||||||
|
NSWorkspace)
|
||||||
|
|
||||||
from . import app, fs
|
from . import app
|
||||||
|
|
||||||
JOBID2TITLE = {
|
JOBID2TITLE = {
|
||||||
app.JOB_SCAN: "Scanning for duplicates",
|
app.JOB_SCAN: "Scanning for duplicates",
|
||||||
@@ -27,286 +26,43 @@ JOBID2TITLE = {
|
|||||||
app.JOB_DELETE: "Sending to Trash",
|
app.JOB_DELETE: "Sending to Trash",
|
||||||
}
|
}
|
||||||
|
|
||||||
def demo_method(method):
|
|
||||||
def wrapper(self, *args, **kwargs):
|
|
||||||
try:
|
|
||||||
return method(self, *args, **kwargs)
|
|
||||||
except RegistrationRequired:
|
|
||||||
NSNotificationCenter.defaultCenter().postNotificationName_object_('RegistrationRequired', self)
|
|
||||||
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
class DupeGuru(app.DupeGuru):
|
class DupeGuru(app.DupeGuru):
|
||||||
def __init__(self, data_module, appdata_subdir, appid):
|
def __init__(self, data_module, appdata_subdir):
|
||||||
LOGGING_LEVEL = logging.DEBUG if NSUserDefaults.standardUserDefaults().boolForKey_('debug') else logging.WARNING
|
LOGGING_LEVEL = logging.DEBUG if NSUserDefaults.standardUserDefaults().boolForKey_('debug') else logging.WARNING
|
||||||
logging.basicConfig(level=LOGGING_LEVEL, format='%(levelname)s %(message)s')
|
logging.basicConfig(level=LOGGING_LEVEL, format='%(levelname)s %(message)s')
|
||||||
logging.debug('started in debug mode')
|
logging.debug('started in debug mode')
|
||||||
install_exception_hook()
|
install_exception_hook()
|
||||||
appsupport = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, True)[0]
|
appsupport = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, True)[0]
|
||||||
appdata = op.join(appsupport, appdata_subdir)
|
appdata = op.join(appsupport, appdata_subdir)
|
||||||
app.DupeGuru.__init__(self, data_module, appdata, appid)
|
app.DupeGuru.__init__(self, data_module, appdata)
|
||||||
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_(str(path))
|
||||||
from AppKit import NSWorkspace, NSWorkspaceRecycleOperation
|
|
||||||
directory = unicode(dupe.path[:-1])
|
|
||||||
filename = dupe.name
|
|
||||||
if objc.__version__ == '1.4': # For a while, we have to support this.
|
|
||||||
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):
|
@staticmethod
|
||||||
|
def _reveal_path(path):
|
||||||
|
NSWorkspace.sharedWorkspace().selectFile_inFileViewerRootedAtPath_(str(path), '')
|
||||||
|
|
||||||
|
def _start_job(self, jobid, func, *args):
|
||||||
try:
|
try:
|
||||||
j = self.progress.create_job()
|
j = self.progress.create_job()
|
||||||
self.progress.run_threaded(func, args=(j, ))
|
args = tuple([j] + list(args))
|
||||||
|
self.progress.run_threaded(func, args=args)
|
||||||
except job.JobInProgressError:
|
except job.JobInProgressError:
|
||||||
NSNotificationCenter.defaultCenter().postNotificationName_object_('JobInProgress', self)
|
NSNotificationCenter.defaultCenter().postNotificationName_object_('JobInProgress', self)
|
||||||
else:
|
else:
|
||||||
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)
|
|
||||||
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
|
||||||
except app.NoScannableFileError:
|
except app.NoScannableFileError:
|
||||||
return 3
|
return 3
|
||||||
except app.AllFilesAreRefError:
|
|
||||||
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]
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
241
core/app_cocoa_inter.py
Normal file
241
core/app_cocoa_inter.py
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
# -*- 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 "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
|
||||||
|
|
||||||
|
# Common interface for all editions' dg_cocoa unit.
|
||||||
|
|
||||||
|
from hscommon.cocoa.inter import signature, PyTable, PyOutline, PyGUIObject, PyFairware
|
||||||
|
|
||||||
|
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_table import ResultTable
|
||||||
|
from .gui.stats_label import StatsLabel
|
||||||
|
|
||||||
|
# Fix py2app's problems on relative imports
|
||||||
|
from core import app, app_cocoa, data, directories, engine, export, ignore, results, fs, scanner
|
||||||
|
from hsutil import conflict
|
||||||
|
|
||||||
|
class PyDupeGuruBase(PyFairware):
|
||||||
|
#---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 loadResultsFrom_(self, filename):
|
||||||
|
self.py.load_from(filename)
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
def saveResultsAs_(self, filename):
|
||||||
|
self.py.save_as(filename)
|
||||||
|
|
||||||
|
#---Actions
|
||||||
|
def addSelectedToIgnoreList(self):
|
||||||
|
self.py.add_selected_to_ignore_list()
|
||||||
|
|
||||||
|
def deleteMarked(self):
|
||||||
|
self.py.delete_marked()
|
||||||
|
|
||||||
|
def hardlinkMarked(self):
|
||||||
|
self.py.delete_marked(replace_with_hardlinks=True)
|
||||||
|
|
||||||
|
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
|
||||||
|
@signature('v@:c')
|
||||||
|
def setMixFileKind_(self, mix_file_kind):
|
||||||
|
self.py.scanner.mix_file_kind = mix_file_kind
|
||||||
|
|
||||||
|
@signature('v@:c')
|
||||||
|
def setEscapeFilterRegexp_(self, escape_filter_regexp):
|
||||||
|
self.py.options['escape_filter_regexp'] = escape_filter_regexp
|
||||||
|
|
||||||
|
@signature('v@:c')
|
||||||
|
def setRemoveEmptyFolders_(self, remove_empty_folders):
|
||||||
|
self.py.options['clean_empty_dirs'] = remove_empty_folders
|
||||||
|
|
||||||
|
@signature('v@:c')
|
||||||
|
def setIgnoreHardlinkMatches_(self, ignore_hardlink_matches):
|
||||||
|
self.py.options['ignore_hardlink_matches'] = ignore_hardlink_matches
|
||||||
|
|
||||||
|
#---Worker
|
||||||
|
def getJobProgress(self):
|
||||||
|
try:
|
||||||
|
return self.py.progress.last_progress
|
||||||
|
except AttributeError:
|
||||||
|
# I have *no idea* why this can possible happen (last_progress is always set by
|
||||||
|
# create_job() *before* any threaded job notification, which shows the progress panel,
|
||||||
|
# is sent), but it happens anyway, so there we go. ref: #106
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def getJobDesc(self):
|
||||||
|
try:
|
||||||
|
return self.py.progress.last_desc
|
||||||
|
except AttributeError:
|
||||||
|
# see getJobProgress
|
||||||
|
return ''
|
||||||
|
|
||||||
|
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 PyResultTable(PyTable):
|
||||||
|
py_class = ResultTable
|
||||||
|
|
||||||
|
@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('@@:ii')
|
||||||
|
def valueForRow_column_(self, row_index, column):
|
||||||
|
return self.py.get_row_value(row_index, 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()
|
||||||
|
|
||||||
|
@signature('i@:')
|
||||||
|
def selectedDupeCount(self):
|
||||||
|
return self.py.selected_dupe_count
|
||||||
|
|
||||||
|
# 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
|
||||||
@@ -2,16 +2,16 @@
|
|||||||
# Created On: 2006/03/15
|
# Created On: 2006/03/15
|
||||||
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
#
|
#
|
||||||
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
# 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
|
# 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/bsd_license
|
||||||
|
|
||||||
from hsutil.str import format_time, FT_DECIMAL, format_size
|
from hsutil.str import format_time, FT_DECIMAL, format_size
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
def format_path(p):
|
def format_path(p):
|
||||||
return unicode(p[:-1])
|
return str(p[:-1])
|
||||||
|
|
||||||
def format_timestamp(t, delta):
|
def format_timestamp(t, delta):
|
||||||
if delta:
|
if delta:
|
||||||
@@ -38,4 +38,4 @@ def format_dupe_count(c):
|
|||||||
return str(c) if c else '---'
|
return str(c) if c else '---'
|
||||||
|
|
||||||
def cmp_value(value):
|
def cmp_value(value):
|
||||||
return value.lower() if isinstance(value, basestring) else value
|
return value.lower() if isinstance(value, str) else value
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
# Created On: 2006/02/27
|
# Created On: 2006/02/27
|
||||||
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
#
|
#
|
||||||
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
# 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
|
# 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/bsd_license
|
||||||
|
|
||||||
import xml.dom.minidom
|
from xml.etree import ElementTree as ET
|
||||||
|
|
||||||
from hsutil import io
|
from hsutil import io
|
||||||
from hsutil.files import FileOrPath
|
from hsutil.files import FileOrPath
|
||||||
@@ -124,40 +124,47 @@ class Directories(object):
|
|||||||
else:
|
else:
|
||||||
return STATE_NORMAL
|
return STATE_NORMAL
|
||||||
|
|
||||||
|
def has_any_file(self):
|
||||||
|
try:
|
||||||
|
next(self.get_files())
|
||||||
|
return True
|
||||||
|
except StopIteration:
|
||||||
|
return False
|
||||||
|
|
||||||
def load_from_file(self, infile):
|
def load_from_file(self, infile):
|
||||||
try:
|
try:
|
||||||
doc = xml.dom.minidom.parse(infile)
|
root = ET.parse(infile).getroot()
|
||||||
except:
|
except Exception:
|
||||||
return
|
return
|
||||||
root_path_nodes = doc.getElementsByTagName('root_directory')
|
for rdn in root.getiterator('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.getiterator('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 = ET.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 = ET.SubElement(root, 'root_directory')
|
||||||
root_path_node.setAttribute('path', unicode(root_path).encode('utf-8'))
|
root_path_node.set('path', str(root_path))
|
||||||
for path, state in self.states.iteritems():
|
for path, state in self.states.items():
|
||||||
state_node = root.appendChild(doc.createElement('state'))
|
state_node = ET.SubElement(root, 'state')
|
||||||
state_node.setAttribute('path', unicode(path).encode('utf-8'))
|
state_node.set('path', str(path))
|
||||||
state_node.setAttribute('value', str(state))
|
state_node.set('value', str(state))
|
||||||
doc.writexml(fp, '\t', '\t', '\n', encoding='utf-8')
|
tree = ET.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:
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
# Created On: 2006/01/29
|
# Created On: 2006/01/29
|
||||||
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
#
|
#
|
||||||
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
# 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
|
# 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/bsd_license
|
||||||
|
|
||||||
|
|
||||||
from __future__ import division
|
|
||||||
import difflib
|
import difflib
|
||||||
import itertools
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
@@ -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 jobprogress import job
|
||||||
|
|
||||||
(WEIGHT_WORDS,
|
(WEIGHT_WORDS,
|
||||||
MATCH_SIMILAR_WORDS,
|
MATCH_SIMILAR_WORDS,
|
||||||
@@ -25,15 +25,15 @@ NO_FIELD_ORDER) = range(3)
|
|||||||
JOB_REFRESH_RATE = 100
|
JOB_REFRESH_RATE = 100
|
||||||
|
|
||||||
def getwords(s):
|
def getwords(s):
|
||||||
if isinstance(s, unicode):
|
if isinstance(s, str):
|
||||||
s = normalize('NFD', s)
|
s = normalize('NFD', s)
|
||||||
s = multi_replace(s, "-_&+():;\\[]{}.,<>/?~!@#$*", ' ').lower()
|
s = multi_replace(s, "-_&+():;\\[]{}.,<>/?~!@#$*", ' ').lower()
|
||||||
s = ''.join(c for c in s if c in string.ascii_letters + string.digits + string.whitespace)
|
s = ''.join(c for c in s if c in string.ascii_letters + string.digits + string.whitespace)
|
||||||
return filter(None, s.split(' ')) # filter() is to remove empty elements
|
return [_f for _f in s.split(' ') if _f] # remove empty elements
|
||||||
|
|
||||||
def getfields(s):
|
def getfields(s):
|
||||||
fields = [getwords(field) for field in s.split(' - ')]
|
fields = [getwords(field) for field in s.split(' - ')]
|
||||||
return filter(None, fields)
|
return [_f for _f in fields if _f]
|
||||||
|
|
||||||
def unpack_fields(fields):
|
def unpack_fields(fields):
|
||||||
result = []
|
result = []
|
||||||
@@ -118,7 +118,7 @@ def build_word_dict(objects, j=job.nulljob):
|
|||||||
def merge_similar_words(word_dict):
|
def merge_similar_words(word_dict):
|
||||||
"""Take all keys in word_dict that are similar, and merge them together.
|
"""Take all keys in word_dict that are similar, and merge them together.
|
||||||
"""
|
"""
|
||||||
keys = word_dict.keys()
|
keys = list(word_dict.keys())
|
||||||
keys.sort(key=len)# we want the shortest word to stay
|
keys.sort(key=len)# we want the shortest word to stay
|
||||||
while keys:
|
while keys:
|
||||||
key = keys.pop(0)
|
key = keys.pop(0)
|
||||||
@@ -138,7 +138,7 @@ def reduce_common_words(word_dict, threshold):
|
|||||||
Because if we remove them, we will miss some duplicates!
|
Because if we remove them, we will miss some duplicates!
|
||||||
"""
|
"""
|
||||||
uncommon_words = set(word for word, objects in word_dict.items() if len(objects) < threshold)
|
uncommon_words = set(word for word, objects in word_dict.items() if len(objects) < threshold)
|
||||||
for word, objects in word_dict.items():
|
for word, objects in list(word_dict.items()):
|
||||||
if len(objects) < threshold:
|
if len(objects) < threshold:
|
||||||
continue
|
continue
|
||||||
reduced = set()
|
reduced = set()
|
||||||
|
|||||||
@@ -2,18 +2,17 @@
|
|||||||
# Created On: 2006/09/16
|
# Created On: 2006/09/16
|
||||||
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
#
|
#
|
||||||
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
# 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
|
# 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/bsd_license
|
||||||
|
|
||||||
import tempfile
|
|
||||||
import os.path as op
|
import os.path as op
|
||||||
from tempfile import mkdtemp
|
from tempfile import mkdtemp
|
||||||
|
|
||||||
# Yes, this is a very low-tech solution, but at least it doesn't have all these annoying dependency
|
# Yes, this is a very low-tech solution, but at least it doesn't have all these annoying dependency
|
||||||
# and resource problems.
|
# and resource problems.
|
||||||
|
|
||||||
MAIN_TEMPLATE = u"""
|
MAIN_TEMPLATE = """
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
|
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
@@ -104,34 +103,34 @@ $rows
|
|||||||
</html>
|
</html>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
COLHEADERS_TEMPLATE = u"<th>{name}</th>"
|
COLHEADERS_TEMPLATE = "<th>{name}</th>"
|
||||||
|
|
||||||
ROW_TEMPLATE = u"""
|
ROW_TEMPLATE = """
|
||||||
<tr>
|
<tr>
|
||||||
<td class="{indented}">{filename}</td>{cells}
|
<td class="{indented}">{filename}</td>{cells}
|
||||||
</tr>
|
</tr>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
CELL_TEMPLATE = u"""<td>{value}</td>"""
|
CELL_TEMPLATE = """<td>{value}</td>"""
|
||||||
|
|
||||||
def export_to_xhtml(colnames, rows):
|
def export_to_xhtml(colnames, rows):
|
||||||
# a row is a list of values with the first value being a flag indicating if the row should be indented
|
# a row is a list of values with the first value being a flag indicating if the row should be indented
|
||||||
if rows:
|
if rows:
|
||||||
assert len(rows[0]) == len(colnames) + 1 # + 1 is for the "indented" flag
|
assert len(rows[0]) == len(colnames) + 1 # + 1 is for the "indented" flag
|
||||||
colheaders = u''.join(COLHEADERS_TEMPLATE.format(name=name) for name in colnames)
|
colheaders = ''.join(COLHEADERS_TEMPLATE.format(name=name) for name in colnames)
|
||||||
rendered_rows = []
|
rendered_rows = []
|
||||||
for row in rows:
|
for row in rows:
|
||||||
# [2:] is to remove the indented flag + filename
|
# [2:] is to remove the indented flag + filename
|
||||||
indented = u'indented' if row[0] else u''
|
indented = 'indented' if row[0] else ''
|
||||||
filename = row[1]
|
filename = row[1]
|
||||||
cells = u''.join(CELL_TEMPLATE.format(value=value) for value in row[2:])
|
cells = ''.join(CELL_TEMPLATE.format(value=value) for value in row[2:])
|
||||||
rendered_rows.append(ROW_TEMPLATE.format(indented=indented, filename=filename, cells=cells))
|
rendered_rows.append(ROW_TEMPLATE.format(indented=indented, filename=filename, cells=cells))
|
||||||
rendered_rows = u''.join(rendered_rows)
|
rendered_rows = ''.join(rendered_rows)
|
||||||
# The main template can't use format because the css code uses {}
|
# The main template can't use format because the css code uses {}
|
||||||
content = MAIN_TEMPLATE.replace('$colheaders', colheaders).replace('$rows', rendered_rows)
|
content = MAIN_TEMPLATE.replace('$colheaders', colheaders).replace('$rows', rendered_rows)
|
||||||
folder = mkdtemp()
|
folder = mkdtemp()
|
||||||
destpath = op.join(folder, u'export.htm')
|
destpath = op.join(folder, 'export.htm')
|
||||||
fp = open(destpath, 'w')
|
fp = open(destpath, 'wt', encoding='utf-8')
|
||||||
fp.write(content.encode('utf-8'))
|
fp.write(content)
|
||||||
fp.close()
|
fp.close()
|
||||||
return destpath
|
return destpath
|
||||||
|
|||||||
26
core/fs.py
26
core/fs.py
@@ -3,16 +3,16 @@
|
|||||||
# Created On: 2009-10-22
|
# Created On: 2009-10-22
|
||||||
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
#
|
#
|
||||||
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
# 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
|
# 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/bsd_license
|
||||||
|
|
||||||
# This is a fork from hsfs. The reason for this fork is that hsfs has been designed for musicGuru
|
# This is a fork from hsfs. The reason for this fork is that hsfs has been designed for musicGuru
|
||||||
# and was re-used for dupeGuru. The problem is that hsfs is way over-engineered for dupeGuru,
|
# and was re-used for dupeGuru. The problem is that hsfs is way over-engineered for dupeGuru,
|
||||||
# resulting needless complexity and memory usage. It's been a while since I wanted to do that fork,
|
# resulting needless complexity and memory usage. It's been a while since I wanted to do that fork,
|
||||||
# and I'm doing it now.
|
# and I'm doing it now.
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import logging
|
import logging
|
||||||
@@ -25,13 +25,13 @@ class FSError(Exception):
|
|||||||
cls_message = "An error has occured on '{name}' in '{parent}'"
|
cls_message = "An error has occured on '{name}' in '{parent}'"
|
||||||
def __init__(self, fsobject, parent=None):
|
def __init__(self, fsobject, parent=None):
|
||||||
message = self.cls_message
|
message = self.cls_message
|
||||||
if isinstance(fsobject, basestring):
|
if isinstance(fsobject, str):
|
||||||
name = fsobject
|
name = fsobject
|
||||||
elif isinstance(fsobject, File):
|
elif isinstance(fsobject, File):
|
||||||
name = fsobject.name
|
name = fsobject.name
|
||||||
else:
|
else:
|
||||||
name = ''
|
name = ''
|
||||||
parentname = unicode(parent) if parent is not None else ''
|
parentname = str(parent) if parent is not None else ''
|
||||||
Exception.__init__(self, message.format(name=name, parent=parentname))
|
Exception.__init__(self, message.format(name=name, parent=parentname))
|
||||||
|
|
||||||
|
|
||||||
@@ -55,7 +55,6 @@ class OperationError(FSError):
|
|||||||
class File(object):
|
class File(object):
|
||||||
INITIAL_INFO = {
|
INITIAL_INFO = {
|
||||||
'size': 0,
|
'size': 0,
|
||||||
'ctime': 0,
|
|
||||||
'mtime': 0,
|
'mtime': 0,
|
||||||
'md5': '',
|
'md5': '',
|
||||||
'md5partial': '',
|
'md5partial': '',
|
||||||
@@ -82,10 +81,9 @@ class File(object):
|
|||||||
raise AttributeError()
|
raise AttributeError()
|
||||||
|
|
||||||
def _read_info(self, field):
|
def _read_info(self, field):
|
||||||
if field in ('size', 'ctime', 'mtime'):
|
if field in ('size', 'mtime'):
|
||||||
stats = io.stat(self.path)
|
stats = io.stat(self.path)
|
||||||
self.size = nonone(stats.st_size, 0)
|
self.size = nonone(stats.st_size, 0)
|
||||||
self.ctime = nonone(stats.st_ctime, 0)
|
|
||||||
self.mtime = nonone(stats.st_mtime, 0)
|
self.mtime = nonone(stats.st_mtime, 0)
|
||||||
elif field == 'md5partial':
|
elif field == 'md5partial':
|
||||||
try:
|
try:
|
||||||
@@ -119,7 +117,7 @@ class File(object):
|
|||||||
If `attrnames` is not None, caches only attrnames.
|
If `attrnames` is not None, caches only attrnames.
|
||||||
"""
|
"""
|
||||||
if attrnames is None:
|
if attrnames is None:
|
||||||
attrnames = self.INITIAL_INFO.keys()
|
attrnames = list(self.INITIAL_INFO.keys())
|
||||||
for attrname in attrnames:
|
for attrname in attrnames:
|
||||||
if attrname not in self.__dict__:
|
if attrname not in self.__dict__:
|
||||||
self._read_info(attrname)
|
self._read_info(attrname)
|
||||||
@@ -160,8 +158,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 "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
|
||||||
|
|
||||||
|
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 "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
|
||||||
|
|
||||||
|
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 = list(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 "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
|
||||||
|
|
||||||
|
from hscommon.gui.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, str(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 "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
|
||||||
|
|
||||||
|
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')
|
||||||
|
|
||||||
42
core/gui/problem_table.py
Normal file
42
core/gui/problem_table.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# -*- 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 "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
|
||||||
|
|
||||||
|
from hscommon.notify import Listener
|
||||||
|
from hscommon.gui.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()
|
||||||
|
|
||||||
|
|
||||||
|
class ProblemRow(Row):
|
||||||
|
def __init__(self, table, dupe, msg):
|
||||||
|
Row.__init__(self, table)
|
||||||
|
self.dupe = dupe
|
||||||
|
self.msg = msg
|
||||||
|
self.path = str(dupe.path)
|
||||||
|
|
||||||
160
core/gui/result_table.py
Normal file
160
core/gui/result_table.py
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
# -*- 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 "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
|
||||||
|
|
||||||
|
from operator import attrgetter
|
||||||
|
|
||||||
|
from hscommon.gui.table import GUITable, Row
|
||||||
|
|
||||||
|
from .base import GUIObject
|
||||||
|
|
||||||
|
class DupeRow(Row):
|
||||||
|
def __init__(self, table, group, dupe):
|
||||||
|
Row.__init__(self, table)
|
||||||
|
self._app = table.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 isref(self):
|
||||||
|
return self._dupe is self._group.ref
|
||||||
|
|
||||||
|
@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 ResultTable(GUIObject, GUITable):
|
||||||
|
def __init__(self, view, app):
|
||||||
|
GUIObject.__init__(self, view, app)
|
||||||
|
GUITable.__init__(self)
|
||||||
|
self._power_marker = False
|
||||||
|
self._delta_values = False
|
||||||
|
self._sort_descriptors = (0, True)
|
||||||
|
|
||||||
|
#--- Override
|
||||||
|
def connect(self):
|
||||||
|
GUIObject.connect(self)
|
||||||
|
self._refresh_with_view()
|
||||||
|
|
||||||
|
def _restore_selection(self, previous_selection):
|
||||||
|
if self.app.selected_dupes:
|
||||||
|
to_find = set(self.app.selected_dupes)
|
||||||
|
indexes = [i for i, r in enumerate(self) if r._dupe in to_find]
|
||||||
|
self.selected_indexes = indexes
|
||||||
|
|
||||||
|
def _update_selection(self):
|
||||||
|
rows = self.selected_rows
|
||||||
|
self.app._select_dupes(list(map(attrgetter('_dupe'), rows)))
|
||||||
|
|
||||||
|
def _fill(self):
|
||||||
|
if not self.power_marker:
|
||||||
|
for group in self.app.results.groups:
|
||||||
|
self.append(DupeRow(self, group, group.ref))
|
||||||
|
for dupe in group.dupes:
|
||||||
|
self.append(DupeRow(self, group, dupe))
|
||||||
|
else:
|
||||||
|
for dupe in self.app.results.dupes:
|
||||||
|
group = self.app.results.get_group_of_duplicate(dupe)
|
||||||
|
self.append(DupeRow(self, group, dupe))
|
||||||
|
|
||||||
|
def _refresh_with_view(self):
|
||||||
|
self.refresh()
|
||||||
|
self.view.show_selected_row()
|
||||||
|
|
||||||
|
#--- Public
|
||||||
|
def get_row_value(self, index, column):
|
||||||
|
try:
|
||||||
|
row = self[index]
|
||||||
|
except IndexError:
|
||||||
|
return '---'
|
||||||
|
if self.delta_values:
|
||||||
|
return row.data_delta[column]
|
||||||
|
else:
|
||||||
|
return row.data[column]
|
||||||
|
|
||||||
|
def rename_selected(self, newname):
|
||||||
|
row = self.selected_row
|
||||||
|
row._data = None
|
||||||
|
row._data_delta = None
|
||||||
|
return self.app.rename_selected(newname)
|
||||||
|
|
||||||
|
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_with_view()
|
||||||
|
|
||||||
|
#--- 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)
|
||||||
|
# no need to refresh, it has happened in sort()
|
||||||
|
|
||||||
|
@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()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def selected_dupe_count(self):
|
||||||
|
return sum(1 for row in self.selected_rows if not row.isref)
|
||||||
|
|
||||||
|
#--- Event Handlers
|
||||||
|
def marking_changed(self):
|
||||||
|
self.view.invalidate_markings()
|
||||||
|
|
||||||
|
def results_changed(self):
|
||||||
|
self._refresh_with_view()
|
||||||
|
|
||||||
|
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*.
|
||||||
|
indexes = self.selected_indexes
|
||||||
|
self.refresh(refresh_view=False)
|
||||||
|
self.select(indexes)
|
||||||
|
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 "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
|
||||||
|
|
||||||
|
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
|
||||||
@@ -2,14 +2,14 @@
|
|||||||
# Created On: 2006/05/02
|
# Created On: 2006/05/02
|
||||||
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
#
|
#
|
||||||
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
# 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
|
# 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/bsd_license
|
||||||
|
|
||||||
|
from xml.etree import ElementTree as ET
|
||||||
|
|
||||||
from hsutil.files import FileOrPath
|
from hsutil.files import FileOrPath
|
||||||
|
|
||||||
import xml.dom.minidom
|
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ class IgnoreList(object):
|
|||||||
self._count = 0
|
self._count = 0
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
for first,seconds in self._ignored.iteritems():
|
for first,seconds in self._ignored.items():
|
||||||
for second in seconds:
|
for second in seconds:
|
||||||
yield (first,second)
|
yield (first,second)
|
||||||
|
|
||||||
@@ -71,45 +71,40 @@ 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 = ET.parse(infile).getroot()
|
||||||
except Exception:
|
except Exception:
|
||||||
return
|
return
|
||||||
file_nodes = doc.getElementsByTagName('file')
|
file_elems = (e for e in root if e.tag == 'file')
|
||||||
for fn in file_nodes:
|
for fn in file_elems:
|
||||||
if not fn.getAttributeNode('path'):
|
file_path = fn.get('path')
|
||||||
|
if not file_path:
|
||||||
continue
|
continue
|
||||||
file_path = fn.getAttributeNode('path').nodeValue
|
subfile_elems = (e for e in fn if e.tag == 'file')
|
||||||
subfile_nodes = fn.getElementsByTagName('file')
|
for sfn in subfile_elems:
|
||||||
for sfn in subfile_nodes:
|
subfile_path = sfn.get('path')
|
||||||
if not sfn.getAttributeNode('path'):
|
if subfile_path:
|
||||||
continue
|
self.Ignore(file_path, subfile_path)
|
||||||
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 = ET.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 = ET.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 = ET.SubElement(file_node, 'file')
|
||||||
file_node.setAttribute('path',file)
|
subfile_node.set('path', subfilename)
|
||||||
for subfile in subfiles:
|
tree = ET.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')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
225
core/results.py
225
core/results.py
@@ -2,22 +2,20 @@
|
|||||||
# Created On: 2006/02/23
|
# Created On: 2006/02/23
|
||||||
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
#
|
#
|
||||||
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
# 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
|
# 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/bsd_license
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
from xml.sax import handler, make_parser, SAXException
|
from xml.etree import ElementTree as ET
|
||||||
from xml.sax.saxutils import XMLGenerator
|
|
||||||
from xml.sax.xmlreader import AttributesImpl
|
|
||||||
|
|
||||||
from . import engine
|
from . import engine
|
||||||
from hsutil.job import nulljob
|
from jobprogress.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,8 @@ 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)
|
||||||
|
self.is_modified = False
|
||||||
|
|
||||||
def _did_mark(self, dupe):
|
def _did_mark(self, dupe):
|
||||||
self.__marked_size += dupe.size
|
self.__marked_size += dupe.size
|
||||||
@@ -116,6 +116,7 @@ class Results(Markable):
|
|||||||
self.__group_of_duplicate[dupe] = g
|
self.__group_of_duplicate[dupe] = g
|
||||||
if not hasattr(dupe, 'is_ref'):
|
if not hasattr(dupe, 'is_ref'):
|
||||||
dupe.is_ref = False
|
dupe.is_ref = False
|
||||||
|
self.is_modified = True
|
||||||
old_filters = nonone(self.__filters, [])
|
old_filters = nonone(self.__filters, [])
|
||||||
self.apply_filter(None)
|
self.apply_filter(None)
|
||||||
for filter_str in old_filters:
|
for filter_str in old_filters:
|
||||||
@@ -148,7 +149,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(str(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,43 +169,56 @@ 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 = ET.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.getiterator('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.getiterator('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.getiterator('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)
|
||||||
|
self.is_modified = False
|
||||||
|
|
||||||
def make_ref(self, dupe):
|
def make_ref(self, dupe):
|
||||||
g = self.get_group_of_duplicate(dupe)
|
g = self.get_group_of_duplicate(dupe)
|
||||||
@@ -218,19 +232,25 @@ class Results(Markable):
|
|||||||
self.__total_count -= 1
|
self.__total_count -= 1
|
||||||
self.__total_size -= dupe.size
|
self.__total_size -= dupe.size
|
||||||
self.__dupes = None
|
self.__dupes = None
|
||||||
|
self.is_modified = True
|
||||||
|
|
||||||
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, str(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.
|
||||||
@@ -253,16 +273,14 @@ class Results(Markable):
|
|||||||
for group in affected_groups:
|
for group in affected_groups:
|
||||||
group.discard_matches()
|
group.discard_matches()
|
||||||
self.__dupes = None
|
self.__dupes = None
|
||||||
|
self.is_modified = True
|
||||||
|
|
||||||
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 = ET.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 = ET.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 +288,23 @@ 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 = ET.SubElement(group_elem, 'file')
|
||||||
'path': unicode(d.path),
|
try:
|
||||||
'is_ref': cond(d.is_ref, 'y', 'n'),
|
file_elem.set('path', str(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 = ET.SubElement(group_elem, 'match')
|
||||||
'first': str(dupe2index[match.first]),
|
match_elem.set('first', str(dupe2index[match.first]))
|
||||||
'second': str(dupe2index[match.second]),
|
match_elem.set('second', str(dupe2index[match.second]))
|
||||||
'percentage': str(int(match.percentage)),
|
match_elem.set('percentage', str(int(match.percentage)))
|
||||||
})
|
tree = ET.ElementTree(root)
|
||||||
writer.startElement('match', attrs)
|
with FileOrPath(outfile, 'wb') as fp:
|
||||||
writer.endElement('match')
|
tree.write(fp, encoding='utf-8')
|
||||||
writer.endElement('group')
|
self.is_modified = False
|
||||||
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 +324,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)
|
|
||||||
|
|
||||||
|
|||||||
231
core/scanner.py
231
core/scanner.py
@@ -1,108 +1,123 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2006/03/03
|
# Created On: 2006/03/03
|
||||||
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||||
#
|
#
|
||||||
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
# 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
|
# 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/bsd_license
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
|
|
||||||
from hsutil import job, io
|
from jobprogress import job
|
||||||
from hsutil.misc import dedupe
|
from hsutil import io
|
||||||
from hsutil.str import get_file_ext, rem_file_ext
|
from hsutil.misc import dedupe
|
||||||
|
from hsutil.str import get_file_ext, rem_file_ext
|
||||||
from . import engine
|
|
||||||
from .ignore import IgnoreList
|
from . import engine
|
||||||
|
from .ignore import IgnoreList
|
||||||
(SCAN_TYPE_FILENAME,
|
|
||||||
SCAN_TYPE_FIELDS,
|
class ScanType:
|
||||||
SCAN_TYPE_FIELDS_NO_ORDER,
|
Filename = 0
|
||||||
SCAN_TYPE_TAG,
|
Fields = 1
|
||||||
UNUSED, # Must not be removed. Constants here are what scan_type in the prefs are.
|
FieldsNoOrder = 2
|
||||||
SCAN_TYPE_CONTENT,
|
Tag = 3
|
||||||
SCAN_TYPE_CONTENT_AUDIO) = range(7)
|
# number 4 is obsolete
|
||||||
|
Contents = 5
|
||||||
SCANNABLE_TAGS = ['track', 'artist', 'album', 'title', 'genre', 'year']
|
ContentsAudio = 6
|
||||||
|
|
||||||
class Scanner(object):
|
SCANNABLE_TAGS = ['track', 'artist', 'album', 'title', 'genre', 'year']
|
||||||
def __init__(self):
|
|
||||||
self.ignore_list = IgnoreList()
|
RE_DIGIT_ENDING = re.compile(r'\d+|\(\d+\)|\[\d+\]|{\d+}')
|
||||||
self.discarded_file_count = 0
|
|
||||||
|
def is_same_with_digit(name, refname):
|
||||||
def _getmatches(self, files, j):
|
# Returns True if name is the same as refname, but with digits (with brackets or not) at the end
|
||||||
if self.size_threshold:
|
if not name.startswith(refname):
|
||||||
j = j.start_subjob([2, 8])
|
return False
|
||||||
for f in j.iter_with_progress(files, 'Read size of %d/%d files'):
|
end = name[len(refname):].strip()
|
||||||
f.size # pre-read, makes a smoother progress if read here (especially for bundles)
|
return RE_DIGIT_ENDING.match(end) is not None
|
||||||
files = [f for f in files if f.size >= self.size_threshold]
|
|
||||||
if self.scan_type in (SCAN_TYPE_CONTENT, SCAN_TYPE_CONTENT_AUDIO):
|
class Scanner(object):
|
||||||
sizeattr = 'size' if self.scan_type == SCAN_TYPE_CONTENT else 'audiosize'
|
def __init__(self):
|
||||||
return engine.getmatches_by_contents(files, sizeattr, partial=self.scan_type==SCAN_TYPE_CONTENT_AUDIO, j=j)
|
self.ignore_list = IgnoreList()
|
||||||
else:
|
self.discarded_file_count = 0
|
||||||
j = j.start_subjob([2, 8])
|
|
||||||
kw = {}
|
def _getmatches(self, files, j):
|
||||||
kw['match_similar_words'] = self.match_similar_words
|
if self.size_threshold:
|
||||||
kw['weight_words'] = self.word_weighting
|
j = j.start_subjob([2, 8])
|
||||||
kw['min_match_percentage'] = self.min_match_percentage
|
for f in j.iter_with_progress(files, 'Read size of %d/%d files'):
|
||||||
if self.scan_type == SCAN_TYPE_FIELDS_NO_ORDER:
|
f.size # pre-read, makes a smoother progress if read here (especially for bundles)
|
||||||
self.scan_type = SCAN_TYPE_FIELDS
|
files = [f for f in files if f.size >= self.size_threshold]
|
||||||
kw['no_field_order'] = True
|
if self.scan_type in (ScanType.Contents, ScanType.ContentsAudio):
|
||||||
func = {
|
sizeattr = 'size' if self.scan_type == ScanType.Contents else 'audiosize'
|
||||||
SCAN_TYPE_FILENAME: lambda f: engine.getwords(rem_file_ext(f.name)),
|
return engine.getmatches_by_contents(files, sizeattr, partial=self.scan_type==ScanType.ContentsAudio, j=j)
|
||||||
SCAN_TYPE_FIELDS: lambda f: engine.getfields(rem_file_ext(f.name)),
|
else:
|
||||||
SCAN_TYPE_TAG: lambda f: [engine.getwords(unicode(getattr(f, attrname))) for attrname in SCANNABLE_TAGS if attrname in self.scanned_tags],
|
j = j.start_subjob([2, 8])
|
||||||
}[self.scan_type]
|
kw = {}
|
||||||
for f in j.iter_with_progress(files, 'Read metadata of %d/%d files'):
|
kw['match_similar_words'] = self.match_similar_words
|
||||||
f.words = func(f)
|
kw['weight_words'] = self.word_weighting
|
||||||
return engine.getmatches(files, j=j, **kw)
|
kw['min_match_percentage'] = self.min_match_percentage
|
||||||
|
if self.scan_type == ScanType.FieldsNoOrder:
|
||||||
@staticmethod
|
self.scan_type = ScanType.Fields
|
||||||
def _key_func(dupe):
|
kw['no_field_order'] = True
|
||||||
return (not dupe.is_ref, -dupe.size)
|
func = {
|
||||||
|
ScanType.Filename: lambda f: engine.getwords(rem_file_ext(f.name)),
|
||||||
@staticmethod
|
ScanType.Fields: lambda f: engine.getfields(rem_file_ext(f.name)),
|
||||||
def _tie_breaker(ref, dupe):
|
ScanType.Tag: lambda f: [engine.getwords(str(getattr(f, attrname))) for attrname in SCANNABLE_TAGS if attrname in self.scanned_tags],
|
||||||
refname = rem_file_ext(ref.name).lower()
|
}[self.scan_type]
|
||||||
dupename = rem_file_ext(dupe.name).lower()
|
for f in j.iter_with_progress(files, 'Read metadata of %d/%d files'):
|
||||||
if 'copy' in refname and 'copy' not in dupename:
|
f.words = func(f)
|
||||||
return True
|
return engine.getmatches(files, j=j, **kw)
|
||||||
if refname.startswith(dupename) and (refname[len(dupename):].strip().isdigit()):
|
|
||||||
return True
|
@staticmethod
|
||||||
return len(dupe.path) > len(ref.path)
|
def _key_func(dupe):
|
||||||
|
return (not dupe.is_ref, -dupe.size)
|
||||||
def GetDupeGroups(self, files, j=job.nulljob):
|
|
||||||
j = j.start_subjob([8, 2])
|
@staticmethod
|
||||||
for f in [f for f in files if not hasattr(f, 'is_ref')]:
|
def _tie_breaker(ref, dupe):
|
||||||
f.is_ref = False
|
refname = rem_file_ext(ref.name).lower()
|
||||||
logging.info('Getting matches')
|
dupename = rem_file_ext(dupe.name).lower()
|
||||||
matches = self._getmatches(files, j)
|
if 'copy' in dupename:
|
||||||
logging.info('Found %d matches' % len(matches))
|
return False
|
||||||
j.set_progress(100, 'Removing false matches')
|
if 'copy' in refname:
|
||||||
if not self.mix_file_kind:
|
return True
|
||||||
matches = [m for m in matches if get_file_ext(m.first.name) == get_file_ext(m.second.name)]
|
if is_same_with_digit(dupename, refname):
|
||||||
matches = [m for m in matches if io.exists(m.first.path) and io.exists(m.second.path)]
|
return False
|
||||||
if self.ignore_list:
|
if is_same_with_digit(refname, dupename):
|
||||||
j = j.start_subjob(2)
|
return True
|
||||||
iter_matches = j.iter_with_progress(matches, 'Processed %d/%d matches against the ignore list')
|
return len(dupe.path) > len(ref.path)
|
||||||
matches = [m for m in iter_matches
|
|
||||||
if not self.ignore_list.AreIgnored(unicode(m.first.path), unicode(m.second.path))]
|
def GetDupeGroups(self, files, j=job.nulljob):
|
||||||
logging.info('Grouping matches')
|
j = j.start_subjob([8, 2])
|
||||||
groups = engine.get_groups(matches, j)
|
for f in [f for f in files if not hasattr(f, 'is_ref')]:
|
||||||
matched_files = dedupe([m.first for m in matches] + [m.second for m in matches])
|
f.is_ref = False
|
||||||
self.discarded_file_count = len(matched_files) - sum(len(g) for g in groups)
|
logging.info('Getting matches')
|
||||||
groups = [g for g in groups if any(not f.is_ref for f in g)]
|
matches = self._getmatches(files, j)
|
||||||
logging.info('Created %d groups' % len(groups))
|
logging.info('Found %d matches' % len(matches))
|
||||||
j.set_progress(100, 'Doing group prioritization')
|
j.set_progress(100, 'Removing false matches')
|
||||||
for g in groups:
|
if not self.mix_file_kind:
|
||||||
g.prioritize(self._key_func, self._tie_breaker)
|
matches = [m for m in matches if get_file_ext(m.first.name) == get_file_ext(m.second.name)]
|
||||||
return groups
|
matches = [m for m in matches if io.exists(m.first.path) and io.exists(m.second.path)]
|
||||||
|
if self.ignore_list:
|
||||||
match_similar_words = False
|
j = j.start_subjob(2)
|
||||||
min_match_percentage = 80
|
iter_matches = j.iter_with_progress(matches, 'Processed %d/%d matches against the ignore list')
|
||||||
mix_file_kind = True
|
matches = [m for m in iter_matches
|
||||||
scan_type = SCAN_TYPE_FILENAME
|
if not self.ignore_list.AreIgnored(str(m.first.path), str(m.second.path))]
|
||||||
scanned_tags = set(['artist', 'title'])
|
logging.info('Grouping matches')
|
||||||
size_threshold = 0
|
groups = engine.get_groups(matches, j)
|
||||||
word_weighting = False
|
matched_files = dedupe([m.first for m in matches] + [m.second for m in matches])
|
||||||
|
self.discarded_file_count = len(matched_files) - sum(len(g) for g in groups)
|
||||||
|
groups = [g for g in groups if any(not f.is_ref for f in g)]
|
||||||
|
logging.info('Created %d groups' % len(groups))
|
||||||
|
j.set_progress(100, 'Doing group prioritization')
|
||||||
|
for g in groups:
|
||||||
|
g.prioritize(self._key_func, self._tie_breaker)
|
||||||
|
return groups
|
||||||
|
|
||||||
|
match_similar_words = False
|
||||||
|
min_match_percentage = 80
|
||||||
|
mix_file_kind = True
|
||||||
|
scan_type = ScanType.Filename
|
||||||
|
scanned_tags = set(['artist', 'title'])
|
||||||
|
size_threshold = 0
|
||||||
|
word_weighting = False
|
||||||
|
|||||||
@@ -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')
|
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user