Finished vList implementation

Monotone-Parent: 2570bc0c998646aa6c0501c971a29d77357cb7a1
Monotone-Revision: b798ab587b14c946102732e79770636904870654

Monotone-Author: crobert@inverse.ca
Monotone-Date: 2009-08-24T20:26:52
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
C Robert 2009-08-24 20:26:52 +00:00
parent 2f39baacc1
commit 7a4b84b9b6
22 changed files with 571 additions and 48 deletions

View File

@ -1,3 +1,10 @@
2009-08-24 Cyril Robert <crobert@inverse.ca>
* UI/MailerUI/UIxMailMainFrame.m: Refactoring + added vLists support.
* UI/Contacts/UIxListEditor.m: Implementation.
* UI/Contacts/UIxContactsListView.m (contactSearchAction): added to support
search in a single folder.
2009-08-21 Cyril Robert <crobert@inverse.ca>
* UI/Contacts/UIxListView.m: Implementation, allows VLISTs to be displayed.

View File

@ -168,3 +168,12 @@
"Forbidden" = "Você não pode gravar neste catálogo.";
"Invalid Contact" = "O contato selecionado não existe.";
"Unknown Destination Folder" = "O catálogo de destino selecionado não existe.";
/* Lists */
"List details" = "List details";
"List name:" = "List name:";
"List nickname:" = "List nickname:";
"List description:" = "List description:";
"Members" = "Members";
"Contacts" = "Contacts";
"Add" = "Add";

View File

@ -168,3 +168,12 @@
"Forbidden" = "Nemůžete zapisovat do tohoto adresáře.";
"Invalid Contact" = "Označený kontakt již neexistuje.";
"Unknown Destination Folder" = "Zvolený cílový adresář již neexistuje.";
/* Lists */
"List details" = "List details";
"List name:" = "List name:";
"List nickname:" = "List nickname:";
"List description:" = "List description:";
"Members" = "Members";
"Contacts" = "Contacts";
"Add" = "Add";

View File

@ -168,3 +168,12 @@
"Forbidden" = "You cannot write to this address book.";
"Invalid Contact" = "The selected contact no longer exists.";
"Unknown Destination Folder" = "The chosen destination address book no longer exists.";
/* Lists */
"List details" = "List details";
"List name:" = "List name:";
"List nickname:" = "List nickname:";
"List description:" = "List description:";
"Members" = "Members";
"Contacts" = "Contacts";
"Add" = "Add";

View File

@ -168,3 +168,12 @@
"Forbidden" = "You cannot write to this address book.";
"Invalid Contact" = "The selected contact no longer exists.";
"Unknown Destination Folder" = "The chosen destination address book no longer exists.";
/* Lists */
"List details" = "List details";
"List name:" = "List name:";
"List nickname:" = "List nickname:";
"List description:" = "List description:";
"Members" = "Members";
"Contacts" = "Contacts";
"Add" = "Add";

View File

@ -168,3 +168,12 @@
"Forbidden" = "Vous ne pouvez pas ajouter de fiches à ce carnet.";
"Invalid Contact" = "La fiche sélectionnée n'existe plus.";
"Unknown Destination Folder" = "Le carnet d'adresses choisi n'existe plus.";
/* Lists */
"List details" = "Détails";
"List name:" = "Liste:";
"List nickname:" = "Surnom:";
"List description:" = "Description:";
"Members" = "Membres";
"Contacts" = "Contacts";
"Add" = "Ajouter";

View File

@ -168,3 +168,12 @@
"Forbidden" = "Sie können nicht auf dieses Adressbuch schreiben.";
"Invalid Contact" = "Der gewählte Kontakt existiert nicht mehr.";
"Unknown Destination Folder" = "Das gewählte Ziel-Adressbuch existiert nicht mehr.";
/* Lists */
"List details" = "List details";
"List name:" = "List name:";
"List nickname:" = "List nickname:";
"List description:" = "List description:";
"Members" = "Members";
"Contacts" = "Contacts";
"Add" = "Add";

View File

@ -168,3 +168,12 @@
"Forbidden" = "Ön nem írhat ebbe a címjegyzékbe.";
"Invalid Contact" = "A kijelölt kapcsolat már nem létezik.";
"Unknown Destination Folder" = "A kijelölt címjegyzék már nem elérhető.";
/* Lists */
"List details" = "List details";
"List name:" = "List name:";
"List nickname:" = "List nickname:";
"List description:" = "List description:";
"Members" = "Members";
"Contacts" = "Contacts";
"Add" = "Add";

View File

@ -168,3 +168,12 @@
"Forbidden" = "You cannot write to this address book.";
"Invalid Contact" = "The selected contact no longer exists.";
"Unknown Destination Folder" = "The chosen destination address book no longer exists.";
/* Lists */
"List details" = "List details";
"List name:" = "List name:";
"List nickname:" = "List nickname:";
"List description:" = "List description:";
"Members" = "Members";
"Contacts" = "Contacts";
"Add" = "Add";

View File

@ -153,3 +153,12 @@
"Forbidden" = "You cannot write to this address book.";
"Invalid Contact" = "The selected contact no longer exists.";
"Unknown Destination Folder" = "The chosen destination address book no longer exists.";
/* Lists */
"List details" = "List details";
"List name:" = "List name:";
"List nickname:" = "List nickname:";
"List description:" = "List description:";
"Members" = "Members";
"Contacts" = "Contacts";
"Add" = "Add";

View File

@ -168,3 +168,12 @@
"Forbidden" = "You cannot write to this address book.";
"Invalid Contact" = "The selected contact no longer exists.";
"Unknown Destination Folder" = "The chosen destination address book no longer exists.";
/* Lists */
"List details" = "List details";
"List name:" = "List name:";
"List nickname:" = "List nickname:";
"List description:" = "List description:";
"Members" = "Members";
"Contacts" = "Contacts";
"Add" = "Add";

View File

@ -7,9 +7,9 @@
onclick = "newContact(this); return false;";
tooltip = "Create a new address book card"; },
{ link = "new_list";
enabled = "NO";
label="New List";
image="new-list.png";
onclick = "newList(this); return false;";
tooltip = "Create a new list"; }
),
(

View File

@ -19,6 +19,12 @@
02111-1307, USA.
*/
#import <Foundation/Foundation.h>
#import <SoObjects/SOGo/NSArray+Utilities.h>
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
#import <SoObjects/SOGo/NSString+Utilities.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WOResponse.h>
#import <NGExtensions/NSString+misc.h>
@ -103,6 +109,66 @@
return contactInfos;
}
- (id <WOActionResults>) contactSearchAction
{
id <WOActionResults> result;
id <SOGoContactFolder> folder;
NSString *searchText, *mail;
NSDictionary *contact, *data;
NSArray *contacts, *descriptors, *sortedContacts;
NSMutableDictionary *uniqueContacts;
unsigned int i;
NSSortDescriptor *commonNameDescriptor;
searchText = [self queryParameterForKey: @"search"];
if ([searchText length] > 0)
{
NS_DURING
folder = [self clientObject];
NS_HANDLER
if ([[localException name] isEqualToString: @"SOGoDBException"])
folder = nil;
else
[localException raise];
NS_ENDHANDLER
uniqueContacts = [NSMutableDictionary dictionary];
contacts = [folder lookupContactsWithFilter: searchText
sortBy: @"c_cn"
ordering: NSOrderedAscending];
for (i = 0; i < [contacts count]; i++)
{
contact = [contacts objectAtIndex: i];
mail = [contact objectForKey: @"c_mail"];
if ([mail isNotNull] && [uniqueContacts objectForKey: mail] == nil)
[uniqueContacts setObject: contact forKey: mail];
}
if ([uniqueContacts count] > 0)
{
// Sort the contacts by display name
commonNameDescriptor = [[[NSSortDescriptor alloc] initWithKey: @"c_cn"
ascending:YES] autorelease];
descriptors = [NSArray arrayWithObjects: commonNameDescriptor, nil];
sortedContacts = [[uniqueContacts allValues] sortedArrayUsingDescriptors: descriptors];
}
else
sortedContacts = [NSArray array];
data = [NSDictionary dictionaryWithObjectsAndKeys: searchText, @"searchText",
sortedContacts, @"contacts", nil];
result = [self responseWithStatus: 200];
[(WOResponse*)result appendContentString: [data jsonRepresentation]];
}
else
result = [NSException exceptionWithHTTPStatus: 400
reason: @"missing 'search' parameter"];
return result;
}
/* actions */
- (BOOL) shouldTakeValuesFromRequest: (WORequest *) _rq

View File

@ -24,8 +24,14 @@
#define UIXLISTEDITOR_H
#import <SOGoUI/UIxComponent.h>
#import <SoObjects/Contacts/SOGoContactGCSList.h>
@interface UIxListEditor : UIxComponent
{
NGVList *list;
SOGoContactGCSList *co;
id reference;
}
@end

View File

@ -20,33 +20,204 @@
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSDictionary.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/WOResponse.h>
#import <Foundation/NSPropertyList.h>
#import <Contacts/SOGoContactGCSFolder.h>
#import <NGCards/NGVCardReference.h>
#import <NGCards/NGVList.h>
#import "UIxListEditor.h"
@implementation UIxListEditor
- (NSString *) name
{
return [list fn];
}
- (void) setName: (NSString *) newName
{
[list setFn: newName];
}
- (NSString *) nickname
{
return [list nickname];
}
- (void) setNickname: (NSString *) newName
{
[list setNickname: newName];
}
- (NSString *) description
{
return [list description];
}
- (void) setDescription: (NSString *) newDescription
{
[list setDescription: newDescription];
}
- (NSArray *) references
{
NSMutableArray *rc;
NSMutableDictionary *row;
id ref;
int i, count;
rc = [NSMutableArray array];
count = [[list cardReferences] count];
for (i = 0; i < count; i++)
{
ref = [[list cardReferences] objectAtIndex: i];
row = [NSMutableDictionary dictionary];
[row setObject: [NSString stringWithFormat: @"%@ <%@>", [ref fn], [ref email]]
forKey: @"name"];
[row setObject: [ref reference] forKey: @"id"];
[rc addObject: row];
}
return rc;
}
- (void) setReferencesValue: (NSString *) value
{
NSData *data;
NSDictionary *references;
NSArray *values, *initialReferences;
NSString *error, *currentReference;
NSPropertyListFormat format;
int i, count;
NGVCardReference *cardReference;
data = [value dataUsingEncoding: NSUTF8StringEncoding];
references = [NSPropertyListSerialization propertyListFromData: data
mutabilityOption: NSPropertyListImmutable
format: &format
errorDescription: &error];
if(!references)
{
NSLog(error);
[error release];
}
else
{
// Remove from list
initialReferences = [list cardReferences];
count = [initialReferences count];
for (i = 0; i < count; i++)
{
cardReference = [initialReferences objectAtIndex: i];
if (![[references allKeys] containsObject: [cardReference reference]])
[list deleteCardReference: cardReference];
}
// Add new objects
initialReferences = [list cardReferences];
count = [[references allKeys] count];
for (i = 0; i < count; i++)
{
currentReference = [[references allKeys] objectAtIndex: i];
if (![self cardReferences: initialReferences
contain: currentReference])
{
NSLog (@"Adding a new cardRef");
values = [references objectForKey: currentReference];
cardReference = [NGVCardReference elementWithTag: @"card"];
[cardReference setFn: [values objectAtIndex: 0]];
[cardReference setEmail: [values objectAtIndex: 1]];
[cardReference setReference: currentReference];
[list addCardReference: cardReference];
}
}
}
}
- (BOOL) cardReferences: (NSArray *) references
contain: (NSString *) ref
{
int i, count;
BOOL rc = NO;
count = [references count];
for (i = 0; i < count; i++)
{
if ([ref isEqualToString: [[references objectAtIndex: i] reference]])
{
rc = YES;
break;
}
}
return rc;
}
- (NSString *) saveURL
{
return [NSString stringWithFormat: @"%@/saveAsList",
[[self clientObject] baseURL]];
}
- (BOOL) canCreateOrModify
{
return ([co isKindOfClass: [SOGoContentObject class]]
&& [super canCreateOrModify]);
}
- (id <WOActionResults>) defaultAction
{
co = [self clientObject];
list = [co vList];
if (list)
NSLog (@"Found list");
else
return [NSException exceptionWithHTTPStatus:404 /* Not Found */
reason: @"could not open list"];
return self;
}
- (void) takeValuesFromRequest: (WORequest *) _rq
inContext: (WOContext *) _ctx
{
co = [self clientObject];
list = [co vList];
[super takeValuesFromRequest: _rq inContext: _ctx];
}
- (BOOL) shouldTakeValuesFromRequest: (WORequest *) request
inContext: (WOContext*) context
{
NSString *actionName;
actionName = [[request requestHandlerPath] lastPathComponent];
return ([[self clientObject] isKindOfClass: [SOGoContactGCSList class]]
&& [actionName hasPrefix: @"save"]);
}
#warning Could this be part of a common parent with UIxAppointment/UIxTaskEditor/UIxListEditor ?
- (id) newAction
{
NSString *objectId, *method, *uri;
id <WOActionResults> result;
SOGoContactGCSFolder *co;
co = [self clientObject];
objectId = [co globallyUniqueObjectId];
if ([objectId length] > 0)
{
method = [NSString stringWithFormat:@"%@/%@.vls/editAsList",
method = [NSString stringWithFormat:@"%@/%@.vlf/editAsList",
[co soURL], objectId];
uri = [self completeHrefForMethod: method];
result = [self redirectToLocation: uri];
@ -58,4 +229,29 @@
return result;
}
- (id <WOActionResults>) saveAction
{
id result;
NSString *jsRefreshMethod;
if (co)
{
[co save];
if ([[[[self context] request] formValueForKey: @"nojs"] intValue])
result = [self redirectToLocation: [self applicationPath]];
else
{
jsRefreshMethod
= [NSString stringWithFormat: @"refreshContacts(\"%@\")",
[co nameInContainer]];
result = [self jsCloseWithRefreshMethod: jsRefreshMethod];
}
}
else
result = [NSException exceptionWithHTTPStatus: 400 /* Bad Request */
reason: @"method cannot be invoked on "
@"the specified object"];
return result;
}
@end

View File

@ -152,3 +152,12 @@
"Forbidden" = "Ni fedrwch ysgrifennu i'r llyfr cyfeiriadau hwn.";
"Invalid Contact" = "Nid yw'r cyswllt dewisol yn bodoli mwyach.";
"Unknown Destination Folder" = "Nid yw'r llyfr cyfeiriadau dewisol yn bodoli mwyach.";
/* Lists */
"List details" = "List details";
"List name:" = "List name:";
"List nickname:" = "List nickname:";
"List description:" = "List description:";
"Members" = "Members";
"Contacts" = "Contacts";
"Add" = "Add";

View File

@ -78,6 +78,11 @@
protectedBy = "View";
pageName = "UIxContactsListView";
};
contactSearch = {
protectedBy = "<public>";
pageName = "UIxContactsListView";
actionName = "contactSearch";
};
newcontact = {
protectedBy = "<public>";
pageName = "UIxContactEditor";

View File

@ -25,6 +25,7 @@
#import <Foundation/NSUserDefaults.h>
#import <NGCards/NGVCard.h>
#import <NGCards/NGVList.h>
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WORequest.h>
#import <NGObjWeb/WOResponse.h>
@ -32,6 +33,8 @@
#import <NGExtensions/NSString+misc.h>
#import <Contacts/SOGoContactObject.h>
#import <Contacts/SOGoContactGCSList.h>
#import <Contacts/SOGoContactGCSEntry.h>
#import <Contacts/SOGoContactFolders.h>
#import <SoObjects/Mailer/SOGoMailObject.h>
@ -154,18 +157,18 @@
- (id <WOActionResults>) composeAction
{
id <SOGoContactObject> contact;
NSArray *accounts, *contactsId, *n;
NSString *firstAccount, *newLocation, *parameters, *folderId, *uid, *email;
NSMutableString *fn;
id contact;
NSArray *accounts, *contactsId, *cards;
NSString *firstAccount, *newLocation, *parameters, *folderId, *uid;
NSEnumerator *uids;
NSMutableArray *addresses;
NGVCard *card;
NGVList *list;
SOGoMailAccounts *co;
SOGoContactFolders *folders;
SOGoParentFolder *folder;
WORequest *request;
unsigned int max;
int i, count;
parameters = nil;
co = [self clientObject];
@ -198,43 +201,21 @@
contact = [folder lookupName: uid
inContext: [self context]
acquire: NO];
if (![(NSObject*)contact isKindOfClass: [NSException class]])
if ([contact isKindOfClass: [SOGoContactGCSList class]])
{
list = [contact vList];
cards = [list cardReferences];
count = [cards count];
for (i = 0; i < count; i++)
[addresses addObject:
[self formattedMailtoString: [cards objectAtIndex: i]]];
}
else if ([contact isKindOfClass: [SOGoContactGCSEntry class]])
{
// We fetch the preferred email address of the contact or
// the first defined email address
card = [contact vCard];
email = [card preferredEMail];
if (email == nil)
email = (NSString*)[card firstChildWithTag: @"EMAIL"];
if (email)
{
email = [NSString stringWithFormat: @"<%@>", email];
// We append the contact's name
fn = [NSMutableString stringWithString: [card fn]];
if ([fn length] == 0)
{
n = [card n];
if (n)
{
max = [n count];
if (max > 0)
{
if (max > 1)
fn = [NSMutableString stringWithFormat: @"%@ %@", [n objectAtIndex: 1], [n objectAtIndex: 0]];
else
fn = [NSMutableString stringWithString: [n objectAtIndex: 0]];
}
}
}
if (fn)
{
[fn appendFormat: @" %@", email];
[addresses addObject: fn];
}
else
[addresses addObject: email];
}
[addresses addObject: [self formattedMailtoString: card]];
}
uid = [uids nextObject];
}
@ -259,6 +240,54 @@
return [self redirectToLocation: newLocation];
}
- (NSString *) formattedMailtoString: (NGVCard *) card
{
NSString *email;
NSMutableString *fn, *rc = nil;
NSArray *n;
unsigned int max;
if ([card respondsToSelector: @selector (preferredEMail)])
email = [card preferredEMail];
else
email = [card email];
if (email == nil)
email = (NSString*)[card firstChildWithTag: @"EMAIL"];
if (email)
{
email = [NSString stringWithFormat: @"<%@>", email];
// We append the contact's name
fn = [NSMutableString stringWithString: [card fn]];
if ([fn length] == 0)
{
n = [card n];
if (n)
{
max = [n count];
if (max > 0)
{
if (max > 1)
fn = [NSMutableString stringWithFormat: @"%@ %@", [n objectAtIndex: 1], [n objectAtIndex: 0]];
else
fn = [NSMutableString stringWithString: [n objectAtIndex: 0]];
}
}
}
if (fn)
{
[fn appendFormat: @" %@", email];
rc = fn;
}
else
rc = email;
}
return rc;
}
- (WOResponse *) getFoldersStateAction
{
NSString *expandedFolders;

View File

@ -9,4 +9,67 @@
className="UIxPageFrame"
title="name"
const:popup="YES"
>Unimplemented</var:component>
const:jsFiles="UIxMailEditor.js"
>
<div class="popupMenu" id="contactsMenu">
<ul></ul>
</div>
<form var:href="saveURL" name="editform"
onsubmit="return validateListEditor();">
<div id="listEditor">
<h3><var:string label:value="List details" /></h3>
<table><tr><td><var:string label:value="List name:"/></td>
<td><input type="text" const:id="name" const:name="name"
var:value="name" class="textField" /></td></tr>
<tr><td><var:string label:value="List nickname:"/></td>
<td><input type="text" const:id="nickname" const:name="nickname"
var:value="nickname" class="textField" /></td></tr>
<tr><td><var:string label:value="List description:"/></td>
<td><input type="text" const:id="description" const:name="description"
var:value="description" class="textField" /></td></tr>
</table>
<h3><var:string label:value="Members" /></h3>
<div id="referenceListWrapper">
<table id="referenceList" cellspacing="0">
<thead>
<tr class="tableview">
<td const:class="tbtv_headercell" const:id="nameTableHeader">
<var:string label:value="Contacts" />
</td>
</tr>
</thead>
<tbody>
<var:foreach list="references" item="reference">
<tr const:class="referenceListRow">
<td const:class="referenceListCell" var:card="reference.id">
<var:string var:value="reference.name"/>
</td></tr>
</var:foreach>
</tbody>
</table>
</div>
</div>
<input type="hidden" name="referencesValue" id="referencesValue"
var:value="referencesValue" />
<div id="windowButtons">
<label><input type="button" class="button"
id="referenceAdd" label:value="Add"/></label>
<label><input type="button" class="button"
id="referenceDelete" label:value="Delete"/></label>
</div>
<div id="buttons">
<input
id="cancelButton"
type="button"
class="button"
label:value="Cancel"
name="cancel"/>
<var:if condition="canCreateOrModify"
><input
type="submit"
class="button"
label:value="Save"
name="submit" /></var:if>
</div>
</form>
</var:component>

View File

@ -501,6 +501,11 @@ function newContact(sender) {
return false; /* stop following the link */
}
function newList(sender) {
openContactWindow(URLForFolderID(Contact.currentAddressBook) + "/newlist");
return false;
}
function onFolderSelectionChange(event) {
var folderList = $("contactFolders");
var nodes = folderList.getSelectedNodes();
@ -1039,8 +1044,10 @@ function onDocumentKeydown(event) {
function fixSearchFieldPosition () {
var panel = $("filterPanel");
panel.style.position = "relative";
panel.style.top = "3px";
if (panel) {
panel.style.position = "relative";
panel.style.top = "3px";
}
}
function initContacts(event) {

View File

@ -360,9 +360,33 @@ function onContactBlur(event) {
MailEditor.currentField = null;
}
function findPos(obj) {
var curleft = curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
}
return [curleft,curtop];
}
function performSearch() {
// Perform address completion
if (MailEditor.currentField) {
var reference = $("referenceList");
if (reference) {
var field = reference.down ("TD.editing INPUT");
if (field && field.value.trim().length > 2) {
/*var pos = findPos (field);
$('contactsMenu').absolutize ();
$('contactsMenu').style.top = pos[1];*/
var urlstr = window.location.href + "/../../contactSearch?search="
+ encodeURIComponent (field.value.trim());
document.contactLookupAjaxRequest =
triggerAjaxRequest(urlstr, performSearchCallback, field);
}
}
else if (MailEditor.currentField) {
if (document.contactLookupAjaxRequest) {
// Abort any pending request
document.contactLookupAjaxRequest.aborted = true;
@ -402,6 +426,8 @@ function performSearchCallback(http) {
var contact = data.contacts[i];
var completeEmail = contact["c_cn"] + " <" + contact["c_mail"] + ">";
var node = new Element('li', { 'address': completeEmail });
node.writeAttribute("mail", contact["c_mail"]);
node.writeAttribute("name", contact["c_cn"]);
var matchPosition = completeEmail.toLowerCase().indexOf(data.searchText.toLowerCase());
var matchBefore = completeEmail.substring(0, matchPosition);
var matchText = completeEmail.substring(matchPosition, matchPosition + data.searchText.length);
@ -417,8 +443,8 @@ function performSearchCallback(http) {
}
// Show popup menu
var offsetScroll = Element.cumulativeScrollOffset(MailEditor.currentField);
var offset = Element.cumulativeOffset(MailEditor.currentField);
var offsetScroll = Element.cumulativeScrollOffset(input);
var offset = Element.cumulativeOffset(input);
var top = offset[1] - offsetScroll[1] + node.offsetHeight + 3;
var height = 'auto';
var heightDiff = window.height() - offset[1];
@ -445,6 +471,12 @@ function performSearchCallback(http) {
// Single result
var contact = data.contacts[0];
input.uid = contact["c_name"];
if ($("referenceList")) {
var line = $(input).ancestors().first();
line.writeAttribute ("card", contact["c_name"]);
line.writeAttribute ("name", contact["c_cn"]);
line.writeAttribute ("mail", contact["c_mail"]);
}
var completeEmail = contact["c_cn"] + " <" + contact["c_mail"] + ">";
if (contact["c_cn"].substring(0, input.value.length).toUpperCase()
== input.value.toUpperCase())
@ -469,6 +501,16 @@ function performSearchCallback(http) {
}
function onAddressResultClick(event) {
var reference = $("referenceList");
if (reference) {
var field = reference.down ("TD.editing INPUT");
var td = reference.down ("TD.editing");
td.writeAttribute ("card", this.uid);
td.writeAttribute ("mail", this.readAttribute("mail"));
td.writeAttribute ("name", this.readAttribute("name"));
field.value = $(this).readAttribute("address");
endAllEditables ();
}
if (MailEditor.currentField) {
MailEditor.currentField.uid = this.uid;
MailEditor.currentField.value = $(this).readAttribute("address");
@ -492,6 +534,7 @@ function initTabIndex(addressList, subjectField, msgArea) {
function initMailEditor() {
var list = $("attachments");
if (!list) return;
$(list).attachMenu("attachmentsMenu");
var elements = $(list).childNodesWithTag("li");
for (var i = 0; i < elements.length; i++)
@ -669,6 +712,8 @@ function onSelectPriority(event) {
}
function onWindowResize(event) {
if (!document.pageform)
return;
var textarea = document.pageform.text;
var rowheight = (Element.getHeight(textarea) / textarea.rows);
var headerarea = $("headerArea");

View File

@ -64,4 +64,4 @@ DIV#windowButtons
height: 3.5em;
line-height: 2em;
vertical-align: middle;
text-align: right; }
text-align: right; }