/* main_window.cpp
- *
- * $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
#include "main_window.h"
#include "ui_main_window.h"
-#include "globals.h"
-
+#include <epan/addr_resolv.h>
#include <epan/epan_dissect.h>
#include <wsutil/filesystem.h>
#include <epan/prefs.h>
//#include <wiretap/wtap.h>
#ifdef HAVE_LIBPCAP
-#include "capture.h"
-#include "capture-pcap-util.h"
-#include "capture_ui_utils.h"
-#include "capture_session.h"
+#include "ui/capture.h"
+#include <capchild/capture_session.h>
#endif
#include "ui/alert_box.h"
+#ifdef HAVE_LIBPCAP
+#include "ui/capture_ui_utils.h"
+#endif
#include "ui/capture_globals.h"
#include "ui/main_statusbar.h"
#include "ui/recent.h"
#include "ui/util.h"
-#include "wireshark_application.h"
-#include "proto_tree.h"
#include "byte_view_tab.h"
#include "display_filter_edit.h"
-#include "import_text_dialog.h"
#include "export_dissection_dialog.h"
+#include "import_text_dialog.h"
+#include "proto_tree.h"
+#include "simple_dialog.h"
+#include "stock_icon.h"
+#include "wireshark_application.h"
#include "qt_ui_utils.h"
#include <QAction>
+#include <QActionGroup>
#include <QDesktopWidget>
#include <QKeyEvent>
#include <QMessageBox>
#include <QToolButton>
#include <QTreeWidget>
-#ifdef QT_MACEXTRAS_LIB
+#if defined(QT_MACEXTRAS_LIB) && QT_VERSION < QT_VERSION_CHECK(5, 2, 1)
#include <QtMacExtras/QMacNativeToolBar>
#endif
//menu_recent_file_write_all
// If we ever add support for multiple windows this will need to be replaced.
-static MainWindow *gbl_cur_main_window = NULL;
+static MainWindow *gbl_cur_main_window_ = NULL;
void pipe_input_set_handler(gint source, gpointer user_data, int *child_process, pipe_input_cb_t input_cb)
{
- gbl_cur_main_window->setPipeInputHandler(source, user_data, child_process, input_cb);
+ gbl_cur_main_window_->setPipeInputHandler(source, user_data, child_process, input_cb);
+}
+
+gpointer
+simple_dialog(ESD_TYPE_E type, gint btn_mask, const gchar *msg_format, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg_format);
+ SimpleDialog sd(gbl_cur_main_window_, type, btn_mask, msg_format, ap);
+ va_end(ap);
+
+ sd.exec();
+ return NULL;
+}
+
+/*
+ * Alert box, with optional "don't show this message again" variable
+ * and checkbox, and optional secondary text.
+ */
+void
+simple_message_box(ESD_TYPE_E type, gboolean *notagain,
+ const char *secondary_msg, const char *msg_format, ...)
+{
+ if (notagain && *notagain) {
+ return;
+ }
+
+ va_list ap;
+
+ va_start(ap, msg_format);
+ SimpleDialog sd(gbl_cur_main_window_, type, ESD_BTN_OK, msg_format, ap);
+ va_end(ap);
+
+ sd.setDetailedText(secondary_msg);
+
+#if (QT_VERSION > QT_VERSION_CHECK(5, 2, 0))
+ QCheckBox *cb = new QCheckBox();
+ if (notagain) {
+ cb->setChecked(true);
+ cb->setText(QObject::tr("Don't show this message again."));
+ sd.setCheckBox(cb);
+ }
+#endif
+
+ sd.exec();
+
+#if (QT_VERSION > QT_VERSION_CHECK(5, 2, 0))
+ if (notagain) {
+ *notagain = cb->isChecked();
+ }
+#endif
+}
+
+/*
+ * Error alert box, taking a format and a va_list argument.
+ */
+void
+vsimple_error_message_box(const char *msg_format, va_list ap)
+{
+ SimpleDialog sd(gbl_cur_main_window_, ESD_TYPE_ERROR, ESD_BTN_OK, msg_format, ap);
+ sd.exec();
}
+
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
main_ui_(new Ui::MainWindow),
df_combo_box_(new DisplayFilterCombo()),
- cap_file_(NULL),
previous_focus_(NULL),
+ show_hide_actions_(NULL),
+ time_display_actions_(NULL),
+ time_precision_actions_(NULL),
capture_stopping_(false),
capture_filter_valid_(false),
#ifdef _WIN32
pipe_notifier_(NULL)
#endif
{
- gbl_cur_main_window = this;
+ if (!gbl_cur_main_window_) {
+ connect(wsApp, SIGNAL(openStatCommandDialog(QString,const char*,void*)),
+ this, SLOT(openStatCommandDialog(QString,const char*,void*)));
+ }
+ gbl_cur_main_window_ = this;
+#ifdef HAVE_LIBPCAP
+ capture_session_init(&cap_session_, CaptureFile::globalCapFile());
+#endif
main_ui_->setupUi(this);
setTitlebarForCaptureFile();
setMenusForCaptureFile();
//Otherwise unexpected problems may occur
setFeaturesEnabled(false);
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(setFeaturesEnabled()));
+ connect(wsApp, SIGNAL(appInitialized()), this, SLOT(zoomText()));
connect(wsApp, SIGNAL(preferencesChanged()), this, SLOT(layoutPanes()));
+ connect(wsApp, SIGNAL(preferencesChanged()), this, SLOT(layoutToolbars()));
+ connect(wsApp, SIGNAL(preferencesChanged()), this, SLOT(updateNameResolutionActions()));
+ connect(wsApp, SIGNAL(preferencesChanged()), this, SLOT(zoomText()));
connect(wsApp, SIGNAL(recentFilesRead()), this, SLOT(loadWindowGeometry()));
connect(wsApp, SIGNAL(updateRecentItemStatus(const QString &, qint64, bool)), this, SLOT(updateRecentFiles()));
updateRecentFiles();
- connect(&summary_dialog_, SIGNAL(captureCommentChanged()), this, SLOT(updateForUnsavedChanges()));
-
#ifdef HAVE_LIBPCAP
connect(&capture_interfaces_dialog_, SIGNAL(startCapture()), this, SLOT(startCapture()));
connect(&capture_interfaces_dialog_, SIGNAL(stopCapture()), this, SLOT(stopCapture()));
connect(df_edit, SIGNAL(addBookmark(QString)), this, SLOT(addDisplayFilterButton(QString)));
connect(this, SIGNAL(displayFilterSuccess(bool)), df_edit, SLOT(displayFilterSuccess(bool)));
- // http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
- // http://qt-project.org/doc/qt-4.8/qstyle.html#StandardPixmap-enum
- main_ui_->actionFileOpen->setIcon(
- QIcon().fromTheme("document-open", style()->standardIcon(QStyle::SP_DirIcon)));
- // main_ui_->actionFileSave set in main_window.ui
- main_ui_->actionFileClose->setIcon(
- QIcon().fromTheme("process-stop", style()->standardIcon(QStyle::SP_DialogCloseButton)));
+ initMainToolbarIcons();
// In Qt4 multiple toolbars and "pretty" are mutually exculsive on OS X. If
// unifiedTitleAndToolBarOnMac is enabled everything ends up in the same row.
#endif
#if defined(Q_OS_MAC)
-#ifdef QT_MACEXTRAS_LIB
+#if defined(QT_MACEXTRAS_LIB) && QT_VERSION < QT_VERSION_CHECK(5, 2, 1)
QMacNativeToolBar *ntb = QtMacExtras::setNativeToolBar(main_ui_->mainToolBar);
ntb->setIconSize(QSize(24, 24));
#endif // QT_MACEXTRAS_LIB
- foreach (QMenu *menu, main_ui_->menuBar->findChildren<QMenu*>()) {
- foreach (QAction *act, menu->actions()) {
- act->setIconVisibleInMenu(false);
- }
- }
main_ui_->goToLineEdit->setAttribute(Qt::WA_MacSmallSize, true);
main_ui_->goToGo->setAttribute(Qt::WA_MacSmallSize, true);
main_ui_->goToCancel->setAttribute(Qt::WA_MacSmallSize, true);
QAction *update_sep = main_ui_->menuHelp->insertSeparator(main_ui_->actionHelpAbout);
QAction *update_action = new QAction(tr("Check for Updates..."), main_ui_->menuHelp);
main_ui_->menuHelp->insertAction(update_sep, update_action);
- connect(update_action, SIGNAL(triggered()), this, SLOT(on_actionHelpCheckForUpdates_triggered()));
+ connect(update_action, SIGNAL(triggered()), this, SLOT(checkForUpdates()));
#endif
master_split_.setObjectName(tr("splitterMaster"));
extra_split_.setObjectName(tr("splitterExtra"));
main_welcome_ = main_ui_->welcomePage;
- connect(wsApp, SIGNAL(captureCapturePrepared(capture_session *)),
+ initShowHideMainWidgets();
+ initTimeDisplayFormatMenu();
+ initTimePrecisionFormatMenu();
+ updateNameResolutionActions();
+
+ connect(&capture_file_, SIGNAL(captureCapturePrepared(capture_session *)),
this, SLOT(captureCapturePrepared(capture_session *)));
- connect(wsApp, SIGNAL(captureCaptureUpdateStarted(capture_session *)),
+ connect(&capture_file_, SIGNAL(captureCaptureUpdateStarted(capture_session *)),
this, SLOT(captureCaptureUpdateStarted(capture_session *)));
- connect(wsApp, SIGNAL(captureCaptureUpdateFinished(capture_session *)),
+ connect(&capture_file_, SIGNAL(captureCaptureUpdateFinished(capture_session *)),
this, SLOT(captureCaptureUpdateFinished(capture_session *)));
- connect(wsApp, SIGNAL(captureCaptureFixedStarted(capture_session *)),
+ connect(&capture_file_, SIGNAL(captureCaptureFixedStarted(capture_session *)),
this, SLOT(captureCaptureFixedStarted(capture_session *)));
- connect(wsApp, SIGNAL(captureCaptureFixedFinished(capture_session *)),
+ connect(&capture_file_, SIGNAL(captureCaptureFixedFinished(capture_session *)),
this, SLOT(captureCaptureFixedFinished(capture_session *)));
- connect(wsApp, SIGNAL(captureCaptureStopping(capture_session *)),
+ connect(&capture_file_, SIGNAL(captureCaptureStopping(capture_session *)),
this, SLOT(captureCaptureStopping(capture_session *)));
- connect(wsApp, SIGNAL(captureCaptureFailed(capture_session *)),
+ connect(&capture_file_, SIGNAL(captureCaptureFailed(capture_session *)),
this, SLOT(captureCaptureFailed(capture_session *)));
- connect(wsApp, SIGNAL(captureFileOpened(const capture_file*)),
- this, SLOT(captureFileOpened(const capture_file*)));
- connect(wsApp, SIGNAL(captureFileReadStarted(const capture_file*)),
- this, SLOT(captureFileReadStarted(const capture_file*)));
- connect(wsApp, SIGNAL(captureFileReadFinished(const capture_file*)),
- this, SLOT(captureFileReadFinished(const capture_file*)));
- connect(wsApp, SIGNAL(captureFileClosing(const capture_file*)),
- this, SLOT(captureFileClosing(const capture_file*)));
- connect(wsApp, SIGNAL(captureFileClosed(const capture_file*)),
- this, SLOT(captureFileClosed(const capture_file*)));
+ connect(&capture_file_, SIGNAL(captureFileOpened()),
+ this, SLOT(captureFileOpened()));
+ connect(&capture_file_, SIGNAL(captureFileReadStarted()),
+ this, SLOT(captureFileReadStarted()));
+ connect(&capture_file_, SIGNAL(captureFileReadFinished()),
+ this, SLOT(captureFileReadFinished()));
+ connect(&capture_file_, SIGNAL(captureFileClosing()),
+ this, SLOT(captureFileClosing()));
+ connect(&capture_file_, SIGNAL(captureFileClosed()),
+ this, SLOT(captureFileClosed()));
+
+ connect(&capture_file_, SIGNAL(captureFileReadStarted()),
+ wsApp, SLOT(captureFileReadStarted()));
+ connect(&capture_file_, SIGNAL(captureFileReadFinished()),
+ wsApp, SLOT(updateTaps()));
+
connect(wsApp, SIGNAL(columnsChanged()),
this, SLOT(recreatePacketList()));
connect(wsApp, SIGNAL(packetDissectionChanged()),
this, SLOT(filterExpressionsChanged()));
connect(wsApp, SIGNAL(filterExpressionsChanged()),
this, SLOT(filterExpressionsChanged()));
+ connect(wsApp, SIGNAL(fieldsChanged()),
+ this, SLOT(fieldsChanged()));
connect(main_welcome_, SIGNAL(startCapture()),
this, SLOT(startCapture()));
connect(this, SIGNAL(setCaptureFile(capture_file*)),
byte_view_tab_, SLOT(setCaptureFile(capture_file*)));
+ connect(this, SIGNAL(monospaceFontChanged(QFont)),
+ packet_list_, SLOT(setMonospaceFont(QFont)));
+ connect(this, SIGNAL(monospaceFontChanged(QFont)),
+ proto_tree_, SLOT(setMonospaceFont(QFont)));
+ connect(this, SIGNAL(monospaceFontChanged(QFont)),
+ byte_view_tab_, SLOT(setMonospaceFont(QFont)));
+
connect(main_ui_->actionGoNextPacket, SIGNAL(triggered()),
packet_list_, SLOT(goNextPacket()));
connect(main_ui_->actionGoPreviousPacket, SIGNAL(triggered()),
connect(proto_tree_, SIGNAL(protoItemSelected(QString&)),
main_ui_->statusBar, SLOT(pushFieldStatus(QString&)));
-
connect(proto_tree_, SIGNAL(protoItemSelected(field_info *)),
this, SLOT(setMenusForSelectedTreeRow(field_info *)));
+ connect(byte_view_tab_, SIGNAL(byteFieldHovered(QString&)),
+ main_ui_->statusBar, SLOT(pushByteStatus(QString&)));
+
+ connect(main_ui_->statusBar, SIGNAL(editCaptureComment()),
+ this, SLOT(on_actionStatisticsCaptureFileProperties_triggered()));
+
connect(&file_set_dialog_, SIGNAL(fileSetOpenCaptureFile(QString&)),
this, SLOT(openCaptureFile(QString&)));
connect(&capture_interfaces_dialog_, SIGNAL(getPoints(int,PointList*)),
this->main_welcome_->getInterfaceTree(), SLOT(getPoints(int,PointList*)));
+ connect(&capture_interfaces_dialog_, SIGNAL(setSelectedInterfaces()),
+ this->main_welcome_->getInterfaceTree(), SLOT(setSelectedInterfaces()));
+ connect(&capture_interfaces_dialog_, SIGNAL(interfaceListChanged()),
+ this->main_welcome_->getInterfaceTree(), SLOT(interfaceListChanged()));
#endif
main_ui_->mainStack->setCurrentWidget(main_welcome_);
return;
}
+#ifdef HAVE_LIBPCAP
+ capture_interfaces_dialog_.close();
+#endif
// Make sure we kill any open dumpcap processes.
delete main_welcome_;
if (// prefs.gui_geometry_save_size &&
recent.gui_geometry_main_width > min_sensible_dimension &&
- recent.gui_geometry_main_width > min_sensible_dimension) {
+ recent.gui_geometry_main_height > min_sensible_dimension) {
shadow_main.resize(recent.gui_geometry_main_width, recent.gui_geometry_main_height);
}
dfilter_t *rfcode = NULL;
int err;
- if (!cap_file_)
+ if (!capture_file_.capFile())
return;
if (prefs.gui_ask_unsaved) {
- if (cf_has_unsaved_data(cap_file_)) {
+ if (cf_has_unsaved_data(capture_file_.capFile())) {
QMessageBox msg_dialog;
gchar *display_basename;
int response;
msg_dialog.setIcon(QMessageBox::Question);
/* This file has unsaved data; ask the user whether to save
the capture. */
- if (cap_file_->is_tempfile) {
+ if (capture_file_.capFile()->is_tempfile) {
msg_dialog.setText(tr("Save packets before merging?"));
msg_dialog.setInformativeText(tr("A temporary capture file can't be merged."));
} else {
/*
* Format the message.
*/
- display_basename = g_filename_display_basename(cap_file_->filename);
+ display_basename = g_filename_display_basename(capture_file_.capFile()->filename);
msg_dialog.setText(QString(tr("Save changes in \"%1\" before merging?")).arg(display_basename));
g_free(display_basename);
msg_dialog.setInformativeText(tr("Changes must be saved before the files can be merged."));
case QMessageBox::Save:
/* Save the file but don't close it */
- saveCaptureFile(cap_file_, FALSE);
+ saveCaptureFile(capture_file_.capFile(), FALSE);
break;
case QMessageBox::Cancel:
}
for (;;) {
- CaptureFileDialog merge_dlg(this, cap_file_, display_filter);
+ CaptureFileDialog merge_dlg(this, capture_file_.capFile(), display_filter);
int file_type;
cf_status_t merge_status;
char *in_filenames[2];
if (merge_dlg.merge(file_name)) {
if (dfilter_compile(display_filter.toUtf8().constData(), &rfcode)) {
- cf_set_rfcode(cap_file_, rfcode);
+ cf_set_rfcode(capture_file_.capFile(), rfcode);
} else {
/* Not valid. Tell the user, and go back and run the file
selection box again once they dismiss the alert. */
return;
}
- file_type = cap_file_->cd_t;
+ file_type = capture_file_.capFile()->cd_t;
/* Try to merge or append the two files */
tmpname = NULL;
if (merge_dlg.mergeType() == 0) {
/* chronological order */
- in_filenames[0] = cap_file_->filename;
+ in_filenames[0] = capture_file_.capFile()->filename;
in_filenames[1] = file_name.toUtf8().data();
merge_status = cf_merge_files(&tmpname, 2, in_filenames, file_type, FALSE);
} else if (merge_dlg.mergeType() <= 0) {
/* prepend file */
in_filenames[0] = file_name.toUtf8().data();
- in_filenames[1] = cap_file_->filename;
+ in_filenames[1] = capture_file_.capFile()->filename;
merge_status = cf_merge_files(&tmpname, 2, in_filenames, file_type, TRUE);
} else {
/* append file */
- in_filenames[0] = cap_file_->filename;
+ in_filenames[0] = capture_file_.capFile()->filename;
in_filenames[1] = file_name.toUtf8().data();
merge_status = cf_merge_files(&tmpname, 2, in_filenames, file_type, TRUE);
}
continue;
}
- cf_close(cap_file_);
+ cf_close(capture_file_.capFile());
/* Try to open the merged capture file. */
- cfile.window = this;
- if (cf_open(&cfile, tmpname, TRUE /* temporary file */, &err) != CF_OK) {
+ CaptureFile::globalCapFile()->window = this;
+ if (cf_open(CaptureFile::globalCapFile(), tmpname, WTAP_TYPE_AUTO, TRUE /* temporary file */, &err) != CF_OK) {
/* We couldn't open it; fail. */
- cfile.window = NULL;
+ CaptureFile::globalCapFile()->window = NULL;
if (rfcode != NULL)
dfilter_free(rfcode);
g_free(tmpname);
/* Attach the new read filter to "cf" ("cf_open()" succeeded, so
it closed the previous capture file, and thus destroyed any
previous read filter attached to "cf"). */
- cfile.rfcode = rfcode;
+ CaptureFile::globalCapFile()->rfcode = rfcode;
- switch (cf_read(&cfile, FALSE)) {
+ switch (cf_read(CaptureFile::globalCapFile(), FALSE)) {
case CF_READ_OK:
case CF_READ_ERROR:
}
/* XXX - cf->filename might get freed out from under us, because
- the code path through which cf_save_packets() goes currently
+ the code path through which cf_save_records() goes currently
closes the current file and then opens and reloads the saved file,
so make a copy and free it later. */
file_name = cf->filename;
- status = cf_save_packets(cf, file_name.toUtf8().constData(), cf->cd_t, cf->iscompressed,
+ status = cf_save_records(cf, file_name.toUtf8().constData(), cf->cd_t, cf->iscompressed,
discard_comments, stay_closed);
switch (status) {
//#endif
/* Attempt to save the file */
- status = cf_save_packets(cf, file_name.toUtf8().constData(), file_type, compressed,
+ status = cf_save_records(cf, file_name.toUtf8().constData(), file_type, compressed,
discard_comments, stay_closed);
switch (status) {
case CF_WRITE_OK:
/* The save succeeded; we're done. */
/* Save the directory name for future file dialogs. */
- dirname = get_dirname(file_name.toUtf8().data()); /* Overwrites cf_name */
+ dirname = get_dirname(qstring_strdup(file_name)); /* Overwrites cf_name */
set_last_open_dir(dirname);
+ g_free(dirname);
/* If we discarded comments, redraw the packet list to reflect
any packets that no longer have comments. */
if (discard_comments)
gchar *dirname;
gboolean discard_comments = FALSE;
- if (!cap_file_)
+ if (!capture_file_.capFile())
return;
/* Init the packet range */
- packet_range_init(&range, cap_file_);
+ packet_range_init(&range, capture_file_.capFile());
range.process_filtered = TRUE;
range.include_dependents = TRUE;
for (;;) {
- CaptureFileDialog esp_dlg(this, cap_file_);
+ CaptureFileDialog esp_dlg(this, capture_file_.capFile());
switch (prefs.gui_fileopen_style) {
* name and the read file name may be relative (if supplied on
* the command line). From Joerg Mayer.
*/
- if (files_identical(cap_file_->filename, file_name.toUtf8().constData())) {
+ if (files_identical(capture_file_.capFile()->filename, file_name.toUtf8().constData())) {
QMessageBox msg_box;
gchar *display_basename = g_filename_display_basename(file_name.toUtf8().constData());
//#endif
/* Attempt to save the file */
- status = cf_export_specified_packets(cap_file_, file_name.toUtf8().constData(), &range, file_type, compressed);
+ status = cf_export_specified_packets(capture_file_.capFile(), file_name.toUtf8().constData(), &range, file_type, compressed);
switch (status) {
case CF_WRITE_OK:
/* The save succeeded; we're done. */
/* Save the directory name for future file dialogs. */
- dirname = get_dirname(file_name.toUtf8().data()); /* Overwrites cf_name */
+ dirname = get_dirname(qstring_strdup(file_name)); /* Overwrites cf_name */
set_last_open_dir(dirname);
+ g_free(dirname);
/* If we discarded comments, redraw the packet list to reflect
any packets that no longer have comments. */
if (discard_comments)
}
void MainWindow::exportDissections(export_type_e export_type) {
- ExportDissectionDialog ed_dlg(this, cap_file_, export_type);
+ ExportDissectionDialog ed_dlg(this, capture_file_.capFile(), export_type);
packet_range_t range;
- if (!cap_file_)
+ if (!capture_file_.capFile())
return;
/* Init the packet range */
- packet_range_init(&range, cap_file_);
+ packet_range_init(&range, capture_file_.capFile());
range.process_filtered = TRUE;
range.include_dependents = TRUE;
bool MainWindow::testCaptureFileClose(bool from_quit, QString &before_what) {
bool capture_in_progress = FALSE;
- if (!cap_file_ || cap_file_->state == FILE_CLOSED)
+ if (!capture_file_.capFile() || capture_file_.capFile()->state == FILE_CLOSED)
return true; /* Already closed, nothing to do */
#ifdef HAVE_LIBPCAP
- if (cap_file_->state == FILE_READ_IN_PROGRESS) {
+ if (capture_file_.capFile()->state == FILE_READ_IN_PROGRESS) {
/* This is true if we're reading a capture file *or* if we're doing
a live capture. If we're reading a capture file, the main loop
is busy reading packets, and only accepting input from the
#endif
if (prefs.gui_ask_unsaved) {
- if (cf_has_unsaved_data(cap_file_) || capture_in_progress) {
+ if (cf_has_unsaved_data(capture_file_.capFile()) || capture_in_progress) {
QMessageBox msg_dialog;
QString question;
QPushButton *saveButton;
QPushButton *discardButton;
msg_dialog.setIcon(QMessageBox::Question);
-
+ msg_dialog.setWindowTitle("Unsaved packets...");
/* This file has unsaved data or there's a capture in
progress; ask the user whether to save the data. */
- if (cap_file_->is_tempfile) {
+ if (capture_file_.capFile()->is_tempfile) {
msg_dialog.setText(tr("You have unsaved packets"));
msg_dialog.setInformativeText(tr("They will be lost if you don't save them."));
if (capture_in_progress) {
question.append(tr("Do you want to stop the capture and save the captured packets"));
question.append(before_what).append(tr("?"));
+ msg_dialog.setText(question);
msg_dialog.setInformativeText(tr("Your captured packets will be lost if you don't save them."));
} else {
- gchar *display_basename = g_filename_display_basename(cap_file_->filename);
+ gchar *display_basename = g_filename_display_basename(capture_file_.capFile()->filename);
question.append(QString(tr("Do you want to save the changes you've made to the capture file \"%1\"%2?"))
.arg(display_basename)
.arg(before_what)
);
g_free(display_basename);
+ msg_dialog.setText(question);
msg_dialog.setInformativeText(tr("Your changes will be lost if you don't save them."));
}
}
msg_dialog.setDefaultButton(saveButton);
if (from_quit) {
- if (cap_file_->state == FILE_READ_IN_PROGRESS) {
+ if (capture_file_.capFile()->state == FILE_READ_IN_PROGRESS) {
discardButton = msg_dialog.addButton(tr("Stop and Quit without Saving"),
QMessageBox::DestructiveRole);
} else {
discardButton = msg_dialog.addButton(tr("Stop and Continue without Saving"),
QMessageBox::DestructiveRole);
} else {
- discardButton = msg_dialog.addButton(QMessageBox::Discard);
+ discardButton = msg_dialog.addButton(tr("Continue &without Saving"), QMessageBox::DestructiveRole);
}
}
captureStop();
#endif
/* Save the file and close it */
- saveCaptureFile(cap_file_, TRUE);
+ saveCaptureFile(capture_file_.capFile(), TRUE);
}
else if(msg_dialog.clickedButton() == discardButton)
{
captureStop();
#endif
/* Just close the file, discarding changes */
- cf_close(cap_file_);
+ cf_close(capture_file_.capFile());
return true;
}
else //cancelButton or some other unspecified button
} else {
/* Unchanged file, just close it */
- cf_close(cap_file_);
+ cf_close(capture_file_.capFile());
}
} else {
/* User asked not to be bothered by those prompts, just close it.
if (capture_in_progress)
captureStop();
#endif
- cf_close(cap_file_);
+ cf_close(capture_file_.capFile());
}
return true; /* File closed */
void MainWindow::captureStop() {
stopCapture();
- while(cap_file_ && cap_file_->state == FILE_READ_IN_PROGRESS) {
+ while(capture_file_.capFile() && capture_file_.capFile()->state == FILE_READ_IN_PROGRESS) {
WiresharkApplication::processEvents();
}
}
+void MainWindow::initMainToolbarIcons()
+{
+#if defined(Q_OS_WIN)
+ // Current GTK+ and other Windows app behavior.
+ main_ui_->mainToolBar->setIconSize(QSize(16, 16));
+#else
+ // Force icons to 24x24 for now, otherwise actionFileOpen looks wonky.
+ main_ui_->mainToolBar->setIconSize(QSize(24, 24));
+#endif
+
+ // Toolbar actions. The GNOME HIG says that we should have a menu icon for each
+ // toolbar item but that clutters up our menu. Set menu icons sparingly.
+
+ main_ui_->actionCaptureStart->setIcon(StockIcon("x-capture-start"));
+ main_ui_->actionCaptureStop->setIcon(StockIcon("x-capture-stop"));
+ main_ui_->actionCaptureRestart->setIcon(StockIcon("x-capture-restart"));
+ main_ui_->actionCaptureOptions->setIcon(StockIcon("x-capture-options"));
+
+ // Menu icons are disabled in main_window.ui for these items.
+ main_ui_->actionFileOpen->setIcon(StockIcon("document-open"));
+ main_ui_->actionFileSave->setIcon(StockIcon("x-capture-file-save"));
+ main_ui_->actionFileClose->setIcon(StockIcon("x-capture-file-close"));
+// main_ui_->actionViewReload->setIcon(StockIcon("x-capture-file-reload"));
+
+ main_ui_->actionEditFindPacket->setIcon(StockIcon("edit-find"));
+ main_ui_->actionGoPreviousPacket->setIcon(StockIcon("go-previous"));
+ main_ui_->actionGoNextPacket->setIcon(StockIcon("go-next"));
+ main_ui_->actionGoGoToPacket->setIcon(StockIcon("go-jump"));
+ main_ui_->actionGoFirstPacket->setIcon(StockIcon("go-first"));
+ main_ui_->actionGoLastPacket->setIcon(StockIcon("go-last"));
+
+ main_ui_->actionViewColorizePacketList->setIcon(StockIcon("x-colorize-packets"));
+ main_ui_->actionViewColorizePacketList->setChecked(recent.packet_list_colorize);
+// main_ui_->actionViewAutoScroll->setIcon(StockIcon("x-stay-last"));
+
+ QList<QKeySequence> zi_seq = main_ui_->actionViewZoomIn->shortcuts();
+ zi_seq << QKeySequence(Qt::CTRL + Qt::Key_Equal);
+ main_ui_->actionViewZoomIn->setIcon(StockIcon("zoom-in"));
+ main_ui_->actionViewZoomIn->setShortcuts(zi_seq);
+ main_ui_->actionViewZoomOut->setIcon(StockIcon("zoom-out"));
+ main_ui_->actionViewNormalSize->setIcon(StockIcon("zoom-original"));
+ main_ui_->actionViewResizeColumns->setIcon(StockIcon("x-resize-columns"));
+}
+
+void MainWindow::initShowHideMainWidgets()
+{
+ if (show_hide_actions_) {
+ return;
+ }
+
+ show_hide_actions_ = new QActionGroup(this);
+ QMap<QAction *, QWidget *> shmw_actions;
+
+ show_hide_actions_->setExclusive(false);
+ shmw_actions[main_ui_->actionViewMainToolbar] = main_ui_->mainToolBar;
+ shmw_actions[main_ui_->actionViewFilterToolbar] = main_ui_->displayFilterToolBar;
+ shmw_actions[main_ui_->actionViewWirelessToolbar] = NULL; // Doesn't exist yet.
+ shmw_actions[main_ui_->actionViewStatusBar] = main_ui_->statusBar;
+ shmw_actions[main_ui_->actionViewPacketList] = packet_list_;
+ shmw_actions[main_ui_->actionViewPacketDetails] = proto_tree_;
+ shmw_actions[main_ui_->actionViewPacketBytes] = byte_view_tab_;
+
+ main_ui_->actionViewMainToolbar->setChecked(recent.main_toolbar_show);
+ main_ui_->actionViewFilterToolbar->setChecked(recent.filter_toolbar_show);
+ main_ui_->actionViewWirelessToolbar->setChecked(recent.wireless_toolbar_show);
+ main_ui_->actionViewStatusBar->setChecked(recent.statusbar_show);
+ main_ui_->actionViewPacketList->setChecked(recent.packet_list_show);
+ main_ui_->actionViewPacketDetails->setChecked(recent.tree_view_show);
+ main_ui_->actionViewPacketBytes->setChecked(recent.byte_view_show);
+
+ foreach (QAction *shmwa, shmw_actions.keys()) {
+ shmwa->setData(qVariantFromValue(shmw_actions[shmwa]));
+ show_hide_actions_->addAction(shmwa);
+ showHideMainWidgets(shmwa);
+ }
+
+ connect(show_hide_actions_, SIGNAL(triggered(QAction*)), this, SLOT(showHideMainWidgets(QAction*)));
+}
+
+Q_DECLARE_METATYPE(ts_type)
+
+void MainWindow::initTimeDisplayFormatMenu()
+{
+ if (time_display_actions_) {
+ return;
+ }
+
+ time_display_actions_ = new QActionGroup(this);
+ QMap<QAction *, ts_type> td_actions;
+
+ td_actions[main_ui_->actionViewTimeDisplayFormatDateYMDandTimeOfDay] = TS_ABSOLUTE_WITH_YMD;
+ td_actions[main_ui_->actionViewTimeDisplayFormatDateYDOYandTimeOfDay] = TS_ABSOLUTE_WITH_YDOY;
+ td_actions[main_ui_->actionViewTimeDisplayFormatTimeOfDay] = TS_ABSOLUTE;
+ td_actions[main_ui_->actionViewTimeDisplayFormatSecondsSinceEpoch] = TS_EPOCH;
+ td_actions[main_ui_->actionViewTimeDisplayFormatSecondsSinceBeginningOfCapture] = TS_RELATIVE;
+ td_actions[main_ui_->actionViewTimeDisplayFormatSecondsSincePreviousCapturedPacket] = TS_DELTA;
+ td_actions[main_ui_->actionViewTimeDisplayFormatSecondsSincePreviousDisplayedPacket] = TS_DELTA_DIS;
+ td_actions[main_ui_->actionViewTimeDisplayFormatUTCDateYMDandTimeOfDay] = TS_UTC_WITH_YMD;
+ td_actions[main_ui_->actionViewTimeDisplayFormatUTCDateYDOYandTimeOfDay] = TS_UTC_WITH_YDOY;
+ td_actions[main_ui_->actionViewTimeDisplayFormatUTCTimeOfDay] = TS_UTC;
+
+ foreach (QAction* tda, td_actions.keys()) {
+ tda->setData(qVariantFromValue(td_actions[tda]));
+ time_display_actions_->addAction(tda);
+ if (recent.gui_time_format == td_actions[tda]) {
+ tda->setChecked(true);
+ }
+ }
+
+ connect(time_display_actions_, SIGNAL(triggered(QAction*)), this, SLOT(setTimestampFormat(QAction*)));
+
+ main_ui_->actionViewTimeDisplaySecondsWithHoursAndMinutes->setChecked(recent.gui_seconds_format == TS_SECONDS_HOUR_MIN_SEC);
+}
+
+Q_DECLARE_METATYPE(ts_precision)
+
+void MainWindow::initTimePrecisionFormatMenu()
+{
+ if (time_precision_actions_) {
+ return;
+ }
+
+ time_precision_actions_ = new QActionGroup(this);
+ QMap<QAction *, ts_precision> tp_actions;
+ tp_actions[main_ui_->actionViewTimeDisplayFormatPrecisionAutomatic] = TS_PREC_AUTO;
+ tp_actions[main_ui_->actionViewTimeDisplayFormatPrecisionSeconds] = TS_PREC_FIXED_SEC;
+ tp_actions[main_ui_->actionViewTimeDisplayFormatPrecisionDeciseconds] = TS_PREC_FIXED_DSEC;
+ tp_actions[main_ui_->actionViewTimeDisplayFormatPrecisionCentiseconds] = TS_PREC_FIXED_CSEC;
+ tp_actions[main_ui_->actionViewTimeDisplayFormatPrecisionMilliseconds] = TS_PREC_FIXED_MSEC;
+ tp_actions[main_ui_->actionViewTimeDisplayFormatPrecisionMicroseconds] = TS_PREC_FIXED_USEC;
+ tp_actions[main_ui_->actionViewTimeDisplayFormatPrecisionNanoseconds] = TS_PREC_FIXED_NSEC;
+
+ foreach (QAction* tpa, tp_actions.keys()) {
+ tpa->setData(qVariantFromValue(tp_actions[tpa]));
+ time_precision_actions_->addAction(tpa);
+ if (recent.gui_time_precision == tp_actions[tpa]) {
+ tpa->setChecked(true);
+ }
+ }
+
+ connect(time_precision_actions_, SIGNAL(triggered(QAction*)), this, SLOT(setTimestampPrecision(QAction*)));
+}
+
// Titlebar
void MainWindow::setTitlebarForCaptureFile()
{
- if (cap_file_ && cap_file_->filename) {
+ if (capture_file_.capFile() && capture_file_.capFile()->filename) {
//
// Qt *REALLY* doesn't like windows that sometimes have a
// title set with setWindowTitle() and other times have a
// live capture at time T1 and then, after you've saved the live
// capture to a user file, associated with a user file at time T2.
//
- if (cap_file_->is_tempfile) {
+ if (capture_file_.capFile()->is_tempfile) {
//
// For a temporary file, put the source of the data
// in the window title, not whatever random pile
//
gchar *window_name;
setWindowFilePath(NULL);
- window_name = g_strdup_printf("Capturing from %s[*]", cf_get_tempfile_source(cap_file_)); //TODO : Fix Translate
+ window_name = g_strdup_printf("Capturing from %s[*]", cf_get_tempfile_source(capture_file_.capFile())); //TODO : Fix Translate
setWindowTitle(window_name);
g_free(window_name);
} else {
// file path to UTF-8. If that fails, we're somewhat
// stuck.
//
- char *utf8_filename = g_filename_to_utf8(cap_file_->filename,
+ char *utf8_filename = g_filename_to_utf8(capture_file_.capFile()->filename,
-1,
NULL,
NULL,
g_free(utf8_filename);
}
}
- setWindowModified(cf_has_unsaved_data(cap_file_));
+ setWindowModified(cf_has_unsaved_data(capture_file_.capFile()));
} else {
/* We have no capture file. */
setWindowFilePath(NULL);
gchar *window_name;
setWindowFilePath(NULL);
- if (cap_file_) {
- window_name = g_strdup_printf("Capturing from %s", cf_get_tempfile_source(cap_file_)); //TODO : Fix Translate
+ if (capture_file_.capFile()) {
+ window_name = g_strdup_printf("Capturing from %s", cf_get_tempfile_source(capture_file_.capFile())); //TODO : Fix Translate
setWindowTitle(window_name);
g_free(window_name);
} else {
{
gboolean is_tcp = FALSE, is_udp = FALSE;
- if (!cap_file_)
+ if (!capture_file_.capFile())
return;
- if (!cap_file_->edt)
+ if (!capture_file_.capFile()->edt)
return;
main_ui_->actionAnalyzeFollowTCPStream->setEnabled(false);
main_ui_->actionAnalyzeFollowUDPStream->setEnabled(false);
main_ui_->actionAnalyzeFollowSSLStream->setEnabled(false);
- proto_get_frame_protocols(cap_file_->edt->pi.layers, NULL, &is_tcp, &is_udp, NULL, NULL);
-
+ proto_get_frame_protocols(capture_file_.capFile()->edt->pi.layers, NULL, &is_tcp, &is_udp, NULL, NULL);
+
if (is_tcp)
{
main_ui_->actionAnalyzeFollowTCPStream->setEnabled(true);
main_ui_->actionAnalyzeFollowUDPStream->setEnabled(true);
}
- if ( epan_dissect_packet_contains_field(cap_file_->edt, "ssl") )
+ if ( epan_dissect_packet_contains_field(capture_file_.capFile()->edt, "ssl") )
{
main_ui_->actionAnalyzeFollowSSLStream->setEnabled(true);
}
and whether it could be saved except by copying the raw packet data. */
void MainWindow::setMenusForCaptureFile(bool force_disable)
{
- if (force_disable || cap_file_ == NULL || cap_file_->state == FILE_READ_IN_PROGRESS) {
+ if (force_disable || capture_file_.capFile() == NULL || capture_file_.capFile()->state == FILE_READ_IN_PROGRESS) {
/* We have no capture file or we're currently reading a file */
main_ui_->actionFileMerge->setEnabled(false);
main_ui_->actionFileClose->setEnabled(false);
main_ui_->actionFileSave->setEnabled(false);
main_ui_->actionFileSaveAs->setEnabled(false);
- main_ui_->actionSummary->setEnabled(false);
+ main_ui_->actionStatisticsCaptureFileProperties->setEnabled(false);
main_ui_->actionFileExportPackets->setEnabled(false);
main_ui_->menuFileExportPacketDissections->setEnabled(false);
main_ui_->actionFileExportPacketBytes->setEnabled(false);
+ main_ui_->actionFileExportPDU->setEnabled(false);
main_ui_->actionFileExportSSLSessionKeys->setEnabled(false);
main_ui_->menuFileExportObjects->setEnabled(false);
main_ui_->actionViewReload->setEnabled(false);
} else {
- main_ui_->actionFileMerge->setEnabled(cf_can_write_with_wiretap(cap_file_));
+ main_ui_->actionFileMerge->setEnabled(cf_can_write_with_wiretap(capture_file_.capFile()));
main_ui_->actionFileClose->setEnabled(true);
- main_ui_->actionFileSave->setEnabled(cf_can_save(cap_file_));
- main_ui_->actionFileSaveAs->setEnabled(cf_can_save_as(cap_file_));
- main_ui_->actionSummary->setEnabled(true);
+ main_ui_->actionFileSave->setEnabled(cf_can_save(capture_file_.capFile()));
+ main_ui_->actionFileSaveAs->setEnabled(cf_can_save_as(capture_file_.capFile()));
+ main_ui_->actionStatisticsCaptureFileProperties->setEnabled(true);
/*
* "Export Specified Packets..." should be available only if
* we can write the file out in at least one format.
*/
- main_ui_->actionFileExportPackets->setEnabled(cf_can_write_with_wiretap(cap_file_));
+ main_ui_->actionFileExportPackets->setEnabled(cf_can_write_with_wiretap(capture_file_.capFile()));
main_ui_->menuFileExportPacketDissections->setEnabled(true);
main_ui_->actionFileExportPacketBytes->setEnabled(true);
+ main_ui_->actionFileExportPDU->setEnabled(true);
main_ui_->actionFileExportSSLSessionKeys->setEnabled(true);
main_ui_->menuFileExportObjects->setEnabled(true);
main_ui_->actionViewReload->setEnabled(true);
main_ui_->menuOpenRecentCaptureFile->setEnabled(!capture_in_progress);
main_ui_->menuFileExportPacketDissections->setEnabled(capture_in_progress);
main_ui_->actionFileExportPacketBytes->setEnabled(capture_in_progress);
+ main_ui_->actionFileExportPDU->setEnabled(capture_in_progress);
main_ui_->actionFileExportSSLSessionKeys->setEnabled(capture_in_progress);
main_ui_->menuFileExportObjects->setEnabled(capture_in_progress);
main_ui_->menuFileSet->setEnabled(!capture_in_progress);
main_ui_->actionFileQuit->setEnabled(true);
- main_ui_->actionSummary->setEnabled(capture_in_progress);
+ main_ui_->actionStatisticsCaptureFileProperties->setEnabled(capture_in_progress);
- qDebug() << "FIX: packet list heading menu sensitivity";
+ // XXX Fix packet list heading menu sensitivity
// set_menu_sensitivity(ui_manager_packet_list_heading, "/PacketListHeadingPopup/SortAscending",
// !capture_in_progress);
// set_menu_sensitivity(ui_manager_packet_list_heading, "/PacketListHeadingPopup/SortDescending",
#ifdef HAVE_LIBPCAP
main_ui_->actionCaptureOptions->setEnabled(!capture_in_progress);
- main_ui_->actionStartCapture->setEnabled(!capture_in_progress);
- main_ui_->actionStartCapture->setChecked(capture_in_progress);
- main_ui_->actionStopCapture->setEnabled(capture_in_progress);
+ main_ui_->actionCaptureStart->setEnabled(!capture_in_progress);
+ main_ui_->actionCaptureStart->setChecked(capture_in_progress);
+ main_ui_->actionCaptureStop->setEnabled(capture_in_progress);
main_ui_->actionCaptureRestart->setEnabled(capture_in_progress);
#endif /* HAVE_LIBPCAP */
void MainWindow::setMenusForCaptureStopping() {
main_ui_->actionFileQuit->setEnabled(false);
- main_ui_->actionSummary->setEnabled(false);
+ main_ui_->actionStatisticsCaptureFileProperties->setEnabled(false);
#ifdef HAVE_LIBPCAP
- main_ui_->actionStartCapture->setChecked(false);
- main_ui_->actionStopCapture->setEnabled(false);
+ main_ui_->actionCaptureStart->setChecked(false);
+ main_ui_->actionCaptureStop->setEnabled(false);
main_ui_->actionCaptureRestart->setEnabled(false);
#endif /* HAVE_LIBPCAP */
}
main_ui_->actionEditFindPacket->setEnabled(have_captured_packets);
main_ui_->actionEditFindNext->setEnabled(have_captured_packets);
main_ui_->actionEditFindPrevious->setEnabled(have_captured_packets);
-// set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/ZoomIn",
-// have_captured_packets);
-// set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/ZoomOut",
-// have_captured_packets);
-// set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/NormalSize",
-// have_captured_packets);
main_ui_->actionGoGoToPacket->setEnabled(have_captured_packets);
main_ui_->actionGoPreviousPacket->setEnabled(have_captured_packets);
main_ui_->actionGoFirstPacket->setEnabled(have_captured_packets);
main_ui_->actionGoLastPacket->setEnabled(have_captured_packets);
+ main_ui_->actionViewZoomIn->setEnabled(have_captured_packets);
+ main_ui_->actionViewZoomOut->setEnabled(have_captured_packets);
+ main_ui_->actionViewNormalSize->setEnabled(have_captured_packets);
+ main_ui_->actionViewResizeColumns->setEnabled(have_captured_packets);
+
// set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/GoMenu/PreviousPacketInConversation",
// have_captured_packets);
// set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/GoMenu/NextPacketInConversation",
// have_captured_packets);
// set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/StatisticsMenu/ProtocolHierarchy",
// have_captured_packets);
+ main_ui_->actionStatisticsIOGraph->setEnabled(have_captured_packets);
}
void MainWindow::setMenusForFileSet(bool enable_list_files) {
void MainWindow::updateForUnsavedChanges() {
setTitlebarForCaptureFile();
setMenusForCaptureFile();
-// set_toolbar_for_capture_file(cf);
+}
+void MainWindow::changeEvent(QEvent* event)
+{
+ if (0 != event)
+ {
+ switch (event->type())
+ {
+ case QEvent::LanguageChange:
+ main_ui_->retranslateUi(this);
+ break;
+ case QEvent::LocaleChange:{
+ QString locale = QLocale::system().name();
+ locale.truncate(locale.lastIndexOf('_'));
+ wsApp->loadLanguage(locale);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ QMainWindow::changeEvent(event);
}
/* Update main window items based on whether there's a capture in progress. */