1 /* 2 * ***** BEGIN LICENSE BLOCK ***** 3 * Zimbra Collaboration Suite Web Client 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. 5 * 6 * The contents of this file are subject to the Common Public Attribution License Version 1.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at: https://www.zimbra.com/license 9 * The License is based on the Mozilla Public License Version 1.1 but Sections 14 and 15 10 * have been added to cover use of software over a computer network and provide for limited attribution 11 * for the Original Developer. In addition, Exhibit A has been modified to be consistent with Exhibit B. 12 * 13 * Software distributed under the License is distributed on an "AS IS" basis, 14 * WITHOUT WARRANTY OF ANY KIND, either express or implied. 15 * See the License for the specific language governing rights and limitations under the License. 16 * The Original Code is Zimbra Open Source Web Client. 17 * The Initial Developer of the Original Code is Zimbra, Inc. All rights to the Original Code were 18 * transferred by Zimbra, Inc. to Synacor, Inc. on September 14, 2015. 19 * 20 * All portions of the code are Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. All Rights Reserved. 21 * ***** END LICENSE BLOCK ***** 22 */ 23 24 /** 25 * @overview 26 */ 27 28 /** 29 * Creates the preferences application. 30 * @class 31 * This class represents the application for the preferences UI. This is where the preferences 32 * hook into the overall application. 33 * 34 * @param {DwtControl} container the control that contains components 35 * @param {ZmController} parentController the parent window controller (set by the child window) 36 * 37 * @extends ZmApp 38 */ 39 ZmPreferencesApp = function(container, parentController) { 40 ZmApp.call(this, ZmApp.PREFERENCES, container, parentController); 41 42 // must be hash for case of multi-accounts 43 this._filterRules = {}; 44 this._outgoingFilterRules = {}; 45 }; 46 47 ZmPreferencesApp.prototype = new ZmApp; 48 ZmPreferencesApp.prototype.constructor = ZmPreferencesApp; 49 50 ZmPreferencesApp.prototype.isZmPreferencesApp = true; 51 ZmPreferencesApp.prototype.toString = function() { return "ZmPreferencesApp"; }; 52 53 54 // Organizer and item-related constants 55 ZmEvent.S_FILTER = "FILTER"; 56 ZmEvent.S_PREF_ZIMLET = "PREF_ZIMLET"; 57 ZmEvent.S_PREF_ACCOUNT = "PREF_ACCOUNT"; 58 ZmEvent.S_PREF_BACKUP = "PREF_BACKUP"; 59 60 // App-related constants 61 /** 62 * Defines the "preferences" application. 63 */ 64 ZmApp.PREFERENCES = ZmId.APP_PREFERENCES; 65 ZmApp.CLASS[ZmApp.PREFERENCES] = "ZmPreferencesApp"; 66 ZmApp.SETTING[ZmApp.PREFERENCES] = ZmSetting.OPTIONS_ENABLED; 67 ZmApp.LOAD_SORT[ZmApp.PREFERENCES] = 10; 68 ZmApp.QS_ARG[ZmApp.PREFERENCES] = "options"; 69 ZmOrganizer.PREF_PAGE = "PREF_PAGE"; 70 ZmPreferencesApp.QS_ARG_SECTION = "section"; 71 72 // NOTE: This is registered staticly to guarantee that all of the 73 // enabled app's preferences will be registered by the time 74 // that another app listener gets the launch event and may 75 // want to alter those prefs. 76 ZmPreferencesApp._registerAllPrefs = 77 function() { 78 AjxDispatcher.require("PreferencesCore"); 79 appCtxt.getAppController().runAppFunction("_registerPrefs"); 80 }; 81 ZmZimbraMail.addAppListener(ZmApp.PREFERENCES, ZmAppEvent.PRE_LAUNCH, new AjxListener(ZmPreferencesApp._registerAllPrefs)); 82 83 // 84 // Public methods 85 // 86 87 // App API 88 89 ZmPreferencesApp.prototype.launch = 90 function(params, callback) { 91 // first time launch of prefs app should reset active app to "local" account 92 if (appCtxt.multiAccounts) { 93 appCtxt.accountList.setActiveAccount(appCtxt.accountList.mainAccount); 94 } 95 96 var gotoSection = (params.qsParams && params.qsParams[ZmPreferencesApp.QS_ARG_SECTION]) || "GENERAL"; 97 callback = new AjxCallback(this, this.gotoSection, [gotoSection, callback]); 98 99 var loadCallback = new AjxCallback(this, this._handleLoadLaunch, [callback]); 100 AjxDispatcher.require(["PreferencesCore", "Preferences"], true, loadCallback, null, true); 101 }; 102 103 // Public methods 104 105 /** 106 * Gets the preferences controller. 107 * 108 * @return {ZmPrefController} the controller 109 */ 110 ZmPreferencesApp.prototype.getPrefController = 111 function() { 112 if (!this._prefController) { 113 AjxDispatcher.require(["PreferencesCore", "Preferences"]); 114 this._prefController = new ZmPrefController(this._container, this); 115 } 116 return this._prefController; 117 }; 118 119 /** 120 * Gets the filter controller. 121 * 122 * @return {ZmFilterController} the controller 123 */ 124 ZmPreferencesApp.prototype.getFilterController = 125 function() { 126 if (!this._filterController) { 127 this._filterController = this.getPrefController().getFilterController(); 128 } 129 return this._filterController; 130 }; 131 132 /** 133 * Gets the filter rules. 134 * 135 * @param {String} [accountName] the account name or <code>null</code> to use the active account 136 * @return {ZmFilterRules} the filter rules 137 */ 138 ZmPreferencesApp.prototype.getFilterRules = 139 function(accountName) { 140 var ac = window.parentAppCtxt || window.appCtxt; 141 var acct = accountName || ac.getActiveAccount().name; 142 143 if (!this._filterRules[acct]) { 144 this._filterRules[acct] = new ZmFilterRules(acct); 145 } 146 return this._filterRules[acct]; 147 }; 148 149 /** 150 * Gets the outgoing filter rules. 151 * 152 * @param {String} [accountName] the account name or <code>null</code> to use the active account 153 * @return {ZmFilterRules} the filter rules 154 */ 155 ZmPreferencesApp.prototype.getOutgoingFilterRules = 156 function(accountName) { 157 var ac = window.parentAppCtxt || window.appCtxt; 158 var acct = accountName || ac.getActiveAccount().name; 159 160 if (!this._outgoingFilterRules[acct]) { 161 this._outgoingFilterRules[acct] = new ZmFilterRules(acct, true); 162 } 163 return this._outgoingFilterRules[acct]; 164 }; 165 166 ZmPreferencesApp.prototype.modifyNotify = 167 function(modifies, force) { 168 169 var sharingView = this._getSharingView(); 170 if (sharingView) { 171 sharingView.notifyModify(modifies); 172 } 173 }; 174 175 ZmPreferencesApp.prototype.refresh = 176 function(refresh, addr) { 177 var trustedPage = this.getPreferencesPage("TRUSTED_ADDR"); 178 if(trustedPage && addr) { 179 trustedPage.addItem(addr); 180 } 181 if (!appCtxt.inStartup) { 182 var sharingView = this._getSharingView(); 183 if (sharingView) { 184 sharingView.refresh(refresh); 185 } 186 } 187 }; 188 189 ZmPreferencesApp.prototype.gotoSection = 190 function(section, callback) { 191 if (section) { 192 var prefCtlr = this.getPrefController(); 193 var prefsView = prefCtlr && prefCtlr.getPrefsView(); 194 if (prefsView) { 195 section = section.toUpperCase(); 196 var overview = this.getOverview(); 197 if (overview) { 198 overview.setSelected([ZmOrganizer.PREF_PAGE, section].join("_")); 199 } 200 prefsView.selectSection(section); 201 } 202 } 203 if (callback && callback.run) { 204 callback.run(); 205 } 206 }; 207 208 209 210 // 211 // Protected methods 212 // 213 214 // Construction 215 216 ZmPreferencesApp.prototype._defineAPI = 217 function() { 218 AjxDispatcher.registerMethod("GetFilterRules", ["PreferencesCore", "Preferences"], new AjxCallback(this, this.getFilterRules)); 219 AjxDispatcher.registerMethod("GetOutgoingFilterRules", ["PreferencesCore", "Preferences"], new AjxCallback(this, this.getOutgoingFilterRules)); 220 AjxDispatcher.registerMethod("GetPrefController", ["PreferencesCore", "Preferences"], new AjxCallback(this, this.getPrefController)); 221 AjxDispatcher.registerMethod("GetFilterController", ["PreferencesCore", "Preferences"], new AjxCallback(this, this.getFilterController)); 222 }; 223 224 ZmPreferencesApp.prototype._registerOrganizers = function() { 225 ZmOrganizer.registerOrg(ZmOrganizer.PREF_PAGE, 226 {app: ZmApp.PREFERENCES, 227 orgClass: "ZmPrefPage", 228 orgPackage: "PreferencesCore", 229 treeController: "ZmPrefPageTreeController", 230 labelKey: "preferences", 231 treeType: ZmOrganizer.PREF_PAGE, 232 displayOrder: 100 233 }); 234 235 }; 236 237 ZmPreferencesApp.prototype._registerOperations = 238 function() { 239 ZmOperation.registerOp(ZmId.OP_MOBILE_REMOVE, {textKey:"mobileRemoveFromList", image:"Delete"}); 240 ZmOperation.registerOp(ZmId.OP_MOBILE_RESUME_SYNC, {textKey:"mobileResumeSync", image:"ImAvailable"}); 241 ZmOperation.registerOp(ZmId.OP_MOBILE_SUSPEND_SYNC, {textKey:"mobileSuspendSync", image:"Offline"}); 242 ZmOperation.registerOp(ZmId.OP_MOBILE_WIPE, {textKey:"mobileWipe", image:"MobileWipe"}, ZmSetting.MOBILE_POLICY_ENABLED); 243 ZmOperation.registerOp(ZmId.OP_MOBILE_CANCEL_WIPE, {textKey:"mobileWipeCancel", image:"MobileWipeCancel"}, ZmSetting.MOBILE_POLICY_ENABLED); 244 ZmOperation.registerOp(ZmId.OP_REVERT_PAGE, {textKey:"restorePage"}); 245 246 /* ZmOperation.registerOp(ZmId.OP_ADD_QUICK_COMMAND, {textKey:"quickCommandAdd", image:"Plus"}, ZmSetting.FILTERS_ENABLED); 247 ZmOperation.registerOp(ZmId.OP_EDIT_QUICK_COMMAND, {textKey:"quickCommandEdit", image:"Edit"}, ZmSetting.FILTERS_ENABLED); 248 ZmOperation.registerOp(ZmId.OP_REMOVE_QUICK_COMMAND, {textKey:"quickCommandRemove", image:"Delete"}, ZmSetting.FILTERS_ENABLED); */ 249 }; 250 251 ZmPreferencesApp.prototype._registerSettings = 252 function(settings) { 253 settings = settings || appCtxt.getSettings(); 254 settings.registerSetting("IMPORT_FOLDER", {type:ZmSetting.T_PSEUDO, dataType:ZmSetting.D_NONE}); 255 settings.registerSetting("IMPORT_BUTTON", {type:ZmSetting.T_PSEUDO, dataType:ZmSetting.D_NONE}); 256 settings.registerSetting("EXPORT_FOLDER", {type:ZmSetting.T_PSEUDO, dataType:ZmSetting.D_NONE}); 257 settings.registerSetting("EXPORT_BUTTON", {type:ZmSetting.T_PSEUDO, dataType:ZmSetting.D_NONE}); 258 settings.registerSetting("PREF_SECTIONS", {type:ZmSetting.T_PSEUDO, dataType:ZmSetting.D_HASH, isGlobal:true}); 259 settings.registerSetting("SIGNATURE_MAX_LENGTH", {name:"zimbraMailSignatureMaxLength", type:ZmSetting.T_COS, dataType:ZmSetting.D_INT, defaultValue:1024}); 260 settings.registerSetting("DISCARD_IN_FILTER_ENABLED", {name:"zimbraFeatureDiscardInFiltersEnabled", type:ZmSetting.T_COS, dataType:ZmSetting.D_BOOLEAN, defaultValue:true}); 261 settings.registerSetting("FROM_DISPLAY_ENABLED", {name: "zimbraFeatureFromDisplayEnabled", type: ZmSetting.T_COS, dataType: ZmSetting.D_BOOLEAN, defaultValue: true}); 262 //settings.registerSetting("QUICK_COMMAND_LIST", {name:"zimbraPrefQuickCommand", type: ZmSetting.T_COS, dataType: ZmSetting.D_LIST}); 263 }; 264 265 ZmPreferencesApp.prototype._registerApp = 266 function() { 267 ZmApp.registerApp(ZmApp.PREFERENCES, 268 {mainPkg: "Preferences", 269 nameKey: "preferences", 270 icon: "Preferences", 271 textPrecedence: 50, 272 chooserTooltipKey: "goToOptions", 273 button: appCtxt.isChildWindow ? null : ZmAppChooser.B_OPTIONS, 274 overviewTrees: [ZmOrganizer.PREF_PAGE], 275 hideZimlets: true, 276 gotoActionCode: ZmKeyMap.GOTO_OPTIONS, 277 chooserSort: 180 278 }); 279 }; 280 281 ZmPreferencesApp.prototype._registerPrefs = function() { 282 283 var sections = { 284 285 GENERAL: { 286 title: ZmMsg.general, 287 templateId: "prefs.Pages#General", 288 priority: 0, 289 prefs: [ 290 ZmSetting.LOCALE_NAME, 291 ZmSetting.COMPOSE_INIT_DIRECTION, 292 ZmSetting.SHOW_COMPOSE_DIRECTION_BUTTONS, 293 ZmSetting.FONT_NAME, 294 ZmSetting.FONT_SIZE, 295 ZmSetting.PASSWORD, 296 ZmSetting.SEARCH_INCLUDES_SHARED, 297 ZmSetting.SEARCH_INCLUDES_SPAM, 298 ZmSetting.SEARCH_INCLUDES_TRASH, 299 ZmSetting.OFFLINE_SHOW_ALL_MAILBOXES, 300 ZmSetting.SHOW_SEARCH_STRING, 301 ZmSetting.SHOW_SELECTION_CHECKBOX, 302 ZmSetting.SKIN_NAME, 303 ZmSetting.CLIENT_TYPE, 304 ZmSetting.DEFAULT_TIMEZONE, 305 ZmSetting.DEFAULT_PRINTFONTSIZE, 306 ZmSetting.OFFLINE_IS_MAILTO_HANDLER, 307 ZmSetting.SHORT_ADDRESS, 308 ZmSetting.OFFLINE_UPDATE_NOTIFY //offline 309 ] 310 }, 311 312 ACCOUNTS: { 313 icon: "Accounts", 314 title: appCtxt.isOffline ? ZmMsg.personas : ZmMsg.accounts, 315 templateId: "prefs.Pages#Accounts", 316 priority: 9, 317 precondition: ZmSetting.MAIL_PREFERENCES_ENABLED, 318 prefs: [ ZmSetting.ACCOUNTS, ZmSetting.SAVE_TO_SENT_DELEGATED_TARGET ], 319 manageDirty: true, 320 createView: function(parent, section, controller) { 321 return new ZmAccountsPage(parent, section, controller); 322 } 323 }, 324 325 FILTERS: { 326 icon: "MailRule", 327 title: ZmMsg.filterRules, 328 templateId: "prefs.Pages#MailFilters", 329 priority: 50, 330 precondition: [ ZmSetting.MAIL_PREFERENCES_ENABLED, ZmSetting.FILTERS_ENABLED ], 331 prefs: [ ZmSetting.FILTERS ], 332 manageChanges: true, 333 createView: function(parent, section, controller) { 334 return controller.getFilterController(section).getFilterView(); 335 } 336 }, 337 338 SIGNATURES: { 339 icon: "AddSignature", 340 title: ZmMsg.signatures, 341 templateId: "prefs.Pages#Signatures", 342 priority: 51, 343 precondition: [ ZmSetting.MAIL_PREFERENCES_ENABLED, ZmSetting.SIGNATURES_ENABLED ], 344 prefs: [ ZmSetting.SIGNATURES, ZmSetting.SIGNATURE_STYLE, ZmSetting.SIGNATURE_ENABLED ], 345 manageDirty: true, 346 createView: function(parent, section, controller) { 347 return new ZmSignaturesPage(parent, section, controller); 348 } 349 }, 350 351 OUTOFOFFICE: { 352 icon: "OutOfOffice", 353 title: ZmMsg.outOfOffice, 354 priority: 55, 355 templateId: "prefs.Pages#OutOfOffice", 356 precondition: [ ZmSetting.MAIL_PREFERENCES_ENABLED, ZmSetting.VACATION_MSG_FEATURE_ENABLED ], 357 prefs: [ 358 ZmSetting.START_DATE_ENABLED, 359 ZmSetting.END_DATE_ENABLED, 360 ZmSetting.VACATION_DURATION_ENABLED, 361 ZmSetting.VACATION_DURATION_ALL_DAY, 362 ZmSetting.VACATION_CALENDAR_ENABLED, 363 ZmSetting.VACATION_FROM, 364 ZmSetting.VACATION_FROM_TIME, 365 ZmSetting.VACATION_MSG_ENABLED, 366 ZmSetting.VACATION_MSG, 367 ZmSetting.VACATION_EXTERNAL_MSG_ENABLED, 368 ZmSetting.VACATION_EXTERNAL_MSG, 369 ZmSetting.VACATION_EXTERNAL_TYPE, 370 ZmSetting.VACATION_EXTERNAL_SUPPRESS, 371 ZmSetting.VACATION_CALENDAR_TYPE, 372 ZmSetting.VACATION_UNTIL, 373 ZmSetting.VACATION_UNTIL_TIME 374 ], 375 manageDirty: true, 376 createView: function(parent, section, controller) { 377 AjxDispatcher.require("Alert"); 378 return new ZmMailPrefsPage(parent, section, controller); 379 } 380 }, 381 382 TRUSTED_ADDR: { 383 title: ZmMsg.trustedAddrs, 384 icon: "TrustedAddresses", 385 templateId: "prefs.Pages#Trusted", 386 priority: 60, 387 precondition: ZmSetting.MAIL_PREFERENCES_ENABLED, 388 createView: function(parent, section, controller) { 389 return new ZmTrustedPage(parent, section, controller, "Prefs_Pages_TrustedAddresses"); 390 }, 391 manageDirty: true, 392 prefs: [ ZmSetting.TRUSTED_ADDR_LIST ] 393 }, 394 395 SHARING: { 396 title: ZmMsg.sharing, 397 icon: "SharedContact", 398 templateId: "prefs.Pages#SharingPrefPage", 399 priority: 85, 400 precondition: ZmSetting.SHARING_ENABLED, 401 manageChanges: true, 402 createView: function(parent, section, controller) { 403 AjxDispatcher.require("Share"); 404 return new ZmSharingPage(parent, section, controller, "Prefs_Pages_Sharing"); 405 } 406 }, 407 408 NOTIFICATIONS: { 409 title: ZmMsg.notifications, 410 icon: "ApptReminder", 411 templateId: "prefs.Pages#Notifications", 412 priority: 88, 413 precondition: [ ZmSetting.CALENDAR_ENABLED, ZmSetting.TASKS_ENABLED ], 414 preconditionAny: true, 415 prefs: [ ZmSetting.CAL_EMAIL_REMINDERS_ADDRESS, ZmSetting.CAL_DEVICE_EMAIL_REMINDERS_ADDRESS ], 416 createView: function(parent, section, controller) { 417 return new ZmNotificationsPage(parent, section, controller); 418 } 419 }, 420 421 MOBILE: { 422 title: ZmMsg.connectedDevicesAndApps, 423 icon: "Mobile", 424 templateId: "prefs.Pages#MobileDevices", 425 priority: 90, 426 precondition: ZmSetting.MOBILE_SYNC_ENABLED, 427 manageChanges: true, 428 createView: function(parent, section, controller) { 429 return new ZmMobileDevicesPage(parent, section, controller); 430 } 431 }, 432 433 IMPORT_EXPORT: { 434 title: ZmMsg.importExport, 435 icon: "SendReceive", 436 templateId: "data.ImportExport#ImportExportPrefPage", 437 priority: 100, 438 precondition: [ ZmSetting.IMPORT_ENABLED, ZmSetting.EXPORT_ENABLED ], 439 preconditionAny: true, 440 prefs: [ 441 ZmSetting.IMPORT_FOLDER, 442 ZmSetting.IMPORT_BUTTON, 443 ZmSetting.EXPORT_FOLDER, 444 ZmSetting.EXPORT_BUTTON 445 ], 446 manageChanges: true, 447 createView: function(parent, section, controller) { 448 AjxDispatcher.require("ImportExport"); 449 return new ZmImportExportPage(parent, section, controller); 450 } 451 }, 452 453 SHORTCUTS: { 454 title: ZmMsg.shortcuts, 455 icon: "Shortcut", 456 templateId: "prefs.Pages#Shortcuts", 457 priority: 120, 458 precondition: ZmSetting.USE_KEYBOARD_SHORTCUTS, 459 createView: function(parent, section, controller) { 460 return new ZmShortcutsPage(parent, section, controller); 461 } 462 }, 463 464 PREF_ZIMLETS: { 465 title: ZmMsg.zimlets, 466 icon: "Zimlet", 467 templateId: "prefs.Pages#Zimlets", 468 manageDirty: true, 469 priority: 140, 470 precondition: ZmSetting.CHECKED_ZIMLETS_ENABLED, 471 prefs: [ 472 ZmSetting.CHECKED_ZIMLETS, 473 ZmSetting.OFFLINE_ZIMLET_SYNC_ACCOUNT_ID 474 ], 475 createView: function(parent, section, controller) { 476 return new ZmZimletsPage(parent, section, controller); 477 } 478 } 479 }; 480 481 if (appCtxt.isOffline) { 482 sections["BACKUP"] = { 483 title: ZmMsg.offlineBackups, 484 icon: "backup", 485 manageDirty: true, 486 templateId: "prefs.Pages#BackUp", 487 priority: 130, 488 prefs: [ 489 ZmSetting.OFFLINE_BACKUP_NOW_BUTTON, 490 ZmSetting.OFFLINE_BACKUP_INTERVAL, 491 ZmSetting.OFFLINE_BACKUP_PATH, 492 ZmSetting.OFFLINE_BACKUP_KEEP, 493 ZmSetting.OFFLINE_BACKUP_ACCOUNT_ID, 494 ZmSetting.OFFLINE_BACKUP_RESTORE 495 ], 496 createView: function(parent, section, controller) { 497 return new ZmBackupPage(parent, section, controller); 498 } 499 } 500 } 501 502 if (appCtxt.get(ZmSetting.CHAT_FEATURE_ENABLED)) { 503 ZmPref.registerPref("CHAT_ENABLED", { 504 displayName: ZmMsg.chatFeatureStatus, 505 displayContainer: ZmPref.TYPE_RADIO_GROUP, 506 orientation: ZmPref.ORIENT_VERTICAL, 507 displayOptions: [ZmMsg.chatFeatureEnabled, ZmMsg.chatFeatureDisabled], 508 options: [true, false] 509 }); 510 511 ZmPref.registerPref("CHAT_PLAY_SOUND", { 512 displayName: ZmMsg.chatPlaySound, 513 displayContainer: ZmPref.TYPE_CHECKBOX 514 }); 515 516 sections["CHAT"] = { 517 title: ZmMsg.chat, 518 icon: "Conversation", 519 templateId: "prefs.Pages#Chat", 520 priority: 65, 521 prefs: [ 522 ZmSetting.CHAT_ENABLED, 523 ZmSetting.CHAT_PLAY_SOUND 524 ] 525 } 526 } 527 528 529 for (var id in sections) { 530 ZmPref.registerPrefSection(id, sections[id]); 531 } 532 533 ZmPref.registerPref("CLIENT_TYPE", { 534 displayName: ZmMsg.clientType, 535 displayContainer: ZmPref.TYPE_RADIO_GROUP, 536 orientation: ZmPref.ORIENT_VERTICAL, 537 displayOptions: [ZmMsg.clientAdvanced, ZmMsg.clientStandard], 538 options: [ZmSetting.CLIENT_ADVANCED, ZmSetting.CLIENT_STANDARD] 539 }); 540 541 ZmPref.registerPref("COMPOSE_AS_FORMAT", { 542 displayName: ZmMsg.composeUsing, 543 displayContainer: ZmPref.TYPE_RADIO_GROUP, 544 orientation: ZmPref.ORIENT_VERTICAL, 545 displayOptions: [ZmMsg.composeAsHTML, ZmMsg.composeAsText], 546 options: [ZmSetting.COMPOSE_HTML, ZmSetting.COMPOSE_TEXT], 547 precondition: ZmSetting.HTML_COMPOSE_ENABLED, 548 inputId: ["COMPOSE_AS_HTML", "COMPOSE_AS_TEXT"] 549 }); 550 551 ZmPref.registerPref("COMPOSE_INIT_FONT_COLOR", { 552 displayOptions: ["rgb(0, 0, 0)"], 553 displayContainer: ZmPref.TYPE_COLOR, 554 precondition: ZmSetting.HTML_COMPOSE_ENABLED 555 }); 556 557 var styles=[],names=[]; 558 for (var key in ZmPref.FONT_FAMILY) { 559 var obj = ZmPref.FONT_FAMILY[key]; 560 styles.push(obj.value); 561 names.push(obj.name); 562 } 563 564 ZmPref.registerPref("COMPOSE_INIT_FONT_FAMILY", { 565 displayName: ZmMsg.defaultFontSettings, 566 displayContainer: ZmPref.TYPE_SELECT, 567 displayOptions: names, 568 options: styles, 569 precondition: [ ZmSetting.HTML_COMPOSE_ENABLED, ZmSetting.NOTEBOOK_ENABLED ], 570 preconditionAny: true, 571 approximateFunction: function(id) { 572 // Choose the style that comes closest, or the first if none is found 573 if (AjxUtil.indexOf(styles, id) != -1) { 574 return id; 575 } 576 return ZmPref._normalizeFontId(id); 577 } 578 }); 579 580 var fontSizes = [ 8, 9, 10, 11, 12, 13, 14, 16, 18, 24, 36, 48 ], // match what TinyMCE provides 581 fontSizeOptions = AjxUtil.map(fontSizes, function(fontSize) { 582 return AjxMessageFormat.format(ZmMsg.pt, fontSize); // pref page version (localized) 583 }), 584 fontSizeValueOptions = AjxUtil.map(fontSizes, function(fontSize) { 585 return fontSize + 'pt'; // server version 586 }); 587 588 var getZimbraAccountList = function(){ 589 var visAccts = appCtxt.accountList.visibleAccounts; 590 var accts = []; 591 accts.push(ZmMsg.zimletPrefDontSync); 592 for (var k=0; k<visAccts.length; k++) { 593 if(visAccts[k].isZimbraAccount && !visAccts[k].isMain) { 594 accts.push([ZmMsg.zimletPrefSyncWith, " ", visAccts[k].name].join("")); 595 } 596 } 597 return accts; 598 }; 599 var getZimbraAccountIds = function(){ 600 var visAccts = appCtxt.accountList.visibleAccounts; 601 var accts = []; 602 accts.push(""); 603 for (var k=0; k<visAccts.length; k++) { 604 if(visAccts[k].isZimbraAccount && !visAccts[k].isMain) { 605 accts.push(visAccts[k].id); 606 } 607 } 608 return accts; 609 610 }; 611 ZmPref.registerPref("COMPOSE_INIT_FONT_SIZE", { 612 displayName: null, 613 displayContainer: ZmPref.TYPE_SELECT, 614 displayOptions: fontSizeOptions, 615 options: fontSizeValueOptions, 616 precondition: ZmSetting.HTML_COMPOSE_ENABLED 617 }); 618 619 ZmPref.registerPref("COMPOSE_SAME_FORMAT", { 620 displayName: ZmMsg.replyForwardInSameFormat, 621 displayContainer: ZmPref.TYPE_CHECKBOX 622 }); 623 624 ZmPref.registerPref("CHECKED_ZIMLETS", { 625 displayName: ZmMsg.zimlets, 626 displayContainer: ZmPref.TYPE_CUSTOM 627 }); 628 629 ZmPref.registerPref("OFFLINE_ZIMLET_SYNC_ACCOUNT_ID", { 630 displayName: ZmMsg.zimletSyncPref, 631 displayContainer: ZmPref.TYPE_SELECT, 632 displayOptions: getZimbraAccountList(), 633 options: getZimbraAccountIds() 634 }); 635 636 ZmPref.registerPref("DEFAULT_TIMEZONE", { 637 displayName: ZmMsg.selectTimezone, 638 displayContainer: ZmPref.TYPE_SELECT, 639 displayParams: { layout: DwtMenu.LAYOUT_SCROLL, maxRows:ZmPref.MAX_ROWS }, 640 displayOptions: AjxTimezone.getZonePreferences(), 641 options: AjxTimezone.getZonePreferencesOptions() 642 }); 643 644 ZmPref.registerPref("DEFAULT_PRINTFONTSIZE", { 645 displayName: ZmMsg.printFontSizePref, 646 displayContainer: ZmPref.TYPE_SELECT, 647 displayOptions: fontSizeOptions, 648 options: fontSizeValueOptions 649 }); 650 651 ZmPref.registerPref("EXPORT_FOLDER", { 652 displayContainer: ZmPref.TYPE_CUSTOM 653 }); 654 655 ZmPref.registerPref("EXPORT_BUTTON", { 656 displayName: ZmMsg._export, 657 displayContainer: ZmPref.TYPE_CUSTOM 658 }); 659 660 ZmPref.registerPref("FORWARD_INCLUDE_WHAT", { 661 displayName: ZmMsg.forwardInclude, 662 displayContainer: ZmPref.TYPE_SELECT, 663 displayOptions: [ZmMsg.includeInBody, ZmMsg.includeOriginalAsAttach], 664 options: [ZmSetting.INC_BODY, ZmSetting.INC_ATTACH], 665 setFunction: ZmPref.setIncludeOrig, 666 initFunction: ZmPref.initIncludeWhat, 667 changeFunction: ZmPref.onChangeIncludeWhat 668 }); 669 670 ZmPref.registerPref("FORWARD_USE_PREFIX", { 671 displayName: ZmMsg.usePrefix, 672 displayContainer: ZmPref.TYPE_CHECKBOX, 673 setFunction: ZmPref.setIncludeOrig 674 }); 675 676 ZmPref.registerPref("FORWARD_INCLUDE_HEADERS", { 677 displayName: ZmMsg.includeHeaders, 678 displayContainer: ZmPref.TYPE_CHECKBOX, 679 setFunction: ZmPref.setIncludeOrig 680 }); 681 682 ZmPref.registerPref("IMPORT_FOLDER", { 683 loadFunction: ZmPref.loadCsvFormats, 684 displayContainer: ZmPref.TYPE_CUSTOM 685 }); 686 ZmPref.registerPref("IMPORT_BUTTON", { 687 displayName: ZmMsg._import, 688 displayContainer: ZmPref.TYPE_CUSTOM 689 }); 690 691 ZmPref.registerPref("LOCALE_NAME", { 692 displayName: ZmMsg.selectLanguage, 693 displayContainer: ZmPref.TYPE_LOCALES, 694 precondition: ZmSetting.LOCALE_CHANGE_ENABLED 695 }); 696 697 ZmPref.registerPref("COMPOSE_INIT_DIRECTION", { 698 displayName: ZmMsg.composeDirectionLabel, 699 displayContainer: ZmPref.TYPE_SELECT, 700 displayOptions: [ZmMsg.directionLTR, ZmMsg.directionRTL], 701 options: [ZmSetting.LTR, ZmSetting.RTL] 702 }); 703 704 ZmPref.registerPref("SHOW_COMPOSE_DIRECTION_BUTTONS", { 705 displayName: ZmMsg.showDirectionButtons, 706 displayContainer: ZmPref.TYPE_CHECKBOX 707 }); 708 709 ZmPref.registerPref("FONT_NAME", { 710 displayName: ZmMsg.selectFong, 711 displayContainer: ZmPref.TYPE_FONT 712 }); 713 714 ZmPref.registerPref("FONT_SIZE", { 715 displayName: ZmMsg.selectFontSize, //this was never defined in ZmMsg in the above case (font_name) and see the typo there too. So not sure what's this for. 716 displayContainer: ZmPref.TYPE_FONT_SIZE 717 }); 718 719 var markReadTime = AjxMessageFormat.format(ZmMsg.messageReadTime, DwtId.makeId(ZmId.WIDGET_INPUT, ZmId.OP_MARK_READ)); 720 ZmPref.registerPref("MARK_MSG_READ", { 721 displayName: ZmMsg.messageReadLabel, 722 displayContainer: ZmPref.TYPE_RADIO_GROUP, 723 displayFunction: ZmPref.markMsgReadDisplay, 724 orientation: ZmPref.ORIENT_VERTICAL, 725 displayOptions: [ZmMsg.messageReadNow, markReadTime, ZmMsg.messageReadNone], 726 options: [ZmSetting.MARK_READ_NOW, ZmSetting.MARK_READ_TIME, ZmSetting.MARK_READ_NONE], 727 valueFunction: ZmPref.markMsgReadValue 728 }); 729 730 ZmPref.registerPref("NEW_WINDOW_COMPOSE", { 731 displayName: ZmMsg.composeInNewWin, 732 displayContainer: ZmPref.TYPE_CHECKBOX, 733 precondition: [ ZmSetting.MAIL_ENABLED, ZmSetting.DETACH_COMPOSE_ENABLED ] 734 }); 735 736 ZmPref.registerPref("MAIL_MANDATORY_SPELLCHECK", { 737 displayName: ZmMsg.mandatorySpellcheck, 738 displayContainer: ZmPref.TYPE_CHECKBOX 739 }); 740 741 ZmPref.registerPref("PAGE_SIZE", { 742 displayContainer: ZmPref.TYPE_SELECT, 743 displayOptions: ["25", "50", "100", "200"] 744 }); 745 746 ZmPref.registerPref("PASSWORD", { 747 displayName: ZmMsg.changePassword, 748 displayContainer: ZmPref.TYPE_PASSWORD, 749 precondition: ZmSetting.CHANGE_PASSWORD_ENABLED 750 }); 751 752 ZmPref.registerPref("SHARING", { 753 displayContainer: ZmPref.TYPE_CUSTOM 754 }); 755 756 ZmPref.registerPref("SHORT_ADDRESS", { 757 displayName: ZmMsg.shortAddress, 758 displayContainer: ZmPref.TYPE_CHECKBOX 759 }); 760 761 762 if (appCtxt.isOffline) { 763 ZmPref.registerPref("OFFLINE_IS_MAILTO_HANDLER", { 764 displayName: ZmMsg.offlineAllowMailTo, 765 displayContainer: ZmPref.TYPE_CHECKBOX 766 }); 767 768 ZmPref.registerPref("OFFLINE_BACKUP_ACCOUNT_ID", { 769 displayName: ZmMsg.offlineBackUpAccounts, 770 displayContainer: ZmPref.TYPE_CUSTOM 771 }); 772 773 ZmPref.registerPref("OFFLINE_BACKUP_RESTORE", { 774 displayContainer: ZmPref.TYPE_CUSTOM 775 }); 776 777 ZmPref.registerPref("OFFLINE_BACKUP_NOW_BUTTON", { 778 displayName: ZmMsg.offlineBackUpButton, 779 displayContainer: ZmPref.TYPE_CUSTOM 780 }); 781 782 ZmPref.registerPref("OFFLINE_BACKUP_INTERVAL", { 783 displayName: ZmMsg.offlineBackUpInterval, 784 displayContainer: ZmPref.TYPE_SELECT, 785 displayOptions: [ZmMsg.pollNever, ZmMsg.everyDay, ZmMsg.everyWeek, ZmMsg.everyMonth], 786 options: [0, 86400000, 604800000, 2628000000] 787 }); 788 789 ZmPref.registerPref("OFFLINE_BACKUP_PATH", { 790 displayName: ZmMsg.offlineBackUpPath, 791 displayContainer: ZmPref.TYPE_INPUT 792 }); 793 794 ZmPref.registerPref("OFFLINE_BACKUP_KEEP", { 795 displayName: ZmMsg.offlineBackUpKeep, 796 displayContainer: ZmPref.TYPE_SELECT, 797 displayOptions: ["1", "2", "3", "4", "5"] 798 }); 799 800 ZmPref.registerPref("OFFLINE_UPDATE_NOTIFY", { 801 displayName: ZmMsg.offlineUpdateNotify, 802 displayContainer: ZmPref.TYPE_SELECT, 803 displayOptions: [ZmMsg.offlineUpdateRelease, ZmMsg.offlineUpdateBeta], 804 options: ["release", "beta"] 805 }); 806 807 } 808 809 // Polling Interval Options - Dynamically constructed according to MIN_POLLING_INTERVAL,POLLING_INTERVAL 810 var neverValue = 525600; 811 var numOptions = 10; 812 var options = [neverValue]; 813 var displayOptions = [ZmMsg.pollManually]; 814 var pollInstant = appCtxt.get(ZmSetting.INSTANT_NOTIFY) ? true : false; 815 816 if (pollInstant) { 817 options.push(appCtxt.get(ZmSetting.INSTANT_NOTIFY_INTERVAL)); 818 displayOptions.push(ZmMsg.pollInstant); 819 } 820 821 var startValue = ZmPref.pollingIntervalDisplay(appCtxt.get(ZmSetting.MIN_POLLING_INTERVAL)); 822 startValue = (startValue < 1) ? 1 : Math.round(startValue); 823 824 var pollInterval = ZmPref.pollingIntervalDisplay(appCtxt.get(ZmSetting.POLLING_INTERVAL)); 825 pollInterval = Math.round(pollInterval); 826 827 while (startValue <= numOptions) { 828 options.push(startValue); 829 startValue++; 830 } 831 startValue = startValue - 1; 832 833 var count = options.length; 834 while (count < numOptions) { 835 startValue = startValue + 5; 836 options.push(startValue); 837 count++; 838 } 839 840 if (pollInterval > startValue && pollInterval !=neverValue && (pollInstant && pollInterval != appCtxt.get(ZmSetting.INSTANT_NOTIFY_INTERVAL))) { 841 //pollInterval may have been set by admin 842 var p = pollInterval % 5; 843 p = (p == 0) ? pollInterval : ((pollInterval / 5 + 1) * 5); 844 options.push(p); 845 } else { 846 startValue = startValue + 5; 847 options.push(startValue); 848 } 849 850 while (displayOptions.length <= count) { 851 displayOptions.push(ZmMsg.pollEveryNMinutes); 852 } 853 854 ZmPref.registerPref("POLLING_INTERVAL", { 855 displayName: ZmMsg.pollingInterval, 856 displayContainer: ZmPref.TYPE_SELECT, 857 displayOptions: displayOptions, 858 //displayOptions: [ ZmMsg.pollNever, ZmMsg.pollEveryNMinutes, ZmMsg.pollEveryNMinutes, ZmMsg.pollEveryNMinutes, ZmMsg.pollEveryNMinutes, ZmMsg.pollEveryNMinutes ], 859 // NOTE: 525600 is the number of minutes in a year. I think that's a 860 // reasonable value for "never" since the server must have 861 // *some* number. 862 options: options, 863 approximateFunction: ZmPref.approximateInterval, 864 displayFunction: ZmPref.pollingIntervalDisplay, 865 valueFunction: ZmPref.pollingIntervalValue, 866 validationFunction: ZmPref.validatePollingInterval 867 }); 868 869 ZmPref.registerPref("REPLY_INCLUDE_WHAT", { 870 displayName: ZmMsg.replyInclude, 871 displayContainer: ZmPref.TYPE_SELECT, 872 displayOptions: [ZmMsg.dontInclude, 873 ZmMsg.includeInBody, 874 ZmMsg.smartInclude, 875 ZmMsg.includeOriginalAsAttach], 876 options: [ZmSetting.INC_NONE, 877 ZmSetting.INC_BODY, 878 ZmSetting.INC_SMART, 879 ZmSetting.INC_ATTACH], 880 setFunction: ZmPref.setIncludeOrig, 881 initFunction: ZmPref.initIncludeWhat, 882 changeFunction: ZmPref.onChangeIncludeWhat 883 }); 884 885 ZmPref.registerPref("REPLY_USE_PREFIX", { 886 displayName: ZmMsg.usePrefix, 887 displayContainer: ZmPref.TYPE_CHECKBOX, 888 setFunction: ZmPref.setIncludeOrig 889 }); 890 891 ZmPref.registerPref("REPLY_INCLUDE_HEADERS", { 892 displayName: ZmMsg.includeHeaders, 893 displayContainer: ZmPref.TYPE_CHECKBOX, 894 setFunction: ZmPref.setIncludeOrig 895 }); 896 897 ZmPref.registerPref("REPLY_PREFIX", { 898 displayName: ZmMsg.prefix, 899 displayContainer: ZmPref.TYPE_RADIO_GROUP, 900 orientation: ZmPref.ORIENT_HORIZONTAL, 901 displayOptions: [">", "|"] 902 }); 903 904 ZmPref.registerPref("SAVE_TO_SENT", { 905 displayName: ZmMsg.saveToSent, 906 displayContainer: ZmPref.TYPE_CHECKBOX, 907 precondition: ZmSetting.MAIL_ENABLED, 908 changeFunction: AjxCallback.simpleClosure(ZmPref.onChangeConfirm, null, ZmMsg.saveToSentWarning, ZmPref.getSendToFiltersActive, true, new AjxCallback(null, ZmPref.setFormValue, ["SAVE_TO_SENT", true])) 909 }); 910 911 ZmPref.registerPref("SAVE_TO_SENT_DELEGATED_TARGET", { 912 displayName: ZmMsg.saveToSentDelegatedTarget, 913 displayContainer: ZmPref.TYPE_RADIO_GROUP, 914 orientation: ZmPref.ORIENT_VERTICAL, 915 displayOptions: [ZmMsg.saveToSentDelegatedOwner, 916 ZmMsg.saveToSentDelegatedSender, 917 ZmMsg.saveToSentDelegatedBoth, 918 ZmMsg.saveToSentDelegatedNone], 919 options: ["owner", "sender", "both", "none"], 920 precondition: ZmSetting.MAIL_ENABLED 921 }); 922 923 ZmPref.registerPref("SEARCH_INCLUDES_SHARED", { 924 displayName: ZmMsg.includeSharedItems, 925 displayContainer: ZmPref.TYPE_CHECKBOX, 926 precondition: ZmSetting.SHARING_ENABLED 927 }); 928 929 ZmPref.registerPref("SEARCH_INCLUDES_SPAM", { 930 displayName: ZmMsg.includeJunkFolder, 931 displayContainer: ZmPref.TYPE_CHECKBOX, 932 precondition: [ ZmSetting.MAIL_ENABLED, ZmSetting.SPAM_ENABLED ] 933 }); 934 935 ZmPref.registerPref("SEARCH_INCLUDES_TRASH", { 936 displayName: ZmMsg.includeTrashFolder, 937 displayContainer: ZmPref.TYPE_CHECKBOX, 938 precondition: [ ZmSetting.MAIL_ENABLED, ZmSetting.CONTACTS_ENABLED ], 939 preconditionAny: true 940 }); 941 942 ZmPref.registerPref("SHOW_FRAGMENTS", { 943 displayName: ZmMsg.showFragments, 944 displayContainer: ZmPref.TYPE_CHECKBOX 945 }); 946 947 ZmPref.registerPref("COLOR_MESSAGES", { 948 displayName: ZmMsg.colorMessages, 949 displayContainer: ZmPref.TYPE_CHECKBOX 950 }); 951 952 if (appCtxt.isOffline) { 953 ZmPref.registerPref("OFFLINE_SHOW_ALL_MAILBOXES", { 954 displayName: ZmMsg.showAllMailboxes, 955 displayContainer: ZmPref.TYPE_CHECKBOX 956 }); 957 } 958 959 ZmPref.registerPref("SHOW_SEARCH_STRING", { 960 displayName: ZmMsg.showSearchString, 961 displayContainer: ZmPref.TYPE_CHECKBOX 962 }); 963 964 ZmPref.registerPref("SHOW_SELECTION_CHECKBOX", { 965 displayName: ZmMsg.showSelectionString, 966 displayContainer: ZmPref.TYPE_CHECKBOX 967 }); 968 969 ZmPref.registerPref("SKIN_NAME", { 970 displayName: ZmMsg.selectSkin, 971 displayContainer: ZmPref.TYPE_SELECT, 972 displayOptions: [], 973 options: [], 974 loadFunction: ZmPref.loadSkins, 975 precondition: ZmSetting.SKIN_CHANGE_ENABLED 976 }); 977 978 ZmPref.registerPref("VIEW_AS_HTML", { 979 displayName: ZmMsg.displayMail, 980 displayContainer: ZmPref.TYPE_RADIO_GROUP, 981 orientation: ZmPref.ORIENT_VERTICAL, 982 displayOptions: [ZmMsg.displayAsHTML, ZmMsg.displayAsText], 983 options: [true, false] 984 }); 985 }; 986 987 // other 988 989 ZmPreferencesApp.prototype._handleLoadLaunch = 990 function(callback) { 991 var respCallback = new AjxCallback(this, this._handleResponseLaunch, [callback]); 992 appCtxt.getSettings().loadPreferenceData(respCallback); 993 }; 994 995 ZmPreferencesApp.prototype._handleResponseLaunch = 996 function(callback) { 997 AjxDispatcher.run("GetPrefController").show(); 998 if (callback) { 999 callback.run(); 1000 } 1001 }; 1002 1003 ZmPreferencesApp.prototype._getSharingView = 1004 function() { 1005 var sharingSection = this.getPreferencesPage("SHARING"); 1006 return (sharingSection && sharingSection.view); 1007 }; 1008 1009 ZmPreferencesApp.prototype.getPreferencesPage = 1010 function(id) { 1011 if (!this._prefController) { 1012 return null; 1013 } 1014 var prefCtlr = this.getPrefController(); 1015 var prefsView = prefCtlr && prefCtlr.getPrefsView(); 1016 return prefsView && prefsView.getView(id); 1017 }; 1018 1019 // needed to hide zimlet tree view for multi-account 1020 ZmPreferencesApp.prototype._getOverviewParams = 1021 function() { 1022 var params = ZmApp.prototype._getOverviewParams.call(this); 1023 params.omit = {}; 1024 params.omit[ZmOrganizer.ID_ZIMLET] = true; 1025 params.actionSupported = false; 1026 return params; 1027 }; 1028 1029 ZmPreferencesApp.getFilterRulesController = 1030 function(outgoing) { 1031 var prefController = AjxDispatcher.run("GetPrefController"); 1032 if (prefController && prefController.getPrefsView()) { 1033 var filterController = prefController.getFilterController(); 1034 return outgoing ? filterController.getOutgoingFilterRulesController() : filterController.getIncomingFilterRulesController(); 1035 } 1036 1037 return null; 1038 }; 1039 1040 ZmPreferencesApp.prototype.getNewButtonProps = 1041 function (){ 1042 return {hidden:true}; 1043 } 1044