//
// P4CocoaMenu.m
// P4CocoaXCode
//
// Created by Jeff Argast on Tue Dec 02 2003.
// Copyright (c) 2003 __MyCompanyName__. All rights reserved.
//
#import "P4CocoaMenu.h"
#import <unistd.h>
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 <NSMenuItem>)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
{
//[NSAlert alertWithMessageText:@"Hello" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:nil];
gP4CocoaMenu = [[P4CocoaMenu alloc] init];
NSApplication* theApp = [NSApplication sharedApplication];
NSMenu* mainMenu = [theApp mainMenu];
if ( mainMenu )
{
// Find the SCM menu item if it exists
// As of Xcode 1.5 the SCM menu is built dynamically by Xcode. Consequently I can't
// add it there any longer.
NSMenu* subMenu = [[[NSMenu alloc] initWithTitle:@"P4Cocoa"] autorelease];;
id<NSMenuItem> 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];
mItem = [mainMenu addItemWithTitle:@"P4Cocoa" action:@selector(submenuAction:) keyEquivalent:@""];
[mItem setSubmenu:subMenu];
}
}
@end