Transmission: update from 2.42 to 2.50
[tomato.git] / release / src / router / transmission / macosx / NSStringAdditions.m
blobe23a6bcaa419b691dce48b29353cff8137bf3118
1 /******************************************************************************
2  * $Id: NSStringAdditions.m 13162 2012-01-14 17:12:04Z livings124 $
3  *
4  * Copyright (c) 2005-2012 Transmission authors and contributors
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  *****************************************************************************/
25 #import "NSStringAdditions.h"
27 #import <transmission.h>
28 #import "utils.h"
30 @interface NSString (Private)
32 + (NSString *) stringForFileSize: (uint64_t) size showUnitUnless: (NSString *) notAllowedUnit
33     unitsUsed: (NSString **) unitUsed;
35 + (NSString *) stringForSpeed: (CGFloat) speed kb: (NSString *) kb mb: (NSString *) mb gb: (NSString *) gb;
37 @end
39 @implementation NSString (NSStringAdditions)
41 + (NSString *) ellipsis
43         return [NSString stringWithUTF8String: "\xE2\x80\xA6"];
46 - (NSString *) stringByAppendingEllipsis
48         return [self stringByAppendingString: [NSString ellipsis]];
51 + (NSString *) formattedUInteger: (NSUInteger) value
53     NSNumberFormatter * numberFormatter = [[[NSNumberFormatter alloc] init] autorelease];
54     [numberFormatter setNumberStyle: NSNumberFormatterDecimalStyle];
55     [numberFormatter setMaximumFractionDigits: 0];
56     
57     return [numberFormatter stringFromNumber: [NSNumber numberWithUnsignedInteger: value]];
60 + (NSString *) stringForFileSize: (uint64_t) size
62     return [self stringForFileSize: size showUnitUnless: nil unitsUsed: nil];
65 + (NSString *) stringForFilePartialSize: (uint64_t) partialSize fullSize: (uint64_t) fullSize
67     NSString * units;
68     NSString * fullString = [self stringForFileSize: fullSize showUnitUnless: nil unitsUsed: &units];
69     NSString * partialString = [self stringForFileSize: partialSize showUnitUnless: units unitsUsed: nil];
70     
71     return [NSString stringWithFormat: NSLocalizedString(@"%@ of %@", "file size string"), partialString, fullString];
74 + (NSString *) stringForSpeed: (CGFloat) speed
76     return [self stringForSpeed: speed
77                 kb: NSLocalizedString(@"KB/s", "Transfer speed (kilobytes per second)")
78                 mb: NSLocalizedString(@"MB/s", "Transfer speed (megabytes per second)")
79                 gb: NSLocalizedString(@"GB/s", "Transfer speed (gigabytes per second)")];
82 + (NSString *) stringForSpeedAbbrev: (CGFloat) speed
84     return [self stringForSpeed: speed kb: @"K" mb: @"M" gb: @"G"];
87 + (NSString *) stringForRatio: (CGFloat) ratio
89     //N/A is different than libtransmission's
90     if ((int)ratio == TR_RATIO_NA)
91         return NSLocalizedString(@"N/A", "No Ratio");
92     else if ((int)ratio == TR_RATIO_INF)
93         return [NSString stringWithUTF8String: "\xE2\x88\x9E"];
94     else
95     {
96         if (ratio < 10.0)
97             return [NSString localizedStringWithFormat: @"%.2f", tr_truncd(ratio, 2)];
98         else if (ratio < 100.0)
99             return [NSString localizedStringWithFormat: @"%.1f", tr_truncd(ratio, 1)];
100         else
101             return [NSString localizedStringWithFormat: @"%.0f", tr_truncd(ratio, 0)];
102     }
105 + (NSString *) percentString: (CGFloat) progress longDecimals: (BOOL) longDecimals
107     if (progress >= 1.0)
108         return @"100%";
109     else if (longDecimals)
110         return [NSString localizedStringWithFormat: @"%.2f%%", tr_truncd(progress * 100.0, 2)];
111     else
112         return [NSString localizedStringWithFormat: @"%.1f%%", tr_truncd(progress * 100.0, 1)];
115 + (NSString *) timeString: (uint64_t) seconds showSeconds: (BOOL) showSeconds
117     return [NSString timeString: seconds showSeconds: showSeconds maxFields: NSUIntegerMax];
120 + (NSString *) timeString: (uint64_t) seconds showSeconds: (BOOL) showSeconds maxFields: (NSUInteger) max
122     NSAssert(max > 0, @"Cannot generate a time string with no fields");
123     
124     NSMutableArray * timeArray = [NSMutableArray arrayWithCapacity: MIN(max, 5)];
125     NSUInteger remaining = seconds; //causes problems for some users when it's a uint64_t
126     
127     if (seconds >= 31557600) //official amount of seconds in one year
128     {
129         const NSUInteger years = remaining / 31557600;
130         if (years == 1)
131             [timeArray addObject: NSLocalizedString(@"1 year", "time string")];
132         else
133             [timeArray addObject: [NSString stringWithFormat: NSLocalizedString(@"%u years", "time string"), years]];
134         remaining %= 31557600;
135         --max;
136     }
137     if (max > 0 && seconds >= (24 * 60 * 60))
138     {
139         const NSUInteger days = remaining / (24 * 60 * 60);
140         if (days == 1)
141             [timeArray addObject: NSLocalizedString(@"1 day", "time string")];
142         else
143             [timeArray addObject: [NSString stringWithFormat: NSLocalizedString(@"%u days", "time string"), days]];
144         remaining %= (24 * 60 * 60);
145         --max;
146     }
147     if (max > 0 && seconds >= (60 * 60))
148     {
149         [timeArray addObject: [NSString stringWithFormat: NSLocalizedString(@"%u hr", "time string"), remaining / (60 * 60)]];
150         remaining %= (60 * 60);
151         --max;
152     }
153     if (max > 0 && (!showSeconds || seconds >= 60))
154     {
155         [timeArray addObject: [NSString stringWithFormat: NSLocalizedString(@"%u min", "time string"), remaining / 60]];
156         remaining %= 60;
157         --max;
158     }
159     if (max > 0 && showSeconds)
160         [timeArray addObject: [NSString stringWithFormat: NSLocalizedString(@"%u sec", "time string"), remaining]];
161     
162     return [timeArray componentsJoinedByString: @" "];
165 - (NSComparisonResult) compareNumeric: (NSString *) string
167     const NSStringCompareOptions comparisonOptions = NSNumericSearch | NSForcedOrderingSearch;
168     return [self compare: string options: comparisonOptions range: NSMakeRange(0, [self length]) locale: [NSLocale currentLocale]];
171 - (NSArray *) betterComponentsSeparatedByCharactersInSet: (NSCharacterSet *) separator
173     NSMutableArray * components = [NSMutableArray array];
174     
175     NSUInteger i = 0;
176     while (i < [self length])
177     {
178         const NSRange range = [self rangeOfCharacterFromSet: separator options: 0 range: NSMakeRange(i, [self length]-i)];
179         
180         if (range.location == NSNotFound)
181         {
182             [components addObject: [self substringFromIndex: i]];
183             break;
184         }
185         else if (range.location != i)
186         {
187             const NSUInteger length = range.location - i;
188             [components addObject: [self substringWithRange: NSMakeRange(i, length)]];
189             
190             i += length;
191         }
192         
193         i += range.length;
194     }
195     
196     return components;
199 @end
201 @implementation NSString (Private)
203 + (NSString *) stringForFileSize: (uint64_t) size showUnitUnless: (NSString *) notAllowedUnit
204     unitsUsed: (NSString **) unitUsed
206     double convertedSize;
207     NSString * unit;
208     NSUInteger decimals;
209     if (size < pow(1000, 2))
210     {
211         convertedSize = size / 1000.0;
212         unit = NSLocalizedString(@"KB", "File size - kilobytes");
213         decimals = convertedSize >= 10.0 ? 0 : 1;
214     }
215     else if (size < pow(1000, 3))
216     {
217         convertedSize = size / powf(1000.0, 2);
218         unit = NSLocalizedString(@"MB", "File size - megabytes");
219         decimals = 1;
220     }
221     else if (size < pow(1000, 4))
222     {
223         convertedSize = size / powf(1000.0, 3);
224         unit = NSLocalizedString(@"GB", "File size - gigabytes");
225         decimals = 2;
226     }
227     else
228     {
229         convertedSize = size / powf(1000.0, 4);
230         unit = NSLocalizedString(@"TB", "File size - terabytes");
231         decimals = 3; //guessing on this one
232     }
233     
234     //match Finder's behavior
235     NSNumberFormatter * numberFormatter = [[NSNumberFormatter alloc] init];
236     [numberFormatter setNumberStyle: NSNumberFormatterDecimalStyle];
237     [numberFormatter setMinimumFractionDigits: 0];
238     [numberFormatter setMaximumFractionDigits: decimals];
239     
240     NSString * fileSizeString = [numberFormatter stringFromNumber: [NSNumber numberWithFloat: convertedSize]];
241     [numberFormatter release];
242     
243     if (!notAllowedUnit || ![unit isEqualToString: notAllowedUnit])
244         fileSizeString = [fileSizeString stringByAppendingFormat: @" %@", unit];
245     
246     if (unitUsed)
247         *unitUsed = unit;
248     
249     return fileSizeString;
252 + (NSString *) stringForSpeed: (CGFloat) speed kb: (NSString *) kb mb: (NSString *) mb gb: (NSString *) gb
254     if (speed <= 999.95) //0.0 KB/s to 999.9 KB/s
255         return [NSString localizedStringWithFormat: @"%.1f %@", speed, kb];
256     
257     speed /= 1000.0;
258     
259     if (speed <= 99.995) //1.00 MB/s to 99.99 MB/s
260         return [NSString localizedStringWithFormat: @"%.2f %@", speed, mb];
261     else if (speed <= 999.95) //100.0 MB/s to 999.9 MB/s
262         return [NSString localizedStringWithFormat: @"%.1f %@", speed, mb];
263     else //insane speeds
264         return [NSString localizedStringWithFormat: @"%.2f %@", (speed / 1000.0), gb];
267 @end