diff --git a/sw/supervision/Makefile b/sw/supervision/Makefile index 7cff7481ba..685fd81484 100644 --- a/sw/supervision/Makefile +++ b/sw/supervision/Makefile @@ -15,21 +15,25 @@ paparazzicenter : $(PAPARAZZICENTERCMO) $(OCAMLLIB)/lib-pprz.cma $(Q)$(OCAMLC) -custom $(INCLUDES) -o $@ unix.cma str.cma xml-light.cma lablgtk.cma lablglade.cma gtkInit.cmo lib-pprz.cma lablgnomeui.cma $^ gtk_pc.ml : paparazzicenter.glade - lablgladecc2 -root window $< > $@ + lablgladecc2 -hide-default -root window $< > $@ gtk_process.ml : paparazzicenter.glade - lablgladecc2 -root hbox_program $< | grep -B 1000000 " end" > $@ + lablgladecc2 -hide-default -root hbox_program $< | grep -B 1000000 " end" > $@ %.cmo : %.ml @echo OC $< $(Q)$(OCAMLC) $(INCLUDES) -c $< +%.cmi : %.mli + @echo OC $< + $(Q)$(OCAMLC) $(INCLUDES) $< + paparazzicenter.cmo : gtk_pc.cmo gtk_process.cmo pc_common.cmo pc_control_panel.cmo pc_aircraft.cmo pc_control_panel.cmo pc_aircraft.cmo : pc_common.cmo clean: - \rm *.cm* gtk_pc.ml gtk_process.ml + \rm *.cm* gtk_pc.ml gtk_process.ml .depend # # Dependencies diff --git a/sw/supervision/paparazzicenter.glade b/sw/supervision/paparazzicenter.glade index abaae931ba..9933a7a4ed 100644 --- a/sw/supervision/paparazzicenter.glade +++ b/sw/supervision/paparazzicenter.glade @@ -3,2092 +3,6 @@ - - True - Paparazzi Center - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_NORMAL - GDK_GRAVITY_NORTH_WEST - True - False - - - - True - False - 0 - - - - True - True - True - True - GTK_POS_TOP - False - False - - - - True - False - 0 - - - - True - 2 - 3 - False - 1 - 2 - - - - 260 - 100 - True - True - GTK_POLICY_AUTOMATIC - GTK_POLICY_ALWAYS - GTK_SHADOW_NONE - GTK_CORNER_TOP_LEFT - - - - True - GTK_SHADOW_IN - - - - True - False - 0 - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 2 - - - - True - ________________ - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - Browse - True - ... - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - True - Launch the GCS editor or a text editor (gedit or EDITOR env variable if set) - True - gtk-edit - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - - - - - True - <b>Airframe</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - _________________ - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - True - ... - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - True - Launch a text editor (gedit or EDITOR env variable if set) - True - gtk-edit - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - - - - - True - <b>Flight plan</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - _________________ - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - Browse (multiple selection allowed) - True - ... - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - True - Launch an editor on the _first_ settings file - True - gtk-edit - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - - - - - True - <b>Settings</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - _________________ - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - True - ... - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - True - True - gtk-edit - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - - - - - True - <b>Radio</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - _________________ - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - True - ... - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - True - True - gtk-edit - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - - - - - True - <b>Telemetry</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - - - - 1 - 2 - 0 - 2 - fill - - - - - - True - False - 1 - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - - - - - - - - - True - <b>A/C</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - False - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - ID of the aircraft (number from 1 to 255) - True - True - True - 3 - - True - * - False - 3 - - - - - - - - True - <b>id</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - False - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - True - False - - - - - - - 0 - True - True - - - - - - True - Color selector - True - ... - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - - - - - True - <b>GUI color</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - False - - - - - 0 - 1 - 0 - 1 - fill - - - - - - - True - True - 0 - - - - True - True - GTK_RELIEF_NORMAL - True - - - - True - 0.5 - 0.5 - 0 - 0 - 0 - 0 - 0 - 0 - - - - True - False - 2 - - - - True - gtk-clear - 4 - 0.5 - 0.5 - 0 - 0 - - - 0 - False - False - - - - - - True - Clean - True - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - - - - 0 - False - False - - - - - - True - Build the selected target of the selected A/C. Warning: Save is required before this action - True - True - GTK_RELIEF_NORMAL - True - - - - True - 0.5 - 0.5 - 0 - 0 - 0 - 0 - 0 - 0 - - - - True - False - 2 - - - - True - gtk-convert - 4 - 0.5 - 0.5 - 0 - 0 - - - 0 - False - False - - - - - - True - Build - True - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - - - - 0 - False - False - - - - - - True - False - Upload into the airborne device (which must be plugged !). - True - GTK_RELIEF_NORMAL - True - - - - True - 0.5 - 0.5 - 0 - 0 - 0 - 0 - 0 - 0 - - - - True - False - 2 - - - - True - gtk-go-up - 4 - 0.5 - 0.5 - 0 - 0 - - - 0 - False - False - - - - - - True - Upload - True - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - - - - 0 - False - False - - - - - 2 - 3 - 1 - 2 - fill - - - - - - - True - False - 0 - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - - - - - - - - - True - <b>Target</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - True - Add a target in the combo list - True - GTK_RELIEF_NORMAL - True - - - - True - 0.5 - 0.5 - 0 - 0 - 0 - 0 - 0 - 0 - - - - True - False - 2 - - - - True - gtk-add - 4 - 0.5 - 0.5 - 0 - 0 - - - 0 - False - False - - - - - - True - New Target - True - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - - - - 0 - False - False - - - - - 2 - 3 - 0 - 1 - fill - - - - - - - True - False - 1 - - - - True - Delete the selected A/C - True - GTK_RELIEF_NORMAL - True - - - - True - 0.5 - 0.5 - 0 - 0 - 0 - 0 - 0 - 0 - - - - True - False - 2 - - - - True - gtk-delete - 4 - 0.5 - 0.5 - 0 - 0 - - - 0 - False - False - - - - - - True - Delete A/C - True - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - - - - 0 - False - False - - - - - - True - Add a new A/C in the configuration, with default configuration files - True - GTK_RELIEF_NORMAL - True - - - - True - 0.5 - 0.5 - 0 - 0 - 0 - 0 - 0 - 0 - - - - True - False - 2 - - - - True - gtk-add - 4 - 0.5 - 0.5 - 0 - 0 - - - 0 - False - False - - - - - - True - New A/C - True - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - - - - 0 - False - False - - - - - - True - Save the current configuration. Required for Build and Upload - True - gtk-save - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - True - Automatic save before Clean, Build or Upload - True - auto - True - GTK_RELIEF_NORMAL - True - True - False - True - - - 0 - False - False - - - - - 0 - 1 - 1 - 2 - fill - - - - - - 0 - False - False - - - - - - True - False - 0 - - - - 200 - True - True - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_SHADOW_IN - GTK_CORNER_TOP_LEFT - - - - True - True - False - False - True - GTK_JUSTIFY_LEFT - GTK_WRAP_WORD - False - 0 - 0 - 0 - 0 - 0 - 0 - - - - - - 0 - True - True - - - - - 0 - True - True - - - - - False - True - - - - - - True - Conf/Console - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - tab - - - - - - True - False - 0 - - - - True - False - 0 - - - - True - GTK_PACK_DIRECTION_LTR - GTK_PACK_DIRECTION_LTR - - - - True - Session - True - - - - - - - True - _Simulation - True - - - - - - - True - _Flight - True - - - - - - - True - Log File _Replay - True - - - - - - - True - - - - - - True - Custom - True - - - - - - - - - - - True - _Tools - True - - - - - - True - _Help - True - - - - - - - True - _About - True - - - - - - - - - - 0 - False - False - - - - - - True - False - 0 - - - - True - Current Operation: - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - True - True - True - 0 - - True - * - False - 20 - - - 0 - False - True - - - - - - True - True - GTK_RELIEF_NORMAL - True - - - - True - 0.5 - 0.5 - 0 - 0 - 0 - 0 - 0 - 0 - - - - True - False - 2 - - - - True - gtk-clear - 4 - 0.5 - 0.5 - 0 - 0 - - - 0 - False - False - - - - - - True - Stop/Remove All Processes - True - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - - - - 0 - False - False - GTK_PACK_END - - - - - - True - Save current process commands in a user session - True - gtk-save - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - True - Delete the current session from the user sessions - True - gtk-delete - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - 0 - False - False - - - - - - True - False - 0 - - - - - - - 0 - False - True - - - - - - True - True - GTK_POLICY_ALWAYS - GTK_POLICY_ALWAYS - GTK_SHADOW_IN - GTK_CORNER_TOP_LEFT - - - - True - True - True - False - True - GTK_JUSTIFY_LEFT - GTK_WRAP_NONE - True - 0 - 0 - 0 - 0 - 0 - 0 - - - - - - 0 - True - True - - - - - 0 - True - True - - - - - False - False - - - - - - True - Control Panel - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - tab - - - - - - True - False - 0 - - - - - - - True - True - - - - - - True - GCS - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - tab - - - - - - True - False - 0 - - - - - - - False - False - GTK_PACK_END - - - - - - True - Quit - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - tab - - - - - 0 - True - True - - - - - - True - True - - - 0 - False - False - - - - - - True window1 @@ -2214,4 +128,1878 @@ + + True + Paparazzi Center + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + True + False + False + GDK_WINDOW_TYPE_HINT_NORMAL + GDK_GRAVITY_NORTH_WEST + True + False + + + + True + False + 0 + + + + True + GTK_PACK_DIRECTION_LTR + GTK_PACK_DIRECTION_LTR + + + + True + _A/C + True + + + + + + + True + _New A/C + True + + + + + + True + gtk-add + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + True + _Delete A/C + True + + + + + + True + gtk-delete + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + True + gtk-save + True + + + + + + + True + + + + + + True + gtk-quit + True + + + + + + + + + + + True + Session + True + + + + + + + True + New session + True + + + + + True + gtk-add + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + True + Save + True + + + + + True + gtk-save + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + True + gtk-delete + True + + + + + + + + + + + True + _Tools + True + + + + + + + True + _View + True + + + + + + + + True + Fullscreen + True + + + + + + True + gtk-fullscreen + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + + + + + True + _Help + True + + + + + + + True + _About + True + + + + + + + + + + 0 + False + False + + + + + + True + False + 0 + + + + 250 + 400 + True + False + 0 + + + + True + False + 0 + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + False + 0 + + + + + + + + + + + + True + <b>A/C</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + ID of the aircraft (number from 1 to 255) + True + True + True + 3 + + True + * + False + 3 + + + + + + + + True + <b>id</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + False + 0 + + + + True + True + False + + + + + + + 0 + True + True + + + + + + True + Color selector + True + ... + True + GTK_RELIEF_NORMAL + True + + + 0 + False + False + + + + + + + + + + True + <b>GUI color</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + 0 + False + True + + + + + + 1 + True + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_NONE + GTK_CORNER_TOP_LEFT + + + + True + GTK_SHADOW_IN + + + + True + False + 0 + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + False + 2 + + + + True + ________________ + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + True + True + + + + + + True + Browse + True + ... + True + GTK_RELIEF_NORMAL + True + + + 0 + False + False + + + + + + True + Launch the GCS editor or a text editor (gedit or EDITOR env variable if set) + True + gtk-edit + True + GTK_RELIEF_NORMAL + True + + + 0 + False + False + + + + + + + + + + True + <b>Airframe</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + False + True + + + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + False + 0 + + + + True + _________________ + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + True + True + + + + + + True + True + ... + True + GTK_RELIEF_NORMAL + True + + + 0 + False + False + + + + + + True + Launch a text editor (gedit or EDITOR env variable if set) + True + gtk-edit + True + GTK_RELIEF_NORMAL + True + + + 0 + False + False + + + + + + + + + + True + <b>Flight plan</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + False + True + + + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + False + 0 + + + + True + _________________ + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + True + True + + + + + + True + Browse (multiple selection allowed) + True + ... + True + GTK_RELIEF_NORMAL + True + + + 0 + False + False + + + + + + True + Launch an editor on the _first_ settings file + True + gtk-edit + True + GTK_RELIEF_NORMAL + True + + + 0 + False + False + + + + + + + + + + True + <b>Settings</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + False + True + + + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + False + 0 + + + + True + _________________ + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + True + True + + + + + + True + True + ... + True + GTK_RELIEF_NORMAL + True + + + 0 + False + False + + + + + + True + True + gtk-edit + True + GTK_RELIEF_NORMAL + True + + + 0 + False + False + + + + + + + + + + True + <b>Radio</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + False + True + + + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + False + 0 + + + + True + _________________ + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + True + True + + + + + + True + True + ... + True + GTK_RELIEF_NORMAL + True + + + 0 + False + False + + + + + + True + True + gtk-edit + True + GTK_RELIEF_NORMAL + True + + + 0 + False + False + + + + + + + + + + True + <b>Telemetry</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + False + True + + + + + + + + + 0 + True + True + + + + + 0 + False + True + + + + + + True + + + 0 + False + True + + + + + + True + False + 0 + + + + True + False + 3 + + + + 1 + True + True + 0 + + + + True + False + 0 + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + False + 0 + + + + + + + + + + + + True + <b>Target</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + True + Add a target in the combo list + True + GTK_RELIEF_NORMAL + True + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-add + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + New Target + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + 0 + False + False + + + + + 0 + False + False + + + + + + True + True + 0 + + + + True + True + GTK_RELIEF_NORMAL + True + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-clear + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Clean + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + 0 + False + False + + + + + + True + Build the selected target of the selected A/C. Warning: Save is required before this action + True + True + GTK_RELIEF_NORMAL + True + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-convert + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Build + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + 0 + False + False + + + + + + True + False + Upload into the airborne device (which must be plugged !). + True + GTK_RELIEF_NORMAL + True + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-go-up + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Upload + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + 0 + False + False + + + + + 0 + False + False + + + + + 0 + True + True + + + + + + True + + + 0 + False + True + + + + + + 1 + True + True + 0 + + + + True + False + 0 + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 12 + 0 + + + + True + False + 0 + + + + + + + + + + + + True + <b>Session</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + + + + + True + True + gtk-execute + True + GTK_RELIEF_NORMAL + True + + + 0 + False + False + + + + + 0 + False + False + + + + + + True + True + GTK_RELIEF_NORMAL + True + + + + True + 0.5 + 0.5 + 0 + 0 + 0 + 0 + 0 + 0 + + + + True + False + 2 + + + + True + gtk-clear + 4 + 0.5 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + True + Stop/Remove All Processes + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + + + + 0 + False + False + + + + + 0 + True + True + + + + + + True + + + 0 + False + True + + + + + + True + GCS + True + GTK_RELIEF_NORMAL + True + + + 0 + False + False + + + + + 0 + False + True + + + + + + True + False + 0 + + + + + + + 0 + False + True + + + + + + True + True + GTK_POLICY_ALWAYS + GTK_POLICY_ALWAYS + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + True + False + True + GTK_JUSTIFY_LEFT + GTK_WRAP_NONE + True + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + 0 + True + True + + + + + 0 + True + True + + + + + 0 + True + True + + + + + + True + True + + + 0 + False + False + + + + + + diff --git a/sw/supervision/paparazzicenter.ml b/sw/supervision/paparazzicenter.ml index 4c54365b07..dcf2a8aa2e 100644 --- a/sw/supervision/paparazzicenter.ml +++ b/sw/supervision/paparazzicenter.ml @@ -25,15 +25,112 @@ *) open Printf -open Pc_common +module Utils = Pc_common module CP = Pc_control_panel module AC = Pc_aircraft - -let quit_page = 3 (* FIXME *) +let (//) = Filename.concat let fullscreen = ref false + +(*********************** Preferences handling **************************) + +let get_entry_value = fun xml name -> + let e = ExtXml.child ~select:(fun x -> Xml.attrib x "name" = name) xml "entry" in + Xml.attrib e "value" + +let read_preferences = fun file (ac_combo:Utils.combo) (session_combo:Utils.combo) (target_combo:Utils.combo) -> + let xml = Xml.parse_file file in + + (*********** Last A/C *) + begin + try + let ac_name = get_entry_value xml "last A/C" in + Utils.select_in_combo ac_combo ac_name + with Not_found -> () + end; + + (*********** Last session *) + begin + try + let session_name = get_entry_value xml "last session" in + Utils.select_in_combo session_combo session_name + with Not_found -> () + end; + + (*********** Last target *) + begin + try + let name = get_entry_value xml "last target" in + Utils.select_in_combo target_combo name + with Not_found -> () + end + + +let gconf_entry = fun name value -> + Xml.Element ("entry", ["name", name; + "value", value; + "application", "paparazzi center"], + []) + +let add_entry = fun xml name value -> + let entry = gconf_entry name value in + let select = fun x -> Xml.attrib x "name" = name in + let xml = ExtXml.remove_child ~select "entry" xml in + Xml.Element (Xml.tag xml, Xml.attribs xml, entry::Xml.children xml) + + +let write_preferences = fun file (ac_combo:Utils.combo) (session_combo:Utils.combo) (target_combo:Utils.combo) -> + let xml = if Sys.file_exists file then Xml.parse_file file else Xml.Element ("gconf", [], []) in + + (* Save A/C name *) + let xml = + try + let ac_name = Utils.combo_value ac_combo in + add_entry xml "last A/C" ac_name + with Not_found -> xml in + + (* Save session *) + let xml = + let session_name = Utils.combo_value session_combo in + add_entry xml "last session" session_name in + + (* Save target *) + let xml = + let name = Utils.combo_value target_combo in + add_entry xml "last target" name in + + let f = open_out file in + Printf.fprintf f "%s\n" (ExtXml.to_string_fmt xml); + close_out f + +let quit_callback = fun gui ac_combo session_combo target_combo () -> + CP.close_programs gui; + write_preferences Env.gconf_file ac_combo session_combo target_combo; + exit 0 + +let quit_button_callback = fun gui ac_combo session_combo target_combo () -> + if Sys.file_exists Utils.backup_xml_file then begin + let rec question_box = fun () -> + match GToolbox.question_box ~title:"Quit" ~buttons:["Save changes"; "Discard changes"; "View changes"; "Cancel"] ~default:1 "Configuration changes have not been saved" with + | 2 -> + Sys.rename Utils.backup_xml_file Utils.conf_xml_file; + quit_callback gui ac_combo session_combo target_combo () + | 3 -> + ignore (Sys.command (sprintf "tkdiff %s %s" Utils.backup_xml_file Utils.conf_xml_file)); + question_box () + | 1 -> + Sys.remove Utils.backup_xml_file; + quit_callback gui ac_combo session_combo target_combo () + | _ -> () in + question_box () + end else + match GToolbox.question_box ~title:"Quit" ~buttons:["Cancel"; "Quit"] ~default:2 "Quit ?" with + 2 -> quit_callback gui ac_combo session_combo target_combo () + | _ -> () + + let () = Arg.parse ["-fullscreen", Arg.Set fullscreen, "Fullscreen window"] @@ -41,7 +138,7 @@ let () = "Usage: "; let file = Env.paparazzi_src // "sw" // "supervision" // "paparazzicenter.glade" in let gui = new Gtk_pc.window ~file () in - ignore (gui#window#connect#destroy ~callback:(fun _ -> CP.close_programs gui; exit 0)); + if !fullscreen then gui#window#fullscreen (); gui#toplevel#show (); @@ -51,17 +148,26 @@ let () = let s = gui#statusbar#new_context "env" in ignore (s#push (sprintf "HOME=%s SRC=%s" Env.paparazzi_home Env.paparazzi_src)); - let ac_combo = AC.parse_conf_xml gui#vbox_ac - and target_combo = combo ["sim";"fbw";"ap"] gui#vbox_target in + if Sys.file_exists Utils.backup_xml_file then begin + let rec question_box = fun () -> + match GToolbox.question_box ~title:"Backup" ~buttons:["Keep changes"; "Discard changes"; "View changes"] ~default:2 "Configuration changes made during the last session were not saved. ?" with + | 2 -> Sys.rename Utils.backup_xml_file Utils.conf_xml_file + | 3 -> ignore (Sys.command (sprintf "tkdiff %s %s" Utils.backup_xml_file Utils.conf_xml_file)); question_box () + | _ -> Sys.remove Utils.backup_xml_file in + question_box () + end; - (combo_widget target_combo)#misc#set_sensitive false; + Utils.build_aircrafts (); + + let ac_combo = AC.parse_conf_xml gui#vbox_ac + and target_combo = Utils.combo ["sim";"fbw";"ap"] gui#vbox_target in + + (Utils.combo_widget target_combo)#misc#set_sensitive false; gui#button_clean#misc#set_sensitive false; gui#button_build#misc#set_sensitive false; AC.ac_combo_handler gui ac_combo target_combo; - AC.conf_handler gui; - (* Change the buffer of the text view to attach a tag_table *) let background_tags = List.map (fun color -> @@ -70,7 +176,7 @@ let () = (color, tag)) ["red"; "green";"orange"] in let tag_table = GText.tag_table () in - List.iter (fun (color, tag) -> tag_table#add tag#as_tag) background_tags; + List.iter (fun (_color, tag) -> tag_table#add tag#as_tag) background_tags; let buffer = GText.buffer ~tag_table () in gui#console#set_buffer buffer; @@ -94,9 +200,6 @@ let () = | [] -> [] in loop color_regexps in - (* Attach the second console to the buffer of the first one *) - gui#console_cp#set_buffer gui#console#buffer; - let log = fun s -> let iter = gui#console#buffer#end_iter in let tags = compute_tags s in @@ -104,29 +207,28 @@ let () = (* Scroll to the bottom line *) let end_iter = gui#console#buffer#end_iter in let end_mark = gui#console#buffer#create_mark end_iter in - gui#console#scroll_mark_onscreen (`MARK end_mark); - gui#console_cp#scroll_mark_onscreen (`MARK end_mark) in + gui#console#scroll_mark_onscreen (`MARK end_mark) in - AC.build_handler gui ac_combo target_combo log; + AC.build_handler ~file gui ac_combo target_combo log; - CP.supervision ~file gui log; - - (* GCS plugin - Cannot reattach a new window: hack by kill and remake the socket *) - let rec socket = fun () -> - let socket_GCS = GWindow.socket ~packing:gui#vbox_GCS#add () in - CP.socket_GCS_id := socket_GCS#xwindow; - ignore(socket_GCS#connect#plug_removed - (fun () -> gui#vbox_GCS#remove socket_GCS#coerce; socket ())) in - socket (); + let session_combo = CP.supervision ~file gui log ac_combo in (* Quit button *) - let callback = fun num_page -> - if num_page = quit_page then - match GToolbox.question_box ~title:"Quit" ~buttons:["Cancel"; "Quit"] ~default:2 "Quit ?" with - 2 -> exit 0 - | _ ->ignore (GMain.Idle.add (fun () -> gui#notebook#goto_page 0; false)) - in - ignore (gui#notebook#connect#switch_page ~callback); - + ignore (gui#menu_item_quit#connect#activate ~callback:(quit_button_callback gui ac_combo session_combo target_combo)); + + ignore (gui#window#connect#destroy ~callback:(quit_callback gui ac_combo session_combo target_combo)); + + let callback = fun () -> + fullscreen := not !fullscreen; + if !fullscreen then + gui#window#fullscreen () + else + gui#window#unfullscreen () in + ignore (gui#menu_item_fullscreen#connect#activate ~callback); + + (* Read preferences *) + if Sys.file_exists Env.gconf_file then begin + read_preferences Env.gconf_file ac_combo session_combo target_combo + end; + GMain.Main.main ();; diff --git a/sw/supervision/pc_aircraft.ml b/sw/supervision/pc_aircraft.ml index 72065fac65..4925921a24 100644 --- a/sw/supervision/pc_aircraft.ml +++ b/sw/supervision/pc_aircraft.ml @@ -24,9 +24,11 @@ * *) -open Pc_common +module Utils = Pc_common open Printf +let (//) = Filename.concat + let gcs = Env.paparazzi_src // "sw/ground_segment/cockpit/gcs" let string_of_gdkcolor = fun c -> @@ -45,30 +47,34 @@ let aircraft_sample = fun name ac_id -> []) - -let airframes_dir = conf_dir // "airframes" -let flight_plans_dir = conf_dir // "flight_plans" - -let write_conf_xml = fun () -> - Sys.rename conf_xml_file (conf_xml_file^"~"); - let l = Hashtbl.fold (fun _ a r -> a::r) aircrafts [] in +let write_conf_xml = fun ?(user_save = false) () -> + let l = Hashtbl.fold (fun _ a r -> a::r) Utils.aircrafts [] in + let l = List.sort (fun ac1 ac2 -> compare (Xml.attrib ac1 "name") (Xml.attrib ac2 "name")) l in let c = Xml.Element ("conf", [], l) in - let f = open_out conf_xml_file in - output_string f (ExtXml.to_string_fmt ~tab_attribs:true c); - close_out f + if c <> Xml.parse_file Utils.conf_xml_file then begin + if not (Sys.file_exists Utils.backup_xml_file) then + ignore (Sys.command (sprintf "cp %s %s" Utils.conf_xml_file Utils.backup_xml_file)); + let f = open_out Utils.conf_xml_file in + fprintf f "%s\n" (ExtXml.to_string_fmt ~tab_attribs:true c); + close_out f + end; + if user_save && Sys.file_exists Utils.backup_xml_file then begin + let today = Unix.localtime (Unix.gettimeofday ()) in + Sys.rename Utils.backup_xml_file (sprintf "%s.%04d-%02d-%02d_%02d:%02d" Utils.conf_xml_file (1900+today.Unix.tm_year) (today.Unix.tm_mon+1) today.Unix.tm_mday today.Unix.tm_hour today.Unix.tm_min) + end let new_ac_id = fun () -> let m = ref 0 in Hashtbl.iter (fun _ x -> m := max !m (int_of_string (ExtXml.attrib x "ac_id"))) - aircrafts ; + Utils.aircrafts ; !m + 1 let parse_conf_xml = fun vbox -> let strings = ref [] in - Hashtbl.iter (fun name _ac -> strings := name :: !strings) aircrafts; - combo ~others:[""] !strings vbox + Hashtbl.iter (fun name _ac -> strings := name :: !strings) Utils.aircrafts; + Utils.combo ("" :: !strings) vbox let combo_connect = fun ((combo: #GEdit.combo_box), (_,column)) cb -> @@ -80,23 +86,6 @@ let combo_connect = fun ((combo: #GEdit.combo_box), (_,column)) cb -> let data = combo#model#get ~row ~column in cb data)) -let combo_value = fun ((combo: #GEdit.combo_box), (_,column)) -> - match combo#active_iter with - | None -> raise Not_found - | Some row -> combo#model#get ~row ~column - -let is_xml_file = fun s -> - let n = String.length s in - n >= 4 && String.sub s (n-4) 4 = ".xml" - -let combo_dir = fun ?others directory vbox -> - let files = Array.to_list (Sys.readdir directory) in - let xml_files = List.filter is_xml_file files in - combo ?others xml_files vbox - - - - let editor = try Sys.getenv "EDITOR" with _ -> "gedit" @@ -121,8 +110,8 @@ let ac_files = fun gui -> (* Awful but easier *) let current_color = ref "white" -let save_callback = fun gui ac_combo () -> - let ac_name = combo_value ac_combo in +let save_callback = fun ?user_save gui ac_combo () -> + let ac_name = Utils.combo_value ac_combo in if ac_name <> "" then begin let color = !current_color in let aircraft = @@ -136,19 +125,30 @@ let save_callback = fun gui ac_combo () -> "settings", gui#label_settings#text; "gui_color", color], []) in - begin try Hashtbl.remove aircrafts ac_name with _ -> () end; - Hashtbl.add aircrafts ac_name aircraft + if gui#entry_ac_id#text <> "" then begin + begin try Hashtbl.remove Utils.aircrafts ac_name with _ -> () end; + Hashtbl.add Utils.aircrafts ac_name aircraft + end end; - write_conf_xml () - + write_conf_xml ?user_save () + + +let first_word = fun s -> + try + let n = String.index s ' ' in + String.sub s 0 n + with + Not_found -> s + + (* Link A/C to airframe & flight_plan labels *) -let ac_combo_handler = fun gui (ac_combo:combo) target_combo -> +let ac_combo_handler = fun gui (ac_combo:Utils.combo) target_combo -> combo_connect ac_combo (fun ac_name -> try + let aircraft = Hashtbl.find Utils.aircrafts ac_name in let sample = aircraft_sample ac_name "42" in - let aircraft = Hashtbl.find aircrafts ac_name in let value = fun a -> try (ExtXml.attrib aircraft a) with _ -> Xml.attrib sample a in List.iter @@ -161,14 +161,14 @@ let ac_combo_handler = fun gui (ac_combo:combo) target_combo -> gui#eventbox_gui_color#misc#modify_bg [`NORMAL, `NAME gui_color]; current_color := gui_color; gui#entry_ac_id#set_text ac_id; - (combo_widget target_combo)#misc#set_sensitive true; + (Utils.combo_widget target_combo)#misc#set_sensitive true; 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; - (combo_widget target_combo)#misc#set_sensitive false + (Utils.combo_widget target_combo)#misc#set_sensitive false ); (* New A/C button *) @@ -176,35 +176,32 @@ let ac_combo_handler = fun gui (ac_combo:combo) target_combo -> match GToolbox.input_string ~title:"New A/C" ~text:"MYAC" "New A/C name ?" with None -> () | Some s -> - let (store, column) = combo_model ac_combo in - let row = store#append () in - store#set ~row ~column s; + Utils.add_to_combo ac_combo s; let a = aircraft_sample s (string_of_int (new_ac_id ())) in - Hashtbl.add aircrafts s a; - aircrafts_table_has_changed := true; - (combo_widget ac_combo)#set_active_iter (Some row) + Hashtbl.add Utils.aircrafts s a; + Utils.aircrafts_table_has_changed := true in - ignore (gui#button_new_ac#connect#clicked ~callback); + ignore (gui#menu_item_new_ac#connect#activate ~callback); (* Delete A/C *) let callback = fun _ -> - let ac_name = combo_value ac_combo in + let ac_name = Utils.combo_value ac_combo in if ac_name <> "" then match GToolbox.question_box ~title:"Delete A/C" ~buttons:["Cancel"; "Delete"] ~default:2 (sprintf "Delete %s ? (no undo after Save)" ac_name) with 2 -> begin - begin try Hashtbl.remove aircrafts ac_name with _ -> () end; - aircrafts_table_has_changed := true; - let combo_box = combo_widget ac_combo in + begin try Hashtbl.remove Utils.aircrafts ac_name with _ -> () end; + Utils.aircrafts_table_has_changed := true; + let combo_box = Utils.combo_widget ac_combo in match combo_box#active_iter with | None -> () | Some row -> - let (store, column) = combo_model ac_combo in + let (store, _column) = Utils.combo_model ac_combo in ignore (store#remove row); combo_box#set_active 1 end | _ -> () in - ignore (gui#button_delete_ac#connect#clicked ~callback); + ignore (gui#delete_ac_menu_item#connect#activate ~callback); (* GUI color *) let callback = fun _ -> @@ -213,16 +210,38 @@ let ac_combo_handler = fun gui (ac_combo: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 (); 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 ())); + + (* Conf *) + List.iter (fun (name, label, button_browse, button_edit, editor, multiple) -> + let callback = fun _ -> + editor (Utils.conf_dir // label#text) in + ignore (button_edit#connect#clicked ~callback); + let callback = fun _ -> + let subdir = Filename.dirname (first_word label#text) in + let cb = fun selected -> + let names = List.map (fun name -> subdir//name) selected in + let names = String.concat " " names in + label#set_text names; + save_callback gui ac_combo () + in + Utils.choose_xml_file ~multiple name subdir cb in + ignore (button_browse#connect#clicked ~callback)) + (ac_files gui); + + (* Save button *) - ignore(gui#button_save_ac#connect#clicked ~callback:(save_callback gui ac_combo)) + ignore(gui#menu_item_save_ac#connect#activate ~callback:(save_callback ~user_save:true gui ac_combo)) -let build_handler = fun gui ac_combo (target_combo:combo) (log:string->unit) -> +let build_handler = fun ~file gui ac_combo (target_combo:Utils.combo) (log:string->unit) -> (* Link target to upload button *) combo_connect target_combo (fun target -> @@ -233,77 +252,30 @@ let build_handler = fun gui ac_combo (target_combo:combo) (log:string->unit) -> match GToolbox.input_string ~title:"New Target" ~text:"tunnel" "New build target ?" with None -> () | Some s -> - let (store, column) = combo_model target_combo in + let (store, column) = Utils.combo_model target_combo in let row = store#append () in store#set ~row ~column s; - (combo_widget target_combo)#set_active_iter (Some row) + (Utils.combo_widget target_combo)#set_active_iter (Some row) in ignore (gui#button_new_target#connect#clicked ~callback); - let autosave = fun () -> - if gui#button_autosave#active then - save_callback gui ac_combo () in - (* Clean button *) let callback = fun () -> - autosave (); - command log (combo_value ac_combo) "clean_ac" in + Utils.command ~file gui log (Utils.combo_value ac_combo) "clean_ac" in ignore (gui#button_clean#connect#clicked ~callback); (* Build button *) let callback = fun () -> - autosave (); - let ac_name = combo_value ac_combo - and target = combo_value target_combo in + let ac_name = Utils.combo_value ac_combo + and target = Utils.combo_value target_combo in let target = if target="sim" then target else sprintf "%s.compile" target in - command log ac_name target in + Utils.command ~file gui log ac_name target in ignore (gui#button_build#connect#clicked ~callback); (* Upload button *) let callback = fun () -> - autosave (); - let ac_name = combo_value ac_combo - and target = combo_value target_combo in - command log ac_name (sprintf "%s.upload" target) in + let ac_name = Utils.combo_value ac_combo + and target = Utils.combo_value target_combo in + Utils.command ~file gui log ac_name (sprintf "%s.upload" target) in ignore (gui#button_upload#connect#clicked ~callback) -let choose_xml_file = fun ?(multiple = false) title subdir cb -> - let dir = conf_dir // subdir in - let dialog = GWindow.file_chooser_dialog ~action:`OPEN ~title () in - ignore (dialog#set_current_folder dir); - dialog#add_filter (GFile.filter ~name:"xml" ~patterns:["*.xml"] ()); - dialog#add_button_stock `CANCEL `CANCEL ; - dialog#add_select_button_stock `OPEN `OPEN ; - dialog#set_select_multiple multiple; - begin match dialog#run (), dialog#filename with - | `OPEN, _ when multiple -> - let names = dialog#get_filenames in - dialog#destroy (); - cb (List.map Filename.basename names) - | `OPEN, Some name -> - dialog#destroy (); - cb [Filename.basename name] - | _ -> dialog#destroy () - end - -let first_word = fun s -> - try - let n = String.index s ' ' in - String.sub s 0 n - with - Not_found -> s - -let conf_handler = fun gui -> - List.iter (fun (name, label, button_browse, button_edit, editor, multiple) -> - let callback = fun _ -> - editor (conf_dir // label#text) in - ignore (button_edit#connect#clicked ~callback); - let callback = fun _ -> - let subdir = Filename.dirname (first_word label#text) in - let cb = fun selected -> - let names = List.map (fun name -> subdir//name) selected in - let names = String.concat " " names in - label#set_text names in - choose_xml_file ~multiple name subdir cb in - ignore (button_browse#connect#clicked ~callback)) - (ac_files gui) diff --git a/sw/supervision/pc_common.ml b/sw/supervision/pc_common.ml index 5d648bfc16..31eeaab0cf 100644 --- a/sw/supervision/pc_common.ml +++ b/sw/supervision/pc_common.ml @@ -60,26 +60,129 @@ let run_and_log = fun log com -> log (sprintf "\nDONE (%s)\n\n" com); false end in - let _io_watch_out = Glib.Io.add_watch [`IN; `HUP] cb channel_out in - pid, channel_out - -let command = fun (log:string->unit) ac_name target -> - let com = sprintf "export PATH=/usr/bin:$PATH; make -C %s -f Makefile.ac AIRCRAFT=%s %s" Env.paparazzi_src ac_name target in - log com; - ignore (run_and_log log com) + let io_watch_out = Glib.Io.add_watch [`IN; `HUP] cb channel_out in + pid, channel_out, com_stdout, io_watch_out type combo = GEdit.combo_box * (GTree.list_store * string GTree.column) let combo_widget = fst let combo_model = snd +let combo_value = fun ((combo: #GEdit.combo_box), (_,column)) -> + match combo#active_iter with + | None -> raise Not_found + | Some row -> combo#model#get ~row ~column -let combo = fun ?(others = []) strings vbox -> - let strings = others @ strings in +let combo_separator = "--" + +let combo = fun strings vbox -> let (combo, (tree, column)) = GEdit.combo_box_text ~packing:vbox#add ~strings () in combo#set_active 0; + combo#set_row_separator_func + (Some (fun m row -> m#get ~row ~column = combo_separator)) ; (combo, (tree, column)) +let add_to_combo = fun (combo : combo) string -> + let (store, column) = combo_model combo in + let row = store#append () in + store#set ~row ~column string; + (combo_widget combo)#set_active_iter (Some row) + + +let select_in_combo = fun (combo : combo) string -> + let (store, column) = combo_model combo in + store#foreach + (fun _path row -> + if store#get ~row ~column = string then begin + (combo_widget combo)#set_active_iter (Some row); + true + end else + false) + +let choose_xml_file = fun ?(multiple = false) title subdir cb -> + let dir = conf_dir // subdir in + let dialog = GWindow.file_chooser_dialog ~action:`OPEN ~title () in + ignore (dialog#set_current_folder dir); + dialog#add_filter (GFile.filter ~name:"xml" ~patterns:["*.xml"] ()); + dialog#add_button_stock `CANCEL `CANCEL ; + dialog#add_select_button_stock `OPEN `OPEN ; + dialog#set_select_multiple multiple; + begin match dialog#run (), dialog#filename with + | `OPEN, _ when multiple -> + let names = dialog#get_filenames in + dialog#destroy (); + cb (List.map Filename.basename names) + | `OPEN, Some name -> + dialog#destroy (); + cb [Filename.basename name] + | _ -> dialog#destroy () + end + + + + +let run_and_monitor = fun ?(once = false) ?file gui log com_name com args -> + let c = sprintf "%s %s" com args in + let p = new Gtk_process.hbox_program ?file () in + (gui#vbox_programs:GPack.box)#pack p#toplevel#coerce; + p#label_com_name#set_text com_name; + p#entry_program#set_text c; + let pid = ref (-1) + and outchan = ref stdin + and watches = ref [] in + let run = fun callback -> + let c = p#entry_program#text in + log (sprintf "Run '%s'\n" c); + let (pi, out, unixfd, io_watch) = run_and_log log ("exec "^c) in + pid := pi; + outchan := unixfd; + let io_watch' = Glib.Io.add_watch [`HUP] (fun _ -> callback true;false) out in + watches := [ io_watch; io_watch'] in + + let remove_callback = fun () -> + gui#vbox_programs#remove p#toplevel#coerce in + + let rec callback = fun stop -> + match p#button_stop#label, stop with + "gtk-stop", _ -> + List.iter Glib.Io.remove !watches; + close_in !outchan; + ignore (Unix.kill !pid Sys.sigkill); + ignore (Unix.waitpid [] !pid); + p#button_stop#set_label "gtk-redo"; + p#button_remove#misc#set_sensitive true; + if once then + remove_callback () + else if stop && p#checkbutton_autolaunch#active then + callback false + | "gtk-redo", false -> + p#button_stop#set_label "gtk-stop"; + run callback; + p#button_remove#misc#set_sensitive false + | _ -> () + in + ignore (p#button_stop#connect#clicked ~callback:(fun () -> callback false)); + run callback; + + (* Stop the program if the box is closed *) + let callback = fun () -> + callback true in + ignore(p#toplevel#connect#destroy ~callback); + + (* Remove button *) + ignore (p#button_remove#connect#clicked ~callback:remove_callback) + + +let basic_command = fun (log:string->unit) ac_name target -> + let com = sprintf "export PATH=/usr/bin:$PATH; make -C %s -f Makefile.ac AIRCRAFT=%s %s" Env.paparazzi_src ac_name target in + log com; + ignore (run_and_log log com) + + +let command = fun ?file gui (log:string->unit) ac_name target -> + let com = sprintf "make -C %s -f Makefile.ac AIRCRAFT=%s %s" Env.paparazzi_src ac_name target in + run_and_monitor ~once:true ?file gui log "make" com "" + let conf_is_set = fun home -> Sys.file_exists home && @@ -99,7 +202,7 @@ let druid = fun home -> d#append_page fp; ignore (fp#connect#next (fun _ -> - command prerr_endline "" "init"; + basic_command prerr_endline "" "init"; false )) @@ -125,11 +228,15 @@ let _ = druid home let conf_xml_file = conf_dir // "conf.xml" -let conf_xml = Xml.parse_file conf_xml_file +let backup_xml_file = conf_xml_file ^ "~" let aircrafts = Hashtbl.create 7 let aircrafts_table_has_changed = ref false -let _ = +let build_aircrafts = fun () -> + let conf_xml = Xml.parse_file conf_xml_file in List.iter (fun aircraft -> Hashtbl.add aircrafts (ExtXml.attrib aircraft "name") aircraft) (Xml.children conf_xml); aircrafts_table_has_changed := true + + + diff --git a/sw/supervision/pc_control_panel.ml b/sw/supervision/pc_control_panel.ml index 2a58beb3bf..c3cc982f4a 100644 --- a/sw/supervision/pc_control_panel.ml +++ b/sw/supervision/pc_control_panel.ml @@ -1,7 +1,7 @@ (* * $Id$ * - * Paparazzi center process handling + * Paparazzi center processes handling * * Copyright (C) 2007 ENAC, Pascal Brisset, Antoine Drouin * @@ -25,11 +25,11 @@ *) open Printf -open Pc_common +module Utils = Pc_common -let socket_GCS_id = ref (Int32.of_int 0) +let (//) = Filename.concat -let control_panel_xml_file = conf_dir // "control_panel.xml" +let control_panel_xml_file = Utils.conf_dir // "control_panel.xml" let control_panel_xml = Xml.parse_file control_panel_xml_file let programs = let h = Hashtbl.create 7 in @@ -67,50 +67,9 @@ let write_control_panel_xml = fun () -> output_string f (ExtXml.to_string_fmt ~tab_attribs:false c); close_out f -let run_and_monitor = fun ?file ?(plugged=false) gui log com_name args -> - let com = program_command com_name in - let c = sprintf "%s %s" com args in - let p = new Gtk_process.hbox_program ?file () in - (gui#vbox_programs:GPack.box)#pack p#toplevel#coerce; - p#label_com_name#set_text com_name; - p#entry_program#set_text c; - let pid = ref (-1) in - let run = fun callback -> - let c = p#entry_program#text in - let c = if plugged then sprintf "%s -wid 0x%lx" c !socket_GCS_id else c in - if plugged then - gui#notebook#goto_page 2; (* FIXME *) - log (sprintf "Run '%s'\n" c); - let (pi, out) = run_and_log log ("exec "^c) in - pid := pi; - ignore (Glib.Io.add_watch [`HUP] (fun _ -> callback true; false) out) in - let rec callback = fun stop -> - match p#button_stop#label, stop with - "gtk-stop", _ -> - ignore (Unix.kill !pid Sys.sigkill); - p#button_stop#set_label "gtk-redo"; - p#button_remove#misc#set_sensitive true; - if stop && p#checkbutton_autolaunch#active then - callback false - | "gtk-redo", false -> - p#button_stop#set_label "gtk-stop"; - run callback; - p#button_remove#misc#set_sensitive false - | _ -> () - in - ignore (p#button_stop#connect#clicked ~callback:(fun () -> callback false)); - run callback; - - (* Stop the program if the box is removed *) - let callback = fun w -> - callback true in - ignore(p#toplevel#connect#destroy ~callback); - - (* Remove button *) - let callback = fun () -> - gui#vbox_programs#remove p#toplevel#coerce in - ignore (p#button_remove#connect#clicked ~callback) +let run_and_monitor = fun ?file gui log com_name args -> + Utils.run_and_monitor ?file gui log com_name (program_command com_name) args let close_programs = fun gui -> List.iter (fun w -> @@ -154,12 +113,12 @@ let parse_process_args = fun (name, args) -> Xml.Element("arg", ["flag",option],[])::xml_args l in Xml.Element("program", ["name", name], xml_args args) -let save_session = fun gui -> +let save_session = fun gui session_combo -> (* Ask for a session name *) - let text = gui#entry_session_name#text in + let text = Utils.combo_value session_combo in let text = if text = "" then "My session" else text in match GToolbox.input_string ~ok:"Save" ~text ~title:"Session name" "Save custom session ?" with - None -> false + None -> "" | Some name -> let current_processes = List.map (fun hbox -> @@ -176,7 +135,7 @@ let save_session = fun gui -> begin try Hashtbl.remove sessions name with _ -> () end; Hashtbl.add sessions name session; write_control_panel_xml (); - true + name let double_quote = fun s -> if String.contains s ' ' then @@ -184,30 +143,72 @@ let double_quote = fun s -> else s - -let supervision = fun ?file gui log -> - let supervision_page = 1 in (* FIXME *) - +let supervision = fun ?file gui log (ac_combo : Utils.combo) -> let run_gcs = fun () -> - run_and_monitor ?file ~plugged:true gui log "GCS" "" + run_and_monitor ?file gui log "GCS" "" and run_server = fun args -> run_and_monitor ?file gui log "Server" args - and run_link = fun args -> - run_and_monitor ?file gui log "Data Link" args and run_sitl = fun ac_name -> let args = sprintf "-a %s -boot -norc" ac_name in run_and_monitor ?file gui log "Simulator" args in - (* Replay menu *) - let callback = fun () -> - gui#entry_session_name#set_text "Replay"; + (* Sessions *) + let session_combo = Utils.combo [] gui#vbox_session in + + let remove_custom_sessions = fun () -> + let (store, _column) = Utils.combo_model session_combo in + store#clear () + in + + let register_custom_sessions = fun () -> + remove_custom_sessions (); + Utils.add_to_combo session_combo "Simulation"; + Utils.add_to_combo session_combo "Replay"; + Utils.add_to_combo session_combo Utils.combo_separator; + Hashtbl.iter + (fun name _session -> + Utils.add_to_combo session_combo name) + sessions in + + register_custom_sessions (); + + let execute_custom = fun session_name -> + let session = Hashtbl.find sessions session_name in + List.iter + (fun program -> + let name = ExtXml.attrib program "name" in + let p = ref "" in + List.iter + (fun arg -> + let constant = + try double_quote (Xml.attrib arg "constant") with _ -> "" in + p := sprintf "%s %s %s" !p (ExtXml.attrib arg "flag") constant) + (Xml.children program); + run_and_monitor ?file gui log name !p) + (Xml.children session) + in + + (* Replay session *) + let replay = fun () -> run_and_monitor ?file gui log "Log File Player" ""; run_server "-n"; - run_gcs () - in - ignore (gui#replay_menu_item#connect#activate ~callback); + run_gcs () in + + (* Simulations *) + let simulation = fun () -> + run_gcs (); + run_server "-n"; + run_sitl (Utils.combo_value ac_combo) in + (* Run session *) + let callback = fun () -> + match Utils.combo_value session_combo with + "Simulation" -> simulation () + | "Replay" -> replay () + | custom -> execute_custom custom in + ignore (gui#button_execute#connect#clicked ~callback); + (* Close session *) let callback = fun () -> close_programs gui in @@ -216,7 +217,7 @@ let supervision = fun ?file gui log -> (* Tools *) let entries = ref [] in Hashtbl.iter - (fun name prog -> + (fun name _prog -> let cb = fun () -> run_and_monitor ?file gui log name "" in entries := `I (name, cb) :: !entries) @@ -230,92 +231,37 @@ let supervision = fun ?file gui log -> GToolbox.build_menu menu sorted_entries; gui#programs_menu_item#set_submenu menu; - (* Simulations *) - let insert_sims_in_menu = fun num_page -> - if num_page = supervision_page && !aircrafts_table_has_changed then - let entries = ref [] in - Hashtbl.iter - (fun ac_name ac -> - let cb = fun () -> - gui#entry_session_name#set_text (sprintf "Simulator %s" ac_name); - run_gcs (); - run_server "-n"; - run_sitl ac_name - in - entries := `I (ac_name, cb) :: !entries) - aircrafts; - let menu = GMenu.menu () - and sorted_entries = List.sort compare !entries in - GToolbox.build_menu menu sorted_entries; - gui#sim_menu_item#set_submenu menu; - aircrafts_table_has_changed := false in - - ignore (gui#notebook#connect#switch_page ~callback:insert_sims_in_menu); - - (* Sessions *) - let insert_sessions_in_menu = fun () -> - let entries = ref [] in - let cb = fun name session () -> - gui#entry_session_name#set_text name; - List.iter - (fun program -> - let name = ExtXml.attrib program "name" in - let p = ref "" in - List.iter - (fun arg -> - let constant = - try double_quote (Xml.attrib arg "constant") with _ -> "" in - p := sprintf "%s %s %s" !p (ExtXml.attrib arg "flag") constant) - (Xml.children program); - run_and_monitor ~plugged:(name="gcs") ?file gui log name !p) - (Xml.children session) - in - Hashtbl.iter - (fun name session -> - entries := `I (name, cb name session) :: !entries) - sessions; - let menu = GMenu.menu () - and sorted_entries = List.sort compare !entries in - GToolbox.build_menu menu sorted_entries; - gui#session_menu_item#set_submenu menu in - - insert_sessions_in_menu (); - - (* Add new session *) + (* New session *) let callback = fun () -> - if save_session gui then - insert_sessions_in_menu () in - ignore (gui#button_save_session#connect#clicked ~callback); + match GToolbox.input_string ~title:"New session" ~text:"My session" "New session name ?" with + None -> () + | Some s -> + Utils.add_to_combo session_combo s in + ignore (gui#menu_item_new_session#connect#activate ~callback); + + (* Save new session *) + let callback = fun () -> + match save_session gui session_combo with + "" -> () + | session_name -> + register_custom_sessions (); + Utils.select_in_combo session_combo session_name + in + ignore (gui#menu_item_save_session#connect#activate ~callback); (* Remove current session *) let callback = fun () -> - let session_name = gui#entry_session_name#text in + let session_name = Utils.combo_value session_combo in match GToolbox.question_box ~title:"Delete custom session" ~buttons:["Cancel"; "Delete"] ~default:2 (sprintf "Delete '%s' custom session ? (NO undo)" session_name) with 2 -> if Hashtbl.mem sessions session_name then begin Hashtbl.remove sessions session_name; write_control_panel_xml (); - insert_sessions_in_menu () + register_custom_sessions () end; - close_programs gui; - gui#entry_session_name#set_text "" + close_programs gui | _ -> () in - ignore (gui#button_delete_session#connect#clicked ~callback); - - (* Flights *) - let cb = fun name args () -> - gui#entry_session_name#set_text (sprintf "Flight: %s" name); - run_gcs (); - run_server ""; - run_link args - in - let entries = - [`I ("Maxstream", cb "Maxstream" "-transport xbee -uplink"); - `I ("Aerocomm", cb "Aerocomm" "-s 57600 -aerocomm -uplink"); - `I ("Serial", cb "Serial" "-uplink")] in - let menu = GMenu.menu () - and sorted_entries = List.sort compare entries in - GToolbox.build_menu menu sorted_entries; - gui#fly_menu_item#set_submenu menu + ignore (gui#menu_item_delete_session#connect#activate ~callback); + session_combo