1999-09-09 04:25:49 +00:00
|
|
|
/* filter_prefs.c
|
1999-12-10 07:20:57 +00:00
|
|
|
* Dialog boxes for filter editing
|
|
|
|
* (This used to be a notebook page under "Preferences", hence the
|
|
|
|
* "prefs" in the file name.)
|
1998-09-16 02:39:15 +00:00
|
|
|
*
|
2000-07-05 02:45:42 +00:00
|
|
|
* $Id: filter_prefs.c,v 1.12 2000/07/05 02:45:39 guy Exp $
|
1998-09-16 03:22:19 +00:00
|
|
|
*
|
1998-09-16 02:39:15 +00:00
|
|
|
* Ethereal - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@zing.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
1998-12-17 05:42:33 +00:00
|
|
|
#include <stdlib.h>
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <sys/stat.h>
|
1999-07-13 02:53:26 +00:00
|
|
|
#ifdef HAVE_UNISTD_H
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <unistd.h>
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
1998-09-27 22:12:47 +00:00
|
|
|
#include <ctype.h>
|
1999-07-13 02:53:26 +00:00
|
|
|
#ifdef HAVE_DIRECT_H
|
|
|
|
#include <direct.h>
|
|
|
|
#endif
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-09-09 02:42:40 +00:00
|
|
|
#include "gtk/main.h"
|
1999-09-09 03:35:32 +00:00
|
|
|
#include "filter_prefs.h"
|
1998-09-16 02:39:15 +00:00
|
|
|
#include "packet.h"
|
|
|
|
#include "file.h"
|
2000-01-29 16:41:28 +00:00
|
|
|
#include "util.h"
|
2000-07-05 02:45:42 +00:00
|
|
|
#include "dlg_utils.h"
|
Split "filter_dialog_cb()" into "filter_dialog_cb()", which pops up a
"global" dialog box when "Edit:Filters" is selected, so that the list of
filters can be edited, and "filter_browse_cb()", which pops up a dialog
box associated with a "Filter:" button and a text entry widget attached
to that button, so that a filter can be selected or saved (although it
also supports the same editing that the "global" dialog box does).
Have "filter_dialog_cb()" connect the window in which the "Filter:"
button lives and the filter dialog box, so that:
if the window in which the "Filter:" button lives goes away, so
does the filter dialog box (as it no longer has a text widget
into which it can stuff the selected filter);
if the "Filter:" button is clicked when there's already a filter
dialog box open, we just reactivate that existing dialog box
rather than popping up a new one.
Also keep a pointer to the "global" filter dialog box, so that we also
arrange that there's only one of them (by reactivating the existing on
if "Edit:Filters" is selected when there's already a "global" filter
dialog box open).
Keep around pointers to the dialog boxes that contain the "Filter:"
buttons, so that we can arrange that there be only one of them (that was
a side-effect of an earlier attempt at fixing the problems described
above, but it's still useful for keeping multiple competing dialog boxes
from being open - there's more of that to be done).
Make the pointer to the "Open Capture File" dialog box widget static to
"file_dlg.c" - nobody outside of "file_dlg.c cares about it.
svn path=/trunk/; revision=1774
2000-04-01 12:03:42 +00:00
|
|
|
#include "ui_util.h"
|
1999-09-09 03:35:32 +00:00
|
|
|
#include "prefs_dlg.h"
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1998-10-13 02:10:57 +00:00
|
|
|
#define E_FILT_NAME_KEY "filter_name"
|
|
|
|
#define E_FILT_LBL_KEY "filter_label"
|
|
|
|
#define E_FILT_CM_KEY "in_cancel_mode"
|
1999-12-10 06:28:24 +00:00
|
|
|
#define E_FILTER_WIDGET_KEY "filter_widget"
|
1998-10-13 02:10:57 +00:00
|
|
|
|
1999-09-09 03:35:32 +00:00
|
|
|
typedef struct _filter_def {
|
|
|
|
char *name;
|
|
|
|
char *strval;
|
|
|
|
} filter_def;
|
|
|
|
|
|
|
|
typedef struct _filter_cb_data {
|
|
|
|
GList *fl;
|
|
|
|
GtkWidget *win;
|
|
|
|
} filter_cb_data;
|
|
|
|
|
|
|
|
|
1999-12-10 06:28:24 +00:00
|
|
|
static GtkWidget *filter_l, *chg_bt, *copy_bt, *del_bt, *name_te, *filter_te, *apply_bt;
|
1999-09-10 06:01:02 +00:00
|
|
|
static GList *fl = NULL;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-09-10 06:01:02 +00:00
|
|
|
static void get_filter_list(void);
|
Split "filter_dialog_cb()" into "filter_dialog_cb()", which pops up a
"global" dialog box when "Edit:Filters" is selected, so that the list of
filters can be edited, and "filter_browse_cb()", which pops up a dialog
box associated with a "Filter:" button and a text entry widget attached
to that button, so that a filter can be selected or saved (although it
also supports the same editing that the "global" dialog box does).
Have "filter_dialog_cb()" connect the window in which the "Filter:"
button lives and the filter dialog box, so that:
if the window in which the "Filter:" button lives goes away, so
does the filter dialog box (as it no longer has a text widget
into which it can stuff the selected filter);
if the "Filter:" button is clicked when there's already a filter
dialog box open, we just reactivate that existing dialog box
rather than popping up a new one.
Also keep a pointer to the "global" filter dialog box, so that we also
arrange that there's only one of them (by reactivating the existing on
if "Edit:Filters" is selected when there's already a "global" filter
dialog box open).
Keep around pointers to the dialog boxes that contain the "Filter:"
buttons, so that we can arrange that there be only one of them (that was
a side-effect of an earlier attempt at fixing the problems described
above, but it's still useful for keeping multiple competing dialog boxes
from being open - there's more of that to be done).
Make the pointer to the "Open Capture File" dialog box widget static to
"file_dlg.c" - nobody outside of "file_dlg.c cares about it.
svn path=/trunk/; revision=1774
2000-04-01 12:03:42 +00:00
|
|
|
static GtkWidget *filter_dialog_new(GtkWidget *caller, GtkWidget *filter_te);
|
1999-12-10 06:28:24 +00:00
|
|
|
static void filter_dlg_ok(GtkWidget *ok_bt, gpointer parent_w);
|
|
|
|
static void filter_dlg_save(GtkWidget *save_bt, gpointer parent_w);
|
|
|
|
static void filter_dlg_cancel(GtkWidget *cancel_bt, gpointer parent_w);
|
Split "filter_dialog_cb()" into "filter_dialog_cb()", which pops up a
"global" dialog box when "Edit:Filters" is selected, so that the list of
filters can be edited, and "filter_browse_cb()", which pops up a dialog
box associated with a "Filter:" button and a text entry widget attached
to that button, so that a filter can be selected or saved (although it
also supports the same editing that the "global" dialog box does).
Have "filter_dialog_cb()" connect the window in which the "Filter:"
button lives and the filter dialog box, so that:
if the window in which the "Filter:" button lives goes away, so
does the filter dialog box (as it no longer has a text widget
into which it can stuff the selected filter);
if the "Filter:" button is clicked when there's already a filter
dialog box open, we just reactivate that existing dialog box
rather than popping up a new one.
Also keep a pointer to the "global" filter dialog box, so that we also
arrange that there's only one of them (by reactivating the existing on
if "Edit:Filters" is selected when there's already a "global" filter
dialog box open).
Keep around pointers to the dialog boxes that contain the "Filter:"
buttons, so that we can arrange that there be only one of them (that was
a side-effect of an earlier attempt at fixing the problems described
above, but it's still useful for keeping multiple competing dialog boxes
from being open - there's more of that to be done).
Make the pointer to the "Open Capture File" dialog box widget static to
"file_dlg.c" - nobody outside of "file_dlg.c cares about it.
svn path=/trunk/; revision=1774
2000-04-01 12:03:42 +00:00
|
|
|
static void filter_dlg_destroy(GtkWidget *win, gpointer data);
|
1999-12-10 06:28:24 +00:00
|
|
|
static void filter_sel_apply_cb(GtkWidget *cancel_bt, gpointer parent_w);
|
1998-10-13 02:10:57 +00:00
|
|
|
|
2000-02-12 06:46:54 +00:00
|
|
|
static GtkWidget *filter_prefs_show(GtkWidget *);
|
|
|
|
static void filter_sel_list_cb(GtkWidget *, gpointer);
|
|
|
|
static void filter_sel_new_cb(GtkWidget *, gpointer);
|
|
|
|
static void filter_sel_chg_cb(GtkWidget *, gpointer);
|
|
|
|
static void filter_sel_copy_cb(GtkWidget *, gpointer);
|
|
|
|
static void filter_sel_del_cb(GtkWidget *, gpointer);
|
|
|
|
static void filter_prefs_ok(GtkWidget *);
|
|
|
|
static void filter_prefs_save(GtkWidget *);
|
|
|
|
static void filter_prefs_cancel(GtkWidget *);
|
|
|
|
static void filter_prefs_delete(GtkWidget *);
|
|
|
|
|
2000-03-28 06:20:08 +00:00
|
|
|
#define FILTER_LINE_SIZE 2048
|
|
|
|
|
2000-02-12 06:46:54 +00:00
|
|
|
static void
|
|
|
|
get_filter_list(void)
|
|
|
|
{
|
1998-09-16 02:39:15 +00:00
|
|
|
filter_def *filt;
|
|
|
|
FILE *ff;
|
2000-03-28 06:20:08 +00:00
|
|
|
gchar *ff_path, *ff_name = PF_DIR "/filters", f_buf[FILTER_LINE_SIZE];
|
1998-09-16 02:39:15 +00:00
|
|
|
gchar *name_begin, *name_end, *filt_begin;
|
|
|
|
int len, line = 0;
|
1998-10-13 02:10:57 +00:00
|
|
|
|
|
|
|
if (fl) return;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
/* To do: generalize this */
|
2000-01-29 16:41:28 +00:00
|
|
|
ff_path = (gchar *) g_malloc(strlen(get_home_dir()) + strlen(ff_name) + 4);
|
|
|
|
sprintf(ff_path, "%s/%s", get_home_dir(), ff_name);
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
if ((ff = fopen(ff_path, "r")) == NULL) {
|
|
|
|
g_free(ff_path);
|
1998-10-13 02:10:57 +00:00
|
|
|
return;
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
|
2000-03-28 06:20:08 +00:00
|
|
|
while (fgets(f_buf, FILTER_LINE_SIZE, ff)) {
|
1998-09-16 02:39:15 +00:00
|
|
|
line++;
|
|
|
|
len = strlen(f_buf);
|
1998-09-27 22:12:47 +00:00
|
|
|
if (f_buf[len - 1] == '\n') {
|
1998-09-16 02:39:15 +00:00
|
|
|
len--;
|
|
|
|
f_buf[len] = '\0';
|
|
|
|
}
|
|
|
|
name_begin = strchr(f_buf, '"');
|
|
|
|
/* Empty line */
|
|
|
|
if (name_begin == NULL)
|
|
|
|
continue;
|
|
|
|
name_end = strchr(name_begin + 1, '"');
|
|
|
|
/* No terminating quote */
|
|
|
|
if (name_end == NULL) {
|
|
|
|
g_warning("Malformed filter in '%s' line %d.", ff_path, line);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
name_begin++;
|
|
|
|
name_end[0] = '\0';
|
|
|
|
filt_begin = name_end + 1;
|
|
|
|
while(isspace(filt_begin[0])) filt_begin++;
|
|
|
|
/* No filter string */
|
|
|
|
if (filt_begin[0] == '\0') {
|
|
|
|
g_warning("Malformed filter in '%s' line %d.", ff_path, line);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
filt = (filter_def *) g_malloc(sizeof(filter_def));
|
|
|
|
filt->name = g_strdup(name_begin);
|
|
|
|
filt->strval = g_strdup(filt_begin);
|
|
|
|
fl = g_list_append(fl, filt);
|
|
|
|
}
|
|
|
|
fclose(ff);
|
|
|
|
g_free(ff_path);
|
|
|
|
}
|
2000-02-12 06:46:54 +00:00
|
|
|
|
Split "filter_dialog_cb()" into "filter_dialog_cb()", which pops up a
"global" dialog box when "Edit:Filters" is selected, so that the list of
filters can be edited, and "filter_browse_cb()", which pops up a dialog
box associated with a "Filter:" button and a text entry widget attached
to that button, so that a filter can be selected or saved (although it
also supports the same editing that the "global" dialog box does).
Have "filter_dialog_cb()" connect the window in which the "Filter:"
button lives and the filter dialog box, so that:
if the window in which the "Filter:" button lives goes away, so
does the filter dialog box (as it no longer has a text widget
into which it can stuff the selected filter);
if the "Filter:" button is clicked when there's already a filter
dialog box open, we just reactivate that existing dialog box
rather than popping up a new one.
Also keep a pointer to the "global" filter dialog box, so that we also
arrange that there's only one of them (by reactivating the existing on
if "Edit:Filters" is selected when there's already a "global" filter
dialog box open).
Keep around pointers to the dialog boxes that contain the "Filter:"
buttons, so that we can arrange that there be only one of them (that was
a side-effect of an earlier attempt at fixing the problems described
above, but it's still useful for keeping multiple competing dialog boxes
from being open - there's more of that to be done).
Make the pointer to the "Open Capture File" dialog box widget static to
"file_dlg.c" - nobody outside of "file_dlg.c cares about it.
svn path=/trunk/; revision=1774
2000-04-01 12:03:42 +00:00
|
|
|
/* XXX - we can have one global dialog box for editing, and a bunch
|
|
|
|
of dialog boxes associated with browse buttons; we want the dialog
|
|
|
|
boxes associated with browse buttons to at least let you save the
|
|
|
|
current filter, so they have to allow editing; however, how do we
|
|
|
|
arrange that if a change is made to the filter list, other dialog
|
|
|
|
boxes get updated appropriately? */
|
|
|
|
|
|
|
|
/* Create a filter dialog for browsing; this is to be used as a callback
|
|
|
|
for a button next to a text entry box, which, when clicked, allows
|
|
|
|
you to browse through the list of filters to select one to be put
|
|
|
|
into the text entry box, and, if you select a filter with this
|
|
|
|
dialog box, enters the text of the filter into a text entry box
|
|
|
|
associated with the button. */
|
|
|
|
void
|
|
|
|
filter_browse_cb(GtkWidget *w)
|
|
|
|
{
|
|
|
|
GtkWidget *caller = gtk_widget_get_toplevel(w);
|
|
|
|
GtkWidget *filter_browse_w;
|
|
|
|
GtkWidget *filter_te;
|
|
|
|
|
|
|
|
/* Has a filter dialog box already been opened for that top-level
|
|
|
|
widget? */
|
|
|
|
filter_browse_w = gtk_object_get_data(GTK_OBJECT(caller),
|
|
|
|
E_FILT_DIALOG_PTR_KEY);
|
|
|
|
|
|
|
|
if (filter_browse_w != NULL) {
|
|
|
|
/* Yes. Just re-activate that dialog box. */
|
|
|
|
reactivate_window(filter_browse_w);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* No. Get the text entry attached to the button. */
|
|
|
|
filter_te = gtk_object_get_data(GTK_OBJECT(w), E_FILT_TE_PTR_KEY);
|
|
|
|
|
|
|
|
/* Now create a new dialog. */
|
|
|
|
filter_browse_w = filter_dialog_new(caller, filter_te);
|
|
|
|
|
|
|
|
/* Set the E_FILT_CALLER_PTR_KEY for the new dialog to point to
|
|
|
|
our caller. */
|
|
|
|
gtk_object_set_data(GTK_OBJECT(filter_browse_w), E_FILT_CALLER_PTR_KEY,
|
|
|
|
caller);
|
|
|
|
|
|
|
|
/* Set the E_FILT_DIALOG_PTR_KEY for the caller to point to us */
|
|
|
|
gtk_object_set_data(GTK_OBJECT(caller), E_FILT_DIALOG_PTR_KEY,
|
|
|
|
filter_browse_w);
|
|
|
|
}
|
|
|
|
|
|
|
|
static GtkWidget *global_filter_w;
|
|
|
|
|
|
|
|
/* Create a filter dialog for editing; this is to be used as a callback
|
|
|
|
for menu items, toolbars, etc.. */
|
1999-12-10 06:28:24 +00:00
|
|
|
void
|
|
|
|
filter_dialog_cb(GtkWidget *w)
|
Split "filter_dialog_cb()" into "filter_dialog_cb()", which pops up a
"global" dialog box when "Edit:Filters" is selected, so that the list of
filters can be edited, and "filter_browse_cb()", which pops up a dialog
box associated with a "Filter:" button and a text entry widget attached
to that button, so that a filter can be selected or saved (although it
also supports the same editing that the "global" dialog box does).
Have "filter_dialog_cb()" connect the window in which the "Filter:"
button lives and the filter dialog box, so that:
if the window in which the "Filter:" button lives goes away, so
does the filter dialog box (as it no longer has a text widget
into which it can stuff the selected filter);
if the "Filter:" button is clicked when there's already a filter
dialog box open, we just reactivate that existing dialog box
rather than popping up a new one.
Also keep a pointer to the "global" filter dialog box, so that we also
arrange that there's only one of them (by reactivating the existing on
if "Edit:Filters" is selected when there's already a "global" filter
dialog box open).
Keep around pointers to the dialog boxes that contain the "Filter:"
buttons, so that we can arrange that there be only one of them (that was
a side-effect of an earlier attempt at fixing the problems described
above, but it's still useful for keeping multiple competing dialog boxes
from being open - there's more of that to be done).
Make the pointer to the "Open Capture File" dialog box widget static to
"file_dlg.c" - nobody outside of "file_dlg.c cares about it.
svn path=/trunk/; revision=1774
2000-04-01 12:03:42 +00:00
|
|
|
{
|
|
|
|
/* Has a filter dialog box already been opened for editing? */
|
|
|
|
if (global_filter_w != NULL) {
|
|
|
|
/* Yes. Just reactivate it. */
|
|
|
|
reactivate_window(global_filter_w);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* No. Create one. */
|
|
|
|
global_filter_w = filter_dialog_new(NULL, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static GtkWidget *
|
|
|
|
filter_dialog_new(GtkWidget *caller, GtkWidget *filter_te)
|
1999-12-10 06:28:24 +00:00
|
|
|
{
|
|
|
|
GtkWidget *main_w, /* main window */
|
|
|
|
*main_vb, /* main container */
|
|
|
|
*bbox, /* button container */
|
|
|
|
*ok_bt, /* ok button */
|
|
|
|
*save_bt, /* save button */
|
|
|
|
*cancel_bt; /* cancel button */
|
|
|
|
GtkWidget *filter_pg = NULL; /* filter settings box */
|
|
|
|
|
2000-07-05 02:45:42 +00:00
|
|
|
main_w = dlg_window_new();
|
1999-12-10 06:28:24 +00:00
|
|
|
gtk_window_set_title(GTK_WINDOW(main_w), "Ethereal: Filters");
|
|
|
|
|
Split "filter_dialog_cb()" into "filter_dialog_cb()", which pops up a
"global" dialog box when "Edit:Filters" is selected, so that the list of
filters can be edited, and "filter_browse_cb()", which pops up a dialog
box associated with a "Filter:" button and a text entry widget attached
to that button, so that a filter can be selected or saved (although it
also supports the same editing that the "global" dialog box does).
Have "filter_dialog_cb()" connect the window in which the "Filter:"
button lives and the filter dialog box, so that:
if the window in which the "Filter:" button lives goes away, so
does the filter dialog box (as it no longer has a text widget
into which it can stuff the selected filter);
if the "Filter:" button is clicked when there's already a filter
dialog box open, we just reactivate that existing dialog box
rather than popping up a new one.
Also keep a pointer to the "global" filter dialog box, so that we also
arrange that there's only one of them (by reactivating the existing on
if "Edit:Filters" is selected when there's already a "global" filter
dialog box open).
Keep around pointers to the dialog boxes that contain the "Filter:"
buttons, so that we can arrange that there be only one of them (that was
a side-effect of an earlier attempt at fixing the problems described
above, but it's still useful for keeping multiple competing dialog boxes
from being open - there's more of that to be done).
Make the pointer to the "Open Capture File" dialog box widget static to
"file_dlg.c" - nobody outside of "file_dlg.c cares about it.
svn path=/trunk/; revision=1774
2000-04-01 12:03:42 +00:00
|
|
|
/* Call a handler when we're destroyed, so we can inform
|
|
|
|
our caller, if any, that we've been destroyed. */
|
|
|
|
gtk_signal_connect(GTK_OBJECT(main_w), "destroy",
|
|
|
|
GTK_SIGNAL_FUNC(filter_dlg_destroy), NULL);
|
|
|
|
|
1999-12-10 06:28:24 +00:00
|
|
|
main_vb = gtk_vbox_new(FALSE, 5);
|
|
|
|
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
|
|
|
gtk_container_add(GTK_CONTAINER(main_w), main_vb);
|
|
|
|
gtk_widget_show(main_vb);
|
|
|
|
|
|
|
|
filter_pg = filter_prefs_show(filter_te);
|
|
|
|
gtk_box_pack_start(GTK_BOX(main_vb), filter_pg, TRUE, TRUE, 0);
|
|
|
|
gtk_object_set_data(GTK_OBJECT(filter_pg), E_FILT_TE_PTR_KEY, filter_te);
|
|
|
|
gtk_object_set_data(GTK_OBJECT(main_w), E_FILTER_WIDGET_KEY, filter_pg);
|
|
|
|
|
|
|
|
bbox = gtk_hbutton_box_new();
|
|
|
|
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
|
|
|
|
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
|
|
|
|
gtk_container_add(GTK_CONTAINER(main_vb), bbox);
|
|
|
|
gtk_widget_show(bbox);
|
|
|
|
|
|
|
|
ok_bt = gtk_button_new_with_label ("OK");
|
|
|
|
gtk_signal_connect(GTK_OBJECT(ok_bt), "clicked",
|
|
|
|
GTK_SIGNAL_FUNC(filter_dlg_ok), GTK_OBJECT(main_w));
|
|
|
|
GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT);
|
|
|
|
gtk_box_pack_start(GTK_BOX(bbox), ok_bt, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_grab_default(ok_bt);
|
|
|
|
gtk_widget_show(ok_bt);
|
|
|
|
|
|
|
|
save_bt = gtk_button_new_with_label ("Save");
|
|
|
|
gtk_signal_connect(GTK_OBJECT(save_bt), "clicked",
|
|
|
|
GTK_SIGNAL_FUNC(filter_dlg_save), GTK_OBJECT(main_w));
|
|
|
|
GTK_WIDGET_SET_FLAGS(save_bt, GTK_CAN_DEFAULT);
|
|
|
|
gtk_box_pack_start(GTK_BOX(bbox), save_bt, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show(save_bt);
|
|
|
|
|
|
|
|
cancel_bt = gtk_button_new_with_label ("Cancel");
|
|
|
|
gtk_signal_connect(GTK_OBJECT(cancel_bt), "clicked",
|
|
|
|
GTK_SIGNAL_FUNC(filter_dlg_cancel), GTK_OBJECT(main_w));
|
|
|
|
GTK_WIDGET_SET_FLAGS(cancel_bt, GTK_CAN_DEFAULT);
|
|
|
|
gtk_box_pack_start(GTK_BOX(bbox), cancel_bt, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show(cancel_bt);
|
|
|
|
|
|
|
|
gtk_widget_show(main_w);
|
Split "filter_dialog_cb()" into "filter_dialog_cb()", which pops up a
"global" dialog box when "Edit:Filters" is selected, so that the list of
filters can be edited, and "filter_browse_cb()", which pops up a dialog
box associated with a "Filter:" button and a text entry widget attached
to that button, so that a filter can be selected or saved (although it
also supports the same editing that the "global" dialog box does).
Have "filter_dialog_cb()" connect the window in which the "Filter:"
button lives and the filter dialog box, so that:
if the window in which the "Filter:" button lives goes away, so
does the filter dialog box (as it no longer has a text widget
into which it can stuff the selected filter);
if the "Filter:" button is clicked when there's already a filter
dialog box open, we just reactivate that existing dialog box
rather than popping up a new one.
Also keep a pointer to the "global" filter dialog box, so that we also
arrange that there's only one of them (by reactivating the existing on
if "Edit:Filters" is selected when there's already a "global" filter
dialog box open).
Keep around pointers to the dialog boxes that contain the "Filter:"
buttons, so that we can arrange that there be only one of them (that was
a side-effect of an earlier attempt at fixing the problems described
above, but it's still useful for keeping multiple competing dialog boxes
from being open - there's more of that to be done).
Make the pointer to the "Open Capture File" dialog box widget static to
"file_dlg.c" - nobody outside of "file_dlg.c cares about it.
svn path=/trunk/; revision=1774
2000-04-01 12:03:42 +00:00
|
|
|
|
|
|
|
return main_w;
|
1999-12-10 06:28:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
filter_dlg_ok(GtkWidget *ok_bt, gpointer parent_w)
|
|
|
|
{
|
|
|
|
filter_prefs_ok(gtk_object_get_data(GTK_OBJECT(parent_w), E_FILTER_WIDGET_KEY));
|
|
|
|
gtk_widget_destroy(GTK_WIDGET(parent_w));
|
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-12-10 06:28:24 +00:00
|
|
|
static void
|
|
|
|
filter_dlg_save(GtkWidget *save_bt, gpointer parent_w)
|
|
|
|
{
|
|
|
|
filter_prefs_save(gtk_object_get_data(GTK_OBJECT(parent_w), E_FILTER_WIDGET_KEY));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
filter_dlg_cancel(GtkWidget *cancel_bt, gpointer parent_w)
|
|
|
|
{
|
|
|
|
filter_prefs_cancel(gtk_object_get_data(GTK_OBJECT(parent_w), E_FILTER_WIDGET_KEY));
|
|
|
|
gtk_widget_destroy(GTK_WIDGET(parent_w));
|
|
|
|
}
|
Split "filter_dialog_cb()" into "filter_dialog_cb()", which pops up a
"global" dialog box when "Edit:Filters" is selected, so that the list of
filters can be edited, and "filter_browse_cb()", which pops up a dialog
box associated with a "Filter:" button and a text entry widget attached
to that button, so that a filter can be selected or saved (although it
also supports the same editing that the "global" dialog box does).
Have "filter_dialog_cb()" connect the window in which the "Filter:"
button lives and the filter dialog box, so that:
if the window in which the "Filter:" button lives goes away, so
does the filter dialog box (as it no longer has a text widget
into which it can stuff the selected filter);
if the "Filter:" button is clicked when there's already a filter
dialog box open, we just reactivate that existing dialog box
rather than popping up a new one.
Also keep a pointer to the "global" filter dialog box, so that we also
arrange that there's only one of them (by reactivating the existing on
if "Edit:Filters" is selected when there's already a "global" filter
dialog box open).
Keep around pointers to the dialog boxes that contain the "Filter:"
buttons, so that we can arrange that there be only one of them (that was
a side-effect of an earlier attempt at fixing the problems described
above, but it's still useful for keeping multiple competing dialog boxes
from being open - there's more of that to be done).
Make the pointer to the "Open Capture File" dialog box widget static to
"file_dlg.c" - nobody outside of "file_dlg.c cares about it.
svn path=/trunk/; revision=1774
2000-04-01 12:03:42 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
filter_dlg_destroy(GtkWidget *win, gpointer data)
|
|
|
|
{
|
|
|
|
GtkWidget *caller;
|
|
|
|
|
|
|
|
/* Get the widget that requested that we be popped up, if any.
|
|
|
|
(It should arrange to destroy us if it's destroyed, so
|
|
|
|
that we don't get a pointer to a non-existent window here.) */
|
|
|
|
caller = gtk_object_get_data(GTK_OBJECT(win), E_FILT_CALLER_PTR_KEY);
|
|
|
|
|
|
|
|
if (caller != NULL) {
|
|
|
|
/* Tell it we no longer exist. */
|
|
|
|
gtk_object_set_data(GTK_OBJECT(caller), E_FILT_DIALOG_PTR_KEY,
|
|
|
|
NULL);
|
|
|
|
} else {
|
|
|
|
/* This is an editing dialog popped up from, for example,
|
|
|
|
a menu item; note that we no longer have one. */
|
|
|
|
g_assert(win == global_filter_w);
|
|
|
|
global_filter_w = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now nuke this window. */
|
|
|
|
gtk_grab_remove(GTK_WIDGET(win));
|
|
|
|
gtk_widget_destroy(GTK_WIDGET(win));
|
|
|
|
}
|
|
|
|
|
1998-11-17 04:29:13 +00:00
|
|
|
/* Create and display the filter selection widgets. */
|
2000-02-12 06:46:54 +00:00
|
|
|
static GtkWidget *
|
1998-10-13 02:10:57 +00:00
|
|
|
filter_prefs_show(GtkWidget *w) {
|
1998-10-10 03:32:20 +00:00
|
|
|
GtkWidget *main_vb, *top_hb, *list_bb, *new_bt, *filter_sc,
|
|
|
|
*nl_item, *nl_lb, *middle_hb, *name_lb, *bottom_hb,
|
|
|
|
*filter_lb;
|
|
|
|
GtkWidget *l_select = NULL;
|
|
|
|
GList *flp = NULL;
|
|
|
|
filter_def *filt;
|
1998-10-13 02:10:57 +00:00
|
|
|
gchar *filter_te_str = NULL;
|
|
|
|
|
|
|
|
/* Make sure everything is set up */
|
|
|
|
get_filter_list();
|
|
|
|
if (w)
|
|
|
|
filter_te_str = gtk_entry_get_text(GTK_ENTRY(w));
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
/* Container for each row of widgets */
|
|
|
|
main_vb = gtk_vbox_new(FALSE, 5);
|
|
|
|
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
|
|
|
gtk_widget_show(main_vb);
|
1998-10-13 02:10:57 +00:00
|
|
|
gtk_object_set_data(GTK_OBJECT(main_vb), E_FILT_CM_KEY, (gpointer)FALSE);
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
/* Top row: Filter list and buttons */
|
|
|
|
top_hb = gtk_hbox_new(FALSE, 5);
|
|
|
|
gtk_container_add(GTK_CONTAINER(main_vb), top_hb);
|
|
|
|
gtk_widget_show(top_hb);
|
|
|
|
|
|
|
|
list_bb = gtk_vbutton_box_new();
|
|
|
|
gtk_button_box_set_layout (GTK_BUTTON_BOX (list_bb), GTK_BUTTONBOX_START);
|
|
|
|
gtk_container_add(GTK_CONTAINER(top_hb), list_bb);
|
|
|
|
gtk_widget_show(list_bb);
|
|
|
|
|
|
|
|
new_bt = gtk_button_new_with_label ("New");
|
|
|
|
gtk_signal_connect(GTK_OBJECT(new_bt), "clicked",
|
|
|
|
GTK_SIGNAL_FUNC(filter_sel_new_cb), NULL);
|
|
|
|
gtk_container_add(GTK_CONTAINER(list_bb), new_bt);
|
|
|
|
gtk_widget_show(new_bt);
|
|
|
|
|
|
|
|
chg_bt = gtk_button_new_with_label ("Change");
|
|
|
|
gtk_widget_set_sensitive(chg_bt, FALSE);
|
|
|
|
gtk_signal_connect(GTK_OBJECT(chg_bt), "clicked",
|
|
|
|
GTK_SIGNAL_FUNC(filter_sel_chg_cb), NULL);
|
|
|
|
gtk_container_add(GTK_CONTAINER(list_bb), chg_bt);
|
|
|
|
gtk_widget_show(chg_bt);
|
|
|
|
|
|
|
|
copy_bt = gtk_button_new_with_label ("Copy");
|
|
|
|
gtk_widget_set_sensitive(copy_bt, FALSE);
|
|
|
|
gtk_signal_connect(GTK_OBJECT(copy_bt), "clicked",
|
|
|
|
GTK_SIGNAL_FUNC(filter_sel_copy_cb), NULL);
|
|
|
|
gtk_container_add(GTK_CONTAINER(list_bb), copy_bt);
|
|
|
|
gtk_widget_show(copy_bt);
|
|
|
|
|
|
|
|
del_bt = gtk_button_new_with_label ("Delete");
|
|
|
|
gtk_widget_set_sensitive(del_bt, FALSE);
|
|
|
|
gtk_signal_connect(GTK_OBJECT(del_bt), "clicked",
|
|
|
|
GTK_SIGNAL_FUNC(filter_sel_del_cb), NULL);
|
|
|
|
gtk_container_add(GTK_CONTAINER(list_bb), del_bt);
|
|
|
|
gtk_widget_show(del_bt);
|
1999-12-10 06:28:24 +00:00
|
|
|
|
|
|
|
apply_bt = gtk_button_new_with_label("Apply");
|
|
|
|
gtk_widget_set_sensitive(apply_bt, FALSE);
|
|
|
|
gtk_signal_connect(GTK_OBJECT(apply_bt), "clicked",
|
|
|
|
GTK_SIGNAL_FUNC(filter_sel_apply_cb), w);
|
|
|
|
gtk_container_add(GTK_CONTAINER(list_bb), apply_bt);
|
|
|
|
gtk_widget_show(apply_bt);
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
filter_sc = gtk_scrolled_window_new(NULL, NULL);
|
|
|
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(filter_sc),
|
|
|
|
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
|
|
|
gtk_widget_set_usize(filter_sc, 250, 150);
|
|
|
|
gtk_container_add(GTK_CONTAINER(top_hb), filter_sc);
|
|
|
|
gtk_widget_show(filter_sc);
|
|
|
|
|
|
|
|
filter_l = gtk_list_new();
|
1998-11-17 04:29:13 +00:00
|
|
|
gtk_list_set_selection_mode(GTK_LIST(filter_l), GTK_SELECTION_SINGLE);
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_signal_connect(GTK_OBJECT(filter_l), "selection_changed",
|
1998-10-10 03:32:20 +00:00
|
|
|
GTK_SIGNAL_FUNC(filter_sel_list_cb), main_vb);
|
1998-12-27 20:44:53 +00:00
|
|
|
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(filter_sc),
|
|
|
|
filter_l);
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_widget_show(filter_l);
|
|
|
|
|
|
|
|
flp = g_list_first(fl);
|
|
|
|
while (flp) {
|
|
|
|
filt = (filter_def *) flp->data;
|
|
|
|
nl_lb = gtk_label_new(filt->name);
|
|
|
|
nl_item = gtk_list_item_new();
|
|
|
|
gtk_misc_set_alignment (GTK_MISC (nl_lb), 0.0, 0.5);
|
|
|
|
gtk_container_add(GTK_CONTAINER(nl_item), nl_lb);
|
|
|
|
gtk_widget_show(nl_lb);
|
|
|
|
gtk_container_add(GTK_CONTAINER(filter_l), nl_item);
|
|
|
|
gtk_widget_show(nl_item);
|
1998-10-13 02:10:57 +00:00
|
|
|
gtk_object_set_data(GTK_OBJECT(nl_item), E_FILT_LBL_KEY, nl_lb);
|
|
|
|
gtk_object_set_data(GTK_OBJECT(nl_item), E_FILT_NAME_KEY, flp);
|
|
|
|
|
|
|
|
if (filter_te_str && filt->strval)
|
|
|
|
if (strcmp(filter_te_str, filt->strval) == 0)
|
1998-09-16 02:39:15 +00:00
|
|
|
l_select = nl_item;
|
1998-10-13 02:10:57 +00:00
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
flp = flp->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Middle row: Filter name entry */
|
|
|
|
middle_hb = gtk_hbox_new(FALSE, 5);
|
|
|
|
gtk_container_add(GTK_CONTAINER(main_vb), middle_hb);
|
|
|
|
gtk_widget_show(middle_hb);
|
|
|
|
|
|
|
|
name_lb = gtk_label_new("Filter name:");
|
|
|
|
gtk_box_pack_start(GTK_BOX(middle_hb), name_lb, FALSE, FALSE, 3);
|
|
|
|
gtk_widget_show(name_lb);
|
|
|
|
|
|
|
|
name_te = gtk_entry_new();
|
|
|
|
gtk_box_pack_start(GTK_BOX(middle_hb), name_te, TRUE, TRUE, 3);
|
|
|
|
gtk_widget_show(name_te);
|
|
|
|
|
|
|
|
/* Bottom row: Filter text entry */
|
|
|
|
bottom_hb = gtk_hbox_new(FALSE, 5);
|
|
|
|
gtk_container_add(GTK_CONTAINER(main_vb), bottom_hb);
|
|
|
|
gtk_widget_show(bottom_hb);
|
|
|
|
|
|
|
|
filter_lb = gtk_label_new("Filter string:");
|
|
|
|
gtk_box_pack_start(GTK_BOX(bottom_hb), filter_lb, FALSE, FALSE, 3);
|
|
|
|
gtk_widget_show(filter_lb);
|
|
|
|
|
|
|
|
filter_te = gtk_entry_new();
|
|
|
|
gtk_box_pack_start(GTK_BOX(bottom_hb), filter_te, TRUE, TRUE, 3);
|
|
|
|
gtk_widget_show(filter_te);
|
|
|
|
|
|
|
|
if (l_select)
|
1998-10-16 01:18:35 +00:00
|
|
|
{
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_list_select_child(GTK_LIST(filter_l), l_select);
|
1998-10-16 01:18:35 +00:00
|
|
|
} else if (filter_te_str && filter_te_str[0]) {
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(name_te), "New filter");
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(filter_te), filter_te_str);
|
|
|
|
}
|
1998-10-10 03:32:20 +00:00
|
|
|
|
|
|
|
return(main_vb);
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
|
2000-02-12 06:46:54 +00:00
|
|
|
static void
|
1998-09-16 02:39:15 +00:00
|
|
|
filter_sel_list_cb(GtkWidget *l, gpointer data) {
|
|
|
|
filter_def *filt;
|
|
|
|
gchar *name = "", *strval = "";
|
|
|
|
GList *sl, *flp;
|
|
|
|
GtkObject *l_item;
|
|
|
|
gint sensitivity = FALSE;
|
|
|
|
|
1998-12-22 07:07:11 +00:00
|
|
|
if (l)
|
|
|
|
sl = GTK_LIST(l)->selection;
|
|
|
|
else
|
|
|
|
sl = NULL;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
if (sl) { /* Something was selected */
|
|
|
|
l_item = GTK_OBJECT(sl->data);
|
1998-10-13 02:10:57 +00:00
|
|
|
flp = (GList *) gtk_object_get_data(l_item, E_FILT_NAME_KEY);
|
1998-09-16 02:39:15 +00:00
|
|
|
if (flp) {
|
|
|
|
filt = (filter_def *) flp->data;
|
|
|
|
name = filt->name;
|
|
|
|
strval = filt->strval;
|
|
|
|
sensitivity = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Did you know that this function is called when the window is destroyed? */
|
|
|
|
/* Funny, that. */
|
1998-10-13 02:10:57 +00:00
|
|
|
if (!gtk_object_get_data(GTK_OBJECT(data), E_FILT_CM_KEY)) {
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_entry_set_text(GTK_ENTRY(name_te), name);
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(filter_te), strval);
|
|
|
|
gtk_widget_set_sensitive(chg_bt, sensitivity);
|
|
|
|
gtk_widget_set_sensitive(copy_bt, sensitivity);
|
|
|
|
gtk_widget_set_sensitive(del_bt, sensitivity);
|
1999-12-10 06:28:24 +00:00
|
|
|
gtk_widget_set_sensitive(apply_bt, sensitivity);
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* To do: add input checking to each of these callbacks */
|
|
|
|
|
2000-02-12 06:46:54 +00:00
|
|
|
static void
|
1998-09-16 02:39:15 +00:00
|
|
|
filter_sel_new_cb(GtkWidget *w, gpointer data) {
|
|
|
|
filter_def *filt;
|
|
|
|
gchar *name, *strval;
|
|
|
|
GtkWidget *nl_item, *nl_lb;
|
|
|
|
|
|
|
|
name = gtk_entry_get_text(GTK_ENTRY(name_te));
|
|
|
|
strval = gtk_entry_get_text(GTK_ENTRY(filter_te));
|
|
|
|
|
|
|
|
if (strlen(name) > 0 && strlen(strval) > 0) {
|
|
|
|
filt = (filter_def *) g_malloc(sizeof(filter_def));
|
|
|
|
filt->name = g_strdup(name);
|
|
|
|
filt->strval = g_strdup(strval);
|
|
|
|
fl = g_list_append(fl, filt);
|
|
|
|
nl_lb = gtk_label_new(filt->name);
|
|
|
|
nl_item = gtk_list_item_new();
|
|
|
|
gtk_misc_set_alignment (GTK_MISC (nl_lb), 0.0, 0.5);
|
|
|
|
gtk_container_add(GTK_CONTAINER(nl_item), nl_lb);
|
|
|
|
gtk_widget_show(nl_lb);
|
|
|
|
gtk_container_add(GTK_CONTAINER(filter_l), nl_item);
|
|
|
|
gtk_widget_show(nl_item);
|
1998-10-13 02:10:57 +00:00
|
|
|
gtk_object_set_data(GTK_OBJECT(nl_item), E_FILT_LBL_KEY, nl_lb);
|
|
|
|
gtk_object_set_data(GTK_OBJECT(nl_item), E_FILT_NAME_KEY, g_list_last(fl));
|
|
|
|
gtk_list_select_child(GTK_LIST(filter_l), nl_item);
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-02-12 06:46:54 +00:00
|
|
|
static void
|
1998-09-16 02:39:15 +00:00
|
|
|
filter_sel_chg_cb(GtkWidget *w, gpointer data) {
|
|
|
|
filter_def *filt;
|
|
|
|
gchar *name = "", *strval = "";
|
|
|
|
GList *sl, *flp;
|
|
|
|
GtkObject *l_item;
|
|
|
|
GtkLabel *nl_lb;
|
|
|
|
|
|
|
|
sl = GTK_LIST(filter_l)->selection;
|
|
|
|
name = gtk_entry_get_text(GTK_ENTRY(name_te));
|
|
|
|
strval = gtk_entry_get_text(GTK_ENTRY(filter_te));
|
|
|
|
|
|
|
|
if (sl) { /* Something was selected */
|
|
|
|
l_item = GTK_OBJECT(sl->data);
|
1998-10-13 02:10:57 +00:00
|
|
|
flp = (GList *) gtk_object_get_data(l_item, E_FILT_NAME_KEY);
|
|
|
|
nl_lb = (GtkLabel *) gtk_object_get_data(l_item, E_FILT_LBL_KEY);
|
1998-09-16 02:39:15 +00:00
|
|
|
if (flp && nl_lb) {
|
|
|
|
filt = (filter_def *) flp->data;
|
|
|
|
|
|
|
|
if (strlen(name) > 0 && strlen(strval) > 0 && filt) {
|
|
|
|
g_free(filt->name);
|
|
|
|
g_free(filt->strval);
|
|
|
|
filt->name = g_strdup(name);
|
|
|
|
filt->strval = g_strdup(strval);
|
|
|
|
gtk_label_set(nl_lb, filt->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-02-12 06:46:54 +00:00
|
|
|
static void
|
1998-09-16 02:39:15 +00:00
|
|
|
filter_sel_copy_cb(GtkWidget *w, gpointer data) {
|
1998-09-27 22:12:47 +00:00
|
|
|
GList *sl, *flp;
|
1998-09-16 02:39:15 +00:00
|
|
|
filter_def *filt, *nfilt;
|
1998-09-27 22:12:47 +00:00
|
|
|
gchar *prefix = "Copy of ";
|
1998-09-16 02:39:15 +00:00
|
|
|
GtkObject *l_item;
|
|
|
|
GtkWidget *nl_item, *nl_lb;
|
|
|
|
|
|
|
|
sl = GTK_LIST(filter_l)->selection;
|
|
|
|
if (sl) { /* Something was selected */
|
|
|
|
l_item = GTK_OBJECT(sl->data);
|
1998-10-13 02:10:57 +00:00
|
|
|
flp = (GList *) gtk_object_get_data(l_item, E_FILT_NAME_KEY);
|
1998-09-16 02:39:15 +00:00
|
|
|
if (flp) {
|
|
|
|
filt = (filter_def *) flp->data;
|
|
|
|
nfilt = (filter_def *) g_malloc(sizeof(filter_def));
|
|
|
|
nfilt->name = g_malloc(strlen(prefix) + strlen(filt->name) + 1);
|
|
|
|
sprintf(nfilt->name, "%s%s", prefix, filt->name);
|
|
|
|
nfilt->strval = g_strdup(filt->strval);
|
|
|
|
fl = g_list_append(fl, nfilt);
|
|
|
|
nl_lb = gtk_label_new(nfilt->name);
|
|
|
|
nl_item = gtk_list_item_new();
|
|
|
|
gtk_misc_set_alignment (GTK_MISC (nl_lb), 0.0, 0.5);
|
|
|
|
gtk_container_add(GTK_CONTAINER(nl_item), nl_lb);
|
|
|
|
gtk_widget_show(nl_lb);
|
|
|
|
gtk_container_add(GTK_CONTAINER(filter_l), nl_item);
|
|
|
|
gtk_widget_show(nl_item);
|
1998-10-13 02:10:57 +00:00
|
|
|
gtk_object_set_data(GTK_OBJECT(nl_item), E_FILT_LBL_KEY, nl_lb);
|
|
|
|
gtk_object_set_data(GTK_OBJECT(nl_item), E_FILT_NAME_KEY, g_list_last(fl));
|
|
|
|
gtk_list_select_child(GTK_LIST(filter_l), nl_item);
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-02-12 06:46:54 +00:00
|
|
|
static void
|
1998-09-16 02:39:15 +00:00
|
|
|
filter_sel_del_cb(GtkWidget *w, gpointer data) {
|
|
|
|
GList *sl, *flp;
|
|
|
|
filter_def *filt;
|
|
|
|
GtkObject *l_item;
|
|
|
|
gint pos;
|
|
|
|
|
|
|
|
sl = GTK_LIST(filter_l)->selection;
|
|
|
|
if (sl) { /* Something was selected */
|
|
|
|
l_item = GTK_OBJECT(sl->data);
|
|
|
|
pos = gtk_list_child_position(GTK_LIST(filter_l),
|
|
|
|
GTK_WIDGET(l_item));
|
1998-10-13 02:10:57 +00:00
|
|
|
flp = (GList *) gtk_object_get_data(l_item, E_FILT_NAME_KEY);
|
1998-09-16 02:39:15 +00:00
|
|
|
if (flp) {
|
|
|
|
filt = (filter_def *) flp->data;
|
|
|
|
g_free(filt->name);
|
|
|
|
g_free(filt->strval);
|
|
|
|
g_free(filt);
|
1999-09-19 14:27:44 +00:00
|
|
|
fl = g_list_remove_link(fl, flp);
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_list_clear_items(GTK_LIST(filter_l), pos, pos + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-12-10 06:28:24 +00:00
|
|
|
void
|
|
|
|
filter_sel_apply_cb(GtkWidget *w, gpointer data)
|
|
|
|
{
|
|
|
|
GList *flp, *sl;
|
|
|
|
GtkObject *l_item;
|
|
|
|
filter_def *filt;
|
|
|
|
GtkWidget *mw_filt = data;
|
|
|
|
|
|
|
|
sl = GTK_LIST(filter_l)->selection;
|
|
|
|
if (sl != NULL && mw_filt != NULL) { /* Place something in the filter box. */
|
|
|
|
l_item = GTK_OBJECT(sl->data);
|
|
|
|
flp = (GList *) gtk_object_get_data(l_item, E_FILT_NAME_KEY);
|
|
|
|
if (flp) {
|
|
|
|
filt = (filter_def *) flp->data;
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(mw_filt), filt->strval);
|
|
|
|
gtk_signal_emit_by_name(GTK_OBJECT(mw_filt), "activate");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-02-12 06:46:54 +00:00
|
|
|
static void
|
1998-10-10 03:32:20 +00:00
|
|
|
filter_prefs_ok(GtkWidget *w) {
|
1998-09-16 02:39:15 +00:00
|
|
|
GList *flp, *sl;
|
|
|
|
GtkObject *l_item;
|
|
|
|
filter_def *filt;
|
1998-10-12 01:40:57 +00:00
|
|
|
GtkWidget *mw_filt = gtk_object_get_data(GTK_OBJECT(w), E_FILT_TE_PTR_KEY);
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
sl = GTK_LIST(filter_l)->selection;
|
1998-10-12 01:40:57 +00:00
|
|
|
if (sl && mw_filt) { /* Place something in the filter box. */
|
1998-09-16 02:39:15 +00:00
|
|
|
l_item = GTK_OBJECT(sl->data);
|
1998-10-13 02:10:57 +00:00
|
|
|
flp = (GList *) gtk_object_get_data(l_item, E_FILT_NAME_KEY);
|
1998-09-16 02:39:15 +00:00
|
|
|
if (flp) {
|
|
|
|
filt = (filter_def *) flp->data;
|
1998-10-12 01:40:57 +00:00
|
|
|
gtk_entry_set_text(GTK_ENTRY(mw_filt), filt->strval);
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
We need to catch a "window delete" event for the preferences dialog box
- that event happens if, say, you nuke the dialog box from a window
manager - and call "delete" routines for each of the preferences tabs,
so that, for preferences tabs that include list widgets, we can set a
flag on the preferences tab widget telling the selection callback for
the list widget that the buttons it would normally set the sensitivity
of, based on whether any row in the list is selected or not, have Joined
the Choir Invisible, and therefore that we shouldn't change their
sensitivity because GTK+ will whine at us if we do, just as is the case
if we press the "OK" or "Cancel" button (which also cause the window to
go away).
Can we just do this in the "window delete" handler? I.e., does that get
called if we explicitly destroy the widget? Or should we catch a
"destroy" event instead?
(There must be a better way to do this....)
svn path=/trunk/; revision=647
1999-09-10 06:53:32 +00:00
|
|
|
filter_prefs_delete(w);
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
|
2000-02-12 06:46:54 +00:00
|
|
|
static void
|
1998-10-10 03:32:20 +00:00
|
|
|
filter_prefs_save(GtkWidget *w) {
|
1998-09-16 02:39:15 +00:00
|
|
|
GList *flp;
|
|
|
|
filter_def *filt;
|
1998-11-17 04:29:13 +00:00
|
|
|
gchar *ff_path, *ff_dir = PF_DIR, *ff_name = "filters";
|
1998-09-16 02:39:15 +00:00
|
|
|
FILE *ff;
|
|
|
|
struct stat s_buf;
|
|
|
|
|
2000-01-29 16:41:28 +00:00
|
|
|
ff_path = (gchar *) g_malloc(strlen(get_home_dir()) + strlen(ff_dir) +
|
1998-09-16 02:39:15 +00:00
|
|
|
strlen(ff_name) + 4);
|
2000-01-29 16:41:28 +00:00
|
|
|
sprintf(ff_path, "%s/%s", get_home_dir(), ff_dir);
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
if (stat(ff_path, &s_buf) != 0)
|
1999-07-13 02:53:26 +00:00
|
|
|
#ifdef WIN32
|
|
|
|
mkdir(ff_path);
|
|
|
|
#else
|
1998-09-16 02:39:15 +00:00
|
|
|
mkdir(ff_path, 0755);
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2000-01-29 16:41:28 +00:00
|
|
|
sprintf(ff_path, "%s/%s/%s", get_home_dir(), ff_dir, ff_name);
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
if ((ff = fopen(ff_path, "w")) != NULL) {
|
|
|
|
flp = g_list_first(fl);
|
|
|
|
while (flp) {
|
|
|
|
filt = (filter_def *) flp->data;
|
|
|
|
fprintf(ff, "\"%s\" %s\n", filt->name, filt->strval);
|
|
|
|
flp = flp->next;
|
|
|
|
}
|
|
|
|
fclose(ff);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free(ff_path);
|
|
|
|
}
|
|
|
|
|
2000-02-12 06:46:54 +00:00
|
|
|
static void
|
1998-10-10 03:32:20 +00:00
|
|
|
filter_prefs_cancel(GtkWidget *w) {
|
We need to catch a "window delete" event for the preferences dialog box
- that event happens if, say, you nuke the dialog box from a window
manager - and call "delete" routines for each of the preferences tabs,
so that, for preferences tabs that include list widgets, we can set a
flag on the preferences tab widget telling the selection callback for
the list widget that the buttons it would normally set the sensitivity
of, based on whether any row in the list is selected or not, have Joined
the Choir Invisible, and therefore that we shouldn't change their
sensitivity because GTK+ will whine at us if we do, just as is the case
if we press the "OK" or "Cancel" button (which also cause the window to
go away).
Can we just do this in the "window delete" handler? I.e., does that get
called if we explicitly destroy the widget? Or should we catch a
"destroy" event instead?
(There must be a better way to do this....)
svn path=/trunk/; revision=647
1999-09-10 06:53:32 +00:00
|
|
|
|
|
|
|
filter_prefs_delete(w);
|
|
|
|
}
|
|
|
|
|
2000-02-12 06:46:54 +00:00
|
|
|
static void
|
We need to catch a "window delete" event for the preferences dialog box
- that event happens if, say, you nuke the dialog box from a window
manager - and call "delete" routines for each of the preferences tabs,
so that, for preferences tabs that include list widgets, we can set a
flag on the preferences tab widget telling the selection callback for
the list widget that the buttons it would normally set the sensitivity
of, based on whether any row in the list is selected or not, have Joined
the Choir Invisible, and therefore that we shouldn't change their
sensitivity because GTK+ will whine at us if we do, just as is the case
if we press the "OK" or "Cancel" button (which also cause the window to
go away).
Can we just do this in the "window delete" handler? I.e., does that get
called if we explicitly destroy the widget? Or should we catch a
"destroy" event instead?
(There must be a better way to do this....)
svn path=/trunk/; revision=647
1999-09-10 06:53:32 +00:00
|
|
|
filter_prefs_delete(GtkWidget *w) {
|
1998-10-13 07:03:37 +00:00
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
/* Let the list cb know we're about to destroy the widget tree, so it */
|
|
|
|
/* doesn't operate on widgets that don't exist. */
|
1998-10-13 02:10:57 +00:00
|
|
|
gtk_object_set_data(GTK_OBJECT(w), E_FILT_CM_KEY, (gpointer)TRUE);
|
1998-10-10 03:32:20 +00:00
|
|
|
gtk_widget_destroy(GTK_WIDGET(w));
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|