1/* SOGoUserDefaults.m - this file is part of SOGo
2 *
3 * Copyright (C) 2009-2016 Inverse inc.
4 *
5 * This file is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This file is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; see the file COPYING.  If not, write to
17 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 */
20
21#import <Foundation/NSArray.h>
22#import <Foundation/NSDictionary.h>
23#import <Foundation/NSSet.h>
24#import <Foundation/NSString.h>
25#import <Foundation/NSTimeZone.h>
26
27#import <NGImap4/NSString+Imap4.h>
28#import <NGObjWeb/WOApplication.h>
29#import <NGObjWeb/WOContext+SoObjects.h>
30#import <NGObjWeb/WEClientCapabilities.h>
31
32#import "NSString+Utilities.h"
33#import "SOGoDomainDefaults.h"
34#import "SOGoSystemDefaults.h"
35#import "SOGoUserProfile.h"
36
37#import "SOGoUserDefaults.h"
38
39
40NSString *SOGoWeekStartJanuary1 = @"January1";
41NSString *SOGoWeekStartFirst4DayWeek = @"First4DayWeek";
42NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek";
43
44@implementation SOGoUserDefaults
45
46+ (NSString *) userProfileClassName
47{
48  return @"SOGoSQLUserProfile";
49}
50
51+ (SOGoUserDefaults *) defaultsForUser: (NSString *) userId
52                              inDomain: (NSString *) domainId
53{
54  SOGoUserProfile *up;
55  SOGoUserDefaults *ud;
56  SOGoDefaultsSource *parent;
57  WOContext *context;
58  WEClientCapabilities *cc;
59  static Class SOGoUserProfileKlass = Nil;
60
61  if (!SOGoUserProfileKlass)
62    SOGoUserProfileKlass = NSClassFromString ([self userProfileClassName]);
63
64  up = [SOGoUserProfileKlass userProfileWithType: SOGoUserProfileTypeDefaults
65                                          forUID: userId];
66  [up fetchProfile];
67
68  parent = [SOGoDomainDefaults defaultsForDomain: domainId];
69  if (!parent)
70    parent = [SOGoSystemDefaults sharedSystemDefaults];
71
72  ud = [self defaultsSourceWithSource: up andParentSource: parent];
73
74  // CKEditor (the HTML editor) is no longer compatible with IE7;
75  // force the user to use the plain text editor with IE7
76  context = [[WOApplication application] context];
77  cc = [[context request] clientCapabilities];
78  if ([cc isInternetExplorer] && [cc majorVersion] < 8)
79    {
80      [ud setObject: @"text" forKey: @"SOGoMailComposeMessageType"];
81    }
82
83  return ud;
84}
85
86- (id) init
87{
88  if ((self = [super init]))
89    {
90      userLanguage = nil;
91    }
92
93  return self;
94}
95
96- (void) dealloc
97{
98  [userLanguage release];
99  [super dealloc];
100}
101
102- (BOOL) _migrateLastModule
103{
104  BOOL rc;
105  NSString *loginModule;
106
107  loginModule = [source objectForKey: @"SOGoUIxLastModule"];
108  if ([loginModule length])
109    {
110      rc = YES;
111      /* we need to use the old key, otherwise the migration will be blocked */
112      [self setObject: loginModule forKey: @"SOGoUIxDefaultModule"];
113      [self setRememberLastModule: YES];
114      [self removeObjectForKey: @"SOGoUIxLastModule"];
115    }
116  else
117    rc = NO;
118
119  return rc;
120}
121
122- (BOOL) _migrateSignature
123{
124  BOOL rc;
125  NSString *signature;
126  NSArray *mailAccounts, *identities;
127  NSDictionary *identity;
128
129  mailAccounts = [self arrayForKey: @"MailAccounts"];
130  if (mailAccounts)
131    {
132      rc = YES;
133      if ([mailAccounts count] > 0)
134        {
135          identities = [[mailAccounts objectAtIndex: 0]
136                         objectForKey: @"identifies"];
137          if ([identities count] > 0)
138            {
139              identity = [identities objectAtIndex: 0];
140              signature = [identity objectForKey: @"signature"];
141              if ([signature length])
142                [self setObject: signature forKey: @"MailSignature"];
143            }
144        }
145      [self removeObjectForKey: @"MailAccounts"];
146    }
147  else
148    rc = NO;
149
150  return rc;
151}
152
153- (BOOL) _migrateCalendarCategories
154{
155  NSArray *categories, *colors;
156  NSDictionary *newColors;
157  BOOL rc;
158
159  colors = [source objectForKey: @"SOGoCalendarCategoriesColors"];
160  if ([colors isKindOfClass: [NSArray class]])
161    {
162      categories = [source objectForKey: @"SOGoCalendarCategories"];
163      if ([categories count] == [colors count])
164        {
165          newColors = [NSDictionary dictionaryWithObjects: colors
166                                                  forKeys: categories];
167          [source setObject: newColors
168                     forKey: @"SOGoCalendarCategoriesColors"];
169        }
170      else
171        [source removeObjectForKey: @"SOGoCalendarCategoriesColors"];
172      rc = YES;
173    }
174  else
175    rc = NO;
176
177  return rc;
178}
179
180- (BOOL) migrate
181{
182  static NSDictionary *migratedKeys = nil;
183
184  if (!migratedKeys)
185    {
186      migratedKeys
187        = [NSDictionary dictionaryWithObjectsAndKeys:
188                        @"SOGoLoginModule", @"SOGoUIxDefaultModule",
189                        @"SOGoLoginModule", @"SOGoDefaultModule",
190                        @"SOGoTimeFormat", @"TimeFormat",
191                        @"SOGoShortDateFormat", @"ShortDateFormat",
192                        @"SOGoLongDateFormat", @"LongDateFormat",
193                        @"SOGoDayStartTime", @"DayStartTime",
194                        @"SOGoDayEndTime", @"DayEndTime",
195                        @"SOGoFirstDayOfWeek", @"WeekStartDay",
196                        @"SOGoFirstWeekOfYear", @"FirstWeek",
197                        @"SOGoLanguage", @"SOGoDefaultLanguage",
198                        @"SOGoLanguage", @"Language",
199                        @"SOGoMailComposeMessageType", @"ComposeMessagesType",
200                        @"SOGoSelectedAddressBook", @"SelectedAddressBook",
201                        @"SOGoRefreshViewCheck", @"RefreshViewCheck",
202                        @"SOGoMailMessageForwarding", @"MessageForwarding",
203                        @"SOGoMailSignature", @"MailSignature",
204                        @"SOGoMailSignaturePlacement", @"SignaturePlacement",
205                        @"SOGoMailReplyPlacement", @"ReplyPlacement",
206                        @"SOGoTimeZone", @"TimeZone",
207                        @"SOGoCalendarShouldDisplayWeekend", @"SOGoShouldDisplayWeekend",
208                        @"SOGoMailShowSubscribedFoldersOnly", @"showSubscribedFoldersOnly",
209                        @"SOGoReminderEnabled", @"ReminderEnabled",
210                        @"SOGoReminderTime", @"ReminderTime",
211                        @"SOGoRemindWithASound", @"RemindWithASound",
212                        nil];
213      [migratedKeys retain];
214    }
215
216  /* we must not use a boolean operation, otherwise subsequent migrations will
217     not be invoked in the case where rc = YES. */
218  return ([self _migrateLastModule]
219          | [self _migrateSignature]
220          | [self _migrateCalendarCategories]
221          | [self migrateOldDefaultsWithDictionary: migratedKeys]
222          | [super migrate]);
223}
224
225- (void) setLoginModule: (NSString *) newLoginModule
226{
227  [self setObject: newLoginModule forKey: @"SOGoLoginModule"];
228}
229
230- (NSString *) loginModule
231{
232  return [self stringForKey: @"SOGoLoginModule"];
233}
234
235- (void) setRememberLastModule: (BOOL) rememberLastModule
236{
237  [self setBool: rememberLastModule forKey: @"SOGoRememberLastModule"];
238}
239
240- (BOOL) rememberLastModule
241{
242  return [self boolForKey: @"SOGoRememberLastModule"];
243}
244
245- (void) setDefaultCalendar: (NSString *) newDefaultCalendar
246{
247  [self setObject: newDefaultCalendar forKey: @"SOGoDefaultCalendar"];
248}
249
250- (NSString *) defaultCalendar
251{
252  return [self stringForKey: @"SOGoDefaultCalendar"];
253}
254
255- (void) setDayStartTime: (NSString *) newValue
256{
257  [self setObject: newValue forKey: @"SOGoDayStartTime"];
258}
259
260- (NSString *) dayStartTime
261{
262  return [self stringForKey: @"SOGoDayStartTime"];
263}
264
265- (unsigned int) dayStartHour
266{
267  return [[self dayStartTime] timeValue];
268}
269
270- (void) setDayEndTime: (NSString *) newValue
271{
272  [self setObject: newValue forKey: @"SOGoDayEndTime"];
273}
274
275- (NSString *) dayEndTime
276{
277  return [self stringForKey: @"SOGoDayEndTime"];
278}
279
280- (unsigned int) dayEndHour
281{
282  return [[self dayEndTime] timeValue];
283}
284
285- (void) setBusyOffHours: (BOOL) newValue
286{
287  [self setBool: newValue forKey: @"SOGoBusyOffHours"];
288}
289
290- (BOOL) busyOffHours
291{
292  return [self boolForKey: @"SOGoBusyOffHours"];
293}
294
295- (void) setTimeZoneName: (NSString *) newValue
296{
297  [self setObject: newValue forKey: @"SOGoTimeZone"];
298}
299
300- (NSString *) timeZoneName
301{
302  return [self stringForKey: @"SOGoTimeZone"];
303}
304
305- (void) setTimeZone: (NSTimeZone *) newValue
306{
307  [self setTimeZoneName: [newValue name]];
308}
309
310- (NSTimeZone *) timeZone
311{
312  return [NSTimeZone timeZoneWithName: [self timeZoneName]];
313}
314
315- (void) setLongDateFormat: (NSString *) newFormat
316{
317  [self setObject: newFormat forKey: @"SOGoLongDateFormat"];
318}
319
320- (void) unsetLongDateFormat
321{
322  [self removeObjectForKey: @"SOGoLongDateFormat"];
323}
324
325- (NSString *) longDateFormat
326{
327  return [self stringForKey: @"SOGoLongDateFormat"];
328}
329
330- (void) setShortDateFormat: (NSString *) newFormat;
331{
332  [self setObject: newFormat forKey: @"SOGoShortDateFormat"];
333}
334
335- (void) unsetShortDateFormat
336{
337  [self removeObjectForKey: @"SOGoShortDateFormat"];
338}
339
340- (NSString *) shortDateFormat;
341{
342  return [self stringForKey: @"SOGoShortDateFormat"];
343}
344
345- (void) setTimeFormat: (NSString *) newFormat
346{
347  [self setObject: newFormat forKey: @"SOGoTimeFormat"];
348}
349
350- (void) unsetTimeFormat
351{
352  [self removeObjectForKey: @"SOGoTimeFormat"];
353}
354
355- (NSString *) timeFormat
356{
357  return [self stringForKey: @"SOGoTimeFormat"];
358}
359
360- (void) setLanguage: (NSString *) newValue
361{
362  [self setObject: newValue forKey: @"SOGoLanguage"];
363}
364
365- (NSString *) language
366{
367  NSArray *supportedLanguages;
368
369  if (!userLanguage)
370    {
371      /* see SOGoDomainDefaults for the meaning of this */
372      userLanguage = [source objectForKey: @"SOGoLanguage"];
373      if (!(userLanguage && [userLanguage isKindOfClass: [NSString class]]))
374        userLanguage = [(SOGoDomainDefaults *) parentSource language];
375
376      supportedLanguages = [[SOGoSystemDefaults sharedSystemDefaults]
377                             supportedLanguages];
378
379      /* make sure the language is part of the supported languages */
380      if (![supportedLanguages containsObject: userLanguage])
381        userLanguage = [parentSource stringForKey: @"SOGoLanguage"];
382      [userLanguage retain];
383    }
384
385  return userLanguage;
386}
387
388- (void) setMailAddOutgoingAddresses: (BOOL) newValue
389{
390  [self setBool: newValue forKey: @"SOGoMailAddOutgoingAddresses"];
391}
392
393- (BOOL) mailAddOutgoingAddresses
394{
395  return [self boolForKey: @"SOGoMailAddOutgoingAddresses"];
396}
397
398- (void) setMailShowSubscribedFoldersOnly: (BOOL) newValue
399{
400  [self setBool: newValue forKey: @"SOGoMailShowSubscribedFoldersOnly"];
401}
402
403- (BOOL) mailShowSubscribedFoldersOnly
404{
405  return [self boolForKey: @"SOGoMailShowSubscribedFoldersOnly"];
406}
407
408- (void) setSynchronizeOnlyDefaultMailFolders: (BOOL) newValue
409{
410  [self setBool: newValue forKey: @"SOGoMailSynchronizeOnlyDefaultFolders"];
411}
412
413- (BOOL) synchronizeOnlyDefaultMailFolders
414{
415  return [self boolForKey: @"SOGoMailSynchronizeOnlyDefaultFolders"];
416}
417
418- (void) setMailSortByThreads: (BOOL) newValue
419{
420  [self setBool: newValue forKey: @"SOGoMailSortByThreads"];
421}
422
423- (BOOL) mailSortByThreads
424{
425  return [self boolForKey: @"SOGoMailSortByThreads"];
426}
427
428- (void) setDraftsFolderName: (NSString *) newValue
429{
430  [self setObject: newValue forKey: @"SOGoDraftsFolderName"];
431}
432
433- (NSString *) draftsFolderName
434{
435  return [[self stringForKey: @"SOGoDraftsFolderName"]
436             stringByEncodingImap4FolderName];
437}
438
439- (void) setSentFolderName: (NSString *) newValue
440{
441  [self setObject: newValue forKey: @"SOGoSentFolderName"];
442}
443
444- (NSString *) sentFolderName
445{
446  return [[self stringForKey: @"SOGoSentFolderName"]
447             stringByEncodingImap4FolderName];
448}
449
450- (void) setTrashFolderName: (NSString *) newValue
451{
452  [self setObject: newValue forKey: @"SOGoTrashFolderName"];
453}
454
455- (NSString *) trashFolderName
456{
457  return [[self stringForKey: @"SOGoTrashFolderName"]
458             stringByEncodingImap4FolderName];
459}
460
461- (void) setJunkFolderName: (NSString *) newValue
462{
463  [self setObject: newValue forKey: @"SOGoJunkFolderName"];
464}
465
466- (NSString *) junkFolderName
467{
468  return [[self stringForKey: @"SOGoJunkFolderName"]
469             stringByEncodingImap4FolderName];
470}
471
472- (void) setFirstDayOfWeek: (int) newValue
473{
474  [self setInteger: newValue forKey: @"SOGoFirstDayOfWeek"];
475}
476
477- (int) firstDayOfWeek
478{
479  return [self integerForKey: @"SOGoFirstDayOfWeek"];
480}
481
482- (void) setFirstWeekOfYear: (NSString *) newValue
483{
484  [self setObject: newValue forKey: @"SOGoFirstWeekOfYear"];
485}
486
487- (NSString *) firstWeekOfYear
488{
489  return [self stringForKey: @"SOGoFirstWeekOfYear"];
490}
491
492- (void) setMailListViewColumnsOrder: (NSArray *) newValue
493{
494  [self setObject: newValue forKey: @"SOGoMailListViewColumnsOrder"];
495}
496
497- (NSArray *) mailListViewColumnsOrder
498{
499  return [self stringArrayForKey: @"SOGoMailListViewColumnsOrder"];
500}
501
502- (void) setSelectedAddressBook:(NSString *) newValue
503{
504  [self setObject: newValue forKey: @"SOGoSelectedAddressBook"];
505}
506
507- (NSString *) selectedAddressBook
508{
509  return [self stringForKey: @"SOGoSelectedAddressBook"];
510}
511
512- (void) setRefreshViewCheck: (NSString *) newValue
513{
514  [self setObject: newValue forKey: @"SOGoRefreshViewCheck"];
515}
516
517- (NSString *) refreshViewCheck
518{
519  return [self stringForKey: @"SOGoRefreshViewCheck"];
520}
521
522- (void) setMailComposeMessageType: (NSString *) newValue
523{
524  [self setObject: newValue forKey: @"SOGoMailComposeMessageType"];
525}
526
527- (NSString *) mailComposeMessageType
528{
529  return [self stringForKey: @"SOGoMailComposeMessageType"];
530}
531
532- (void) setMailDisplayRemoteInlineImages: (NSString *) newValue
533{
534  [self setObject: newValue forKey: @"SOGoMailDisplayRemoteInlineImages"];
535}
536
537- (NSString *) mailDisplayRemoteInlineImages;
538{
539  return [self stringForKey: @"SOGoMailDisplayRemoteInlineImages"];
540}
541
542- (void) setMailAutoSave: (NSString *) newValue
543{
544  NSString *s;
545
546  if ([newValue intValue] <= 0)
547    s = @"5";
548  else
549    s = newValue;
550
551  [self setObject: s forKey: @"SOGoMailAutoSave"];
552}
553
554- (NSString *) mailAutoSave
555{
556  NSString *s;
557
558  s = [self stringForKey: @"SOGoMailAutoSave"];
559
560  if ([s intValue] <= 0)
561    s = @"5";
562
563  return s;
564}
565
566- (void) setMailMessageForwarding: (NSString *) newValue
567{
568  [self setObject: newValue forKey: @"SOGoMailMessageForwarding"];
569}
570
571- (NSString *) mailMessageForwarding
572{
573  return [self stringForKey: @"SOGoMailMessageForwarding"];
574}
575
576- (void) setMailReplyPlacement: (NSString *) newValue
577{
578  [self setObject: newValue forKey: @"SOGoMailReplyPlacement"];
579}
580
581- (NSString *) mailReplyPlacement
582{
583  return [self stringForKey: @"SOGoMailReplyPlacement"];
584}
585
586- (void) setMailSignature: (NSString *) newValue
587{
588  if ([newValue length] == 0)
589    newValue = nil;
590  [self setObject: newValue forKey: @"SOGoMailSignature"];
591}
592
593- (NSString *) mailSignature
594{
595  return [self stringForKey: @"SOGoMailSignature"];
596}
597
598- (void) setMailSignaturePlacement: (NSString *) newValue
599{
600  [self setObject: newValue forKey: @"SOGoMailSignaturePlacement"];
601}
602
603- (NSString *) mailSignaturePlacement
604{
605  NSString *signaturePlacement;
606
607  if ([[self mailReplyPlacement] isEqualToString: @"below"])
608    // When replying to an email, if the reply is below the quoted text,
609    // the signature must also be below the quoted text.
610    signaturePlacement = @"below";
611  else
612    signaturePlacement = [self stringForKey: @"SOGoMailSignaturePlacement"];
613
614  return signaturePlacement;
615}
616
617- (void) setMailCustomFullName: (NSString *) newValue
618{
619  if ([newValue length] == 0)
620    newValue = nil;
621  [self setObject: [newValue stringByTrimmingSpaces]
622           forKey: @"SOGoMailCustomFullName"];
623}
624
625- (NSString *) mailCustomFullName
626{
627  return [self stringForKey: @"SOGoMailCustomFullName"];
628}
629
630- (void) setMailCustomEmail: (NSString *) newValue
631{
632  if ([newValue length] == 0)
633    newValue = nil;
634  [self setObject: [newValue stringByTrimmingSpaces]
635           forKey: @"SOGoMailCustomEmail"];
636}
637
638- (NSString *) mailCustomEmail
639{
640  return [self stringForKey: @"SOGoMailCustomEmail"];
641}
642
643- (void) setMailReplyTo: (NSString *) newValue
644{
645  if ([newValue length] == 0)
646    newValue = nil;
647  [self setObject: [newValue stringByTrimmingSpaces]
648           forKey: @"SOGoMailReplyTo"];
649}
650
651- (NSString *) mailReplyTo
652{
653  return [self stringForKey: @"SOGoMailReplyTo"];
654}
655
656- (void) setAllowUserReceipt: (BOOL) allow
657{
658  [self setBool: allow forKey: @"SOGoMailReceiptAllow"];
659}
660
661- (BOOL) allowUserReceipt
662{
663  return [self boolForKey: @"SOGoMailReceiptAllow"];
664}
665
666- (void) setUserReceiptNonRecipientAction: (NSString *) action
667{
668  [self setObject: action forKey: @"SOGoMailReceiptNonRecipientAction"];
669}
670
671- (NSString *) userReceiptNonRecipientAction
672{
673  return [self stringForKey: @"SOGoMailReceiptNonRecipientAction"];
674}
675
676- (void) setUserReceiptOutsideDomainAction: (NSString *) action
677{
678  [self setObject: action forKey: @"SOGoMailReceiptOutsideDomainAction"];
679}
680
681- (NSString *) userReceiptOutsideDomainAction
682{
683  return [self stringForKey: @"SOGoMailReceiptOutsideDomainAction"];
684}
685
686- (void) setUserReceiptAnyAction: (NSString *) action
687{
688  [self setObject: action forKey: @"SOGoMailReceiptAnyAction"];
689}
690
691- (NSString *) userReceiptAnyAction
692{
693  return [self stringForKey: @"SOGoMailReceiptAnyAction"];
694}
695
696- (void) setMailUseOutlookStyleReplies: (BOOL) newValue
697{
698  [self setBool: newValue forKey: @"SOGoMailUseOutlookStyleReplies"];
699}
700
701- (BOOL) mailUseOutlookStyleReplies
702{
703  return [self boolForKey: @"SOGoMailUseOutlookStyleReplies"];
704}
705
706- (void) setAuxiliaryMailAccounts: (NSArray *) newAccounts
707{
708  [self setObject: newAccounts forKey: @"AuxiliaryMailAccounts"];
709}
710
711- (NSArray *) auxiliaryMailAccounts
712{
713  return [self arrayForKey: @"AuxiliaryMailAccounts"];
714}
715
716- (void) setCalendarCategories: (NSArray *) newValues
717{
718  [self setObject: newValues forKey: @"SOGoCalendarCategories"];
719}
720
721- (NSArray *) calendarCategories
722{
723  return [self stringArrayForKey: @"SOGoCalendarCategories"];
724}
725
726- (void) setCalendarCategoriesColors: (NSDictionary *) newValues
727{
728  [self setObject: newValues forKey: @"SOGoCalendarCategoriesColors"];
729}
730
731- (NSDictionary *) calendarCategoriesColors
732{
733  return [self objectForKey: @"SOGoCalendarCategoriesColors"];
734}
735
736- (void) setCalendarShouldDisplayWeekend: (BOOL) newValue
737{
738  [self setBool: newValue forKey: @"SOGoCalendarShouldDisplayWeekend"];
739}
740
741- (BOOL) calendarShouldDisplayWeekend
742{
743  return [self boolForKey: @"SOGoCalendarShouldDisplayWeekend"];
744}
745
746- (void) setCalendarEventsDefaultClassification: (NSString *) newValue
747{
748  [self setObject: newValue forKey: @"SOGoCalendarEventsDefaultClassification"];
749}
750
751- (NSString *) calendarEventsDefaultClassification
752{
753  return [self stringForKey: @"SOGoCalendarEventsDefaultClassification"];
754}
755
756- (void) setCalendarTasksDefaultClassification: (NSString *) newValue
757{
758  [self setObject: newValue forKey: @"SOGoCalendarTasksDefaultClassification"];
759}
760
761- (NSString *) calendarTasksDefaultClassification
762{
763  return [self stringForKey: @"SOGoCalendarTasksDefaultClassification"];
764}
765
766- (void) setCalendarDefaultReminder: (NSString *) newValue
767{
768  [self setObject: newValue forKey: @"SOGoCalendarDefaultReminder"];
769}
770
771- (NSString *) calendarDefaultReminder
772{
773  return [self stringForKey: @"SOGoCalendarDefaultReminder"];
774}
775
776//
777// Dictionary of arrays. Example:
778//
779// {
780//   label1 => ("Important", "#FF0000");
781//   label2 => ("Work" "#00FF00");
782//   foo_bar => ("Foo Bar", "#0000FF");
783// }
784//
785- (void) setMailLabelsColors: (NSDictionary *) newValues
786{
787  [self setObject: newValues forKey: @"SOGoMailLabelsColors"];
788}
789
790- (NSDictionary *) mailLabelsColors
791{
792  return [self objectForKey: @"SOGoMailLabelsColors"];
793}
794
795
796- (void) setSieveFilters: (NSArray *) newValue
797{
798  [self setObject: newValue forKey: @"SOGoSieveFilters"];
799}
800
801- (NSArray *) sieveFilters
802{
803  return [self arrayForKey: @"SOGoSieveFilters"];
804}
805
806- (void) setVacationOptions: (NSDictionary *) newValue
807{
808  [self setObject: newValue forKey: @"Vacation"];
809}
810
811- (NSDictionary *) vacationOptions
812{
813  return [self dictionaryForKey: @"Vacation"];
814}
815
816- (void) setForwardOptions: (NSDictionary *) newValue
817{
818  [self setObject: newValue forKey: @"Forward"];
819}
820
821- (NSDictionary *) forwardOptions
822{
823  return [self dictionaryForKey: @"Forward"];
824}
825
826- (void) setContactsCategories: (NSArray *) newValues
827{
828  [self setObject: newValues forKey: @"SOGoContactsCategories"];
829}
830
831- (NSArray *) contactsCategories
832{
833  return [self stringArrayForKey: @"SOGoContactsCategories"];
834}
835
836@end
837