Wireshark-dev: Re: [Wireshark-dev] [Patch] Add "Copy as Filter" to the detail-pane context menu

From: Sake Blok <sake@xxxxxxxxxx>
Date: Mon, 26 Feb 2007 23:30:30 +0100
On Sat, Feb 24, 2007 at 09:17:20AM +0100, Sake Blok wrote:
> Hi,
> 
> Many times I find myself using prepare as filter, just to copy the filter
> to another instance of wireshark with a second trace (think of selecting
> the tcp.seq to match packets between two traces). As this distroys the filter
> that was currently active, I wrote a little patch that adds a "Copy as Filter"
> item to the context-menu in the detail-view.
> 
> Could someone review this patch and add it to the trunk?

I took another look at all the sources (grepping for "Apply as") and
updated the following files with the "Copy as Filter" functionality:

./doc/wireshark.pod
./docbook/wsug_src/WSUG_chapter_work.xml
./docbook/wsug_src/WSUG_chapter_use.xml
./gtk/menu.c
./gtk/main.c
./gtk/main.h

I did not change the following files:

./gtk/expert_comp_table.c
./gtk/service_response_time_table.c
./gtk/conversations_table.c
./gtk/hostlist_table.c

Personally I don't need the "Copy as Filter" there. But if other people
would like it there also (or if it should be there because of GUI-
consistency) I'm more than happy to spend some more time to implement
it there also.

Please also note that I did not use the "and|or|not|..." options since
it would be unclear if the new filter string would be merged with the
clipboard or the filter currently in the filter strip. Also it would
not add any value imho.

Please review this second patch (and discard the first one) and add it
to the trunk if it is found useful :)

Cheers,


Sake
Index: doc/wireshark.pod
===================================================================
--- doc/wireshark.pod	(revision 20934)
+++ doc/wireshark.pod	(working copy)
@@ -970,30 +970,34 @@
 Edit the saved list of display filters, allowing filters to be added,
 changed, or deleted.
 
-=item Analyze:Apply as Filter
+=item Analyze:Copy as Filter
 
-Create a display filter, or add to the display filter strip at the
-bottom, a display filter based on the data currently highlighted in the
-packe details, and apply the filter.
+Create a display filter based on the data currently highlighted in the
+packet details and copy that filter to the clipboard.
 
 If that data is a field that can be tested in a display filter
 expression, the display filter will test that field; otherwise, the
-display filter will be based on absolute offset within the packet, and
-so could be unreliable if the packet contains protocols with
+display filter will be based on the absolute offset within the packet.
+Therefore it could be unreliable if the packet contains protocols with
 variable-length headers, such as a source-routed token-ring packet.
 
+=item Analyze:Apply as Filter
+
+Create a display filter based on the data currently highlighted in the
+packet details and apply the filter.
+
 The B<Selected> option creates a display filter that tests for a match
 of the data; the B<Not Selected> option creates a display filter that
 tests for a non-match of the data.  The B<And Selected>, B<Or Selected>,
 B<And Not Selected>, and B<Or Not Selected> options add to the end of
-the display filter in the strip at the bottom an AND or OR operator
-followed by the new display filter expression.
+the display filter in the strip at the top (or bottom) an AND or OR
+operator followed by the new display filter expression.
 
 =item Analyze:Prepare a Filter
 
-Create a display filter, or add to the display filter strip at the
-bottom, a display filter based on the data currently highlighted in the
-packet details, but don't apply the filter.
+Create a display filter based on the data currently highlighted in the
+packet details. The filter strip at the top (or bottom) is updated but 
+it is not yet applied.
 
 =item Analyze:Enabled Protocols
 
Index: docbook/wsug_src/WSUG_chapter_work.xml
===================================================================
--- docbook/wsug_src/WSUG_chapter_work.xml	(revision 20934)
+++ docbook/wsug_src/WSUG_chapter_work.xml	(working copy)
@@ -101,6 +101,16 @@
 		<entry></entry>
 	      </row>
 	      <row>
+		<entry><command>Copy as Filter</command></entry>
+		<entry>Analyze</entry>
+		<entry>
+	    <para>
+		  Prepare a display filter based on the currently selected item
+		  but copy it to the clipboard.
+	    </para>
+		</entry>
+	      </row>
+	      <row>
 		<entry><command>Apply as Filter</command></entry>
 		<entry>Analyze</entry>
 		<entry>
@@ -430,6 +440,16 @@
 		<entry></entry>
 	      </row>
 	      <row>
+		<entry><command>Copy as Filter</command></entry>
+		<entry>Analyze</entry>
+		<entry>
+	    <para>
+		  Prepare a display filter based on the currently selected item
+		  but copy it to the clipboard.
+	    </para>
+		</entry>
+	      </row>
+	      <row>
 		<entry><command>Apply as Filter</command></entry>
 		<entry>Analyze</entry>
 		<entry>
Index: docbook/wsug_src/WSUG_chapter_use.xml
===================================================================
--- docbook/wsug_src/WSUG_chapter_use.xml	(revision 20934)
+++ docbook/wsug_src/WSUG_chapter_use.xml	(working copy)
@@ -1229,6 +1229,15 @@
 		  </para></entry>
 	      </row>
 	      <row>
+		<entry><command>Copy as Filter</command></entry>
+		<entry></entry>
+		<entry><para>
+			This menu item will use the selected item in the detail view to
+			create a display filter. This display filter is then copied to
+			the clipboard.
+		  </para></entry>
+	      </row>
+	      <row>
 		<entry><command>Apply as Filter > ...</command></entry>
 		<entry></entry>
 		<entry><para>
Index: gtk/menu.c
===================================================================
--- gtk/menu.c	(revision 20934)
+++ gtk/menu.c	(working copy)
@@ -568,6 +568,7 @@
     ITEM_FACTORY_ENTRY("/_Analyze", NULL, NULL, 0, "<Branch>", NULL),
     ITEM_FACTORY_STOCK_ENTRY("/Analyze/_Display Filters...", NULL, dfilter_dialog_cb,
                        0, WIRESHARK_STOCK_DISPLAY_FILTER),
+    ITEM_FACTORY_ENTRY("/Copy as Filter", NULL, copy_selected_ptree_cb, 0, NULL, NULL),
     ITEM_FACTORY_ENTRY("/Analyze/Appl_y as Filter", NULL, NULL, 0, "<Branch>", NULL),
     ITEM_FACTORY_ENTRY("/Analyze/Apply as Filter/_Selected", NULL, match_selected_ptree_cb,
                        MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
@@ -656,6 +657,8 @@
 
     ITEM_FACTORY_ENTRY("/<separator>", NULL, NULL, 0, "<Separator>", NULL),
 
+    ITEM_FACTORY_ENTRY("/Copy as Filter", NULL, copy_selected_ptree_cb, 0, NULL, NULL),
+
     ITEM_FACTORY_ENTRY("/Apply as Filter", NULL, NULL, 0, "<Branch>", NULL),
     ITEM_FACTORY_ENTRY("/Apply as Filter/_Selected", NULL, match_selected_plist_cb,
                        MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
@@ -762,6 +765,8 @@
 
     ITEM_FACTORY_ENTRY("/<separator>", NULL, NULL, 0, "<Separator>", NULL),
 
+    ITEM_FACTORY_ENTRY("/Copy as Filter", NULL, copy_selected_ptree_cb, 0, NULL, NULL),
+
     ITEM_FACTORY_ENTRY("/Apply as Filter", NULL, NULL, 0, "<Branch>", NULL),
     ITEM_FACTORY_ENTRY("/Apply as Filter/_Selected", NULL, match_selected_ptree_cb,
                        MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
@@ -2399,6 +2404,8 @@
       cf->current_frame != NULL && (g_resolv_flags & RESOLV_ALL_ADDRS) != RESOLV_ALL_ADDRS);
   set_menu_sensitivity(tree_view_menu_factory, "/Resolve Name",
       cf->current_frame != NULL && (g_resolv_flags & RESOLV_ALL_ADDRS) != RESOLV_ALL_ADDRS);
+  set_menu_sensitivity(packet_list_menu_factory, "/Copy as Filter",
+      cf->current_frame != NULL);
   set_menu_sensitivity(packet_list_menu_factory, "/Apply as Filter",
       cf->current_frame != NULL);
   set_menu_sensitivity(packet_list_menu_factory, "/Prepare a Filter",
@@ -2486,6 +2493,10 @@
 	  "/Go/Go to Corresponding Packet", hfinfo->type == FT_FRAMENUM);
 	set_menu_sensitivity(tree_view_menu_factory,
 	  "/Go to Corresponding Packet", hfinfo->type == FT_FRAMENUM);
+	set_menu_sensitivity(main_menu_factory, "/Analyze/Copy as Filter",
+	  proto_can_match_selected(cf->finfo_selected, cf->edt));
+	set_menu_sensitivity(tree_view_menu_factory, "/Copy as Filter",
+	  proto_can_match_selected(cf->finfo_selected, cf->edt));
 	set_menu_sensitivity(main_menu_factory, "/Analyze/Apply as Filter",
 	  proto_can_match_selected(cf->finfo_selected, cf->edt));
 	set_menu_sensitivity(tree_view_menu_factory, "/Apply as Filter",
@@ -2507,6 +2518,8 @@
 	    "/Go/Go to Corresponding Packet", FALSE);
 	set_menu_sensitivity(tree_view_menu_factory,
 	    "/Go to Corresponding Packet", FALSE);
+	set_menu_sensitivity(main_menu_factory, "/Analyze/Copy as Filter", FALSE);
+	set_menu_sensitivity(tree_view_menu_factory, "/Copy as Filter", FALSE);
 	set_menu_sensitivity(main_menu_factory, "/Analyze/Apply as Filter", FALSE);
 	set_menu_sensitivity(tree_view_menu_factory, "/Apply as Filter", FALSE);
 	set_menu_sensitivity(main_menu_factory, "/Analyze/Prepare a Filter", FALSE);
Index: gtk/main.c
===================================================================
--- gtk/main.c	(revision 20934)
+++ gtk/main.c	(working copy)
@@ -327,6 +327,30 @@
 }
 
 
+/* This function allows users to right click in the details window and copy the
+ * currently selected item as a display filter to the operating systems clipboard.
+ */
+void
+copy_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_)
+{
+    GString *gtk_text_str = g_string_new("");
+    char *filter;
+
+    if (cfile.finfo_selected) {
+        filter = proto_construct_match_selected_string(cfile.finfo_selected,
+                                                       cfile.edt);
+        if (strlen(filter) == 0) {              /* If no representation then... */
+            simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                "Could not acquire information to copy, try expanding or choosing another item");
+	} else {                                 /* Copy string to clipboard */
+	    g_string_sprintfa(gtk_text_str, "%s", filter);
+	    copy_to_clipboard(gtk_text_str); 
+	}
+    }
+    g_string_free(gtk_text_str, TRUE);           /* Free the memory */
+}
+
+
 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
 {
     gchar *selected_proto_url;
Index: gtk/main.h
===================================================================
--- gtk/main.h	(revision 20934)
+++ gtk/main.h	(working copy)
@@ -142,6 +142,13 @@
  */
 extern void match_selected_ptree_cb(GtkWidget *widget, gpointer data, MATCH_SELECTED_E action);
 
+/** User requested "Copy as Filter" function by context menu of protocol tree.
+ *
+ * @param widget parent widget
+ * @param data parent widget
+ */
+extern void copy_selected_ptree_cb(GtkWidget *widget _U_, gpointer data);
+
 /** User requested one of "Apply as Filter" or "Prepare a Filter" functions
  *  by context menu of packet list.
  *