1 /*
  2  * ***** BEGIN LICENSE BLOCK *****
  3  * Zimbra Collaboration Suite Web Client
  4  * Copyright (C) 2009, 2010, 2011, 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, 2011, 2013, 2014, 2016 Synacor, Inc. All Rights Reserved.
 21  * ***** END LICENSE BLOCK *****
 22  */
 23 
 24 /**
 25  * Creates a preferences page tree controller.
 26  * @class
 27  * This class represents the preferences page tree controller.
 28  * 
 29  * @extends		ZmTreeController
 30  */
 31 ZmPrefPageTreeController = function() {
 32 	ZmTreeController.apply(this, arguments);
 33 };
 34 ZmPrefPageTreeController.prototype = new ZmTreeController;
 35 ZmPrefPageTreeController.prototype.constructor = ZmPrefPageTreeController;
 36 
 37 ZmPrefPageTreeController.prototype.toString =
 38 function() {
 39 	return "ZmPrefPageTreeController";
 40 };
 41 
 42 //
 43 // Public methods
 44 //
 45 
 46 ZmPrefPageTreeController.prototype.show =
 47 function(params) {
 48 	// populate tree
 49 	var app = appCtxt.getApp(ZmApp.PREFERENCES);
 50 	var view = app.getPrefController().getPrefsView();
 51 	var account = params.account;
 52 
 53 	if (appCtxt.multiAccounts && !this._currentAccount) {
 54 		this._currentAccount = account;
 55 	}
 56 
 57 	var tree = new ZmTree(ZmOrganizer.PREF_PAGE);
 58 	var root = tree.root = new ZmPrefPage({id:ZmId.getPrefPageId(0), name:"", tree:tree});
 59 	appCtxt.cacheSet(root.id, root);
 60 
 61 	// create pseudo-organizers
 62 	var organizers = [];
 63 	var count = view.getNumTabs();
 64 	for (var i = 0; i < count; i++) {
 65 		var tabKey = i+1;
 66 		var name = view.getTabTitle(tabKey);
 67 		var section = view.getSectionForTab(tabKey);
 68 		if (!account || this._showSection(account, section.id)) {
 69 			// for multi-account mbox, child accounts only show a select few pref options
 70 			var organizer = ZmPrefPage.createFromSection(section);
 71 			organizer.pageId = tabKey;
 72 			organizer.account = account;
 73 			organizers.push(organizer);
 74 		}
 75 	}
 76 
 77 	// order pages
 78 	for (var i = 0; i < organizers.length; i++) {
 79 		var organizer = organizers[i];
 80 		var section = view.getSectionForTab(organizer.pageId);
 81 		var parentId = section.parentId;
 82 		if (appCtxt.isOffline &&
 83 			(section.id == "SIGNATURES" ||
 84 			 section.id == "ACCOUNTS" ||
 85 			 section.id == "COMPOSING" ||
 86 			 section.id == "FILTERS"))
 87 		{
 88 			parentId = null;
 89 		}
 90 		var parent = (parentId && tree.getById(ZmId.getPrefPageId(parentId))) || root;
 91 		parent.children.add(organizer);
 92 
 93 		organizer.parent = parent;
 94 		organizer.icon = section.icon || parent.getIcon();
 95 	}
 96 
 97 	appCtxt.setTree(tree.type, tree, account);
 98 
 99 	// setup tree view
100 	var treeView = ZmTreeController.prototype.show.apply(this, arguments);
101 
102 	if (!appCtxt.multiAccounts || (appCtxt.multiAccounts && account.isMain)) {
103 		var page1 = root.children.get(0);
104 		if (page1) {
105 			treeView.setSelected(page1, true);
106 		}
107 	}
108 	if (!appCtxt.isOffline) {
109 		var hi = treeView.getHeaderItem();
110 		if (hi) {
111 			hi.setExpanded(true, true);
112 		}
113 	}
114 	treeView.addSelectionListener(new AjxListener(this, this._handleTreeItemSelection, view));
115 
116 	return treeView;
117 };
118 
119 ZmPrefPageTreeController.prototype._showSection =
120 function(account, sectionId) {
121 
122 	if (appCtxt.isOffline) {
123 		if (sectionId == "MOBILE") {
124 			return false;
125 		}
126 
127 		if (account.isMain) {
128 			if (sectionId == "FILTERS" ||
129 				sectionId == "SHARING" ||
130 				sectionId == "SIGNATURES" ||
131 				sectionId == "ACCOUNTS" ||
132                 sectionId == "NOTIFICATIONS" ||
133                 sectionId == "TRUSTED_ADDR")
134 			{
135 				return false;
136 			}
137 		}
138 		else {
139 			if (sectionId == "COMPOSING") {
140 				return false;
141 			}
142 			if (!account.isZimbraAccount &&
143 				(sectionId == "MAIL" ||
144 				 sectionId == "SHARING" ||
145 				 sectionId == "CALENDAR" ||
146                  sectionId == "NOTIFICATIONS" ||
147                  sectionId == "TRUSTED_ADDR" ))
148 			{
149 				return false;
150 			}
151 		}
152 
153 	}
154 
155 	return (account.isMain ||
156 			(!account.isMain && (sectionId != "GENERAL" &&
157 								 sectionId != "SHORTCUTS" &&
158 								 sectionId != "PREF_ZIMLETS" &&
159                                  sectionId != "BACKUP" &&
160 								 sectionId != "COMPOSING")
161 			));
162 };
163 
164 //
165 // Protected methods
166 //
167 
168 // ZmTreeController methods
169 
170 ZmPrefPageTreeController.prototype._dragListener =
171 function(ev) {
172 	ev.operation = Dwt.DND_DROP_NONE;
173 };
174 
175 ZmPrefPageTreeController.prototype._dropListener =
176 function(ev) {
177 	ev.doIt = false;
178 };
179 
180 // handlers
181 
182 ZmPrefPageTreeController.prototype._handleTreeItemSelection =
183 function(tabView, ev) {
184 	if (ev.detail != DwtTree.ITEM_SELECTED || ev.handled) { return; }
185 
186 	var organizer = ev.item.getData(Dwt.KEY_OBJECT);
187 	tabView.switchToTab(organizer && organizer.pageId);
188 };
189 
190 ZmPrefPageTreeController.prototype._handleMultiAccountItemSelection =
191 function(ev, overview, treeItem, item) {
192 	if (this._currentAccount != item.account) {
193 		var prefsController = appCtxt.getApp(ZmApp.PREFERENCES).getPrefController();
194 		var prefsView = prefsController.getPrefsView();
195 
196 		this._currentAccount = prefsController._activeAccount = item.account;
197 
198 		if (prefsView.getChangedPrefs(true, true)) {
199 			ev.handled = true;
200 
201 			var dialog = appCtxt.getYesNoCancelMsgDialog();
202 			var args = [ev, overview, treeItem, item, prefsController, dialog];
203 			var yesCallback = new AjxCallback(this, this._savePrefsYes, args);
204 			var noCallback = new AjxCallback(this, this._savePrefsNo, args);
205 			var cancelCallback = new AjxCallback(this, this._savePrefsCancel, dialog);
206 
207 			dialog.reset();
208 			dialog.setMessage(ZmMsg.confirmExitPreferencesChangeAcct, DwtMessageDialog.WARNING_STYLE);
209 			dialog.registerCallback(DwtDialog.YES_BUTTON, yesCallback, this);
210 			dialog.registerCallback(DwtDialog.NO_BUTTON, noCallback, this);
211 			dialog.registerCallback(DwtDialog.CANCEL_BUTTON, cancelCallback, this);
212 			dialog.popup();
213 			return;
214 		}
215 		else {
216 			prefsView.resetOnAccountChange();
217 		}
218 	}
219 
220 	ev.handled = false;
221 	this._handleItemSelection(ev, overview, treeItem, item);
222 };
223 
224 ZmPrefPageTreeController.prototype._savePrefsYes =
225 function(ev, overview, treeItem, item, prefsController, dialog) {
226 	dialog.popdown();
227 
228 	var callback = new AjxCallback(this, this._continueTreeItemSelection, [ev, overview, treeItem, item, prefsController]);
229 	prefsController.save(callback, true);
230 };
231 
232 ZmPrefPageTreeController.prototype._savePrefsNo =
233 function(ev, overview, treeItem, item, prefsController, dialog) {
234 	dialog.popdown();
235 
236 	prefsController.getPrefsView().reset();
237 	this._continueTreeItemSelection(ev, overview, treeItem, item, prefsController);
238 };
239 
240 ZmPrefPageTreeController.prototype._savePrefsCancel =
241 function(dialog) {
242 	dialog.popdown();
243 };
244 
245 ZmPrefPageTreeController.prototype._continueTreeItemSelection =
246 function(ev, overview, treeItem, item, prefsController) {
247 	prefsController.getPrefsView().resetOnAccountChange();
248 
249 	this._handleItemSelection(ev, overview, treeItem, item);
250 	prefsController.getPrefsView().switchToTab(item.pageId);
251 };
252