summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland Knall <roland.knall@br-automation.com>2017-01-24 17:34:07 +0100
committerRoland Knall <rknall@gmail.com>2017-02-24 08:12:46 +0000
commit321386e9f49d88b64f48868c6e4079b2073547a1 (patch)
treed30943f392b322b6dd7e1245f7efc3915051ab55
parentbd9afdddfe45b4c9c6e966df7264d12cdfd85f42 (diff)
downloadwireshark-321386e9f49d88b64f48868c6e4079b2073547a1.tar.gz
PluginIF: AdditionalToolbar
Creates an interface for plugins and other parts of the code, to add a new toolbar to the system and have various widget types interact with this toolbar. All toolbars added via this interface, will be added to an additional submenu called "Additional Toolbars" within Wireshark. Also a demo plugin is being provided, demonstrating various features of the toolbar, including updating the gui elements. It also demonstrates how to update toolbar items. Change-Id: I8d0351224b3d7f4b90220d58970b51695551d7e3 Reviewed-on: https://code.wireshark.org/review/19803 Petri-Dish: Roland Knall <rknall@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Stig Bjørlykke <stig@bjorlykke.org> Reviewed-by: Roland Knall <rknall@gmail.com>
-rw-r--r--CMakeLists.txt9
-rw-r--r--CMakeOptions.txt1
-rw-r--r--epan/plugin_if.c337
-rw-r--r--epan/plugin_if.h178
-rw-r--r--plugins/pluginifdemo/AUTHORS2
-rw-r--r--plugins/pluginifdemo/CMakeLists.txt87
-rw-r--r--plugins/pluginifdemo/COPYING340
-rw-r--r--plugins/pluginifdemo/Makefile.am66
-rw-r--r--plugins/pluginifdemo/NEWS1
-rw-r--r--plugins/pluginifdemo/README2
-rw-r--r--plugins/pluginifdemo/moduleinfo.h39
-rw-r--r--plugins/pluginifdemo/plugin.rc.in34
-rw-r--r--plugins/pluginifdemo/pluginifdemo.c157
-rw-r--r--plugins/pluginifdemo/pluginifdemo.h23
-rw-r--r--plugins/pluginifdemo/ui/pluginifdemo_about.cpp61
-rw-r--r--plugins/pluginifdemo/ui/pluginifdemo_about.h65
-rw-r--r--plugins/pluginifdemo/ui/pluginifdemo_about.ui156
-rw-r--r--plugins/pluginifdemo/ui/pluginifdemo_main.cpp320
-rw-r--r--plugins/pluginifdemo/ui/pluginifdemo_main.h133
-rw-r--r--plugins/pluginifdemo/ui/pluginifdemo_main.ui315
-rw-r--r--plugins/pluginifdemo/ui/uiclasshandler.cpp128
-rw-r--r--plugins/pluginifdemo/ui/uihandler.cpp81
-rw-r--r--plugins/pluginifdemo/ui/uihandler.h101
-rw-r--r--ui/qt/CMakeLists.txt4
-rw-r--r--ui/qt/Makefile.am4
-rw-r--r--ui/qt/additional_toolbar.cpp537
-rw-r--r--ui/qt/additional_toolbar.h101
-rw-r--r--ui/qt/apply_line_edit.cpp181
-rw-r--r--ui/qt/apply_line_edit.h82
-rw-r--r--ui/qt/main_window.cpp133
-rw-r--r--ui/qt/main_window.h5
-rw-r--r--ui/qt/main_window.ui6
-rw-r--r--ui/qt/main_window_slots.cpp70
-rw-r--r--ui/recent.c14
-rw-r--r--ui/recent.h1
35 files changed, 3743 insertions, 31 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 75d001162d..92b2df5e31 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1240,6 +1240,15 @@ if(ENABLE_PLUGINS)
plugins/wimaxmacphy
${CUSTOM_PLUGIN_SRC_DIR}
)
+
+ # Build demo plugin, only if asked explicitly
+ if(ENABLE_PLUGIN_IFDEMO)
+ set(PLUGIN_SRC_DIRS
+ ${PLUGIN_SRC_DIRS}
+ plugins/pluginifdemo
+ )
+ endif()
+
# It seems this stuff doesn't build with autofoo either...
# if(YAPP_FOUND)
# set(PLUGIN_SRC_DIRS
diff --git a/CMakeOptions.txt b/CMakeOptions.txt
index 9e507b3150..0a9ff5909c 100644
--- a/CMakeOptions.txt
+++ b/CMakeOptions.txt
@@ -55,6 +55,7 @@ endif()
option(ENABLE_STATIC "Build a static version of Wireshark (not yet working)" OFF)
option(ENABLE_ECHLD "Enable echld support" OFF)
option(ENABLE_PLUGINS "Build with plugins" ON)
+option(ENABLE_PLUGIN_IFDEMO "Build with plugin interface demo" OFF)
option(ENABLE_EXTCAP "Build with extcap hooks" ON)
option(ENABLE_HTML_GUIDES "Build HTML User & Developer Guides" OFF)
option(ENABLE_PDF_GUIDES "Build PDF User & Developer Guides" OFF)
diff --git a/epan/plugin_if.c b/epan/plugin_if.c
index eb0ad03f5f..1a7b307667 100644
--- a/epan/plugin_if.c
+++ b/epan/plugin_if.c
@@ -38,6 +38,35 @@
static GList * menubar_entries = NULL;
static GList * menubar_menunames = NULL;
+static GHashTable * plugin_if_callback_functions;
+
+static void
+plugin_if_init_hashtable(void)
+{
+ if ( plugin_if_callback_functions == 0 )
+ plugin_if_callback_functions = g_hash_table_new(g_int_hash, g_int_equal);
+}
+
+static void plugin_if_call_gui_cb(plugin_if_callback_t actionType, GHashTable * dataSet)
+{
+ plugin_if_gui_cb action;
+ gint * key = 0;
+
+ key = (gint *)g_malloc0(sizeof(gint));
+ *key = (gint) actionType;
+
+ plugin_if_init_hashtable();
+
+ if ( g_hash_table_size(plugin_if_callback_functions) != 0 )
+ {
+ if ( g_hash_table_lookup_extended(plugin_if_callback_functions, key, NULL, (gpointer*)&action) )
+ {
+ if ( action != NULL )
+ action(dataSet);
+ }
+ }
+}
+
extern GList * ext_menubar_get_entries(void)
{
@@ -175,42 +204,308 @@ extern void ext_menubar_add_separator(ext_menu_t *parent)
ext_menubar_add_generic_entry ( EXT_MENUBAR_SEPARATOR, parent, g_strdup("-"), NULL, NULL, NULL );
}
-/* Implementation of GUI callback methods follows.
- * This is a necessity, as using modern UI systems, gui interfaces often operate
- * in different threads then the calling application. Even more so, if the calling
- * application is implemented using a separate plugin. Therefore the external menubars
- * cannot call gui functionality directly, the gui has to perform the function within
- * it' own scope. */
+/* Implementation of external toolbar handlers */
-static GHashTable * plugin_if_callback_functions;
+static GList * toolbar_entries = NULL;
-static void
-plugin_if_init_hashtable(void)
+extern GList * ext_toolbar_get_entries(void)
{
- if ( plugin_if_callback_functions == 0 )
- plugin_if_callback_functions = g_hash_table_new(g_int_hash, g_int_equal);
+ return toolbar_entries;
}
-static void plugin_if_call_gui_cb(plugin_if_callback_t actionType, GHashTable * dataSet)
+ext_toolbar_t * ext_toolbar_register_toolbar(const gchar * toolbarlabel)
{
- plugin_if_gui_cb action;
- gint * key = 0;
+ ext_toolbar_t * entry = NULL;
- key = (gint *)g_malloc0(sizeof(gint));
- *key = (gint) actionType;
+ /* A name for the entry must be provided */
+ g_assert(toolbarlabel != NULL && strlen ( toolbarlabel ) > 0 );
- plugin_if_init_hashtable();
+ entry = g_new0(ext_toolbar_t, 1);
+ entry->type = EXT_TOOLBAR_BAR;
- if ( g_hash_table_size(plugin_if_callback_functions) != 0 )
+ /* Create a name for this toolbar */
+ entry->name = g_strdup(toolbarlabel);
+ entry->tooltip = g_strdup(toolbarlabel);
+
+ entry->submenu_cnt = 0;
+ entry->item_cnt = 0;
+
+ toolbar_entries = g_list_append(toolbar_entries, entry);
+
+ return entry;
+}
+
+static gint
+ext_toolbar_compare(gconstpointer a, gconstpointer b)
+{
+ if ( !a || !b )
+ return -1;
+
+ ext_toolbar_t * ta = (ext_toolbar_t *)a;
+ ext_toolbar_t * tb = (ext_toolbar_t *)b;
+
+ return strcmp(ta->name, tb->name);
+}
+
+void ext_toolbar_unregister_toolbar_by_name(const gchar * toolbar_name)
+{
+ GList * walker = 0;
+
+ if ( ! toolbar_name )
+ return;
+
+ walker = toolbar_entries;
+ while ( walker && walker->data )
{
- if ( g_hash_table_lookup_extended(plugin_if_callback_functions, key, NULL, (gpointer*)&action) )
+ ext_toolbar_t * entry = (ext_toolbar_t *)walker->data;
+ if ( g_strcmp0(entry->name, toolbar_name) == 0)
{
- if ( action != NULL )
- action(dataSet);
+ ext_toolbar_unregister_toolbar(entry);
+ break;
}
+
+ walker = g_list_next(walker);
+ }
+}
+
+void ext_toolbar_unregister_toolbar(ext_toolbar_t * toolbar)
+{
+ if ( ! toolbar )
+ return;
+
+ GList * entry = g_list_find_custom(toolbar_entries, toolbar, (GCompareFunc) ext_toolbar_compare);
+ if ( entry && entry->data )
+ {
+ ext_toolbar_t * et = (ext_toolbar_t *)entry->data;
+ toolbar_entries = g_list_remove(toolbar_entries, et);
+
+ if ( ! g_list_find_custom(toolbar_entries, toolbar, (GCompareFunc) ext_toolbar_compare) )
+ {
+ GHashTable * dataSet = g_hash_table_new(g_str_hash, g_str_equal);
+ g_hash_table_insert( dataSet, g_strdup("toolbar_name"), g_strdup(et->name) );
+ plugin_if_call_gui_cb(PLUGIN_IF_REMOVE_TOOLBAR, dataSet);
+
+ g_free(et->name);
+ g_free(et->tooltip);
+ g_free(et->defvalue);
+ g_free(et->regex);
+
+ g_free(et);
+ }
+ }
+}
+
+static gint
+ext_toolbar_insert_sort(gconstpointer a, gconstpointer b)
+{
+ ext_toolbar_t * ca = (ext_toolbar_t *)a;
+ ext_toolbar_t * cb = (ext_toolbar_t *)b;
+
+ if ( ca == 0 || cb == 0 )
+ return 0;
+
+ /* Sort buttons after rest of objects */
+ if ( ca->item_type == EXT_TOOLBAR_BUTTON && cb->item_type != EXT_TOOLBAR_BUTTON )
+ return 1;
+ else if ( ca->item_type != EXT_TOOLBAR_BUTTON && cb->item_type == EXT_TOOLBAR_BUTTON )
+ return -1;
+ else
+ {
+ if ( ca->item_cnt > cb->item_cnt )
+ return 2;
+ else if ( ca->item_cnt < cb->item_cnt )
+ return -2;
+ else
+ return 0;
+ }
+}
+
+ext_toolbar_t *
+ext_toolbar_add_entry( ext_toolbar_t * parent, ext_toolbar_item_t type, const gchar *label,
+ const gchar *defvalue, const gchar *tooltip, gboolean capture_only, GList * value_list,
+ gboolean is_required, const gchar * regex, ext_toolbar_action_cb callback, gpointer user_data)
+{
+ ext_toolbar_t * entry = NULL;
+
+ /* A valid parent must exist */
+ g_assert(parent != NULL && parent->type == EXT_TOOLBAR_BAR);
+ /* A label for the entry must be provided */
+ g_assert(label != NULL && strlen ( label ) > 0 );
+ /* A callback must be provided */
+ g_assert(callback != NULL);
+
+ parent->item_cnt++;
+
+ /* Create menu entry */
+ entry = g_new0(ext_toolbar_t, 1);
+ entry->type = EXT_TOOLBAR_ITEM;
+ entry->item_type = type;
+ entry->item_cnt = g_list_length(parent->children) + 1;
+
+ entry->name = g_strdup(label);
+
+ if ( tooltip != NULL && strlen(tooltip) > 0 )
+ entry->tooltip = g_strdup(tooltip);
+
+ if ( defvalue != NULL && strlen(defvalue) > 0 )
+ entry->defvalue = g_strdup(defvalue);
+
+ if ( value_list != NULL && g_list_length(value_list) > 0 )
+ entry->values = g_list_copy(value_list);
+
+ if ( regex )
+ entry->regex = g_strdup(regex);
+
+ entry->is_required = is_required;
+ entry->capture_only = capture_only;
+ entry->callback = callback;
+ entry->user_data = user_data;
+
+ parent->children = g_list_insert_sorted(parent->children, entry, ext_toolbar_insert_sort);
+
+ return entry;
+}
+
+static gint
+ext_toolbar_search_label(gconstpointer tb, gconstpointer lbl)
+{
+ if ( ! tb || ! lbl )
+ return -1;
+
+ ext_toolbar_t * toolbar = (ext_toolbar_t *) tb;
+ if ( toolbar->type != EXT_TOOLBAR_ITEM )
+ return -2;
+
+ gchar * label = (gchar * )lbl;
+
+ return g_strcmp0(toolbar->name, label);
+}
+
+ext_toolbar_t * ext_toolbar_entry_by_label(const ext_toolbar_t * toolbar, const gchar * label)
+{
+ ext_toolbar_t * result = 0;
+ GList * entry = g_list_find_custom(toolbar->children, label, ext_toolbar_search_label);
+ if ( entry )
+ result = (ext_toolbar_t *)entry->data;
+ return result;
+}
+
+GList * ext_toolbar_add_val(GList * entries, gchar * value, gchar * display, gboolean is_default)
+{
+ ext_toolbar_value_t * newval = g_new0(ext_toolbar_value_t, 1);
+ newval->value = g_strdup(value);
+ newval->display = g_strdup(display);
+ newval->is_default = is_default;
+
+ return g_list_append(entries, newval);
+}
+
+typedef struct _ext_toolbar_update_entry_t
+{
+ ext_toolbar_action_cb callback;
+ gpointer item_data;
+} ext_toolbar_update_entry_t;
+
+typedef struct _ext_toolbar_update_list_t
+{
+ ext_toolbar_t * item;
+ GList * entries;
+} ext_toolbar_update_list_t;
+
+extern gint
+ext_toolbar_find_item(gconstpointer a, gconstpointer b)
+{
+ if ( a == 0 || b == 0 )
+ return -1;
+
+ ext_toolbar_update_list_t * item = (ext_toolbar_update_list_t *)a;
+ ext_toolbar_t * entry = (ext_toolbar_t *)b;
+
+ if ( item->item && g_strcmp0 ( item->item->name, entry->name ) == 0 )
+ return 0;
+
+ return -1;
+}
+
+static GList * toolbar_updates = NULL;
+
+void ext_toolbar_register_update_cb(ext_toolbar_t * entry, ext_toolbar_action_cb callback, gpointer item_data)
+{
+ if ( entry == 0 || item_data == 0 || callback == 0 )
+ return;
+
+ ext_toolbar_update_list_t * update = NULL;
+ GList * update_list = g_list_find_custom(toolbar_updates, entry, ext_toolbar_find_item);
+ if ( ! update_list )
+ {
+ update = g_new0(ext_toolbar_update_list_t, 1);
+ update->item = entry;
+ toolbar_updates = g_list_append(toolbar_updates, update);
+ }
+ else
+ {
+ update = (ext_toolbar_update_list_t*)update_list->data;
+ }
+
+ ext_toolbar_update_entry_t * update_entry = g_new0(ext_toolbar_update_entry_t, 1);
+ update_entry->callback = callback;
+ update_entry->item_data = item_data;
+ update->entries = g_list_append(update->entries, update_entry);
+}
+
+static void
+ext_toolbar_update_entry(ext_toolbar_update_type_t update_type, ext_toolbar_t * entry, gpointer data, gpointer idx, gboolean silent)
+{
+ GList * update = g_list_find_custom(toolbar_updates, entry, ext_toolbar_find_item);
+ GList * walker = NULL;
+
+ if ( ! update || ! update->data )
+ return;
+
+ ext_toolbar_update_t * update_data = g_new0(ext_toolbar_update_t, 1);
+ update_data->user_data = data;
+ update_data->data_index = idx;
+ update_data->silent = silent;
+ update_data->type = update_type;
+
+ walker = ((ext_toolbar_update_list_t *)(update->data))->entries;
+
+ while ( walker && walker->data )
+ {
+ ext_toolbar_update_entry_t * update_entry = (ext_toolbar_update_entry_t *)walker->data;
+ /* Call Callback */
+ if ( update_entry->callback && update_entry->item_data )
+ update_entry->callback(entry, update_entry->item_data, update_data);
+ walker = g_list_next(walker);
}
+
+ g_free(update_data);
+}
+
+void ext_toolbar_update_value(ext_toolbar_t * entry, gpointer data, gboolean silent)
+{
+ ext_toolbar_update_entry( EXT_TOOLBAR_UPDATE_VALUE, entry, data, NULL, silent );
+}
+
+void ext_toolbar_update_data(ext_toolbar_t * entry, gpointer data, gboolean silent)
+{
+ if ( entry->item_type == EXT_TOOLBAR_SELECTOR )
+ ext_toolbar_update_entry( EXT_TOOLBAR_UPDATE_DATA, entry, data, NULL, silent );
}
+void ext_toolbar_update_data_by_index(ext_toolbar_t * entry, gpointer data, gpointer idx, gboolean silent)
+{
+ if ( entry->item_type == EXT_TOOLBAR_SELECTOR )
+ ext_toolbar_update_entry( EXT_TOOLBAR_UPDATE_DATABYINDEX, entry, data, idx, silent );
+}
+
+/* Implementation of GUI callback methods follows.
+ * This is a necessity, as using modern UI systems, gui interfaces often operate
+ * in different threads then the calling application. Even more so, if the calling
+ * application is implemented using a separate plugin. Therefore the external menubars
+ * cannot call gui functionality directly, the gui has to perform the function within
+ * it' own scope. */
+
extern void plugin_if_apply_filter(const char * filter_string, gboolean force)
{
plugin_if_callback_t actionType;
diff --git a/epan/plugin_if.h b/epan/plugin_if.h
index c74f86e422..76048e36f3 100644
--- a/epan/plugin_if.h
+++ b/epan/plugin_if.h
@@ -85,6 +85,70 @@ struct _ext_menubar_t
gchar * parent_menu;
};
+typedef void (*ext_toolbar_action_cb)(gpointer toolbar_item, gpointer item_data, gpointer user_data);
+
+typedef enum
+{
+ EXT_TOOLBAR_BAR,
+ EXT_TOOLBAR_ITEM
+} ext_toolbar_entry_t;
+
+typedef enum
+{
+ EXT_TOOLBAR_BOOLEAN,
+ EXT_TOOLBAR_BUTTON,
+ EXT_TOOLBAR_STRING,
+ EXT_TOOLBAR_SELECTOR,
+} ext_toolbar_item_t;
+
+typedef struct _ext_toolbar_value_t
+{
+ gchar * value;
+ gchar * display;
+
+ gboolean is_default;
+
+} ext_toolbar_value_t;
+
+typedef struct _ext_toolbar_t
+{
+ ext_toolbar_entry_t type;
+
+ GList * children;
+ guint submenu_cnt;
+ guint item_cnt;
+
+ gchar * name;
+ gchar * defvalue;
+ gchar * tooltip;
+ gpointer user_data;
+
+ gboolean is_required;
+ gboolean capture_only;
+ ext_toolbar_item_t item_type;
+
+ GList * values;
+ gchar * regex;
+
+ ext_toolbar_action_cb callback;
+
+} ext_toolbar_t;
+
+typedef enum
+{
+ EXT_TOOLBAR_UPDATE_VALUE,
+ EXT_TOOLBAR_UPDATE_DATA,
+ EXT_TOOLBAR_UPDATE_DATABYINDEX
+} ext_toolbar_update_type_t;
+
+typedef struct _ext_toolbar_update_t
+{
+ ext_toolbar_update_type_t type;
+ gboolean silent;
+ gpointer user_data;
+ gpointer data_index;
+} ext_toolbar_update_t;
+
/* Registers a new main menu.
*
* This will register a new main menu entry, underneath all other menu entries will
@@ -162,6 +226,108 @@ WS_DLL_PUBLIC void ext_menubar_add_separator(ext_menu_t *parent_menu);
WS_DLL_PUBLIC void ext_menubar_add_website(ext_menu_t * parent, const gchar *label,
const gchar *tooltip, const gchar *url);
+/* Registers a toolbar.
+ *
+ * This will register a new toolbar, which can contain various gui elements
+ *
+ * @param toolbar_label the entry label (the displayed name) for the toolbar item
+ */
+WS_DLL_PUBLIC ext_toolbar_t * ext_toolbar_register_toolbar(const gchar * toolbar_label);
+
+/* Removes a toolbar from the system.
+ *
+ * This will remove the provided toolbar from the application
+ *
+ * @param toolbar the toolbar to be removed
+ */
+WS_DLL_PUBLIC void ext_toolbar_unregister_toolbar(ext_toolbar_t * toolbar);
+
+/* Removes a toolbar from the system by providing the name of the toolbar.
+ *
+ * This will remove the provided toolbar from the application
+ *
+ * @param toolbar_name the name of the toolbar to be removed
+ */
+WS_DLL_PUBLIC void ext_toolbar_unregister_toolbar_by_name(const gchar * toolbar_name);
+
+/* Registers a new toolbar entry.
+ *
+ * This registers a new toolbar entry, which will have the given name, and
+ * call the provided callback on activation
+ *
+ * The callback will be fired on different events, depending on the item type
+ * and the implementation of the item type in a GUI element. The following types should
+ * behave as following
+ *
+ * * EXT_TOOLBAR_STRING - Every change of the content fires the callback
+ * * EXT_TOOLBAR_BOOLEAN - Every change of the value fires the callback
+ * * EXT_TOOLBAR_BUTTON - if the button is pressed, the callback fires
+ * * EXT_TOOLBAR_SELECTION - every time the selection changes the callback fires
+ *
+ * @param parent_bar the parent toolbar for this entry
+ * @param name the entry name (the internal used one) for the item
+ * @param label the entry label (the displayed name) for the item
+ * @param defvalue the default value for the toolbar element
+ * @param tooltip a tooltip to be displayed on mouse-over
+ * @param capture_only entry is only active, if capture is active
+ * @param callback the action which will be invoked after click on the item
+ * @param value_list a non-null list of values, if the item type is EXT_TOOLBAR_SELECTOR
+ * @param valid_regex a validation regular expression for EXT_TOOLBAR_STRING
+ *
+ * @return a reference to the newly created toolbar entry
+ */
+WS_DLL_PUBLIC ext_toolbar_t * ext_toolbar_add_entry(
+ ext_toolbar_t * parent_bar,
+ ext_toolbar_item_t type,
+ const gchar *label,
+ const gchar *defvalue,
+ const gchar *tooltip,
+ gboolean capture_only,
+ GList * value_list,
+ gboolean is_required,
+ const gchar * valid_regex,
+ ext_toolbar_action_cb callback,
+ gpointer user_data);
+
+WS_DLL_PUBLIC GList * ext_toolbar_add_val(GList * entries, gchar * value, gchar * display, gboolean is_default);
+
+WS_DLL_PUBLIC void ext_toolbar_register_update_cb(ext_toolbar_t * entry, ext_toolbar_action_cb callback, gpointer item_data);
+
+/* Updates the entry values
+ *
+ * Update the values for the entry, it is up to the implemented widget, to interpret the
+ * given character values
+ *
+ * @param entry the entry to be updated
+ * @param data the data for the entry
+ * @param silent the update for the entry should not trigger additional actions
+ */
+WS_DLL_PUBLIC void ext_toolbar_update_value(ext_toolbar_t * entry, gpointer data, gboolean silent);
+
+/* Updates the entry data
+ *
+ * Update the data for the entry, it is up to the implemented widget, to interpret the given character data
+ *
+ * @param entry the entry to be updated
+ * @param data the data for the entry
+ * @param silent the update for the entry should not trigger additional actions
+ */
+WS_DLL_PUBLIC void ext_toolbar_update_data(ext_toolbar_t * entry, gpointer data, gboolean silent);
+
+/* Updates the entry data by index
+ *
+ * This is used to update a single entry of a selector list, by giving it's value and a new display
+ * entry
+ *
+ * @param entry the entry to be updated
+ * @param data the display data for the entry
+ * @param value the value for the entry to be updated
+ * @param silent the update for the entry should not trigger additional actions
+ */
+WS_DLL_PUBLIC void ext_toolbar_update_data_by_index(ext_toolbar_t * entry, gpointer data, gpointer value, gboolean silent);
+
+/* Search for and return if found an entry from the toolbar with the given label */
+WS_DLL_PUBLIC ext_toolbar_t * ext_toolbar_entry_by_label(const ext_toolbar_t * toolbar, const gchar * label);
/*
* Structure definition for the plugin_if_get_ws_info function
@@ -196,7 +362,11 @@ typedef enum
PLUGIN_IF_GOTO_FRAME,
/* Gets status information about the currently loaded capture file */
- PLUGIN_IF_GET_WS_INFO
+ PLUGIN_IF_GET_WS_INFO,
+
+ /* Remove toolbar */
+ PLUGIN_IF_REMOVE_TOOLBAR
+
} plugin_if_callback_t;
@@ -222,6 +392,12 @@ WS_DLL_PUBLIC void plugin_if_get_ws_info(ws_info_t ** ws_info);
*/
WS_DLL_PUBLIC GList * ext_menubar_get_entries(void);
+/* Private Method for retrieving the toolbar entries
+ *
+ * Is only to be used by the UI interfaces to retrieve the toolbar entries
+ */
+WS_DLL_PUBLIC GList * ext_toolbar_get_entries(void);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/plugins/pluginifdemo/AUTHORS b/plugins/pluginifdemo/AUTHORS
new file mode 100644
index 0000000000..ca50630cb9
--- /dev/null
+++ b/plugins/pluginifdemo/AUTHORS
@@ -0,0 +1,2 @@
+Author :
+Roland Knall <rknall@gmail.com>
diff --git a/plugins/pluginifdemo/CMakeLists.txt b/plugins/pluginifdemo/CMakeLists.txt
new file mode 100644
index 0000000000..5090f3d63b
--- /dev/null
+++ b/plugins/pluginifdemo/CMakeLists.txt
@@ -0,0 +1,87 @@
+# CMakeLists.txt
+#
+# 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.
+#
+
+include(WiresharkPlugin)
+
+# Plugin name and version info (major minor micro extra)
+set_module_info(pluginifdemo 0 0 1 0)
+
+SET(CMAKE_AUTOMOC ON)
+SET(CMAKE_AUTOUIC ON)
+
+find_package(Qt5Core)
+find_package(Qt5PrintSupport)
+find_package(Qt5Widgets)
+
+set(DISSECTOR_SRC
+ pluginifdemo.c
+ ui/uihandler.cpp
+ ui/uiclasshandler.cpp
+ ui/pluginifdemo_main.cpp
+ ui/pluginifdemo_about.cpp
+ ${UI_SRC}
+)
+
+set(PLUGIN_FILES
+ plugin.c
+ ${DISSECTOR_SRC}
+)
+
+set(CLEAN_FILES
+ ${PLUGIN_FILES}
+)
+
+if (WERROR_COMMON_FLAGS)
+ set_source_files_properties(
+ ${CLEAN_FILES}
+ PROPERTIES
+ COMPILE_FLAGS ${WERROR_COMMON_FLAGS}
+ )
+endif()
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+register_dissector_files(plugin.c
+ plugin
+ ${DISSECTOR_SRC}
+)
+
+add_plugin_library(pluginifdemo)
+
+target_link_libraries(pluginifdemo Qt5::Core Qt5::Widgets Qt5::PrintSupport)
+
+install(TARGETS pluginifdemo
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${CPACK_PACKAGE_NAME}/plugins/${CPACK_PACKAGE_VERSION} NAMELINK_SKIP
+ RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}/${CPACK_PACKAGE_NAME}/plugins/${CPACK_PACKAGE_VERSION}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${CPACK_PACKAGE_NAME}/plugins/${CPACK_PACKAGE_VERSION}
+)
+
+file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h")
+CHECKAPI(
+ NAME
+ pluginifdemo
+ SWITCHES
+ -g abort -g termoutput -build
+ SOURCES
+ ${DISSECTOR_SRC}
+ ${DISSECTOR_HEADERS}
+)
diff --git a/plugins/pluginifdemo/COPYING b/plugins/pluginifdemo/COPYING
new file mode 100644
index 0000000000..f7962229f1
--- /dev/null
+++ b/plugins/pluginifdemo/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/plugins/pluginifdemo/Makefile.am b/plugins/pluginifdemo/Makefile.am
new file mode 100644
index 0000000000..f2311806a2
--- /dev/null
+++ b/plugins/pluginifdemo/Makefile.am
@@ -0,0 +1,66 @@
+# Makefile.am
+#
+# 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.
+
+include $(top_srcdir)/Makefile.am.inc
+include ../Makefile.am.inc
+
+# the name of the plugin
+PLUGIN_NAME = pluginifdemo
+
+# Non-generated sources to be scanned for registration routines
+NONGENERATED_REGISTER_C_FILES = \
+ pluginifdemo.c
+
+# Non-generated sources
+NONGENERATED_C_FILES = \
+ $(NONGENERATED_REGISTER_C_FILES)
+
+# Headers.
+CLEAN_HEADER_FILES = \
+ pluginifdemo.h
+
+HEADER_FILES = \
+ $(CLEAN_HEADER_FILES)
+
+plugin_LTLIBRARIES = pluginifdemo.la
+
+pluginifdemo_la_SOURCES = \
+ plugin.c \
+ moduleinfo.h \
+ $(SRC_FILES) \
+ $(HEADER_FILES)
+
+pluginifdemo_la_CPPFLAGS = $(AM_CPPFLAGS) $(PLUGIN_CPPFLAGS)
+
+pluginifdemo_la_CFLAGS = $(AM_CFLAGS) $(PLUGIN_CFLAGS)
+
+pluginifdemo_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+
+CLEANFILES = \
+ pluginifdemo \
+ *~
+
+MAINTAINERCLEANFILES = \
+ Makefile.in \
+ plugin.c
+
+EXTRA_DIST = \
+ plugin.rc.in \
+ CMakeLists.txt
diff --git a/plugins/pluginifdemo/NEWS b/plugins/pluginifdemo/NEWS
new file mode 100644
index 0000000000..e6a8d1263b
--- /dev/null
+++ b/plugins/pluginifdemo/NEWS
@@ -0,0 +1 @@
+Initial version
diff --git a/plugins/pluginifdemo/README b/plugins/pluginifdemo/README
new file mode 100644
index 0000000000..7aa753f711
--- /dev/null
+++ b/plugins/pluginifdemo/README
@@ -0,0 +1,2 @@
+This plugin demonstrates a Qt integration using plugin_if and
+menubar_ext functionality.
diff --git a/plugins/pluginifdemo/moduleinfo.h b/plugins/pluginifdemo/moduleinfo.h
new file mode 100644
index 0000000000..b1b10a58dc
--- /dev/null
+++ b/plugins/pluginifdemo/moduleinfo.h
@@ -0,0 +1,39 @@
+/* moduleinfo.h
+ *
+ * Module info header for wireshark plugins.
+ *
+ * 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.
+ */
+
+/* Included *after* config.h, in order to re-define these macros */
+
+#ifdef PACKAGE
+#undef PACKAGE
+#endif
+
+/* Name of package */
+#define PACKAGE "pluginifdemo"
+
+
+#ifdef VERSION
+#undef VERSION
+#endif
+
+/* Version number of package */
+#define VERSION "0.0.1"
diff --git a/plugins/pluginifdemo/plugin.rc.in b/plugins/pluginifdemo/plugin.rc.in
new file mode 100644
index 0000000000..cac1f406ac
--- /dev/null
+++ b/plugins/pluginifdemo/plugin.rc.in
@@ -0,0 +1,34 @@
+#include "winver.h"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION @RC_MODULE_VERSION@
+ PRODUCTVERSION @RC_VERSION@
+ FILEFLAGSMASK 0x0L
+#ifdef _DEBUG
+ FILEFLAGS VS_FF_DEBUG
+#else
+ FILEFLAGS 0
+#endif
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "The Wireshark developer community, http://www.wireshark.org/\0"
+ VALUE "FileDescription", "@PACKAGE@ dissector\0"
+ VALUE "FileVersion", "@MODULE_VERSION@\0"
+ VALUE "InternalName", "@PACKAGE@ @MODULE_VERSION@\0"
+ VALUE "LegalCopyright", "Copyright © 1998 Gerald Combs <gerald@wireshark.org>, Gilbert Ramirez <gram@alumni.rice.edu> and others\0"
+ VALUE "OriginalFilename", "@PLUGIN_NAME@.dll\0"
+ VALUE "ProductName", "Wireshark\0"
+ VALUE "ProductVersion", "@VERSION@\0"
+ VALUE "Comments", "Built with @MSVC_VARIANT@\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/plugins/pluginifdemo/pluginifdemo.c b/plugins/pluginifdemo/pluginifdemo.c
new file mode 100644
index 0000000000..548677a80c
--- /dev/null
+++ b/plugins/pluginifdemo/pluginifdemo.c
@@ -0,0 +1,157 @@
+/* pluginifdemo.c
+ * Routines for plugin_if demo capability
+ * Author: Roland Knall <rknall@gmail.com>
+ *
+ * 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.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+
+#include <epan/packet.h>
+#include <epan/prefs.h>
+#include <epan/tap.h>
+#include <epan/plugin_if.h>
+#include "pluginifdemo.h"
+
+#include <ui/uihandler.h>
+
+void proto_register_pluginifdemo(void);
+void proto_reg_handoff_pluginifdemo(void);
+
+static int proto_pluginifdemo = -1;
+
+void toolbar_cb(gpointer object, gpointer item_data, gpointer user_data);
+
+void
+menu_cb(ext_menubar_gui_type gui_type, gpointer gui_data, gpointer user_data _U_)
+{
+ pluginifdemo_ui_main(gui_type, gui_data);
+}
+
+void
+about_cb(ext_menubar_gui_type gui_type _U_, gpointer gui_data _U_, gpointer user_data _U_)
+{
+ pluginifdemo_ui_about(gui_type, gui_data);
+}
+
+void
+proto_register_pluginifdemo(void)
+{
+ static hf_register_info hf[] = {
+ };
+
+ static gint *ett[] = {
+ };
+
+#if 0
+ module_t *pluginif_module = NULL;
+#endif
+ ext_menu_t * ext_menu = NULL;
+
+ proto_pluginifdemo = proto_register_protocol("Plugin IF Demo Protocol", "Pluginifdemo", "pluginifdemo");
+
+ proto_register_field_array(proto_pluginifdemo, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+
+ ext_menu = ext_menubar_register_menu ( proto_pluginifdemo, "Plugin IF Demonstration", TRUE );
+ ext_menubar_set_parentmenu (ext_menu, "Tools");
+
+ ext_menubar_add_entry(ext_menu, "Toolbar Action Demonstrator", "Action demonstrator for the plugin toolbar", menu_cb, NULL);
+ ext_menubar_add_separator(ext_menu);
+ ext_menubar_add_website(ext_menu, "Wireshark Development", "See Wireshark Development", "https://www.wireshark.org/develop.html");
+ ext_menubar_add_separator(ext_menu);
+ ext_menubar_add_entry(ext_menu, "&About Plugin IF Demonstration", "Further information", about_cb, NULL);
+#if 0
+ pluginif_module = prefs_register_protocol(proto_pluginifdemo, NULL);
+#endif
+
+
+ ext_toolbar_t * tb = ext_toolbar_register_toolbar("Plugin Interface Demo Toolbar");
+
+ ext_toolbar_add_entry(tb, EXT_TOOLBAR_BUTTON, "Test Button", 0, "Button to press", FALSE, 0, FALSE, 0, toolbar_cb, 0);
+ ext_toolbar_add_entry(tb, EXT_TOOLBAR_BUTTON, "Test 2 Button", 0, "Button 2 to press", TRUE, 0, FALSE, 0, toolbar_cb, 0);
+ ext_toolbar_add_entry(tb, EXT_TOOLBAR_BOOLEAN, "Test CheckBox", 0, "CheckBox to Select", FALSE, 0, FALSE, 0, toolbar_cb, 0);
+ ext_toolbar_add_entry(tb, EXT_TOOLBAR_STRING, "Reg String", "Default String", "Test Testbox", FALSE, 0, TRUE, 0, toolbar_cb, 0);
+ ext_toolbar_add_entry(tb, EXT_TOOLBAR_STRING, "Test Textbox", "ABC", "Box with Validation", FALSE, 0, FALSE, "^[A-Z]+", toolbar_cb, 0);
+ GList * entries = 0;
+ entries = ext_toolbar_add_val( entries, "1", "ABCD", FALSE );
+ entries = ext_toolbar_add_val(entries, "2", "EFG", FALSE );
+ entries = ext_toolbar_add_val(entries, "3", "HIJ", TRUE );
+ entries = ext_toolbar_add_val(entries, "4", "KLM", FALSE );
+ entries = ext_toolbar_add_val(entries, "5", "NOP", FALSE );
+ entries = ext_toolbar_add_val(entries, "6", "QRS", FALSE );
+ entries = ext_toolbar_add_val(entries, "7", "TUVW", FALSE );
+ entries = ext_toolbar_add_val(entries, "8", "XYZ", FALSE );
+ ext_toolbar_add_entry(tb, EXT_TOOLBAR_SELECTOR, "Test Selector", 0, "Selector to choose from", FALSE, entries, FALSE, 0, toolbar_cb, 0);
+
+ pluginifdemo_toolbar_register(tb);
+}
+
+void toolbar_cb(gpointer toolbar_item, gpointer item_data, gpointer user_data _U_)
+{
+ if ( ! toolbar_item )
+ return;
+
+ gchar * message = 0;
+ ext_toolbar_t * entry = (ext_toolbar_t *)toolbar_item;
+
+ if ( entry->item_type == EXT_TOOLBAR_BUTTON )
+ pluginifdemo_toolbar_log ( "Button pressed at toolbar" );
+ else if ( entry->item_type == EXT_TOOLBAR_BOOLEAN )
+ {
+ gboolean data = *((gboolean *)item_data);
+ message = g_strdup_printf( "Checkbox selected value: %d", (int) (data) );
+ pluginifdemo_toolbar_log(message);
+ }
+ else if ( entry->item_type == EXT_TOOLBAR_STRING )
+ {
+ gchar * data = (gchar *)item_data;
+ message = g_strdup_printf( "String entered in toolbar: %s", data );
+ pluginifdemo_toolbar_log(message);
+ }
+ else if ( entry->item_type == EXT_TOOLBAR_SELECTOR )
+ {
+ ext_toolbar_value_t * data = (ext_toolbar_value_t *)item_data;
+ message = g_strdup_printf( "Value from toolbar: %s", data->value );
+ pluginifdemo_toolbar_log(message);
+ }
+
+ g_free(message);
+}
+
+void
+proto_reg_handoff_pluginifdemo(void)
+{
+
+}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/plugins/pluginifdemo/pluginifdemo.h b/plugins/pluginifdemo/pluginifdemo.h
new file mode 100644
index 0000000000..59b2a649c1
--- /dev/null
+++ b/plugins/pluginifdemo/pluginifdemo.h
@@ -0,0 +1,23 @@
+/* pluginifdemo.h
+ * Definitions for plugin_if_demo structures and routines
+ * By Steve Limkemann <stevelim@dgtech.com>
+ * Copyright 1998 Steve Limkemann
+ *
+ * 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.
+ */
diff --git a/plugins/pluginifdemo/ui/pluginifdemo_about.cpp b/plugins/pluginifdemo/ui/pluginifdemo_about.cpp
new file mode 100644
index 0000000000..3284b3bebc
--- /dev/null
+++ b/plugins/pluginifdemo/ui/pluginifdemo_about.cpp
@@ -0,0 +1,61 @@
+/* pluginifdemo_about.cpp
+ *
+ * Author: Roland Knall <rknall@gmail.com>
+ *
+ * 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.
+ */
+
+#include <plugins/pluginifdemo/ui/pluginifdemo_about.h>
+#include <ui_pluginifdemo_about.h>
+
+#include <config.h>
+
+#include <QDialog>
+#include <QWidget>
+#include <QAbstractButton>
+
+PluginIFDemo_About::PluginIFDemo_About(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::PluginIFDemo_About)
+{
+ ui->setupUi(this);
+}
+
+PluginIFDemo_About::~PluginIFDemo_About()
+{
+ delete ui;
+}
+
+void PluginIFDemo_About::on_buttonBox_clicked(QAbstractButton *button _U_)
+{
+ this->close();
+}
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/plugins/pluginifdemo/ui/pluginifdemo_about.h b/plugins/pluginifdemo/ui/pluginifdemo_about.h
new file mode 100644
index 0000000000..aa4bb4726d
--- /dev/null
+++ b/plugins/pluginifdemo/ui/pluginifdemo_about.h
@@ -0,0 +1,65 @@
+/* pluginifdemo_about.h
+ *
+ * Author: Roland Knall <rknall@gmail.com>
+ *
+ * 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 PLUGINIFDEMO_ABOUT_H_
+#define PLUGINIFDEMO_ABOUT_H_
+
+#include <QWidget>
+#include <QDialog>
+#include <QAbstractButton>
+#include <QPixmap>
+#include <QGraphicsScene>
+
+namespace Ui {
+class PluginIFDemo_About;
+}
+
+class PluginIFDemo_About : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit PluginIFDemo_About(QWidget *parent = 0);
+ ~PluginIFDemo_About();
+
+private slots:
+ void on_buttonBox_clicked(QAbstractButton *button);
+
+private:
+ Ui::PluginIFDemo_About *ui;
+};
+
+#endif /* PLUGINIFDEMO_ABOUT_H_ */
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/plugins/pluginifdemo/ui/pluginifdemo_about.ui b/plugins/pluginifdemo/ui/pluginifdemo_about.ui
new file mode 100644
index 0000000000..2353dd76ac
--- /dev/null
+++ b/plugins/pluginifdemo/ui/pluginifdemo_about.ui
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PluginIFDemo_About</class>
+ <widget class="QDialog" name="PluginIFDemo_About">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>545</width>
+ <height>401</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>545</width>
+ <height>401</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>545</width>
+ <height>401</height>
+ </size>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::NoContextMenu</enum>
+ </property>
+ <property name="windowTitle">
+ <string>About Plugin Interface Demonstrator</string>
+ </property>
+ <property name="modal">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>10</number>
+ </property>
+ <property name="leftMargin">
+ <number>9</number>
+ </property>
+ <property name="topMargin">
+ <number>9</number>
+ </property>
+ <property name="rightMargin">
+ <number>9</number>
+ </property>
+ <property name="bottomMargin">
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="lblAboutDialog">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style=&quot; font-size:10pt; font-weight:600;&quot;&gt;PlugIn Interface Demonstration&lt;/span&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;&lt;br/&gt;Version: &lt;/span&gt;&lt;span style=&quot; font-size:10pt; font-weight:600;&quot;&gt;0.0.1 &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Copyright © &lt;/span&gt;&lt;span style=&quot; font-size:10pt; font-style:italic;&quot;&gt;Wireshark Foundation&lt;/span&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;a href=&quot;http://www.wireshark.org&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;www.wireshark.org&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>License Information</string>
+ </attribute>
+ <widget class="QLabel" name="lblLicense">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>0</y>
+ <width>511</width>
+ <height>102</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This PlugIn demonstrates functionality of the interface API for plugins and extcap interfaces.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Ok</set>
+ </property>
+ <property name="centerButtons">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/plugins/pluginifdemo/ui/pluginifdemo_main.cpp b/plugins/pluginifdemo/ui/pluginifdemo_main.cpp
new file mode 100644
index 0000000000..33f88356e1
--- /dev/null
+++ b/plugins/pluginifdemo/ui/pluginifdemo_main.cpp
@@ -0,0 +1,320 @@
+/* pluginifdemo_main.cpp
+ *
+ * Author: Roland Knall <rknall@gmail.com>
+ *
+ * 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.
+ */
+
+#include <plugins/pluginifdemo/ui/pluginifdemo_main.h>
+#include <ui_pluginifdemo_main.h>
+
+#include <config.h>
+
+#include <ui/uihandler.h>
+
+#include <QWidget>
+#include <QLineEdit>
+#include <QListView>
+#include <QStandardItemModel>
+
+PluginIfType::PluginIfType(const QString &label, const ext_toolbar_item_t &itemType)
+ : m_label(label), m_itemType(itemType)
+{}
+
+QString PluginIfType::label() const { return m_label; }
+ext_toolbar_item_t PluginIfType::itemType() const { return m_itemType; }
+
+PluginIfTypeModel::PluginIfTypeModel(QObject * parent)
+ :QAbstractListModel(parent)
+{
+}
+
+void PluginIfTypeModel::addPluginIfType(const PluginIfType &ifType)
+{
+ beginInsertRows(QModelIndex(), rowCount(), rowCount());
+ m_pluginIfTypes << ifType;
+ endInsertRows();
+}
+
+int PluginIfTypeModel::rowCount(const QModelIndex &) const
+{
+ return m_pluginIfTypes.count();
+}
+
+QVariant PluginIfTypeModel::data(const QModelIndex & idx, int role) const
+{
+ if ( idx.row() < 0 || idx.row() >= m_pluginIfTypes.count() )
+ return QVariant();
+
+ const PluginIfType &ifType = m_pluginIfTypes[idx.row()];
+ if ( role == Qt::UserRole )
+ {
+ return ifType.itemType();
+ } else if ( role == Qt::DisplayRole ) {
+ return ifType.label();
+ }
+
+ return QVariant();
+}
+
+PluginIfTypeSortFilterProxyModel::PluginIfTypeSortFilterProxyModel(QObject * parent)
+:QSortFilterProxyModel(parent)
+{
+ m_filterType = EXT_TOOLBAR_BOOLEAN;
+}
+
+void PluginIfTypeSortFilterProxyModel::setFilterElement(ext_toolbar_item_t filterType)
+{
+ m_filterType = filterType;
+ invalidateFilter();
+}
+
+bool PluginIfTypeSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
+{
+ QModelIndex dataIndex = sourceModel()->index(sourceRow, 0, sourceParent);
+ QVariant varData = sourceModel()->data(dataIndex, Qt::UserRole);
+ if ( varData.isValid() && varData.toInt() == (int) m_filterType )
+ return true;
+
+ return false;
+}
+
+PluginIFDemo_Main::PluginIFDemo_Main(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::PluginIFDemo_Main)
+{
+ ui->setupUi(this);
+
+ _toolbar = 0;
+ sourceModel = new PluginIfTypeModel(this);
+ proxyModel = new PluginIfTypeSortFilterProxyModel(this);
+ proxyModel->setSourceModel(sourceModel);
+ ui->cmbElements->setModel(proxyModel);
+
+ listModel = new QStandardItemModel(this);
+ ui->lstItems->setModel(listModel);
+
+ indexModel = new QStandardItemModel(this);
+ ui->cmbEntryIndex->setModel(indexModel);
+
+ ui->logView->setModel(new QStandardItemModel(ui->logView));
+
+ ui->tabInterfaceTypes->setCurrentIndex(0);
+
+ connect ( GuiHandler::getInstance(), SIGNAL(reset(void)), this, SLOT(closeDialog()) );
+ connect ( GuiHandler::getInstance(), SIGNAL(logChanged(QString)), this, SLOT(logChanged(QString)) );
+}
+
+PluginIFDemo_Main::~PluginIFDemo_Main()
+{
+ delete ui;
+}
+
+void PluginIFDemo_Main::setToolbar(ext_toolbar_t * &toolbar)
+{
+ _toolbar = toolbar;
+
+ GList * walker = toolbar->children;
+ while ( walker && walker->data )
+ {
+ ext_toolbar_t * entry = (ext_toolbar_t *)walker->data;
+ if ( entry && entry->type == EXT_TOOLBAR_ITEM && entry->name )
+ sourceModel->addPluginIfType(PluginIfType(QString(entry->name), entry->item_type));
+ walker = g_list_next(walker);
+ }
+}
+
+void PluginIFDemo_Main::closeDialog()
+{
+ this->close();
+}
+
+void PluginIFDemo_Main::on_buttonBox_clicked(QAbstractButton *button _U_)
+{
+ this->close();
+}
+
+void PluginIFDemo_Main::logChanged(QString message)
+{
+ QStandardItemModel * model = (QStandardItemModel *) ui->logView->model();
+ model->appendRow(new QStandardItem(message));
+}
+
+void PluginIFDemo_Main::on_btnSendButtonText_clicked()
+{
+ if ( ! _toolbar )
+ return;
+
+ ext_toolbar_t *item = ext_toolbar_entry_by_label(_toolbar, ui->cmbElements->currentText().toStdString().c_str());
+ if ( ! item )
+ return;
+
+ QString entryText = ui->txtButtonName->text();
+ bool silent = ui->chkSilent->checkState() == Qt::Checked ? true : false;
+
+ ext_toolbar_update_value(item, (gpointer) entryText.toStdString().c_str(), silent);
+}
+
+void PluginIFDemo_Main::on_btnSendText_clicked()
+{
+ if ( ! _toolbar )
+ return;
+
+ ext_toolbar_t *item = ext_toolbar_entry_by_label(_toolbar, ui->cmbElements->currentText().toStdString().c_str());
+ if ( ! item )
+ return;
+
+ QString entryText = ui->txtEdit->text();
+ bool silent = ui->chkSilent->checkState() == Qt::Checked ? true : false;
+
+ ext_toolbar_update_value(item, (gpointer) entryText.toStdString().c_str(), silent);
+}
+
+void PluginIFDemo_Main::on_chkTestCheckbox_stateChanged(int newState)
+{
+ if ( ! _toolbar )
+ return;
+
+ ext_toolbar_t * item = ext_toolbar_entry_by_label(_toolbar, ui->cmbElements->currentText().toStdString().c_str());
+ if ( ! item )
+ return;
+ bool silent = ui->chkSilent->checkState() == Qt::Checked ? true : false;
+
+ ext_toolbar_update_value(item, GINT_TO_POINTER(newState == Qt::Checked ? 1 : 0), silent);
+}
+
+void PluginIFDemo_Main::on_tabInterfaceTypes_currentChanged(int newTab)
+{
+ proxyModel->setFilterElement((ext_toolbar_item_t) newTab);
+}
+
+void PluginIFDemo_Main::on_cmbElements_currentTextChanged(const QString & newText)
+{
+ if ( ! _toolbar )
+ return;
+
+ ext_toolbar_t * item = ext_toolbar_entry_by_label(_toolbar, newText.toStdString().c_str());
+ if ( ! item || item->item_type != EXT_TOOLBAR_SELECTOR )
+ return;
+
+ listModel->clear();
+ indexModel->clear();
+
+ GList * walker = item->values;
+ while ( walker && walker->data )
+ {
+ ext_toolbar_value_t * listItem = (ext_toolbar_value_t *)walker->data;
+ QString content = QString("%1: %2").arg(listItem->value).arg(listItem->display);
+ listModel->appendRow(new QStandardItem(content));
+ indexModel->appendRow(new QStandardItem(listItem->value));
+
+ walker = g_list_next(walker);
+ }
+
+}
+
+void PluginIFDemo_Main::on_btnAddItem_clicked()
+{
+ if ( ui->txtNewItemDisplay->text().length() <= 0 || ui->txtNewItemValue->text().length() <= 0 )
+ return;
+
+ QString content = QString("%1: %2").arg(ui->txtNewItemValue->text()).arg(ui->txtNewItemDisplay->text());
+
+ QList<QStandardItem *> items = listModel->findItems(content);
+ if ( items.count() > 0 )
+ return;
+ items = listModel->findItems(QString("%1: ").arg(ui->txtNewItemValue->text()), Qt::MatchStartsWith);
+ if ( items.count() > 0 )
+ return;
+
+ listModel->appendRow(new QStandardItem(content));
+}
+
+void PluginIFDemo_Main::on_btnRemoveItem_clicked()
+{
+ QItemSelectionModel * selModel = ui->lstItems->selectionModel();
+
+ if ( selModel->selectedIndexes().count() == 0 )
+ return;
+
+ QModelIndexList selIndeces = selModel-> selectedIndexes();
+ foreach(QModelIndex idx, selIndeces)
+ listModel->removeRow(idx.row());
+}
+
+void PluginIFDemo_Main::on_btnSendList_clicked()
+{
+ if ( ! _toolbar )
+ return;
+
+ ext_toolbar_t * item = ext_toolbar_entry_by_label(_toolbar, ui->cmbElements->currentText().toStdString().c_str());
+ if ( ! item || item->item_type != EXT_TOOLBAR_SELECTOR )
+ return;
+
+ GList * items = NULL;
+
+ for( int i = 0; i < listModel->rowCount(); i++ )
+ {
+ QString content = listModel->data(listModel->index(i, 0)).toString();
+ int pos = content.indexOf(":");
+
+ ext_toolbar_value_t * valEntry = g_new0(ext_toolbar_value_t, 1);
+ valEntry->value = g_strdup(content.left(pos).toStdString().c_str() );
+ valEntry->display = g_strdup(content.right(content.size() - pos + 1).toStdString().c_str());
+
+ items = g_list_append(items, valEntry);
+ }
+
+ bool silent = ui->chkSilent->checkState() == Qt::Checked ? true : false;
+
+ ext_toolbar_update_data(item, items , silent);
+}
+
+void PluginIFDemo_Main::on_btnSendUpdateItem_clicked()
+{
+ if ( ! _toolbar )
+ return;
+
+ ext_toolbar_t * item = ext_toolbar_entry_by_label(_toolbar, ui->cmbElements->currentText().toStdString().c_str());
+ if ( ! item || item->item_type != EXT_TOOLBAR_SELECTOR )
+ return;
+
+ QString cmbIndexText = ui->cmbEntryIndex->currentText();
+ QString displayValue = ui->txtUpdateDisplayValue->text();
+ if ( displayValue.length() == 0 )
+ return;
+
+ bool silent = ui->chkSilent->checkState() == Qt::Checked ? true : false;
+
+ ext_toolbar_update_data_by_index(item,
+ (gpointer) displayValue.toStdString().c_str(), (gpointer) cmbIndexText.toStdString().c_str(), silent );
+}
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/plugins/pluginifdemo/ui/pluginifdemo_main.h b/plugins/pluginifdemo/ui/pluginifdemo_main.h
new file mode 100644
index 0000000000..439712e556
--- /dev/null
+++ b/plugins/pluginifdemo/ui/pluginifdemo_main.h
@@ -0,0 +1,133 @@
+/* pluginifdemo_main.h
+ *
+ * Author: Roland Knall <rknall@gmail.com>
+ *
+ * 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 PLUGINIFDEMO_MAIN_H_
+#define PLUGINIFDEMO_MAIN_H_
+
+#include <QWidget>
+#include <QDialog>
+#include <QAbstractButton>
+#include <QListWidget>
+#include <QAbstractListModel>
+#include <QSortFilterProxyModel>
+#include <QStandardItemModel>
+
+#include <plugin_if.h>
+
+namespace Ui {
+class PluginIFDemo_Main;
+}
+
+class PluginIfType
+{
+public:
+ PluginIfType(const QString &label, const ext_toolbar_item_t &itemType);
+
+ QString label() const;
+ ext_toolbar_item_t itemType() const;
+private:
+ QString m_label;
+ ext_toolbar_item_t m_itemType;
+};
+
+class PluginIfTypeModel : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ PluginIfTypeModel(QObject * parent = 0);
+
+ void addPluginIfType(const PluginIfType & pluginIfType);
+
+ int rowCount(const QModelIndex & parent = QModelIndex()) const;
+ QVariant data(const QModelIndex & idx, int role = Qt::DisplayRole) const;
+
+private:
+ QList<PluginIfType> m_pluginIfTypes;
+
+};
+
+class PluginIfTypeSortFilterProxyModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ PluginIfTypeSortFilterProxyModel(QObject * parent = 0);
+
+ bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
+
+ void setFilterElement(ext_toolbar_item_t filterType);
+
+private:
+ ext_toolbar_item_t m_filterType;
+};
+
+class PluginIFDemo_Main : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit PluginIFDemo_Main(QWidget *parent = 0);
+ ~PluginIFDemo_Main();
+
+ void setToolbar(ext_toolbar_t * &toolbar);
+
+private slots:
+ void on_buttonBox_clicked(QAbstractButton *button);
+ void on_btnSendButtonText_clicked();
+ void on_btnSendText_clicked();
+ void on_btnSendUpdateItem_clicked();
+ void on_chkTestCheckbox_stateChanged(int newState);
+ void on_tabInterfaceTypes_currentChanged(int newTab);
+ void on_btnAddItem_clicked();
+ void on_btnRemoveItem_clicked();
+ void on_btnSendList_clicked();
+ void on_cmbElements_currentTextChanged(const QString & newText);
+
+ void logChanged(QString message);
+ void closeDialog();
+
+private:
+ Ui::PluginIFDemo_Main *ui;
+
+ PluginIfTypeModel * sourceModel;
+ PluginIfTypeSortFilterProxyModel * proxyModel;
+ QStandardItemModel * listModel;
+ QStandardItemModel * indexModel;
+
+ ext_toolbar_t * _toolbar;
+};
+
+
+#endif /* PLUGINIFDEMO_MAIN_H_ */
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/plugins/pluginifdemo/ui/pluginifdemo_main.ui b/plugins/pluginifdemo/ui/pluginifdemo_main.ui
new file mode 100644
index 0000000000..0871ee8e81
--- /dev/null
+++ b/plugins/pluginifdemo/ui/pluginifdemo_main.ui
@@ -0,0 +1,315 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PluginIFDemo_Main</class>
+ <widget class="QDialog" name="PluginIFDemo_Main">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>500</width>
+ <height>570</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>500</width>
+ <height>570</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QTabWidget" name="tabInterfaceTypes">
+ <property name="currentIndex">
+ <number>3</number>
+ </property>
+ <widget class="QWidget" name="tabBoolean">
+ <attribute name="title">
+ <string>Boolean</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QCheckBox" name="chkTestCheckbox">
+ <property name="text">
+ <string>Check the value in the toolbar checkbox</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tabButton">
+ <attribute name="title">
+ <string>Button</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_7">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4" stretch="0,0">
+ <item>
+ <widget class="QLineEdit" name="txtButtonName">
+ <property name="placeholderText">
+ <string>Text to be sent to toolbar</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnSendButtonText">
+ <property name="text">
+ <string>Send Text</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tabString">
+ <attribute name="title">
+ <string>String</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0">
+ <item>
+ <widget class="QLineEdit" name="txtEdit">
+ <property name="placeholderText">
+ <string>Text to be sent to toolbar</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnSendText">
+ <property name="text">
+ <string>Send Text</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tabSelector">
+ <attribute name="title">
+ <string>Selector</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Display:</string>
+ </property>
+ <property name="buddy">
+ <cstring>txtNewItemDisplay</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="txtNewItemDisplay">
+ <property name="placeholderText">
+ <string>Enter display text</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Value:</string>
+ </property>
+ <property name="buddy">
+ <cstring>txtNewItemValue</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="txtNewItemValue">
+ <property name="placeholderText">
+ <string>Enter value text</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnAddItem">
+ <property name="text">
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QListView" name="lstItems"/>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QPushButton" name="btnRemoveItem">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnSendList">
+ <property name="text">
+ <string>Send List</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Update</string>
+ </property>
+ <property name="buddy">
+ <cstring>cmbEntryIndex</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="cmbEntryIndex"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>with</string>
+ </property>
+ <property name="buddy">
+ <cstring>txtUpdateDisplayValue</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="txtUpdateDisplayValue">
+ <property name="placeholderText">
+ <string>Enter value text</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnSendUpdateItem">
+ <property name="text">
+ <string>Send</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line">
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="lineWidth">
+ <number>1</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Element to be updated</string>
+ </property>
+ <property name="buddy">
+ <cstring>cmbElements</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="cmbElements"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="chkSilent">
+ <property name="text">
+ <string>Activate updates silently</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListView" name="logView"/>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/plugins/pluginifdemo/ui/uiclasshandler.cpp b/plugins/pluginifdemo/ui/uiclasshandler.cpp
new file mode 100644
index 0000000000..e88f17a35e
--- /dev/null
+++ b/plugins/pluginifdemo/ui/uiclasshandler.cpp
@@ -0,0 +1,128 @@
+/* uiclasshandler.cpp
+ *
+ * Author: Roland Knall <rknall@gmail.com>
+ *
+ * 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.
+ */
+
+#include <config.h>
+
+#include <glib.h>
+
+#include <QObject>
+#include <QApplication>
+#include <QMutex>
+
+#include <epan/plugin_if.h>
+
+#if defined(_WIN32)
+#define _WINSOCKAPI_
+#endif
+
+#include <ui/qt/main_window.h>
+
+#include <ui/uihandler.h>
+#include <ui/pluginifdemo_main.h>
+#include <ui/pluginifdemo_about.h>
+
+QMutex * GuiHandler::singletonMutex = new QMutex();
+
+GuiHandler::GuiHandler()
+{
+}
+
+GuiHandler * GuiHandler::getInstance()
+{
+ static GuiHandler * instance = 0;
+
+ QMutexLocker locker(singletonMutex);
+
+ if ( instance == 0 )
+ {
+ instance = new GuiHandler();
+ }
+
+ return instance;
+}
+
+void GuiHandler::showAboutDialog(ext_menubar_gui_type gui_type _U_, gpointer gui_data _U_)
+{
+ PluginIFDemo_About * mainwindow = new PluginIFDemo_About();
+ executeDialog((QDialog*)mainwindow);
+}
+
+void GuiHandler::showMainDialog(ext_menubar_gui_type gui_type _U_, gpointer gui_data _U_)
+{
+ PluginIFDemo_Main * mainwindow = new PluginIFDemo_Main();
+ mainwindow->setToolbar(_toolbar);
+ executeDialog((QDialog*)mainwindow);
+}
+
+void GuiHandler::executeDialog(QDialog * dialog)
+{
+ bool hasGuiApp = (qobject_cast<QApplication*>(QCoreApplication::instance())!=0);
+
+ if ( ! hasGuiApp )
+ {
+ /* Necessity for creating the correct app context */
+ int argc = 1;
+ char * argv = (char *) "Test";
+
+ /* In Gtk there is no application context, must be created and displayed */
+ QApplication app(argc, &argv);
+
+ dialog->show();
+
+ app.exec();
+ }
+ else
+ {
+ /* With Wireshark Qt, an application context already exists, therefore just
+ * displaying the dialog using show to have it non-modal */
+ dialog->show();
+ }
+}
+
+void GuiHandler::doReset()
+{
+ emit reset();
+}
+
+void GuiHandler::addLogMessage(QString message)
+{
+ emit logChanged(message);
+}
+
+void GuiHandler::setToolbar(ext_toolbar_t * toolbar)
+{
+ _toolbar = toolbar;
+}
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/plugins/pluginifdemo/ui/uihandler.cpp b/plugins/pluginifdemo/ui/uihandler.cpp
new file mode 100644
index 0000000000..8dc3940669
--- /dev/null
+++ b/plugins/pluginifdemo/ui/uihandler.cpp
@@ -0,0 +1,81 @@
+/* uihandler.cpp
+ * Author: Roland Knall <rknall@gmail.com>
+ *
+ * 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.
+ */
+
+#include <config.h>
+
+#include <glib.h>
+
+#include <QObject>
+#include <QApplication>
+
+#include <epan/plugin_if.h>
+#include <epan/tap.h>
+
+#if defined(_WIN32)
+#define _WINSOCKAPI_
+#endif
+
+#include <ui/qt/main_window.h>
+
+#include <ui/uihandler.h>
+
+static void
+reset_dialog(void *data _U_)
+{
+ GuiHandler::getInstance()->doReset();
+}
+
+void pluginifdemo_ui_main(ext_menubar_gui_type gui_type, gpointer gui_data)
+{
+ /* ensures, that the dialog is closing, if scm udid is set or a filter is applied */
+ register_tap_listener("frame", NULL, NULL, 0, reset_dialog, NULL, NULL );
+
+ GuiHandler::getInstance()->showMainDialog(gui_type, gui_data);
+}
+
+void pluginifdemo_ui_about(ext_menubar_gui_type gui_type, gpointer gui_data)
+{
+ GuiHandler::getInstance()->showAboutDialog(gui_type, gui_data);
+}
+
+void pluginifdemo_toolbar_log(const gchar * message)
+{
+ GuiHandler::getInstance()->addLogMessage(QString(message));
+}
+
+void pluginifdemo_toolbar_register(ext_toolbar_t * toolbar)
+{
+ GuiHandler::getInstance()->setToolbar(toolbar);
+}
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/plugins/pluginifdemo/ui/uihandler.h b/plugins/pluginifdemo/ui/uihandler.h
new file mode 100644
index 0000000000..ce78a23940
--- /dev/null
+++ b/plugins/pluginifdemo/ui/uihandler.h
@@ -0,0 +1,101 @@
+/* uihandler.h
+ * Author: Roland Knall <rknall@gmail.com>
+ *
+ * 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 PLUGINIFDEMO_UI_UIHANDLER_H_
+#define PLUGINIFDEMO_UI_UIHANDLER_H_
+
+#ifdef __cplusplus
+
+#include <QObject>
+#include <QDialog>
+#include <QMutex>
+
+#include <epan/plugin_if.h>
+
+#include "ws_symbol_export.h"
+
+class WS_DLL_PUBLIC_DEF GuiHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ static GuiHandler * getInstance();
+
+ void showAboutDialog(ext_menubar_gui_type gui_type, gpointer gui_data);
+ void showMainDialog(ext_menubar_gui_type gui_type, gpointer gui_data);
+
+ void doReset();
+
+ void addLogMessage(QString message);
+
+ void setToolbar(ext_toolbar_t * toolbar);
+ ext_toolbar_t * toolBar();
+
+signals:
+ void reset();
+ void logChanged(QString newEntry);
+
+protected:
+
+ GuiHandler();
+
+ // Stop the compiler generating methods of "copy the object"
+ GuiHandler(GuiHandler const& copy); // Not implemented
+ GuiHandler& operator=(GuiHandler const& copy); // Not implemented
+
+private:
+
+ static QMutex * singletonMutex;
+
+ ext_toolbar_t * _toolbar;
+
+ void executeDialog(QDialog * object);
+};
+
+extern "C" {
+#endif
+
+extern void pluginifdemo_ui_about(ext_menubar_gui_type gui_type, gpointer gui_data);
+extern void pluginifdemo_ui_main(ext_menubar_gui_type gui_type, gpointer gui_data);
+extern void pluginifdemo_toolbar_log(const gchar * message);
+
+extern void pluginifdemo_toolbar_register(ext_toolbar_t * toolbar);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BURANALYZER_UI_UIHANDLER_H_ */
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt
index 2eb0b43beb..f70606e1a4 100644
--- a/ui/qt/CMakeLists.txt
+++ b/ui/qt/CMakeLists.txt
@@ -27,6 +27,7 @@ set(WIRESHARK_QT_HEADERS
about_dialog.h
accordion_frame.h
address_editor_frame.h
+ apply_line_edit.h
bluetooth_att_server_attributes_dialog.h
bluetooth_device_dialog.h
bluetooth_devices_dialog.h
@@ -84,6 +85,7 @@ set(WIRESHARK_QT_HEADERS
gsm_map_summary_dialog.h
iax2_analysis_dialog.h
import_text_dialog.h
+ additional_toolbar.h
interface_tree_model.h
interface_tree_cache_model.h
interface_sort_filter_model.h
@@ -198,6 +200,7 @@ set(WIRESHARK_QT_SRC
about_dialog.cpp
accordion_frame.cpp
address_editor_frame.cpp
+ apply_line_edit.cpp
bluetooth_att_server_attributes_dialog.cpp
bluetooth_device_dialog.cpp
bluetooth_devices_dialog.cpp
@@ -250,6 +253,7 @@ set(WIRESHARK_QT_SRC
geometry_state_dialog.cpp
iax2_analysis_dialog.cpp
import_text_dialog.cpp
+ additional_toolbar.cpp
interface_tree_model.cpp
interface_tree_cache_model.cpp
interface_sort_filter_model.cpp
diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am
index b199e7ff3d..eb1d77e7a4 100644
--- a/ui/qt/Makefile.am
+++ b/ui/qt/Makefile.am
@@ -156,6 +156,7 @@ MOC_HDRS = \
about_dialog.h \
accordion_frame.h \
address_editor_frame.h \
+ apply_line_edit.h \
bluetooth_att_server_attributes_dialog.h \
bluetooth_device_dialog.h \
bluetooth_devices_dialog.h \
@@ -212,6 +213,7 @@ MOC_HDRS = \
iax2_analysis_dialog.h \
import_text_dialog.h \
interface_frame.h \
+ additional_toolbar.h \
interface_tree_model.h \
interface_tree_cache_model.h \
interface_sort_filter_model.h \
@@ -439,6 +441,7 @@ WIRESHARK_QT_SRC = \
about_dialog.cpp \
accordion_frame.cpp \
address_editor_frame.cpp \
+ apply_line_edit.cpp \
bluetooth_att_server_attributes_dialog.cpp \
bluetooth_device_dialog.cpp \
bluetooth_devices_dialog.cpp \
@@ -492,6 +495,7 @@ WIRESHARK_QT_SRC = \
iax2_analysis_dialog.cpp \
import_text_dialog.cpp \
interface_frame.cpp \
+ additional_toolbar.cpp \
interface_tree_model.cpp \
interface_tree_cache_model.cpp \
interface_sort_filter_model.cpp \
diff --git a/ui/qt/additional_toolbar.cpp b/ui/qt/additional_toolbar.cpp
new file mode 100644
index 0000000000..5192fb5312
--- /dev/null
+++ b/ui/qt/additional_toolbar.cpp
@@ -0,0 +1,537 @@
+/* additional_toolbar.cpp
+ *
+ * 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.
+ */
+
+#include <additional_toolbar.h>
+#include <config.h>
+
+#include <glib.h>
+
+#include <ui/qt/apply_line_edit.h>
+#include <ui/qt/qt_ui_utils.h>
+#include <ui/qt/variant_pointer.h>
+#include <ui/qt/wireshark_application.h>
+
+#include <QLabel>
+#include <QLineEdit>
+#include <QHBoxLayout>
+#include <QComboBox>
+#include <QWidget>
+#include <QCheckBox>
+#include <QPushButton>
+#include <QStandardItem>
+#include <QStandardItemModel>
+#include <QLayoutItem>
+
+const char * AdditionalToolbarWidgetAction::propertyName = "additional_toolbar_item";
+
+AdditionalToolBar::AdditionalToolBar(ext_toolbar_t * exttoolbar, QWidget * parent)
+: QToolBar(parent),
+ toolbar(exttoolbar)
+{ }
+
+AdditionalToolBar::~AdditionalToolBar()
+{ }
+
+AdditionalToolBar * AdditionalToolBar::create(QWidget * parent, ext_toolbar_t * toolbar)
+{
+ if ( g_list_length( toolbar->children ) == 0 )
+ return NULL;
+
+ AdditionalToolBar * result = new AdditionalToolBar(toolbar, parent);
+ result->setMovable(false);
+ result->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
+ result->layout()->setMargin(0);
+ result->layout()->setSpacing(4);
+
+ GList * walker = toolbar->children;
+ bool spacerNeeded = true;
+
+ while ( walker && walker->data )
+ {
+ ext_toolbar_t * item = (ext_toolbar_t *)walker->data;
+ if ( item->type == EXT_TOOLBAR_ITEM )
+ {
+ if ( item->item_type == EXT_TOOLBAR_STRING )
+ spacerNeeded = false;
+
+ QAction * newAction = new AdditionalToolbarWidgetAction(item, result);
+ if ( newAction )
+ {
+ result->addAction(newAction);
+ /* Necessary, because enable state is resetted upon adding the action */
+ result->actions()[result->actions().count() - 1]->setEnabled(!item->capture_only);
+ }
+ }
+
+ walker = g_list_next ( walker );
+ }
+
+ if ( result->children().count() == 0 )
+ return NULL;
+
+ if ( spacerNeeded )
+ {
+ QWidget * empty = new QWidget();
+ empty->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred);
+ result->addWidget(empty);
+
+ }
+
+ return result;
+}
+
+QString AdditionalToolBar::menuName()
+{
+ return (toolbar && toolbar->name) ? QString(toolbar->name) : QString();
+}
+
+AdditionalToolbarWidgetAction::AdditionalToolbarWidgetAction(QObject * parent)
+: QWidgetAction(parent),
+ toolbar_item(0)
+{ }
+
+AdditionalToolbarWidgetAction::AdditionalToolbarWidgetAction(ext_toolbar_t * item, QObject * parent)
+: QWidgetAction(parent),
+ toolbar_item(item)
+{
+ connect(wsApp, SIGNAL(captureActive(int)), this, SLOT(captureActive(int)));
+}
+
+AdditionalToolbarWidgetAction::AdditionalToolbarWidgetAction(const AdditionalToolbarWidgetAction & copy_object)
+: QWidgetAction(copy_object.parent()),
+ toolbar_item(copy_object.toolbar_item)
+{
+ connect(wsApp, SIGNAL(captureActive(int)), this, SLOT(captureActive(int)));
+}
+
+
+void AdditionalToolbarWidgetAction::captureActive(int activeCaptures)
+{
+ if ( toolbar_item && toolbar_item->capture_only )
+ {
+ setEnabled(activeCaptures != 0);
+ }
+}
+
+/* Exists, so a default deconstructor does not call delete on toolbar_item */
+AdditionalToolbarWidgetAction::~AdditionalToolbarWidgetAction() { }
+
+QWidget * AdditionalToolbarWidgetAction::createWidget(QWidget * parent)
+{
+ QWidget * barItem = 0;
+
+ if ( toolbar_item->type != EXT_TOOLBAR_ITEM )
+ return barItem;
+
+ switch ( toolbar_item->item_type )
+ {
+ case EXT_TOOLBAR_BUTTON:
+ barItem = createButton(toolbar_item, parent);
+ break;
+ case EXT_TOOLBAR_BOOLEAN:
+ barItem = createBoolean(toolbar_item, parent);
+ break;
+ case EXT_TOOLBAR_STRING:
+ barItem = createTextEditor(toolbar_item, parent);
+ break;
+ case EXT_TOOLBAR_SELECTOR:
+ barItem = createSelector(toolbar_item, parent);
+ break;
+ }
+
+ if ( ! barItem )
+ return 0;
+
+ barItem->setToolTip(toolbar_item->tooltip);
+ barItem->setProperty(propertyName, VariantPointer<ext_toolbar_t>::asQVariant(toolbar_item));
+
+#ifdef Q_OS_MAC
+ barItem->setAttribute(Qt::WA_MacSmallSize, true);
+#endif
+
+ return barItem;
+}
+
+static void
+toolbar_button_cb(gpointer item, gpointer item_data, gpointer user_data)
+{
+ if ( ! item || ! item_data || ! user_data )
+ return;
+
+ QPushButton * widget = (QPushButton *)(item_data);
+ ext_toolbar_update_t * update_entry = (ext_toolbar_update_t *)user_data;
+
+ if ( widget && update_entry->type == EXT_TOOLBAR_UPDATE_VALUE )
+ widget->setText((gchar *)update_entry->user_data);
+}
+
+QWidget * AdditionalToolbarWidgetAction::createButton(ext_toolbar_t * item, QWidget * parent)
+{
+ if ( ! item || item->type != EXT_TOOLBAR_ITEM || item->item_type != EXT_TOOLBAR_BUTTON )
+ return 0;
+
+ QString defValue = item->defvalue;
+
+ QPushButton * button = new QPushButton(item->name, parent);
+ button->setText(item->name);
+ connect(button, SIGNAL(clicked()), this, SLOT(onButtonClicked()));
+
+ ext_toolbar_register_update_cb(item, (ext_toolbar_action_cb)&toolbar_button_cb, (void *)button);
+
+ return button;
+}
+
+static void
+toolbar_boolean_cb(gpointer item, gpointer item_data, gpointer user_data)
+{
+ if ( ! item || ! item_data || ! user_data )
+ return;
+
+ QCheckBox * widget = (QCheckBox *)(item_data);
+ ext_toolbar_update_t * update_entry = (ext_toolbar_update_t *)user_data;
+
+ if ( widget && update_entry->type == EXT_TOOLBAR_UPDATE_VALUE )
+ {
+ bool oldState = false;
+ if ( update_entry->silent )
+ oldState = widget->blockSignals(true);
+
+ widget->setCheckState(GPOINTER_TO_INT(update_entry->user_data) == 1 ? Qt::Checked : Qt::Unchecked);
+
+ if ( update_entry->silent )
+ widget->blockSignals(oldState);
+ }
+}
+
+QWidget * AdditionalToolbarWidgetAction::createBoolean(ext_toolbar_t * item, QWidget * parent)
+{
+ if ( ! item || item->type != EXT_TOOLBAR_ITEM || item->item_type != EXT_TOOLBAR_BOOLEAN )
+ return 0;
+
+ QString defValue = toolbar_item->defvalue;
+
+ QCheckBox * checkbox = new QCheckBox(item->name, parent);
+ checkbox->setText(item->name);
+ setCheckable(true);
+ checkbox->setCheckState(defValue.compare("true", Qt::CaseInsensitive) == 0 ? Qt::Checked : Qt::Unchecked);
+ connect(checkbox, SIGNAL(stateChanged(int)), this, SLOT(onCheckBoxChecked(int)));
+
+ ext_toolbar_register_update_cb(item, (ext_toolbar_action_cb)&toolbar_boolean_cb, (void *)checkbox);
+
+ return checkbox;
+}
+
+QWidget * AdditionalToolbarWidgetAction::createLabelFrame(ext_toolbar_t * item, QWidget * parent)
+{
+ if ( ! item )
+ return new QWidget();
+
+ QWidget * frame = new QWidget(parent);
+
+ QHBoxLayout * frameLayout = new QHBoxLayout(frame);
+ frameLayout->setMargin(0);
+ frameLayout->setSpacing(0);
+
+ QLabel * strLabel = new QLabel(item->name, frame);
+ strLabel->setToolTip(item->tooltip);
+
+#ifdef Q_OS_MAC
+ frame->setAttribute(Qt::WA_MacSmallSize, true);
+ strLabel->setAttribute(Qt::WA_MacSmallSize, true);
+#endif
+
+ frameLayout->addWidget(strLabel);
+
+ frame->setLayout(frameLayout);
+
+ return frame;
+}
+
+static void
+toolbar_string_cb(gpointer item, gpointer item_data, gpointer user_data)
+{
+ if ( ! item || ! item_data || ! user_data )
+ return;
+
+ ApplyLineEdit * edit = (ApplyLineEdit *)(item_data);
+ ext_toolbar_update_t * update_entry = (ext_toolbar_update_t *)user_data;
+
+ if ( edit && update_entry->type == EXT_TOOLBAR_UPDATE_VALUE )
+ {
+ bool oldState = false;
+ if ( update_entry->silent )
+ oldState = edit->blockSignals(true);
+
+ edit->setText((gchar *)update_entry->user_data);
+
+ if ( update_entry->silent )
+ edit->blockSignals(oldState);
+ }
+}
+
+QWidget * AdditionalToolbarWidgetAction::createTextEditor(ext_toolbar_t * item, QWidget * parent)
+{
+ if ( ! item || item->type != EXT_TOOLBAR_ITEM || item->item_type != EXT_TOOLBAR_STRING )
+ return 0;
+
+ QWidget * frame = createLabelFrame(toolbar_item, parent);
+
+ ApplyLineEdit * strEdit = new ApplyLineEdit(toolbar_item->defvalue, frame);
+ strEdit->setToolTip(toolbar_item->tooltip);
+ strEdit->setRegEx(toolbar_item->regex);
+ strEdit->setEmptyAllowed(toolbar_item->is_required);
+ strEdit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
+
+#ifdef Q_OS_MAC
+ strEdit->setAttribute(Qt::WA_MacSmallSize, true);
+#endif
+
+ frame->layout()->addWidget(strEdit);
+
+ connect(strEdit, SIGNAL(textApplied()), this, SLOT(sendTextToCallback()));
+
+ ext_toolbar_register_update_cb(item, (ext_toolbar_action_cb)&toolbar_string_cb, (void *)strEdit);
+
+ return frame;
+}
+
+static void
+toolbar_selector_cb(gpointer item, gpointer item_data, gpointer user_data)
+{
+ if ( ! item || ! item_data || ! user_data )
+ return;
+
+ QComboBox * comboBox = (QComboBox *)(item_data);
+ ext_toolbar_update_t * update_entry = (ext_toolbar_update_t *)user_data;
+
+ bool oldState = false;
+
+ if ( update_entry->silent )
+ oldState = comboBox->blockSignals(true);
+
+ if ( update_entry->type == EXT_TOOLBAR_UPDATE_VALUE )
+ {
+ QString data = QString((gchar *)update_entry->user_data);
+ bool conv_ok = false;
+
+ int dataValue = data.toInt(&conv_ok, 10);
+ if ( conv_ok && dataValue >= 0 && comboBox->model()->rowCount() < dataValue )
+ comboBox->setCurrentIndex(dataValue);
+ else
+ comboBox->setCurrentText(data);
+ }
+ else if ( update_entry->type == EXT_TOOLBAR_UPDATE_DATA )
+ {
+ QStandardItemModel * sourceModel = (QStandardItemModel *)comboBox->model();
+
+ GList * walker = (GList *)update_entry->user_data;
+ if ( g_list_length(walker) == 0 )
+ return;
+
+ sourceModel->clear();
+
+ while ( walker && walker->data )
+ {
+ ext_toolbar_value_t * listvalue = (ext_toolbar_value_t *)walker->data;
+
+ QStandardItem * si = new QStandardItem(listvalue->display);
+ si->setData(VariantPointer<ext_toolbar_value_t>::asQVariant(listvalue), Qt::UserRole);
+ sourceModel->appendRow(si);
+
+ walker = g_list_next(walker);
+ }
+ }
+ else if ( update_entry->type == EXT_TOOLBAR_UPDATE_DATABYINDEX )
+ {
+ QStandardItemModel * sourceModel = (QStandardItemModel *)comboBox->model();
+
+ if ( ! update_entry->user_data || ! update_entry->data_index )
+ return;
+
+ gchar * idx = (gchar *)update_entry->data_index;
+ gchar * display = (gchar *)update_entry->user_data;
+
+ for ( int i = 0; i < sourceModel->rowCount(); i++ )
+ {
+ QStandardItem * item = sourceModel->item(i, 0);
+ ext_toolbar_value_t * entry = VariantPointer<ext_toolbar_value_t>::asPtr(item->data(Qt::UserRole));
+ if ( entry && g_strcmp0( entry->value, idx) == 0 )
+ {
+ item->setText(display);
+ break;
+ }
+ }
+ }
+
+ if ( update_entry->silent )
+ comboBox->blockSignals(oldState);
+
+}
+
+QWidget * AdditionalToolbarWidgetAction::createSelector(ext_toolbar_t * item, QWidget * parent)
+{
+ if ( ! item || item->type != EXT_TOOLBAR_ITEM || item->item_type != EXT_TOOLBAR_SELECTOR )
+ return 0;
+
+ if ( g_list_length(item->values) == 0 )
+ return 0;
+
+ QWidget * frame = createLabelFrame(item, parent);
+
+ QComboBox * myBox = new QComboBox(parent);
+ myBox->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+
+ QStandardItemModel * sourceModel = new QStandardItemModel();
+
+ GList * walker = item->values;
+ int selIndex = 0;
+ while ( walker && walker->data )
+ {
+ ext_toolbar_value_t * listvalue = (ext_toolbar_value_t *)walker->data;
+
+ QStandardItem * si = new QStandardItem(listvalue->display);
+ si->setData(VariantPointer<ext_toolbar_value_t>::asQVariant(listvalue), Qt::UserRole);
+ sourceModel->appendRow(si);
+
+ if ( listvalue->is_default )
+ selIndex = sourceModel->rowCount();
+
+ walker = g_list_next(walker);
+ }
+
+ myBox->setModel(sourceModel);
+ myBox->setCurrentIndex(selIndex);
+
+#ifdef Q_OS_MAC
+ myBox->setAttribute(Qt::WA_MacSmallSize, true);
+#endif
+
+ frame->layout()->addWidget(myBox);
+
+ connect(myBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onSelectionInWidgetChanged(int)));
+
+ ext_toolbar_register_update_cb(item, (ext_toolbar_action_cb)&toolbar_selector_cb, (void *)myBox);
+
+ return frame;
+}
+
+ext_toolbar_t * AdditionalToolbarWidgetAction::extractToolbarItemFromObject(QObject * object)
+{
+ QWidget * widget = dynamic_cast<QWidget *>(object);
+ if ( ! widget )
+ return 0;
+
+ QVariant propValue = widget->property(propertyName);
+
+ /* If property is invalid, look if our parent has this property */
+ if ( ! propValue.isValid() )
+ {
+ QWidget * frame = dynamic_cast<QWidget *>(widget->parent());
+ if ( ! frame )
+ return 0;
+
+ propValue = frame->property(propertyName);
+ }
+
+ if ( ! propValue.isValid() )
+ return 0;
+
+ return VariantPointer<ext_toolbar_t>::asPtr(propValue);
+}
+
+void AdditionalToolbarWidgetAction::onButtonClicked()
+{
+ ext_toolbar_t * item = extractToolbarItemFromObject(sender());
+ if ( ! item )
+ return;
+
+ item->callback(item, 0, item->user_data);
+}
+
+void AdditionalToolbarWidgetAction::onCheckBoxChecked(int checkState)
+{
+ ext_toolbar_t * item = extractToolbarItemFromObject(sender());
+ if ( ! item )
+ return;
+
+ gboolean value = checkState == Qt::Checked ? true : false;
+
+ item->callback(item, &value, item->user_data);
+}
+
+void AdditionalToolbarWidgetAction::sendTextToCallback()
+{
+ ext_toolbar_t * item = extractToolbarItemFromObject(sender());
+ if ( ! item )
+ return;
+
+ if (item->item_type != EXT_TOOLBAR_STRING )
+ return;
+
+ ApplyLineEdit * editor = dynamic_cast<ApplyLineEdit *>(sender());
+ if ( ! editor )
+ {
+ /* Called from button, searching for acompanying line edit */
+ QWidget * parent = dynamic_cast<QWidget *>(sender()->parent());
+ if ( parent )
+ {
+ QList<ApplyLineEdit *> children = parent->findChildren<ApplyLineEdit *>();
+ if ( children.count() >= 0 )
+ editor = children.at(0);
+ }
+ }
+
+ if ( editor )
+ item->callback(item, qstring_strdup(editor->text()), item->user_data);
+}
+
+void AdditionalToolbarWidgetAction::onSelectionInWidgetChanged(int idx)
+{
+ QComboBox * editor = dynamic_cast<QComboBox *>(sender());
+ ext_toolbar_t * item = extractToolbarItemFromObject(editor);
+ if ( ! item || item->item_type != EXT_TOOLBAR_SELECTOR )
+ return;
+
+ QStandardItemModel * sourceModel = (QStandardItemModel *) editor->model();
+ if ( sourceModel->rowCount() <= idx )
+ return;
+
+ QModelIndex mdIdx = sourceModel->index(idx, 0);
+ QVariant dataSet = sourceModel->data(mdIdx, Qt::UserRole);
+ if ( dataSet.isValid() )
+ {
+ ext_toolbar_value_t * value_entry = VariantPointer<ext_toolbar_value_t>::asPtr(dataSet);
+ item->callback(item, value_entry, item->user_data);
+ }
+}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/additional_toolbar.h b/ui/qt/additional_toolbar.h
new file mode 100644
index 0000000000..b5b274945e
--- /dev/null
+++ b/ui/qt/additional_toolbar.h
@@ -0,0 +1,101 @@
+/* additional_toolbar.h
+ *
+ * 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 UI_QT_ADDITIONAL_TOOLBAR_H_
+#define UI_QT_ADDITIONAL_TOOLBAR_H_
+
+#include <epan/plugin_if.h>
+
+#include <QToolBar>
+#include <QWidgetAction>
+
+/* Class for all display widgets.
+ *
+ * Inherits QWidgetAction, otherwise the extension popup might not work for the toolbar
+ */
+class AdditionalToolbarWidgetAction: public QWidgetAction
+{
+ Q_OBJECT
+
+public:
+
+ AdditionalToolbarWidgetAction(QObject * parent = 0);
+ AdditionalToolbarWidgetAction(ext_toolbar_t * item, QObject * parent = 0);
+ AdditionalToolbarWidgetAction(const AdditionalToolbarWidgetAction & copy_object);
+ ~AdditionalToolbarWidgetAction();
+
+protected:
+ virtual QWidget * createWidget(QWidget * parent);
+
+ static const char * propertyName;
+
+private:
+
+ ext_toolbar_t * toolbar_item;
+
+ QWidget * createButton(ext_toolbar_t * item, QWidget * parent);
+ QWidget * createBoolean(ext_toolbar_t * item, QWidget * parent);
+ QWidget * createTextEditor(ext_toolbar_t * item, QWidget * parent);
+ QWidget * createSelector(ext_toolbar_t * item, QWidget * parent);
+
+ QWidget * createLabelFrame(ext_toolbar_t * item, QWidget * parent);
+
+ ext_toolbar_t * extractToolbarItemFromObject(QObject *);
+
+private slots:
+ void onButtonClicked();
+ void onCheckBoxChecked(int);
+ void sendTextToCallback();
+ void onSelectionInWidgetChanged(int idx);
+
+ void captureActive(int);
+};
+
+class AdditionalToolBar: public QToolBar
+{
+ Q_OBJECT
+
+public:
+ AdditionalToolBar(ext_toolbar_t * toolbar, QWidget * parent = 0);
+ virtual ~AdditionalToolBar();
+
+ static AdditionalToolBar * create(QWidget * parent, ext_toolbar_t * toolbar);
+
+ QString menuName();
+
+private:
+ ext_toolbar_t * toolbar;
+};
+
+#endif /* UI_QT_ADDITIONAL_TOOLBAR_H_ */
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/apply_line_edit.cpp b/ui/qt/apply_line_edit.cpp
new file mode 100644
index 0000000000..2e2acc7454
--- /dev/null
+++ b/ui/qt/apply_line_edit.cpp
@@ -0,0 +1,181 @@
+/* apply_lineedit.cpp
+ *
+ * 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.
+ */
+
+#include <ui/qt/apply_line_edit.h>
+
+#include <epan/prefs.h>
+
+#include <ui/qt/color_utils.h>
+
+#include <QRegExp>
+#include <QRegExpValidator>
+#include <QStyle>
+
+ApplyLineEdit::ApplyLineEdit(QString linePlaceholderText, QWidget * parent)
+: QLineEdit(parent),
+ applyButton(0)
+{
+ emptyAllowed_ = false;
+ regex_ = QString();
+
+ applyButton = new StockIconToolButton(parent, "x-filter-apply");
+ applyButton->setCursor(Qt::ArrowCursor);
+ applyButton->setEnabled(false);
+ applyButton->setToolTip(tr("Apply changes"));
+ applyButton->setIconSize(QSize(24, 14));
+ applyButton->setMaximumWidth(30);
+ applyButton->setStyleSheet(
+ "QToolButton {"
+ " border: none;"
+ " background: transparent;" // Disables platform style on Windows.
+ " padding: 0 0 0 0;"
+ "}"
+ );
+
+#ifdef Q_OS_MAC
+ setAttribute(Qt::WA_MacSmallSize, true);
+ applyButton->setAttribute(Qt::WA_MacSmallSize, true);
+#endif
+
+ setPlaceholderText(linePlaceholderText);
+
+ connect(this, SIGNAL(textEdited(const QString&)), this, SLOT(onTextEdited(const QString&)));
+ connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(onTextChanged(const QString&)));
+
+ connect(this, SIGNAL(returnPressed()), this, SLOT(onSubmitContent()));
+ connect(applyButton, SIGNAL(clicked()), this, SLOT(onSubmitContent()));
+
+ handleValidation(QString(linePlaceholderText));
+
+ setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
+}
+
+ApplyLineEdit::~ApplyLineEdit() {}
+
+void ApplyLineEdit::setRegEx(QString regex)
+{
+ regex_ = regex;
+}
+
+QString ApplyLineEdit::regex()
+{
+ return regex_;
+}
+
+void ApplyLineEdit::setEmptyAllowed(bool emptyAllowed)
+{
+ emptyAllowed_ = emptyAllowed;
+}
+
+bool ApplyLineEdit::emptyAllowed()
+{
+ return emptyAllowed_;
+}
+
+bool ApplyLineEdit::isValidText(QString & text, bool ignoreEmptyCheck)
+{
+ if ( text.length() == 0 )
+ {
+ if ( ! ignoreEmptyCheck && ! emptyAllowed_ )
+ return false;
+ else if ( ignoreEmptyCheck )
+ return true;
+ }
+
+ if ( regex_.length() > 0 )
+ {
+ QRegExp rx ( regex_ );
+ QRegExpValidator v(rx, 0);
+
+ int pos = 0;
+ if ( ! rx.isValid() || v.validate(text, pos) != QValidator::Acceptable )
+ return false;
+ }
+
+ return true;
+}
+
+void ApplyLineEdit::onTextEdited(const QString & text)
+{
+ QString newText = QString(text);
+ applyButton->setEnabled(isValidText(newText));
+ handleValidation(newText);
+}
+
+void ApplyLineEdit::onTextChanged(const QString & text)
+{
+ handleValidation(QString(text));
+}
+
+void ApplyLineEdit::handleValidation(QString newText)
+{
+ int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
+
+ QString style_sheet = QString(
+ "ApplyLineEdit {"
+ " padding-left: %1px;"
+ " padding-right: %2px;"
+ " background-color: %3;"
+ "}"
+ )
+ .arg(frameWidth + 1)
+ .arg(applyButton->sizeHint().width() + frameWidth)
+ .arg(isValidText(newText, true) ? QString("") : ColorUtils::fromColorT(prefs.gui_text_invalid).name());
+
+ setStyleSheet(style_sheet);
+}
+
+void ApplyLineEdit::resizeEvent(QResizeEvent *)
+{
+ int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
+ QSize apsz = applyButton->sizeHint();
+
+ applyButton->move((contentsRect().right() + pos().x()) - ( frameWidth + apsz.width() ) - 2,
+ contentsRect().top() + pos().y());
+
+ applyButton->setMinimumHeight(height());
+ applyButton->setMaximumHeight(height());
+}
+
+void ApplyLineEdit::onSubmitContent()
+{
+ QString data = text();
+ if ( ! isValidText(data) )
+ return;
+
+ /* Freeze apply button to signal the text has been sent. Will be unfreezed, if the text in the textbox changes again */
+ applyButton->setEnabled(false);
+
+ emit textApplied();
+}
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/apply_line_edit.h b/ui/qt/apply_line_edit.h
new file mode 100644
index 0000000000..d26b514f68
--- /dev/null
+++ b/ui/qt/apply_line_edit.h
@@ -0,0 +1,82 @@
+/* apply_lineedit.h
+ *
+ * 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 UI_QT_APPLY_LINE_EDIT_H_
+#define UI_QT_APPLY_LINE_EDIT_H_
+
+#include <QLineEdit>
+#include <QString>
+
+#include <ui/qt/stock_icon_tool_button.h>
+
+class ApplyLineEdit : public QLineEdit
+{
+ Q_OBJECT
+
+public:
+ explicit ApplyLineEdit(QString linePlaceholderText, QWidget *parent = 0);
+ ~ApplyLineEdit();
+
+ Q_PROPERTY(QString regex READ regex WRITE setRegEx);
+ Q_PROPERTY(bool emptyAllowed READ emptyAllowed WRITE setEmptyAllowed);
+
+ QString regex();
+ void setRegEx(QString);
+
+ bool emptyAllowed();
+ void setEmptyAllowed(bool);
+
+signals:
+ void textApplied();
+
+protected:
+ void resizeEvent(QResizeEvent *);
+
+private:
+
+ QString regex_;
+ bool emptyAllowed_;
+
+ StockIconToolButton *applyButton;
+
+ bool isValidText(QString &, bool ignoreEmptyCheck = false);
+ void handleValidation(QString newText);
+
+private slots:
+ void onTextEdited(const QString &);
+ void onTextChanged(const QString &);
+ void onSubmitContent();
+};
+
+#endif /* UI_QT_APPLY_LINE_EDIT_H_ */
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp
index 45479df68d..6573a7c6f6 100644
--- a/ui/qt/main_window.cpp
+++ b/ui/qt/main_window.cpp
@@ -69,6 +69,9 @@
#include "wireless_frame.h"
#include "wireshark_application.h"
+#include "additional_toolbar.h"
+#include "variant_pointer.h"
+
#include "qt_ui_utils.h"
#include <QAction>
@@ -193,6 +196,18 @@ static void plugin_if_mainwindow_get_ws_info(gconstpointer user_data)
#endif /* HAVE_LIBPCAP */
+static void plugin_if_mainwindow_update_toolbars(gconstpointer user_data)
+{
+ if (!gbl_cur_main_window_ || ! user_data)
+ return;
+
+ GHashTable * data_set = (GHashTable *)user_data;
+ if (g_hash_table_lookup_extended(data_set, "toolbar_name", NULL, NULL)) {
+ QString toolbarName((const char *)g_hash_table_lookup(data_set, "toolbar_name"));
+ gbl_cur_main_window_->removeAdditionalToolbar(toolbarName);
+ }
+}
+
gpointer
simple_dialog(ESD_TYPE_E type, gint btn_mask, const gchar *msg_format, ...)
{
@@ -350,7 +365,7 @@ MainWindow::MainWindow(QWidget *parent) :
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(initViewColorizeMenu()));
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(addStatsPluginsToMenu()));
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(addDynamicMenus()));
- connect(wsApp, SIGNAL(appInitialized()), this, SLOT(addExternalMenus()));
+ connect(wsApp, SIGNAL(appInitialized()), this, SLOT(addPluginIFStructures()));
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(initConversationMenus()));
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(initExportObjectsMenus()));
@@ -722,6 +737,7 @@ MainWindow::MainWindow(QWidget *parent) :
#ifdef HAVE_LIBPCAP
plugin_if_register_gui_cb(PLUGIN_IF_GET_WS_INFO, plugin_if_mainwindow_get_ws_info);
#endif
+ plugin_if_register_gui_cb(PLUGIN_IF_REMOVE_TOOLBAR, plugin_if_mainwindow_update_toolbars);
main_ui_->mainStack->setCurrentWidget(main_welcome_);
}
@@ -742,7 +758,17 @@ QMenu *MainWindow::createPopupMenu()
menu->addAction(main_ui_->actionViewMainToolbar);
menu->addAction(main_ui_->actionViewFilterToolbar);
menu->addAction(main_ui_->actionViewWirelessToolbar);
+
+ if ( ! main_ui_->actionViewAdditionalToolbars->actions().isEmpty() )
+ {
+ QMenu * subMenu = menu->addMenu(main_ui_->actionViewAdditionalToolbars->title());
+ foreach ( QAction * action, main_ui_->actionViewAdditionalToolbars->actions() )
+ subMenu->addAction(action);
+
+ }
+
menu->addAction(main_ui_->actionViewStatusBar);
+
menu->addSeparator();
menu->addAction(main_ui_->actionViewPacketList);
menu->addAction(main_ui_->actionViewPacketDetails);
@@ -1845,6 +1871,9 @@ void MainWindow::initShowHideMainWidgets()
showHideMainWidgets(shmwa);
}
+ /* Initially hide the additional toolbars menus */
+ main_ui_->actionViewAdditionalToolbars->menuAction()->setVisible(false);
+
connect(show_hide_actions_, SIGNAL(triggered(QAction*)), this, SLOT(showHideMainWidgets(QAction*)));
}
@@ -2554,16 +2583,13 @@ QMenu * MainWindow::searchSubMenu(QString objectName)
return 0;
}
-void MainWindow::addExternalMenus()
+void MainWindow::addPluginIFStructures()
{
- QMenu * subMenu = NULL;
- GList * user_menu = NULL;
- ext_menu_t * menu = NULL;
-
- user_menu = ext_menubar_get_entries();
+ GList * user_menu = ext_menubar_get_entries();
while (user_menu && user_menu->data) {
- menu = (ext_menu_t *) user_menu->data;
+ QMenu * subMenu = NULL;
+ ext_menu_t * menu = (ext_menu_t *) user_menu->data;
/* On this level only menu items should exist. Not doing an assert here,
* as it could be an honest mistake */
@@ -2589,8 +2615,99 @@ void MainWindow::addExternalMenus()
/* Iterate Loop */
user_menu = g_list_next (user_menu);
}
+
+ int cntToolbars = 0;
+
+ QMenu * tbMenu = main_ui_->actionViewAdditionalToolbars;
+ GList * if_toolbars = ext_toolbar_get_entries();
+ while ( if_toolbars && if_toolbars->data ) {
+
+ ext_toolbar_t * toolbar = (ext_toolbar_t*) if_toolbars->data;
+
+ if ( toolbar->type != EXT_TOOLBAR_BAR) {
+ if_toolbars = g_list_next ( if_toolbars );
+ continue;
+ }
+
+ bool visible = g_list_find_custom(recent.gui_additional_toolbars, toolbar->name, (GCompareFunc) strcmp) ? true : false;
+
+ AdditionalToolBar * ifToolBar = AdditionalToolBar::create(this, toolbar);
+ ifToolBar->setVisible(visible);
+
+ if ( ifToolBar )
+ {
+
+ QAction * iftbAction = new QAction(QString(toolbar->name), this);
+ iftbAction->setToolTip(toolbar->tooltip);
+ iftbAction->setEnabled(true);
+ iftbAction->setCheckable(true);
+ iftbAction->setChecked(visible);
+ iftbAction->setToolTip(tr("Show or hide the toolbar"));
+ iftbAction->setData(VariantPointer<ext_toolbar_t>::asQVariant(toolbar));
+
+ QAction * before = 0;
+
+ foreach ( QAction * action, tbMenu->actions() )
+ {
+ /* Ensure we add the menu entries in sorted order */
+ if ( action->text().compare(toolbar->name, Qt::CaseInsensitive) > 0 )
+ {
+ before = action;
+ break;
+ }
+ }
+
+ tbMenu->insertAction(before, iftbAction);
+
+ addToolBar(Qt::TopToolBarArea, ifToolBar);
+ insertToolBarBreak(ifToolBar);
+
+ if ( show_hide_actions_ )
+ show_hide_actions_->addAction(iftbAction);
+
+ cntToolbars++;
+ }
+
+ if_toolbars = g_list_next ( if_toolbars );
+ }
+
+ if ( cntToolbars )
+ tbMenu->menuAction()->setVisible(true);
+
}
+void MainWindow::removeAdditionalToolbar(QString toolbarName)
+{
+ if ( toolbarName.length() == 0 )
+ return;
+
+ QList<QToolBar *> toolbars = findChildren<QToolBar *>();
+ foreach(QToolBar * tb, toolbars) {
+ AdditionalToolBar * ifToolBar = dynamic_cast<AdditionalToolBar *>(tb);
+
+ if ( ifToolBar && ifToolBar->menuName().compare(toolbarName) ) {
+
+ GList *entry = g_list_find_custom(recent.gui_additional_toolbars, ifToolBar->menuName().toStdString().c_str(), (GCompareFunc) strcmp);
+ if (entry) {
+ recent.gui_additional_toolbars = g_list_remove(recent.gui_additional_toolbars, entry->data);
+ }
+ QList<QAction *> actions = main_ui_->actionViewAdditionalToolbars->actions();
+ foreach(QAction * action, actions) {
+ ext_toolbar_t * item = VariantPointer<ext_toolbar_t>::asPtr(action->data());
+ if ( item && ifToolBar->menuName().compare(item->name) ) {
+ if ( show_hide_actions_ )
+ show_hide_actions_->removeAction(action);
+ main_ui_->actionViewAdditionalToolbars->removeAction(action);
+ }
+ }
+
+ break;
+ }
+ }
+
+}
+
+
/*
* Editor modelines
*
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index eb96f3e03f..aeb3a18052 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -98,6 +98,8 @@ public:
void gotoFrame(int packet_num);
CaptureFile *captureFile() { return &capture_file_; }
+ void removeAdditionalToolbar(QString toolbarName);
+
protected:
virtual bool eventFilter(QObject *obj, QEvent *event);
virtual void keyPressEvent(QKeyEvent *event);
@@ -334,8 +336,9 @@ private slots:
void addStatsPluginsToMenu();
void addDynamicMenus();
void reloadDynamicMenus();
- void addExternalMenus();
+ void addPluginIFStructures();
QMenu * searchSubMenu(QString objectName);
+ void activatePluginIFToolbar(bool);
void startInterfaceCapture(bool valid, const QString capture_filter);
diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui
index 14569e72cf..0d66379c9f 100644
--- a/ui/qt/main_window.ui
+++ b/ui/qt/main_window.ui
@@ -335,9 +335,15 @@
<addaction name="actionViewInternalsDissectorTables"/>
<addaction name="actionViewInternalsSupportedProtocols"/>
</widget>
+ <widget class="QMenu" name="actionViewAdditionalToolbars">
+ <property name="title">
+ <string>Additional Toolbars</string>
+ </property>
+ </widget>
<addaction name="actionViewMainToolbar"/>
<addaction name="actionViewFilterToolbar"/>
<addaction name="actionViewWirelessToolbar"/>
+ <addaction name="actionViewAdditionalToolbars" />
<addaction name="actionViewStatusBar"/>
<addaction name="separator"/>
<addaction name="actionViewFullScreen"/>
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index 48be263011..0a578fd706 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -55,6 +55,7 @@
#include "epan/epan_dissect.h"
#include "epan/filter_expressions.h"
#include "epan/prefs.h"
+#include "epan/plugin_if.h"
#include "epan/uat.h"
#include "epan/value_string.h"
@@ -119,6 +120,7 @@
#include "gsm_map_summary_dialog.h"
#include "iax2_analysis_dialog.h"
#include "io_graph_dialog.h"
+#include <additional_toolbar.h>
#include "lbm_stream_dialog.h"
#include "lbm_uimflow_dialog.h"
#include "lbm_lbtrm_transport_dialog.h"
@@ -483,6 +485,18 @@ void MainWindow::layoutToolbars()
main_ui_->displayFilterToolBar->setVisible(recent.filter_toolbar_show);
main_ui_->wirelessToolBar->setVisible(recent.wireless_toolbar_show);
main_ui_->statusBar->setVisible(recent.statusbar_show);
+
+ QList<QToolBar *> toolbars = findChildren<QToolBar *>();
+ foreach (QToolBar * bar, toolbars ) {
+ AdditionalToolBar * iftoolbar = dynamic_cast<AdditionalToolBar *>(bar);
+ if ( iftoolbar ) {
+ bool visible = false;
+ if ( g_list_find_custom(recent.gui_additional_toolbars, iftoolbar->menuName().toUtf8().constData(), (GCompareFunc) strcmp) )
+ visible = true;
+
+ iftoolbar->setVisible(visible);
+ }
+ }
}
void MainWindow::updatePreferenceActions()
@@ -509,6 +523,15 @@ void MainWindow::updateRecentActions()
main_ui_->actionViewPacketDetails->setChecked(recent.tree_view_show && prefs_has_layout_pane_content(layout_pane_content_pdetails));
main_ui_->actionViewPacketBytes->setChecked(recent.byte_view_show && prefs_has_layout_pane_content(layout_pane_content_pbytes));
+ foreach ( QAction * action, main_ui_->actionViewAdditionalToolbars->actions() ) {
+ ext_toolbar_t * toolbar = VariantPointer<ext_toolbar_t>::asPtr(action->data());
+ bool checked = false;
+ if ( toolbar && g_list_find_custom(recent.gui_additional_toolbars, toolbar->name, (GCompareFunc) strcmp) )
+ checked = true;
+
+ action->setChecked( checked );
+ }
+
foreach (QAction* tda, td_actions.keys()) {
if (recent.gui_time_format == td_actions[tda]) {
tda->setChecked(true);
@@ -2223,6 +2246,25 @@ void MainWindow::showHideMainWidgets(QAction *action)
} else if (widget == byte_view_tab_) {
recent.byte_view_show = show;
main_ui_->actionViewPacketBytes->setChecked(show);
+ } else {
+ ext_toolbar_t * toolbar = VariantPointer<ext_toolbar_t>::asPtr(action->data());
+ if (toolbar) {
+ GList *entry = g_list_find_custom(recent.gui_additional_toolbars, toolbar->name, (GCompareFunc) strcmp);
+ if (show && !entry) {
+ recent.gui_additional_toolbars = g_list_append(recent.gui_additional_toolbars, g_strdup(toolbar->name));
+ } else if (!show && entry) {
+ recent.gui_additional_toolbars = g_list_remove(recent.gui_additional_toolbars, entry->data);
+ }
+ action->setChecked(show);
+
+ QList<QToolBar *> toolbars = findChildren<QToolBar *>();
+ foreach (QToolBar * bar, toolbars ) {
+ AdditionalToolBar * iftoolbar = dynamic_cast<AdditionalToolBar *>(bar);
+ if ( iftoolbar && iftoolbar->menuName().compare(toolbar->name) == 0 ) {
+ iftoolbar->setVisible(show);
+ }
+ }
+ }
}
if (widget) {
@@ -3898,6 +3940,34 @@ void MainWindow::on_actionViewFullScreen_triggered(bool checked)
}
}
+void MainWindow::activatePluginIFToolbar(bool)
+{
+ QAction * sendingAction = dynamic_cast<QAction *>(sender());
+ if ( ! sendingAction || ! sendingAction->data().isValid() )
+ return;
+
+ ext_toolbar_t * toolbar = VariantPointer<ext_toolbar_t>::asPtr(sendingAction->data());
+
+ QList<QToolBar *> toolbars = findChildren<QToolBar *>();
+ foreach (QToolBar * bar, toolbars )
+ {
+ AdditionalToolBar * iftoolbar = dynamic_cast<AdditionalToolBar *>(bar);
+ if ( iftoolbar && iftoolbar->menuName().compare(toolbar->name) == 0 )
+ {
+ if ( iftoolbar->isVisible() )
+ {
+ iftoolbar->setVisible(false);
+ sendingAction->setChecked(true);
+ }
+ else
+ {
+ iftoolbar->setVisible(true);
+ sendingAction->setChecked(true);
+ }
+ }
+ }
+}
+
#ifdef _MSC_VER
#pragma warning(pop)
#endif
diff --git a/ui/recent.c b/ui/recent.c
index aaad91b0ad..d1894e0ed8 100644
--- a/ui/recent.c
+++ b/ui/recent.c
@@ -73,6 +73,7 @@
#define RECENT_GUI_ENDPOINT_TABS "gui.endpoint_tabs"
#define RECENT_GUI_RLC_PDUS_FROM_MAC_FRAMES "gui.rlc_pdus_from_mac_frames"
#define RECENT_GUI_CUSTOM_COLORS "gui.custom_colors"
+#define RECENT_GUI_TOOLBAR_SHOW "gui.additional_toolbar_show"
#define RECENT_GUI_GEOMETRY "gui.geom."
@@ -858,6 +859,12 @@ write_profile_recent(void)
fprintf(rf, RECENT_GUI_FILEOPEN_REMEMBERED_DIR ": %s\n", get_last_open_dir());
}
+ fprintf(rf, "\n# Additional Toolbars shown\n");
+ fprintf(rf, "# List of additional toolbars to show.\n");
+ string_list = join_string_list(recent.gui_additional_toolbars);
+ fprintf(rf, RECENT_GUI_TOOLBAR_SHOW ": %s\n", string_list);
+ g_free(string_list);
+
fclose(rf);
/* XXX - catch I/O errors (e.g. "ran out of disk space") and return
@@ -1111,6 +1118,8 @@ read_set_recent_pair_static(gchar *key, const gchar *value,
g_free (recent.gui_fileopen_remembered_dir);
}
recent.gui_fileopen_remembered_dir = g_strdup(value);
+ } else if (strcmp(key, RECENT_GUI_TOOLBAR_SHOW) == 0) {
+ recent.gui_additional_toolbars = prefs_get_string_list(value);
}
return PREFS_SET_OK;
@@ -1279,6 +1288,11 @@ recent_read_profile_static(char **rf_path_return, int *rf_errno_return)
recent.gui_fileopen_remembered_dir = NULL;
}
+ if (recent.gui_additional_toolbars) {
+ g_list_free_full (recent.gui_additional_toolbars, g_free);
+ recent.gui_additional_toolbars = NULL;
+ }
+
/* Construct the pathname of the user's profile recent file. */
rf_path = get_persconffile_path(RECENT_FILE_NAME, TRUE);
diff --git a/ui/recent.h b/ui/recent.h
index bce8214b85..2f33302b9b 100644
--- a/ui/recent.h
+++ b/ui/recent.h
@@ -110,6 +110,7 @@ typedef struct recent_settings_tag {
gchar *gui_fileopen_remembered_dir; /* folder of last capture loaded in File Open dialog */
gboolean gui_rlc_use_pdus_from_mac;
GList *custom_colors;
+ GList *gui_additional_toolbars;
} recent_settings_t;
/** Global recent settings. */