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

📄 userinfowindowcontroller.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 02111-1307 USA
 */

#import "Constants.h"
#import "UserInfoWindowController.h"
#import "MainWindowController.h"
#import "PreferenceManager.h"
#import "FileTool.h"
#import "AlertTool.h"
#import "AuthInfoOpReplyPacket.h"
#import "ModifyInfoReplyPacket.h"
#import "ModifyInfoPacket.h"
#import "SignatureOpPacket.h"
#import "AuthQuestionOpReplyPacket.h"
#import "AuthQuestionOpPacket.h"
#import "PrivacyOpPacket.h"
#import "ClusterGetCardPacket.h"
#import "WindowRegistry.h"
#import "LocalizedStringTool.h"
#import "NSString-Validate.h"

// workflow name
#define _kWorkflowGetInfos @"GetInfos"
#define _kWorkflowModifyInfos @"ModifyInfos"
#define _kWorkflowGetCard @"GetCard"
#define _kWorkflowModifyCard @"ModifyCard"

// workflow unit name
#define _kWorkflowUnitGetAuthInfo @"GetAuthInfo"
#define _kWorkflowUnitGetMyQuestion @"GetMyQuestion"
#define _kWorkflowUnitModifyQuestion @"ModifyQuestion"
#define _kWorkflowUnitGetClusterNameCard @"GetClusterNameCard"
#define _kWorkflowUnitGetUserInfo @"GetUserInfo"
#define _kWorkflowUnitModifyInfo @"ModifyInfo"
#define _kWorkflowUnitSetSearchMeByQQ @"SetSearchMeByQQ"
#define _kWorkflowUnitModifySignature @"ModifySignature"
#define _kWorkflowUnitDeleteSignature @"DeleteSignature"
#define _kWorkflowUnitGetSignature @"GetSignature"
#define _kWorkflowUnitGetLevel @"GetLevel"
#define _kWorkflowUnitModifyClusterNameCard @"ModifyClusterNameCard"
#define _kWorkflowUnitGetPrivacy @"GetPrivacy"

// sheet type
#define _kSheetOperationFinished 0

static const int headMap[][40] = {
	// start from 1, first element is count
	// Male
	{
		30,
		5,  7,  10, 14, 15, 16, 17, 28,
		36, 37, 43, 44, 46, 50, 52, 53,
		54, 60, 61, 63, 68, 72, 74, 77,
		79, 80, 82, 85, 94, 95
	},

	// Female
	{
		29, 
		6,  9,  12, 20, 29, 30, 34, 38,
		40, 45, 47, 49, 51, 55, 57, 58,
		62, 67, 70, 75, 78, 81, 83, 84, 
		86, 87, 88, 89, 90
	},

	// Pet
	{
		36,
		1,  2,  3,  4,  8,  11, 13, 17,
		18, 19, 21, 22, 23, 24, 25, 26,
		31, 32, 33, 35, 39, 41, 42, 48,
		56, 59, 64, 65, 66, 69, 71, 73,
		76, 91, 92, 93
	},

	// QQ Tang
	{
		5,
		96, 97, 98, 99, 100
	},
	
	// QQ fantasy
	{
		5,
		113, 114, 115, 116, 117
	},

	// QQ Sonic
	{
		5,
		101, 102, 103, 104, 105
	},

	// QQ HuaXia
	{
		17,
		106, 107, 108, 109, 110, 111, 112, 118, 
		119, 120, 121, 122, 123, 124, 125, 126,
		127
	}
};

@implementation UserInfoWindowController

- (id)initWithMainWindowController:(MainWindowController*)mainWindowController user:(User*)user {
	return [self initWithMainWindowController:mainWindowController user:user cluster:nil];
}

- (id)initWithMainWindowController:(MainWindowController*)mainWindowController user:(User*)user cluster:(Cluster*)cluster {
	self = [super initWithWindowNibName:@"UserInfo"];
	if(self != nil) {
		m_mainWindowController = [mainWindowController retain];
		m_user = [user retain];
		if(cluster)
			m_cluster = [cluster retain];
		m_sheetType = -1;
	}
	return self;
}

- (void) dealloc {
	[m_mainWindowController release];
	[m_user release];
	if(m_qqShowDownloader) {
		[m_qqShowDownloader cancel];
		[m_qqShowDownloader release];
		m_qqShowDownloader = nil;
	}
	if(m_tempInfo)
		[m_tempInfo release];
	if(m_authInfo)
		[m_authInfo release];
	[super dealloc];
}

- (void)windowDidLoad {
	// remove cluste name card if cluster is nil
	if(m_cluster == nil || [self isMe])
		[m_tabMain removeTabViewItem:[m_tabMain tabViewItemAtIndex:4]];
	
	// set button image
	[m_btnRefreshQQShow setImage:[NSImage imageNamed:kImageRefresh]];
	[m_headControl setEnabled:[self isMe]];
	
	// refresh combo box
	[m_cbProvince reloadData];
	[m_cbCity reloadData];
	
	//
	// init qq show panel
	//
	
	[self reloadQQShow];
	
	//
	// init other
	//
	
	[self reloadInfo];
	
	// init window
	[[self window] setTitle:[NSString stringWithFormat:L(@"LQTitleWindow", @"UserInfo"), [m_user QQ]]];
	
	// create workflow
	m_moderator = [[WorkflowModerator alloc] initWithName:_kWorkflowGetInfos dataSource:self];
	[self buildWorkflow:_kWorkflowGetInfos];
	
	// add listener to alert notification
	[[NSNotificationCenter defaultCenter] addObserver:self
											 selector:@selector(handleHeadSelectorWindowWillClose:)
												 name:NSWindowWillCloseNotification
											   object:nil];
	
	// start
	m_showAlert = NO;
	[m_moderator start:[m_mainWindowController client]];
}

- (void)windowWillClose:(NSNotification *)aNotification {
	if([aNotification object] != [self window])
		return;
	
	if(m_moderator) {
		[m_moderator cancel];
		[m_moderator release];
		m_moderator = nil;
	}
	[[m_mainWindowController windowRegistry] unregisterUserInfoWindow:[m_user QQ]];
	if(m_headSelector)
		[m_headSelector close];
	[[NSNotificationCenter defaultCenter] removeObserver:self
													name:NSWindowWillCloseNotification 
												  object:nil];
	[self release];
}

- (void)windowDidEndSheet:(NSNotification *)aNotification {
	if([aNotification object] != [self window])
		return;
	
	switch(m_sheetType) {
		case _kSheetOperationFinished:
			[self close];
			break;
	}
	
	m_sheetType = -1;
}

#pragma mark -
#pragma mark helper

- (void)handleHeadSelectorWindowWillClose:(NSNotification*)notification {
	if(m_headSelector) {
		if([notification object] == [m_headSelector window])
			m_headSelector = nil;
	}
}

- (void)reloadInfo {
	//
	// init basic info panel
	//
	
	[m_txtQQ setStringValue:[NSString stringWithFormat:@"%u", [m_user QQ]]];
	[m_txtNick setStringValue:[m_user nick]];
	[m_txtSignature setString:[m_user signature]];
	[m_levelControl setLevel:[m_user level]];
	[m_levelControl setUpgradeDays:[m_user upgradeDays]];
	[m_headControl setOwner:[[m_mainWindowController me] QQ]];
	[m_headControl setShowStatus:NO];
	[m_headControl setObjectValue:m_user];
	[m_txtName setStringValue:[m_user name]];
	[m_txtAge setStringValue:[NSString stringWithFormat:@"%d", [m_user age]]];
	if([m_user contact]) {
		[m_cbGender setStringValue:[[m_user contact] gender]];
		[m_txtCollege setStringValue:[[m_user contact] college]];
		[m_cbOccupation setStringValue:[[m_user contact] occupation]];
		[m_txtHomepage setStringValue:[[m_user contact] homepage]];
		[m_txtIntroduction setString:[[m_user contact] introduction]];
		[m_pbHoroscope selectItemAtIndex:[[m_user contact] horoscope]];
		[m_pbZodiac selectItemAtIndex:[[m_user contact] zodiac]];
		[m_pbBlood selectItemAtIndex:[[m_user contact] blood]];
	}
	
	//
	// init contact panel
	//
	
	if([m_user contact]) {
		[m_cbCountry setStringValue:[[m_user contact] country]];
		[m_cbProvince setStringValue:[[m_user contact] province]];
		[m_cbCity setStringValue:[[m_user contact] city]];
		[m_txtZipcode setStringValue:[[m_user contact] zipcode]];
		[m_pbVisibility selectItemAtIndex:[[m_user contact] contactVisibility]];
		[m_txtEmail setStringValue:[[m_user contact] email]];
		[m_txtAddress setStringValue:[[m_user contact] address]];
		[m_txtMobile setStringValue:[[m_user contact] mobile]];
		[m_txtTelephone setStringValue:[[m_user contact] telephone]];
	}
	
	//
	// init auth panel
	//
	
	if([m_user contact]) 
		[m_matrixAuthType selectCellAtRow:[[m_user contact] authType] column:0];
	[self onAuthTypeChanged:self];
}

- (void)reloadQQShow {
	NSString* qqShowPath = [FileTool getQQShowFilePath:[self myQQ] qq:[m_user QQ]];
	if([FileTool isFileExist:qqShowPath]) {
		NSImage* img = [[NSImage alloc] initWithContentsOfFile:qqShowPath];
		[m_ivQQShow setImage:img];
		[m_ivQQShow setAnimates:YES];
		[img release];
	}
}

- (BOOL)isMe {
	return [self myQQ] == [m_user QQ];
}

- (UInt32)myQQ {
	return [[m_mainWindowController me] QQ];
}

- (NSString*)titleOfCancelUpdateButton {
	if([self isMe])
		return L(@"LQCancel");
	else
		return L(@"LQUpdate");
}

- (NSString*)titleOfApplyCloseButton {
	if([self isMe])
		return L(@"LQApply");
	else
		return L(@"LQClose");
}

- (BOOL)isNameCardEditable {
	return [[m_mainWindowController me] isSuperUser:m_cluster] && [m_user isManaged:m_cluster];
}

- (void)buildWorkflow:(NSString*)name {
	[m_moderator reset:name];
	
	if([_kWorkflowGetInfos isEqualToString:name]) {
		[m_moderator addUnit:_kWorkflowUnitGetUserInfo failEvent:0];
		
		// get signature or level of a stranger always timeout, so I have to check it here
		if([[m_mainWindowController groupManager] isUserFriendly:m_user]) {
			[m_moderator addUnit:_kWorkflowUnitGetSignature failEvent:kQQEventGetSignatureFailed];
			[m_moderator addUnit:_kWorkflowUnitGetLevel failEvent:0];
		}

		[m_moderator addUnit:_kWorkflowUnitGetMyQuestion failEvent:0];
		[m_moderator addUnit:_kWorkflowUnitGetClusterNameCard failEvent:kQQEventClusterGetCardFailed];
	} else if([_kWorkflowModifyInfos isEqualToString:name]) {
		[m_moderator addUnit:_kWorkflowUnitGetAuthInfo failEvent:0 critical:YES];
		[m_moderator addUnit:_kWorkflowUnitModifyInfo failEvent:kQQEventModifyInfoFailed critical:YES];
		if([[m_txtSignature string] isEmpty])
			[m_moderator addUnit:_kWorkflowUnitDeleteSignature failEvent:kQQEventDeleteSignatureFailed critical:YES];
		else
			[m_moderator addUnit:_kWorkflowUnitModifySignature failEvent:kQQEventModifySigatureFailed critical:YES];
		[m_moderator addUnit:_kWorkflowUnitSetSearchMeByQQ failEvent:kQQEventPrivacyOpFailed critical:YES];
		[m_moderator addUnit:_kWorkflowUnitModifyQuestion failEvent:kQQEventModifyQuestionFailed critical:YES];
	} else if([_kWorkflowGetCard isEqualToString:name])
		[m_moderator addUnit:_kWorkflowUnitGetClusterNameCard failEvent:kQQEventClusterGetCardFailed critical:YES];
	else if([_kWorkflowModifyCard isEqualToString:name])
		[m_moderator addUnit:_kWorkflowUnitModifyClusterNameCard failEvent:kQQEventClusterModifyCardFailed critical:YES];
}

#pragma mark -
#pragma mark actions

- (IBAction)onOK:(id)sender {
	switch([[[m_tabMain selectedTabViewItem] identifier] intValue]) {
		case 4:
			m_apply = YES;
			m_showAlert = YES;
			[self buildWorkflow:_kWorkflowModifyCard];
			[m_moderator start:[m_mainWindowController client]];
			break;
		default:
			m_apply = NO;
			m_showAlert = YES;
			[self buildWorkflow:_kWorkflowModifyInfos];
			[m_moderator start:[m_mainWindowController client]];
			break;
	}
}

- (IBAction)onCancel:(id)sender {
	if([self isMe])
		[self close];
	else {
		switch([[[m_tabMain selectedTabViewItem] identifier] intValue]) {
			case 4:
				m_showAlert = NO;
				[self buildWorkflow:_kWorkflowGetCard];
				[m_moderator start:[m_mainWindowController client]];
				break;
			default:
				m_showAlert = NO;
				[self buildWorkflow:_kWorkflowGetInfos];
				[m_moderator start:[m_mainWindowController client]];
				break;
		}
	}
}

- (IBAction)onApply:(id)sender {
	if([self isMe]) {
		m_apply = YES;
		m_showAlert = YES;
		[self buildWorkflow:_kWorkflowModifyInfos];
		[m_moderator start:[m_mainWindowController client]];
	} else
		[self close];
}

- (IBAction)onRefreshQQShow:(id)sender {
	// start progress indicator
	[m_piDownloading setHidden:NO];
	[m_piDownloading startAnimation:self];
	[m_btnRefreshQQShow setEnabled:NO];
	
	// ensure the directory is created
	NSString* qqShowPath = [FileTool getQQShowFilePath:[self myQQ] qq:[m_user QQ]];
	[FileTool initDirectoryForFile:qqShowPath];
	
	// start downloading
	NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:L(@"LQURLQQShow"), [m_user QQ]]];
	NSURLRequest* request = [NSURLRequest requestWithURL:url];
	m_qqShowDownloader = [[NSURLDownload alloc] initWithRequest:request delegate:self];
	[m_qqShowDownloader setDeletesFileUponFailure:NO];
	[m_qqShowDownloader setDestination:qqShowPath allowOverwrite:YES];
	[m_qqShowDownloader request];
}

- (IBAction)onAuthTypeChanged:(id)sender {
	[m_cbQuestion setEnabled:([m_matrixAuthType selectedRow] == 3)];
	[m_txtAnswer setEnabled:([m_matrixAuthType selectedRow] == 3)];
}

- (IBAction)onHead:(id)sender {
	if(m_headSelector)
		return;
	
	// get head bound
	NSRect bound = [m_headControl bounds];	
	
	// calculate
	bound = [m_headControl convertRect:bound toView:nil];
		
	// create image selector window controller with frame
	m_headSelector = [[ImageSelectorWindowController alloc] initWithDataSource:self 
																	  delegate:self];
	[m_headSelector showWindow:self];
	[m_headSelector setOneShot:NO];
	[[m_headSelector window] setFrameTopLeftPoint:[[self window] convertBaseToScreen:bound.origin]];
}

#pragma mark -
#pragma mark qq show download delegate

- (void)downloadDidFinish:(NSURLDownload *)download {
	[m_piDownloading setHidden:YES];
	[m_piDownloading stopAnimation:self];
	[m_btnRefreshQQShow setEnabled:YES];
	
	[m_qqShowDownloader release];
	m_qqShowDownloader = nil;
	[self reloadQQShow];
}

- (void)download:(NSURLDownload *)download didFailWithError:(NSError *)error {

⌨️ 快捷键说明

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