PageRenderTime 57ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/lilypad/Sources/LPAccountsController.m

https://github.com/sapo/sapo-messenger-for-mac
Objective C | 1255 lines | 916 code | 290 blank | 49 comment | 166 complexity | 8a65a3560d843930748d3b6b7a792967 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0, LGPL-2.1, BSD-3-Clause
  1. //
  2. // LPAccountsController.m
  3. // Lilypad
  4. //
  5. // Copyright (C) 2006-2008 PT.COM, All rights reserved.
  6. // Author: Joao Pavao <jpavao@co.sapo.pt>
  7. //
  8. // For more information on licensing, read the README file.
  9. // Para mais informações sobre o licenciamento, leia o ficheiro README.
  10. //
  11. #import "LPAccountsController.h"
  12. #import "LPAccount.h"
  13. #import "LPServerItemsInfo.h"
  14. #import "LPKeychainManager.h"
  15. static NSString *LPAllAccountsDefaultsKey = @"Accounts";
  16. static NSString *LPSortedAccountUUIDsDefaultsKey = @"Accounts Sort Order";
  17. // KVO Contexts
  18. static void *LPAccountsConfigurationChangeContext = (void *)1001;
  19. static void *LPAccountsPasswordsChangeContext = (void *)1002;
  20. static void *LPAccountsDynamicStateChangeContext = (void *)1003;
  21. @interface LPAccount () // Private Methods
  22. - (void)p_updateLocationFromChangedComputerName;
  23. @end
  24. static NSString *
  25. LPAccountsControllerNewUUIDString()
  26. {
  27. CFUUIDRef uuid = CFUUIDCreate(NULL);
  28. NSString *uuidStr = (NSString *)CFUUIDCreateString(NULL, uuid);
  29. if (uuid != NULL) CFRelease(uuid);
  30. return [uuidStr autorelease];
  31. }
  32. static void
  33. LPAccountsControllerSCDynamicStoreCallBack (SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
  34. {
  35. LPAccountsController *accountsCtrl = (LPAccountsController *)info;
  36. [[accountsCtrl accounts] makeObjectsPerformSelector:@selector(p_updateLocationFromChangedComputerName)];
  37. }
  38. @interface LPAccountsController () // Private Methods
  39. + (NSArray *)p_persistentAccountKeys;
  40. - (void)p_saveAccountsWithTimer:(NSTimer *)timer;
  41. - (void)p_saveAccountsToDefaults;
  42. - (void)p_savePasswordsForAccount:(LPAccount *)account;
  43. - (void)p_zeroOutSupportFolder:(NSString *)folder ifDifferentFromVersion:(int)versionNr;
  44. - (LPAccount *)p_firstAccountPassingOwnPredicate:(SEL)pred;
  45. - (id)p_accountsFirstNonNilObjectValueForKey:(NSString *)key;
  46. - (LPStatus)p_accountsFirstNonOfflineStatusForKey:(NSString *)key;
  47. - (NSString *)p_computedGlobalAccountName;
  48. - (LPStatus)p_computedGlobalAccountStatus;
  49. - (NSString *)p_computedGlobalAccountStatusMessage;
  50. - (LPStatus)p_computedGlobalAccountTargetStatus;
  51. - (BOOL)p_computedGlobalAccountOnlineFlag;
  52. - (BOOL)p_computedGlobalAccountOfflineFlag;
  53. - (BOOL)p_computedGlobalAccountDebuggerFlag;
  54. - (BOOL)p_computedGlobalAccountTryingToAutoReconnectFlag;
  55. - (NSImage *)p_computedGlobalAccountAvatar;
  56. - (void)p_computedGlobalAccountSMSCredit:(int *)smsCredit
  57. nrOfFreeMessages:(int *)smsFreeMessages
  58. nrOfTotalSent:(int *)smsTotalSent;
  59. - (void)p_updateCachedGlobalAccountValuesForAllKeys;
  60. - (void)p_updateCachedGlobalAccountValueForKey:(NSString *)key;
  61. @end
  62. @implementation LPAccountsController
  63. + (void)initialize
  64. {
  65. if (self == [LPAccountsController class]) {
  66. // Start by initializing some stuff on the bridge before adding any accounts
  67. NSTimeZone *tz = [NSTimeZone defaultTimeZone];
  68. NSBundle *appBundle = [NSBundle mainBundle];
  69. NSString *clientName = [NSString stringWithFormat:@"%@ Mac", [appBundle objectForInfoDictionaryKey:@"CFBundleExecutable"]];
  70. id bundleShortVersionStr = [appBundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
  71. id bundleVersion = [appBundle objectForInfoDictionaryKey:@"CFBundleVersion"];
  72. NSString *versionString = [NSString stringWithFormat:@"%@ (%@)", bundleShortVersionStr, bundleVersion];
  73. NSString *capsVersionString = [NSString stringWithFormat:@"%@_%@", bundleShortVersionStr, bundleVersion];
  74. [LFAppController setTimeZoneName:[tz abbreviation] timeZoneOffset:([tz secondsFromGMT] / 3600)];
  75. [LFAppController setClientName:clientName
  76. version:versionString
  77. OSName:@"Mac OS X"
  78. capsNode:@"http://messenger.sapo.pt/caps/mac"
  79. capsVersion:capsVersionString];
  80. }
  81. }
  82. + (LPAccountsController *)sharedAccountsController
  83. {
  84. static LPAccountsController *sharedController = nil;
  85. if (sharedController == nil) {
  86. sharedController = [[LPAccountsController alloc] init];
  87. }
  88. return sharedController;
  89. }
  90. + (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key
  91. {
  92. // Cached computed account attributes
  93. NSArray *manualNotificationKeys = [NSArray arrayWithObjects:@"name", @"status", @"statusMessage", @"targetStatus", @"online", @"offline", @"debugger", @"tryingToAutoReconnect", @"avatar", nil];
  94. return ([manualNotificationKeys containsObject:key] == NO);
  95. }
  96. - init
  97. {
  98. if (self = [super init]) {
  99. m_accountsByUUID = [[NSMutableDictionary alloc] init];
  100. m_accounts = [[NSMutableArray alloc] init];
  101. m_globalAccountStatus = LPStatusOffline;
  102. m_globalAccountTargetStatus = LPStatusOffline;
  103. m_globalAccountOfflineFlag = YES;
  104. m_isLoadingFromDefaults = NO;
  105. // System Configuration change notifications
  106. SCDynamicStoreContext ctx = { 0, (void *)self, NULL, NULL, NULL };
  107. m_dynamicStore = SCDynamicStoreCreate(NULL,
  108. (CFStringRef)[[NSBundle mainBundle] bundleIdentifier],
  109. &LPAccountsControllerSCDynamicStoreCallBack,
  110. &ctx);
  111. CFStringRef computerNameKey = SCDynamicStoreKeyCreateComputerName(NULL);
  112. if (computerNameKey) {
  113. SCDynamicStoreSetNotificationKeys(m_dynamicStore, (CFArrayRef)[NSArray arrayWithObject:(id)computerNameKey], NULL);
  114. CFRelease(computerNameKey);
  115. m_dynamicStoreNotificationsRunLoopSource = SCDynamicStoreCreateRunLoopSource(NULL, m_dynamicStore, 0);
  116. if (m_dynamicStoreNotificationsRunLoopSource)
  117. CFRunLoopAddSource(CFRunLoopGetCurrent(), m_dynamicStoreNotificationsRunLoopSource, kCFRunLoopCommonModes);
  118. }
  119. [LFPlatformBridge registerNotificationsObserver:self];
  120. [[NSNotificationCenter defaultCenter] addObserver:self
  121. selector:@selector(applicationWillTerminate:)
  122. name:NSApplicationWillTerminateNotification
  123. object:nil];
  124. }
  125. return self;
  126. }
  127. - (void)dealloc
  128. {
  129. [[NSNotificationCenter defaultCenter] removeObserver:self];
  130. [LFPlatformBridge unregisterNotificationsObserver:self];
  131. if ([self needsToSaveAccounts]) {
  132. [m_accountsSaveTimer fire];
  133. [m_accountsSaveTimer release];
  134. }
  135. [[NSUserDefaults standardUserDefaults] synchronize];
  136. [m_accounts release];
  137. [m_accountsByUUID release];
  138. if (m_dynamicStoreNotificationsRunLoopSource) {
  139. CFRunLoopSourceInvalidate(m_dynamicStoreNotificationsRunLoopSource);
  140. CFRelease(m_dynamicStoreNotificationsRunLoopSource);
  141. }
  142. if (m_dynamicStore) {
  143. CFRelease(m_dynamicStore);
  144. }
  145. // Cache of computed account attributes
  146. [m_globalAccountName release];
  147. [m_globalAccountStatusMessage release];
  148. [m_globalAccountAvatar release];
  149. [super dealloc];
  150. }
  151. - (void)loadAccountsFromDefaults
  152. {
  153. m_isLoadingFromDefaults = YES;
  154. // Setup the Caches folder and clear it if needed
  155. NSString *cachesFolder = LPOurApplicationCachesFolderPath();
  156. [self p_zeroOutSupportFolder:cachesFolder ifDifferentFromVersion:3];
  157. [LFAppController setCachesFolder:cachesFolder];
  158. NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
  159. NSDictionary *accountsFromPrefs = [defaults dictionaryForKey:LPAllAccountsDefaultsKey];
  160. NSArray *sortedAccountUUIDs = [defaults arrayForKey:LPSortedAccountUUIDsDefaultsKey];
  161. NSEnumerator *accountUUIDEnumerator = (sortedAccountUUIDs != nil ?
  162. [sortedAccountUUIDs objectEnumerator] :
  163. [accountsFromPrefs keyEnumerator]);
  164. NSString *accountUUID;
  165. while (accountUUID = [accountUUIDEnumerator nextObject]) {
  166. LPAccount *account = [m_accountsByUUID objectForKey:accountUUID];
  167. if (account == nil) {
  168. account = [[LPAccount alloc] initWithUUID:accountUUID];
  169. [self addAccount:account];
  170. [account release];
  171. }
  172. // Load the persistent account keys
  173. NSDictionary *accountDict = [accountsFromPrefs objectForKey:accountUUID];
  174. NSEnumerator *keyEnumerator = [accountDict keyEnumerator];
  175. NSString *key;
  176. while (key = [keyEnumerator nextObject]) {
  177. @try {
  178. [account setValue:[accountDict objectForKey:key] forKey:key];
  179. }
  180. @catch (NSException *exception) {
  181. if ([key isEqualToString:@"shouldAutoLogin"]) {
  182. // Once a property of the only existing account, this is now a default used by the accounts controller
  183. [defaults setObject:[accountDict objectForKey:key] forKey:@"AccountAutoLogin"];
  184. }
  185. else if ([[exception name] isEqualToString:NSUndefinedKeyException]) {
  186. // Do nothing. It's probably a key that was saved by a previous version of leapfrog but that is unknown to this version.
  187. }
  188. else {
  189. @throw exception;
  190. }
  191. }
  192. }
  193. // Accounts are assumed enabled by default when the corresponding key isn't found in the defaults
  194. if ([accountDict valueForKey:@"enabled"] == nil)
  195. [account setEnabled:YES];
  196. // Load the passwords
  197. [account setValue:[LPKeychainManager passwordForAccount:[account JID]]
  198. forKey:@"password"];
  199. NSString *username = [account lastRegisteredMSNEmail];
  200. [account setValue:[LPKeychainManager passwordForAccount:[NSString stringWithFormat:@"MSN: %@", (username ? username : @"")]]
  201. forKey:@"lastRegisteredMSNPassword"];
  202. }
  203. m_isLoadingFromDefaults = NO;
  204. }
  205. - (BOOL)needsToSaveAccounts
  206. {
  207. return (m_accountsSaveTimer != nil);
  208. }
  209. - (void)setNeedsToSaveAccounts:(BOOL)shouldSave
  210. {
  211. if (shouldSave && m_isLoadingFromDefaults == NO && m_accountsSaveTimer == nil) {
  212. m_accountsSaveTimer = [[NSTimer scheduledTimerWithTimeInterval:23.0
  213. target:self
  214. selector:@selector(p_saveAccountsWithTimer:)
  215. userInfo:nil
  216. repeats:NO] retain];
  217. }
  218. }
  219. - (LPAccount *)defaultAccount
  220. {
  221. if ([m_accounts count] == 0)
  222. [self addNewAccount];
  223. LPAccount *account = [m_accounts objectAtIndex:0];
  224. if (![account isEnabled]) {
  225. // Try to find the first enabled account
  226. NSEnumerator *accountEnum = [m_accounts objectEnumerator];
  227. // Skip the first one, as we have already tested it
  228. [accountEnum nextObject];
  229. while (account = [accountEnum nextObject])
  230. if ([account isEnabled])
  231. break;
  232. if (account == nil)
  233. account = [m_accounts objectAtIndex:0];
  234. }
  235. return account;
  236. }
  237. - (NSArray *)accounts
  238. {
  239. return [[m_accounts retain] autorelease];
  240. }
  241. - (id)delegate
  242. {
  243. return m_delegate;
  244. }
  245. - (void)setDelegate:(id)delegate
  246. {
  247. m_delegate = delegate;
  248. }
  249. - (LPAccount *)addNewAccount
  250. {
  251. LPAccount *newAccount = [[LPAccount alloc] initWithUUID: LPAccountsControllerNewUUIDString() ];
  252. [self addAccount:newAccount];
  253. return [newAccount autorelease];
  254. }
  255. - (void)addAccount:(LPAccount *)account
  256. {
  257. NSIndexSet *changedIndexes = [NSIndexSet indexSetWithIndex:[m_accounts count]];
  258. [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:changedIndexes forKey:@"accounts"];
  259. [m_accounts addObject:account];
  260. [account setDelegate:self];
  261. [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:changedIndexes forKey:@"accounts"];
  262. [m_accountsByUUID setObject:account forKey:[account UUID]];
  263. // Observe keys that should trigger a save to the defaults
  264. NSEnumerator *interestingKeyEnumerator = [[LPAccountsController p_persistentAccountKeys] objectEnumerator];
  265. NSString *someKey;
  266. while (someKey = [interestingKeyEnumerator nextObject])
  267. [account addObserver:self forKeyPath:someKey
  268. options:0 context:LPAccountsConfigurationChangeContext];
  269. // The password is a special case: it is saved to the keychain instead of going to the defaults DB along with the other properties
  270. [account addObserver:self forKeyPath:@"password"
  271. options:0 context:LPAccountsPasswordsChangeContext];
  272. [account addObserver:self forKeyPath:@"lastRegisteredMSNPassword"
  273. options:0 context:LPAccountsPasswordsChangeContext];
  274. [self setNeedsToSaveAccounts:YES];
  275. [self p_savePasswordsForAccount:account];
  276. // Also observe the keys that may change the values of some of our accessors that consider all the accounts to compute their return value
  277. // No need to add the "name" key, it is already being observed due to being a "persistent account key"
  278. [account addObserver:self forKeyPath:@"status"
  279. options:0 context:LPAccountsDynamicStateChangeContext];
  280. [account addObserver:self forKeyPath:@"statusMessage"
  281. options:0 context:LPAccountsDynamicStateChangeContext];
  282. [account addObserver:self forKeyPath:@"targetStatus"
  283. options:0 context:LPAccountsDynamicStateChangeContext];
  284. [account addObserver:self forKeyPath:@"online"
  285. options:0 context:LPAccountsDynamicStateChangeContext];
  286. [account addObserver:self forKeyPath:@"offline"
  287. options:0 context:LPAccountsDynamicStateChangeContext];
  288. [account addObserver:self forKeyPath:@"debugger"
  289. options:0 context:LPAccountsDynamicStateChangeContext];
  290. [account addObserver:self forKeyPath:@"tryingToAutoReconnect"
  291. options:0 context:LPAccountsDynamicStateChangeContext];
  292. [account addObserver:self forKeyPath:@"avatar"
  293. options:0 context:LPAccountsDynamicStateChangeContext];
  294. [account addObserver:self forKeyPath:@"SMSCreditValues"
  295. options:0 context:LPAccountsDynamicStateChangeContext];
  296. // Make sure the core is aware of it
  297. [LFAppController addAccountWithUUID:[account UUID]];
  298. [self p_updateCachedGlobalAccountValuesForAllKeys];
  299. }
  300. - (void)removeAccount:(LPAccount *)account
  301. {
  302. [account setTargetStatus:LPStatusOffline];
  303. [LFAppController removeAccountWithUUID:[account UUID]];
  304. [account removeObserver:self forKeyPath:@"SMSCreditValues"];
  305. [account removeObserver:self forKeyPath:@"avatar"];
  306. [account removeObserver:self forKeyPath:@"tryingToAutoReconnect"];
  307. [account removeObserver:self forKeyPath:@"debugger"];
  308. [account removeObserver:self forKeyPath:@"offline"];
  309. [account removeObserver:self forKeyPath:@"online"];
  310. [account removeObserver:self forKeyPath:@"targetStatus"];
  311. [account removeObserver:self forKeyPath:@"statusMessage"];
  312. [account removeObserver:self forKeyPath:@"status"];
  313. [account removeObserver:self forKeyPath:@"lastRegisteredMSNPassword"];
  314. [account removeObserver:self forKeyPath:@"password"];
  315. // Remove as observer of keys that should trigger a save to the defaults
  316. NSEnumerator *interestingKeyEnumerator = [[LPAccountsController p_persistentAccountKeys] objectEnumerator];
  317. NSString *someKey;
  318. while (someKey = [interestingKeyEnumerator nextObject])
  319. [account removeObserver:self forKeyPath:someKey];
  320. [m_accountsByUUID removeObjectForKey:[account UUID]];
  321. NSIndexSet *changedIndexes = [NSIndexSet indexSetWithIndex:[m_accounts indexOfObject:account]];
  322. [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:changedIndexes forKey:@"accounts"];
  323. [m_accounts removeObject:account];
  324. [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:changedIndexes forKey:@"accounts"];
  325. [self setNeedsToSaveAccounts:YES];
  326. [self p_updateCachedGlobalAccountValuesForAllKeys];
  327. }
  328. - (void)moveAccount:(LPAccount *)account toIndex:(int)newIndex
  329. {
  330. NSAssert([m_accounts containsObject:account], @"The account is not a member of this accounts controller!");
  331. if ([m_accounts indexOfObject:account] != newIndex) {
  332. [account retain];
  333. [self willChangeValueForKey:@"accounts"];
  334. [m_accounts removeObject:account];
  335. [m_accounts insertObject:account atIndex:newIndex];
  336. [self didChangeValueForKey:@"accounts"];
  337. [account release];
  338. [self setNeedsToSaveAccounts:YES];
  339. }
  340. }
  341. - (LPAccount *)accountForUUID:(NSString *)theUUID
  342. {
  343. return [m_accountsByUUID objectForKey:theUUID];
  344. }
  345. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
  346. {
  347. // Do the changes require that we save the current accounts configuration?
  348. if (context == LPAccountsConfigurationChangeContext) {
  349. [self setNeedsToSaveAccounts:YES];
  350. if ([keyPath isEqualToString:@"JID"] || [keyPath isEqualToString:@"lastRegisteredMSNEmail"]) {
  351. // The passwords saved in the keychain reference these values
  352. [self p_savePasswordsForAccount:object];
  353. }
  354. }
  355. else if (context == LPAccountsPasswordsChangeContext) {
  356. [self p_savePasswordsForAccount:object];
  357. }
  358. if ([keyPath isEqualToString:@"enabled"])
  359. {
  360. [self p_updateCachedGlobalAccountValuesForAllKeys];
  361. LPAccount *account = object;
  362. if ([account isEnabled] && [account isOffline])
  363. [account setTargetStatus:[self targetStatus] message:[self statusMessage] saveToServer:YES];
  364. if (![account isEnabled] && ![account isOffline])
  365. [account setTargetStatus:LPStatusOffline];
  366. }
  367. else
  368. {
  369. [self p_updateCachedGlobalAccountValueForKey:keyPath];
  370. }
  371. }
  372. #pragma mark -
  373. #pragma mark NSApplication Notifications
  374. - (void)applicationWillTerminate:(NSNotification *)notif
  375. {
  376. if ([self needsToSaveAccounts])
  377. [m_accountsSaveTimer fire];
  378. [[NSUserDefaults standardUserDefaults] synchronize];
  379. }
  380. #pragma mark -
  381. #pragma mark Private
  382. + (NSArray *)p_persistentAccountKeys
  383. {
  384. return [NSArray arrayWithObjects:
  385. @"description", @"enabled", @"name", @"JID", @"location",
  386. @"customServerHost", @"usesCustomServerHost",
  387. @"lastSuccessfullyConnectedServerHost",
  388. @"usesSSL", @"locationUsesComputerName",
  389. @"lastRegisteredMSNEmail", nil];
  390. }
  391. - (void)p_saveAccountsWithTimer:(NSTimer *)timer
  392. {
  393. if (!m_isLoadingFromDefaults) {
  394. [self p_saveAccountsToDefaults];
  395. }
  396. [m_accountsSaveTimer autorelease];
  397. m_accountsSaveTimer = nil;
  398. }
  399. - (void)p_saveAccountsToDefaults
  400. {
  401. NSMutableDictionary *accountsPropsToSave = [NSMutableDictionary dictionary];
  402. NSArray *keysToBeSaved = [LPAccountsController p_persistentAccountKeys];
  403. NSEnumerator *accountEnumerator = [m_accounts objectEnumerator];
  404. LPAccount *account;
  405. while (account = [accountEnumerator nextObject]) {
  406. // Get the values for the persistent keys. We don't use -dictionaryWithValuesForKeys: because the NSNulls returned for nil
  407. // values aren't valid plist objects and can't be saved to the defaults.
  408. NSMutableDictionary *currentValuesAndKeys = [NSMutableDictionary dictionary];
  409. NSEnumerator *keyEnumerator = [keysToBeSaved objectEnumerator];
  410. NSString *key;
  411. while (key = [keyEnumerator nextObject]) {
  412. id value = [account valueForKey:key];
  413. if (value != nil && value != [NSNull null]) {
  414. [currentValuesAndKeys setValue:value forKey:key];
  415. }
  416. }
  417. // Save the persistent account keys
  418. [accountsPropsToSave setObject:currentValuesAndKeys forKey:[account UUID]];
  419. }
  420. [[NSUserDefaults standardUserDefaults] setObject:accountsPropsToSave forKey:LPAllAccountsDefaultsKey];
  421. [[NSUserDefaults standardUserDefaults] setObject:[m_accounts valueForKey:@"UUID"] forKey:LPSortedAccountUUIDsDefaultsKey];
  422. }
  423. - (void)p_savePasswordsForAccount:(LPAccount *)account
  424. {
  425. if (!m_isLoadingFromDefaults) {
  426. if ([[account JID] length] > 0 && [[account password] length] > 0) {
  427. [LPKeychainManager savePassword:[account password] forAccount:[account JID]];
  428. }
  429. NSString *username = [account lastRegisteredMSNEmail];
  430. if ([username length] > 0 && [[account lastRegisteredMSNPassword] length] > 0) {
  431. [LPKeychainManager savePassword:[account lastRegisteredMSNPassword]
  432. forAccount:[NSString stringWithFormat:@"MSN: %@", (username ? username : @"")]];
  433. }
  434. }
  435. }
  436. - (void)p_zeroOutSupportFolder:(NSString *)folder ifDifferentFromVersion:(int)versionNr
  437. {
  438. NSString *contentsVersionFilePath = [folder stringByAppendingPathComponent:@"version"];
  439. NSString *folderContentsVersionStr = [NSString stringWithContentsOfFile:contentsVersionFilePath encoding:NSUTF8StringEncoding error:NULL];
  440. if ([folderContentsVersionStr intValue] != versionNr) {
  441. NSFileManager *fm = [NSFileManager defaultManager];
  442. [fm removeFileAtPath:folder handler:nil];
  443. [fm createDirectoryAtPath:folder attributes:nil];
  444. [[NSString stringWithFormat:@"%d", versionNr] writeToFile:contentsVersionFilePath
  445. atomically:YES
  446. encoding:NSUTF8StringEncoding
  447. error:NULL];
  448. }
  449. }
  450. #pragma mark Attributes computed from all the accounts managed by this controller
  451. - (LPAccount *)p_firstAccountPassingOwnPredicate:(SEL)pred
  452. {
  453. NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[LPAccount instanceMethodSignatureForSelector:pred]];
  454. [inv setSelector:pred];
  455. NSAssert([[inv methodSignature] methodReturnLength] <= sizeof(BOOL), @"Return value of the provided predicate takes more space than a BOOL!");
  456. NSEnumerator *accountEnum = [m_accounts objectEnumerator];
  457. LPAccount *account = nil;
  458. BOOL passedPredicate = NO;
  459. while (account = [accountEnum nextObject]) {
  460. if ([account isEnabled]) {
  461. [inv invokeWithTarget:account];
  462. [inv getReturnValue:&passedPredicate];
  463. if (passedPredicate) break;
  464. }
  465. }
  466. return account;
  467. }
  468. - (id)p_accountsFirstNonNilObjectValueForKey:(NSString *)key
  469. {
  470. NSEnumerator *accountEnum = [m_accounts objectEnumerator];
  471. LPAccount *account;
  472. id value = nil;
  473. while (value == nil && (account = [accountEnum nextObject]))
  474. if ([account isEnabled])
  475. value = [account valueForKey:key];
  476. return value;
  477. }
  478. - (LPStatus)p_accountsFirstNonOfflineStatusForKey:(NSString *)key
  479. {
  480. NSEnumerator *accountEnum = [m_accounts objectEnumerator];
  481. LPAccount *account;
  482. LPStatus status = LPStatusOffline;
  483. while (status == LPStatusOffline && (account = [accountEnum nextObject]))
  484. if ([account isEnabled])
  485. status = (LPStatus)[[account valueForKey:key] intValue];
  486. return status;
  487. }
  488. - (NSString *)p_computedGlobalAccountName
  489. {
  490. NSString *computedName = nil;
  491. NSEnumerator *accountEnum = [m_accounts objectEnumerator];
  492. LPAccount *account;
  493. while (account = [accountEnum nextObject]) {
  494. if ([account isEnabled]) {
  495. NSString *accountName = [account name];
  496. if ([accountName length] > 0) {
  497. computedName = accountName;
  498. break;
  499. }
  500. }
  501. }
  502. return computedName;
  503. }
  504. - (LPStatus)p_computedGlobalAccountStatus
  505. {
  506. return [self p_accountsFirstNonOfflineStatusForKey:@"status"];
  507. }
  508. - (NSString *)p_computedGlobalAccountStatusMessage
  509. {
  510. // Check whether there is some account trying to get connected. If there is, we want to use this as the prevailing
  511. // status message to be displayed to the user.
  512. NSEnumerator *accountEnum = [m_accounts objectEnumerator];
  513. LPAccount *account;
  514. LPStatus status = LPStatusOffline;
  515. while (status != LPStatusConnecting && (account = [accountEnum nextObject]))
  516. if ([account isEnabled])
  517. status = [account status];
  518. if (account != nil)
  519. return [account statusMessage];
  520. else
  521. return [self p_accountsFirstNonNilObjectValueForKey:@"statusMessage"];
  522. }
  523. - (LPStatus)p_computedGlobalAccountTargetStatus
  524. {
  525. return [self p_accountsFirstNonOfflineStatusForKey:@"targetStatus"];
  526. }
  527. - (BOOL)p_computedGlobalAccountOnlineFlag
  528. {
  529. return ([self p_firstAccountPassingOwnPredicate:@selector(isOnline)] != nil);
  530. }
  531. - (BOOL)p_computedGlobalAccountOfflineFlag
  532. {
  533. // We can't use the p_firstAccountPassingOwnPredicate: method because we want the inverse: we want to know if all the accounts are offline
  534. NSEnumerator *accountEnum = [m_accounts objectEnumerator];
  535. LPAccount *account;
  536. BOOL isOffline = YES;
  537. while (isOffline == YES && (account = [accountEnum nextObject]))
  538. isOffline = [account isOffline];
  539. return isOffline;
  540. }
  541. - (BOOL)p_computedGlobalAccountDebuggerFlag
  542. {
  543. return ([self p_firstAccountPassingOwnPredicate:@selector(isDebugger)] != nil);
  544. }
  545. - (BOOL)p_computedGlobalAccountTryingToAutoReconnectFlag
  546. {
  547. return ([self p_firstAccountPassingOwnPredicate:@selector(isTryingToAutoReconnect)] != nil);
  548. }
  549. - (NSImage *)p_computedGlobalAccountAvatar
  550. {
  551. return [self p_accountsFirstNonNilObjectValueForKey:@"avatar"];
  552. }
  553. - (void)p_computedGlobalAccountSMSCredit:(int *)smsCredit nrOfFreeMessages:(int *)smsFreeMessages nrOfTotalSent:(int *)smsTotalSent
  554. {
  555. NSEnumerator *accountEnum = [m_accounts objectEnumerator];
  556. LPAccount *account = nil;
  557. *smsCredit = *smsFreeMessages = *smsTotalSent = LPAccountSMSCreditUnknown;
  558. while (account = [accountEnum nextObject]) {
  559. if ([account isEnabled]) {
  560. if ([account SMSCreditAvailable] != LPAccountSMSCreditUnknown) {
  561. if (*smsCredit == LPAccountSMSCreditUnknown)
  562. *smsCredit = 0;
  563. *smsCredit += [account SMSCreditAvailable];
  564. }
  565. if ([account nrOfFreeSMSMessagesAvailable] != LPAccountSMSCreditUnknown) {
  566. if (*smsFreeMessages == LPAccountSMSCreditUnknown)
  567. *smsFreeMessages = 0;
  568. *smsFreeMessages += [account nrOfFreeSMSMessagesAvailable];
  569. }
  570. if ([account nrOfSMSMessagesSentThisMonth] != LPAccountSMSCreditUnknown) {
  571. if (*smsTotalSent == LPAccountSMSCreditUnknown)
  572. *smsTotalSent = 0;
  573. *smsTotalSent += [account nrOfSMSMessagesSentThisMonth];
  574. }
  575. }
  576. }
  577. }
  578. #pragma mark -
  579. - (void)p_updateCachedGlobalAccountValuesForAllKeys
  580. {
  581. [self p_updateCachedGlobalAccountValueForKey:nil];
  582. }
  583. - (void)p_updateCachedGlobalAccountValueForKey:(NSString *)key
  584. {
  585. // Update the cached values of any account attribute that has changed
  586. if (key == nil || [key isEqualToString:@"name"]) {
  587. [self willChangeValueForKey:@"name"];
  588. [m_globalAccountName release];
  589. m_globalAccountName = [[self p_computedGlobalAccountName] copy];
  590. [self didChangeValueForKey:@"name"];
  591. }
  592. if (key == nil || [key isEqualToString:@"status"]) {
  593. [self willChangeValueForKey:@"status"];
  594. m_globalAccountStatus = [self p_computedGlobalAccountStatus];
  595. [self didChangeValueForKey:@"status"];
  596. }
  597. if (key == nil || [key isEqualToString:@"statusMessage"]) {
  598. [self willChangeValueForKey:@"statusMessage"];
  599. [m_globalAccountStatusMessage release];
  600. m_globalAccountStatusMessage = [[self p_computedGlobalAccountStatusMessage] copy];
  601. [self didChangeValueForKey:@"statusMessage"];
  602. }
  603. if (key == nil || [key isEqualToString:@"targetStatus"]) {
  604. [self willChangeValueForKey:@"targetStatus"];
  605. m_globalAccountTargetStatus = [self p_computedGlobalAccountTargetStatus];
  606. [self didChangeValueForKey:@"targetStatus"];
  607. }
  608. if (key == nil || [key isEqualToString:@"online"]) {
  609. [self willChangeValueForKey:@"online"];
  610. m_globalAccountOnlineFlag = [self p_computedGlobalAccountOnlineFlag];
  611. [self didChangeValueForKey:@"online"];
  612. }
  613. if (key == nil || [key isEqualToString:@"offline"]) {
  614. [self willChangeValueForKey:@"offline"];
  615. m_globalAccountOfflineFlag = [self p_computedGlobalAccountOfflineFlag];
  616. [self didChangeValueForKey:@"offline"];
  617. }
  618. if (key == nil || [key isEqualToString:@"debugger"]) {
  619. [self willChangeValueForKey:@"debugger"];
  620. m_globalAccountDebuggerFlag = [self p_computedGlobalAccountDebuggerFlag];
  621. [self didChangeValueForKey:@"debugger"];
  622. }
  623. if (key == nil || [key isEqualToString:@"tryingToAutoReconnect"]) {
  624. [self willChangeValueForKey:@"tryingToAutoReconnect"];
  625. m_globalAccountReconnectingFlag = [self p_computedGlobalAccountTryingToAutoReconnectFlag];
  626. [self didChangeValueForKey:@"tryingToAutoReconnect"];
  627. }
  628. if (key == nil || [key isEqualToString:@"avatar"]) {
  629. [self willChangeValueForKey:@"avatar"];
  630. [m_globalAccountAvatar release];
  631. m_globalAccountAvatar = [[self p_computedGlobalAccountAvatar] retain];
  632. [self didChangeValueForKey:@"avatar"];
  633. }
  634. if (key == nil || [key isEqualToString:@"SMSCreditValues"]) {
  635. [self willChangeValueForKey:@"SMSCreditValues"];
  636. [self p_computedGlobalAccountSMSCredit:&m_globalAccountSMSCredit
  637. nrOfFreeMessages:&m_globalAccountSMSFreeMessages
  638. nrOfTotalSent:&m_globalAccountSMSTotalSent];
  639. [self didChangeValueForKey:@"SMSCreditValues"];
  640. }
  641. }
  642. #pragma mark -
  643. #pragma mark Actions
  644. - (IBAction)connectAllEnabledAccounts:(id)sender
  645. {
  646. [self setTargetStatus:LPStatusAvailable];
  647. }
  648. - (IBAction)disconnectAllAccounts:(id)sender
  649. {
  650. NSEnumerator *accountEnumerator = [m_accounts objectEnumerator];
  651. LPAccount *account;
  652. while (account = [accountEnumerator nextObject]) {
  653. [account setTargetStatus:LPStatusOffline];
  654. }
  655. }
  656. #pragma mark -
  657. #pragma mark Attributes computed from all the accounts managed by this controller
  658. - (NSString *)name
  659. {
  660. return [[m_globalAccountName copy] autorelease];
  661. }
  662. - (void)setName:(NSString *)theName
  663. {
  664. [m_accounts setValue:theName forKey:@"name"];
  665. }
  666. - (LPStatus)status
  667. {
  668. return m_globalAccountStatus;
  669. }
  670. - (NSString *)statusMessage
  671. {
  672. return [[m_globalAccountStatusMessage copy] autorelease];
  673. }
  674. - (void)setStatusMessage:(NSString *)theStatusMessage
  675. {
  676. NSEnumerator *accountEnum = [m_accounts objectEnumerator];
  677. LPAccount *account;
  678. while (account = [accountEnum nextObject])
  679. if ([account isEnabled])
  680. [account setStatusMessage:theStatusMessage];
  681. }
  682. - (void)setStatusMessage:(NSString *)theStatusMessage saveToServer:(BOOL)saveFlag
  683. {
  684. NSEnumerator *accountEnum = [m_accounts objectEnumerator];
  685. LPAccount *account;
  686. while (account = [accountEnum nextObject])
  687. if ([account isEnabled])
  688. [account setStatusMessage:theStatusMessage saveToServer:saveFlag];
  689. }
  690. - (LPStatus)targetStatus
  691. {
  692. return m_globalAccountTargetStatus;
  693. }
  694. - (void)setTargetStatus:(LPStatus)theStatus
  695. {
  696. NSEnumerator *accountEnum = [m_accounts objectEnumerator];
  697. LPAccount *account;
  698. while (account = [accountEnum nextObject])
  699. if ([account isEnabled])
  700. [account setTargetStatus:theStatus];
  701. }
  702. - (void)setTargetStatus:(LPStatus)theStatus saveToServer:(BOOL)saveFlag
  703. {
  704. NSEnumerator *accountEnum = [m_accounts objectEnumerator];
  705. LPAccount *account;
  706. while (account = [accountEnum nextObject])
  707. if ([account isEnabled])
  708. [account setTargetStatus:theStatus saveToServer:saveFlag];
  709. }
  710. - (void)setTargetStatus:(LPStatus)theStatus message:(NSString *)theMessage saveToServer:(BOOL)saveFlag
  711. {
  712. NSEnumerator *accountEnum = [m_accounts objectEnumerator];
  713. LPAccount *account;
  714. while (account = [accountEnum nextObject])
  715. if ([account isEnabled])
  716. [account setTargetStatus:theStatus message:theMessage saveToServer:saveFlag];
  717. }
  718. - (void)setTargetStatus:(LPStatus)theStatus message:(NSString *)theMessage saveToServer:(BOOL)saveFlag alsoSaveStatusMessage:(BOOL)saveMsg
  719. {
  720. NSEnumerator *accountEnum = [m_accounts objectEnumerator];
  721. LPAccount *account;
  722. while (account = [accountEnum nextObject])
  723. if ([account isEnabled])
  724. [account setTargetStatus:theStatus message:theMessage saveToServer:saveFlag alsoSaveStatusMessage:saveMsg];
  725. }
  726. - (BOOL)isOnline
  727. {
  728. return m_globalAccountOnlineFlag;
  729. }
  730. - (BOOL)isOffline
  731. {
  732. return m_globalAccountOfflineFlag;
  733. }
  734. - (BOOL)isDebugger
  735. {
  736. return m_globalAccountDebuggerFlag;
  737. }
  738. - (BOOL)isTryingToAutoReconnect
  739. {
  740. return m_globalAccountReconnectingFlag;
  741. }
  742. - (NSImage *)avatar
  743. {
  744. return [[m_globalAccountAvatar retain] autorelease];
  745. }
  746. - (void)setAvatar:(NSImage *)avatar
  747. {
  748. NSEnumerator *accountEnum = [m_accounts objectEnumerator];
  749. LPAccount *account;
  750. while (account = [accountEnum nextObject])
  751. if ([account isEnabled])
  752. [account setAvatar:avatar];
  753. }
  754. - (LPAccount *)accountForSendingSMS
  755. {
  756. NSEnumerator *accountsEnum = [[self accounts] objectEnumerator];
  757. LPAccount *account;
  758. while (account = [accountsEnum nextObject]) {
  759. NSDictionary *itemsInfoByFeature = [[account serverItemsInfo] itemsByFeature];
  760. NSArray *itemForSMS = [itemsInfoByFeature objectForKey:@"sapo:sms"];
  761. if (itemForSMS != nil && [itemForSMS count] > 0) {
  762. // This one will do
  763. break;
  764. }
  765. }
  766. return account;
  767. }
  768. - (int)SMSCreditAvailable
  769. {
  770. return m_globalAccountSMSCredit;
  771. }
  772. - (int)nrOfFreeSMSMessagesAvailable
  773. {
  774. return m_globalAccountSMSFreeMessages;
  775. }
  776. - (int)nrOfSMSMessagesSentThisMonth
  777. {
  778. return m_globalAccountSMSTotalSent;
  779. }
  780. #pragma mark -
  781. #pragma mark LPAccount Delegate Methods
  782. - (void)account:(LPAccount *)account didReceiveErrorNamed:(NSString *)errorName errorKind:(int)errorKind errorCode:(int)errorCode
  783. {
  784. if ([m_delegate respondsToSelector:@selector(accountsController:account:didReceiveErrorNamed:errorKind:errorCode:)]) {
  785. [m_delegate accountsController:self account:account didReceiveErrorNamed:errorName errorKind:errorKind errorCode:errorCode];
  786. }
  787. }
  788. - (void)account:(LPAccount *)account didReceiveSavedStatus:(LPStatus)status message:(NSString *)statusMessage
  789. {
  790. if ([m_delegate respondsToSelector:@selector(accountsController:account:didReceiveSavedStatus:message:)]) {
  791. [m_delegate accountsController:self account:account didReceiveSavedStatus:status message:statusMessage];
  792. }
  793. }
  794. - (void)account:(LPAccount *)account didReceiveLiveUpdateURL:(NSString *)URLString
  795. {
  796. if ([m_delegate respondsToSelector:@selector(accountsController:account:didReceiveLiveUpdateURL:)]) {
  797. [m_delegate accountsController:self account:account didReceiveLiveUpdateURL:URLString];
  798. }
  799. }
  800. - (void)account:(LPAccount *)account didReceiveServerVarsDictionary:(NSDictionary *)varsValues
  801. {
  802. if ([m_delegate respondsToSelector:@selector(accountsController:account:didReceiveServerVarsDictionary:)]) {
  803. [m_delegate accountsController:self account:account didReceiveServerVarsDictionary:varsValues];
  804. }
  805. }
  806. - (void)account:(LPAccount *)account didReceiveOfflineMessageFromJID:(NSString *)jid nick:(NSString *)nick timestamp:(NSString *)timestamp subject:(NSString *)subject plainTextVariant:(NSString *)plainTextVariant XHTMLVariant:(NSString *)xhtmlVariant URLs:(NSArray *)urls
  807. {
  808. if ([m_delegate respondsToSelector:@selector(accountsController:account:didReceiveOfflineMessageFromJID:nick:timestamp:subject:plainTextVariant:XHTMLVariant:URLs:)]) {
  809. [m_delegate accountsController:self account:account didReceiveOfflineMessageFromJID:jid nick:nick timestamp:timestamp
  810. subject:subject plainTextVariant:plainTextVariant XHTMLVariant:xhtmlVariant URLs:urls];
  811. }
  812. }
  813. - (void)account:(LPAccount *)account didReceiveHeadlineNotificationMessageFromChannel:(NSString *)channelName subject:(NSString *)subject body:(NSString *)body itemURL:(NSString *)itemURL flashURL:(NSString *)flashURL iconURL:(NSString *)iconURL
  814. {
  815. if ([m_delegate respondsToSelector:@selector(accountsController:account:didReceiveHeadlineNotificationMessageFromChannel:subject:body:itemURL:flashURL:iconURL:)]) {
  816. [m_delegate accountsController:self account:account didReceiveHeadlineNotificationMessageFromChannel:channelName subject:subject body:body
  817. itemURL:itemURL flashURL:flashURL iconURL:iconURL];
  818. }
  819. }
  820. - (void)account:(LPAccount *)account didReceiveChatRoomsList:(NSArray *)chatRoomsList forHost:(NSString *)host
  821. {
  822. if ([m_delegate respondsToSelector:@selector(accountsController:account:didReceiveChatRoomsList:forHost:)]) {
  823. [m_delegate accountsController:self account:account didReceiveChatRoomsList:chatRoomsList forHost:host];
  824. }
  825. }
  826. - (void)account:(LPAccount *)account didReceiveInfo:(NSDictionary *)chatRoomInfo forChatRoomWithJID:(NSString *)roomJID
  827. {
  828. if ([m_delegate respondsToSelector:@selector(accountsController:account:didReceiveInfo:forChatRoomWithJID:)]) {
  829. [m_delegate accountsController:self account:account didReceiveInfo:chatRoomInfo forChatRoomWithJID:roomJID];
  830. }
  831. }
  832. - (void)account:(LPAccount *)account didReceiveInvitationToRoomWithJID:(NSString *)roomJID from:(NSString *)senderJID reason:(NSString *)reason password:(NSString *)password
  833. {
  834. if ([m_delegate respondsToSelector:@selector(accountsController:account:didReceiveInvitationToRoomWithJID:from:reason:password:)]) {
  835. [m_delegate accountsController:self account:account didReceiveInvitationToRoomWithJID:roomJID from:senderJID reason:reason password:password];
  836. }
  837. }
  838. #pragma mark -
  839. #pragma mark Bridge Notifications
  840. - (void)leapfrogBridge_accountConnectedToServer:(NSString *)accountUUID :(NSString *)localAddress :(NSString *)remoteAddress
  841. {
  842. [[self accountForUUID:accountUUID] handleAccountConnectedToServerUsingLocalAddress:localAddress remoteAddress:remoteAddress];
  843. }
  844. - (void)leapfrogBridge_connectionError:(NSString *)accountUUID :(NSString *)errorName :(int)errorKind :(int)errorCode
  845. {
  846. [[self accountForUUID:accountUUID] handleConnectionErrorWithName:errorName kind:errorKind code:errorCode];
  847. }
  848. - (void)leapfrogBridge_statusUpdated:(NSString *)accountUUID :(NSString *)status :(NSString *)statusMessage
  849. {
  850. [[self accountForUUID:accountUUID] handleStatusUpdated:status message:statusMessage];
  851. }
  852. - (void)leapfrogBridge_savedStatusReceived:(NSString *)accountUUID :(NSString *)status :(NSString *)statusMessage
  853. {
  854. [[self accountForUUID:accountUUID] handleSavedStatusReceived:status message:statusMessage];
  855. }
  856. - (void)leapfrogBridge_selfAvatarChanged:(NSString *)accountUUID :(NSString *)type :(NSData *)avatarData
  857. {
  858. [[self accountForUUID:accountUUID] handleSelfAvatarChangedWithType:type data:avatarData];
  859. }
  860. - (oneway void)leapfrogBridge_accountXmlIO:(NSString *)accountUUID :(BOOL)isInbound :(NSString *)xml
  861. {
  862. [[self accountForUUID:accountUUID] handleAccountXmlIO:xml isInbound:isInbound];
  863. }
  864. - (void)leapfrogBridge_offlineMessageReceived:(NSString *)accountUUID :(NSString *)timestamp :(NSString *)jid :(NSString *)nick :(NSString *)subject :(NSString *)plainTextMessage :(NSString *)XHTMLMessage :(NSArray *)URLs
  865. {
  866. [[self accountForUUID:accountUUID] handleReceivedOfflineMessageAt:(NSString *)timestamp
  867. fromJID:(NSString *)jid nickname:(NSString *)nick
  868. subject:(NSString *)subject
  869. plainTextMessage:(NSString *)plainTextMessage XHTMLMessaage:(NSString *)XHTMLMessage
  870. URLs:(NSArray *)URLs];
  871. }
  872. - (void)leapfrogBridge_headlineNotificationMessageReceived:(NSString *)accountUUID :(NSString *)channel :(NSString *)item_url :(NSString *)flash_url :(NSString *)icon_url :(NSString *)nick :(NSString *)subject :(NSString *)plainTextMessage :(NSString *)XHTMLMessage
  873. {
  874. [[self accountForUUID:accountUUID] handleReceivedHeadlineNotificationMessageFromChannel:channel
  875. itemURL:item_url flashURL:flash_url iconURL:icon_url
  876. nickname:nick subject:subject
  877. plainTextMessage:plainTextMessage
  878. XHTMLMessage:XHTMLMessage];
  879. }
  880. - (void)leapfrogBridge_smsCreditUpdated:(NSString *)accountUUID :(int)credit :(int)free_msgs :(int)total_sent_this_month
  881. {
  882. [[self accountForUUID:accountUUID] handleSMSCreditUpdated:credit freeMessages:free_msgs totalSent:total_sent_this_month];
  883. }
  884. - (void)leapfrogBridge_smsSent:(NSString *)accountUUID
  885. :(int)result :(int)nr_used_msgs :(int)nr_used_chars
  886. :(NSString *)destination_phone_nr :(NSString *)body
  887. :(int)credit :(int)free_msgs :(int)total_sent_this_month
  888. {
  889. [[self accountForUUID:accountUUID] handleSMSSentWithResult:result nrUsedMessages:nr_used_msgs nrUsedChars:nr_used_chars
  890. destinationPhoneNr:destination_phone_nr body:body
  891. credit:credit freeMessages:free_msgs totalSent:total_sent_this_month];
  892. }
  893. - (void)leapfrogBridge_smsReceived:(NSString *)accountUUID
  894. :(NSString *)date_received
  895. :(NSString *)source_phone_nr :(NSString *)body
  896. :(int)credit :(int)free_msgs :(int)total_sent_this_month
  897. {
  898. [[self accountForUUID:accountUUID] handleSMSReceivedAt:date_received fromPhoneNr:source_phone_nr body:body
  899. credit:credit freeMessages:free_msgs totalSent:total_sent_this_month];
  900. }
  901. - (void)leapfrogBridge_serverItemsUpdated:(NSString *)accountUUID :(NSArray *)serverItems
  902. {
  903. [[self accountForUUID:accountUUID] handleServerItemsUpdated:serverItems];
  904. }
  905. - (void)leapfrogBridge_serverItemInfoUpdated:(NSString *)accountUUID :(NSString *)item :(NSString *)name :(NSArray *)identities :(NSArray *)features
  906. {
  907. [[self accountForUUID:accountUUID] handleInfoUpdatedForServerItem:item withName:name identities:identities features:features];
  908. }
  909. - (void)leapfrogBridge_sapoAgentsUpdated:(NSString *)accountUUID :(NSDictionary *)sapoAgentsDescription
  910. {
  911. [[self accountForUUID:accountUUID] handleSapoAgentsUpdated:sapoAgentsDescription];
  912. }
  913. - (void)leapfrogBridge_chatRoomsListReceived:(NSString *)host :(NSArray *)roomsList
  914. {
  915. // DEBUG
  916. //NSLog(@"MUC ITEMS UPDATED:\nHost: %@\nRooms: %@\n", host, roomsList);
  917. #warning CHAT ROOMS LIST
  918. // if ([m_delegate respondsToSelector:@selector(account:didReceiveChatRoomsList:forHost:)]) {
  919. // [m_delegate account:self didReceiveChatRoomsList:roomsList forHost:host];
  920. // }
  921. }
  922. - (void)leapfrogBridge_chatRoomInfoReceived:(NSString *)roomJID :(NSDictionary *)infoDict
  923. {
  924. // DEBUG
  925. //NSLog(@"MUC ITEM INFO UPDATED:\nRoom JID: %@\nInfo: %@\n", roomJID, infoDict);
  926. #warning CHAT ROOMS INFO
  927. // if ([m_delegate respondsToSelector:@selector(account:didReceiveInfo:forChatRoomWithJID:)]) {
  928. // [m_delegate account:self didReceiveInfo:infoDict forChatRoomWithJID:roomJID];
  929. // }
  930. }
  931. - (void)leapfrogBridge_groupChatInvitationReceived:(NSString *)accountUUID :(NSString *)roomJID :(NSString *)sender :(NSString *)reason :(NSString *)password
  932. {
  933. [[self accountForUUID:accountUUID] handleReceivedInvitationToGroupChat:roomJID from:sender reason:reason password:password];
  934. }
  935. - (void)leapfrogBridge_liveUpdateURLReceived:(NSString *)accountUUID :(NSString *)liveUpdateURLStr
  936. {
  937. [[self accountForUUID:accountUUID] handleReceivedLiveUpdateURLString:liveUpdateURLStr];
  938. }
  939. - (void)leapfrogBridge_sapoChatOrderReceived:(NSString *)accountUUID :(NSDictionary *)orderDict
  940. {
  941. [[self accountForUUID:accountUUID] handleReceivedSapoChatOrderDictionary:orderDict];
  942. }
  943. - (void)leapfrogBridge_transportRegistrationStatusUpdated:(NSString *)accountUUID :(NSString *)transportAgent :(BOOL)isRegistered :(NSString *)registeredUsername
  944. {
  945. [[self accountForUUID:accountUUID] handleTransportRegistrationStatusUpdatedForAgent:transportAgent
  946. isRegistered:isRegistered
  947. username:registeredUsername];
  948. }
  949. - (void)leapfrogBridge_transportLoggedInStatusUpdated:(NSString *)accountUUID :(NSString *)transportAgent :(BOOL)isLoggedIn
  950. {
  951. [[self accountForUUID:accountUUID] handleTransportLoggedInStatusUpdatedForAgent:transportAgent isLoggedIn:isLoggedIn];
  952. }
  953. - (void)leapfrogBridge_serverVarsReceived:(NSString *)accountUUID :(NSDictionary *)varsValues
  954. {
  955. [[self accountForUUID:accountUUID] handleReceivedServerVarsDictionary:varsValues];
  956. }
  957. - (void)leapfrogBridge_selfVCardChanged:(NSString *)accountUUID :(NSDictionary *)vCard
  958. {
  959. [[self accountForUUID:accountUUID] handleSelfVCardChanged:vCard];
  960. }
  961. - (void)leapfrogBridge_debuggerStatusChanged:(NSString *)accountUUID :(BOOL)isDebugger
  962. {
  963. [[self accountForUUID:accountUUID] handleDebuggerStatusChanged:isDebugger];
  964. }
  965. @end