Skip to content

Commit

Permalink
Removed add to Dock feature and cleaned up the project a little. Bump…
Browse files Browse the repository at this point in the history
…ed up to version 1.2.
  • Loading branch information
Andy Kim committed Dec 14, 2009
1 parent 097b6fd commit 56c1544
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 107 deletions.
24 changes: 14 additions & 10 deletions English.lproj/MainMenu.xib
Expand Up @@ -2,13 +2,13 @@
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
<data>
<int key="IBDocument.SystemTarget">1060</int>
<string key="IBDocument.SystemVersion">10B504</string>
<string key="IBDocument.InterfaceBuilderVersion">732</string>
<string key="IBDocument.AppKitVersion">1038.2</string>
<string key="IBDocument.HIToolboxVersion">437.00</string>
<string key="IBDocument.SystemVersion">10C540</string>
<string key="IBDocument.InterfaceBuilderVersion">740</string>
<string key="IBDocument.AppKitVersion">1038.25</string>
<string key="IBDocument.HIToolboxVersion">458.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">732</string>
<string key="NS.object.0">740</string>
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
Expand Down Expand Up @@ -2060,7 +2060,7 @@
<reference key="source" ref="976324537"/>
<reference key="destination" ref="972006081"/>
</object>
<int key="connectionID">532</int>
<int key="connectionID">535</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
Expand Down Expand Up @@ -3486,7 +3486,7 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="1"/>
<string>{{525, 802}, {197, 73}}</string>
<string>{{380, 836}, {433, 20}}</string>
<string>{{380, 394}, {433, 20}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="1"/>
<string>{74, 862}</string>
Expand All @@ -3511,9 +3511,9 @@
<integer value="1"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="1"/>
<string>{{580, 339}, {480, 360}}</string>
<string>{{1054, 339}, {480, 360}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{580, 339}, {480, 360}}</string>
<string>{{1054, 339}, {480, 360}}</string>
<boolean value="NO"/>
<string>{{33, 99}, {480, 360}}</string>
<string>{3.40282e+38, 3.40282e+38}</string>
Expand Down Expand Up @@ -3652,14 +3652,18 @@
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">534</int>
<int key="maxID">535</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">LetsMoveAppDelegate</string>
<string key="superclassName">NSObject</string>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">window</string>
<string key="NS.object.0">NSWindow</string>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">LetsMoveAppDelegate.h</string>
Expand Down
3 changes: 0 additions & 3 deletions French.lproj/MoveApplication.strings
Expand Up @@ -6,6 +6,3 @@
"Move to Applications folder?" = "Déplacer dans le dossier Applications?";
"Note that this will require an administrator password." = "Notez que vous aurez besoin de votre mot de passe administrateur.";
"This will keep your Downloads folder uncluttered." = "Ceci permet de ne pas encombrer votre dossier Téléchargements.";

/* Needs translation */
/*"Add to Dock" = "" */
Binary file modified Japanese.lproj/MoveApplication.strings
Binary file not shown.
18 changes: 0 additions & 18 deletions LetsMove.xcodeproj/project.pbxproj
Expand Up @@ -144,7 +144,6 @@
buildPhases = (
8D11072C0486CEB800E47090 /* Sources */,
8D11072E0486CEB800E47090 /* Frameworks */,
A10D5AB1106C03E400E53420 /* Generate Strings File */,
8D1107290486CEB800E47090 /* Resources */,
);
buildRules = (
Expand Down Expand Up @@ -196,23 +195,6 @@
};
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
A10D5AB1106C03E400E53420 /* Generate Strings File */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Generate Strings File";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/usr/bin/genstrings -o English.lproj PFMoveApplication.m";
};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
8D11072C0486CEB800E47090 /* Sources */ = {
isa = PBXSourcesBuildPhase;
Expand Down
84 changes: 14 additions & 70 deletions PFMoveApplication.m
@@ -1,5 +1,5 @@
//
// PFMoveApplication.m, version 1.1
// PFMoveApplication.m, version 1.2
// LetsMove
//
// Created by Andy Kim at Potion Factory LLC on 9/17/09
Expand All @@ -10,7 +10,7 @@
// Andy Kim
// John Brayton
// Chad Sellers
// Eita Hayashi (Japanese localization)
// Kevin LaCoste
// Rasmus Andersson / Spotify
//

Expand All @@ -28,30 +28,12 @@
#define kStrMoveApplicationButtonDoNotMove _I10NS(@"Do Not Move")
#define kStrMoveApplicationQuestionInfoWillRequirePasswd _I10NS(@"Note that this will require an administrator password.")
#define kStrMoveApplicationQuestionInfoInDownloadsFolder _I10NS(@"This will keep your Downloads folder uncluttered.")
#define kStrMoveApplicationAddToDock _I10NS(@"Add to Dock")

// Need to be defined
#ifndef NSAppKitVersionNumber10_4
#define NSAppKitVersionNumber10_4 824
#endif

// Experimental feature: Add to Dock
//
// Enabling this adds a "Add to Dock" checkbox, enabling the user to
// automatically have the app added to the Dock.
//
// Note: This is a feature you should think really hard about before enabling.
// The OS X user experience will be bad unless the user in the general use
// cases _do want_ the icon in the Dock.
#ifndef PFMOVE_INCLUDE_ADD_TO_DOCK_OPTION
#define PFMOVE_INCLUDE_ADD_TO_DOCK_OPTION 0
#endif
// Controls if the checkbox is checked by default or not
#ifndef PFMOVE_INCLUDE_ADD_TO_DOCK_DEFAULT_STATE
#define PFMOVE_INCLUDE_ADD_TO_DOCK_DEFAULT_STATE NSOnState
#endif


static NSString *AlertSuppressKey = @"moveToApplicationsFolderAlertSuppress";


Expand All @@ -63,8 +45,10 @@
static BOOL AuthorizedInstall(NSString *srcPath, NSString *dstPath, BOOL *canceled);
static BOOL CopyBundle(NSString *srcPath, NSString *dstPath);


// Main worker function
void PFMoveToApplicationsFolderIfNecessary() {
void PFMoveToApplicationsFolderIfNecessary()
{
// Skip if user suppressed the alert before
if ([[NSUserDefaults standardUserDefaults] boolForKey:AlertSuppressKey]) return;

Expand All @@ -83,7 +67,7 @@ void PFMoveToApplicationsFolderIfNecessary() {

// Fail silently if there's no access to delete the original application
if (!isLaunchedFromDMG && !bundlePathIsWritable) {
NSLog(@"No access to delete the app. Not offering to move it.");
NSLog(@"INFO -- No access to delete the app. Not offering to move it.");
return;
}

Expand All @@ -96,10 +80,6 @@ void PFMoveToApplicationsFolderIfNecessary() {
// Check if we need admin password to write to the Applications directory
BOOL needAuthorization = ([fm isWritableFileAtPath:applicationsDirectory] == NO);

#if PFMOVE_INCLUDE_ADD_TO_DOCK_OPTION
NSButton *addToDockCheckbox = nil;
#endif

// Setup the alert
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
{
Expand Down Expand Up @@ -128,26 +108,6 @@ void PFMoveToApplicationsFolderIfNecessary() {
NSButton *cancelButton = [alert addButtonWithTitle:kStrMoveApplicationButtonDoNotMove];
[cancelButton setKeyEquivalent:@"\e"];

// Add "Add to Dock" checkbox
#if PFMOVE_INCLUDE_ADD_TO_DOCK_OPTION
// Only go ahead if the app is not already in the Dock
NSTask *ps = [NSTask launchedTaskWithLaunchPath:@"/bin/sh" arguments:[NSArray arrayWithObjects:@"-c", [NSString stringWithFormat:@"defaults read com.apple.dock persistent-apps | grep '%@/' >/dev/null 2>&1", destinationPath], nil]];
[ps waitUntilExit];
if ([ps terminationStatus] != 0) {
NSRect cboxFrame = NSMakeRect(0.0,0.0,[[alert window] frame].size.width,18.0);
NSView *av = [[[NSView alloc] initWithFrame:cboxFrame] autorelease];
addToDockCheckbox = [[[NSButton alloc] initWithFrame:cboxFrame] autorelease];
[addToDockCheckbox setButtonType:NSSwitchButton];
[[addToDockCheckbox cell] setControlSize:NSSmallControlSize];
[[addToDockCheckbox cell] setFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]];
[addToDockCheckbox setState:NSOnState];
[addToDockCheckbox setTitle:kStrMoveApplicationAddToDock];
[addToDockCheckbox sizeToFit];
[av addSubview:addToDockCheckbox];
[alert setAccessoryView:av];
}
#endif

#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_4) {
// Setup suppression button
Expand All @@ -159,26 +119,7 @@ void PFMoveToApplicationsFolderIfNecessary() {
}

if ([alert runModal] == NSAlertFirstButtonReturn) {
NSLog(@"Moving myself to the Applications folder");

// Add to Dock
#if PFMOVE_INCLUDE_ADD_TO_DOCK_OPTION
if (addToDockCheckbox && [addToDockCheckbox state] == NSOnState) {
// Note: here, we could have a if (not already in dock) {... but we trust
// that the initial check (when building the alert box) is ok.
NSLog(@"Adding myself to the Dock");
NSTask *addTask = [NSTask launchedTaskWithLaunchPath:@"/usr/bin/defaults" arguments:[NSArray arrayWithObjects:@"write", @"com.apple.dock", @"persistent-apps", @"-array-add", [NSString stringWithFormat:@"<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>%@</string><key>_CFURLStringType</key><integer>0</integer></dict></dict><key>tile-type</key><string>file-tile</string></dict>", destinationPath], nil]];
[addTask waitUntilExit];
if ([addTask terminationStatus] != 0) {
NSLog(@"failed to add myself to the dock");
}
else {
// Delay reloading of Dock until we guess the new app is running.
// We do this to avoid the "blank icon" bug.
[NSTask launchedTaskWithLaunchPath:@"/bin/sh" arguments:[NSArray arrayWithObjects:@"-c", @"sleep 4; killall -HUP Dock", nil]];
}
}
#endif
NSLog(@"INFO -- Moving myself to the Applications folder");

// Move
if (needAuthorization) {
Expand All @@ -199,13 +140,16 @@ void PFMoveToApplicationsFolderIfNecessary() {
// If a copy already exists in the Applications folder, put it in the Trash
if ([fm fileExistsAtPath:destinationPath]) {
// If the app at destinationPath is running already, give that app focus and exit.
NSTask *ps = [NSTask launchedTaskWithLaunchPath:@"/bin/sh" arguments:[NSArray arrayWithObjects:@"-c", [NSString stringWithFormat:@"ps xa -o pid,comm | grep '%@/' | grep -v grep | cut -d' ' -f1 | grep -v '^%d$' >/dev/null", destinationPath, getpid()], nil]];
NSString *script = [NSString stringWithFormat:@"ps xa -o pid,comm | grep '%@/' | grep -v grep | cut -d' ' -f1 | grep -v '^%d$' >/dev/null", destinationPath, getpid()];
NSTask *ps = [NSTask launchedTaskWithLaunchPath:@"/bin/sh" arguments:[NSArray arrayWithObjects:@"-c", script, nil]];
[ps waitUntilExit];

if ([ps terminationStatus] == 0) {
NSLog(@"Switching to an already running version");
NSLog(@"INFO -- Switching to an already running version");
[[NSTask launchedTaskWithLaunchPath:@"/usr/bin/open" arguments:[NSArray arrayWithObject:destinationPath]] waitUntilExit];
[NSApp terminate:nil];
}

if (!Trash([applicationsDirectory stringByAppendingPathComponent:bundleName]))
goto fail;
}
Expand Down Expand Up @@ -409,7 +353,7 @@ static BOOL CopyBundle(NSString *srcPath, NSString *dstPath)
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_4) {
NSError *error = nil;
if (![fm copyItemAtPath:srcPath toPath:dstPath error:&error]) {
NSLog(@"Could not copy '%@' to '%@' (%@)", srcPath, dstPath, error);
NSLog(@"ERROR -- Could not copy '%@' to '%@' (%@)", srcPath, dstPath, error);
return NO;
}
return YES;
Expand All @@ -430,7 +374,7 @@ static BOOL CopyBundle(NSString *srcPath, NSString *dstPath)
[invocation getReturnValue:&success];

if (!success) {
NSLog(@"Could not copy '%@' to '%@'", srcPath, dstPath);
NSLog(@"ERROR -- Could not copy '%@' to '%@'", srcPath, dstPath);
}

return success;
Expand Down
20 changes: 17 additions & 3 deletions README.markdown
@@ -1,26 +1,40 @@
LetsMove
========

This is a sample project that demonstrates how to move a running Mac OS X application to the Applications folder.
A sample project that demonstrates how to move a running Mac OS X application to the Applications folder.


Version History
---------------

* 1.2
- Copy application from disk image then unmount disk image
- Spanish, French, Dutch, and Russian localizations

* 1.1
- Prefers ~/Applications over /Applications if it exists
- Escape key pushes the "Do Not Move" button

* 1.0 - First release


Requirements
------------
Builds and runs on Mac OS X 10.4 or higher


Contributors:
-------------
* Andy Kim
* John Brayton
* Chad Sellers
* Eita Hayashi (Japanese localization)
* Kevin LaCoste
* Rasmus Andersson / Spotify
* Rasmus Andersson


Translators:
------------
* Eita Hayashi (Japanese)
* Gleb M. Borisov (Russian)
* Wouter Broekhof (Dutch)
* Rasmus Andersson / Spotify (French and Spanish)
3 changes: 0 additions & 3 deletions Spanish.lproj/MoveApplication.strings
Expand Up @@ -6,6 +6,3 @@
"Move to Applications folder?" = "¿Trasladar a la carpeta Aplicaciones?";
"Note that this will require an administrator password." = "Ten en cuenta que esto requerirá la contraseña del administrador.";
"This will keep your Downloads folder uncluttered." = "Esto tendrá tu carpeta de descargas sin amontonar.";

/* Needs translation */
/*"Add to Dock" = "" */

0 comments on commit 56c1544

Please sign in to comment.