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

source: content/vI_rdfDataTree.js @ 07ec84

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

added last-used and created column in rdf

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