Changeset 2102

Show
Ignore:
Timestamp:
11/12/04 21:51:32 (4 years ago)
Author:
timothy
Message:

Merged in changes for contextual menus from 2101.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/overhaul/JVChatMessage.m

    r1948 r2102  
    257257        if( ! _attributedMessage ) { 
    258258                if( [message isKindOfClass:[NSTextStorage class]] ) _attributedMessage = [message retain]; 
    259                 else _attributedMessage = [[NSTextStorage alloc] initWithAttributedString:message]; 
    260         } else [_attributedMessage setAttributedString:message]; 
     259                else if( [message isKindOfClass:[NSAttributedString class]] ) _attributedMessage = [[NSTextStorage alloc] initWithAttributedString:message]; 
     260                else if( [message isKindOfClass:[NSString class]] ) _attributedMessage = [[NSAttributedString alloc] initWithString:(NSString *)message]; 
     261        } else if( _attributedMessage && [message isKindOfClass:[NSAttributedString class]] ) { 
     262                [_attributedMessage setAttributedString:message]; 
     263        } else if( _attributedMessage && [message isKindOfClass:[NSString class]] ) { 
     264                id string = [[[NSAttributedString alloc] initWithString:(NSString *)message] autorelease]; 
     265                [_attributedMessage setAttributedString:string]; 
     266        } 
    261267} 
    262268 
  • branches/overhaul/JVChatTranscript.m

    r1948 r2102  
    1919#import "NSBundleAdditions.h" 
    2020#import "NSURLAdditions.h" 
    21  
    2221#import "unistd.h" 
    2322 
     
    690689        NSMenuItem *item = nil; 
    691690        unsigned i = 0; 
     691        BOOL found = NO; 
    692692 
    693693        for( i = 0; i < [ret count]; i++ ) { 
     
    704704                        i--; 
    705705                        break; 
     706                case WebMenuItemTagCopy: 
     707                        found = YES; 
     708                        break; 
    706709                case WebMenuItemTagDownloadLinkToDisk: 
    707710                case WebMenuItemTagDownloadImageToDisk: 
    708711                        [item setTarget:[sender UIDelegate]]; 
     712                        found = YES; 
    709713                        break; 
    710714                } 
    711715        } 
    712716 
    713         if( ! [defaultMenuItems count] && ! [[element objectForKey:WebElementIsSelectedKey] boolValue] ) { 
     717        if( ! found && ! [ret count] && ! [[element objectForKey:WebElementIsSelectedKey] boolValue] ) { 
    714718                item = [[[NSMenuItem alloc] initWithTitle:NSLocalizedString( @"Style", "choose style contextual menu" ) action:NULL keyEquivalent:@""] autorelease]; 
    715719                [item setSubmenu:_styleMenu]; 
     
    722726        } 
    723727 
     728        NSMethodSignature *signature = [NSMethodSignature methodSignatureWithReturnAndArgumentTypes:@encode( NSArray * ), @encode( id ), @encode( id ), nil]; 
     729        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; 
     730 
     731        id object = [[element objectForKey:WebElementImageURLKey] description]; 
     732        if( ! object ) object = [[element objectForKey:WebElementLinkURLKey] description]; 
     733        if( ! object ) object = [(id <WebDocumentText>)[[[display mainFrame] frameView] documentView] selectedString]; 
     734 
     735        [invocation setSelector:@selector( contextualMenuItemsForObject:inView: )]; 
     736        [invocation setArgument:&object atIndex:2]; 
     737        [invocation setArgument:&self atIndex:3]; 
     738 
     739        NSArray *results = [[MVChatPluginManager defaultManager] makePluginsPerformInvocation:invocation]; 
     740        if( [results count] ) { 
     741                if( [ret count] ) [ret addObject:[NSMenuItem separatorItem]]; 
     742 
     743                NSArray *items = nil; 
     744                NSEnumerator *enumerator = [results objectEnumerator]; 
     745                while( ( items = [enumerator nextObject] ) ) { 
     746                        if( ! [items respondsToSelector:@selector( objectEnumerator )] ) continue; 
     747                        NSEnumerator *ienumerator = [items objectEnumerator]; 
     748                        while( ( item = [ienumerator nextObject] ) ) 
     749                                if( [item isKindOfClass:[NSMenuItem class]] ) [ret addObject:item]; 
     750                } 
     751 
     752                if( [[ret lastObject] isSeparatorItem] ) 
     753                        [ret removeObjectIdenticalTo:[ret lastObject]]; 
     754        } 
     755 
    724756        return ret; 
     757} 
     758 
     759- (unsigned) webView:(WebView *) webView dragSourceActionMaskForPoint:(NSPoint) point { 
     760        return UINT_MAX; // WebDragSourceActionAny 
    725761} 
    726762 
  • branches/overhaul/MVApplicationController.m

    r2031 r2102  
    11#import <ExceptionHandling/NSExceptionHandler.h> 
    22#import <ChatCore/MVFileTransfer.h> 
     3#import <ChatCore/MVChatPluginManager.h> 
     4#import <ChatCore/NSMethodSignatureAdditions.h> 
     5#import <ChatCore/MVChatScriptPlugin.h> 
     6#import "NSURLAdditions.h" 
    37#import "MVColorPanel.h" 
    48#import "MVApplicationController.h" 
     
    1721#import "JVTranscriptPreferences.h" 
    1822#import "MVBuddyListController.h" 
    19 #import "MVChatPluginManager.h" 
    2023#import "JVChatController.h" 
    2124#import "MVChatConnection.h" 
    2225#import "JVChatRoomBrowser.h" 
    2326#import "NSBundleAdditions.h" 
    24 #import "NSURLAdditions.h" 
    2527#import "JVStyle.h" 
    2628 
     
    325327} 
    326328 
     329- (NSMenu *) applicationDockMenu:(NSApplication *) sender { 
     330        NSMenu *menu = [[[NSMenu allocWithZone:[self zone]] initWithTitle:@""] autorelease]; 
     331 
     332        NSMethodSignature *signature = [NSMethodSignature methodSignatureWithReturnAndArgumentTypes:@encode( NSArray * ), @encode( id ), @encode( id ), nil]; 
     333        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; 
     334        id view = nil; 
     335 
     336        [invocation setSelector:@selector( contextualMenuItemsForObject:inView: )]; 
     337        [invocation setArgument:&sender atIndex:2]; 
     338        [invocation setArgument:&view atIndex:3]; 
     339 
     340        NSArray *results = [[MVChatPluginManager defaultManager] makePluginsPerformInvocation:invocation]; 
     341        if( [results count] ) { 
     342                NSArray *items = nil; 
     343                NSMenuItem *item = nil; 
     344                NSEnumerator *enumerator = [results objectEnumerator]; 
     345                while( ( items = [enumerator nextObject] ) ) { 
     346                        if( ! [items respondsToSelector:@selector( objectEnumerator )] ) continue; 
     347                        NSEnumerator *ienumerator = [items objectEnumerator]; 
     348                        while( ( item = [ienumerator nextObject] ) ) 
     349                                if( [item isKindOfClass:[NSMenuItem class]] ) [menu addItem:item]; 
     350                } 
     351 
     352                if( [[[menu itemArray] lastObject] isSeparatorItem] ) 
     353                        [menu removeItem:[[menu itemArray] lastObject]]; 
     354        } 
     355 
     356        return menu; 
     357} 
     358 
    327359- (BOOL) application:(NSApplication *) sender delegateHandlesKey:(NSString *) key { 
    328360        if( [key isEqualToString:@"chatController"] || [key isEqualToString:@"connectionsController"] || [key isEqualToString:@"transferManager"] || [key isEqualToString:@"buddyList"] ) 
     
    342374#pragma mark - 
    343375 
     376@implementation MVChatScriptPlugin (MVChatPluginContextualMenuSupport) 
     377- (IBAction) performContextualMenuItemAction:(id) sender { 
     378        id object = [sender representedObject]; 
     379        NSMutableArray *submenu = [NSMutableArray array]; 
     380 
     381        NSMenu *menu = [sender menu]; 
     382        NSMenu *parent = nil; 
     383        while( ( parent = [menu supermenu] ) ) { 
     384                [submenu insertObject:[menu title] atIndex:0]; 
     385                menu = parent; 
     386        } 
     387 
     388        NSString *title = [sender title]; 
     389        NSDictionary *args = [NSDictionary dictionaryWithObjectsAndKeys:title, @"----", object, @"pcM1", submenu, @"pcM2", nil]; 
     390        [self callScriptHandler:'pcMX' withArguments:args forSelector:_cmd]; 
     391} 
     392 
     393- (void) buildMenuInto:(NSMutableArray *) itemList fromReturnContainer:(id) container withRepresentedObject:(id) object { 
     394        if( [container respondsToSelector:@selector( objectEnumerator )] ) { 
     395                NSEnumerator *enumerator = [container objectEnumerator]; 
     396                id item = nil; 
     397 
     398                while( ( item = [enumerator nextObject] ) ) { 
     399                        if( [item isKindOfClass:[NSString class]] ) { 
     400                                if( [item isEqualToString:@"-"] ) { 
     401                                        [itemList addObject:[NSMenuItem separatorItem]]; 
     402                                } else { 
     403                                        NSMenuItem *mitem = [[[NSMenuItem alloc] initWithTitle:item action:@selector( performContextualMenuItemAction: ) keyEquivalent:@""] autorelease]; 
     404                                        [mitem setTarget:self]; 
     405                                        [mitem setRepresentedObject:object]; 
     406                                        [itemList addObject:mitem]; 
     407                                } 
     408                        } else if( [item isKindOfClass:[NSDictionary class]] ) { 
     409                                NSString *title = [item objectForKey:@"title"]; 
     410                                NSArray *sub = [item objectForKey:@"submenu"]; 
     411                                NSNumber *enabled = [item objectForKey:@"enabled"]; 
     412                                NSNumber *checked = [item objectForKey:@"checked"]; 
     413                                NSNumber *indent = [item objectForKey:@"indent"]; 
     414                                NSNumber *alternate = [item objectForKey:@"alternate"]; 
     415                                NSString *iconPath = [item objectForKey:@"icon"]; 
     416                                id iconSize = [item objectForKey:@"iconsize"]; 
     417                                NSString *tooltip = [item objectForKey:@"tooltip"]; 
     418                                id context = [item objectForKey:@"context"]; 
     419 
     420                                if( ! [title isKindOfClass:[NSString class]] ) continue; 
     421                                if( ! [tooltip isKindOfClass:[NSString class]] ) tooltip = nil; 
     422                                if( ! [enabled isKindOfClass:[NSNumber class]] ) enabled = nil; 
     423                                if( ! [checked isKindOfClass:[NSNumber class]] ) checked = nil; 
     424                                if( ! [indent isKindOfClass:[NSNumber class]] ) indent = nil; 
     425                                if( ! [alternate isKindOfClass:[NSNumber class]] ) alternate = nil; 
     426                                if( ! [iconPath isKindOfClass:[NSString class]] ) iconPath = nil; 
     427                                if( ! [iconSize isKindOfClass:[NSArray class]] && ! [iconSize isKindOfClass:[NSNumber class]] ) iconSize = nil; 
     428                                if( ! [sub isKindOfClass:[NSArray class]] && ! [sub isKindOfClass:[NSDictionary class]] ) sub = nil; 
     429                                 
     430                                NSMenuItem *mitem = [[[NSMenuItem alloc] initWithTitle:title action:@selector( performContextualMenuItemAction: ) keyEquivalent:@""] autorelease]; 
     431                                if( context ) [mitem setRepresentedObject:context]; 
     432                                else [mitem setRepresentedObject:object]; 
     433                                if( ! enabled || ( enabled && [enabled boolValue] ) ) [mitem setTarget:self]; 
     434                                if( enabled && ! [enabled boolValue] ) [mitem setEnabled:[enabled boolValue]]; 
     435                                if( checked ) [mitem setState:[checked intValue]]; 
     436                                if( indent ) [mitem setIndentationLevel:MIN( 15, [indent unsignedIntValue] )]; 
     437                                if( tooltip ) [mitem setToolTip:tooltip]; 
     438 
     439                                if( alternate && [alternate unsignedIntValue] == 1 ) { 
     440                                        [mitem setKeyEquivalentModifierMask:NSAlternateKeyMask]; 
     441                                        [mitem setAlternate:YES]; 
     442                                } else if( alternate && [alternate unsignedIntValue] == 2 ) { 
     443                                        [mitem setKeyEquivalentModifierMask:( NSShiftKeyMask | NSAlternateKeyMask )]; 
     444                                        [mitem setAlternate:YES]; 
     445                                } else if( alternate && [alternate unsignedIntValue] == 3 ) { 
     446                                        [mitem setKeyEquivalentModifierMask:( NSShiftKeyMask | NSAlternateKeyMask | NSControlKeyMask )]; 
     447                                        [mitem setAlternate:YES]; 
     448                                } 
     449 
     450                                if( [iconPath length] ) { 
     451                                        NSURL *iconURL; 
     452                                        if( iconURL = [NSURL URLWithString:iconPath] ) { 
     453                                                // NSImage *icon = [[[NSImage allocWithZone:[self zone]] initByReferencingURL:[NSURL URLWithString:iconPath]] autorelease]; 
     454                                                // Lets download the icon with a 1-second timeout 
     455                                                // Let's also ask for the cache if it exists rather than using protocol default 
     456                                                NSURLRequest *iconRequest = [NSURLRequest requestWithURL:iconURL cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:1.0]; 
     457                                                NSData *iconData = [NSURLConnection sendSynchronousRequest:iconRequest returningResponse:nil error:nil]; 
     458                                                NSImage *icon = [[[NSImage alloc] initWithData:iconData] autorelease]; 
     459                                                if( icon ) [mitem setImage:icon]; 
     460                                        } else { 
     461                                                if( ! [iconPath isAbsolutePath] ) { 
     462                                                        NSString *dir = [[self scriptFilePath] stringByDeletingLastPathComponent]; 
     463                                                        iconPath = [dir stringByAppendingPathComponent:iconPath]; 
     464                                                } 
     465 
     466                                                NSImage *icon = [[[NSImage allocWithZone:[self zone]] initByReferencingFile:iconPath] autorelease]; 
     467                                                if( icon ) [mitem setImage:icon]; 
     468                                        } 
     469 
     470                                        NSSize size = NSZeroSize; 
     471                                        if( [iconSize isKindOfClass:[NSArray class]] && [(NSArray *)iconSize count] == 2 ) { 
     472                                                size = NSMakeSize( [[iconSize objectAtIndex:0] unsignedIntValue], [[iconSize objectAtIndex:1] unsignedIntValue] ); 
     473                                        } else if( [iconSize isKindOfClass:[NSNumber class]] ) { 
     474                                                size = NSMakeSize( [iconSize unsignedIntValue], [iconSize unsignedIntValue] ); 
     475                                        } 
     476 
     477                                        if( [mitem image] && ! NSEqualSizes( size, NSZeroSize ) ) { 
     478                                                [[mitem image] setScalesWhenResized:YES]; 
     479                                                [[mitem image] setSize:size]; 
     480                                        } 
     481                                } 
     482 
     483                                [itemList addObject:mitem]; 
     484 
     485                                if( [sub respondsToSelector:@selector( objectEnumerator )] && [sub respondsToSelector:@selector( count )] && [sub count] ) { 
     486                                        NSMenu *submenu = [[[NSMenu allocWithZone:[self zone]] initWithTitle:title] autorelease]; 
     487                                        NSMutableArray *subArray = [NSMutableArray array]; 
     488 
     489                                        [self buildMenuInto:subArray fromReturnContainer:sub withRepresentedObject:object]; 
     490 
     491                                        id subItem = nil; 
     492                                        NSEnumerator *subenumerator = [subArray objectEnumerator]; 
     493                                        while( ( subItem = [subenumerator nextObject] ) ) 
     494                                                [submenu addItem:subItem]; 
     495 
     496                                        [mitem setSubmenu:submenu]; 
     497                                } 
     498                        } 
     499                } 
     500        } 
     501} 
     502 
     503- (NSArray *) contextualMenuItemsForObject:(id) object inView:(id <JVChatViewController>) view { 
     504        NSDictionary *args = [NSDictionary dictionaryWithObjectsAndKeys:object, @"----", view, @"cMi1", nil]; 
     505        id result = [self callScriptHandler:'cMiX' withArguments:args forSelector:_cmd]; 
     506        NSMutableArray *ret = [NSMutableArray array]; 
     507 
     508        if( ! result ) return nil; 
     509        if( ! [result isKindOfClass:[NSArray class]] ) 
     510                result = [NSArray arrayWithObject:result]; 
     511 
     512        [self buildMenuInto:ret fromReturnContainer:result withRepresentedObject:object]; 
     513 
     514        if( [ret count] ) return ret; 
     515        return nil; 
     516} 
     517@end 
     518 
     519#pragma mark - 
     520 
    344521@implementation NSApplication (NSApplicationScripting) 
    345522- (void) newConnection:(NSScriptCommand *) command {