Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
501 lines (444 sloc) 15.1 KB
//
// MPActionsController.m
// MPGUI
//
// Created by Juan Germán Castañeda Echevarría on 6/19/09.
// Copyright 2009 UNAM. All rights reserved.
//
#import "MPActionsController.h"
@implementation MPActionsController
- (IBAction)openPreferences:(id)sender {
[NSBundle loadNibNamed:@"Preferences" owner:self];
}
//After choosing the variants, this method is called when the user clicks on the Go button
- (IBAction)installWithVariantsPerform:(id)sender {
if (altWasPressed)
{
[self clearQueue];
}
[variantsPanel close];
[tableController open:nil];
NSLog(@"Staring Installation");
NSArray *selectedPorts = [ports selectedObjects];
id port = [selectedPorts objectAtIndex:0];
//NSLog(@"Lets see %@", [checkboxes[0] title]);
//NSLog(@"Port variants:");
NSMutableString *variantsString = [NSMutableString stringWithCapacity:50];
[variantsString appendString:[port name]];
NSMutableArray *variants=[NSMutableArray arrayWithCapacity:10];
for(UInt i=0; i<[[port valueForKey:@"variants"] count];i++)
{
//NSLog(@"%@",[[port valueForKey:@"variants"] objectAtIndex:i]);
//If the checkbox is checked, the variant is added on the list. If it is a default_variant, a '+' is added in the name,
//to comply with the mportopen arguments
if ([checkboxes[i] state] == NSOnState)
{
if (![checkboxes[i] isDefault])
{
[variants addObject: [[port valueForKey:@"variants"] objectAtIndex:i]];
[variants addObject: [NSString stringWithString:@"+"]];
}
[variantsString appendString:@"+"];
[variantsString appendString:[[port valueForKey:@"variants"] objectAtIndex:i]];
}
else if([checkboxes[i] isDefault])
{
//If the checkbox is unchecked, we need to check if it is a default_variant, and if so, add it in the list with '-'
//in the name, to let macports know that we wish to not use it
[variants addObject: [[port valueForKey:@"variants"] objectAtIndex:i]];
[variants addObject: [NSString stringWithString:@"-"]];
[variantsString appendString:@"-"];
[variantsString appendString:[[port valueForKey:@"variants"] objectAtIndex:i]];
}
}
//NSLog(@"End of Variants");
[self queueOperation:@"install+" portName:variantsString portObject:port variants: variants];
NSLog(@"%@",[port name]);
if (altWasPressed)
[self startQueue:nil];
}
//This method is called when the user clicks install with variants
- (IBAction)installWithVariantsChoose:(id)sender
{
NSArray *selectedPorts = [ports selectedObjects];
id port = [selectedPorts objectAtIndex:0];
//Only go through the fuss if there are variants, otherwise, perform a normal install
if([[port valueForKey:@"variants"] count] > 0)
{
checkboxes[0]=chckbx0;
checkboxes[1]=chckbx1;
checkboxes[2]=chckbx2;
checkboxes[3]=chckbx3;
checkboxes[4]=chckbx4;
checkboxes[5]=chckbx5;
checkboxes[6]=chckbx6;
checkboxes[7]=chckbx7;
checkboxes[8]=chckbx8;
checkboxes[9]=chckbx9;
//Hide all checkboxes first
for(UInt i=0; i< 10;i++)
{
[checkboxes[i] setAlphaValue:0];
}
//NSLog(@"Port variants:");
//Call checkDefaults to compute the NSMutableArray for key default_variants
[port checkDefaults];
NSMutableArray *defaultVariants= [port objectForKey:@"default_variants"];
NSLog(@"Default variants count: %i", [defaultVariants count]);
for(UInt i=0; i<[[port valueForKey:@"variants"] count];i++)
{
//If the variant is included in the default_variants, then check it. Otherwise leave it unchecked
//NSLog(@"%@",[[port valueForKey:@"variants"] objectAtIndex:i]);
if(defaultVariants != nil && [defaultVariants indexOfObject:[[port valueForKey:@"variants"] objectAtIndex:i]] != NSNotFound)
{
//NSLog(@"Default %@", [[port valueForKey:@"variants"] objectAtIndex:i]);
[checkboxes[i] setState:NSOnState];
[checkboxes[i] setIsDefault:YES];
}
else
{
[checkboxes[i] setState:NSOffState];
[checkboxes[i] setIsDefault:NO];\
}
//Show all existing variants, and set their titles
[checkboxes[i] setAlphaValue:1];
NSAttributedString *tempString = [[NSAttributedString alloc]\
initWithString:[[port valueForKey:@"variants"] objectAtIndex:i]\
attributes: [NSDictionary dictionaryWithObject: [NSColor whiteColor] forKey: NSForegroundColorAttributeName]];
[checkboxes[i] setAttributedTitle:tempString];
}
//NSLog(@"End of Variants");
//Call setConflicts to initialize conflicting variants in the GUI
[self setConflicts:port];
[variantsPanel makeKeyAndOrderFront:self];
//[variantsPanel makeFirstResponder:[tableController mainWindow]];
}
else
{
[self install:nil];
}
}
- (IBAction)install:(id)sender {
if (altWasPressed)
{
[self clearQueue];
}
[tableController open:nil];
NSLog(@"Staring Installation");
NSArray *selectedPorts = [ports selectedObjects];
for (id port in selectedPorts) {
[self queueOperation:@"install" portName:[port name] portObject:port variants:0];
NSLog(@"%@",[port name]);
//[[MPActionLauncher sharedInstance]
// performSelectorInBackground:@selector(installPort:) withObject:port];
}
//NSLog(@"Installation Completed");
if (altWasPressed)
[self startQueue:nil];
}
- (IBAction)uninstall:(id)sender {
if (altWasPressed)
{
[self clearQueue];
}
[tableController open:nil];
NSArray *selectedPorts = [ports selectedObjects];
for (id port in selectedPorts) {
[self queueOperation:@"uninstall" portName:[port name] portObject:port variants:0];
NSLog(@"%@",[port name]);
/*
[[MPActionLauncher sharedInstance]
performSelectorInBackground:@selector(uninstallPort:) withObject:port];
*/
}
if (altWasPressed)
[self startQueue:nil];
}
- (IBAction)upgrade:(id)sender {
if (altWasPressed)
{
[self clearQueue];
}
[tableController open:nil];
NSArray *selectedPorts = [ports selectedObjects];
for (id port in selectedPorts) {
[self queueOperation:@"upgrade" portName:[port name] portObject:port variants:0];
NSLog(@"%@",[port name]);
/*
[[MPActionLauncher sharedInstance]
performSelectorInBackground:@selector(upgradePort:) withObject:port];
*/
}
if (altWasPressed)
[self startQueue:nil];
}
- (IBAction)sync:(id)sender {
if (altWasPressed)
{
[self clearQueue];
}
[tableController open:nil];
[self queueOperation:@"sync" portName:@"-" portObject:@"-" variants:0];
/*
[[MPActionLauncher sharedInstance]
performSelectorInBackground:@selector(sync) withObject:nil];
*/
if (altWasPressed)
[self startQueue:nil];
}
- (IBAction)selfupdate:(id)sender {
if (altWasPressed)
{
[self clearQueue];
}
[tableController open:nil];
[self queueOperation:@"selfupdate" portName:@"-" portObject:@"-" variants:0];
/*
[[MPActionLauncher sharedInstance]
performSelectorInBackground:@selector(selfupdate) withObject:nil];
*/
if (altWasPressed)
[self startQueue:nil];
}
- (IBAction)cancel:(id)sender {
[[MPMacPorts sharedInstance] cancelCurrentCommand];
}
- (IBAction) toggleInfoPanel: (id) sender;
{
if ([infoPanel isVisible]) {
[infoPanel close];
//[variantsPanel close];
} else {
[infoPanel makeKeyAndOrderFront:self];
//May need to make our MPTableView as the first responder
//[infoPanel makeFirstResponder:self];
}
}
-(IBAction)clickCheckbox:(id)sender
{
//Are we checking or unchecking the checkbox?
BOOL enableDisable;
if([sender state]==NSOnState)
{
enableDisable=NO;
}
else
{
enableDisable=YES;
}
for(UInt j=0;j<[[sender conflictsWith] count]; j++)
{
//If we are checking the checkbox, then disable and uncheck the conflicting ones
//If we are unchecking the checkbox, enable the conflicting ones
for(UInt i=0; i<10; i++)
{
if ([[checkboxes[i] title] isEqualToString:[[sender conflictsWith] objectAtIndex:j]])
{
[checkboxes[i] setEnabled:enableDisable];
if (!enableDisable)
{
[checkboxes[i] setState:NSOffState];
}
}
}
}
}
-(void)setConflicts: (MPPort *) port
{
//Initialize the conflicts NSMutableArray for the port, if it wasn't already initialized
[port checkConflicts];
NSArray *conflicts = [port objectForKey:@"conflicts"];
//For each conflict in the array, check which checkbox/variant has the same name as the conflict, and
//call the setConflictsWith method to add the conflicting checkbox to the conflictsWith array
for(UInt j=0; j< [conflicts count];j++)
{
UInt i;
for( i=0; i<10; i++)
{
if ([[conflicts objectAtIndex:j] objectForKey:[checkboxes[i] title]] != nil)
{
break;
}
}
[checkboxes[i] setConflictsWith:[[conflicts objectAtIndex:j] objectForKey:[checkboxes[i] title]]];
}
}
-(BOOL)validateToolbarItem:(NSToolbarItem *)toolbarItem {
BOOL enable = ![activityController busy];
if ([[toolbarItem itemIdentifier] isEqual:[cancel itemIdentifier]]) {
// Cancel button is enabled when busy
return !enable;
}
return enable;
}
#pragma mark App Delegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[tableController hidePredicateEditor:self];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *pkgPath = [defaults objectForKey:@"PKGPath"];
if (pkgPath == nil) {
[self openPreferences:self];
} else {
[MPMacPorts setPKGPath:pkgPath];
[[MPActionLauncher sharedInstance]
performSelectorInBackground:@selector(loadPorts) withObject:nil];
}
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication {
return YES;
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// I should check if it is running also
if (![[NSFileManager defaultManager] isWritableFileAtPath:[MPMacPorts PKGPath]]) {
[[MPActionLauncher sharedInstance] cancelPortProcess];
}
}
//This is called when clicking on the 'start queue' button, or clicking on an operation while holding the alt key
-(void) startQueue:(id) sender
{
NSLog(@"Starting Queue");
NSUInteger index;
index = [queueArray count]-1;
NSLog(@"Array Size is: %u", index);
NSUInteger i;
[queue setSelectionIndex: 0];
queueCounter=0;
//We add ourselves as an observer in the Notification Center, and call advanceQueue whenever we receive an 'advanceQ' notification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(advanceQueue)
name:@"advanceQ" object:nil];
//We start the operations by advancing in the queue once. When that operation is completed, it will
//automatically advance to the next queue by sending an advanceQ notification.
[self advanceQueue];
}
//This method is called to move through the queue and perform all the operations one by one. Each time this method is called,
//we advance one spot in the queue
-(void) advanceQueue
{
NSUInteger index=queueCounter;
if([queueArray count]>index)
{
NSLog(@"Advancing Queue for %u", index);
//index = [queue selectionIndex];
NSLog(@"Index before: %u", index);
//We select each object from the array
[queue setSelectionIndex:index];
//We sleep the process for debugging puproses
//sleep(3);
//We then take the dictionary
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:[queueArray objectAtIndex:index]];
//And we print the operations
NSLog(@"Port %@ Operation %@",[dict objectForKey:@"port"], [dict objectForKey:@"operation"]);
id port= [dict objectForKey:@"object"];
if ([[dict objectForKey:@"operation"] isEqualToString:@"install"])
{
NSLog(@"We have installation");
[[MPActionLauncher sharedInstance]
performSelectorInBackground:@selector(installPort:) withObject:port];
}
else if([[dict objectForKey:@"operation"] isEqualToString:@"install+"])
{
NSLog(@"We have installation with variants");
NSArray *variants = [dict objectForKey:@"variants"];
NSArray *portAndVariants = [NSArray arrayWithObjects:port, variants, nil];
[[MPActionLauncher sharedInstance]
performSelectorInBackground:@selector(installPortWithVariants:) withObject:portAndVariants];
}
else if([[dict objectForKey:@"operation"] isEqualToString:@"uninstall"])
{
NSLog(@"We have uninstallation");
[[MPActionLauncher sharedInstance]
performSelectorInBackground:@selector(uninstallPort:) withObject:port];
}
else if([[dict objectForKey:@"operation"] isEqualToString:@"upgrade"])
{
NSLog(@"We have upgrade");
[[MPActionLauncher sharedInstance]
performSelectorInBackground:@selector(upgradePort:) withObject:port];
}
else if([[dict objectForKey:@"operation"] isEqualToString:@"selfupdate"])
{
NSLog(@"We have selfupdate");
[[MPActionLauncher sharedInstance]
performSelectorInBackground:@selector(selfupdate) withObject:nil];
}
else if([[dict objectForKey:@"operation"] isEqualToString:@"sync"])
{
NSLog(@"We have sync");
[[MPActionLauncher sharedInstance]
performSelectorInBackground:@selector(sync) withObject:nil];
}
}
else
{
//If we are done, we remove ourselves as an observer from the Notification Center, and we notify the user
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"advanceQ" object:nil];
int allops=GROWL_ALLOPS;
[[MPActionLauncher sharedInstance]
performSelectorInBackground:@selector(sendGrowlNotification:) withObject:(id) allops];
}
queueCounter++;
}
//This method is called when adding a new operation on the queue. Its inputs are the operation to be performed, the port name, the
//equivalent port object, and the variants
-(void) queueOperation:(NSString*)operation portName:(NSString*)name portObject: (id) port variants: (NSMutableArray*) variants
{
//We set the operation's icon
NSImage *image;
if ([operation isEqualToString:@"install"])
{
image = [NSImage imageNamed:@"TB_Install.icns"];
}
else if ([operation isEqualToString:@"install+"])
{
image = [NSImage imageNamed:@"TB_InstallWithVar.icns"];
}
else if ([operation isEqualToString:@"uninstall"])
{
image = [NSImage imageNamed:@"TB_Uninstall.icns"];
}
else if ([operation isEqualToString:@"upgrade"])
{
image = [NSImage imageNamed:@"TB_Upgrade.icns"];
}
else if ([operation isEqualToString:@"sync"])
{
image = [NSImage imageNamed:@"TB_Sync.icns"];
}
else if ([operation isEqualToString:@"selfupdate"])
{
image = [NSImage imageNamed:@"TB_Selfupdate.icns"];
}
//If we have variants, print them out for debugging purposes
if(variants!=nil)
{
for(UInt i=0; i<[variants count]; i++)
{
NSLog(@"variants array at #%i: %@", i, [variants objectAtIndex:i]);
}
}
NSLog(@"Queueing our Operation");
//Add the operation to the queue
[queue addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:operation, @"operation", name, @"port", port, @"object", image, @"image", variants, @"variants", nil]];
}
/*
-(void) removeFromQueue:(id)sender
{
UInt index = [queue selectionIndex];
[queue removeObject: [[queue selectedObjects] objectAtIndex:0]];
[queue setSelectionIndex: index];
}
*/
//This is called when we have the alt key pressed, so that we clear the queue before adding and performing our new operation
-(void) clearQueue
{
NSIndexSet *tempIndex = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [queueArray count])];
[queue removeObjectsAtArrangedObjectIndexes:tempIndex];
}
-(id) init
{
[variantsPanel setFloatingPanel:YES];
[super init];
return self;
}
@end