From 300160e73da486946ae513f1d039dcd7b85ff17c Mon Sep 17 00:00:00 2001 From: Jose Antonio Ortega Ruiz Date: Mon, 20 Mar 2006 22:46:46 +0000 Subject: Version 1.2.1 imported git-archimport-id: mdk@sv.gnu.org/mdk--devel--1--patch-1 --- mixgtk/mixgtk_wm.c | 573 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 573 insertions(+) create mode 100644 mixgtk/mixgtk_wm.c (limited to 'mixgtk/mixgtk_wm.c') diff --git a/mixgtk/mixgtk_wm.c b/mixgtk/mixgtk_wm.c new file mode 100644 index 0000000..7821d0e --- /dev/null +++ b/mixgtk/mixgtk_wm.c @@ -0,0 +1,573 @@ +/* -*-c-*- -------------- mixgtk_wm.c : + * Implementation of the functions declared in mixgtk_wm.h + * ------------------------------------------------------------------ + * $Id: mixgtk_wm.c,v 1.12 2005/09/20 19:43:14 jao Exp $ + * ------------------------------------------------------------------ + * Copyright (C) 2001, 2002, 2004 Free Software Foundation, 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. + * + */ + +#include + +#include "mixgtk_wm.h" + +#include "mixgtk_widgets.h" +#include "mixgtk_config.h" +#include "mixgtk_device.h" +#include "mixgtk_mixvm.h" +#include "mixgtk_mixal.h" +#include "mixgtk_widgets.h" +#include "mixgtk_cmd_dispatcher.h" +#include "mixgtk.h" + + +typedef struct window_info_t_ +{ + mixgtk_dialog_id_t dialog; + GtkWidget *widget; + GtkCheckMenuItem *menu; + const gchar *menu_name; + const gchar *config_key; + gboolean detached; + void (*detach) (void); + void (*attach) (void); +} window_info_t_; + +static const gchar *DETACH_YES_ = "Yes"; +static const gchar *DETACH_NO_ = "No"; +static GtkWidget *about_ = NULL; + +static GtkContainer *mixvm_container_ = NULL; +static GtkContainer *mixal_container_ = NULL; +static GtkContainer *dev_container_ = NULL; + +static const gchar *TB_MENU_NAME_ = "show_toolbars"; +static GtkCheckMenuItem *tb_menu_ = NULL; +static GtkNotebook *notebook_ = NULL; + +static mix_vm_t *vm_ = NULL; + +static void init_info_ (void); +static void init_notebook_ (void); +static void init_dispatcher_ (void); +static void init_mixvm_ (void); +static void init_mixal_ (void); +static void init_dev_ (void); +static void init_signals_ (void); +static void init_visibility_ (void); +static void init_tb_ (void); +static void init_about_ (void); +static void init_autosave_ (void); +static void show_toolbars_ (gboolean show); +static void add_page_ (GtkWidget *w, mixgtk_window_id_t id); +static void mixvm_attach_ (void); +static void mixvm_detach_ (void); +static void mixal_attach_ (void); +static void mixal_detach_ (void); +static void dev_attach_ (void); +static void dev_detach_ (void); +static void on_nb_switch_ (GtkNotebook *notebook, GtkWidget *page, + guint page_num, gpointer user_data); + +static window_info_t_ infos_[] = { + {MIXGTK_MIXVM_DIALOG, NULL, NULL, "detach_vm", "MIX.detach", + FALSE, mixvm_detach_, mixvm_attach_}, + {MIXGTK_MIXAL_DIALOG, NULL, NULL, "detach_source", "MIXAL.detach", + FALSE, mixal_detach_, mixal_attach_}, + {MIXGTK_DEVICES_DIALOG, NULL, NULL, "detach_dev", "Devices.detach", + FALSE, dev_detach_, dev_attach_} +}; + +static size_t INF_NO_ = sizeof (infos_) / sizeof (infos_[0]); + + +gboolean +mixgtk_wm_init (void) +{ + gint k; + + init_info_ (); + init_notebook_ (); + init_dispatcher_ (); + init_mixvm_ (); + init_mixal_ (); + init_dev_ (); + + for (k = 0; k < INF_NO_; ++k) + { + if (infos_[k].detached) + mixgtk_wm_detach_window (k); + else + mixgtk_wm_attach_window (k); + } + + init_tb_ (); + init_about_ (); + init_autosave_ (); + init_visibility_ (); + init_signals_ (); + + return TRUE; +} + +void +mixgtk_wm_detach_window (mixgtk_window_id_t w) +{ + if (w < INF_NO_) + { + (*(infos_[w].detach)) (); + infos_[w].detached = TRUE; + gtk_check_menu_item_set_active (infos_[w].menu, TRUE); + mixgtk_config_update (infos_[w].config_key, DETACH_YES_); + if (infos_[w].widget != NULL) gtk_widget_show (infos_[w].widget); + if (gtk_notebook_get_n_pages (notebook_) < 1) + gtk_widget_hide (GTK_WIDGET (notebook_)); + gtk_widget_show (mixgtk_widget_factory_get_dialog (infos_[w].dialog)); + } +} + +void +mixgtk_wm_attach_window (mixgtk_window_id_t w) +{ + if (w < INF_NO_) + { + gint page = gtk_notebook_page_num (notebook_, infos_[w].widget); + + gtk_widget_hide (mixgtk_widget_factory_get_dialog (infos_[w].dialog)); + + if (page < 0) (*(infos_[w].attach)) (); + + infos_[w].detached = FALSE; + gtk_check_menu_item_set_active (infos_[w].menu, FALSE); + mixgtk_config_update (infos_[w].config_key, DETACH_NO_); + if (gtk_notebook_get_n_pages (notebook_) == 1) + gtk_widget_show (GTK_WIDGET (notebook_)); + } +} + + + +/* callbacks */ +void +on_detach_clicked (GtkWidget *ignored) +{ + gint page = gtk_notebook_get_current_page (notebook_); + if (page >= 0) + { + gint k; + GtkWidget *w = gtk_notebook_get_nth_page (notebook_, page); + + for (k = 0; k < INF_NO_; ++k) + if (infos_[k].widget == w) mixgtk_wm_detach_window (k); + } +} + +void +on_attach_all_clicked () +{ + gint k; + for (k = INF_NO_; k > 0; --k) + if (infos_[k - 1].detached) mixgtk_wm_attach_window (k - 1); +} + +void +on_attach_toggled (GtkCheckMenuItem *item) +{ + gint k; + for (k = 0; k < INF_NO_; ++k) + if (item == infos_[k].menu) break; + g_return_if_fail (k < INF_NO_); + if (item->active) mixgtk_wm_detach_window (k); + else mixgtk_wm_attach_window (k); + mixgtk_config_update (infos_[k].config_key, + (item->active)? DETACH_YES_ : DETACH_NO_); +} + +void +on_window_hide (GtkWidget *w) +{ + gint k; + for (k = 0; k < INF_NO_; ++k) + if (w == mixgtk_widget_factory_get_dialog (infos_[k].dialog)) break; + g_return_if_fail (k < INF_NO_); + mixgtk_wm_attach_window (k); +} + +void +on_show_toolbars_toggled (GtkCheckMenuItem *item) +{ + if (item->active != mixgtk_config_show_toolbars ()) + show_toolbars_ (item->active); +} + +void +on_widget_attach (GtkWidget *ign, gpointer id) +{ + mixgtk_wm_attach_window (GPOINTER_TO_INT (id)); +} + + +/* about box */ +void +on_about_activate (GtkWidget *w, gpointer data) +{ + if (!about_) init_about_ (); + gtk_widget_show (about_); +} + + +static void +init_info_ (void) +{ + gint k; + for (k = 0; k < INF_NO_; ++k) + { + const gchar *txt; + + infos_[k].menu = + GTK_CHECK_MENU_ITEM + (mixgtk_widget_factory_get_child_by_name (MIXGTK_MAIN, + infos_[k].menu_name)); + g_assert (infos_[k].menu != NULL); + txt = mixgtk_config_get (infos_[k].config_key); + infos_[k].detached = txt && !g_ascii_strcasecmp (txt, DETACH_YES_); + } +} + +static void +init_notebook_ (void) +{ + notebook_ = + GTK_NOTEBOOK (mixgtk_widget_factory_get (MIXGTK_MAIN, + MIXGTK_WIDGET_NOTEBOOK)); + g_assert (notebook_ != NULL); + gtk_widget_show (GTK_WIDGET (notebook_)); +} + +static void +add_page_ (GtkWidget *page, mixgtk_window_id_t id) +{ + static const gchar *LABELS[] = { + N_("_Virtual machine"), N_("_Source"), N_("_Devices") + }; + + gint p = 0; + + g_assert (page != NULL); + g_assert (id < INF_NO_); + g_assert (notebook_ != NULL); + + if (id > MIXGTK_MIXVM_WINDOW) + { + if (id == MIXGTK_DEVICES_WINDOW) + p = gtk_notebook_get_n_pages (notebook_); + else + p = infos_[MIXGTK_MIXVM_WINDOW].detached ? 0 : 1; + } + + gtk_notebook_insert_page (notebook_, page, + gtk_label_new_with_mnemonic (LABELS[id]), + p); + gtk_notebook_set_current_page (notebook_, p); + gtk_widget_show (page); + gtk_widget_show (GTK_WIDGET (notebook_)); +} + +static void +init_signals_ (void) +{ + gint k; + for (k = 0; k < INF_NO_; ++k) + { + GObject *dialog = + G_OBJECT (mixgtk_widget_factory_get_dialog (infos_[k].dialog)); + + GObject *button = + G_OBJECT (mixgtk_widget_factory_get (infos_[k].dialog, + MIXGTK_WIDGET_ATTACH_BUTTON)); + + g_assert (dialog != NULL); + g_assert (button != NULL); + + g_signal_connect (button, "clicked", + G_CALLBACK (on_widget_attach), GINT_TO_POINTER (k)); + g_signal_connect (dialog, "destroy", + G_CALLBACK (on_window_hide), NULL); + g_signal_connect (dialog, "destroy_event", + G_CALLBACK (on_window_hide), NULL); + g_signal_connect (dialog, "delete_event", + G_CALLBACK (on_window_hide), NULL); + g_signal_connect (G_OBJECT (infos_[k].menu), "toggled", + G_CALLBACK (on_attach_toggled), NULL); + } + +} + +static void +init_visibility_ (void) +{ + gint k; + for (k = 0; k < INF_NO_; ++k) + if (infos_[k].detached) + gtk_widget_show (mixgtk_widget_factory_get_dialog (infos_[k].dialog)); + + if (gtk_notebook_get_n_pages (notebook_) > 0) + gtk_notebook_set_current_page (notebook_, 0); + + gtk_widget_show (mixgtk_widget_factory_get_dialog (MIXGTK_MAIN)); +} + +static void +init_dispatcher_ (void) +{ + if (!mixgtk_cmd_dispatcher_init (MIXGTK_MAIN)) + g_assert (FALSE); + vm_ = mixgtk_cmd_dispatcher_get_vm (); + g_assert (vm_ != NULL); +} + +static void +init_mixvm_ (void) +{ + GtkContainer *vm = + GTK_CONTAINER + (mixgtk_widget_factory_get (MIXGTK_MIXVM_DIALOG, MIXGTK_WIDGET_MIXVM)); + + mixvm_container_ = + GTK_CONTAINER (mixgtk_widget_factory_get (MIXGTK_MIXVM_DIALOG, + MIXGTK_WIDGET_MIXVM_CONTAINER)); + + g_assert (mixvm_container_ != NULL); + + g_assert (vm != NULL); + g_object_ref (G_OBJECT (vm)); + infos_[MIXGTK_MIXVM_WINDOW].widget = GTK_WIDGET (vm); + + mixgtk_mixvm_init (vm_); + mixgtk_mixvm_update_vm_widgets (); + + gtk_widget_show (GTK_WIDGET (vm)); + +} + +static void +init_mixal_ (void) +{ + GtkWidget *page = gtk_scrolled_window_new (NULL, NULL); + GtkWidget *mixal = mixgtk_mixal_init (vm_); + + g_assert (page != NULL); + g_assert (mixal != NULL); + + g_object_ref (page); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (page), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + + gtk_container_add (GTK_CONTAINER (page), mixal); + + infos_[MIXGTK_MIXAL_WINDOW].widget = page; + + mixal_container_ = + GTK_CONTAINER (mixgtk_widget_factory_get (MIXGTK_MIXAL_DIALOG, + MIXGTK_WIDGET_MIXAL_CONTAINER)); + + g_assert (mixal_container_ != NULL); + + gtk_container_add (mixal_container_, page); + + gtk_widget_show (mixal); + gtk_widget_show (page); + gtk_widget_show (GTK_WIDGET (mixal_container_)); +} + +static void +init_dev_ (void) +{ + GtkWidget *page = gtk_scrolled_window_new (NULL, NULL); + GtkWidget *devs = mixgtk_device_init (vm_); + + g_assert (page != NULL); + g_assert (devs != NULL); + + g_object_ref (page); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (page), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + + gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (page), devs); + + infos_[MIXGTK_DEVICES_WINDOW].widget = page; + + dev_container_ = + GTK_CONTAINER (mixgtk_widget_factory_get (MIXGTK_DEVICES_DIALOG, + MIXGTK_WIDGET_DEV_CONTAINER)); + + g_assert (dev_container_ != NULL); + + gtk_container_add (dev_container_, page); + + gtk_widget_show (devs); + gtk_widget_show (page); +} + +static void +init_tb_ (void) +{ + tb_menu_ = GTK_CHECK_MENU_ITEM + (mixgtk_widget_factory_get_child_by_name (MIXGTK_MAIN, + TB_MENU_NAME_)); + g_assert (tb_menu_ != NULL); + + gtk_check_menu_item_set_active (tb_menu_, mixgtk_config_show_toolbars ()); + show_toolbars_ (mixgtk_config_show_toolbars ()); + + g_signal_connect (G_OBJECT (tb_menu_), "toggled", + G_CALLBACK (on_show_toolbars_toggled), NULL); +} + +static void +show_toolbars_ (gboolean show) +{ + static const gchar *HANDLE_NAME = "tb_handle"; + + int k; + + GtkWidget *handle = + mixgtk_widget_factory_get_child_by_name (MIXGTK_MAIN, HANDLE_NAME); + + if (show) + gtk_widget_show (handle); + else + gtk_widget_hide (handle); + + for (k = 0; k < INF_NO_; ++k) + { + GtkWidget *hd = + mixgtk_widget_factory_get_child_by_name (infos_[k].dialog, HANDLE_NAME); + if (show) gtk_widget_show (hd); else gtk_widget_hide (hd); + } + + mixgtk_config_set_show_toolbars (show); +} + +static void +init_autosave_ (void) +{ +#define AUTOSAVE_ITEM_ "save_on_exit" + + GtkCheckMenuItem *item = GTK_CHECK_MENU_ITEM + (mixgtk_widget_factory_get_child_by_name (MIXGTK_MAIN, AUTOSAVE_ITEM_)); + if (item) + { + gtk_check_menu_item_set_active (item, mixgtk_config_is_autosave ()); + } +} + +static void +init_about_ (void) +{ +#define VERSION_LABEL_ "version_label" +#define GPL_TEXT_ "gpl_text" + GtkWidget *label; + about_ = mixgtk_widget_factory_get_dialog (MIXGTK_ABOUT_DIALOG); + g_assert (about_ != NULL); + label = mixgtk_widget_factory_get_child_by_name (MIXGTK_ABOUT_DIALOG, + VERSION_LABEL_); + g_assert (label != NULL); + gtk_label_set_text (GTK_LABEL (label), VERSION); + gtk_widget_show (label); +} + +static void +mixvm_attach_ (void) +{ + gtk_container_remove (mixvm_container_, infos_[MIXGTK_MIXVM_WINDOW].widget); + add_page_ (infos_[MIXGTK_MIXVM_WINDOW].widget, MIXGTK_MIXVM_WINDOW); +} + +static void +mixvm_detach_ (void) +{ + gtk_widget_reparent (infos_[MIXGTK_MIXVM_WINDOW].widget, + GTK_WIDGET (mixvm_container_)); +} + +static void +mixal_attach_ (void) +{ + static GtkStatusbar *stat = NULL; + + if (stat == NULL) + { + stat = + GTK_STATUSBAR + (mixgtk_widget_factory_get (MIXGTK_MAIN, MIXGTK_WIDGET_STATUSBAR)); + g_assert (stat); + + g_signal_connect (G_OBJECT (notebook_), "switch-page", + G_CALLBACK (on_nb_switch_), NULL); + } + + mixgtk_mixal_reparent (stat); + gtk_container_remove (mixal_container_, infos_[MIXGTK_MIXAL_WINDOW].widget); + add_page_ (infos_[MIXGTK_MIXAL_WINDOW].widget, MIXGTK_MIXAL_WINDOW); +} + +static void +mixal_detach_ (void) +{ + static GtkStatusbar *stat = NULL; + + if (stat == NULL) + { + stat = + GTK_STATUSBAR + (mixgtk_widget_factory_get (MIXGTK_MIXAL_DIALOG, + MIXGTK_WIDGET_MIXAL_STATUSBAR)); + g_assert (stat); + } + + mixgtk_mixal_reparent (stat); + gtk_widget_reparent (infos_[MIXGTK_MIXAL_WINDOW].widget, + GTK_WIDGET (mixal_container_)); +} + +static void +dev_attach_ (void) +{ + gtk_container_remove (dev_container_, infos_[MIXGTK_DEVICES_WINDOW].widget); + add_page_ (infos_[MIXGTK_DEVICES_WINDOW].widget, MIXGTK_DEVICES_WINDOW); +} + +static void +dev_detach_ (void) +{ + gtk_widget_reparent (infos_[MIXGTK_DEVICES_WINDOW].widget, + GTK_WIDGET (dev_container_)); +} + +static void +on_nb_switch_ (GtkNotebook *notebook, GtkWidget *page, + guint page_num, gpointer user_data) +{ + if (!(infos_[MIXGTK_MIXAL_WINDOW].detached) + && (page != infos_[MIXGTK_MIXAL_WINDOW].widget)) + mixgtk_mixal_pop_status (); +} + + -- cgit v1.2.3