Frameworks/Adium Framework/Source/AIAccount.m
author Zachary West <zacw@adium.im>
Fri Nov 27 15:50:57 2009 -0500 (2009-11-27)
changeset 2835 1e8c89f99dfe
parent 2356 ca99ae8114c2
child 3051 961833271e26
permissions -rw-r--r--
Simplify the "status message" contact/account property into one getter method. Correct error -1728 from AS on contact's status messages. Fixes #13460.

The totally undocumented -1728 error appears to be caused by runtime type disagreeing with event type. "status message" is apparently assumed to only have 1 code, so specifying one for contacts and one for accounts was confusing it when it was going to fetch it.
David@0
     1
/* 
David@0
     2
 * Adium is the legal property of its developers, whose names are listed in the copyright file included
David@0
     3
 * with this source distribution.
David@0
     4
 * 
David@0
     5
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
David@0
     6
 * General Public License as published by the Free Software Foundation; either version 2 of the License,
David@0
     7
 * or (at your option) any later version.
David@0
     8
 * 
David@0
     9
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
David@0
    10
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
David@0
    11
 * Public License for more details.
David@0
    12
 * 
David@0
    13
 * You should have received a copy of the GNU General Public License along with this program; if not,
David@0
    14
 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
David@0
    15
 */
David@0
    16
David@0
    17
#import <Adium/AIAbstractAccount.h>
David@0
    18
#import <Adium/AIAccount.h>
David@0
    19
#import <Adium/AIListContact.h>
zacw@2131
    20
#import <Adium/AIListGroup.h>
David@0
    21
#import <Adium/AIContentMessage.h>
David@0
    22
#import <Adium/AIContentNotification.h>
David@0
    23
#import <Adium/AIService.h>
David@0
    24
#import <Adium/AIChat.h>
David@0
    25
#import <Adium/ESFileTransfer.h>
David@557
    26
#import "AIStatusItem.h"
David@557
    27
#import "AIStatus.h"
David@0
    28
#import "AdiumAccounts.h"
David@0
    29
David@0
    30
#import <Adium/AIContactControllerProtocol.h>
David@0
    31
#import <Adium/AIContentControllerProtocol.h>
David@0
    32
#import <Adium/AIAccountControllerProtocol.h>
David@0
    33
David@0
    34
#import "DCJoinChatViewController.h"
David@0
    35
#import "AIChatControllerProtocol.h"
David@0
    36
#import "AIMessageWindowController.h"
David@0
    37
#import "AIMessageWindow.h"
David@0
    38
#import "AIInterfaceControllerProtocol.h"
David@0
    39
#import "AIStatusControllerProtocol.h"
David@0
    40
David@0
    41
#define NEW_ACCOUNT_DISPLAY_TEXT			AILocalizedString(@"<New Account>", "Placeholder displayed as the name of a new account")
David@0
    42
David@0
    43
@interface AIAccountDeletionDialog : NSObject <AIAccountControllerRemoveConfirmationDialog> {
David@0
    44
	AIAccount *account;
David@0
    45
	NSAlert *alert;
David@1598
    46
	id userData;
David@0
    47
}
David@0
    48
David@0
    49
- (id)initWithAccount:(AIAccount*)ac alert:(NSAlert*)al;
David@0
    50
David@1598
    51
@property (readwrite, retain, nonatomic) id userData;
David@0
    52
David@0
    53
- (void)alertDidEnd:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(void *)contextInfo;
David@0
    54
David@0
    55
@end
David@0
    56
David@0
    57
@implementation AIAccountDeletionDialog
David@0
    58
David@0
    59
- (id)initWithAccount:(AIAccount*)ac alert:(NSAlert*)al {
David@0
    60
	if((self = [super init])) {
David@0
    61
		account = ac;
David@0
    62
		alert = [al retain];
David@0
    63
	}
David@0
    64
	return self;
David@0
    65
}
David@0
    66
David@0
    67
- (void)dealloc {
David@0
    68
	[alert release];
David@1598
    69
	[userData release];
David@0
    70
	[super dealloc];
David@0
    71
}
David@0
    72
David@1598
    73
@synthesize userData;
David@0
    74
David@0
    75
- (void)runModal {
David@0
    76
	[self alertDidEnd:alert returnCode:[alert runModal] contextInfo:NULL];
David@0
    77
}
David@0
    78
David@0
    79
- (void)beginSheetModalForWindow:(NSWindow*)window {
David@0
    80
	[alert beginSheetModalForWindow:window modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:NULL];
David@0
    81
}
David@0
    82
David@0
    83
- (void)alertDidEnd:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(void *)contextInfo {
David@0
    84
	[account alertForAccountDeletion:self didReturn:returnCode];
David@0
    85
}
David@0
    86
David@0
    87
@end
David@0
    88
David@0
    89
//Proxy types for applescript
David@0
    90
typedef enum
David@0
    91
{
David@0
    92
	Adium_Proxy_HTTP_AS = 'HTTP',
David@0
    93
	Adium_Proxy_SOCKS4_AS = 'SCK4',
David@0
    94
	Adium_Proxy_SOCKS5_AS = 'SCK5',
David@0
    95
	Adium_Proxy_Default_HTTP_AS = 'DHTP',
David@0
    96
	Adium_Proxy_Default_SOCKS4_AS = 'DSK4',
David@0
    97
	Adium_Proxy_Default_SOCKS5_AS = 'DSK5',
David@0
    98
	Adium_Proxy_None_AS = 'NONE'
David@0
    99
} AdiumProxyTypeApplescript;
David@0
   100
David@0
   101
@interface AIAccount(AppleScriptPRIVATE)
David@0
   102
- (AdiumProxyType)proxyTypeFromApplescript:(AdiumProxyTypeApplescript)proxyTypeAS;
David@0
   103
- (AdiumProxyTypeApplescript)applescriptProxyType:(AdiumProxyType)proxyType;
David@0
   104
@end
David@0
   105
David@0
   106
/*!
David@0
   107
 * @class AIAccount
David@0
   108
 * @brief An account
David@0
   109
 *
David@0
   110
 * This abstract class represents an account the user has setup in Adium.  Subclass this for every service.
David@0
   111
 */
David@0
   112
@implementation AIAccount
David@0
   113
David@0
   114
/*!
David@0
   115
 * @brief Init Account
David@0
   116
 *
David@0
   117
 * Init this account instance
David@0
   118
 */
David@0
   119
- (void)initAccount
David@0
   120
{
David@0
   121
}
David@0
   122
David@0
   123
/*!
David@0
   124
 * @brief Connect
David@0
   125
 *
David@0
   126
 * Connect the account, transitioning it into an online state.
David@0
   127
 */
David@0
   128
- (void)connect
David@0
   129
{
David@0
   130
	//We are connecting
David@0
   131
	[self setValue:[NSNumber numberWithBool:YES] forProperty:@"Connecting" notify:NotifyNow];
David@0
   132
}
David@0
   133
David@0
   134
/*!
David@0
   135
 * @brief rejoinChat
David@0
   136
 * 
David@0
   137
 * Rejoin the open group chats after disconnect
David@0
   138
 */
David@0
   139
-(BOOL)rejoinChat:(AIChat*)chat
David@0
   140
{
David@0
   141
	return NO;
David@0
   142
}	
David@0
   143
David@0
   144
/*!
zacw@1301
   145
 * @brief Do group chats support topics?
zacw@1301
   146
 */
zacw@1301
   147
- (BOOL)groupChatsSupportTopic
zacw@1301
   148
{
zacw@1301
   149
	return NO;
zacw@1301
   150
}
zacw@1301
   151
zacw@1301
   152
/*!
zacw@1301
   153
 * @brief Set a chat's topic
zacw@1301
   154
 *
zacw@1301
   155
 * This only has an effect on group chats.
zacw@1301
   156
 */
zacw@1301
   157
- (void)setTopic:(NSString *)topic forChat:(AIChat *)chat
zacw@1301
   158
{
zacw@1301
   159
}
zacw@1301
   160
zacw@1301
   161
/*!
David@0
   162
 * @brief Disconnect
David@0
   163
 *
David@0
   164
 * Disconnect the account, transitioning it into an offline state.
David@0
   165
 */
David@0
   166
- (void)disconnect
David@0
   167
{
David@0
   168
	[self cancelAutoReconnect];
David@0
   169
	[self setValue:nil forProperty:@"Connecting" notify:NotifyLater];
David@0
   170
David@0
   171
	[self notifyOfChangedPropertiesSilently:NO];
David@0
   172
}
David@0
   173
David@0
   174
/*!
David@0
   175
 * @brief Disconnect as a result of the network connection dropping out
David@0
   176
 *
David@0
   177
 * The default implementation is identical to [self disconect], but subclasses may want to act differently
David@0
   178
 * if the network connection is gone than if the user chose to disconnect.
David@0
   179
 *
David@0
   180
 * Subclasses should call super's implementation.
David@0
   181
 */
David@0
   182
- (void)disconnectFromDroppedNetworkConnection
David@0
   183
{
David@0
   184
	[self disconnect];
David@0
   185
}
David@0
   186
David@0
   187
/*!
David@0
   188
 * @brief Register an account
David@0
   189
 *
David@0
   190
 * Register an account on this service using the currently entered information.  This is for services which support
David@0
   191
 * in-client registration such as jabber.
David@0
   192
 */
David@0
   193
- (void)performRegisterWithPassword:(NSString *)inPassword
David@0
   194
{
David@0
   195
David@0
   196
}
David@0
   197
David@0
   198
/*!
David@0
   199
 * @brief The UID will be changed. The account has a chance to perform modifications
David@0
   200
 *
David@0
   201
 * For example, MSN adds \@hotmail.com to the proposedUID and returns the new value
David@0
   202
 *
David@0
   203
 * @param proposedUID The proposed, pre-filtered UID (filtered means it has no characters invalid for this servce)
David@0
   204
 * @result The UID to use; the default implementation just returns proposedUID.
David@0
   205
 */
David@0
   206
- (NSString *)accountWillSetUID:(NSString *)proposedUID
David@0
   207
{
David@0
   208
	return proposedUID;
David@0
   209
}
David@0
   210
David@0
   211
/*!
David@0
   212
 * @brief The account's UID changed
David@0
   213
 */
David@0
   214
- (void)didChangeUID
David@0
   215
{
David@0
   216
David@0
   217
}
David@0
   218
David@0
   219
/*!
David@0
   220
 * @brief The account will be deleted
David@0
   221
 *
David@0
   222
 * The default implementation disconnects the account.  Subclasses should call super's implementation.
David@0
   223
 * If asynchronous behavior is required, the next three methods should be overridden instead.
David@0
   224
 */
David@0
   225
- (void)willBeDeleted
David@0
   226
{
David@0
   227
	[self setShouldBeOnline:NO];
David@0
   228
David@0
   229
	//Remove our contacts immediately.
David@0
   230
	[self removeAllContacts];
David@0
   231
}
David@0
   232
David@0
   233
/*!
David@0
   234
 * @brief Perform the deletion of this account
David@0
   235
 *
David@0
   236
 * This should be called only after proper confirmation has been made by the user.
David@0
   237
 */
David@0
   238
- (void)performDelete
David@0
   239
{
David@95
   240
	[adium.accountController deleteAccount:self];
David@0
   241
}
David@0
   242
David@0
   243
- (id<AIAccountControllerRemoveConfirmationDialog>)confirmationDialogForAccountDeletion
David@0
   244
{
David@0
   245
	//Will be released in alertForAccountDeletion:didReturn:
David@0
   246
	return [[AIAccountDeletionDialog alloc] initWithAccount:self alert:[self alertForAccountDeletion]];
David@0
   247
}
David@0
   248
David@0
   249
/*!
David@0
   250
 * @brief The alert used for confirming the account deletion
David@0
   251
 *
David@0
   252
 * Meant for subclassers. By default, returns the dialog that asks the user if the account should really be deleted (and how).
David@0
   253
 */
David@0
   254
- (NSAlert*)alertForAccountDeletion
David@0
   255
{
David@0
   256
	return [NSAlert alertWithMessageText:AILocalizedString(@"Delete Account",nil)
David@0
   257
						   defaultButton:AILocalizedString(@"Delete",nil)
David@0
   258
						 alternateButton:AILocalizedString(@"Cancel",nil)
David@0
   259
							 otherButton:nil
David@427
   260
			   informativeTextWithFormat:AILocalizedString(@"Delete the account %@?",nil), ([self.formattedUID length] ? self.formattedUID : NEW_ACCOUNT_DISPLAY_TEXT)];
David@0
   261
}
David@0
   262
David@0
   263
/*!
David@0
   264
 * @brief The dialog asking for confirmation for deleting the account did return.
David@0
   265
 *
David@0
   266
 * @param dialog The dialog that has completed
David@0
   267
 * @param returnCode One of the regular NSAlert return codes
David@0
   268
 *
David@0
   269
 * This method should be overridden when alertForAccountDeletion: was overridden, and/or asynchronous behavior is required.
David@0
   270
 * This implementation disconnects and deletes the account from the accounts list when returnCode == NSAlertDefaultReturn.
David@0
   271
 *
David@0
   272
 * If this implementation is not called, dialog should be released by the subclass.
David@0
   273
 */
David@0
   274
- (void)alertForAccountDeletion:(id<AIAccountControllerRemoveConfirmationDialog>)dialog didReturn:(int)returnCode
David@0
   275
{
David@0
   276
	if(returnCode == NSAlertDefaultReturn) {
David@0
   277
		[self performDelete];
David@0
   278
	}
David@0
   279
David@0
   280
	[(AIAccountDeletionDialog*)dialog release];
David@0
   281
}
David@0
   282
David@0
   283
/*!
David@0
   284
 * @brief A formatted UID which may include additional necessary identifying information.
David@0
   285
 *
David@0
   286
 * For example, an AIM account (tekjew) and a .Mac account (tekjew@mac.com, entered only as tekjew) may appear identical
David@0
   287
 * without service information (tekjew). The explicit formatted UID is therefore tekjew@mac.com
David@0
   288
 */
David@0
   289
- (NSString *)explicitFormattedUID
David@0
   290
{
David@427
   291
	return self.formattedUID;
David@0
   292
}
David@0
   293
zacw@1121
   294
/*!
zacw@1121
   295
 * @brief Use our host for the servername when storing password
zacw@1121
   296
 *
zacw@1121
   297
 * This should be YES for services which depend upon server information. For example, a password for an IRC account
zacw@1121
   298
 * is uniqued by what server it is on.
zacw@1121
   299
 */
zacw@1121
   300
- (BOOL)useHostForPasswordServerName
zacw@1121
   301
{
zacw@1121
   302
	return NO;
zacw@1121
   303
}
zacw@1121
   304
zacw@1131
   305
/*!
zacw@1131
   306
 * @brief Use our internal object ID for the username when storing password
zacw@1131
   307
 *
zacw@1131
   308
 * For accounts whose signup process may not be contingent upon the UID. For example, a Twitter account using OAuth might
zacw@1131
   309
 * not know its UID when it wants to save itself.
zacw@1131
   310
 */
zacw@1131
   311
- (BOOL)useInternalObjectIDForPasswordName
zacw@1131
   312
{
zacw@1131
   313
	return NO;
zacw@1131
   314
}
zacw@1131
   315
David@0
   316
//Properties -----------------------------------------------------------------------------------------------------------
David@0
   317
#pragma mark Properties
David@0
   318
/*!
David@0
   319
 * @brief Send Autoresponses while away
David@0
   320
 *
David@0
   321
 * Subclass to alter the behavior of this account with regards to autoresponses.  Certain services expect the client to
David@0
   322
 * auto-respond with away messages.  Adium will provide this behavior automatically if desired.
David@0
   323
 */
David@0
   324
- (BOOL)supportsAutoReplies
David@0
   325
{
David@0
   326
	return NO;
David@0
   327
}
David@0
   328
David@0
   329
/*!
David@0
   330
 * @brief Disconnect on fast user switch
David@0
   331
 *
David@0
   332
 * It may be required for a service to disconnect when logged in users change.  If this is the case, subclass this
David@0
   333
 * method to return YES and Adium will automatically disconnect and reconnect on FUS events.
David@0
   334
 */
David@0
   335
- (BOOL)disconnectOnFastUserSwitch
David@0
   336
{
David@0
   337
	return NO;
David@0
   338
}
David@0
   339
David@0
   340
/*!
David@0
   341
 * @brief Connectivity based on network reachability
David@0
   342
 *
David@0
   343
 * By default, accounts are automatically disconnected and reconnected when network reachability changes.  Accounts
David@0
   344
 * that do not require persistent network connections can choose to disable this by returning NO from this method.
David@0
   345
 */
David@0
   346
- (BOOL)connectivityBasedOnNetworkReachability
David@0
   347
{
David@0
   348
	return YES;
David@0
   349
}
David@0
   350
David@0
   351
/*!
David@0
   352
 * @brief Suppress typing notifications after send
David@0
   353
 *
David@0
   354
 * Some protocols require a 'Stopped typing' notification to be sent along with an instant message.  Other protocols
David@0
   355
 * implicitly assume that typing has stopped with an incoming message and the extraneous typing notification may cause
David@0
   356
 * strange behavior.  Return YES from this method to suppress the sending of a stopped typing notification along with
David@0
   357
 * messages.
David@0
   358
 */
David@0
   359
- (BOOL)suppressTypingNotificationChangesAfterSend
David@0
   360
{
David@0
   361
	return NO;
David@0
   362
}
David@0
   363
David@0
   364
/*!
David@0
   365
 * @brief Support server-side storing of messages to offline users?
David@0
   366
 *
David@0
   367
 * Some protocols store messages to offline contacts on the server. Subclasses may return YES if their service supports 
David@0
   368
 * this. Adium will not store the message as an Event, and will just send it along to the server. This may cause a Gaim
David@0
   369
 * error on Jabber if the Jabber server they are using is down.
David@0
   370
 */
David@0
   371
- (BOOL)canSendOfflineMessageToContact:(AIListContact *)inContact
David@0
   372
{
David@0
   373
	return NO;
David@0
   374
}
David@0
   375
David@0
   376
/*!
Evan@46
   377
 * @brief Support messaging invisible contacts?
Evan@46
   378
 *
Evan@46
   379
 * This will only be called if the protocol returns NO to -[self canSendOfflineMessageToContact:] 
Evan@46
   380
 * If invisible contacts exist and can be messaged, return YES.
Evan@46
   381
 * If the protocol has no concept of invisible contacts, or invisible contacts can't be messaged, return NO.
Evan@46
   382
 */
Evan@48
   383
- (BOOL)maySendMessageToInvisibleContact:(AIListContact *)inContact
Evan@46
   384
{
Evan@46
   385
	return YES;
Evan@46
   386
}
Evan@46
   387
Evan@46
   388
/*!
David@0
   389
 * @brief Should offline messages be sent without prompting the user?
David@0
   390
 *
David@0
   391
 * If -[self canSendOfflineMessageToContact:] returns YES, Adium typically asks the user whether or not to send a message
David@0
   392
 * to be stored on the server. If sendOfflineMessagesWithoutPrompting returns YES, this prompt is always suppressed.
David@0
   393
 *
Evan@672
   394
 * This should only be true if offline messaging is a well-established expectation for the service. We assume that
Evan@672
   395
 * this is the case by default.
David@0
   396
 */
David@0
   397
- (BOOL)sendOfflineMessagesWithoutPrompting
David@0
   398
{
Evan@672
   399
	return YES;
David@0
   400
}
David@0
   401
David@0
   402
/*!
David@0
   403
 * @brief Does the account itself display file transfer messages in chat windows?
David@0
   404
 *
David@0
   405
 * If YES, Adium won't attempt to display messages in chat windows regarding file transfers.
David@0
   406
 * If NO, Adium automatically displays appropriate messages in open chats.
David@0
   407
 */
David@0
   408
- (BOOL)accountDisplaysFileTransferMessages
David@0
   409
{
David@0
   410
	return NO;
David@0
   411
}
David@0
   412
David@0
   413
/*!
David@0
   414
 * @brief Does the account manage its own cache of serverside contact icons?
David@0
   415
 */
David@0
   416
- (BOOL)managesOwnContactIconCache
David@0
   417
{
David@0
   418
	return NO;
David@0
   419
}
David@0
   420
David@0
   421
/*!
David@0
   422
 * @brief Called once the display name has been properly filtered
David@0
   423
 *
David@0
   424
 * Subclasses may override to pass this name on to the server if appropriate.
David@0
   425
 * Super's implementation should then be called.
David@0
   426
 */
David@0
   427
- (void)gotFilteredDisplayName:(NSAttributedString *)attributedDisplayName
David@0
   428
{
David@0
   429
	[self updateLocalDisplayNameTo:attributedDisplayName];
David@0
   430
}
David@0
   431
David@0
   432
- (NSImage *)userIcon
David@0
   433
{
David@0
   434
	NSData	*iconData = [self userIconData];
David@0
   435
	return (iconData ? [[[NSImage alloc] initWithData:iconData] autorelease] : nil);
David@0
   436
}
David@0
   437
David@1599
   438
@synthesize isTemporary;
David@1599
   439
David@0
   440
//Status ---------------------------------------------------------------------------------------------------------------
David@0
   441
#pragma mark Status
David@0
   442
/*!
David@0
   443
 * @brief Supported properties
David@0
   444
 *
David@0
   445
 * Returns an array of properties supported by this account.  This account will not be informed of changes to keys
David@0
   446
 * it does not support.  Available keys are:
David@0
   447
 *   @"Display Name", @"Online", @"Offline", @"IdleSince", @"IdleManuallySet", @"User Icon"
David@0
   448
 *   @"TextProfile", @"DefaultUserIconFilename", @"StatusState"
David@0
   449
 * @return NSSet of supported keys
David@0
   450
 */
David@0
   451
- (NSSet *)supportedPropertyKeys
David@0
   452
{
David@0
   453
	static	NSSet	*supportedPropertyKeys = nil;
David@0
   454
	if (!supportedPropertyKeys) {
David@0
   455
		supportedPropertyKeys = [[NSSet alloc] initWithObjects:
David@0
   456
			@"Online",
David@0
   457
			@"FormattedUID",
David@0
   458
			KEY_ACCOUNT_DISPLAY_NAME,
David@0
   459
			@"Display Name",
David@0
   460
			@"StatusState",
David@0
   461
			KEY_USE_USER_ICON, KEY_USER_ICON, KEY_DEFAULT_USER_ICON,
David@0
   462
			@"Enabled",
David@0
   463
			nil];
David@0
   464
	}
David@0
   465
David@0
   466
	return supportedPropertyKeys;
David@0
   467
}
David@0
   468
David@0
   469
/*!
David@0
   470
 * @brief Status for key
David@0
   471
 *
David@0
   472
 * Returns the status this account should be for a specific key
David@0
   473
 * @param key Property
David@0
   474
 * @return id Status value
David@0
   475
 */
David@0
   476
- (id)statusForKey:(NSString *)key
David@0
   477
{
David@0
   478
	return [self preferenceForKey:key group:GROUP_ACCOUNT_STATUS];
David@0
   479
}
David@0
   480
David@0
   481
/*!
David@0
   482
 * @brief Update account status
David@0
   483
 *
David@0
   484
 * Update account status for the changed key.  This is called when account status changes Adium-side and the account
David@0
   485
 * code should update status account/server side in response.  The new value for the key can be accessed using
David@0
   486
 * the statusForKey method.
David@0
   487
 * @param key The updated property
David@0
   488
 */
David@0
   489
- (void)updateStatusForKey:(NSString *)key
David@0
   490
{
David@0
   491
	[self updateCommonStatusForKey:key];
David@0
   492
}
David@0
   493
David@0
   494
/*!
David@0
   495
 * @brief Update contact status
David@0
   496
 *
David@0
   497
 * Adium is requesting that the account update a contact's status.  This method is primarily called by the get info
David@0
   498
 * window.  Since this is called sparsely, accounts may choose to look up additional information such as profiles
David@0
   499
 * in response to this.  Adium guards this method to prevent it from being called too rapidly, so expensive lookups
David@0
   500
 * are not a problem if the delayedUpdateStatusInterval is set correctly.
David@0
   501
 */
David@0
   502
- (void)delayedUpdateContactStatus:(AIListContact *)inContact
David@0
   503
{
David@0
   504
	
David@0
   505
}
David@0
   506
David@0
   507
/*!
David@0
   508
 * @brief Update contact interval
David@0
   509
 *
David@0
   510
 * Specifies the mininum interval at which delayedUpdateContactStatus will be called.  If the account code is performing
David@0
   511
 * expensive operations (such as profile or web lookups) in response to updateContactStatus, it can guard against
David@0
   512
 * the lookups being performed too frequently by returning an interval here.
David@0
   513
 */
David@0
   514
- (float)delayedUpdateStatusInterval
David@0
   515
{
David@0
   516
	return 0.5;
David@0
   517
}
David@0
   518
David@0
   519
/*!
David@0
   520
 * @brief Perform the setting of a status state
David@0
   521
 *
David@0
   522
 * Sets the account to a passed status state.  The account should set itself to best possible status given the return
David@0
   523
 * values of statusState's accessors.  The passed statusMessage has been filtered; it should be used rather than
David@837
   524
 * statusState.statusMessage, which returns an unfiltered statusMessage.
David@0
   525
 *
David@0
   526
 * @param statusState The state to enter
David@0
   527
 * @param statusMessage The filtered status message to use.
David@0
   528
 */
David@0
   529
- (void)setStatusState:(AIStatus *)statusState usingStatusMessage:(NSAttributedString *)statusMessage
David@0
   530
{
David@0
   531
	
David@0
   532
}
David@0
   533
David@0
   534
/*!
David@0
   535
 * @brief Set the social networking status message for this account
David@0
   536
 *
David@427
   537
 * This will only be called if [self.service isSocialNetworkingService] returns TRUE.
David@0
   538
 *
David@0
   539
 * @param statusMessage The status message, which has already been filtered.
David@0
   540
 */
David@0
   541
- (void)setSocialNetworkingStatusMessage:(NSAttributedString *)statusMessage
David@0
   542
{
David@0
   543
	
David@0
   544
}
David@0
   545
/*!
David@0
   546
 * @brief Should the autorefreshing attributed string associated with a key be updated at the moment?
David@0
   547
 *
David@0
   548
 * The default implementation causes all dynamic strings which need updating to be updated if the account is
David@0
   549
 * online.  Subclasses may choose to implement more complex logic; for example, a nickname seen only in a chat
David@0
   550
 * might be updated only if a chat is open.
David@0
   551
 */
David@0
   552
- (BOOL)shouldUpdateAutorefreshingAttributedStringForKey:(NSString *)inKey
David@0
   553
{
David@837
   554
	return self.online;
David@0
   555
}
David@0
   556
David@0
   557
//Messaging, Chatting, Strings -----------------------------------------------------------------------------------------
David@0
   558
#pragma mark Messaging, Chatting, Strings
David@0
   559
/*!
David@0
   560
 * @brief Available for sending content
David@0
   561
 *
David@0
   562
 * Returns YES if the contact is available for receiving content of the specified type.  If contact is nil, instead
David@0
   563
 * check for the availiability to send any content of the given type.
David@0
   564
 *
David@0
   565
 * The default implementation indicates the account, if online, can send messages to any online contact.
David@0
   566
 * It can also send files to any online contact if the account subclass conforms to the AIAccount_Files protocol.
David@0
   567
 *
David@0
   568
 * @param inType A string content type
David@0
   569
 * @param inContact The destination contact, or nil to check global availability
David@0
   570
 */
David@0
   571
- (BOOL)availableForSendingContentType:(NSString *)inType toContact:(AIListContact *)inContact
David@0
   572
{
David@0
   573
	if ([inType isEqualToString:CONTENT_MESSAGE_TYPE] ||
David@0
   574
		[inType isEqualToString:CONTENT_NOTIFICATION_TYPE]) {
David@837
   575
		return (self.online &&
David@837
   576
				(!inContact || inContact.online || inContact.isStranger || [self canSendOfflineMessageToContact:inContact]));
David@0
   577
				
David@0
   578
	} else if ([inType isEqualToString:CONTENT_FILE_TRANSFER_TYPE]) {
David@837
   579
		return (self.online && [self conformsToProtocol:@protocol(AIAccount_Files)] &&
David@837
   580
				(!inContact || inContact.online || inContact.isStranger));
David@0
   581
	}
David@0
   582
David@0
   583
	return NO;
David@0
   584
}
David@0
   585
David@0
   586
/*!
David@0
   587
 * @brief Open a chat
David@0
   588
 *
David@0
   589
 * Open the passed chat account-side.  Depending on the protocol, account code may need to establish a connection in
David@0
   590
 * response to this method or perhaps make no actions at all.  This method is used by both one-on-one chats and
David@0
   591
 * multi-user chats.
David@0
   592
 * @param chat The chat to open
David@0
   593
 * @return YES on success
David@0
   594
 */
David@0
   595
- (BOOL)openChat:(AIChat *)chat
David@0
   596
{
David@0
   597
	return NO;
David@0
   598
}
David@0
   599
David@0
   600
/*!
David@0
   601
 * @brief Close a chat
David@0
   602
 *
David@0
   603
 * Close the passed chat account-side.  Depending on the protocol, account code may need to close a connection in
David@0
   604
 * response to this method or perhaps make no actions at all.  This method is used by both one-on-one chats and
David@0
   605
 * multi-user chats.
David@0
   606
 *
David@100
   607
 * This method should *only* be called by a core controller.  Call [adium.interfaceController closeChat:chat] to perform a close from other code.
David@0
   608
 *
David@0
   609
 * @param chat The chat to close
David@0
   610
 * @return YES on success
David@0
   611
 */
David@0
   612
- (BOOL)closeChat:(AIChat *)chat
David@0
   613
{
David@0
   614
	return NO;
David@0
   615
}
David@0
   616
David@0
   617
/*!
David@0
   618
 * @brief Invite a contact to an open chat
David@0
   619
 *
David@0
   620
 * Invite a contact to the passed chat, if supported by the protocol and the specific chat instance.  An invite
David@0
   621
 * message is provided as a convenience to protocols that require or support one.
David@0
   622
 * @param contact AIListObject to invite
David@0
   623
 * @param chat AIChat they are being invited to
David@0
   624
 * @param inviteMessage NSString invite message for the invited contact
David@0
   625
 * @return YES on success
David@0
   626
 */
David@0
   627
- (BOOL)inviteContact:(AIListObject *)contact toChat:(AIChat *)chat withMessage:(NSString *)inviteMessage
David@0
   628
{
David@0
   629
	NSLog(@"invite contact to chat with message");
David@0
   630
	return NO;
David@0
   631
}
David@0
   632
David@0
   633
/*!
David@0
   634
 * @brief Send a typing object
David@0
   635
 *
David@0
   636
 * The content object contains all the necessary information for sending,
David@0
   637
 * including the destination contact.
David@0
   638
 */
David@0
   639
- (void)sendTypingObject:(AIContentTyping *)inTypingObject
David@0
   640
{
David@0
   641
David@0
   642
}
David@0
   643
David@0
   644
/*!
David@0
   645
 * @brief Send a message
David@0
   646
 *
David@0
   647
 * The content object contains all the necessary information for sending,
David@0
   648
 * including the destination contact. [inMessageObject encodedMessage] contains the NSString which should be sent.
David@0
   649
 */
David@0
   650
- (BOOL)sendMessageObject:(AIContentMessage *)inMessageObject
David@0
   651
{
David@0
   652
	return NO;
David@0
   653
}
David@0
   654
David@0
   655
/*!
zacw@1716
   656
 * @brief Does the account support sending notifications?
zacw@1716
   657
 */
zacw@1716
   658
- (BOOL)supportsSendingNotifications
zacw@1716
   659
{
zacw@1716
   660
	return NO;
zacw@1716
   661
}
zacw@1716
   662
zacw@1716
   663
/*!
zacw@1716
   664
 * @brief Send a notification
zacw@1716
   665
 */
zacw@1716
   666
- (BOOL)sendNotificationObject:(AIContentNotification *)inContentNotification
zacw@1716
   667
{
zacw@1716
   668
	return NO;
zacw@1716
   669
}
zacw@1716
   670
zacw@1716
   671
/*!
David@0
   672
 * @brief Encode attributed string (generic)
David@0
   673
 *
David@0
   674
 * Encode an NSAttributedString into a NSString for this account.  Accounts that support formatted text or require
David@0
   675
 * special encoding on strings should do that work here.  For example, HTML based accounts should convert the 
David@0
   676
 * NSAttributedString to HTML appropriate for their protocol (Adium can help with this).
David@0
   677
 * @param inAttributedString String to encode
David@0
   678
 * @param inListObject List object associated with the string; nil if the string is not associated with a particular list object, which is the case if encoding for a status message or a group chat message.
David@0
   679
 * @return NSString result from encoding
David@0
   680
 */
David@0
   681
- (NSString *)encodedAttributedString:(NSAttributedString *)inAttributedString forListObject:(AIListObject *)inListObject
David@0
   682
{
David@0
   683
    return [inAttributedString string];
David@0
   684
}
David@0
   685
David@0
   686
/*!
David@0
   687
 * @brief Encode attributed string to send as a message
David@0
   688
 */
David@0
   689
- (NSString *)encodedAttributedStringForSendingContentMessage:(AIContentMessage *)inContentMessage
David@0
   690
{
David@813
   691
    return [self encodedAttributedString:inContentMessage.message forListObject:[inContentMessage destination]];
David@0
   692
}
David@0
   693
Evan@522
   694
/*!
Evan@522
   695
 * @brief Should an autoreply be sent to this message?
Evan@522
   696
 *
Evan@522
   697
 * This will only be called if the generic algorithm determines that an autoreply is appropriate. The account
Evan@522
   698
 * gets an opportunity to suppress sending the autoreply, e.g. on the basis of the message's content or source.
Evan@522
   699
 */
Evan@522
   700
- (BOOL)shouldSendAutoreplyToMessage:(AIContentMessage *)message
Evan@522
   701
{
Evan@522
   702
	return YES;
Evan@522
   703
}
Evan@522
   704
David@0
   705
//Presence Tracking ----------------------------------------------------------------------------------------------------
David@0
   706
#pragma mark Presence Tracking
David@0
   707
/*!
David@0
   708
 * @brief Contact list editable?
David@0
   709
 *
David@0
   710
 * @return YES if the contact list is currently editable
David@0
   711
 */
David@0
   712
- (BOOL)contactListEditable
David@0
   713
{
David@0
   714
	return NO;
David@0
   715
}
David@0
   716
David@0
   717
/*!
David@0
   718
 * @brief Add contacts
David@0
   719
 *
David@0
   720
 * Add contacts to a group on this account.  Create the group if it doesn't already exist.
David@0
   721
 * @param objects NSArray of AIListContact objects to add
David@0
   722
 * @param group AIListGroup destination for contacts
David@0
   723
 */
David@199
   724
- (void)addContact:(AIListContact *)contact toGroup:(AIListGroup *)group
David@0
   725
{
David@0
   726
	//XXX - Our behavior for duplicate contacts isn't specified here.  Should we handle that adium-side automatically? -ai
David@0
   727
}
David@0
   728
David@0
   729
/*!
David@0
   730
 * @brief Remove contacts
David@0
   731
 *
David@0
   732
 * Remove contacts from this account.
David@0
   733
 * @param objects NSArray of AIListContact objects to remove
zacw@2131
   734
 * @param groups NSArray of AIListGroup objects to remove from.
David@0
   735
 */
zacw@2131
   736
- (void)removeContacts:(NSArray *)objects fromGroups:(NSArray *)groups
David@0
   737
{
David@0
   738
	
David@0
   739
}
David@0
   740
David@0
   741
/*!
David@0
   742
 * @brief Remove a group
David@0
   743
 *
David@0
   744
 * Remove a group from this account.
David@0
   745
 * @param group AIListGroup to remove
David@0
   746
 */
David@0
   747
- (void)deleteGroup:(AIListGroup *)group
David@0
   748
{
David@0
   749
	//XXX - Adium's current behavior is to delete all the contacts within a group, and then delete the group.  This is innefficient on protocols which support deleting groups. -ai
David@0
   750
}
David@0
   751
David@0
   752
/*!
David@0
   753
 * @brief Move contacts
David@0
   754
 *
David@0
   755
 * Move existing contacts to a specific group on this account.  The passed contacts should already exist somewhere on
David@0
   756
 * this account.
David@0
   757
 * @param objects NSArray of AIListContact objects to remove
zacw@2128
   758
 * @param oldGroups NSSet of AIListGroup source for contacts
zacw@2128
   759
 * @param group NSSet of AIListGroup destination for contacts
David@0
   760
 */
zacw@2128
   761
- (void)moveListObjects:(NSArray *)objects fromGroups:(NSSet *)oldGroups toGroups:(NSSet *)groups
David@0
   762
{
David@709
   763
	NSAssert(NO, @"Should not be reached");
David@0
   764
}
David@0
   765
David@0
   766
/*!
David@0
   767
 * @brief Rename a group
David@0
   768
 *
David@0
   769
 * Rename a group on this account.
David@0
   770
 * @param group AIListGroup to rename
David@0
   771
 * @param newName NSString name for the group
David@0
   772
 */
David@0
   773
- (void)renameGroup:(AIListGroup *)group to:(NSString *)newName
David@0
   774
{
David@709
   775
	NSAssert(NO, @"Should not be reached");
David@0
   776
}
David@0
   777
David@0
   778
/*!
David@0
   779
 * @brief Menu items for contact
David@0
   780
 *
David@0
   781
 * Returns an array of menu items for a contact on this account.  This is the best place to add protocol-specific
David@0
   782
 * actions that aren't otherwise supported by Adium.
David@0
   783
 * @param inContact AIListContact for menu items
David@0
   784
 * @return NSArray of NSMenuItem instances for the passed contact
David@0
   785
 */
David@0
   786
- (NSArray *)menuItemsForContact:(AIListContact *)inContact
David@0
   787
{
David@0
   788
	return nil;
David@0
   789
}
David@0
   790
David@0
   791
/*!
zacw@806
   792
 * @brief Menu items for chat
zacw@806
   793
 *
zacw@806
   794
 * Returns an array of menu items for a chat on this account.  This is the best place to add protocol-specific
zacw@806
   795
 * actions that aren't otherwise supported by Adium.
zacw@806
   796
 * @param inChat AIChat for menu items
zacw@806
   797
 * @return NSArray of NSMenuItem instances for the passed contact
zacw@806
   798
 */
zacw@806
   799
- (NSArray *)menuItemsForChat:(AIChat *)inChat
zacw@806
   800
{
zacw@806
   801
	return nil;
zacw@806
   802
}
zacw@806
   803
zacw@806
   804
/*!
David@0
   805
 * @brief Menu items for the account's actions
David@0
   806
 *
David@0
   807
 * Returns an array of menu items for account-specific actions.  This is the best place to add protocol-specific
David@0
   808
 * actions that aren't otherwise supported by Adium.  It will only be queried if the account is online.
David@0
   809
 * @return NSArray of NSMenuItem instances for this account
David@0
   810
 */
David@0
   811
- (NSArray *)accountActionMenuItems
David@0
   812
{
David@0
   813
	return nil;
David@0
   814
}
David@0
   815
David@0
   816
/*!
David@0
   817
 * @brief The account menu item was updated
David@0
   818
 *
David@0
   819
 * This method allows the opportunity to update the account menu item, e.g. to add information to it
David@0
   820
 */
David@0
   821
- (void)accountMenuDidUpdate:(NSMenuItem*)menuItem
David@0
   822
{
David@0
   823
David@0
   824
}
David@0
   825
David@0
   826
/*!
David@0
   827
 * @brief Is a contact on the contact list intentionally listed?
David@0
   828
 *
David@0
   829
 * By default, it is assumed that any contact on the list is intended be there.
David@0
   830
 * This is used by AIListContact to determine if the prescence of itself on the list is indicative of a degree
David@0
   831
 * of trust, for preferences such as "automatically accept files from contacts on my contact list".
David@0
   832
 */
David@0
   833
- (BOOL)isContactIntentionallyListed:(AIListContact *)contact
David@0
   834
{
David@0
   835
	return YES;
David@0
   836
}
David@0
   837
David@0
   838
/*!
David@0
   839
 * @brief Return the data for the serverside icon for a contact
David@0
   840
 */
David@0
   841
- (NSData *)serversideIconDataForContact:(AIListContact *)contact
David@0
   842
{
David@0
   843
	return nil;
David@0
   844
}
David@0
   845
David@0
   846
#pragma mark Secure messsaging
David@0
   847
David@0
   848
/*!
David@0
   849
 * @brief Allow secure messaging toggling on a chat?
David@0
   850
 *
David@0
   851
 * Returns YES if secure (encrypted) messaging's status for this chat should be able to be changed.
David@0
   852
 * This allows the account to determine on a per-chat basis whether the chat's initial security setting should be permanently
David@0
   853
 * maintained.  If it returns NO, the user can not request for the chat to become encrypted or unencrypted.
David@0
   854
 * This is currently implemented by Gaim accounts to return YES for one-on-one chats and NO for group chats to indicate
David@0
   855
 * the functionality provided by Off-the-Record Messaging (OTR).
David@0
   856
 *
David@0
   857
 * @param inChat The query chat 
David@0
   858
 * @result Should the state of secure messaging be allowed to change?
David@0
   859
 */
David@0
   860
- (BOOL)allowSecureMessagingTogglingForChat:(AIChat *)inChat
David@0
   861
{
David@0
   862
	//Allow secure messaging via OTR for one-on-one chats
David@812
   863
	return !inChat.isGroupChat;
David@0
   864
}
David@0
   865
David@0
   866
/*!
David@0
   867
 * @brief Provide a localized description of the encryption this account provides
David@0
   868
 *
David@0
   869
 * Returns a localized string which describes the encryption this account supports.
David@0
   870
 *
David@0
   871
 * @result An <tt>NSString</tt> describing the encryption offerred by this account, if any.
David@0
   872
 */
David@0
   873
- (NSString *)aboutEncryption
David@0
   874
{
David@0
   875
	return [NSString stringWithFormat:
David@0
   876
		AILocalizedStringFromTableInBundle(@"Adium provides encryption, authentication, deniability, and perfect forward secrecy over %@ via Off-the-Record Messaging (OTR). If your contact is not using an OTR-compatible messaging system, your contact will be sent a link to the OTR web site when you attempt to connect. For more information on OTR, visit http://www.cypherpunks.ca/otr/.", nil, [NSBundle bundleForClass:[AIAccount class]], nil),
David@427
   877
		[self.service shortDescription]];
David@0
   878
}
David@0
   879
David@0
   880
/*!
David@0
   881
 * @brief Start or stop secure messaging in a chat
David@0
   882
 *
David@0
   883
 * @param inSecureMessaging The desired state of the chat in terms of encryption
David@0
   884
 * @param inChat The chat to change
David@0
   885
 */
David@0
   886
- (void)requestSecureMessaging:(BOOL)inSecureMessaging
David@0
   887
						inChat:(AIChat *)inChat
David@0
   888
{
David@95
   889
	[adium.contentController requestSecureOTRMessaging:inSecureMessaging
David@0
   890
												  inChat:inChat];
David@0
   891
}
David@0
   892
David@0
   893
/*!
David@0
   894
 * @brief Allow the user to verify (or unverify) the identity being used for encryption in a chat
David@0
   895
 *
David@0
   896
 * It is an error to call this on a chat which is not currently encrypted.
David@0
   897
 *
David@0
   898
 * @param inChat The chat
David@0
   899
 */
David@0
   900
- (void)promptToVerifyEncryptionIdentityInChat:(AIChat *)inChat
David@0
   901
{
David@95
   902
	[adium.contentController promptToVerifyEncryptionIdentityInChat:inChat];
David@0
   903
}
David@0
   904
David@0
   905
#pragma mark Image sending
David@0
   906
/*!
David@0
   907
 * @brief Can the account send images inline within a chat?
David@0
   908
 */
David@0
   909
- (BOOL)canSendImagesForChat:(AIChat *)inChat
David@0
   910
{
David@0
   911
	return NO;
David@0
   912
}
David@0
   913
David@0
   914
#pragma mark Authorization
David@0
   915
/*!
David@0
   916
 * @brief An authorization prompt closed, granting or denying a contact's request for authorization
David@0
   917
 *
zacw@1257
   918
 * @param inDict A dictionary of authorization information created by the account originally and unmodified
David@0
   919
 * @param authorizationResponse An AIAuthorizationResponse indicating if authorization was granted or denied or if there was no response
David@0
   920
 */
zacw@1257
   921
- (void)authorizationWithDict:(NSDictionary *)infoDict response:(AIAuthorizationResponse)authorizationResponse;
David@0
   922
{}
David@0
   923
zacw@1442
   924
#pragma mark Group Chats
zacw@963
   925
/*!
zacw@963
   926
 * @brief Should the chat autocomplete the UID instead of the Display Name?
zacw@963
   927
 */
zacw@963
   928
- (BOOL)chatShouldAutocompleteUID:(AIChat *)inChat
zacw@963
   929
{
zacw@963
   930
	return NO;
zacw@963
   931
}
zacw@963
   932
zacw@1609
   933
-(NSMenu*)actionMenuForChat:(AIChat*)chat
David@0
   934
{
David@0
   935
	return nil;
David@0
   936
}
David@0
   937
zacw@1442
   938
/*!
zacw@1442
   939
 * @brief Does the account manage group chat ignoring?
zacw@1442
   940
 *
zacw@1442
   941
 * If it doesn't, the AIChat will handle ignoring itself.
zacw@1442
   942
 */
zacw@1442
   943
- (BOOL)accountManagesGroupChatIgnore
zacw@1442
   944
{
zacw@1442
   945
	return NO;
zacw@1442
   946
}
zacw@1442
   947
zacw@1442
   948
/*!
zacw@1442
   949
 * @brief Return if a contact is ignored
zacw@1442
   950
 *
zacw@1442
   951
 * @param inContact The AIListContact
zacw@1442
   952
 * @param chat The AIChat the inContact is a member of.
zacw@1442
   953
 *
zacw@1442
   954
 * @return YES if ignored, NO otherwise.
zacw@1442
   955
 */
zacw@1442
   956
- (BOOL)contact:(AIListContact *)inContact isIgnoredInChat:(AIChat *)chat
zacw@1442
   957
{
zacw@1442
   958
	return NO;
zacw@1442
   959
}
zacw@1442
   960
zacw@1442
   961
/*!
zacw@1442
   962
 * @brief Ignore a contact
zacw@1442
   963
 *
zacw@1442
   964
 * @param inContact The AIListContact
zacw@1442
   965
 * @param inIgnored YES if the contact should be ignored, NO otherwise.
zacw@1442
   966
 * @param chat The AIChat the inContact is a member of.
zacw@1442
   967
 */
zacw@1442
   968
- (void)setContact:(AIListContact *)inContact ignored:(BOOL)inIgnored inChat:(AIChat *)chat
zacw@1442
   969
{
zacw@1442
   970
	
zacw@1442
   971
}
zacw@1442
   972
Evan@364
   973
#pragma mark Logging
Evan@364
   974
- (BOOL)shouldLogChat:(AIChat *)chat
Evan@364
   975
{
Evan@364
   976
	return ![self isTemporary];
Evan@364
   977
}
Evan@364
   978
David@0
   979
#pragma mark AppleScript
David@0
   980
- (NSNumber *)scriptingInternalObjectID
David@0
   981
{
David@838
   982
	return [NSNumber numberWithInt:[self.internalObjectID intValue]];
David@0
   983
}
David@0
   984
David@0
   985
/**
David@0
   986
 * @brief The standard objectSpecifier for this model object.
David@0
   987
 *
David@0
   988
 * AIAccount is contained by AIService, using the 'accounts' key.
David@0
   989
 * Each instance has a unique integer identifier.
David@0
   990
 */
David@0
   991
- (NSScriptObjectSpecifier *)objectSpecifier
David@0
   992
{
David@0
   993
	//get my service
David@427
   994
	AIService *theService = self.service;
David@0
   995
	NSScriptObjectSpecifier *containerRef = [theService objectSpecifier];
David@0
   996
David@0
   997
	return [[[NSUniqueIDSpecifier alloc]
David@0
   998
			 initWithContainerClassDescription:[containerRef keyClassDescription]
David@0
   999
			 containerSpecifier:containerRef key:@"accounts"
David@0
  1000
			 uniqueID:[self scriptingInternalObjectID]] autorelease];
David@0
  1001
}
David@0
  1002
David@0
  1003
/**
David@0
  1004
 * @brief Returns the UID of this account.
David@0
  1005
 */
David@0
  1006
- (NSString *)scriptingUID
David@0
  1007
{
David@427
  1008
	return self.UID;
David@0
  1009
}
David@0
  1010
David@0
  1011
/**
David@0
  1012
 * @brief Ensures that it's impossible to set the UID of an account.
David@0
  1013
 *
David@0
  1014
 * This makes sense for the services I'm familiar with, like AIM and GTalk. It may not make sense for other protocols.
David@0
  1015
 * However, it still doesn't seem necessary to do from code.
David@0
  1016
 */
David@0
  1017
- (void)setScriptingUID:(NSString *)n
David@0
  1018
{
David@0
  1019
	[[NSScriptCommand currentCommand] setScriptErrorNumber:errOSACantAssign];
David@0
  1020
	[[NSScriptCommand currentCommand] setScriptErrorString:@"Can't dynamically change the UID of this account."];
David@0
  1021
}
David@0
  1022
David@0
  1023
/**
David@0
  1024
 * @brief Make a contact, according to the passed dictionary of AppleScript properties
David@0
  1025
 * 
David@0
  1026
 * @param properties A dictionary of the following keys:
David@0
  1027
 *		@"KeyDictionary" is the list of the properties in the "with properties" clause of the AS make command.
David@0
  1028
 *			@"UID" key of KeyDictionary is the required "name" property of contacts
David@0
  1029
 *			@"parentGroup" key of keyDictionary is the optional "contact group" property of contacts.
David@0
  1030
 *						   If the parentGroup is not specified, the contact will not be added to the contact list.
David@0
  1031
 */
David@0
  1032
- (id)makeContactWithProperties:(NSDictionary *)properties
David@0
  1033
{
David@0
  1034
	NSDictionary *keyDictionary = [properties objectForKey:@"KeyDictionary"];
David@0
  1035
	if (!keyDictionary) {
David@0
  1036
		[[NSScriptCommand currentCommand] setScriptErrorNumber:errOSACantAssign];
David@0
  1037
		[[NSScriptCommand currentCommand] setScriptErrorString:@"Can't create a contact without specifying contact properties."];
David@0
  1038
		return nil;
David@0
  1039
	}
David@0
  1040
	NSString *contactUID = [keyDictionary objectForKey:@"UID"];
David@0
  1041
	if (!contactUID) {
David@0
  1042
		[[NSScriptCommand currentCommand] setScriptErrorNumber:errOSACantAssign];
David@0
  1043
		[[NSScriptCommand currentCommand] setScriptErrorString:@"Can't create a contact without specifying the contact name."];
David@0
  1044
		return nil;
David@0
  1045
	}
David@427
  1046
	AIListContact *newContact = [adium.contactController contactWithService:self.service account:self UID:contactUID];
David@0
  1047
	NSScriptObjectSpecifier *groupSpecifier = [keyDictionary objectForKey:@"parentGroup"];
David@0
  1048
	AIListGroup *group = [groupSpecifier objectsByEvaluatingSpecifier];
David@0
  1049
	//If we have a group, we add this contact to the contact list.
David@0
  1050
	if (groupSpecifier && group) {
David@199
  1051
		[self addContact:newContact toGroup:group];
David@0
  1052
	}
David@0
  1053
	
David@0
  1054
	return newContact;
David@0
  1055
}
David@0
  1056
- (void)insertObject:(AIListObject *)contact inContactsAtIndex:(int)index
David@0
  1057
{
David@0
  1058
	//Intentially unimplemented. This should never be called (contacts are created a different way), but is required for KVC-compliance.
David@0
  1059
}
zacw@2131
  1060
- (void)removeObjectFromContactsAtIndex:(NSInteger)index
David@0
  1061
{
zacw@2131
  1062
	AIListObject *object = [self.contacts objectAtIndex:index];
zacw@2131
  1063
	
zacw@2131
  1064
	for (AIListGroup *group in object.groups) {
zacw@2131
  1065
		[object removeFromGroup:group];
zacw@2131
  1066
	}
David@0
  1067
}
David@0
  1068
David@0
  1069
/**
David@0
  1070
 * @brief Creates a chat according to the given properties.
David@0
  1071
 * @param resolvedKeyDictionary The dictionary of arguments to the 'make' command.
David@0
  1072
 *
David@0
  1073
 * This uses my own custom make<Key>WithProperties KVC method. :)
David@0
  1074
 * The idea is that be default Cocoa-AS will try to make an object using the standard alloc/init routines
David@0
  1075
 * However, you may not want that to be the case. If an AS model object implements this method, then when its the 
David@0
  1076
 * target of a 'make' command, it will be called. The method should return a new object, already assigned to a
David@0
  1077
 * container, as AICreateCommand will not do that for you.
David@0
  1078
 */
David@0
  1079
- (id)makeChatWithProperties:(NSDictionary *)resolvedKeyDictionary
David@0
  1080
{
David@0
  1081
	AILogWithSignature(@"%@", resolvedKeyDictionary);
David@0
  1082
	NSArray *participants = [resolvedKeyDictionary objectForKey:@"withContacts"];
David@0
  1083
	if (!participants) {
David@0
  1084
		[[NSScriptCommand currentCommand] setScriptErrorNumber:errOSACantAssign];
David@0
  1085
		[[NSScriptCommand currentCommand] setScriptErrorString:@"Can't create a chat without a contact!"];
David@0
  1086
		return nil;
David@0
  1087
	}
David@0
  1088
	if (![resolvedKeyDictionary objectForKey:@"newChatWindow"] && ![resolvedKeyDictionary objectForKey:@"Location"]) {
David@0
  1089
		[[NSScriptCommand currentCommand] setScriptErrorNumber:errOSACantAssign];
David@0
  1090
		[[NSScriptCommand currentCommand] setScriptErrorString:@"Can't create a chat without specifying its containing window."];
David@0
  1091
		return nil;
David@0
  1092
	}
David@0
  1093
	
David@0
  1094
	if ([participants count] == 1) {
David@0
  1095
		AIListContact *contact = [[participants objectAtIndex:0] objectsByEvaluatingSpecifier];
David@0
  1096
		if (!contact) {
David@0
  1097
			[[NSScriptCommand currentCommand] setScriptErrorNumber:errOSACantAssign];
David@0
  1098
			[[NSScriptCommand currentCommand] setScriptErrorString:@"Can't find that contact!"];
David@0
  1099
			return nil;
David@0
  1100
		}
David@0
  1101
		AIMessageWindowController *chatWindowController = nil;
David@0
  1102
		int index = -1; //at end by default
David@0
  1103
		if ([resolvedKeyDictionary objectForKey:@"newChatWindow"]) {
David@0
  1104
			//I need to put this in a new chat window
David@100
  1105
			chatWindowController = [adium.interfaceController openContainerWithID:nil name:nil];
David@0
  1106
		} else {
David@0
  1107
			//I need to figure out to which chat window the location specifier is referring.
David@0
  1108
			//NSLog(@"Here is the info about the location specifier: %@",[resolvedKeyDictionary objectForKey:@"Location"]);
David@0
  1109
			NSPositionalSpecifier *location = [resolvedKeyDictionary objectForKey:@"Location"];
David@0
  1110
			AIMessageWindow *chatWindow = [location insertionContainer];
David@0
  1111
			index = [location insertionIndex];
David@0
  1112
			chatWindowController = (AIMessageWindowController *)[chatWindow windowController];
David@0
  1113
		}
David@0
  1114
		
David@0
  1115
		if (!chatWindowController) {
David@0
  1116
			[[NSScriptCommand currentCommand] setScriptErrorNumber:errOSACantAssign];
David@0
  1117
			[[NSScriptCommand currentCommand] setScriptErrorString:@"Can't create chat in that chat window."];
David@0
  1118
			return nil;
David@0
  1119
		}
David@0
  1120
		
David@95
  1121
		AIChat *newChat = [adium.chatController chatWithContact:contact];
David@0
  1122
//		NSLog(@"Making new chat %@ in chat window %@:%@",newChat,chatWindowController,[chatWindowController containerID]);
David@100
  1123
		[adium.interfaceController openChat:newChat inContainerWithID:[chatWindowController containerID] atIndex:index];
David@0
  1124
		return newChat;
David@0
  1125
	} else {
David@427
  1126
		if (![self.service canCreateGroupChats]) {
David@0
  1127
			[[NSScriptCommand currentCommand] setScriptErrorNumber:errOSACantAssign];
David@0
  1128
			[[NSScriptCommand currentCommand] setScriptErrorString:@"Can't create a group chat with this service!"];
David@0
  1129
			return nil;
David@0
  1130
		}
David@0
  1131
		NSString *name = [resolvedKeyDictionary objectForKey:@"name"];
David@0
  1132
		if (!name) {
David@0
  1133
			[[NSScriptCommand currentCommand] setScriptErrorNumber:errOSACantAssign];
David@0
  1134
			[[NSScriptCommand currentCommand] setScriptErrorString:@"Can't create a group chat without a name!"];
David@0
  1135
			return nil;
David@0
  1136
		}
David@0
  1137
		//this can take a while...
David@0
  1138
		NSMutableArray *newParticipants = [[[NSMutableArray alloc] init] autorelease];
David@0
  1139
		for (int i=0;i<[participants count];i++) {
David@0
  1140
			[newParticipants addObject:[[participants objectAtIndex:i] objectsByEvaluatingSpecifier]];
David@0
  1141
		}
David@0
  1142
		
David@95
  1143
		//AIChat *newChat = [adium.chatController chatWithName:name identifier:nil onAccount:self chatCreationInfo:nil];
David@0
  1144
		DCJoinChatViewController *chatController = [DCJoinChatViewController joinChatView];
David@0
  1145
		[chatController doJoinChatWithName:name onAccount:self chatCreationInfo:nil invitingContacts:newParticipants withInvitationMessage:@"Hey, wanna join my chat?"];
David@95
  1146
		return [adium.chatController existingChatWithName:name onAccount:self];
David@0
  1147
	}
David@0
  1148
}
David@0
  1149
David@0
  1150
/**
David@0
  1151
 * @brief Returns the current status type of this account.
David@0
  1152
 */
David@0
  1153
- (AIStatusTypeApplescript)scriptingStatusType
David@0
  1154
{
David@837
  1155
	return [self.statusState statusTypeApplescript];
David@0
  1156
}
David@0
  1157
David@0
  1158
/**
David@0
  1159
 * @brief Sets the type of the current status.
David@0
  1160
 *
David@0
  1161
 * If the current status is a temporary status, then we simply set it.
David@0
  1162
 * Otherwise, we create a temporary copy of it, and set that.
David@0
  1163
 */
David@0
  1164
- (void)setScriptingStatusType:(AIStatusTypeApplescript)scriptingType
David@0
  1165
{
David@0
  1166
	AIStatusType type;
David@0
  1167
	switch (scriptingType) {
David@0
  1168
		case AIAvailableStatusTypeAS:
David@0
  1169
			type = AIAvailableStatusType;
David@0
  1170
			break;
David@0
  1171
		case AIAwayStatusTypeAS:
David@0
  1172
			type = AIAwayStatusType;
David@0
  1173
			break;
David@0
  1174
		case AIInvisibleStatusTypeAS:
David@0
  1175
			type = AIInvisibleStatusType;
David@0
  1176
			break;
David@0
  1177
		case AIOfflineStatusTypeAS:
David@0
  1178
		default:
David@0
  1179
			type = AIOfflineStatusType;
David@0
  1180
			break;
David@0
  1181
	}
David@0
  1182
	
David@837
  1183
	AIStatus *currentStatus = self.statusState;
David@0
  1184
	if ([currentStatus mutabilityType] == AILockedStatusState || [currentStatus mutabilityType] == AISecondaryLockedStatusState) {
David@0
  1185
		switch (type) {
David@0
  1186
			case AIAvailableStatusType:
David@100
  1187
				currentStatus = [adium.statusController availableStatus];
David@0
  1188
				break;
David@0
  1189
			case AIAwayStatusType:
David@100
  1190
				currentStatus = [adium.statusController awayStatus];
David@0
  1191
				break;
David@0
  1192
			case AIInvisibleStatusType:
David@100
  1193
				currentStatus = [adium.statusController invisibleStatus];
David@0
  1194
				break;
David@0
  1195
			case AIOfflineStatusType:
David@100
  1196
				currentStatus = [adium.statusController offlineStatus];
David@0
  1197
				break;
David@0
  1198
		}
David@0
  1199
	} else {
David@0
  1200
		if ([currentStatus mutabilityType] != AITemporaryEditableStatusState) {
David@0
  1201
			currentStatus = [[currentStatus mutableCopy] autorelease];
David@0
  1202
			[currentStatus setMutabilityType:AITemporaryEditableStatusState];
David@0
  1203
		}
David@0
  1204
		[currentStatus setStatusType:type];
David@100
  1205
		[currentStatus setStatusName:[adium.statusController defaultStatusNameForType:type]];
David@0
  1206
	}
David@100
  1207
	[adium.statusController setActiveStatusState:currentStatus forAccount:self];
David@0
  1208
}
David@0
  1209
David@0
  1210
/**
zacw@2340
  1211
 * @brief Returns a mutable status
David@0
  1212
 *
David@0
  1213
 * If the current status is built in, we create a temporary copy of the current status and set that.
zacw@2340
  1214
 *
zacw@2340
  1215
 * @return An AIStatus fit for being modified.
David@0
  1216
 */
hg@2356
  1217
- (AIStatus *)modifiableCurrentStatus
David@0
  1218
{
David@837
  1219
	AIStatus *currentStatus = self.statusState;
zacw@2340
  1220
	
David@0
  1221
	if ([currentStatus mutabilityType] != AITemporaryEditableStatusState) {
David@745
  1222
		currentStatus = [[currentStatus mutableCopy] autorelease];
David@0
  1223
		[currentStatus setMutabilityType:AITemporaryEditableStatusState];
David@0
  1224
	}	
zacw@2340
  1225
	
David@0
  1226
	return currentStatus;
David@0
  1227
}
David@0
  1228
David@0
  1229
/**
David@0
  1230
 * @brief Sets the status message
David@0
  1231
 *
David@0
  1232
 * @param message, which may be an NSAttributedString or NSString
David@0
  1233
 */
David@0
  1234
- (void)setScriptingStatusMessageWithAttributedString:(id)message
David@0
  1235
{
hg@2356
  1236
	AIStatus *currentStatus = [self modifiableCurrentStatus];
zacw@2340
  1237
	
David@0
  1238
	if ([message isKindOfClass:[NSAttributedString class]])
David@0
  1239
		[currentStatus setStatusMessage:(NSAttributedString *)message];
David@0
  1240
	else
David@0
  1241
		[currentStatus setStatusMessageString:message];
zacw@2340
  1242
	
David@100
  1243
	[adium.statusController setActiveStatusState:currentStatus forAccount:self];
David@0
  1244
}
David@0
  1245
David@0
  1246
- (void)setScriptingStatusMessage:(NSString *)message
David@0
  1247
{
David@0
  1248
  [self setScriptingStatusMessageWithAttributedString:message];
David@0
  1249
}
David@0
  1250
David@0
  1251
/**
David@0
  1252
 * @brief Sets the status message to a NSAttributedString extracted of a NSScriptCommand
David@0
  1253
 */
David@0
  1254
- (void)setScriptingStatusMessageFromScriptCommand:(NSScriptCommand *)c
David@0
  1255
{
David@0
  1256
	//messageString could also be an NSTextStorage, due to WithMessage being able to also accept rich text
David@0
  1257
	NSString *messageString = [[c evaluatedArguments] objectForKey:@"WithMessage"];
David@0
  1258
	if (messageString)
David@0
  1259
		[self setScriptingStatusMessageWithAttributedString:messageString];	
David@0
  1260
}
David@0
  1261
David@0
  1262
/**
David@0
  1263
 * @brief Tells this account to be available, with an optional temporary status message.
David@0
  1264
 */
David@0
  1265
- (void)scriptingGoAvailable:(NSScriptCommand *)c
David@0
  1266
{
David@100
  1267
	[adium.statusController setActiveStatusState:[adium.statusController availableStatus] forAccount:self];
David@0
  1268
	
David@0
  1269
	[self setScriptingStatusMessageFromScriptCommand:c];
David@0
  1270
}
David@0
  1271
David@0
  1272
/**
David@0
  1273
 * @brief Tells this account to be online, with an optional temporary status message.
David@0
  1274
 */
David@0
  1275
- (void)scriptingGoOnline:(NSScriptCommand *)c
David@0
  1276
{
David@837
  1277
	if (self.statusType == AIInvisibleStatusType) {
David@0
  1278
		[self scriptingGoAvailable:c];
David@0
  1279
David@0
  1280
	} else {		
David@0
  1281
		[self setShouldBeOnline:YES];
David@0
  1282
		
David@0
  1283
		[self setScriptingStatusMessageFromScriptCommand:c];
David@0
  1284
	}
David@0
  1285
}
David@0
  1286
David@0
  1287
/**
David@0
  1288
 * @brief Tells this account to be offline, with an optional temporary status message.
David@0
  1289
 */
David@0
  1290
- (void)scriptingGoOffline:(NSScriptCommand *)c
David@0
  1291
{
David@0
  1292
	[self setShouldBeOnline:NO];
David@0
  1293
David@0
  1294
	[self setScriptingStatusMessageFromScriptCommand:c];
David@0
  1295
}
David@0
  1296
David@0
  1297
/**
David@0
  1298
 * @brief Tells this account to be away, with an optional temporary status message.
David@0
  1299
 */
David@0
  1300
- (void)scriptingGoAway:(NSScriptCommand *)c
David@0
  1301
{
David@100
  1302
	[adium.statusController setActiveStatusState:[adium.statusController awayStatus] forAccount:self];
David@0
  1303
David@0
  1304
	[self setScriptingStatusMessageFromScriptCommand:c];
David@0
  1305
}
David@0
  1306
David@0
  1307
/**
David@0
  1308
 * @brief Tells this account to be invisible.
David@0
  1309
 */
David@0
  1310
- (void)scriptingGoInvisible:(NSScriptCommand *)c
David@0
  1311
{
David@100
  1312
	[adium.statusController setActiveStatusState:[adium.statusController invisibleStatus] forAccount:self];
David@0
  1313
	
David@0
  1314
	[self setScriptingStatusMessageFromScriptCommand:c];
David@0
  1315
}
David@0
  1316
David@0
  1317
/**
David@0
  1318
 * @brief True, if a proxy is enabled
David@0
  1319
 */
David@0
  1320
- (BOOL)proxyEnabled
David@0
  1321
{
David@0
  1322
	return [[self preferenceForKey:KEY_ACCOUNT_PROXY_ENABLED group:GROUP_ACCOUNT_STATUS] boolValue];
David@0
  1323
}
David@0
  1324
/**
David@0
  1325
 * @brief Sets whether or not the proxy is enabled for this account.
David@0
  1326
 * This does not change the proxy setting immediately, a disconnect and reconnect is still required.
David@0
  1327
 */
David@0
  1328
- (void)setProxyEnabled:(BOOL)proxyEnabled
David@0
  1329
{
David@0
  1330
	[self setPreference:[NSNumber numberWithBool:proxyEnabled] forKey:KEY_ACCOUNT_PROXY_ENABLED group:GROUP_ACCOUNT_STATUS];
David@0
  1331
}
David@0
  1332
/**
David@0
  1333
 * @brief Gets the type of the proxy (one of the defined AdiumProxyTypes)
David@0
  1334
 */
David@0
  1335
- (AdiumProxyType)proxyType
David@0
  1336
{
David@0
  1337
	return [[self preferenceForKey:KEY_ACCOUNT_PROXY_TYPE group:GROUP_ACCOUNT_STATUS] intValue];
David@0
  1338
}
David@0
  1339
/**
David@0
  1340
 * @brief Sets the proxy type (one of the defined AdiumProxyTypes)
David@0
  1341
 */
David@0
  1342
- (void)setProxyType:(AdiumProxyType)type
David@0
  1343
{
David@0
  1344
	[self setPreference:[NSNumber numberWithInt:type] forKey:KEY_ACCOUNT_PROXY_TYPE group:GROUP_ACCOUNT_STATUS];
David@0
  1345
}
David@0
  1346
/**
David@0
  1347
 * @brief Gets the proxy host as a string
David@0
  1348
 */
David@0
  1349
- (NSString *)proxyHost
David@0
  1350
{
David@0
  1351
	return [self preferenceForKey:KEY_ACCOUNT_PROXY_HOST group:GROUP_ACCOUNT_STATUS];
David@0
  1352
}
David@0
  1353
/**
David@0
  1354
 * @brief Sets the proxy host
David@0
  1355
 */
David@0
  1356
- (void)setProxyHost:(NSString *)host
David@0
  1357
{
David@0
  1358
	[self setPreference:host forKey:KEY_ACCOUNT_PROXY_HOST group:GROUP_ACCOUNT_STATUS];
David@0
  1359
}
David@0
  1360
/**
David@0
  1361
 * @brief Gets the proxy's port
David@0
  1362
 */
Matt@347
  1363
- (NSNumber *)proxyPort
David@0
  1364
{
Matt@347
  1365
	NSString *proxyPort = [self preferenceForKey:KEY_ACCOUNT_PROXY_PORT group:GROUP_ACCOUNT_STATUS];
Matt@347
  1366
	return [NSNumber numberWithUnsignedShort:[proxyPort integerValue]];
David@0
  1367
}
David@0
  1368
/**
David@0
  1369
 * @brief Set the port to which we should connect when connecting to the proxy
David@0
  1370
 */
Matt@347
  1371
- (void)setProxyPort:(NSNumber *)port
David@0
  1372
{
Matt@347
  1373
	[self setPreference:[port stringValue] forKey:KEY_ACCOUNT_PROXY_PORT group:GROUP_ACCOUNT_STATUS];
David@0
  1374
}
David@0
  1375
/**
David@0
  1376
 * @brief Gets the username we use when connecting to the proxy
David@0
  1377
 */
David@0
  1378
- (NSString *)proxyUsername
David@0
  1379
{
David@0
  1380
	return [self preferenceForKey:KEY_ACCOUNT_PROXY_USERNAME group:GROUP_ACCOUNT_STATUS];
David@0
  1381
}
David@0
  1382
/**
David@0
  1383
 * @brief Sets the username we should use when connecting to the proxy
David@0
  1384
 */
David@0
  1385
- (void)setProxyUsername:(NSString *)username
David@0
  1386
{
David@0
  1387
	[self setPreference:username forKey:KEY_ACCOUNT_PROXY_USERNAME group:GROUP_ACCOUNT_STATUS];
David@0
  1388
}
David@0
  1389
/**
David@0
  1390
 * @brief Gets the password we use when connecting to the proxy
David@0
  1391
 */
David@0
  1392
- (NSString *)proxyPassword
David@0
  1393
{
David@0
  1394
	return [self preferenceForKey:KEY_ACCOUNT_PROXY_PASSWORD group:GROUP_ACCOUNT_STATUS];
David@0
  1395
}
David@0
  1396
/**
David@0
  1397
 * @brief Sets the password we should use when connecting to the proxy
David@0
  1398
 */
David@0
  1399
- (void)setProxyPassword:(NSString *)proxyPassword
David@0
  1400
{
David@0
  1401
	[self setPreference:proxyPassword forKey:KEY_ACCOUNT_PROXY_PASSWORD group:GROUP_ACCOUNT_STATUS];
David@0
  1402
}
David@0
  1403
David@0
  1404
/**
David@0
  1405
 * @brief Gets the proxy type for applescript (using the nice four-letter codes defined by AdiumProxyTypeApplescript)
David@0
  1406
 */
David@0
  1407
- (AdiumProxyTypeApplescript)scriptingProxyType
David@0
  1408
{
David@0
  1409
	return [self applescriptProxyType:[self proxyType]];
David@0
  1410
}
David@0
  1411
/**
David@0
  1412
 * @brief Sets the proxy type to one of the defined AdiumProxyTypeApplescripts
David@0
  1413
 */
David@0
  1414
- (void)setScriptingProxyType:(AdiumProxyTypeApplescript)type
David@0
  1415
{
David@0
  1416
	[self setProxyType:[self proxyTypeFromApplescript:type]];
David@0
  1417
}
David@0
  1418
David@0
  1419
@end
David@0
  1420
David@0
  1421
@implementation AIAccount(AppleScriptPRIVATE)
David@0
  1422
- (AdiumProxyType)proxyTypeFromApplescript:(AdiumProxyTypeApplescript)proxyTypeAS
David@0
  1423
{
David@0
  1424
	switch(proxyTypeAS)
David@0
  1425
	{
David@0
  1426
		case Adium_Proxy_HTTP_AS:
David@0
  1427
			return Adium_Proxy_HTTP;
David@0
  1428
		case Adium_Proxy_SOCKS4_AS:
David@0
  1429
			return Adium_Proxy_SOCKS4;
David@0
  1430
		case Adium_Proxy_SOCKS5_AS:
David@0
  1431
			return Adium_Proxy_SOCKS5;
David@0
  1432
		case Adium_Proxy_Default_HTTP_AS:
David@0
  1433
			return Adium_Proxy_Default_HTTP;
David@0
  1434
		case Adium_Proxy_Default_SOCKS4_AS:
David@0
  1435
			return Adium_Proxy_Default_SOCKS4;
David@0
  1436
		case Adium_Proxy_Default_SOCKS5_AS:
David@0
  1437
			return Adium_Proxy_Default_SOCKS5;
David@0
  1438
		default:
David@0
  1439
			return Adium_Proxy_None;
David@0
  1440
	}
David@0
  1441
}
David@0
  1442
- (AdiumProxyTypeApplescript)applescriptProxyType:(AdiumProxyType)proxyType
David@0
  1443
{
David@0
  1444
	switch(proxyType)
David@0
  1445
	{
David@0
  1446
		case Adium_Proxy_HTTP:
David@0
  1447
			return Adium_Proxy_HTTP_AS;
David@0
  1448
		case Adium_Proxy_SOCKS4:
David@0
  1449
			return Adium_Proxy_SOCKS4_AS;
David@0
  1450
		case Adium_Proxy_SOCKS5:
David@0
  1451
			return Adium_Proxy_SOCKS5_AS;
David@0
  1452
		case Adium_Proxy_Default_HTTP:
David@0
  1453
			return Adium_Proxy_Default_HTTP_AS;
David@0
  1454
		case Adium_Proxy_Default_SOCKS4:
David@0
  1455
			return Adium_Proxy_Default_SOCKS4_AS;
David@0
  1456
		case Adium_Proxy_Default_SOCKS5:
David@0
  1457
			return Adium_Proxy_Default_SOCKS5_AS;
David@0
  1458
		default:
David@0
  1459
			return Adium_Proxy_None_AS;
David@0
  1460
	}
David@0
  1461
}
David@0
  1462
David@0
  1463
@end