diff options
author | Ulf Lamping <ulf.lamping@web.de> | 2004-05-23 17:37:36 +0000 |
---|---|---|
committer | Ulf Lamping <ulf.lamping@web.de> | 2004-05-23 17:37:36 +0000 |
commit | 01c236864ac165449462e9d197efee3e47fde43e (patch) | |
tree | 86264de02e07c71a7d27de5313ec8c5f6f09d361 /gtk | |
parent | 461c0d59cd323ef1c437e49503b76a99bcc2279f (diff) | |
download | wireshark-01c236864ac165449462e9d197efee3e47fde43e.tar.gz wireshark-01c236864ac165449462e9d197efee3e47fde43e.tar.bz2 wireshark-01c236864ac165449462e9d197efee3e47fde43e.zip |
next step to save the size and postition of the dialogs (using a hashtable)
move the get/set window size functionality from main to ui_util,
add some functions to handle windows/dialogs.
changed help and about dialog to suit the current window API
svn path=/trunk/; revision=10974
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/about_dlg.c | 25 | ||||
-rw-r--r-- | gtk/dlg_utils.c | 33 | ||||
-rw-r--r-- | gtk/dlg_utils.h | 11 | ||||
-rw-r--r-- | gtk/help_dlg.c | 36 | ||||
-rw-r--r-- | gtk/main.c | 89 | ||||
-rw-r--r-- | gtk/ui_util.c | 285 | ||||
-rw-r--r-- | gtk/ui_util.h | 92 |
7 files changed, 412 insertions, 159 deletions
diff --git a/gtk/about_dlg.c b/gtk/about_dlg.c index 15f308f93a..365e8ae757 100644 --- a/gtk/about_dlg.c +++ b/gtk/about_dlg.c @@ -1,6 +1,6 @@ /* about_dlg.c * - * $Id: about_dlg.c,v 1.10 2004/05/22 07:32:11 guy Exp $ + * $Id: about_dlg.c,v 1.11 2004/05/23 17:37:36 ulfl Exp $ * * Ulf Lamping <ulf.lamping@web.de> * @@ -228,7 +228,16 @@ about_ethereal_cb( GtkWidget *w _U_, gpointer data _U_ ) * not? (The GNOME 1.x GnomeAbout widget uses GnomeDialog.) */ about_ethereal_w = dlg_window_new("About Ethereal"); - SIGNAL_CONNECT(about_ethereal_w, "destroy", about_ethereal_destroy_cb, NULL); + /* set the initial position (must be done, before show is called!) */ + /* default position is not appropriate for the about dialog */ +#if GTK_MAJOR_VERSION >= 2 + gtk_window_set_position(GTK_WINDOW(about_ethereal_w), GTK_WIN_POS_CENTER_ON_PARENT); +#else + gtk_window_set_position(GTK_WINDOW(about_ethereal_w), GTK_WIN_POS_CENTER); +#endif + /* setting the size is dangerous here, as making it too short will + * clip content on GTK1, so simply use the natural size */ + /*gtk_window_set_default_size(GTK_WINDOW(about_ethereal_w), 600, 400);*/ gtk_container_border_width(GTK_CONTAINER(about_ethereal_w), 6); main_vb = gtk_vbox_new(FALSE, 12); @@ -249,7 +258,6 @@ about_ethereal_cb( GtkWidget *w _U_, gpointer data _U_ ) #endif folders_page = about_folders_page_new(); - WIDGET_SET_SIZE(folders_page, 500, 200); page_lb = gtk_label_new("Folders"); gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), folders_page, page_lb); @@ -264,16 +272,13 @@ about_ethereal_cb( GtkWidget *w _U_, gpointer data _U_ ) gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0); ok_btn = OBJECT_GET_DATA(bbox, GTK_STOCK_OK); - SIGNAL_CONNECT_OBJECT(ok_btn, "clicked", gtk_widget_destroy, - about_ethereal_w); - gtk_widget_grab_default(ok_btn); + window_set_cancel_button(about_ethereal_w, ok_btn, window_cancel_button_cb); - /* Catch the "key_press_event" signal in the window, so that we can catch - the ESC key being pressed and act as if the "Cancel" button had - been selected. */ - dlg_set_cancel(about_ethereal_w, ok_btn); + SIGNAL_CONNECT(about_ethereal_w, "delete_event", window_delete_event_cb, NULL); + SIGNAL_CONNECT(about_ethereal_w, "destroy", about_ethereal_destroy_cb, NULL); gtk_widget_show_all(about_ethereal_w); + window_present(about_ethereal_w); } static void diff --git a/gtk/dlg_utils.c b/gtk/dlg_utils.c index 105a954f33..c1f766c92a 100644 --- a/gtk/dlg_utils.c +++ b/gtk/dlg_utils.c @@ -1,7 +1,7 @@ /* dlg_utils.c * Utilities to use when constructing dialogs * - * $Id: dlg_utils.c,v 1.31 2004/05/22 19:56:18 ulfl Exp $ + * $Id: dlg_utils.c,v 1.32 2004/05/23 17:37:36 ulfl Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -287,7 +287,7 @@ dlg_button_row_new(gchar *stock_id_first, ...) /* this is called, when a dialog was closed */ -void on_dialog_destroyed(GtkWidget *dialog _U_, gpointer data _U_) +void dlg_destroy_cb(GtkWidget *dialog, gpointer data) { #if GTK_MAJOR_VERSION >= 2 if(top_level) { @@ -296,9 +296,6 @@ void on_dialog_destroyed(GtkWidget *dialog _U_, gpointer data _U_) gtk_window_present(GTK_WINDOW(top_level)); } #endif - - /* XXX - saved the size of this dialog */ - /* currently unclear, how the dialogs should be identified */ } @@ -313,6 +310,7 @@ dlg_window_new(const gchar *title) #else win = window_new(GTK_WINDOW_TOPLEVEL, title); #endif + /* * XXX - if we're running in the capture child process, we can't easily * make this window transient for the main process's window. We just @@ -331,34 +329,11 @@ dlg_window_new(const gchar *title) gtk_window_set_transient_for(GTK_WINDOW(win), GTK_WINDOW(top_level)); } - SIGNAL_CONNECT(win, "destroy", on_dialog_destroyed, win); + SIGNAL_CONNECT(win, "destroy", dlg_destroy_cb, NULL); return win; } -void -dlg_window_present(GtkWidget *win, GtkWindowPosition pos) -{ - - /* to stay compatible with GTK1.x, only these three pos values are allowed */ - g_assert( - pos == GTK_WIN_POS_NONE || - pos == GTK_WIN_POS_CENTER || - pos == GTK_WIN_POS_MOUSE); /* preferred for most dialogs */ - -#if GTK_MAJOR_VERSION >= 2 - gtk_window_present(GTK_WINDOW(win)); - - if(pos == GTK_WIN_POS_CENTER) { - pos = GTK_WIN_POS_CENTER_ON_PARENT; - } -#endif - gtk_window_set_position(GTK_WINDOW(win), pos); - - /* XXX - set a previously saved size of this dialog */ - /* currently unclear, how the dialogs should be identified */ -} - /* Create a file selection dialog box window that belongs to Ethereal's main window. */ diff --git a/gtk/dlg_utils.h b/gtk/dlg_utils.h index 151c33a089..4b6d4b9979 100644 --- a/gtk/dlg_utils.h +++ b/gtk/dlg_utils.h @@ -1,7 +1,7 @@ /* dlg_utils.h * Declarations of utilities to use when constructing dialogs * - * $Id: dlg_utils.h,v 1.13 2004/05/22 19:56:18 ulfl Exp $ + * $Id: dlg_utils.h,v 1.14 2004/05/23 17:37:36 ulfl Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -25,13 +25,10 @@ #ifndef __DLG_UTILS_H__ #define __DLG_UTILS_H__ -/* Create a dialog box window that belongs to Ethereal's main window. */ +/* Create a dialog box window that belongs to Ethereal's main window, + * see wíndow_new() for usage */ extern GtkWidget *dlg_window_new(const gchar *); -/* Show the created dialog box window. */ -/* use GTK_WIN_POS_CENTER or GTK_WIN_POS_MOUSE only! */ -extern void dlg_window_present(GtkWidget *win, GtkWindowPosition pos); - /* Create a file selection dialog box window that belongs to Ethereal's main window. */ typedef enum { @@ -60,6 +57,8 @@ extern void dlg_set_activate(GtkWidget *widget, GtkWidget *ok_button); the key being pressed is the <Esc> key. */ extern void dlg_set_cancel(GtkWidget *widget, GtkWidget *cancel_button); + +/* used by compat_macros.h only */ extern GtkWidget *dlg_radio_button_new_with_label_with_mnemonic(GSList *group, const gchar *label, GtkAccelGroup *accel_group); extern GtkWidget *dlg_check_button_new_with_label_with_mnemonic(const gchar *label, diff --git a/gtk/help_dlg.c b/gtk/help_dlg.c index 6c403caac5..8bf808d5c0 100644 --- a/gtk/help_dlg.c +++ b/gtk/help_dlg.c @@ -1,6 +1,6 @@ /* help_dlg.c * - * $Id: help_dlg.c,v 1.52 2004/05/22 19:56:18 ulfl Exp $ + * $Id: help_dlg.c,v 1.53 2004/05/23 17:37:36 ulfl Exp $ * * Laurent Deniel <laurent.deniel@free.fr> * @@ -48,7 +48,6 @@ #define NOTEBOOK_KEY "notebook_key" #define TEXT_KEY "txt_key" -static void help_close_cb(GtkWidget *w, gpointer data); static void help_destroy_cb(GtkWidget *w, gpointer data); static void insert_text(GtkWidget *w, const char *buffer, int nchars); static void set_help_text(GtkWidget *w, const char *help_file_path); @@ -98,7 +97,7 @@ GtkWidget * text_page_new(const char *absolute_path) gtk_text_set_line_wrap(GTK_TEXT(txt), TRUE); #else gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scrollw), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); txt = gtk_text_view_new(); gtk_text_view_set_editable(GTK_TEXT_VIEW(txt), FALSE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt), GTK_WRAP_WORD); @@ -174,10 +173,8 @@ void help_cb(GtkWidget *w _U_, gpointer data _U_) return; } - help_w = dlg_window_new("Ethereal: Help"); - SIGNAL_CONNECT(help_w, "destroy", help_destroy_cb, NULL); - /* XXX: improve this, e.g. remember the last window size in a file */ - WIDGET_SET_SIZE(help_w, DEF_WIDTH, DEF_HEIGHT); + help_w = window_new(GTK_WINDOW_TOPLEVEL, "Ethereal: Help"); + gtk_window_set_default_size(GTK_WINDOW(help_w), DEF_WIDTH, DEF_HEIGHT); gtk_container_border_width(GTK_CONTAINER(help_w), 2); /* Container for each row of widgets */ @@ -219,24 +216,20 @@ void help_cb(GtkWidget *w _U_, gpointer data _U_) fclose(help_toc_file); - /* Buttons (only "Ok" for now) */ + /* Button row */ bbox = dlg_button_row_new(GTK_STOCK_OK, NULL); gtk_box_pack_end(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5); close_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_OK); - SIGNAL_CONNECT(close_bt, "clicked", help_close_cb, help_w); - gtk_widget_grab_default(close_bt); + window_set_cancel_button(help_w, close_bt, window_cancel_button_cb); - gtk_quit_add_destroy(gtk_main_level(), GTK_OBJECT(help_w)); + SIGNAL_CONNECT(help_w, "delete_event", window_delete_event_cb, NULL); + SIGNAL_CONNECT(help_w, "destroy", help_destroy_cb, NULL); - /* Catch the "key_press_event" signal in the window, so that we can catch - the ESC key being pressed and act as if the "Cancel" button had - been selected. */ - dlg_set_cancel(help_w, close_bt); + gtk_quit_add_destroy(gtk_main_level(), GTK_OBJECT(help_w)); gtk_widget_show_all(help_w); - dlg_window_present(help_w, GTK_WIN_POS_MOUSE); - + window_present(help_w); } /* help_cb */ @@ -276,15 +269,6 @@ void help_topic_cb(GtkWidget *w _U_, gpointer data _U_) { /* - * Close help dialog. - */ -static void help_close_cb(GtkWidget *w _U_, gpointer data) -{ - gtk_widget_destroy(GTK_WIDGET(data)); -} - - -/* * Help dialog is closed now. */ static void help_destroy_cb(GtkWidget *w _U_, gpointer data _U_) diff --git a/gtk/main.c b/gtk/main.c index 40e89749ef..407d6f193e 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1,6 +1,6 @@ /* main.c * - * $Id: main.c,v 1.438 2004/05/22 04:15:01 guy Exp $ + * $Id: main.c,v 1.439 2004/05/23 17:37:36 ulfl Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -1168,35 +1168,25 @@ main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer } } + + static void -main_load_window_geometry(GtkWidget *widget -#if GTK_MAJOR_VERSION < 2 - _U_ -#endif -) +main_load_window_geometry(GtkWidget *widget) { - /* as we now have the geometry from the recent file, set it */ - if (prefs.gui_geometry_save_position) { - gtk_widget_set_uposition(GTK_WIDGET(top_level), - recent.gui_geometry_main_x, - recent.gui_geometry_main_y); - } - if (prefs.gui_geometry_save_size) { - WIDGET_SET_SIZE(top_level, - recent.gui_geometry_main_width, - recent.gui_geometry_main_height); - } else { - WIDGET_SET_SIZE(top_level, DEF_WIDTH, -1); - } -#if GTK_MAJOR_VERSION >= 2 - if(prefs.gui_geometry_save_maximized) { - if (recent.gui_geometry_main_maximized) { - gdk_window_maximize(widget->window); - } else { - gdk_window_unmaximize(widget->window); - } - } + window_geometry_t geom; + + geom.set_pos = prefs.gui_geometry_save_position; + geom.x = recent.gui_geometry_main_x; + geom.y = recent.gui_geometry_main_y; + geom.set_size = prefs.gui_geometry_save_size; + geom.width = recent.gui_geometry_main_width; + geom.height = recent.gui_geometry_main_height; + geom.set_maximized = prefs.gui_geometry_save_maximized; + geom.maximized = recent.gui_geometry_main_maximized; + window_set_geometry(widget, &geom); + +#if GTK_MAJOR_VERSION >= 2 /* XXX - rename recent settings? */ if (recent.gui_geometry_main_upper_pane) gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane); @@ -1207,56 +1197,27 @@ main_load_window_geometry(GtkWidget *widget #endif } + static void main_save_window_geometry(GtkWidget *widget) { - gint desk_x, desk_y; -#if GTK_MAJOR_VERSION >= 2 - GdkWindowState state; -#endif - - /* Try to grab our geometry. - - GTK+ provides two routines to get a window's position relative - to the X root window. If I understand the documentation correctly, - gdk_window_get_deskrelative_origin applies mainly to Enlightenment - and gdk_window_get_root_origin applies for all other WMs. - - The code below tries both routines, and picks the one that returns - the upper-left-most coordinates. - - More info at: + window_geometry_t geom; - http://mail.gnome.org/archives/gtk-devel-list/2001-March/msg00289.html - http://www.gtk.org/faq/#AEN606 - */ + window_get_geometry(widget, &geom); if (prefs.gui_geometry_save_position) { - gdk_window_get_root_origin(widget->window, - &recent.gui_geometry_main_x, - &recent.gui_geometry_main_y); - if (gdk_window_get_deskrelative_origin(widget->window, - &desk_x, &desk_y)) { - if (desk_x <= recent.gui_geometry_main_x && - desk_y <= recent.gui_geometry_main_y) - { - recent.gui_geometry_main_x = desk_x; - recent.gui_geometry_main_y = desk_y; - } - } + recent.gui_geometry_main_x = geom.x; + recent.gui_geometry_main_y = geom.y; } if (prefs.gui_geometry_save_size) { - /* XXX - Is this the "approved" method? */ - gdk_window_get_size(widget->window, - &recent.gui_geometry_main_width, - &recent.gui_geometry_main_height); + recent.gui_geometry_main_width = geom.width, + recent.gui_geometry_main_height = geom.height; } #if GTK_MAJOR_VERSION >= 2 if(prefs.gui_geometry_save_maximized) { - state = gdk_window_get_state(widget->window); - recent.gui_geometry_main_maximized = (state == GDK_WINDOW_STATE_MAXIMIZED); + recent.gui_geometry_main_maximized = geom.maximized; } recent.gui_geometry_main_upper_pane = gtk_paned_get_position(GTK_PANED(main_first_pane)); diff --git a/gtk/ui_util.c b/gtk/ui_util.c index e51e011550..0f24fa5313 100644 --- a/gtk/ui_util.c +++ b/gtk/ui_util.c @@ -1,7 +1,7 @@ /* ui_util.c * UI utility routines * - * $Id: ui_util.c,v 1.23 2004/05/21 08:55:07 ulfl Exp $ + * $Id: ui_util.c,v 1.24 2004/05/23 17:37:36 ulfl Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -45,6 +45,11 @@ #include "image/eicon3d16.xpm" +/* XXX - remove this later again, when dlg_xx function cleanup done */ +#include "dlg_utils.h" + +#define WIN_REG_KEY "win_reg_key" + /* Set our window icon. The GDK documentation doesn't provide any actual documentation for gdk_window_set_icon(), so we'll steal libgimp/gimpdialog.c:gimp_dialog_realize_callback() from the Gimp @@ -107,6 +112,7 @@ window_icon_realize_cb (GtkWidget *win, gpointer data _U_) #endif } + /* Create a new window, of the specified type, with the specified title (if any) and the Ethereal icon. */ GtkWidget * @@ -118,44 +124,244 @@ window_new(GtkWindowType type, const gchar *title) if (title != NULL) gtk_window_set_title(GTK_WINDOW(win), title); SIGNAL_CONNECT(win, "realize", window_icon_realize_cb, NULL); + + /* register this window title (it might change later!) */ + if(title && strlen(title)) { + OBJECT_SET_DATA(win, WIN_REG_KEY, g_strdup(title)); + } + + /* XXX - which one is the correct default policy? or use a preference for this? */ + /* GTK_WIN_POS_NONE, GTK_WIN_POS_CENTER or GTK_WIN_POS_MOUSE */ + + /* set the initial position (must be done, before show is called!) */ + gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_MOUSE); + +#if GTK_MAJOR_VERSION < 2 + /* allow window to be shrinked by user, as gtk_widget_set_usize() will set minimum size and */ + /* the user never couldn't shrink the window again */ + gtk_window_set_policy(GTK_WINDOW(win), TRUE, TRUE, FALSE); +#endif + return win; } -/* Set the name of the top-level window and its icon to the specified - string. */ +/* Present the created window. */ void -set_main_window_name(gchar *window_name) +window_present(GtkWidget *win) { - gtk_window_set_title(GTK_WINDOW(top_level), window_name); - gdk_window_set_icon_name(top_level->window, window_name); + window_geometry_t geom; + +#if GTK_MAJOR_VERSION >= 2 + /* present this window */ + gtk_window_present(GTK_WINDOW(win)); +#endif + + /* do we have a previously saved size and position of this window? */ + if(window_load_geom(win, &geom)) { + /* XXX - use prefs to select which values to set? */ + geom.set_pos = TRUE; + geom.set_size = TRUE; + geom.set_maximized = TRUE; + window_set_geometry(win, &geom); + } } -#ifdef HAVE_LIBPCAP +/* set the actions needed for the cancel "Close"/"Ok"/"Cancel button that closes the window */ +void window_set_cancel_button(GtkWidget *win, GtkWidget *bt, window_cancel_button_fct cb) +{ +/* SIGNAL_CONNECT_OBJECT(bt, "clicked", cb, win);*/ + SIGNAL_CONNECT(bt, "clicked", cb, win); -/* update the main window */ -void main_window_update(void) + gtk_widget_grab_default(bt); + + /* Catch the "key_press_event" signal in the window, so that we can catch + the ESC key being pressed and act as if the "Cancel" button had + been selected. */ + dlg_set_cancel(win, bt); +} + + +/* default callback handler for cancel button "clicked" signal */ +void window_cancel_button_cb(GtkWidget *w _U_, gpointer data) { - while (gtk_events_pending()) gtk_main_iteration(); + window_destroy(GTK_WIDGET(data)); } -/* exit the main window */ -void main_window_exit(void) + +/* default callback handler: the window managers X of the window was clicked (delete_event) */ +gboolean +window_delete_event_cb(GtkWidget *win, GdkEvent *event _U_, gpointer user_data _U_) { - gtk_exit(0); + window_destroy(win); + + /* event handled, don't do anything else */ + return TRUE; } -/* quit a nested main window */ -void main_window_nested_quit(void) + +/* get the geometry of a window from window_new() */ +void +window_get_geometry(GtkWidget *widget, window_geometry_t *geom) { - if (gtk_main_level() > 0) - gtk_main_quit(); + gint desk_x, desk_y; +#if GTK_MAJOR_VERSION >= 2 + GdkWindowState state; +#endif + + /* Try to grab our geometry. + + GTK+ provides two routines to get a window's position relative + to the X root window. If I understand the documentation correctly, + gdk_window_get_deskrelative_origin applies mainly to Enlightenment + and gdk_window_get_root_origin applies for all other WMs. + + The code below tries both routines, and picks the one that returns + the upper-left-most coordinates. + + More info at: + + http://mail.gnome.org/archives/gtk-devel-list/2001-March/msg00289.html + http://www.gtk.org/faq/#AEN606 + */ + + gdk_window_get_root_origin(widget->window, + &geom->x, + &geom->y); + if (gdk_window_get_deskrelative_origin(widget->window, + &desk_x, &desk_y)) { + if (desk_x <= geom->x && + desk_y <= geom->y) + { + geom->x = desk_x; + geom->y = desk_y; + } + } + + /* XXX - Is this the "approved" method? */ + gdk_window_get_size(widget->window, + &geom->width, + &geom->height); + +#if GTK_MAJOR_VERSION >= 2 + state = gdk_window_get_state(widget->window); + geom->maximized = (state == GDK_WINDOW_STATE_MAXIMIZED); +#endif } -/* quit the main window */ -void main_window_quit(void) + +/* set the geometry of a window from window_new() */ +void +window_set_geometry(GtkWidget *widget, window_geometry_t *geom) { - gtk_main_quit(); + /* as we now have the geometry from the recent file, set it */ + if (geom->set_pos) { + gtk_widget_set_uposition(widget, + geom->x, + geom->y); + } + + if (geom->set_size) { +#if GTK_MAJOR_VERSION >= 2 + gtk_window_resize(GTK_WINDOW(widget), +#else + gtk_window_set_default_size(GTK_WINDOW(widget), + geom->width, + geom->height); + gtk_widget_set_usize(widget, +#endif + /*WIDGET_SET_SIZE(widget,*/ + geom->width, + geom->height); + } + +#if GTK_MAJOR_VERSION >= 2 + if(geom->set_maximized) { + if (geom->maximized) { + gdk_window_maximize(widget->window); + } else { + gdk_window_unmaximize(widget->window); + } + } +#endif +} + +/* the hashtable for all known window classes, + * the initial window title is the key, and the geometry is the value */ +GHashTable *window_class_hash = NULL; + + +/* save the window and it's current geometry into the hashtable */ +static void +window_save_geom(GtkWidget *win, window_geometry_t *geom) +{ + gchar *reg; + gchar *key; + window_geometry_t *work; + + reg = OBJECT_GET_DATA(win, WIN_REG_KEY); + if(reg) { + /* init hashtable, if not already done */ + if(!window_class_hash) { + window_class_hash = g_hash_table_new (g_str_hash, g_str_equal); + } + /* if we have an old one, remove and free it first */ + work = g_hash_table_lookup(window_class_hash, reg); + if(work) { + g_hash_table_remove(window_class_hash, reg); + g_free(work->key); + g_free(work); + } + + /* malloc and insert the new one */ + work = g_malloc(sizeof(*geom)); + *work = *geom; + key = g_strdup(reg); + work->key = key; + g_hash_table_insert(window_class_hash, key, work); + } +} + + +/* load the desired geometry for this window from the hashtable */ +gboolean +window_load_geom(GtkWidget *win, window_geometry_t *geom) +{ + gchar *reg; + window_geometry_t *p; + + reg = OBJECT_GET_DATA(win, WIN_REG_KEY); + if(reg) { + /* init hashtable, if not already done */ + if(!window_class_hash) { + window_class_hash = g_hash_table_new (g_str_hash, g_str_equal); + } + + p = g_hash_table_lookup(window_class_hash, reg); + if(p) { + *geom = *p; + return TRUE; + } + } + return FALSE; +} + +void +window_destroy(GtkWidget *win) +{ + window_geometry_t geom; + gchar * title; + + /* this must be done *before* destroy is running, as the window geometry */ + /* cannot be retrieved at destroy time (so don't use event "destroy" for this) */ + window_get_geometry(win, &geom); + window_save_geom(win, &geom); + + title = OBJECT_GET_DATA(win, WIN_REG_KEY); + + gtk_widget_destroy(win); + + g_free(title); } @@ -183,6 +389,45 @@ GtkWidget *xpm_to_widget(const char ** xpm) { } +/* Set the name of the top-level window and its icon to the specified + string. */ +void +set_main_window_name(gchar *window_name) +{ + gtk_window_set_title(GTK_WINDOW(top_level), window_name); + gdk_window_set_icon_name(top_level->window, window_name); +} + + +#ifdef HAVE_LIBPCAP + +/* update the main window */ +void main_window_update(void) +{ + while (gtk_events_pending()) gtk_main_iteration(); +} + +/* exit the main window */ +void main_window_exit(void) +{ + gtk_exit(0); +} + +/* quit a nested main window */ +void main_window_nested_quit(void) +{ + if (gtk_main_level() > 0) + gtk_main_quit(); +} + +/* quit the main window */ +void main_window_quit(void) +{ + gtk_main_quit(); +} + + + typedef struct pipe_input_tag { gint source; gpointer user_data; diff --git a/gtk/ui_util.h b/gtk/ui_util.h index b8e1d0cb9c..05ffb5ec8a 100644 --- a/gtk/ui_util.h +++ b/gtk/ui_util.h @@ -1,7 +1,7 @@ /* ui_util.h * Definitions for UI utility routines * - * $Id: ui_util.h,v 1.9 2004/05/20 18:18:12 ulfl Exp $ + * $Id: ui_util.h,v 1.10 2004/05/23 17:37:36 ulfl Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -25,16 +25,100 @@ #ifndef __GTKGUIUI_UTIL_H__ #define __GTKGUIUI_UTIL_H__ +/* Some words about windows / dialogs. + * + * delete event: the window managers "X" (e.g. upper right edge) of the window + * was clicked, default handler will call gtk_widget_destroy() + * destroy event: everything is already gone, only cleanup of left over ressources + * can/should be done now + * + * Hint: don't use WIDGET_SET_SIZE() to set the size of a window, + * use gtk_window_set_default_size() for that purpose! + * + * be sure, to call window_present() / window_destroy() appropriately, if you + * want to have size and position handled by ui_util + * + * A typical window / dialog will be created by: + * + * window_new(...) will create a new window with default position and size + * use dlg_window_new() if you need a dialog (transient to the main window) + * + * gtk_window_set_default_size(...) to set the default size of the window, only + * needed, if the initial size is not appropriate, e.g. a scrolled_window_new() is used + * be sure the given is larger than the initial size, otherwise might get clipped content on GTK1 + * + * SIGNAL_CONNECT(my_win, "destroy", my_destroy_cb, NULL) callback, if some cleanup needs to be + * done after the window is destroyed, e.g. free up memory, or set the window pointer + * of a singleton window (only one instance allowed, e.g. about dialog) back to zero + * + * create and fill in the content and button widgets + * + * gtk_widget_show_all(my_win) show all the widgets in the window + * + * window_present(...) present the window on screen and + * (if available) set previously saved position and size + * + * if you want to save size and position, be sure to call window_destroy() instead of only + * gtk_widget_destroy(), so you will probably have to SIGNAL_CONNECT to the "delete_event"! + */ + /* Create a new window, of the specified type, with the specified title - (if any) and the Ethereal icon. */ -GtkWidget *window_new(GtkWindowType, const gchar *); + * (if any) and the Ethereal icon. + * If you want to create a dialog, use dlg_window_new() instead. + * type window type, typical GTK_WINDOW_TOPLEVEL + * title title to show, will also set the window class for saving size etc. */ +extern GtkWidget *window_new(GtkWindowType type, const gchar *title); + +/* Present the created window. This will put the window on top and + * (if available) set previously saved position and size. */ +extern void window_present(GtkWidget *win); + +typedef void (*window_cancel_button_fct) (GtkWidget *w, gpointer data); + +/* register the default cancel button "Cancel"/"Close"/"Ok" of this window */ +extern void window_set_cancel_button(GtkWidget *win, GtkWidget *bt, window_cancel_button_fct cb); + +/* Remember current window position and size and then destroy the window, + * call this instead of gtk_widget_destroy(); */ +extern void window_destroy(GtkWidget *win); + +/* default callback handler for cancel button "clicked" signal, + * use this for window_set_cancel_button(), will simply call window_destroy() */ +extern void window_cancel_button_cb(GtkWidget *w _U_, gpointer data); + +/* default callback handler: the window managers X of the window was clicked (delete_event), + * use this for SIGNAL_CONNECT(), will simply call window_destroy() */ +extern gboolean +window_delete_event_cb(GtkWidget *win, GdkEvent *event _U_, gpointer user_data _U_); + + +typedef struct window_geometry_s { + gchar *key; + gboolean set_pos; + gint x; + gint y; + gboolean set_size; + gint width; + gint height; + + gboolean set_maximized; + gboolean maximized; /* this is valid in GTK2 only */ +} window_geometry_t; + +/* get the geometry of a window from window_new() */ +extern void window_get_geometry(GtkWidget *win, window_geometry_t *geom); +/* set the geometry of a window from window_new() */ +extern void window_set_geometry(GtkWidget *win, window_geometry_t *geom); + +/* load the geometry values for a window from previously saved values */ +extern gboolean window_load_geom(GtkWidget *win, window_geometry_t *geom); /* Given a pointer to a GtkWidget for a top-level window, raise it and de-iconify it. This routine is used if the user has done something to ask that a window of a certain type be popped up when there can be only one such window and such a window has already been popped up - we pop up the existing one rather than creating a new one. */ -void reactivate_window(GtkWidget *); +void reactivate_window(GtkWidget *win); /* Create a GtkScrolledWindow, set its scrollbar placement appropriately, and remember it. */ |