Use more reliable multiple select instead of checkboxes.
authorW. Trevor King <wking@drexel.edu>
Sun, 18 Jul 2010 12:56:02 +0000 (08:56 -0400)
committerW. Trevor King <wking@drexel.edu>
Sun, 18 Jul 2010 16:45:59 +0000 (12:45 -0400)
I couldn't figure out how to use setCellValue to change and display
the checkbox values.  The current implementation adds a "Set Tags"
button which reads off the selected rows and uploads any tag changes.

Problem with the current implementation:

When the tree is rebuilt following a data refresh, the rebuild seems
to unselect any repainted rows.  I'm not sure why.  The current
workaround is to run setup_checkboxes() some reasonable delay after
refreshing the data.  Too bad I can't find a blocking refresh, or
better yet, a post-refresh hook to use instead of setTimeout().

Anyhow, any tag selection activity by the user that happens during the
timeout will, obviously, be overwritten by the setup_checkboxes()
call.

static/dirtag.js
template/dirtag.xul

index b6f5373e93884ec745e3260cb64ecfc0628edb1b..a51198dabaf0b6d5bf43015ecbe7dbd2589181ab 100644 (file)
@@ -38,12 +38,13 @@ function tag_in_tags(tag, tags) {
 
 function setup_checkboxes(tags) {
     var tree = document.getElementById('checkbox-tree');
-    var ctags = tree.columns.getLastColumn();
     for (var row=0; row<tree.view.rowCount; row++) {
        p = tree_path(tree, row);
-       tree.view.origSetCellValue(row, ctags, tag_in_tags(p, tags));
+       if (tag_in_tags(p, tags) != tree.view.selection.isSelected(row)) {
+           tree.view.selection.toggleSelect(row);
+       }
     }
-    tree.treeBoxObject.invalidateColumn(ctags);
+    tree.treeBoxObject.invalidate();
 }
 
 /* Functions driving the CherryPy backend */
@@ -60,15 +61,23 @@ function reload_rdf(e) {
        document.getElementById('raw-tree').builder.refresh();
        document.getElementById('tag-tree').builder.refresh();
        document.getElementById('checkbox-tree').builder.refresh();
+    }
 
+    /* Reloaded rows may be unselected.  Attempt to fix the
+       selections after reloading.
+    */
+    window.setTimeout( function z () {
        var id = document.getElementById('element').tree_id;
+       if (id == null)
+           return;
        var path_tags = tree_selection(id);
        setup_checkboxes(path_tags[1]);
-    }
+       }, 3000);
 }
 
 function push_data(url) {
     /* https://developer.mozilla.org/en/using_xmlhttprequest */
+    //alert(url);
     xmlDoc = new XMLHttpRequest();
     xmlDoc.open('GET', url, true);
     xmlDoc.onreadystatechange = function() { reload_rdf(xmlDoc); };
@@ -130,15 +139,24 @@ function tag_tree_select() {
     set_selected_element(path_tags[0], path_tags[1], 'tag-tree');
 }
 
-function checkbox_activity(tree, row, col, value) {
+function set_tags_button() {
     var path = document.getElementById('element').file_path;
-    var name = tree.columns.getPrimaryColumn();
-    id = tree_path(tree, row);
-    if (path == 'UNDEFINED') {
+    if (path == 'UNDEFINED')
        return;
-    } else if (value == true || value == 'true') {
-       add_tag(path, id);
-    } else {
-       remove_tag(path, id);
+    var tree = document.getElementById('checkbox-tree');
+    var element = document.getElementById('element');
+    var tags = Array();
+    for (var row=0; row<tree.view.rowCount; row++) {
+       value = tree.view.selection.isSelected(row);
+       tag = tree_path(tree, row);
+       if (value == true || value == 'true') {
+           tags.push(tag);
+           if (!tag_in_tags(tag, element.file_tags))
+               add_tag(path, tag);
+       } else {
+           if (tag_in_tags(tag, element.file_tags))
+               remove_tag(path, tag);
+       }
     }
+    element.file_tags = tags;
 }
index 26b145766b55fd736e9ff15c3a82cbb8797e1977..2e1ad9d442f0502948aa8e1d87177ecda1d75feb 100644 (file)
@@ -19,6 +19,8 @@
   <!ENTITY path_column.label "Path">
   <!ENTITY tag_column.label "Tags">
   <!ENTITY tags.caption "Tags">
+  <!ENTITY set_tags_button.label "Set Tags">
+  <!ENTITY set_tags_button.key "s">
   <!ENTITY selected.caption "Selected">
 ]>
 
       <caption id="selected-caption" label="&selected.caption;"/>
       <groupbox id="tags" flex="1">
        <caption label="&tags.caption;"/>
-       <tree id="checkbox-tree" rows="2" seltype="single" selstype="primary"
-             editable="true"
+       <button
+          id="set-tags-button"
+          class="dialog"
+          disabled="false"
+          label="&set_tags_button.label;"
+          accesskey="&set_tags_button.key;"
+          oncommand="set_tags_button();"/>
+       <tree id="checkbox-tree" rows="1" seltype="multiple"
              datasources="tag.rdf raw.rdf"
              ref="http://dirtag.com/tag/files"
              flex="1">
-         <!-- checkbox callback attached in dirtag.js's initialize() -->
          <treecols>
-           <treecol id="checkbox-tree-check-column" label="CK" type="checkbox"
-                    editable="true"/>
            <treecol id="checkbox-tree-path-column" label="&path_column.label;"
-                    editable="true" primary="true"
+                    primary="true"
                     sort="rdf:http://dirtag.com/rdf#name" flex="1"/>
            <splitter class="tree-splitter"/>
          </treecols>
              <treechildren>
                <treeitem uri="rdf:*" open="true">
                  <treerow>
-                   <treecell editable="true"/>
                    <treecell label="rdf:http://dirtag.com/rdf#name"/>
                  </treerow>
                </treeitem>