aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--file.c22
-rw-r--r--file.h9
-rw-r--r--gtk/main.c15
-rw-r--r--gtk/menu.c54
-rw-r--r--menu.h9
5 files changed, 71 insertions, 38 deletions
diff --git a/file.c b/file.c
index cc61a67a2a..a3de5552d0 100644
--- a/file.c
+++ b/file.c
@@ -3332,6 +3332,28 @@ save_packet(capture_file *cf _U_, frame_data *fdata,
return TRUE;
}
+/*
+ * Can this capture file be saved in any format except by copying the raw data?
+ */
+gboolean
+cf_can_save_as(capture_file *cf)
+{
+ int ft;
+
+ for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
+ /* To save a file with Wiretap, Wiretap has to handle that format,
+ and its code to handle that format must be able to write a file
+ with this file's encapsulation type. */
+ if (wtap_dump_can_open(ft) && wtap_dump_can_write_encap(ft, cf->lnk_t)) {
+ /* OK, we can write it out in this type. */
+ return TRUE;
+ }
+ }
+
+ /* No, we couldn't save it in any format. */
+ return FALSE;
+}
+
cf_status_t
cf_save(capture_file *cf, const char *fname, packet_range_t *range, guint save_format, gboolean compressed)
{
diff --git a/file.h b/file.h
index 716ea5da99..c5c00b2095 100644
--- a/file.h
+++ b/file.h
@@ -154,6 +154,15 @@ cf_read_status_t cf_continue_tail(capture_file *cf, int to_read, int *err);
cf_read_status_t cf_finish_tail(capture_file *cf, int *err);
/**
+ * Determine whether this capture file (or a range of it) can be saved
+ * (except by copying the raw file data).
+ *
+ * @param cf the capture file to check
+ * @return TRUE if it can be saved, FALSE if it can't
+ */
+gboolean cf_can_save_as(capture_file *cf);
+
+/**
* Save a capture file (or a range of it).
*
* @param cf the capture file to save to
diff --git a/gtk/main.c b/gtk/main.c
index 963ac567e1..028a5b619e 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -1494,8 +1494,7 @@ main_cf_cb_file_closing(capture_file *cf)
set_main_window_name("The Wireshark Network Analyzer");
/* Disable all menu items that make sense only if you have a capture. */
- set_menus_for_capture_file(FALSE);
- set_menus_for_unsaved_capture_file(FALSE);
+ set_menus_for_capture_file(NULL);
set_menus_for_captured_packets(FALSE);
set_menus_for_selected_packet(cf);
set_menus_for_capture_in_progress(FALSE);
@@ -1542,9 +1541,8 @@ main_cf_cb_file_read_finished(capture_file *cf)
set_display_filename(cf);
/* Enable menu items that make sense if you have a capture file you've
- finished reading. */
- set_menus_for_capture_file(TRUE);
- set_menus_for_unsaved_capture_file(!cf->user_saved);
+ finished reading. */
+ set_menus_for_capture_file(cf);
/* Enable menu items that make sense if you have some captured packets. */
set_menus_for_captured_packets(TRUE);
@@ -1745,9 +1743,8 @@ main_cf_cb_live_capture_update_finished(capture_file *cf)
set_menus_for_capture_in_progress(FALSE);
/* Enable menu items that make sense if you have a capture file
- you've finished reading. */
- set_menus_for_capture_file(TRUE);
- set_menus_for_unsaved_capture_file(!cf->user_saved);
+ you've finished reading. */
+ set_menus_for_capture_file(cf);
/* Set up main window for a capture file. */
main_set_for_capture_file(TRUE);
@@ -1952,7 +1949,7 @@ main_cf_cb_file_safe_failed(gpointer data _U_)
static void
main_cf_cb_file_safe_reload_finished(gpointer data _U_)
{
- set_menus_for_unsaved_capture_file(FALSE);
+ set_menus_for_capture_file(&cfile);
}
static void main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
diff --git a/gtk/menu.c b/gtk/menu.c
index 7266b9e098..3a5040fae6 100644
--- a/gtk/menu.c
+++ b/gtk/menu.c
@@ -886,8 +886,7 @@ menus_init(void) {
merge_all_tap_menus(tap_menu_tree_root);
/* Initialize enabled/disabled state of menu items */
- set_menus_for_unsaved_capture_file(FALSE);
- set_menus_for_capture_file(FALSE);
+ set_menus_for_capture_file(NULL);
#if 0
/* Un-#if this when we actually implement Cut/Copy/Paste.
Then make sure you enable them when they can be done. */
@@ -2088,32 +2087,41 @@ popup_menu_handler(GtkWidget *widget, GdkEvent *event, gpointer data)
}
/* Enable or disable menu items based on whether you have a capture file
- you've finished reading. */
+ you've finished reading and, if you have one, whether it's been saved
+ and whether it could be saved except by copying the raw packet data. */
void
-set_menus_for_capture_file(gboolean have_capture_file)
+set_menus_for_capture_file(capture_file *cf)
{
- set_menu_sensitivity(main_menu_factory, "/File/Open...", have_capture_file);
- set_menu_sensitivity(main_menu_factory, "/File/Open Recent", have_capture_file);
- set_menu_sensitivity(main_menu_factory, "/File/Merge...", have_capture_file);
- set_menu_sensitivity(main_menu_factory, "/File/Close", have_capture_file);
- set_menu_sensitivity(main_menu_factory, "/File/Save As...",
- have_capture_file);
- set_menu_sensitivity(main_menu_factory, "/File/Export", have_capture_file);
- set_menu_sensitivity(main_menu_factory, "/View/Reload", have_capture_file);
- set_toolbar_for_capture_file(have_capture_file);
+ if (cf == NULL) {
+ /* We have no capture file */
+ set_menu_sensitivity(main_menu_factory, "/File/Merge...", FALSE);
+ set_menu_sensitivity(main_menu_factory, "/File/Close", FALSE);
+ set_menu_sensitivity(main_menu_factory, "/File/Save", FALSE);
+ set_menu_sensitivity(main_menu_factory, "/File/Save As...", FALSE);
+ set_menu_sensitivity(main_menu_factory, "/File/Export", FALSE);
+ set_menu_sensitivity(main_menu_factory, "/View/Reload", FALSE);
+ set_toolbar_for_capture_file(FALSE);
+ set_toolbar_for_unsaved_capture_file(FALSE);
+ } else {
+ set_menu_sensitivity(main_menu_factory, "/File/Merge...", TRUE);
+ set_menu_sensitivity(main_menu_factory, "/File/Close", TRUE);
+ set_menu_sensitivity(main_menu_factory, "/File/Save", !cf->user_saved);
+ /*
+ * "Save As..." works only if we can write the file out in at least
+ * one format (so we can save the whole file or just a subset) or
+ * if we have an unsaved capture (so writing the whole file out
+ * with a raw data copy makes sense).
+ */
+ set_menu_sensitivity(main_menu_factory, "/File/Save As...",
+ cf_can_save_as(cf) || !cf->user_saved);
+ set_menu_sensitivity(main_menu_factory, "/File/Export", TRUE);
+ set_menu_sensitivity(main_menu_factory, "/View/Reload", TRUE);
+ set_toolbar_for_unsaved_capture_file(!cf->user_saved);
+ set_toolbar_for_capture_file(TRUE);
+ }
packets_bar_update();
}
-/* Enable or disable menu items based on whether you have an unsaved
- capture file you've finished reading. */
-void
-set_menus_for_unsaved_capture_file(gboolean have_unsaved_capture_file)
-{
- set_menu_sensitivity(main_menu_factory, "/File/Save",
- have_unsaved_capture_file);
- set_toolbar_for_unsaved_capture_file(have_unsaved_capture_file);
-}
-
/* Enable or disable menu items based on whether there's a capture in
progress. */
void
diff --git a/menu.h b/menu.h
index 9664ac02a6..686834addc 100644
--- a/menu.h
+++ b/menu.h
@@ -38,12 +38,9 @@ void add_menu_recent_capture_file(gchar *file);
/* Routines to enable or disable sets of menu items. */
/* Enable or disable menu items based on whether you have a capture file
- you've finished reading. */
-void set_menus_for_capture_file(gboolean);
-
-/* Enable or disable menu items based on whether you have an unsaved
- capture file you've finished reading. */
-void set_menus_for_unsaved_capture_file(gboolean);
+ you've finished reading and, if you have one, whether it's been saved
+ and whether it could be saved except by copying the raw packet data. */
+void set_menus_for_capture_file(capture_file *);
/* Enable or disable menu items based on whether there's a capture in
progress. */