Prevent sending 0-byte files. Fixes #8711.
[adiumx.git] / Source / CBActionSupportPlugin.m
blob6177956602438f9eb565d925a408fac6fc311695
1 /* 
2  * Adium is the legal property of its developers, whose names are listed in the copyright file included
3  * with this source distribution.
4  * 
5  * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
6  * General Public License as published by the Free Software Foundation; either version 2 of the License,
7  * or (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
10  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
11  * Public License for more details.
12  * 
13  * You should have received a copy of the GNU General Public License along with this program; if not,
14  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
15  */
17 #import <Adium/AIContentControllerProtocol.h>
18 #import "CBActionSupportPlugin.h"
19 #import <Adium/AIInterfaceControllerProtocol.h>
20 #import <Adium/AIChat.h>
21 #import <Adium/AIAccount.h>
23 /*!
24  * @class CBActionSupportPlugin
25  * @brief Simple content filter to turn "/me blah" into "*blah*"
26  */
27 @implementation CBActionSupportPlugin
29 /*!
30  * @brief Install
31  */
32 - (void)installPlugin
34         [[adium contentController] registerContentFilter:self ofType:AIFilterContent direction:AIFilterOutgoing];
35         [[adium contentController] registerContentFilter:self ofType:AIFilterContent direction:AIFilterIncoming];
38 - (void)uninstallPlugin
40         [[adium contentController] unregisterContentFilter:self];
43 #pragma mark -
45 - (BOOL)includesDisplayNameInReplacement
47         return includesDisplayName;
49 - (void)setIncludesDisplayNameInReplacement:(BOOL)flag
51         includesDisplayName = YES;
54 #pragma mark -
56 /*!
57  * @brief Filter
58  */
59 - (NSAttributedString *)filterAttributedString:(NSAttributedString *)inAttributedString context:(id)context
61         NSMutableAttributedString   *ourMessage = nil;
62         
63         if (inAttributedString && 
64                 [inAttributedString length] &&
65                 [[inAttributedString string] rangeOfString:@"/me"
66                                                                                    options:NSLiteralSearch
67                                                                                          range:NSMakeRange(0, [inAttributedString length])].location != NSNotFound) {
68                 NSMutableString *str;
69                 NSString                *startReplacement = @"*", *endReplacement = @"*";
70                 NSRange                 extent;
71                 unsigned                replacementLength;
72                 
73                 ourMessage = [[inAttributedString mutableCopyWithZone:[inAttributedString zone]] autorelease];
74                 str = [ourMessage mutableString];
76                 if (includesDisplayName) {
77                         startReplacement = [startReplacement stringByAppendingString:[[[[[adium interfaceController] activeChat] account] displayName] stringByAppendingString:@" "]];
78                         endReplacement = @"";
79                 }
80                 replacementLength = [startReplacement length] + [endReplacement length];
82                 extent = NSMakeRange(0, [str length]);
83                 do { //while (extent.length)
84                         NSRange lineRange, searchRange, meRange;
85                         signed shift = 0;
86                         unsigned endInsertPoint;
87                         
88                         lineRange = NSMakeRange(extent.location, 1);
89                         endInsertPoint = 0;
90                         [str getLineStart:&lineRange.location
91                                       end:&lineRange.length
92                               contentsEnd:&endInsertPoint
93                                  forRange:lineRange];
94                         lineRange.length -= lineRange.location;
95                         
96                         searchRange = NSMakeRange(lineRange.location, endInsertPoint - lineRange.location);
97                         meRange = [str rangeOfString:@"/me " options:(NSLiteralSearch | NSCaseInsensitiveSearch) range:searchRange];
98                         
99                         if (meRange.location == lineRange.location && meRange.length == 4) {
100                                 NSAttributedString *endSplat = [[NSAttributedString alloc] initWithString:endReplacement 
101                                                                                                                                                         attributes:[ourMessage attributesAtIndex:endInsertPoint-1
102                                                                                                                                                                                                           effectiveRange:nil]];
103                                 [ourMessage insertAttributedString:endSplat atIndex:endInsertPoint];
104                                 [endSplat release];
106                                 [ourMessage replaceCharactersInRange:meRange withString:startReplacement];
108                                 shift = meRange.length - replacementLength;
109                         }
110                         
111                         shift += lineRange.length;
112                         if (shift > extent.length) shift = extent.length;
113                         extent.location += shift;
114                         extent.length   -= shift;
115                 } while (extent.length);
116         }
117         
118         return (ourMessage ? ourMessage : inAttributedString);
122  * @brief Filter priority
123  */
124 - (float)filterPriority
126         return DEFAULT_FILTER_PRIORITY;
129 @end