summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--color_filters.c4
-rw-r--r--file.c110
-rw-r--r--gtk/Makefile.common4
-rw-r--r--gtk/capture_file_dlg.c11
-rw-r--r--gtk/color_dlg.c13
-rw-r--r--gtk/drag_and_drop.c2
-rw-r--r--gtk/font_utils.c2
-rw-r--r--gtk/gtkglobals.h2
-rw-r--r--gtk/main.c31
-rw-r--r--gtk/main.h2
-rw-r--r--gtk/main_packet_list.c6
-rw-r--r--gtk/main_packet_list.h4
-rw-r--r--gtk/main_proto_draw.c8
-rw-r--r--gtk/main_toolbar.c9
-rw-r--r--gtk/menus.c19
-rw-r--r--gtk/new_packet_list.c231
-rw-r--r--gtk/new_packet_list.h43
-rw-r--r--gtk/packet_list_store.c674
-rw-r--r--gtk/packet_list_store.h94
-rw-r--r--gtk/prefs_column.c2
-rw-r--r--gtk/prefs_gui.c2
-rw-r--r--gtk/prefs_stream.c2
-rw-r--r--gtk/recent.c9
-rw-r--r--ui_util.h3
24 files changed, 1275 insertions, 12 deletions
diff --git a/color_filters.c b/color_filters.c
index 6d72c1928e..4076e22203 100644
--- a/color_filters.c
+++ b/color_filters.c
@@ -431,6 +431,7 @@ color_filters_prime_edt(epan_dissect_t *edt)
g_slist_foreach(color_filter_list, prime_edt, edt);
}
+#ifndef NEW_PACKET_LIST
/* Colorize a single packet of the packet list */
color_filter_t *
color_filters_colorize_packet(gint row, epan_dissect_t *edt)
@@ -448,7 +449,9 @@ color_filters_colorize_packet(gint row, epan_dissect_t *edt)
(colorf->c_colorfilter != NULL) &&
dfilter_apply_edt(colorf->c_colorfilter, edt)) {
/* this is the filter to use, apply it to the packet list */
+#ifndef NEW_PACKET_LIST
packet_list_set_colors(row, &(colorf->fg_color), &(colorf->bg_color));
+#endif
return colorf;
}
curr = g_slist_next(curr);
@@ -457,6 +460,7 @@ color_filters_colorize_packet(gint row, epan_dissect_t *edt)
return NULL;
}
+#endif /* NEW_PACKET_LIST */
/* read filters from the given file */
/* XXX - Would it make more sense to use GStrings here instead of reallocing
diff --git a/file.c b/file.c
index 1ed059c761..b85931e9a9 100644
--- a/file.c
+++ b/file.c
@@ -73,6 +73,10 @@
#include <epan/column-utils.h>
#include <epan/strutil.h>
+#ifdef NEW_PACKET_LIST
+#include "gtk/new_packet_list.h"
+#endif
+
#ifdef HAVE_LIBPCAP
gboolean auto_scroll_live;
#endif
@@ -354,9 +358,14 @@ cf_reset_state(capture_file *cf)
cf->finfo_selected = NULL;
/* Clear the packet list. */
+#ifdef NEW_PACKET_LIST
+ new_packet_list_freeze();
+ new_packet_list_thaw();
+#else
packet_list_freeze();
packet_list_clear();
packet_list_thaw();
+#endif
cf->f_datalen = 0;
cf->count = 0;
@@ -456,7 +465,11 @@ cf_read(capture_file *cf)
/* Progress so far. */
progbar_val = 0.0f;
+#ifdef NEW_PACKET_LIST
+ new_packet_list_freeze();
+#else
packet_list_freeze();
+#endif
stop_flag = FALSE;
g_get_current_time(&start_time);
@@ -501,14 +514,18 @@ cf_read(capture_file *cf)
if (progbar_quantum > 500000 || displayed_once == 0) {
if ((auto_scroll_live || displayed_once == 0 || cf->displayed_count < 1000) && cf->plist_end != NULL) {
displayed_once = 1;
+#ifdef NEW_PACKET_LIST
+ /* XXX - Add move to end function call. Freeze/thaw if
+ * necessary. */
+#else
packet_list_thaw();
if (auto_scroll_live)
packet_list_moveto_end();
packet_list_freeze();
+#endif /* NEW_PACKET_LIST */
}
- }
-#endif
-
+ }
+#endif /* HAVE_LIBPCAP */
g_snprintf(status_str, sizeof(status_str),
"%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
file_pos / 1024, size / 1024);
@@ -581,14 +598,20 @@ cf_read(capture_file *cf)
cf->current_frame = cf->first_displayed;
cf->current_row = 0;
+#ifdef NEW_PACKET_LIST
+ new_packet_list_thaw();
+#else
packet_list_thaw();
+#endif
cf_callback_invoke(cf_cb_file_read_finished, cf);
+#ifndef NEW_PACKET_LIST
/* If we have any displayed packets to select, select the first of those
packets by making the first row the selected row. */
if (cf->first_displayed != NULL)
packet_list_select_row(0);
+#endif /* NEW_PACKET_LIST */
if(stop_flag) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
@@ -684,8 +707,12 @@ cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
*err = 0;
+#ifdef NEW_PACKET_LIST
+ new_packet_list_freeze();
+#else
packet_list_check_end();
packet_list_freeze();
+#endif
/*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: %u new: %u", cf->count, to_read);*/
@@ -723,7 +750,11 @@ cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
/* XXX - how to avoid a busy wait? */
/* Sleep(100); */
};
- packet_list_thaw();
+#ifdef NEW_PACKET_LIST
+ new_packet_list_thaw();
+#else
+ packet_list_thaw();
+#endif
return CF_READ_ABORTED;
}
ENDTRY;
@@ -738,9 +769,14 @@ cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
/*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: count %u state: %u err: %u",
cf->count, cf->state, *err);*/
+#ifdef NEW_PACKET_LIST
+ new_packet_list_thaw();
+#else
/* XXX - this causes "flickering" of the list */
packet_list_thaw();
+#endif
+#ifndef NEW_PACKET_LIST
/* moving to the end of the packet list - if the user requested so and
we have some new packets.
this doesn't seem to work well with a frozen GTK_Clist, so do this after
@@ -749,6 +785,7 @@ cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
row number. */
if (newly_displayed_packets && auto_scroll_live && cf->plist_end != NULL)
packet_list_moveto_end();
+#endif /* NEW_PACKET_LIST */
if (cf->state == FILE_READ_ABORTED) {
/* Well, the user decided to exit Wireshark. Return CF_READ_ABORTED
@@ -797,8 +834,12 @@ cf_finish_tail(capture_file *cf, int *err)
return CF_READ_ERROR;
}
+#ifdef NEW_PACKET_LIST
+ new_packet_list_freeze();
+#else
packet_list_check_end();
packet_list_freeze();
+#endif
while ((wtap_read(cf->wth, err, &err_info, &data_offset))) {
if (cf->state == FILE_READ_ABORTED) {
@@ -815,7 +856,11 @@ cf_finish_tail(capture_file *cf, int *err)
dfilter_free(dfcode);
}
+#ifdef NEW_PACKET_LIST
+ new_packet_list_thaw();
+#else
packet_list_thaw();
+#endif
if (cf->state == FILE_READ_ABORTED) {
/* Well, the user decided to abort the read. We're only called
@@ -827,10 +872,12 @@ cf_finish_tail(capture_file *cf, int *err)
return CF_READ_ABORTED;
}
+#ifndef NEW_PACKET_LIST
if (auto_scroll_live && cf->plist_end != NULL)
/* XXX - this cheats and looks inside the packet list to find the final
row number. */
packet_list_moveto_end();
+#endif
/* We're done reading sequentially through the file. */
cf->state = FILE_READ_DONE;
@@ -1085,8 +1132,14 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
}
}
#endif
+
+#ifdef NEW_PACKET_LIST
+ row = new_packet_list_append(cf->cinfo, fdata);
+#else
row = packet_list_append(cf->cinfo.col_data, fdata);
+#endif
+#ifndef NEW_PACKET_LIST
/* colorize packet: first apply color filters
* then if packet is marked, use preferences to overwrite color
* we do both to make sure that when a packet gets un-marked, the
@@ -1096,6 +1149,7 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
if (fdata->flags.marked) {
packet_list_set_colors(row, &prefs.gui_marked_fg, &prefs.gui_marked_bg);
}
+#endif /* NEW_PACKET_LIST */
/* Set the time of the previous displayed frame to the time of this
frame. */
@@ -1587,10 +1641,14 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
/* Freeze the packet list while we redo it, so we don't get any
screen updates while it happens. */
+#ifdef NEW_PACKET_LIST
+ new_packet_list_freeze();
+#else
packet_list_freeze();
/* Clear it out. */
packet_list_clear();
+#endif
/* We don't yet know which will be the first and last frames displayed. */
cf->first_displayed = NULL;
@@ -1731,8 +1789,10 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
/* We are done redissecting the packet list. */
cf->redissecting = FALSE;
+#ifndef NEW_PACKET_LIST
/* Re-sort the list using the previously selected order */
packet_list_set_sort_column();
+#endif
if (redissect) {
/* Clear out what remains of the visited flags and per-frame data
@@ -1759,7 +1819,11 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
destroy_progress_dlg(progbar);
/* Unfreeze the packet list. */
+#ifdef NEW_PACKET_LIST
+ new_packet_list_thaw();
+#else
packet_list_thaw();
+#endif
if (selected_row == -1) {
/* The selected frame didn't pass the filter. */
@@ -1798,6 +1862,7 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
/* There are no frames displayed at all. */
cf_unselect_packet(cf);
} else {
+#ifndef NEW_PACKET_LIST
/* Either the frame that was selected passed the filter, or we've
found the nearest displayed frame to that frame. Select it, make
it the focus row, and make it visible. */
@@ -1806,6 +1871,7 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
cf->current_row = -1;
}
packet_list_set_selected_row(selected_row);
+#endif /* NEW_PACKET_LIST */
}
/* Cleanup and release all dfilter resources */
@@ -2617,7 +2683,11 @@ cf_change_time_formats(capture_file *cf)
/* Freeze the packet list while we redo it, so we don't get any
screen updates while it happens. */
+#ifdef NEW_PACKET_LIST
+ new_packet_list_freeze();
+#else
packet_list_freeze();
+#endif
/* Update the progress bar when it gets to this value. */
progbar_nextstep = 0;
@@ -2645,7 +2715,9 @@ cf_change_time_formats(capture_file *cf)
for (i = 0; i < cf->cinfo.num_cols; i++) {
if (cf->cinfo.col_fmt[i] == COL_NUMBER)
{
+#ifndef NEW_PACKET_LIST
sorted_by_frame_column = (i == packet_list_get_sort_column());
+#endif
break;
}
}
@@ -2703,7 +2775,9 @@ cf_change_time_formats(capture_file *cf)
/* Find what row this packet is in. */
if (!sorted_by_frame_column) {
/* This function is O(N), so we try to avoid using it... */
+#ifndef NEW_PACKET_LIST
row = packet_list_find_row_from_data(fdata);
+#endif
} else {
/* ...which we do by maintaining a count of packets that are
being displayed (i.e., that have passed the display filter),
@@ -2725,7 +2799,9 @@ cf_change_time_formats(capture_file *cf)
"command-line-specified" format; update it. */
cf->cinfo.col_buf[i][0] = '\0';
col_set_fmt_time(fdata, &cf->cinfo, cf->cinfo.col_fmt[i], i);
+#ifndef NEW_PACKET_LIST
packet_list_set_text(row, i, cf->cinfo.col_data[i]);
+#endif
}
}
}
@@ -2740,12 +2816,18 @@ cf_change_time_formats(capture_file *cf)
"command-line-specified" format. */
for (i = 0; i < cf->cinfo.num_cols; i++) {
if (col_has_time_fmt(&cf->cinfo, i)) {
+#ifndef NEW_PACKET_LIST
packet_list_set_time_width(cf->cinfo.col_fmt[i], i);
+#endif
}
}
/* Unfreeze the packet list. */
+#ifdef NEW_PACKET_LIST
+ new_packet_list_thaw();
+#else
packet_list_thaw();
+#endif
}
typedef struct {
@@ -3091,7 +3173,9 @@ find_packet(capture_file *cf,
int count;
int err;
gchar *err_info;
+#ifndef NEW_PACKET_LIST
int row;
+#endif
float progbar_val;
GTimeVal start_time;
gchar status_str[100];
@@ -3248,6 +3332,7 @@ find_packet(capture_file *cf,
}
if (new_fd != NULL) {
+#ifndef NEW_PACKET_LIST
/* We found a frame. Find what row it's in. */
row = packet_list_find_row_from_data(new_fd);
if (row == -1) {
@@ -3263,6 +3348,7 @@ find_packet(capture_file *cf,
/* Select that row, make it the focus row, and make it visible. */
packet_list_set_selected_row(row);
+#endif /* NEW_PACKET_LIST */
return TRUE; /* success */
} else
return FALSE; /* failure */
@@ -3272,7 +3358,9 @@ gboolean
cf_goto_frame(capture_file *cf, guint fnumber)
{
frame_data *fdata;
+#ifndef NEW_PACKET_LIST
int row;
+#endif
for (fdata = cf->plist; fdata != NULL && fdata->num < fnumber; fdata = fdata->next)
;
@@ -3291,6 +3379,7 @@ cf_goto_frame(capture_file *cf, guint fnumber)
return FALSE; /* we failed to go to that packet */
}
+#ifndef NEW_PACKET_LIST
/* We found that packet, and it's currently being displayed.
Find what row it's in. */
row = packet_list_find_row_from_data(fdata);
@@ -3298,6 +3387,7 @@ cf_goto_frame(capture_file *cf, guint fnumber)
/* Select that row, make it the focus row, and make it visible. */
packet_list_set_selected_row(row);
+#endif /* NEW_PACKET_LIST */
return TRUE; /* we got to that packet */
}
@@ -3305,7 +3395,9 @@ gboolean
cf_goto_top_frame(capture_file *cf)
{
frame_data *fdata;
+#ifndef NEW_PACKET_LIST
int row;
+#endif
frame_data *lowest_fdata = NULL;
for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
@@ -3319,6 +3411,7 @@ cf_goto_top_frame(capture_file *cf)
return FALSE;
}
+#ifndef NEW_PACKET_LIST
/* We found that packet, and it's currently being displayed.
Find what row it's in. */
row = packet_list_find_row_from_data(lowest_fdata);
@@ -3326,6 +3419,7 @@ cf_goto_top_frame(capture_file *cf)
/* Select that row, make it the focus row, and make it visible. */
packet_list_set_selected_row(row);
+#endif /* NEW_PACKET_LIST */
return TRUE; /* we got to that packet */
}
@@ -3333,7 +3427,9 @@ gboolean
cf_goto_bottom_frame(capture_file *cf)
{
frame_data *fdata;
+#ifndef NEW_PACKET_LIST
int row;
+#endif
frame_data *highest_fdata = NULL;
for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
@@ -3346,6 +3442,7 @@ cf_goto_bottom_frame(capture_file *cf)
return FALSE;
}
+#ifndef NEW_PACKET_LIST
/* We found that packet, and it's currently being displayed.
Find what row it's in. */
row = packet_list_find_row_from_data(highest_fdata);
@@ -3353,6 +3450,7 @@ cf_goto_bottom_frame(capture_file *cf)
/* Select that row, make it the focus row, and make it visible. */
packet_list_set_selected_row(row);
+#endif /* NEW_PACKET_LIST */
return TRUE; /* we got to that packet */
}
@@ -3387,7 +3485,11 @@ cf_select_packet(capture_file *cf, int row)
gchar *err_info;
/* Get the frame data struct pointer for this frame */
+#ifdef NEW_PACKET_LIST
+ fdata = new_packet_list_get_row_data(row);
+#else
fdata = (frame_data *)packet_list_get_row_data(row);
+#endif
if (fdata == NULL) {
/* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
diff --git a/gtk/Makefile.common b/gtk/Makefile.common
index 4ff9b3c291..e0f31df051 100644
--- a/gtk/Makefile.common
+++ b/gtk/Makefile.common
@@ -87,7 +87,9 @@ WIRESHARK_GTK_SRC = \
main_toolbar.c \
main_welcome.c \
mcast_stream.c \
+ new_packet_list.c \
packet_history.c \
+ packet_list_store.c \
packet_win.c \
pixmap_save.c \
plugins_dlg.c \
@@ -267,7 +269,9 @@ noinst_HEADERS = \
mcast_stream.h \
mcast_stream_dlg.h \
mtp3_stat.h \
+ new_packet_list.h \
packet_history.h \
+ packet_list_store.h \
packet_win.h \
pixmap_save.h \
plugins_dlg.h \
diff --git a/gtk/capture_file_dlg.c b/gtk/capture_file_dlg.c
index b4b472ecff..787a2c6614 100644
--- a/gtk/capture_file_dlg.c
+++ b/gtk/capture_file_dlg.c
@@ -690,7 +690,9 @@ file_open_ok_cb(GtkWidget *w, gpointer fs) {
"get_dirname()" does write over its argument. */
s = get_dirname(cf_name);
set_last_open_dir(s);
+#ifndef NEW_PACKET_LIST
gtk_widget_grab_focus(packet_list);
+#endif
g_free(cf_name);
}
@@ -716,8 +718,13 @@ file_merge_cmd(GtkWidget *w)
{
#if _WIN32
win32_merge_file(GDK_WINDOW_HWND(top_level->window));
+#ifdef NEW_PACKET_LIST
+ new_packet_list_freeze();
+ new_packet_list_thaw();
+#else
packet_list_freeze();
packet_list_thaw();
+#endif /* NEW_PACKET_LIST */
#else /* _WIN32 */
GtkWidget *main_hb, *main_vb, *ft_hb, *ft_lb, *filter_hbox,
*filter_bt, *filter_te, *prepend_rb, *chrono_rb,
@@ -1020,7 +1027,9 @@ file_merge_ok_cb(GtkWidget *w, gpointer fs) {
"get_dirname()" does write over its argument. */
s = get_dirname(tmpname);
set_last_open_dir(s);
+#ifndef NEW_PACKET_LIST
gtk_widget_grab_focus(packet_list);
+#endif
}
static void
@@ -1586,7 +1595,9 @@ file_color_import_ok_cb(GtkWidget *w, gpointer color_filters) {
"get_dirname()" does write over its argument. */
s = get_dirname(cf_name);
set_last_open_dir(s);
+#ifndef NEW_PACKET_LIST
gtk_widget_grab_focus(packet_list);
+#endif
g_free(cf_name);
}
diff --git a/gtk/color_dlg.c b/gtk/color_dlg.c
index e2bb740cef..6f6b212529 100644
--- a/gtk/color_dlg.c
+++ b/gtk/color_dlg.c
@@ -64,8 +64,10 @@ static void color_filter_down_cb(GtkButton *button, gpointer user_data);
static void remember_selected_row(GtkTreeSelection *sel, gpointer list);
static void color_destroy_cb(GtkButton *button, gpointer user_data);
static void destroy_edit_dialog_cb(gpointer filter_arg, gpointer dummy);
+#ifndef NEW_PACKET_LIST
static void create_new_color_filter(GtkButton *button, const char *filter);
static void color_new_cb(GtkButton *button, gpointer user_data);
+#endif
static void color_edit_cb(GtkButton *button, gpointer user_data);
static gint color_filters_button_cb(GtkWidget *, GdkEventButton *, gpointer);
static void color_disable_cb(GtkWidget *widget, gboolean user_data);
@@ -400,7 +402,9 @@ colorize_dialog_new (char *filter)
g_object_set_data(G_OBJECT(color_filters), COLOR_DISABLE_LB, color_disable);
g_object_set_data(G_OBJECT(color_filters), COLOR_DELETE_LB, color_delete);
g_object_set_data(G_OBJECT(color_new), COLOR_FILTERS_CL, color_filters);
+#ifndef NEW_PACKET_LIST
g_signal_connect(color_new, "clicked", G_CALLBACK(color_new_cb), NULL);
+#endif
g_object_set_data(G_OBJECT(color_edit), COLOR_FILTERS_CL, color_filters);
g_signal_connect(color_edit, "clicked", G_CALLBACK(color_edit_cb), NULL);
g_object_set_data(G_OBJECT(color_enable), COLOR_FILTERS_CL, color_filters);
@@ -439,7 +443,9 @@ colorize_dialog_new (char *filter)
if(filter){
/* if we specified a preset filter string, open the new dialog and
set the filter */
+#ifndef NEW_PACKET_LIST
create_new_color_filter(GTK_BUTTON(color_new), filter);
+#endif
}
return color_win;
@@ -698,6 +704,7 @@ color_destroy_cb (GtkButton *button _U_,
}
+#ifndef NEW_PACKET_LIST
static void
select_row(GtkWidget *color_filters, int row)
{
@@ -713,7 +720,7 @@ select_row(GtkWidget *color_filters, int row)
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
gtk_tree_selection_select_iter(sel, &iter);
}
-
+#endif
/* add a single color filter to the list */
@@ -760,6 +767,7 @@ color_filter_add_cb(color_filter_t *colorf, gpointer user_data)
gtk_widget_grab_focus(color_filters);
}
+#ifndef NEW_PACKET_LIST
/* Create a new filter, add it to the list, and pop up an
"Edit color filter" dialog box to edit it. */
static void
@@ -791,7 +799,9 @@ create_new_color_filter(GtkButton *button, const char *filter)
gtk_widget_grab_focus(color_filters);
}
+#endif /* NEW_PACKET_LIST */
+#ifndef NEW_PACKET_LIST
/* User pressed the "New" button: Create a new filter in the list,
and pop up an "Edit color filter" dialog box to edit it. */
static void
@@ -799,6 +809,7 @@ color_new_cb(GtkButton *button, gpointer user_data _U_)
{
create_new_color_filter(button, "filter");
}
+#endif
/* User pressed the "Edit" button: Pop up an "Edit color filter" dialog box
* to edit an existing filter. */
diff --git a/gtk/drag_and_drop.c b/gtk/drag_and_drop.c
index 1e43326aa3..f5bd0db1ee 100644
--- a/gtk/drag_and_drop.c
+++ b/gtk/drag_and_drop.c
@@ -194,7 +194,9 @@ dnd_merge_files(int in_file_count, char **in_filenames)
return;
}
+#ifndef NEW_PACKET_LIST
gtk_widget_grab_focus(packet_list);
+#endif
}
/* open/merge the dnd file */
diff --git a/gtk/font_utils.c b/gtk/font_utils.c
index 456af0b9d0..e9799aa09a 100644
--- a/gtk/font_utils.c
+++ b/gtk/font_utils.c
@@ -274,7 +274,9 @@ user_font_apply(void) {
}
/* the font(s) seem to be ok */
+#ifndef NEW_PACKET_LIST
packet_list_set_font(new_r_font);
+#endif
set_ptree_font_all(new_r_font);
old_r_font = m_r_font;
old_b_font = m_b_font;
diff --git a/gtk/gtkglobals.h b/gtk/gtkglobals.h
index 3099a06974..f233d2c9d3 100644
--- a/gtk/gtkglobals.h
+++ b/gtk/gtkglobals.h
@@ -42,8 +42,10 @@
/** Application window. */
extern GtkWidget *top_level;
+#ifndef NEW_PACKET_LIST
/** Packet list pane. */
extern GtkWidget *packet_list;
+#endif
/** Tree view (packet details) pane. */
extern GtkWidget *tree_view;
diff --git a/gtk/main.c b/gtk/main.c
index 44f4eee6dc..35adcdd5b0 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -173,6 +173,10 @@
#include <epan/crypt/airpdcap_ws.h>
#endif
+#ifdef NEW_PACKET_LIST
+#include "gtk/new_packet_list.h"
+#endif
+
/*
* Files under personal and global preferences directories in which
* GTK settings for Wireshark are stored.
@@ -490,6 +494,7 @@ selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
}
}
+#ifndef NEW_PACKET_LIST
static gchar *
get_filter_from_packet_list_row_and_column(gpointer data)
{
@@ -513,6 +518,7 @@ match_selected_plist_cb(GtkWidget *w _U_, gpointer data, MATCH_SELECTED_E action
action,
get_filter_from_packet_list_row_and_column(data));
}
+#endif /* NEW_PACKET_LIST */
/* This function allows users to right click in the details window and copy the text
* information to the operating systems clipboard.
@@ -2524,13 +2530,16 @@ main(int argc, char *argv[])
is displayed.
XXX - is that still true, with fixed-width columns? */
+#ifndef NEW_PACKET_LIST
packet_list_set_column_titles();
+#endif
menu_recent_read_finished();
#ifdef HAVE_LIBPCAP
menu_auto_scroll_live_changed(auto_scroll_live);
#endif
+#ifndef NEW_PACKET_LIST
switch (user_font_apply()) {
case FA_SUCCESS:
break;
@@ -2549,6 +2558,7 @@ main(int argc, char *argv[])
recent.gui_zoom_level = 0;
/* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
}
+#endif /* NEW_PACKET_LIST */
dnd_init(top_level);
@@ -3136,8 +3146,10 @@ main_widgets_show_or_hide(void)
}
/* workaround for bug in GtkCList to ensure packet list scrollbar is updated */
+#ifndef NEW_PACKET_LIST
packet_list_freeze ();
- packet_list_thaw ();
+ packet_list_thaw ();
+#endif
}
@@ -3166,10 +3178,14 @@ static int
top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
{
if (event->keyval == GDK_F8) {
+#ifndef NEW_PACKET_LIST
packet_list_next();
+#endif
return TRUE;
} else if (event->keyval == GDK_F7) {
+#ifndef NEW_PACKET_LIST
packet_list_prev();
+#endif
return TRUE;
} else if (event->state & NO_SHIFT_MOD_MASK) {
return FALSE; /* Skip control, alt, and other modifiers */
@@ -3243,9 +3259,15 @@ create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
filter_tb = filter_toolbar_new();
/* Packet list */
+#ifdef NEW_PACKET_LIST
+ pkt_scrollw = new_packet_list_create();
+ gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
+ gtk_widget_show_all(pkt_scrollw);
+#else
pkt_scrollw = packet_list_new(prefs);
gtk_widget_set_size_request(packet_list, -1, pl_size);
gtk_widget_show(pkt_scrollw);
+#endif
/* Tree view */
tv_scrollw = main_tree_view_new(prefs, &tree_view);
@@ -3254,8 +3276,10 @@ create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)),
"changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
+#ifndef NEW_PACKET_LIST
g_signal_connect(tree_view, "button_press_event", G_CALLBACK(popup_menu_handler),
g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
+#endif /* NEW_PACKET_LIST */
gtk_widget_show(tree_view);
/* Byte view. */
@@ -3263,9 +3287,10 @@ create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
gtk_widget_set_size_request(byte_nb_ptr, -1, bv_size);
gtk_widget_show(byte_nb_ptr);
+#ifndef NEW_PACKET_LIST
g_signal_connect(byte_nb_ptr, "button_press_event", G_CALLBACK(popup_menu_handler),
g_object_get_data(G_OBJECT(popup_menu_object), PM_HEXDUMP_KEY));
-
+#endif /* NEW_PACKET_LIST */
/* Panes for the packet list, tree, and byte view */
main_pane_v1 = gtk_vpaned_new();
@@ -3394,10 +3419,12 @@ void change_configuration_profile (const gchar *profile_name)
/* Reload list of interfaces on welcome page */
welcome_if_panel_reload();
+#ifndef NEW_PACKET_LIST
/* Recreate the packet list according to new preferences */
packet_list_recreate ();
cfile.cinfo.columns_changed = FALSE; /* Reset value */
user_font_apply();
+#endif
}
/** redissect packets and update UI */
diff --git a/gtk/main.h b/gtk/main.h
index 5dafbf2e19..acd5a221f8 100644
--- a/gtk/main.h
+++ b/gtk/main.h
@@ -159,6 +159,7 @@ extern void copy_selected_plist_cb(GtkWidget *w _U_, gpointer data, COPY_SELECTE
*/
extern void colorize_selected_ptree_cb(GtkWidget *w, gpointer data, guint8 filt_nr);
+#ifndef NEW_PACKET_LIST
/** User requested one of "Apply as Filter" or "Prepare a Filter" functions
* by context menu of packet list.
*
@@ -167,6 +168,7 @@ extern void colorize_selected_ptree_cb(GtkWidget *w, gpointer data, guint8 filt_
* @param action the function to use
*/
extern void match_selected_plist_cb(GtkWidget *widget, gpointer data, MATCH_SELECTED_E action);
+#endif /* NEW_PACKET_LIST */
/** User requested "Quit" by menu or toolbar.
*
diff --git a/gtk/main_packet_list.c b/gtk/main_packet_list.c
index ab41c902f0..9ec04716a1 100644
--- a/gtk/main_packet_list.c
+++ b/gtk/main_packet_list.c
@@ -26,6 +26,8 @@
# include "config.h"
#endif
+#ifndef NEW_PACKET_LIST
+
#include <gtk/gtk.h>
#include <string.h>
@@ -378,6 +380,7 @@ void packet_list_unmark_all_frames_cb(GtkWidget *w _U_, gpointer data _U_)
mark_all_frames(FALSE);
}
+#ifndef NEW_PACKET_LIST */
gboolean
packet_list_get_event_row_column(GtkWidget *w, GdkEventButton *event_button,
gint *row, gint *column)
@@ -386,6 +389,7 @@ packet_list_get_event_row_column(GtkWidget *w, GdkEventButton *event_button,
(gint) event_button->x, (gint) event_button->y,
row, column);
}
+#endif /* NEW_PACKET_LIST */
static gint
packet_list_button_pressed_cb(GtkWidget *w, GdkEvent *event, gpointer data _U_)
@@ -988,3 +992,5 @@ packet_list_recent_write_all(FILE *rf)
}
fprintf (rf, "\n");
}
+
+#endif /* NEW_PACKET_LIST */
diff --git a/gtk/main_packet_list.h b/gtk/main_packet_list.h
index 49f2d7e302..cc6d1eca9c 100644
--- a/gtk/main_packet_list.h
+++ b/gtk/main_packet_list.h
@@ -25,6 +25,8 @@
#ifndef __PACKET_LIST_H__
#define __PACKET_LIST_H__
+#ifndef NEW_PACKET_LIST
+
#define RECENT_KEY_COL_WIDTH "column.width"
/** @file
@@ -140,4 +142,6 @@ extern void packet_list_copy_summary_cb(GtkWidget * w _U_, gpointer data _U_, co
*/
extern void packet_list_recent_write_all(FILE *rf);
+#endif /* NEW_PACKET_LIST */
+
#endif /* __PACKET_LIST_H__ */
diff --git a/gtk/main_proto_draw.c b/gtk/main_proto_draw.c
index 83f29145c5..4a0b3d9d46 100644
--- a/gtk/main_proto_draw.c
+++ b/gtk/main_proto_draw.c
@@ -518,8 +518,10 @@ byte_view_button_press_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
case 1:
return byte_view_select(widget, event_button);
+#ifndef NEW_PACKET_LIST
case 3:
return popup_menu_handler(widget, event, data);
+#endif
default:
return FALSE;
}
@@ -588,13 +590,19 @@ add_byte_tab(GtkWidget *byte_nb, const char *name, tvbuff_t *tvb,
gtk_text_view_set_editable(GTK_TEXT_VIEW(byte_view), FALSE);
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(byte_view), FALSE);
buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(byte_view));
+
+#ifdef NEW_PACKET_LIST
+ style = gtk_widget_get_style(GTK_WIDGET(top_level));
+#else
style = gtk_widget_get_style(GTK_WIDGET(packet_list));
+ #endif
gtk_text_buffer_create_tag(buf, "plain", "font-desc", user_font_get_regular(), NULL);
gtk_text_buffer_create_tag(buf, "reverse",
"font-desc", user_font_get_regular(),
"foreground-gdk", &style->text[GTK_STATE_SELECTED],
"background-gdk", &style->base[GTK_STATE_SELECTED],
NULL);
+
gtk_text_buffer_create_tag(buf, "bold", "font-desc", user_font_get_bold(), NULL);
g_object_set_data(G_OBJECT(byte_view), E_BYTE_VIEW_TVBUFF_KEY, tvb);
gtk_container_add(GTK_CONTAINER(byte_scrollw), byte_view);
diff --git a/gtk/main_toolbar.c b/gtk/main_toolbar.c
index 0994171995..a32f004558 100644
--- a/gtk/main_toolbar.c
+++ b/gtk/main_toolbar.c
@@ -76,7 +76,10 @@ static GtkToolItem *open_button, *save_button, *close_button, *reload_button;
static GtkToolItem *print_button, *find_button, *history_forward_button, *history_back_button;
static GtkToolItem *go_to_button, *go_to_top_button, *go_to_bottom_button;
static GtkToolItem *display_filter_button;
-static GtkToolItem *zoom_in_button, *zoom_out_button, *zoom_100_button, *colorize_button, *resize_columns_button;
+static GtkToolItem *zoom_in_button, *zoom_out_button, *zoom_100_button, *colorize_button;
+#ifndef NEW_PACKET_LIST
+static GtkToolItem *resize_columns_button;
+#endif
static GtkToolItem *color_display_button, *prefs_button, *help_button;
#define SAVE_BUTTON_TOOLTIP_TEXT "Save this capture file..."
@@ -202,8 +205,10 @@ void set_toolbar_for_captured_packets(gboolean have_captured_packets) {
have_captured_packets);
gtk_widget_set_sensitive(GTK_WIDGET(zoom_100_button),
have_captured_packets);
+#ifndef NEW_PACKET_LIST
gtk_widget_set_sensitive(GTK_WIDGET(resize_columns_button),
have_captured_packets);
+#endif
/* XXX - I don't see a reason why this should be done (as it is in the
* menus) */
/* gtk_widget_set_sensitive(GTK_WIDGET(color_display_button),
@@ -381,8 +386,10 @@ toolbar_new(void)
toolbar_item(zoom_100_button, main_tb,
GTK_STOCK_ZOOM_100, tooltips, "Zoom 100%", view_zoom_100_cb, NULL);
+#ifndef NEW_PACKET_LIST
toolbar_item(resize_columns_button, main_tb,
WIRESHARK_STOCK_RESIZE_COLUMNS, tooltips, "Resize All Columns", packet_list_resize_columns_cb, NULL);
+#endif
toolbar_append_separator(main_tb);
diff --git a/gtk/menus.c b/gtk/menus.c
index 4cdb10c9a7..6413d0cabc 100644
--- a/gtk/menus.c
+++ b/gtk/menus.c
@@ -492,6 +492,7 @@ static GtkItemFactoryEntry menu_items[] =
{"/Edit/Find Ne_xt", "<control>N", GTK_MENU_FUNC(find_next_cb), 0, NULL, NULL,},
{"/Edit/Find Pre_vious", "<control>B", GTK_MENU_FUNC(find_previous_cb), 0, NULL, NULL,},
{"/Edit/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
+#ifndef NEW_PACKET_LIST
{"/Edit/_Mark Packet (toggle)", "<control>M", GTK_MENU_FUNC(packet_list_mark_frame_cb),
0, NULL, NULL,},
{"/Edit/Find Next Mark", "<shift><control>N", GTK_MENU_FUNC(find_next_mark_cb),
@@ -503,6 +504,7 @@ static GtkItemFactoryEntry menu_items[] =
{"/Edit/_Unmark All Packets", "<control>D", GTK_MENU_FUNC(packet_list_unmark_all_frames_cb),
0, NULL, NULL,},
{"/Edit/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
+#endif /* NEW_PACKET_LIST */
{"/Edit/Set Time Reference (toggle)", "<control>T", GTK_MENU_FUNC(reftime_frame_cb),
REFTIME_TOGGLE, "<StockItem>", WIRESHARK_STOCK_TIME,},
{"/Edit/Find Next Reference", "<alt><shift><control>N", GTK_MENU_FUNC(reftime_frame_cb), REFTIME_FIND_NEXT, NULL, NULL,},
@@ -568,8 +570,10 @@ static GtkItemFactoryEntry menu_items[] =
0, "<StockItem>", GTK_STOCK_ZOOM_OUT,},
{"/View/_Normal Size", "<control>equal", GTK_MENU_FUNC(view_zoom_100_cb),
0, "<StockItem>", GTK_STOCK_ZOOM_100,},
+#ifndef NEW_PACKET_LIST
{"/View/Resize All Columns", "<shift><control>R", GTK_MENU_FUNC(packet_list_resize_columns_cb),
0, "<StockItem>", WIRESHARK_STOCK_RESIZE_COLUMNS,},
+#endif /* NEW_PACKET_LIST */
{"/View/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
{"/View/E_xpand Subtrees", "<shift>Right", GTK_MENU_FUNC(expand_tree_cb), 0, NULL, NULL,},
{"/View/_Expand All", "<control>Right", GTK_MENU_FUNC(expand_all_cb),
@@ -623,6 +627,7 @@ static GtkItemFactoryEntry menu_items[] =
{"/Go/Go to _Corresponding Packet", NULL, GTK_MENU_FUNC(goto_framenum_cb),
0, NULL, NULL,},
{"/Go/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
+ #ifndef NEW_PACKET_LIST
{"/Go/Previous Packet", "<control>Up",
GTK_MENU_FUNC(packet_list_prev), 0, "<StockItem>", GTK_STOCK_GO_UP,},
{"/Go/Next Packet", "<control>Down",
@@ -631,6 +636,7 @@ static GtkItemFactoryEntry menu_items[] =
GTK_MENU_FUNC(goto_top_frame_cb), 0, "<StockItem>", GTK_STOCK_GOTO_TOP,},
{"/Go/_Last Packet", "<control>End",
GTK_MENU_FUNC(goto_bottom_frame_cb), 0, "<StockItem>", GTK_STOCK_GOTO_BOTTOM,},
+#endif /* NEW_PACKET_LIST */
#ifdef HAVE_LIBPCAP
{"/_Capture", NULL, NULL, 0, "<Branch>", NULL,},
{"/Capture/_Interfaces...", "<control>I",
@@ -735,12 +741,15 @@ static int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
/* packet list popup */
static GtkItemFactoryEntry packet_list_menu_items[] =
{
+#ifndef NEW_PACKET_LIST
{"/Mark Packet (toggle)", NULL, GTK_MENU_FUNC(packet_list_mark_frame_cb), 0, NULL, NULL,},
+#endif /* NEW_PACKET_LIST */
{"/Set Time Reference (toggle)", NULL, GTK_MENU_FUNC(reftime_frame_cb), REFTIME_TOGGLE, "<StockItem>", WIRESHARK_STOCK_TIME,},
{"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
{"/Apply as Filter", NULL, NULL, 0, "<Branch>", NULL,},
+#ifndef NEW_PACKET_LIST */
{"/Apply as Filter/_Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
{"/Apply as Filter/_Not Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
@@ -753,7 +762,6 @@ static GtkItemFactoryEntry packet_list_menu_items[] =
MATCH_SELECTED_AND_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
{"/Apply as Filter/... o_r not Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
MATCH_SELECTED_OR_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
-
{"/Prepare a Filter", NULL, NULL, 0, "<Branch>", NULL,},
{"/Prepare a Filter/_Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
MATCH_SELECTED_REPLACE, NULL, NULL,},
@@ -767,7 +775,7 @@ static GtkItemFactoryEntry packet_list_menu_items[] =
MATCH_SELECTED_AND_NOT, NULL, NULL,},
{"/Prepare a Filter/... o_r not Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
MATCH_SELECTED_OR_NOT, NULL, NULL,},
-
+#endif /* NEW_PACKET_LIST */
{"/Conversation Filter", NULL, NULL, 0, "<Branch>",NULL,},
{"/Conversation Filter/Ethernet", NULL, GTK_MENU_FUNC(conversation_cb),
CONV_ETHER, NULL, NULL,},
@@ -921,13 +929,14 @@ static GtkItemFactoryEntry packet_list_menu_items[] =
0, NULL, NULL,},
{"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
-
+#ifndef NEW_PACKET_LIST
{"/Copy", NULL, NULL, 0, "<Branch>", NULL,},
{"/Copy/Summary (Text)", NULL, GTK_MENU_FUNC(packet_list_copy_summary_cb), CS_TEXT, NULL, NULL,},
{"/Copy/Summary (CSV)", NULL, GTK_MENU_FUNC(packet_list_copy_summary_cb), CS_CSV, NULL, NULL,},
{"/Copy/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
{"/Copy/As Filter", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
MATCH_SELECTED_REPLACE|MATCH_SELECTED_COPY_ONLY, NULL, NULL,},
+#endif /* NEW_PACKET_LIST */
{"/Copy/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
{"/Copy/Bytes (Offset Hex Text)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_ALLINFO, NULL, NULL,},
{"/Copy/Bytes (Offset Hex)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_HEXCOLUMNS, NULL, NULL,},
@@ -1594,8 +1603,10 @@ set_menu_sensitivity(GtkItemFactory *ifactory, const gchar *path, gint val)
}
gtk_widget_set_sensitive(menu_item, val);
} else{
+#ifndef NEW_PACKET_LIST
/* be sure this menu item *is* existing */
g_assert_not_reached();
+#endif
}
}
@@ -2254,6 +2265,7 @@ menu_recent_read_finished(void) {
}
+#ifndef NEW_PACKET_LIST
gint
popup_menu_handler(GtkWidget *widget, GdkEvent *event, gpointer data)
{
@@ -2332,6 +2344,7 @@ popup_menu_handler(GtkWidget *widget, GdkEvent *event, gpointer data)
}
return FALSE;
}
+#endif /* NEW_PACKET_LIST */
/* Enable or disable menu items based on whether you have a capture file
you've finished reading and, if you have one, whether it's been saved
diff --git a/gtk/new_packet_list.c b/gtk/new_packet_list.c
new file mode 100644
index 0000000000..a89bc149ee
--- /dev/null
+++ b/gtk/new_packet_list.c
@@ -0,0 +1,231 @@
+/* new_packet_list.c
+ * Routines to implement a new GTK2 packet list using our custom model
+ * Copyright 2008-2009, Stephen Fisher <stephentfisher@yahoo.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#ifdef NEW_PACKET_LIST
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_STRING_H
+#include "string.h"
+#endif
+
+#include <gtk/gtk.h>
+#include <glib.h>
+
+#include "gui_utils.h"
+#include "packet_list_store.h"
+#include "epan/column_info.h"
+#include "epan/emem.h"
+#include "globals.h"
+#include "gtk/gtkglobals.h"
+#include "gtk/font_utils.h"
+#include "epan/column.h"
+#include "gtk/recent.h"
+#include "gtk/keys.h"
+#include "gtk/menus.h"
+
+static PacketList *packetlist;
+
+static GtkWidget *create_view_and_model(void);
+static guint row_from_iter(GtkTreeIter *iter);
+static void new_packet_list_select_cb(GtkTreeView *tree_view, gpointer data _U_);
+
+GtkWidget *
+new_packet_list_create(void)
+{
+ GtkWidget *view, *scrollwin;
+
+ scrollwin = scrolled_window_new(NULL, NULL);
+
+ view = create_view_and_model();
+
+ gtk_container_add(GTK_CONTAINER(scrollwin), view);
+
+ /* XXX - Implement me
+ g_signal_connect(view, "row-activated",
+ G_CALLBACK(popup_menu_handler),
+ g_object_get_data(G_OBJECT(popup_menu_object),
+ PM_PACKET_LIST_KEY));
+ g_signal_connect(view, "button_press_event",
+ G_CALLBACK(new_packet_list_button_pressed_cb), NULL);
+ */
+
+ g_object_set_data(G_OBJECT(popup_menu_object), E_MPACKET_LIST_KEY, view);
+
+ return scrollwin;
+}
+
+guint
+new_packet_list_append(column_info cinfo, frame_data *fdata)
+{
+ gint i;
+ row_data_t *row_data;
+
+ row_data = g_new0(row_data_t, NUM_COL_FMTS+1);
+
+ for(i = 0; i < cfile.cinfo.num_cols; i++) {
+ row_data->col_text[cinfo.col_fmt[i]] =
+ se_strdup(cinfo.col_data[i]);
+ }
+
+ row_data->fdata = fdata;
+
+ packet_list_append_record(packetlist, row_data);
+
+ g_free(row_data);
+
+ return packetlist->num_rows; /* XXX - Check that this is the right # */
+}
+
+static GtkWidget *
+create_view_and_model(void)
+{
+ GtkTreeViewColumn *col;
+ GtkCellRenderer *renderer;
+ PangoLayout *layout;
+ gint i, col_width;
+
+ packetlist = new_packet_list_new();
+
+ packetlist->view = tree_view_new(GTK_TREE_MODEL(packetlist));
+
+ gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(packetlist->view),
+ TRUE);
+
+ g_signal_connect(packetlist->view, "cursor-changed",
+ G_CALLBACK(new_packet_list_select_cb), NULL);
+
+ /* g_object_unref(packetlist); */ /* Destroy automatically with view for now */ /* XXX - Messes up freezing & thawing */
+
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "ypad", 0, "font-desc", user_font_get_regular(),
+ NULL);
+
+ for(i = 0; i < cfile.cinfo.num_cols; i++) {
+ col = gtk_tree_view_column_new();
+ gtk_tree_view_column_pack_start(col, renderer, TRUE);
+ gtk_tree_view_column_add_attribute(col, renderer, "text",
+ cfile.cinfo.col_fmt[i]);
+ gtk_tree_view_column_set_title(col, cfile.cinfo.col_title[i]);
+ gtk_tree_view_column_set_sort_column_id(col, i);
+ gtk_tree_view_column_set_resizable(col, TRUE);
+ gtk_tree_view_column_set_sizing(col,GTK_TREE_VIEW_COLUMN_FIXED);
+
+ col_width = recent_get_column_width(i);
+ if(col_width == -1) {
+ layout = gtk_widget_create_pango_layout(packetlist->view, get_column_width_string(get_column_format(i), i));
+ pango_layout_get_pixel_size(layout, &col_width, NULL);
+ gtk_tree_view_column_set_min_width(col, col_width);
+ g_object_unref(G_OBJECT(layout));
+ }
+
+ gtk_tree_view_append_column(GTK_TREE_VIEW(packetlist->view), col);
+ }
+
+ return packetlist->view;
+}
+
+void
+new_packet_list_freeze(void)
+{
+ /* So we don't lose the model by the time we want to thaw it */
+ g_object_ref(packetlist);
+
+ /* Detach view from model */
+ gtk_tree_view_set_model(GTK_TREE_VIEW(packetlist->view), NULL);
+}
+
+void
+new_packet_list_thaw(void)
+{
+ /* Remove extra reference added by new_packet_list_freeze() */
+ g_object_unref(packetlist);
+
+ /* Re-attach view to the model */
+ gtk_tree_view_set_model(GTK_TREE_VIEW(packetlist->view),
+ GTK_TREE_MODEL(packetlist));
+}
+
+void
+new_packet_list_resize_columns_cb(GtkWidget *widget _U_, gpointer data _U_)
+{
+ g_warning("*** new_packet_list_resize_columns_cb() not yet implemented.");
+}
+
+void
+new_packet_list_next(void)
+{
+ g_warning("*** new_packet_list_next() not yet implemented.");
+}
+
+void
+new_packet_list_prev(void)
+{
+ g_warning("*** new_packet_list_prev() not yet implemented.");
+}
+
+static void
+new_packet_list_select_cb(GtkTreeView *tree_view, gpointer data _U_)
+{
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+ guint row;
+
+ selection = gtk_tree_view_get_selection(tree_view);
+ gtk_tree_selection_get_selected(selection, NULL, &iter);
+
+ /* Remove the hex display tab pages */
+ while(gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr), 0))
+ gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr), 0);
+
+ row = row_from_iter(&iter);
+
+ cf_select_packet(&cfile, row);
+}
+
+frame_data *
+new_packet_list_get_row_data(gint row)
+{
+ PacketListRecord *record;
+
+ record = packetlist->rows[row];
+
+ return record->fdata;
+}
+
+static guint
+row_from_iter(GtkTreeIter *iter)
+{
+ PacketListRecord *record;
+
+ record = iter->user_data;
+
+ return record->pos;
+}
+
+#endif /* NEW_PACKET_LIST */
diff --git a/gtk/new_packet_list.h b/gtk/new_packet_list.h
new file mode 100644
index 0000000000..7f748a9315
--- /dev/null
+++ b/gtk/new_packet_list.h
@@ -0,0 +1,43 @@
+/* new_packet_list.h
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#ifndef __NEW_PACKET_LIST_H__
+#define __NEW_PACKET_LIST_H__
+
+#ifdef NEW_PACKET_LIST
+
+#include <gtk/gtk.h>
+
+GtkWidget *new_packet_list_create(void);
+guint new_packet_list_append(column_info cinfo, gpointer fdata);
+void new_packet_list_freeze(void);
+void new_packet_list_thaw(void);
+void new_packet_list_next(void);
+void new_packet_list_prev(void);
+void new_packet_list_resize_columns_cb(GtkWidget *widget _U_, gpointer data _U_);
+gpointer new_packet_list_get_row_data(gint row);
+
+#endif /* NEW_PACKET_LIST */
+
+#endif /* __NEW_PACKET_LIST_H__ */
diff --git a/gtk/packet_list_store.c b/gtk/packet_list_store.c
new file mode 100644
index 0000000000..0263348d26
--- /dev/null
+++ b/gtk/packet_list_store.c
@@ -0,0 +1,674 @@
+/* packet_list_store.c
+ * Routines to implement a custom GTK+ list model for Wireshark's packet list
+ * Copyright 2008-2009, Stephen Fisher <stephentfisher@yahoo.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+/* This code is based on the GTK+ Tree View tutorial at http://scentric.net */
+
+#ifdef NEW_PACKET_LIST
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <glib.h>
+
+#include "packet_list_store.h"
+#include "globals.h"
+
+static void packet_list_init(PacketList *pkg_tree);
+static void packet_list_class_init(PacketListClass *klass);
+static void packet_list_tree_model_init(GtkTreeModelIface *iface);
+static void packet_list_finalize(GObject *object);
+static GtkTreeModelFlags packet_list_get_flags(GtkTreeModel *tree_model);
+static gint packet_list_get_n_columns(GtkTreeModel *tree_model);
+static GType packet_list_get_column_type(GtkTreeModel *tree_model, gint index);
+static gboolean packet_list_get_iter(GtkTreeModel *tree_model,
+ GtkTreeIter *iter, GtkTreePath *path);
+static GtkTreePath *packet_list_get_path(GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
+static void packet_list_get_value(GtkTreeModel *tree_model, GtkTreeIter *iter,
+ gint column, GValue *value);
+static gboolean packet_list_iter_next(GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
+static gboolean packet_list_iter_children(GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent);
+static gboolean packet_list_iter_has_child(GtkTreeModel *tree_model _U_,
+ GtkTreeIter *iter _U_);
+static gint packet_list_iter_n_children(GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
+static gboolean packet_list_iter_nth_child(GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent,
+ gint n);
+static gboolean packet_list_iter_parent(GtkTreeModel *tree_model _U_,
+ GtkTreeIter *iter _U_,
+ GtkTreeIter *child _U_);
+
+static gboolean packet_list_sortable_get_sort_column_id(GtkTreeSortable
+ *sortable,
+ gint *sort_col_id,
+ GtkSortType *order);
+static void packet_list_sortable_set_sort_column_id(GtkTreeSortable *sortable,
+ gint sort_col_id,
+ GtkSortType order);
+static void packet_list_sortable_set_sort_func(GtkTreeSortable *sortable,
+ gint sort_col_id,
+ GtkTreeIterCompareFunc sort_func,
+ gpointer user_data,
+ GtkDestroyNotify destroy_func);
+static void packet_list_sortable_set_default_sort_func(GtkTreeSortable
+ *sortable,
+ GtkTreeIterCompareFunc
+ sort_func,
+ gpointer user_data,
+ GtkDestroyNotify
+ destroy_func);
+static gboolean packet_list_sortable_has_default_sort_func(GtkTreeSortable
+ *sortable);
+static void packet_list_sortable_init(GtkTreeSortableIface *iface);
+static gint packet_list_compare_records(gint sort_id _U_, PacketListRecord *a,
+ PacketListRecord *b);
+static gint packet_list_qsort_compare_func(PacketListRecord **a,
+ PacketListRecord **b,
+ PacketList *packet_list);
+static void packet_list_resort(PacketList *packet_list);
+
+static GObjectClass *parent_class = NULL;
+
+
+GType
+packet_list_get_type(void)
+{
+ static GType packet_list_type = 0;
+
+ if(packet_list_type == 0) {
+ static const GTypeInfo packet_list_info = {
+ sizeof(PacketListClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) packet_list_class_init,
+ NULL, /* class finalize */
+ NULL, /* class_data */
+ sizeof(PacketList),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) packet_list_init,
+ NULL /* value_table */
+ };
+
+ static const GInterfaceInfo tree_model_info = {
+ (GInterfaceInitFunc) packet_list_tree_model_init,
+ NULL,
+ NULL
+ };
+
+ static const GInterfaceInfo tree_sortable_info = {
+ (GInterfaceInitFunc) packet_list_sortable_init,
+ NULL,
+ NULL
+ };
+
+ /* Register the new derived type with the GObject type system */
+ packet_list_type = g_type_register_static(G_TYPE_OBJECT,
+ "PacketList",
+ &packet_list_info,
+ (GTypeFlags)0);
+
+ g_type_add_interface_static(packet_list_type,
+ GTK_TYPE_TREE_MODEL,
+ &tree_model_info);
+
+
+ /* Register our GtkTreeModel interface with the type system */
+ g_type_add_interface_static(packet_list_type,
+ GTK_TYPE_TREE_SORTABLE,
+ &tree_sortable_info);
+ }
+
+ return packet_list_type;
+}
+
+static void
+packet_list_sortable_init(GtkTreeSortableIface *iface)
+{
+ iface->get_sort_column_id = packet_list_sortable_get_sort_column_id;
+ iface->set_sort_column_id = packet_list_sortable_set_sort_column_id;
+ /* The following three functions are not implemented */
+ iface->set_sort_func = packet_list_sortable_set_sort_func;
+ iface->set_default_sort_func =
+ packet_list_sortable_set_default_sort_func;
+ iface->has_default_sort_func =
+ packet_list_sortable_has_default_sort_func;
+}
+
+static void
+packet_list_class_init(PacketListClass *klass)
+{
+ GObjectClass *object_class;
+
+ parent_class = (GObjectClass*) g_type_class_peek_parent(klass);
+ object_class = (GObjectClass*) klass;
+
+ object_class->finalize = packet_list_finalize;
+}
+
+static void
+packet_list_tree_model_init(GtkTreeModelIface *iface)
+{
+ iface->get_flags = packet_list_get_flags;
+ iface->get_n_columns = packet_list_get_n_columns;
+ iface->get_column_type = packet_list_get_column_type;
+ iface->get_iter = packet_list_get_iter;
+ iface->get_path = packet_list_get_path;
+ iface->get_value = packet_list_get_value;
+ iface->iter_next = packet_list_iter_next;
+ iface->iter_children = packet_list_iter_children;
+ iface->iter_has_child = packet_list_iter_has_child;
+ iface->iter_n_children = packet_list_iter_n_children;
+ iface->iter_nth_child = packet_list_iter_nth_child;
+ iface->iter_parent = packet_list_iter_parent;
+}
+
+/* This is called every time a new packet list object instance is created in
+ * packet_list_new. Initialize the list structure's fields here. */
+static void
+packet_list_init(PacketList *packet_list)
+{
+ guint i;
+
+ for(i = 0; i <= NUM_COL_FMTS; i++) { /* XXX - Temporary? */
+ packet_list->column_types[i] = G_TYPE_STRING;
+ }
+
+
+ packet_list->n_columns = NUM_COL_FMTS;
+ packet_list->num_rows = 0;
+ packet_list->rows = NULL;
+
+ packet_list->sort_id = 0; /* defaults to first column for now */
+ packet_list->sort_order = GTK_SORT_ASCENDING;
+
+ packet_list->stamp = g_random_int(); /* To check whether an iter belongs
+ * to our model. */
+}
+
+/* This function is called just before a packet list is destroyed. Free
+ * dynamically allocated memory here. */
+static void
+packet_list_finalize(GObject *object)
+{
+ /* PacketList *packet_list = PACKET_LIST(object); */
+
+ /* XXX - Free all records and free all memory used by the list */
+
+ /* must chain up - finalize parent */
+ (* parent_class->finalize) (object);
+}
+
+static GtkTreeModelFlags
+packet_list_get_flags(GtkTreeModel *tree_model)
+{
+ g_return_val_if_fail(PACKETLIST_IS_LIST(tree_model),
+ (GtkTreeModelFlags)0);
+
+ return (GTK_TREE_MODEL_LIST_ONLY | GTK_TREE_MODEL_ITERS_PERSIST);
+}
+
+static gint
+packet_list_get_n_columns(GtkTreeModel *tree_model)
+{
+ g_return_val_if_fail(PACKETLIST_IS_LIST(tree_model), 0);
+
+ return PACKET_LIST(tree_model)->n_columns;
+}
+
+static GType
+packet_list_get_column_type(GtkTreeModel *tree_model, gint index)
+{
+ g_return_val_if_fail(PACKETLIST_IS_LIST(tree_model), G_TYPE_INVALID);
+ g_return_val_if_fail(index < PACKET_LIST(tree_model)->n_columns &&
+ index >= 0, G_TYPE_INVALID);
+
+ return PACKET_LIST(tree_model)->column_types[index];
+}
+
+static gboolean
+packet_list_get_iter(GtkTreeModel *tree_model, GtkTreeIter *iter,
+ GtkTreePath *path)
+{
+ PacketList *packet_list;
+ PacketListRecord *record;
+ gint *indices, depth;
+ guint n;
+
+ g_assert(PACKETLIST_IS_LIST(tree_model));
+ g_assert(path != NULL);
+
+ packet_list = PACKET_LIST(tree_model);
+
+ indices = gtk_tree_path_get_indices(path);
+ depth = gtk_tree_path_get_depth(path);
+
+ /* we do not allow children since it's just a list */
+ g_assert(depth == 1);
+
+ n = indices[0]; /* the n-th top level row */
+
+ if(n >= packet_list->num_rows)
+ return FALSE;
+
+ record = packet_list->rows[n];
+
+ g_assert(record != NULL);
+ g_assert(record->pos == n);
+
+ /* We simply store a pointer to our custom record in the iter */
+ iter->stamp = packet_list->stamp;
+ iter->user_data = record;
+ iter->user_data2 = NULL;
+ iter->user_data3 = NULL;
+
+ return TRUE;
+}
+
+static GtkTreePath *
+packet_list_get_path(GtkTreeModel *tree_model, GtkTreeIter *iter)
+{
+ GtkTreePath *path;
+ PacketListRecord *record;
+ PacketList *packet_list;
+
+ g_return_val_if_fail(PACKETLIST_IS_LIST(tree_model), NULL);
+ g_return_val_if_fail(iter != NULL, NULL);
+ g_return_val_if_fail(iter->user_data != NULL, NULL);
+
+ packet_list = PACKET_LIST(tree_model);
+
+ record = (PacketListRecord*) iter->user_data;
+
+ path = gtk_tree_path_new();
+ gtk_tree_path_append_index(path, record->pos);
+
+ return path;
+}
+
+static void
+packet_list_get_value(GtkTreeModel *tree_model, GtkTreeIter *iter, gint column,
+ GValue *value)
+{
+ PacketListRecord *record;
+ PacketList *packet_list;
+
+ g_return_if_fail(PACKETLIST_IS_LIST(tree_model));
+ g_return_if_fail(iter != NULL);
+ g_return_if_fail(column < PACKET_LIST(tree_model)->n_columns);
+
+ g_value_init(value, PACKET_LIST(tree_model)->column_types[column]);
+
+ packet_list = PACKET_LIST(tree_model);
+
+ record = (PacketListRecord*) iter->user_data;
+
+ if(record->pos >= packet_list->num_rows)
+ g_return_if_reached();
+
+ g_value_set_string(value, record->col_text[column]);
+}
+
+/* Takes an iter structure and sets it to point to the next row. */
+static gboolean
+packet_list_iter_next(GtkTreeModel *tree_model, GtkTreeIter *iter)
+{
+ PacketListRecord *record, *nextrecord;
+ PacketList *packet_list;
+
+ g_return_val_if_fail(PACKETLIST_IS_LIST(tree_model), FALSE);
+
+ if(iter == NULL || iter->user_data == NULL)
+ return FALSE;
+
+ packet_list = PACKET_LIST(tree_model);
+
+ record = (PacketListRecord*) iter->user_data;
+
+ /* Is this the last record in the list? */
+ if((record->pos + 1) >= packet_list->num_rows)
+ return FALSE;
+
+ nextrecord = packet_list->rows[(record->pos + 1)];
+
+ g_assert(nextrecord != NULL);
+ g_assert(nextrecord->pos == (record->pos + 1));
+
+ iter->stamp = packet_list->stamp;
+ iter->user_data = nextrecord;
+
+ return TRUE;
+}
+
+static gboolean
+packet_list_iter_children(GtkTreeModel *tree_model, GtkTreeIter *iter,
+ GtkTreeIter *parent)
+{
+ PacketList *packet_list;
+
+ g_return_val_if_fail(parent == NULL || parent->user_data != NULL,
+ FALSE);
+
+ /* This is a list, nodes have no children. */
+ if(parent)
+ return FALSE;
+
+ /* parent == NULL is a special case; we need to return the first top-
+ * level row */
+
+ g_return_val_if_fail(PACKETLIST_IS_LIST(tree_model), FALSE);
+
+ packet_list = PACKET_LIST(tree_model);
+
+ /* No rows => no first row */
+ if(packet_list->num_rows == 0)
+ return FALSE;
+
+ /* Set iter to first item in list */
+ iter->stamp = packet_list->stamp;
+ iter->user_data = packet_list->rows[0];
+
+ return TRUE;
+}
+
+static gboolean
+packet_list_iter_has_child(GtkTreeModel *tree_model _U_, GtkTreeIter *iter _U_)
+{
+ return FALSE; /* Lists have no children */
+}
+
+static gint
+packet_list_iter_n_children(GtkTreeModel *tree_model, GtkTreeIter *iter)
+{
+ PacketList *packet_list;
+
+ g_return_val_if_fail(PACKETLIST_IS_LIST(tree_model), -1);
+ g_return_val_if_fail(iter == NULL || iter->user_data != NULL, FALSE);
+
+ packet_list = PACKET_LIST(tree_model);
+
+ /* special case: if iter == NULL, return number of top-level rows */
+ if(!iter)
+ return packet_list->num_rows;
+
+ return 0; /* Lists have zero children */
+}
+
+static gboolean
+packet_list_iter_nth_child(GtkTreeModel *tree_model, GtkTreeIter *iter,
+ GtkTreeIter *parent, gint n)
+{
+ PacketListRecord *record;
+ PacketList *packet_list;
+
+ g_return_val_if_fail(PACKETLIST_IS_LIST(tree_model), FALSE);
+
+ packet_list = PACKET_LIST(tree_model);
+
+ /* A list only has top-level rows */
+ if(parent)
+ return FALSE;
+
+ /* Special case: if parent == NULL, set iter to n-th
+ * top-level row. */
+ if((guint)n >= packet_list->num_rows)
+ return FALSE;
+
+ record = packet_list->rows[n];
+
+ g_assert(record != NULL);
+ g_assert(record->pos == (guint)n);
+
+ iter->stamp = packet_list->stamp;
+ iter->user_data = record;
+
+ return TRUE;
+}
+
+static gboolean
+packet_list_iter_parent(GtkTreeModel *tree_model _U_, GtkTreeIter *iter _U_,
+ GtkTreeIter *child _U_)
+{
+ return FALSE; /* No parents since no children in a list */
+}
+
+PacketList *
+new_packet_list_new(void)
+{
+ PacketList *newpacketlist;
+
+ newpacketlist = (PacketList*) g_object_new(PACKETLIST_TYPE_LIST, NULL);
+
+ g_assert(newpacketlist != NULL);
+
+ return newpacketlist;
+}
+
+void
+packet_list_append_record(PacketList *packet_list, row_data_t *row_data)
+{
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ PacketListRecord *newrecord;
+ guint pos;
+ gint i;
+
+ g_return_if_fail(PACKETLIST_IS_LIST(packet_list));
+
+ pos = packet_list->num_rows;
+
+ packet_list->num_rows++;
+
+ packet_list->rows = g_renew(PacketListRecord*, packet_list->rows,
+ packet_list->num_rows);
+
+ newrecord = se_alloc0(sizeof(PacketListRecord));
+
+ for(i = 0; i < NUM_COL_FMTS; i++)
+ newrecord->col_text[i] = row_data->col_text[i];
+
+ newrecord->fdata = row_data->fdata;
+
+ packet_list->rows[pos] = newrecord;
+ newrecord->pos = pos;
+
+ /* Inform the tree view and other interested objects (such as tree row
+ * references) that we have inserted a new row and where it was
+ * inserted. */
+ path = gtk_tree_path_new();
+ gtk_tree_path_append_index(path, newrecord->pos);
+
+ packet_list_get_iter(GTK_TREE_MODEL(packet_list), &iter, path);
+
+ gtk_tree_model_row_inserted(GTK_TREE_MODEL(packet_list), path, &iter);
+
+ gtk_tree_path_free(path);
+
+ packet_list_resort(packet_list);
+}
+
+static gboolean
+packet_list_sortable_get_sort_column_id(GtkTreeSortable *sortable,
+ gint *sort_col_id,
+ GtkSortType *order)
+{
+ PacketList *packet_list;
+
+ g_return_val_if_fail(sortable != NULL, FALSE);
+ g_return_val_if_fail(PACKETLIST_IS_LIST(sortable), FALSE);
+
+ packet_list = PACKET_LIST(sortable);
+
+ if(sort_col_id)
+ *sort_col_id = packet_list->sort_id;
+
+ if(order)
+ *order = packet_list->sort_order;
+
+ return TRUE;
+}
+
+static void
+packet_list_sortable_set_sort_column_id(GtkTreeSortable *sortable,
+ gint sort_col_id,
+ GtkSortType order)
+{
+ PacketList *packet_list;
+
+ g_return_if_fail(sortable != NULL);
+ g_return_if_fail(PACKETLIST_IS_LIST(sortable));
+
+ packet_list = PACKET_LIST(sortable);
+
+ if(packet_list->sort_id == sort_col_id &&
+ packet_list->sort_order == order)
+ return;
+
+ packet_list->sort_id = sort_col_id;
+ packet_list->sort_order = order;
+
+ packet_list_resort(packet_list);
+
+ /* emit "sort-column-changed" signal to tell any tree views
+ * that the sort column has changed (so the little arrow
+ * in the column header of the sort column is drawn
+ * in the right column) */
+
+ gtk_tree_sortable_sort_column_changed(sortable);
+}
+
+static void
+packet_list_sortable_set_sort_func(GtkTreeSortable *sortable _U_,
+ gint sort_col_id _U_,
+ GtkTreeIterCompareFunc sort_func _U_,
+ gpointer user_data _U_,
+ GtkDestroyNotify destroy_func _U_)
+{
+ g_warning("%s is not supported by the PacketList model.\n",
+ __FUNCTION__);
+}
+
+static void
+packet_list_sortable_set_default_sort_func(GtkTreeSortable *sortable _U_,
+ GtkTreeIterCompareFunc sort_func _U_,
+ gpointer user_data _U_,
+ GtkDestroyNotify destroy_func _U_)
+{
+ g_warning("%s is not supported by the PacketList model.\n",
+ __FUNCTION__);
+}
+
+static gboolean
+packet_list_sortable_has_default_sort_func(GtkTreeSortable *sortable _U_)
+{
+ return FALSE; /* Since packet_list_sortable_set_sort_func and
+ set_default_sort_func are not implemented. */
+}
+
+static gint
+packet_list_compare_records(gint sort_id, PacketListRecord *a,
+ PacketListRecord *b)
+{
+ /* The following is necessary because sort_id is a column number as
+ * seen by the user, whereas the col_text array from a and b is a
+ * column format number. This matches them to each other to get
+ * the right column text. */
+ gchar *a_col_text = a->col_text[cfile.cinfo.col_fmt[sort_id]];
+ gchar *b_col_text = b->col_text[cfile.cinfo.col_fmt[sort_id]];
+
+ if((a_col_text) && (b_col_text))
+ return strcmp(a_col_text, b_col_text);
+
+ if(a_col_text == b_col_text)
+ return 0; /* both are NULL */
+ else
+ return (a_col_text == NULL) ? -1 : 1;
+
+ g_return_val_if_reached(0);
+}
+
+static gint
+packet_list_qsort_compare_func(PacketListRecord **a, PacketListRecord **b,
+ PacketList *packet_list)
+{
+ gint ret;
+
+ g_assert((a) && (b) && (packet_list));
+
+ ret = packet_list_compare_records(packet_list->sort_id, *a, *b);
+
+ /* Swap -1 and 1 if sort order is reverse */
+ if(ret != 0 && packet_list->sort_order == GTK_SORT_DESCENDING)
+ ret = (ret < 0) ? 1 : -1;
+
+ return ret;
+}
+
+static void
+packet_list_resort(PacketList *packet_list)
+{
+ GtkTreePath *path;
+ gint *neworder;
+ guint i;
+
+ g_return_if_fail(packet_list != NULL);
+ g_return_if_fail(PACKETLIST_IS_LIST(packet_list));
+
+ if(packet_list->num_rows == 0)
+ return;
+
+ /* resort */
+ g_qsort_with_data(packet_list->rows, packet_list->num_rows,
+ sizeof(PacketListRecord*),
+ (GCompareDataFunc) packet_list_qsort_compare_func,
+ packet_list);
+
+ /* let other objects know about the new order */
+ neworder = g_new0(gint, packet_list->num_rows);
+
+ for(i = 0; i < packet_list->num_rows; ++i) {
+ neworder[i] = (packet_list->rows[i])->pos;
+ (packet_list->rows[i])->pos = i;
+ }
+
+ path = gtk_tree_path_new();
+
+ gtk_tree_model_rows_reordered(GTK_TREE_MODEL(packet_list), path, NULL,
+ neworder);
+
+ gtk_tree_path_free(path);
+ g_free(neworder);
+}
+
+#endif /* NEW_PACKET_LIST */
diff --git a/gtk/packet_list_store.h b/gtk/packet_list_store.h
new file mode 100644
index 0000000000..9fa7429e14
--- /dev/null
+++ b/gtk/packet_list_store.h
@@ -0,0 +1,94 @@
+/* packet_list_store.h
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#ifndef __NEW_PACKET_LIST_H__
+#define __NEW_PACKET_LIST_H__
+
+#ifdef NEW_PACKET_LIST
+
+#include "epan/column_info.h"
+#include "epan/frame_data.h"
+
+#define PACKETLIST_TYPE_LIST (packet_list_get_type())
+#define PACKET_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PACKETLIST_TYPE_LIST, PacketList))
+#define PACKETLIST_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CART((klass), PACKETLIST_TYPE_LIST))
+#define PACKETLIST_IS_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PACKETLIST_TYPE_LIST))
+#define PACKETLIST_IS_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE(klass), PACKETLIST_TYPE_LIST)
+#define PACKETLIST_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PACKETLIST_TYPE_LIST, PacketListClass))
+
+typedef struct {
+ gchar *col_text[NUM_COL_FMTS], *col_filter[NUM_COL_FMTS];
+ frame_data *fdata;
+} row_data_t;
+
+typedef struct _PacketListRecord PacketListRecord;
+typedef struct _PacketList PacketList;
+typedef struct _PacketListClass PacketListClass;
+
+/* PacketListRecord: represents a row */
+struct _PacketListRecord
+
+{
+ frame_data *fdata;
+ gchar *col_text[NUM_COL_FMTS];
+
+ /* admin stuff used by the custom list model */
+ guint pos; /* position within the array */
+};
+
+/* PacketListRecord: Everything for our model implementation. */
+struct _PacketList
+{
+ GObject parent; /* MUST be first */
+
+ guint num_rows;
+ PacketListRecord **rows; /* Dynamically allocated array of pointers to
+ * the PacketListRecord structure for each
+ * row. */
+
+ gint n_columns;
+ GType column_types[NUM_COL_FMTS];
+ GtkWidget *view; /* XXX - Does this really belong here?? */
+
+ gint sort_id;
+ GtkSortType sort_order;
+
+ gint stamp; /* Random integer to check whether an iter belongs to our
+ * model. */
+};
+
+
+/* PacketListClass: more boilerplate GObject stuff */
+struct _PacketListClass
+{
+ GObjectClass parent_class;
+};
+
+GType packet_list_list_get_type(void);
+PacketList *new_packet_list_new(void);
+void packet_list_append_record(PacketList *packet_list, row_data_t *row_data);
+
+#endif /* NEW_PACKET_LIST */
+
+#endif /* __NEW_PACKET_LIST_H__ */
diff --git a/gtk/prefs_column.c b/gtk/prefs_column.c
index 86f38e8114..4527008f31 100644
--- a/gtk/prefs_column.c
+++ b/gtk/prefs_column.c
@@ -602,7 +602,9 @@ column_prefs_apply(GtkWidget *w _U_)
{
/* Redraw the packet list if the columns were changed */
if(cfile.cinfo.columns_changed) {
+#ifndef NEW_PACKET_LIST
packet_list_recreate();
+#endif
cfile.cinfo.columns_changed = FALSE; /* Reset value */
}
}
diff --git a/gtk/prefs_gui.c b/gtk/prefs_gui.c
index f90a8739bd..3de2fdd904 100644
--- a/gtk/prefs_gui.c
+++ b/gtk/prefs_gui.c
@@ -502,7 +502,9 @@ gui_prefs_apply(GtkWidget *w _U_ , gboolean redissect)
toolbar_redraw_all();
set_scrollbar_placement_all();
+#ifndef NEW_PACKET_LIST
packet_list_set_sel_browse(prefs.gui_plist_sel_browse, FALSE);
+#endif
set_ptree_sel_browse_all(prefs.gui_ptree_sel_browse);
set_tree_styles_all();
main_widgets_rearrange();
diff --git a/gtk/prefs_stream.c b/gtk/prefs_stream.c
index 5368ea4434..8f8a56a042 100644
--- a/gtk/prefs_stream.c
+++ b/gtk/prefs_stream.c
@@ -203,7 +203,9 @@ stream_prefs_apply(GtkWidget *w _U_)
{
follow_tcp_redraw_all();
+#ifndef NEW_PACKET_LIST
packet_list_update_marked_frames();
+#endif
}
void
diff --git a/gtk/recent.c b/gtk/recent.c
index 1ac34d5fbe..47af8b8628 100644
--- a/gtk/recent.c
+++ b/gtk/recent.c
@@ -373,7 +373,9 @@ write_profile_recent(void)
fprintf(rf, "\n# Packet list column pixel widths.\n");
fprintf(rf, "# Each pair of strings consists of a column format and its pixel width.\n");
+#ifndef NEW_PACKET_LIST
packet_list_recent_write_all(rf);
+#endif
if (get_last_open_dir() != NULL) {
fprintf(rf, "\n# Last directory navigated to in File Open dialog.\n");
@@ -515,10 +517,12 @@ read_set_recent_pair_static(gchar *key, gchar *value, void *private_data _U_)
{
long num;
char *p;
+#ifndef NEW_PACKET_LIST
GList *col_l, *col_l_elt;
col_width_data *cfmt;
const gchar *cust_format = col_format_to_string(COL_CUSTOM);
int cust_format_len = (int) strlen(cust_format);
+#endif
if (strcmp(key, RECENT_KEY_MAIN_TOOLBAR_SHOW) == 0) {
if (g_ascii_strcasecmp(value, "true") == 0) {
@@ -618,7 +622,9 @@ read_set_recent_pair_static(gchar *key, gchar *value, void *private_data _U_)
return PREFS_SET_SYNTAX_ERR; /* number must be positive */
recent.gui_geometry_main_lower_pane = num;
recent.has_gui_geometry_main_lower_pane = TRUE;
- } else if (strcmp(key, RECENT_KEY_COL_WIDTH) == 0) {
+ }
+#ifndef NEW_PACKET_LIST
+ else if (strcmp(key, RECENT_KEY_COL_WIDTH) == 0) {
col_l = prefs_get_string_list(value);
if (col_l == NULL)
return PREFS_SET_SYNTAX_ERR;
@@ -679,6 +685,7 @@ read_set_recent_pair_static(gchar *key, gchar *value, void *private_data _U_)
}
prefs_clear_string_list(col_l);
}
+#endif /* NEW_PACKET_LIST */
return PREFS_SET_OK;
}
diff --git a/ui_util.h b/ui_util.h
index ac85a65d1b..5509dd3110 100644
--- a/ui_util.h
+++ b/ui_util.h
@@ -54,6 +54,8 @@ extern void pipe_input_set_handler(gint source, gpointer user_data, int *child_p
/* packet_list.c */
+#ifndef NEW_PACKET_LIST
+
/* packet list related functions */
void packet_list_clear(void);
void packet_list_freeze(void);
@@ -71,6 +73,7 @@ gint packet_list_get_sort_column(void);
void packet_list_set_sort_column(void);
gboolean packet_list_check_end(void);
+#endif /* NEW_PACKET_LIST */
#ifdef __cplusplus
}