⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tabimwindowcontroller.mm

📁 lumaqq
💻 MM
📖 第 1 页 / 共 2 页
字号:
/*
 * LumaQQ - Cross platform QQ client, special edition for Mac
 *
 * Copyright (C) 2007 luma <stubma@163.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 0 2111-1307 USA
 */

#import "TabIMWindowController.h"
#import "MainWindowController.h"
#import "Constants.h"
#import "AlertTool.h"
#import "NSData-MD5.h"
#import "NSData-BytesOperation.h"

#define _kToolBarTabIMWindow @"TabIMToolBar"

// toolbar item
#define _kToolbarItemOwner @"ToolbarItemOwner"
#define _kToolbarItemKeySetting @"ToolbarItemKeySetting"
#define _kToolbarItemHistory @"ToolbarItemHistory"

// sheet type
#define _kSheetCloseTabConfirm 0
#define _kSheetClusterCommandFailed 1

@implementation TabIMWindowController

- (id)initWithMainWindow:(MainWindowController*)mainWindowController {
	self = [super initWithWindowNibName:@"TabIM"];
	if(self) {
		m_mainWindowController = [mainWindowController retain];
		m_containerArray = [[NSMutableArray array] retain];
		m_historyRegistry = [[NSMutableDictionary dictionary] retain];
		m_historyDrawerOpened = NO;
		m_sheetType = -1;
	}
	return self;
}

- (void) dealloc {
	if(m_shortcutWindowController)
		[m_shortcutWindowController release];
	[m_mainWindowController release];
	[m_containerArray release];
	[m_historyRegistry release];
	[super dealloc];
}

- (void)windowDidLoad {
	// configure tab bar control
	[m_tabBar setCanCloseOnlyTab:YES];
	[m_tabBar setSizeCellsToFit:YES];
	[m_tabBar setCellMinWidth:50];
	
	// remove all tab item
	NSArray* tabItems = [m_tabView tabViewItems];
	NSEnumerator* e = [tabItems objectEnumerator];
	while(NSTabViewItem* item = [e nextObject])
		[m_tabView removeTabViewItem:item];
	
	// add observers
	[[NSNotificationCenter defaultCenter] addObserver:self
											 selector:@selector(handleScreenscrapDataDidPopulatedNotification:)
												 name:kScreenscrapDataDidPopulatedNotificationName
											   object:nil];
	[[NSNotificationCenter defaultCenter] addObserver:self
											 selector:@selector(handleTempJPGDidCreatedNotification:)
												 name:kTempJPGFileDidCreatedNotificationName
											   object:nil];
	[[NSNotificationCenter defaultCenter] addObserver:self
											 selector:@selector(handleIMContainerModelDidChangedNotification:)
												 name:kIMContainerModelDidChangedNotificationName
											   object:nil];
	
	// add qq listener
	[[m_mainWindowController client] addQQListener:self];
}

- (void)windowDidEndSheet:(NSNotification *)aNotification {
	if([aNotification object] != [self window])
		return;
	
	switch(m_sheetType) {
		case _kSheetCloseTabConfirm:
			// if only one tab exists, close window
			if([m_tabView numberOfTabViewItems] == 1)
				[self close];
			else
				[m_tabView removeTabViewItem:[m_tabView selectedTabViewItem]];
			break;
		case _kSheetClusterCommandFailed:			
			// remove cluster from ui
			id<IMContainer> container = [[[m_tabView selectedTabViewItem] identifier] content];
			[[m_mainWindowController groupManager] removeCluster:[container model]];
			[m_mainWindowController reloadClusters];
			
			// if only one tab exists, close window
			if([m_tabView numberOfTabViewItems] == 1)
				[self close];
			else
				[m_tabView removeTabViewItem:[m_tabView selectedTabViewItem]];
			break;
	}
	
	m_sheetType = -1;
}

- (BOOL)windowShouldClose:(id)sender {
	// if tab count > 1, close tab, not window
	if([m_containerArray count] > 1) {
		[m_tabBar closeTab:[m_tabView selectedTabViewItem]];
		return NO;
	} else
		return YES;
}

- (void)windowWillClose:(NSNotification *)aNotification {
	if([aNotification object] != [self window])
		return;
	
	[[NSNotificationCenter defaultCenter] removeObserver:self
													name:kScreenscrapDataDidPopulatedNotificationName
												  object:nil];	
	[[NSNotificationCenter defaultCenter] removeObserver:self
													name:kTempJPGFileDidCreatedNotificationName
												  object:nil];
	[[NSNotificationCenter defaultCenter] removeObserver:self
													name:kIMContainerModelDidChangedNotificationName
												  object:nil];	
	
	// unregister me
	[WindowRegistry unregisterTabIMWindow:[[m_mainWindowController me] QQ]];
	
	// remove all qq listener
	NSArray* items = [m_tabView tabViewItems];
	NSEnumerator* e = [items objectEnumerator];
	while(NSTabViewItem* item = [e nextObject]) {
		id<IMContainer> container = [[item identifier] content];
		[[m_mainWindowController client] removeQQListener:container];
	}
	[[m_mainWindowController client] removeQQListener:self];
	
	[self release];
}

- (void)windowDidBecomeKey:(NSNotification *)aNotification {
	if([aNotification object] != [self window])
		return;
	
	id<IMContainer> container = [self activeContainer];
	if(container) {
		[container walkMessageQueue:[m_mainWindowController messageQueue]];
	}
}

- (IBAction)showWindow:(id)sender {
	[super showWindow:sender];
	NSTabViewItem* item = [m_tabView selectedTabViewItem];
	if(item) {
		id<IMContainer> container = [[item identifier] content];
		[container walkMessageQueue:[m_mainWindowController messageQueue]];
	}
}

- (void)handleScreenscrapDataDidPopulatedNotification:(NSNotification*)notification {
	// only process this notification when I am focused
	if([[self window] isKeyWindow]) {				
		// get md5
		NSData* md5 = [[notification object] MD5];
		NSString* md5Str = [md5 hexString];
		
		// insert screenscrap
		id<IMContainer> container = [self activeContainer];
		if(container && [container allowCustomFace]) {
			[[container inputBox] insertCustomFace:kFaceTypeScreenscrap
											   md5:md5Str
											  path:[[notification userInfo] objectForKey:kUserInfoImagePath]
										  received:NO];
		}
	}
}

- (void)handleTempJPGDidCreatedNotification:(NSNotification*)notification {
	// only process this notification when I am focused
	if([[self window] isKeyWindow]) {				
		// get md5
		NSData* md5 = [[notification object] MD5];
		NSString* md5Str = [md5 hexString];
		
		// insert screenscrap
		id<IMContainer> container = [self activeContainer];
		if(container && [container allowCustomFace]) {
			[[container inputBox] insertCustomFace:kFaceTypePicture
											   md5:md5Str
											  path:[[notification userInfo] objectForKey:kUserInfoImagePath]
										  received:NO];
		}
	}
}

- (void)handleIMContainerModelDidChangedNotification:(NSNotification*)notification {
	id model = [notification object];
	id<IMContainer> container = [self activeContainer];
	if(container) {
		if([model isEqual:[container model]]) {
			// get head control
			NSToolbar* toolbar = [[self window] toolbar];
			NSToolbarItem* headItem = [[toolbar items] objectAtIndex:0];
			HeadControl* headControl = (HeadControl*)[headItem view];
			
			// refresh
			[headControl setOwner:[[m_mainWindowController me] QQ]];
			[headControl setObjectValue:model];
			[headControl display];
			
			// refresh window title, tab label if current tab model is same as changed model
			NSTabViewItem* item = [m_tabView selectedTabViewItem];
			id<IMContainer> currentContainer = [[item identifier] content];
			if(currentContainer == container) {
				// set new window title
				[[self window] setTitle:[(id)container description]];
				
				// refresh tab label
				[item setLabel:[container shortDescription]];
			}
		}
	}
}

#pragma mark -
#pragma mark helper

- (id<IMContainer>)activeContainer {
	NSTabViewItem* item = [m_tabView selectedTabViewItem];
	if(item)
		return [[item identifier] content];
	else
		return nil;
}

- (void)activateContainer:(id<IMContainer>)container {
	NSEnumerator* e = [[m_tabView tabViewItems] objectEnumerator];
	while(NSTabViewItem* item = [e nextObject]) {
		if([(id)container isEqual:[[item identifier] content]]) {
			[m_tabView selectTabViewItem:item];
			break;
		}
	}
}

- (id<IMContainer>)findContainer:(id)model {
	NSEnumerator* e = [m_containerArray objectEnumerator];
	while(id<IMContainer> container = [e nextObject]) {
		if([[container model] isEqual:model])
			return container;
	}
	return nil;
}

#pragma mark -
#pragma mark API

- (void)addContainerTab:(id<IMContainer>)container {
	// create ite
	NSTabViewItem* item = [[[NSTabViewItem alloc] initWithIdentifier:[container controller]] autorelease];
	[item setView:[container view]];
	[item setLabel:[container shortDescription]];
	
	// add item and select item
	[m_tabView addTabViewItem:item];
	[m_tabView selectTabViewItem:item];
	
	// init container
	[[container inputBox] setDelegate:self];
	
	// create history drawer
	HistoryDrawerController* historyController = [[HistoryDrawerController alloc] initWithMainWindow:m_mainWindowController history:[container history]];
	[NSBundle loadNibNamed:@"HistoryDrawer" owner:historyController];
	[[historyController drawer] setParentWindow:[self window]];
	[m_historyRegistry setObject:historyController forKey:container];
	[historyController release];
	
	// add qq listener
	[[m_mainWindowController client] addQQListener:container];
	
	// register container
	[m_containerArray addObject:container];
	
	// post notification
	[[NSNotificationCenter defaultCenter] postNotificationName:kIMContainerAttachedToWindowNotificationName
														object:[container view]
													  userInfo:[NSDictionary dictionaryWithObject:[self window] forKey:kUserInfoAttachToWindow]];
}

- (void)addUserTab:(User*)user {
	NormalIMContainerController* container = [[NormalIMContainerController alloc] initWithObject:user mainWindow:m_mainWindowController];
	if(![m_containerArray containsObject:container]) {
		// load container
		[NSBundle loadNibNamed:@"NormalIMContainer" owner:container];
		[self addContainerTab:container];
	} else
		[self activateContainer:container];
	[container release];
}

- (void)addClusterTab:(Cluster*)cluster {
	ClusterIMContainerController* container = [[ClusterIMContainerController alloc] initWithObject:cluster mainWindow:m_mainWindowController];
	if(![m_containerArray containsObject:container]) {
		// load container
		[NSBundle loadNibNamed:@"ClusterIMContainer" owner:container];
		[self addContainerTab:container];
		
		// show member list
		[container performAction:kToolbarItemSwitchMemberView];
	} else
		[self activateContainer:container];
	[container release];
}

- (void)addMobileTab:(Mobile*)mobile {
	MobileIMContainerController* container = [[MobileIMContainerController alloc] initWithObject:mobile mainWindow:m_mainWindowController];
	if(![m_containerArray containsObject:container]) {
		// load container
		[NSBundle loadNibNamed:@"MobileIMContainer" owner:container];
		[self addContainerTab:container];
	} else
		[self activateContainer:container];
	[container release];
}

- (void)addMobileTabByUser:(User*)user {
	MobileIMContainerController* container = [[MobileIMContainerController alloc] initWithObject:user mainWindow:m_mainWindowController];
	if(![m_containerArray containsObject:container]) {
		// load container
		[NSBundle loadNibNamed:@"MobileIMContainer" owner:container];
		[self addContainerTab:container];
	} else
		[self activateContainer:container];
	[container release];
}

- (void)addTempSessionTab:(User*)user {
	TempSessionIMContainerController* container = [[TempSessionIMContainerController alloc] initWithObject:user mainWindow:m_mainWindowController];
	if(![m_containerArray containsObject:container]) {
		// load container
		[NSBundle loadNibNamed:@"TempSessionIMContainer" owner:container];
		[self addContainerTab:container];
	} else
		[self activateContainer:container];
	[container release];
}

- (BOOL)isNormalIMTabFocused:(User*)user {
	if(![[self window] isKeyWindow])
		return NO;
	
	NSTabViewItem* item = [m_tabView selectedTabViewItem];
	id<IMContainer> container = [[item identifier] content];
	if([(id)container isMemberOfClass:[NormalIMContainerController class]] &&
	   [[container model] isEqual:user])
		return YES;
	else
		return NO;
}

- (BOOL)isTempSessionIMTabFocused:(User*)user {
	if(![[self window] isKeyWindow])
		return NO;
	
	NSTabViewItem* item = [m_tabView selectedTabViewItem];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -