adium 5537:e367ff752c9e: Reimplement libpurple's request UI usin...
commits at adium.im
commits at adium.im
Wed Jun 5 21:34:32 UTC 2013
details: http://hg.adium.im/adium/rev/e367ff752c9e
revision: 5537:e367ff752c9e
branch: adium-1.6
author: Thijs Alkemade <me at thijsalkema.de>
date: Wed Jun 05 23:31:24 2013 +0200
Reimplement libpurple's request UI using Cocoa, with separate xibs for every element type.
In most cases, this should look decent. Overly long labels will become scrollable, which looks rather weird, but better than overflowing.
Fixes #12750
diffs (truncated from 6323 to 1000 lines):
diff -r bf8f8206070c -r e367ff752c9e Adium.xcodeproj/project.pbxproj
--- a/Adium.xcodeproj/project.pbxproj Tue Jun 04 23:54:22 2013 -0400
+++ b/Adium.xcodeproj/project.pbxproj Wed Jun 05 23:31:24 2013 +0200
@@ -1345,6 +1345,14 @@
761D58801636C60100210B12 /* AINewMessageTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 761D587F1636C60100210B12 /* AINewMessageTableView.m */; };
761D58831636EDE100210B12 /* AINewMessageTextFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 761D58821636EDE100210B12 /* AINewMessageTextFieldCell.m */; };
761D58861636F94300210B12 /* AINewMessageSearchField.m in Sources */ = {isa = PBXBuildFile; fileRef = 761D58851636F94200210B12 /* AINewMessageSearchField.m */; };
+ 7652804C175FC0F500710EC8 /* RequestFieldBoolean.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7652803F175FC0EB00710EC8 /* RequestFieldBoolean.xib */; };
+ 7652804D175FC0F500710EC8 /* RequestFieldChoice.xib in Resources */ = {isa = PBXBuildFile; fileRef = 76528040175FC0EB00710EC8 /* RequestFieldChoice.xib */; };
+ 7652804E175FC0F500710EC8 /* RequestFieldInteger.xib in Resources */ = {isa = PBXBuildFile; fileRef = 76528041175FC0EB00710EC8 /* RequestFieldInteger.xib */; };
+ 7652804F175FC0F500710EC8 /* RequestFieldList.xib in Resources */ = {isa = PBXBuildFile; fileRef = 76528042175FC0EB00710EC8 /* RequestFieldList.xib */; };
+ 76528050175FC0F500710EC8 /* RequestFieldString.xib in Resources */ = {isa = PBXBuildFile; fileRef = 76528043175FC0EB00710EC8 /* RequestFieldString.xib */; };
+ 76528054175FCEF700710EC8 /* RequestFieldMultilineString.xib in Resources */ = {isa = PBXBuildFile; fileRef = 76528052175FCEF700710EC8 /* RequestFieldMultilineString.xib */; };
+ 76528055175FCEF700710EC8 /* RequestFieldSecureString.xib in Resources */ = {isa = PBXBuildFile; fileRef = 76528053175FCEF700710EC8 /* RequestFieldSecureString.xib */; };
+ 7652805A175FD35B00710EC8 /* RequestFieldMultiList.xib in Resources */ = {isa = PBXBuildFile; fileRef = 76528059175FD35B00710EC8 /* RequestFieldMultiList.xib */; };
765F5DC51635934400C57904 /* AIRejoinGroupChatTopBar.xib in Resources */ = {isa = PBXBuildFile; fileRef = 765F5DC71635934400C57904 /* AIRejoinGroupChatTopBar.xib */; };
7664EAA5162E086A008CF995 /* libffi.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7664EAA4162E086A008CF995 /* libffi.framework */; };
7664EAA6162E0874008CF995 /* libffi.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 7664EAA4162E086A008CF995 /* libffi.framework */; };
@@ -4413,6 +4421,14 @@
761D58821636EDE100210B12 /* AINewMessageTextFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AINewMessageTextFieldCell.m; path = Source/AINewMessageTextFieldCell.m; sourceTree = "<group>"; };
761D58841636F94200210B12 /* AINewMessageSearchField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AINewMessageSearchField.h; path = Source/AINewMessageSearchField.h; sourceTree = "<group>"; };
761D58851636F94200210B12 /* AINewMessageSearchField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AINewMessageSearchField.m; path = Source/AINewMessageSearchField.m; sourceTree = "<group>"; };
+ 7652803F175FC0EB00710EC8 /* RequestFieldBoolean.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = RequestFieldBoolean.xib; path = "Plugins/Purple Service/Request UI/RequestFieldBoolean.xib"; sourceTree = "<group>"; };
+ 76528040175FC0EB00710EC8 /* RequestFieldChoice.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = RequestFieldChoice.xib; path = "Plugins/Purple Service/Request UI/RequestFieldChoice.xib"; sourceTree = "<group>"; };
+ 76528041175FC0EB00710EC8 /* RequestFieldInteger.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = RequestFieldInteger.xib; path = "Plugins/Purple Service/Request UI/RequestFieldInteger.xib"; sourceTree = "<group>"; };
+ 76528042175FC0EB00710EC8 /* RequestFieldList.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = RequestFieldList.xib; path = "Plugins/Purple Service/Request UI/RequestFieldList.xib"; sourceTree = "<group>"; };
+ 76528043175FC0EB00710EC8 /* RequestFieldString.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = RequestFieldString.xib; path = "Plugins/Purple Service/Request UI/RequestFieldString.xib"; sourceTree = "<group>"; };
+ 76528052175FCEF700710EC8 /* RequestFieldMultilineString.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = RequestFieldMultilineString.xib; path = "Plugins/Purple Service/Request UI/RequestFieldMultilineString.xib"; sourceTree = "<group>"; };
+ 76528053175FCEF700710EC8 /* RequestFieldSecureString.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = RequestFieldSecureString.xib; path = "Plugins/Purple Service/Request UI/RequestFieldSecureString.xib"; sourceTree = "<group>"; };
+ 76528059175FD35B00710EC8 /* RequestFieldMultiList.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = RequestFieldMultiList.xib; path = "Plugins/Purple Service/Request UI/RequestFieldMultiList.xib"; sourceTree = "<group>"; };
765F5DC61635934400C57904 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/AIRejoinGroupChatTopBar.xib; sourceTree = "<group>"; };
7664EAA4162E086A008CF995 /* libffi.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = libffi.framework; path = Frameworks/libffi.framework; sourceTree = "<group>"; };
766ABAB41306D1020049FFB7 /* AIUnreadMessagesTooltip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIUnreadMessagesTooltip.h; path = Source/AIUnreadMessagesTooltip.h; sourceTree = "<group>"; };
@@ -6094,6 +6110,14 @@
34C2CF8F0633405C0018E5D2 /* Request UI */ = {
isa = PBXGroup;
children = (
+ 7652803F175FC0EB00710EC8 /* RequestFieldBoolean.xib */,
+ 76528040175FC0EB00710EC8 /* RequestFieldChoice.xib */,
+ 76528041175FC0EB00710EC8 /* RequestFieldInteger.xib */,
+ 76528059175FD35B00710EC8 /* RequestFieldMultiList.xib */,
+ 76528042175FC0EB00710EC8 /* RequestFieldList.xib */,
+ 76528043175FC0EB00710EC8 /* RequestFieldString.xib */,
+ 76528052175FCEF700710EC8 /* RequestFieldMultilineString.xib */,
+ 76528053175FCEF700710EC8 /* RequestFieldSecureString.xib */,
34AEE7E808E35A5800AE1C78 /* ESPurpleRequestAbstractWindowController.h */,
34AEE7E908E35A5800AE1C78 /* ESPurpleRequestAbstractWindowController.m */,
3499F4A706309AF60035B468 /* ESPurpleRequestWindowController.h */,
@@ -9653,6 +9677,14 @@
34D8153F13B663650022C8C4 /* AIFacebookXMPPOauthWebViewWindow.xib in Resources */,
5A22D6E214834F44004E15F7 /* AIFacebookXMPPAccountView.xib in Resources */,
769D634B17393CBE008B97BC /* AMPurpleJabberDiscoveryBrowser.xib in Resources */,
+ 7652804C175FC0F500710EC8 /* RequestFieldBoolean.xib in Resources */,
+ 7652804D175FC0F500710EC8 /* RequestFieldChoice.xib in Resources */,
+ 7652804E175FC0F500710EC8 /* RequestFieldInteger.xib in Resources */,
+ 7652804F175FC0F500710EC8 /* RequestFieldList.xib in Resources */,
+ 76528050175FC0F500710EC8 /* RequestFieldString.xib in Resources */,
+ 76528054175FCEF700710EC8 /* RequestFieldMultilineString.xib in Resources */,
+ 76528055175FCEF700710EC8 /* RequestFieldSecureString.xib in Resources */,
+ 7652805A175FD35B00710EC8 /* RequestFieldMultiList.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff -r bf8f8206070c -r e367ff752c9e Plugins/Purple Service/AMPurpleRequestFieldsController.h
--- a/Plugins/Purple Service/AMPurpleRequestFieldsController.h Tue Jun 04 23:54:22 2013 -0400
+++ b/Plugins/Purple Service/AMPurpleRequestFieldsController.h Wed Jun 05 23:31:24 2013 +0200
@@ -25,12 +25,21 @@
GCallback cancelcb;
void *userData;
PurpleRequestFields *fields;
- NSMutableDictionary *fieldobjects;
+ NSMutableArray *fieldobjects;
BOOL wasSubmitted;
- IBOutlet WebView *webview;
+ IBOutlet NSTextField *primaryTextField;
+ IBOutlet NSTextField *secondaryTextField;
+
+ IBOutlet NSButton *okButton;
+ IBOutlet NSButton *cancelButton;
+
+ IBOutlet NSView *contentView;
}
+- (IBAction)submit:(id)sender;
+- (IBAction)cancel:(id)sender;
+
- (id)initWithTitle:(NSString *)title
primaryText:(NSString *)primary
secondaryText:(NSString *)secondary
diff -r bf8f8206070c -r e367ff752c9e Plugins/Purple Service/AMPurpleRequestFieldsController.m
--- a/Plugins/Purple Service/AMPurpleRequestFieldsController.m Tue Jun 04 23:54:22 2013 -0400
+++ b/Plugins/Purple Service/AMPurpleRequestFieldsController.m Wed Jun 05 23:31:24 2013 +0200
@@ -16,6 +16,7 @@
#import "AMPurpleRequestFieldsController.h"
#import <AIUtilities/AIImageAdditions.h>
+#import <AIUtilities/AIMenuAdditions.h>
#import <AIUtilities/AIStringAdditions.h>
@interface WebView ()
@@ -26,43 +27,70 @@
@interface AMPurpleRequestField : NSObject {
PurpleRequestField *field;
CBPurpleAccount *account;
+ IBOutlet NSView *view;
+ IBOutlet NSTextView *label;
+
+ NSInteger height;
}
- (id)initWithAccount:(CBPurpleAccount*)_account requestField:(PurpleRequestField*)_field;
-
-- (NSXMLElement*)xhtml;
-- (NSString*)key;
-
-- (void)applyValue:(NSString*)value;
+- (NSString *)nibName;
+- (NSView *)makeView;
+- (NSAttributedString *)label;
+- (void)submit;
@end
@interface AMPurpleRequestFieldString : AMPurpleRequestField {
+ IBOutlet NSTextField *textField;
}
+ at end
+ at interface AMPurpleRequestFieldSecureString : AMPurpleRequestField {
+ IBOutlet NSSecureTextField *maskedField;
+}
+ at end
+
+ at interface AMPurpleRequestFieldMultilineString : AMPurpleRequestField {
+ IBOutlet NSTextView *textView;
+}
@end
@interface AMPurpleRequestFieldInteger : AMPurpleRequestField {
+ IBOutlet NSTextField *textField;
}
@end
@interface AMPurpleRequestFieldBoolean : AMPurpleRequestField {
+ IBOutlet NSButton *checkBox;
}
@end
@interface AMPurpleRequestFieldChoice : AMPurpleRequestField {
+ IBOutlet NSPopUpButton *popUp;
}
@end
@interface AMPurpleRequestFieldList : AMPurpleRequestField {
+ IBOutlet NSPopUpButton *popUp;
}
@end
+ at interface AMPurpleRequestFieldMultiList : AMPurpleRequestField {
+ IBOutlet NSPopUpButton *popDown;
+}
+
+- (IBAction)didSelect:(id)sender;
+
+ at end
+
+
@interface AMPurpleRequestFieldLabel : AMPurpleRequestField {
+ IBOutlet NSTextView *labelview;
}
@end
@@ -83,259 +111,440 @@
if((self = [super init])) {
account = _account;
field = _field;
- }
+
+ [NSBundle loadNibNamed:[self nibName] owner:self];
+
+ height = view.frame.size.height;
+
+ NSInteger dh = height - label.frame.size.height;
+
+ [[label textStorage] setAttributedString:[self label]];
+
+ [label setHorizontallyResizable:FALSE];
+ [label setTextContainerInset:NSMakeSize(0, 0)];
+ [label sizeToFit];
+
+ if (height < label.frame.size.height + dh) {
+ height = label.frame.size.height + dh;
+ }
+ }
return self;
}
-- (NSXMLElement*)xhtml {
- NSXMLElement *result = [NSXMLNode elementWithName:@"div"];
-
- [result addAttribute:[NSXMLNode attributeWithName:@"class" stringValue:@"field"]];
-
- const char *labelstr = purple_request_field_get_label(field);
-
- if(labelstr) {
- NSXMLElement *label = [NSXMLNode elementWithName:@"label" stringValue:[NSString stringWithUTF8String:labelstr]];
- [label addAttribute:[NSXMLNode attributeWithName:@"for" stringValue:[self key]]];
-
- [result addChild:[NSXMLNode elementWithName:@"div"
- children:[NSArray arrayWithObject:label]
- attributes:[NSArray arrayWithObject:[NSXMLNode attributeWithName:@"class" stringValue:@"label"]]]];
- }
- return result;
+- (NSView *)makeView {
+ assert(FALSE);
}
-- (NSString*)key {
- return [NSString stringWithFormat:@"%p",self];
+- (NSString *)nibName {
+ return nil;
}
-- (void)applyValue:(NSString*)value {
- NSLog(@"Applied the value \"%@\" to an AMPurpleRequestField!", value);
+- (NSAttributedString *)label
+{
+ const char *labelstr = purple_request_field_get_label(field);
+
+ if (labelstr) {
+ NSString *labelString = [NSString stringWithUTF8String:labelstr];
+
+ char endsWith = [labelString lastCharacter];
+
+ if (endsWith == ':' || endsWith == ';' || endsWith == ',' || endsWith == '.' || endsWith == '?') {
+ labelString = [labelString substringToIndex:[labelString length] - 1];
+ }
+
+ labelString = [labelString stringByAppendingString:@":"];
+
+ NSMutableParagraphStyle *rightAlign = [[NSMutableParagraphStyle alloc] init];
+ [rightAlign setAlignment:NSRightTextAlignment];
+
+ NSAttributedString *labelText = [[NSAttributedString alloc] initWithString:labelString
+ attributes:@{
+ NSParagraphStyleAttributeName: rightAlign,
+ NSFontAttributeName: [NSFont systemFontOfSize:[NSFont systemFontSize]]
+ }];
+
+ [rightAlign release];
+
+ return [labelText autorelease];
+ }
+
+ return [[[NSAttributedString alloc] initWithString:@""] autorelease];
+}
+
+- (void)submit
+{
+
}
@end
@implementation AMPurpleRequestFieldString
-- (NSXMLElement*)xhtml {
- NSXMLElement *result = [super xhtml];
-
- const char *defaultvalue = purple_request_field_string_get_default_value(field);
- BOOL isMultiline = (purple_request_field_string_is_multiline(field) == TRUE) ? YES : NO;
- BOOL isEditable = (purple_request_field_string_is_editable(field) == TRUE) ? YES : NO;
- BOOL isMasked = (purple_request_field_string_is_masked(field) == TRUE) ? YES : NO;
- BOOL isVisible = (purple_request_field_is_visible(field) == TRUE) ? YES : NO;
-
- NSXMLElement *textinput;
-
- if(isMultiline) {
- textinput = [NSXMLNode elementWithName:@"textarea"];
- [textinput addAttribute:[NSXMLNode attributeWithName:@"rows" stringValue:@"5"]];
- [textinput addAttribute:[NSXMLNode attributeWithName:@"cols" stringValue:@"40"]];
- if(defaultvalue)
- [textinput setStringValue:[NSString stringWithUTF8String:defaultvalue]];
- } else {
- textinput = [NSXMLNode elementWithName:@"input"];
- if (isVisible)
- [textinput addAttribute:[NSXMLNode attributeWithName:@"type" stringValue:isMasked?@"password":@"text"]];
- else
- [textinput addAttribute:[NSXMLNode attributeWithName:@"type" stringValue:@"hidden"]];
- [textinput addAttribute:[NSXMLNode attributeWithName:@"size" stringValue:@"50"]];
- if(defaultvalue)
- [textinput addAttribute:[NSXMLNode attributeWithName:@"value" stringValue:[NSString stringWithUTF8String:defaultvalue]]];
- }
- [textinput addAttribute:[NSXMLNode attributeWithName:@"name" stringValue:[self key]]];
- if(!isEditable)
- [textinput addAttribute:[NSXMLNode attributeWithName:@"readonly" stringValue:@"readonly"]];
-
- if (isVisible)
- [result addChild:[NSXMLNode elementWithName:@"div"
- children:[NSArray arrayWithObject:textinput]
- attributes:[NSArray arrayWithObject:[NSXMLNode attributeWithName:@"class" stringValue:@"input"]]]];
- else
- return textinput;
-
- return result;
+- (NSString *)nibName
+{
+ return @"RequestFieldString";
}
-- (void)applyValue:(NSString*)value {
- purple_request_field_string_set_value(field, [value UTF8String]);
+- (NSView *)makeView
+{
+ AILogWithSignature(@"Appending this to the window");
+ NSString *defaultvalue = [NSString stringWithUTF8String:purple_request_field_string_get_default_value(field)];
+ BOOL isEditable = purple_request_field_string_is_editable(field);
+ BOOL isVisible = purple_request_field_is_visible(field);
+
+ if (!isVisible) return nil;
+
+ [textField setEditable:isEditable];
+ [textField setStringValue:defaultvalue];
+
+ return view;
+}
+
+- (void)submit
+{
+ BOOL isVisible = purple_request_field_is_visible(field);
+
+ if (!isVisible) {
+ purple_request_field_string_set_value(field, purple_request_field_string_get_default_value(field));
+ } else {
+ purple_request_field_string_set_value(field, [[textField stringValue] UTF8String]);
+ }
}
@end
+ at implementation AMPurpleRequestFieldSecureString
+
+- (NSString *)nibName
+{
+ return @"RequestFieldSecureString";
+}
+
+- (NSView *)makeView
+{
+ AILogWithSignature(@"Appending this to the window");
+ NSString *defaultvalue = [NSString stringWithUTF8String:purple_request_field_string_get_default_value(field)];
+ BOOL isEditable = purple_request_field_string_is_editable(field);
+ BOOL isVisible = purple_request_field_is_visible(field);
+
+ if (!isVisible) return nil;
+
+ [maskedField setEditable:isEditable];
+ [maskedField setStringValue:defaultvalue];
+
+ return view;
+}
+
+- (void)submit
+{
+ BOOL isVisible = purple_request_field_is_visible(field);
+
+ if (!isVisible) {
+ purple_request_field_string_set_value(field, purple_request_field_string_get_default_value(field));
+ } else {
+ purple_request_field_string_set_value(field, [[maskedField stringValue] UTF8String]);
+ }
+}
+
+ at end
+
+ at implementation AMPurpleRequestFieldMultilineString
+
+- (NSString *)nibName
+{
+ return @"RequestFieldMultilineString";
+}
+
+- (NSView *)makeView
+{
+ AILogWithSignature(@"Appending this to the window");
+ NSString *defaultvalue = [NSString stringWithUTF8String:purple_request_field_string_get_default_value(field)];
+ BOOL isEditable = purple_request_field_string_is_editable(field);
+ BOOL isVisible = purple_request_field_is_visible(field);
+
+ if (!isVisible) return nil;
+
+ [[textView enclosingScrollView] setHasVerticalScroller:TRUE];
+
+ [textView setEditable:isEditable];
+ [[textView textStorage] setAttributedString:[[[NSAttributedString alloc] initWithString:defaultvalue] autorelease]];
+
+ if (height < textView.frame.size.height + 15) {
+ height = textView.frame.size.height + 15;
+ }
+
+ [view setFrame:NSMakeRect(0, 0, view.frame.size.width, height)];
+
+ return view;
+}
+
+- (void)submit
+{
+ BOOL isVisible = purple_request_field_is_visible(field);
+
+ if (!isVisible) {
+ purple_request_field_string_set_value(field, purple_request_field_string_get_default_value(field));
+ } else {
+ purple_request_field_string_set_value(field, [[[textView textStorage] string] UTF8String]);
+ }
+}
+
+ at end
+
@implementation AMPurpleRequestFieldInteger
-- (NSXMLElement*)xhtml {
- NSXMLElement *result = [super xhtml];
-
- NSInteger defaultvalue = purple_request_field_int_get_default_value(field);
-
- NSXMLElement *textinput = [NSXMLNode elementWithName:@"input"];
- [textinput addAttribute:[NSXMLNode attributeWithName:@"type" stringValue:@"text"]];
- [textinput addAttribute:[NSXMLNode attributeWithName:@"value" stringValue:[NSString stringWithFormat:@"%ld",defaultvalue]]];
- [textinput addAttribute:[NSXMLNode attributeWithName:@"name" stringValue:[self key]]];
- // XXX add javascript to make sure this is integer-only
-
- [result addChild:[NSXMLNode elementWithName:@"div"
- children:[NSArray arrayWithObject:textinput]
- attributes:[NSArray arrayWithObject:[NSXMLNode attributeWithName:@"class" stringValue:@"input"]]]];
-
- return result;
+- (NSString *)nibName
+{
+ return @"RequestFieldInteger";
}
-- (void)applyValue:(NSString*)value {
- purple_request_field_int_set_value(field, [value intValue]);
+
+- (NSView *)makeView
+{
+ NSInteger defaultvalue = purple_request_field_int_get_default_value(field);
+
+ [textField setIntegerValue:defaultvalue];
+
+ return view;
+}
+
+- (void)submit
+{
+ purple_request_field_int_set_value(field, [textField intValue]);
}
@end
@implementation AMPurpleRequestFieldBoolean
-- (NSXMLElement*)xhtml {
- NSXMLElement *result = [super xhtml];
-
- BOOL defaultvalue = (purple_request_field_bool_get_default_value(field) == TRUE) ? YES : NO;
-
- NSXMLElement *checkbox = [NSXMLNode elementWithName:@"input"];
- [checkbox addAttribute:[NSXMLNode attributeWithName:@"type" stringValue:@"checkbox"]];
- [checkbox addAttribute:[NSXMLNode attributeWithName:@"value" stringValue:[self key]]];
- [checkbox addAttribute:[NSXMLNode attributeWithName:@"name" stringValue:[self key]]];
-
- if(defaultvalue)
- [checkbox addAttribute:[NSXMLNode attributeWithName:@"checked" stringValue:@"checked"]];
-
- [result addChild:[NSXMLNode elementWithName:@"div"
- children:[NSArray arrayWithObject:checkbox]
- attributes:[NSArray arrayWithObject:[NSXMLNode attributeWithName:@"class" stringValue:@"input"]]]];
-
- purple_request_field_bool_set_value(field, FALSE); // since we won't get an -applyValue: message when the checkbox isn't checked, assume false for now. This might be changed later.
- return result;
+- (NSString *)nibName
+{
+ return @"RequestFieldBoolean";
}
-- (void)applyValue:(NSString*)value {
- purple_request_field_bool_set_value(field, TRUE);
+- (NSView *)makeView
+{
+ BOOL defaultvalue = purple_request_field_bool_get_default_value(field);
+
+ [checkBox setState:defaultvalue];
+
+ return view;
+}
+
+- (void)submit
+{
+ purple_request_field_bool_set_value(field, [checkBox state] == NSOnState);
+}
+
+- (NSAttributedString *)label
+{
+
+ const char *labelstr = purple_request_field_get_label(field);
+
+ if (labelstr) {
+ NSString *labelString = [NSString stringWithUTF8String:labelstr];
+
+ char endsWith = [labelString lastCharacter];
+
+ if (endsWith == '.' || endsWith == '?') {
+ labelString = [labelString substringToIndex:[labelString length] - 1];
+ }
+
+ NSAttributedString *labelText = [[NSAttributedString alloc] initWithString:labelString
+ attributes:@{ NSFontAttributeName: [NSFont systemFontOfSize:[NSFont systemFontSize]] }];
+ return [labelText autorelease];
+ }
+
+ return [[[NSAttributedString alloc] initWithString:@""] autorelease];
}
@end
@implementation AMPurpleRequestFieldChoice
-- (NSXMLElement*)xhtml {
- NSXMLElement *result = [super xhtml];
-
+- (NSString *)nibName
+{
+ return @"RequestFieldChoice";
+}
+
+
+- (NSView *)makeView
+{
GList *labels = purple_request_field_choice_get_labels(field);
- guint len = g_list_length(labels);
- NSInteger defaultvalue = purple_request_field_choice_get_default_value(field);
+ NSInteger defaultvalue = purple_request_field_choice_get_default_value(field);
- // Apple HIG: Don't use checkboxes for lists of more than 5 items, use a popupbutton instead
- if(len > 5) {
- NSXMLElement *popup = [NSXMLNode elementWithName:@"select"];
- [popup addAttribute:[NSXMLNode attributeWithName:@"name" stringValue:[self key]]];
- NSInteger i=0;
- GList *label;
- for(label = labels; label; label = g_list_next(label), ++i) {
- const char *labelstr = label->data;
- if(!labelstr)
- continue;
-
- NSXMLElement *option = [NSXMLNode elementWithName:@"option" stringValue:[NSString stringWithUTF8String:labelstr]];
- [option addAttribute:[NSXMLNode attributeWithName:@"value" stringValue:[NSString stringWithFormat:@"%lu",i]]];
- if(i == defaultvalue)
- [option addAttribute:[NSXMLNode attributeWithName:@"selected" stringValue:@"selected"]];
- [popup addChild:option];
- }
- [result addChild:[NSXMLNode elementWithName:@"div"
- children:[NSArray arrayWithObject:popup]
- attributes:[NSArray arrayWithObject:[NSXMLNode attributeWithName:@"class" stringValue:@"input"]]]];
- } else {
- NSInteger i=0;
- NSMutableArray *radios = [NSMutableArray array];
- GList *label;
- for(label = labels; label; label = g_list_next(label), ++i) {
- const char *labelstr = label->data;
- if(!labelstr)
- continue;
-
- NSXMLElement *radiobutton = [NSXMLNode elementWithName:@"input"];
- [radiobutton addAttribute:[NSXMLNode attributeWithName:@"type" stringValue:@"radio"]];
- [radiobutton addAttribute:[NSXMLNode attributeWithName:@"value" stringValue:[NSString stringWithFormat:@"%lu",i]]];
- [radiobutton addAttribute:[NSXMLNode attributeWithName:@"name" stringValue:[self key]]];
-
- if(i == defaultvalue)
- [radiobutton addAttribute:[NSXMLNode attributeWithName:@"checked" stringValue:@"checked"]];
-
- [radios addObject:radiobutton];
- [radios addObject:[NSXMLNode textWithStringValue:[NSString stringWithUTF8String:labelstr]]];
- }
- [result addChild:[NSXMLNode elementWithName:@"div"
- children:radios
- attributes:[NSArray arrayWithObject:[NSXMLNode attributeWithName:@"class" stringValue:@"input"]]]];
+ [view setFrame:NSMakeRect(0, 0, view.frame.size.width, height)];
+
+ [popUp removeAllItems];
+
+ for (; labels; labels = labels->next) {
+ [popUp addItemWithTitle:[NSString stringWithUTF8String:(char *)labels->data]];
}
- return result;
+ if (defaultvalue < [popUp numberOfItems]) {
+ [popUp selectItemAtIndex:defaultvalue];
+ }
+
+ return view;
}
-- (void)applyValue:(NSString*)value {
- purple_request_field_choice_set_value(field, [value intValue]);
+- (void)submit
+{
+ purple_request_field_choice_set_value(field, (int)[popUp indexOfItem:[popUp selectedItem]]);
}
@end
@implementation AMPurpleRequestFieldList
-- (NSXMLElement*)xhtml {
- NSXMLElement *result = [super xhtml];
+- (NSString *)nibName
+{
+ return @"RequestFieldList";
+}
+
+- (NSView *)makeView
+{
+ GList *items = purple_request_field_list_get_items(field);
+
+ [popUp removeAllItems];
- BOOL isMultiSelect = (purple_request_field_list_get_multi_select(field) == TRUE) ? YES : NO;
-
- NSXMLElement *list = [NSXMLNode elementWithName:@"select"];
- [list addAttribute:[NSXMLNode attributeWithName:@"name" stringValue:[self key]]];
+ NSInteger i;
- if(isMultiSelect)
- [list addAttribute:[NSXMLNode attributeWithName:@"multiple" stringValue:@"multiple"]];
-
- const GList *items = purple_request_field_list_get_items(field);
- guint len = g_list_length((GList*)items);
-
- // show all items up to 10
- [list addAttribute:[NSXMLNode attributeWithName:@"size" stringValue:[NSString stringWithFormat:@"%u",(len>10)?10:len]]];
-
- const GList *item;
- for(item = items; item; item = g_list_next(item)) {
- const char *labelstr = item->data;
- if(!labelstr)
- continue;
-
- NSXMLElement *option = [NSXMLNode elementWithName:@"option" stringValue:[NSString stringWithUTF8String:labelstr]];
- if(purple_request_field_list_is_selected(field, labelstr))
- [option addAttribute:[NSXMLNode attributeWithName:@"selected" stringValue:@"selected"]];
- [list addChild:option];
- }
- [result addChild:[NSXMLNode elementWithName:@"div"
- children:[NSArray arrayWithObject:list]
- attributes:[NSArray arrayWithObject:[NSXMLNode attributeWithName:@"class" stringValue:@"input"]]]];
-
+ for (i = 0; items; items = items->next, i++) {
+ NSString *item = [NSString stringWithUTF8String:items->data];
+ [popUp addItemWithTitle:item];
+ if (purple_request_field_list_is_selected(field, items->data)) {
+ [popUp selectItemAtIndex:i];
+ }
+ }
+
+ return view;
+}
+- (void)submit
+{
purple_request_field_list_clear_selected(field);
- return result;
+ GList *items = NULL;
+ const char *text;
+
+ text = [[[popUp selectedItem] title] UTF8String];
+ items = g_list_prepend(items, (gpointer)text);
+
+ purple_request_field_list_set_selected(field, items);
+
+ g_list_free(items);
}
-- (void)applyValue:(NSString*)value {
- purple_request_field_list_add_selected(field, [value UTF8String]);
+ at end
+
+ at implementation AMPurpleRequestFieldMultiList
+
+- (NSString *)nibName
+{
+ return @"RequestFieldMultiList";
+}
+
+- (NSView *)makeView
+{
+ GList *items = purple_request_field_list_get_items(field);
+ NSInteger i = 0;
+
+ [popDown removeAllItems];
+ [popDown addItemWithTitle:AILocalizedString(@"Select...", "Used in the request UI for popdown buttons")];
+
+ for (i = 0; items; items = items->next, i++) {
+ NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:[NSString stringWithUTF8String:items->data]
+ target:self
+ action:@selector(didSelect:)
+ keyEquivalent:@""];
+ if(purple_request_field_list_is_selected(field, items->data)) {
+ [menuItem setState:NSOnState];
+ }
+
+ [[popDown menu] addItem:menuItem];
+
+ [menuItem release];
+ }
+
+ return view;
+}
+
+- (IBAction)didSelect:(id)sender
+{
+ NSInteger state = [sender state];
+
+ if (state == NSOnState)
+ state = NSOffState;
+ else
+ state = NSOnState;
+
+ [sender setState:state];
+}
+
+- (void)submit
+{
+ purple_request_field_list_clear_selected(field);
+
+ BOOL skipped = FALSE;
+
+ GList *items = NULL;
+ const char *text;
+
+ for (NSMenuItem *item in [[popDown menu] itemArray]) {
+ if (!skipped) {
+ skipped = TRUE;
+ continue;
+ }
+
+ if ([item state] == NSOnState) {
+ text = [[item title] UTF8String];
+ items = g_list_prepend(items, (gpointer)text);
+ }
+ }
+
+ purple_request_field_list_set_selected(field, items);
+
+ g_list_free(items);
}
@end
@implementation AMPurpleRequestFieldLabel
-#if 0
-- (NSXMLNode*)xhtml {
- return [super xhtml];
+- (NSString *)nibName
+{
+ return @"RequestFieldLabel";
}
-#endif
+
+- (NSView *)makeView
+{
+ [[labelview textStorage] setAttributedString:self.label];
+ [labelview setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]];
+ [labelview setHorizontallyResizable:FALSE];
+ [labelview setTextContainerInset:NSMakeSize(0, 0)];
+ [labelview sizeToFit];
+
+ [view setFrame:NSMakeRect(0, 0, view.frame.size.width, height)];
+
+ return view;
+}
+
+// Do not append a :
+- (NSString *)label
+{
+
+ const char *labelstr = purple_request_field_get_label(field);
+
+ if (labelstr) {
+ NSString *labelString = [NSString stringWithUTF8String:labelstr];
+
+ return labelString;
+ }
+
+ return @"";
+}
@end
@@ -345,54 +554,6 @@
@implementation AMPurpleRequestFieldImage
-- (NSXMLElement*)xhtml {
- NSXMLElement *result = [super xhtml];
-
- //unsigned int scale_x = purple_request_field_image_get_scale_x(field);
- //unsigned int scale_y = purple_request_field_image_get_scale_y(field);
-
- //This could be base 64 encoded and embedded directly, but it seems like a heavy fix...
- NSData *data = [NSData dataWithBytes:purple_request_field_image_get_buffer(field)
- length:purple_request_field_image_get_size(field)];
-
- NSString *extension = [NSImage extensionForBitmapImageFileType:[NSImage fileTypeOfData:data]];
- if (!extension) {
- //We don't know what it is; try to make a png out of it
- NSImage *image = [[NSImage alloc] initWithData:data];
- NSData *imageTIFFData = [image TIFFRepresentation];
- NSBitmapImageRep *bitmapRep = [NSBitmapImageRep imageRepWithData:imageTIFFData];
-
- data = [bitmapRep representationUsingType:NSPNGFileType properties:nil];
- extension = @"png";
- [image release];
- }
-
- NSString *filename = [[[NSString stringWithFormat:@"TEMP-Image_%@",[self key]] stringByAppendingPathExtension:extension] safeFilenameString];
- NSString *imagePath = [[adium cachesPath] stringByAppendingPathComponent:filename];
-
- NSXMLElement *imageElement = [NSXMLNode elementWithName:@"image"];
-
- if ([data writeToFile:imagePath atomically:YES]) {
- [imageElement addAttribute:[NSXMLNode attributeWithName:@"src" stringValue:[[NSURL fileURLWithPath:imagePath] absoluteString]]];
- [imageElement addAttribute:[NSXMLNode attributeWithName:@"name" stringValue:[self key]]];
-
- [result addChild:[NSXMLNode elementWithName:@"div"
- children:[NSArray arrayWithObject:imageElement]
- attributes:[NSArray arrayWithObject:[NSXMLNode attributeWithName:@"class" stringValue:@"image"]]]];
- } else {
- AILogWithSignature(@"Failed to write image to %@",imagePath);
- }
-
- return result;
-}
-
-
- at end
-
-
- at interface AMPurpleRequestFieldsController ()
-- (void)loadForm:(NSXMLDocument*)doc;
-- (void)webviewWindowWillClose:(NSNotification *)notification;
@end
@implementation AMPurpleRequestFieldsController
@@ -416,152 +577,28 @@
cancelcb = _cancelcb;
userData = _userData;
- // generate XHTML
- NSXMLElement *root = [NSXMLNode elementWithName:@"html"];
- [root addNamespace:[NSXMLNode namespaceWithName:@"" stringValue:@"http://www.w3.org/1999/xhtml"]];
- NSXMLElement *head = [NSXMLNode elementWithName:@"head"];
- [root addChild:head];
-
- [head addChild:[NSXMLNode elementWithName:@"style" children:[NSArray arrayWithObject:
- [NSXMLNode textWithStringValue:
- @"body {"
- @" font-family:'Lucida Grande';"
- @" font-size: 13pt;"
- @"}"
- @"h1 {"
- @" display: none;"
- @"}"
- @"h2 {"
- @" font-size: 13pt;"
- @" font-weight: normal;"
- @"}"
- @"h3 {"
- @" font-size: 11pt;"
- @" font-weight: normal;"
- @"}"
- @"#formwrapper"
- @"{"
- @" position: fixed;"
- @" top: 0px;"
- @" left: 0;"
- @" bottom: 50px;"
- @" right: 0;"
- @" overflow: auto;"
- @"}"
- @"#form2"
- @"{"
- @" margin: 20px;"
- @" overflow: none;"
- @"}"
- @"#formtable"
- @"{"
- @" display: table;"
- @" margin: 0 auto;"
- @"}"
- @".field {"
- @" position: relative;"
- @" display: table-row;"
- @" font-size: 13pt;"
- @"}"
- @".label {"
- @" text-align: right;"
- @" display: table-cell;"
- @" width: 50%;"
- @" padding-right: .2em;"
- @" vertical-align: top;"
- @" font-size: 13pt;"
- @"}"
- @".label:after {"
- @" content: \":\";"
- @"}"
- @".input {"
- @" display: table-cell;"
- @" width: 50%;"
- @" padding-left: .2em;"
- @" vertical-align: top;"
- @"}"
- @"#cancel {"
- @" font-size: 13pt;"
- @" margin-right: 10px;"
- @"}"
- @"#submit {"
- @" font-size: 13pt;"
- @" margin-right: 20px;"
- @" margin-left: 10px;"
- @"}"
- @"#submitbuttons {"
- @" text-align: right;"
- @" position: absolute;"
- @" bottom: 0;"
- @" right: 0;"
- @" overflow: auto;"
- @" height: 45px;"
- @" width: 100%;"
- @" border-color: #000;"
- @" border-width: 1px 0 0 0;"
- @" border-style: solid;"
- @"}"
- ]] attributes:[NSArray arrayWithObject:
- [NSXMLNode attributeWithName:@"type" stringValue:@"text/css"]]]];
-
- NSXMLElement *titleelem = [NSXMLNode elementWithName:@"title" stringValue:title];
- [head addChild:titleelem];
-
- NSXMLElement *body = [NSXMLNode elementWithName:@"body"];
- [root addChild:body];
-
-
- NSXMLElement *formnode = [NSXMLNode elementWithName:@"form" children:nil attributes:[NSArray arrayWithObjects:
- [NSXMLNode attributeWithName:@"action" stringValue:@"http://www.adium.im/XMPP/form"],
- [NSXMLNode attributeWithName:@"method" stringValue:@"POST"],nil]];
- [body addChild:formnode];
+ [self showWindow:nil];
- NSXMLElement *formwrapper = [NSXMLNode elementWithName:@"div"];
- [formwrapper addAttribute:[NSXMLNode attributeWithName:@"id" stringValue:@"formwrapper"]];
- [formnode addChild:formwrapper];
- NSXMLElement *form2 = [NSXMLNode elementWithName:@"div"];
- [form2 addAttribute:[NSXMLNode attributeWithName:@"id" stringValue:@"form2"]];
- [formwrapper addChild:form2];
+ [primaryTextField setStringValue:primary ?: @""];
- formwrapper = form2;
-
- NSXMLElement *heading = [NSXMLNode elementWithName:@"h1" stringValue:title];
- [formwrapper addChild:heading];
-
- NSXMLElement *heading2 = [NSXMLNode elementWithName:@"h2" stringValue:primary];
- [formwrapper addChild:heading2];
-
- NSXMLElement *heading3 = [NSXMLNode elementWithName:@"h3" stringValue:secondary];
- [formwrapper addChild:heading3];
-
- NSXMLElement *formdiv = [NSXMLNode elementWithName:@"div"];
- [formdiv addAttribute:[NSXMLNode attributeWithName:@"id" stringValue:@"formtable"]];
- [formwrapper addChild:formdiv];
+ if (secondary && ![secondary isEqualToString:primary]) {
+ [secondaryTextField setStringValue:secondary];
+ } else {
+ [secondaryTextField setStringValue:@""];
+ }
// load field objects
- fieldobjects = [[NSMutableDictionary alloc] init];
+ fieldobjects = [[NSMutableArray alloc] init];
More information about the commits
mailing list