1 /* 2 * ***** BEGIN LICENSE BLOCK ***** 3 * Zimbra Collaboration Suite Web Client 4 * Copyright (C) 2009, 2010, 2013, 2014, 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) 2009, 2010, 2013, 2014, 2016 Synacor, Inc. All Rights Reserved. 21 * ***** END LICENSE BLOCK ***** 22 */ 23 24 /** 25 * @overview 26 */ 27 28 /** 29 * Creates a timezone dialog. 30 * @class 31 * This class represents a timezone dialog. 32 * 33 * @param {DwtComposite} parent the parent 34 * @param {String} className the class name 35 * 36 * @extends DwtDialog 37 */ 38 ZmTimezonePicker = function(parent, className) { 39 40 var buttons = [ ZmTimezonePicker.SAVE_BUTTON ]; 41 var saveButton = new DwtDialog_ButtonDescriptor(ZmTimezonePicker.SAVE_BUTTON, ZmMsg.save, DwtDialog.ALIGN_RIGHT); 42 DwtDialog.call(this, {parent:parent, className:className, 43 title:ZmMsg.selectTimezoneTitle, standardButtons:DwtDialog.NO_BUTTONS, 44 extraButtons: [saveButton]}); 45 46 this.setButtonListener(ZmTimezonePicker.SAVE_BUTTON, new AjxListener(this, this._handleSaveButton)); 47 this.setContent(this._contentHtml()); 48 this._setTimezoneMenu(); 49 }; 50 51 ZmTimezonePicker.prototype = new DwtDialog; 52 ZmTimezonePicker.prototype.constructor = ZmTimezonePicker; 53 54 ZmTimezonePicker.SAVE_BUTTON = ++DwtDialog.LAST_BUTTON; 55 56 ZmTimezonePicker.prototype.toString = 57 function() { 58 return "ZmTimezonePicker"; 59 }; 60 61 ZmTimezonePicker.prototype.popup = 62 function() { 63 this._initTzSelect(); 64 this.autoSelectTimezone(); 65 DwtDialog.prototype.popup.call(this); 66 }; 67 68 ZmTimezonePicker.prototype.cleanup = 69 function(bPoppedUp) { 70 DwtDialog.prototype.cleanup.call(this, bPoppedUp); 71 }; 72 73 ZmTimezonePicker.prototype._setTimezoneMenu = 74 function() { 75 var timezoneListener = new AjxListener(this, this._timezoneListener); 76 this._tzoneSelect = new DwtSelect({parent:this, parentElement: (this._htmlElId + "_tzSelect"), layout: DwtMenu.LAYOUT_SCROLL, maxRows:7}); 77 this._tzoneSelect.addChangeListener(timezoneListener); 78 79 this._tzoneShowAll = new DwtCheckbox({parent:this, parentElement:(this._htmlElId+"_tzShowAll")}); 80 this._tzoneShowAll.setText(ZmMsg.selectTimezoneIShowAll); 81 this._tzoneShowAll.addSelectionListener(new AjxListener(this, this._handleShowAllChange)); 82 }; 83 84 ZmTimezonePicker.prototype._initTzSelect = 85 function(force) { 86 var showAll = this._tzoneShowAll.isSelected(); 87 var options = showAll ? AjxTimezone.getAbbreviatedZoneChoices() : AjxTimezone.getMatchingTimezoneChoices(); 88 var serverIdMap = {}; 89 var serverId; 90 if (force || options.length != this._tzCount) { 91 this._tzCount = options.length; 92 this._tzoneSelect.clearOptions(); 93 for (var i = 0; i < options.length; i++) { 94 if(options[i].autoDetected) continue; 95 96 serverId = options[i].value; 97 //avoid duplicate entries 98 if(!showAll && serverIdMap[serverId]) continue; 99 serverIdMap[serverId] = true; 100 101 this._tzoneSelect.addOption(options[i]); 102 } 103 } 104 }; 105 106 ZmTimezonePicker.prototype.autoSelectTimezone = 107 function() { 108 if(AjxTimezone.DEFAULT_RULE.autoDetected) { 109 110 var cRule = AjxTimezone.DEFAULT_RULE; 111 var standardOffsetMatch, daylightOffsetMatch, transMatch; 112 113 for(var i in AjxTimezone.MATCHING_RULES) { 114 var rule = AjxTimezone.MATCHING_RULES[i]; 115 if(rule.autoDetected) continue; 116 if(rule.standard.offset == cRule.standard.offset) { 117 118 if(!standardOffsetMatch) standardOffsetMatch = rule.serverId; 119 120 var isDayLightOffsetMatching = (cRule.daylight && rule.daylight && (rule.daylight.offset == cRule.daylight.offset)); 121 122 if(isDayLightOffsetMatching) { 123 124 if(!daylightOffsetMatch) daylightOffsetMatch = rule.serverId; 125 126 var isTransYearMatching = (rule.daylight.trans[0] == cRule.daylight.trans[0]); 127 var isTransMonthMatching = (rule.daylight.trans[1] == cRule.daylight.trans[1]); 128 129 if(isTransYearMatching && isTransMonthMatching && !transMatch) { 130 transMatch = rule.serverId; 131 } 132 } 133 } 134 } 135 //select closest matching timezone 136 var serverId = transMatch ? transMatch : (daylightOffsetMatch || standardOffsetMatch); 137 if(serverId) this._tzoneSelect.setSelectedValue(serverId); 138 }else { 139 var tz = AjxTimezone.getServerId(AjxTimezone.DEFAULT); 140 this._tzoneSelect.setSelectedValue(tz); 141 } 142 }; 143 144 /** 145 * Updates the selected timezone. 146 * 147 * @param {Hash} dateInfo a hash of date information 148 * @param {ZmTimezone} timezone the timezone 149 */ 150 ZmTimezonePicker.prototype.updateTimezone = 151 function(dateInfo) { 152 this._tzoneSelect.setSelectedValue(dateInfo.timezone); 153 }; 154 155 ZmTimezonePicker.prototype.setCallback = 156 function(callback) { 157 this._callback = callback; 158 }; 159 160 ZmTimezonePicker.prototype._timezoneListener = 161 function(ev) { 162 //todo: timezone change listener 163 }; 164 165 ZmTimezonePicker.prototype._handleShowAllChange = function(evt) { 166 var value = this._tzoneSelect.getValue(); 167 this._initTzSelect(true); 168 this._tzoneSelect.setSelectedValue(value); 169 }; 170 171 ZmTimezonePicker.prototype._contentHtml = 172 function() { 173 return AjxTemplate.expand("share.Dialogs#ZmTimezonePicker", {id:this._htmlElId}); 174 }; 175 176 ZmTimezonePicker.prototype._okButtonListener = 177 function(ev) { 178 DwtDialog.prototype._buttonListener.call(this, ev, results); 179 }; 180 181 ZmTimezonePicker.prototype._enterListener = 182 function(ev) { 183 }; 184 185 ZmTimezonePicker.prototype._getTabGroupMembers = 186 function() { 187 return [this._tzoneSelect]; 188 }; 189 190 ZmTimezonePicker.prototype._handleSaveButton = 191 function(event) { 192 var timezone = this._tzoneSelect.getValue(); 193 this.popdown(); 194 if(this._callback) { 195 this._callback.run(timezone); 196 } 197 }; 198 199 ZmTimezonePicker.prototype.handleKeyAction = 200 function(actionCode, ev) { 201 switch (actionCode) { 202 case DwtKeyMap.CANCEL: 203 this._runCallbackForButtonId(DwtDialog.CANCEL_BUTTON); 204 break; 205 default: 206 DwtDialog.prototype.handleKeyAction.call(this, actionCode, ev); 207 break; 208 } 209 return true; 210 }; 211