Merge to 2.1.1

maint-2.1.1 SOGo-2.1.1
Jean Raby 2013-11-19 14:00:22 -05:00
commit 2cf66e037d
69 changed files with 1830 additions and 806 deletions

222
ChangeLog
View File

@ -1,3 +1,225 @@
commit c8a4ea5548e06de1341312a1cabb00fb0ef232e8
Author: Francis Lachapelle <flachapelle@inverse.ca>
Date: Tue Nov 19 13:57:18 2013 -0500
Update translations
M UI/MailPartViewers/Czech.lproj/Localizable.strings
M UI/MailPartViewers/Finnish.lproj/Localizable.strings
M UI/MailPartViewers/Polish.lproj/Localizable.strings
M UI/MailPartViewers/Russian.lproj/Localizable.strings
M UI/MailPartViewers/SpanishSpain.lproj/Localizable.strings
commit 148fd4936cc648a7264ef363afccd024a9e5d177
Author: Jean Raby <jraby@inverse.ca>
Date: Tue Nov 19 13:43:45 2013 -0500
Update Version to 2.1.1 and update news
M NEWS
M Version
commit a7fef39448d0735aaf8fa9da1ad43fc96ae82efb
Author: Jean Raby <jraby@inverse.ca>
Date: Tue Nov 19 13:43:22 2013 -0500
Update to 2.1.1
M Documentation/SOGo Installation Guide.odt
M Documentation/SOGo Mobile Devices Configuration.odt
M Documentation/SOGo Mozilla Thunderbird Configuration.odt
M Documentation/SOGo Native Microsoft Outlook Configuration.odt
commit 5a3d0d27e0ecea09daa1bca791e6baaeecdf397a
Author: Francis Lachapelle <flachapelle@inverse.ca>
Date: Tue Nov 19 13:39:48 2013 -0500
Fix bug following mail tags management CSS changes
M UI/WebServerResources/SOGoTabsController.js
M UI/WebServerResources/UIxPreferences.css
M UI/WebServerResources/generic.css
commit eb9111b5fa1dcd17e8bdccec6bef595b31c6a2ec
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
Date: Tue Nov 19 11:40:33 2013 -0500
Updated news for the recent bug fix
M NEWS
commit eb7d1f08bcfe0c9de6f14042a57b8032662906c3
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
Date: Tue Nov 19 11:39:45 2013 -0500
Fix for bug #2482
M SoObjects/Mailer/SOGoDraftObject.m
M UI/MailerUI/UIxMailEditor.m
commit 854fed529c14bd70ac827520ed05a425fe99359f
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
Date: Tue Nov 19 09:52:53 2013 -0500
Added SOGoMailAuxiliaryUserAccountsEnabled
M Scripts/sogo.conf
commit 3c29e0724d89cbe102fbb11a9bb8c7d565d46b3e
Author: Jean Raby <jraby@inverse.ca>
Date: Fri Nov 15 16:12:15 2013 -0500
update news file
M NEWS
commit aae26602b0200d865ba2a9a3ea8d986d6e3b8960
Author: Jean Raby <jraby@inverse.ca>
Date: Fri Nov 15 16:04:09 2013 -0500
Use raw (utf7) name when checking folder type
M UI/MailerUI/UIxMailAccountActions.m
commit 05233d9c53b40b7c6dc685358d9438b5c0f8bcdb
Author: Jean Raby <jraby@inverse.ca>
Date: Fri Nov 15 16:02:59 2013 -0500
Use modified utf7 for special folder names
M SoObjects/SOGo/SOGoUserDefaults.m
commit e862194b323ef09bf318243cfca96e802c89dd26
Author: Francis Lachapelle <flachapelle@inverse.ca>
Date: Fri Nov 15 15:50:46 2013 -0500
Convert color picker to an inline widget
The colors are now limited to the colors offered in Thunderbird.
M NEWS
M UI/Scheduler/GNUmakefile
D UI/Scheduler/UIxColorPicker.h
D UI/Scheduler/UIxColorPicker.m
M UI/Scheduler/product.plist
M UI/Templates/PreferencesUI/UIxPreferences.wox
M UI/Templates/SchedulerUI/UIxCalendarProperties.wox
M UI/WebServerResources/SchedulerUI.js
M UI/WebServerResources/UIxCalendarProperties.css
M UI/WebServerResources/UIxCalendarProperties.js
M UI/WebServerResources/UIxPreferences.css
M UI/WebServerResources/UIxPreferences.js
M UI/WebServerResources/generic.css
D UI/WebServerResources/js_color_picker_v2.css
commit 884fbfdb7359db6a24057a4f958db6a563e04944
Author: Jean Raby <jraby@inverse.ca>
Date: Fri Nov 15 13:17:37 2013 -0500
Bump copyright and fix whitespace (tab kill)
M UI/MailerUI/UIxMailAccountActions.m
commit c05cf00db7b1f5878cac9130cadbebbf0649b8dc
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
Date: Thu Nov 14 09:00:19 2013 -0500
Update standard tag colors to match TB and improve tags id generation.
M SoObjects/SOGo/SOGoDefaults.plist
M UI/WebServerResources/UIxPreferences.js
commit 198db855f6aad1dd9bd0f9d482ef7f0a6783a677
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
Date: Wed Nov 13 15:55:25 2013 -0500
Specify color in which TB can grok it.
M SoObjects/SOGo/SOGoDefaults.plist
commit 1c439c866efc5e639e7b3bc1259fb442942d0e19
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
Date: Wed Nov 13 15:44:57 2013 -0500
Added DAV support for mails labels.
M SoObjects/Contacts/SOGoContactFolders.m
M SoObjects/Mailer/SOGoMailAccount.h
M SoObjects/Mailer/SOGoMailAccount.m
M SoObjects/Mailer/SOGoMailAccounts.h
M SoObjects/Mailer/SOGoMailAccounts.m
M SoObjects/Mailer/SOGoMailNamespace.m
M SoObjects/Mailer/product.plist
M SoObjects/SOGo/NSDictionary+DAV.m
M SoObjects/SOGo/NSObject+DAV.h
M SoObjects/SOGo/NSObject+DAV.m
M SoObjects/SOGo/NSString+DAV.h
M SoObjects/SOGo/NSString+Utilities.m
M SoObjects/SOGo/SOGoDefaults.plist
M SoObjects/SOGo/SOGoObject.m
M SoObjects/SOGo/SOGoWebDAVValue.m
M UI/Templates/MailerUI/UIxMailMainFrame.wox
commit 616ee7c6e4d42ad8258c66eed11446a48981fba1
Author: Francis Lachapelle <flachapelle@inverse.ca>
Date: Wed Nov 13 14:46:08 2013 -0500
GUI changes for mail labels management
M NEWS
M UI/Templates/MailerUI/UIxMailMainFrame.wox
M UI/Templates/PreferencesUI/UIxPreferences.wox
M UI/Templates/SchedulerUI/UIxCalendarSelector.wox
M UI/WebServerResources/MailerUI.css
M UI/WebServerResources/SOGoTabsController.js
M UI/WebServerResources/SchedulerUI.css
M UI/WebServerResources/SchedulerUI.js
M UI/WebServerResources/UIxPreferences.css
M UI/WebServerResources/UIxPreferences.js
M UI/WebServerResources/generic.css
M UI/WebServerResources/iefixes.css
commit 37d3234b6067df7047ef5035e8f28f7906de893b
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
Date: Mon Nov 11 10:49:58 2013 -0500
Added support for dynamic mail labels/tags management.
The CSS in the UIxPreferences remains to be done.
M SoObjects/Mailer/GNUmakefile
A SoObjects/Mailer/SOGoMailLabel.h
A SoObjects/Mailer/SOGoMailLabel.m
M SoObjects/SOGo/SOGoDefaults.plist
M SoObjects/SOGo/SOGoUserDefaults.h
M SoObjects/SOGo/SOGoUserDefaults.m
M UI/MailerUI/UIxMailActions.h
M UI/MailerUI/UIxMailActions.m
M UI/MailerUI/UIxMailListActions.m
M UI/MailerUI/UIxMailMainFrame.h
M UI/MailerUI/UIxMailMainFrame.m
M UI/MailerUI/product.plist
M UI/PreferencesUI/English.lproj/Localizable.strings
M UI/PreferencesUI/UIxFilterEditor.m
M UI/PreferencesUI/UIxPreferences.h
M UI/PreferencesUI/UIxPreferences.m
M UI/Templates/MailerUI/UIxMailMainFrame.wox
M UI/Templates/PreferencesUI/UIxFilterEditor.wox
M UI/Templates/PreferencesUI/UIxPreferences.wox
M UI/WebServerResources/MailerUI.css
M UI/WebServerResources/MailerUI.js
M UI/WebServerResources/UIxColorPicker.js
M UI/WebServerResources/UIxFilterEditor.js
M UI/WebServerResources/UIxPreferences.js
commit 6a9bcfda684135e518dc4f63b15926c1d4d06fa0
Author: Francis Lachapelle <flachapelle@inverse.ca>
Date: Thu Nov 7 14:42:48 2013 -0500
Update ChangeLog
M ChangeLog
commit d0b09ebe35d9bde78f627b6569660627c60c8e42
Author: Francis Lachapelle <flachapelle@inverse.ca>
Date: Thu Nov 7 14:14:39 2013 -0500

17
NEWS
View File

@ -1,3 +1,18 @@
2.1.1 (2013-11-19)
------------------
New features
- creation and modification of mail labels
Enhancements
- the color picker is no longer a popup window
Bug fixes
- fixed utf8 character handling in special folder names
Special folder names can now be set as UTF8 or modified UTF7 in sogo.conf
- fixed reply-to header not being set for auxiliary IMAP accounts
- fixed handling of broken/invalid email addresses
2.1.0 (2013-11-07)
------------------
@ -32,7 +47,7 @@ Bug fixes
- fixed S/MIME verification issues with certain OpenSSL versions
- worked around an issue with chunked encoding of CAS replies (#2408)
- fixed OpenChange corruption issue regarding predecessors change list (#2405)
- avoid unnecessary UTF-7 conversions (#2318)
- avoid unnecessary UTF-7 conversions (#2318)
- improved RTF parser to fix vCards (#2354)
- fixed definition of the COMPLETED attribute of vTODO (#2240)
- fixed DAV:resource-id property when sharing calendars (#2399)

View File

@ -84,6 +84,7 @@
//SOGoVacationEnabled = YES;
//SOGoForwardEnabled = YES;
//SOGoSieveScriptsEnabled = YES;
//SOGoMailAuxiliaryUserAccountsEnabled = YES;
/* General */
//SOGoLanguage = English;

View File

@ -1,8 +1,6 @@
/* SOGoContactFolders.m - this file is part of SOGo
*
* Copyright (C) 2006-2011 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2006-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,13 +18,6 @@
* Boston, MA 02111-1307, USA.
*/
/* MailItems IPF.Note
ContactItems IPF.Contact
AppointmentItems IPF.Appointment
NoteItems IPF.StickyNote
TaskItems IPF.Task
JournalItems IPF.Journal */
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
@ -50,6 +41,7 @@
#import "SOGoContactFolders.h"
#define XMLNS_INVERSEDAV @"urn:inverse:params:xml:ns:inverse-dav"
@implementation SOGoContactFolders
+ (NSString *) gcsFolderType

View File

@ -16,6 +16,7 @@ Mailer_OBJC_FILES += \
SOGoMailAccounts.m \
SOGoMailAccount.m \
SOGoMailFolder.m \
SOGoMailLabel.m \
SOGoMailNamespace.m \
SOGoMailObject.m \
SOGoMailObject+Draft.m \

View File

@ -619,11 +619,40 @@ static NSString *userAgent = nil;
TODO: what about sender (RFC 822 3.6.2)
*/
NSMutableArray *to, *addrs, *allRecipients;
NSArray *envelopeAddresses, *userEmails;
NSArray *envelopeAddresses;
allRecipients = [NSMutableArray array];
userEmails = [[context activeUser] allEmails];
[allRecipients addObjectsFromArray: userEmails];
//
// When we do a Reply-To or a Reply-To-All, we strip our own addresses
// from the list of recipients so we don't reply to ourself! We check
// which addresses we should use - that is the ones for the current
// user if we're dealing with the default "SOGo mail account" or
// the ones specified in the auxiliary IMAP accounts
//
if ([[[self->container mailAccountFolder] nameInContainer] intValue] == 0)
{
NSArray *userEmails;
userEmails = [[context activeUser] allEmails];
[allRecipients addObjectsFromArray: userEmails];
}
else
{
NSArray *identities;
NSString *email;
int i;
identities = [[[self container] mailAccountFolder] identities];
for (i = 0; i < [identities count]; i++)
{
email = [[identities objectAtIndex: i] objectForKey: @"email"];
if (email)
[allRecipients addObject: email];
}
}
to = [NSMutableArray arrayWithCapacity: 2];
@ -634,20 +663,19 @@ static NSString *userAgent = nil;
else
[addrs setArray: [_envelope from]];
[self _purgeRecipients: allRecipients
fromAddresses: addrs];
[self _addEMailsOfAddresses: addrs toArray: to];
[self _addRecipients: addrs toArray: allRecipients];
[_info setObject: to forKey: @"to"];
[self _purgeRecipients: allRecipients fromAddresses: addrs];
[self _addEMailsOfAddresses: addrs toArray: to];
[self _addRecipients: addrs toArray: allRecipients];
[_info setObject: to forKey: @"to"];
/* If "to" is empty, we add at least ourself as a recipient!
This is for emails in the "Sent" folder that we reply to... */
if (![to count])
{
if ([[_envelope replyTo] count])
[self _addEMailsOfAddresses: [_envelope replyTo] toArray: to];
[self _addEMailsOfAddresses: [_envelope replyTo] toArray: to];
else
[self _addEMailsOfAddresses: [_envelope from] toArray: to];
[self _addEMailsOfAddresses: [_envelope from] toArray: to];
}
/* If we have no To but we have Cc recipients, let's move the Cc
@ -661,7 +689,7 @@ static NSString *userAgent = nil;
[_info removeObjectForKey: @"cc"];
}
/* CC processing if we reply-to-all: add all 'to' and 'cc' */
/* CC processing if we reply-to-all: - we add all 'to' and 'cc' fields */
if (_replyToAll)
{
to = [NSMutableArray new];

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2009-2011 Inverse inc.
Copyright (C) 2009-2013 Inverse inc.
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of SOGo.

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2004-2005 SKYRIX Software AG
Copyright (C) 2007-2011 Inverse inc.
Copyright (C) 2007-2013 Inverse inc.
This file is part of SOGo.
@ -26,6 +26,9 @@
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
#import <DOM/DOMElement.h>
#import <DOM/DOMProtocols.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/SoHTTPAuthenticator.h>
#import <NGObjWeb/WORequest.h>
@ -56,6 +59,8 @@
#import "SOGoMailAccount.h"
#define XMLNS_INVERSEDAV @"urn:inverse:params:xml:ns:inverse-dav"
@implementation SOGoMailAccount
static NSString *inboxFolderName = @"INBOX";

View File

@ -1,20 +1,21 @@
/*
Copyright (C) 2009-2013 Inverse inc.
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of OpenGroupware.org.
This file is part of SOGo.
OGo is free software; you can redistribute it and/or modify it under
SOGo is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public
License along with OGo; see the file COPYING. If not, write to the
License along with SOGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/

View File

@ -1,14 +1,15 @@
/*
Copyright (C) 2004-2005 SKYRIX Software AG
Copyright (C) 2007-2013 Inverse inc.
This file is part of OpenGroupware.org.
This file is part of SOGo.
OGo is free software; you can redistribute it and/or modify it under
SOGo is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
@ -26,14 +27,20 @@
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGExtensions/NSNull+misc.h>
#import <NGExtensions/NSObject+Logs.h>
#import <DOM/DOMElement.h>
#import <DOM/DOMProtocols.h>
#import "../SOGo/NSArray+Utilities.h"
#import "../SOGo/NSObject+DAV.h"
#import "../SOGo/NSString+Utilities.h"
#import "../SOGo/SOGoUser.h"
#import "../SOGo/SOGoUserDefaults.h"
#import "SOGoMailAccount.h"
#import "SOGoMailAccounts.h"
#define XMLNS_INVERSEDAV @"urn:inverse:params:xml:ns:inverse-dav"
@implementation SOGoMailAccounts
- (NSArray *) mailAccounts
@ -92,4 +99,156 @@
return obj;
}
/*
Mail labels/tags synchronization.
Request:
<D:propfind xmlns:D="DAV:" xmlns:x0="urn:inverse:params:xml:ns:inverse-dav"><D:prop><x0:mails-labels/></D:prop></D:propfind>
Result:
<?xml version="1.0" encoding="UTF-8"?>
<D:multistatus>
<D:response>
<D:href>/SOGo/dav/sogo10/Mail/</D:href>
<D:propstat>
<D:status>HTTP/1.1 200 OK</D:status>
<D:prop>
<n1:mails-labels>
<n1:label color="#f00" id="$label1">Important</n1:label>
<n1:label color="#ff9a00" id="$label2">Work</n1:label>
<n1:label color="#009a00" id="$label3">Personal</n1:label>
<n1:label color="#3130ff" id="$label4">To Do</n1:label>
<n1:label color="#9c309c" id="$label5">Later</n1:label>
</n1:mails-labels>
</D:prop>
</D:propstat>
</D:response>
</D:multistatus>
*/
- (SOGoWebDAVValue *) davMailsLabels
{
NSDictionary *labelsFromDefaults, *labelValues, *attributes;
NSMutableArray *davMailsLabels;
NSUInteger count, max;
SOGoUser *ownerUser;
NSArray *allKeys, *values;
NSString *key;
ownerUser = [SOGoUser userWithLogin: owner];
labelsFromDefaults = [[ownerUser userDefaults] mailLabelsColors];
allKeys = [labelsFromDefaults allKeys];
max = [allKeys count];
davMailsLabels = [NSMutableArray arrayWithCapacity: max];
for (count = 0; count < max; count++)
{
key = [allKeys objectAtIndex: count];
values = [labelsFromDefaults objectForKey: key];
attributes = [NSDictionary dictionaryWithObjectsAndKeys: key, @"id",
[values objectAtIndex: 1], @"color",
nil];
labelValues = davElementWithAttributesAndContent(@"label",
attributes,
XMLNS_INVERSEDAV,
[values objectAtIndex: 0]);
[davMailsLabels addObject: labelValues];
}
return [davElementWithContent (@"mails-labels",
XMLNS_INVERSEDAV,
davMailsLabels)
asWebDAVValue];
}
/*
We get something like that:
Request:
<?xml version="1.0" encoding="UTF-8"?>
<propertyupdate xmlns="DAV:" xmlns:i="urn:inverse:params:xml:ns:inverse-dav">
<set>
<prop>
<i:mails-labels>
<i:label color="#f00" id="$label1">Important</i:label>
<i:label color="#ff9a00" id="$label2">Work</i:label>
<i:label color="#009a00" id="$label3">Personal</i:label>
<i:label color="#3130ff" id="$label4">To Do</i:label>
<i:label color="#9c309c" id="$label5">Later</i:label>
</i:mails-labels>
</prop>
</set>
</propertyupdate>
Response:
<D:multistatus>
<D:response>
<D:href>/SOGo/dav/sogo10/Mail/</D:href>
<D:propstat>
<D:prop>
<a:mails-labels/>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
</D:multistatus>
*/
- (NSException *) setDavMailsLabels: (NSString *) newLabels
{
id <DOMElement> documentElement, labelNode;
id <DOMNodeList> labelNodes;
id <DOMDocument> document;
NSString *label, *name, *color;
NSMutableDictionary *labels;
NSMutableArray *values;
SOGoUserDefaults *ud;
SOGoUser *ownerUser;
NSUInteger count, max;
labels = [NSMutableDictionary dictionary];
if ([newLabels length] > 0)
{
document = [[context request] contentAsDOMDocument];
documentElement = [document documentElement];
labelNodes = [documentElement getElementsByTagName: @"label"];
max = [labelNodes length];
for (count = 0; count < max; count++)
{
values = [NSMutableArray array];
labelNode = [labelNodes objectAtIndex: count];
label = [labelNode attribute: @"id"];
name = [labelNode textValue];
color = [labelNode attribute: @"color"];
[values addObject: name];
[values addObject: color];
[labels setObject: values forKey: label];
}
}
ownerUser = [SOGoUser userWithLogin: owner];
ud = [ownerUser userDefaults];
[ud setMailLabelsColors: labels];
[ud synchronize];
return nil;
}
@end /* SOGoMailAccounts */

View File

@ -0,0 +1,50 @@
/*
Copyright (C) 2013 Inverse inc.
This file is part of SOGo.
SOGo is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public
License along with OGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#ifndef SOGOMAILLABEL_H
#define SOGOMAILLABEL_H
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
#import "../../UI/SOGoUI/UIxComponent.h";
@interface SOGoMailLabel : NSObject
{
NSString *_name;
NSString *_label;
NSString *_color;
}
- (id) initWithName: (NSString *) theName
label: (NSString *) theLabel
color: (NSString *) theColor;
- (NSString *) name;
- (NSString *) label;
- (NSString *) color;
+ (NSArray *) labelsFromDefaults: (NSDictionary *) theDefaults
component: (UIxComponent *) theComponent;
@end
#endif // SOGOMAILLABEL_H

View File

@ -0,0 +1,96 @@
/*
Copyright (C) 2007-2013 Inverse inc.
This file is part of SOGo.
SOGo is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public
License along with OGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#import "SOGoMailLabel.h"
#import <Foundation/NSDictionary.h>
@implementation SOGoMailLabel
- (id) initWithName: (NSString *) theName
label: (NSString *) theLabel
color: (NSString *) theColor
{
self = [super init];
if (self)
{
ASSIGN(_name, theName);
ASSIGN(_label, theLabel);
ASSIGN(_color, theColor);
}
return self;
}
- (void) dealloc
{
RELEASE(_name);
RELEASE(_label);
RELEASE(_color);
[super dealloc];
}
- (NSString *) name
{
return _name;
}
- (NSString *) label
{
return _label;
}
- (NSString *) color
{
return _color;
}
+ (NSArray *) labelsFromDefaults: (NSDictionary *) theDefaults
component: (UIxComponent *) theComponent
{
NSMutableArray *allLabels, *allKeys;
NSDictionary *mailLabelsColors;
NSString *key, *name;
SOGoMailLabel *label;
NSArray *values;
int i;
allLabels = [NSMutableArray array];
allKeys = [[theDefaults allKeys] sortedArrayUsingSelector: @selector (caseInsensitiveCompare:)];
for (i = 0; i < [allKeys count]; i++)
{
key = [allKeys objectAtIndex: i];
values = [theDefaults objectForKey: key];
name = [theComponent labelForKey: [values objectAtIndex: 0]];
label = [[self alloc] initWithName: key
label: name
color: [values objectAtIndex: 1]];
[allLabels addObject: label];
RELEASE(label);
}
return allLabels;
}
@end

View File

@ -1,8 +1,6 @@
/* SOGoMailNamespace.m - this file is part of SOGo
*
* Copyright (C) 2010 Wolfgang Sourdeau
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2010-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -29,9 +29,6 @@
"WebDAV Access" = ( "Owner", "AuthorizedSubscriber" );
};
};
/* SOGoSharedMailAccount = {
superclass = "SOGoMailAccount";
}; */
SOGoMailFolder = {
superclass = "SOGoMailBaseObject";
defaultRoles = {
@ -44,9 +41,6 @@
"Change Permissions" = ( "Owner", "MailAdministrator" );
};
};
/* SOGoSharedInboxFolder = {
superclass = "SOGoMailFolder";
}; */
SOGoTrashFolder = {
superclass = "SOGoMailFolder";
};

View File

@ -1,8 +1,6 @@
/* NSDictionary+DAV.m - this file is part of SOGo
*
* Copyright (C) 2008-2009 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2008-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -59,6 +57,7 @@
- (NSString *)
asWebDavStringWithNamespaces: (NSMutableDictionary *) namespaces
{
NSDictionary *attributes;
NSMutableString *webdavString;
NSString *nsTag, *ns, *subString, *element;
BOOL firstLevel;
@ -88,6 +87,22 @@
[webdavString appendString: [self _namespaceDecl: namespaces]];
[namespaces release];
}
attributes = [self objectForKey: @"attributes"];
if (attributes)
{
NSArray *keys;
int i;
keys = [attributes allKeys];
for (i = 0; i < [keys count]; i++)
{
[webdavString appendFormat: @" %@=\"%@\"", [keys objectAtIndex: i], [attributes objectForKey: [keys objectAtIndex: i]]];
}
}
if (subString)
[webdavString appendFormat: @">%@</%@>", subString, element];
else

View File

@ -1,8 +1,6 @@
/* NSObject+DAV.h - this file is part of SOGo
*
* Copyright (C) 2008 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2008-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -47,6 +45,12 @@ typedef enum _HTTPStatusCode {
n, @"ns", \
c, @"content", nil]
#define davElementWithAttributesAndContent(t,a,n,c) \
[NSDictionary dictionaryWithObjectsAndKeys: t, @"method", \
a, @"attributes", \
n, @"ns", \
c, @"content", nil]
SEL SOGoSelectorForPropertyGetter (NSString *property);
SEL SOGoSelectorForPropertySetter (NSString *property);

View File

@ -1,8 +1,6 @@
/* NSObject+DAV.m - this file is part of SOGo
*
* Copyright (C) 2008-2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2008-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -1,8 +1,6 @@
/* NSString+DAV.h - this file is part of SOGo
*
* Copyright (C) 2008 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2008-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -314,12 +314,12 @@ static int cssEscapingCount;
int count;
strings = [NSArray arrayWithObjects: @"_U_", @"_D_", @"_H_", @"_A_", @"_S_",
@"_C_", @"_CO_", @"_SP_", @"_SQ_", @"_AM_", @"_P_", nil];
@"_C_", @"_CO_", @"_SP_", @"_SQ_", @"_AM_", @"_P_", @"_DS_", nil];
[strings retain];
cssEscapingStrings = [strings asPointersOfObjects];
characters = [NSArray arrayWithObjects: @"_", @".", @"#", @"@", @"*", @":",
@",", @" ", @"'", @"&", @"+", nil];
@",", @" ", @"'", @"&", @"+", @"$", nil];
cssEscapingCount = [strings count];
cssEscapingCharacters = NSZoneMalloc (NULL,
(cssEscapingCount + 1)

View File

@ -76,4 +76,12 @@
SOGoRemindWithASound = YES;
SOGoSearchMinimumWordLength = 2;
SOGoMailLabelsColors = {
$label1 = ("Important", "#FF0000");
$label2 = ("Work", "#FF9900");
$label3 = ("Personal", "#009900");
$label4 = ("To Do", "#3333FF");
$label5 = ("Later", "#993399");
};
}

View File

@ -1,9 +1,7 @@
/* SOGoObject.m - this file is part of SOGo
*
* Copyright (C) 2004-2005 SKYRIX Software AG
* Copyright (C) 2006-2009 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2006-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -1,8 +1,6 @@
/* SOGoUserDefaults.h - this file is part of SOGo
*
* Copyright (C) 2011-2012 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2011-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -166,6 +164,9 @@ extern NSString *SOGoWeekStartFirstFullWeek;
- (void) setForwardOptions: (NSDictionary *) newValue;
- (NSDictionary *) forwardOptions;
- (void) setMailLabelsColors: (NSDictionary *) newValues;
- (NSDictionary *) mailLabelsColors;
/* calendar */
- (void) setCalendarCategories: (NSArray *) newValues;
- (NSArray *) calendarCategories;

View File

@ -1,8 +1,6 @@
/* SOGoUserDefaults.m - this file is part of SOGo
*
* Copyright (C) 2009-2012 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2009-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -26,6 +24,8 @@
#import <Foundation/NSString.h>
#import <Foundation/NSTimeZone.h>
#import <NGImap4/NSString+Imap4.h>
#import "NSString+Utilities.h"
#import "SOGoDomainDefaults.h"
#import "SOGoSystemDefaults.h"
@ -420,7 +420,8 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek";
- (NSString *) draftsFolderName
{
return [self stringForKey: @"SOGoDraftsFolderName"];
return [[self stringForKey: @"SOGoDraftsFolderName"]
stringByEncodingImap4FolderName];
}
- (void) setSentFolderName: (NSString *) newValue
@ -430,7 +431,8 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek";
- (NSString *) sentFolderName
{
return [self stringForKey: @"SOGoSentFolderName"];
return [[self stringForKey: @"SOGoSentFolderName"]
stringByEncodingImap4FolderName];
}
- (void) setTrashFolderName: (NSString *) newValue
@ -440,7 +442,8 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek";
- (NSString *) trashFolderName
{
return [self stringForKey: @"SOGoTrashFolderName"];
return [[self stringForKey: @"SOGoTrashFolderName"]
stringByEncodingImap4FolderName];
}
- (void) setFirstDayOfWeek: (int) newValue
@ -733,6 +736,26 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek";
return [self boolForKey: @"SOGoRemindWithASound"];
}
//
// Dictionary of arrays. Example:
//
// {
// label1 => ("Important", "#FF0000");
// label2 => ("Work" "#00FF00");
// foo_bar => ("Foo Bar", "#0000FF");
// }
//
- (void) setMailLabelsColors: (NSDictionary *) newValues
{
[self setObject: newValues forKey: @"SOGoMailLabelsColors"];
}
- (NSDictionary *) mailLabelsColors
{
return [self objectForKey: @"SOGoMailLabelsColors"];
}
- (void) setSieveFilters: (NSArray *) newValue
{
[self setObject: newValue forKey: @"SOGoSieveFilters"];

View File

@ -1,8 +1,6 @@
/* SOGoWebDAVValue.m - this file is part of $PROJECT_NAME_HERE$
*
* Copyright (C) 2008 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2008-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -12,6 +12,8 @@ publish_info_text = "Odesílatel Vás informuje o přiložené události.";
cancel_info_text = "Vaše pozvánka nebo celá událost byla zrušena.";
request_info_no_attendee = "navrhuje setkání účastníků. Tento mail jste obdrželi jako oznámení, nejste nastaveni jako účastník.";
Appointment = "Schůzka";
"Status Update" = "Aktualizace stavu";
was = "bylo";
Organizer = "Organizátor";
Time = "Čas";

View File

@ -12,6 +12,8 @@ publish_info_text = "Lähettäjä ilmoittaa sinulle liitteenä olevan tapahtuman
cancel_info_text = "Kutsusi tai tapahtuma on peruttu.";
request_info_no_attendee = "ehdottaa kokousta osallistujille. Saat tämän sähköpostin ilmoituksena, et osallistujana.";
Appointment = "Tapahtuma";
"Status Update" = "Tilapäivitys";
was = "oli";
Organizer = "Järjestäjä";
Time = "Aika";

View File

@ -12,6 +12,8 @@ publish_info_text = "Nadawca informuje cię o załączonym wydarzeniu.";
cancel_info_text = "Twoje zaproszenie lub całe wydarzenie zostało anulowane.";
request_info_no_attendee = "proponuje uczestnikom spotkanie. Otrzymujesz tę wiadomość jako powiadomienie, nie jesteś planowany jako uczestnik.";
Appointment = "Spotkanie";
"Status Update" = "Aktualizacja Statusu";
was = "było";
Organizer = "Organizator";
Time = "Czas";

View File

@ -12,6 +12,8 @@ publish_info_text = "Отправитель сообщает о приложен
cancel_info_text = "Ваше приглашение или все мероприятие отменено.";
request_info_no_attendee = "предлагает участникам встретиться. Вы получили это сообщение как приглашенное лицо. Вы еще не включены в список подтвержденных участников.";
Appointment = "Встреча";
"Status Update" = "Обновление статуса";
was = "был";
Organizer = "Организатор";
Time = "Время";

View File

@ -12,6 +12,8 @@ publish_info_text = "El remitente le informa del evento adjunto.";
cancel_info_text = "Su invitación o el evento ha sido cancelado.";
request_info_no_attendee = "ha propuesto un evento a los participantes. Ud recibe este correo como notificación, pero no aparece como participante.";
Appointment = "Cita";
"Status Update" = "Actualización de Estado";
was = "estaba";
Organizer = "Organizador";
Time = "Hora";

View File

@ -1,6 +1,6 @@
/* UIxMailAccountActions.m - this file is part of SOGo
*
* Copyright (C) 2007-2011 Inverse inc.
* Copyright (C) 2007-2013 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Ludovic Marcotte <lmarcotte@inverse.ca>
@ -87,21 +87,21 @@
{
co = [self clientObject];
specialFolders = [[NSArray arrayWithObjects:
[co inboxFolderNameInContext: context],
[co draftsFolderNameInContext: context],
[co sentFolderNameInContext: context],
[co trashFolderNameInContext: context],
[co otherUsersFolderNameInContext: context],
[co sharedFoldersNameInContext: context],
nil] stringsWithFormat: @"/%@"];
[co inboxFolderNameInContext: context],
[co draftsFolderNameInContext: context],
[co sentFolderNameInContext: context],
[co trashFolderNameInContext: context],
[co otherUsersFolderNameInContext: context],
[co sharedFoldersNameInContext: context],
nil] stringsWithFormat: @"/%@"];
ASSIGN(inboxFolderName, [specialFolders objectAtIndex: 0]);
ASSIGN(draftsFolderName, [specialFolders objectAtIndex: 1]);
ASSIGN(sentFolderName, [specialFolders objectAtIndex: 2]);
ASSIGN(trashFolderName, [specialFolders objectAtIndex: 3]);
if ([specialFolders count] > 4)
ASSIGN(otherUsersFolderName, [specialFolders objectAtIndex: 4]);
ASSIGN(otherUsersFolderName, [specialFolders objectAtIndex: 4]);
if ([specialFolders count] > 5)
ASSIGN(sharedFoldersName, [specialFolders objectAtIndex: 5]);
ASSIGN(sharedFoldersName, [specialFolders objectAtIndex: 5]);
}
if ([folderName isEqualToString: inboxFolderName])
@ -141,48 +141,50 @@
pool = [[NSAutoreleasePool alloc] init];
currentDecodedFolder = [currentFolder stringByDecodingImap4FolderName];
currentFolderType = [self _folderType: currentDecodedFolder];
currentFolderType = [self _folderType: currentFolder];
// We translate the "Other Users" and "Shared Folders" namespaces.
// While we're at it, we also translate the user's mailbox names
// to the full name of the person.
if (otherUsersFolderName && [currentDecodedFolder hasPrefix: otherUsersFolderName])
{
// We have a string like /Other Users/lmarcotte/... under Cyrus, but we could
// also have something like /shared under Dovecot. So we swap the username only
// if we have one, of course.
pathComponents = [NSMutableArray arrayWithArray: [currentDecodedFolder pathComponents]];
if ([pathComponents count] > 2)
{
login = [pathComponents objectAtIndex: 2];
userManager = [SOGoUserManager sharedUserManager];
fullName = [userManager getCNForUID: login];
[pathComponents removeObjectsInRange: NSMakeRange(0,3)];
currentDisplayName = [NSString stringWithFormat: @"/%@/%@/%@",
[self labelForKey: @"OtherUsersFolderName"],
(fullName != nil ? fullName : login),
[pathComponents componentsJoinedByString: @"/"]];
}
else
{
currentDisplayName = [NSString stringWithFormat: @"/%@%@", [self labelForKey: @"OtherUsersFolderName"],
[currentDecodedFolder substringFromIndex: [otherUsersFolderName length]]];
}
}
{
// We have a string like /Other Users/lmarcotte/... under Cyrus, but we could
// also have something like /shared under Dovecot. So we swap the username only
// if we have one, of course.
pathComponents = [NSMutableArray arrayWithArray: [currentDecodedFolder pathComponents]];
if ([pathComponents count] > 2)
{
login = [pathComponents objectAtIndex: 2];
userManager = [SOGoUserManager sharedUserManager];
fullName = [userManager getCNForUID: login];
[pathComponents removeObjectsInRange: NSMakeRange(0,3)];
currentDisplayName = [NSString stringWithFormat: @"/%@/%@/%@",
[self labelForKey: @"OtherUsersFolderName"],
(fullName != nil ? fullName : login),
[pathComponents componentsJoinedByString: @"/"]];
}
else
{
currentDisplayName = [NSString stringWithFormat: @"/%@%@",
[self labelForKey: @"OtherUsersFolderName"],
[currentDecodedFolder substringFromIndex:
[otherUsersFolderName length]]];
}
}
else if (sharedFoldersName && [currentDecodedFolder hasPrefix: sharedFoldersName])
currentDisplayName = [NSString stringWithFormat: @"/%@%@", [self labelForKey: @"SharedFoldersName"],
[currentDecodedFolder substringFromIndex: [sharedFoldersName length]]];
currentDisplayName = [NSString stringWithFormat: @"/%@%@", [self labelForKey: @"SharedFoldersName"],
[currentDecodedFolder substringFromIndex: [sharedFoldersName length]]];
else
currentDisplayName = currentDecodedFolder;
currentDisplayName = currentDecodedFolder;
folderData = [NSDictionary dictionaryWithObjectsAndKeys:
currentFolder, @"path",
currentFolderType, @"type",
currentDisplayName, @"displayName",
nil];
currentFolder, @"path",
currentFolderType, @"type",
currentDisplayName, @"displayName",
nil];
[folders addObject: folderData];
[pool release];
}
@ -207,7 +209,7 @@
response = [self responseWithStatus: 200
andString: [data jsonRepresentation]];
[response setHeader: @"application/json"
forKey: @"content-type"];
forKey: @"content-type"];
return response;
}
@ -256,7 +258,7 @@
nl = ([[[[context activeUser] userDefaults] mailComposeMessageType] isEqualToString: @"html"] ? @"<br/>" : @"\n");
[newDraftMessage
setText: [NSString stringWithFormat: @"%@%@-- %@%@", nl, nl, nl, signature]];
setText: [NSString stringWithFormat: @"%@%@-- %@%@", nl, nl, nl, signature]];
save = YES;
}
if (save)
@ -264,8 +266,8 @@
urlBase = [newDraftMessage baseURLInContext: context];
url = [urlBase composeURLWithAction: @"edit"
parameters: nil
andHash: NO];
parameters: nil
andHash: NO];
return [self redirectToLocation: url];
}

View File

@ -1,8 +1,6 @@
/* UIxMailActions.h - this file is part of SOGo
*
* Copyright (C) 2007 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2007-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -1,8 +1,6 @@
/* UIxMailActions.m - this file is part of SOGo
*
* Copyright (C) 2007 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2007-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -21,6 +19,7 @@
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <NGObjWeb/WOContext.h>
@ -32,6 +31,8 @@
#import <SoObjects/Mailer/SOGoDraftsFolder.h>
#import <SoObjects/Mailer/SOGoMailAccount.h>
#import <SoObjects/Mailer/SOGoMailObject.h>
#import <SoObjects/SOGo/SOGoUserDefaults.h>
#import "../Common/WODirectAction+SOGo.h"
@ -194,16 +195,18 @@
return response;
}
- (WOResponse *) _addLabel: (unsigned int) number
- (WOResponse *) addLabelAction
{
WOResponse *response;
SOGoMailObject *co;
NSException *error;
NSArray *flags;
NSString *flag;
flag = [[[self->context request] formValueForKey: @"flag"] fromCSSIdentifier];
co = [self clientObject];
flags = [NSArray arrayWithObject:
[NSString stringWithFormat: @"$Label%u", number]];
flags = [NSArray arrayWithObject: flag];
error = [co addFlags: flags];
if (error)
response = (WOResponse *) error;
@ -213,16 +216,18 @@
return response;
}
- (WOResponse *) _removeLabel: (unsigned int) number
- (WOResponse *) removeLabelAction
{
WOResponse *response;
SOGoMailObject *co;
NSException *error;
NSArray *flags;
NSString *flag;
flag = [[[self->context request] formValueForKey: @"flag"] fromCSSIdentifier];
co = [self clientObject];
flags = [NSArray arrayWithObject:
[NSString stringWithFormat: @"$Label%u", number]];
flags = [NSArray arrayWithObject: flag];
error = [co removeFlags: flags];
if (error)
response = (WOResponse *) error;
@ -232,66 +237,25 @@
return response;
}
- (WOResponse *) addLabel1Action
{
return [self _addLabel: 1];
}
- (WOResponse *) addLabel2Action
{
return [self _addLabel: 2];
}
- (WOResponse *) addLabel3Action
{
return [self _addLabel: 3];
}
- (WOResponse *) addLabel4Action
{
return [self _addLabel: 4];
}
- (WOResponse *) addLabel5Action
{
return [self _addLabel: 5];
}
- (WOResponse *) removeLabel1Action
{
return [self _removeLabel: 1];
}
- (WOResponse *) removeLabel2Action
{
return [self _removeLabel: 2];
}
- (WOResponse *) removeLabel3Action
{
return [self _removeLabel: 3];
}
- (WOResponse *) removeLabel4Action
{
return [self _removeLabel: 4];
}
- (WOResponse *) removeLabel5Action
{
return [self _removeLabel: 5];
}
- (WOResponse *) removeAllLabelsAction
{
NSMutableArray *flags;
WOResponse *response;
SOGoMailObject *co;
NSException *error;
NSArray *flags;
NSDictionary *v;
co = [self clientObject];
flags = [NSArray arrayWithObjects: @"$Label1", @"$Label2", @"$Label3",
@"$Label4", @"$Label5", nil];
v = [[[context activeUser] userDefaults] mailLabelsColors];
// We always unconditionally remove the Mozilla tags
flags = [NSMutableArray arrayWithObjects: @"$Label1", @"$Label2", @"$Label3",
@"$Label4", @"$Label5", nil];
[flags addObjectsFromArray: [v allKeys]];
error = [co removeFlags: flags];
if (error)
response = (WOResponse *) error;

View File

@ -253,11 +253,33 @@ static NSArray *infoKeys = nil;
- (NSString *) replyTo
{
SOGoUserDefaults *ud;
NSString *value;
value = nil;
ud = [[context activeUser] userDefaults];
//
// We add the correct replyTo here. That is, the one specified in the defaults
// for the main "SOGo mail account" versus the one specified in the auxiliary
// IMAP accounts.
//
if ([[[[self clientObject] mailAccountFolder] nameInContainer] intValue] == 0)
{
SOGoUserDefaults *ud;
ud = [[context activeUser] userDefaults];
value = [ud mailReplyTo];
}
else
{
NSArray *identities;
identities = [[[self clientObject] mailAccountFolder] identities];
return [ud mailReplyTo];
if ([identities count])
value = [[identities objectAtIndex: 0] objectForKey: @"replyTo"];
}
return value;
}
- (void) setSubject: (NSString *) newSubject

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2004-2005 SKYRIX Software AG
Copyright (C) 2006-2011 Inverse inc.
Copyright (C) 2006-2013 Inverse inc.
This file is part of SOGo
@ -861,8 +861,9 @@
flags = [[message objectForKey: @"flags"] objectEnumerator];
while ((currentFlag = [flags nextObject]))
if ([currentFlag hasPrefix: @"$label"])
[labels addObject: [currentFlag substringFromIndex: 1]];
{
[labels addObject: currentFlag];
}
return [labels componentsJoinedByString: @" "];
}

View File

@ -1,8 +1,6 @@
/* UIxMailMainFrame.h - this file is part of SOGo
*
* Copyright (C) 2006-2011 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2006-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -25,6 +23,8 @@
#import "../SOGoUI/UIxComponent.h"
@class SOGoMailLabel;
@interface UIxMailMainFrame : UIxComponent
{
SOGoUserSettings *us;
@ -33,6 +33,7 @@
NSArray *columnsOrder;
int folderType;
NSDictionary *currentColumn;
SOGoMailLabel *_currentLabel;
}
- (WOResponse *) getFoldersStateAction;

View File

@ -1,9 +1,5 @@
/*
Copyright (C) 2007-2011 Inverse inc.
Copyright (C) 2004-2005 SKYRIX Software AG
Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
Ludovic Marcotte <lmarcotte@inverse.ca>
Copyright (C) 2007-2013 Inverse inc.
This file is part of SOGo.
@ -48,6 +44,7 @@
#import <Mailer/SOGoMailAccount.h>
#import <Mailer/SOGoMailAccounts.h>
#import <Mailer/SOGoMailFolder.h>
#import <Mailer/SOGoMailLabel.h>
#import <Mailer/SOGoMailObject.h>
#import <Mailer/SOGoSentFolder.h>
#import <SOGo/NSDictionary+URL.h>
@ -84,6 +81,12 @@
return self;
}
- (void) dealloc
{
RELEASE(_currentLabel);
[super dealloc];
}
- (void) _setupContext
{
SOGoUser *activeUser;
@ -687,4 +690,32 @@
return [folders jsonRepresentation];
}
//
// Standard mapping done by Thunderbird:
//
// label1 => Important
// label2 => Work
// label3 => Personal
// label4 => To Do
// label5 => Later
//
- (NSArray *) availableLabels
{
NSDictionary *v;
v = [[[context activeUser] userDefaults] mailLabelsColors];
return [SOGoMailLabel labelsFromDefaults: v component: self];
}
- (void) setCurrentLabel: (SOGoMailLabel *) theCurrentLabel
{
ASSIGN(_currentLabel, theCurrentLabel);
}
- (SOGoMailLabel *) currentLabel
{
return _currentLabel;
}
@end /* UIxMailMainFrame */

View File

@ -272,55 +272,15 @@
actionClass = "UIxMailActions";
actionName = "markMessageRead";
};
addLabel1 = {
addLabel = {
protectedBy = "View";
actionClass = "UIxMailActions";
actionName = "addLabel1";
actionName = "addLabel";
};
addLabel2 = {
removeLabel = {
protectedBy = "View";
actionClass = "UIxMailActions";
actionName = "addLabel2";
};
addLabel3 = {
protectedBy = "View";
actionClass = "UIxMailActions";
actionName = "addLabel3";
};
addLabel4 = {
protectedBy = "View";
actionClass = "UIxMailActions";
actionName = "addLabel4";
};
addLabel5 = {
protectedBy = "View";
actionClass = "UIxMailActions";
actionName = "addLabel5";
};
removeLabel1 = {
protectedBy = "View";
actionClass = "UIxMailActions";
actionName = "removeLabel1";
};
removeLabel2 = {
protectedBy = "View";
actionClass = "UIxMailActions";
actionName = "removeLabel2";
};
removeLabel3 = {
protectedBy = "View";
actionClass = "UIxMailActions";
actionName = "removeLabel3";
};
removeLabel4 = {
protectedBy = "View";
actionClass = "UIxMailActions";
actionName = "removeLabel4";
};
removeLabel5 = {
protectedBy = "View";
actionClass = "UIxMailActions";
actionName = "removeLabel5";
actionName = "removeLabel";
};
removeAllLabels = {
protectedBy = "View";

View File

@ -288,12 +288,13 @@
"Flagged" = "Flagged";
"Junk" = "Junk";
"Not Junk" = "Not Junk";
"Label 1" = "Label 1";
"Label 2" = "Label 2";
"Label 3" = "Label 3";
"Label 4" = "Label 4";
"Label 5" = "Label 5";
"Important" = "Important";
"Work" = "Work";
"Personal" = "Personal";
"To Do" = "To Do";
"Later" = "Later";
/* Password policy */
"The password was changed successfully." = "The password was changed successfully.";
"Password must not be empty." = "Password must not be empty.";
"The passwords do not match. Please try again." = "The passwords do not match. Please try again.";
@ -306,4 +307,4 @@
"Unhandled policy error: %{0}" = "Unhandled policy error: %{0}";
"Unhandled error response" = "Unhandled error response";
"Password change is not supported." = "Password change is not supported.";
"Unhandled HTTP error code: %{0}" = "Unhandled HTTP error code: %{0}";
"Unhandled HTTP error code: %{0}" = "Unhandled HTTP error code: %{0}";

View File

@ -1,8 +1,6 @@
/* UIxFilterEditor.m - this file is part of SOGo
*
* Copyright (C) 2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2010-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -26,20 +24,44 @@
#import <NGObjWeb/WORequest.h>
#import <NGObjWeb/WOResponse.h>
#import <SOGo/NSDictionary+Utilities.h>
#import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
#import <SOGoUI/UIxComponent.h>
@interface UIxFilterEditor : UIxComponent
{
NSString *filterId;
NSDictionary *labels;
}
@end
@implementation UIxFilterEditor
- (id) init
{
self = [super init];
if (self)
{
filterId = nil;
labels = nil;
}
return self;
}
- (void) dealloc
{
RELEASE(filterId);
RELEASE(labels);
[super dealloc];
}
/* convert and save */
- (BOOL) _validateFilterId
{
@ -80,4 +102,14 @@
return filterId;
}
- (NSString *) labels
{
if (!labels)
{
ASSIGN(labels, [[[context activeUser] userDefaults] mailLabelsColors]);
}
return [labels jsonRepresentation];
}
@end

View File

@ -1,8 +1,6 @@
/* UIxPreferences.h - this file is part of SOGo
*
* Copyright (C) 2007-2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2007-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -27,23 +25,36 @@
@class NSString;
@class SOGoMailLabel;
@class SOGoUser;
@interface UIxPreferences : UIxComponent
{
id item;
SOGoUser *user;
// Calendar categories
NSString *category;
NSArray *calendarCategories;
NSDictionary *calendarCategoriesColors;
NSArray *contactsCategories;
NSString *defaultCategoryColor;
NSCalendarDate *today;
// Mail labels/tags
SOGoMailLabel *label;
NSArray *mailLabels;
// Sieve filtering
NSArray *daysOfWeek, *daysBetweenResponsesList;
NSArray *sieveFilters;
NSMutableDictionary *vacationOptions, *forwardOptions;
BOOL mailCustomFromEnabled;
BOOL hasChanged;
}
- (NSString *) userLongDateFormat;

View File

@ -1,9 +1,6 @@
/* UIxPreferences.m - this file is part of SOGo
*
* Copyright (C) 2007-2011 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Francis Lachapelle <flachapelle@inverse.ca>
* Copyright (C) 2007-2013 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -31,6 +28,8 @@
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WORequest.h>
#import <NGImap4/NSString+Imap4.h>
#import <NGExtensions/NSObject+Logs.h>
#import <NGCards/iCalTimeZone.h>
@ -47,6 +46,7 @@
#import <SOGo/WOResourceManager+SOGo.h>
#import <Mailer/SOGoMailAccount.h>
#import <Mailer/SOGoMailAccounts.h>
#import <Mailer/SOGoMailLabel.h>
#import "UIxPreferences.h"
@ -77,6 +77,9 @@
defaultCategoryColor = nil;
category = nil;
label = nil;
mailLabels = nil;
ASSIGN (daysOfWeek, [locale objectForKey: NSWeekDayNameArray]);
dd = [user domainDefaults];
@ -120,6 +123,8 @@
[calendarCategoriesColors release];
[defaultCategoryColor release];
[category release];
[label release];
[mailLabels release];
[contactsCategories release];
[forwardOptions release];
[daysOfWeek release];
@ -1175,6 +1180,67 @@
sortedArrayUsingSelector: @selector (localizedCaseInsensitiveCompare:)];
}
- (SOGoMailLabel *) label
{
return label;
}
- (void) setLabel: (SOGoMailLabel *) newLabel
{
ASSIGN(label, newLabel);
}
- (NSArray *) mailLabelList
{
if (!mailLabels)
{
NSDictionary *v;
v = [[[context activeUser] userDefaults] mailLabelsColors];
ASSIGN(mailLabels, [SOGoMailLabel labelsFromDefaults: v component: self]);
}
return mailLabels;
}
- (NSString *) mailLabelsValue
{
return @"";
}
- (void) setMailLabelsValue: (NSString *) value
{
NSMutableDictionary *sanitizedLabels;
NSDictionary *newLabels;
NSArray *allKeys;
NSString *name;
int i;
newLabels = [value objectFromJSONString];
if (newLabels && [newLabels isKindOfClass: [NSDictionary class]])
{
// We encode correctly our keys
sanitizedLabels = [NSMutableDictionary dictionary];
allKeys = [newLabels allKeys];
for (i = 0; i < [allKeys count]; i++)
{
name = [allKeys objectAtIndex: i];
if (![name is7bitSafe])
name = [name stringByEncodingImap4FolderName];
name = [name lowercaseString];
[sanitizedLabels setObject: [newLabels objectForKey: [allKeys objectAtIndex: i]]
forKey: name];
}
[userDefaults setMailLabelsColors: sanitizedLabels];
}
}
- (void) setCategory: (NSString *) newCategory
{
ASSIGN (category, newCategory);

View File

@ -15,13 +15,12 @@ SchedulerUI_OBJC_FILES = \
\
UIxCalMainView.m \
UIxCalendarProperties.m \
UIxColorPicker.m \
\
UIxCalFilterPanel.m \
UIxCalDayTable.m \
UIxCalDateSelector.m \
UIxCalUserRightsEditor.m \
UIxCalFolderActions.m \
UIxCalFolderActions.m \
\
UIxCalView.m \
UIxCalDayView.m \

View File

@ -1,31 +0,0 @@
/* UIxColorPicker.h - this file is part of SOGo
*
* Copyright (C) 2008 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef UIXCOLORPICKER_H
#define UIXCOLORPICKER_H
#import <SOGoUI/UIxComponent.h>
@interface UIxColorPicker : UIxComponent
@end
#endif /* UIXCOLORPICKER_H */

View File

@ -1,29 +0,0 @@
/* UIxColorPicker.m - this file is part of SOGo
*
* Copyright (C) 2008 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import "UIxColorPicker.h"
#warning this module should probably be moved into a "Utility" product
@implementation UIxColorPicker
@end

View File

@ -131,10 +131,6 @@
protectedBy = "View";
pageName = "UIxReminderEditor";
};
colorPicker = {
protectedBy = "View";
pageName = "UIxColorPicker";
};
};
};

View File

@ -16,6 +16,16 @@
var unseenCountFolders = <var:string value="unseenCountFolders" const:escapeHTML="NO"/>;
</script>
<style type="text/css">
<var:foreach list="availableLabels" item="currentLabel">
#label-menu LI.<var:string value="currentLabel.name.asCSSIdentifier"/>,
TABLE.messageList TR[labels~=<var:string const:value='"' const:escapeHTML="NO"
/><var:string value="currentLabel.name"/><var:string const:value='"' const:escapeHTML="NO"/>] TD
{ color: <var:string value="currentLabel.color"/>; }
TABLE.messageList TR[labels~=<var:string const:value='"' const:escapeHTML="NO"
/><var:string value="currentLabel.name"/><var:string const:value='"' const:escapeHTML="NO"/>]._selected TD
{ color: #fff;
background-color: <var:string value="currentLabel.color"/> !important; }
</var:foreach>
<var:if condition="horizontalDragHandleStyle">
DIV#verticalDragHandle, DIV#rightPanel
{ left: <var:string value="horizontalDragHandleStyle" />; }
@ -170,11 +180,9 @@
<ul id="" class="choiceMenu">
<li><var:string label:value="None" /></li>
<li><!-- separator --></li>
<li class="label1"><var:string label:value="Important" /></li>
<li class="label2"><var:string label:value="Work" /></li>
<li class="label3"><var:string label:value="Personal" /></li>
<li class="label4"><var:string label:value="To Do" /></li>
<li class="label5"><var:string label:value="Later" /></li>
<var:foreach list="availableLabels" item="currentLabel">
<li var:class="currentLabel.name.asCSSIdentifier" var:data-name="currentLabel.name"> <var:string value="currentLabel.label"/></li>
</var:foreach>
</ul>
</div>

View File

@ -13,6 +13,7 @@
>
<script type="text/javascript">
var filterId = '<var:string value="filterId"/>';
var labels = <var:string value="labels"/>;
</script>
<form id="mainForm" var:href="ownPath">
<div id="filterNameContainer" class="container">

View File

@ -16,6 +16,82 @@
<script type="text/javascript">
var localeCode = '<var:string value="localeCode"/>';
</script>
<div id="colorPickerDialog" style="display: none;" class="dialog right bottom">
<div>
<span class="blc-FFFFFF"><!-- --></span>
<span class="blc-330033"><!-- --></span>
<span class="blc-C0C0C0"><!-- --></span>
<span class="blc-999999"><!-- --></span>
<span class="blc-666666"><!-- --></span>
<span class="blc-333333"><!-- --></span>
<span class="blc-000000"><!-- --></span>
<span class="blc-FFCCCC"><!-- --></span>
<span class="blc-FF6666"><!-- --></span>
<span class="blc-FF0000"><!-- --></span>
<span class="blc-CC0000"><!-- --></span>
<span class="blc-990000"><!-- --></span>
<span class="blc-660000"><!-- --></span>
<span class="blc-330000"><!-- --></span>
<span class="blc-FFCC99"><!-- --></span>
<span class="blc-FF9966"><!-- --></span>
<span class="blc-FF9900"><!-- --></span>
<span class="blc-FF6600"><!-- --></span>
<span class="blc-CC6600"><!-- --></span>
<span class="blc-993300"><!-- --></span>
<span class="blc-663300"><!-- --></span>
<span class="blc-FFFF99"><!-- --></span>
<span class="blc-FFFF66"><!-- --></span>
<span class="blc-FFCC66"><!-- --></span>
<span class="blc-FFCC33"><!-- --></span>
<span class="blc-CC9933"><!-- --></span>
<span class="blc-996633"><!-- --></span>
<span class="blc-663333"><!-- --></span>
<span class="blc-FFFFCC"><!-- --></span>
<span class="blc-FFFF33"><!-- --></span>
<span class="blc-FFFF00"><!-- --></span>
<span class="blc-FFCC00"><!-- --></span>
<span class="blc-999900"><!-- --></span>
<span class="blc-666600"><!-- --></span>
<span class="blc-333300"><!-- --></span>
<span class="blc-CCCCCC"><!-- --></span>
<span class="blc-66FF99"><!-- --></span>
<span class="blc-33FF33"><!-- --></span>
<span class="blc-33CC00"><!-- --></span>
<span class="blc-009900"><!-- --></span>
<span class="blc-006600"><!-- --></span>
<span class="blc-003300"><!-- --></span>
<span class="blc-99FFFF"><!-- --></span>
<span class="blc-33FFFF"><!-- --></span>
<span class="blc-66CCCC"><!-- --></span>
<span class="blc-00CCCC"><!-- --></span>
<span class="blc-339999"><!-- --></span>
<span class="blc-336666"><!-- --></span>
<span class="blc-003333"><!-- --></span>
<span class="blc-CCFFFF"><!-- --></span>
<span class="blc-66FFFF"><!-- --></span>
<span class="blc-33CCFF"><!-- --></span>
<span class="blc-3366FF"><!-- --></span>
<span class="blc-3333FF"><!-- --></span>
<span class="blc-000099"><!-- --></span>
<span class="blc-000066"><!-- --></span>
<span class="blc-CCCCFF"><!-- --></span>
<span class="blc-9999FF"><!-- --></span>
<span class="blc-6666CC"><!-- --></span>
<span class="blc-6633FF"><!-- --></span>
<span class="blc-6600CC"><!-- --></span>
<span class="blc-333399"><!-- --></span>
<span class="blc-330099"><!-- --></span>
<span class="blc-FFCCFF"><!-- --></span>
<span class="blc-FF99FF"><!-- --></span>
<span class="blc-CC66CC"><!-- --></span>
<span class="blc-CC33CC"><!-- --></span>
<span class="blc-993399"><!-- --></span>
<span class="blc-663366"><!-- --></span>
<span class="blc-99FF99"><!-- --></span>
</div>
</div>
<form id="mainForm" var:href="ownPath">
<div class="tabsContainer" id="preferencesTabs">
<ul>
@ -147,8 +223,7 @@
><td const:class="categoryListCell"
><var:string var:value="category"/></td
><td const:class="categoryListCell"
><div const:class="colorBox"><var:string var:value="categoryColor"
/></div></td
><div const:class="colorBox" var:data-color="categoryColor"><entity name="nbsp"/></div></td
></tr>
</var:foreach>
</tbody>
@ -248,42 +323,88 @@
string="itemDisplayRemoteInlineImagesText"
selection="userDisplayRemoteInlineImages"/></dd>
</dl>
<var:if condition="isSieveScriptsEnabled"
><label><var:string label:value="Filters"/></label>
<script type="text/javascript">
var sieveCapabilities = <var:string value="sieveCapabilities" const:escapeHTML="NO"/>;
</script>
<div id="filtersListWrapper" class="listWrapper"
><table id="filtersList" cellspacing="0">
<thead>
<tr class="tableview"
><th const:class="tbtv_headercell" const:id="nameTableHeader"
><var:string label:value="Name" /></th
><th const:class="tbtv_headercell" const:id="activeTableHeader"
><var:string label:value="Active" /></th
></tr
></thead>
<tbody><!--space --></tbody>
</table>
<input type="hidden" const:name="sieveFilters" const:id="sieveFilters"
var:value="sieveFiltersValue"/>
</div>
<div class="bottomToolbar">
<a const:id="filterAdd" class="bottomButton" href="#">
<span><img rsrc:src="add-icon.png" label:title="Add" />
</span></a>
<a const:id="filterDelete" class="bottomButton" href="#">
<span><img rsrc:src="remove-icon.png" label:title="Delete" />
</span></a>
<a const:id="filterMoveUp" class="bottomButton" href="#">
<span><img rsrc:src="up-icon.png" label:title="Move Up" />
</span></a>
<a const:id="filterMoveDown" class="bottomButton" href="#">
<span><img rsrc:src="down-icon.png" label:title="Move Down" />
</span></a>
</div>
</var:if>
</div>
<div class="tabsContainer" id="mailOptionsTabs">
<ul>
<var:if condition="isSieveScriptsEnabled"
><li target="mailFiltersView"><span><var:string
label:value="Filters"/></span></li
></var:if>
<li target="mailLabelsView"><span><var:string
label:value="Labels"/></span></li>
</ul>
<div class="tabs">
<var:if condition="isSieveScriptsEnabled"
><div id="mailFiltersView" class="tab">
<script type="text/javascript">
var sieveCapabilities = <var:string value="sieveCapabilities" const:escapeHTML="NO"/>;
</script>
<div id="filtersListWrapper" class="listWrapper">
<table id="filtersList" cellspacing="0">
<thead>
<tr class="tableview">
<th const:class="tbtv_headercell" const:id="nameTableHeader"
><var:string label:value="Name" /></th>
<th const:class="tbtv_headercell" const:id="activeTableHeader"
><var:string label:value="Active" /></th>
</tr>
</thead>
<tbody><!--space --></tbody>
</table>
<input type="hidden" const:name="sieveFilters" const:id="sieveFilters"
var:value="sieveFiltersValue"/>
</div><!-- #filtersListWrapper -->
<div class="bottomToolbar">
<a const:id="filterAdd" class="bottomButton" href="#">
<span><img rsrc:src="add-icon.png" label:title="Add" /></span></a>
<a const:id="filterDelete" class="bottomButton" href="#">
<span><img rsrc:src="remove-icon.png" label:title="Delete" /></span></a>
<a const:id="filterMoveUp" class="bottomButton" href="#">
<span><img rsrc:src="up-icon.png" label:title="Move Up" /></span></a>
<a const:id="filterMoveDown" class="bottomButton" href="#">
<span><img rsrc:src="down-icon.png" label:title="Move Down" /></span></a>
</div><!-- .bottomToolbar -->
</div
></var:if><!-- #mailFiltersView -->
<div id="mailLabelsView" class="tab">
<div id="mailLabelsListWrapper" class="listWrapper">
<table id="labelsList" cellspacing="0">
<thead>
<tr class="tableview">
<th const:class="tbtv_headercell" const:id="labelTableHeader"
><var:string label:value="Label"/></th>
<th const:class="tbtv_headercell" const:id="colorTableHeader"
><var:string label:value="Color"/></th>
</tr>
</thead>
<tbody>
<var:foreach list="mailLabelList" item="label"
><tr var:data-name="label.name" const:class="labelListRow">
<td const:class="labelListCell"
><var:string var:value="label.label"/></td>
<td const:class="labelListCell">
<div const:class="colorBox" var:data-color="label.color"><entity name="nbsp"/></div>
</td>
</tr>
</var:foreach>
</tbody>
</table>
</div><!-- #mailLabelsListWrapper -->
<div class="bottomToolbar">
<a const:id="mailLabelAdd" class="bottomButton" href="#">
<span><img rsrc:src="add-icon.png" label:title="Add" />
</span></a>
<a const:id="mailLabelDelete" class="bottomButton" href="#">
<span><img rsrc:src="remove-icon.png" label:title="Delete" />
</span></a>
</div><!-- .bottomToolbar -->
<input type="hidden" const:id="mailLabelsValue"
const:name="mailLabelsValue" var:value="mailLabelsValue"/>
</div><!-- #mailLabelsView -->
</div><!-- .tabs -->
</div><!-- #mailOptionsTabs -->
</div><!-- #mailOptionsView -->
<div id="mailAccountsView" class="tab">
<input type="hidden" const:name="mailAccountsJSON" const:id="mailAccountsJSON"
@ -457,12 +578,11 @@
const:id="forwardKeepCopy"
var:checked="forwardKeepCopy" />
<var:string label:value="Keep a copy" /></label><br/>
</div>
</div>
</var:if
></var:if
><var:if condition="shouldDisplayPasswordChange">
</var:if>
</var:if><!-- userHasMailAccess -->
<var:if condition="shouldDisplayPasswordChange">
<div id="passwordView" class="tab">
<p id="passwordFields"><label><var:string label:value="New password:"
/><input const:id="newPasswordField" class="textField"

View File

@ -10,6 +10,82 @@
const:toolbar="none"
const:popup="YES"
title="title">
<div id="colorPickerDialog" style="display: none;" class="dialog left">
<div>
<span class="blc-FFFFFF"><!-- --></span>
<span class="blc-330033"><!-- --></span>
<span class="blc-C0C0C0"><!-- --></span>
<span class="blc-999999"><!-- --></span>
<span class="blc-666666"><!-- --></span>
<span class="blc-333333"><!-- --></span>
<span class="blc-000000"><!-- --></span>
<span class="blc-FFCCCC"><!-- --></span>
<span class="blc-FF6666"><!-- --></span>
<span class="blc-FF0000"><!-- --></span>
<span class="blc-CC0000"><!-- --></span>
<span class="blc-990000"><!-- --></span>
<span class="blc-660000"><!-- --></span>
<span class="blc-330000"><!-- --></span>
<span class="blc-FFCC99"><!-- --></span>
<span class="blc-FF9966"><!-- --></span>
<span class="blc-FF9900"><!-- --></span>
<span class="blc-FF6600"><!-- --></span>
<span class="blc-CC6600"><!-- --></span>
<span class="blc-993300"><!-- --></span>
<span class="blc-663300"><!-- --></span>
<span class="blc-FFFF99"><!-- --></span>
<span class="blc-FFFF66"><!-- --></span>
<span class="blc-FFCC66"><!-- --></span>
<span class="blc-FFCC33"><!-- --></span>
<span class="blc-CC9933"><!-- --></span>
<span class="blc-996633"><!-- --></span>
<span class="blc-663333"><!-- --></span>
<span class="blc-FFFFCC"><!-- --></span>
<span class="blc-FFFF33"><!-- --></span>
<span class="blc-FFFF00"><!-- --></span>
<span class="blc-FFCC00"><!-- --></span>
<span class="blc-999900"><!-- --></span>
<span class="blc-666600"><!-- --></span>
<span class="blc-333300"><!-- --></span>
<span class="blc-CCCCCC"><!-- --></span>
<span class="blc-66FF99"><!-- --></span>
<span class="blc-33FF33"><!-- --></span>
<span class="blc-33CC00"><!-- --></span>
<span class="blc-009900"><!-- --></span>
<span class="blc-006600"><!-- --></span>
<span class="blc-003300"><!-- --></span>
<span class="blc-99FFFF"><!-- --></span>
<span class="blc-33FFFF"><!-- --></span>
<span class="blc-66CCCC"><!-- --></span>
<span class="blc-00CCCC"><!-- --></span>
<span class="blc-339999"><!-- --></span>
<span class="blc-336666"><!-- --></span>
<span class="blc-003333"><!-- --></span>
<span class="blc-CCFFFF"><!-- --></span>
<span class="blc-66FFFF"><!-- --></span>
<span class="blc-33CCFF"><!-- --></span>
<span class="blc-3366FF"><!-- --></span>
<span class="blc-3333FF"><!-- --></span>
<span class="blc-000099"><!-- --></span>
<span class="blc-000066"><!-- --></span>
<span class="blc-CCCCFF"><!-- --></span>
<span class="blc-9999FF"><!-- --></span>
<span class="blc-6666CC"><!-- --></span>
<span class="blc-6633FF"><!-- --></span>
<span class="blc-6600CC"><!-- --></span>
<span class="blc-333399"><!-- --></span>
<span class="blc-330099"><!-- --></span>
<span class="blc-FFCCFF"><!-- --></span>
<span class="blc-FF99FF"><!-- --></span>
<span class="blc-CC66CC"><!-- --></span>
<span class="blc-CC33CC"><!-- --></span>
<span class="blc-993399"><!-- --></span>
<span class="blc-663366"><!-- --></span>
<span class="blc-99FF99"><!-- --></span>
</div>
</div>
<form const:href="saveProperties" name="propertiesform" id="propertiesform">
<input type="hidden" const:name="calendarID" const:id="calendarID"
var:value="calendarID"/>
@ -32,15 +108,11 @@
class="textField"
var:value="calendarName"
/></span></div>
<div><span class="label"><var:string
label:value="Color:"
/></span><span class="content"
><button id="colorButton"><!-- space --></button
><input type="hidden"
name="calendarColor"
id="calendarColor"
var:value="calendarColor"
/></span></div>
<div><span class="label"><var:string label:value="Color:"/></span
><span class="content"
><div id="colorButton" class="colorBox" var:data-color="calendarColor"><!-- space --></div
><input type="hidden" name="calendarColor" id="calendarColor" var:value="calendarColor"
/></span></div>
<var:if condition="userIsOwner"
><div
><label><input type="checkbox" const:class="checkBox"

View File

@ -36,14 +36,11 @@ div.colorBox.calendarFolder<var:string value="currentCalendar.folder" />
</div>
<ul id="calendarList">
<var:foreach list="calendars" item="currentCalendar"
><li class="denied" var:id="currentCalendar.id"
var:owner="currentCalendar.owner" >
<input type="checkbox" class="checkBox"
const:disabled="disabled"
var:checked="currentCalendar.active" />
<div var:class="currentCalendarClass">OO</div
><var:string value="currentCalendar.displayName"
/></li>
><li class="denied" var:id="currentCalendar.id" var:owner="currentCalendar.owner" >
<input type="checkbox" class="checkBox" const:disabled="disabled" var:checked="currentCalendar.active" />
<div var:class="currentCalendarClass"><entity name="nbsp"/></div
><var:string value="currentCalendar.displayName"
/></li>
</var:foreach>
</ul>
</div>

View File

@ -1,14 +1,15 @@
/*
Copyright (C) 2005-2013 Inverse inc.
Copyright (C) 2005 SKYRIX Software AG
This file is part of OpenGroupware.org.
This file is part of SOGo.
OGo is free software; you can redistribute it and/or modify it under
SOGo is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
@ -93,21 +94,6 @@ DIV#folderTreeContent
right: 0px;
overflow: auto; }
#label-menu LI.label1
{ color: #f00; }
#label-menu LI.label2
{ color: #ff9a00; }
#label-menu LI.label3
{ color: #009a00; }
#label-menu LI.label4
{ color: #3130ff; }
#label-menu LI.label5
{ color: #9c309c; }
.aptview_title
{
color: #000000;
@ -338,41 +324,6 @@ TABLE.messageList TR._selected TD
TABLE.messageList TR._deleted TD
{ text-decoration: line-through; }
TABLE.messageList TR[labels~="label5"] TD
{ color: #9c309c; }
TABLE.messageList TR[labels~="label5"]._selected TD
{ color: #fff;
background-color: #9c309c; }
TABLE.messageList TR[labels~="label4"] TD
{ color: #3130ff; }
TABLE.messageList TR[labels~="label4"]._selected TD
{ color: #fff;
background-color: #3130ff; }
TABLE.messageList TR[labels~="label3"] TD
{ color: #009a00; }
TABLE.messageList TR[labels~="label3"]._selected TD
{ color: #fff;
background-color: #009a00; }
TABLE.messageList TR[labels~="label2"] TD
{ color: #ff9a00; }
TABLE.messageList TR[labels~="label2"]._selected TD
{ color: #fff;
background-color: #ff9a00; }
TABLE.messageList TR[labels~="label1"] TD
{ color: #f00; }
TABLE.messageList TR[labels~="label1"]._selected TD
{ color: #fff;
background-color: #f00; }
TABLE.messageList TR.mailer_unreadmail TD,
TR.mailer_unreadmail TD.messageSubjectColumn
{ font-weight: bold !important; }

View File

@ -2488,9 +2488,11 @@ function onMenuLabelNone() {
});
}
function _onMenuLabelFlagX(flag) {
function onMenuLabelFlag() {
var messages = new Hash();
var flag = this.readAttribute("data-name");
if (document.menuTarget.tagName == "DIV")
// Menu called from message content view
messages.set(Mailer.currentMessages[Mailer.currentMailbox],
@ -2502,45 +2504,25 @@ function _onMenuLabelFlagX(flag) {
if (row)
messages.set(rowID.substr(4),
row.getAttribute("labels"));
});
});
else
// Menu called from one selection in messages list view
messages.set(document.menuTarget.getAttribute("id").substr(4),
document.menuTarget.getAttribute("labels"));
var url = ApplicationBaseURL + encodeURI(Mailer.currentMailbox) + "/";
messages.keys().each(function(id) {
var flags = messages.get(id).split(" ");
var operation = "add";
if (flags.indexOf("label" + flag) > -1)
operation = "remove";
triggerAjaxRequest(url + id + "/" + operation + "Label" + flag,
messageFlagCallback,
{ mailbox: Mailer.currentMailbox, msg: id,
label: operation + flag } );
});
}
function onMenuLabelFlag1() {
_onMenuLabelFlagX(1);
}
function onMenuLabelFlag2() {
_onMenuLabelFlagX(2);
}
function onMenuLabelFlag3() {
_onMenuLabelFlagX(3);
}
function onMenuLabelFlag4() {
_onMenuLabelFlagX(4);
}
function onMenuLabelFlag5() {
_onMenuLabelFlagX(5);
var flags = messages.get(id).split(" ");
var operation = "add";
if (flags.indexOf(flag) > -1)
operation = "remove";
triggerAjaxRequest(url + id + "/" + operation + "Label?flag=" + flag.asCSSIdentifier(),
messageFlagCallback,
{ mailbox: Mailer.currentMailbox, msg: id,
label: operation + flag } );
});
}
function onMenuToggleMessageFlag(event) {
@ -2707,14 +2689,33 @@ function onLabelMenuPrepareVisibility() {
var lis = this.childNodesWithTag("ul")[0].childNodesWithTag("li");
var isFlagged = false;
for (var i = 1; i < 6; i++) {
if (flags["label" + i]) {
isFlagged = true;
lis[1 + i].addClassName("_chosen");
// lis is our array of labels, ex:
// li
// li.seperator
// li.label1
// li.broccoli
// ...
for (var i = 2; i < lis.length; i++) {
// We bind the event handlers if we need to
if (lis[i].menuCallback == null) {
lis[i].menuCallback = onMenuLabelFlag;
lis[i].on("mousedown", onMenuClickHandler);
lis[i].removeClassName("disabled");
}
var flag = lis[i].readAttribute("data-name");
if (flags[flag]) {
isFlagged = true;
lis[i].addClassName("_chosen");
}
else {
lis[i].removeClassName("_chosen");
}
else
lis[1 + i].removeClassName("_chosen");
}
if (isFlagged)
lis[0].removeClassName("_chosen");
else
@ -2834,12 +2835,9 @@ function getMenus() {
onMenuChangeToDraftsFolder,
onMenuChangeToTrashFolder ],
"label-menu": [ onMenuLabelNone, "-", onMenuLabelFlag1,
onMenuLabelFlag2, onMenuLabelFlag3,
onMenuLabelFlag4, onMenuLabelFlag5 ],
"label-menu": [ onMenuLabelNone, "-" ],
"mark-menu": [ onMenuToggleMessageRead, null, null, null, "-", onMenuToggleMessageFlag ],
// , "-",
// null, null, null ],
searchMenu: [ setSearchCriteria, setSearchCriteria,
setSearchCriteria, setSearchCriteria,

View File

@ -68,10 +68,8 @@ SOGoTabsController.prototype = {
attachToTabsContainer: function STC_attachToTabsContainer(container) {
this.container = container;
container.controller = this;
this.onTabMouseDownBound
= this.onTabMouseDown.bindAsEventListener(this);
this.onTabClickBound
= this.onTabClick.bindAsEventListener(this);
this.onTabMouseDownBound = this.onTabMouseDown.bindAsEventListener(this);
this.onTabClickBound = this.onTabClick.bindAsEventListener(this);
var list = container.childNodesWithTag("ul");
if (list.length > 0) {
@ -81,8 +79,7 @@ SOGoTabsController.prototype = {
this.firstTab = $(nodes[0]);
for (var i = 0; i < nodes.length; i++) {
var currentNode = $(nodes[i]);
currentNode.observe("mousedown",
this.onTabMouseDownBound, false);
currentNode.observe("mousedown", this.onTabMouseDownBound, false);
currentNode.observe("click", this.onTabClickBound, false);
if (currentNode.hasClassName("active"))
this.activeTab = currentNode;
@ -147,6 +144,13 @@ SOGoTabsController.prototype = {
content.addClassName("active");
this.activeTab.fire("tabs:click", content.id);
content.select('.tabsContainer').each(function(c) {
// When the tab contains an inner tabs container,
// show or hide the tabs navigation arrows of this
// inner container
c.controller.recomputeMinOffset();
});
// Prototype alternative
//oldContent.removeClassName("active");

View File

@ -26,14 +26,10 @@ DIV#calendarSelectorButtons
{ padding-left: 6px; }
DIV.colorBox
{ display: inline;
font-weight: normal;
margin-right: 3px;
font-size: 80%;
width: 1em;
height: .75em;
-webkit-border-radius: 2px;
border-radius: 2px; }
{ display: inline-block; }
TD DIV.colorBox, TD DIV.colorBox:hover
{ border-color: #fff; }
UL#calendarList
{ cursor: default;
@ -248,7 +244,7 @@ TABLE#tasksList
{ width: 100%; }
TABLE#eventsList .colorBox
{ margin-left: 2px; }
{ margin-right: 4px; }
#eventsList TD.headerTitle,
#eventsList TD.headerDateTime

View File

@ -699,7 +699,6 @@ function onViewEventCallback(http) {
var cellDimensions = cell.getDimensions();
var div = $("eventDialog");
var divDimensions = div.getDimensions();
var viewPosition = $("calendarView").cumulativeOffset();
var view;
var left;
var top = cellPosition[1] - 5;
@ -965,7 +964,7 @@ function eventsListCallback(http) {
td.observe("mousedown", listRowMouseDownHandler, true);
var colorDiv = createElement("div", false, "colorBox calendarFolder" + calendar);
td.appendChild(colorDiv);
colorDiv.update('OO');
colorDiv.update('&nbsp;');
var span = createElement("span");
td.appendChild(span);
span.update(data[i][4]); // title
@ -1093,7 +1092,7 @@ function tasksListCallback(http) {
row.appendChild(cell);
var colorDiv = createElement("div", false, "colorBox calendarFolder" + calendar);
cell.appendChild(colorDiv);
colorDiv.update('OO');
colorDiv.update('&nbsp;');
var t = new Element ("span");
cell.appendChild(t);
t.update(data[i][4]); // title
@ -2834,8 +2833,9 @@ function initCalendarSelector() {
function onCalendarSelectionChange(event) {
var target = Event.element(event);
if (target.tagName == 'SPAN')
if (target.tagName == 'DIV') {
target = target.parentNode;
}
onRowClick(event, target);
}
@ -3073,7 +3073,7 @@ function appendCalendar(folderName, folderPath) {
var colorBox = document.createElement("div");
li.appendChild(colorBox);
li.appendChild(document.createTextNode(folderName));
colorBox.appendChild(document.createTextNode("OO"));
colorBox.appendChild(document.createTextNode("\u00a0"));
$(colorBox).addClassName("colorBox");
$(colorBox).addClassName('calendarFolder' + folderPath.substr(1));

View File

@ -31,13 +31,19 @@ SPAN.content
SPAN.content INPUT.textField
{ width: 160px; }
BUTTON#colorButton
{ display: none;
border: 1px solid #FFFFFF;
border-top: 1px solid #909090;
border-left: 1px solid #909090;
width: 3em;
height: 18px; }
DIV.colorBox
{ margin: 5px 0;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: 2px solid #eee; }
DIV.colorBox:hover
{ border-color: #fff; }
#colorPickerDialog
{ width: 146px;
height: 191px; }
DIV#buttons
{ position: absolute;

View File

@ -7,9 +7,12 @@ function onLoadCalendarProperties() {
var colorButton = $("colorButton");
var calendarColor = $("calendarColor");
colorButton.setStyle({ "backgroundColor": calendarColor.value, display: "inline" });
colorButton.setStyle({ "backgroundColor": colorButton.readAttribute('data-color') });
colorButton.observe("click", onColorClick);
$('colorPickerDialog').on('click', 'span', onColorPickerChoice);
$(document.body).on("click", onBodyClickHandler);
var cancelButton = $("cancelButton");
cancelButton.observe("click", onCancelClick);
@ -74,22 +77,31 @@ function onOKClick(event) {
Event.stop(event);
}
function onColorClick(event) {
var cPicker = window.open(ApplicationBaseURL + "colorPicker", "colorPicker",
"width=250,height=200,resizable=0,scrollbars=0"
+ "toolbar=0,location=0,directories=0,status=0,"
+ "menubar=0,copyhistory=0", "test"
);
cPicker.focus();
preventDefault(event);
function onBodyClickHandler(event) {
var target = getTarget(event);
if (!target.hasClassName('colorBox'))
$("colorPickerDialog").hide();
}
function onColorPickerChoice(newColor) {
var colorButton = $("colorButton");
colorButton.setStyle({ "backgroundColor": newColor });
var calendarColor = $("calendarColor");
calendarColor.value = newColor;
function onColorClick(event) {
var cellPosition = this.cumulativeOffset();
var cellDimensions = this.getDimensions();
var div = $('colorPickerDialog');
var divDimensions = div.getDimensions();
var left = cellPosition[0] + cellDimensions["width"] + 4;
var top = cellPosition[1] - 5;
div.setStyle({ left: left + "px", top: top + "px" });
div.show();
preventDefault(event);
}
function onColorPickerChoice(event) {
var span = getTarget(event);
var newColor = "#" + span.className.substr(4);
var colorButton = $("colorButton");
colorButton.setStyle({ "backgroundColor": newColor });
$("calendarColor").value = newColor;
}
document.observe("dom:loaded", onLoadCalendarProperties);

View File

@ -1,11 +1,13 @@
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
var type;
function onLoadColorPicker(event) {
showColorPicker();
}
function onChooseColor(newColor) {
window.opener.onColorPickerChoice(newColor);
window.opener.onColorPickerChoice(newColor, type);
window.close();
}

View File

@ -90,9 +90,10 @@ function setupConstants() {
"flagged": _("Flagged"),
"junk": _("Junk"),
"not_junk": _("Not Junk") };
for (var i = 1; i < 6; i++) {
var key = "label" + i;
flagLabels[key] = _("Label " + i);
for (var name in labels) {
flagLabels[name] = _( labels[name][0] );
}
}

View File

@ -33,12 +33,13 @@ TD.categoryListCell
{ -moz-user-select: none; }
DIV.colorBox
{ border: 1px solid #333333;
font-size: 80%;
font-weight: normal;
height: 0.75em;
margin: 0 3px 0 0;
width: 1em; }
{ -webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: 2px solid #ccddec; }
DIV.colorBox:hover
{ border-color: #eee; }
DIV.listWrapper
{ overflow: auto;
@ -48,6 +49,9 @@ DIV.listWrapper
border-left: 1px solid #9b9b9b;
background: #ccddec;}
.listWrapper TABLE TD
{ height: 22px; }
#calendarCategoriesListWrapper
{ top: 210px;
bottom: 30px;
@ -94,19 +98,37 @@ SPAN.timeDateControl INPUT.textField
#passwordView BR
{ clear: both; }
/* mail filters */
DIV#filtersListWrapper
/* mail options */
DIV#mailOptionsTabs
{ position: absolute;
top: 200px;
left: 0px;
right: 0px;
bottom: 0px; }
DIV#filtersListWrapper,
DIV#mailLabelsListWrapper
{ bottom: 30px;
bottom: 22px;
right: 2em;
right: 0px;
top: 208px;
left: 2em; }
top: 0px;
left: 2em;
left: 0px; }
#mailOptionsTabs .bottomToolbar
{ bottom: 0px;
left: 0px;
right: 0px; }
DIV#filtersListWrapper TD,
DIV#mailLabelsListWrapper TD,
DIV.bottomToolbar
{ -khtml-user-select: none;
-moz-user-select: none; }
TABLE#filtersList
#filtersList, #labelsList
{ width: 100%;
cursor: default; }
@ -212,3 +234,19 @@ P.infoMessage#passwordError
#receiptOptions
{ text-align: right; }
#colorPickerDialog
{ width: 146px;
height: 191px; }
#colorPickerDialog.dialog.right > DIV
{ padding-left: 10px; }
.dialog.bottom > DIV:before {
top: auto;
bottom: 12px;
}
.dialog.bottom > DIV:after {
top: auto;
bottom: 13px;
}

View File

@ -17,6 +17,10 @@ function savePreferences(sender) {
serializeContactsCategories();
}
if ($("mailLabelsListWrapper")) {
serializeMailLabels();
}
if (typeof mailCustomFromEnabled !== "undefined" && !emailRE.test($("email").value)) {
showAlertDialog(_("Please specify a valid sender address."));
sendForm = false;
@ -48,8 +52,8 @@ function savePreferences(sender) {
sendForm = false;
}
if ($("autoReplyText").value.strip().endsWith('\n.')) {
showAlertDialog(_("Your vacation message must not end with a single dot on a line."));
sendForm = false;
showAlertDialog(_("Your vacation message must not end with a single dot on a line."));
sendForm = false;
}
if ($("enableVacationEndDate") && $("enableVacationEndDate").checked) {
var e = $("vacationEndDate_date");
@ -144,6 +148,12 @@ function _setupEvents() {
}
}
function onBodyClickHandler(event) {
var target = getTarget(event);
if (!target.hasClassName('colorBox'))
$("colorPickerDialog").hide();
}
function onChoiceChanged(event) {
var hasChanged = $("hasChanged");
hasChanged.value = "1";
@ -157,12 +167,12 @@ function addDefaultEmailAddresses(event) {
else addresses = new Array();
defaultAddresses.each(function(adr) {
for (var i = 0; i < addresses.length; i++)
if (adr == addresses[i])
break;
if (i == addresses.length)
addresses.push(adr);
});
for (var i = 0; i < addresses.length; i++)
if (adr == addresses[i])
break;
if (i == addresses.length)
addresses.push(adr);
});
$("autoReplyEmailAddresses").value = addresses.join(", ");
@ -174,6 +184,9 @@ function initPreferences() {
var controller = new SOGoTabsController();
controller.attachToTabsContainer(tabsContainer);
var mailController = new SOGoTabsController();
mailController.attachToTabsContainer($('mailOptionsTabs'));
var filtersListWrapper = $("filtersListWrapper");
if (filtersListWrapper) {
isSieveScriptsEnabled = true;
@ -182,6 +195,10 @@ function initPreferences() {
if (typeof (initAdditionalPreferences) != "undefined")
initAdditionalPreferences();
$('colorPickerDialog').on('click', 'span', onColorPickerChoice);
$(document.body).on("click", onBodyClickHandler);
// Calender categories
var wrapper = $("calendarCategoriesListWrapper");
if (wrapper) {
var table = wrapper.childNodesWithTag("table")[0];
@ -193,8 +210,25 @@ function initPreferences() {
resetCalendarTableActions();
$("calendarCategoryAdd").observe("click", onCalendarCategoryAdd);
$("calendarCategoryDelete").observe("click", onCalendarCategoryDelete);
wrapper.observe("scroll", onBodyClickHandler);
}
// Mail labels/tags
var wrapper = $("mailLabelsListWrapper");
if (wrapper) {
var table = wrapper.childNodesWithTag("table")[0];
resetMailLabelsColors(null);
var r = $$("#mailLabelsListWrapper tbody tr");
for (var i= 0; i < r.length; i++)
r[i].identify();
table.multiselect = true;
resetMailTableActions();
$("mailLabelAdd").observe("click", onMailLabelAdd);
$("mailLabelDelete").observe("click", onMailLabelDelete);
}
// Contact categories
wrapper = $("contactsCategoriesListWrapper");
if (wrapper) {
var table = wrapper.childNodesWithTag("table")[0];
@ -314,7 +348,7 @@ function onFilterDelete(event) {
var node = nodes[i];
deletedFilters.push(node.rowIndex - 1);
}
deletedFilters = deletedFilters.sort(function (x,y) { return x-y; });
deletedFilters = deletedFilters.sort(function(x,y) { return x-y; });
var rows = filtersList.rows;
for (var i = 0; i < deletedFilters.length; i++) {
var filterNbr = deletedFilters[i];
@ -647,11 +681,13 @@ function onMailAccountEntryClick(event) {
function displayMailAccount(mailAccount, readOnly) {
var inputs = $$("#accountInfo input");
inputs.each(function (i) { i.disabled = readOnly;
i.mailAccount = mailAccount; });
inputs.each(function(i) {
i.disabled = readOnly;
i.mailAccount = mailAccount;
});
inputs = $$("#identityInfo input");
inputs.each(function (i) { i.mailAccount = mailAccount; });
inputs.each(function(i) { i.mailAccount = mailAccount; });
if (!mailCustomFromEnabled) {
for (var i = 0; i < 2; i++) {
inputs[i].disabled = readOnly;
@ -815,7 +851,7 @@ function onMailAccountDelete(event) {
function saveMailAccounts() {
/* This removal enables us to avoid a few warning from SOPE for the inputs
that were created dynamically. */
that were created dynamically. */
var editor = $("mailAccountEditor");
// Could be null if ModuleConstraints disables email access
@ -855,6 +891,45 @@ function compactMailAccounts() {
}
}
/* common function between calendar categories and mail labels */
function onColorEdit(e, target) {
var view = $(target);
view.select('div.colorEditing').each(function(box) {
box.removeClassName('colorEditing');
});
this.addClassName("colorEditing");
var cellPosition = this.cumulativeOffset();
var cellDimensions = this.getDimensions();
var div = $('colorPickerDialog');
var divDimensions = div.getDimensions();
var left = cellPosition[0] - divDimensions["width"];
var top = cellPosition[1] - 165 - view.scrollTop;
div.setStyle({ left: left + "px", top: top + "px" });
div.writeAttribute('data-target', target);
div.show();
}
function onColorPickerChoice(event) {
var span = getTarget(event);
var dialog = span.up('.dialog');
var target = dialog.readAttribute('data-target');
var newColor = "#" + span.className.substr(4);
var wrapper = $(target);
var div = wrapper.select("div.colorEditing").first();
div.writeAttribute('data-color', newColor);
div.style.background = newColor;
if (parseInt($("hasChanged").value) == 0) {
var hasChanged = $("hasChanged");
hasChanged.value = "1";
}
dialog.hide();
}
/* calendar categories */
function resetCalendarTableActions() {
var r = $$("#calendarCategoriesListWrapper tbody tr");
@ -864,70 +939,45 @@ function resetCalendarTableActions() {
var tds = row.childElements();
var editionCtlr = new RowEditionController();
editionCtlr.attachToRowElement(tds[0]);
tds[1].childElements()[0].observe("dblclick", onColorEdit);
tds[1].childElements()[0].observe("click", onCalendarColorEdit);
}
}
function onColorEdit (e) {
var r = $$("#calendarCategoriesListWrapper div.colorEditing");
for (var i=0; i<r.length; i++)
r[i].removeClassName("colorEditing");
this.addClassName ("colorEditing");
var cPicker = window.open(ApplicationBaseURL + "../" + UserLogin
+ "/Calendar/colorPicker", "colorPicker",
"width=250,height=200,resizable=0,scrollbars=0"
+ "toolbar=0,location=0,directories=0,status=0,"
+ "menubar=0,copyhistory=0", "test"
);
cPicker.focus();
preventDefault(e);
function onCalendarColorEdit(e) {
var onCCE = onColorEdit.bind(this);
onCCE(e, "calendarCategoriesListWrapper");
}
function onColorPickerChoice (newColor) {
var div = $$("#calendarCategoriesListWrapper div.colorEditing").first ();
// div.removeClassName ("colorEditing");
div.showColor = newColor;
div.style.background = newColor;
if (parseInt($("hasChanged").value) == 0) {
var hasChanged = $("hasChanged");
hasChanged.value = "1";
}
}
function onCalendarCategoryAdd(e) {
var row = new Element("tr");
var nametd = new Element("td").update("");
var colortd = new Element("td");
var colordiv = new Element("div", {"class": "colorBox", dataColor: "#F0F0F0"});
function onCalendarCategoryAdd (e) {
var row = new Element ("tr");
var nametd = new Element ("td").update ("");
var colortd = new Element ("td");
var colordiv = new Element ("div", {"class": "colorBox"});
row.identify();
row.addClassName("categoryListRow");
row.identify ();
row.addClassName ("categoryListRow");
nametd.addClassName("categoryListCell");
colortd.addClassName("categoryListCell");
colordiv.setStyle({backgroundColor: "#F0F0F0"});
nametd.addClassName ("categoryListCell");
colortd.addClassName ("categoryListCell");
colordiv.innerHTML = "&nbsp;";
colordiv.showColor = "#F0F0F0";
colordiv.style.background = colordiv.showColor;
colortd.appendChild(colordiv);
row.appendChild(nametd);
row.appendChild(colortd);
$("calendarCategoriesListWrapper").childNodesWithTag("table")[0].tBodies[0].appendChild(row);
colortd.appendChild (colordiv);
row.appendChild (nametd);
row.appendChild (colortd);
$("calendarCategoriesListWrapper").childNodesWithTag("table")[0].tBodies[0].appendChild (row);
resetCalendarTableActions ();
resetCalendarTableActions();
nametd.editionController.startEditing();
}
function onCalendarCategoryDelete (e) {
function onCalendarCategoryDelete(e) {
var list = $('calendarCategoriesListWrapper').down("TABLE").down("TBODY");
var rows = list.getSelectedNodes();
var count = rows.length;
for (var i=0; i < count; i++) {
rows[i].editionController = null;
rows[i].remove ();
rows[i].remove();
}
}
@ -936,29 +986,112 @@ function serializeCalendarCategories() {
var values = [];
for (var i = 0; i < r.length; i++) {
var tds = r[i].childElements ();
var name = $(tds.first ()).innerHTML;
var color = $(tds.last ().childElements ().first ()).showColor;
var tds = r[i].childElements();
var name = $(tds.first()).innerHTML;
var color = $(tds.last().childElements().first()).readAttribute('data-color');
values.push("\"" + name + "\": \"" + color + "\"");
}
$("calendarCategoriesValue").value = "{ " + values.join(",\n") + "}";
}
function resetCalendarCategoriesColors (e) {
function resetCalendarCategoriesColors(e) {
var divs = $$("#calendarCategoriesListWrapper DIV.colorBox");
for (var i = 0; i < divs.length; i++) {
var d = divs[i];
var color = d.innerHTML;
d.showColor = color;
var color = d.readAttribute("data-color");
if (color != "undefined")
d.setStyle({ backgroundColor: color });
d.update("&nbsp;");
}
}
/* /calendar categories */
/* mail label/tags */
function resetMailTableActions() {
var r = $$("#mailLabelsListWrapper tbody tr");
for (var i = 0; i < r.length; i++) {
var row = $(r[i]);
row.observe("mousedown", onRowClick);
var tds = row.childElements();
var editionCtlr = new RowEditionController();
editionCtlr.attachToRowElement(tds[0]);
tds[1].childElements()[0].observe("click", onMailColorEdit);
}
}
function onMailColorEdit(e) {
var onMCE = onColorEdit.bind(this);
onMCE(e, "mailLabelsListWrapper");
}
function onMailLabelAdd(e) {
var row = new Element("tr");
var nametd = new Element("td").update("");
var colortd = new Element("td");
var colordiv = new Element("div", {"class": "colorBox", dataColor: "#F0F0F0"});
row.identify();
row.addClassName("labelListRow");
nametd.addClassName("labelListCell");
colortd.addClassName("labelListCell");
colordiv.setStyle({backgroundColor: "#F0F0F0"});
colortd.appendChild(colordiv);
row.appendChild(nametd);
row.appendChild(colortd);
$("mailLabelsListWrapper").childNodesWithTag("table")[0].tBodies[0].appendChild(row);
resetMailTableActions();
nametd.editionController.startEditing();
}
function onMailLabelDelete(e) {
var list = $('mailLabelsListWrapper').down("TABLE").down("TBODY");
var rows = list.getSelectedNodes();
var count = rows.length;
for (var i=0; i < count; i++) {
rows[i].editionController = null;
rows[i].remove();
}
}
function resetMailLabelsColors(e) {
var divs = $$("#mailLabelsListWrapper DIV.colorBox");
for (var i = 0; i < divs.length; i++) {
var d = divs[i];
var color = d.readAttribute('data-color');
if (color != "undefined")
d.setStyle({ backgroundColor: color });
}
}
function serializeMailLabels() {
var r = $$("#mailLabelsListWrapper TBODY TR");
var values = [];
for (var i = 0; i < r.length; i++) {
var tds = r[i].childElements();
var name = r[i].readAttribute("data-name");
var label = $(tds.first()).innerHTML;
var color = $(tds.last().childElements().first()).readAttribute('data-color');
/* if name is null, that's because we've just added a new tag */
if (!name) {
name = label.replace(/[ \(\)\/\{%\*<>\\\"]/g, "_");
}
values.push("\"" + name + "\": [\"" + label + "\", \"" + color + "\"]");
}
$("mailLabelsValue").value = "{ " + values.join(",\n") + "}";
}
/* /mail label/tags */
/* contacts categories */
function resetContactsTableActions() {
var r = $$("#contactsCategoriesListWrapper tbody tr");
@ -986,7 +1119,7 @@ function onContactsCategoryAdd(e) {
nametd.editionController.startEditing();
}
function onContactsCategoryDelete (e) {
function onContactsCategoryDelete(e) {
var list = $('contactsCategoriesListWrapper').down("TABLE").down("TBODY");
var rows = list.getSelectedNodes();
var count = rows.length;
@ -1071,13 +1204,10 @@ function onChangePasswordClick(event) {
policy.changePassword(password);
}
else
SetLogMessage("passwordError", _("Password must not be empty."),
"error");
SetLogMessage("passwordError", _("Password must not be empty."), "error");
}
else {
SetLogMessage("passwordError", _("The passwords do not match."
+ " Please try again."),
"error");
SetLogMessage("passwordError", _("The passwords do not match. Please try again."), "error");
field.focus();
field.select();
}

View File

@ -70,8 +70,9 @@ TABLE
border-spacing: 0px; }
TABLE TD
{ padding-left: .25em;
padding-right: .25em; }
{ padding-left: .5em;
padding-right: .25em;
}
a:link
{ color: #0033CC; }
@ -1151,6 +1152,238 @@ DIV.bottomToolbar A.bottomButton SPAN:active
bottom: 0px;
left: 0px; }
/* color box */
DIV.colorBox,
#colorPickerDialog SPAN
{ cursor: pointer;
margin: 0 3px 0 0;
height: 12px;
line-height: 12px;
width: 12px;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
border: 0px; }
#colorPickerDialog SPAN
{ float: left;
margin: 3px; }
#colorPickerDialog SPAN:hover
{ border: 2px solid transparent;
margin: 1px; }
.blc-FFFFFF {
background-color: #FFFFFF;
}
.blc-CCCCCC {
background-color: #CCCCCC;
}
.blc-C0C0C0 {
background-color: #C0C0C0;
}
.blc-999999 {
background-color: #999999;
}
.blc-666666 {
background-color: #666666;
}
.blc-333333 {
background-color: #333333;
}
.blc-000000 {
background-color: #000000;
}
.blc-FFCCCC {
background-color: #FFCCCC;
}
.blc-FF6666 {
background-color: #FF6666;
}
.blc-FF0000 {
background-color: #FF0000;
}
.blc-CC0000 {
background-color: #CC0000;
}
.blc-990000 {
background-color: #990000;
}
.blc-660000 {
background-color: #660000;
}
.blc-330000 {
background-color: #330000;
}
.blc-FFCC99 {
background-color: #FFCC99;
}
.blc-FF9966 {
background-color: #FF9966;
}
.blc-FF9900 {
background-color: #FF9900;
}
.blc-FF6600 {
background-color: #FF6600;
}
.blc-CC6600 {
background-color: #CC6600;
}
.blc-993300 {
background-color: #993300;
}
.blc-663300 {
background-color: #663300;
}
.blc-FFFF99 {
background-color: #FFFF99;
}
.blc-FFFF66 {
background-color: #FFFF66;
}
.blc-FFCC66 {
background-color: #FFCC66;
}
.blc-FFCC33 {
background-color: #FFCC33;
}
.blc-CC9933 {
background-color: #CC9933;
}
.blc-996633 {
background-color: #996633;
}
.blc-663333 {
background-color: #663333;
}
.blc-FFFFCC {
background-color: #FFFFCC;
}
.blc-FFFF33 {
background-color: #FFFF33;
}
.blc-FFFF00 {
background-color: #FFFF00;
}
.blc-FFCC00 {
background-color: #FFCC00;
}
.blc-999900 {
background-color: #999900;
}
.blc-666600 {
background-color: #666600;
}
.blc-333300 {
background-color: #333300;
}
.blc-99FF99 {
background-color: #99FF99;
}
.blc-66FF99 {
background-color: #66FF99;
}
.blc-33FF33 {
background-color: #33FF33;
}
.blc-33CC00 {
background-color: #33CC00;
}
.blc-009900 {
background-color: #009900;
}
.blc-006600 {
background-color: #006600;
}
.blc-003300 {
background-color: #003300;
}
.blc-99FFFF {
background-color: #99FFFF;
}
.blc-33FFFF {
background-color: #33FFFF;
}
.blc-66CCCC {
background-color: #66CCCC;
}
.blc-00CCCC {
background-color: #00CCCC;
}
.blc-339999 {
background-color: #339999;
}
.blc-336666 {
background-color: #336666;
}
.blc-003333 {
background-color: #003333;
}
.blc-CCFFFF {
background-color: #CCFFFF;
}
.blc-66FFFF {
background-color: #66FFFF;
}
.blc-33CCFF {
background-color: #33CCFF;
}
.blc-3366FF {
background-color: #3366FF;
}
.blc-3333FF {
background-color: #3333FF;
}
.blc-000099 {
background-color: #000099;
}
.blc-000066 {
background-color: #000066;
}
.blc-CCCCFF {
background-color: #CCCCFF;
}
.blc-9999FF {
background-color: #9999FF;
}
.blc-6666CC {
background-color: #6666CC;
}
.blc-6633FF {
background-color: #6633FF;
}
.blc-6600CC {
background-color: #6600CC;
}
.blc-333399 {
background-color: #333399;
}
.blc-330099 {
background-color: #330099;
}
.blc-FFCCFF {
background-color: #FFCCFF;
}
.blc-FF99FF {
background-color: #FF99FF;
}
.blc-CC66CC {
background-color: #CC66CC;
}
.blc-CC33CC {
background-color: #CC33CC;
}
.blc-993399 {
background-color: #993399;
}
.blc-663366 {
background-color: #663366;
}
.blc-330033 {
background-color: #330033;
}
/* ckeditor */
span.cke_skin_kama
{ padding: 0px !important; }

View File

@ -46,6 +46,9 @@ DIV#bgDialogDiv
{ background-color: #555;
filter: alpha(opacity=40); }
DIV.colorBox
{ line-height: 15px; }
/* MailerUI */
IMG.dragMessage
@ -88,6 +91,10 @@ DIV.eventInside.delegated,
DIV.eventInside.declined
{ filter: alpha(opacity=40); }
#calendarList DIV.colorBox,
#schedulerTabs DIV.colorBox
{ *display: inline; /* for IE7 */ }
/* UIxAppointmentEditor */
DIV#attendeesMenu LI.separator

View File

@ -1,191 +0,0 @@
#dhtmlgoodies_colorPicker{
position:absolute;
width:250px;
padding-bottom:1px;
background-color:#FFF;
border:1px solid #317082;
width: 252px; /* IE 5.x */
width/* */:/**/250px; /* Other browsers */
width: /**/250px;
}
#dhtmlgoodies_colorPicker .colorPicker_topRow{
padding-bottom:1px;
border-bottom:3px double #317082;
background-color:#E2EBED;
padding-left:2px;
width: 250px; /* IE 5.x */
width/* */:/**/248px; /* Other browsers */
width: /**/248px;
height: 20px; /* IE 5.x */
height/* */:/**/16px; /* Other browsers */
height: /**/16px;
}
#dhtmlgoodies_colorPicker .colorPicker_statusBar{
height:13px;
padding-bottom:2px;
width:248px;
border-top:3px double #317082;
background-color:#E2EBED;
padding-left:2px;
clear:both;
width: 250px; /* IE 5.x */
width/* */:/**/248px; /* Other browsers */
width: /**/248px;
height: 18px; /* IE 5.x */
height/* */:/**/13px; /* Other browsers */
height: /**/13px;
}
#dhtmlgoodies_colorPicker .colorSquare{
margin-left:1px;
margin-bottom:1px;
float:left;
border:1px solid #000;
cursor:pointer;
width: 12px; /* IE 5.x */
width/* */:/**/10px; /* Other browsers */
width: /**/10px;
height: 12px; /* IE 5.x */
height/* */:/**/10px; /* Other browsers */
height: /**/10px;
}
.colorPickerTab_inactive,.colorPickerTab_active{
height:17px;
padding-left:4px;
cursor:pointer;
}
.colorPickerTab_inactive span{
background-image:url('tab_left_inactive.gif');
}
.colorPickerTab_active span{
background-image:url('tab_left_active.gif');
}
.colorPickerTab_inactive span, .colorPickerTab_active span{
line-height:16px;
font-weight:bold;
font-family:arial;
font-size:11px;
padding-top:1px;
vertical-align:middle;
background-position:top left;
background-repeat: no-repeat;
float:left;
padding-left:6px;
-moz-user-select:no;
}
.colorPickerTab_inactive img,.colorPickerTab_active img{
float:left;
}
.colorPickerCloseButton{
width:11px;
height:11px;
text-align:center;
line-height:10px;
border:1px solid #317082;
position:absolute;
right:1px;
font-size:12px;
font-weight:bold;
top:1px;
padding:1px;
cursor:pointer;
width: 15px; /* IE 5.x */
width/* */:/**/11px; /* Other browsers */
width: /**/11px;
height: 15px; /* IE 5.x */
height/* */:/**/11px; /* Other browsers */
height: /**/11px;
}
#colorPicker_statusBarTxt{
font-size:11px;
font-family:arial;
vertical-align:top;
line-height:13px;
}
form{
padding-left:5px;
}
.form_widget_amount_slider{
border-top:1px solid #9d9c99;
border-left:1px solid #9d9c99;
border-bottom:1px solid #eee;
border-right:1px solid #eee;
background-color:#f0ede0;
position:absolute;
bottom:0px;
width: 5px; /* IE 5.x */
width/* */:/**/3px; /* Other browsers */
width: /**/3px;
height: 5px; /* IE 5.x */
height/* */:/**/3px; /* Other browsers */
height: /**/3px;
}
.colorSliderLabel{
width:15px;
height:20px;
float:left;
font-size:11px;
font-weight:bold;
}
.colorSlider{
width:175px;
height:20px;
float:left;
}
.colorInput{
width:45px;
height:20px;
float:left;
}
.colorPreviewDiv{
width:186px;
margin-right:2px;
margin-top:1px;
border:1px solid #CCC;
height:20px;
float:left;
cursor:pointer;
width: 188px; /* IE 5.x */
width/* */:/**/186px; /* Other browsers */
width: /**/186px;
height: 22px; /* IE 5.x */
height/* */:/**/20px; /* Other browsers */
height: /**/20px;
}
.colorCodeDiv{
width:50px;
height:20px;
float:left;
}

View File

@ -4,4 +4,4 @@
MAJOR_VERSION=2
MINOR_VERSION=1
SUBMINOR_VERSION=0
SUBMINOR_VERSION=1