diff options
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><html><head/><body><p><span style=" font-size:10pt;"><br/></span><span style=" font-size:10pt; font-weight:600;">PlugIn Interface Demonstration</span><span style=" font-size:10pt;"><br/>Version: </span><span style=" font-size:10pt; font-weight:600;">0.0.1 </span></p><p><span style=" font-size:10pt;">Copyright © </span><span style=" font-size:10pt; font-style:italic;">Wireshark Foundation</span><span style=" font-size:10pt;"><br/></span><a href="http://www.wireshark.org"><span style=" text-decoration: underline; color:#0000ff;">www.wireshark.org</span></a></p></body></html></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><html><head/><body><p>This PlugIn demonstrates functionality of the interface API for plugins and extcap interfaces.</p></body></html></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. */ |