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

Compare commits

...

23 Commits

Author SHA1 Message Date
Virgil Dupras
b2ff02c773 Added missing entry in 3.0.2 changelog. 2011-03-16 14:38:17 +01:00
Virgil Dupras
2c242aedfd se v3.0.2 2011-03-16 14:36:46 +01:00
Virgil Dupras
70e4e6f5af Depend specifically on python 3.1 in deb packages instead of depending on python3 because PyQt modules are not binary compatiable with python 3.2 2011-03-16 04:07:22 -07:00
Virgil Dupras
ebeb068042 Removed an old workaround in the Qt version that doesn't seem to be needed with the current version of Qt. 2011-03-16 08:41:29 +00:00
Virgil Dupras
731e68f164 [#153 state:fixed] Fixed a refresh bug in directory panel. 2011-03-16 09:31:16 +01:00
Virgil Dupras
fa0c3aeb78 Added tag pe2.1.0 for changeset d274bcb98f2d 2011-03-07 15:59:13 +01:00
Virgil Dupras
5a36f15667 Fixed bug causing PE progress report to be (very) wrong during matching. 2011-03-07 11:55:37 +01:00
Virgil Dupras
b96fae74b6 pe v2.1.0 2011-03-07 11:33:40 +01:00
Virgil Dupras
404743a27f Merged heads. 2011-03-06 17:25:54 +01:00
Virgil Dupras
58c8fd0f09 Updated qtlib subrepo 2011-03-06 17:25:02 +01:00
Virgil Dupras
fb3d3a135d [#148 state:fixed] Fixed a crash on copy/move when windows drive letters were involved. 2011-03-06 17:21:42 +01:00
Virgil Dupras
96bddd1995 Adjusted extra fairware reminder according to platform. 2011-03-06 03:12:16 -08:00
Virgil Dupras
6e60ea6984 Added extra Fairware reminder. We'll see if that boosts dupeGuru contributions. 2011-03-05 13:03:23 +01:00
Virgil Dupras
e410f88926 Catch a random occurrence of an exception on multiprocessing.cpu_count() so that dupeGuru doesn't crash because of that. 2011-03-05 13:02:11 +01:00
Virgil Dupras
1b52feb8b8 Optimized the scanning process in PE. 2011-03-04 11:15:04 +01:00
Virgil Dupras
ec8e915830 Updated hscommon subrepo. 2011-02-22 15:59:34 +01:00
Virgil Dupras
0bdbbbdf16 Only import pluginbuilder when building the Cocoa version. 2011-02-22 10:04:54 +01:00
Virgil Dupras
92e0647f19 Use pluginbuilder instead of py2app. 2011-02-21 11:57:37 +01:00
Virgil Dupras
69498147a2 Added tag before-pluginbuilder for changeset ff43c6d9feb3 2011-02-21 11:56:28 +01:00
Virgil Dupras
4249c528e9 [#144 state:fixed] Fixed crash on error handling under windows when sys.stderr is None. 2011-02-18 10:10:11 +00:00
Virgil Dupras
084068852e [#140 state:fixed] Fixed a crash on showing details panel in PE right after a mark-based removal (selection wasn't refreshed). 2011-02-18 10:37:40 +01:00
Virgil Dupras
c524a85897 Greatly improved iPhoto deletion process. 2011-02-17 15:08:23 +01:00
Virgil Dupras
d39d46be5a Added tag me6.0.0 for changeset 2fd901a516f8 2011-02-01 12:23:44 +01:00
40 changed files with 2601 additions and 113 deletions

View File

@@ -43,3 +43,6 @@ ca93352ce35184853ad9fcb881935a43a8b1e249 me5.10.3
8d12cab3b12b723e3a86d02cf8002731a0f73f95 se3.0.0
778876a8a9787658aa6adf6944b53aebcb7faeea se3.0.1
f1d40b556c01f32c58f9ef9f9acac5b78e01ba7a pe2.0.0
2fd901a516f8cb6b4438491f63f2ebfd52a57c13 me6.0.0
ff43c6d9feb388f103b7857eaa6f7809185f78ec before-pluginbuilder
d274bcb98f2d02b86470a04cd62e718eff33b74f pe2.1.0

18
README
View File

@@ -1,5 +1,5 @@
Contents
=====
========
This package contains the source for dupeGuru. To learn how to build it, refer to the "Build dupeGuru" section. Below is the description of the various subfolders:
@@ -19,14 +19,14 @@ with as mercurial subrepos):
- qtlib: A collection of helpers used across Qt UI codebases of HS applications.
dupeGuru Dependencies
=====
=====================
Before being able to build dupeGuru, a few dependencies have to be installed:
General dependencies
-----
--------------------
- Python 3.1 (http://www.python.org)
- Python 3.1 (3.2 on Mac OS X) (http://www.python.org)
- Send2Trash3k (http://hg.hardcoded.net/send2trash)
- hsaudiotag3k 1.1.0 (for ME) (http://hg.hardcoded.net/hsaudiotag)
- jobprogress (http://hg.hardcoded.net/jobprogress)
@@ -38,16 +38,16 @@ by the build system through command line, so you can build dupeGuru even if Sphi
your Python 2.x install.
OS X prerequisites
-----
------------------
- XCode 3.1 (http://developer.apple.com/TOOLS/xcode/)
- Sparkle (http://sparkle.andymatuschak.org/)
- PyObjC 2.3 (http://pyobjc.sourceforge.net/)
- py2app 0.5.4 (http://bitbucket.org/ronaldoussoren/py2app)
- appscript 0.22.0 for ME and PE (http://appscript.sourceforge.net/)
- pluginbuilder 1.0.1 (http://bitbucket.org/hsoft/pluginbuilder)
- appscript 1.0.0 for ME and PE (http://appscript.sourceforge.net/)
Windows prerequisites
---
---------------------
- Visual Studio 2008 (Express is enough) is needed to build C extensions. (http://www.microsoft.com/Express/)
- PyQt 4.7.5 (http://www.riverbankcomputing.co.uk/news)
@@ -55,7 +55,7 @@ Windows prerequisites
- Advanced Installer, if you want to build the installer file. (http://www.advancedinstaller.com/)
Building dupeGuru
=====
=================
First, make sure you meet the dependencies listed in the section above. Then you need to configure your build with:

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Created By: Virgil Dupras
# Created On: 2009-12-30
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
@@ -31,6 +30,7 @@ def parse_args():
return options
def build_cocoa(edition, dev):
from pluginbuilder import build_plugin
build_all_cocoa_locs('cocoalib')
build_all_cocoa_locs(op.join('cocoa', 'base'))
build_all_cocoa_locs(op.join('cocoa', edition))
@@ -46,12 +46,8 @@ def build_cocoa(edition, dev):
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'],
)
# We have to exclude PyQt4 specifically because it's conditionally imported in hscommon.trans
build_plugin('dg_cocoa.py', excludes=['PyQt4'], alias=dev)
os.chdir('..')
pluginpath = op.join(cocoa_project_path, 'dg_cocoa.plugin')
if op.exists(pluginpath):

View File

@@ -9,6 +9,7 @@ http://www.hardcoded.net/licenses/bsd_license
#import "AppDelegate.h"
#import "ProgressController.h"
#import "HSFairwareReminder.h"
#import "ExtraFairwareReminder.h"
#import "Utils.h"
#import "Consts.h"
#import "Dialogs.h"
@@ -32,6 +33,8 @@ http://www.hardcoded.net/licenses/bsd_license
_aboutBox = nil; // Lazily loaded
_preferencesPanel = nil; // Lazily loaded
[[[self directoryPanel] window] makeKeyAndOrderFront:self];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(showExtraFairwareReminder:) name:ShowExtraFairwareReminder object:nil];
}
/* Virtual */
@@ -203,4 +206,12 @@ http://www.hardcoded.net/licenses/bsd_license
{
[py loadResultsFrom:path];
}
- (void)showExtraFairwareReminder:(NSNotification *)aNotification
{
ExtraFairwareReminder *dialog = [[ExtraFairwareReminder alloc] initWithPy:py];
[dialog start];
[NSApp runModalForWindow:[dialog window]];
[dialog release];
}
@end

View File

@@ -10,6 +10,7 @@ http://www.hardcoded.net/licenses/bsd_license
#define JobStarted @"JobStarted"
#define JobInProgress @"JobInProgress"
#define ShowExtraFairwareReminder @"ShowExtraFairwareReminder"
#define jobLoad @"job_load"
#define jobScan @"job_scan"

View File

@@ -0,0 +1,27 @@
/*
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 "PyExtraFairwareReminder.h"
#import "HSWindowController.h"
#import "PyApp.h"
@interface ExtraFairwareReminder : HSWindowController
{
IBOutlet NSButton *continueButton;
NSTimer *timer;
}
- (id)initWithPy:(PyApp *)aPy;
- (PyExtraFairwareReminder *)py;
- (void)start;
- (void)updateButton;
- (IBAction)continue:(id)sender;
- (IBAction)contribute:(id)sender;
@end

View File

@@ -0,0 +1,74 @@
/*
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 "ExtraFairwareReminder.h"
@implementation ExtraFairwareReminder
- (id)initWithPy:(PyApp *)aPy
{
self = [super initWithNibName:@"ExtraFairwareReminder" pyClassName:@"PyExtraFairwareReminder" pyParent:aPy];
[self window];
[continueButton setEnabled:NO];
return self;
}
- (void)dealloc
{
[timer release];
[super dealloc];
}
- (PyExtraFairwareReminder *)py
{
return (PyExtraFairwareReminder *)py;
}
- (void)start
{
[[self py] start];
}
- (void)updateButton
{
[[self py] updateButton];
}
- (IBAction)continue:(id)sender
{
[NSApp stopModal];
}
- (IBAction)contribute:(id)sender
{
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://open.hardcoded.net/contribute/"]];
}
/* Model --> View */
- (void)startTimer
{
timer = [[NSTimer timerWithTimeInterval:0.2 target:self selector:@selector(updateButton)
userInfo:nil repeats:YES] retain];
// Needed for the timer to work in modal mode.
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSModalPanelRunLoopMode];
}
- (void)stopTimer
{
[timer invalidate];
}
- (void)setButtonText:(NSString *)text
{
[continueButton setTitle:text];
}
- (void)enableButton
{
[continueButton setEnabled:YES];
}
@end

View 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 PyExtraFairwareReminder : PyGUI
- (void)start;
- (void)updateButton;
@end

View File

@@ -0,0 +1,11 @@
/* Class = "NSWindow"; title = "Sorry, I must insist"; ObjectID = "1"; */
"1.title" = "Sorry, I must insist";
/* Class = "NSTextFieldCell"; title = "This reminder showed up because:1. You are processing more than 100 duplicates2. You have not yet contributed to dupeGuru3. There are unpaid hours in the project"; ObjectID = "4"; */
"4.title" = "This reminder showed up because:\n\n1. You are processing more than 100 duplicates\n2. You have not yet contributed to dupeGuru\n3. There are unpaid hours in the project";
/* Class = "NSTextFieldCell"; title = "It seems that you found a lot of duplicates. Nice! I must insist, however, that contributions are expected when there are unpaid hours on the project.You might think \"but I'm only going to use this once, I don't have to contribute\". The problem is that most people use dupeGuru only once in a while. If everyone thinks like that, dupeGuru development cannot be funded.If you can't afford to contribute, you can ignore this reminder or send me an e-mail at hsoft@hardcoded.net so I can give you a key to remove this popup."; ObjectID = "6"; */
"6.title" = "It seems that you found a lot of duplicates. Nice! I must insist, however, that contributions are expected when there are unpaid hours on the project.\n\nYou might think \"but I'm only going to use this once, I don't have to contribute\". The problem is that most people use dupeGuru only once in a while. If everyone thinks like that, dupeGuru development cannot be funded. It's because of this tendency inherent to dupeGuru's nature that I have to insist here.\n\nIf you can't afford to contribute, you can ignore this reminder or send me an e-mail at hsoft@hardcoded.net so I can give you a key to remove this popup.";
/* Class = "NSButtonCell"; title = "Contribute"; ObjectID = "10"; */
"10.title" = "Contribute";

View File

@@ -0,0 +1,945 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
<data>
<int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">10J567</string>
<string key="IBDocument.InterfaceBuilderVersion">823</string>
<string key="IBDocument.AppKitVersion">1038.35</string>
<string key="IBDocument.HIToolboxVersion">462.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">823</string>
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="2"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys" id="0">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSCustomObject" id="1001">
<string key="NSClassName">ExtraFairwareReminder</string>
</object>
<object class="NSCustomObject" id="1003">
<string key="NSClassName">FirstResponder</string>
</object>
<object class="NSCustomObject" id="1004">
<string key="NSClassName">NSApplication</string>
</object>
<object class="NSWindowTemplate" id="1005">
<int key="NSWindowStyleMask">1</int>
<int key="NSWindowBacking">2</int>
<string key="NSWindowRect">{{418, 295}, {480, 390}}</string>
<int key="NSWTFlags">1081606144</int>
<string key="NSWindowTitle">Sorry, I must insist</string>
<string key="NSWindowClass">NSWindow</string>
<nil key="NSViewClass"/>
<string key="NSWindowContentMaxSize">{1.79769e+308, 1.79769e+308}</string>
<object class="NSView" key="NSWindowView" id="1006">
<reference key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSTextField" id="359672030">
<reference key="NSNextResponder" ref="1006"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{17, 48}, {446, 85}}</string>
<reference key="NSSuperview" ref="1006"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="855705720">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">272629760</int>
<string key="NSContents">This reminder showed up because:1. You are processing more than 100 duplicates2. You have not yet contributed to dupeGuru3. There are unpaid hours in the project</string>
<object class="NSFont" key="NSSupport">
<string key="NSName">LucidaGrande-Bold</string>
<double key="NSSize">12</double>
<int key="NSfFlags">16</int>
</object>
<reference key="NSControlView" ref="359672030"/>
<object class="NSColor" key="NSBackgroundColor" id="732565682">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">controlColor</string>
<object class="NSColor" key="NSColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
</object>
</object>
<object class="NSColor" key="NSTextColor" id="873511993">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">controlTextColor</string>
<object class="NSColor" key="NSColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MAA</bytes>
</object>
</object>
</object>
</object>
<object class="NSTextField" id="450147645">
<reference key="NSNextResponder" ref="1006"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{17, 141}, {446, 229}}</string>
<reference key="NSSuperview" ref="1006"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="307619415">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">205520896</int>
<string key="NSContents">It seems that you found a lot of duplicates. Nice! I must insist, however, that contributions are expected when there are unpaid hours on the project.You might think "but I'm only going to use this once, I don't have to contribute". The problem is that most people use dupeGuru only once in a while. If everyone thinks like that, dupeGuru development cannot be funded. It's because of this tendency inherent to dupeGuru's nature that I have to insist here.If you can't afford to contribute, you can ignore this reminder or send me an e-mail at hsoft@hardcoded.net so I can give you a key to remove this popup.</string>
<object class="NSFont" key="NSSupport">
<string key="NSName">LucidaGrande</string>
<double key="NSSize">12</double>
<int key="NSfFlags">16</int>
</object>
<reference key="NSControlView" ref="450147645"/>
<reference key="NSBackgroundColor" ref="732565682"/>
<reference key="NSTextColor" ref="873511993"/>
</object>
</object>
<object class="NSButton" id="858267836">
<reference key="NSNextResponder" ref="1006"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{338, 12}, {128, 32}}</string>
<reference key="NSSuperview" ref="1006"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="444055328">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents">Continue</string>
<object class="NSFont" key="NSSupport" id="534597488">
<string key="NSName">LucidaGrande</string>
<double key="NSSize">13</double>
<int key="NSfFlags">1044</int>
</object>
<reference key="NSControlView" ref="858267836"/>
<int key="NSButtonFlags">-2038284033</int>
<int key="NSButtonFlags2">129</int>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
<int key="NSPeriodicDelay">200</int>
<int key="NSPeriodicInterval">25</int>
</object>
</object>
<object class="NSButton" id="789504727">
<reference key="NSNextResponder" ref="1006"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{210, 12}, {128, 32}}</string>
<reference key="NSSuperview" ref="1006"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="639557916">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents">Contribute</string>
<reference key="NSSupport" ref="534597488"/>
<reference key="NSControlView" ref="789504727"/>
<int key="NSButtonFlags">-2038284033</int>
<int key="NSButtonFlags2">129</int>
<string key="NSAlternateContents"/>
<string type="base64-UTF8" key="NSKeyEquivalent">DQ</string>
<int key="NSPeriodicDelay">200</int>
<int key="NSPeriodicInterval">25</int>
</object>
</object>
</object>
<string key="NSFrameSize">{480, 390}</string>
<reference key="NSSuperview"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
<string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
</object>
</object>
<object class="IBObjectContainer" key="IBDocument.Objects">
<object class="NSMutableArray" key="connectionRecords">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">contribute:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="789504727"/>
</object>
<int key="connectionID">11</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">continue:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="858267836"/>
</object>
<int key="connectionID">12</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">window</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="1005"/>
</object>
<int key="connectionID">13</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">continueButton</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="858267836"/>
</object>
<int key="connectionID">14</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBObjectRecord">
<int key="objectID">0</int>
<reference key="object" ref="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="1001"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="1003"/>
<reference key="parent" ref="0"/>
<string key="objectName">First Responder</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-3</int>
<reference key="object" ref="1004"/>
<reference key="parent" ref="0"/>
<string key="objectName">Application</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">1</int>
<reference key="object" ref="1005"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="1006"/>
</object>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2</int>
<reference key="object" ref="1006"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="450147645"/>
<reference ref="359672030"/>
<reference ref="858267836"/>
<reference ref="789504727"/>
</object>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="359672030"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="855705720"/>
</object>
<reference key="parent" ref="1006"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">4</int>
<reference key="object" ref="855705720"/>
<reference key="parent" ref="359672030"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">5</int>
<reference key="object" ref="450147645"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="307619415"/>
</object>
<reference key="parent" ref="1006"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">6</int>
<reference key="object" ref="307619415"/>
<reference key="parent" ref="450147645"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">7</int>
<reference key="object" ref="858267836"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="444055328"/>
</object>
<reference key="parent" ref="1006"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">8</int>
<reference key="object" ref="444055328"/>
<reference key="parent" ref="858267836"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">9</int>
<reference key="object" ref="789504727"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="639557916"/>
</object>
<reference key="parent" ref="1006"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">10</int>
<reference key="object" ref="639557916"/>
<reference key="parent" ref="789504727"/>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>-1.IBPluginDependency</string>
<string>-2.IBPluginDependency</string>
<string>-3.IBPluginDependency</string>
<string>1.IBEditorWindowLastContentRect</string>
<string>1.IBPluginDependency</string>
<string>1.IBWindowTemplateEditedContentRect</string>
<string>1.NSWindowTemplate.visibleAtLaunch</string>
<string>1.WindowOrigin</string>
<string>1.editorWindowContentRectSynchronizationRect</string>
<string>10.IBPluginDependency</string>
<string>2.IBPluginDependency</string>
<string>3.IBPluginDependency</string>
<string>3.IBViewBoundsToFrameTransform</string>
<string>4.IBPluginDependency</string>
<string>5.IBPluginDependency</string>
<string>5.IBViewBoundsToFrameTransform</string>
<string>6.IBPluginDependency</string>
<string>7.IBPluginDependency</string>
<string>7.IBViewBoundsToFrameTransform</string>
<string>8.IBPluginDependency</string>
<string>9.IBPluginDependency</string>
<string>9.IBViewBoundsToFrameTransform</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{418, 295}, {480, 390}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{418, 295}, {480, 390}}</string>
<boolean value="NO"/>
<string>{196, 240}</string>
<string>{{357, 418}, {480, 270}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBiAAAwxwAAA</bytes>
</object>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABAoAAAw3gAAA</bytes>
</object>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABDqQAAwigAAA</bytes>
</object>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABDUgAAwigAAA</bytes>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<nil key="activeLocalization"/>
<object class="NSMutableDictionary" key="localizations">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">14</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">ExtraFairwareReminder</string>
<string key="superclassName">HSWindowController</string>
<object class="NSMutableDictionary" key="actions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>continue:</string>
<string>contribute:</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<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>continue:</string>
<string>contribute:</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBActionInfo">
<string key="name">continue:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">contribute:</string>
<string key="candidateClassName">id</string>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">continueButton</string>
<string key="NS.object.0">NSButton</string>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<string key="NS.key.0">continueButton</string>
<object class="IBToOneOutletInfo" key="NS.object.0">
<string key="name">continueButton</string>
<string key="candidateClassName">NSButton</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">../base/ExtraFairwareReminder.h</string>
</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">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">../views/HSTableView.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/NSTableViewAdditions.h</string>
</object>
</object>
</object>
<object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">NSActionCell</string>
<string key="superclassName">NSCell</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSActionCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<string key="superclassName">NSResponder</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="131375392">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSApplication.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="645066809">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSApplicationScripting.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="295119366">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSColorPanel.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSHelpManager.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSPageLayout.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSUserInterfaceItemSearching.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSButton</string>
<string key="superclassName">NSControl</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSButton.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSButtonCell</string>
<string key="superclassName">NSActionCell</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSButtonCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSCell</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSControl</string>
<string key="superclassName">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="947202395">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSControl.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSFormatter</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSFormatter.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSMenu</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="754383277">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSMenu.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSAccessibility.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<reference key="sourceIdentifier" ref="131375392"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<reference key="sourceIdentifier" ref="645066809"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<reference key="sourceIdentifier" ref="295119366"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<reference key="sourceIdentifier" ref="947202395"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSDictionaryController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSDragging.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSFontManager.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSFontPanel.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSKeyValueBinding.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<reference key="sourceIdentifier" ref="754383277"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSNibLoading.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSOutlineView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSPasteboard.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSSavePanel.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSTableView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSToolbarItem.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="756921129">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSArchiver.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSClassDescription.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSError.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSObjectScripting.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSPortCoder.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSScriptClassDescription.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSScriptKeyValueCoding.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSScriptObjectSpecifiers.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSScriptWhoseTests.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSURLDownload.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Sparkle.framework/Headers/SUAppcast.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Sparkle.framework/Headers/SUUpdater.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSResponder</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSInterfaceStyle.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSResponder</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSResponder.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSTextField</string>
<string key="superclassName">NSControl</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSTextField.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSTextFieldCell</string>
<string key="superclassName">NSActionCell</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSTextFieldCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSClipView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSMenuItem.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSRulerView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSView</string>
<string key="superclassName">NSResponder</string>
<reference key="sourceIdentifier" ref="756921129"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSWindow</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSDrawer.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSWindow</string>
<string key="superclassName">NSResponder</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSWindow.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSWindow</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSWindowScripting.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSWindowController</string>
<string key="superclassName">NSResponder</string>
<object class="NSMutableDictionary" key="actions">
<string key="NS.key.0">showWindow:</string>
<string key="NS.object.0">id</string>
</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">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSWindowController.h</string>
</object>
</object>
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
<integer value="1050" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
<integer value="1050" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3</string>
<integer value="3000" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<string key="IBDocument.LastKnownRelativeProjectPath">../../pe/dupeguru.xcodeproj</string>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
</data>
</archive>

View File

@@ -11,15 +11,17 @@
"Grouped %d/%d matches" = "Grouped %d/%d matches";
"%d / %d (%s / %s) duplicates marked." = "%d / %d (%s / %s) duplicates marked.";
" filter: %s" = " filter: %s";
"Read size of %d/%d files" = "Read size of %d/%d files";
"Read metadata of %d/%d files" = "Read metadata of %d/%d files";
"Removing false matches" = "Removing false matches";
"Processed %d/%d matches against the ignore list" = "Processed %d/%d matches against the ignore list";
"Doing group prioritization" = "Doing group prioritization";
"Continue" = "Continue";
"Continue ({})" = "Continue ({})";
"Analyzed %d/%d pictures" = "Analyzed %d/%d pictures";
"Preparing for matching" = "Preparing for matching";
"Matched %d/%d pictures" = "Matched %d/%d pictures";
"Performed %d/%d chunk matches" = "Performed %d/%d chunk matches";
"Verified %d/%d matches" = "Verified %d/%d matches";
"Removing dead tracks from your iTunes Library" = "Removing dead tracks from your iTunes Library";

View File

@@ -0,0 +1,11 @@
/* Class = "NSWindow"; title = "Sorry, I must insist"; ObjectID = "1"; */
"1.title" = "Désolé, je dois insister";
/* Class = "NSTextFieldCell"; title = "This reminder showed up because:1. You are processing more than 100 duplicates2. You have not yet contributed to dupeGuru3. There are unpaid hours in the project"; ObjectID = "4"; */
"4.title" = "Ce rappel apparaît parce que:\n\n1. Plus de 100 doublons sont traités\n2. Vous n'avez pas encore contribué à dupeGuru\n3. Il y a des heures non-payées au projet";
/* Class = "NSTextFieldCell"; title = "It seems that you found a lot of duplicates. Nice! I must insist, however, that contributions are expected when there are unpaid hours on the project.You might think \"but I'm only going to use this once, I don't have to contribute\". The problem is that most people use dupeGuru only once in a while. If everyone thinks like that, dupeGuru development cannot be funded.If you can't afford to contribute, you can ignore this reminder or send me an e-mail at hsoft@hardcoded.net so I can give you a key to remove this popup."; ObjectID = "6"; */
"6.title" = "Il semble que vous ayez trouvé beaucoup de doublons. Super! Je dois par contre insister que des contributions sont attendues lorsqu'il y'a des heures non-payées au projet.\n\nVous pensez peut-être \"je n'utiliserai ce programme qu'une fois, pas besoin de contribuer\". Le problème c'est que la plupart des utilisateurs de dupeGuru ne l'utilisent qu'une fois. Si tous suivent ce raisonnement, le développement de dupeGuru ne peut pas continuer. C'est à cause de cette tendance inhérente à la nature de dupeGuru que je me vois contraint d'insister ici.\n\nSi vous n'avez pas les moyens de contribuer, ignorez ce message ou envoyez moi un message à hsoft@hardcoded.net pour que je vous envoie une clé d'enregistrement.";
/* Class = "NSButtonCell"; title = "Contribute"; ObjectID = "10"; */
"10.title" = "Contribuer";

View File

@@ -0,0 +1,962 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
<data>
<int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">10J567</string>
<string key="IBDocument.InterfaceBuilderVersion">823</string>
<string key="IBDocument.AppKitVersion">1038.35</string>
<string key="IBDocument.HIToolboxVersion">462.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">823</string>
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="1"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys" id="0">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSCustomObject" id="1001">
<string key="NSClassName">ExtraFairwareReminder</string>
</object>
<object class="NSCustomObject" id="1003">
<string key="NSClassName">FirstResponder</string>
</object>
<object class="NSCustomObject" id="1004">
<string key="NSClassName">NSApplication</string>
</object>
<object class="NSWindowTemplate" id="1005">
<int key="NSWindowStyleMask">1</int>
<int key="NSWindowBacking">2</int>
<string key="NSWindowRect">{{418, 295}, {480, 390}}</string>
<int key="NSWTFlags">1081606144</int>
<string key="NSWindowTitle">Désolé, je dois insister</string>
<string key="NSWindowClass">NSWindow</string>
<nil key="NSViewClass"/>
<string key="NSWindowContentMaxSize">{1.79769e+308, 1.79769e+308}</string>
<object class="NSView" key="NSWindowView" id="1006">
<reference key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSTextField" id="359672030">
<reference key="NSNextResponder" ref="1006"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{17, 48}, {446, 85}}</string>
<reference key="NSSuperview" ref="1006"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="855705720">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">272629760</int>
<string type="base64-UTF8" key="NSContents">Q2UgcmFwcGVsIGFwcGFyYcOudCBwYXJjZSBxdWU6CgoxLiBQbHVzIGRlIDEwMCBkb3VibG9ucyBzb250
IHRyYWl0w6lzCjIuIFZvdXMgbidhdmV6IHBhcyBlbmNvcmUgY29udHJpYnXDqSDDoCBkdXBlR3VydQoz
LiBJbCB5IGEgZGVzIGhldXJlcyBub24tcGF5w6llcyBhdSBwcm9qZXQ</string>
<object class="NSFont" key="NSSupport">
<string key="NSName">LucidaGrande-Bold</string>
<double key="NSSize">12</double>
<int key="NSfFlags">16</int>
</object>
<reference key="NSControlView" ref="359672030"/>
<object class="NSColor" key="NSBackgroundColor" id="732565682">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">controlColor</string>
<object class="NSColor" key="NSColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
</object>
</object>
<object class="NSColor" key="NSTextColor" id="873511993">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">controlTextColor</string>
<object class="NSColor" key="NSColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MAA</bytes>
</object>
</object>
</object>
</object>
<object class="NSTextField" id="450147645">
<reference key="NSNextResponder" ref="1006"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{17, 141}, {446, 229}}</string>
<reference key="NSSuperview" ref="1006"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="307619415">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">205520896</int>
<string type="base64-UTF8" key="NSContents">SWwgc2VtYmxlIHF1ZSB2b3VzIGF5ZXogdHJvdXbDqSBiZWF1Y291cCBkZSBkb3VibG9ucy4gU3VwZXIh
IEplIGRvaXMgcGFyIGNvbnRyZSBpbnNpc3RlciBxdWUgZGVzIGNvbnRyaWJ1dGlvbnMgc29udCBhdHRl
bmR1ZXMgbG9yc3F1J2lsIHknYSBkZXMgaGV1cmVzIG5vbi1wYXnDqWVzIGF1IHByb2pldC4KClZvdXMg
cGVuc2V6IHBldXQtw6p0cmUgImplIG4ndXRpbGlzZXJhaSBjZSBwcm9ncmFtbWUgcXUndW5lIGZvaXMs
IHBhcyBiZXNvaW4gZGUgY29udHJpYnVlciIuIExlIHByb2Jsw6htZSBjJ2VzdCBxdWUgbGEgcGx1cGFy
dCBkZXMgdXRpbGlzYXRldXJzIGRlIGR1cGVHdXJ1IG5lIGwndXRpbGlzZW50IHF1J3VuZSBmb2lzLiBT
aSB0b3VzIHN1aXZlbnQgY2UgcmFpc29ubmVtZW50LCBsZSBkw6l2ZWxvcHBlbWVudCBkZSBkdXBlR3Vy
dSBuZSBwZXV0IHBhcyBjb250aW51ZXIuIEMnZXN0IMOgIGNhdXNlIGRlIGNldHRlIHRlbmRhbmNlIGlu
aMOpcmVudGUgw6AgbGEgbmF0dXJlIGRlIGR1cGVHdXJ1IHF1ZSBqZSBtZSB2b2lzIGNvbnRyYWludCBk
J2luc2lzdGVyIGljaS4KClNpIHZvdXMgbidhdmV6IHBhcyBsZXMgbW95ZW5zIGRlIGNvbnRyaWJ1ZXIs
IGlnbm9yZXogY2UgbWVzc2FnZSBvdSBlbnZveWV6IG1vaSB1biBtZXNzYWdlIMOgIGhzb2Z0QGhhcmRj
b2RlZC5uZXQgcG91ciBxdWUgamUgdm91cyBlbnZvaWUgdW5lIGNsw6kgZCdlbnJlZ2lzdHJlbWVudC4</string>
<object class="NSFont" key="NSSupport">
<string key="NSName">LucidaGrande</string>
<double key="NSSize">12</double>
<int key="NSfFlags">16</int>
</object>
<reference key="NSControlView" ref="450147645"/>
<reference key="NSBackgroundColor" ref="732565682"/>
<reference key="NSTextColor" ref="873511993"/>
</object>
</object>
<object class="NSButton" id="858267836">
<reference key="NSNextResponder" ref="1006"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{338, 12}, {128, 32}}</string>
<reference key="NSSuperview" ref="1006"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="444055328">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents">Continue</string>
<object class="NSFont" key="NSSupport" id="534597488">
<string key="NSName">LucidaGrande</string>
<double key="NSSize">13</double>
<int key="NSfFlags">1044</int>
</object>
<reference key="NSControlView" ref="858267836"/>
<int key="NSButtonFlags">-2038284033</int>
<int key="NSButtonFlags2">129</int>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
<int key="NSPeriodicDelay">200</int>
<int key="NSPeriodicInterval">25</int>
</object>
</object>
<object class="NSButton" id="789504727">
<reference key="NSNextResponder" ref="1006"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{210, 12}, {128, 32}}</string>
<reference key="NSSuperview" ref="1006"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="639557916">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents">Contribuer</string>
<reference key="NSSupport" ref="534597488"/>
<reference key="NSControlView" ref="789504727"/>
<int key="NSButtonFlags">-2038284033</int>
<int key="NSButtonFlags2">129</int>
<string key="NSAlternateContents"/>
<string type="base64-UTF8" key="NSKeyEquivalent">DQ</string>
<int key="NSPeriodicDelay">200</int>
<int key="NSPeriodicInterval">25</int>
</object>
</object>
</object>
<string key="NSFrameSize">{480, 390}</string>
<reference key="NSSuperview"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
<string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
</object>
</object>
<object class="IBObjectContainer" key="IBDocument.Objects">
<object class="NSMutableArray" key="connectionRecords">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">contribute:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="789504727"/>
</object>
<int key="connectionID">11</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">continue:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="858267836"/>
</object>
<int key="connectionID">12</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">window</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="1005"/>
</object>
<int key="connectionID">13</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">continueButton</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="858267836"/>
</object>
<int key="connectionID">14</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBObjectRecord">
<int key="objectID">0</int>
<reference key="object" ref="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="1001"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="1003"/>
<reference key="parent" ref="0"/>
<string key="objectName">First Responder</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-3</int>
<reference key="object" ref="1004"/>
<reference key="parent" ref="0"/>
<string key="objectName">Application</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">1</int>
<reference key="object" ref="1005"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="1006"/>
</object>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2</int>
<reference key="object" ref="1006"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="450147645"/>
<reference ref="359672030"/>
<reference ref="858267836"/>
<reference ref="789504727"/>
</object>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="359672030"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="855705720"/>
</object>
<reference key="parent" ref="1006"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">4</int>
<reference key="object" ref="855705720"/>
<reference key="parent" ref="359672030"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">5</int>
<reference key="object" ref="450147645"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="307619415"/>
</object>
<reference key="parent" ref="1006"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">6</int>
<reference key="object" ref="307619415"/>
<reference key="parent" ref="450147645"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">7</int>
<reference key="object" ref="858267836"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="444055328"/>
</object>
<reference key="parent" ref="1006"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">8</int>
<reference key="object" ref="444055328"/>
<reference key="parent" ref="858267836"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">9</int>
<reference key="object" ref="789504727"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="639557916"/>
</object>
<reference key="parent" ref="1006"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">10</int>
<reference key="object" ref="639557916"/>
<reference key="parent" ref="789504727"/>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>-1.IBPluginDependency</string>
<string>-2.IBPluginDependency</string>
<string>-3.IBPluginDependency</string>
<string>1.IBEditorWindowLastContentRect</string>
<string>1.IBPluginDependency</string>
<string>1.IBWindowTemplateEditedContentRect</string>
<string>1.NSWindowTemplate.visibleAtLaunch</string>
<string>1.WindowOrigin</string>
<string>1.editorWindowContentRectSynchronizationRect</string>
<string>1.windowTemplate.maxSize</string>
<string>1.windowTemplate.minSize</string>
<string>10.IBPluginDependency</string>
<string>2.IBPluginDependency</string>
<string>3.IBPluginDependency</string>
<string>3.IBViewBoundsToFrameTransform</string>
<string>4.IBPluginDependency</string>
<string>5.IBPluginDependency</string>
<string>5.IBViewBoundsToFrameTransform</string>
<string>6.IBPluginDependency</string>
<string>7.IBPluginDependency</string>
<string>7.IBViewBoundsToFrameTransform</string>
<string>8.IBPluginDependency</string>
<string>9.IBPluginDependency</string>
<string>9.IBViewBoundsToFrameTransform</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{418, 295}, {480, 390}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{418, 295}, {480, 390}}</string>
<boolean value="NO"/>
<string>{196, 240}</string>
<string>{{357, 418}, {480, 270}}</string>
<string>{1.79769e+308, 1.79769e+308}</string>
<string>{0, 0}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBiAAAwxwAAA</bytes>
</object>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABAoAAAw3gAAA</bytes>
</object>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABDqQAAwigAAA</bytes>
</object>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABDUgAAwigAAA</bytes>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<nil key="activeLocalization"/>
<object class="NSMutableDictionary" key="localizations">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">14</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">ExtraFairwareReminder</string>
<string key="superclassName">HSWindowController</string>
<object class="NSMutableDictionary" key="actions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>continue:</string>
<string>contribute:</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<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>continue:</string>
<string>contribute:</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBActionInfo">
<string key="name">continue:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">contribute:</string>
<string key="candidateClassName">id</string>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">continueButton</string>
<string key="NS.object.0">NSButton</string>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<string key="NS.key.0">continueButton</string>
<object class="IBToOneOutletInfo" key="NS.object.0">
<string key="name">continueButton</string>
<string key="candidateClassName">NSButton</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">../base/ExtraFairwareReminder.h</string>
</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">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">../views/HSTableView.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/NSTableViewAdditions.h</string>
</object>
</object>
</object>
<object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">NSActionCell</string>
<string key="superclassName">NSCell</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSActionCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<string key="superclassName">NSResponder</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="131375392">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSApplication.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="645066809">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSApplicationScripting.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="295119366">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSColorPanel.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSHelpManager.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSPageLayout.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSUserInterfaceItemSearching.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSButton</string>
<string key="superclassName">NSControl</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSButton.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSButtonCell</string>
<string key="superclassName">NSActionCell</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSButtonCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSCell</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSControl</string>
<string key="superclassName">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="947202395">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSControl.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSFormatter</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSFormatter.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSMenu</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="754383277">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSMenu.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSAccessibility.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<reference key="sourceIdentifier" ref="131375392"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<reference key="sourceIdentifier" ref="645066809"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<reference key="sourceIdentifier" ref="295119366"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<reference key="sourceIdentifier" ref="947202395"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSDictionaryController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSDragging.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSFontManager.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSFontPanel.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSKeyValueBinding.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<reference key="sourceIdentifier" ref="754383277"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSNibLoading.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSOutlineView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSPasteboard.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSSavePanel.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSTableView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSToolbarItem.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="756921129">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSArchiver.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSClassDescription.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSError.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSObjectScripting.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSPortCoder.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSScriptClassDescription.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSScriptKeyValueCoding.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSScriptObjectSpecifiers.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSScriptWhoseTests.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSURLDownload.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Sparkle.framework/Headers/SUAppcast.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Sparkle.framework/Headers/SUUpdater.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSResponder</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSInterfaceStyle.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSResponder</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSResponder.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSTextField</string>
<string key="superclassName">NSControl</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSTextField.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSTextFieldCell</string>
<string key="superclassName">NSActionCell</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSTextFieldCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSClipView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSMenuItem.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSRulerView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSView</string>
<string key="superclassName">NSResponder</string>
<reference key="sourceIdentifier" ref="756921129"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSWindow</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSDrawer.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSWindow</string>
<string key="superclassName">NSResponder</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSWindow.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSWindow</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSWindowScripting.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSWindowController</string>
<string key="superclassName">NSResponder</string>
<object class="NSMutableDictionary" key="actions">
<string key="NS.key.0">showWindow:</string>
<string key="NS.object.0">id</string>
</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">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSWindowController.h</string>
</object>
</object>
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
<integer value="1050" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
<integer value="1050" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3</string>
<integer value="3000" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<string key="IBDocument.LastKnownRelativeProjectPath">../../pe/dupeguru.xcodeproj</string>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
</data>
</archive>

View File

@@ -16,9 +16,12 @@
"Processed %d/%d matches against the ignore list" = "Vérification de %d/%d paires dans la ignore list";
"Doing group prioritization" = "Prioritization des groupes";
"Continue" = "Continuer";
"Continue ({})" = "Continuer ({})";
"Analyzed %d/%d pictures" = "Analyzé %d/%d images";
"Preparing for matching" = "Préparation pour la comparaison";
"Matched %d/%d pictures" = "Comparé %d/%d images";
"Performed %d/%d chunk matches" = "%d/%d blocs d'images comparés";
"Verified %d/%d matches" = "Vérifié %d/%d paires";
"Removing dead tracks from your iTunes Library" = "Retrait des tracks mortes de votre librairie iTunes";

View File

@@ -67,6 +67,8 @@
CE74A12712537F2E008A8DF0 /* FairwareReminder.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE74A12512537F2E008A8DF0 /* FairwareReminder.xib */; };
CE848A1909DD85810004CB44 /* Consts.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE848A1809DD85810004CB44 /* Consts.h */; };
CEB14D29124DFC2800FA7481 /* ResultTable.m in Sources */ = {isa = PBXBuildFile; fileRef = CEB14D28124DFC2800FA7481 /* ResultTable.m */; };
CEB5E07813225C89009F521D /* ExtraFairwareReminder.m in Sources */ = {isa = PBXBuildFile; fileRef = CEB5E07613225C89009F521D /* ExtraFairwareReminder.m */; };
CEB5E07D13225CA2009F521D /* ExtraFairwareReminder.xib in Resources */ = {isa = PBXBuildFile; fileRef = CEB5E07B13225CA2009F521D /* ExtraFairwareReminder.xib */; };
CEDF07A3112493B200EE5BC0 /* StatsLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = CEDF07A2112493B200EE5BC0 /* StatsLabel.m */; };
CEEB135209C837A2004D2330 /* dupeguru.icns in Resources */ = {isa = PBXBuildFile; fileRef = CEEB135109C837A2004D2330 /* dupeguru.icns */; };
CEFC294609C89E3D00D9F998 /* folder32.png in Resources */ = {isa = PBXBuildFile; fileRef = CEFC294509C89E3D00D9F998 /* folder32.png */; };
@@ -186,6 +188,11 @@
CEB14D26124DFC2800FA7481 /* PyResultTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyResultTable.h; path = ../base/PyResultTable.h; sourceTree = SOURCE_ROOT; };
CEB14D27124DFC2800FA7481 /* ResultTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ResultTable.h; path = ../base/ResultTable.h; sourceTree = SOURCE_ROOT; };
CEB14D28124DFC2800FA7481 /* ResultTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ResultTable.m; path = ../base/ResultTable.m; sourceTree = SOURCE_ROOT; };
CEB5E07513225C89009F521D /* ExtraFairwareReminder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExtraFairwareReminder.h; path = ../base/ExtraFairwareReminder.h; sourceTree = SOURCE_ROOT; };
CEB5E07613225C89009F521D /* ExtraFairwareReminder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ExtraFairwareReminder.m; path = ../base/ExtraFairwareReminder.m; sourceTree = SOURCE_ROOT; };
CEB5E07713225C89009F521D /* PyExtraFairwareReminder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyExtraFairwareReminder.h; path = ../base/PyExtraFairwareReminder.h; sourceTree = SOURCE_ROOT; };
CEB5E07C13225CA2009F521D /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../base/en.lproj/ExtraFairwareReminder.xib; sourceTree = SOURCE_ROOT; };
CEB5E07E13225CB8009F521D /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../base/fr.lproj/ExtraFairwareReminder.xib; 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; };
@@ -341,6 +348,7 @@
CE05331312E5D3ED0029EF25 /* ProblemDialog.xib */,
CE05331512E5D3ED0029EF25 /* ResultWindow.xib */,
CE05332112E5D4100029EF25 /* Preferences.xib */,
CEB5E07B13225CA2009F521D /* ExtraFairwareReminder.xib */,
);
name = xib;
sourceTree = "<group>";
@@ -402,7 +410,6 @@
CE515E140FC6C17900EC695D /* dgbase */ = {
isa = PBXGroup;
children = (
CEB14D26124DFC2800FA7481 /* PyResultTable.h */,
CEB14D27124DFC2800FA7481 /* ResultTable.h */,
CEB14D28124DFC2800FA7481 /* ResultTable.m */,
CE003CCD11242D2C004B0AA7 /* DirectoryOutline.h */,
@@ -421,10 +428,14 @@
CE515E1C0FC6C19300EC695D /* ResultWindow.m */,
CEDF07A1112493B200EE5BC0 /* StatsLabel.h */,
CEDF07A2112493B200EE5BC0 /* StatsLabel.m */,
CEB5E07513225C89009F521D /* ExtraFairwareReminder.h */,
CEB5E07613225C89009F521D /* ExtraFairwareReminder.m */,
CE515E1A0FC6C19300EC695D /* PyDupeGuru.h */,
CED0A591111C9FD10020AD7D /* PyDetailsPanel.h */,
CE0A0C031175A1DE00DCA3C6 /* PyProblemDialog.h */,
CEDF07A0112493B200EE5BC0 /* PyStatsLabel.h */,
CEB14D26124DFC2800FA7481 /* PyResultTable.h */,
CEB5E07713225C89009F521D /* PyExtraFairwareReminder.h */,
);
name = dgbase;
sourceTree = "<group>";
@@ -508,6 +519,7 @@
CE05332312E5D4100029EF25 /* Preferences.xib in Resources */,
CE05332F12E5D6100029EF25 /* Localizable.strings in Resources */,
CE45274F12E5F62D00005A15 /* core.strings in Resources */,
CEB5E07D13225CA2009F521D /* ExtraFairwareReminder.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -548,6 +560,7 @@
CE74A12412537F06008A8DF0 /* HSFairwareReminder.m in Sources */,
CE4F934912CCA96C0067A3AE /* HSAboutBox.m in Sources */,
CE1EAA0A12DF3E81009BA949 /* HSRecentFiles.m in Sources */,
CEB5E07813225C89009F521D /* ExtraFairwareReminder.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -636,6 +649,15 @@
path = ../../cocoalib/xib;
sourceTree = SOURCE_ROOT;
};
CEB5E07B13225CA2009F521D /* ExtraFairwareReminder.xib */ = {
isa = PBXVariantGroup;
children = (
CEB5E07C13225CA2009F521D /* en */,
CEB5E07E13225CB8009F521D /* fr */,
);
name = ExtraFairwareReminder.xib;
sourceTree = SOURCE_ROOT;
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */

View File

@@ -23,6 +23,8 @@
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 */; };
CE2A29F413213BE3005899AC /* ExtraFairwareReminder.m in Sources */ = {isa = PBXBuildFile; fileRef = CE2A29F313213BE3005899AC /* ExtraFairwareReminder.m */; };
CE2A29F713213BFB005899AC /* ExtraFairwareReminder.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE2A29F513213BFB005899AC /* ExtraFairwareReminder.xib */; };
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.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 */; };
@@ -115,6 +117,10 @@
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; };
CE2A29F213213BE3005899AC /* ExtraFairwareReminder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExtraFairwareReminder.h; path = ../base/ExtraFairwareReminder.h; sourceTree = SOURCE_ROOT; };
CE2A29F313213BE3005899AC /* ExtraFairwareReminder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ExtraFairwareReminder.m; path = ../base/ExtraFairwareReminder.m; sourceTree = SOURCE_ROOT; };
CE2A29F613213BFB005899AC /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../base/en.lproj/ExtraFairwareReminder.xib; sourceTree = SOURCE_ROOT; };
CE2A29FF13213C31005899AC /* PyExtraFairwareReminder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyExtraFairwareReminder.h; path = ../base/PyExtraFairwareReminder.h; 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; };
CE381C9A09914ADF003581CE /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = ResultWindow.m; sourceTree = SOURCE_ROOT; };
@@ -184,6 +190,7 @@
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>"; };
CECA899B09DB132E00A3D774 /* DetailsPanel.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = DetailsPanel.m; sourceTree = "<group>"; };
CEE660B7132253910036DB04 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../base/fr.lproj/ExtraFairwareReminder.xib; sourceTree = SOURCE_ROOT; };
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; };
@@ -299,6 +306,7 @@
CE05339912E5DA350029EF25 /* ResultWindow.xib */,
CE0533A312E5DA4D0029EF25 /* DetailsPanel.xib */,
CE0533A512E5DA4D0029EF25 /* Preferences.xib */,
CE2A29F513213BFB005899AC /* ExtraFairwareReminder.xib */,
);
name = xib;
sourceTree = "<group>";
@@ -354,6 +362,7 @@
CE80DB810FC194BD0086DCA6 /* dgbase */ = {
isa = PBXGroup;
children = (
CE2A29FF13213C31005899AC /* PyExtraFairwareReminder.h */,
CEF12A81124DFD620087B51D /* PyResultTable.h */,
CEF12A82124DFD620087B51D /* ResultTable.h */,
CEF12A83124DFD620087B51D /* ResultTable.m */,
@@ -372,6 +381,8 @@
CE80DB890FC1951C0086DCA6 /* ResultWindow.m */,
CE95865C112C516400F95FD2 /* StatsLabel.h */,
CE95865D112C516400F95FD2 /* StatsLabel.m */,
CE2A29F213213BE3005899AC /* ExtraFairwareReminder.h */,
CE2A29F313213BE3005899AC /* ExtraFairwareReminder.m */,
CE80DB870FC1951C0086DCA6 /* PyDupeGuru.h */,
CE18126F111C9D5100E49FCE /* PyDetailsPanel.h */,
CE9EA7711122CA0B008CD2BC /* PyDirectoryOutline.h */,
@@ -512,6 +523,7 @@
CE0533A812E5DA4D0029EF25 /* Preferences.xib in Resources */,
CE0533AB12E5DA6A0029EF25 /* Localizable.strings in Resources */,
CE4527AC12E5F6E700005A15 /* core.strings in Resources */,
CE2A29F713213BFB005899AC /* ExtraFairwareReminder.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -555,6 +567,7 @@
CE1EB5FE12537F9D0034AABB /* HSFairwareReminder.m in Sources */,
CEC9DB4C12CCAA7D003102F0 /* HSAboutBox.m in Sources */,
CE60180812DF3EA900236FDC /* HSRecentFiles.m in Sources */,
CE2A29F413213BE3005899AC /* ExtraFairwareReminder.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -634,6 +647,15 @@
path = ../../cocoalib/xib;
sourceTree = SOURCE_ROOT;
};
CE2A29F513213BFB005899AC /* ExtraFairwareReminder.xib */ = {
isa = PBXVariantGroup;
children = (
CE2A29F613213BFB005899AC /* en */,
CEE660B7132253910036DB04 /* fr */,
);
name = ExtraFairwareReminder.xib;
sourceTree = SOURCE_ROOT;
};
CE4527AA12E5F6E700005A15 /* core.strings */ = {
isa = PBXVariantGroup;
children = (

View File

@@ -21,6 +21,8 @@
CE45579B0AE3BC2B005A9546 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE45579A0AE3BC2B005A9546 /* Sparkle.framework */; };
CE4557B40AE3BC50005A9546 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE45579A0AE3BC2B005A9546 /* Sparkle.framework */; };
CE647E571173024A006D28BA /* ProblemDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = CE647E551173024A006D28BA /* ProblemDialog.m */; };
CE665B3013225ADD003F5CFB /* ExtraFairwareReminder.m in Sources */ = {isa = PBXBuildFile; fileRef = CE665B2E13225ADD003F5CFB /* ExtraFairwareReminder.m */; };
CE665B3313225AF8003F5CFB /* ExtraFairwareReminder.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE665B3113225AF8003F5CFB /* ExtraFairwareReminder.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 */; };
@@ -97,6 +99,11 @@
CE647E541173024A006D28BA /* ProblemDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProblemDialog.h; path = ../base/ProblemDialog.h; sourceTree = SOURCE_ROOT; };
CE647E551173024A006D28BA /* ProblemDialog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProblemDialog.m; path = ../base/ProblemDialog.m; sourceTree = SOURCE_ROOT; };
CE647E561173024A006D28BA /* PyProblemDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyProblemDialog.h; path = ../base/PyProblemDialog.h; sourceTree = SOURCE_ROOT; };
CE665B2D13225ADD003F5CFB /* ExtraFairwareReminder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExtraFairwareReminder.h; path = ../base/ExtraFairwareReminder.h; sourceTree = SOURCE_ROOT; };
CE665B2E13225ADD003F5CFB /* ExtraFairwareReminder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ExtraFairwareReminder.m; path = ../base/ExtraFairwareReminder.m; sourceTree = SOURCE_ROOT; };
CE665B2F13225ADD003F5CFB /* PyExtraFairwareReminder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PyExtraFairwareReminder.h; path = ../base/PyExtraFairwareReminder.h; sourceTree = SOURCE_ROOT; };
CE665B3213225AF8003F5CFB /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = ../base/en.lproj/ExtraFairwareReminder.xib; sourceTree = SOURCE_ROOT; };
CE665B3413225B07003F5CFB /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = ../base/fr.lproj/ExtraFairwareReminder.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; };
@@ -340,6 +347,7 @@
CE81134812E5CE4D00A36C80 /* ProblemDialog.xib */,
CE81134A12E5CE4D00A36C80 /* ResultWindow.xib */,
CE81135612E5CE6D00A36C80 /* Preferences.xib */,
CE665B3113225AF8003F5CFB /* ExtraFairwareReminder.xib */,
);
name = xib;
sourceTree = "<group>";
@@ -403,6 +411,8 @@
CEE7EA120FE675C80004E467 /* DetailsPanel.m */,
CEFC7FB40FC951A700CD5728 /* DirectoryPanel.h */,
CEFC7FB50FC951A700CD5728 /* DirectoryPanel.m */,
CE665B2D13225ADD003F5CFB /* ExtraFairwareReminder.h */,
CE665B2E13225ADD003F5CFB /* ExtraFairwareReminder.m */,
CEFC7FB60FC951A700CD5728 /* PyDupeGuru.h */,
CE6E7407111C997500C350E3 /* PyDetailsPanel.h */,
CEFC7FB70FC951A700CD5728 /* ResultWindow.h */,
@@ -410,6 +420,7 @@
CE647E541173024A006D28BA /* ProblemDialog.h */,
CE647E551173024A006D28BA /* ProblemDialog.m */,
CE647E561173024A006D28BA /* PyProblemDialog.h */,
CE665B2F13225ADD003F5CFB /* PyExtraFairwareReminder.h */,
);
name = dgbase;
sourceTree = "<group>";
@@ -487,6 +498,7 @@
CE81135812E5CE6D00A36C80 /* Preferences.xib in Resources */,
CE8113EB12E5CE9A00A36C80 /* Localizable.strings in Resources */,
CE4526F212E5F55F00005A15 /* core.strings in Resources */,
CE665B3313225AF8003F5CFB /* ExtraFairwareReminder.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -526,6 +538,7 @@
CE79638C12536F4E008D405B /* HSFairwareReminder.m in Sources */,
CE27D3C412CCA43800859E67 /* HSAboutBox.m in Sources */,
CEF0ACCE12DF3C2000B32F7E /* HSRecentFiles.m in Sources */,
CE665B3013225ADD003F5CFB /* ExtraFairwareReminder.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -541,6 +554,15 @@
name = core.strings;
sourceTree = SOURCE_ROOT;
};
CE665B3113225AF8003F5CFB /* ExtraFairwareReminder.xib */ = {
isa = PBXVariantGroup;
children = (
CE665B3213225AF8003F5CFB /* en */,
CE665B3413225B07003F5CFB /* fr */,
);
name = ExtraFairwareReminder.xib;
sourceTree = SOURCE_ROOT;
};
CE79638412536C94008D405B /* FairwareReminder.xib */ = {
isa = PBXVariantGroup;
children = (

View File

@@ -35,6 +35,11 @@ DEBUG_MODE_PREFERENCE = 'DebugMode'
class NoScannableFileError(Exception):
pass
class DestType:
Direct = 0
Relative = 1
Absolute = 2
class DupeGuru(RegistrableApplication, Broadcaster):
def __init__(self, data_module, appdata):
if self.get_default(DEBUG_MODE_PREFERENCE, False):
@@ -98,12 +103,19 @@ class DupeGuru(RegistrableApplication, Broadcaster):
except EnvironmentError:
return None
def _results_changed(self):
self.selected_dupes = [d for d in self.selected_dupes
if self.results.get_group_of_duplicate(d) is not None]
self.notify('results_changed')
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._results_changed()
elif jobid in {JOB_LOAD, JOB_MOVE, JOB_DELETE}:
self._results_changed()
if jobid in {JOB_COPY, JOB_MOVE, JOB_DELETE}:
self.notify('problems_changed')
@staticmethod
@@ -145,6 +157,9 @@ class DupeGuru(RegistrableApplication, Broadcaster):
def _set_default(self, key_name, value):
raise NotImplementedError()
def _show_extra_fairware_reminder(self):
raise NotImplementedError()
#--- Public
def add_directory(self, d):
try:
@@ -171,7 +186,11 @@ class DupeGuru(RegistrableApplication, Broadcaster):
filter = escape(filter, set('()[]\\.|+?^'))
filter = escape(filter, '*', '.')
self.results.apply_filter(filter)
self.notify('results_changed')
self._results_changed()
def show_extra_fairware_reminder_if_needed(self):
if self.results.mark_count > 100 and self.should_show_fairware_reminder:
self._show_extra_fairware_reminder()
def clean_empty_dirs(self, path):
if self.options['clean_empty_dirs']:
@@ -182,17 +201,17 @@ class DupeGuru(RegistrableApplication, Broadcaster):
"""
copy: True = Copy False = Move
destination: string.
dest_type: 0 = right in destination.
1 = relative re-creation.
2 = absolute re-creation.
dest_type: DestType constants
"""
source_path = dupe.path
location_path = first(p for p in self.directories if dupe.path in p)
dest_path = Path(destination)
if dest_type == 2:
dest_path = dest_path + source_path[1:-1] #Remove drive letter and filename
elif dest_type == 1:
dest_path = dest_path + source_path[location_path:-1]
if dest_type in {DestType.Relative, DestType.Absolute}:
# no filename, no windows drive letter
source_base = source_path.remove_drive_letter()[:-1]
if dest_type == DestType.Relative:
source_base = source_base[location_path:]
dest_path = dest_path + source_base
if not io.exists(dest_path):
io.makedirs(dest_path)
# Raises an EnvironmentError if there's a problem
@@ -211,10 +230,12 @@ class DupeGuru(RegistrableApplication, Broadcaster):
j.start_job(self.results.mark_count)
self.results.perform_on_marked(op, not copy)
self.show_extra_fairware_reminder_if_needed()
jobid = JOB_COPY if copy else JOB_MOVE
self._start_job(jobid, do)
def delete_marked(self, replace_with_hardlinks=False):
self.show_extra_fairware_reminder_if_needed()
self._start_job(JOB_DELETE, self._do_delete, replace_with_hardlinks)
def export_to_xhtml(self, column_ids):
@@ -316,7 +337,7 @@ class DupeGuru(RegistrableApplication, Broadcaster):
def remove_marked(self):
self.results.perform_on_marked(lambda x:None, True)
self.notify('results_changed')
self._results_changed()
def remove_selected(self):
self.remove_duplicates(self.selected_dupes)
@@ -356,7 +377,7 @@ class DupeGuru(RegistrableApplication, Broadcaster):
if not self.directories.has_any_file():
raise NoScannableFileError()
self.results.groups = []
self.notify('results_changed')
self._results_changed()
self._start_job(JOB_SCAN, do)
def toggle_selected_mark_state(self):

View File

@@ -64,6 +64,9 @@ class DupeGuru(app.DupeGuru):
def _set_default(self, key_name, value):
NSUserDefaults.standardUserDefaults().setObject_forKey_(value, key_name)
def _show_extra_fairware_reminder(self):
NSNotificationCenter.defaultCenter().postNotificationName_object_userInfo_('ShowExtraFairwareReminder', self, None)
#--- Public
def start_scanning(self):
self._select_dupes([])

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Created By: Virgil Dupras
# Created On: 2010-02-02
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
@@ -17,6 +16,7 @@ from .gui.problem_dialog import ProblemDialog
from .gui.problem_table import ProblemTable
from .gui.result_table import ResultTable
from .gui.stats_label import StatsLabel
from .gui.extra_fairware_reminder import ExtraFairwareReminder
class PyDupeGuruBase(PyFairware):
#---Directories
@@ -236,3 +236,26 @@ class PyProblemDialog(PyGUIObject):
class PyProblemTable(PyTable):
py_class = ProblemTable
class PyExtraFairwareReminder(PyGUIObject):
py_class = ExtraFairwareReminder
def start(self):
self.py.start()
def updateButton(self):
self.py.update_button()
# model --> view
def start_timer(self):
self.cocoa.startTimer()
def stop_timer(self):
self.cocoa.stopTimer()
def enable_button(self):
self.cocoa.enableButton()
def set_button_text(self, text):
self.cocoa.setButtonText_(text)

View File

@@ -16,12 +16,12 @@ STATE_ORDER = [STATE_NORMAL, STATE_REFERENCE, STATE_EXCLUDED]
# Lazily loads children
class DirectoryNode(Node):
def __init__(self, app, path, name):
def __init__(self, tree, path, name):
Node.__init__(self, name)
self._app = app
self._tree = tree
self._directory_path = path
self._loaded = False
self._state = STATE_ORDER.index(self._app.directories.get_state(path))
self._state = STATE_ORDER.index(self._tree.app.directories.get_state(path))
def __len__(self):
if not self._loaded:
@@ -30,9 +30,9 @@ class DirectoryNode(Node):
def _load(self):
self.clear()
subpaths = self._app.directories.get_subfolders(self._directory_path)
subpaths = self._tree.app.directories.get_subfolders(self._directory_path)
for path in subpaths:
self.append(DirectoryNode(self._app, path, path[-1]))
self.append(DirectoryNode(self._tree, path, path[-1]))
self._loaded = True
# The state propery is an index to the combobox
@@ -46,7 +46,9 @@ class DirectoryNode(Node):
return
self._state = value
state = STATE_ORDER[value]
self._app.directories.set_state(self._directory_path, state)
self._tree.app.directories.set_state(self._directory_path, state)
self._tree._refresh()
self._tree.view.refresh()
class DirectoryTree(GUIObject, Tree):
@@ -62,7 +64,7 @@ class DirectoryTree(GUIObject, Tree):
def _refresh(self):
self.clear()
for path in self.app.directories:
self.append(DirectoryNode(self.app, path, str(path)))
self.append(DirectoryNode(self, path, str(path)))
def add_directory(self, path):
self.app.add_directory(path)

View File

@@ -0,0 +1,30 @@
# Created By: Virgil Dupras
# Created On: 2011-03-04
# Copyright 2011 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 time
from hscommon.trans import tr
from .base import GUIObject
class ExtraFairwareReminder(GUIObject):
def start(self):
self.start_time = time.time()
self.view.start_timer()
def update_button(self):
elapsed = time.time() - self.start_time
remaining = 60 - round(elapsed)
if remaining > 0:
text = tr("Continue ({})").format(remaining)
else:
text = tr("Continue")
self.view.enable_button()
self.view.stop_timer()
self.view.set_button_text(text)

View File

@@ -259,11 +259,14 @@ class Results(Markable):
group = self.get_group_of_duplicate(dupe)
if dupe not in group.dupes:
return
ref = group.ref
group.remove_dupe(dupe, False)
del self.__group_of_duplicate[dupe]
self._remove_mark_flag(dupe)
self.__total_count -= 1
self.__total_size -= dupe.size
if not group:
del self.__group_of_duplicate[ref]
self.__groups.remove(group)
if self.__filtered_groups:
self.__filtered_groups.remove(group)

View File

@@ -390,6 +390,16 @@ class TestCaseDupeGuruWithResults:
add_fake_files_to_directories(app.directories, self.objects) # We want the scan to at least start
app.start_scanning() # will be cancelled immediately
eq_(len(self.rtable), 0)
def test_selected_dupes_after_removal(self, do_setup):
# Purge the app's `selected_dupes` attribute when removing dupes, or else it might cause a
# crash later with None refs.
app = self.app
app.results.mark_all()
self.rtable.select([0, 1, 2, 3, 4])
app.remove_marked()
eq_(len(self.rtable), 0)
eq_(app.selected_dupes, [])
class TestCaseDupeGuru_renameSelected:
def pytest_funcarg__do_setup(self, request):
@@ -452,3 +462,31 @@ class TestCaseDupeGuru_renameSelected:
assert 'foo bar 2' in names
eq_(g.dupes[0].name, 'foo bar 2')
class TestAppWithDirectoriesInTree:
def pytest_funcarg__do_setup(self, request):
tmpdir = request.getfuncargvalue('tmpdir')
p = Path(str(tmpdir))
io.mkdir(p + 'sub1')
io.mkdir(p + 'sub2')
io.mkdir(p + 'sub3')
self.app = DupeGuru()
self.dtree_gui = CallLogger()
self.dtree = DirectoryTree(self.dtree_gui, self.app)
self.dtree.connect()
self.dtree.add_directory(p)
self.dtree_gui.clear_calls()
def test_set_root_as_ref_makes_subfolders_ref_as_well(self, do_setup):
# Setting a node state to something also affect subnodes. These subnodes must be correctly
# refreshed.
node = self.dtree[0]
eq_(len(node), 3) # a len() call is required for subnodes to be loaded
subnode = node[0]
node.state = 1 # the state property is a state index
node = self.dtree[0]
eq_(len(node), 3)
subnode = node[0]
eq_(subnode.state, 1)
self.dtree_gui.check_gui_calls(['refresh'])

View File

@@ -231,6 +231,15 @@ class TestCaseResultsWithSomeGroups:
self.results.perform_on_marked(lambda x:None, True)
assert not self.results.is_modified
def test_group_of_duplicate_after_removal(self):
# removing a duplicate also removes it from the dupe:group map.
dupe = self.results.groups[1].dupes[0]
ref = self.results.groups[1].ref
self.results.remove_duplicates([dupe])
assert self.results.get_group_of_duplicate(dupe) is None
# also remove group ref
assert self.results.get_group_of_duplicate(ref) is None
class TestCaseResultsWithSavedResults:
def setup_method(self, method):

View File

@@ -1,2 +1,2 @@
__version__ = '2.0.0'
__version__ = '2.1.0'
__appname__ = 'dupeGuru Picture Edition'

View File

@@ -11,12 +11,11 @@ import plistlib
import logging
import re
from appscript import app, k, CommandError, ApplicationNotFoundError
from appscript import app, its, CommandError, ApplicationNotFoundError
from hscommon import io
from hscommon.util import get_file_ext, remove_invalid_xml
from hscommon.path import Path
from hscommon.cocoa import as_fetch
from hscommon.cocoa.objcmin import NSUserDefaults, NSURL
from hscommon.trans import tr
@@ -151,37 +150,28 @@ class DupeGuruPE(app_cocoa.DupeGuru):
return self._do_delete_dupe(dupe, replace_with_hardlinks)
marked = [dupe for dupe in self.results.dupes if self.results.is_marked(dupe)]
self.path2iphoto = {}
j.start_job(self.results.mark_count, tr("Sending dupes to the Trash"))
if any(isinstance(dupe, IPhoto) for dupe in marked):
j = j.start_subjob([6, 4], tr("Probing iPhoto. Don't touch it during the operation!"))
j.add_progress(0, desc=tr("Talking to iPhoto. Don't touch it!"))
try:
a = app('iPhoto')
a.activate(timeout=0)
a.select(a.photo_library_album(timeout=0), timeout=0)
photos = as_fetch(a.photo_library_album().photos, k.item)
for photo in j.iter_with_progress(photos):
try:
self.path2iphoto[str(photo.image_path(timeout=0))] = photo
except CommandError:
pass
except (CommandError, RuntimeError, ApplicationNotFoundError):
pass
j.start_job(self.results.mark_count, tr("Sending dupes to the Trash"))
self.results.perform_on_marked(op, True)
del self.path2iphoto
def _do_delete_dupe(self, dupe, replace_with_hardlinks):
if isinstance(dupe, IPhoto):
if str(dupe.path) in self.path2iphoto:
photo = self.path2iphoto[str(dupe.path)]
try:
a = app('iPhoto')
a.remove(photo, timeout=0)
except (CommandError, RuntimeError) as e:
raise EnvironmentError(str(e))
else:
msg = "Could not find photo %s in iPhoto Library" % str(dupe.path)
try:
a = app('iPhoto')
[photo] = a.photo_library_album().photos[its.image_path == str(dupe.path)]()
a.remove(photo, timeout=0)
except ValueError:
msg = "Could not find photo '{}' in iPhoto Library".format(str(dupe.path))
raise EnvironmentError(msg)
except (CommandError, RuntimeError) as e:
raise EnvironmentError(str(e))
else:
app_cocoa.DupeGuru._do_delete_dupe(self, dupe, replace_with_hardlinks)

View File

@@ -8,8 +8,9 @@
import logging
import multiprocessing
from collections import defaultdict, deque
from itertools import combinations
from hscommon.util import extract
from hscommon.trans import tr
from jobprogress import job
@@ -17,15 +18,38 @@ from core.engine import Match
from .block import avgdiff, DifferentBlockCountError, NoBlocksError
from .cache import Cache
# OPTIMIZATION NOTES:
# The bottleneck of the matching phase is CPU, which is why we use multiprocessing. However, another
# bottleneck that shows up when a lot of pictures are involved is Disk IO's because blocks
# constantly have to be read from disks by subprocesses. This problem is especially big on CPUs
# with a lot of cores. Therefore, we must minimize Disk IOs. The best way to achieve that is to
# separate the files to scan in "chunks" and it's by chunk that blocks are read in memory and
# compared to each other. Each file in a chunk has to be compared to each other, of course, but also
# to files in other chunks. So chunkifying doesn't save us any actual comparison, but the advantage
# is that instead of reading blocks from disk number_of_files**2 times, we read it
# number_of_files*number_of_chunks times.
# Determining the right chunk size is tricky, bceause if it's too big, too many blocks will be in
# memory at the same time and we might end up with memory trashing, which is awfully slow. So,
# because our *real* bottleneck is CPU, the chunk size must simply be enough so that the CPU isn't
# starved by Disk IOs.
MIN_ITERATIONS = 3
BLOCK_COUNT_PER_SIDE = 15
DEFAULT_CHUNK_SIZE = 1000
MIN_CHUNK_SIZE = 100
# Enough so that we're sure that the main thread will not wait after a result.get() call
# cpucount*2 should be enough to be sure that the spawned process will not wait after the results
# cpucount+1 should be enough to be sure that the spawned process will not wait after the results
# collection made by the main process.
RESULTS_QUEUE_LIMIT = multiprocessing.cpu_count() * 2
try:
RESULTS_QUEUE_LIMIT = multiprocessing.cpu_count() + 1
except Exception:
# I had an IOError on app launch once. It seems to be a freak occurrence. In any case, we want
# the app to launch, so let's just put an arbitrary value.
logging.warning("Had problems to determine cpu count on launch.")
RESULTS_QUEUE_LIMIT = 8
def prepare_pictures(pictures, cache_path, j=job.nulljob):
def prepare_pictures(pictures, cache_path, with_dimensions, j=job.nulljob):
# The MemoryError handlers in there use logging without first caring about whether or not
# there is enough memory left to carry on the operation because it is assumed that the
# MemoryError happens when trying to read an image file, which is freed from memory by the
@@ -36,7 +60,8 @@ def prepare_pictures(pictures, cache_path, j=job.nulljob):
for picture in j.iter_with_progress(pictures, tr("Analyzed %d/%d pictures")):
picture.unicode_path = str(picture.path)
logging.debug("Analyzing picture at {}".format(picture.unicode_path))
picture.dimensions # pre-read dimensions
if with_dimensions:
picture.dimensions # pre-read dimensions
try:
if picture.unicode_path not in cache:
blocks = picture.get_blocks(BLOCK_COUNT_PER_SIDE)
@@ -53,18 +78,42 @@ def prepare_pictures(pictures, cache_path, j=job.nulljob):
cache.close()
return prepared
def get_chunks(pictures):
min_chunk_count = multiprocessing.cpu_count() * 2 # have enough chunks to feed all subprocesses
chunk_count = len(pictures) // DEFAULT_CHUNK_SIZE
chunk_count = max(min_chunk_count, chunk_count)
chunk_size = (len(pictures) // chunk_count) + 1
chunk_size = max(MIN_CHUNK_SIZE, chunk_size)
logging.info("Creating {} chunks with a chunk size of {} for {} pictures".format(
chunk_count, chunk_size, len(pictures)))
chunks = [pictures[i:i+chunk_size] for i in range(0, len(pictures), chunk_size)]
return chunks
def get_match(first, second, percentage):
if percentage < 0:
percentage = 0
return Match(first, second, percentage)
def async_compare(ref_id, other_ids, dbname, threshold):
def async_compare(ref_ids, other_ids, dbname, threshold, picinfo):
# The list of ids in ref_ids have to be compared to the list of ids in other_ids. other_ids
# can be None. In this case, ref_ids has to be compared with itself
# picinfo is a dictionary {pic_id: (dimensions, is_ref)}
cache = Cache(dbname)
limit = 100 - threshold
ref_blocks = cache[ref_id]
pairs = cache.get_multiple(other_ids)
ref_pairs = list(cache.get_multiple(ref_ids))
if other_ids is not None:
other_pairs = list(cache.get_multiple(other_ids))
comparisons_to_do = [(r, o) for r in ref_pairs for o in other_pairs]
else:
comparisons_to_do = list(combinations(ref_pairs, 2))
results = []
for other_id, other_blocks in pairs:
for (ref_id, ref_blocks), (other_id, other_blocks) in comparisons_to_do:
ref_dimensions, ref_is_ref = picinfo[ref_id]
other_dimensions, other_is_ref = picinfo[other_id]
if ref_is_ref and other_is_ref:
continue
if ref_dimensions != other_dimensions:
continue
try:
diff = avgdiff(ref_blocks, other_blocks, limit, MIN_ITERATIONS)
percentage = 100 - diff
@@ -76,48 +125,60 @@ def async_compare(ref_id, other_ids, dbname, threshold):
return results
def getmatches(pictures, cache_path, threshold=75, match_scaled=False, j=job.nulljob):
def get_picinfo(p):
if match_scaled:
return (None, p.is_ref)
else:
return (p.dimensions, p.is_ref)
def collect_results(collect_all=False):
# collect results and wait until the queue is small enough to accomodate a new results.
nonlocal async_results, matches, comparison_count
limit = 0 if collect_all else RESULTS_QUEUE_LIMIT
while len(async_results) > limit:
ready, working = extract(lambda r: r.ready(), async_results)
for result in ready:
matches += result.get()
async_results.remove(result)
comparison_count += 1
progress_msg = tr("Performed %d/%d chunk matches") % (comparison_count, len(comparisons_to_do))
j.set_progress(comparison_count, progress_msg)
j = j.start_subjob([3, 7])
pictures = prepare_pictures(pictures, cache_path, j)
pictures = prepare_pictures(pictures, cache_path, with_dimensions=not match_scaled, j=j)
j = j.start_subjob([9, 1], tr("Preparing for matching"))
cache = Cache(cache_path)
id2picture = {}
dimensions2pictures = defaultdict(set)
for picture in pictures:
try:
picture.cache_id = cache.get_id(picture.unicode_path)
id2picture[picture.cache_id] = picture
if not match_scaled:
dimensions2pictures[picture.dimensions].add(picture)
except ValueError:
pass
cache.close()
pictures = [p for p in pictures if hasattr(p, 'cache_id')]
pool = multiprocessing.Pool()
async_results = deque()
async_results = []
matches = []
pictures_copy = set(pictures)
for ref in j.iter_with_progress(pictures, tr("Matched %d/%d pictures")):
others = pictures_copy if match_scaled else dimensions2pictures[ref.dimensions]
others.remove(ref)
if ref.is_ref:
# Don't spend time comparing two ref pics together.
others = [pic for pic in others if not pic.is_ref]
if others:
cache_ids = [f.cache_id for f in others]
# We limit the number of cache_ids we send for multi-processing because otherwise, we
# might get an error saying "String or BLOB exceeded size limit"
ARG_LIMIT = 1000
while cache_ids:
args = (ref.cache_id, cache_ids[:ARG_LIMIT], cache_path, threshold)
async_results.append(pool.apply_async(async_compare, args))
cache_ids = cache_ids[ARG_LIMIT:]
# We use a while here because it's possible that more than one result has been added if
# ARG_LIMIT has been reached.
while len(async_results) > RESULTS_QUEUE_LIMIT:
result = async_results.popleft()
matches.extend(result.get())
for result in async_results: # process the rest of the results
matches.extend(result.get())
chunks = get_chunks(pictures)
# We add a None element at the end of the chunk list because each chunk has to be compared
# with itself. Thus, each chunk will show up as a ref_chunk having other_chunk set to None once.
comparisons_to_do = list(combinations(chunks + [None], 2))
comparison_count = 0
j.start_job(len(comparisons_to_do))
for ref_chunk, other_chunk in comparisons_to_do:
picinfo = {p.cache_id: get_picinfo(p) for p in ref_chunk}
ref_ids = [p.cache_id for p in ref_chunk]
if other_chunk is not None:
other_ids = [p.cache_id for p in other_chunk]
picinfo.update({p.cache_id: get_picinfo(p) for p in other_chunk})
else:
other_ids = None
args = (ref_ids, other_ids, cache_path, threshold, picinfo)
async_results.append(pool.apply_async(async_compare, args))
collect_results()
collect_results(collect_all=True)
pool.close()
result = []
for ref_id, other_id, percentage in j.iter_with_progress(matches, tr("Verified %d/%d matches"), every=10):
@@ -126,6 +187,8 @@ def getmatches(pictures, cache_path, threshold=75, match_scaled=False, j=job.nul
if percentage == 100 and ref.md5 != other.md5:
percentage = 99
if percentage >= threshold:
ref.dimensions # pre-read dimensions for display in results
other.dimensions
result.append(get_match(ref, other, percentage))
return result

View File

@@ -1,2 +1,2 @@
__version__ = '3.0.1'
__version__ = '3.0.2'
__appname__ = 'dupeGuru'

View File

@@ -8,5 +8,5 @@ Homepage: http://www.hardcoded.net
Package: dupeguru-me
Architecture: any
Depends: python3 (>= 3.1)
Depends: python3.1
Description: dupeGuru Music Edition

View File

@@ -8,5 +8,5 @@ Homepage: http://www.hardcoded.net
Package: dupeguru-pe
Architecture: any
Depends: python3 (>= 3.1)
Depends: python3.1
Description: dupeGuru Picture Edition

View File

@@ -8,5 +8,5 @@ Homepage: http://www.hardcoded.net
Package: dupeguru-se
Architecture: any
Depends: python3 (>= 3.1)
Depends: python3.1
Description: dupeGuru

View File

@@ -1,3 +1,13 @@
=== 2.1.0 (2011-03-07)
* Improved scanning speed, especially for big scans with a lot of CPU cores.
* Improved iPhoto integration. [Mac OS X]
* Fixed crash after removing marked dupes. (#140)
* Fixed crash on error handling. [Windows] (#144)
* Fixed crash on copy/move. [Windows] (#148)
* Fixed crash when launching dupeGuru from a very long folder name. [Mac OS X] (#119)
* Tweaked Fairware reminders.
=== 2.0.0 (2011-01-29)
* Re-designed the UI. (#129)

View File

@@ -1,3 +1,13 @@
=== 3.0.2 (2011-03-16)
* Fixed crash after removing marked dupes. (#140)
* Fixed crash on error handling. [Windows] (#144)
* Fixed crash on copy/move. [Windows] (#148)
* Fixed crash when launching dupeGuru from a very long folder name. [Mac OS X] (#119)
* Fixed a refresh bug in directory panel. (#153)
* Improved reliability of the "Send to Trash" operation. [Linux]
* Tweaked Fairware reminders.
=== 3.0.1 (2011-01-27)
* Restored the context menu which had been broken in 3.0.0. [Mac OS X] (#133)

View File

@@ -10,6 +10,7 @@ import sys
import logging
import os
import os.path as op
import io
from PyQt4.QtCore import QTimer, QObject, QCoreApplication, QUrl, QProcess, SIGNAL, pyqtSignal
from PyQt4.QtGui import QDesktopServices, QFileDialog, QDialog, QMessageBox, QApplication
@@ -25,6 +26,7 @@ from qtlib.recent import Recent
from qtlib.reg import Registration
from . import platform
from .extra_fairware_reminder import ExtraFairwareReminder
from .result_window import ResultWindow
from .directories_dialog import DirectoriesDialog
from .problem_dialog import ProblemDialog
@@ -38,6 +40,11 @@ JOBID2TITLE = {
JOB_DELETE: tr("Sending files to the recycle bin"),
}
class SysWrapper(io.IOBase):
def write(self, s):
if s.strip(): # don't log empty stuff
logging.warning(s)
class DupeGuru(DupeGuruBase, QObject):
LOGO_NAME = '<replace this>'
NAME = '<replace this>'
@@ -49,6 +56,10 @@ class DupeGuru(DupeGuruBase, QObject):
# For basicConfig() to work, we have to be sure that no logging has taken place before this call.
logging.basicConfig(filename=op.join(appdata, 'debug.log'), level=logging.WARNING,
format='%(asctime)s - %(levelname)s - %(message)s')
if sys.stderr is None: # happens under a cx_freeze environment
sys.stderr = SysWrapper()
if sys.stdout is None:
sys.stdout = SysWrapper()
self.prefs = self._create_preferences()
self.prefs.load()
DupeGuruBase.__init__(self, data_module, appdata)
@@ -153,6 +164,10 @@ class DupeGuru(DupeGuruBase, QObject):
def _set_default(self, key, value):
self.prefs.set_value(key, value)
def _show_extra_fairware_reminder(self):
dialog = ExtraFairwareReminder(self.directories_dialog, self)
dialog.exec_()
def add_selected_to_ignore_list(self):
dupes = self.without_ref(self.selected_dupes)
if not dupes:

View File

@@ -8,8 +8,8 @@
import urllib.parse
from PyQt4.QtCore import pyqtSignal, Qt, QRect, QEvent, QPoint, QUrl
from PyQt4.QtGui import (QComboBox, QStyledItemDelegate, QMouseEvent, QApplication, QBrush, QStyle,
from PyQt4.QtCore import pyqtSignal, Qt, QRect, QUrl
from PyQt4.QtGui import (QComboBox, QStyledItemDelegate, QApplication, QBrush, QStyle,
QStyleOptionComboBox, QStyleOptionViewItemV4)
from hscommon.trans import tr
@@ -47,11 +47,7 @@ class DirectoriesDelegate(QStyledItemDelegate):
def setEditorData(self, editor, index):
value = index.model().data(index, Qt.EditRole)
editor.setCurrentIndex(value);
press = QMouseEvent(QEvent.MouseButtonPress, QPoint(0, 0), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier)
release = QMouseEvent(QEvent.MouseButtonRelease, QPoint(0, 0), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier)
QApplication.sendEvent(editor, press)
QApplication.sendEvent(editor, release)
# editor.showPopup() # this causes a weird glitch. the ugly workaround is above.
editor.showPopup()
def setModelData(self, editor, model, index):
value = editor.currentIndex()

View File

@@ -0,0 +1,91 @@
# Created By: Virgil Dupras
# Created On: 2011-03-04
# Copyright 2011 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 sys
from PyQt4.QtCore import Qt, QUrl, QTimer
from PyQt4.QtGui import (QDialog, QDesktopServices, QApplication, QVBoxLayout, QHBoxLayout, QLabel,
QFont, QSpacerItem, QSizePolicy, QPushButton)
from hscommon.trans import tr as trbase, trmsg as trmsgbase
tr = lambda s: trbase(s, "ExtraFairwareReminder")
trmsg = lambda s: trmsgbase(s, "ExtraFairwareReminder")
from core.gui.extra_fairware_reminder import ExtraFairwareReminder as ExtraFairwareReminderModel
class ExtraFairwareReminder(QDialog):
def __init__(self, parent, app):
flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint
QDialog.__init__(self, parent, flags)
self.setModal(True)
self.app = app
self.model = ExtraFairwareReminderModel(self, app)
self._setupUi()
self.continueButton.setEnabled(False)
self.continueButton.clicked.connect(self.accept)
self.contributeButton.clicked.connect(self.contributeClicked)
self.model.start()
def _setupUi(self):
self.setWindowTitle(tr("Sorry, I must insist"))
dlg_height = 410 if sys.platform == 'linux2' else 330
self.resize(380, dlg_height)
self.verticalLayout = QVBoxLayout(self)
self.descLabel = QLabel(self)
self.descLabel.setText(trmsg("ExtraFairwarePromptMsg"))
self.descLabel.setWordWrap(True)
self.verticalLayout.addWidget(self.descLabel)
self.reasonLabel = QLabel(self)
self.reasonLabel.setText(trmsg("ExtraFairwareReasonMsg"))
self.reasonLabel.setWordWrap(True)
font = QFont()
font.setWeight(75)
font.setBold(True)
self.reasonLabel.setFont(font)
self.verticalLayout.addWidget(self.reasonLabel)
self.horizontalLayout = QHBoxLayout()
spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.contributeButton = QPushButton(self)
self.contributeButton.setText(tr("Contribute"))
self.horizontalLayout.addWidget(self.contributeButton)
self.continueButton = QPushButton(self)
self.continueButton.setText(tr("Continue"))
self.horizontalLayout.addWidget(self.continueButton)
self.verticalLayout.addLayout(self.horizontalLayout)
#--- model --> view
def start_timer(self):
self._timer = QTimer()
self._timer.setInterval(200)
self._timer.timeout.connect(self.model.update_button)
self._timer.start()
def stop_timer(self):
self._timer.stop()
del self._timer
def enable_button(self):
self.continueButton.setEnabled(True)
def set_button_text(self, text):
self.continueButton.setText(text)
#--- Events
def contributeClicked(self):
url = QUrl('http://open.hardcoded.net/contribute/')
QDesktopServices.openUrl(url)
if __name__ == '__main__':
app = QApplication([])
class FakeReg:
app = app
dialog = ExtraFairwareReminder(None, FakeReg())
dialog.show()
sys.exit(app.exec_())

View File

@@ -100,4 +100,24 @@
<translation>Picture cache cleared.</translation>
</message>
</context>
<context>
<name>ExtraFairwareReminder</name>
<message>
<source>ExtraFairwarePromptMsg</source>
<translation>It seems that you found a lot of duplicates. Nice! I must insist, however, that contributions are expected when there are unpaid hours on the project.
You might think &quot;but I'm only going to use this once, I don't have to contribute&quot;. The problem is that most people use dupeGuru only once in a while. If everyone thinks like that, dupeGuru development cannot be funded. It's because of this tendency inherent to dupeGuru's nature that I have to insist here.
If you can't afford to contribute, you can ignore this reminder or send me an e-mail at hsoft@hardcoded.net so I can give you a key to remove this reminder.</translation>
</message>
<message>
<source>ExtraFairwareReasonMsg</source>
<translation>This reminder showed up because:
1. You are processing more than 100 duplicates
2. You have not yet contributed to dupeGuru
3. There are unpaid hours in the project</translation>
</message>
</context>
</TS>

View File

@@ -74,6 +74,15 @@
<translation>Prioritization des groupes</translation>
</message>
<message>
<source>Continue</source>
<translation>Continuer</translation>
</message>
<message>
<source>Continue ({})</source>
<translation>Continuer ({})</translation>
</message>
<message>
<source>Analyzed %d/%d pictures</source>
<translation>Analyzé %d/%d images</translation>
@@ -84,7 +93,7 @@
</message>
<message>
<source>Matched %d/%d pictures</source>
<translation>Comparé %d/%d images</translation>
<translation>%d/%d blocs d'images comparés</translation>
</message>
<message>
<source>Verified %d/%d matches</source>
@@ -629,6 +638,34 @@
</message>
</context>
<!-- ******** ExtraFairwareReminder ******** -->
<context>
<name>ExtraFairwareReminder</name>
<message>
<source>Sorry, I must insist</source>
<translation>Désolé, je dois insister</translation>
</message>
<message>
<source>Contribute</source>
<translation>Contribuer</translation>
</message>
<message>
<source>ExtraFairwarePromptMsg</source>
<translation>Il semble que vous ayez trouvé beaucoup de doublons. Super! Je dois par contre insister que des contributions sont attendues lorsqu'il y'a des heures non-payées au projet.
Vous pensez peut-être &quot;je n'utiliserai ce programme qu'une fois, pas besoin de contribuer&quot;. Le problème c'est que la plupart des utilisateurs de dupeGuru ne l'utilisent qu'une fois. Si tous suivent ce raisonnement, le développement de dupeGuru ne peut pas continuer. C'est à cause de cette tendance inhérente à la nature de dupeGuru que je me vois contraint d'insister ici.
Si vous n'avez pas les moyens de contribuer, ignorez ce message ou envoyez moi un message à hsoft@hardcoded.net pour que je vous envoie une clé d'enregistrement.</translation>
</message>
<message>
<source>ExtraFairwareReasonMsg</source>
<translation>Ce rappel apparaît parce que:
1. Plus de 100 doublons sont traités
2. Vous n'avez pas encore contribué à dupeGuru
3. Il y a des heures non-payées au projet</translation>
</message>
</context>
<!-- ******** Message ******** -->
<context>
<name>message</name>

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python3.1
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
#
# This software is licensed under the "BSD" License as described in the "LICENSE" file,