adium/adium
Clone
Summary
Browse
Changes
Graph
Adding +[NSString randomString] seems to be popular, it appears to be colliding with some plugin I have loaded. Add a prefix here.
adium-1.5.11
2014-12-16, Thijs Alkemade
c4b291694b4a
Adding +[NSString randomString] seems to be popular, it appears to be colliding with some plugin I have loaded. Add a prefix here.
/*
* Adium is the legal property of its developers, whose names are listed in the copyright file included
* with this source distribution.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if not,
* write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <Adium/AIAccount.h>
#import <Adium/AIService.h>
#import <Adium/AIAccountControllerProtocol.h>
#import <Adium/AIAccountViewController.h>
#import "AICreateCommand.h"
/*!
* @class AIService
* @brief An IM Service
*
* This abstract class represents a service that Adium supports. Subclass this for every service.
*/
@implementation
AIService
+
(
void
)
registerService
{
[[[
self
alloc
]
init
]
autorelease
];
}
/*!
* @brief Init
*/
-
(
id
)
init
{
if
((
self
=
[
super
init
]))
{
//Register this service with Adium
[
adium
.
accountController
registerService
:
self
];
[
self
registerStatuses
];
}
return
self
;
}
//Account Creation -----------------------------------------------------------------------------------------------------
#pragma mark Account Creation
/*!
* @brief Create a new account for this service
*
* Creates a new account of this service. Accounts are identified by a unique number. We can't use service or
* UID, since both those values may change.
* @param inUID A unique identifier for the account being created.
* @param inInternalObjectID A unique internalObjectID for the account being created.
* @return An AIAccount object for this service.
*/
-
(
id
)
accountWithUID:
(
NSString
*
)
inUID
internalObjectID:
(
NSString
*
)
inInternalObjectID
{
return
[[[[
self
accountClass
]
alloc
]
initWithUID
:
[
self
normalizeUID
:
inUID
removeIgnoredCharacters
:
YES
]
internalObjectID
:
inInternalObjectID
service
:
self
]
autorelease
];
}
/*!
* @brief Account class associated with this service
*
* Subclass to return the account class associated with this service ([AISomethingAccount class]).
* @return The account class associated with this service.
*/
-
(
Class
)
accountClass
{
return
nil
;
}
/*!
* @brief Account view controller for this service
*
* Subclass to return an account view controller which provides the necessary controls for configuring an account
* on this service.
* @return An AIAccountViewController or subclass for this service.
*/
-
(
AIAccountViewController
*
)
accountViewController
{
return
[
AIAccountViewController
accountViewController
];
}
/*!
* @brief Join chat view controller for this service
*
* Subclass to return a join chat view controller which provides the necessary controls for joining a chat on this
* service.
* @return An DCJoinChatViewController or subclass for this service.
*/
-
(
DCJoinChatViewController
*
)
joinChatView
{
return
nil
;
}
//Service Description --------------------------------------------------------------------------------------------------
#pragma mark Service Description
/*!
* @brief Unique ID for this class
*
* Subclass to return a unique string ID which identifies this class. No two classes should have the same uniqueID.
* This value is used to determine which protocol code to use for the user's accounts.
* Examples: "libgaim-aim", "aim-toc2", "imservices-aim-.mac"
* @return NSString unique ID
*/
-
(
NSString
*
)
serviceCodeUniqueID
{
return
@""
;
}
/*!
* @brief Service ID for this service
*
* Subclass to return a string which identifies this service. If multiple service classes are supporting the same
* service they should have the same serviceID. Not for user-display.
* Examples: "AIM", "MSN", "Jabber", "ICQ", "Mac"
* @return NSString service ID
*/
-
(
NSString
*
)
serviceID
{
return
@""
;
}
/*!
* @brief Service class for this service
*
* Some separate services can communicate with eachother. These services, while they have separate serviceID's,
* are all part of a common service class. For instance, AIM, ICQ, and .Mac are all part of the "AIM" service class.
* For many services, the serviceClass will be identical to the serviceID. Not for user-display.
* Service classes may change, do not use them for any permenant storage (logs, preferences, etc).
* Examples: "AIM-compatible", "Jabber", "MSN"
* @return NSString service class
*/
-
(
NSString
*
)
serviceClass
{
return
@""
;
}
/*!
* @brief Human readable short description
*
* Human readable, short description of this service
* This value is used in tooltips and the message window.
* Examples: "Jabber", "MSN", "AIM", ".Mac"
* @return NSString short description
*/
-
(
NSString
*
)
shortDescription
{
return
@""
;
}
/*!
* @brief Human readable long description
*
* Human readable, long description of this service
* If there are multiple classes available for the same service, this description should briefly show the difference
* between the implementations. This value is used in the account preferences service menu.
* Examples: "Jabber", "MSN", "AOL Instant Messenger", ".Mac"
* @return NSString long description
*/
-
(
NSString
*
)
longDescription
{
return
@""
;
}
/*!
* @brief Label for user name (general)
*
* String to use for describing the UID/username of this service. This value varies by service, but should be something
* along the lines of "User name", "Account name", "Screen name", "Member name", etc.
*
* This will be used for the account preferences to indicate the field for the account's user name. By default, contactUserNameLabel
* will return this value, as well.
*
* @return NSString label for username
*/
-
(
NSString
*
)
userNameLabel
{
return
AILocalizedStringFromTableInBundle
(
@"User Name"
,
nil
,
[
NSBundle
bundleForClass
:
[
AIService
class
]],
nil
);
}
/*!
* @brief Label for user name
*
* String to use for describing the UID/username of contacts for this service. This value varies by service, but should be something
* along the lines of "User name", "Account name", "Screen name", "Member name", etc.
*
* By default, this returns -[self userNameLabel]; only override this method if contacts are named differently than own-account usernames.
*
* @return NSString label for username
*/
-
(
NSString
*
)
contactUserNameLabel
{
return
[
self
userNameLabel
];
}
/*!
* @brief Placeholder string for the UID field
*/
-
(
NSString
*
)
UIDPlaceholder
{
return
@""
;
}
/*!
* @brief Service importance
*
* Importance grouping of this service. Used to make service listings and menus more organized by placing more important
* services at the top of lists or displaying them with more visibility.
* @return AIServiceImportance importance of this service
*/
-
(
AIServiceImportance
)
serviceImportance
{
return
AIServiceUnsupported
;
}
/*!
* @brief Default icon
*
* Service Icon packs should always include images for all the built-in Adium services. This method allows external
* service plugins to specify an image which will be used when the service icon pack does not specify one. It will
* also be useful if new services are added to Adium itself after a significant number of Service Icon packs exist
* which do not yet have an image for this service. If the active Service Icon pack provides an image for this service,
* this method will not be called.
*
* The service should _not_ cache this icon internally; multiple calls should return unique NSImage objects.
*
* @param iconType The AIServiceIconType of the icon to return. This specifies the desired size of the icon.
* @return NSImage to use for this service by default
*/
-
(
NSImage
*
)
defaultServiceIconOfType:
(
AIServiceIconType
)
iconType
{
return
nil
;
}
/*!
* @brief Path for default icon
*
* For use in message views, this is the path to a default icon as described above.
*
* @param iconType The AIServiceIconType of the icon to return.
* @return The path to the image, otherwise nil.
*/
-
(
NSString
*
)
pathForDefaultServiceIconOfType:
(
AIServiceIconType
)
iconType
{
return
nil
;
}
//Service Properties ---------------------------------------------------------------------------------------------------
#pragma mark Service Properties
/*!
* @brief Allowed characters
*
* Characters allowed in user names on this service. The user will not be allowed to type any characters not in this
* set as a contact or account name.
* @return NSCharacterSet of allowed characters
*/
-
(
NSCharacterSet
*
)
allowedCharacters
{
return
[[
NSCharacterSet
illegalCharacterSet
]
invertedSet
];
}
/*!
* @brief Allowed characters for our account name
*
* Offers further distinction of allowed characters, for situations where certain characters are allowed
* for our account name only, or characters which are allowed in user names are forbidden in our own account name.
* If this distinction is not made, do not subclass this methods and instead subclass allowedCharacters.
* @return NSCharacterSet of allowed characters
*/
-
(
NSCharacterSet
*
)
allowedCharactersForAccountName
{
return
([
self
allowedCharacters
]);
}
/*!
* @brief Allowed characters for UIDs
*
* Offers further distinction of allowed characters, for situations where certain characters are allowed
* for our account name only, or characters which are allowed in user names are forbidden in our own account name.
* If this distinction is not made, do not subclass this methods and instead subclass allowedCharacters.
*
* @return NSCharacterSet of allowed characters, or nil if all characters are allowed
*/
-
(
NSCharacterSet
*
)
allowedCharactersForUIDs
{
return
[
self
allowedCharacters
];
}
/*!
* @brief Ignored characters
*
* Ignored characters for user names on this service. Ignored characters are stripped from account and contact names
* before they are used, but the user is free to type them and they may be used by the service code. For instance,
* spaces are allowed in AIM usernames, but "ad am" is treated as equal to "adam" because space is an ignored character.
*
* @return NSCharacterSet of ignored characters, or nil if no characters are ignored
*/
-
(
NSCharacterSet
*
)
ignoredCharacters
{
return
nil
;
}
/*!
* @brief Allowed name length
*
* Max allowed length of user names of this service. Account and contact names longer than this will not be allowed.
* @return Max name length
*/
-
(
NSUInteger
)
allowedLength
{
return
NSUIntegerMax
;
}
/*!
* @brief Allowed account name length
*
* Offers further distinction of allowed name length, for situations where our account name has a different
* length restriction than the names of our contacts. If this distinction is not made, do not subclass these methods
* and instead subclass allowedLength.
* @return Max name length
*/
-
(
NSUInteger
)
allowedLengthForAccountName
{
return
[
self
allowedLength
];
}
/*!
* @brief Allowed UID length
*
* Offers further distinction of allowed name length, for situations where our account name has a different
* length restriction than the names of our contacts. If this distinction is not made, do not subclass these methods
* and instead subclass allowedLength.
* @return Max name length
*/
-
(
NSUInteger
)
allowedLengthForUIDs
{
return
[
self
allowedLength
];
}
/*!
* @brief Case sensitivity of names
*
* Determines if usernames such as "Adam" and "adam" are unique.
* @return Case sensitivity
*/
-
(
BOOL
)
caseSensitive
{
return
NO
;
}
/*!
* @brief Can create group chats?
*
* Does this service support group chats (Also known as multi-user chats, chat rooms, conferences, etc)? Services
* which do not support group chats are automatically excluded from the group chat interface elements.
* @return Can create group chats
*/
-
(
BOOL
)
canCreateGroupChats
{
return
NO
;
}
/*!
* @brief Can register accounts?
*
* Does this service support registering new accounts from within Adium? This is here for Jabber.
* @return Can register accounts
*/
-
(
BOOL
)
canRegisterNewAccounts
{
return
NO
;
}
/*!
* @brief Supports proxy settings?
*
* Does this service support connecting via a proxy?
* @return Supports proxy settings
*/
-
(
BOOL
)
supportsProxySettings
{
return
YES
;
}
/*!
* @brief Supports password
*
* Subclasses should return NO if this service does not use passwords at all for connectivity.
* If NO, all fields related to passwords will be hidden for this service and the user will never be prompted to
* enter passwords.
*/
-
(
BOOL
)
supportsPassword
{
return
YES
;
}
/*!
* @brief Requires Password
*
* Subclasses should return NO if this service does not require a password. Returning NO from this method will use the password if
* entered but allow a conection to be initiated with no password without prompting for one.
* If YES, Adium will insist upon a password being entered before a connection can begin.
*
* By default, the service requires a password if it is supported. See -[AIService supportsPassword].
*/
-
(
BOOL
)
requiresPassword
{
return
[
self
supportsPassword
];
}
/*!
* @brief Register statuses
*
* Called automatically. Services should register any supported status with the statusController.
*/
-
(
void
)
registerStatuses
{};
/*!
* @brief Default user name
*
* The default user name for a service is set for all new accounts. As it's not
* possible to guess the user name for most service types (AIM, MSN, etc.), the
* base class returns @"".
*
* @return The default user name for this service, or @"" for no default
*/
-
(
NSString
*
)
defaultUserName
{
return
@""
;
}
/*!
* @brief Is this a social networking service like Twitter or Facebook?
*
* If YES, accounts on this service treat status very differently than non-social-networking accounts.
* For example, global status messages dont apply to social networking services, and their status is handled uniquely.
*/
-
(
BOOL
)
isSocialNetworkingService
{
return
NO
;
}
/*!
* @brief Is this service hidden?
*
* If YES, it will not appear in service dropdowns.
* This is useful for allowing a legacy service to stick around seamlessly.
*/
-
(
BOOL
)
isHidden
{
return
NO
;
}
//Utilities ------------------------------------------------------------------------------------------------------------
#pragma mark Utilities
/*!
* @brief Normalize a UID
*
* Normalizes a UID. All invalid characters and ignored characters are removed.
* UID's are ONLY filtered when creating contacts, and when renaming contacts.
* - When changing ownership of a contact, a filter is not necessary, since all the accounts should have the same service
* types and requirements.
* - When account code retrieves contacts from the contact list, filtering is NOT done. It is up to the account to
* ensure it passes UIDs in the proper format for its service type.
* - Filter UIDs only when the user has entered or mucked with them in some way... UID's TO and FROM account code
* SHOULD ALWAYS BE VALID.
* @return NSString filtered UID
*/
-
(
NSString
*
)
normalizeUID:
(
NSString
*
)
inUID
removeIgnoredCharacters:
(
BOOL
)
removeIgnored
{
NSString
*
workingString
=
([
self
caseSensitive
]
?
inUID
:
[
inUID
lowercaseString
]);
NSCharacterSet
*
allowedCharacters
=
[
self
allowedCharactersForUIDs
];
NSCharacterSet
*
ignoredCharacters
=
[
self
ignoredCharacters
];
/* If all characters are allowed, and we're either not removing ignored characters OR there are none, no change
* needed. */
if
(
!
allowedCharacters
&&
(
!
removeIgnored
||
!
ignoredCharacters
))
return
[[
inUID
copy
]
autorelease
];
//Prepare a little buffer for our filtered UID
NSUInteger
destLength
=
0
;
NSUInteger
workingStringLength
=
[
workingString
length
];
unichar
*
dest
=
malloc
(
workingStringLength
*
sizeof
(
unichar
));
//Filter the UID
unsigned
pos
;
for
(
pos
=
0
;
pos
<
workingStringLength
;
pos
++
)
{
unichar
c
=
[
workingString
characterAtIndex
:
pos
];
if
([
allowedCharacters
characterIsMember
:
c
]
&&
(
!
removeIgnored
||
!
[
ignoredCharacters
characterIsMember
:
c
]))
{
dest
[
destLength
]
=
(
removeIgnored
?
c
:
[
inUID
characterAtIndex
:
pos
]);
destLength
++
;
}
}
//Turn it back into a string and return
NSString
*
filteredString
=
[
NSString
stringWithCharacters
:
dest
length
:
destLength
];
free
(
dest
);
return
filteredString
;
}
/*!
* @brief Normalize a chat name
*
* The default implementation only lowercases the name.
*/
-
(
NSString
*
)
normalizeChatName:
(
NSString
*
)
inChatName
{
return
[
inChatName
lowercaseString
];
}
/*!
* @brief Compare this service to another, ranking by long description
*/
-
(
NSComparisonResult
)
compareLongDescription:
(
AIService
*
)
inService
{
return
[[
self
longDescription
]
compare
:
[
inService
longDescription
]];
}
-
(
NSString
*
)
description
{
return
[
NSString
stringWithFormat
:
@"<%@: serviceCodeUniqueID = %@; serviceID = %@; serviceClass = %@; longDescription = %@>"
,
NSStringFromClass
([
self
class
]),
self
.
serviceCodeUniqueID
,
self
.
serviceID
,
self
.
serviceClass
,
self
.
longDescription
];
}
#pragma mark AppleScript
/**
* @brief Returns a list of all accounts that use this service.
*/
-
(
NSArray
*
)
accounts
{
NSMutableArray
*
accountsForThisService
=
[[[
NSMutableArray
alloc
]
init
]
autorelease
];
for
(
AIAccount
*
account
in
adium
.
accountController
.
accounts
)
{
if
(
account
.
service
==
self
)
[
accountsForThisService
addObject
:
account
];
}
return
accountsForThisService
;
}
/**
* @brief This class is specified using the 'services' key of AIApplication
*/
-
(
NSScriptObjectSpecifier
*
)
objectSpecifier
{
NSScriptClassDescription
*
containerClassDesc
=
(
NSScriptClassDescription
*
)[
NSScriptClassDescription
classDescriptionForClass
:
[
NSApp
class
]];
return
[[[
NSNameSpecifier
alloc
]
initWithContainerClassDescription
:
containerClassDesc
containerSpecifier
:
nil
key
:
@"services"
name
:
self
.
serviceID
]
autorelease
];
}
-
(
NSData
*
)
image
{
return
[[
AIServiceIcons
serviceIconForService
:
self
type
:
AIServiceIconLarge
direction
:
AIIconNormal
]
TIFFRepresentation
];
}
@end