and add_top_level_vol ({ model = model; hash = hash } as t) name dev =
let markup =
- sprintf "<b>%s: %s</b>" (markup_escape name) (markup_escape dev) in
+ sprintf "<b>%s</b>\n<small>from %s</small>"
+ (markup_escape dev) (markup_escape name) in
let row = model#append () in
make_node t row (Top (Slave.Volume dev));
Slave.set_failure_hook (Window.failure ws);
Slave.set_busy_hook (Window.throbber_busy ws);
Slave.set_idle_hook (Window.throbber_idle ws);
+ Slave.set_progress_hook (Window.progress ws);
(* What did the user request on the command line? *)
(*Window.run_cli_request ws cli_request;*)
let failure_hook = ref (fun _ -> ())
let busy_hook = ref (fun _ -> ())
let idle_hook = ref (fun _ -> ())
+let progress_hook = ref (fun _ -> ())
let set_failure_hook cb = failure_hook := cb
let set_busy_hook cb = busy_hook := cb
let set_idle_hook cb = idle_hook := cb
+let set_progress_hook cb = progress_hook := cb
(* Execute a function, while holding a mutex. If the function
* fails, ensure we release the mutex before rethrowing the
*)
(* g#set_verbose (verbose ());*)
+ (* Attach progress bar callback. *)
+ g#set_progress_callback (
+ fun proc_nr serial position total ->
+ debug "progress callback proc_nr=%d serial=%d posn=%Ld total=%Ld"
+ proc_nr serial position total;
+ GtkThread.async !progress_hook (position, total)
+ );
+
List.iter (
function
| filename, None ->
and display those in the main thread.
{!set_busy_hook} and {!set_idle_hook} are used to implement a
- "throbber". *)
+ "throbber".
+
+ {!set_progress_hook} is used to implement a progress bar. *)
val set_failure_hook : exn callback -> unit
(** Set the function in the main thread which is called if there is
(** Set the function in the main thread which is called whenever
the slave thread stops working on a command {i and} has no
more commands left in the queue to work on. *)
+
+val set_progress_hook : (int64 * int64) callback -> unit
+ (** Set the function in the main thread which is called whenever
+ the slave thread receives a progress notification message
+ from libguestfs. *)
let throbber_idle ws () =
ws.throbber#set_pixbuf ws.throbber_static
+let progress ws (position, total) =
+ ws.progress_bar#set_fraction
+ (Int64.to_float position /. Int64.to_float total)
+
(* This is called in the main thread whenever a command fails in the
* slave thread. The command queue has been cleared before this is
* called, so our job here is to reset the main window, and if
let view = make_filetree ~packing:(vbox#pack ~expand:true ~fill:true) () in
(* Status bar and progress bar. *)
- let hbox = GPack.hbox ~packing:vbox#pack () in
+ let hbox = GPack.hbox ~spacing:4 ~packing:vbox#pack () in
let progress_bar = GRange.progress_bar ~packing:hbox#pack () in
let statusbar = GMisc.statusbar ~packing:(hbox#pack ~expand:true) () in
let statusbar_context = statusbar#new_context ~name:"Standard" in
thread) which are called whenever the throbber should be
animated/busy or idle. *)
+val progress : window_state -> int64 * int64 -> unit
+ (** This called whenever the progress bar should move. *)
+
(*
val run_cli_request : window_state -> Cmdline.cli_request -> unit
(** This function performs the {!Cmdline.cli_request} operation.