This is just some static backup of the original site, don't expect every link to work!

source: content/vI_rdfDataTree.js @ d5349d

ng_0.9
Last change on this file since d5349d was d5349d, checked in by rene <rene@…>, 8 years ago

cleanup for javascript strict mode

  • Property mode set to 100644
File size: 20.3 KB
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2    This program is free software; you can redistribute it and/or modify
3    it under the terms of the GNU General Public License as published by
4    the Free Software Foundation; either version 2 of the License, or
5    (at your option) any later version.
6
7    This program is distributed in the hope that it will be useful,
8    but WITHOUT ANY WARRANTY; without even the implied warranty of
9    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10    GNU General Public License for more details.
11
12    You should have received a copy of the GNU General Public License
13    along with this program; if not, write to the Free Software
14    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
15
16    The Original Code is the Virtual Identity Extension.
17
18    The Initial Developer of the Original Code is Rene Ejury.
19    Portions created by the Initial Developer are Copyright (C) 2007
20    the Initial Developer. All Rights Reserved.
21
22    Contributor(s):
23 * ***** END LICENSE BLOCK ***** */
24
25/*  Parts of this code taken from
26    http://developer.mozilla.org/en/docs/Sorting_and_filtering_a_custom_tree_view
27    under MIT license
28    http://www.ibiblio.org/pub/Linux/LICENSES/mit.license
29*/
30
31Components.utils.import("resource://v_identity/vI_nameSpaceWrapper.js");
32virtualIdentityExtension.ns(function() { with (virtualIdentityExtension.LIB) {
33
34let Log = vI.setupLogging("virtualIdentity.rdfDataTree");
35
36Components.utils.import("resource://v_identity/vI_identityData.js", virtualIdentityExtension);
37Components.utils.import("resource://v_identity/vI_rdfDatasource.js", virtualIdentityExtension);
38Components.utils.import("resource://v_identity/vI_prefs.js", virtualIdentityExtension);
39
40//prepares an object for easy comparison against another. for strings, lowercases them
41var prepareForComparison = function(element, field) {
42    if (field == "changedCol") {
43        field = "changed"
44    }
45    if (field == "usedCol") {
46        field = "used"
47    }
48    var o = element[field];
49    if (typeof o == "string") { return o.toLowerCase().replace(/\"/g,""); }
50    return "";
51};
52
53
54var rdfDataTree = function(treeType, rdfDatasource) {
55    this.treeType = treeType;
56    this._rdfDatasource = rdfDatasource;
57    this.filterText = "";
58    this.loadTable();
59};
60
61rdfDataTree.prototype = {
62    idTable : null,
63    idData : null,
64    filterText : null,
65    treeType : null,
66    _rdfDatasource : null,
67
68    get treeElem() { return document.getElementById("rdfDataTree_" + this.treeType); },
69    get tabElem() { return document.getElementById(this.treeType + "Tab"); },
70   
71    //this function is called every time the tree is sorted, filtered, or reloaded
72    loadTable : function() {
73//         Log.debug("loadTable.");
74        //remember scroll position. this is useful if this is an editable table
75        //to prevent the user from losing the row they edited
76        var topVisibleRow = null;
77        if (this.idTable)
78          topVisibleRow = this.treeElem.treeBoxObject.getFirstVisibleRow();
79        if (this.idData == null) {
80            this.idData = [];
81            this._rdfDatasource.readAllEntriesFromRDF(this.addNewDatum, this.treeType, this.idData);
82        }
83        if (this.filterText == "") {
84            //show all of them
85            this.idTable = this.idData;
86        } else {
87            //filter out the ones we want to display
88            var curTable = [];
89            var curFilterText = this.filterText;
90            this.idData.forEach(function(element) {
91                //we'll match on every property
92                for (var i in element) {
93                    if (prepareForComparison(element, i).indexOf(curFilterText) != -1) {
94                        curTable.push(element);
95                        break;
96                    }
97                }
98            });
99            this.idTable = curTable;
100        }   
101       
102        this.sort();
103       
104        //restore scroll position
105        if (topVisibleRow && topVisibleRow <= this.idTable.length) {
106            this.treeElem.treeBoxObject.scrollToRow(topVisibleRow);
107        }
108
109        // set Tab label
110        this.tabElem.setAttribute("label", this.treeType + " (" + this.idTable.length + ")");
111//         Log.debug("loadTable done.");
112    },
113
114    addNewDatum : function(resource, name, localIdentityData, idData, used, changed) {
115        var usedDate = "", changedDate = "";
116        var format = vI.prefroot.getCharPref("extensions.virtualIdentity.storage_timeFormat")
117        if (format != "") {
118            if (used) usedDate = new Date(parseFloat(used)).toLocaleFormat(format);
119            if (changed) changedDate = new Date(parseFloat(changed)).toLocaleFormat(format);
120        } else {
121            if (used) usedDate = new Date(parseFloat(used)).toLocaleString();
122            if (changed) changedDate = new Date(parseFloat(changed)).toLocaleString();
123        }
124        var pref = {    recipientCol : name,
125                indexCol : idData.length + 1 + ".",
126                senderCol : localIdentityData.combinedName,
127                smtpCol : localIdentityData.smtp.value,
128//              smtpKey : localIdentityData.smtp.key,
129                idCol : localIdentityData.id.value,
130                usedCol : usedDate,
131                used : used,
132                changedCol : changedDate,
133                changed : changed,
134//              idKey : localIdentityData.id.key,
135                resource : resource,
136                identityData : localIdentityData}
137//      Log.debug("addNewDatum.");
138        localIdentityData.extras.addPrefs(pref);
139        idData.push(pref);
140    },
141    sort : function(columnName) {
142//      Log.debug("sort: " + columnName);
143        var order = this.treeElem.getAttribute("sortDirection") == "ascending" ? 1 : -1;
144        // if the column is passed and it's already sorted by that column, reverse sort
145        if (columnName && (this.treeElem.getAttribute("sortResource") == columnName)) {
146                order *= -1;
147        }
148       
149        function columnSort(a, b) {
150          try {
151            if (prepareForComparison(a, columnName) > 
152                prepareForComparison(b, columnName)) return 1 * order;
153            if (prepareForComparison(a, columnName) < 
154                prepareForComparison(b, columnName)) return -1 * order;
155          } catch(e) {};
156            return 0;
157        }
158       
159        if (!columnName)
160          columnName = this.treeElem.getAttribute("sortResource")
161       
162        this.idTable.sort(columnSort);
163       
164        //setting these will make the sort option persist
165        this.treeElem.setAttribute("sortDirection", order == 1 ? "ascending" : "descending");
166        this.treeElem.setAttribute("sortResource", columnName);
167       
168        this.treeElem.view = new rdfDataTreeCollection.treeView(this.idTable);
169       
170        //set the appropriate attributes to show to indicator
171        var cols = this.treeElem.getElementsByTagName("treecol");
172        for (var i = 0; i < cols.length; i++) {
173            cols[i].removeAttribute("sortDirection");
174            if (cols[i].id.match(columnName))
175                cols[i].setAttribute("sortDirection", order == 1 ? "ascending" : "descending");
176        }
177    }
178};
179
180var rdfDataTreeCollection = {
181    promptService : Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
182            .getService(Components.interfaces.nsIPromptService),
183
184    treeTypes : Array("email", "maillist", "newsgroup", "filter"),
185
186    trees : {},
187    tabbox : null,
188   
189    _strings : null,
190    _rdfDatasource : null,
191   
192    onTabSelect : function () {
193        rdfDataTreeCollection.hideInfoBox();
194        if (rdfDataTreeCollection.tabbox) {
195            rdfDataTreeCollection.moveConstraints();
196            rdfDataTreeCollection.updateButtonMenu();
197        }
198    },
199   
200    onselect : function () {
201        rdfDataTreeCollection.moveConstraints();
202        rdfDataTreeCollection.updateButtonMenu();
203
204        var tree = rdfDataTreeCollection.trees[rdfDataTreeCollection.tabbox.selectedPanel.id];
205        var htmlBox = document.getElementById("rdfDataTreeCollectionInfoBox")
206        if (tree.treeElem.view.selection.count != 1)
207            { rdfDataTreeCollection.hideInfoBox(); return; }
208       
209        var identityData = tree.idTable[tree.treeElem.currentIndex]["identityData"];
210        var _identityInfo = 
211            "<div id='recipientLabel'>" +
212                tree.idTable[tree.treeElem.currentIndex]["recipientCol"].replace(/>/g,"&gt;").replace(/</g,"&lt;") +
213            "</div><div id='vICard'>" +
214            "<table><tr>" +
215                "<td class='image'><img src='chrome://v_identity/skin/vi-info.png' /></td>" +
216                "<td class='identityTable'>" +
217                    "<div class='name'>" + identityData.combinedNameHtml + "</div>" +   
218                    "<table><tbody>" + identityData.getMatrix() + "</tbody></table>" +
219                "</td>" +
220            "</tr></table></div>"
221
222        htmlBox.outputString = _identityInfo;
223        rdfDataTreeCollection.infoBoxHidden = false;
224        htmlBox.setAttribute("style", "height:" + htmlBox.contentDocument.lastChild.scrollHeight +"px");
225        rdfDataTreeCollection.overflow(); // better resize one time too much, mozilla is still magic  :)
226    },
227
228    init : function() {
229        rdfDataTreeCollection.tabbox = document.getElementById("TreeTabbox");
230        rdfDataTreeCollection._strings = Components.classes["@mozilla.org/intl/stringbundle;1"]
231          .getService(Components.interfaces.nsIStringBundleService)
232          .createBundle("chrome://v_identity/locale/vI_rdfDataEditor.properties");
233
234        rdfDataTreeCollection._rdfDatasource = new vI.rdfDatasource("virtualIdentity.rdf");
235       
236        for each (var treeType in rdfDataTreeCollection.treeTypes)
237            rdfDataTreeCollection.trees[treeType] = new rdfDataTree(treeType, rdfDataTreeCollection._rdfDatasource);
238    },
239   
240    clean : function() {
241        if (rdfDataTreeCollection._rdfDatasource) rdfDataTreeCollection._rdfDatasource.clean();
242    },
243
244    get _braille() {
245        var braille = false;
246        try {   braille = (vI.prefroot.getCharPref("accessibility.usebrailledisplay") || 
247                vI.prefroot.getCharPref("accessibility.usetexttospeech")); }
248        catch (e) { };
249        return braille;
250    },
251
252    // generic custom tree view stuff
253    treeView : function (table) {
254        this.rowCount = table.length;
255        this.getCellText = function(row, col) {
256            var retValue = table[row][col.id.substr(0,col.id.indexOf("_"))];
257            if (!rdfDataTreeCollection._braille && (retValue == "no" || retValue == "yes"))
258                return ""; // image will be used as indicator
259            else return retValue;
260        };
261        this.getCellValue = function(row, col) {
262            return this.getCellText(row, col);
263        };
264        this.setTree = function(treebox) {
265            this.treebox = treebox;
266        };
267        this.isEditable = function(row, col) {
268            return col.editable;
269        };
270        this.isContainer = function(row){ return false; };
271        this.isSeparator = function(row){ return false; };
272        this.isSorted = function(){ return false; };
273        this.getLevel = function(row){ return 0; };
274        this.getImageSrc = function(row,col){ return null; };
275        this.getRowProperties = function(row,props){};
276        this.getCellProperties = function(row,col,props){};
277        this.getColumnProperties = function(colid,col,props){};
278        this.cycleHeader = function(col, elem) {
279            var treeType = rdfDataTreeCollection.tabbox.selectedPanel.id;
280            if (treeType != "filter")
281                rdfDataTreeCollection.trees[treeType].sort(col.id.substr(0,col.id.indexOf("_")));
282        };
283        this.getCellProperties = function(row,col,props){
284            var returnValue = null;
285            if (!rdfDataTreeCollection._braille) {
286                var aserv=Components.classes["@mozilla.org/atom-service;1"].
287                    getService(Components.interfaces.nsIAtomService);
288                if (typeof props == 'undefined') {
289                    // Requires Gecko 22
290                    switch (table[row][col.id.substr(0,col.id.indexOf("_"))]) {
291                        case "yes": returnValue = aserv.getAtom("yes"); break;
292                        case "no":  returnValue = aserv.getAtom("no"); break;
293                    }
294                } else {
295                    // Obsolete since Gecko 22
296                    switch (table[row][col.id.substr(0,col.id.indexOf("_"))]) {
297                        case "yes": props.AppendElement(aserv.getAtom("yes")); break;
298                        case "no":  props.AppendElement(aserv.getAtom("no")); break;
299                    }
300                }
301            }
302            return returnValue;
303        };
304    },
305
306   
307    __setFilter : function (text) {
308        // loop trough all trees
309        for each (var treeType in rdfDataTreeCollection.treeTypes) {
310            var tree = rdfDataTreeCollection.trees[treeType];
311            tree.filterText = text;
312            tree.loadTable();
313        }
314    },
315
316    inputFilter : function(event) {
317        var value = "";
318        if (typeof event.target.value == "string") {
319            value = event.target.value.toLowerCase().replace(/\"/g,"");
320        }
321        rdfDataTreeCollection.__setFilter(value);
322        document.getElementById("clearFilter").disabled = value.length == 0;
323    },
324   
325    clearFilter : function() {
326        document.getElementById("clearFilter").disabled = true;
327        var filterElement = document.getElementById("filter");
328        filterElement.focus();
329        filterElement.value = "";
330        rdfDataTreeCollection.__setFilter("");
331    },
332   
333    __updateMenu : function(modifySelected, removeSelected) {
334        var tree = rdfDataTreeCollection.trees[rdfDataTreeCollection.tabbox.selectedPanel.id];
335        var noSelections = (tree.treeElem.view.selection.count == 0)
336        modifySelected.setAttribute("disabled", noSelections)
337        removeSelected.setAttribute("disabled", noSelections)   
338    },
339   
340    updateButtonMenu : function() {
341        rdfDataTreeCollection.__updateMenu(
342            document.getElementById("editButton_" + rdfDataTreeCollection.tabbox.selectedPanel.id),
343            document.getElementById("deleteButton_" + rdfDataTreeCollection.tabbox.selectedPanel.id))
344    },
345   
346    updateContextMenu : function() {
347        rdfDataTreeCollection.__updateMenu(
348            document.getElementById("context_modifySelected"),
349            document.getElementById("context_removeSelected"))
350    },
351   
352    updateMenu : function() {
353        rdfDataTreeCollection.__updateMenu(
354            document.getElementById("menu_modifySelected"),
355            document.getElementById("menu_removeSelected"))
356    },
357
358    modifySelected : function() {
359        var treeType = rdfDataTreeCollection.tabbox.selectedPanel.id;
360        var tree = rdfDataTreeCollection.trees[treeType];
361        if (tree.treeElem.view.selection.count == 0) return;
362        if (tree.treeElem.view.selection.count > 5) {
363            var warning = rdfDataTreeCollection._strings.GetStringFromName("vI_rdfDataTree.modify.Warning1") + " " +
364                tree.treeElem.view.selection.count + " " +
365                rdfDataTreeCollection._strings.GetStringFromName("vI_rdfDataTree.modify.Warning2")
366            if (!rdfDataTreeCollection.promptService.confirm(window,"Warning",warning)) return;
367        }
368       
369        var start = new Object(); var end = new Object();
370        var numRanges = tree.treeElem.view.selection.getRangeCount();
371
372        var retVar = { treeType: null };
373        for (var t=0; t<numRanges; t++){
374            tree.treeElem.view.selection.getRangeAt(t,start,end);
375            for (var v=start.value; v<=end.value; v++)
376                window.openDialog("chrome://v_identity/content/vI_rdfDataEditor.xul",0,
377                    "chrome, dialog, modal, alwaysRaised, resizable=yes",
378                    tree.idTable[v], treeType,
379                    rdfDataTreeCollection._rdfDatasource, retVar).focus();
380        }
381       
382        // reload all trees (multiple types might have changed)
383        for each (var treeType in rdfDataTreeCollection.treeTypes) {
384            rdfDataTreeCollection.trees[treeType].idData = null;
385            rdfDataTreeCollection.trees[treeType].loadTable()
386        }
387        rdfDataTreeCollection.tabbox.selectedTab = document.getElementById(retVar.treeType + "Tab");
388        rdfDataTreeCollection.hideInfoBox();
389    },
390   
391    removeSelected : function() {
392        var treeType = rdfDataTreeCollection.tabbox.selectedPanel.id;
393        var tree = rdfDataTreeCollection.trees[treeType];
394        if (tree.treeElem.view.selection.count == 0) return;
395        var warning = rdfDataTreeCollection._strings.GetStringFromName("vI_rdfDataTree.remove.Warning1") + " " +
396            tree.treeElem.view.selection.count + " " +
397            rdfDataTreeCollection._strings.GetStringFromName("vI_rdfDataTree.remove.Warning2")
398       
399        if (!rdfDataTreeCollection.promptService.confirm(window,"Warning",warning)) return;
400       
401        var start = new Object(); var end = new Object();
402        var numRanges = tree.treeElem.view.selection.getRangeCount();
403
404        for (var t=0; t<numRanges; t++){
405            tree.treeElem.view.selection.getRangeAt(t,start,end);
406            for (var v=start.value; v<=end.value; v++){
407                rdfDataTreeCollection._rdfDatasource.removeVIdentityFromRDF(tree.idTable[v]["resource"], treeType)
408            }
409        }
410       
411        tree.idData = null; tree.idTable = null;
412        tree.loadTable();
413        rdfDataTreeCollection.hideInfoBox();
414    },
415   
416    moveConstraints : function() {
417        var treeType = rdfDataTreeCollection.tabbox.selectedPanel.id;
418        if (treeType != "filter") return;
419        var tree = rdfDataTreeCollection.trees[treeType];
420        if (tree.treeElem.view.selection.count == 0) {
421            document.getElementById("reorderUpButton_filter").setAttribute("disabled","true");
422            document.getElementById("reorderDownButton_filter").setAttribute("disabled","true");
423            return;
424        };
425        var start = new Object(); var end = new Object();
426        var numRanges = tree.treeElem.view.selection.getRangeCount();
427        if (numRanges > 1) {
428            document.getElementById("reorderUpButton_filter").setAttribute("disabled","true");
429            document.getElementById("reorderDownButton_filter").setAttribute("disabled","true");
430            return;
431        }
432        tree.treeElem.view.selection.getRangeAt(0,start,end);
433        if (start.value > 0)
434            document.getElementById("reorderUpButton_filter").removeAttribute("disabled");
435        else    document.getElementById("reorderUpButton_filter").setAttribute("disabled","true");
436        if (end.value < tree.idTable.length - 1)
437            document.getElementById("reorderDownButton_filter").removeAttribute("disabled");
438        else    document.getElementById("reorderDownButton_filter").setAttribute("disabled","true");
439    },
440
441    moveUpSelected : function() {
442        var treeType = rdfDataTreeCollection.tabbox.selectedPanel.id;
443        if (treeType != "filter") return; // just to be safe, button should be disabled
444        var tree = rdfDataTreeCollection.trees[treeType];
445        if (tree.treeElem.view.selection.count == 0) return; // just to be safe, button should be disabled
446
447        var start = new Object(); var end = new Object();
448        var numRanges = tree.treeElem.view.selection.getRangeCount();
449        if (numRanges > 1) return;  // just to be safe, button should be disabled
450       
451        tree.treeElem.view.selection.getRangeAt(0,start,end);
452        for (var v=start.value; v<=end.value; v++){
453            var resource = rdfDataTreeCollection._rdfDatasource.filterContainer.RemoveElementAt(v+1, true);
454            rdfDataTreeCollection._rdfDatasource.filterContainer.InsertElementAt(resource,v,true); 
455        }
456        tree.idData = null; tree.idTable = null;
457        tree.loadTable();
458        tree.treeElem.view.selection.rangedSelect(start.value-1,end.value-1,false);
459    },
460
461    moveDownSelected : function() {
462        var treeType = rdfDataTreeCollection.tabbox.selectedPanel.id;
463        if (treeType != "filter") return; // just to be safe, button should be disabled
464        var tree = rdfDataTreeCollection.trees[treeType];
465        if (tree.treeElem.view.selection.count == 0) return; // just to be safe, button should be disabled
466
467        var start = new Object(); var end = new Object();
468        var numRanges = tree.treeElem.view.selection.getRangeCount();
469        if (numRanges > 1) return;  // just to be safe, button should be disabled
470       
471        tree.treeElem.view.selection.getRangeAt(0,start,end);
472        for (var v=end.value; v>=start.value; v--){
473            var resource = rdfDataTreeCollection._rdfDatasource.filterContainer.RemoveElementAt(v+1, true);
474            rdfDataTreeCollection._rdfDatasource.filterContainer.InsertElementAt(resource,v+2,true); 
475        }
476        tree.idData = null; tree.idTable = null;
477        tree.loadTable();
478        tree.treeElem.view.selection.rangedSelect(start.value+1,end.value+1,false);
479    },
480
481    infoBoxHidden : true,
482    overflow : function() {
483        if (rdfDataTreeCollection.infoBoxHidden) return;
484        var htmlBox = document.getElementById("rdfDataTreeCollectionInfoBox")
485        htmlBox.setAttribute("style", "height:" + htmlBox.contentDocument.lastChild.scrollHeight +"px");
486    },
487
488    hideInfoBox : function() {
489        rdfDataTreeCollection.infoBoxHidden = true;
490        document.getElementById("rdfDataTreeCollectionInfoBox").setAttribute("style", "height:0px");
491        for each (var treeType in rdfDataTreeCollection.treeTypes) {
492            try { if (rdfDataTreeCollection.trees[treeType])
493                rdfDataTreeCollection.trees[treeType].treeElem.view.selection.selectNone() } catch (e) { }
494        }
495    },
496
497    selectAll : function() {
498        var treeType = rdfDataTreeCollection.tabbox.selectedPanel.id;
499        var tree = rdfDataTreeCollection.trees[treeType];
500        tree.treeElem.view.selection.selectAll();
501    },
502   
503    newItem : function() {
504        var treeType = rdfDataTreeCollection.tabbox.selectedPanel.id;
505        var newItemPreset = { identityData : new vI.identityData ("", null, null, vI.NO_SMTP_TAG, null, null) };
506        var retVar = { treeType: null };
507
508        window.openDialog("chrome://v_identity/content/vI_rdfDataEditor.xul",0,
509            "chrome, dialog, modal, alwaysRaised, resizable=yes",
510            newItemPreset, treeType,
511            rdfDataTreeCollection._rdfDatasource, retVar).focus();
512
513        // reload all trees (multiple types might have changed)
514        for each (var treeType in rdfDataTreeCollection.treeTypes) {
515            rdfDataTreeCollection.trees[treeType].idData = null;
516            rdfDataTreeCollection.trees[treeType].idTable = null;
517            rdfDataTreeCollection.trees[treeType].loadTable()
518        }
519        rdfDataTreeCollection.tabbox.selectedTab = document.getElementById(retVar.treeType + "Tab");
520        rdfDataTreeCollection.hideInfoBox();
521    }
522};
523
524vI.rdfDataTreeCollection = rdfDataTreeCollection;
525vI.rdfDataTree = rdfDataTree;
526}});
Note: See TracBrowser for help on using the repository browser.