Version 0.1.3.
[guestfs-browser.git] / filetree.ml
index a007d97..2bf0b3d 100644 (file)
@@ -155,9 +155,9 @@ and button_press ({ model = model; view = view } as t) ev =
     (* Based on number of selected rows and what is selected, construct
      * the context menu.
      *)
-    if paths <> [] then (
-      let menu = make_context_menu t paths in
-      menu#popup ~button ~time
+    (match make_context_menu t paths with
+     | Some menu -> menu#popup ~button ~time
+     | None -> ()
     );
 
     (* Return true so no other handler will run. *)
@@ -170,9 +170,6 @@ and make_context_menu t paths =
   let menu = GMenu.menu () in
   let factory = new GMenu.factory menu in
 
-  let item = factory#add_item "Open" in
-  item#misc#set_sensitive false;
-
   let rec add_file_items path =
     let item = factory#add_item "File information" in
     item#misc#set_sensitive false;
@@ -202,46 +199,70 @@ and make_context_menu t paths =
     let item = factory#add_item "Download list of filenames ..." in
     ignore (item#connect#activate ~callback:(download_dir_find0 t path));
 
-  and add_os_items path =
+  and add_top_os_items path =
     let item = factory#add_item "Operating system information" in
     ignore (item#connect#activate ~callback:(display_inspection_data t path));
     ignore (factory#add_separator ());
-    add_volume_items path
+    add_top_volume_items path
 
-  and add_volume_items path =
+  and add_top_volume_items path =
     let item = factory#add_item "Filesystem used & free" in
     item#misc#set_sensitive false;
     let item = factory#add_item "Block device information" in
     item#misc#set_sensitive false;
     ignore (factory#add_separator ());
     add_directory_items path
+
+  and add_topwinreg_items path =
+    let item = factory#add_item "Download hive file ..." in
+    item#misc#set_sensitive false;
+    ignore (factory#add_separator ());
+    add_regkey_items path
+
+  and add_regkey_items path =
+    let item = factory#add_item "Download as .reg file ..." in
+    item#misc#set_sensitive false
+
+  and add_regvalue_items path =
+    let item = factory#add_item "Copy value to clipboard" in
+    ignore (item#connect#activate ~callback:(copy_regvalue t path));
+
   in
 
-  (match paths with
-   (* single selection *)
-   | [path, { content=Top (Slave.OS os)} ] ->  (* top level operating system *)
-       add_os_items path
+  let has_menu =
+    match paths with
+    | [] -> false
 
-   | [path, { content=Top (Slave.Volume dev) }] -> (* top level volume *)
-       add_volume_items path
+    (* single selection *)
+    | [path, { content=Top (Slave.OS os)} ] ->  (* top level operating system *)
+        add_top_os_items path; true
 
-   | [path, { content=Directory direntry }] ->     (* directory *)
-       add_directory_items path
+    | [path, { content=Top (Slave.Volume dev) }] -> (* top level volume *)
+        add_top_volume_items path; true
 
-   | [path, { content=File direntry }] ->          (* file *)
-       add_file_items path
+    | [path, { content=Directory _ }] -> (* directory *)
+        add_directory_items path; true
 
-   | [_, { content=Loading }]
-   | [_, { content=ErrorMessage _ }] -> ()
+    | [path, { content=File _ }] ->      (* file *)
+        add_file_items path; true
 
-   | _ ->
-       (* At the moment multiple selection is disabled.  When/if we
-        * enable it we should do something intelligent here. XXX
-        *)
-       ()
-  );
+    | [path, { content=TopWinReg _ }] -> (* top level registry node *)
+        add_topwinreg_items path; true
+
+    | [path, { content=RegKey _ }] ->    (* registry node *)
+        add_regkey_items path; true
+
+    | [path, { content=RegValue _ }] ->  (* registry key/value pair *)
+        add_regvalue_items path; true
 
-  menu
+    | [_, { content=(Loading|ErrorMessage _|Info _) }] -> false
+
+    | _::_::_ ->
+        (* At the moment multiple selection is disabled.  When/if we
+         * enable it we should do something intelligent here. XXX
+         *)
+        false in
+  if has_menu then Some menu else None
 
 let clear { model = model; hash = hash } =
   model#clear ();
@@ -435,6 +456,12 @@ and when_read_directory ({ model = model } as t) path entries =
 
   let row = model#get_iter path in
 
+  (* Sort the entries by lexicographic ordering. *)
+  let cmp { Slave.dent_name = n1 } { Slave.dent_name = n2 } =
+    UTF8.compare n1 n2
+  in
+  let entries = List.sort ~cmp entries in
+
   (* Add the entries. *)
   List.iter (
     fun direntry ->
@@ -543,7 +570,7 @@ and expand_hive_node ({ model = model } as t) row node =
    * to the tree.
    *)
   let values = Hivex.node_values h node in
-  let cmp v1 v2 = compare (Hivex.value_key h v1) (Hivex.value_key h v2) in
+  let cmp v1 v2 = UTF8.compare (Hivex.value_key h v1) (Hivex.value_key h v2) in
   Array.sort cmp values;
   Array.iter (
     fun value ->
@@ -555,7 +582,7 @@ and expand_hive_node ({ model = model } as t) row node =
   ) values;
 
   let children = Hivex.node_children h node in
-  let cmp n1 n2 = compare (Hivex.node_name h n1) (Hivex.node_name h n2) in
+  let cmp n1 n2 = UTF8.compare (Hivex.node_name h n1) (Hivex.node_name h n2) in
   Array.sort cmp children;
   Array.iter (
     fun node ->