-/* xscreensaver, Copyright (c) 2006-2008 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 2006-2011 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
if (! old) {
NSAssert2 (0, @"unknown attribute \"%@\" in \"%@\"", key, [node name]);
} else if ([old length] != 0) {
- NSAssert2 (0, @"duplicate %@: \"%@\", \"%@\"", old, val);
+ NSAssert3 (0, @"duplicate %@: \"%@\", \"%@\"", key, old, val);
} else {
[dict setValue:val forKey:key];
}
const XrmOptionDescRec *opts,
NSView *parent, NSXMLNode *node,
BOOL dirs_only_p,
- BOOL no_label_p)
+ BOOL no_label_p,
+ BOOL editable_text_p)
{
NSMutableDictionary *dict =
[NSMutableDictionary dictionaryWithObjectsAndKeys:
[txt setStringValue:@"123456789 123456789 "];
[txt sizeToFit];
[txt setSelectable:YES];
- [txt setEditable:NO];
- [txt setBezeled:NO];
- [txt setDrawsBackground:NO];
+ [txt setEditable:editable_text_p];
+ [txt setBezeled:editable_text_p];
+ [txt setDrawsBackground:editable_text_p];
[[txt cell] setWraps:NO];
[[txt cell] setScrollable:YES];
[[txt cell] setLineBreakMode:NSLineBreakByTruncatingHead];
bind_switch_to_preferences (prefs, txt, arg, opts);
[txt release];
- // Make the text field be the same height as the label.
+ // Make the text field and label be the same height, whichever is taller.
if (lab) {
rect = [txt frame];
- rect.size.height = [lab frame].size.height;
+ rect.size.height = ([lab frame].size.height > [txt frame].size.height
+ ? [lab frame].size.height
+ : [txt frame].size.height);
[txt setFrame:rect];
}
types:nil];
if (result == NSOKButton) {
NSArray *files = [panel filenames];
- NSString *file = ([files count] > 0 ? [files objectAtIndex:0] : @"");
+ file = ([files count] > 0 ? [files objectAtIndex:0] : @"");
file = [file stringByAbbreviatingWithTildeInPath];
[txt setStringValue:file];
rect.origin.x = rect.origin.y = 0;
rect.size.width = 10;
rect.size.height = 10;
+
+ // #### "Build and Analyze" says that all of our widgets leak, because it
+ // seems to not realize that place_child -> addSubview retains them.
+ // Not sure what to do to make these warnings go away.
+
NSPopUpButton *popup = [[NSPopUpButton alloc] initWithFrame:rect
pullsDown:NO];
if ([child kind] == NSXMLCommentKind)
continue;
if ([child kind] != NSXMLElementKind) {
- NSAssert2 (0, @"weird XML node kind: %d: %@", [child kind], node);
+ NSAssert2 (0, @"weird XML node kind: %d: %@", (int)[child kind], node);
continue;
}
anchorize (const char *url)
{
const char *wiki = "http://en.wikipedia.org/wiki/";
+ const char *math = "http://mathworld.wolfram.com/";
if (!strncmp (wiki, url, strlen(wiki))) {
char *anchor = (char *) malloc (strlen(url) * 3 + 10);
strcpy (anchor, "Wikipedia: \"");
*out = 0;
return anchor;
+ } else if (!strncmp (math, url, strlen(math))) {
+ char *anchor = (char *) malloc (strlen(url) * 3 + 10);
+ strcpy (anchor, "MathWorld: \"");
+ const char *start = url + strlen(wiki);
+ const char *in = start;
+ char *out = anchor + strlen(anchor);
+ while (*in) {
+ if (*in == '_') {
+ *out++ = ' ';
+ } else if (in != start && *in >= 'A' && *in <= 'Z') {
+ *out++ = ' ';
+ *out++ = *in;
+ } else if (!strncmp (in, ".htm", 4)) {
+ break;
+ } else {
+ *out++ = *in;
+ }
+ in++;
+ }
+ *out++ = '"';
+ *out = 0;
+ return anchor;
+
} else {
return strdup (url);
}
}
NSRect rect;
+ rect.origin.x = 0;
+ rect.origin.y = 0;
rect.size.width = maxx;
rect.size.height = -miny;
[group setFrame:rect];
( ) Text [__________________________]
( ) Text file [_________________] [Choose]
( ) URL [__________________________]
+ ( ) Shell Cmd [__________________________]
textMode -text-mode date
textMode -text-mode literal textLiteral -text-literal %
textMode -text-mode file textFile -text-file %
textMode -text-mode url textURL -text-url %
+ textMode -text-mode program textProgram -text-program %
*/
NSRect rect;
rect.size.width = rect.size.height = 1;
rect.origin.x = rect.origin.y = 0;
- NSView *group = [[NSView alloc] initWithFrame:rect];
+ NSView *group = [[NSView alloc] initWithFrame:rect];
NSView *rgroup = [[NSView alloc] initWithFrame:rect];
+ Bool program_p = TRUE;
+
NSXMLElement *node2;
NSView *control;
initWithFrame:rect
mode:NSRadioModeMatrix
prototype:proto
- numberOfRows:4
+ numberOfRows: 4 + (program_p ? 1 : 0)
numberOfColumns:1];
[matrix setAllowsEmptySelection:NO];
[cnames addObject:@"Text"];
[cnames addObject:@"File"];
[cnames addObject:@"URL"];
+ if (program_p) [cnames addObject:@"Shell Cmd"];
[matrix bind:@"content"
toObject:cnames
withKeyPath:@"arrangedObjects"
make_text_field (prefs, opts, rgroup, node2, YES);
[node2 release];
- rect = [last_child(rgroup) frame];
+// rect = [last_child(rgroup) frame];
/* // trying to make the text fields be enabled only when the checkbox is on..
control = last_child (rgroup);
@"textFile", @"id",
@"-text-file %", @"arg",
nil]];
- make_file_selector (prefs, opts, rgroup, node2, NO, YES);
+ make_file_selector (prefs, opts, rgroup, node2, NO, YES, NO);
[node2 release];
- rect = [last_child(rgroup) frame];
+// rect = [last_child(rgroup) frame];
// <string id="textURL" _label="" arg-set="text-url %"/>
node2 = [[NSXMLElement alloc] initWithName:@"string"];
make_text_field (prefs, opts, rgroup, node2, YES);
[node2 release];
- rect = [last_child(rgroup) frame];
+// rect = [last_child(rgroup) frame];
+
+ if (program_p) {
+ // <string id="textProgram" _label="" arg-set="text-program %"/>
+ node2 = [[NSXMLElement alloc] initWithName:@"string"];
+ [node2 setAttributesAsDictionary:
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ @"textProgram", @"id",
+ @"-text-program %", @"arg",
+ nil]];
+ make_text_field (prefs, opts, rgroup, node2, YES);
+ [node2 release];
+ }
+
+// rect = [last_child(rgroup) frame];
layout_group (rgroup, NO);
control = last_child (rgroup);
rect = [control frame];
rect.size.width = 30; // width of the string "Text", plus a bit...
+ if (program_p)
+ rect.size.width += 25;
rect.size.height += LINE_SPACING;
[matrix setCellSize:rect.size];
[matrix sizeToCells];
// the text fields.
//
rect.size = [matrix cellSize];
- rect.size.width *= 10;
+ rect.size.width = 300;
[matrix setCellSize:rect.size];
[matrix sizeToCells];
[node2 setAttributesAsDictionary:
[NSDictionary dictionaryWithObjectsAndKeys:
@"imageDirectory", @"id",
- @"Images directory:", @"_label",
+ @"Images from:", @"_label",
@"-image-directory %", @"arg",
nil]];
- make_file_selector (prefs, opts, parent, node2, YES, NO);
+ make_file_selector (prefs, opts, parent, node2, YES, NO, YES);
[node2 release];
+
+ // Add a second, explanatory label below the file/URL selector.
+
+ NSTextField *lab2 = 0;
+ lab2 = make_label (@"(Local folder, or URL of RSS or Atom feed)");
+ place_child (parent, lab2, NO);
+
+ // Pack it in a little tighter vertically.
+ NSRect r2 = [lab2 frame];
+ r2.origin.x += 20;
+ r2.origin.y += 14;
+ [lab2 setFrameOrigin:r2.origin];
+ [lab2 release];
}
if ([node kind] == NSXMLCommentKind)
return;
if ([node kind] != NSXMLElementKind) {
- NSAssert2 (0, @"weird XML node kind: %d: %@", [node kind], node);
+ NSAssert2 (0, @"weird XML node kind: %d: %@", (int)[node kind], node);
return;
}
make_text_field (prefs, opts, parent, node, NO);
} else if ([name isEqualToString:@"file"]) {
- make_file_selector (prefs, opts, parent, node, NO, NO);
+ make_file_selector (prefs, opts, parent, node, NO, NO, NO);
} else if ([name isEqualToString:@"number"]) {
make_number_selector (prefs, opts, parent, node);
NSRect f;
NSArray *kids = [parent subviews];
int nkids = [kids count];
- NSView *text; // the NSText at the bottom of the window
- NSView *last; // the last child before the NSText
+ NSView *text = 0; // the NSText at the bottom of the window
double maxx = 0, miny = 0;
int i;
f = [kid frame];
if (f.origin.x + f.size.width > maxx) maxx = f.origin.x + f.size.width;
if (f.origin.y - f.size.height < miny) miny = f.origin.y;
- last = kid;
// NSLog(@"start: %3.0f x %3.0f @ %3.0f %3.0f %3.0f %@",
// f.size.width, f.size.height, f.origin.x, f.origin.y,
// f.origin.y + f.size.height, [kid class]);
/* Now that we know the width of the window, set the width of the NSText to
that, so that it can decide what its height needs to be.
*/
+ if (! text) abort();
f = [text frame];
// NSLog(@"text old: %3.0f x %3.0f @ %3.0f %3.0f %3.0f %@",
// f.size.width, f.size.height, f.origin.x, f.origin.y,
f = [text frame];
float dh = f.size.height - oh;
f.origin.y += dh;
+
+ // #### This is needed in OSX 10.5, but is wrong in OSX 10.6. WTF??
+ // If we do this in 10.6, the text field moves down, off the window.
+ // So instead we repair it at the end, at the "WTF2" comment.
[text setFrame:f];
// Also adjust the parent height by the change in height of the text field.
/* Set the contentView to the size of the children.
*/
f = [parent frame];
- float yoff = f.size.height;
+// float yoff = f.size.height;
f.size.width = maxx + LEFT_MARGIN;
f.size.height = -(miny - LEFT_MARGIN*2);
- yoff = f.size.height - yoff;
+// yoff = f.size.height - yoff;
[parent setFrame:f];
// NSLog(@"max: %3.0f x %3.0f @ %3.0f %3.0f",
// f.origin.y + f.size.height, [kid class]);
}
+/*
+Bad:
+ parent: 420 x 541 @ 0 0
+ text: 380 x 100 @ 20 22 miny=-501
+
+Good:
+ parent: 420 x 541 @ 0 0
+ text: 380 x 100 @ 20 50 miny=-501
+*/
+
+ // #### WTF2: See "WTF" above. If the text field is off the screen,
+ // move it up. We need this on 10.6 but not on 10.5. Auugh.
+ //
+ f = [text frame];
+ if (f.origin.y < 50) { // magic numbers, yay
+ f.origin.y = 50;
+ [text setFrame:f];
+ }
+
/* Set the kids to track the top left corner of the window when resized.
Set the NSText to track the bottom right corner as well.
*/
options:(NSXMLNodePreserveWhitespace |
NSXMLNodePreserveCDATA)
error:&err];
-/* clean up?
- if (!xmlDoc) {
- xmlDoc = [[NSXMLDocument alloc] initWithContentsOfURL:furl
- options:NSXMLDocumentTidyXML
- error:&err];
- }
-*/
if (!xmlDoc || err) {
if (err)
NSAssert2 (0, @"XML Error: %@: %@",
}
traverse_tree (prefs, self, opts, [xmlDoc rootElement]);
+ [xmlDoc release];
return self;
}