// // P4CocoaMenu.m // P4CocoaXCode // // Created by Jeff Argast on Tue Dec 02 2003. // Copyright (c) 2003 __MyCompanyName__. All rights reserved. // #import "P4CocoaMenu.h" #import static P4CocoaMenu* gP4CocoaMenu = nil; // ////////////////////////////////////////////////////////////////////////////////////// // @protocol DistributedP4CocoaProtocol - (oneway void) perforceEdit: (NSArray*) pathArray; - (oneway void) perforceSync: (NSArray*) pathArray; - (oneway void) perforceRevert: (NSArray*) pathArray; - (oneway void) perforceReveal: (NSArray*) pathArray; @end // ////////////////////////////////////////////////////////////////////////////////////// // @interface DummyInterface - (id) selectedProjectItems; - (id) absolutePath; @end // ////////////////////////////////////////////////////////////////////////////////////// // @interface P4CocoaMenuItem : NSMenuItem { } @end // @implementation P4CocoaMenuItem // HACK: XCode is setting the target to null. Don't allow that - (void) setTarget: (id) target { if ( target != gP4CocoaMenu ) return; [super setTarget:target]; } @end // ////////////////////////////////////////////////////////////////////////////////////// // @interface P4CocoaMenu (Private) + (NSArray*) selectedPaths; + (void) launchP4Cocoa; + (id) retainP4CocoaServer; - (void) p4CocoaEdit: (id) sender; - (void) p4CocoaSync: (id) sender; - (void) p4CocoaRevert: (id) sender; - (void) p4CocoaReveal: (id) sender; @end // ////////////////////////////////////////////////////////////////////////////////////// // @implementation P4CocoaMenu (Private) + (NSArray*) selectedPaths { NSMutableArray* pathArray = [NSMutableArray array]; NSApplication* theApp = [NSApplication sharedApplication]; NSWindow* mainWindow = [theApp mainWindow]; NSResponder* currentResponder = [mainWindow firstResponder]; if ( currentResponder ) { // First see if this is the outline view if ( [currentResponder isKindOfClass:[NSOutlineView class]] ) { NSOutlineView* outlineView = (NSOutlineView*)currentResponder; NSEnumerator* enumerator = [outlineView selectedRowEnumerator]; id rowNum; while (rowNum = [enumerator nextObject]) { int rowIdx = [rowNum intValue]; id object = [outlineView itemAtRow:rowIdx]; if ( object ) { if ( [object respondsToSelector:@selector(absolutePath)] ) { id absolutePath = [object absolutePath]; if ( absolutePath ) { [pathArray addObject:absolutePath]; } } } } } // Otherwise, is this the table view? else if ( [currentResponder isKindOfClass:[NSTableView class]] ) { NSTableView* tableView = (NSOutlineView*)currentResponder; id dataSource = [tableView dataSource]; if ( [dataSource respondsToSelector:@selector(selectedProjectItems)] ) { NSArray* items = [dataSource selectedProjectItems]; NSEnumerator* enumerator = [items objectEnumerator]; id object; while ( object = [enumerator nextObject] ) { if ( [object respondsToSelector:@selector(absolutePath)] ) { id absolutePath = [object absolutePath]; if ( absolutePath ) { [pathArray addObject:absolutePath]; } } } } } else // is this the document view? { while ( currentResponder ) { if ( [currentResponder isKindOfClass:[NSWindowController class]] ) { break; } currentResponder = [currentResponder nextResponder]; } if ( currentResponder ) { NSWindowController* wController = (NSWindowController*) currentResponder; NSDocument* doc = [wController document]; if ( doc ) { id fileName = [doc fileName]; if ( fileName ) { [pathArray addObject:fileName]; } } } } } return pathArray; } + (void) launchP4Cocoa { NSWorkspace* ws = [NSWorkspace sharedWorkspace]; NSArray* apps = [ws launchedApplications]; NSEnumerator* enumer = [apps objectEnumerator]; id object; BOOL running = NO; while ( object = [enumer nextObject] ) { NSDictionary* dict = (NSDictionary*) object; NSString* name = (NSString*) [dict objectForKey:@"NSApplicationName"]; if ( [name isEqualToString:@"P4Cocoa"] ) { running = YES; break; } } if ( !running ) { [[NSWorkspace sharedWorkspace] launchApplication:@"P4Cocoa"]; // HACK sleep for a few seconds to let it finish launching sleep (4); } } + (id) retainP4CocoaServer { [P4CocoaMenu launchP4Cocoa]; id server = [[NSConnection rootProxyForConnectionWithRegisteredName:@"DistributedP4Cocoa" host:nil] retain]; if ( server ) { [server setProtocolForProxy:@protocol(DistributedP4CocoaProtocol)]; } return server; } - (void) p4CocoaEdit: (id) sender { NSArray* selectedPaths = [P4CocoaMenu selectedPaths]; if ( [selectedPaths count] > 0 ) { id p4CocoaServer = [P4CocoaMenu retainP4CocoaServer]; [p4CocoaServer perforceEdit:selectedPaths]; [p4CocoaServer release]; } } - (void) p4CocoaSync: (id) sender { NSArray* selectedPaths = [P4CocoaMenu selectedPaths]; if ( [selectedPaths count] > 0 ) { id p4CocoaServer = [P4CocoaMenu retainP4CocoaServer]; [p4CocoaServer perforceSync:selectedPaths]; [p4CocoaServer release]; } } - (void) p4CocoaRevert: (id) sender { NSArray* selectedPaths = [P4CocoaMenu selectedPaths]; if ( [selectedPaths count] > 0 ) { id p4CocoaServer = [P4CocoaMenu retainP4CocoaServer]; [p4CocoaServer perforceRevert:selectedPaths]; [p4CocoaServer release]; } } - (void) p4CocoaReveal: (id) sender { NSArray* selectedPaths = [P4CocoaMenu selectedPaths]; if ( [selectedPaths count] > 0 ) { id p4CocoaServer = [P4CocoaMenu retainP4CocoaServer]; [p4CocoaServer perforceReveal:selectedPaths]; [p4CocoaServer release]; } } - (BOOL)validateMenuItem:(id )menuItem { NSArray* selectedPaths = [P4CocoaMenu selectedPaths]; SEL selector = [menuItem action]; if ( [selectedPaths count] < 1 ) { if ( selector == @selector(p4CocoaEdit:) ) { [menuItem setTitle:@"P4Cocoa Edit"]; } else if ( selector == @selector(p4CocoaRevert:) ) { [menuItem setTitle:@"P4Cocoa Revert"]; } else if ( selector == @selector(p4CocoaSync:) ) { [menuItem setTitle:@"P4Cocoa Sync"]; } return NO; } if ( [selectedPaths count] == 1 ) { NSString* pathName = [selectedPaths objectAtIndex:0]; NSString* name = [pathName lastPathComponent]; if ( selector == @selector(p4CocoaEdit:) ) { NSString *titleString = [NSString localizedStringWithFormat:@"%@ %@\n",@"P4Cocoa Edit", name]; [menuItem setTitle:titleString]; } else if ( selector == @selector(p4CocoaRevert:) ) { NSString *titleString = [NSString localizedStringWithFormat:@"%@ %@\n",@"P4Cocoa Revert", name]; [menuItem setTitle:titleString]; } else if ( selector == @selector(p4CocoaSync:) ) { NSString *titleString = [NSString localizedStringWithFormat:@"%@ %@\n",@"P4Cocoa Sync", name]; [menuItem setTitle:titleString]; } } else { if ( selector == @selector(p4CocoaEdit:) ) { [menuItem setTitle:@"P4Cocoa Edit Items"]; } else if ( selector == @selector(p4CocoaRevert:) ) { [menuItem setTitle:@"P4Cocoa Revert Items"]; } else if ( selector == @selector(p4CocoaSync:) ) { [menuItem setTitle:@"P4Cocoa Sync Itmes"]; } } return YES; } @end // ////////////////////////////////////////////////////////////////////////////////////// // @implementation P4CocoaMenu + (void) installMenus { gP4CocoaMenu = [[P4CocoaMenu alloc] init]; NSApplication* theApp = [NSApplication sharedApplication]; NSMenu* mainMenu = [theApp mainMenu]; if ( mainMenu ) { // Find the SCM menu item if it exists id scmMenuItem = [mainMenu itemWithTitle:@"SCM"]; NSMenu* subMenu = nil; if ( scmMenuItem ) { subMenu = [scmMenuItem submenu]; } else { subMenu = [[[NSMenu alloc] initWithTitle:@"P4Cocoa"] autorelease]; } id mItem = nil; mItem = [[[P4CocoaMenuItem alloc] initWithTitle:@"P4cocoa Edit" action:@selector(p4CocoaEdit:) keyEquivalent:@""] autorelease]; [mItem setTarget:gP4CocoaMenu]; [subMenu insertItem:mItem atIndex:0]; mItem = [[[P4CocoaMenuItem alloc] initWithTitle:@"P4cocoa Revert" action:@selector(p4CocoaRevert:) keyEquivalent:@""] autorelease]; [mItem setTarget:gP4CocoaMenu]; [subMenu insertItem:mItem atIndex:1]; mItem = [[[P4CocoaMenuItem alloc] initWithTitle:@"P4cocoa Sync" action:@selector(p4CocoaSync:) keyEquivalent:@""] autorelease]; [mItem setTarget:gP4CocoaMenu]; [subMenu insertItem:mItem atIndex:2]; [subMenu insertItem:[NSMenuItem separatorItem] atIndex:3]; mItem = [[[P4CocoaMenuItem alloc] initWithTitle:@"P4Cocoa Reveal In Depot" action:@selector(p4CocoaReveal:) keyEquivalent:@""] autorelease]; [mItem setTarget:gP4CocoaMenu]; [subMenu insertItem:mItem atIndex:4]; if ( !scmMenuItem ) { mItem = [mainMenu addItemWithTitle:@"P4Cocoa" action:@selector(submenuAction:) keyEquivalent:@""]; [mItem setSubmenu:subMenu]; } else { [subMenu insertItem:[NSMenuItem separatorItem] atIndex:5]; } } } @end