Commits

Iñigo Serna  committed f4b580f

navigator: implemented un/select files, less full refreshes, select folder after up dir

  • Participants
  • Parent commits b3b781d

Comments (0)

Files changed (2)

File navigator/README

 
 TODO
 ----
+. led busy: start, remove files
 . bulk edit metadata: get from book contents
+. change icon
 . update docs
-  . workflow
   . differences view_edit / bulk_edit
   . NOTE: opening books in UDS will change metadata
+  . workflow
+  . selection globs
+. what's new
+  . less full screen refreshes
+  . up dir -> cursor to par
 
 * Todo:
-  - write a selection dialog: mark all, none, by extension, except extension
   - actions:
     . rename file -> update global.db
   - search: by folder/filename, or by metadata -> virtual folder
+  - cover-based view, details box 2
   - viewedit, bulkedit:
     . tags editing not implemented yet -> waiting for DR800+ enhancements
   - tags-based browsing

File navigator/navigator.vala

 // Copyright (C) 2011  Iñigo Serna <inigoserna@gmail.com>
 // Released under GPL v3+
 //
-// Time-stamp: <2011-09-11 20:25:17 inigo>
+// Time-stamp: <2011-11-28 00:32:41 inigo>
 //////////////////////////////////////////////////////////////////////
 
 
 """;
 
 Navigator app;
-Config    cfg;
+Config   cfg;
 
 
 //////////////////////////////////////////////////////////////////////
     }
 
     public string size_str() {
-        return format_size(size);
+        return MyUtils.format_size(size, "");
     }
 
     public string mtime_str(string fmt="%d/%m/%Y %H:%M") {
 }
 
 
-string format_size(int64 size, string sep="") {
-    if (size >= 1000000000)
-        return "%.2f%sGB".printf(size/(1024*1024*1024.0), sep);
-    else if (size >= 1000000)
-        return "%.2f%sMB".printf(size/(1024*1024.0), sep);
-    else if (size >= 1000)
-        return "%.2f%sKB".printf(size/1024.0, sep);
-    else
-        return "%lld%sB".printf(size, sep);
-}
-
-
 bool is_hidden(string fname) {
     if (fname == "System")
         return true;
     // constants
     const string CONFIG_FILE = SDCARD + "/Programs/_config/.navigator/navigator.ini";
     const int MAX_BOOKMARKS = 25;
+    const int MAX_SELECTION_GLOBS = 10;
 
     // variables
     public bool show_details;
     public bool is_sort_case_sensitive;
     public int nels_in_vfolders;
     public string[] bookmarks;
+	public List<string> selection_globs;
 
     public Config() {
         this.show_details           = false;
                             bookmarks[bid-1] = keyfile.get_string(g, k);
                         }
                         break;
+                    case "Selection Globs":
+                        foreach (string k in keyfile.get_keys(g)) {
+                            var gid = int.parse(k);
+                            if (gid<1 || gid>MAX_SELECTION_GLOBS) {
+                                GLib.stderr.printf("Invalid glob number: %d\n", gid);
+                                continue;
+                            }
+							selection_globs.insert(keyfile.get_string(g, k), gid-1);
+                        }
+                        break;
                     default:
                         GLib.stderr.printf("Invalid configuration group: %s\n", g);
                         continue;
         for (int i=1; i<bookmarks.length+1; i++) {
             cfg_file.printf("%d=%s\n", i, bookmarks[i-1]);
         }
+        cfg_file.puts("\n[Selection Globs]\n");
+		var i = 1;
+        foreach (string glob in selection_globs) {
+            cfg_file.printf("%d=%s\n", i, glob);
+			i++;
+        }
         cfg_file.puts("##### End of file");
         return true;
     }
 
 
 //////////////////////////////////////////////////////////////////////
+///// Some dialogs
+public void dialog_select_files(Navigator app) {
+    var dlg = new Gtk.Dialog.with_buttons("File Selection",
+                                          app,
+                                          Gtk.DialogFlags.DESTROY_WITH_PARENT,
+                                          Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL,
+                                          Gtk.Stock.OK, Gtk.ResponseType.OK);
+    var rbtn_select = new Gtk.RadioButton.with_label(null, "Select");
+    rbtn_select.set_active(true);
+    dlg.vbox.pack_start(rbtn_select, false, true, 5);
+    var rbtn_unselect = new Gtk.RadioButton.with_label(rbtn_select.get_group(), "Unselect");
+    dlg.vbox.pack_start(rbtn_unselect, false, true, 5);
+    var hbox = new Gtk.HBox(false, 10);
+    dlg.vbox.pack_start(hbox, false, true, 10);
+    var lbl2 = new Gtk.Label("Glob:");
+    hbox.pack_start(lbl2, false, false, 0);
+    var cmbboxentry = new Gtk.ComboBoxEntry.text();
+    cmbboxentry.append_text("*");
+	foreach (string glob in cfg.selection_globs) {
+		cmbboxentry.append_text(glob);
+	}
+    cmbboxentry.active = 0;
+    hbox.pack_start(cmbboxentry, true, true, 0);
+	dlg.show_all();
+    if (dlg.run() == Gtk.ResponseType.OK) {
+		var select = rbtn_select.get_active();
+		var glob = cmbboxentry.get_active_text();
+		if (glob==null || glob=="")
+			return;
+		if (glob != "*") {
+			for (int i=0; i<cfg.selection_globs.length(); i++) {
+				if (cfg.selection_globs.nth_data(i) == glob)
+					cfg.selection_globs.remove(cfg.selection_globs.nth_data(i));
+			}
+			while (cfg.selection_globs.length() >= 10)
+				cfg.selection_globs.remove(cfg.selection_globs.last().data);
+			cfg.selection_globs.prepend(glob);
+		}
+		app.select_files(select, glob);
+	}
+    dlg.destroy();
+}
+
+
+public void search_dialog(Navigator app) {
+    var dlg = new Gtk.Dialog.with_buttons ("Search",
+                                           app,
+                                           Gtk.DialogFlags.DESTROY_WITH_PARENT,
+                                           Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL,
+                                           Gtk.Stock.FIND, Gtk.ResponseType.OK);
+    var label = new Gtk.Label ("Please enter a label for the tag to create");
+    dlg.vbox.pack_start(label, true, true, 3);
+    label.show();
+    var entry = new Gtk.Entry();
+    dlg.vbox.pack_start(entry, false, true, 3);
+    entry.show();
+    if (dlg.run() == Gtk.ResponseType.OK) {
+    }
+    dlg.destroy();
+}
+
+
+//////////////////////////////////////////////////////////////////////
 ///// Navigator
 public class Navigator : Gtk.Window, irex.Application {
 
             if (i==0 || i==5) {
                 col = new Gtk.TreeViewColumn.with_attributes(VIEW_COLSNAME[i], cr_icon, "text", i);
                 col.set("alignment", 0.5, "sizing", TreeViewColumnSizing.FIXED, "fixed-width", VIEW_COLSWIDTH[i]);
+                if (i==5) {
+                    col.clickable = true;
+                    col.clicked.connect(() => { dialog_select_files(this); });
+                }
             } else if (i==1) {
                 col = new Gtk.TreeViewColumn.with_attributes(VIEW_COLSNAME[i], cr_left, "text", i);
                 col.set("alignment", 0.5, "expand", true);
         group_main.addItem("close",       "Close",        NAVIGATOR_HOME+"/icons/nav_close.png");
         var subgroup_actions0 = group_main.addSubGroup("groupactions0", "Actions");
         var subgroup_actions = subgroup_actions0.addSubGroup("groupactions", "Actions");
-        subgroup_actions.addItem("vieweditmetadata", "View/Edit metadata",     "rename");
+        subgroup_actions.addItem("vieweditmetadata", "View/Edit metadata",     "/usr/share/ctb/icon-newspaper-mini.png");
         subgroup_actions.addItem("bulkeditmetadata", "Bulk edit metadata",     "tools_character");
+        subgroup_actions.addItem("renamefiles",      "Rename file(s)",         "rename");
         subgroup_actions.addItem("deletefiles",      "Delete file(s)",         "delete");
         subgroup_actions.addItem("unsetlastread",    "Mark as unread",         "cancel");
         subgroup_actions.addItem("createshortcut",   "Create shortcut",        "bookmark");
                 viewedit_metadata();
             else if (item=="bulkeditmetadata")
                 bulkedit_metadata();
+            else if (item=="renamefiles")
+                rename_files();
             else if (item=="deletefiles")
                 delete_files();
             else if (item=="unsetlastread")
                 unset_lastread();
             else if (item=="createshortcut")
                 create_shortcut();
+            else if (item=="viewfile")
+                view_file();
             else if (item=="openfolder")
                 open_folder();
-            else if (item=="viewfile")
-                view_file();
         } else if (group=="Navigator_groupplaces") {
             if (item=="shortcuts")
                 init_path("#shortcuts");
 
 
     private bool cb_key_released(Gtk.Widget w, Gdk.EventKey ev) {
+		var i = row_idx;
         if (row_idx == -1)
             return false;
         if (ev.keyval == KEY_UP) {
             if (row_idx == 0)
                 return false;
-            row_idx--;
+            i--;
         } else if (ev.keyval == KEY_PAGEUP) {
             if (row_idx == 0) {
                 var newpath = Path.get_dirname(dir).replace("//", "/");
-                if (newpath.has_prefix(SDCARD))
+                var oldpath = Path.get_basename(dir).replace("//", "/");
+                if (newpath.has_prefix(SDCARD)) {
                     init_path(newpath);
+					model_files.foreach((model, tpath, iter) => {
+                            GLib.Value val;
+                            model_files.get_value(iter, 1, out val);
+                            if (val.get_string() == oldpath) {
+                                focus_on_row_withiter(iter);
+                                return true;
+                            }
+                            return false;
+                        });
+                }
                 return false;
             }
-            row_idx -= PAGE_STEP;
+            i -= PAGE_STEP;
         } else if (ev.keyval == KEY_DOWN) {
             if (row_idx == model_files.length-1)
                 return false;
-            row_idx++;
+            i++;
         } else if (ev.keyval == KEY_PAGEDOWN) {
             if (row_idx == model_files.length-1)
                 return false;
-            row_idx += PAGE_STEP;
+            i += PAGE_STEP;
         } else if (ev.keyval == KEY_LSHIFT) {
             return false;
         } else {
             return false;
         }
-        row_idx = row_idx<0 ? 0 : row_idx;
-        row_idx = row_idx>model_files.length-1 ? model_files.length-1 : row_idx;
-        focus_on_row(row_idx);
+        i = i<0 ? 0 : (i>model_files.length-1 ? model_files.length-1 : i);
+        focus_on_row(i);
         return false;
     }
 
     }
 
 
+    public void select_files(bool select, string glob) {
+        var pat = new GLib.PatternSpec(glob);
+        model_files.foreach((model, tpath, iter) => {
+                GLib.Value val;
+                model_files.get_value(iter, 1, out val);
+                var filename = val.get_string();
+                if (pat.match_string(filename))
+                    model_files.set_value(iter, 5, select ? "✓" : "");
+                return false;
+            });
+        _selection_update_info();
+    }
+
+
     private void selection_unmark_all() {
         model_files.foreach((model, tpath, iter) => {
                 model_files.set_value(iter, 5, "");
 
 
     public void set_row_and_focus(int i=0) {
-        row_idx = i;
         focus_on_row(i);
     }
 
             dbox.update_book(null);
             return;
         }
-        Gtk.TreePath tpath = new Gtk.TreePath.from_string(i.to_string());
+        Gtk.TreeIter iter;
+        Gtk.TreePath tpath;
+        if (row_idx > -1) {
+            tpath = new Gtk.TreePath.from_string(row_idx.to_string());
+            model_files.get_iter(out iter, tpath);
+            model_files.set_value(iter, 0, "");
+        }
+        row_idx = i;
+        tpath = new Gtk.TreePath.from_string(i.to_string());
         view_files.set_cursor(tpath, view_files.get_column(0), false);
-        model_files.foreach((model, tpath, iter) => {
-                model_files.set_value(iter, 0, "");
-                return false;
-            });
-        Gtk.TreeIter iter;
-        model_files.get_iter(out iter, tpath);
+		model_files.get_iter(out iter, tpath);
         model_files.set_value(iter, 0, "➭");
         GLib.Value val;
         model_files.get_value(iter, 6, out val);
 
 
     private void focus_on_row_withiter(Gtk.TreeIter iter) {
-        if (row_idx== -1)
+        if (row_idx == -1)
             return;
-        row_idx = int.parse(model_files.get_string_from_iter(iter));
-        focus_on_row(row_idx);
+        focus_on_row(int.parse(model_files.get_string_from_iter(iter)));
     }
 
 
             model_files.set_sort_func(3, _sort_size);
             model_files.set_sort_func(4, _sort_time);
         }
-        row_idx = model_files.length==0 ? -1 : 0;
     }
 
 
         lastfolders.prepend(dir);
         dir = newpath;
         populate_model_files(dir);
-        focus_on_row(row_idx);
+        focus_on_row(model_files.length==0 ? -1 : 0);
         stbar_fs_lbl.label = STBAR_FS.printf(get_sdcard_free());
     }
 
     }
 
 
+    private void rename_files() {
+        // var d = new SearchDialog();
+        // d.run();
+        search_dialog(this);
+    }
+
+
     private void delete_files() {
         var files = get_selection_or_current_file();
         var buf = "<span size='large' weight='bold'>Delete files</span>\n\n" +