P4CocoaMenu.m #1

  • //
  • guest/
  • jeff_argast/
  • P4CocoaXCode/
  • P4CocoaMenu.m
  • View
  • Commits
  • Open Download .zip Download (9 KB)
//
//  P4CocoaMenu.m
//  P4CocoaXCode
//
//  Created by Jeff Argast on Tue Dec 02 2003.
//  Copyright (c) 2003 __MyCompanyName__. All rights reserved.
//

#import "P4CocoaMenu.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)] )
					{
						[pathArray addObject:[object 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)] )
					{
						[pathArray addObject:[object 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 )
				{
					[pathArray addObject:[doc 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"];
	}
}

+ (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
{
	gP4CocoaMenu = [[P4CocoaMenu alloc] init];
	
	NSApplication* theApp = [NSApplication sharedApplication];
	NSMenu* mainMenu = [theApp mainMenu];
	
	if ( mainMenu )
	{
		// Find the SCM menu item if it exists
		id<NSMenuItem> scmMenuItem = [mainMenu itemWithTitle:@"SCM"];
		NSMenu* subMenu = nil;
		
		if ( scmMenuItem )
		{
			subMenu = [scmMenuItem submenu];
		}
		else
		{
			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];
		
		if ( !scmMenuItem )
		{
			mItem = [mainMenu addItemWithTitle:@"P4Cocoa" action:@selector(submenuAction:) keyEquivalent:@""];
			[mItem setSubmenu:subMenu];
		}
		else
		{
			[subMenu insertItem:[NSMenuItem separatorItem] atIndex:5];
		}
	}
}

@end
# Change User Description Committed
#4 4524 Jeff Argast Updated the plugin to work with XCode 1.5
#3 3985 Jeff Argast Fixed broken project, fixed crash in xcode plugin
#2 3984 Jeff Argast Updated version information
#1 3980 Jeff Argast Added distributed protocol