From 962b4f08f76e70ca445523027c1792883ae3ea9d Mon Sep 17 00:00:00 2001 From: Gerald Combs Date: Fri, 21 Dec 2012 17:37:57 +0000 Subject: Move common time shifting code to ui/time_shift.[ch]. Change the shifting routines to return an error message on failure or NULL on success. Prettify and simplify the layout of the GTK+ time shift dialog. Make the cancel button work as expected. Add a time shift dialog to the Qt port. I used a Mad Lib (sentence) layout. Hopefully that won't make translation too difficult. For some reason time shifts aren't immediately shown in the packet detail. This appears to be a bug in the packet list / packet detail code. Add warning role color definitions to tango_colors.h and use them. svn path=/trunk/; revision=46680 --- ui/CMakeLists.txt | 1 + ui/Makefile.common | 2 + ui/gtk/dlg_utils.h | 2 + ui/gtk/time_shift_dlg.c | 707 ++++++-------------------------------- ui/gtk/time_shift_dlg.h | 2 - ui/qt/QtShark.pro | 21 +- ui/qt/label_stack.cpp | 4 +- ui/qt/main_status_bar.cpp | 4 +- ui/qt/main_window.h | 1 + ui/qt/main_window.ui | 47 +++ ui/qt/main_window_slots.cpp | 10 + ui/qt/packet_format_group_box.cpp | 5 +- ui/qt/tango_colors.h | 3 + ui/qt/time_shift_dialog.cpp | 298 ++++++++++++++++ ui/qt/time_shift_dialog.h | 77 +++++ ui/qt/time_shift_dialog.ui | 275 +++++++++++++++ ui/time_shift.c | 515 +++++++++++++++++++++++++++ ui/time_shift.h | 103 ++++++ 18 files changed, 1458 insertions(+), 619 deletions(-) create mode 100644 ui/qt/time_shift_dialog.cpp create mode 100644 ui/qt/time_shift_dialog.h create mode 100644 ui/qt/time_shift_dialog.ui create mode 100644 ui/time_shift.c create mode 100644 ui/time_shift.h (limited to 'ui') diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt index 201bb7f738..06ced1f19d 100644 --- a/ui/CMakeLists.txt +++ b/ui/CMakeLists.txt @@ -32,6 +32,7 @@ set(COMMON_UI_SRC iface_lists.c ssl_key_export.c text_import.c + time_shift.c util.c ) diff --git a/ui/Makefile.common b/ui/Makefile.common index 5a8c96d1da..04bffdb03b 100644 --- a/ui/Makefile.common +++ b/ui/Makefile.common @@ -53,6 +53,7 @@ WIRESHARK_UI_SRC = \ help_url.c \ ssl_key_export.c \ text_import.c \ + time_shift.c \ util.c noinst_HEADERS = \ @@ -71,6 +72,7 @@ noinst_HEADERS = \ ssl_key_export.h \ text_import.h \ text_import_scanner.h \ + time_shift.h \ ui_util.h \ utf8_entities.h \ util.h diff --git a/ui/gtk/dlg_utils.h b/ui/gtk/dlg_utils.h index 725bebbe39..618b6b2fce 100644 --- a/ui/gtk/dlg_utils.h +++ b/ui/gtk/dlg_utils.h @@ -79,6 +79,7 @@ #define DLG_OUTER_MARGIN 11 #define DLG_BUTTON_SPACING 7 +#define DLG_LABEL_SPACING 5 #define DLG_UNRELATED_SPACING 11 /* elif defined (__APPLE__) */ @@ -88,6 +89,7 @@ #define DLG_OUTER_MARGIN 12 #define DLG_BUTTON_SPACING 6 +#define DLG_LABEL_SPACING 4 /* Not specified. Guessing. */ #define DLG_UNRELATED_SPACING 12 #endif diff --git a/ui/gtk/time_shift_dlg.c b/ui/gtk/time_shift_dlg.c index dc80cb58ac..0ce0db04fb 100644 --- a/ui/gtk/time_shift_dlg.c +++ b/ui/gtk/time_shift_dlg.c @@ -25,24 +25,19 @@ #include "config.h" -#include -#include -#include +#include "globals.h" #include #include #include -#include #include #include -#include "../globals.h" - +#include "ui/time_shift.h" #include "ui/alert_box.h" #include "ui/simple_dialog.h" #include "ui/main_statusbar.h" -#include "ui/ui_util.h" #include "ui/gtk/gui_utils.h" #include "ui/gtk/time_shift_dlg.h" @@ -72,14 +67,6 @@ static void time_shift_frame_destroy_cb(GtkWidget *win, gpointer user_data); static void error_message(const gchar *msg); -#define SHIFT_POS 0 -#define SHIFT_NEG 1 -#define SHIFT_SETTOZERO 1 -#define SHIFT_KEEPOFFSET 0 -static void modify_time_init(frame_data *fd); -static void modify_time_perform(frame_data *fd, int neg, nstime_t *offset, - int settozero); - /* * Keep a static pointer to the current "Time Shift" window, if any, so * that if somebody tries to do "Time Shift" while there's already a @@ -91,8 +78,8 @@ static GtkWidget *time_shift_frame_w; void time_shift_cb(GtkWidget *w _U_, gpointer d _U_) { - GtkWidget *main_vb, *main_hb, *label, - *types_frame, *types_vb, + GtkWidget *main_vb, *label, + *types_vb, *indent, *timeshift_offset_hb, *timeshift_offset_text_box, @@ -114,6 +101,8 @@ time_shift_cb(GtkWidget *w _U_, gpointer d _U_) *adjtime_rb, *undo_rb, *bbox, *apply_bt, *close_bt, *help_bt; + GString * frame_str = g_string_new(""); + gint rb_size = 0, rb_spacing = 0, indent_width = 0; if (time_shift_frame_w != NULL) { /* There's already a "Time Shift" dialog box; reactivate it. */ @@ -122,53 +111,44 @@ time_shift_cb(GtkWidget *w _U_, gpointer d _U_) } time_shift_frame_w = dlg_window_new("Wireshark: Time Shift"); + gtk_container_set_border_width (GTK_CONTAINER (time_shift_frame_w), DLG_OUTER_MARGIN); /* Container for each row of widgets */ - main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE); - gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5); + main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, DLG_UNRELATED_SPACING, FALSE); gtk_container_add(GTK_CONTAINER(time_shift_frame_w), main_vb); - gtk_widget_show(main_vb); /* * Shift All Packets frame */ - main_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE); - gtk_box_pack_start(GTK_BOX(main_vb), main_hb, TRUE, TRUE, 0); - gtk_widget_show(main_hb); - - types_frame = gtk_frame_new(NULL); - gtk_box_pack_start(GTK_BOX(main_hb), types_frame, TRUE, TRUE, 0); - gtk_widget_show(types_frame); - - types_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE); - gtk_container_set_border_width(GTK_CONTAINER(types_vb), 3); - gtk_container_add(GTK_CONTAINER(types_frame), types_vb); - gtk_widget_show(types_vb); + types_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, DLG_LABEL_SPACING, FALSE); + gtk_container_add(GTK_CONTAINER(main_vb), types_vb); /* Radio button row */ - timeshift_offset_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE); + timeshift_offset_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DLG_BUTTON_SPACING, FALSE); gtk_box_pack_start(GTK_BOX(types_vb), timeshift_offset_hb, FALSE, FALSE, 0); - gtk_widget_show(timeshift_offset_hb); timeshift_rb = gtk_radio_button_new_with_label (NULL, "Shift all packets"); gtk_box_pack_start(GTK_BOX(timeshift_offset_hb), timeshift_rb, TRUE, TRUE, 0); - gtk_widget_show(timeshift_rb); gtk_widget_set_tooltip_text(timeshift_rb, "Shift the time on the frames."); + gtk_widget_style_get(timeshift_rb, "indicator-size", &rb_size, + "indicator-spacing", &rb_spacing, NULL); + indent_width += rb_size + rb_spacing; /* Time Shift entry row */ - timeshift_offset_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE); + timeshift_offset_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DLG_BUTTON_SPACING, FALSE); gtk_box_pack_start(GTK_BOX(types_vb), timeshift_offset_hb, FALSE, FALSE, 0); - gtk_widget_show(timeshift_offset_hb); + + indent = gtk_alignment_new(0,0,0,0); + gtk_widget_set_size_request(indent, indent_width, -1); + gtk_box_pack_start(GTK_BOX(timeshift_offset_hb), indent, FALSE, FALSE, 0); label = gtk_label_new("Time offset in the format [+-][[hh:]mm:]ss[.ddd]"); gtk_box_pack_start(GTK_BOX(timeshift_offset_hb), label, FALSE, FALSE, 0); - gtk_widget_show(label); timeshift_offset_text_box = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(timeshift_offset_hb), timeshift_offset_text_box, TRUE, TRUE, 0); - gtk_widget_show(timeshift_offset_text_box); gtk_widget_set_tooltip_text(timeshift_offset_text_box, "Enter the time to shift here. The format is " "[+-][[hh:]mm:]ss.[.ddddddddd]."); @@ -176,64 +156,59 @@ time_shift_cb(GtkWidget *w _U_, gpointer d _U_) /* * Set Packet Number to Time frame */ - main_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE); - gtk_box_pack_start(GTK_BOX(main_vb), main_hb, TRUE, TRUE, 0); - gtk_widget_show(main_hb); - - types_frame = gtk_frame_new(NULL); - gtk_box_pack_start(GTK_BOX(main_hb), types_frame, TRUE, TRUE, 0); - gtk_widget_show(types_frame); - - types_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE); - gtk_container_set_border_width(GTK_CONTAINER(types_vb), 3); - gtk_container_add(GTK_CONTAINER(types_frame), types_vb); - gtk_widget_show(types_vb); + types_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, DLG_LABEL_SPACING, FALSE); + gtk_container_add(GTK_CONTAINER(main_vb), types_vb); /* time shift type row */ - settime_time_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE); + settime_time_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DLG_BUTTON_SPACING, FALSE); gtk_box_pack_start(GTK_BOX(types_vb), settime_time_hb, FALSE, FALSE, 0); - gtk_widget_show(settime_time_hb); settime_rb = gtk_radio_button_new_with_label(gtk_radio_button_get_group( GTK_RADIO_BUTTON(timeshift_rb)), "Set packet to time"); gtk_box_pack_start(GTK_BOX(settime_time_hb), settime_rb, TRUE, TRUE, 0); - gtk_widget_show(settime_rb); gtk_widget_set_tooltip_text(settime_rb, "Set the time of a certain frame and adjust the rest of the frames " "automatically."); - settime_time_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE); + settime_time_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DLG_BUTTON_SPACING, FALSE); gtk_box_pack_start(GTK_BOX(types_vb), settime_time_hb, FALSE, FALSE, 0); - gtk_widget_show(settime_time_hb); + + indent = gtk_alignment_new(0,0,0,0); + gtk_widget_set_size_request(indent, indent_width, -1); + gtk_box_pack_start(GTK_BOX(settime_time_hb), indent, FALSE, FALSE, 0); label = gtk_label_new("Packet number"); gtk_box_pack_start(GTK_BOX(settime_time_hb), label, FALSE, FALSE, 0); - gtk_widget_show(label); + if (cfile.current_frame) { + g_string_printf(frame_str, "%u", cfile.current_frame->num); + } else { + g_string_printf(frame_str, "%u", cfile.first_displayed); + } settime_packetnumber_text_box = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(settime_time_hb), settime_packetnumber_text_box, TRUE, TRUE, 0); - gtk_entry_set_text(GTK_ENTRY(settime_packetnumber_text_box), ""); - gtk_widget_show(settime_packetnumber_text_box); + gtk_entry_set_text(GTK_ENTRY(settime_packetnumber_text_box), frame_str->str); gtk_widget_set_tooltip_text(settime_packetnumber_text_box, "The frame which will be set to the time."); /* time shift row */ - settime_time_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE); + settime_time_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DLG_BUTTON_SPACING, FALSE); gtk_box_pack_start(GTK_BOX(types_vb), settime_time_hb, FALSE, FALSE, 0); - gtk_widget_show(settime_time_hb); + + indent = gtk_alignment_new(0,0,0,0); + gtk_widget_set_size_request(indent, indent_width, -1); + gtk_box_pack_start(GTK_BOX(settime_time_hb), indent, FALSE, FALSE, 0); label = gtk_label_new("Set packet to time [YYYY-MM-DD] hh:mm:ss[.ddd]"); gtk_box_pack_start(GTK_BOX(settime_time_hb), label, FALSE, FALSE, 0); - gtk_widget_show(label); settime_time_text_box = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(settime_time_hb), settime_time_text_box, TRUE, TRUE, 0); - gtk_widget_show(settime_time_text_box); gtk_widget_set_tooltip_text(settime_time_text_box, "The time for the frame in the format of [YYYY-MM-DD] " "hh:mm:ss[.ddddddddd]"); @@ -241,100 +216,93 @@ time_shift_cb(GtkWidget *w _U_, gpointer d _U_) /* * Set two Packet Numbers to Time frame and extrapolate */ - main_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE); - gtk_box_pack_start(GTK_BOX(main_vb), main_hb, TRUE, TRUE, 0); - gtk_widget_show(main_hb); - - types_frame = gtk_frame_new(NULL); - gtk_box_pack_start(GTK_BOX(main_hb), types_frame, TRUE, TRUE, 0); - gtk_widget_show(types_frame); - - types_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE); - gtk_container_set_border_width(GTK_CONTAINER(types_vb), 3); - gtk_container_add(GTK_CONTAINER(types_frame), types_vb); - gtk_widget_show(types_vb); + types_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, DLG_LABEL_SPACING, FALSE); + gtk_container_add(GTK_CONTAINER(main_vb), types_vb); /* packet number row 1 */ - adjtime_offset_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE); + adjtime_offset_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DLG_BUTTON_SPACING, FALSE); gtk_box_pack_start(GTK_BOX(types_vb), adjtime_offset_hb, FALSE, FALSE, 0); - gtk_widget_show(adjtime_offset_hb); adjtime_rb = gtk_radio_button_new_with_label(gtk_radio_button_get_group( GTK_RADIO_BUTTON(timeshift_rb)), "Set packets to time and extrapolate"); gtk_box_pack_start(GTK_BOX(adjtime_offset_hb), adjtime_rb, TRUE, TRUE, 0); - gtk_widget_show(adjtime_rb); gtk_widget_set_tooltip_text(adjtime_rb, "Set the time of two frames and adjust the rest of the frames " "automatically."); - adjtime_offset_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE); + adjtime_offset_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DLG_BUTTON_SPACING, FALSE); gtk_box_pack_start(GTK_BOX(types_vb), adjtime_offset_hb, FALSE, FALSE, 0); - gtk_widget_show(adjtime_offset_hb); + + indent = gtk_alignment_new(0,0,0,0); + gtk_widget_set_size_request(indent, indent_width, -1); + gtk_box_pack_start(GTK_BOX(adjtime_offset_hb), indent, FALSE, FALSE, 0); label = gtk_label_new("Packet number"); gtk_box_pack_start(GTK_BOX(adjtime_offset_hb), label, FALSE, FALSE, 0); - gtk_widget_show(label); adjtime_packetnumber1_text_box = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(adjtime_offset_hb), adjtime_packetnumber1_text_box, TRUE, TRUE, 0); - gtk_entry_set_text(GTK_ENTRY(adjtime_packetnumber1_text_box), ""); - gtk_widget_show(adjtime_packetnumber1_text_box); + gtk_entry_set_text(GTK_ENTRY(adjtime_packetnumber1_text_box), frame_str->str); gtk_widget_set_tooltip_text(adjtime_packetnumber1_text_box, "The frame which will be set to the time."); /* time shift row */ - adjtime_offset_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE); + adjtime_offset_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DLG_BUTTON_SPACING, FALSE); gtk_box_pack_start(GTK_BOX(types_vb), adjtime_offset_hb, FALSE, FALSE, 0); - gtk_widget_show(adjtime_offset_hb); + + indent = gtk_alignment_new(0,0,0,0); + gtk_widget_set_size_request(indent, indent_width, -1); + gtk_box_pack_start(GTK_BOX(adjtime_offset_hb), indent, FALSE, FALSE, 0); label = gtk_label_new("Set packet to time [YYYY-MM-DD] hh:mm:ss[.ddd]"); gtk_box_pack_start(GTK_BOX(adjtime_offset_hb), label, FALSE, FALSE, 0); - gtk_widget_show(label); adjtime_time1_text_box = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(adjtime_offset_hb), adjtime_time1_text_box, TRUE, TRUE, 0); gtk_entry_set_text(GTK_ENTRY(adjtime_time1_text_box), ""); - gtk_widget_show(adjtime_time1_text_box); gtk_widget_set_tooltip_text(adjtime_time1_text_box, "The time for the frame in the format of [YYYY-MM-DD] " "hh:mm:ss[.ddddddddd]"); /* packet number row 2 */ - adjtime_offset_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE); + adjtime_offset_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DLG_BUTTON_SPACING, FALSE); gtk_box_pack_start(GTK_BOX(types_vb), adjtime_offset_hb, FALSE, FALSE, 0); - gtk_widget_show(adjtime_offset_hb); + + indent = gtk_alignment_new(0,0,0,0); + gtk_widget_set_size_request(indent, indent_width, -1); + gtk_box_pack_start(GTK_BOX(adjtime_offset_hb), indent, FALSE, FALSE, 0); label = gtk_label_new("Packet number"); gtk_box_pack_start(GTK_BOX(adjtime_offset_hb), label, FALSE, FALSE, 0); - gtk_widget_show(label); + g_string_printf(frame_str, "%u", cfile.last_displayed); adjtime_packetnumber2_text_box = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(adjtime_offset_hb), adjtime_packetnumber2_text_box, TRUE, TRUE, 0); - gtk_entry_set_text(GTK_ENTRY(adjtime_packetnumber2_text_box), ""); - gtk_widget_show(adjtime_packetnumber2_text_box); + gtk_entry_set_text(GTK_ENTRY(adjtime_packetnumber2_text_box), frame_str->str); gtk_widget_set_tooltip_text(adjtime_packetnumber2_text_box, "The frame which will be set to the time."); /* time shift row */ - adjtime_offset_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE); + adjtime_offset_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DLG_BUTTON_SPACING, FALSE); gtk_box_pack_start(GTK_BOX(types_vb), adjtime_offset_hb, FALSE, FALSE, 0); - gtk_widget_show(adjtime_offset_hb); + + indent = gtk_alignment_new(0,0,0,0); + gtk_widget_set_size_request(indent, indent_width, -1); + gtk_box_pack_start(GTK_BOX(adjtime_offset_hb), indent, FALSE, FALSE, 0); label = gtk_label_new("Set packet to time [YYYY-MM-DD] hh:mm:ss[.ddd]"); gtk_box_pack_start(GTK_BOX(adjtime_offset_hb), label, FALSE, FALSE, 0); - gtk_widget_show(label); adjtime_time2_text_box = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(adjtime_offset_hb), adjtime_time2_text_box, TRUE, TRUE, 0); gtk_entry_set_text(GTK_ENTRY(adjtime_time2_text_box), ""); - gtk_widget_show(adjtime_time2_text_box); gtk_widget_set_tooltip_text(adjtime_time2_text_box, "The time for the frame in the format of [YYYY-MM-DD] " "hh:mm:ss[.ddddddddd]"); @@ -342,34 +310,21 @@ time_shift_cb(GtkWidget *w _U_, gpointer d _U_) /* * Undo all shifts */ - main_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE); - gtk_box_pack_start(GTK_BOX(main_vb), main_hb, TRUE, TRUE, 0); - gtk_widget_show(main_hb); - - types_frame = gtk_frame_new(NULL); - gtk_box_pack_start(GTK_BOX(main_hb), types_frame, TRUE, TRUE, 0); - gtk_widget_show(types_frame); - - types_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE); - gtk_container_set_border_width(GTK_CONTAINER(types_vb), 3); - gtk_container_add(GTK_CONTAINER(types_frame), types_vb); - gtk_widget_show(types_vb); + types_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, DLG_LABEL_SPACING, FALSE); + gtk_container_add(GTK_CONTAINER(main_vb), types_vb); /* time shift type row */ - undo_type_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE); + undo_type_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DLG_BUTTON_SPACING, FALSE); gtk_box_pack_start(GTK_BOX(types_vb), undo_type_hb, TRUE, TRUE, 0); - gtk_widget_show(undo_type_hb); /* time shift row */ - undo_offset_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE); + undo_offset_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DLG_BUTTON_SPACING, FALSE); gtk_box_pack_start(GTK_BOX(types_vb), undo_offset_hb, FALSE, FALSE, 0); - gtk_widget_show(undo_offset_hb); undo_rb = gtk_radio_button_new_with_label(gtk_radio_button_get_group( GTK_RADIO_BUTTON(timeshift_rb)), "Undo all shifts"); gtk_box_pack_start(GTK_BOX(undo_offset_hb), undo_rb, TRUE, TRUE, 0); - gtk_widget_show(undo_rb); gtk_widget_set_tooltip_text(undo_rb, "Undo all the Time Shift offsets on the frames."); @@ -379,7 +334,6 @@ time_shift_cb(GtkWidget *w _U_, gpointer d _U_) bbox = dlg_button_row_new(GTK_STOCK_APPLY, GTK_STOCK_CLOSE, GTK_STOCK_HELP, NULL); gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0); - gtk_widget_show(bbox); apply_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_APPLY); g_signal_connect(apply_bt, "clicked", G_CALLBACK(time_shift_apply_cb), @@ -388,9 +342,10 @@ time_shift_cb(GtkWidget *w _U_, gpointer d _U_) "Apply the Time Shift options to the frame data."); close_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE); + window_set_cancel_button(time_shift_frame_w, close_bt, window_cancel_button_cb); g_signal_connect(close_bt, "clicked", G_CALLBACK(time_shift_close_cb), time_shift_frame_w); - gtk_widget_set_tooltip_text(close_bt, "Close this dialogbox."); + gtk_widget_set_tooltip_text(close_bt, "Close this dialog box."); help_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP); g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), @@ -430,25 +385,24 @@ time_shift_cb(GtkWidget *w _U_, gpointer d _U_) g_signal_connect(time_shift_frame_w, "destroy", G_CALLBACK(time_shift_frame_destroy_cb), NULL); - gtk_widget_show(time_shift_frame_w); + g_string_free(frame_str, TRUE); + gtk_widget_show_all(time_shift_frame_w); window_present(time_shift_frame_w); } static void error_message(const gchar *msg) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", msg); + if (msg) + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", msg); } -static int action_timeshift(GtkWindow *parent_w); -static void action_settime(GtkWindow *parent_w); -static void action_adjtime(GtkWindow *parent_w); -static void action_undo(GtkWindow *parent_w); - static void time_shift_apply_cb(GtkWidget *ok_bt _U_, GtkWindow *parent_w) { - GtkWidget *flag_rb; + GtkWidget *flag_rb, *offset_te, *packetnumber_te, *time_te; + const gchar *offset_text, *time_text, *time2_text; + guint packet_num, packet2_num; if (cfile.state == FILE_CLOSED) { /* Nothing to do here */ @@ -463,457 +417,54 @@ time_shift_apply_cb(GtkWidget *ok_bt _U_, GtkWindow *parent_w) flag_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_TIMESHIFT_SELECT); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(flag_rb)) == TRUE) { - action_timeshift(parent_w); + offset_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), + E_TIMESHIFT_OFFSET_KEY); + offset_text = gtk_entry_get_text(GTK_ENTRY(offset_te)); + error_message(time_shift_all(&cfile, offset_text)); return; } flag_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_SETTIME_SELECT); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(flag_rb)) == TRUE) { - action_settime(parent_w); + packetnumber_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), + E_SETTIME_PACKETNUMBER_KEY); + packet_num = strtol((char *)gtk_entry_get_text(GTK_ENTRY(packetnumber_te)), NULL, 10); + time_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), + E_SETTIME_TIME_KEY); + time_text = gtk_entry_get_text(GTK_ENTRY(time_te)); + error_message(time_shift_settime(&cfile, packet_num, time_text)); return; } flag_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_ADJTIME_SELECT); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(flag_rb)) == TRUE) { - action_adjtime(parent_w); + packetnumber_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), + E_ADJTIME_PACKETNUMBER1_KEY); + packet_num = strtol((char *)gtk_entry_get_text(GTK_ENTRY(packetnumber_te)), NULL, 10); + time_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), + E_ADJTIME_TIME1_KEY); + time_text = gtk_entry_get_text(GTK_ENTRY(time_te)); + + packetnumber_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), + E_ADJTIME_PACKETNUMBER2_KEY); + packet2_num = strtol((char *)gtk_entry_get_text(GTK_ENTRY(packetnumber_te)), NULL, 10); + time_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), + E_ADJTIME_TIME2_KEY); + time2_text = gtk_entry_get_text(GTK_ENTRY(time_te)); + + error_message(time_shift_adjtime(&cfile, packet_num, time_text, packet2_num, time2_text)); return; } flag_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_UNDO_SELECT); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(flag_rb)) == TRUE) { - action_undo(parent_w); + error_message(time_shift_undo(&cfile)); return; } } -#define CHECK_YEARS(Y) \ - if (Y < 1970) { \ - error_message("years must be larger than 1970"); \ - return(1); \ - } -#define CHECK_MONTHS(M) \ - if (M < 1 || M > 12) { \ - error_message("months must be between [1..12]"); \ - return(1); \ - } -#define CHECK_DAYS(D) \ - if (D < 1 || D > 31) { \ - error_message("days must be between [1..31]"); \ - return(1); \ - } -#define CHECK_HOURS(h) \ - if (h < 0 || h > 23) { \ - error_message("hours must be between [0..23]"); \ - return(1); \ - } -#define CHECK_HOUR(h) \ - if (h < 0) { \ - error_message("negative hours, you have have specified more than " \ - "one minus character?"); \ - return(1); \ - } \ - offset_float += h * 3600 -#define CHECK_MINUTE(m) \ - if (m < 0 || m > 59) { \ - error_message("minutes must be between [0..59]"); \ - return(1); \ - } \ - offset_float += m * 60 -#define CHECK_SECOND(s) \ - if (s < 0 || s > 59) { \ - error_message("seconds must be between [0..59]"); \ - return(1); \ - } \ - offset_float += s -#define CHECK_SEC_DEC(f) \ - if (f < 0) { \ - error_message("fractional seconds must be > 0"); \ - return(1); \ - } \ - offset_float += f - -static int -action_timeshift(GtkWindow *parent_w) -{ - GtkWidget *offset_te; - const gchar *offset_text; - gchar *poffset_text; - nstime_t offset; - long double offset_float = 0; - guint32 i; - frame_data *fd; - int neg; - int h, m; - long double f; - - /* - * The following offset types are allowed: - * -?((hh:)mm:)ss(.decimals)? - * - * Since Wireshark doesn't support regular expressions (please prove me - * wrong :-) we will have to figure it out ourselves in the - * following order: - * - * 1. hh:mm:ss.decimals - * 2. mm:ss.decimals - * 3. ss.decimals - * - */ - - offset_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), - E_TIMESHIFT_OFFSET_KEY); - offset_text = gtk_entry_get_text(GTK_ENTRY(offset_te)); - poffset_text = (gchar *)offset_text; - - /* strip whitespace */ - while (isspace(poffset_text[0])) - ++poffset_text; - - /* check for minus sign */ - neg = FALSE; - if (poffset_text[0] == '-') { - neg = TRUE; - poffset_text++; - } - - /* check for empty string */ - if (poffset_text[0] == '\0') - return(1); - - h = m = 0; - f = 0.0; - if (sscanf(poffset_text, "%d:%d:%Lf", &h, &m, &f) == 3) { - /* printf("%%d:%%d:%%d.%%d\n"); */ - CHECK_HOUR(h); - CHECK_MINUTE(m); - CHECK_SEC_DEC(f); - } else if (sscanf(poffset_text, "%d:%Lf", &m, &f) == 2) { - /* printf("%%d:%%d.%%d\n"); */ - CHECK_MINUTE(m); - CHECK_SEC_DEC(f); - } else if (sscanf(poffset_text, "%Lf", &f) == 1) { - /* printf("%%d.%%d\n"); */ - CHECK_SEC_DEC(f); - } else { - error_message("Could not parse the time: Expected ((hh:)mm:)ss.(dec)."); - return(1); - } - - if (offset_float == 0) - return(1); - - nstime_set_zero(&offset); - offset.secs = (time_t)floorl(offset_float); - offset_float -= offset.secs; - offset.nsecs = (int)(offset_float * 1000000000); - - if ((fd = frame_data_sequence_find(cfile.frames, 1)) == NULL) - return(1); /* Shouldn't happen */ - modify_time_init(fd); - - for (i = 1; i <= cfile.count; i++) { - if ((fd = frame_data_sequence_find(cfile.frames, i)) == NULL) - continue; /* Shouldn't happen */ - modify_time_perform(fd, neg, &offset, SHIFT_KEEPOFFSET); - } - packet_list_queue_draw(); - - return(0); -} - -static int -timestring2nstime(const gchar *ts, nstime_t *packettime, nstime_t *nstime) -{ - gchar *pts; - int h, m, Y, M, D; - long double f; - struct tm tm, *tmptm; - time_t tt; - long double offset_float = 0; - - /* - * The following time format is allowed: - * [YYYY-MM-DD] hh:mm:ss(.decimals)? - * - * Since Wireshark doesn't support regular expressions (please prove me - * wrong :-) we will have to figure it out ourselves in the - * following order: - * - * 1. YYYY-MM-DD hh:mm:ss.decimals - * 2. hh:mm:ss.decimals - * - */ - - pts = (gchar *)ts; - - /* strip whitespace */ - while (isspace(pts[0])) - ++pts; - - /* check for empty string */ - if (pts[0] == '\0') - return(1); - - if (sscanf(pts, "%d-%d-%d %d:%d:%Lf", &Y, &M, &D, &h, &m, &f) == 6) { - /* printf("%%d-%%d-%%d %%d:%%d:%%f\n"); */ - CHECK_YEARS(Y); - CHECK_MONTHS(M); - CHECK_DAYS(D); - CHECK_HOURS(h); - CHECK_MINUTE(m); - CHECK_SEC_DEC(f); - } else if (sscanf(pts, "%d:%d:%Lf", &h, &m, &f) == 3) { - /* printf("%%d:%%d:%%f\n"); */ - Y = M = D = 0; - CHECK_HOUR(h); - CHECK_MINUTE(m); - CHECK_SEC_DEC(f); - } else { - error_message("Could not parse the time: Expected (YYYY-MM-DD) " - "hh:mm:ss(.dec)"); - return(1); - } - - /* Convert the time entered in an epoch offset */ - tmptm = localtime(&(packettime->secs)); - if (tmptm) { - tm = *tmptm; - } else { - memset (&tm, 0, sizeof (tm)); - } - if (Y != 0) { - tm.tm_year = Y - 1900; - tm.tm_mon = M - 1; - tm.tm_mday = D; - } - tm.tm_hour = h; - tm.tm_min = m; - tm.tm_sec = (int)floorl(f); - tt = mktime(&tm); - if (tt == -1) { - error_message("mktime went wrong. Was the time invalid?"); - return(1); - } - - nstime->secs = tt; - f -= tm.tm_sec; - nstime->nsecs = (int)(f * 1000000000); - - return(0); -} - -static void -action_settime(GtkWindow *parent_w) -{ - GtkWidget *packetnumber_te; - const gchar *packetnumber_text; - long packetnumber; - GtkWidget *time_te; - const gchar *time_text; - nstime_t set_time, diff_time, packet_time; - frame_data *fd, *packetfd; - guint32 i; - - packetnumber_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), - E_SETTIME_PACKETNUMBER_KEY); - packetnumber_text = gtk_entry_get_text(GTK_ENTRY(packetnumber_te)); - packetnumber = strtol((char *)packetnumber_text, NULL, 10); - - time_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), - E_SETTIME_TIME_KEY); - time_text = gtk_entry_get_text(GTK_ENTRY(time_te)); - - /* - * Get a copy of the real time (abs_ts - shift_offset) do we can find out the - * difference between the specified time and the original packet - */ - if ((packetfd = frame_data_sequence_find(cfile.frames, packetnumber)) == NULL) - return; - nstime_delta(&packet_time, &(packetfd->abs_ts), &(packetfd->shift_offset)); - - if (timestring2nstime(time_text, &packet_time, &set_time) != 0) - return; - - /* Calculate difference between packet time and requested time */ - nstime_delta(&diff_time, &set_time, &packet_time); - - /* Up to here nothing is changed */ - - if ((fd = frame_data_sequence_find(cfile.frames, 1)) == NULL) - return; /* Shouldn't happen */ - modify_time_init(fd); - - /* Set everything back to the original time */ - for (i = 1; i <= cfile.count; i++) { - if ((fd = frame_data_sequence_find(cfile.frames, i)) == NULL) - continue; /* Shouldn't happen */ - modify_time_perform(fd, SHIFT_POS, &diff_time, SHIFT_SETTOZERO); - } - - packet_list_queue_draw(); -} - -/* - * If the line between (OT1, NT1) and (OT2, NT2) is a straight line - * and (OT3, NT3) is on that line, - * then (NT2 - NT1) / (OT2 - OT2) = (NT3 - NT1) / (OT3 - OT1) and - * then (OT3 - OT1) * (NT2 - NT1) / (OT2 - OT2) = (NT3 - NT1) and - * then NT1 + (OT3 - OT1) * (NT2 - NT1) / (OT2 - OT2) = NT3 and - * then NT3 = NT1 + (OT3 - OT1) * (NT2 - NT1) / (OT2 - OT2) and - * thus NT3 = NT1 + (OT3 - OT1) * (NT2 - NT1) / (OT2 - OT1) - * or NT3 = NT1 + (OT3 - OT1) * ( deltaNT12 / deltaOT12) - * - * All the things you come up when waiting for the train to come... - */ -static void -calcNT3(nstime_t *OT1, nstime_t *OT3, nstime_t *NT1, nstime_t *NT3, - nstime_t *deltaOT, nstime_t *deltaNT) -{ - long double fnt, fot, f, secs, nsecs; - - fnt = (long double)deltaNT->secs + (deltaNT->nsecs / 1000000000.0L); - fot = (long double)deltaOT->secs + (deltaOT->nsecs / 1000000000.0L); - f = fnt / fot; - - nstime_copy(NT3, OT3); - nstime_subtract(NT3, OT1); - - secs = f * (long double)NT3->secs; - nsecs = f * (long double)NT3->nsecs; - nsecs += (secs - floorl(secs)) * 1000000000.0L; - while (nsecs > 1000000000L) { - secs += 1; - nsecs -= 1000000000L; - } - while (nsecs < 0) { - secs -= 1; - nsecs += 1000000000L; - } - NT3->secs = (time_t)secs; - NT3->nsecs = (int)nsecs; - nstime_add(NT3, NT1); -} - -static void -action_adjtime(GtkWindow *parent_w _U_) -{ - GtkWidget *packetnumber_te; - const gchar *packetnumber_text; - long packetnumber1, packetnumber2; - GtkWidget *time_te; - const gchar *time1_text, *time2_text; - nstime_t nt1, nt2, ot1, ot2, nt3; - nstime_t dnt, dot, d3t; - frame_data *fd, *packet1fd, *packet2fd; - guint32 i; - - packetnumber_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), - E_ADJTIME_PACKETNUMBER1_KEY); - packetnumber_text = gtk_entry_get_text(GTK_ENTRY(packetnumber_te)); - packetnumber1 = strtol((char *)packetnumber_text, NULL, 10); - packetnumber_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), - E_ADJTIME_PACKETNUMBER2_KEY); - packetnumber_text = gtk_entry_get_text(GTK_ENTRY(packetnumber_te)); - packetnumber2 = strtol((char *)packetnumber_text, NULL, 10); - - /* - * The following time format is allowed: - * [YYYY-MM-DD] hh:mm:ss(.decimals)? - * - * Since Wireshark doesn't support regular expressions (please prove me - * wrong :-) we will have to figure it out ourselves in the - * following order: - * - * 1. YYYY-MM-DD hh:mm:ss.decimals - * 2. hh:mm:ss.decimals - * - */ - - time_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), - E_ADJTIME_TIME1_KEY); - time1_text = gtk_entry_get_text(GTK_ENTRY(time_te)); - time_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), - E_ADJTIME_TIME2_KEY); - time2_text = gtk_entry_get_text(GTK_ENTRY(time_te)); - - /* - * Get a copy of the real time (abs_ts - shift_offset) do we can find out the - * difference between the specified time and the original packet - */ - if ((packet1fd = frame_data_sequence_find(cfile.frames, packetnumber1)) == NULL) - return; - nstime_copy(&ot1, &(packet1fd->abs_ts)); - nstime_subtract(&ot1, &(packet1fd->shift_offset)); - - if (timestring2nstime(time1_text, &ot1, &nt1) != 0) - return; - - /* - * Get a copy of the real time (abs_ts - shift_offset) do we can find out the - * difference between the specified time and the original packet - */ - if ((packet2fd = frame_data_sequence_find(cfile.frames, packetnumber2)) == NULL) - return; - nstime_copy(&ot2, &(packet2fd->abs_ts)); - nstime_subtract(&ot2, &(packet2fd->shift_offset)); - - if (timestring2nstime(time2_text, &ot2, &nt2) != 0) - return; - - nstime_copy(&dot, &ot2); - nstime_subtract(&dot, &ot1); - - nstime_copy(&dnt, &nt2); - nstime_subtract(&dnt, &nt1); - - /* Up to here nothing is changed */ - if ((fd = frame_data_sequence_find(cfile.frames, 1)) == NULL) - return; /* Shouldn't happen */ - modify_time_init(fd); - - for (i = 1; i <= cfile.count; i++) { - if ((fd = frame_data_sequence_find(cfile.frames, i)) == NULL) - continue; /* Shouldn't happen */ - - /* Set everything back to the original time */ - nstime_subtract(&(fd->abs_ts), &(fd->shift_offset)); - nstime_set_zero(&(fd->shift_offset)); - - /* Add the difference to each packet */ - calcNT3(&ot1, &(fd->abs_ts), &nt1, &nt3, &dot, &dnt); - - nstime_copy(&d3t, &nt3); - nstime_subtract(&d3t, &(fd->abs_ts)); - - modify_time_perform(fd, SHIFT_POS, &d3t, SHIFT_SETTOZERO); - } - - packet_list_queue_draw(); -} - -static void -action_undo(GtkWindow *parent_w _U_) -{ - guint32 i; - frame_data *fd; - nstime_t nulltime; - - nulltime.secs = nulltime.nsecs = 0; - - if ((fd = frame_data_sequence_find(cfile.frames, 1)) == NULL) - return; /* Shouldn't happen */ - modify_time_init(fd); - - for (i = 1; i <= cfile.count; i++) { - if ((fd = frame_data_sequence_find(cfile.frames, i)) == NULL) - continue; /* Shouldn't happen */ - modify_time_perform(fd, SHIFT_NEG, &nulltime, SHIFT_SETTOZERO); - } - packet_list_queue_draw(); -} - static void time_shift_close_cb(GtkWidget *close_bt _U_, gpointer parent_w _U_) { @@ -927,53 +478,3 @@ time_shift_frame_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_) /* Note that we no longer have a "Time Shift" dialog box. */ time_shift_frame_w = NULL; } - -static void -modify_time_init(frame_data *fd) -{ - modify_time_perform(fd, SHIFT_NEG, NULL, SHIFT_KEEPOFFSET); -} - -static void -modify_time_perform(frame_data *fd, int neg, nstime_t *offset, int settozero) -{ - static frame_data *first_packet = NULL; - static nstime_t nulltime; - - /* Only for initializing */ - if (offset == NULL) { - first_packet = fd; - nulltime.secs = nulltime.nsecs = 0; - return; - } - if (first_packet == NULL) { - fprintf(stderr, "modify_time_perform: not initialized?\n"); - return; - } - - /* The actual shift */ - - if (settozero == SHIFT_SETTOZERO) { - nstime_subtract(&(fd->abs_ts), &(fd->shift_offset)); - nstime_copy(&(fd->shift_offset), &nulltime); - } - - if (neg == SHIFT_POS) { - nstime_add(&(fd->abs_ts), offset); - nstime_add(&(fd->shift_offset), offset); - } else if (neg == SHIFT_NEG) { - nstime_subtract(&(fd->abs_ts), offset); - nstime_subtract(&(fd->shift_offset), offset); - } else { - fprintf(stderr, "modify_time_perform: neg = %d?\n", neg); - } - - /* - * rel_ts - Relative timestamp to first packet - */ - if (first_packet != NULL) { - nstime_copy(&(fd->rel_ts), &(fd->abs_ts)); - nstime_subtract(&(fd->rel_ts), &(first_packet->abs_ts)); - } else - nstime_copy(&(fd->rel_ts), &nulltime); -} diff --git a/ui/gtk/time_shift_dlg.h b/ui/gtk/time_shift_dlg.h index 93d4dd12e3..61846b494e 100644 --- a/ui/gtk/time_shift_dlg.h +++ b/ui/gtk/time_shift_dlg.h @@ -25,8 +25,6 @@ #ifndef __TIME_SHIFT_DLG_H__ #define __TIME_SHIFT_DLG_H__ -#include "globals.h" - /** User requested to shift the time of the trace * * @param widget parent widget (unused) diff --git a/ui/qt/QtShark.pro b/ui/qt/QtShark.pro index 31323766af..5381644fae 100644 --- a/ui/qt/QtShark.pro +++ b/ui/qt/QtShark.pro @@ -182,15 +182,16 @@ HEADERS_WS_C = \ ../../wsutil/privileges.h FORMS += main_window.ui \ - main_welcome.ui \ - import_text_dialog.ui \ + export_object_dialog.ui \ file_set_dialog.ui \ - packet_range_group_box.ui \ + import_text_dialog.ui \ + main_welcome.ui \ packet_format_group_box.ui \ - export_object_dialog.ui \ + packet_range_group_box.ui \ print_dialog.ui \ + search_frame.ui \ splash_overlay.ui \ - search_frame.ui + time_shift_dialog.ui win32 { ## These should be in config.pri ?? !isEmpty(PORTAUDIO_DIR) { @@ -214,13 +215,15 @@ win32 { ## These should be in config.pri ?? } HEADERS += $$HEADERS_WS_C \ + accordion_frame.h \ export_dissection_dialog.h \ - packet_format_group_box.h \ export_object_dialog.h \ + packet_format_group_box.h \ print_dialog.h \ - splash_overlay.h \ search_frame.h \ - accordion_frame.h + splash_overlay.h \ + tango_colors.h \ + time_shift_dialog.h win32 { OBJECTS_WS_C = $$SOURCES_WS_C @@ -394,6 +397,7 @@ HEADERS += \ simple_dialog_qt.h \ sparkline_delegate.h \ syntax_line_edit.h \ + time_shift_dialog.h \ wireshark_application.h SOURCES += \ @@ -434,4 +438,5 @@ SOURCES += \ sparkline_delegate.cpp \ splash_overlay.cpp \ syntax_line_edit.cpp \ + time_shift_dialog.cpp \ wireshark_application.cpp diff --git a/ui/qt/label_stack.cpp b/ui/qt/label_stack.cpp index 8480a3eb5e..d1cc1673ba 100644 --- a/ui/qt/label_stack.cpp +++ b/ui/qt/label_stack.cpp @@ -68,8 +68,8 @@ void LabelStack::fillLabel() { " color: #%1;" " background-color: #%2;" ) - .arg(tango_aluminium_6, 6, 16, QChar('0')) - .arg(tango_butter_2, 6, 16, QChar('0')); + .arg(ws_css_warn_text, 6, 16, QChar('0')) + .arg(ws_css_warn_background, 6, 16, QChar('0')); } style_sheet += "}"; diff --git a/ui/qt/main_status_bar.cpp b/ui/qt/main_status_bar.cpp index deaa1829af..4494878053 100644 --- a/ui/qt/main_status_bar.cpp +++ b/ui/qt/main_status_bar.cpp @@ -293,8 +293,8 @@ void MainStatusBar::toggleBackground(bool enabled) " background-color: #%2;" "}" ) - .arg(tango_aluminium_6, 6, 16, QChar('0')) - .arg(tango_butter_2, 6, 16, QChar('0'))); + .arg(ws_css_warn_text, 6, 16, QChar('0')) + .arg(ws_css_warn_background, 6, 16, QChar('0'))); } else { setStyleSheet(""); } diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h index 9a3ea8a619..0082616ab0 100644 --- a/ui/qt/main_window.h +++ b/ui/qt/main_window.h @@ -219,6 +219,7 @@ private slots: void on_actionEditUnsetAllTimeReferences_triggered(); void on_actionEditNextTimeReference_triggered(); void on_actionEditPreviousTimeReference_triggered(); + void on_actionEditTimeShift_triggered(); void on_actionGoGoToPacket_triggered(); void resetPreviousFocus(); diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui index 28341d099e..3f0384227f 100644 --- a/ui/qt/main_window.ui +++ b/ui/qt/main_window.ui @@ -187,6 +187,12 @@ + + + + + + @@ -1114,6 +1120,47 @@ Ctrl+Alt+B + + + Time Shift... + + + Shift or change packet timestamps + + + Ctrl+Shift+T + + + + + Packet Comment... + + + Add or change a packet comment + + + + + Configuration Profiles... + + + Manage configuration profiles + + + Ctrl+Shift+A + + + + + Preferences... + + + Manage Wireshark's preferences + + + Ctrl+Shift+P + + diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp index 3da3bf4037..8d2806d367 100644 --- a/ui/qt/main_window_slots.cpp +++ b/ui/qt/main_window_slots.cpp @@ -62,6 +62,7 @@ #include "capture_file_dialog.h" #include "export_object_dialog.h" #include "print_dialog.h" +#include "time_shift_dialog.h" #include #include @@ -1261,6 +1262,15 @@ void MainWindow::on_actionEditPreviousTimeReference_triggered() cf_find_packet_time_reference(cap_file_, SD_BACKWARD); } +void MainWindow::on_actionEditTimeShift_triggered() +{ + TimeShiftDialog ts_dialog(this, cap_file_); + connect(this, SIGNAL(setCaptureFile(capture_file*)), + &ts_dialog, SLOT(setCaptureFile(capture_file*))); + + ts_dialog.exec(); +} + // View Menu // Expand / collapse slots in proto_tree diff --git a/ui/qt/packet_format_group_box.cpp b/ui/qt/packet_format_group_box.cpp index 511a7d7b22..d28dcce0d0 100644 --- a/ui/qt/packet_format_group_box.cpp +++ b/ui/qt/packet_format_group_box.cpp @@ -2,7 +2,6 @@ #include "ui_packet_format_group_box.h" #include -#include PacketFormatGroupBox::PacketFormatGroupBox(QWidget *parent) : QGroupBox(parent), @@ -10,11 +9,13 @@ PacketFormatGroupBox::PacketFormatGroupBox(QWidget *parent) : { pf_ui_->setupUi(this); + QStyleOption style_opt; + int cb_label_offset = pf_ui_->detailsCheckBox->style()->subElementRect(QStyle::SE_CheckBoxContents, &style_opt).left(); setStyleSheet(QString( "QRadioButton {" " padding-left: %1px;" "}" - ).arg(style()->pixelMetric(QStyle::PM_LayoutLeftMargin))); + ).arg(cb_label_offset)); } PacketFormatGroupBox::~PacketFormatGroupBox() diff --git a/ui/qt/tango_colors.h b/ui/qt/tango_colors.h index da2cf1bf41..7a4432f190 100644 --- a/ui/qt/tango_colors.h +++ b/ui/qt/tango_colors.h @@ -85,4 +85,7 @@ const QRgb tango_sky_blue_4 = 0x3465a4; const QRgb tango_sky_blue_5 = 0x204a87; const QRgb tango_sky_blue_6 = 0x0a3050; +const QRgb ws_css_warn_background = tango_butter_2; +const QRgb ws_css_warn_text = tango_aluminium_6; + #endif // __TANGO_COLORS_H__ diff --git a/ui/qt/time_shift_dialog.cpp b/ui/qt/time_shift_dialog.cpp new file mode 100644 index 0000000000..a662617804 --- /dev/null +++ b/ui/qt/time_shift_dialog.cpp @@ -0,0 +1,298 @@ +/* time_shift_dialog.cpp + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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 "time_shift_dialog.h" +#include "ui_time_shift_dialog.h" + +#include "wireshark_application.h" + +#include +#include "tango_colors.h" + +#include + +#include +TimeShiftDialog::TimeShiftDialog(QWidget *parent, capture_file *cf) : + QDialog(parent), + ts_ui_(new Ui::TimeShiftDialog), + cap_file_(cf), + apply_button_(NULL) +{ + ts_ui_->setupUi(this); + apply_button_ = ts_ui_->buttonBox->button(QDialogButtonBox::Apply); + connect(apply_button_, SIGNAL(clicked()), this, SLOT(applyTimeShift())); + + QStyleOption style_opt; + int rb_label_offset = ts_ui_->shiftAllButton->style()->subElementRect(QStyle::SE_RadioButtonContents, &style_opt).left(); + int cb_label_offset = ts_ui_->shiftAllButton->style()->subElementRect(QStyle::SE_CheckBoxContents, &style_opt).left(); + setStyleSheet(QString( + "QCheckBox#setTwoCheckBox {" + " margin-left: %1px;" + "}" + "QLabel#extrapolateLabel {" + " margin-left: %2px;" + "}" + ) + .arg(rb_label_offset) + .arg(rb_label_offset + cb_label_offset) + ); + + if (cap_file_) { + if (cap_file_->current_frame) { + ts_ui_->setOneFrameLineEdit->setText(QString::number(cap_file_->current_frame->num)); + } else { + ts_ui_->setOneFrameLineEdit->setText(QString::number(cap_file_->first_displayed)); + } + ts_ui_->setTwoFrameLineEdit->setText(QString::number(cap_file_->last_displayed)); + } + + ts_ui_->shiftAllButton->setChecked(true); + ts_ui_->setTwoCheckBox->setChecked(false); + enableWidgets(); +} + +TimeShiftDialog::~TimeShiftDialog() +{ + delete ts_ui_; +} + +void TimeShiftDialog::enableWidgets() +{ + bool enable_two = ts_ui_->setOneButton->isChecked(); + bool enable_ok = false; + + ts_ui_->setTwoCheckBox->setEnabled(enable_two); + ts_ui_->setTwoFrameLineEdit->setEnabled(enable_two); + ts_ui_->setTwoToLabel->setEnabled(enable_two); + ts_ui_->setTwoTimeLineEdit->setEnabled(enable_two); + ts_ui_->extrapolateLabel->setEnabled(enable_two && ts_ui_->setTwoCheckBox->isChecked()); + + if (ts_ui_->shiftAllButton->isChecked()) { + if (ts_ui_->shiftAllTimeLineEdit->syntaxState() == SyntaxLineEdit::Valid) + enable_ok = true; + } else if (ts_ui_->setOneButton->isChecked()) { + bool set_two_valid; + if (ts_ui_->setTwoCheckBox->isChecked()) { + if (ts_ui_->setTwoFrameLineEdit->syntaxState() == SyntaxLineEdit::Valid && + ts_ui_->setTwoTimeLineEdit->syntaxState() == SyntaxLineEdit::Valid) { + set_two_valid = true; + } + } else { + set_two_valid = true; + } + if (set_two_valid && + ts_ui_->setOneFrameLineEdit->syntaxState() == SyntaxLineEdit::Valid && + ts_ui_->setOneTimeLineEdit->syntaxState() == SyntaxLineEdit::Valid) { + enable_ok = true; + } + } else if (ts_ui_->unshiftAllButton->isChecked()) { + enable_ok = true; + } + + if (syntax_err_.isEmpty()) { + ts_ui_->errorLabel->clear(); + ts_ui_->errorLabel->setStyleSheet(" QLabel { margin-top: 0.5em; }"); + } else { + ts_ui_->errorLabel->setText(syntax_err_); + ts_ui_->errorLabel->setStyleSheet(QString( + "QLabel {" + " margin-top: 0.5em;" + " color: #%1;" + " background-color: #%2;" + "}" + ) + .arg(ws_css_warn_text, 6, 16, QChar('0')) + .arg(ws_css_warn_background, 6, 16, QChar('0')) + ); + } + apply_button_->setEnabled(enable_ok); +} + +void TimeShiftDialog::checkFrameNumber(SyntaxLineEdit &frame_le) +{ + bool frame_valid; + guint frame_num = frame_le.text().toUInt(&frame_valid); + + syntax_err_.clear(); + if (frame_le.text().isEmpty()) { + frame_le.setSyntaxState(SyntaxLineEdit::Empty); + } else if (!frame_valid || !cap_file_ || frame_num < 1 || frame_num > cap_file_->count) { + frame_le.setSyntaxState(SyntaxLineEdit::Invalid); + if (cap_file_) { + syntax_err_ = QString(tr("Frame numbers must be between 1 and %1.").arg(cap_file_->count)); + } else { + syntax_err_ = "Invalid frame number."; + } + } else { + frame_le.setSyntaxState(SyntaxLineEdit::Valid); + } +} + +void TimeShiftDialog::checkDateTime(SyntaxLineEdit &time_le) +{ + int Y, M, D, h, m; + long double s; + const gchar *err_str; + + syntax_err_.clear(); + if (time_le.text().isEmpty()) { + time_le.setSyntaxState(SyntaxLineEdit::Empty); + } else if ((err_str = time_string_parse(time_le.text().toUtf8().constData(), + &Y, &M, &D, NULL, &h, &m, &s)) != NULL) { + syntax_err_ = err_str; + time_le.setSyntaxState(SyntaxLineEdit::Invalid); + } else { + time_le.setSyntaxState(SyntaxLineEdit::Valid); + } +} + +void TimeShiftDialog::on_shiftAllButton_toggled(bool checked) +{ + Q_UNUSED(checked); + enableWidgets(); +} + +void TimeShiftDialog::on_setOneButton_toggled(bool checked) +{ + Q_UNUSED(checked); + enableWidgets(); +} + +void TimeShiftDialog::on_unshiftAllButton_toggled(bool checked) +{ + Q_UNUSED(checked); + enableWidgets(); +} + +void TimeShiftDialog::on_setTwoCheckBox_toggled(bool checked) +{ + Q_UNUSED(checked); + enableWidgets(); +} + +void TimeShiftDialog::on_shiftAllTimeLineEdit_textChanged(const QString &sa_text) +{ + int h, m; + long double s; + gboolean neg; + const gchar *err_str; + + syntax_err_.clear(); + if (sa_text.isEmpty()) { + ts_ui_->shiftAllTimeLineEdit->setSyntaxState(SyntaxLineEdit::Empty); + } else if ((err_str = time_string_parse(sa_text.toUtf8().constData(), + NULL, NULL, NULL, &neg, &h, &m, &s)) != NULL) { + syntax_err_ = err_str; + ts_ui_->shiftAllTimeLineEdit->setSyntaxState(SyntaxLineEdit::Invalid); + } else { + ts_ui_->shiftAllTimeLineEdit->setSyntaxState(SyntaxLineEdit::Valid); + } + ts_ui_->shiftAllButton->setChecked(true); + enableWidgets(); +} + +void TimeShiftDialog::on_setOneFrameLineEdit_textChanged(const QString &frame_text) +{ + Q_UNUSED(frame_text); + checkFrameNumber(*ts_ui_->setOneFrameLineEdit); + ts_ui_->setOneButton->setChecked(true); + enableWidgets(); +} +void TimeShiftDialog::on_setOneTimeLineEdit_textChanged(const QString &so_text) +{ + Q_UNUSED(so_text); + checkDateTime(*ts_ui_->setOneTimeLineEdit); + ts_ui_->setOneButton->setChecked(true); + enableWidgets(); +} + +void TimeShiftDialog::on_setTwoFrameLineEdit_textChanged(const QString &frame_text) +{ + Q_UNUSED(frame_text); + Q_UNUSED(frame_text); + checkFrameNumber(*ts_ui_->setTwoFrameLineEdit); + if (ts_ui_->setTwoCheckBox->isEnabled()) + ts_ui_->setTwoCheckBox->setChecked(true); + enableWidgets(); +} + +void TimeShiftDialog::on_setTwoTimeLineEdit_textChanged(const QString &st_text) +{ + Q_UNUSED(st_text); + checkDateTime(*ts_ui_->setTwoTimeLineEdit); + if (ts_ui_->setTwoCheckBox->isEnabled()) + ts_ui_->setTwoCheckBox->setChecked(true); + enableWidgets(); +} + +void TimeShiftDialog::applyTimeShift() +{ + const gchar *err_str = NULL; + + if (!cap_file_ || cap_file_->state == FILE_CLOSED) return; + + syntax_err_.clear(); + if (cap_file_->state == FILE_READ_IN_PROGRESS) { + syntax_err_ = "Time shifting is not available capturing packets."; + } else if (ts_ui_->shiftAllButton->isChecked()) { + err_str = time_shift_all(cap_file_, + ts_ui_->shiftAllTimeLineEdit->text().toUtf8().constData()); + } else if (ts_ui_->setOneButton->isChecked()) { + if (!ts_ui_->setTwoCheckBox->isChecked()) { + err_str = time_shift_settime(cap_file_, + ts_ui_->setOneFrameLineEdit->text().toUInt(), + ts_ui_->setOneTimeLineEdit->text().toUtf8().constData() + ); + } else { + err_str = time_shift_adjtime(cap_file_, + ts_ui_->setOneFrameLineEdit->text().toUInt(), + ts_ui_->setOneTimeLineEdit->text().toUtf8().constData(), + ts_ui_->setTwoFrameLineEdit->text().toUInt(), + ts_ui_->setTwoTimeLineEdit->text().toUtf8().constData() + ); + } + } else if (ts_ui_->unshiftAllButton->isChecked()) { + err_str = time_shift_undo(cap_file_); + } + if (err_str) syntax_err_ = err_str; + enableWidgets(); +} + +void TimeShiftDialog::on_buttonBox_helpRequested() +{ + wsApp->helpTopicAction(HELP_TIME_SHIFT_DIALOG); +} + +/* + * 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/time_shift_dialog.h b/ui/qt/time_shift_dialog.h new file mode 100644 index 0000000000..d150cbfce9 --- /dev/null +++ b/ui/qt/time_shift_dialog.h @@ -0,0 +1,77 @@ +/* time_shift_dialog.h + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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 TIME_SHIFT_DIALOG_H +#define TIME_SHIFT_DIALOG_H + +#include "config.h" + +#include + +#include "cfile.h" + +#include "syntax_line_edit.h" + +#include +#include + +namespace Ui { +class TimeShiftDialog; +} + +class TimeShiftDialog : public QDialog +{ + Q_OBJECT + +public: + explicit TimeShiftDialog(QWidget *parent = 0, capture_file *cf = NULL); + ~TimeShiftDialog(); + +public slots: + void setCaptureFile(capture_file *cf) { cap_file_ = cf; } + +private: + Ui::TimeShiftDialog *ts_ui_; + capture_file *cap_file_; + QPushButton *apply_button_; + QString syntax_err_; + + void enableWidgets(); + void checkFrameNumber(SyntaxLineEdit &frame_le); + void checkDateTime(SyntaxLineEdit &time_le); + +private slots: + void on_shiftAllButton_toggled(bool checked); + void on_setOneButton_toggled(bool checked); + void on_unshiftAllButton_toggled(bool checked); + void on_setTwoCheckBox_toggled(bool checked); + void on_shiftAllTimeLineEdit_textChanged(const QString &sa_text); + void on_setOneTimeLineEdit_textChanged(const QString &so_text); + void on_setOneFrameLineEdit_textChanged(const QString &frame_text); + void on_setTwoFrameLineEdit_textChanged(const QString &frame_text); + void on_setTwoTimeLineEdit_textChanged(const QString &st_text); + void applyTimeShift(); + void on_buttonBox_helpRequested(); +}; + +#endif // TIME_SHIFT_DIALOG_H diff --git a/ui/qt/time_shift_dialog.ui b/ui/qt/time_shift_dialog.ui new file mode 100644 index 0000000000..9c3a0e93b6 --- /dev/null +++ b/ui/qt/time_shift_dialog.ui @@ -0,0 +1,275 @@ + + + TimeShiftDialog + + + + 0 + 0 + 537 + 299 + + + + + 0 + 0 + + + + Wireshark: Time Shift + + + + + + + + Shift all packets by + + + true + + + + + + + + + + <html><head/><body><p><span style=" font-size:small; font-style:italic;">[-][[hh:]mm:]ss[.ddd] </span></p></body></html> + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Set the time for packet + + + + + + + + + + to + + + + + + + + 1 + 0 + + + + + + + + + + + + true + + + ...then set packet + + + + + + + + + + to + + + + + + + + 1 + 0 + + + + + + + + Qt::Horizontal + + + + 28 + 20 + + + + + + + + + + + + and extrapolate the time for all other packets + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + <html><head/><body><p align="right"><span style=" font-size:small; font-style:italic;">Time format: [YYYY-MM-DD] hh:mm:ss[.ddd] </span></p></body></html> + + + + + + + + + Undo all shifts + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Apply|QDialogButtonBox::Close|QDialogButtonBox::Help + + + + + buttonBox + unshiftAllButton + errorLabel + horizontalSpacer_5 + + + + SyntaxLineEdit + QLineEdit +
syntax_line_edit.h
+
+
+ + + + buttonBox + accepted() + TimeShiftDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + TimeShiftDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
diff --git a/ui/time_shift.c b/ui/time_shift.c new file mode 100644 index 0000000000..faeb17ece5 --- /dev/null +++ b/ui/time_shift.c @@ -0,0 +1,515 @@ +/* time_shift.c + * Routines for "Time Shift" window + * Submitted by Edwin Groothuis + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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 +#include +#include +#include + +#include + +#include "time_shift.h" + +#include "ui/ui_util.h" + +#define SHIFT_POS 0 +#define SHIFT_NEG 1 +#define SHIFT_SETTOZERO 1 +#define SHIFT_KEEPOFFSET 0 + +#define CHECK_YEARS(Y) \ + if (*Y < 1970) { \ + return "Years must be larger than 1970"; \ + } +#define CHECK_MONTHS(M) \ + if (*M < 1 || *M > 12) { \ + return "Months must be between [1..12]"; \ + } +#define CHECK_DAYS(D) \ + if (*D < 1 || *D > 31) { \ + return "Days must be between [1..31]"; \ + } +#define CHECK_HOURS(h) \ + if (*h < 0 || *h > 23) { \ + return "Hours must be between [0..23]"; \ + } +#define CHECK_HOUR(h) \ + if (*h < 0) { \ + return "Negative hours. Have you specified more than " \ + "one minus character?"; \ + } +#define CHECK_MINUTE(m) \ + if (*m < 0 || *m > 59) { \ + return "Minutes must be between [0..59]"; \ + } +#define CHECK_SECOND(s) \ + if (*s < 0 || *s > 59) { \ + return "Seconds must be between [0..59]"; \ + } + +static void modify_time_init(frame_data *fd); +static void modify_time_perform(frame_data *fd, int neg, nstime_t *offset, + int settozero); + +static void +modify_time_init(frame_data *fd) +{ + modify_time_perform(fd, SHIFT_NEG, NULL, SHIFT_KEEPOFFSET); +} + +static void +modify_time_perform(frame_data *fd, int neg, nstime_t *offset, int settozero) +{ + static frame_data *first_packet = NULL; + static nstime_t nulltime; + + /* Only for initializing */ + if (offset == NULL) { + first_packet = fd; + nulltime.secs = nulltime.nsecs = 0; + return; + } + if (first_packet == NULL) { + fprintf(stderr, "Modify_time_perform: not initialized?\n"); + return; + } + + /* The actual shift */ + + if (settozero == SHIFT_SETTOZERO) { + nstime_subtract(&(fd->abs_ts), &(fd->shift_offset)); + nstime_copy(&(fd->shift_offset), &nulltime); + } + + if (neg == SHIFT_POS) { + nstime_add(&(fd->abs_ts), offset); + nstime_add(&(fd->shift_offset), offset); + } else if (neg == SHIFT_NEG) { + nstime_subtract(&(fd->abs_ts), offset); + nstime_subtract(&(fd->shift_offset), offset); + } else { + fprintf(stderr, "Modify_time_perform: neg = %d?\n", neg); + } + + /* + * rel_ts - Relative timestamp to first packet + */ + if (first_packet != NULL) { + nstime_copy(&(fd->rel_ts), &(fd->abs_ts)); + nstime_subtract(&(fd->rel_ts), &(first_packet->abs_ts)); + } else + nstime_copy(&(fd->rel_ts), &nulltime); +} + +/* + * If the line between (OT1, NT1) and (OT2, NT2) is a straight line + * and (OT3, NT3) is on that line, + * then (NT2 - NT1) / (OT2 - OT2) = (NT3 - NT1) / (OT3 - OT1) and + * then (OT3 - OT1) * (NT2 - NT1) / (OT2 - OT2) = (NT3 - NT1) and + * then NT1 + (OT3 - OT1) * (NT2 - NT1) / (OT2 - OT2) = NT3 and + * then NT3 = NT1 + (OT3 - OT1) * (NT2 - NT1) / (OT2 - OT2) and + * thus NT3 = NT1 + (OT3 - OT1) * (NT2 - NT1) / (OT2 - OT1) + * or NT3 = NT1 + (OT3 - OT1) * ( deltaNT12 / deltaOT12) + * + * All the things you come up when waiting for the train to come... + */ +static void +calcNT3(nstime_t *OT1, nstime_t *OT3, nstime_t *NT1, nstime_t *NT3, + nstime_t *deltaOT, nstime_t *deltaNT) +{ + long double fnt, fot, f, secs, nsecs; + + fnt = (long double)deltaNT->secs + (deltaNT->nsecs / 1000000000.0L); + fot = (long double)deltaOT->secs + (deltaOT->nsecs / 1000000000.0L); + f = fnt / fot; + + nstime_copy(NT3, OT3); + nstime_subtract(NT3, OT1); + + secs = f * (long double)NT3->secs; + nsecs = f * (long double)NT3->nsecs; + nsecs += (secs - floorl(secs)) * 1000000000.0L; + while (nsecs > 1000000000L) { + secs += 1; + nsecs -= 1000000000L; + } + while (nsecs < 0) { + secs -= 1; + nsecs += 1000000000L; + } + NT3->secs = (time_t)secs; + NT3->nsecs = (int)nsecs; + nstime_add(NT3, NT1); +} + +const gchar * +time_string_parse(const gchar *time_text, int *year, int *month, int *day, gboolean *negative, int *hour, int *minute, long double *second) { + gchar *pts; + + if (!time_text || !hour || !minute || !second) + return "Unable to convert time."; + + pts = (gchar *)time_text; + + /* strip whitespace */ + while (isspace(pts[0])) + ++pts; + + if (year && month && day) { + /* + * The following time format is allowed: + * [YYYY-MM-DD] hh:mm:ss(.decimals)? + * + * Since Wireshark doesn't support regular expressions (please prove me + * wrong :-) we will have to figure it out ourselves in the + * following order: + * + * 1. YYYY-MM-DD hh:mm:ss.decimals + * 2. hh:mm:ss.decimals + * + */ + + /* check for empty string */ + if (pts[0] == '\0') + return "Time is empty."; + + if (sscanf(pts, "%d-%d-%d %d:%d:%Lf", year, month, day, hour, minute, second) == 6) { + /* printf("%%d-%%d-%%d %%d:%%d:%%f\n"); */ + CHECK_YEARS(year); + CHECK_MONTHS(month); + CHECK_DAYS(day); + CHECK_HOURS(hour); + CHECK_MINUTE(minute); + CHECK_SECOND(second); + } else if (sscanf(pts, "%d:%d:%Lf", hour, minute, second) == 3) { + /* printf("%%d:%%d:%%f\n"); */ + *year = *month = *day = 0; + CHECK_HOUR(hour); + CHECK_MINUTE(minute); + CHECK_SECOND(second); + } else { + return "Could not parse the time. Expected [YYYY-MM-DD] " + "hh:mm:ss[.dec]."; + } + } else { + if (!negative) + return "Unable to convert time."; + + /* + * The following offset types are allowed: + * -?((hh:)mm:)ss(.decimals)? + * + * Since Wireshark doesn't support regular expressions (please prove me + * wrong :-) we will have to figure it out ourselves in the + * following order: + * + * 1. hh:mm:ss.decimals + * 2. mm:ss.decimals + * 3. ss.decimals + * + */ + + /* check for minus sign */ + *negative = FALSE; + if (pts[0] == '-') { + *negative = TRUE; + pts++; + } + + /* check for empty string */ + if (pts[0] == '\0') + return "Time is empty."; + + if (sscanf(pts, "%d:%d:%Lf", hour, minute, second) == 3) { + /* printf("%%d:%%d:%%d.%%d\n"); */ + CHECK_HOUR(hour); + CHECK_MINUTE(minute); + CHECK_SECOND(second); + } else if (sscanf(pts, "%d:%Lf", minute, second) == 2) { + /* printf("%%d:%%d.%%d\n"); */ + CHECK_MINUTE(minute); + CHECK_SECOND(second); + *hour = 0; + } else if (sscanf(pts, "%Lf", second) == 1) { + /* printf("%%d.%%d\n"); */ + CHECK_SECOND(second); + *hour = *minute = 0; + } else { + return "Could not parse the time: Expected [[hh:]mm:]ss.[dec]."; + } + } + + return NULL; +} + +static const gchar * +time_string_to_nstime(const gchar *time_text, nstime_t *packettime, nstime_t *nstime) +{ + int h, m, Y, M, D; + long double f; + struct tm tm, *tmptm; + time_t tt; + const gchar *err_str; + + if ((err_str = time_string_parse(time_text, &Y, &M, &D, NULL, &h, &m, &f)) != NULL) + return err_str; + + /* Convert the time entered in an epoch offset */ + tmptm = localtime(&(packettime->secs)); + if (tmptm) { + tm = *tmptm; + } else { + memset (&tm, 0, sizeof (tm)); + } + if (Y != 0) { + tm.tm_year = Y - 1900; + tm.tm_mon = M - 1; + tm.tm_mday = D; + } + tm.tm_hour = h; + tm.tm_min = m; + tm.tm_sec = (int)floorl(f); + tt = mktime(&tm); + if (tt == -1) { + return "Mktime went wrong. Is the time valid?"; + } + + nstime->secs = tt; + f -= tm.tm_sec; + nstime->nsecs = (int)(f * 1000000000); + + return NULL; +} + +const gchar * +time_shift_all(capture_file *cf, const gchar *offset_text) +{ + nstime_t offset; + long double offset_float = 0; + guint32 i; + frame_data *fd; + gboolean neg; + int h, m; + long double f; + const gchar *err_str; + + if (!cf || !offset_text) + return "Nothing to work with."; + + if ((err_str = time_string_parse(offset_text, NULL, NULL, NULL, &neg, &h, &m, &f)) != NULL) + return err_str; + + offset_float = h * 3600 + m * 60 + f; + + if (offset_float == 0) + return "Offset is zero."; + + nstime_set_zero(&offset); + offset.secs = (time_t)floorl(offset_float); + offset_float -= offset.secs; + offset.nsecs = (int)(offset_float * 1000000000); + + if ((fd = frame_data_sequence_find(cf->frames, 1)) == NULL) + return "No frames found."; /* Shouldn't happen */ + modify_time_init(fd); + + for (i = 1; i <= cf->count; i++) { + if ((fd = frame_data_sequence_find(cf->frames, i)) == NULL) + continue; /* Shouldn't happen */ + modify_time_perform(fd, neg ? SHIFT_NEG : SHIFT_POS, &offset, SHIFT_KEEPOFFSET); + } + packet_list_queue_draw(); + + return NULL; +} + +const gchar * +time_shift_settime(capture_file *cf, guint packet_num, const gchar *time_text) +{ + nstime_t set_time, diff_time, packet_time; + frame_data *fd, *packetfd; + guint32 i; + const gchar *err_str; + + if (!cf || !time_text) + return "Nothing to work with."; + + if (packet_num < 1 || packet_num > cf->count) + return "Packet out of range."; + + /* + * Get a copy of the real time (abs_ts - shift_offset) do we can find out the + * difference between the specified time and the original packet + */ + if ((packetfd = frame_data_sequence_find(cf->frames, packet_num)) == NULL) + return "No packets found."; + nstime_delta(&packet_time, &(packetfd->abs_ts), &(packetfd->shift_offset)); + + if ((err_str = time_string_to_nstime(time_text, &packet_time, &set_time)) != NULL) + return err_str; + + /* Calculate difference between packet time and requested time */ + nstime_delta(&diff_time, &set_time, &packet_time); + + /* Up to here nothing is changed */ + + if ((fd = frame_data_sequence_find(cf->frames, 1)) == NULL) + return "No frames found."; /* Shouldn't happen */ + modify_time_init(fd); + + /* Set everything back to the original time */ + for (i = 1; i <= cf->count; i++) { + if ((fd = frame_data_sequence_find(cf->frames, i)) == NULL) + continue; /* Shouldn't happen */ + modify_time_perform(fd, SHIFT_POS, &diff_time, SHIFT_SETTOZERO); + } + + packet_list_queue_draw(); + return NULL; +} + +const gchar * +time_shift_adjtime(capture_file *cf, guint packet1_num, const gchar *time1_text, guint packet2_num, const gchar *time2_text) +{ + nstime_t nt1, nt2, ot1, ot2, nt3; + nstime_t dnt, dot, d3t; + frame_data *fd, *packet1fd, *packet2fd; + guint32 i; + const gchar *err_str; + + if (!cf || !time1_text || !time2_text) + return "Nothing to work with."; + + if (packet1_num < 1 || packet1_num > cf->count || packet2_num < 1 || packet2_num > cf->count) + return "Packet out of range."; + + /* + * The following time format is allowed: + * [YYYY-MM-DD] hh:mm:ss(.decimals)? + * + * Since Wireshark doesn't support regular expressions (please prove me + * wrong :-) we will have to figure it out ourselves in the + * following order: + * + * 1. YYYY-MM-DD hh:mm:ss.decimals + * 2. hh:mm:ss.decimals + * + */ + + /* + * Get a copy of the real time (abs_ts - shift_offset) do we can find out the + * difference between the specified time and the original packet + */ + if ((packet1fd = frame_data_sequence_find(cf->frames, packet1_num)) == NULL) + return "No frames found."; + nstime_copy(&ot1, &(packet1fd->abs_ts)); + nstime_subtract(&ot1, &(packet1fd->shift_offset)); + + if ((err_str = time_string_to_nstime(time1_text, &ot1, &nt1)) != NULL) + return err_str; + + /* + * Get a copy of the real time (abs_ts - shift_offset) do we can find out the + * difference between the specified time and the original packet + */ + if ((packet2fd = frame_data_sequence_find(cf->frames, packet2_num)) == NULL) + return "No frames found."; + nstime_copy(&ot2, &(packet2fd->abs_ts)); + nstime_subtract(&ot2, &(packet2fd->shift_offset)); + + if ((err_str = time_string_to_nstime(time2_text, &ot2, &nt2)) != NULL) + return err_str; + + nstime_copy(&dot, &ot2); + nstime_subtract(&dot, &ot1); + + nstime_copy(&dnt, &nt2); + nstime_subtract(&dnt, &nt1); + + /* Up to here nothing is changed */ + if ((fd = frame_data_sequence_find(cf->frames, 1)) == NULL) + return "No frames found."; /* Shouldn't happen */ + modify_time_init(fd); + + for (i = 1; i <= cf->count; i++) { + if ((fd = frame_data_sequence_find(cf->frames, i)) == NULL) + continue; /* Shouldn't happen */ + + /* Set everything back to the original time */ + nstime_subtract(&(fd->abs_ts), &(fd->shift_offset)); + nstime_set_zero(&(fd->shift_offset)); + + /* Add the difference to each packet */ + calcNT3(&ot1, &(fd->abs_ts), &nt1, &nt3, &dot, &dnt); + + nstime_copy(&d3t, &nt3); + nstime_subtract(&d3t, &(fd->abs_ts)); + + modify_time_perform(fd, SHIFT_POS, &d3t, SHIFT_SETTOZERO); + } + + packet_list_queue_draw(); + return NULL; +} + +const gchar * +time_shift_undo(capture_file *cf) +{ + guint32 i; + frame_data *fd; + nstime_t nulltime; + + if (!cf) + return "Nothing to work with."; + + nulltime.secs = nulltime.nsecs = 0; + + if ((fd = frame_data_sequence_find(cf->frames, 1)) == NULL) + return "No frames found."; /* Shouldn't happen */ + modify_time_init(fd); + + for (i = 1; i <= cf->count; i++) { + if ((fd = frame_data_sequence_find(cf->frames, i)) == NULL) + continue; /* Shouldn't happen */ + modify_time_perform(fd, SHIFT_NEG, &nulltime, SHIFT_SETTOZERO); + } + packet_list_queue_draw(); + return NULL; +} + +/* + * 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/time_shift.h b/ui/time_shift.h new file mode 100644 index 0000000000..bedc353bf4 --- /dev/null +++ b/ui/time_shift.h @@ -0,0 +1,103 @@ +/* time_shift.h + * Submitted by Edwin Groothuis + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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 __TIME_SHIFT_H__ +#define __TIME_SHIFT_H__ + +#include "cfile.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * XXX - We might want to move all of this somewhere more accessible to + * editcap so that we can make its time adjustments more versatile. + */ + +/** + * Parse a time string and fill in each component. + * + * If year, month, and day are non-NULL a full time format "[YYYY-MM-DD] hh:mm:ss[.decimals]" + * is allowed. Otherwise an offset format "[-][[hh:]mm:]ss[.decimals]" is allowed. + * + * @param time_text Time string + * @param year Year. May be NULL + * @param month Month. May be NULL + * @param day Day. May be NULL. + * @param negative Time offset is negative. May be NULL if year, month, and day are not NULL. + * @param hour Hours. Must not be NULL. + * @param minute Minutes. Must not be NULL. + * @param second Seconds. Must not be NULL. + * + * @return NULL on success or an error description on failure. + */ + +const gchar * time_string_parse(const gchar *time_text, int *year, int *month, int *day, gboolean *negative, int *hour, int *minute, long double *second); + +/** Shift all packets by an offset + * + * @param cf Capture file to shift + * @param offset_text String representation of the offset. + * + * @return NULL on success or an error description on failure. + */ +const gchar * time_shift_all(capture_file *cf, const gchar *offset_text); + +/* Set the time for a single packet + * + * @param cf Capture file to set + * @param packet_num Packet to set + * @param time_text String representation of the time + * + * @return NULL on success or an error description on failure. + */ +const gchar * time_shift_settime(capture_file *cf, guint packet_num, const gchar *time_text); + +/* Set the time for two packets and extrapolate the rest + * + * @param cf Capture file to set + * @param packet1_num First packet to set + * @param time1_text String representation of the first packet time + * @param packet2_num Second packet to set + * @param time2_text String representation of the second packet time + * + * @return NULL on success or an error description on failure. + */ +const gchar * time_shift_adjtime(capture_file *cf, guint packet1_num, const gchar *time1_text, guint packet2_num, const gchar *time2_text); + +/* Reset the times for all packets + * + * @param cf Capture file to set + * + * @return NULL on success or an error description on failure. + */ +const gchar * time_shift_undo(capture_file *cf); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __TIME_SHIFT_H__ */ -- cgit v1.2.3