1 /**
2 * ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is Mozilla Calendar Code.
16 *
17 * The Initial Developer of the Original Code is
18 * Mike Potter.
19 * Portions created by the Initial Developer are Copyright (C) 2002
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 * ArentJan Banck <ajbanck@planet.nl>
24 * Matthew Willis <mattwillis@gmail.com>
25 * Stefan Sitter <ssitter@googlemail.com>
26 * Martin Schroeder <mschroeder@mozilla.x-home.org>
27 *
28 * Alternatively, the contents of this file may be used under the terms of
29 * either the GNU General Public License Version 2 or later (the "GPL"), or
30 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31 * in which case the provisions of the GPL or the LGPL are applicable instead
32 * of those above. If you wish to allow use of your version of this file only
33 * under the terms of either the GPL or the LGPL, and not to allow others to
34 * use your version of this file under the terms of the MPL, indicate your
35 * decision by deleting the provisions above and replace them with the notice
36 * and other provisions required by the GPL or the LGPL. If you do not delete
37 * the provisions above, a recipient may use your version of this file under
38 * the terms of any one of the MPL, the GPL or the LGPL.
39 *
40 * ***** END LICENSE BLOCK *****
41 */
42
43 var gCategoryList;
44 var prefService = Components.classes["@mozilla.org/preferences-service;1"]
45 .getService(Components.interfaces.nsIPrefService);
46 var categoryPrefBranch = prefService.getBranch("calendar.category.color.");
47
48 var gCategoriesPane = {
49
init
50 init: function () {
51 // On non-instant-apply platforms, once this pane has been loaded,
52 // attach our "revert all changes" function to the parent prefwindow's
53 // "ondialogcancel" event.
54 var parentPrefWindow = document.getElementById("CalendarPreferences") ||
55 document.getElementById("MailPreferences");
56 if (!parentPrefWindow.instantApply) {
57 var existingOnDialogCancel = parentPrefWindow.getAttribute("ondialogcancel");
58 parentPrefWindow.setAttribute("ondialogcancel",
59 "gCategoriesPane.panelOnCancel(); " +
60 existingOnDialogCancel);
61 }
62
63 // A list of preferences to be reverted when the dialog is cancelled.
64 // It needs to be a property of the parent to be visible onCancel
65 if (!parent.backupPrefList) {
66 parent.backupPrefList = [];
67 }
68
69 var categories = document.getElementById("calendar.categories.names").value;
70
71 // If no categories are configured load a default set from properties file
72 if (!categories || categories == "") {
73 categories = calGetString("categories", "categories");
74 document.getElementById("calendar.categories.names").value = categories;
75 }
76
77 gCategoryList = categoriesStringToArray(categories);
78
79 // When categories is empty, split returns an array containing one empty
80 // string, rather than an empty array. This results in an empty listbox
81 // child with no corresponding category.
82 if (gCategoryList.length == 1 && !gCategoryList[0].length) {
83 gCategoryList.pop();
84 }
85
86 this.updateCategoryList();
87 },
88
updateCategoryList
89 updateCategoryList: function () {
90 sortArrayByLocaleCollator(gCategoryList);
91 document.getElementById("calendar.categories.names").value =
92 categoriesArrayToString(gCategoryList);
93
94 var listbox = document.getElementById("categorieslist");
95
96 listbox.clearSelection();
97 document.getElementById("editCButton").disabled = "true";
98 document.getElementById("deleteCButton").disabled = "true";
99
100 while (listbox.lastChild.id != "categoryColumns")
101 listbox.removeChild(listbox.lastChild);
102
103 for (var i=0; i < gCategoryList.length; i++) {
104 var newListItem = document.createElement("listitem");
105 var categoryName = document.createElement("listcell");
106 categoryName.setAttribute("id", gCategoryList[i]);
107 categoryName.setAttribute("label", gCategoryList[i]);
108 var categoryNameFix = formatStringForCSSRule(gCategoryList[i]);
109 var categoryColor = document.createElement("listcell");
110 try {
111 var colorCode = categoryPrefBranch.getCharPref(categoryNameFix);
112 categoryColor.setAttribute("id", colorCode);
113 categoryColor.setAttribute("style","background-color: "+colorCode+';');
114 } catch (ex) {
115 categoryColor.setAttribute("label", noneLabel);
116 }
117
118 newListItem.appendChild(categoryName);
119 newListItem.appendChild(categoryColor);
120 listbox.appendChild(newListItem);
121 }
122 },
123
addCategory
124 addCategory: function () {
125 var list = document.getElementById("categorieslist");
126 list.selectedIndex = -1;
127 document.getElementById("editCButton").disabled = "true";
128 document.getElementById("deleteCButton").disabled = "true";
129 window.openDialog("chrome://calendar/content/preferences/editCategory.xul",
130 "addCategory", "modal,centerscreen,chrome,resizable=no",
131 "", null, addTitle);
132 },
133
editCategory
134 editCategory: function () {
135 var list = document.getElementById("categorieslist");
136 var categoryNameFix = formatStringForCSSRule(gCategoryList[list.selectedIndex]);
137 try {
138 var currentColor = categoryPrefBranch.getCharPref(categoryNameFix);
139 } catch (ex) {
140 var currentColor = null;
141 }
142
143 if (list.selectedItem) {
144 window.openDialog("chrome://calendar/content/preferences/editCategory.xul",
145 "editCategory", "modal,centerscreen,chrome,resizable=no",
146 gCategoryList[list.selectedIndex], currentColor, editTitle);
147 }
148 },
149
deleteCategory
150 deleteCategory: function () {
151 var list = document.getElementById("categorieslist");
152 if (list.selectedItem) {
153 var categoryNameFix = formatStringForCSSRule(gCategoryList[list.selectedIndex]);
154 this.backupData(categoryNameFix);
155 try {
156 categoryPrefBranch.clearUserPref(categoryNameFix);
157 } catch (ex) {
158 }
159 gCategoryList.splice(list.selectedIndex, 1);
160 this.updateCategoryList();
161 }
162 },
163
saveCategory
164 saveCategory: function (categoryName, categoryColor) {
165 var list = document.getElementById("categorieslist");
166 // Check to make sure another category doesn't have the same name
167 var toBeDeleted = -1;
168 var promptService =
169 Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
170 .getService(Components.interfaces.nsIPromptService);
171 for (var i=0; i < gCategoryList.length; i++) {
172 if (i == list.selectedIndex)
173 continue;
174 if (categoryName.toLowerCase() == gCategoryList[i].toLowerCase()) {
175 if (promptService.confirm(null, overwriteTitle, overwrite)) {
176 if (list.selectedIndex != -1)
177 // Don't delete the old category yet. It will mess up indices.
178 toBeDeleted = list.selectedIndex;
179 list.selectedIndex = i;
180 } else {
181 return;
182 }
183 }
184 }
185
186 if (categoryName.length == 0) {
187 promptService.alert(null, null, noBlankCategories);
188 return;
189 }
190
191 var categoryNameFix = formatStringForCSSRule(categoryName);
192 if (list.selectedIndex == -1) {
193 this.backupData(categoryNameFix);
194 gCategoryList.push(categoryName);
195 if (categoryColor)
196 categoryPrefBranch.setCharPref(categoryNameFix, categoryColor);
197 } else {
198 this.backupData(categoryNameFix);
199 gCategoryList.splice(list.selectedIndex, 1, categoryName);
200 if (categoryColor) {
201 categoryPrefBranch.setCharPref(categoryNameFix, categoryColor);
202 } else {
203 try {
204 categoryPrefBranch.clearUserPref(categoryNameFix);
205 } catch (ex) {
206 dump("Exception caught in 'saveCategory': " + ex + "\n");
207 }
208 }
209 }
210
211 // If 'Overwrite' was chosen, delete category that was being edited
212 if (toBeDeleted != -1) {
213 list.selectedIndex = toBeDeleted;
214 this.deleteCategory();
215 }
216
217 this.updateCategoryList();
218 },
219
enableButtons
220 enableButtons: function () {
221 document.getElementById("editCButton").disabled = null;
222 document.getElementById("deleteCButton").disabled = null;
223 },
224
backupData
225 backupData: function (categoryNameFix) {
226 var currentColor;
227 try {
228 currentColor = categoryPrefBranch.getCharPref(categoryNameFix);
229 } catch (ex) {
230 dump("Exception caught in 'backupData': " + ex + "\n");
231 currentColor = "##NEW";
232 }
233
234 for (var i=0; i < parent.backupPrefList.length; i++) {
235 if (categoryNameFix == parent.backupPrefList[i].name) {
236 return;
237 }
238 }
239 parent.backupPrefList[parent.backupPrefList.length] =
240 { name : categoryNameFix, color : currentColor };
241 },
242
panelOnCancel
243 panelOnCancel: function () {
244 for (var i=0; i < parent.backupPrefList.length; i++) {
245 if (parent.backupPrefList[i].color == "##NEW") {
246 try {
247 categoryPrefBranch.clearUserPref(parent.backupPrefList[i].name);
248 } catch (ex) {
249 dump("Exception caught in 'panelOnCancel': " + ex + "\n");
250 }
251 } else {
252 categoryPrefBranch.setCharPref(parent.backupPrefList[i].name,
253 parent.backupPrefList[i].color);
254 }
255 }
256 }
257
258 };