(* Virt resize UI. * Copyright (C) 2011 Red Hat Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *) open Printf open Slave_types open Utils type file_input = { file_button : GButton.radio_button; file_chooser : GFile.chooser_button; file_format_raw : GButton.radio_button; file_format_qcow2 : GButton.radio_button; file_format_detect : GButton.radio_button; file_open_button : GButton.button; } let file_input_set_sensitive t b = t.file_chooser#misc#set_sensitive b; t.file_format_raw#misc#set_sensitive b; t.file_format_qcow2#misc#set_sensitive b; t.file_format_detect#misc#set_sensitive b; t.file_open_button#misc#set_sensitive b type libvirt_input = { libvirt_button : GButton.radio_button; libvirt_combo : GEdit.combo; } let libvirt_input_set_sensitive t b = t.libvirt_combo#misc#set_sensitive b type inspection = { inspection_label : GMisc.label; } class tab (tbl : GPack.table) ready_signal not_ready_signal file_input libvirt_input inspection = object (self) inherit GObj.widget (tbl#as_widget) inherit GUtil.ml_signals [ready_signal#disconnect; not_ready_signal#disconnect] (* Signals. *) method ready : callback:(unit -> unit) -> GtkSignal.id = ready_signal#connect ~after method not_ready : callback:(unit -> unit) -> GtkSignal.id = not_ready_signal#connect ~after (* This method will be called back when disk image or guest is opened. *) method private opened inspection_data = (* We expect that there are some filesystems in the image, otherwise fail. *) if inspection_data.insp_all_filesystems = [] then inspection.inspection_label#set_text "error: no filesystems were found in the selected disk image or guest" else ( (match inspection_data.insp_oses with | [] -> (* no OS, but there were filesystems *) inspection.inspection_label#set_text "warning: no operating systems were recognized in this disk image or guest" | [ os ] -> let label = sprintf "%s %s %d.%d" os.insp_type os.insp_distro os.insp_major_version os.insp_minor_version in let label = if os.insp_product_name <> "" then label ^ " (" ^ os.insp_product_name ^ ")" else label in inspection.inspection_label#set_text label | _ -> inspection.inspection_label#set_text "warning: resizing multi-boot virtual machines may not be successful" ); (* Raise the ready signal. *) ready_signal#call () ) initializer (* Set the inputs to be sensitive according to the state of the top level radio buttons. *) let make_sensitive = function | `FileInput -> file_input_set_sensitive file_input true; libvirt_input_set_sensitive libvirt_input false | `LibvirtInput -> file_input_set_sensitive file_input false; libvirt_input_set_sensitive libvirt_input true in ignore ( file_input.file_button#connect#toggled ~callback:( fun () -> if file_input.file_button#active then make_sensitive `FileInput else make_sensitive `LibvirtInput ) ); ignore ( libvirt_input.libvirt_button#connect#toggled ~callback:( fun () -> if libvirt_input.libvirt_button#active then make_sensitive `LibvirtInput else make_sensitive `FileInput ) ); (* Default sensitivity. *) make_sensitive `FileInput; (* Wire up file dialog. *) ignore ( file_input.file_open_button#connect#clicked ~callback:( fun () -> match file_input.file_chooser#filename with | None -> () (* nothing selected yet *) | Some filename -> (* filename selected *) let format = if file_input.file_format_raw#active then Some "raw" else if file_input.file_format_qcow2#active then Some "qcow2" else if file_input.file_format_detect#active then None else assert false in (* shouldn't be possible??? *) let msg = Slave.Open_images ([filename, format], self#opened) in Slave.send_message msg ) ) end let tab () = let tbl = GPack.table ~border_width:8 ~columns:2 ~rows:1 () in (* Signals. *) let ready_signal = new GUtil.signal () in let not_ready_signal = new GUtil.signal () in let file_input = let button = GButton.radio_button ~label:"File or device:" ~packing:(tbl#attach ~top:0 ~left:0) () in let chooser = GFile.chooser_button ~action:`OPEN ~packing:(tbl#attach ~top:0 ~left:1) () in (* We have an "unnecessary" open button here for a couple of reasons: Firstly because lablgtk2 doesn't bind the file-set callback, so we can't tell when a file has been picked in the file chooser. But secondly because it allows the user to pick a file and the format before actually opening the file (which could be an expensive operation). *) let open_button = GButton.button ~label:"Open" ~packing:(tbl#attach ~top:0 ~left:2) () in let raw = GButton.radio_button ~label:"raw" ~packing:(tbl#attach ~top:1 ~left:1) () in let group = raw#group in let qcow2 = GButton.radio_button ~label:"qcow2" ~group ~packing:(tbl#attach ~top:2 ~left:1) () in let detect = GButton.radio_button ~label:"autodetect format" ~group ~active:true ~packing:(tbl#attach ~top:3 ~left:1) () in { file_button = button; file_chooser = chooser; file_format_raw = raw; file_format_qcow2 = qcow2; file_format_detect = detect; file_open_button = open_button } in (* Add a dummy row as a spacer. *) ignore (GMisc.label ~packing:(tbl#attach ~top:4 ~left:0) ()); tbl#set_row_spacing 4 16; let libvirt_input = let group = file_input.file_button#group in let button = GButton.radio_button ~label:"Guest:" ~group ~packing:(tbl#attach ~top:5 ~left:0) () in let combo = GEdit.combo ~packing:(tbl#attach ~top:5 ~left:1) () in { libvirt_button = button; libvirt_combo = combo } in (* Add a dummy row as a spacer. *) ignore (GMisc.label ~packing:(tbl#attach ~top:6 ~left:0) ()); tbl#set_row_spacing 6 16; let inspection = let label = GMisc.label ~packing:(tbl#attach ~top:7 ~left:0 ~right:2) () in { inspection_label = label } in (* Return the object. *) new tab tbl ready_signal not_ready_signal file_input libvirt_input inspection