5 // Created by Erik Beerepoot on 19/07/07.
6 // Copyright 2007 Adium Team. All rights reserved.
9 #import "AIListBookmark.h"
10 #import <Adium/AIAccountControllerProtocol.h>
11 #import <Adium/AIInterfaceControllerProtocol.h>
12 #import <Adium/AIChatControllerProtocol.h>
13 #import <Adium/AIContactControllerProtocol.h>
14 #import <Adium/AIUserIcons.h>
15 #import <Adium/AIService.h>
16 #import <Adium/AIChat.h>
18 #warning Wrong file location
20 #define KEY_CONTAINING_OBJECT_ID @"ContainingObjectInternalObjectID"
21 #define OBJECT_STATUS_CACHE @"Object Status Cache"
23 #define KEY_ACCOUNT_INTERNAL_ID @"AccountInternalObjectID"
25 @interface AIListBookmark (PRIVATE)
26 - (void)restoreGrouping;
29 @implementation AIListBookmark
30 - (void)_initListBookmark
32 [[self account] addObserver:self
34 options:NSKeyValueObservingOptionNew
36 [self observeValueForKeyPath:@"Online" ofObject:[self account] change:nil context:NULL];
39 -(id)initWithChat:(AIChat *)inChat
41 if ((self = [self initWithUID:[NSString stringWithFormat:@"Bookmark:%@",[inChat uniqueChatID]]
42 account:[inChat account]
43 service:[[inChat account] service]])) {
44 chatCreationDictionary = [[inChat chatCreationDictionary] copy];
45 name = [[inChat name] copy];
46 [self _initListBookmark];
47 AILog(@"Created AIListBookmark %@", self);
52 - (id)initWithCoder:(NSCoder *)decoder
54 //Be sure to use [AIObject sharedAdiumInstance] rather than the adium ivar since that isn't set until super's init is called.
55 AIAccount *myAccount = [[[AIObject sharedAdiumInstance] accountController] accountWithInternalObjectID:[decoder decodeObjectForKey:KEY_ACCOUNT_INTERNAL_ID]];
61 if ((self = [self initWithUID:[decoder decodeObjectForKey:@"UID"]
63 service:[[[AIObject sharedAdiumInstance] accountController] firstServiceWithServiceID:[decoder decodeObjectForKey:@"ServiceID"]]])) {
64 chatCreationDictionary = [[decoder decodeObjectForKey:@"chatCreationDictionary"] retain];
65 name = [[decoder decodeObjectForKey:@"name"] retain];
66 [self _initListBookmark];
67 AILog(@"Created AIListBookmark from coder with dict %@",chatCreationDictionary);
68 [self restoreGrouping];
75 - (void)encodeWithCoder:(NSCoder *)encoder
77 [encoder encodeObject:[self UID] forKey:@"UID"];
78 [encoder encodeObject:[[self account] internalObjectID] forKey:KEY_ACCOUNT_INTERNAL_ID];
79 [encoder encodeObject:[[self service] serviceID] forKey:@"ServiceID"];
80 [encoder encodeObject:[self chatCreationDictionary] forKey:@"chatCreationDictionary"];
81 [encoder encodeObject:name forKey:@"name"];
86 [[self account] removeObserver:self forKeyPath:@"Online"];
90 - (NSString *)formattedUID
92 //XXX should query chat for its name if we're in it
96 - (NSDictionary *)chatCreationDictionary
98 return chatCreationDictionary;
106 //XXX how to handle passwords
112 -(void)setPassword:(NSString*)newPassword
114 if(password != newPassword) {
116 password = [newPassword retain];
120 //When called, cache the internalObjectID of the new group so we can restore it immediately next time.
121 - (void)setContainingObject:(AIListObject <AIContainingObject> *)inGroup
123 NSString *inGroupInternalObjectID = [inGroup internalObjectID];
125 //Save the change of containing object so it can be restored on launch next time if we are using groups.
126 //We don't save if we are not using groups as this set will be for the contact list root and probably not desired permanently.
127 if ([[adium contactController] useContactListGroups] &&
128 inGroupInternalObjectID &&
129 ![inGroupInternalObjectID isEqualToString:[self preferenceForKey:KEY_CONTAINING_OBJECT_ID
130 group:OBJECT_STATUS_CACHE
131 ignoreInheritedValues:YES]] &&
132 (inGroup != [[adium contactController] offlineGroup])) {
133 [self setPreference:inGroupInternalObjectID
134 forKey:KEY_CONTAINING_OBJECT_ID
135 group:OBJECT_STATUS_CACHE];
138 [super setContainingObject:inGroup];
142 * @brief Restore the AIListGroup grouping into which this object was last manually placed
144 - (void)restoreGrouping
146 AIListGroup *targetGroup = nil;
148 if ([[adium contactController] useContactListGroups]) {
149 NSString *oldContainingObjectID;
150 AIListObject *oldContainingObject;
152 oldContainingObjectID = [self preferenceForKey:KEY_CONTAINING_OBJECT_ID
153 group:OBJECT_STATUS_CACHE];
154 //Get the group's UID out of the internal object ID by taking the substring after "Group."
155 oldContainingObject = ((oldContainingObjectID && [oldContainingObjectID hasPrefix:@"Group."]) ?
156 [[adium contactController] groupWithUID:[oldContainingObjectID substringFromIndex:6]] :
159 if (oldContainingObject &&
160 [oldContainingObject isKindOfClass:[AIListGroup class]] &&
161 oldContainingObject != [[adium contactController] contactList]) {
162 //A previous grouping (to a non-root group) is saved; restore it
163 targetGroup = (AIListGroup *)oldContainingObject;
167 [[adium contactController] _moveContactLocally:self
168 toGroup:(targetGroup ? targetGroup : [[adium contactController] contactList])];
173 AIChat *chat = [[adium chatController] existingChatWithName:[self name]
174 onAccount:[self account]];
175 if (chat && [[chat chatCreationDictionary] isEqualToDictionary:
176 [self chatCreationDictionary]]) {
177 //An existing open chat matches this bookmark. Switch to it!
178 [[adium interfaceController] setActiveChat:chat];
181 //Open a new group chat (bookmarked chat)
182 [[adium chatController] chatWithName:[self name]
184 onAccount:[self account]
185 chatCreationInfo:[self chatCreationDictionary]];
190 * @brief Can this object be part of a metacontact?
192 * It makes no sense for a bookmark to be in a metacontact, I think.
194 - (BOOL)canJoinMetaContacts
200 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
202 if ([keyPath isEqualToString:@"Online"] && (object == [self account])) {
203 BOOL online = [[self account] online];
204 [self setVisible:online];
205 [self setOnline:online notify:NotifyNow silently:YES];
210 - (NSString *)description
212 return [NSString stringWithFormat:@"<%@:%x %@ - %@ on %@>",NSStringFromClass([self class]), self, [self formattedUID], [self chatCreationDictionary], [self account]];