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

source: content/vI_rdfDataTree.js @ 036c4d

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

further debug cleanup

  • Property mode set to 100644
File size: 18.7 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
41function prepareForComparison (o) {
42    if (typeof o == "string") { return o.toLowerCase().replace(/\"/g,""); }
43//  if (typeof o == "number") { return o; }
44    return "";
45};
46
47
48function rdfDataTree(treeType, rdfDatasource) {
49    this.treeType = treeType;
50    this._rdfDatasource = rdfDatasource;
51    this.filterText = "";
52    this.loadTable();
53};
54
55rdfDataTree.prototype = {
56    idTable : null,
57    idData : null,
58    filterText : null,
59    treeType : null,
60    _rdfDatasource : null,
61
62    get treeElem() { return document.getElementById("rdfDataTree_" + this.treeType); },
63    get tabElem() { return document.getElementById(this.treeType + "Tab"); },
64   
65    //this function is called every time the tree is sorted, filtered, or reloaded
66    loadTable : function() {
67//         Log.debug("loadTable.");
68        //remember scroll position. this is useful if this is an editable table
69        //to prevent the user from losing the row they edited
70        var topVisibleRow = null;
71        if (this.idTable) { topVisibleRow = this.treeElem.treeBoxObject.getFirstVisibleRow(); }
72        if (this.idData == null) {
73            this.idData = [];
74            this._rdfDatasource.readAllEntriesFromRDF(this.addNewDatum, this.treeType, this.idData);
75        }
76        if (this.filterText == "") {
77            //show all of them
78            this.idTable = this.idData;
79        } else {
80            //filter out the ones we want to display
81            var curTable = [];
82            var curFilterText = this.filterText;
83            this.idData.forEach(function(element) {
84                //we'll match on every property
85                for (var i in element) {
86                    if (prepareForComparison(element[i]).indexOf(curFilterText) != -1) {
87                        curTable.push(element);
88                        break;
89                    }
90                }
91            });
92            this.idTable = curTable;
93        }   
94        this.sort();
95       
96        //restore scroll position
97        if (topVisibleRow) {
98            this.treeElem.treeBoxObject.scrollToRow(topVisibleRow);
99        }
100
101        // set Tab label
102        this.tabElem.setAttribute("label", this.treeType + " (" + this.idTable.length + ")");
103//         Log.debug("loadTable done.");
104    },
105
106    addNewDatum : function(resource, name, localIdentityData, idData) {
107        var pref = {    recipientCol : name,
108                indexCol : idData.length + 1 + ".",
109                senderCol : localIdentityData.combinedName,
110                smtpCol : localIdentityData.smtp.value,
111//              smtpKey : localIdentityData.smtp.key,
112                idCol : localIdentityData.id.value,
113//              idKey : localIdentityData.id.key,
114                resource : resource,
115                identityData : localIdentityData}
116//      Log.debug("addNewDatum.");
117        localIdentityData.extras.addPrefs(pref);
118        idData.push(pref);
119    },
120    sort : function(columnName) {
121//      Log.debug("sort: " + columnName);
122        var order = this.treeElem.getAttribute("sortDirection") == "ascending" ? 1 : -1;
123        //if the column is passed and it's already sorted by that column, reverse sort
124        if (columnName && (this.treeElem.getAttribute("sortResource") == columnName)) {
125                order *= -1;
126        }
127       
128        function columnSort(a, b) {
129            if (prepareForComparison(a[columnName]) > 
130                prepareForComparison(b[columnName])) return 1 * order;
131            if (prepareForComparison(a[columnName]) < 
132                prepareForComparison(b[columnName])) return -1 * order;
133            return 0;
134        }
135        if (columnName) this.idTable.sort(columnSort);
136       
137        //setting these will make the sort option persist
138        this.treeElem.setAttribute("sortDirection", order == 1 ? "ascending" : "descending");
139        this.treeElem.setAttribute("sortResource", columnName);
140       
141        this.treeElem.view = new rdfDataTreeCollection.treeView(this.idTable);
142       
143        //set the appropriate attributes to show to indicator
144        var cols = this.treeElem.getElementsByTagName("treecol");
145        for (var i = 0; i < cols.length; i++) {
146            cols[i].removeAttribute("sortDirection");
147            if (cols[i].id.match(columnName))
148                cols[i].setAttribute("sortDirection", order == 1 ? "ascending" : "descending");
149        }
150    }
151};
152
153var rdfDataTreeCollection = {
154    promptService : Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
155            .getService(Components.interfaces.nsIPromptService),
156
157    treeTypes : Array("email", "maillist", "newsgroup", "filter"),
158
159    trees : {},
160    tabbox : null,
161   
162    _strings : null,
163    _rdfDatasource : null,
164   
165    onTabSelect : function () {
166        rdfDataTreeCollection.hideInfoBox();
167        if (rdfDataTreeCollection.tabbox) {
168            rdfDataTreeCollection.moveConstraints();
169            rdfDataTreeCollection.updateButtonMenu();
170        }
171    },
172   
173    onselect : function () {
174        rdfDataTreeCollection.moveConstraints();
175        rdfDataTreeCollection.updateButtonMenu();
176
177        var tree = rdfDataTreeCollection.trees[rdfDataTreeCollection.tabbox.selectedPanel.id];
178        var htmlBox = document.getElementById("rdfDataTreeCollectionInfoBox")
179        if (tree.treeElem.view.selection.count != 1)
180            { rdfDataTreeCollection.hideInfoBox(); return; }
181       
182        var identityData = tree.idTable[tree.treeElem.currentIndex]["identityData"];
183        var _identityInfo = 
184            "<div id='recipientLabel'>" +
185                tree.idTable[tree.treeElem.currentIndex]["recipientCol"].replace(/>/g,"&gt;").replace(/</g,"&lt;") +
186            "</div><div id='vICard'>" +
187            "<table><tr>" +
188                "<td class='image'><img src='chrome://v_identity/skin/vi-info.png' /></td>" +
189                "<td class='identityTable'>" +
190                    "<div class='name'>" + identityData.combinedNameHtml + "</div>" +   
191                    "<table><tbody>" + identityData.getMatrix() + "</tbody></table>" +
192                "</td>" +
193            "</tr></table></div>"
194
195        htmlBox.outputString = _identityInfo;
196        rdfDataTreeCollection.infoBoxHidden = false;
197        htmlBox.setAttribute("style", "height:" + htmlBox.contentDocument.lastChild.scrollHeight +"px");
198        rdfDataTreeCollection.overflow(); // better resize one time too much, mozilla is still magic  :)
199    },
200
201    init : function() {
202        rdfDataTreeCollection.tabbox = document.getElementById("TreeTabbox");
203        rdfDataTreeCollection._strings = Components.classes["@mozilla.org/intl/stringbundle;1"]
204          .getService(Components.interfaces.nsIStringBundleService)
205          .createBundle("chrome://v_identity/locale/vI_rdfDataEditor.properties");
206
207        rdfDataTreeCollection._rdfDatasource = new vI.rdfDatasource("virtualIdentity.rdf");
208       
209        for each (var treeType in rdfDataTreeCollection.treeTypes)
210            rdfDataTreeCollection.trees[treeType] = new rdfDataTree(treeType, rdfDataTreeCollection._rdfDatasource);
211    },
212   
213    clean : function() {
214        if (rdfDataTreeCollection._rdfDatasource) rdfDataTreeCollection._rdfDatasource.clean();
215    },
216
217    get _braille() {
218        var braille = false;
219        try {   braille = (vI.prefroot.getCharPref("accessibility.usebrailledisplay") || 
220                vI.prefroot.getCharPref("accessibility.usetexttospeech")); }
221        catch (e) { };
222        return braille;
223    },
224
225    // generic custom tree view stuff
226    treeView : function (table) {
227        this.rowCount = table.length;
228        this.getCellText = function(row, col) {
229            var retValue = table[row][col.id.substr(0,col.id.indexOf("_"))];
230            if (!rdfDataTreeCollection._braille && (retValue == "no" || retValue == "yes"))
231                return ""; // image will be used as indicator
232            else return retValue;
233        };
234        this.getCellValue = function(row, col) {
235            return this.getCellText(row, col);
236        };
237        this.setTree = function(treebox) {
238            this.treebox = treebox;
239        };
240        this.isEditable = function(row, col) {
241            return col.editable;
242        };
243        this.isContainer = function(row){ return false; };
244        this.isSeparator = function(row){ return false; };
245        this.isSorted = function(){ return false; };
246        this.getLevel = function(row){ return 0; };
247        this.getImageSrc = function(row,col){ return null; };
248        this.getRowProperties = function(row,props){};
249        this.getCellProperties = function(row,col,props){};
250        this.getColumnProperties = function(colid,col,props){};
251        this.cycleHeader = function(col, elem) {
252            var treeType = rdfDataTreeCollection.tabbox.selectedPanel.id;
253            if (treeType != "filter")
254                rdfDataTreeCollection.trees[treeType].sort(col.id.substr(0,col.id.indexOf("_")));
255        };
256        this.getCellProperties = function(row,col,props){
257            if (rdfDataTreeCollection._braille) return;
258            var aserv=Components.classes["@mozilla.org/atom-service;1"].
259                getService(Components.interfaces.nsIAtomService);
260            switch (table[row][col.id.substr(0,col.id.indexOf("_"))]) {
261                case "yes": props.AppendElement(aserv.getAtom("yes")); break;
262                case "no":  props.AppendElement(aserv.getAtom("no")); break;
263            }
264        };
265    },
266
267   
268    __setFilter : function (text) {
269        // loop trough all trees
270        for each (var treeType in rdfDataTreeCollection.treeTypes) {
271            var tree = rdfDataTreeCollection.trees[treeType];
272            tree.filterText = text;
273            tree.loadTable();
274        }
275    },
276
277    inputFilter : function(event) {
278        //do this now rather than doing it at every comparison
279        var value = prepareForComparison(event.target.value);
280        rdfDataTreeCollection.__setFilter(value);
281        document.getElementById("clearFilter").disabled = value.length == 0;
282    },
283   
284    clearFilter : function() {
285        document.getElementById("clearFilter").disabled = true;
286        var filterElement = document.getElementById("filter");
287        filterElement.focus();
288        filterElement.value = "";
289        rdfDataTreeCollection.__setFilter("");
290    },
291   
292    __updateMenu : function(modifySelected, removeSelected) {
293        var tree = rdfDataTreeCollection.trees[rdfDataTreeCollection.tabbox.selectedPanel.id];
294        var noSelections = (tree.treeElem.view.selection.count == 0)
295        modifySelected.setAttribute("disabled", noSelections)
296        removeSelected.setAttribute("disabled", noSelections)   
297    },
298   
299    updateButtonMenu : function() {
300        rdfDataTreeCollection.__updateMenu(
301            document.getElementById("editButton_" + rdfDataTreeCollection.tabbox.selectedPanel.id),
302            document.getElementById("deleteButton_" + rdfDataTreeCollection.tabbox.selectedPanel.id))
303    },
304   
305    updateContextMenu : function() {
306        rdfDataTreeCollection.__updateMenu(
307            document.getElementById("context_modifySelected"),
308            document.getElementById("context_removeSelected"))
309    },
310   
311    updateMenu : function() {
312        rdfDataTreeCollection.__updateMenu(
313            document.getElementById("menu_modifySelected"),
314            document.getElementById("menu_removeSelected"))
315    },
316
317    modifySelected : function() {
318        var treeType = rdfDataTreeCollection.tabbox.selectedPanel.id;
319        var tree = rdfDataTreeCollection.trees[treeType];
320        if (tree.treeElem.view.selection.count == 0) return;
321        if (tree.treeElem.view.selection.count > 5) {
322            var warning = rdfDataTreeCollection._strings.GetStringFromName("vI_rdfDataTree.modify.Warning1") + " " +
323                tree.treeElem.view.selection.count + " " +
324                rdfDataTreeCollection._strings.GetStringFromName("vI_rdfDataTree.modify.Warning2")
325            if (!rdfDataTreeCollection.promptService.confirm(window,"Warning",warning)) return;
326        }
327       
328        var start = new Object(); var end = new Object();
329        var numRanges = tree.treeElem.view.selection.getRangeCount();
330
331        var retVar = { treeType: null };
332        for (var t=0; t<numRanges; t++){
333            tree.treeElem.view.selection.getRangeAt(t,start,end);
334            for (var v=start.value; v<=end.value; v++)
335                window.openDialog("chrome://v_identity/content/vI_rdfDataEditor.xul",0,
336                    "chrome, dialog, modal, alwaysRaised, resizable=yes",
337                    tree.idTable[v], treeType,
338                    rdfDataTreeCollection._rdfDatasource, retVar).focus();
339        }
340       
341        // reload all trees (multiple types might have changed)
342        for each (var treeType in rdfDataTreeCollection.treeTypes) {
343            rdfDataTreeCollection.trees[treeType].idData = null;
344            rdfDataTreeCollection.trees[treeType].idTable = null;
345            rdfDataTreeCollection.trees[treeType].loadTable()
346        }
347        rdfDataTreeCollection.tabbox.selectedTab = document.getElementById(retVar.treeType + "Tab");
348        rdfDataTreeCollection.hideInfoBox();
349    },
350   
351    removeSelected : function() {
352        var treeType = rdfDataTreeCollection.tabbox.selectedPanel.id;
353        var tree = rdfDataTreeCollection.trees[treeType];
354        if (tree.treeElem.view.selection.count == 0) return;
355        var warning = rdfDataTreeCollection._strings.GetStringFromName("vI_rdfDataTree.remove.Warning1") + " " +
356            tree.treeElem.view.selection.count + " " +
357            rdfDataTreeCollection._strings.GetStringFromName("vI_rdfDataTree.remove.Warning2")
358       
359        if (!rdfDataTreeCollection.promptService.confirm(window,"Warning",warning)) return;
360       
361        var start = new Object(); var end = new Object();
362        var numRanges = tree.treeElem.view.selection.getRangeCount();
363
364        for (var t=0; t<numRanges; t++){
365            tree.treeElem.view.selection.getRangeAt(t,start,end);
366            for (var v=start.value; v<=end.value; v++){
367                rdfDataTreeCollection._rdfDatasource.removeVIdentityFromRDF(tree.idTable[v]["resource"], treeType)
368            }
369        }
370       
371        tree.idData = null; tree.idTable = null;
372        tree.loadTable();
373        rdfDataTreeCollection.hideInfoBox();
374    },
375   
376    moveConstraints : function() {
377        var treeType = rdfDataTreeCollection.tabbox.selectedPanel.id;
378        if (treeType != "filter") return;
379        var tree = rdfDataTreeCollection.trees[treeType];
380        if (tree.treeElem.view.selection.count == 0) {
381            document.getElementById("reorderUpButton_filter").setAttribute("disabled","true");
382            document.getElementById("reorderDownButton_filter").setAttribute("disabled","true");
383            return;
384        };
385        var start = new Object(); var end = new Object();
386        var numRanges = tree.treeElem.view.selection.getRangeCount();
387        if (numRanges > 1) {
388            document.getElementById("reorderUpButton_filter").setAttribute("disabled","true");
389            document.getElementById("reorderDownButton_filter").setAttribute("disabled","true");
390            return;
391        }
392        tree.treeElem.view.selection.getRangeAt(0,start,end);
393        if (start.value > 0)
394            document.getElementById("reorderUpButton_filter").removeAttribute("disabled");
395        else    document.getElementById("reorderUpButton_filter").setAttribute("disabled","true");
396        if (end.value < tree.idTable.length - 1)
397            document.getElementById("reorderDownButton_filter").removeAttribute("disabled");
398        else    document.getElementById("reorderDownButton_filter").setAttribute("disabled","true");
399    },
400
401    moveUpSelected : function() {
402        var treeType = rdfDataTreeCollection.tabbox.selectedPanel.id;
403        if (treeType != "filter") return; // just to be safe, button should be disabled
404        var tree = rdfDataTreeCollection.trees[treeType];
405        if (tree.treeElem.view.selection.count == 0) return; // just to be safe, button should be disabled
406
407        var start = new Object(); var end = new Object();
408        var numRanges = tree.treeElem.view.selection.getRangeCount();
409        if (numRanges > 1) return;  // just to be safe, button should be disabled
410       
411        tree.treeElem.view.selection.getRangeAt(0,start,end);
412        for (var v=start.value; v<=end.value; v++){
413            var resource = rdfDataTreeCollection._rdfDatasource.filterContainer.RemoveElementAt(v+1, true);
414            rdfDataTreeCollection._rdfDatasource.filterContainer.InsertElementAt(resource,v,true); 
415        }
416        tree.idData = null; tree.idTable = null;
417        tree.loadTable();
418        tree.treeElem.view.selection.rangedSelect(start.value-1,end.value-1,false);
419    },
420
421    moveDownSelected : function() {
422        var treeType = rdfDataTreeCollection.tabbox.selectedPanel.id;
423        if (treeType != "filter") return; // just to be safe, button should be disabled
424        var tree = rdfDataTreeCollection.trees[treeType];
425        if (tree.treeElem.view.selection.count == 0) return; // just to be safe, button should be disabled
426
427        var start = new Object(); var end = new Object();
428        var numRanges = tree.treeElem.view.selection.getRangeCount();
429        if (numRanges > 1) return;  // just to be safe, button should be disabled
430       
431        tree.treeElem.view.selection.getRangeAt(0,start,end);
432        for (var v=end.value; v>=start.value; v--){
433            var resource = rdfDataTreeCollection._rdfDatasource.filterContainer.RemoveElementAt(v+1, true);
434            rdfDataTreeCollection._rdfDatasource.filterContainer.InsertElementAt(resource,v+2,true); 
435        }
436        tree.idData = null; tree.idTable = null;
437        tree.loadTable();
438        tree.treeElem.view.selection.rangedSelect(start.value+1,end.value+1,false);
439    },
440
441    infoBoxHidden : true,
442    overflow : function() {
443        if (rdfDataTreeCollection.infoBoxHidden) return;
444        var htmlBox = document.getElementById("rdfDataTreeCollectionInfoBox")
445        htmlBox.setAttribute("style", "height:" + htmlBox.contentDocument.lastChild.scrollHeight +"px");
446    },
447
448    hideInfoBox : function() {
449        rdfDataTreeCollection.infoBoxHidden = true;
450        document.getElementById("rdfDataTreeCollectionInfoBox").setAttribute("style", "height:0px");
451        for each (var treeType in rdfDataTreeCollection.treeTypes) {
452            try { if (rdfDataTreeCollection.trees[treeType])
453                rdfDataTreeCollection.trees[treeType].treeElem.view.selection.selectNone() } catch (e) { }
454        }
455    },
456
457    selectAll : function() {
458        var treeType = rdfDataTreeCollection.tabbox.selectedPanel.id;
459        var tree = rdfDataTreeCollection.trees[treeType];
460        tree.treeElem.view.selection.selectAll();
461    },
462   
463    newItem : function() {
464        var treeType = rdfDataTreeCollection.tabbox.selectedPanel.id;
465        var newItemPreset = { identityData : new vI.identityData ("", null, null, vI.NO_SMTP_TAG, null, null) };
466        var retVar = { treeType: null };
467
468        window.openDialog("chrome://v_identity/content/vI_rdfDataEditor.xul",0,
469            "chrome, dialog, modal, alwaysRaised, resizable=yes",
470            newItemPreset, treeType,
471            rdfDataTreeCollection._rdfDatasource, retVar).focus();
472
473        // reload all trees (multiple types might have changed)
474        for each (var treeType in rdfDataTreeCollection.treeTypes) {
475            rdfDataTreeCollection.trees[treeType].idData = null;
476            rdfDataTreeCollection.trees[treeType].idTable = null;
477            rdfDataTreeCollection.trees[treeType].loadTable()
478        }
479        rdfDataTreeCollection.tabbox.selectedTab = document.getElementById(retVar.treeType + "Tab");
480        rdfDataTreeCollection.hideInfoBox();
481    }
482};
483vI.rdfDataTreeCollection = rdfDataTreeCollection;
484vI.rdfDataTree = rdfDataTree;
485}});
Note: See TracBrowser for help on using the repository browser.