further work on the yet to come welcome page ...
[obnox/wireshark/wip.git] / gtk / main_menu.c
index f66f999795b50d7916572209da1b46c3b9279af8..c770e9edd8e419e61da08eadf899ba92433d590c 100644 (file)
 #include <epan/ipproto.h>
 #include <epan/dissector_filters.h>
 #include <epan/strutil.h>
-
-#include "about_dlg.h"
-#include "capture_dlg.h"
-#include "color_dlg.h"
-#include "filter_dlg.h"
-#include "profile_dlg.h"
-#include "dlg_utils.h"
-#include "capture_file_dlg.h"
-#include "fileset_dlg.h"
-#include "find_dlg.h"
-#include "goto_dlg.h"
-#include "summary_dlg.h"
-#include "prefs_dlg.h"
-#include "packet_win.h"
-#include "print.h"
-#include "follow_tcp.h"
-#include "follow_udp.h"
-#include "follow_ssl.h"
-#include "decode_as_dlg.h"
-#include "help_dlg.h"
-#include "supported_protos_dlg.h"
-#include "proto_dlg.h"
-#include "proto_hier_stats_dlg.h"
-#include "keys.h"
 #include <epan/plugins.h>
 #include <epan/epan_dissect.h>
-#include "stock_icons.h"
-#include "gtkglobals.h"
-#include "register.h"
-#include "recent.h"
+
+#include "../print.h"
+#include "../register.h"
 #include "../ui_util.h"
-#include "proto_draw.h"
-#include "conversations_table.h"
-#include "hostlist_table.h"
-#include "simple_dialog.h"
-#include "packet_history.h"
-#include "color_filters.h"
-#include "sctp_stat.h"
-#include "firewall_dlg.h"
-#include "u3.h"
-#include "macros_dlg.h"
-#include "export_object.h"
-
-#include "main.h"
-#include "main_menu.h"
-#include "main_packet_list.h"
-#include "main_toolbar.h"
+#include "../simple_dialog.h"
+#include "../color_filters.h"
 #include "../stat_menu.h"
-#include "gui_stat_menu.h"
+
+#include "gtk/about_dlg.h"
+#include "gtk/capture_dlg.h"
+#include "gtk/color_dlg.h"
+#include "gtk/filter_dlg.h"
+#include "gtk/profile_dlg.h"
+#include "gtk/dlg_utils.h"
+#include "gtk/capture_file_dlg.h"
+#include "gtk/fileset_dlg.h"
+#include "gtk/find_dlg.h"
+#include "gtk/goto_dlg.h"
+#include "gtk/summary_dlg.h"
+#include "gtk/prefs_dlg.h"
+#include "gtk/packet_win.h"
+#include "gtk/follow_tcp.h"
+#include "gtk/follow_udp.h"
+#include "gtk/follow_ssl.h"
+#include "gtk/decode_as_dlg.h"
+#include "gtk/help_dlg.h"
+#include "gtk/supported_protos_dlg.h"
+#include "gtk/proto_dlg.h"
+#include "gtk/proto_hier_stats_dlg.h"
+#include "gtk/keys.h"
+#include "gtk/stock_icons.h"
+#include "gtk/gtkglobals.h"
+#include "gtk/recent.h"
+#include "gtk/main_proto_draw.h"
+#include "gtk/conversations_table.h"
+#include "gtk/hostlist_table.h"
+#include "gtk/packet_history.h"
+#include "gtk/sctp_stat.h"
+#include "gtk/firewall_dlg.h"
+#include "gtk/u3.h"
+#include "gtk/macros_dlg.h"
+#include "gtk/export_object.h"
+#include "gtk/gui_stat_menu.h"
+#include "gtk/main.h"
+#include "gtk/main_menu.h"
+#include "gtk/main_packet_list.h"
+#include "gtk/main_toolbar.h"
+#include "gtk/main_welcome.h"
 
 
 typedef struct _menu_item {
     char    *name;
     gint    group;
+    const char *stock_id;
     gboolean enabled;
     GtkItemFactoryCallback callback;
     gpointer callback_data;
@@ -413,11 +415,6 @@ colorize_conversation_cb(GtkWidget * w _U_, gpointer data _U_, int action)
     }
 }
 
-#ifdef HAVE_LUA_5_1
-static gboolean have_items_in_tools_menu = FALSE;
-#endif
-
-
 /* main menu */
 static GtkItemFactoryEntry menu_items[] =
 {
@@ -675,8 +672,6 @@ static GtkItemFactoryEntry menu_items[] =
                        MATCH_SELECTED_AND_NOT, NULL, NULL,},
     {"/Analyze/Prepare a Filter/... o_r not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
                        MATCH_SELECTED_OR_NOT, NULL, NULL,},
-    {"/Analyze/Firewall ACL Rules", NULL,
-                       firewall_rule_cb, 0, NULL, NULL,},
     {"/Analyze/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
     {"/Analyze/_Enabled Protocols...", "<shift><control>R", GTK_MENU_FUNC(proto_cb), 
                        0, "<StockItem>", WIRESHARK_STOCK_CHECKBOX,},
@@ -699,12 +694,12 @@ static GtkItemFactoryEntry menu_items[] =
                        GTK_MENU_FUNC(init_conversation_notebook_cb), 0, "<StockItem>", WIRESHARK_STOCK_CONVERSATIONS,},
     {"/Statistics/Endpoints", NULL,
                        GTK_MENU_FUNC(init_hostlist_notebook_cb), 0, "<StockItem>", WIRESHARK_STOCK_ENDPOINTS,},
-#ifdef HAVE_LUA_5_1
     {"/_Tools", NULL, NULL, 0, "<Branch>", NULL,},
-#endif
+    {"/Tools/Firewall ACL Rules", NULL,
+                       firewall_rule_cb, 0, NULL, NULL,},
     {"/_Help", NULL, NULL, 0, "<Branch>", NULL,},
     {"/Help/_Contents", "F1", GTK_MENU_FUNC(topic_menu_cb), HELP_CONTENT, "<StockItem>", GTK_STOCK_HELP,},
-    {"/Help/_Supported Protocols", NULL, GTK_MENU_FUNC(supported_cb), 0, NULL, NULL,},
+    {"/Help/FAQ's", NULL, GTK_MENU_FUNC(topic_menu_cb), ONLINEPAGE_FAQ, NULL, NULL,},
     {"/Help/Manual Pages", NULL, NULL, 0, "<Branch>", NULL,},
     {"/Help/Manual Pages/Wireshark", NULL, GTK_MENU_FUNC(topic_menu_cb), LOCALPAGE_MAN_WIRESHARK, NULL, NULL,},
     {"/Help/Manual Pages/Wireshark Filter", NULL, GTK_MENU_FUNC(topic_menu_cb), LOCALPAGE_MAN_WIRESHARK_FILTER, NULL, NULL,},
@@ -715,13 +710,13 @@ static GtkItemFactoryEntry menu_items[] =
     {"/Help/Manual Pages/Mergecap", NULL, GTK_MENU_FUNC(topic_menu_cb), LOCALPAGE_MAN_MERGECAP, NULL, NULL,},
     {"/Help/Manual Pages/Editcap", NULL, GTK_MENU_FUNC(topic_menu_cb), LOCALPAGE_MAN_EDITCAP, NULL, NULL,},
     {"/Help/Manual Pages/Text2pcap", NULL, GTK_MENU_FUNC(topic_menu_cb), LOCALPAGE_MAN_TEXT2PCAP, NULL, NULL,},
-    {"/Help/Wireshark Online", NULL, NULL, 0, "<Branch>", NULL,},
-    {"/Help/Wireshark Online/Home Page", NULL, GTK_MENU_FUNC(topic_menu_cb), ONLINEPAGE_HOME, "<StockItem>", GTK_STOCK_HOME,},
-    {"/Help/Wireshark Online/Wiki", NULL, GTK_MENU_FUNC(topic_menu_cb), ONLINEPAGE_WIKI, "<StockItem>", WIRESHARK_STOCK_WIKI,},
-    {"/Help/Wireshark Online/User's Guide", NULL, GTK_MENU_FUNC(topic_menu_cb), ONLINEPAGE_USERGUIDE, "<StockItem>", WIRESHARK_STOCK_WEB_SUPPORT,},
-    {"/Help/Wireshark Online/FAQ's", NULL, GTK_MENU_FUNC(topic_menu_cb), ONLINEPAGE_FAQ, NULL, NULL,},
-    {"/Help/Wireshark Online/Downloads", NULL, GTK_MENU_FUNC(topic_menu_cb), ONLINEPAGE_DOWNLOAD, NULL, NULL,},
-    {"/Help/Wireshark Online/Example Files", NULL, GTK_MENU_FUNC(topic_menu_cb), ONLINEPAGE_SAMPLE_FILES, NULL, NULL,},
+    {"/Help/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
+    {"/Help/Website", NULL, GTK_MENU_FUNC(topic_menu_cb), ONLINEPAGE_HOME, "<StockItem>", GTK_STOCK_HOME,},
+    {"/Help/Wiki", NULL, GTK_MENU_FUNC(topic_menu_cb), ONLINEPAGE_WIKI, "<StockItem>", WIRESHARK_STOCK_WIKI,},
+    {"/Help/Downloads", NULL, GTK_MENU_FUNC(topic_menu_cb), ONLINEPAGE_DOWNLOAD, NULL, NULL,},
+    {"/Help/Sample Captures", NULL, GTK_MENU_FUNC(topic_menu_cb), ONLINEPAGE_SAMPLE_FILES, NULL, NULL,},
+    {"/Help/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
+    {"/Help/_Supported Protocols (slow!)", NULL, GTK_MENU_FUNC(supported_cb), 0, NULL, NULL,},
     {"/Help/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
     {"/Help/_About Wireshark", NULL, GTK_MENU_FUNC(about_wireshark_cb),
                        0, "<StockItem>", WIRESHARK_STOCK_ABOUT}
@@ -1144,12 +1139,6 @@ menus_init(void) {
     main_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", grp);
     gtk_item_factory_create_items_ac(main_menu_factory, nmenu_items, menu_items, NULL, 2);
 
-#ifdef HAVE_LUA_5_1
-    if (! have_items_in_tools_menu) {
-      gtk_widget_hide(gtk_item_factory_get_item(main_menu_factory,"/Tools"));
-    }
-#endif
-
     menu_dissector_filter();
     merge_all_tap_menus(tap_menu_tree_root);
 
@@ -1167,7 +1156,7 @@ menus_init(void) {
     set_menus_for_selected_packet(&cfile);
     set_menus_for_selected_tree_row(&cfile);
     set_menus_for_capture_in_progress(FALSE);
-       set_menus_for_file_set(/* dialog */TRUE, /* previous file */ FALSE, /* next_file */ FALSE);
+    set_menus_for_file_set(/* dialog */TRUE, /* previous file */ FALSE, /* next_file */ FALSE);
 
     /* init with an empty recent files list */
     clear_menu_recent_capture_file_cmd_cb(NULL, NULL);
@@ -1188,6 +1177,7 @@ static gint tap_menu_item_add_compare(gconstpointer a, gconstpointer b)
 static GList * tap_menu_item_add(
     char *name,
     gint group,
+    const char *stock_id,
     GtkItemFactoryCallback callback,
     gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *, gpointer callback_data),
     gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data),
@@ -1199,8 +1189,9 @@ static GList * tap_menu_item_add(
 
 
     child = g_malloc(sizeof (menu_item_t));
-    child->group            = group;
     child->name             = name;
+    child->group            = group;
+    child->stock_id         = stock_id;
     child->callback         = callback;
     child->selected_packet_enabled = selected_packet_enabled;
     child->selected_tree_row_enabled = selected_tree_row_enabled;
@@ -1239,9 +1230,10 @@ static GList * tap_menu_item_add(
  * is selected and, if one is, on the tree row) and FALSE if not.
  */
 void
-register_stat_menu_item(
+register_stat_menu_item_stock(
     const char *name,
     register_stat_group_t group,
+    const char *stock_id,
     GtkItemFactoryCallback callback,
     gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *, gpointer callback_data),
     gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data),
@@ -1271,10 +1263,7 @@ register_stat_menu_item(
     case(REGISTER_ANALYZE_GROUP_NONE): toolspath = "/Analyze/"; break;
     case(REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER): toolspath = "/Analyze/Conversation Filter/"; break;
 #ifdef HAVE_LUA_5_1
-    case(REGISTER_TOOLS_GROUP_NONE):
-        toolspath = "/Tools/";
-        have_items_in_tools_menu = TRUE;
-        break;
+    case(REGISTER_TOOLS_GROUP_NONE): toolspath = "/Tools/"; break;
 #endif
     default:
         g_assert(!"no such menu group");
@@ -1321,7 +1310,7 @@ register_stat_menu_item(
              * add it to the Tools menu tree.
              */
             childnode = tap_menu_item_add(
-                menupath, group, NULL, NULL ,NULL, NULL, curnode);
+                menupath, group, "", NULL, NULL ,NULL, NULL, curnode);
         } else {
             /*
              * Yes.  We don't need this "menupath" any longer.
@@ -1349,12 +1338,31 @@ register_stat_menu_item(
      * the main menu.
      */
     tap_menu_item_add(
-        menupath, group, callback,
+        menupath, group, stock_id, callback,
         selected_packet_enabled, selected_tree_row_enabled,
         callback_data, curnode);
 }
 
 
+void
+register_stat_menu_item(
+    const char *name,
+    register_stat_group_t group,
+    GtkItemFactoryCallback callback,
+    gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *, gpointer callback_data),
+    gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data),
+    gpointer callback_data)
+{
+    register_stat_menu_item_stock(
+        name,
+        group,
+        NULL,
+        callback,
+        selected_packet_enabled,
+        selected_tree_row_enabled,
+        callback_data);
+}
+
 static guint merge_tap_menus_layered(GList *node, gint group) {
     GtkItemFactoryEntry *entry;
     GList       *child;
@@ -1409,6 +1417,10 @@ static guint merge_tap_menus_layered(GList *node, gint group) {
             default:
                 g_assert_not_reached();
             }
+            if(node_data->stock_id!= NULL) {
+                entry->item_type = "<StockItem>";
+                entry->extra_data = node_data->stock_id;
+            }
             gtk_item_factory_create_item(main_menu_factory, entry, node_data->callback_data, /* callback_type */ 2);
             set_menu_sensitivity(main_menu_factory, node_data->name, FALSE); /* no capture file yet */
             added++;
@@ -1447,45 +1459,45 @@ static guint merge_tap_menus_layered(GList *node, gint group) {
 
 
 void merge_all_tap_menus(GList *node) {
-    GtkItemFactoryEntry *entry;
+    GtkItemFactoryEntry *sep_entry;
 
-    entry = g_malloc0(sizeof (GtkItemFactoryEntry));
-    entry->item_type = "<Separator>";
-    entry->path = "/Statistics/";
+    sep_entry = g_malloc0(sizeof (GtkItemFactoryEntry));
+    sep_entry->item_type = "<Separator>";
+    sep_entry->path = "/Statistics/";
 
     /*
      * merge only the menu items of the specific group,
      * and then append a seperator
      */
     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_GENERIC)) {
-        gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);
+        gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);
     }
     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_CONVERSATION_LIST)) {
-        /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
+        /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
     }
     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_ENDPOINT_LIST)) {
-        /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
+        /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
     }
     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_RESPONSE_TIME)) {
-        gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);
+        gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);
     }
     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_TELEPHONY)) {
-        gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);
+        gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);
     }
     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_NONE)) {
-        /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
+        /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
     }
     if (merge_tap_menus_layered(node, REGISTER_ANALYZE_GROUP_NONE)) {
-        entry->path = "/Analyze/";
-        /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
+        sep_entry->path = "/Analyze/";
+        /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
     }
     if (merge_tap_menus_layered(node, REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER)) {
-        entry->path = "/Analyze/Conversation Filter/";
-        /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
+        sep_entry->path = "/Analyze/Conversation Filter/";
+        /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
     }
 #ifdef HAVE_LUA_5_1
     if (merge_tap_menus_layered(node, REGISTER_TOOLS_GROUP_NONE)) {
-        /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
+        /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
     }
 #endif
 }
@@ -1583,6 +1595,8 @@ set_menu_object_data (const gchar *path, const gchar *key, gpointer data) {
 #define MENU_RECENT_FILES_PATH "/File/Open Recent"
 #define MENU_RECENT_FILES_KEY "Recent File Name"
 
+
+
 static void
 update_menu_recent_capture_file1(GtkWidget *widget, gpointer cnt) {
     gchar *widget_cf_name;
@@ -1592,15 +1606,20 @@ update_menu_recent_capture_file1(GtkWidget *widget, gpointer cnt) {
     /* if this menu item is a file, count it */
     if (widget_cf_name) {
         (*(guint *)cnt)++;
+        main_welcome_add_recent_capture_files(widget_cf_name);
     }
 }
 
 
+
 /* update the menu */
 static void
 update_menu_recent_capture_file(GtkWidget *submenu_recent_files) {
     guint cnt = 0;
 
+
+    main_welcome_reset_recent_capture_files();
+
     gtk_container_foreach(GTK_CONTAINER(submenu_recent_files),
                update_menu_recent_capture_file1, &cnt);
 
@@ -1609,6 +1628,40 @@ update_menu_recent_capture_file(GtkWidget *submenu_recent_files) {
 }
 
 
+
+/* remove the capture filename from the "Recent Files" menu */
+static void
+remove_menu_recent_capture_filename(gchar *cf_name) {
+    GtkWidget *submenu_recent_files;
+    GList* child_list;
+    GList* child_list_item;
+       GtkWidget *menu_item_child;
+       gchar     *menu_item_cf_name;
+    
+
+    /* get the submenu container item */
+    submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
+
+    /* find the corresponding menu item to be removed */
+    child_list = gtk_container_get_children(GTK_CONTAINER(submenu_recent_files));
+    child_list_item = child_list;
+    while(child_list_item) {
+           menu_item_child = (GTK_BIN(child_list_item->data))->child;
+           gtk_label_get(GTK_LABEL(menu_item_child), &menu_item_cf_name);
+        if(strcmp(menu_item_cf_name, cf_name) == 0) {
+            /* XXX: is this all we need to do, to free the menu item and its label?
+               The reference count of widget will go to 0, so it'll be freed;
+               will that free the label? */
+            gtk_container_remove(GTK_CONTAINER(submenu_recent_files), child_list_item->data);
+        }
+        child_list_item = g_list_next(child_list_item);
+    }
+    g_list_free(child_list);
+
+    update_menu_recent_capture_file(submenu_recent_files);
+}
+
+
 /* remove the capture filename from the "Recent Files" menu */
 static void
 remove_menu_recent_capture_file(GtkWidget *widget, gpointer unused _U_) {
@@ -1629,7 +1682,7 @@ remove_menu_recent_capture_file(GtkWidget *widget, gpointer unused _U_) {
 }
 
 
-/* callback, if the user pushed the <Clear File List> item */
+/* callback, if the user pushed the <Clear> menu item */
 static void
 clear_menu_recent_capture_file_cmd_cb(GtkWidget *w _U_, gpointer unused _U_) {
     GtkWidget *submenu_recent_files;
@@ -1644,6 +1697,29 @@ clear_menu_recent_capture_file_cmd_cb(GtkWidget *w _U_, gpointer unused _U_) {
 }
 
 
+/* Open a file by it's name
+   (Beware: will not ask to close existing capture file!) */
+void
+menu_open_filename(gchar *cf_name)
+{
+       GtkWidget *submenu_recent_files;
+       int       err;
+
+       submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
+
+       /* open and read the capture file (this will close an existing file) */
+       if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
+               cf_read(&cfile);
+       } else {
+               /* the capture file isn't existing any longer, remove menu item */
+               /* XXX: ask user to remove item, it's maybe only a temporary problem */
+               remove_menu_recent_capture_filename(cf_name);
+       }
+
+       update_menu_recent_capture_file(submenu_recent_files);
+}
+
+
 /* callback, if the user pushed a recent file submenu item */
 void
 menu_open_recent_file_cmd(GtkWidget *w)
@@ -1671,7 +1747,7 @@ menu_open_recent_file_cmd(GtkWidget *w)
        update_menu_recent_capture_file(submenu_recent_files);
 }
 
-static void menu_open_recent_file_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
+static void menu_open_recent_file_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
 {
     switch(btn) {
     case(ESD_BTN_YES):
@@ -2496,8 +2572,6 @@ set_menus_for_selected_packet(capture_file *cf)
       cf->current_frame != NULL);
   set_menu_sensitivity(packet_list_menu_factory, "/SCTP",
       cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_SCTP) : FALSE);
-  set_menu_sensitivity(main_menu_factory, "/Analyze/Firewall ACL Rules",
-      cf->current_frame != NULL);
   set_menu_sensitivity(main_menu_factory, "/Analyze/Follow TCP Stream",
       cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
   set_menu_sensitivity(packet_list_menu_factory, "/Follow TCP Stream",
@@ -2556,6 +2630,8 @@ set_menus_for_selected_packet(capture_file *cf)
       cf->current_frame != NULL);
   set_menu_sensitivity(packet_list_menu_factory, "/Prepare a Filter",
       cf->current_frame != NULL);
+  set_menu_sensitivity(main_menu_factory, "/Tools/Firewall ACL Rules",
+      cf->current_frame != NULL);
 
   walk_menu_tree_for_selected_packet(tap_menu_tree_root, cf->current_frame,
       cf->edt);