Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /XspfManager/XspfMRule.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 164 - (hide annotations) (download)
Sun Dec 20 00:41:35 2009 UTC (14 years, 4 months ago) by masaki
Original Path: XspfManager/XspfMRuleEditorRow.m
File size: 16294 byte(s)
[Mod] XspfMRuleをNSCodingに準拠。
1 masaki 120 //
2     // XspfMRuleEditorRow.m
3     // XspfManager
4     //
5     // Created by Hori,Masaki on 09/11/29.
6     // Copyright 2009 masakih. All rights reserved.
7     //
8    
9     #import "XspfMRuleEditorRow.h"
10    
11 masaki 143 @implementation XspfMCompound
12     - (NSInteger)numberOfChildrenForChild:(id)child
13 masaki 120 {
14 masaki 143 if(!child) return 2;
15     if([child isEqualToString:@"All"] || [child isEqualToString:@"Any"]) return 1;
16     return 0;
17 masaki 120 }
18 masaki 143 - (id)childForChild:(id)child atIndex:(NSInteger)index
19 masaki 120 {
20 masaki 143 if(!child) {
21     if(index == 0) return @"All";
22     if(index == 1) return @"Any";
23     }
24     return @"of the following are true";
25 masaki 120 }
26 masaki 143 - (id)displayValueForChild:(id)child
27 masaki 120 {
28 masaki 143 return child;
29 masaki 120 }
30 masaki 143 - (NSDictionary *)predicateForChild:(id)child withDisplayValue:(id)value
31 masaki 122 {
32 masaki 143 NSDictionary *result = nil;
33 masaki 122
34 masaki 143 NSUInteger type = 9999;
35     if([child isEqualToString:@"All"]) {
36     type = NSAndPredicateType;
37     } else if([child isEqualToString:@"Any"]) {
38     type = NSOrPredicateType;
39     }
40     if(type < 10) {
41     result = [NSDictionary dictionaryWithObject:[NSNumber numberWithUnsignedInt:type]
42     forKey:NSRuleEditorPredicateCompoundType];
43     }
44    
45     return result;
46 masaki 122 }
47 masaki 120 @end
48    
49 masaki 152
50     @interface XspfMRule (XspfMAccessor)
51     - (void)setChildren:(NSArray *)newChildren;
52     - (void)addChild:(XspfMRule *)child;
53     - (void)setPredicateParts:(NSDictionary *)parts;
54     - (void)setExpression:(id)expression forKey:(id)key;
55     - (void)setValue:(NSString *)newValue;
56     @end
57    
58     @interface XspfMRule (XspfMExpressionBuilder)
59     @end
60    
61     @implementation XspfMRule (XspfMAccessor)
62     - (void)setChildren:(NSArray *)newChildren
63 masaki 120 {
64 masaki 158 if(!newChildren) newChildren = [NSMutableArray array];
65 masaki 152
66     [children autorelease];
67 masaki 158 children = [[NSMutableArray alloc] initWithArray:newChildren copyItems:YES];
68 masaki 120 }
69 masaki 152 - (void)addChild:(XspfMRule *)child
70     {
71     [children addObject:child];
72     }
73     - (void)setPredicateParts:(NSDictionary *)parts
74     {
75     [predicateHints autorelease];
76     predicateHints = [parts mutableCopy];
77     }
78     - (void)setExpression:(id)expression forKey:(id)key
79     {
80     [predicateHints setObject:expression forKey:key];
81     }
82     - (void)setValue:(NSString *)newValue
83     {
84 masaki 153 if([_value isEqualToString:newValue]) return;
85 masaki 152
86 masaki 153 [_value autorelease];
87     _value = [newValue copy];
88 masaki 152 }
89 masaki 153 - (NSString *)value { return _value; }
90 masaki 143 @end
91 masaki 152
92     @implementation XspfMRule
93     @dynamic value;
94    
95     - (NSInteger)numberOfChildren
96 masaki 120 {
97 masaki 152 return [children count];
98 masaki 120 }
99 masaki 152 - (id)childAtIndex:(NSInteger)index
100 masaki 120 {
101 masaki 152 return [children objectAtIndex:index];
102     }
103     - (id)displayValueForRuleEditor:(NSRuleEditor *)ruleEditor inRow:(NSInteger)row
104     {
105 masaki 153 return _value;
106 masaki 152 }
107     - (NSDictionary *)predicatePartsWithDisplayValue:(id)displayValue forRuleEditor:(NSRuleEditor *)ruleEditor inRow:(NSInteger)row
108     {
109     id result = [NSMutableDictionary dictionary];
110 masaki 142
111 masaki 152 NSRuleEditorRowType rowType = [ruleEditor rowTypeForRow:row];
112     if(rowType == NSRuleEditorRowTypeCompound) {
113     return predicateHints;
114     }
115    
116     if([predicateHints valueForKey:@"XspfMIgnoreExpression"]) return nil;
117    
118     id operatorType = [predicateHints valueForKey:@"NSRuleEditorPredicateOperatorType"];
119     id option = [predicateHints valueForKey:@"NSRuleEditorPredicateOptions"];
120     id leftExp = [predicateHints valueForKey:@"NSRuleEditorPredicateLeftExpression"];
121     id rightExp = [predicateHints valueForKey:@"NSRuleEditorPredicateRightExpression"];
122     id customRightExp = [predicateHints valueForKey:@"XspfMPredicateRightExpression"];
123    
124     if(operatorType) {
125     [result setValue:operatorType forKey:NSRuleEditorPredicateOperatorType];
126     }
127     if(option) {
128     [result setValue:option forKey:NSRuleEditorPredicateOptions];
129     }
130     if(leftExp) {
131     id exp = nil;
132     if([leftExp isEqual:@"value"]) {
133     exp = [NSExpression expressionForKeyPath:displayValue];
134     } else {
135     exp = [NSExpression expressionForKeyPath:leftExp];
136     }
137     if(exp) {
138     [result setValue:exp forKey:NSRuleEditorPredicateLeftExpression];
139     }
140     }
141     if(rightExp) {
142     SEL selector = NSSelectorFromString(rightExp);
143     id exp = nil;
144     if(selector) {
145     exp = [NSExpression expressionForConstantValue:[displayValue performSelector:selector]];
146     } else {
147     exp = [NSExpression expressionForConstantValue:rightExp];
148     }
149     if(exp) {
150     [result setValue:exp forKey:NSRuleEditorPredicateRightExpression];
151     }
152     }
153     if(customRightExp) {
154     SEL selector = NSSelectorFromString(customRightExp);
155     id arg01 = [predicateHints valueForKey:@"XspfMRightExpressionArg01"];
156     id arg02 = [predicateHints valueForKey:@"XspfMRightExpressionArg02"];
157    
158    
159     if(arg02 && arg01) {
160     if([arg01 isEqual:@"displayValues"]) {
161     arg01 = [ruleEditor displayValuesForRow:row];
162     }
163     if([arg02 isEqual:@"displayValues"]) {
164     arg02 = [ruleEditor displayValuesForRow:row];
165     }
166 masaki 163 id rhs = [self performSelector:selector withObject:arg01 withObject:arg02];
167     [result setValue:rhs forKey:NSRuleEditorPredicateRightExpression];
168 masaki 152 } else if(arg01) {
169     if([arg01 isEqual:@"displayValues"]) {
170     arg01 = [ruleEditor displayValuesForRow:row];
171     }
172 masaki 163 id rhs = [self performSelector:selector withObject:arg01];
173     [result setValue:rhs forKey:NSRuleEditorPredicateRightExpression];
174 masaki 152 } else {
175 masaki 163 id rhs = [self performSelector:selector];
176     [result setValue:rhs forKey:NSRuleEditorPredicateRightExpression];
177 masaki 152 }
178     }
179    
180 masaki 163 NSString *selName = [predicateHints valueForKey:@"XspfMCustomSelector"];
181     if(selName) {
182 masaki 154 id args = nil;
183     NSString *argSelName = [predicateHints valueForKey:@"XspfMCustomSelectorArgumentsCteator"];
184     if(argSelName) {
185     SEL argSel = NSSelectorFromString(argSelName);
186     id argSelArg01 = [predicateHints valueForKey:@"XspfMCustomSelectorArgumentsCteatorArg01"];
187     if([argSelArg01 isEqual:@"displayValues"]) {
188     argSelArg01 = [ruleEditor displayValuesForRow:row];
189     }
190     id argSelArg02 = [predicateHints valueForKey:@"XspfMCustomSelectorArgumentsCteatorArg02"];
191     if([argSelArg02 isEqual:@"displayValues"]) {
192     argSelArg02 = [ruleEditor displayValuesForRow:row];
193     }
194     if(argSelArg02) {
195     args = [self performSelector:argSel withObject:argSelArg01 withObject:argSelArg02];
196     } else if(argSelArg01) {
197     args = [self performSelector:argSel withObject:argSelArg01];
198     } else {
199     args = [self performSelector:argSel];
200     }
201     } else {
202     id arg01 = [predicateHints valueForKey:@"XspfMCustomSelectorArg01"];
203     args = [NSArray arrayWithObjects:[NSExpression expressionForConstantValue:arg01], nil];
204     }
205 masaki 152
206     id exp03 = [NSExpression expressionForConstantValue:@"DATE_RANGE_CREATOR"];
207 masaki 154 id exp02 = [NSExpression expressionForFunction:exp03 selectorName:selName arguments:args];
208 masaki 152 [result setValue:exp02 forKey:@"NSRuleEditorPredicateRightExpression"];
209     }
210    
211     // NSLog(@"predicate\tcriterion -> %@, value -> %@, row -> %d, result -> %@", predicateHints, displayValue, row, result);
212    
213     return result;
214 masaki 142 }
215 masaki 152
216 masaki 153 - (id)displayValue { return _value; }
217 masaki 120
218 masaki 164 #pragma mark == NSCopying Protocol ==
219 masaki 152 - (id)copyWithZone:(NSZone *)zone
220 masaki 142 {
221 masaki 152 XspfMRule *result = [[[self class] allocWithZone:zone] init];
222 masaki 158 [result setChildren:children];
223     [result setPredicateParts:predicateHints];
224     [result setValue:_value];
225 masaki 152
226     return result;
227 masaki 142 }
228 masaki 152
229 masaki 164 #pragma mark == NSCoding Protocol ==
230     static NSString *const XspfMRuleChildrenKey = @"XspfMRuleChildrenKey";
231     static NSString *const XspfMRulePredicateHintsKey = @"XspfMRulePredicateHintsKey";
232     static NSString *const XspfMRuleValueKey = @"XspfMRuleValueKey";
233     - (id)initWithCoder:(NSCoder *)decoder
234     {
235     self = [self init];
236    
237     [self setChildren:[decoder decodeObjectForKey:XspfMRuleChildrenKey]];
238     [self setPredicateParts:[decoder decodeObjectForKey:XspfMRulePredicateHintsKey]];
239     [self setValue:[decoder decodeObjectForKey:XspfMRuleValueKey]];
240    
241     return self;
242     }
243     - (void)encodeWithCoder:(NSCoder *)encoder
244     {
245     [encoder encodeObject:children forKey:XspfMRuleChildrenKey];
246     [encoder encodeObject:predicateHints forKey:XspfMRulePredicateHintsKey];
247     [encoder encodeObject:_value forKey:XspfMRuleValueKey];
248     }
249    
250 masaki 152 - (BOOL)isEqual:(id)other
251 masaki 120 {
252 masaki 152 if([super isEqual:other]) return YES;
253     if(![other isKindOfClass:[XspfMRule class]]) return NO;
254 masaki 120
255 masaki 152 XspfMRule *o = other;
256 masaki 153 if(![_value isEqualToString:o->_value]) return NO;
257 masaki 152 // if(![children isEqual:o->children]) return NO;
258     // if(![predicateHints isEqual:o->predicateHints]) return NO;
259    
260 masaki 120 return YES;
261     }
262 masaki 152 - (NSUInteger)hash
263     {
264 masaki 153 return _value ? [_value hash] : [super hash];
265 masaki 152 }
266    
267 masaki 120 - (id)description
268     {
269 masaki 152 return [NSString stringWithFormat:@"%@ {\n\t%@ = %@;\n\t%@ = %@;\n\t%@ = %@;}",
270     NSStringFromClass([self class]),
271 masaki 153 @"value", _value,
272 masaki 152 @"hints", predicateHints,
273     @"children", children,
274     nil];
275 masaki 120 }
276     @end
277    
278 masaki 152 @implementation XspfMRule (XspfMCreation)
279 masaki 120
280 masaki 152 - (id)init
281 masaki 120 {
282 masaki 152 [super init];
283    
284     children = [[NSMutableArray array] retain];
285     predicateHints = [[NSMutableDictionary dictionary] retain];
286    
287     return self;
288 masaki 120 }
289 masaki 152
290     - (id)initWithValue:(NSString *)newValue children:(NSArray *)newChildren predicateHints:(NSDictionary *)parts
291 masaki 120 {
292 masaki 152 [self init];
293 masaki 120
294 masaki 152 if([newValue isEqualToString:@"separator"]) {
295     [self release];
296     return [[XspfMSeparatorRule alloc] initSparetorRule];
297     }
298    
299     NSInteger tag = XspfMDefaultTag;
300     XspfMFieldType type = XspfMUnknownType;
301     if([newValue hasPrefix:@"textField"]) {
302     type = XspfMTextFieldType;
303     } else if([newValue hasPrefix:@"dateField"]) {
304     type = XspfMDateFieldType;
305     if([newValue isEqualToString:@"dateField"]) {
306     tag = XspfMPrimaryDateFieldTag;
307     } else {
308     tag = XspfMSeconraryDateFieldTag;
309     }
310     } else if([newValue hasPrefix:@"rateField"]) {
311     type = XspfMRateFieldType;
312     } else if([newValue hasPrefix:@"numberField"]) {
313     type = XspfMNumberFieldType;
314     if([newValue isEqualToString:@"numberField"]) {
315     tag = XspfMPrimaryNumberFieldTag;
316     } else {
317     tag = XspfMSecondaryNumberFieldTag;
318     }
319     }
320     if(type != XspfMUnknownType) {
321     [self release];
322     self = [[XspfMFieldRule alloc] initWithFieldType:type tag:tag];
323     }
324    
325     [self setValue:newValue];
326     [self setChildren:newChildren];
327     [self setPredicateParts:parts];
328    
329 masaki 120 return self;
330     }
331 masaki 152 + (id)ruleWithValue:(NSString *)newValue children:(NSArray *)newChildren predicateHints:(NSDictionary *)parts
332 masaki 120 {
333 masaki 152 return [[[self alloc] initWithValue:newValue children:newChildren predicateHints:parts] autorelease];
334 masaki 120 }
335 masaki 152
336     + (NSArray *)compoundRule
337 masaki 120 {
338 masaki 152 id comp = [self ruleWithValue:@"of the following are true" children:nil predicateHints:[NSDictionary dictionary]];
339    
340     id allExp = [NSNumber numberWithUnsignedInt:NSAndPredicateType];
341     id all = [self ruleWithValue:@"All"
342     children:[NSArray arrayWithObject:comp]
343     predicateHints:[NSDictionary dictionaryWithObject:allExp forKey:NSRuleEditorPredicateCompoundType]];
344    
345     id anyExp = [NSNumber numberWithUnsignedInt:NSOrPredicateType];
346     id any = [self ruleWithValue:@"Any"
347     children:[NSArray arrayWithObject:comp]
348     predicateHints:[NSDictionary dictionaryWithObject:anyExp forKey:NSRuleEditorPredicateCompoundType]];
349    
350     return [NSArray arrayWithObjects:all, any, nil];
351 masaki 120 }
352 masaki 152
353     - (NSDictionary *)predicateHintsWithPlist:(NSDictionary *)plist
354 masaki 120 {
355 masaki 152 NSMutableDictionary *result = [NSMutableDictionary dictionaryWithDictionary:plist];
356     [result removeObjectForKey:@"criteria"];
357     [result removeObjectForKey:@"value"];
358    
359     return result;
360 masaki 120 }
361 masaki 152
362     + (id)ruleWithPlist:(id)plist
363 masaki 120 {
364 masaki 152 return [[[self alloc] initWithPlist:plist] autorelease];
365 masaki 120 }
366 masaki 152 - (id)initWithPlist:(id)plist
367 masaki 120 {
368 masaki 152 if(![plist isKindOfClass:[NSDictionary class]]) {
369     [self init];
370     [self release];
371     return nil;
372     }
373    
374     id pValue = [plist valueForKey:@"value"];
375     id criteria = [plist valueForKey:@"criteria"];
376     id pChildren = [NSMutableArray array];
377     for(id criterion in criteria) {
378     id c = [[self class] ruleWithPlist:criterion];
379     if(c) [pChildren addObject:c];
380     }
381     id hints = [self predicateHintsWithPlist:plist];
382    
383     return [self initWithValue:pValue children:pChildren predicateHints:hints];
384 masaki 120 }
385 masaki 152
386     - (void)dealloc
387 masaki 120 {
388 masaki 152 [children release];
389     [predicateHints release];
390 masaki 153 [_value release];
391 masaki 152
392     [super dealloc];
393 masaki 120 }
394 masaki 152
395 masaki 120 @end
396    
397 masaki 153 @implementation XspfMRule (XspfMPrivate)
398 masaki 142
399 masaki 153 - (NSView *)textField
400     {
401     id text = [[[NSTextField alloc] initWithFrame:NSMakeRect(0,0,100,19)] autorelease];
402     [[text cell] setControlSize:NSSmallControlSize];
403     [text setFont:[NSFont controlContentFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]];
404     [text setStringValue:@"1234567890"];
405     [text sizeToFit];
406     [text setStringValue:@""];
407     [text setDelegate:self];
408    
409     return text;
410     }
411     - (NSView *)datePicker
412     {
413     id date = [[[NSDatePicker alloc] initWithFrame:NSMakeRect(0,0,100,19)] autorelease];
414     [[date cell] setControlSize:NSSmallControlSize];
415     [date setFont:[NSFont controlContentFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]];
416     [date setDatePickerElements:NSYearMonthDayDatePickerElementFlag];
417     [date setDrawsBackground:YES];
418     [date setDateValue:[NSDate dateWithTimeIntervalSinceNow:0.0]];
419     [date sizeToFit];
420     [date setDelegate:self];
421    
422     return date;
423     }
424     - (NSView *)ratingIndicator
425     {
426     id rate = [[[NSLevelIndicator alloc] initWithFrame:NSMakeRect(0,0,100,19)] autorelease];
427     id cell = [rate cell];
428     [cell setControlSize:NSSmallControlSize];
429     [rate setFont:[NSFont controlContentFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]];
430     [rate setMinValue:0];
431     [rate setMaxValue:5];
432     [cell setLevelIndicatorStyle:NSRatingLevelIndicatorStyle];
433     [cell setEditable:YES];
434     [rate sizeToFit];
435    
436     return rate;
437     }
438     - (NSView *)numberField
439     {
440     id text = [[[NSTextField alloc] initWithFrame:NSMakeRect(0,0,100,19)] autorelease];
441     [[text cell] setControlSize:NSSmallControlSize];
442     [text setFont:[NSFont controlContentFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]];
443     [text setStringValue:@"123"];
444     NSNumberFormatter *formatter = [[[NSNumberFormatter alloc] init] autorelease];
445     [formatter setNumberStyle:NSNumberFormatterDecimalStyle];
446     [formatter setMinimum:[NSNumber numberWithInt:0]];
447     [text setFormatter:formatter];
448     [text sizeToFit];
449     [text setStringValue:@"1"];
450     [text setDelegate:self];
451    
452     return text;
453     }
454     @end
455 masaki 152 @implementation XspfMRule (XspfMExpressionBuilder)
456 masaki 156 - (NSArray *)twoNumberAndUnitArgs:(NSArray *)displayValues
457     {
458     id value03 = [displayValues objectAtIndex:2];
459     id arg01 = [NSNumber numberWithInt:[[value03 objectValue] intValue]];
460    
461     id value05 = [displayValues objectAtIndex:4];
462     id arg02 = [NSNumber numberWithInt:[[value05 objectValue] intValue]];
463    
464     id value06 = [displayValues objectAtIndex:5];
465     id arg03 = nil;
466     if([value06 isEqualToString:@"Days"]) {
467 masaki 163 arg03 = [NSNumber numberWithInt:XspfMDaysUnitType];
468 masaki 156 } else if([value06 isEqualToString:@"Weeks"]) {
469 masaki 163 arg03 = [NSNumber numberWithInt:XpsfMWeeksUnitType];
470 masaki 156 } else if([value06 isEqualToString:@"Months"]) {
471 masaki 163 arg03 = [NSNumber numberWithInt:XspfMMonthsUnitType];
472 masaki 156 } else if([value06 isEqualToString:@"Years"]) {
473 masaki 163 arg03 = [NSNumber numberWithInt:XspfMYearsUnitType];
474 masaki 156 }
475    
476     if([arg01 compare:arg02] == NSOrderedDescending) {
477     id t = arg01;
478     arg01 = arg02;
479     arg02 = t;
480     }
481    
482     return [NSArray arrayWithObjects:[NSExpression expressionForConstantValue:arg01],
483     [NSExpression expressionForConstantValue:arg02],
484     [NSExpression expressionForConstantValue:arg03],
485     nil];
486     }
487 masaki 154 - (NSArray *)numberAndUnitArgs:(NSArray *)displayValues
488     {
489     id value03 = [displayValues objectAtIndex:2];
490     id arg01 = [NSNumber numberWithInt:[[value03 objectValue] intValue]];
491    
492     id value04 = [displayValues objectAtIndex:3];
493     id arg02 = nil;
494     if([value04 isEqualToString:@"Days"]) {
495 masaki 163 arg02 = [NSNumber numberWithInt:XspfMDaysUnitType];
496 masaki 154 } else if([value04 isEqualToString:@"Weeks"]) {
497 masaki 163 arg02 = [NSNumber numberWithInt:XpsfMWeeksUnitType];
498 masaki 154 } else if([value04 isEqualToString:@"Months"]) {
499 masaki 163 arg02 = [NSNumber numberWithInt:XspfMMonthsUnitType];
500 masaki 154 } else if([value04 isEqualToString:@"Years"]) {
501 masaki 163 arg02 = [NSNumber numberWithInt:XspfMYearsUnitType];
502 masaki 154 }
503    
504     return [NSArray arrayWithObjects:[NSExpression expressionForConstantValue:arg01],
505     [NSExpression expressionForConstantValue:arg02], nil];
506     }
507 masaki 152 - (NSExpression *)rangeDateFromDisplayValues:(NSArray *)displayValues
508     {
509     id field01 = nil;
510     id field02 = nil;
511    
512     Class datepickerclass = [NSDatePicker class];
513     for(id v in displayValues) {
514     if([v isKindOfClass:datepickerclass]) {
515     if([v tag] == XspfMPrimaryDateFieldTag) {
516     field01 = v;
517     } else {
518     field02 = v;
519     }
520     }
521 masaki 142 }
522    
523 masaki 152 if(!field01 || !field02) return nil;
524    
525     id value01, value02;
526     value01 = [field01 dateValue]; value02 = [field02 dateValue];
527     if([value01 compare:value02] == NSOrderedDescending) {
528     id t = value02;
529     value02 = value01;
530     value01 = t;
531 masaki 142 }
532    
533 masaki 152 id expression01, expression02;
534     expression01 = [NSExpression expressionForConstantValue:value01];
535     expression02 = [NSExpression expressionForConstantValue:value02];
536    
537     return [NSExpression expressionForAggregate:[NSArray arrayWithObjects:expression01, expression02, nil]];
538 masaki 142 }
539 masaki 120 @end
540 masaki 152

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26