Qt: Add a CaptureFile class.
[metze/wireshark/wip.git] / ui / qt / main_window.cpp
index d3e08a2c0d2eec9a7d7cf7e87518ad5679827ca8..cfa317e3388cca7f883edbb8089977a5a244ccae 100644 (file)
@@ -1,6 +1,4 @@
 /* main_window.cpp
- *
- * $Id$
  *
  * Wireshark - Network traffic analyzer
  * By Gerald Combs <gerald@wireshark.org>
@@ -24,8 +22,7 @@
 #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>
@@ -64,7 +65,7 @@
 #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
@@ -94,7 +159,14 @@ MainWindow::MainWindow(QWidget *parent) :
     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();
@@ -109,16 +181,18 @@ MainWindow::MainWindow(QWidget *parent) :
     //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()));
@@ -133,13 +207,7 @@ MainWindow::MainWindow(QWidget *parent) :
     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.
@@ -160,16 +228,11 @@ MainWindow::MainWindow(QWidget *parent) :
 #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);
@@ -182,7 +245,7 @@ MainWindow::MainWindow(QWidget *parent) :
     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"));
@@ -206,31 +269,42 @@ MainWindow::MainWindow(QWidget *parent) :
 
     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()),
@@ -239,6 +313,8 @@ MainWindow::MainWindow(QWidget *parent) :
             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()));
@@ -258,6 +334,13 @@ MainWindow::MainWindow(QWidget *parent) :
     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()),
@@ -283,10 +366,15 @@ MainWindow::MainWindow(QWidget *parent) :
 
     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&)));
 
@@ -301,6 +389,10 @@ MainWindow::MainWindow(QWidget *parent) :
 
     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_);
@@ -411,6 +503,9 @@ void MainWindow::closeEvent(QCloseEvent *event) {
         return;
     }
 
+#ifdef HAVE_LIBPCAP
+    capture_interfaces_dialog_.close();
+#endif
     // Make sure we kill any open dumpcap processes.
     delete main_welcome_;
 
@@ -447,7 +542,7 @@ void MainWindow::loadWindowGeometry()
 
     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);
     }
 
@@ -523,11 +618,11 @@ void MainWindow::mergeCaptureFile()
     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;
@@ -535,14 +630,14 @@ void MainWindow::mergeCaptureFile()
             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."));
@@ -557,7 +652,7 @@ void MainWindow::mergeCaptureFile()
 
             case QMessageBox::Save:
                 /* Save the file but don't close it */
-                saveCaptureFile(cap_file_, FALSE);
+                saveCaptureFile(capture_file_.capFile(), FALSE);
                 break;
 
             case QMessageBox::Cancel:
@@ -569,7 +664,7 @@ void MainWindow::mergeCaptureFile()
     }
 
     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];
@@ -597,7 +692,7 @@ void MainWindow::mergeCaptureFile()
 
         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. */
@@ -611,23 +706,23 @@ void MainWindow::mergeCaptureFile()
             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);
         }
@@ -639,13 +734,13 @@ void MainWindow::mergeCaptureFile()
             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);
@@ -655,9 +750,9 @@ void MainWindow::mergeCaptureFile()
         /* 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:
@@ -765,11 +860,11 @@ void MainWindow::saveCaptureFile(capture_file *cf, bool stay_closed) {
             }
 
             /* 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) {
 
@@ -885,15 +980,16 @@ void MainWindow::saveAsCaptureFile(capture_file *cf, bool must_support_comments,
 //#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)
@@ -924,16 +1020,16 @@ void MainWindow::exportSelectedPackets() {
     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) {
 
@@ -998,7 +1094,7 @@ void MainWindow::exportSelectedPackets() {
          * 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());
 
@@ -1026,14 +1122,15 @@ void MainWindow::exportSelectedPackets() {
 //#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)
@@ -1053,14 +1150,14 @@ void MainWindow::exportSelectedPackets() {
 }
 
 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;
 
@@ -1126,11 +1223,11 @@ void MainWindow::fileAddExtension(QString &file_name, int file_type, bool compre
 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
@@ -1141,17 +1238,17 @@ bool MainWindow::testCaptureFileClose(bool from_quit, QString &before_what) {
 #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."));
@@ -1172,14 +1269,16 @@ bool MainWindow::testCaptureFileClose(bool from_quit, QString &before_what) {
                 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."));
                 }
             }
@@ -1199,7 +1298,7 @@ bool MainWindow::testCaptureFileClose(bool from_quit, QString &before_what) {
             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 {
@@ -1211,7 +1310,7 @@ bool MainWindow::testCaptureFileClose(bool from_quit, QString &before_what) {
                     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);
                 }
             }
 
@@ -1230,7 +1329,7 @@ bool MainWindow::testCaptureFileClose(bool from_quit, QString &before_what) {
                     captureStop();
 #endif
                 /* Save the file and close it */
-                saveCaptureFile(cap_file_, TRUE);
+                saveCaptureFile(capture_file_.capFile(), TRUE);
             }
             else if(msg_dialog.clickedButton() == discardButton)
             {
@@ -1243,7 +1342,7 @@ bool MainWindow::testCaptureFileClose(bool from_quit, QString &before_what) {
                     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
@@ -1253,7 +1352,7 @@ bool MainWindow::testCaptureFileClose(bool from_quit, QString &before_what) {
 
         } 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.
@@ -1264,7 +1363,7 @@ bool MainWindow::testCaptureFileClose(bool from_quit, QString &before_what) {
         if (capture_in_progress)
             captureStop();
 #endif
-        cf_close(cap_file_);
+        cf_close(capture_file_.capFile());
     }
 
     return true; /* File closed */
@@ -1273,15 +1372,158 @@ bool MainWindow::testCaptureFileClose(bool from_quit, QString &before_what) {
 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
@@ -1302,7 +1544,7 @@ void MainWindow::setTitlebarForCaptureFile()
         // 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
@@ -1314,7 +1556,7 @@ void MainWindow::setTitlebarForCaptureFile()
             //
             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 {
@@ -1328,7 +1570,7 @@ void MainWindow::setTitlebarForCaptureFile()
             // 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,
@@ -1343,7 +1585,7 @@ void MainWindow::setTitlebarForCaptureFile()
                 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);
@@ -1362,8 +1604,8 @@ void MainWindow::setTitlebarForCaptureInProgress()
     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 {
@@ -1378,18 +1620,18 @@ void MainWindow::setMenusForFollowStream()
 {
     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);
@@ -1400,7 +1642,7 @@ void MainWindow::setMenusForFollowStream()
         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);
     }
@@ -1411,33 +1653,35 @@ void MainWindow::setMenusForFollowStream()
    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);
@@ -1452,14 +1696,15 @@ void MainWindow::setMenusForCaptureInProgress(bool capture_in_progress) {
     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",
@@ -1469,9 +1714,9 @@ void MainWindow::setMenusForCaptureInProgress(bool capture_in_progress) {
 
 #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 */
 
@@ -1479,10 +1724,10 @@ void MainWindow::setMenusForCaptureInProgress(bool capture_in_progress) {
 
 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 */
 }
@@ -1497,12 +1742,6 @@ void MainWindow::setForCapturedPackets(bool have_captured_packets)
     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);
@@ -1510,6 +1749,11 @@ void MainWindow::setForCapturedPackets(bool 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",
@@ -1518,6 +1762,7 @@ void MainWindow::setForCapturedPackets(bool have_captured_packets)
 //                         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) {
@@ -1532,8 +1777,28 @@ 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. */