Merge remote branch 'gautier/multi_select' into master. Closes gh-6.

This commit is contained in:
Felix Ruess
2010-12-21 19:50:54 +01:00
4 changed files with 197 additions and 53 deletions
+44
View File
@@ -106,3 +106,47 @@ let combo_connect = fun ((combo: #GEdit.combo_box), (_,column)) cb ->
let data = combo#model#get ~row ~column in
cb data))
type tree = GTree.view * (GTree.list_store * string GTree.column)
let tree_widget = fst
let tree_model = snd
let tree = fun (t:GTree.view) ->
let cols = new GTree.column_list in
let col_name = cols#add Gobject.Data.string in
let store = GTree.list_store cols in
t#set_model (Some store#coerce);
let col1 = GTree.view_column ~renderer:(GTree.cell_renderer_text [], ["text",col_name]) () in
ignore (t#append_column col1);
(t , (store, col_name))
let tree_of = fun (t:GTree.view) (m:(GTree.list_store * string GTree.column)) ->
(t, m)
let tree_values = fun (tree : tree) ->
let (store, column) = tree_model tree in
let values = ref "" in
store#foreach (fun _ row ->
values := !values^" "^(store#get ~row ~column);
false);
!values
let get_selected_in_tree = fun (tree : tree) ->
let (store, column) = tree_model tree in
let t = tree_widget tree in
let sel_paths = t#selection#get_selected_rows in
List.map (fun p -> store#get_row_reference p) sel_paths
let add_to_tree = fun (tree : tree) string ->
let (store, column) = tree_model tree in
let row = store#append () in
store#set ~row ~column string
let remove_selected_from_tree = fun (tree : tree) ->
let selected = get_selected_in_tree tree in
let (store, _) = tree_model tree in
List.iter (fun r -> ignore (store#remove r#iter)) selected
let clear_tree = fun (tree : tree) ->
let (store, _) = tree_model tree in
store#clear ()
+14
View File
@@ -58,3 +58,17 @@ val combo_separator : string
val combo_value : combo -> string
val select_in_combo : combo -> string -> unit
val combo_connect : combo -> (string -> unit) -> unit
(*** Utilities for a tree view widget ***)
type tree
val tree_widget : tree -> GTree.view
val tree_model : tree -> (GTree.list_store * string GTree.column)
val tree : GTree.view -> tree
val tree_of : GTree.view -> (GTree.list_store * string GTree.column) -> tree
val tree_values : tree -> string
val get_selected_in_tree : tree -> GTree.row_reference list
val add_to_tree : tree -> string -> unit
val remove_selected_from_tree : tree -> unit
val clear_tree : tree -> unit
+58 -16
View File
@@ -102,6 +102,7 @@
<widget class="GtkImageMenuItem" id="menu_item_new_ac">
<property name="label">gtk-new</property>
<property name="visible">True</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_menu_item_new_ac_activate"/>
<accelerator key="N" signal="activate" modifiers="GDK_CONTROL_MASK"/>
@@ -111,6 +112,7 @@
<widget class="GtkImageMenuItem" id="delete_ac_menu_item">
<property name="label">gtk-delete</property>
<property name="visible">True</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_delete_a/c2_activate"/>
<accelerator key="X" signal="activate" modifiers="GDK_CONTROL_MASK"/>
@@ -154,6 +156,7 @@
<widget class="GtkImageMenuItem" id="menu_item_new session">
<property name="label">gtk-new</property>
<property name="visible">True</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_menu_item_new session_activate"/>
</widget>
@@ -162,6 +165,7 @@
<widget class="GtkImageMenuItem" id="menu_item_save_session">
<property name="label">gtk-save</property>
<property name="visible">True</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_menu_item_save_session_activate"/>
</widget>
@@ -542,38 +546,76 @@
<widget class="GtkHBox" id="hbox58">
<property name="visible">True</property>
<child>
<widget class="GtkLabel" id="label_settings">
<widget class="GtkTreeView" id="tree_settings">
<property name="height_request">4</property>
<property name="visible">True</property>
<property name="label" translatable="yes">_________________</property>
<property name="wrap">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">False</property>
</widget>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="button_browse_settings">
<property name="label" translatable="yes">...</property>
<widget class="GtkVScrollbar" id="tree_settings_scrollbar">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip" translatable="yes">Browse (multiple selection allowed)</property>
<property name="use_underline">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="button_edit_settings">
<property name="label">gtk-edit</property>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip" translatable="yes">Launch an editor on the _first_ settings file</property>
<property name="use_stock">True</property>
<child>
<widget class="GtkButton" id="button_browse_settings">
<property name="label">gtk-add</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip" translatable="yes">Add a settings file</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="button_edit_settings">
<property name="label">gtk-edit</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip" translatable="yes">Launch an editor on all the settings file</property>
<property name="use_stock">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="button_remove_settings">
<property name="label">gtk-remove</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip" translatable="yes">Remove the selected settings file</property>
<property name="use_stock">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
+81 -37
View File
@@ -96,12 +96,21 @@ let gcs_or_edit = fun file ->
| 2 -> ignore (Sys.command (sprintf "%s -edit '%s'&" gcs file))
| _ -> failwith "Internal error: gcs_or_edit"
let ac_files = fun gui ->
["airframe", "airframes", gui#label_airframe, gui#button_browse_airframe, gui#button_edit_airframe, edit, false;
"flight_plan", "flight_plans", gui#label_flight_plan, gui#button_browse_flight_plan, gui#button_edit_flight_plan, gcs_or_edit, false;
"settings", "settings", gui#label_settings, gui#button_browse_settings, gui#button_edit_settings, edit, true;
"radio", "radios", gui#label_radio, gui#button_browse_radio, gui#button_edit_radio, edit, false;
"telemetry", "telemetry", gui#label_telemetry, gui#button_browse_telemetry, gui#button_edit_telemetry, edit, false]
type ac_data =
Label of GMisc.label
| Tree of Gtk_tools.tree
let string_of_ac_data = fun d ->
match d with
Label l -> l#text
| Tree t -> Gtk_tools.tree_values t
let ac_files = fun gui model ->
["airframe", "airframes", Label gui#label_airframe, gui#button_browse_airframe, gui#button_edit_airframe, edit, None;
"flight_plan", "flight_plans", Label gui#label_flight_plan, gui#button_browse_flight_plan, gui#button_edit_flight_plan, gcs_or_edit, None;
"settings", "settings", Tree (Gtk_tools.tree_of gui#tree_settings model), gui#button_browse_settings, gui#button_edit_settings, edit, Some gui#button_remove_settings;
"radio", "radios", Label gui#label_radio, gui#button_browse_radio, gui#button_edit_radio, edit, None;
"telemetry", "telemetry", Label gui#label_telemetry, gui#button_browse_telemetry, gui#button_edit_telemetry, edit, None]
(* Awful but easier *)
@@ -124,7 +133,8 @@ let correct_ac_name = fun s ->
with
Exit -> false
let save_callback = fun ?user_save gui ac_combo () ->
(*TODO function text of date_type*)
let save_callback = fun ?user_save gui ac_combo model () ->
let ac_name = Gtk_tools.combo_value ac_combo
and ac_id = gui#entry_ac_id#text in
@@ -133,6 +143,7 @@ let save_callback = fun ?user_save gui ac_combo () ->
GToolbox.message_box ~title:"Error on A/C id" "A/C id must be a non null number less than 255"
else
let color = !current_color in
let tree = Gtk_tools.tree_of gui#tree_settings model in
let aircraft =
Xml.Element ("aircraft",
["name", ac_name;
@@ -141,7 +152,7 @@ let save_callback = fun ?user_save gui ac_combo () ->
"radio", gui#label_radio#text;
"telemetry", gui#label_telemetry#text;
"flight_plan", gui#label_flight_plan#text;
"settings", gui#label_settings#text;
"settings", Gtk_tools.tree_values tree;
"gui_color", color],
[]) in
begin try Hashtbl.remove Utils.aircrafts ac_name with _ -> () end;
@@ -205,31 +216,43 @@ let parse_ac_targets = fun target_combo ac_file ->
(* Link A/C to airframe & flight_plan labels *)
let ac_combo_handler = fun gui (ac_combo:Gtk_tools.combo) target_combo ->
(* build tree for settings *)
let tree_set = Gtk_tools.tree gui#tree_settings in
let model = Gtk_tools.tree_model tree_set in
(* attach vertical scrollbar *)
gui#tree_settings#set_vadjustment gui#tree_settings_scrollbar#adjustment;
(* Update_params callback *)
let update_params = fun ac_name ->
try
let aircraft = Hashtbl.find Utils.aircrafts ac_name in
let sample = aircraft_sample ac_name "42" in
let value = fun a ->
try (ExtXml.attrib aircraft a) with _ -> Xml.attrib sample a in
List.iter
(fun (a, _subdir, label, _, _, _, _) -> label#set_text (value a))
(ac_files gui);
let ac_id = ExtXml.attrib aircraft "ac_id"
and gui_color = ExtXml.attrib_or_default aircraft "gui_color" "white" in
gui#button_clean#misc#set_sensitive true;
gui#button_build#misc#set_sensitive true;
gui#eventbox_gui_color#misc#modify_bg [`NORMAL, `NAME gui_color];
current_color := gui_color;
gui#entry_ac_id#set_text ac_id;
(Gtk_tools.combo_widget target_combo)#misc#set_sensitive true;
parse_ac_targets target_combo (ExtXml.attrib aircraft "airframe");
try (ExtXml.attrib aircraft a) with _ -> Xml.attrib sample a in
List.iter (fun (a, _subdir, label, _, _, _, _) ->
match label with
Label l -> l#set_text (value a)
| Tree t ->
ignore (Gtk_tools.clear_tree tree_set);
let names = Str.split regexp_space (value a) in
List.iter (fun n -> Gtk_tools.add_to_tree t n) names
) (ac_files gui model);
let ac_id = ExtXml.attrib aircraft "ac_id"
and gui_color = ExtXml.attrib_or_default aircraft "gui_color" "white" in
gui#button_clean#misc#set_sensitive true;
gui#button_build#misc#set_sensitive true;
gui#eventbox_gui_color#misc#modify_bg [`NORMAL, `NAME gui_color];
current_color := gui_color;
gui#entry_ac_id#set_text ac_id;
(Gtk_tools.combo_widget target_combo)#misc#set_sensitive true;
parse_ac_targets target_combo (ExtXml.attrib aircraft "airframe");
with
Not_found ->
gui#label_airframe#set_text "";
gui#label_flight_plan#set_text "";
gui#button_clean#misc#set_sensitive false;
gui#button_build#misc#set_sensitive false;
(Gtk_tools.combo_widget target_combo)#misc#set_sensitive false
gui#label_airframe#set_text "";
gui#label_flight_plan#set_text "";
gui#button_clean#misc#set_sensitive false;
gui#button_build#misc#set_sensitive false;
(Gtk_tools.combo_widget target_combo)#misc#set_sensitive false
in
Gtk_tools.combo_connect ac_combo update_params;
@@ -275,19 +298,22 @@ let ac_combo_handler = fun gui (ac_combo:Gtk_tools.combo) target_combo ->
let colorname = string_of_gdkcolor csd#colorsel#color in
gui#eventbox_gui_color#misc#modify_bg [`NORMAL, `NAME colorname];
current_color := colorname;
save_callback gui ac_combo ();
save_callback gui ac_combo model ();
csd#destroy () in
ignore (csd#ok_button#connect#clicked ~callback);
ignore (csd#cancel_button#connect#clicked ~callback:csd#destroy) in
ignore(gui#button_gui_color#connect#clicked ~callback);
(* A/C id *)
ignore(gui#entry_ac_id#connect#changed ~callback:(fun () -> save_callback gui ac_combo ()));
ignore(gui#entry_ac_id#connect#changed ~callback:(fun () -> save_callback gui ac_combo model ()));
(* Conf *)
List.iter (fun (name, subdir, label, button_browse, button_edit, editor, multiple) ->
List.iter (fun (name, subdir, label, button_browse, button_edit, editor, remove) ->
let callback = fun _ ->
let rel_files = Str.split regexp_space label#text in
let rel_files = match label with
Label l -> Str.split regexp_space l#text
| Tree t -> Str.split regexp_space (Gtk_tools.tree_values t)
in
let abs_files = List.map (Filename.concat Utils.conf_dir) rel_files in
let quoted_files = List.map (fun s -> "'"^s^"'") abs_files in
let arg = String.concat " " quoted_files in
@@ -295,17 +321,35 @@ let ac_combo_handler = fun gui (ac_combo:Gtk_tools.combo) target_combo ->
ignore (button_edit#connect#clicked ~callback);
let callback = fun _ ->
let cb = fun names ->
let names = String.concat " " names in
label#set_text names;
save_callback gui ac_combo ()
ignore (match label with
Label l ->
let names = String.concat " " names in
l#set_text names
| Tree t ->
List.iter (fun n -> Gtk_tools.add_to_tree t n) names
);
save_callback gui ac_combo model ()
in
Utils.choose_xml_file ~multiple name subdir cb in
ignore (button_browse#connect#clicked ~callback))
(ac_files gui);
Utils.choose_xml_file name subdir cb in
ignore (button_browse#connect#clicked ~callback);
ignore (match remove with
Some r ->
let callback = fun _ ->
match label with
Tree t ->
Gtk_tools.remove_selected_from_tree t;
save_callback gui ac_combo model ()
| _ -> ()
in
ignore (r#connect#clicked ~callback)
| _ -> ()
)
)
(ac_files gui model);
(* Save button *)
ignore(gui#menu_item_save_ac#connect#activate ~callback:(save_callback ~user_save:true gui ac_combo))
ignore(gui#menu_item_save_ac#connect#activate ~callback:(save_callback ~user_save:true gui ac_combo model))
let build_handler = fun ~file gui ac_combo (target_combo:Gtk_tools.combo) (log:string->unit) ->