📄 userinfowindowcontroller.mm
字号:
/*
* 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 + -