William Bowling is sharing code with you
Bitbucket is a code hosting site. Unlimited public and private repositories. Free for small teams.
Don't show this again1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | /*
* 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 "AIExtendedStatusPlugin.h"
#import <Adium/AIContactControllerProtocol.h>
#import <Adium/AIContentControllerProtocol.h>
#import <AIUtilities/AIMutableOwnerArray.h>
#import <AIUtilities/AIAttributedStringAdditions.h>
#import <AIUtilities/AIMutableStringAdditions.h>
#import <AIUtilities/AIDateFormatterAdditions.h>
#import <Adium/AIAbstractListController.h>
#import <Adium/AIListObject.h>
#import <Adium/AIListContact.h>
#define STATUS_MAX_LENGTH 100
/*!
* @class AIExtendedStatusPlugin
* @brief Manage the 'extended status' shown in the contact list
*
* If the contact list layout calls for displaying a status message or idle time (or both), this component manages
* generating the appropriate string, storing it in the @"ExtendedStatus" property, and updating it as necessary.
*/
@implementation AIExtendedStatusPlugin
/*!
* @brief Install
*/
- (void)installPlugin
{
[adium.preferenceController registerPreferenceObserver:self forGroup:PREF_GROUP_LIST_LAYOUT];
whitespaceAndNewlineCharacterSet = [[NSCharacterSet whitespaceAndNewlineCharacterSet] retain];
}
/*!
* @brief Uninstall
*/
- (void)uninstallPlugin
{
[adium.preferenceController unregisterPreferenceObserver:self];
[[AIContactObserverManager sharedManager] unregisterListObjectObserver:self];
}
/*!
* @brief Preferences changes
*
* PREF_GROUP_LIST_LAYOUT changed; update our list objects if needed.
*/
- (void)preferencesChangedForGroup:(NSString *)group key:(NSString *)key
object:(AIListObject *)object preferenceDict:(NSDictionary *)prefDict firstTime:(BOOL)firstTime
{
BOOL oldShowStatus = showStatus;
BOOL oldShowIdle = showIdle;
BOOL oldIncludeIdleInExtendedStatus = includeIdleInExtendedStatus;
EXTENDED_STATUS_STYLE statusStyle = [[prefDict objectForKey:KEY_LIST_LAYOUT_EXTENDED_STATUS_STYLE] integerValue];
showStatus = ((statusStyle == STATUS_ONLY) || (statusStyle == IDLE_AND_STATUS));
showIdle = ((statusStyle == IDLE_ONLY) || (statusStyle == IDLE_AND_STATUS));
EXTENDED_STATUS_POSITION statusPosition = [[prefDict objectForKey:KEY_LIST_LAYOUT_EXTENDED_STATUS_POSITION] integerValue];
includeIdleInExtendedStatus = (statusPosition != EXTENDED_STATUS_POSITION_BOTH);
if (firstTime) {
[[AIContactObserverManager sharedManager] registerListObjectObserver:self];
} else {
if ((oldShowStatus != showStatus) ||
(oldShowIdle != showIdle) ||
(oldIncludeIdleInExtendedStatus != includeIdleInExtendedStatus)) {
[[AIContactObserverManager sharedManager] updateAllListObjectsForObserver:self];
}
}
}
/*!
* @brief Update list object's extended status messages
*/
- (NSSet *)updateListObject:(AIListObject *)inObject keys:(NSSet *)inModifiedKeys silent:(BOOL)silent
{
NSSet *modifiedAttributes = nil;
/* Work at the parent contact (metacontact, etc.) level for extended status, since that's what's displayed in the contact list.
* We completely ignore status updates sent for an object which isn't the highest-level up (e.g. is within a metacontact).
*/
if ((inModifiedKeys == nil ||
(showIdle && [inModifiedKeys containsObject:@"Idle"]) ||
(showStatus && ([inModifiedKeys containsObject:@"StatusMessage"] ||
[inModifiedKeys containsObject:@"StatusName"]))) &&
[inObject isKindOfClass:[AIListContact class]]){
NSMutableString *statusMessage = nil;
NSString *finalMessage = nil, *finalIdleReadable = nil;
NSInteger idle;
if (showStatus) {
NSAttributedString *filteredMessage;
filteredMessage = [adium.contentController filterAttributedString:[(AIListContact *)inObject contactListStatusMessage]
usingFilterType:AIFilterContactList
direction:AIFilterIncoming
context:inObject];
statusMessage = [[[[filteredMessage string] stringByTrimmingCharactersInSet:whitespaceAndNewlineCharacterSet] mutableCopy] autorelease];
//Incredibly long status messages are slow to size, so we crop them to a reasonable length
NSInteger statusMessageLength = [statusMessage length];
if (statusMessageLength == 0) {
statusMessage = nil;
} else if (statusMessageLength > STATUS_MAX_LENGTH) {
[statusMessage deleteCharactersInRange:NSMakeRange(STATUS_MAX_LENGTH,
[statusMessage length] - STATUS_MAX_LENGTH)];
}
/* Linebreaks in the status message cause vertical alignment issues. */
[statusMessage convertNewlinesToSlashes];
}
idle = (showIdle ? inObject.idleTime : 0);
//
NSString *idleString = ((idle > 0) ? [self idleStringForMinutes:idle] : nil);
if (idle > 0 && statusMessage) {
finalMessage = (includeIdleInExtendedStatus ?
[NSString stringWithFormat:@"(%@) %@",idleString, statusMessage] :
statusMessage);
finalIdleReadable = [NSString stringWithFormat:@"(%@)", idleString];
} else if (idle > 0) {
finalIdleReadable = [NSString stringWithFormat:@"(%@)",idleString];
finalMessage = (includeIdleInExtendedStatus ?
finalIdleReadable :
statusMessage);
} else {
finalMessage = statusMessage;
}
[inObject setValue:finalIdleReadable
forProperty:@"IdleReadable"
notify:NotifyNever];
[inObject setValue:finalMessage
forProperty:@"ExtendedStatus"
notify:NotifyNever];
modifiedAttributes = [NSSet setWithObject:@"ExtendedStatus"];
}
return modifiedAttributes;
}
/*!
* @brief Determine the idle string
*
* @param minutes Number of minutes idle
* @result A localized string to display for the idle time
*/
- (NSString *)idleStringForMinutes:(NSInteger)minutes //input is actualy minutes
{
// Cap Idletime at 599400 minutes (999 hours)
return ((minutes > 599400) ? AILocalizedString(@"Idle",nil) : [NSDateFormatter stringForApproximateTimeInterval:(minutes * 60) abbreviated:YES]);
}
@end
|