Frameworks/Adium Framework/Source/AIService.m
author Zachary West <zacw@adium.im>
Sat Oct 17 17:35:57 2009 -0400 (2009-10-17)
changeset 2743 df2c24e3844c
parent 1956 fe470f38b994
child 3074 c867117688bb
permissions -rw-r--r--
Add -[AIService pathForDefaultServiceIconOfType:], and use it for replacing %serviceIconImg% in headers. Fixes #12697.
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/AIAccount.h>
David@0
    18
#import <Adium/AIService.h>
David@0
    19
#import <Adium/AIAccountControllerProtocol.h>
David@0
    20
#import <Adium/AIAccountViewController.h>
David@0
    21
#import "AICreateCommand.h"
David@0
    22
David@0
    23
/*!
David@0
    24
 * @class AIService
David@0
    25
 * @brief An IM Service
David@0
    26
 *
David@0
    27
 * This abstract class represents a service that Adium supports.  Subclass this for every service.
David@0
    28
 */
David@0
    29
@implementation AIService
David@0
    30
David@0
    31
+ (void)registerService
David@0
    32
{
David@0
    33
	[[[self alloc] init] autorelease];
David@0
    34
}
David@0
    35
David@0
    36
/*!
David@0
    37
 * @brief Init
David@0
    38
 */
David@0
    39
- (id)init
David@0
    40
{
David@0
    41
	if ((self = [super init])) {
David@0
    42
		//Register this service with Adium
David@95
    43
		[adium.accountController registerService:self];
David@0
    44
		
David@0
    45
		[self registerStatuses];
David@0
    46
	}
David@0
    47
	
David@0
    48
	return self;
David@0
    49
}
David@0
    50
David@0
    51
David@0
    52
//Account Creation -----------------------------------------------------------------------------------------------------
David@0
    53
#pragma mark Account Creation
David@0
    54
/*!
David@0
    55
 * @brief Create a new account for this service
David@0
    56
 *
David@0
    57
 * Creates a new account of this service.  Accounts are identified by a unique number.  We can't use service or
David@0
    58
 * UID, since both those values may change.
David@0
    59
 * @param inUID A unique identifier for the account being created.
David@0
    60
 * @param inInternalObjectID A unique internalObjectID for the account being created.
David@0
    61
 * @return An AIAccount object for this service.
David@0
    62
 */
David@0
    63
- (id)accountWithUID:(NSString *)inUID internalObjectID:(NSString *)inInternalObjectID
David@0
    64
{
David@0
    65
	return [[[[self accountClass] alloc] initWithUID:[self normalizeUID:inUID removeIgnoredCharacters:YES]
David@0
    66
									internalObjectID:inInternalObjectID
David@0
    67
											 service:self] autorelease];
David@0
    68
}
David@0
    69
David@0
    70
/*!
David@0
    71
 * @brief Account class associated with this service
David@0
    72
 *
David@0
    73
 * Subclass to return the account class associated with this service ([AISomethingAccount class]).
David@0
    74
 * @return The account class associated with this service.
David@0
    75
 */
David@0
    76
- (Class)accountClass
David@0
    77
{
David@0
    78
	return nil;
David@0
    79
}
David@0
    80
David@0
    81
/*!
David@0
    82
 * @brief Account view controller for this service
David@0
    83
 *
David@0
    84
 * Subclass to return an account view controller which provides the necessary controls for configuring an account
David@0
    85
 * on this service.
David@0
    86
 * @return An AIAccountViewController or subclass for this service.
David@0
    87
 */
David@0
    88
- (AIAccountViewController *)accountViewController
David@0
    89
{
David@0
    90
	return [AIAccountViewController accountViewController];
David@0
    91
}
David@0
    92
David@0
    93
/*!
David@0
    94
 * @brief Join chat view controller for this service
David@0
    95
 *
David@0
    96
 * Subclass to return a join chat view controller which provides the necessary controls for joining a chat on this
David@0
    97
 * service.
David@0
    98
 * @return An DCJoinChatViewController or subclass for this service.
David@0
    99
 */
David@0
   100
- (DCJoinChatViewController *)joinChatView
David@0
   101
{
David@0
   102
	return nil;
David@0
   103
}
David@0
   104
David@0
   105
David@0
   106
//Service Description --------------------------------------------------------------------------------------------------
David@0
   107
#pragma mark Service Description
David@0
   108
/*!
David@0
   109
 * @brief Unique ID for this class
David@0
   110
 *
David@0
   111
 * Subclass to return a unique string ID which identifies this class.  No two classes should have the same uniqueID.
David@0
   112
 * This value is used to determine which protocol code to use for the user's accounts.
David@0
   113
 * Examples: "libgaim-aim", "aim-toc2", "imservices-aim-.mac"
David@0
   114
 * @return NSString unique ID
David@0
   115
 */
David@0
   116
- (NSString *)serviceCodeUniqueID{
David@0
   117
    return @"";
David@0
   118
}
David@0
   119
David@0
   120
/*!
David@0
   121
 * @brief Service ID for this service
David@0
   122
 *
David@0
   123
 * Subclass to return a string which identifies this service.  If multiple service classes are supporting the same
David@0
   124
 * service they should have the same serviceID.  Not for user-display.
David@0
   125
 * Examples: "AIM", "MSN", "Jabber", "ICQ", "Mac"
David@0
   126
 * @return NSString service ID
David@0
   127
 */
David@0
   128
- (NSString *)serviceID{
David@0
   129
    return @"";
David@0
   130
}
David@0
   131
David@0
   132
/*!
David@0
   133
 * @brief Service class for this service
David@0
   134
 *
David@0
   135
 * Some separate services can communicate with eachother.  These services, while they have separate serviceID's,
David@0
   136
 * are all part of a common service class.  For instance, AIM, ICQ, and .Mac are all part of the "AIM" service class.
David@0
   137
 * For many services, the serviceClass will be identical to the serviceID.  Not for user-display.
David@0
   138
 * Service classes may change, do not use them for any permenant storage (logs, preferences, etc).
David@0
   139
 * Examples: "AIM-compatible", "Jabber", "MSN"
David@0
   140
 * @return NSString service class
David@0
   141
 */
David@0
   142
- (NSString *)serviceClass{
David@0
   143
	return @"";
David@0
   144
}
David@0
   145
David@0
   146
/*!
David@0
   147
 * @brief Human readable short description
David@0
   148
 *
David@0
   149
 * Human readable, short description of this service
David@0
   150
 * This value is used in tooltips and the message window.
David@0
   151
 * Examples: "Jabber", "MSN", "AIM", ".Mac"
David@0
   152
 * @return NSString short description
David@0
   153
 */
David@0
   154
- (NSString *)shortDescription{
David@0
   155
    return @"";
David@0
   156
}
David@0
   157
David@0
   158
/*!
David@0
   159
 * @brief Human readable long description
David@0
   160
 *
David@0
   161
 * Human readable, long description of this service
David@0
   162
 * If there are multiple classes available for the same service, this description should briefly show the difference
David@0
   163
 * between the implementations.  This value is used in the account preferences service menu.
David@0
   164
 * Examples: "Jabber", "MSN", "AOL Instant Messenger", ".Mac"
David@0
   165
 * @return NSString long description
David@0
   166
 */
David@0
   167
- (NSString *)longDescription{
David@0
   168
    return @"";
David@0
   169
}
David@0
   170
David@0
   171
/*!
David@0
   172
 * @brief Label for user name (general)
David@0
   173
 *
David@0
   174
 * String to use for describing the UID/username of this service.  This value varies by service, but should be something
David@0
   175
 * along the lines of "User name", "Account name", "Screen name", "Member name", etc.
David@0
   176
 *
David@0
   177
 * This will be used for the account preferences to indicate the field for the account's user name.  By default, contactUserNameLabel
David@0
   178
 * will return this value, as well.
David@0
   179
 *
David@0
   180
 * @return NSString label for username
David@0
   181
 */
David@0
   182
- (NSString *)userNameLabel
David@0
   183
{
David@0
   184
    return AILocalizedStringFromTableInBundle(@"User Name", nil, [NSBundle bundleForClass:[AIService class]], nil);    
David@0
   185
}
David@0
   186
David@0
   187
/*!
David@0
   188
 * @brief Label for user name
David@0
   189
 *
David@0
   190
 * String to use for describing the UID/username of contacts for this service.  This value varies by service, but should be something
David@0
   191
 * along the lines of "User name", "Account name", "Screen name", "Member name", etc.
David@0
   192
 *
David@0
   193
 * By default, this returns -[self userNameLabel]; only override this method if contacts are named differently than own-account usernames.
David@0
   194
 *
David@0
   195
 * @return NSString label for username
David@0
   196
 */
David@0
   197
- (NSString *)contactUserNameLabel
David@0
   198
{
David@0
   199
	return [self userNameLabel];
David@0
   200
}
David@0
   201
David@0
   202
/*!
David@0
   203
 * @brief Placeholder string for the UID field
David@0
   204
 */
David@0
   205
- (NSString *)UIDPlaceholder
David@0
   206
{
David@0
   207
	return @"";
David@0
   208
}
David@0
   209
David@0
   210
/*!
David@0
   211
 * @brief Service importance
David@0
   212
 *
David@0
   213
 * Importance grouping of this service.  Used to make service listings and menus more organized by placing more important
David@0
   214
 * services at the top of lists or displaying them with more visibility.
David@0
   215
 * @return AIServiceImportance importance of this service
David@0
   216
 */
David@0
   217
- (AIServiceImportance)serviceImportance
David@0
   218
{
David@0
   219
	return AIServiceUnsupported;
David@0
   220
}
David@0
   221
David@0
   222
/*!
David@0
   223
 * @brief Default icon
David@0
   224
 *
David@0
   225
 * Service Icon packs should always include images for all the built-in Adium services.  This method allows external
David@0
   226
 * service plugins to specify an image which will be used when the service icon pack does not specify one.  It will
David@0
   227
 * also be useful if new services are added to Adium itself after a significant number of Service Icon packs exist
David@0
   228
 * which do not yet have an image for this service.  If the active Service Icon pack provides an image for this service,
David@0
   229
 * this method will not be called.
David@0
   230
 *
David@0
   231
 * The service should _not_ cache this icon internally; multiple calls should return unique NSImage objects.
David@0
   232
 *
David@0
   233
 * @param iconType The AIServiceIconType of the icon to return. This specifies the desired size of the icon.
David@0
   234
 * @return NSImage to use for this service by default
David@0
   235
 */
David@0
   236
- (NSImage *)defaultServiceIconOfType:(AIServiceIconType)iconType
David@0
   237
{
David@0
   238
	return nil;
David@0
   239
}
David@0
   240
zacw@2743
   241
/*!
zacw@2743
   242
 * @brief Path for default icon
zacw@2743
   243
 *
zacw@2743
   244
 * For use in message views, this is the path to a default icon as described above.
zacw@2743
   245
 *
zacw@2743
   246
 * @param iconType The AIServiceIconType of the icon to return.
zacw@2743
   247
 * @return The path to the image, otherwise nil.
zacw@2743
   248
 */
zacw@2743
   249
- (NSString *)pathForDefaultServiceIconOfType:(AIServiceIconType)iconType
zacw@2743
   250
{
zacw@2743
   251
	return nil;
zacw@2743
   252
}
zacw@2743
   253
David@0
   254
//Service Properties ---------------------------------------------------------------------------------------------------
David@0
   255
#pragma mark Service Properties
David@0
   256
/*!
David@0
   257
 * @brief Allowed characters
David@0
   258
 *
David@0
   259
 * Characters allowed in user names on this service.  The user will not be allowed to type any characters not in this
David@0
   260
 * set as a contact or account name.
David@0
   261
 * @return NSCharacterSet of allowed characters
David@0
   262
 */
David@0
   263
- (NSCharacterSet *)allowedCharacters
David@0
   264
{
David@0
   265
    return nil;
David@0
   266
}
David@0
   267
David@0
   268
/*!
David@0
   269
 * @brief Allowed characters for our account name
David@0
   270
 *
David@0
   271
 * Offers further distinction of allowed characters, for situations where certain characters are allowed
David@0
   272
 * for our account name only, or characters which are allowed in user names are forbidden in our own account name.
David@0
   273
 * If this distinction is not made, do not subclass this methods and instead subclass allowedCharacters.
David@0
   274
 * @return NSCharacterSet of allowed characters
David@0
   275
 */
David@0
   276
- (NSCharacterSet *)allowedCharactersForAccountName
David@0
   277
{
David@0
   278
	return ([self allowedCharacters]);
David@0
   279
}
David@0
   280
David@0
   281
/*!
David@0
   282
 * @brief Allowed characters for UIDs
David@0
   283
 *
David@0
   284
 * Offers further distinction of allowed characters, for situations where certain characters are allowed
David@0
   285
 * for our account name only, or characters which are allowed in user names are forbidden in our own account name.
David@0
   286
 * If this distinction is not made, do not subclass this methods and instead subclass allowedCharacters.
David@0
   287
 * @return NSCharacterSet of allowed characters
David@0
   288
 */
David@0
   289
- (NSCharacterSet *)allowedCharactersForUIDs
David@0
   290
{
David@0
   291
	return [self allowedCharacters];
David@0
   292
}
David@0
   293
David@0
   294
/*!
David@0
   295
 * @brief Ignored characters
David@0
   296
 *
David@0
   297
 * Ignored characters for user names on this service.  Ignored characters are stripped from account and contact names
David@0
   298
 * before they are used, but the user is free to type them and they may be used by the service code.  For instance, 
David@0
   299
 * spaces are allowed in AIM usernames, but "ad am" is treated as equal to "adam" because space is an ignored character.
David@0
   300
 * @return NSCharacterSet of ignored characters
David@0
   301
 */
David@0
   302
- (NSCharacterSet *)ignoredCharacters
David@0
   303
{
David@716
   304
    return [NSCharacterSet characterSetWithCharactersInString:@""];
David@0
   305
}
David@0
   306
David@0
   307
/*!
David@0
   308
 * @brief Allowed name length
David@0
   309
 *
David@0
   310
 * Max allowed length of user names of this service.  Account and contact names longer than this will not be allowed.
David@0
   311
 * @return Max name length
David@0
   312
 */
David@60
   313
- (NSUInteger)allowedLength
David@0
   314
{
David@60
   315
    return NSUIntegerMax;
David@0
   316
}
David@0
   317
David@0
   318
/*!
David@0
   319
 * @brief Allowed account name length
David@0
   320
 *
David@0
   321
 * Offers further distinction of allowed name length, for situations where our account name has a different
David@0
   322
 * length restriction than the names of our contacts.  If this distinction is not made, do not subclass these methods
David@0
   323
 * and instead subclass allowedLength.
David@0
   324
 * @return Max name length
David@0
   325
 */
David@0
   326
- (int)allowedLengthForAccountName
David@0
   327
{
David@0
   328
	return [self allowedLength];
David@0
   329
}
David@0
   330
David@0
   331
/*!
David@0
   332
 * @brief Allowed UID length
David@0
   333
 *
David@0
   334
 * Offers further distinction of allowed name length, for situations where our account name has a different
David@0
   335
 * length restriction than the names of our contacts.  If this distinction is not made, do not subclass these methods
David@0
   336
 * and instead subclass allowedLength.
David@0
   337
 * @return Max name length
David@0
   338
 */
David@0
   339
- (int)allowedLengthForUIDs
David@0
   340
{
David@0
   341
	return [self allowedLength];
David@0
   342
}
David@0
   343
David@0
   344
/*!
David@0
   345
 * @brief Case sensitivity of names
David@0
   346
 *
David@0
   347
 * Determines if usernames such as "Adam" and "adam" are unique.
David@0
   348
 * @return Case sensitivity
David@0
   349
 */
David@0
   350
- (BOOL)caseSensitive
David@0
   351
{
David@0
   352
    return NO;
David@0
   353
}
David@0
   354
David@0
   355
/*!
David@0
   356
 * @brief Can create group chats?
David@0
   357
 *
David@0
   358
 * Does this service support group chats (Also known as multi-user chats, chat rooms, conferences, etc)?  Services
David@0
   359
 * which do not support group chats are automatically excluded from the group chat interface elements.
David@0
   360
 * @return Can create group chats
David@0
   361
 */
David@0
   362
- (BOOL)canCreateGroupChats
David@0
   363
{
David@0
   364
	return NO;
David@0
   365
}
David@0
   366
David@0
   367
/*!
David@0
   368
 * @brief Can register accounts?
David@0
   369
 *
David@0
   370
 * Does this service support registering new accounts from within Adium?  This is here for Jabber.
David@0
   371
 * @return Can register accounts
David@0
   372
 */
David@0
   373
- (BOOL)canRegisterNewAccounts
David@0
   374
{
David@0
   375
	return NO;
David@0
   376
}
David@0
   377
David@0
   378
/*!
David@0
   379
 * @brief Supports proxy settings?
David@0
   380
 *
David@0
   381
 * Does this service support connecting via a proxy?
David@0
   382
 * @return Supports proxy settings
David@0
   383
 */
David@0
   384
- (BOOL)supportsProxySettings
David@0
   385
{
David@0
   386
	return YES;
David@0
   387
}
David@0
   388
/*!
David@0
   389
 * @brief Supports password
David@0
   390
 *
David@0
   391
 * Subclasses should return NO if this service does not use passwords at all for connectivity.
David@0
   392
 * If NO, all fields related to passwords will be hidden for this service and the user will never be prompted to
David@0
   393
 * enter passwords.
David@0
   394
 */
David@0
   395
- (BOOL)supportsPassword
David@0
   396
{
David@0
   397
	return YES;
David@0
   398
}
David@0
   399
David@0
   400
/*!
David@0
   401
 * @brief Requires Password
David@0
   402
 *
David@0
   403
 * Subclasses should return NO if this service does not require a password.  Returning NO from this method will use the password if
David@0
   404
 * entered but allow a conection to be initiated with no password without prompting for one.
David@0
   405
 * If YES, Adium will insist upon a password being entered before a connection can begin.
David@0
   406
 *
David@0
   407
 * By default, the service requires a password if it is supported. See -[AIService supportsPassword].
David@0
   408
 */
David@0
   409
- (BOOL)requiresPassword
David@0
   410
{
David@0
   411
	return [self supportsPassword];
David@0
   412
}
David@0
   413
David@0
   414
/*!
David@0
   415
 * @brief Register statuses
David@0
   416
 *
David@0
   417
 * Called automatically.  Services should register any supported status with the statusController.
David@0
   418
 */
David@0
   419
- (void)registerStatuses{};
David@0
   420
David@0
   421
/*!
David@0
   422
 * @brief Default user name 
David@0
   423
 * 
David@0
   424
 * The default user name for a service is set for all new accounts. As it's not 
David@0
   425
 * possible to guess the user name for most service types (AIM, MSN, etc.), the 
David@0
   426
 * base class returns @"".
David@0
   427
 *
David@0
   428
 * @return The default user name for this service, or @"" for no default 
David@0
   429
 */ 
David@0
   430
- (NSString *)defaultUserName 
David@0
   431
{ 
David@0
   432
	return @""; 
David@0
   433
}
David@0
   434
David@0
   435
/*!
David@0
   436
 * @brief Is this a social networking service like Twitter or Facebook?
David@0
   437
 *
David@0
   438
 * If YES, accounts on this service treat status very differently than non-social-networking accounts.
David@0
   439
 * For example, global status messages dont apply to social networking services, and their status is handled uniquely.
David@0
   440
 */
David@0
   441
- (BOOL)isSocialNetworkingService
David@0
   442
{
David@0
   443
	return NO;
David@0
   444
}
David@0
   445
David@0
   446
/*!
David@0
   447
 * @brief Is this service hidden?
David@0
   448
 *
David@0
   449
 * If YES, it will not appear in service dropdowns.
David@0
   450
 * This is useful for allowing a legacy service to stick around seamlessly.
David@0
   451
 */
David@0
   452
- (BOOL)isHidden
David@0
   453
{
David@0
   454
	return NO;
David@0
   455
}
David@0
   456
David@0
   457
//Utilities ------------------------------------------------------------------------------------------------------------
David@0
   458
#pragma mark Utilities
David@0
   459
/*!
David@0
   460
 * @brief Normalize a UID
David@0
   461
 *
David@0
   462
 * Normalizes a UID.  All invalid characters and ignored characters are removed.
David@0
   463
 * UID's are ONLY filtered when creating contacts, and when renaming contacts.
David@0
   464
 * - When changing ownership of a contact, a filter is not necessary, since all the accounts should have the same service
David@0
   465
 *   types and requirements.
David@0
   466
 * - When account code retrieves contacts from the contact list, filtering is NOT done.  It is up to the account to
David@0
   467
 *   ensure it passes UIDs in the proper format for its service type.
David@0
   468
 * - Filter UIDs only when the user has entered or mucked with them in some way... UID's TO and FROM account code
David@0
   469
 *   SHOULD ALWAYS BE VALID.
David@0
   470
 * @return NSString filtered UID
David@0
   471
 */
David@0
   472
- (NSString *)normalizeUID:(NSString *)inUID removeIgnoredCharacters:(BOOL)removeIgnored
David@0
   473
{
David@0
   474
	NSString		*workingString = ([self caseSensitive] ? inUID : [inUID lowercaseString]);
David@0
   475
	NSCharacterSet	*allowedCharacters = [self allowedCharactersForUIDs];
David@0
   476
	NSCharacterSet	*ignoredCharacters = [self ignoredCharacters];
David@0
   477
David@0
   478
	//Prepare a little buffer for our filtered UID
David@0
   479
	unsigned	destLength = 0;
David@0
   480
	unsigned	workingStringLength = [workingString length];
David@0
   481
	unichar		*dest = malloc(workingStringLength * sizeof(unichar));
David@0
   482
David@0
   483
	//Filter the UID
David@0
   484
	unsigned	pos;
David@0
   485
	for (pos = 0; pos < workingStringLength; pos++) {
David@0
   486
		unichar c = [workingString characterAtIndex:pos];
David@0
   487
		
David@0
   488
        if ([allowedCharacters characterIsMember:c] && (!removeIgnored || ![ignoredCharacters characterIsMember:c])) {
David@0
   489
            dest[destLength] = (removeIgnored ? c : [inUID characterAtIndex:pos]);
David@0
   490
			destLength++;
David@0
   491
		}
David@0
   492
	}
David@0
   493
David@0
   494
	//Turn it back into a string and return
David@0
   495
    NSString *filteredString = [NSString stringWithCharacters:dest length:destLength];
David@0
   496
	free(dest);
David@0
   497
David@0
   498
	return filteredString;
David@0
   499
}
David@0
   500
David@0
   501
/*!
David@0
   502
 * @brief Normalize a chat name
David@0
   503
 *
zacw@1956
   504
 * The default implementation only lowercases the name.
David@0
   505
 */
David@0
   506
- (NSString *)normalizeChatName:(NSString *)inChatName
David@0
   507
{
zacw@1956
   508
	return [inChatName lowercaseString];
David@0
   509
}
David@0
   510
David@0
   511
/*!
David@0
   512
 * @brief Compare this service to another, ranking by long description
David@0
   513
 */
David@0
   514
- (NSComparisonResult)compareLongDescription:(AIService *)inService
David@0
   515
{
David@0
   516
	return [[self longDescription] compare:[inService longDescription]];
David@0
   517
}
David@0
   518
David@0
   519
- (NSString *)description
David@0
   520
{
David@0
   521
	return [NSString stringWithFormat:@"<%@: serviceCodeUniqueID = %@; serviceID = %@; serviceClass = %@; longDescription = %@>",
David@715
   522
		NSStringFromClass([self class]), self.serviceCodeUniqueID, self.serviceID, self.serviceClass, self.longDescription];
David@0
   523
	
David@0
   524
}
David@0
   525
David@0
   526
#pragma mark AppleScript
David@0
   527
David@0
   528
/**
David@0
   529
 * @brief Returns a list of all accounts that use this service.
David@0
   530
 */
David@0
   531
- (NSArray *)accounts
David@0
   532
{
David@0
   533
	NSMutableArray *accountsForThisService = [[[NSMutableArray alloc] init] autorelease];
catfish@1823
   534
	for (AIAccount *account in adium.accountController.accounts) {
David@837
   535
		if (account.service == self)
David@0
   536
			[accountsForThisService addObject:account];
David@0
   537
	}
David@0
   538
	return accountsForThisService;
David@0
   539
}
David@0
   540
David@0
   541
/**
David@0
   542
 * @brief This class is specified using the 'services' key of AIApplication
David@0
   543
 */
David@0
   544
- (NSScriptObjectSpecifier *)objectSpecifier
David@0
   545
{
David@0
   546
	NSScriptClassDescription *containerClassDesc = (NSScriptClassDescription *)[NSScriptClassDescription classDescriptionForClass:[NSApp class]];
David@0
   547
	return [[[NSNameSpecifier alloc]
David@0
   548
		   initWithContainerClassDescription:containerClassDesc
David@0
   549
		   containerSpecifier:nil key:@"services"
David@715
   550
		   name:self.serviceID] autorelease];
David@0
   551
}
David@0
   552
David@0
   553
- (NSData *)image
David@0
   554
{
David@0
   555
	return [[AIServiceIcons serviceIconForService:self type:AIServiceIconLarge direction:AIIconNormal] TIFFRepresentation];
David@0
   556
}
David@0
   557
David@0
   558
@end