2007-01-29 10:25:54 +00:00
|
|
|
/*
|
|
|
|
* uat_gui.c
|
|
|
|
*
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* User Accessible Tables GUI
|
|
|
|
* Mantain an array of user accessible data strucures
|
2012-09-18 21:51:22 +00:00
|
|
|
*
|
2008-08-05 21:03:46 +00:00
|
|
|
* (c) 2007, Luis E. Garcia Ontanon <luis@ontanon.org>
|
2007-01-29 10:25:54 +00:00
|
|
|
*
|
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
|
|
* Copyright 2001 Gerald Combs
|
2012-09-18 21:51:22 +00:00
|
|
|
*
|
2007-01-29 10:25:54 +00:00
|
|
|
* 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.
|
2012-09-18 21:51:22 +00:00
|
|
|
*
|
2007-01-29 10:25:54 +00:00
|
|
|
* 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.
|
2012-09-18 21:51:22 +00:00
|
|
|
*
|
2007-01-29 10:25:54 +00:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
2012-06-28 22:56:06 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2007-01-29 10:25:54 +00:00
|
|
|
*/
|
2007-02-07 03:39:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* TO DO:
|
|
|
|
* + improvements
|
|
|
|
* - field value check (red/green editbox)
|
|
|
|
* - tooltips (add field descriptions)
|
2010-04-30 22:33:51 +00:00
|
|
|
* - Make cells editable
|
|
|
|
* - Allow reordering via drag and drop
|
2007-02-07 03:39:40 +00:00
|
|
|
*/
|
|
|
|
|
2012-09-20 01:48:30 +00:00
|
|
|
#include "config.h"
|
2007-01-29 10:25:54 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <math.h>
|
2008-04-13 03:32:24 +00:00
|
|
|
|
2007-01-29 10:25:54 +00:00
|
|
|
#include <gtk/gtk.h>
|
2008-04-13 03:32:24 +00:00
|
|
|
#include <gdk/gdkkeysyms.h>
|
2011-06-20 00:48:05 +00:00
|
|
|
#if GTK_CHECK_VERSION(3,0,0)
|
|
|
|
# include <gdk/gdkkeysyms-compat.h>
|
|
|
|
#endif
|
2008-04-13 03:32:24 +00:00
|
|
|
|
2007-01-29 10:25:54 +00:00
|
|
|
#include <epan/dfilter/dfilter-macro.h>
|
2007-01-29 14:14:01 +00:00
|
|
|
#include <epan/emem.h>
|
|
|
|
#include <epan/report_err.h>
|
2007-02-09 03:11:14 +00:00
|
|
|
#include <epan/proto.h>
|
|
|
|
#include <epan/packet.h>
|
2007-01-29 10:25:54 +00:00
|
|
|
#include <epan/uat-int.h>
|
2007-02-07 03:39:40 +00:00
|
|
|
#include <epan/value_string.h>
|
2011-10-09 09:55:14 +00:00
|
|
|
#include <epan/filesystem.h>
|
2008-04-13 03:32:24 +00:00
|
|
|
|
|
|
|
#include "../stat_menu.h"
|
|
|
|
|
2012-09-18 21:51:22 +00:00
|
|
|
#include "ui/help_url.h"
|
2012-01-15 21:59:11 +00:00
|
|
|
#include "ui/gtk/gtkglobals.h"
|
|
|
|
#include "ui/gtk/gui_utils.h"
|
|
|
|
#include "ui/gtk/dlg_utils.h"
|
|
|
|
#include "ui/gtk/stock_icons.h"
|
|
|
|
#include "ui/gtk/gui_stat_menu.h"
|
|
|
|
#include "ui/gtk/main.h"
|
|
|
|
#include "ui/gtk/uat_gui.h"
|
2012-09-04 01:57:36 +00:00
|
|
|
#include "ui/gtk/packet_list.h"
|
2012-09-18 21:51:22 +00:00
|
|
|
#include "ui/gtk/webbrowser.h"
|
2012-01-15 21:59:11 +00:00
|
|
|
#include "ui/gtk/old-gtk-compat.h"
|
2013-03-24 16:47:38 +00:00
|
|
|
#include "ui/gtk/packet_win.h"
|
2007-01-29 10:25:54 +00:00
|
|
|
|
|
|
|
# define BUTTON_SIZE_X -1
|
|
|
|
# define BUTTON_SIZE_Y -1
|
|
|
|
|
|
|
|
struct _uat_rep_t {
|
2013-01-24 18:28:31 +00:00
|
|
|
GtkWidget *window;
|
|
|
|
GtkWidget *vbox;
|
|
|
|
GtkWidget *scrolledwindow;
|
|
|
|
GtkTreeView *list;
|
2010-04-30 22:33:51 +00:00
|
|
|
GtkListStore *list_store;
|
2013-01-24 18:28:31 +00:00
|
|
|
GtkWidget *bbox;
|
|
|
|
GtkWidget *bt_new;
|
|
|
|
GtkWidget *bt_edit;
|
|
|
|
GtkWidget *bt_copy;
|
|
|
|
GtkWidget *bt_delete;
|
|
|
|
GtkWidget *bt_refresh;
|
|
|
|
GtkWidget *bt_clear;
|
|
|
|
GtkWidget *bt_up;
|
|
|
|
GtkWidget *bt_down;
|
|
|
|
GtkWidget *bt_apply;
|
|
|
|
GtkWidget *bt_cancel;
|
|
|
|
GtkWidget *bt_ok;
|
|
|
|
GtkWidget *unsaved_window;
|
|
|
|
|
|
|
|
gint selected;
|
2007-01-29 10:25:54 +00:00
|
|
|
};
|
|
|
|
|
2007-01-29 14:14:01 +00:00
|
|
|
struct _str_pair {
|
2013-01-24 18:28:31 +00:00
|
|
|
const char *ptr;
|
|
|
|
guint len;
|
2007-01-29 14:14:01 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct _uat_dlg_data {
|
2013-01-24 18:28:31 +00:00
|
|
|
GtkWidget *win;
|
|
|
|
GPtrArray *entries;
|
|
|
|
uat_t *uat;
|
|
|
|
void *rec;
|
|
|
|
gboolean is_new;
|
|
|
|
gint row;
|
|
|
|
GPtrArray *tobe_freed;
|
2007-01-29 14:14:01 +00:00
|
|
|
};
|
|
|
|
|
2007-02-05 04:22:06 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
static gboolean unsaved_dialog(GtkWindow *w, GdkEvent *e, gpointer u);
|
|
|
|
static gboolean uat_window_delete_event_cb(GtkWindow *w, GdkEvent *e, gpointer u);
|
2007-02-05 04:22:06 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
static void set_buttons(uat_t *uat, gint row) {
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-03-04 02:27:11 +00:00
|
|
|
if (!uat->rep) return;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-05 04:22:06 +00:00
|
|
|
if (row > 0) {
|
|
|
|
gtk_widget_set_sensitive (uat->rep->bt_up, TRUE);
|
|
|
|
} else {
|
|
|
|
gtk_widget_set_sensitive (uat->rep->bt_up, FALSE);
|
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-04-22 02:10:49 +00:00
|
|
|
if (row < (gint)(uat->raw_data->len - 1) && row >= 0) {
|
2007-02-05 04:22:06 +00:00
|
|
|
gtk_widget_set_sensitive (uat->rep->bt_down, TRUE);
|
|
|
|
} else {
|
|
|
|
gtk_widget_set_sensitive (uat->rep->bt_down, FALSE);
|
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2009-12-27 13:26:00 +00:00
|
|
|
if (row < 0) {
|
|
|
|
gtk_widget_set_sensitive (uat->rep->bt_edit, FALSE);
|
2010-10-29 19:48:51 +00:00
|
|
|
gtk_widget_set_sensitive (uat->rep->bt_copy, FALSE);
|
2009-12-27 13:26:00 +00:00
|
|
|
gtk_widget_set_sensitive (uat->rep->bt_delete, FALSE);
|
|
|
|
}
|
|
|
|
|
2007-02-05 04:22:06 +00:00
|
|
|
if (uat->changed) {
|
2008-04-11 20:34:30 +00:00
|
|
|
g_signal_handlers_disconnect_by_func(uat->rep->window, uat_window_delete_event_cb, uat);
|
2008-04-11 23:16:06 +00:00
|
|
|
g_signal_connect(uat->rep->window, "delete_event", G_CALLBACK(unsaved_dialog), uat);
|
|
|
|
g_signal_connect(uat->rep->window, "destroy", G_CALLBACK(unsaved_dialog), uat);
|
2007-02-05 04:22:06 +00:00
|
|
|
} else {
|
2008-04-11 20:34:30 +00:00
|
|
|
g_signal_handlers_disconnect_by_func(uat->rep->window, unsaved_dialog, uat);
|
2008-04-11 23:16:06 +00:00
|
|
|
g_signal_connect(GTK_WINDOW(uat->rep->window), "delete_event", G_CALLBACK(uat_window_delete_event_cb), uat);
|
|
|
|
g_signal_connect(GTK_WINDOW(uat->rep->window), "destroy", G_CALLBACK(uat_window_delete_event_cb), uat);
|
2007-02-05 04:22:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
static char *fld_tostr(void *rec, uat_field_t *f) {
|
|
|
|
guint len;
|
|
|
|
const char *ptr;
|
|
|
|
char *out;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
f->cb.tostr(rec, &ptr, &len, f->cbdata.tostr, f->fld_data);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
switch(f->mode) {
|
|
|
|
case PT_TXTMOD_STRING:
|
|
|
|
case PT_TXTMOD_ENUM:
|
2011-09-20 10:14:58 +00:00
|
|
|
case PT_TXTMOD_FILENAME:
|
|
|
|
case PT_TXTMOD_DIRECTORYNAME:
|
2013-01-24 18:28:31 +00:00
|
|
|
out = ep_strndup(ptr, len);
|
2007-02-07 03:39:40 +00:00
|
|
|
break;
|
|
|
|
case PT_TXTMOD_HEXBYTES: {
|
2013-01-24 18:28:31 +00:00
|
|
|
GString *s = g_string_sized_new( len*2 + 1 );
|
2007-02-07 03:39:40 +00:00
|
|
|
guint i;
|
2012-09-18 21:51:22 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
for (i=0; i<len;i++) g_string_append_printf(s, "%.2X", ((guint8*)ptr)[i]);
|
2012-09-18 21:51:22 +00:00
|
|
|
|
2008-10-31 09:53:56 +00:00
|
|
|
out = ep_strdup(s->str);
|
2012-09-18 21:51:22 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
g_string_free(s, TRUE);
|
2007-02-07 03:39:40 +00:00
|
|
|
break;
|
2012-09-18 21:51:22 +00:00
|
|
|
}
|
2007-02-07 03:39:40 +00:00
|
|
|
default:
|
|
|
|
g_assert_not_reached();
|
2007-02-19 01:21:10 +00:00
|
|
|
out = NULL;
|
2007-02-07 03:39:40 +00:00
|
|
|
break;
|
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
static void append_row(uat_t *uat, guint idx) {
|
|
|
|
GPtrArray *a = g_ptr_array_new();
|
|
|
|
void *rec = UAT_INDEX_PTR(uat, idx);
|
|
|
|
uat_field_t *f = uat->fields;
|
|
|
|
guint colnum;
|
|
|
|
GtkTreeIter iter;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-03-04 02:27:11 +00:00
|
|
|
if (! uat->rep) return;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2010-04-30 22:33:51 +00:00
|
|
|
gtk_list_store_insert_before(uat->rep->list_store, &iter, NULL);
|
|
|
|
for ( colnum = 0; colnum < uat->ncols; colnum++ ) {
|
2013-01-24 18:28:31 +00:00
|
|
|
g_ptr_array_add(a, fld_tostr(rec, &(f[colnum])));
|
|
|
|
gtk_list_store_set(uat->rep->list_store, &iter, colnum, fld_tostr(rec, &(f[colnum])), -1);
|
2010-04-30 22:33:51 +00:00
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
g_ptr_array_free(a, TRUE);
|
2007-01-29 14:14:01 +00:00
|
|
|
}
|
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
static void reset_row(uat_t *uat, guint idx) {
|
|
|
|
void *rec = UAT_INDEX_PTR(uat, idx);
|
|
|
|
uat_field_t *f = uat->fields;
|
|
|
|
guint colnum;
|
2010-04-30 22:33:51 +00:00
|
|
|
GtkTreePath *path;
|
2013-01-24 18:28:31 +00:00
|
|
|
GtkTreeIter iter;
|
2007-03-04 02:27:11 +00:00
|
|
|
|
|
|
|
if (! uat->rep) return;
|
|
|
|
|
2010-04-30 22:33:51 +00:00
|
|
|
path = gtk_tree_path_new_from_indices(idx, -1);
|
|
|
|
if (!path || !gtk_tree_model_get_iter(GTK_TREE_MODEL(uat->rep->list_store), &iter, path)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-02-03 14:25:02 +00:00
|
|
|
for ( colnum = 0; colnum < uat->ncols; colnum++ ) {
|
2013-01-24 18:28:31 +00:00
|
|
|
gtk_list_store_set(uat->rep->list_store, &iter, colnum, fld_tostr(rec, &(f[colnum])), -1);
|
2007-01-29 14:14:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
static guint8 *unhexbytes(const char *si, guint len, guint *len_p, const char** err) {
|
|
|
|
guint8 *buf;
|
|
|
|
guint8 *p;
|
2013-03-21 02:29:09 +00:00
|
|
|
const guint8 *s = (const guint8 *)si;
|
2013-01-24 18:28:31 +00:00
|
|
|
guint i;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
if (len % 2) {
|
2013-01-24 18:28:31 +00:00
|
|
|
*err = ep_strdup_printf("Uneven number of chars hex string %u \n'%s'", len, si);
|
2007-02-07 03:39:40 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-03-21 02:29:09 +00:00
|
|
|
buf = (guint8 *)ep_alloc(len/2+1);
|
2007-02-07 03:39:40 +00:00
|
|
|
p = buf;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
for (i = 0; i<len ; i += 2) {
|
|
|
|
guint8 lo = s[i+1];
|
|
|
|
guint8 hi = s[i];
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
if (hi >= '0' && hi <= '9') {
|
|
|
|
hi -= '0';
|
|
|
|
} else if (hi >= 'a' && hi <= 'f') {
|
|
|
|
hi -= 'a';
|
|
|
|
hi += 0xa;
|
|
|
|
} else if (hi >= 'A' && hi <= 'F') {
|
|
|
|
hi -= 'A';
|
|
|
|
hi += 0xa;
|
|
|
|
} else {
|
|
|
|
goto on_error;
|
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
if (lo >= '0' && lo <= '9') {
|
|
|
|
lo -= '0';
|
|
|
|
} else if (lo >= 'a' && lo <= 'f') {
|
|
|
|
lo -= 'a';
|
|
|
|
lo += 0xa;
|
|
|
|
} else if (lo >= 'A' && lo <= 'F') {
|
|
|
|
lo -= 'A';
|
|
|
|
lo += 0xa;
|
|
|
|
} else {
|
|
|
|
goto on_error;
|
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
*(p++) = (hi*0x10) + lo;
|
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
len /= 2;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
if (len_p) *len_p = len;
|
|
|
|
|
|
|
|
buf[len] = '\0';
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
*err = NULL;
|
|
|
|
return buf;
|
2012-09-18 21:51:22 +00:00
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
on_error:
|
|
|
|
*err = "Error parsing hex string";
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-01-29 14:14:01 +00:00
|
|
|
|
|
|
|
static gboolean uat_dlg_cb(GtkWidget *win _U_, gpointer user_data) {
|
2013-03-21 02:29:09 +00:00
|
|
|
struct _uat_dlg_data *dd = (struct _uat_dlg_data *)user_data;
|
2013-01-24 18:28:31 +00:00
|
|
|
guint ncols = dd->uat->ncols;
|
|
|
|
uat_field_t *f = dd->uat->fields;
|
|
|
|
const char *err = NULL;
|
|
|
|
guint colnum;
|
2007-02-03 14:25:02 +00:00
|
|
|
|
|
|
|
for ( colnum = 0; colnum < ncols; colnum++ ) {
|
2013-01-24 18:28:31 +00:00
|
|
|
void *e = g_ptr_array_index(dd->entries, colnum);
|
2011-09-20 10:14:58 +00:00
|
|
|
const char *text = NULL;
|
|
|
|
char *text_free = NULL;
|
2013-01-04 05:22:43 +00:00
|
|
|
guint len = 0;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
switch(f[colnum].mode) {
|
2011-09-20 10:14:58 +00:00
|
|
|
case PT_TXTMOD_FILENAME:
|
|
|
|
case PT_TXTMOD_DIRECTORYNAME:
|
|
|
|
text = text_free = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(e));
|
|
|
|
if (text) {
|
|
|
|
len = (unsigned) strlen(text);
|
|
|
|
} else {
|
|
|
|
text = "";
|
|
|
|
len = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
case PT_TXTMOD_STRING:
|
|
|
|
text = gtk_entry_get_text(GTK_ENTRY(e));
|
2009-04-16 03:18:10 +00:00
|
|
|
len = (unsigned) strlen(text);
|
2007-02-07 03:39:40 +00:00
|
|
|
break;
|
|
|
|
case PT_TXTMOD_HEXBYTES: {
|
|
|
|
text = gtk_entry_get_text(GTK_ENTRY(e));
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-03-21 02:29:09 +00:00
|
|
|
text = (const char *) unhexbytes(text, (guint) strlen(text), &len, &err);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
if (err) {
|
2013-01-24 18:28:31 +00:00
|
|
|
err = ep_strdup_printf("error in field '%s': %s", f[colnum].title, err);
|
2007-02-07 03:39:40 +00:00
|
|
|
goto on_failure;
|
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
break;
|
2008-01-19 07:46:52 +00:00
|
|
|
}
|
2007-02-07 03:39:40 +00:00
|
|
|
case PT_TXTMOD_ENUM: {
|
2010-02-17 22:26:30 +00:00
|
|
|
gint idx = *(int*)e;
|
|
|
|
text = (idx >= 0) ? ((value_string *)(f[colnum].fld_data))[idx].strptr : "";
|
2009-04-16 03:18:10 +00:00
|
|
|
len = (unsigned) strlen(text);
|
2010-04-30 22:33:51 +00:00
|
|
|
break;
|
2008-01-19 07:46:52 +00:00
|
|
|
}
|
2007-02-07 03:39:40 +00:00
|
|
|
default:
|
|
|
|
g_assert_not_reached();
|
|
|
|
return FALSE;
|
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-03 14:25:02 +00:00
|
|
|
if (f[colnum].cb.chk) {
|
2007-02-07 03:39:40 +00:00
|
|
|
if (! f[colnum].cb.chk(dd->rec, text, len, f[colnum].cbdata.chk, f[colnum].fld_data, &err)) {
|
2013-01-24 18:28:31 +00:00
|
|
|
err = ep_strdup_printf("error in column '%s': %s", f[colnum].title, err);
|
2007-01-29 14:14:01 +00:00
|
|
|
goto on_failure;
|
|
|
|
}
|
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
f[colnum].cb.set(dd->rec, text, len, f[colnum].cbdata.set, f[colnum].fld_data);
|
2011-09-20 10:14:58 +00:00
|
|
|
|
|
|
|
g_free(text_free);
|
2007-01-29 14:14:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (dd->uat->update_cb) {
|
2013-01-24 18:28:31 +00:00
|
|
|
dd->uat->update_cb(dd->rec, &err);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-01-29 14:14:01 +00:00
|
|
|
if (err) {
|
2013-01-24 18:28:31 +00:00
|
|
|
err = ep_strdup_printf("error updating record: %s", err);
|
2007-01-29 14:14:01 +00:00
|
|
|
goto on_failure;
|
|
|
|
}
|
2007-02-03 14:25:02 +00:00
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-03 14:25:02 +00:00
|
|
|
if (dd->is_new) {
|
2013-01-24 18:28:31 +00:00
|
|
|
void *rec_tmp = dd->rec;
|
2013-04-22 02:10:49 +00:00
|
|
|
dd->rec = uat_add_record(dd->uat, dd->rec, TRUE);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-03 14:25:02 +00:00
|
|
|
if (dd->uat->free_cb) {
|
|
|
|
dd->uat->free_cb(rec_tmp);
|
2007-01-29 14:14:01 +00:00
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-03 14:25:02 +00:00
|
|
|
g_free(rec_tmp);
|
2007-01-29 14:14:01 +00:00
|
|
|
}
|
2012-09-18 21:51:22 +00:00
|
|
|
|
2007-02-04 05:19:02 +00:00
|
|
|
dd->uat->changed = TRUE;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2010-10-29 19:48:51 +00:00
|
|
|
set_buttons(dd->uat, dd->uat->rep ? dd->uat->rep->selected : -1);
|
2007-02-05 04:22:06 +00:00
|
|
|
|
2007-01-29 14:14:01 +00:00
|
|
|
if (dd->is_new) {
|
2013-04-22 02:10:49 +00:00
|
|
|
append_row(dd->uat, dd->uat->raw_data->len - 1 );
|
2007-01-29 14:14:01 +00:00
|
|
|
} else {
|
2013-01-24 18:28:31 +00:00
|
|
|
reset_row(dd->uat, dd->row);
|
2007-01-29 14:14:01 +00:00
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
g_ptr_array_free(dd->entries, TRUE);
|
2008-01-19 07:46:52 +00:00
|
|
|
window_destroy(GTK_WIDGET(dd->win));
|
|
|
|
|
2007-03-04 02:27:11 +00:00
|
|
|
if (dd->uat->rep)
|
|
|
|
window_present(GTK_WIDGET(dd->uat->rep->window));
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2008-01-21 07:35:16 +00:00
|
|
|
while (dd->tobe_freed->len) g_free( g_ptr_array_remove_index_fast(dd->tobe_freed, dd->tobe_freed->len - 1 ) );
|
|
|
|
|
|
|
|
g_free(dd);
|
|
|
|
|
2008-01-19 07:46:52 +00:00
|
|
|
return TRUE;
|
2007-01-29 14:14:01 +00:00
|
|
|
on_failure:
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
report_failure("%s", err);
|
2007-01-29 14:14:01 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean uat_cancel_dlg_cb(GtkWidget *win _U_, gpointer user_data) {
|
2013-03-21 02:29:09 +00:00
|
|
|
struct _uat_dlg_data *dd = (struct _uat_dlg_data *)user_data;
|
2007-01-29 14:14:01 +00:00
|
|
|
|
2007-03-04 02:27:11 +00:00
|
|
|
if (dd->uat->rep)
|
|
|
|
window_present(GTK_WIDGET(dd->uat->rep->window));
|
2007-01-29 14:14:01 +00:00
|
|
|
|
|
|
|
if (dd->is_new) g_free(dd->rec);
|
2013-01-24 18:28:31 +00:00
|
|
|
g_ptr_array_free(dd->entries, TRUE);
|
2008-01-19 07:46:52 +00:00
|
|
|
window_destroy(GTK_WIDGET(dd->win));
|
2007-01-29 14:14:01 +00:00
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
while (dd->tobe_freed->len) g_free( g_ptr_array_remove_index_fast(dd->tobe_freed, dd->tobe_freed->len - 1 ) );
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-14 19:21:37 +00:00
|
|
|
g_free(dd);
|
|
|
|
|
2008-01-19 07:46:52 +00:00
|
|
|
return TRUE;
|
2007-01-29 14:14:01 +00:00
|
|
|
}
|
|
|
|
|
2010-02-17 22:26:30 +00:00
|
|
|
static void fld_combo_box_changed_cb(GtkComboBox *combo_box, gpointer user_data) {
|
2013-03-21 02:29:09 +00:00
|
|
|
int *valptr = (int *)user_data;
|
2013-01-24 18:28:31 +00:00
|
|
|
|
2010-02-17 22:26:30 +00:00
|
|
|
*valptr = gtk_combo_box_get_active(combo_box);
|
2007-02-07 03:39:40 +00:00
|
|
|
}
|
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
static void uat_edit_dialog(uat_t *uat, gint row, gboolean copy) {
|
|
|
|
GtkWidget *win, *main_grid, *main_vb, *bbox, *bt_cancel, *bt_ok;
|
2013-03-21 02:29:09 +00:00
|
|
|
struct _uat_dlg_data *dd = (struct _uat_dlg_data *)g_malloc(sizeof(struct _uat_dlg_data));
|
2013-01-24 18:28:31 +00:00
|
|
|
uat_field_t *f = uat->fields;
|
|
|
|
guint colnum;
|
2012-09-18 21:51:22 +00:00
|
|
|
|
2008-01-19 07:46:52 +00:00
|
|
|
dd->entries = g_ptr_array_new();
|
2008-04-14 15:01:34 +00:00
|
|
|
dd->win = dlg_conf_window_new(ep_strdup_printf("%s: %s", uat->name, (row == -1 ? "New" : "Edit")));
|
2008-01-19 07:46:52 +00:00
|
|
|
dd->uat = uat;
|
2010-10-29 19:48:51 +00:00
|
|
|
if (copy && row >= 0) {
|
|
|
|
dd->rec = g_malloc0(uat->record_size);
|
|
|
|
if (uat->copy_cb) {
|
2013-01-24 18:28:31 +00:00
|
|
|
uat->copy_cb (dd->rec, UAT_INDEX_PTR(uat, row), uat->record_size);
|
2010-10-29 19:48:51 +00:00
|
|
|
}
|
|
|
|
dd->is_new = TRUE;
|
|
|
|
} else if (row >= 0) {
|
2013-01-24 18:28:31 +00:00
|
|
|
dd->rec = UAT_INDEX_PTR(uat, row);
|
2010-10-29 19:48:51 +00:00
|
|
|
dd->is_new = FALSE;
|
|
|
|
} else {
|
|
|
|
dd->rec = g_malloc0(uat->record_size);
|
|
|
|
dd->is_new = TRUE;
|
|
|
|
}
|
2007-01-29 14:14:01 +00:00
|
|
|
dd->row = row;
|
2008-01-19 07:46:52 +00:00
|
|
|
dd->tobe_freed = g_ptr_array_new();
|
|
|
|
|
|
|
|
win = dd->win;
|
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
gtk_window_set_resizable(GTK_WINDOW(win), FALSE);
|
|
|
|
gtk_window_resize(GTK_WINDOW(win), 400, 30*(uat->ncols+2));
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2012-04-21 16:40:14 +00:00
|
|
|
main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 5, FALSE);
|
2008-01-19 07:46:52 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(win), main_vb);
|
2008-06-29 15:51:43 +00:00
|
|
|
gtk_container_set_border_width(GTK_CONTAINER(main_vb), 6);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
main_grid = ws_gtk_grid_new();
|
|
|
|
gtk_box_pack_start(GTK_BOX(main_vb), main_grid, FALSE, FALSE, 0);
|
|
|
|
ws_gtk_grid_set_row_spacing(GTK_GRID(main_grid), 5);
|
|
|
|
ws_gtk_grid_set_column_spacing(GTK_GRID(main_grid), 10);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
bbox = dlg_button_row_new(GTK_STOCK_CANCEL, GTK_STOCK_OK, NULL);
|
2009-03-08 22:56:12 +00:00
|
|
|
gtk_box_pack_end(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0);
|
|
|
|
|
2013-03-21 02:29:09 +00:00
|
|
|
bt_ok = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
|
2009-03-08 22:56:12 +00:00
|
|
|
g_signal_connect(bt_ok, "clicked", G_CALLBACK(uat_dlg_cb), dd);
|
|
|
|
|
2013-03-21 02:29:09 +00:00
|
|
|
bt_cancel = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
|
2009-03-08 22:56:12 +00:00
|
|
|
g_signal_connect(bt_cancel, "clicked", G_CALLBACK(uat_cancel_dlg_cb), dd);
|
|
|
|
window_set_cancel_button(win, bt_cancel, NULL);
|
|
|
|
|
2007-02-03 14:25:02 +00:00
|
|
|
for ( colnum = 0; colnum < uat->ncols; colnum++ ) {
|
2008-01-19 07:46:52 +00:00
|
|
|
GtkWidget *entry, *label, *event_box;
|
2013-01-24 18:28:31 +00:00
|
|
|
char *text = fld_tostr(dd->rec, &(f[colnum]));
|
2007-02-12 19:57:41 +00:00
|
|
|
|
|
|
|
event_box = gtk_event_box_new();
|
|
|
|
|
2009-03-08 22:56:12 +00:00
|
|
|
label = gtk_label_new(ep_strdup_printf("%s:", f[colnum].title));
|
2007-02-12 19:57:41 +00:00
|
|
|
if (f[colnum].desc != NULL)
|
2011-07-13 08:48:13 +00:00
|
|
|
gtk_widget_set_tooltip_text(event_box, f[colnum].desc);
|
2007-02-12 19:57:41 +00:00
|
|
|
|
2009-04-21 16:57:52 +00:00
|
|
|
gtk_misc_set_alignment(GTK_MISC(label), 1.0f, 0.5f);
|
2013-01-24 18:28:31 +00:00
|
|
|
ws_gtk_grid_attach_defaults(GTK_GRID(main_grid), event_box, 0, colnum, 1, 1);
|
2007-02-12 19:57:41 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(event_box), label);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
switch(f[colnum].mode) {
|
2011-09-20 10:14:58 +00:00
|
|
|
case PT_TXTMOD_FILENAME:
|
|
|
|
case PT_TXTMOD_DIRECTORYNAME:
|
|
|
|
entry = gtk_file_chooser_button_new(f[colnum].desc,
|
|
|
|
(f[colnum].mode == PT_TXTMOD_FILENAME) ? GTK_FILE_CHOOSER_ACTION_OPEN : GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
|
|
|
|
if (! dd->is_new || copy) {
|
|
|
|
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(entry), text);
|
|
|
|
}
|
2013-01-24 18:28:31 +00:00
|
|
|
g_ptr_array_add(dd->entries, entry);
|
|
|
|
ws_gtk_grid_attach_defaults(GTK_GRID(main_grid), entry, 1, colnum, 1, 1);
|
2011-09-20 10:14:58 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PT_TXTMOD_STRING:
|
|
|
|
case PT_TXTMOD_HEXBYTES:
|
|
|
|
entry = gtk_entry_new();
|
2010-10-29 19:48:51 +00:00
|
|
|
if (! dd->is_new || copy) {
|
2013-01-24 18:28:31 +00:00
|
|
|
gtk_entry_set_text(GTK_ENTRY(entry), text);
|
2007-02-07 03:39:40 +00:00
|
|
|
}
|
2013-01-24 18:28:31 +00:00
|
|
|
g_ptr_array_add(dd->entries, entry);
|
|
|
|
ws_gtk_grid_attach_defaults(GTK_GRID(main_grid), entry, 1, colnum, 1, 1);
|
2009-03-08 22:56:12 +00:00
|
|
|
dlg_set_activate(entry, bt_ok);
|
2007-02-07 03:39:40 +00:00
|
|
|
break;
|
2011-09-20 10:14:58 +00:00
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
case PT_TXTMOD_ENUM: {
|
2010-02-17 22:26:30 +00:00
|
|
|
GtkWidget *combo_box;
|
|
|
|
int idx;
|
2013-03-21 02:29:09 +00:00
|
|
|
const value_string *enum_vals = (const value_string *)f[colnum].fld_data;
|
|
|
|
int *valptr = (int *)g_malloc(sizeof(int)); /* A place to store the index of the */
|
2010-02-17 22:26:30 +00:00
|
|
|
/* "active" fld_data array entry */
|
|
|
|
/* -1 means "nothing selected (active)" */
|
2011-07-24 18:03:53 +00:00
|
|
|
combo_box = gtk_combo_box_text_new();
|
2010-02-17 22:26:30 +00:00
|
|
|
*valptr = -1;
|
2010-01-29 19:09:01 +00:00
|
|
|
for (idx = 0; enum_vals[idx].strptr != NULL; idx++) {
|
2013-01-24 18:28:31 +00:00
|
|
|
const char *str = enum_vals[idx].strptr;
|
2011-07-24 18:03:53 +00:00
|
|
|
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(combo_box), str);
|
2012-09-18 21:51:22 +00:00
|
|
|
|
2007-02-07 03:39:40 +00:00
|
|
|
if ( g_str_equal(str, text) ) {
|
2010-02-17 22:26:30 +00:00
|
|
|
*valptr = idx;
|
2007-02-07 03:39:40 +00:00
|
|
|
}
|
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
g_ptr_array_add(dd->entries, valptr);
|
|
|
|
g_ptr_array_add(dd->tobe_freed, valptr);
|
2007-02-07 03:39:40 +00:00
|
|
|
|
2010-02-17 22:26:30 +00:00
|
|
|
if (*valptr != -1)
|
2010-04-30 22:33:51 +00:00
|
|
|
gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), *valptr);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2010-02-17 22:26:30 +00:00
|
|
|
g_signal_connect(combo_box, "changed", G_CALLBACK(fld_combo_box_changed_cb), valptr);
|
2013-01-24 18:28:31 +00:00
|
|
|
ws_gtk_grid_attach_defaults(GTK_GRID(main_grid), combo_box, 1, colnum, 1, 1);
|
2007-02-07 03:39:40 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
g_assert_not_reached();
|
|
|
|
return;
|
2007-01-29 14:14:01 +00:00
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
}
|
2012-09-18 21:51:22 +00:00
|
|
|
|
2009-03-08 22:56:12 +00:00
|
|
|
gtk_widget_grab_default(bt_ok);
|
2008-01-19 07:46:52 +00:00
|
|
|
gtk_widget_show_all(win);
|
2007-01-29 14:14:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
struct _uat_del {
|
|
|
|
GtkWidget *win;
|
2013-01-24 18:28:31 +00:00
|
|
|
uat_t *uat;
|
|
|
|
gint idx;
|
2007-01-29 14:14:01 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static void uat_del_cb(GtkButton *button _U_, gpointer u) {
|
2013-03-21 02:29:09 +00:00
|
|
|
struct _uat_del *ud = (struct _uat_del *)u;
|
2013-01-24 18:28:31 +00:00
|
|
|
GtkTreeIter iter;
|
|
|
|
GtkTreePath *path;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-01-29 14:14:01 +00:00
|
|
|
uat_remove_record_idx(ud->uat, ud->idx);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2010-04-30 22:33:51 +00:00
|
|
|
if (ud->uat->rep) {
|
|
|
|
path = gtk_tree_path_new_from_indices(ud->idx, -1);
|
|
|
|
if (path && gtk_tree_model_get_iter(GTK_TREE_MODEL(ud->uat->rep->list_store), &iter, path)) {
|
|
|
|
gtk_list_store_remove(ud->uat->rep->list_store, &iter);
|
|
|
|
}
|
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-04 05:19:02 +00:00
|
|
|
ud->uat->changed = TRUE;
|
2013-01-24 18:28:31 +00:00
|
|
|
set_buttons(ud->uat, -1);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
|
|
|
window_destroy(GTK_WIDGET(ud->win));
|
|
|
|
|
2007-03-04 02:27:11 +00:00
|
|
|
if (ud->uat->rep)
|
|
|
|
window_present(GTK_WIDGET(ud->uat->rep->window));
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-01-29 14:14:01 +00:00
|
|
|
g_free(ud);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void uat_cancel_del_cb(GtkButton *button _U_, gpointer u) {
|
2013-03-21 02:29:09 +00:00
|
|
|
struct _uat_del *ud = (struct _uat_del *)u;
|
2013-01-24 18:28:31 +00:00
|
|
|
|
2008-01-19 07:46:52 +00:00
|
|
|
window_destroy(GTK_WIDGET(ud->win));
|
2007-03-04 02:27:11 +00:00
|
|
|
|
|
|
|
if (ud->uat->rep)
|
|
|
|
window_present(GTK_WIDGET(ud->uat->rep->window));
|
2007-01-29 14:14:01 +00:00
|
|
|
g_free(ud);
|
|
|
|
}
|
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
static void uat_del_dlg(uat_t *uat, int idx) {
|
|
|
|
GtkWidget *win, *main_grid, *main_vb, *bbox, *bt_cancel, *bt_ok;
|
|
|
|
uat_field_t *f = uat->fields;
|
|
|
|
guint colnum;
|
|
|
|
void *rec = UAT_INDEX_PTR(uat, idx);
|
2013-03-21 02:29:09 +00:00
|
|
|
struct _uat_del *ud = (struct _uat_del *)g_malloc(sizeof(struct _uat_del));
|
2007-01-29 14:14:01 +00:00
|
|
|
|
|
|
|
ud->uat = uat;
|
|
|
|
ud->idx = idx;
|
2008-04-14 15:01:34 +00:00
|
|
|
ud->win = win = dlg_conf_window_new(ep_strdup_printf("%s: Confirm Delete", uat->name));
|
2012-09-18 21:51:22 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
gtk_window_set_resizable(GTK_WINDOW(win), FALSE);
|
|
|
|
gtk_window_resize(GTK_WINDOW(win), 400, 25*(uat->ncols+2));
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2012-04-21 16:40:14 +00:00
|
|
|
main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 5, FALSE);
|
2008-01-19 07:46:52 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(win), main_vb);
|
2008-06-29 15:51:43 +00:00
|
|
|
gtk_container_set_border_width(GTK_CONTAINER(main_vb), 6);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
main_grid = ws_gtk_grid_new();
|
|
|
|
gtk_box_pack_start(GTK_BOX(main_vb), main_grid, FALSE, FALSE, 0);
|
|
|
|
ws_gtk_grid_set_row_spacing(GTK_GRID(main_grid), 10);
|
|
|
|
ws_gtk_grid_set_column_spacing(GTK_GRID(main_grid), 15);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-03 14:25:02 +00:00
|
|
|
for ( colnum = 0; colnum < uat->ncols; colnum++ ) {
|
2008-01-19 07:46:52 +00:00
|
|
|
GtkWidget *label;
|
2013-01-24 18:28:31 +00:00
|
|
|
char *text = fld_tostr(rec, &(f[colnum]));
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2009-03-08 22:56:12 +00:00
|
|
|
label = gtk_label_new(ep_strdup_printf("%s:", f[colnum].title));
|
2009-04-21 16:57:52 +00:00
|
|
|
gtk_misc_set_alignment(GTK_MISC(label), 1.0f, 0.5f);
|
2013-01-24 18:28:31 +00:00
|
|
|
ws_gtk_grid_attach_defaults(GTK_GRID(main_grid), label, 0, colnum, 1, 1);
|
2012-09-18 21:51:22 +00:00
|
|
|
|
2008-01-19 07:46:52 +00:00
|
|
|
label = gtk_label_new(text);
|
2009-04-21 16:57:52 +00:00
|
|
|
gtk_misc_set_alignment(GTK_MISC(label), 1.0f, 0.5f);
|
2013-01-24 18:28:31 +00:00
|
|
|
ws_gtk_grid_attach_defaults(GTK_GRID(main_grid), label, 1, colnum, 1, 1);
|
2007-02-03 14:25:02 +00:00
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
bbox = dlg_button_row_new(GTK_STOCK_CANCEL, GTK_STOCK_DELETE, NULL);
|
2007-01-29 14:14:01 +00:00
|
|
|
gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-03-21 02:29:09 +00:00
|
|
|
bt_ok = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_DELETE);
|
2008-04-11 23:16:06 +00:00
|
|
|
g_signal_connect(bt_ok, "clicked", G_CALLBACK(uat_del_cb), ud);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-03-21 02:29:09 +00:00
|
|
|
bt_cancel = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
|
2008-04-11 23:16:06 +00:00
|
|
|
g_signal_connect(bt_cancel, "clicked", G_CALLBACK(uat_cancel_del_cb), ud);
|
2008-01-19 07:46:52 +00:00
|
|
|
window_set_cancel_button( win, bt_cancel, NULL);
|
|
|
|
|
|
|
|
gtk_widget_show_all(win);
|
2007-01-29 14:14:01 +00:00
|
|
|
}
|
2007-01-29 10:25:54 +00:00
|
|
|
|
|
|
|
static void uat_new_cb(GtkButton *button _U_, gpointer u) {
|
2013-03-21 02:29:09 +00:00
|
|
|
uat_t *uat = (uat_t *)u;
|
2007-03-04 02:27:11 +00:00
|
|
|
|
|
|
|
if (! uat->rep) return;
|
|
|
|
|
2010-10-29 19:48:51 +00:00
|
|
|
uat_edit_dialog(uat, -1, FALSE);
|
2007-01-29 10:25:54 +00:00
|
|
|
}
|
|
|
|
|
2010-04-30 22:33:51 +00:00
|
|
|
static void uat_edit_cb(GtkWidget *button _U_, gpointer u) {
|
2013-03-21 02:29:09 +00:00
|
|
|
uat_t *uat = (uat_t *)u;
|
2007-03-04 02:27:11 +00:00
|
|
|
|
|
|
|
if (! uat->rep) return;
|
|
|
|
|
2010-10-29 19:48:51 +00:00
|
|
|
uat_edit_dialog(uat, uat->rep->selected, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void uat_copy_cb(GtkWidget *button _U_, gpointer u) {
|
2013-03-21 02:29:09 +00:00
|
|
|
uat_t *uat = (uat_t *)u;
|
2010-10-29 19:48:51 +00:00
|
|
|
|
|
|
|
if (! uat->rep) return;
|
|
|
|
|
|
|
|
uat_edit_dialog(uat, uat->rep->selected, TRUE);
|
2007-01-29 10:25:54 +00:00
|
|
|
}
|
|
|
|
|
2010-04-30 22:33:51 +00:00
|
|
|
static void uat_double_click_cb(GtkWidget *tv, GtkTreePath *path _U_, GtkTreeViewColumn *column _U_, gpointer u) {
|
|
|
|
uat_edit_cb(tv, u);
|
|
|
|
}
|
|
|
|
|
2007-01-29 10:25:54 +00:00
|
|
|
static void uat_delete_cb(GtkButton *button _U_, gpointer u) {
|
2013-03-21 02:29:09 +00:00
|
|
|
uat_t *uat = (uat_t *)u;
|
2007-03-04 02:27:11 +00:00
|
|
|
|
|
|
|
if (! uat->rep) return;
|
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
uat_del_dlg(uat, uat->rep->selected);
|
2007-01-29 10:25:54 +00:00
|
|
|
}
|
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
static gboolean uat_window_delete_event_cb(GtkWindow *w _U_, GdkEvent *e _U_, gpointer u) {
|
2013-03-21 02:29:09 +00:00
|
|
|
uat_t *uat = (uat_t *)u;
|
2012-09-18 21:51:22 +00:00
|
|
|
|
2007-02-11 16:09:21 +00:00
|
|
|
if (uat->rep) {
|
2013-01-24 18:28:31 +00:00
|
|
|
void *rep = uat->rep;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2008-04-11 20:34:30 +00:00
|
|
|
g_signal_handlers_disconnect_by_func(uat->rep->window, uat_window_delete_event_cb, uat);
|
|
|
|
g_signal_handlers_disconnect_by_func(uat->rep->window, unsaved_dialog, uat);
|
2007-02-05 04:22:06 +00:00
|
|
|
|
2007-02-11 16:09:21 +00:00
|
|
|
gtk_widget_destroy(uat->rep->window);
|
2007-02-05 04:22:06 +00:00
|
|
|
|
2007-02-11 16:09:21 +00:00
|
|
|
uat->rep = NULL;
|
2009-03-13 22:06:48 +00:00
|
|
|
g_free(rep);
|
2007-02-11 16:09:21 +00:00
|
|
|
}
|
2007-02-05 04:22:06 +00:00
|
|
|
return TRUE;
|
2007-02-04 05:19:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void uat_up_cb(GtkButton *button _U_, gpointer u) {
|
2013-03-21 02:29:09 +00:00
|
|
|
uat_t *uat = (uat_t *)u;
|
2013-01-24 18:28:31 +00:00
|
|
|
gint row = uat->rep->selected;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-04 05:19:02 +00:00
|
|
|
g_assert(row > 0);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
uat_swap(uat, row, row-1);
|
2010-04-30 22:33:51 +00:00
|
|
|
tree_view_list_store_move_selection(uat->rep->list, TRUE);
|
2007-02-04 05:19:02 +00:00
|
|
|
|
|
|
|
uat->changed = TRUE;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-04 05:19:02 +00:00
|
|
|
row -= 1;
|
|
|
|
uat->rep->selected = row;
|
2013-01-24 18:28:31 +00:00
|
|
|
set_buttons(uat, row);
|
2007-02-04 05:19:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void uat_down_cb(GtkButton *button _U_, gpointer u) {
|
2013-03-21 02:29:09 +00:00
|
|
|
uat_t *uat = (uat_t *)u;
|
2013-01-24 18:28:31 +00:00
|
|
|
gint row = uat->rep->selected;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-04-22 02:10:49 +00:00
|
|
|
g_assert(row >= 0 && (guint) row < uat->raw_data->len - 1);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
uat_swap(uat, row, row+1);
|
2010-04-30 22:33:51 +00:00
|
|
|
tree_view_list_store_move_selection(uat->rep->list, FALSE);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-04 05:19:02 +00:00
|
|
|
uat->changed = TRUE;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-04 05:19:02 +00:00
|
|
|
row += 1;
|
|
|
|
uat->rep->selected = row;
|
2013-01-24 18:28:31 +00:00
|
|
|
set_buttons(uat, row);
|
2007-02-04 05:19:02 +00:00
|
|
|
}
|
|
|
|
|
2012-03-30 08:57:57 +00:00
|
|
|
static void uat_apply_changes(uat_t *uat) {
|
2013-01-24 18:28:31 +00:00
|
|
|
if (uat->flags & UAT_AFFECTS_FIELDS) {
|
2012-03-30 08:57:57 +00:00
|
|
|
/* Recreate list with new fields and redissect packets */
|
2012-09-04 02:35:25 +00:00
|
|
|
packet_list_recreate ();
|
UATs could be put into "categories". The categories were defined only
implicitly by the #define name and string they were defined to; not all
UATs neatly fit into any of the categories, so some of them were put
into categories that weren't obviously correct for them, and one - the
display filter macro UAT - wasn't put into any category at all (which
caused crashes when editing them, as the GUI code that handled UAT
changes from a dialog assumed the category field was non-null).
The category was, in practice, used only to decide, in the
aforementioned GUI code, whether the packet summary pane needed to be
updated or not. It also offered no option of "don't update the packet
summary pane *and* don't redissect anything", which is what would be
appropriate for the display filter macro UAT.
Replace the category with a set of fields indicating what the UAT
affects; we currently offer "dissection", which applies to most UATs
(any UAT in libwireshark presumably affects dissection at a minimum) and
"the set of named fields that exist". Changing any UAT that affects
dissection requires a redissection; changing any UAT that affects the
set of named fields that exist requires a redissection *and* rebuilding
the packet summary pane.
Perhaps we also need "filtering", so that if you change a display filter
macro, we re-filter, in case the display is currently filtered with a
display filter that uses a macro that changed.
svn path=/trunk/; revision=43603
2012-07-08 01:00:46 +00:00
|
|
|
} else {
|
2013-01-24 18:28:31 +00:00
|
|
|
if (uat->flags & UAT_AFFECTS_DISSECTION) {
|
UATs could be put into "categories". The categories were defined only
implicitly by the #define name and string they were defined to; not all
UATs neatly fit into any of the categories, so some of them were put
into categories that weren't obviously correct for them, and one - the
display filter macro UAT - wasn't put into any category at all (which
caused crashes when editing them, as the GUI code that handled UAT
changes from a dialog assumed the category field was non-null).
The category was, in practice, used only to decide, in the
aforementioned GUI code, whether the packet summary pane needed to be
updated or not. It also offered no option of "don't update the packet
summary pane *and* don't redissect anything", which is what would be
appropriate for the display filter macro UAT.
Replace the category with a set of fields indicating what the UAT
affects; we currently offer "dissection", which applies to most UATs
(any UAT in libwireshark presumably affects dissection at a minimum) and
"the set of named fields that exist". Changing any UAT that affects
dissection requires a redissection; changing any UAT that affects the
set of named fields that exist requires a redissection *and* rebuilding
the packet summary pane.
Perhaps we also need "filtering", so that if you change a display filter
macro, we re-filter, in case the display is currently filtered with a
display filter that uses a macro that changed.
svn path=/trunk/; revision=43603
2012-07-08 01:00:46 +00:00
|
|
|
/* Just redissect packets if we have any */
|
2013-01-24 18:28:31 +00:00
|
|
|
if (cfile.state != FILE_CLOSED) {
|
UATs could be put into "categories". The categories were defined only
implicitly by the #define name and string they were defined to; not all
UATs neatly fit into any of the categories, so some of them were put
into categories that weren't obviously correct for them, and one - the
display filter macro UAT - wasn't put into any category at all (which
caused crashes when editing them, as the GUI code that handled UAT
changes from a dialog assumed the category field was non-null).
The category was, in practice, used only to decide, in the
aforementioned GUI code, whether the packet summary pane needed to be
updated or not. It also offered no option of "don't update the packet
summary pane *and* don't redissect anything", which is what would be
appropriate for the display filter macro UAT.
Replace the category with a set of fields indicating what the UAT
affects; we currently offer "dissection", which applies to most UATs
(any UAT in libwireshark presumably affects dissection at a minimum) and
"the set of named fields that exist". Changing any UAT that affects
dissection requires a redissection; changing any UAT that affects the
set of named fields that exist requires a redissection *and* rebuilding
the packet summary pane.
Perhaps we also need "filtering", so that if you change a display filter
macro, we re-filter, in case the display is currently filtered with a
display filter that uses a macro that changed.
svn path=/trunk/; revision=43603
2012-07-08 01:00:46 +00:00
|
|
|
redissect_packets ();
|
2013-03-24 16:47:38 +00:00
|
|
|
redissect_all_packet_windows ();
|
UATs could be put into "categories". The categories were defined only
implicitly by the #define name and string they were defined to; not all
UATs neatly fit into any of the categories, so some of them were put
into categories that weren't obviously correct for them, and one - the
display filter macro UAT - wasn't put into any category at all (which
caused crashes when editing them, as the GUI code that handled UAT
changes from a dialog assumed the category field was non-null).
The category was, in practice, used only to decide, in the
aforementioned GUI code, whether the packet summary pane needed to be
updated or not. It also offered no option of "don't update the packet
summary pane *and* don't redissect anything", which is what would be
appropriate for the display filter macro UAT.
Replace the category with a set of fields indicating what the UAT
affects; we currently offer "dissection", which applies to most UATs
(any UAT in libwireshark presumably affects dissection at a minimum) and
"the set of named fields that exist". Changing any UAT that affects
dissection requires a redissection; changing any UAT that affects the
set of named fields that exist requires a redissection *and* rebuilding
the packet summary pane.
Perhaps we also need "filtering", so that if you change a display filter
macro, we re-filter, in case the display is currently filtered with a
display filter that uses a macro that changed.
svn path=/trunk/; revision=43603
2012-07-08 01:00:46 +00:00
|
|
|
}
|
|
|
|
}
|
2012-03-30 08:57:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-08-31 23:22:45 +00:00
|
|
|
static void uat_cancel_cb(GtkWidget *button _U_, gpointer u) {
|
2013-03-21 02:29:09 +00:00
|
|
|
uat_t *uat = (uat_t *)u;
|
2013-02-08 09:06:08 +00:00
|
|
|
const gchar *err = NULL;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-11 16:09:21 +00:00
|
|
|
if (uat->changed) {
|
|
|
|
uat_clear(uat);
|
2013-01-24 18:28:31 +00:00
|
|
|
uat_load(uat, &err);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-11 16:09:21 +00:00
|
|
|
if (err) {
|
2013-01-24 18:28:31 +00:00
|
|
|
report_failure("Error while loading %s: %s", uat->name, err);
|
2007-02-11 16:09:21 +00:00
|
|
|
}
|
2007-02-04 05:19:02 +00:00
|
|
|
|
2012-03-30 08:57:57 +00:00
|
|
|
uat_apply_changes (uat);
|
2007-02-11 16:09:21 +00:00
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2008-04-11 20:34:30 +00:00
|
|
|
g_signal_handlers_disconnect_by_func(uat->rep->window, uat_window_delete_event_cb, uat);
|
|
|
|
g_signal_handlers_disconnect_by_func(uat->rep->window, unsaved_dialog, uat);
|
2007-02-11 16:09:21 +00:00
|
|
|
gtk_widget_destroy(uat->rep->window);
|
|
|
|
g_free(uat->rep);
|
|
|
|
uat->rep = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void uat_apply_cb(GtkButton *button _U_, gpointer u) {
|
2013-03-21 02:29:09 +00:00
|
|
|
uat_t *uat = (uat_t *)u;
|
2007-02-11 16:09:21 +00:00
|
|
|
|
2010-03-04 12:50:18 +00:00
|
|
|
if (uat->changed) {
|
|
|
|
if (uat->post_update_cb) uat->post_update_cb();
|
2012-03-30 08:57:57 +00:00
|
|
|
uat_apply_changes (uat);
|
2010-03-04 12:50:18 +00:00
|
|
|
}
|
2007-02-11 16:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void uat_ok_cb(GtkButton *button _U_, gpointer u) {
|
2013-03-21 02:29:09 +00:00
|
|
|
uat_t *uat = (uat_t *)u;
|
2013-04-17 19:39:11 +00:00
|
|
|
const gchar *err = NULL;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-11 16:09:21 +00:00
|
|
|
if (uat->changed) {
|
2013-01-24 18:28:31 +00:00
|
|
|
uat_save(uat, &err);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-11 16:09:21 +00:00
|
|
|
if (err) {
|
2013-01-24 18:28:31 +00:00
|
|
|
report_failure("Error while saving %s: %s", uat->name, err);
|
2007-02-11 16:09:21 +00:00
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2010-03-04 12:50:18 +00:00
|
|
|
if (uat->post_update_cb) uat->post_update_cb();
|
2012-03-30 08:57:57 +00:00
|
|
|
uat_apply_changes (uat);
|
2007-02-04 05:19:02 +00:00
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2008-04-11 20:34:30 +00:00
|
|
|
g_signal_handlers_disconnect_by_func(uat->rep->window, uat_window_delete_event_cb, uat);
|
|
|
|
g_signal_handlers_disconnect_by_func(uat->rep->window, unsaved_dialog, uat);
|
2007-02-11 16:09:21 +00:00
|
|
|
gtk_widget_destroy(uat->rep->window);
|
|
|
|
g_free(uat->rep);
|
|
|
|
uat->rep = NULL;
|
2007-02-04 05:19:02 +00:00
|
|
|
}
|
|
|
|
|
2011-10-09 09:55:14 +00:00
|
|
|
static void uat_clear_cb(GtkButton *button _U_, gpointer u) {
|
2013-03-21 02:29:09 +00:00
|
|
|
uat_t *uat = (uat_t *)u;
|
2011-10-09 09:55:14 +00:00
|
|
|
|
|
|
|
gtk_list_store_clear(uat->rep->list_store);
|
|
|
|
uat_clear(uat);
|
|
|
|
uat->changed = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void uat_refresh_cb(GtkButton *button _U_, gpointer u) {
|
2013-03-21 02:29:09 +00:00
|
|
|
uat_t *uat = (uat_t *)u;
|
2013-02-08 09:06:08 +00:00
|
|
|
const gchar *err = NULL;
|
2013-01-24 18:28:31 +00:00
|
|
|
guint i;
|
2011-10-09 09:55:14 +00:00
|
|
|
|
|
|
|
uat_clear_cb(button, u);
|
|
|
|
|
|
|
|
uat->from_global = TRUE;
|
2013-01-24 18:28:31 +00:00
|
|
|
uat_load(uat, &err);
|
2011-10-09 09:55:14 +00:00
|
|
|
uat->from_global = FALSE;
|
|
|
|
uat->changed = TRUE;
|
|
|
|
|
|
|
|
if (err) {
|
2013-01-24 18:28:31 +00:00
|
|
|
report_failure("Error while loading %s: %s", uat->name, err);
|
2011-10-09 09:55:14 +00:00
|
|
|
}
|
|
|
|
|
2013-04-22 02:10:49 +00:00
|
|
|
for (i = 0 ; i < uat->raw_data->len; i++) {
|
2011-10-09 09:55:14 +00:00
|
|
|
append_row(uat, i);
|
|
|
|
}
|
|
|
|
}
|
2007-02-11 16:09:21 +00:00
|
|
|
|
|
|
|
|
2010-04-30 22:33:51 +00:00
|
|
|
static void remember_selected_row(GtkWidget *w _U_, gpointer u) {
|
2013-03-21 02:29:09 +00:00
|
|
|
uat_t *uat = (uat_t *)u;
|
2013-01-24 18:28:31 +00:00
|
|
|
gint row;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2010-04-30 22:33:51 +00:00
|
|
|
row = tree_view_list_store_get_selected_row(uat->rep->list);
|
2008-01-19 07:46:52 +00:00
|
|
|
uat->rep->selected = row;
|
|
|
|
|
|
|
|
gtk_widget_set_sensitive (uat->rep->bt_edit, TRUE);
|
2010-10-29 19:48:51 +00:00
|
|
|
gtk_widget_set_sensitive (uat->rep->bt_copy, uat->copy_cb ? TRUE : FALSE);
|
2008-01-19 07:46:52 +00:00
|
|
|
gtk_widget_set_sensitive(uat->rep->bt_delete, TRUE);
|
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
set_buttons(uat, row);
|
2007-01-29 10:25:54 +00:00
|
|
|
}
|
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
static void uat_yessave_cb(GtkWindow *w _U_, void *u) {
|
2013-03-21 02:29:09 +00:00
|
|
|
uat_t *uat = (uat_t *)u;
|
2013-04-17 19:39:11 +00:00
|
|
|
const gchar *err = NULL;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
window_delete_event_cb(uat->rep->unsaved_window, NULL, NULL);
|
2007-02-11 16:09:21 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
uat_save(uat, &err);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-11 16:09:21 +00:00
|
|
|
if (err) {
|
2013-01-24 18:28:31 +00:00
|
|
|
report_failure("Error while saving %s: %s", uat->name, err);
|
2007-02-11 16:09:21 +00:00
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2008-04-11 20:34:30 +00:00
|
|
|
g_signal_handlers_disconnect_by_func(uat->rep->window, uat_window_delete_event_cb, uat);
|
|
|
|
g_signal_handlers_disconnect_by_func(uat->rep->window, unsaved_dialog, uat);
|
2007-02-05 04:22:06 +00:00
|
|
|
window_destroy(uat->rep->window);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-05 04:22:06 +00:00
|
|
|
g_free(uat->rep);
|
2007-01-29 10:25:54 +00:00
|
|
|
uat->rep = NULL;
|
2007-02-05 04:22:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
static void uat_nosave_cb(GtkWindow *w _U_, void *u) {
|
2013-03-21 02:29:09 +00:00
|
|
|
uat_t *uat = (uat_t *)u;
|
2013-01-24 18:28:31 +00:00
|
|
|
|
|
|
|
window_delete_event_cb(uat->rep->unsaved_window, NULL, NULL);
|
2008-04-11 20:34:30 +00:00
|
|
|
g_signal_handlers_disconnect_by_func(uat->rep->window, uat_window_delete_event_cb, uat);
|
|
|
|
g_signal_handlers_disconnect_by_func(uat->rep->window, unsaved_dialog, uat);
|
2007-02-11 16:09:21 +00:00
|
|
|
window_destroy(uat->rep->window);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-11 16:09:21 +00:00
|
|
|
g_free(uat->rep);
|
|
|
|
uat->rep = NULL;
|
2007-02-05 04:22:06 +00:00
|
|
|
}
|
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
static gboolean unsaved_dialog(GtkWindow *w _U_, GdkEvent *e _U_, gpointer u) {
|
2007-02-05 04:22:06 +00:00
|
|
|
GtkWidget *win, *vbox, *label, *bbox;
|
2007-02-11 16:09:21 +00:00
|
|
|
GtkWidget *yes_bt, *no_bt;
|
2013-01-24 18:28:31 +00:00
|
|
|
gchar *message;
|
2013-03-21 02:29:09 +00:00
|
|
|
uat_t *uat = (uat_t *)u;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-05 04:22:06 +00:00
|
|
|
if (uat->rep->unsaved_window) {
|
|
|
|
window_present(uat->rep->unsaved_window);
|
|
|
|
return TRUE;
|
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2008-04-14 15:01:34 +00:00
|
|
|
uat->rep->unsaved_window = win = dlg_conf_window_new("Discard Changes?");
|
2007-02-05 04:22:06 +00:00
|
|
|
gtk_window_set_default_size(GTK_WINDOW(win), 360, 140);
|
|
|
|
|
|
|
|
gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER_ON_PARENT);
|
2012-04-21 16:40:14 +00:00
|
|
|
vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 12, FALSE);
|
2008-06-29 15:51:43 +00:00
|
|
|
gtk_container_set_border_width(GTK_CONTAINER(vbox), 6);
|
2007-02-05 04:22:06 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(win), vbox);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-11 16:09:21 +00:00
|
|
|
message = ep_strdup_printf("Changes to '%s' are not being saved!\n"
|
2008-01-19 07:46:52 +00:00
|
|
|
"Do you want to save '%s'?", uat->name, uat->name);
|
|
|
|
|
2007-02-05 04:22:06 +00:00
|
|
|
label = gtk_label_new(message);
|
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
bbox = dlg_button_row_new(GTK_STOCK_YES, GTK_STOCK_NO, NULL);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-03-21 02:29:09 +00:00
|
|
|
yes_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_YES);
|
|
|
|
no_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_NO);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2008-04-11 23:16:06 +00:00
|
|
|
g_signal_connect(no_bt, "clicked", G_CALLBACK(uat_nosave_cb), uat);
|
|
|
|
g_signal_connect(yes_bt, "clicked", G_CALLBACK(uat_yessave_cb), uat);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-02-05 04:22:06 +00:00
|
|
|
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
|
|
|
|
gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
|
|
|
|
|
|
|
|
gtk_widget_show_all(win);
|
|
|
|
window_present(win);
|
|
|
|
|
|
|
|
return TRUE;
|
2007-01-29 10:25:54 +00:00
|
|
|
}
|
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
static void uat_help_cb(GtkWidget *w _U_, gpointer u) {
|
2012-09-18 21:51:22 +00:00
|
|
|
gchar *help_page, *url;
|
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
help_page = g_strdup_printf("%s.html", ((uat_t*)u)->help);
|
2012-09-18 21:51:22 +00:00
|
|
|
url = user_guide_url(help_page);
|
|
|
|
if (url) {
|
|
|
|
browser_open_url(url);
|
|
|
|
}
|
|
|
|
g_free(help_page);
|
|
|
|
g_free(url);
|
2007-02-05 05:06:21 +00:00
|
|
|
}
|
2007-01-29 10:25:54 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
static GtkWidget *uat_window(void *u) {
|
2013-03-21 02:29:09 +00:00
|
|
|
uat_t *uat = (uat_t *)u;
|
2013-01-24 18:28:31 +00:00
|
|
|
uat_field_t *f = uat->fields;
|
|
|
|
uat_rep_t *rep;
|
|
|
|
guint i;
|
|
|
|
guint colnum;
|
|
|
|
GType *col_types;
|
|
|
|
GtkWidget *hbox, *vbox, *move_hbox, *edit_hbox, *refresh_hbox;
|
2010-04-30 22:33:51 +00:00
|
|
|
GtkTreeViewColumn *column;
|
2013-01-24 18:28:31 +00:00
|
|
|
GtkCellRenderer *renderer;
|
|
|
|
GtkTreeSelection *selection;
|
|
|
|
gchar *global_fname;
|
|
|
|
gboolean global_file_exists;
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-01-29 10:25:54 +00:00
|
|
|
if (uat->rep) {
|
|
|
|
window_present(uat->rep->window);
|
|
|
|
return uat->rep->window;
|
|
|
|
} else {
|
2013-03-21 02:29:09 +00:00
|
|
|
uat->rep = rep = (uat_rep_t *)g_malloc0(sizeof(uat_rep_t));
|
2007-01-29 10:25:54 +00:00
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2011-10-09 09:55:14 +00:00
|
|
|
global_fname = get_datafile_path(uat->filename);
|
|
|
|
global_file_exists = file_exists(global_fname);
|
|
|
|
g_free (global_fname);
|
|
|
|
|
2008-04-14 15:01:34 +00:00
|
|
|
rep->window = dlg_conf_window_new(uat->name);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
gtk_window_set_default_size(GTK_WINDOW(rep->window), 720, 512);
|
2007-01-29 10:25:54 +00:00
|
|
|
gtk_window_set_position(GTK_WINDOW(rep->window), GTK_WIN_POS_CENTER_ON_PARENT);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2008-06-29 15:51:43 +00:00
|
|
|
gtk_container_set_border_width(GTK_CONTAINER(rep->window), 6);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2012-04-21 16:40:14 +00:00
|
|
|
rep->vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 12, FALSE);
|
2008-06-29 15:51:43 +00:00
|
|
|
gtk_container_set_border_width(GTK_CONTAINER(rep->vbox), 6);
|
2007-01-29 10:25:54 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(rep->window), rep->vbox);
|
|
|
|
|
2012-04-21 16:40:14 +00:00
|
|
|
hbox = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12, FALSE);
|
2008-06-29 15:51:43 +00:00
|
|
|
gtk_container_set_border_width(GTK_CONTAINER(hbox), 6);
|
2012-07-20 15:21:40 +00:00
|
|
|
gtk_box_pack_start(GTK_BOX(rep->vbox), hbox, TRUE, TRUE, 0);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2012-04-21 16:40:14 +00:00
|
|
|
vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 12, FALSE);
|
2008-06-29 15:51:43 +00:00
|
|
|
gtk_container_set_border_width(GTK_CONTAINER(vbox), 6);
|
2007-02-11 16:09:21 +00:00
|
|
|
gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-01-29 10:25:54 +00:00
|
|
|
rep->scrolledwindow = scrolled_window_new(NULL, NULL);
|
2008-01-19 07:46:52 +00:00
|
|
|
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(rep->scrolledwindow), GTK_SHADOW_IN);
|
|
|
|
|
2013-03-21 02:29:09 +00:00
|
|
|
col_types = (GType *)g_malloc(sizeof(GType) *uat->ncols);
|
2010-04-30 22:33:51 +00:00
|
|
|
for ( colnum = 0; colnum < uat->ncols; colnum++ ) {
|
|
|
|
col_types[colnum] = G_TYPE_STRING;
|
|
|
|
}
|
|
|
|
rep->list_store = gtk_list_store_newv(uat->ncols, col_types);
|
|
|
|
g_free(col_types);
|
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
rep->list = GTK_TREE_VIEW(tree_view_new(GTK_TREE_MODEL(rep->list_store))); /*uat->ncols */
|
2010-04-30 22:33:51 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(rep->scrolledwindow), GTK_WIDGET(rep->list));
|
2007-05-25 16:47:22 +00:00
|
|
|
gtk_box_pack_start(GTK_BOX(hbox), rep->scrolledwindow, TRUE, TRUE, 0);
|
|
|
|
|
2010-04-30 22:33:51 +00:00
|
|
|
selection = gtk_tree_view_get_selection(rep->list);
|
|
|
|
gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
|
|
|
|
|
2007-02-03 14:25:02 +00:00
|
|
|
for ( colnum = 0; colnum < uat->ncols; colnum++ ) {
|
2010-04-30 22:33:51 +00:00
|
|
|
renderer = gtk_cell_renderer_text_new();
|
|
|
|
column = gtk_tree_view_column_new_with_attributes(f[colnum].title,
|
|
|
|
renderer, "text", colnum, NULL);
|
2013-01-24 18:28:31 +00:00
|
|
|
gtk_tree_view_column_set_resizable (column, TRUE);
|
|
|
|
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
|
2010-04-30 22:33:51 +00:00
|
|
|
gtk_tree_view_append_column (rep->list, column);
|
2010-05-02 09:59:02 +00:00
|
|
|
if (f[colnum].desc != NULL)
|
2011-07-27 10:05:09 +00:00
|
|
|
gtk_widget_set_tooltip_text(gtk_tree_view_column_get_button(column), f[colnum].desc);
|
2007-01-29 10:25:54 +00:00
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-04-22 02:10:49 +00:00
|
|
|
for ( i = 0 ; i < uat->raw_data->len; i++ ) {
|
2007-01-29 10:25:54 +00:00
|
|
|
append_row(uat, i);
|
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
if (uat->help) {
|
|
|
|
GtkWidget *help_btn;
|
2007-02-11 16:09:21 +00:00
|
|
|
rep->bbox = dlg_button_row_new(GTK_STOCK_HELP, GTK_STOCK_OK, GTK_STOCK_APPLY, GTK_STOCK_CANCEL, NULL);
|
2013-03-21 02:29:09 +00:00
|
|
|
help_btn = (GtkWidget *)g_object_get_data(G_OBJECT(rep->bbox), GTK_STOCK_HELP);
|
2008-04-11 23:16:06 +00:00
|
|
|
g_signal_connect(help_btn, "clicked", G_CALLBACK(uat_help_cb), uat);
|
2007-02-11 16:09:21 +00:00
|
|
|
} else {
|
2008-04-07 05:22:54 +00:00
|
|
|
|
2007-02-11 16:09:21 +00:00
|
|
|
rep->bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_APPLY, GTK_STOCK_CANCEL, NULL);
|
2012-09-18 21:51:22 +00:00
|
|
|
}
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2012-04-21 21:13:13 +00:00
|
|
|
move_hbox = gtk_button_box_new(GTK_ORIENTATION_VERTICAL);
|
2008-01-19 07:46:52 +00:00
|
|
|
gtk_box_pack_start(GTK_BOX(vbox), move_hbox, TRUE, FALSE, 0);
|
2007-02-04 05:19:02 +00:00
|
|
|
|
2012-04-21 21:13:13 +00:00
|
|
|
edit_hbox = gtk_button_box_new(GTK_ORIENTATION_VERTICAL);
|
2011-10-09 09:55:14 +00:00
|
|
|
gtk_box_pack_start(GTK_BOX(vbox), edit_hbox, TRUE, FALSE, 0);
|
|
|
|
|
2012-04-21 21:13:13 +00:00
|
|
|
refresh_hbox = gtk_button_box_new(GTK_ORIENTATION_VERTICAL);
|
2011-10-09 09:55:14 +00:00
|
|
|
gtk_box_pack_end(GTK_BOX(vbox), refresh_hbox, TRUE, FALSE, 0);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
|
|
|
|
2008-04-11 18:58:19 +00:00
|
|
|
rep->bt_up = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
|
2011-10-09 09:55:14 +00:00
|
|
|
gtk_widget_set_tooltip_text(rep->bt_up, "Move selected entry up");
|
|
|
|
|
|
|
|
rep->bt_down = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
|
|
|
|
gtk_widget_set_tooltip_text(rep->bt_down, "Move selected entry down");
|
2007-08-31 23:22:45 +00:00
|
|
|
|
2007-02-11 16:09:21 +00:00
|
|
|
gtk_box_pack_start(GTK_BOX(move_hbox), rep->bt_up, TRUE, FALSE, 5);
|
|
|
|
gtk_box_pack_start(GTK_BOX(move_hbox), rep->bt_down, TRUE, FALSE, 5);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2007-08-31 23:22:45 +00:00
|
|
|
|
2008-04-11 18:58:19 +00:00
|
|
|
rep->bt_new = gtk_button_new_from_stock(GTK_STOCK_NEW);
|
2011-10-09 09:55:14 +00:00
|
|
|
gtk_widget_set_tooltip_text(rep->bt_new, "Create a new entry");
|
|
|
|
|
2008-04-11 18:58:19 +00:00
|
|
|
rep->bt_edit = gtk_button_new_from_stock(WIRESHARK_STOCK_EDIT);
|
2011-10-09 09:55:14 +00:00
|
|
|
gtk_widget_set_tooltip_text(rep->bt_edit, "Edit selected entry");
|
|
|
|
|
2010-10-29 19:48:51 +00:00
|
|
|
rep->bt_copy = gtk_button_new_from_stock(GTK_STOCK_COPY);
|
2011-10-09 09:55:14 +00:00
|
|
|
gtk_widget_set_tooltip_text(rep->bt_copy, "Copy selected entry");
|
|
|
|
|
2008-04-11 18:58:19 +00:00
|
|
|
rep->bt_delete = gtk_button_new_from_stock(GTK_STOCK_DELETE);
|
2011-10-09 09:55:14 +00:00
|
|
|
gtk_widget_set_tooltip_text(rep->bt_delete, "Delete selected entry");
|
2007-02-05 04:22:06 +00:00
|
|
|
|
2007-02-11 16:09:21 +00:00
|
|
|
gtk_box_pack_end(GTK_BOX(edit_hbox), rep->bt_new, TRUE, FALSE, 5);
|
|
|
|
gtk_box_pack_end(GTK_BOX(edit_hbox), rep->bt_edit, TRUE, FALSE, 5);
|
2010-10-29 19:48:51 +00:00
|
|
|
gtk_box_pack_end(GTK_BOX(edit_hbox), rep->bt_copy, TRUE, FALSE, 5);
|
2007-02-11 16:09:21 +00:00
|
|
|
gtk_box_pack_end(GTK_BOX(edit_hbox), rep->bt_delete, TRUE, FALSE, 5);
|
2007-02-05 05:06:21 +00:00
|
|
|
|
2011-10-09 09:55:14 +00:00
|
|
|
rep->bt_refresh = gtk_button_new_from_stock(GTK_STOCK_REFRESH);
|
|
|
|
gtk_widget_set_tooltip_text(rep->bt_refresh, "Refresh from system defaults");
|
|
|
|
|
|
|
|
rep->bt_clear = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
|
|
|
|
gtk_widget_set_tooltip_text(rep->bt_clear, "Delete all entries");
|
|
|
|
|
|
|
|
gtk_box_pack_end(GTK_BOX(refresh_hbox), rep->bt_refresh, TRUE, FALSE, 5);
|
|
|
|
gtk_box_pack_end(GTK_BOX(refresh_hbox), rep->bt_clear, TRUE, FALSE, 5);
|
|
|
|
|
2007-08-31 23:22:45 +00:00
|
|
|
|
2013-03-21 02:29:09 +00:00
|
|
|
rep->bt_apply = (GtkWidget *)g_object_get_data(G_OBJECT(rep->bbox), GTK_STOCK_APPLY);
|
|
|
|
rep->bt_cancel = (GtkWidget *)g_object_get_data(G_OBJECT(rep->bbox), GTK_STOCK_CANCEL);
|
|
|
|
rep->bt_ok = (GtkWidget *)g_object_get_data(G_OBJECT(rep->bbox), GTK_STOCK_OK);
|
2007-02-05 04:22:06 +00:00
|
|
|
|
2007-02-11 16:09:21 +00:00
|
|
|
gtk_box_pack_end(GTK_BOX(rep->vbox), rep->bbox, FALSE, FALSE, 0);
|
2007-02-05 04:22:06 +00:00
|
|
|
|
|
|
|
gtk_widget_set_sensitive (rep->bt_up, FALSE);
|
|
|
|
gtk_widget_set_sensitive (rep->bt_down, FALSE);
|
|
|
|
gtk_widget_set_sensitive (rep->bt_edit, FALSE);
|
2010-10-29 19:48:51 +00:00
|
|
|
gtk_widget_set_sensitive (rep->bt_copy, FALSE);
|
2007-02-05 04:22:06 +00:00
|
|
|
gtk_widget_set_sensitive (rep->bt_delete, FALSE);
|
2011-10-09 09:55:14 +00:00
|
|
|
gtk_widget_set_sensitive (rep->bt_refresh, global_file_exists);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2010-04-30 22:33:51 +00:00
|
|
|
g_signal_connect(rep->list, "row-activated", G_CALLBACK(uat_double_click_cb), uat);
|
|
|
|
g_signal_connect(selection, "changed", G_CALLBACK(remember_selected_row), uat);
|
2008-08-02 13:47:31 +00:00
|
|
|
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2008-04-11 23:16:06 +00:00
|
|
|
g_signal_connect(rep->bt_new, "clicked", G_CALLBACK(uat_new_cb), uat);
|
|
|
|
g_signal_connect(rep->bt_edit, "clicked", G_CALLBACK(uat_edit_cb), uat);
|
2010-10-29 19:48:51 +00:00
|
|
|
g_signal_connect(rep->bt_copy, "clicked", G_CALLBACK(uat_copy_cb), uat);
|
2008-04-11 23:16:06 +00:00
|
|
|
g_signal_connect(rep->bt_delete, "clicked", G_CALLBACK(uat_delete_cb), uat);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2011-10-09 09:55:14 +00:00
|
|
|
g_signal_connect(rep->bt_refresh, "clicked", G_CALLBACK(uat_refresh_cb), uat);
|
|
|
|
g_signal_connect(rep->bt_clear, "clicked", G_CALLBACK(uat_clear_cb), uat);
|
|
|
|
|
2008-04-11 23:16:06 +00:00
|
|
|
g_signal_connect(rep->bt_up, "clicked", G_CALLBACK(uat_up_cb), uat);
|
|
|
|
g_signal_connect(rep->bt_down, "clicked", G_CALLBACK(uat_down_cb), uat);
|
2008-01-19 07:46:52 +00:00
|
|
|
|
2008-04-11 23:16:06 +00:00
|
|
|
g_signal_connect(rep->bt_apply, "clicked", G_CALLBACK(uat_apply_cb), uat);
|
|
|
|
g_signal_connect(rep->bt_cancel, "clicked", G_CALLBACK(uat_cancel_cb), uat);
|
|
|
|
g_signal_connect(rep->bt_ok, "clicked", G_CALLBACK(uat_ok_cb), uat);
|
2007-02-05 04:22:06 +00:00
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
window_set_cancel_button(rep->window, rep->bt_cancel, NULL); /*set esc to activate cancel button */
|
2007-08-31 23:22:45 +00:00
|
|
|
|
2007-02-05 04:22:06 +00:00
|
|
|
if (uat->changed) {
|
2008-04-11 23:16:06 +00:00
|
|
|
g_signal_connect(GTK_WINDOW(rep->window), "delete_event", G_CALLBACK(unsaved_dialog), uat);
|
|
|
|
g_signal_connect(GTK_WINDOW(rep->window), "destroy", G_CALLBACK(unsaved_dialog), uat);
|
2007-02-05 04:22:06 +00:00
|
|
|
} else {
|
2008-04-11 23:16:06 +00:00
|
|
|
g_signal_connect(GTK_WINDOW(rep->window), "delete_event", G_CALLBACK(uat_window_delete_event_cb), uat);
|
|
|
|
g_signal_connect(GTK_WINDOW(rep->window), "destroy", G_CALLBACK(uat_window_delete_event_cb), uat);
|
2007-02-05 04:22:06 +00:00
|
|
|
}
|
2012-09-18 21:51:22 +00:00
|
|
|
|
2010-04-30 22:33:51 +00:00
|
|
|
gtk_widget_grab_focus(GTK_WIDGET(rep->list));
|
2007-01-29 10:25:54 +00:00
|
|
|
|
|
|
|
gtk_widget_show_all(rep->window);
|
|
|
|
window_present(rep->window);
|
|
|
|
|
|
|
|
return rep->window;
|
|
|
|
}
|
|
|
|
|
2013-01-24 18:28:31 +00:00
|
|
|
void uat_window_cb(GtkWidget *u _U_, void *uat) {
|
2007-02-03 14:25:02 +00:00
|
|
|
uat_window(uat);
|
|
|
|
}
|