📄 user.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 "User.h"#import "QQConstants.h"#import "PreferenceCache.h"#import "NSString-Validate.h"#import "Cluster.h"#import "ImageTool.h"#import "FileTool.h"// encoding key#define _kKeyQQ @"QQ"#define _kKeyHead @"Head"#define _kKeyNick @"Nick"#define _kKeyName @"Name"#define _kKeySignature @"Signature"#define _kKeySignatureModifiedTime @"SignatureModifiedTime"#define _kKeyLevel @"Level"#define _kKeyUpgradeDays @"UpgradeDays"#define _kKeyFlagEx @"FlagEx"#define _kKeyFlag @"Flag"#define _kKeyGroupIndex @"GroupIndex"#define _kKeyInputBoxPortion @"InputBoxPortion"#define _kKeyCustomHead @"CustomHead"@implementation User- (NSImage*)head:(UInt32)myQQ handleStatus:(BOOL)handleStatus { // head NSImage* imgMain = nil; // check custom head if([self hasCustomHead] && m_customHead != nil) { NSString* path = [FileTool getCustomHeadPath:myQQ md5:[m_customHead md5]]; imgMain = [NSImage imageNamed:path]; if(imgMain == nil) { if([FileTool isFileExist:path]) { imgMain = [[[NSImage alloc] initWithContentsOfFile:path] autorelease]; [imgMain setName:path]; } } } // check TM if(imgMain == nil) { if([self isTM]) { NSString* name = [self isMM] ? @"tm_female.gif" : @"tm_male.gif"; imgMain = [NSImage imageNamed:name]; } else imgMain = [ImageTool headWithId:m_head]; } // check offline if(handleStatus && [self isOffline]) imgMain = [ImageTool grayImage:imgMain]; return imgMain;}- (id)initWithQQ:(UInt32)QQ domain:(MainWindowController*)domain { self = [super init]; if(self) { m_domain = [domain retain]; m_QQ = QQ; m_level = 0; m_upgradeDays = 0; m_gender = kQQGenderMale; m_status = kQQStatusOffline; m_userFlag = 0; m_signatureModifiedTime = 0; m_groupIndex = kGroupIndexUndefined; m_clusterSpecificInfos = [[NSMutableDictionary dictionary] retain]; m_status = kQQStatusOffline; m_messageCount = 0; m_mobileMessageCount = 0; m_tempSessionMessageCount = 0; m_onlining = NO; m_inputBoxProportion = 0.2; m_mobileChatting = NO; m_statusMessage = kStringEmpty; } return self;}- (id)copyWithZone:(NSZone *)zone { return [self retain];}- (void)copyWithFriend:(Friend*)f { [self setHead:[f head]]; [self setAge:[f age]]; [self setMM:([f gender] == kQQGenderFemale)]; [self setNick:[f nick]]; [self setUserFlag:[f userFlag]];}- (void)copyWithFriendStatus:(FriendStatus*)fs { [self setIp:[fs ip]]; [self setPort:[fs port]]; [self setStatus:[fs status]]; [self setUserFlag:[fs userFlag]];}- (void)copyWithFriendStatusChangedNotification:(FriendStatusChangedNotification*)notify { [self setStatusMessage:[notify statusMessage]];}- (void)copyWithUserProperty:(UserProperty*)p { [self setUserFlagEx:[p userFlagEx]];}- (void)copyWithFriendLevel:(FriendLevel*)level { [self setLevel:[level level]]; [self setUpgradeDays:[level upgradeDays]];}- (void)copyWithSignature:(Signature*)sig { [self setSignature:[sig signature]]; [self setSignatureModifiedTime:[sig lastModifiedTime]];}- (void)copyWithSignatureChangedNotification:(SignatureChangedNotification*)notification { [self setSignature:[notification signature]]; [self setSignatureModifiedTime:[notification lastModifiedTime]];}- (void)copyWithRemarks:(FriendRemark*)remark { [self setRemarkName:[remark name]];}- (void) dealloc { [m_domain release]; [m_nick release]; [m_name release]; [m_signature release]; [m_userFlagEx release]; [m_contact release]; [m_remarkName release]; [m_clusterSpecificInfos release]; [m_statusMessage release]; [m_customHead release]; [super dealloc];}- (BOOL)isEqual:(id)anObject { if([anObject isKindOfClass:[User class]]) return m_QQ == [(User*)anObject QQ]; else return NO;}- (unsigned)hash { return m_QQ;}#pragma mark -#pragma mark compare- (NSComparisonResult)compareQQ:(User*)user { if(m_QQ < [user QQ]) return NSOrderedAscending; else if(m_QQ > [user QQ]) return NSOrderedDescending; else return NSOrderedSame;}- (NSComparisonResult)compareDisplayName:(User*)user { NSString* src = (m_name == nil || [m_name isEmpty]) ? m_nick : m_name; NSString* dest = ([user name] == nil || [[user name] isEmpty]) ? [user nick] : [user name]; return [src compare:dest];}- (NSComparisonResult)compare:(User*)user { // compare status, then name or nick switch(m_status) { case kQQStatusOnline: switch([user status]) { case kQQStatusOnline: return [self compareDisplayName:user]; default: return NSOrderedAscending; } break; case kQQStatusQMe: switch([user status]) { case kQQStatusOnline: return NSOrderedDescending; case kQQStatusQMe: return [self compareDisplayName:user]; default: return NSOrderedAscending; } break; case kQQStatusBusy: switch([user status]) { case kQQStatusOnline: case kQQStatusQMe: return NSOrderedDescending; case kQQStatusBusy: return [self compareDisplayName:user]; default: return NSOrderedAscending; } break; case kQQStatusAway: switch([user status]) { case kQQStatusOnline: case kQQStatusQMe: case kQQStatusBusy: return NSOrderedDescending; case kQQStatusAway: return [self compareDisplayName:user]; default: return NSOrderedAscending; } break; case kQQStatusMute: switch([user status]) { case kQQStatusOnline: case kQQStatusQMe: case kQQStatusBusy: case kQQStatusAway: return NSOrderedDescending; case kQQStatusMute: return [self compareDisplayName:user]; default: return NSOrderedAscending; } break; case kQQStatusHidden: switch([user status]) { case kQQStatusHidden: return [self compareDisplayName:user]; case kQQStatusOnline: case kQQStatusAway: case kQQStatusQMe: case kQQStatusBusy: case kQQStatusMute: return NSOrderedDescending; default: return NSOrderedAscending; } break; case kQQStatusOffline: switch([user status]) { case kQQStatusOffline: return [self compareDisplayName:user]; default: return NSOrderedDescending; } break; default: return [self compareDisplayName:user]; }}#pragma mark -#pragma mark NSCoding protocol- (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeInt32:m_QQ forKey:_kKeyQQ]; [encoder encodeInt:m_head forKey:_kKeyHead]; [encoder encodeInt:m_level forKey:_kKeyLevel]; [encoder encodeInt:m_upgradeDays forKey:_kKeyUpgradeDays]; [encoder encodeInt:m_userFlag forKey:_kKeyFlag]; [encoder encodeObject:m_userFlagEx forKey:_kKeyFlagEx]; [encoder encodeObject:m_nick forKey:_kKeyNick]; [encoder encodeObject:m_remarkName forKey:_kKeyName]; [encoder encodeObject:m_signature forKey:_kKeySignature]; [encoder encodeInt32:m_signatureModifiedTime forKey:_kKeySignatureModifiedTime]; [encoder encodeInt:m_groupIndex forKey:_kKeyGroupIndex]; [encoder encodeFloat:m_inputBoxProportion forKey:_kKeyInputBoxPortion]; if(m_customHead) [encoder encodeObject:m_customHead forKey:_kKeyCustomHead];}- (id)initWithCoder:(NSCoder *)decoder { m_QQ = [decoder decodeInt32ForKey:_kKeyQQ]; m_head = [decoder decodeIntForKey:_kKeyHead]; m_level = [decoder decodeIntForKey:_kKeyLevel]; m_upgradeDays = [decoder decodeIntForKey:_kKeyUpgradeDays]; m_userFlag = [decoder decodeIntForKey:_kKeyFlag]; m_userFlagEx = [[decoder decodeObjectForKey:_kKeyFlagEx] retain]; m_nick = [[decoder decodeObjectForKey:_kKeyNick] retain]; m_remarkName = [[decoder decodeObjectForKey:_kKeyName] retain]; m_signature = [[decoder decodeObjectForKey:_kKeySignature] retain]; m_signatureModifiedTime = [decoder decodeInt32ForKey:_kKeySignatureModifiedTime]; m_groupIndex = [decoder decodeIntForKey:_kKeyGroupIndex]; m_inputBoxProportion = [decoder decodeFloatForKey:_kKeyInputBoxPortion]; if(m_inputBoxProportion <= 0) m_inputBoxProportion = 0.2; m_customHead = [[decoder decodeObjectForKey:_kKeyCustomHead] retain]; m_gender = kQQGenderMale; m_status = kQQStatusOffline; m_contact = [[ContactInfo alloc] init]; [m_contact setHead:m_head]; [m_contact setQQ:m_QQ]; [m_contact setUserFlag:m_userFlag]; [m_contact setNick:m_nick]; m_clusterSpecificInfos = [[NSMutableDictionary dictionary] retain]; m_status = kQQStatusOffline; m_messageCount = 0; m_mobileMessageCount = 0; m_tempSessionMessageCount = 0; m_onlining = NO; m_mobileChatting = NO; m_statusMessage = kStringEmpty; return self;}#pragma mark -#pragma mark helper- (BOOL)checkFlagEx:(int)bit { if(m_userFlagEx == nil) return NO; else { const char* bytes = (const char*)[m_userFlagEx bytes]; int index = bit / 8; int shift = bit % 8; if(index >= [m_userFlagEx length]) return NO; int r = bytes[index] >> shift; return (r & 0x1) == 0x1; }}- (BOOL)isMember { return (m_userFlag & kQQFlagMember) != 0;}- (BOOL)isVIP { return (m_userFlag & kQQFlagVIP) != 0;}- (BOOL)isTM { return (m_userFlag & kQQFlagTM) != 0;}- (BOOL)isMobileQQ { return [self isBind] && (m_userFlag & kQQFlagMobile) != 0;}- (BOOL)isBind { return (m_userFlag & kQQFlagBind) != 0;}- (BOOL)hasCam { return (m_userFlag & kQQFlagCamera) != 0;}- (BOOL)hasSignature { return [self checkFlagEx:kQQFlagExHasSignature];}- (BOOL)hasCustomHead { return [self checkFlagEx:kQQFlagExHasCustomHead];}- (BOOL)has3DShow { return [self checkFlagEx:kQQFlagEx3DAvatar];}- (BOOL)hasAlbum { return [self checkFlagEx:kQQFlagExAlbum];}- (BOOL)hasFantasy { return [self checkFlagEx:kQQFlagExFantasy];}- (BOOL)hasHome { return (m_userFlag & kQQFlagHome) != 0;}- (BOOL)hasHuaXia { return [self checkFlagEx:kQQFlagExHuaXia];}- (BOOL)hasLove { return [self checkFlagEx:kQQFlagExLove];}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -