-/* xscreensaver, Copyright (c) 2006-2014 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2006-2016 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
[n setName:key];
[n setObjectValue:val];
[attributes addObject:n];
+ [n release];
}
}
@end
+#pragma mark textMode value transformer
+
+// A value transformer for mapping "url" to "3" and vice versa in the
+// "textMode" preference, since NSMatrix uses NSInteger selectedIndex.
+
+#ifndef USE_IPHONE
+@interface TextModeTransformer: NSValueTransformer {}
+@end
+@implementation TextModeTransformer
++ (Class)transformedValueClass { return [NSString class]; }
++ (BOOL)allowsReverseTransformation { return YES; }
+
+- (id)transformedValue:(id)value {
+ if ([value isKindOfClass:[NSString class]]) {
+ int i = -1;
+ if ([value isEqualToString:@"date"]) { i = 0; }
+ else if ([value isEqualToString:@"literal"]) { i = 1; }
+ else if ([value isEqualToString:@"file"]) { i = 2; }
+ else if ([value isEqualToString:@"url"]) { i = 3; }
+ else if ([value isEqualToString:@"program"]) { i = 4; }
+ if (i != -1)
+ value = [NSNumber numberWithInt: i];
+ }
+ return value;
+}
+
+- (id)reverseTransformedValue:(id)value {
+ if ([value isKindOfClass:[NSNumber class]]) {
+ switch ((int) [value doubleValue]) {
+ case 0: value = @"date"; break;
+ case 1: value = @"literal"; break;
+ case 2: value = @"file"; break;
+ case 3: value = @"url"; break;
+ case 4: value = @"program"; break;
+ }
+ }
+ return value;
+}
+@end
+#endif // USE_IPHONE
+
+
#pragma mark Implementing radio buttons
/* The UIPickerView is a hideous and uncustomizable piece of shit.
opts:(const XrmOptionDescRec *)opts_array
valRet:(NSString **)val_ret
{
- char buf[255];
+ char buf[1280];
char *tail = 0;
NSAssert(cmdline_switch, @"cmdline switch is null");
if (! [cmdline_switch getCString:buf maxLength:sizeof(buf)
- (void) okAction:(NSObject *)arg
{
+ // Without the setAppliesImmediately:, when the saver restarts, it's still
+ // got the old settings. -[XScreenSaverConfigSheet traverseTree] sets this
+ // to NO; default is YES.
+ [userDefaultsController setAppliesImmediately:YES];
+ [globalDefaultsController setAppliesImmediately:YES];
[userDefaultsController commitEditing];
[globalDefaultsController commitEditing];
[userDefaultsController save:self];
{
NSUserDefaultsController *prefs = [self controllerForKey:pref_key];
# ifndef USE_IPHONE
+ NSDictionary *opts_dict = nil;
NSString *bindto = ([control isKindOfClass:[NSPopUpButton class]]
? @"selectedObject"
: ([control isKindOfClass:[NSMatrix class]]
? @"selectedIndex"
: @"value"));
+
+ if ([control isKindOfClass:[NSMatrix class]]) {
+ opts_dict = @{ NSValueTransformerNameBindingOption:
+ @"TextModeTransformer" };
+ }
+
[control bind:bindto
toObject:prefs
withKeyPath:[@"values." stringByAppendingString: pref_key]
- options:nil];
+ options:opts_dict];
+
# else // USE_IPHONE
SEL sel;
NSObject *val = [prefs objectForKey:pref_key];
NSObject *def = [[prefs defaults] objectForKey:pref_key];
NSString *s = [NSString stringWithFormat:@"bind: \"%@\"", pref_key];
s = [s stringByPaddingToLength:18 withString:@" " startingAtIndex:0];
- s = [NSString stringWithFormat:@"%@ = \"%@\"", s, def];
- s = [s stringByPaddingToLength:28 withString:@" " startingAtIndex:0];
- NSLog (@"%@ %@/%@", s, [def class], [control class]);
+ s = [NSString stringWithFormat:@"%@ = %@", s,
+ ([def isKindOfClass:[NSString class]]
+ ? [NSString stringWithFormat:@"\"%@\"", def]
+ : def)];
+ s = [s stringByPaddingToLength:30 withString:@" " startingAtIndex:0];
+ s = [NSString stringWithFormat:@"%@ %@ / %@", s,
+ [def class], [control class]];
+# ifndef USE_IPHONE
+ s = [NSString stringWithFormat:@"%@ / %@", s, bindto];
+# endif
+ NSLog (@"%@", s);
# endif
}
[self parseAttrs:dict node:node];
NSString *name = [dict objectForKey:@"name"];
NSString *label = [dict objectForKey:@"_label"];
+ [dict release];
+ dict = 0;
NSAssert1 (label, @"no _label in %@", [node name]);
NSAssert1 (name, @"no name in \"%@\"", label);
[lab setAutoresizingMask: (UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight)];
# endif // USE_IPHONE
+ [lab autorelease];
return lab;
}
NSString *label = [dict objectForKey:@"_label"];
NSString *arg_set = [dict objectForKey:@"arg-set"];
NSString *arg_unset = [dict objectForKey:@"arg-unset"];
+ [dict release];
+ dict = 0;
if (!label) {
NSAssert1 (0, @"no _label in %@", [node name]);
[self placeChild:lab on:parent];
UISwitch *button = [[UISwitch alloc] initWithFrame:rect];
[self placeChild:button on:parent right:YES];
- [lab release];
# endif // USE_IPHONE
NSString *high = [dict objectForKey:@"high"];
NSString *def = [dict objectForKey:@"default"];
NSString *cvt = [dict objectForKey:@"convert"];
+ [dict release];
+ dict = 0;
NSAssert1 (arg, @"no arg in %@", label);
NSAssert1 (type, @"no type in %@", label);
while (range2 > max_ticks)
range2 /= 10;
+# ifndef USE_IPHONE
// If we have elided ticks, leave it at the max number of ticks.
if (range != range2 && range2 < max_ticks)
range2 = max_ticks;
if (float_p && range2 < max_ticks)
range2 = max_ticks;
-# ifndef USE_IPHONE
[slider setNumberOfTickMarks:range2];
[slider setAllowsTickMarkValuesOnly:
[lab setFont:[NSFont boldSystemFontOfSize:s]];
}
# endif
- [lab release];
}
if (low_label) {
[lab setLineBreakMode:NSLineBreakByClipping];
[self placeChild:lab on:parent right:(label ? YES : NO)];
# endif // USE_IPHONE
-
- [lab release];
}
# ifndef USE_IPHONE
[lab setLineBreakMode:NSLineBreakByClipping];
# endif
[self placeChild:lab on:parent right:YES];
- [lab release];
}
[self bindSwitch:slider cmdline:arg];
rect.size.height = [txt frame].size.height;
[lab setFrame:rect];
[self placeChild:lab on:parent];
- [lab release];
}
[self placeChild:txt on:parent right:(label ? YES : NO)];
//
NSMutableDictionary *dict = [@{ @"id": @"", } mutableCopy];
[self parseAttrs:dict node:node];
+ [dict release];
+ dict = 0;
NSRect rect;
rect.origin.x = rect.origin.y = 0;
[self parseAttrs:dict2 node:child];
NSString *label = [dict2 objectForKey:@"_label"];
NSString *arg_set = [dict2 objectForKey:@"arg-set"];
+ [dict2 release];
+ dict2 = 0;
if (!label) {
NSAssert1 (0, @"no _label in %@", [child name]);
[b setLineBreakMode:NSLineBreakByTruncatingHead];
[b setFont:[NSFont boldSystemFontOfSize: FONT_SIZE]];
[self placeChild:b on:parent];
+ [b release];
i++;
}
rect.size.height = 50; // sized later
# ifndef USE_IPHONE
NSText *lab = [[NSText alloc] initWithFrame:rect];
+ [lab autorelease];
[lab setEditable:NO];
[lab setDrawsBackground:NO];
[lab setHorizontallyResizable:YES];
HTMLLabel *lab = [[HTMLLabel alloc]
initWithText:text
font:[NSFont systemFontOfSize: [NSFont systemFontSize]]];
+ [lab autorelease];
[lab setFrame:rect];
[lab sizeToFit];
# endif // USE_HTML_LABELS
# endif // USE_IPHONE
[self placeChild:lab on:parent];
- [lab release];
}
[self parseAttrs:dict node:node];
NSString *label = [dict objectForKey:@"_label"];
NSString *arg = [dict objectForKey:@"arg"];
+ [dict release];
+ dict = 0;
if (!label && label_p) {
NSAssert1 (0, @"no _label in %@", [node name]);
if (label) {
LABEL *lab = [self makeLabel:label];
[self placeChild:lab on:parent];
- [lab release];
}
[self placeChild:txt on:parent right:(label ? YES : NO)];
[self parseAttrs:dict node:node];
NSString *label = [dict objectForKey:@"_label"];
NSString *arg = [dict objectForKey:@"arg"];
+ [dict release];
+ dict = 0;
if (!label && label_p) {
NSAssert1 (0, @"no _label in %@", [node name]);
if (label) {
lab = [self makeLabel:label];
[self placeChild:lab on:parent];
- [lab release];
}
[self placeChild:txt on:parent right:(label ? YES : NO)];
[panel setCanChooseFiles:!dirs_p];
[panel setCanChooseDirectories:dirs_p];
- NSString *file = [txt stringValue];
- if ([file length] <= 0) {
- file = NSHomeDirectory();
- if (dirs_p)
- file = [file stringByAppendingPathComponent:@"Pictures"];
- }
-
-// NSString *dir = [file stringByDeletingLastPathComponent];
-
- int result = [panel runModalForDirectory:file //dir
- file:nil //[file lastPathComponent]
- types:nil];
+ int result = [panel runModal];
if (result == NSOKButton) {
- NSArray *files = [panel filenames];
- file = ([files count] > 0 ? [files objectAtIndex:0] : @"");
+ NSArray *files = [panel URLs];
+ NSString *file = ([files count] > 0 ? [[files objectAtIndex:0] path] : @"");
file = [file stringByAbbreviatingWithTildeInPath];
[txt setStringValue:file];
if ([path hasPrefix:@"values."]) // WTF.
path = [path substringFromIndex:7];
[[prefs values] setValue:file forKey:path];
-
-#if 0
- // make sure the end of the string is visible.
- NSText *fe = [[txt window] fieldEditor:YES forObject:txt];
- NSRange range;
- range.location = [file length]-3;
- range.length = 1;
- if (! [[txt window] makeFirstResponder:[txt window]])
- [[txt window] endEditingFor:nil];
-// [[txt window] makeFirstResponder:nil];
- [fe setSelectedRange:range];
-// [tv scrollRangeToVisible:range];
-// [txt setNeedsDisplay:YES];
-// [[txt cell] setNeedsDisplay:YES];
-// [txt selectAll:txt];
-#endif
}
}
[self placeChild:matrix on:group];
[self placeChild:rgroup on:group right:YES];
+ [proto release];
+ [matrix release];
+ [rgroup release];
NSXMLNode *node2;
@"arg-set": @"-text-mode date",
@"_label": @"Display the date and time" }];
[node3 setParent: node2];
- //[node3 release];
+ [node3 autorelease];
node3 = [[NSXMLElement alloc] initWithName:@"option"];
[node3 setAttributesAsDictionary:
@"arg-set": @"-text-mode literal",
@"_label": @"Display static text" }];
[node3 setParent: node2];
- //[node3 release];
+ [node3 autorelease];
node3 = [[NSXMLElement alloc] initWithName:@"option"];
[node3 setAttributesAsDictionary:
@{ @"id": @"url",
@"_label": @"Display the contents of a URL" }];
[node3 setParent: node2];
- //[node3 release];
+ [node3 autorelease];
[self makeOptionMenu:node2 on:rgroup];
+ [node2 release];
# endif // USE_IPHONE
withLabel:YES
# endif
horizontal:NO];
+ [node2 release];
// rect = [last_child(rgroup) frame];
@"arg": @"-text-file %" }];
[self makeFileSelector:node2 on:rgroup
dirsOnly:NO withLabel:NO editable:NO];
+ [node2 release];
# endif // !USE_IPHONE
// rect = [last_child(rgroup) frame];
withLabel:YES
# endif
horizontal:NO];
+ [node2 release];
// rect = [last_child(rgroup) frame];
@"arg": @"-text-program %",
}];
[self makeTextField:node2 on:rgroup withLabel:NO horizontal:NO];
+ [node2 release];
}
// rect = [last_child(rgroup) frame];
[box sizeToFit];
[self placeChild:box on:parent];
+ [group release];
+ [box release];
# endif // !USE_IPHONE
}
@"arg-unset": @"-no-grab-desktop",
}];
[self makeCheckbox:node2 on:parent];
+ [node2 release];
node2 = [[NSXMLElement alloc] initWithName:@"boolean"];
[node2 setAttributesAsDictionary:
@"arg-set": @"-choose-random-images",
}];
[self makeCheckbox:node2 on:parent];
+ [node2 release];
node2 = [[NSXMLElement alloc] initWithName:@"string"];
[node2 setAttributesAsDictionary:
}];
[self makeFileSelector:node2 on:parent
dirsOnly:YES withLabel:YES editable:YES];
+ [node2 release];
# undef SCREENS
# undef PHOTOS
r2.origin.x += 20;
r2.origin.y += 14;
[lab2 setFrameOrigin:r2.origin];
- [lab2 release];
# endif // USE_IPHONE
}
@"arg-unset": @"-no-" SUSUEnableAutomaticChecksKey,
}];
[self makeCheckbox:node2 on:group];
+ [node2 release];
// <select ...>
@"arg-set": @"-" SUScheduledCheckIntervalKey " 3600",
@"_label": @"Hourly" }];
[node3 setParent: node2];
- //[node3 release];
+ [node3 autorelease];
node3 = [[NSXMLElement alloc] initWithName:@"option"];
[node3 setAttributesAsDictionary:
@"arg-set": @"-" SUScheduledCheckIntervalKey " 86400",
@"_label": @"Daily" }];
[node3 setParent: node2];
- //[node3 release];
+ [node3 autorelease];
node3 = [[NSXMLElement alloc] initWithName:@"option"];
[node3 setAttributesAsDictionary:
@"_label": @"Weekly",
}];
[node3 setParent: node2];
- //[node3 release];
+ [node3 autorelease];
node3 = [[NSXMLElement alloc] initWithName:@"option"];
[node3 setAttributesAsDictionary:
@"_label": @"Monthly",
}];
[node3 setParent: node2];
- //[node3 release];
+ [node3 autorelease];
// </option>
[self makeOptionMenu:node2 on:group];
+ [node2 release];
// </hgroup>
layout_group (group, TRUE);
[box sizeToFit];
[self placeChild:box on:parent];
+ [group release];
+ [box release];
# endif // !USE_IPHONE
}
attributes:(NSDictionary *)attrs
{
NSXMLElement *e = [[NSXMLElement alloc] initWithName:elt];
+ [e autorelease];
[e setKind:SimpleXMLElementKind];
[e setAttributesAsDictionary:attrs];
NSXMLElement *p = xml_parsing;
NSXMLElement *p = xml_parsing;
[e setParent:p];
[e setObjectValue: string];
+ [e autorelease];
}
CGFloat ww = [tv frame].size.width;
CGFloat hh = [self tableView:tv heightForRowAtIndexPath:ip];
+ float os_version = [[[UIDevice currentDevice] systemVersion] floatValue];
+
// Width of the column of labels on the left.
CGFloat left_width = ww * 0.4;
CGFloat right_edge = ww - LEFT_MARGIN;
+ if (os_version < 7) // margins were wider on iOS 6.1
+ right_edge -= 10;
+
CGFloat max = FONT_SIZE * 12;
if (left_width > max) left_width = max;
if ([ctl isKindOfClass:[UISwitch class]]) { // Checkboxes.
r.size.width = 80; // Magic.
r.origin.x = right_edge - r.size.width + 30; // beats me
+
+ if (os_version < 7) // checkboxes were wider on iOS 6.1
+ r.origin.x -= 25;
+
} else {
r.origin.x = left_width; // Text fields, etc.
r.size.width = right_edge - r.origin.x;
[label setFrame:r];
[label setFont:[NSFont boldSystemFontOfSize: FONT_SIZE]];
[box addSubview: label];
+ [box autorelease];
ctl = box;
}
[box addSubview: left];
[box addSubview: right];
[box addSubview: mid];
+ [box autorelease];
ctl = box;
}
return nil;
}
+# ifndef USE_IPHONE
+ TextModeTransformer *t = [[TextModeTransformer alloc] init];
+ [NSValueTransformer setValueTransformer:t
+ forName:@"TextModeTransformer"];
+ [t release];
+# endif // USE_IPHONE
+
[self traverseTree];
xml_root = 0;