Qt: Lazily create dialogs.
[metze/wireshark/wip.git] / ui / qt / main_window_slots.cpp
index dfcff451850ce0d60225b4c507176809ce03c3b7..f543890d040763505c23f1090478524654519862 100644 (file)
 
 #include <config.h>
 
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
+// Qt 5.5.0 + Visual C++ 2013
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4996)
 #endif
 
 #include "main_window.h"
 
 #ifdef _WIN32
 #include <windows.h>
-#include <io.h>
 #endif
 
 #ifdef HAVE_LIBPCAP
 #include "ui/capture.h"
 #endif
 
-#include "color_filters.h"
+#include "epan/color_filters.h"
 
 #include "wsutil/file_util.h"
 #include "wsutil/filesystem.h"
-#include <wsutil/str_util.h>
 
 #include "epan/addr_resolv.h"
-#include "epan/color_dissector_filters.h"
 #include "epan/column.h"
 #include "epan/dfilter/dfilter-macro.h"
+#include "epan/dissector_filters.h"
 #include "epan/epan_dissect.h"
 #include "epan/filter_expressions.h"
 #include "epan/prefs.h"
@@ -74,6 +70,7 @@
 #include "ui/recent_utils.h"
 #include "ui/ssl_key_export.h"
 #include "ui/ui_util.h"
+#include "ui/all_files_wildcard.h"
 #include "ui/qt/simple_dialog.h"
 
 #ifdef HAVE_SOFTWARE_UPDATE
 #include "bluetooth_hci_summary_dialog.h"
 #include "capture_file_dialog.h"
 #include "capture_file_properties_dialog.h"
+#ifdef HAVE_LIBPCAP
+#include "capture_interfaces_dialog.h"
+#endif
 #include "color_utils.h"
 #include "coloring_rules_dialog.h"
 #include "conversation_dialog.h"
+#include "conversation_colorize_action.h"
+#include "conversation_hash_tables_dialog.h"
 #include "enabled_protocols_dialog.h"
 #include "decode_as_dialog.h"
 #include "display_filter_edit.h"
 #include "display_filter_expression_dialog.h"
+#include "dissector_tables_dialog.h"
 #include "endpoint_dialog.h"
 #include "expert_info_dialog.h"
 #include "export_object_dialog.h"
 #include "export_pdu_dialog.h"
-#if HAVE_EXTCAP
+#ifdef HAVE_EXTCAP
 #include "extcap_options_dialog.h"
 #endif
+#include "file_set_dialog.h"
 #include "filter_action.h"
 #include "filter_dialog.h"
 #include "funnel_statistics.h"
 #include "lbm_uimflow_dialog.h"
 #include "lbm_lbtrm_transport_dialog.h"
 #include "lbm_lbtru_transport_dialog.h"
+#include "lte_mac_statistics_dialog.h"
+#include "lte_rlc_statistics_dialog.h"
+#include "lte_rlc_graph_dialog.h"
 #include "mtp3_summary_dialog.h"
 #include "multicast_statistics_dialog.h"
 #include "packet_comment_dialog.h"
 #include "sctp_assoc_analyse_dialog.h"
 #include "sctp_graph_dialog.h"
 #include "sequence_dialog.h"
+#include "show_packet_bytes_dialog.h"
 #include "stats_tree_dialog.h"
 #include "stock_icon.h"
+#include "supported_protocols_dialog.h"
 #include "tap_parameter_dialog.h"
 #include "tcp_stream_dialog.h"
 #include "time_shift_dialog.h"
 
 static const char *dfe_property_ = "display filter expression"; //TODO : Fix Translate
 
-// We're too lazy to sublcass QAction.
-static const char *color_number_property_ = "color number";
-
 bool MainWindow::openCaptureFile(QString cf_path, QString read_filter, unsigned int type)
 {
     QString file_name = "";
@@ -172,26 +178,6 @@ bool MainWindow::openCaptureFile(QString cf_path, QString read_filter, unsigned
         if (cf_path.isEmpty()) {
             CaptureFileDialog open_dlg(this, capture_file_.capFile(), read_filter);
 
-            switch (prefs.gui_fileopen_style) {
-
-            case FO_STYLE_LAST_OPENED:
-                /* The user has specified that we should start out in the last directory
-                   we looked in.  If we've already opened a file, use its containing
-                   directory, if we could determine it, as the directory, otherwise
-                   use the "last opened" directory saved in the preferences file if
-                   there was one. */
-                /* This is now the default behaviour in file_selection_new() */
-                break;
-
-            case FO_STYLE_SPECIFIED:
-                /* The user has specified that we should always start out in a
-                   specified directory; if they've specified that directory,
-                   start out by showing the files in that dir. */
-                if (prefs.gui_fileopen_dir[0] != '\0')
-                    open_dlg.setDirectory(prefs.gui_fileopen_dir);
-                break;
-            }
-
             if (open_dlg.open(file_name, type)) {
                 cf_path = file_name;
             } else {
@@ -199,7 +185,8 @@ bool MainWindow::openCaptureFile(QString cf_path, QString read_filter, unsigned
             }
         }
 
-        if (!testCaptureFileClose(false)) {
+        QString before_what(tr(" before opening another file"));
+        if (!testCaptureFileClose(before_what)) {
             return false;
         }
 
@@ -257,7 +244,7 @@ bool MainWindow::openCaptureFile(QString cf_path, QString read_filter, unsigned
         }
         break;
     }
-    // get_dirname overwrites its path. Hopefully this isn't a problem.
+    // get_dirname overwrites its path.
     wsApp->setLastOpenDir(get_dirname(cf_path.toUtf8().data()));
 
     main_ui_->statusBar->showExpert();
@@ -287,6 +274,9 @@ void MainWindow::filterPackets(QString new_filter, bool force)
     } else {
         emit displayFilterSuccess(false);
     }
+    if (packet_list_) {
+        packet_list_->resetColumns();
+    }
 }
 
 // A new layout should be applied when it differs from the old layout AND
@@ -299,7 +289,11 @@ void MainWindow::layoutPanes()
     QVector<unsigned> new_layout = QVector<unsigned>() << prefs.gui_layout_type
                                                        << prefs.gui_layout_content_1
                                                        << prefs.gui_layout_content_2
-                                                       << prefs.gui_layout_content_3;
+                                                       << prefs.gui_layout_content_3
+                                                       << recent.packet_list_show
+                                                       << recent.tree_view_show
+                                                       << recent.byte_view_show;
+
     if (cur_layout_ == new_layout) return;
 
     QSplitter *parents[3];
@@ -446,6 +440,11 @@ void MainWindow::layoutToolbars()
     }
 
     main_ui_->mainToolBar->setToolButtonStyle(tbstyle);
+
+    main_ui_->mainToolBar->setVisible(recent.main_toolbar_show);
+    main_ui_->displayFilterToolBar->setVisible(recent.filter_toolbar_show);
+    main_ui_->wirelessToolBar->setVisible(recent.wireless_toolbar_show);
+    main_ui_->statusBar->setVisible(recent.statusbar_show);
 }
 
 void MainWindow::updatePreferenceActions()
@@ -458,6 +457,31 @@ void MainWindow::updatePreferenceActions()
     main_ui_->actionGoAutoScroll->setChecked(prefs.capture_auto_scroll);
 }
 
+void MainWindow::updateRecentActions()
+{
+    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* tda, td_actions.keys()) {
+        if (recent.gui_time_format == td_actions[tda]) {
+            tda->setChecked(true);
+        }
+    }
+    foreach (QAction* tpa, tp_actions.keys()) {
+        if (recent.gui_time_precision == tp_actions[tpa]) {
+            tpa->setChecked(true);
+        }
+    }
+    main_ui_->actionViewTimeDisplaySecondsWithHoursAndMinutes->setChecked(recent.gui_seconds_format == TS_SECONDS_HOUR_MIN_SEC);
+
+    main_ui_->actionViewColorizePacketList->setChecked(recent.packet_list_colorize);
+}
+
 void MainWindow::filterAction(QString &action_filter, FilterAction::Action action, FilterAction::ActionType type)
 {
     QString cur_filter, new_filter;
@@ -636,7 +660,9 @@ void MainWindow::captureCaptureFailed(capture_session *) {
 void MainWindow::captureFileOpened() {
     if (capture_file_.window() != this) return;
 
-    file_set_dialog_.fileOpened(capture_file_.capFile());
+    if (file_set_dialog_) {
+        file_set_dialog_->fileOpened(capture_file_.capFile());
+    }
     setMenusForFileSet(true);
     emit setCaptureFile(capture_file_.capFile());
 }
@@ -652,6 +678,8 @@ void MainWindow::captureFileReadStarted(const QString &action) {
     QString msgtip = QString();
     main_ui_->statusBar->pushFileStatus(msg, msgtip);
     main_ui_->mainStack->setCurrentWidget(&master_split_);
+    main_ui_->actionAnalyzeReloadLuaPlugins->setEnabled(false);
+
     WiresharkApplication::processEvents();
 }
 
@@ -663,8 +691,8 @@ void MainWindow::captureFileReadFinished() {
         add_menu_recent_capture_file(capture_file_.capFile()->filename);
 
         /* Remember folder for next Open dialog and save it in recent */
-        dir_path = get_dirname(g_strdup(capture_file_.capFile()->filename));
-        wsApp->setLastOpenDir(dir_path);
+        dir_path = g_strdup(capture_file_.capFile()->filename);
+        wsApp->setLastOpenDir(get_dirname(dir_path));
         g_free(dir_path);
     }
 
@@ -675,39 +703,32 @@ void MainWindow::captureFileReadFinished() {
     setForCapturedPackets(true);
 
     main_ui_->statusBar->setFileName(capture_file_);
+    main_ui_->actionAnalyzeReloadLuaPlugins->setEnabled(true);
 
     packet_list_->captureFileReadFinished();
 
     emit setDissectedCaptureFile(capture_file_.capFile());
 }
 
-// Our event loop becomes nested whenever we call update_progress_dlg, which
-// includes several places in file.c. The GTK+ UI stays out of trouble by
-// showing a modal progress dialog. We attempt to do the equivalent below by
-// disabling parts of the main window. At a minumum the ProgressFrame in the
-// main status bar must remain accessible.
-//
-// We might want to do this any time the main status bar progress frame is
-// shown and hidden.
 void MainWindow::captureFileRetapStarted()
 {
     // XXX Push a status message?
-    main_ui_->actionFileClose->setEnabled(false);
-    main_ui_->actionViewReload->setEnabled(false);
-    main_ui_->centralWidget->setEnabled(false);
+    freeze();
 }
 
 void MainWindow::captureFileRetapFinished()
 {
-    main_ui_->actionFileClose->setEnabled(true);
-    main_ui_->actionViewReload->setEnabled(true);
-    main_ui_->centralWidget->setEnabled(true);
+    thaw();
+}
+
+void MainWindow::captureFileFlushTapsData()
+{
+    draw_tap_listeners(FALSE);
 }
 
 void MainWindow::captureFileClosing() {
     setMenusForCaptureFile(true);
     setForCapturedPackets(false);
-    setMenusForSelectedPacket();
     setForCaptureInProgress(false);
 
     // Reset expert information indicator
@@ -721,15 +742,20 @@ void MainWindow::captureFileClosing() {
 void MainWindow::captureFileClosed() {
     packets_bar_update();
 
-    file_set_dialog_.fileClosed();
+    if (file_set_dialog_) {
+        file_set_dialog_->fileClosed();
+    }
     setMenusForFileSet(false);
+    setWindowModified(false);
 
     // Reset expert information indicator
     main_ui_->statusBar->captureFileClosing();
 
     main_ui_->statusBar->popFileStatus();
 
-    setTitlebarForSelectedTreeRow();
+    setWSWindowTitle();
+    setWindowIcon(wsApp->normalIcon());
+    setMenusForSelectedPacket();
     setMenusForSelectedTreeRow();
 
     if (!global_capture_opts.multi_files_on)
@@ -748,13 +774,13 @@ void MainWindow::filterExpressionsChanged()
     // Recreate filter buttons
     foreach (QAction *act, main_ui_->displayFilterToolBar->actions()) {
         // Permanent actions shouldn't have data
-        if (act->property(dfe_property_).isValid() || act->isSeparator()) {
+        if (act->property(dfe_property_).isValid()) {
             main_ui_->displayFilterToolBar->removeAction(act);
             delete act;
         }
     }
 
-    bool first = true;
+    // XXX Add a context menu for removing and changing buttons.
     for (struct filter_expression *fe = *pfilter_expression_head; fe != NULL; fe = fe->next) {
         if (!fe->enabled) continue;
         QAction *dfb_action = new QAction(fe->label, main_ui_->displayFilterToolBar);
@@ -763,10 +789,6 @@ void MainWindow::filterExpressionsChanged()
         dfb_action->setProperty(dfe_property_, true);
         main_ui_->displayFilterToolBar->addAction(dfb_action);
         connect(dfb_action, SIGNAL(triggered()), this, SLOT(displayFilterButtonClicked()));
-        if (first) {
-            first = false;
-            main_ui_->displayFilterToolBar->insertSeparator(dfb_action);
-        }
     }
 }
 
@@ -789,8 +811,6 @@ void MainWindow::startCapture() {
         return;
     }
 
-    main_ui_->mainStack->setCurrentWidget(&master_split_);
-
     // Ideally we should have disabled the start capture
     // toolbar buttons and menu items. This may not be the
     // case, e.g. with QtMacExtras.
@@ -801,6 +821,8 @@ void MainWindow::startCapture() {
         return;
     }
 
+    main_ui_->mainStack->setCurrentWidget(&master_split_);
+
     /* XXX - we might need to init other pref data as well... */
 
     /* XXX - can this ever happen? */
@@ -815,12 +837,12 @@ void MainWindow::startCapture() {
     collect_ifaces(&global_capture_opts);
 
     CaptureFile::globalCapFile()->window = this;
-    if (capture_start(&global_capture_opts, &cap_session_, main_window_update)) {
+    if (capture_start(&global_capture_opts, &cap_session_, &info_data_, main_window_update)) {
         capture_options *capture_opts = cap_session_.capture_opts;
         GString *interface_names;
 
         /* enable autoscroll timer as needed. */
-        packet_list_->setAutoScroll(main_ui_->actionGoAutoScroll->isChecked());
+        packet_list_->setVerticalAutoScroll(main_ui_->actionGoAutoScroll->isChecked());
 
         /* Add "interface name<live capture in progress>" on main status bar */
         interface_names = get_iface_list_string(capture_opts, 0);
@@ -837,12 +859,28 @@ void MainWindow::startCapture() {
 
         /* The capture succeeded, which means the capture filter syntax is
          valid; add this capture filter to the recent capture filter list. */
+        QByteArray filter_ba;
         for (i = 0; i < global_capture_opts.ifaces->len; i++) {
             interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
             if (interface_opts.cfilter) {
-//              cfilter_combo_add_recent(interface_opts.cfilter);
+                recent_add_cfilter(interface_opts.name, interface_opts.cfilter);
+                if (filter_ba.isEmpty()) {
+                    filter_ba = interface_opts.cfilter;
+                } else {
+                    /* Not the first selected interface; is its capture filter
+                       the same as the one the other interfaces we've looked
+                       at have? */
+                    if (strcmp(interface_opts.cfilter, filter_ba.constData()) != 0) {
+                      /* No, so not all selected interfaces have the same capture
+                         filter. */
+                        filter_ba.clear();
+                    }
+                }
             }
         }
+        if (!filter_ba.isEmpty()) {
+            recent_add_cfilter(NULL, filter_ba.constData());
+        }
     } else {
         CaptureFile::globalCapFile()->window = NULL;
     }
@@ -935,7 +973,7 @@ void MainWindow::stopCapture() {
     main_ui_->statusBar->setFileName(capture_file_);
 
     /* disable autoscroll timer if any. */
-    packet_list_->setAutoScroll(false);
+    packet_list_->setVerticalAutoScroll(false);
 }
 
 // Keep focus rects from showing through the welcome screen. Primarily for
@@ -1012,7 +1050,7 @@ void MainWindow::recentActionTriggered() {
 
 void MainWindow::setMenusForSelectedPacket()
 {
-    gboolean is_ip = FALSE, is_tcp = FALSE, is_udp = FALSE, is_sctp = FALSE, is_ssl = FALSE, is_rtp = FALSE;
+    gboolean is_ip = FALSE, is_tcp = FALSE, is_udp = FALSE, is_sctp = FALSE, is_ssl = FALSE, is_rtp = FALSE, is_lte_rlc = FALSE, is_http = FALSE;
 
     /* Making the menu context-sensitive allows for easier selection of the
        desired item and has the added benefit, with large captures, of
@@ -1063,7 +1101,10 @@ void MainWindow::setMenusForSelectedPacket()
 
         if (capture_file_.capFile()->edt)
         {
-            proto_get_frame_protocols(capture_file_.capFile()->edt->pi.layers, &is_ip, &is_tcp, &is_udp, &is_sctp, &is_ssl, &is_rtp);
+            proto_get_frame_protocols(capture_file_.capFile()->edt->pi.layers,
+                                      &is_ip, &is_tcp, &is_udp, &is_sctp,
+                                      &is_ssl, &is_rtp, &is_lte_rlc);
+            is_http = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "http");
         }
     }
 
@@ -1112,57 +1153,19 @@ void MainWindow::setMenusForSelectedPacket()
     main_ui_->actionAnalyzeFollowTCPStream->setEnabled(is_tcp);
     main_ui_->actionAnalyzeFollowUDPStream->setEnabled(is_udp);
     main_ui_->actionAnalyzeFollowSSLStream->setEnabled(is_ssl);
+    main_ui_->actionAnalyzeFollowHTTPStream->setEnabled(is_http);
 
     foreach (QAction *cc_action, cc_actions) {
         cc_action->setEnabled(frame_selected);
     }
-    main_ui_->actionViewColorizeNewConversationRule->setEnabled(frame_selected);
+    main_ui_->actionViewColorizeNewColoringRule->setEnabled(frame_selected);
 
     main_ui_->actionViewColorizeResetColorization->setEnabled(tmp_color_filters_used());
 
-    main_ui_->actionViewColorizeNewConversationRule->setEnabled(frame_selected);
-
     main_ui_->actionViewShowPacketInNewWindow->setEnabled(frame_selected);
     main_ui_->actionViewEditResolvedName->setEnabled(frame_selected && is_ip);
 
-    main_ui_->menuConversationFilter->clear();
-
-    packet_list_->conversationMenu()->clear();
-    packet_list_->colorizeMenu()->clear();
-
-    for (GList *color_list_entry = color_conv_filter_list; color_list_entry; color_list_entry = g_list_next(color_list_entry)) {
-        // Main menu items
-        color_conversation_filter_t* color_filter = (color_conversation_filter_t *)color_list_entry->data;
-        QAction *conv_action = main_ui_->menuConversationFilter->addAction(color_filter->display_name);
-
-        bool enable = false;
-        QString filter;
-        if (capture_file_.capFile()->edt) {
-            enable = color_filter->is_filter_valid(&capture_file_.capFile()->edt->pi);
-            filter = gchar_free_to_qstring(color_filter->build_filter_string(&capture_file_.capFile()->edt->pi));
-        }
-        conv_action->setEnabled(enable);
-        conv_action->setData(filter);
-        connect(conv_action, SIGNAL(triggered()), this, SLOT(applyConversationFilter()));
-
-        // Packet list context menu items
-        packet_list_->conversationMenu()->addAction(conv_action);
-
-        QMenu *submenu = packet_list_->colorizeMenu()->addMenu(conv_action->text());
-        int i = 1;
-        foreach (QAction *cc_action, cc_actions) {
-            QAction *colorize_action = submenu->addAction(cc_action->icon(), cc_action->text());
-            colorize_action->setProperty(color_number_property_, i++);
-            colorize_action->setData(filter);
-            colorize_action->setEnabled(enable);
-            connect(colorize_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
-        }
-
-        QAction *conv_rule_action = submenu->addAction(main_ui_->actionViewColorizeNewConversationRule->text());
-        conv_rule_action->setData(conv_action->data());
-        conv_rule_action->setEnabled(enable);
-        connect(conv_rule_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
-    }
+    emit packetInfoChanged(capture_file_.packetInfo());
 
 //    set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/NameResolution/ResolveName",
 //                         frame_selected && (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
@@ -1174,30 +1177,19 @@ void MainWindow::setMenusForSelectedPacket()
     main_ui_->actionSCTPShowAllAssociations->setEnabled(is_sctp);
     main_ui_->actionSCTPFilterThisAssociation->setEnabled(is_sctp);
     main_ui_->actionTelephonyRTPStreamAnalysis->setEnabled(is_rtp);
+    main_ui_->actionTelephonyLteRlcGraph->setEnabled(is_lte_rlc);
 }
 
 void MainWindow::setMenusForSelectedTreeRow(field_info *fi) {
-    // XXX Add commented items below
-
-    // The ProtoTree either doesn't exist yet or emitted protoItemSelected as
-    // a result of a packet list selection. Don't assume control of the menu.
-    if (!proto_tree_ || !proto_tree_->hasFocus()) return;
 
     bool can_match_selected = false;
     bool is_framenum = false;
     bool have_field_info = false;
     bool have_subtree = false;
     bool can_open_url = false;
-    QString field_filter;
+    QByteArray field_filter;
     int field_id = -1;
 
-    QList<QAction *> cc_actions = QList<QAction *>()
-            << main_ui_->actionViewColorizeConversation1 << main_ui_->actionViewColorizeConversation2
-            << main_ui_->actionViewColorizeConversation3 << main_ui_->actionViewColorizeConversation4
-            << main_ui_->actionViewColorizeConversation5 << main_ui_->actionViewColorizeConversation6
-            << main_ui_->actionViewColorizeConversation7 << main_ui_->actionViewColorizeConversation8
-            << main_ui_->actionViewColorizeConversation9 << main_ui_->actionViewColorizeConversation10;
-
     if (capture_file_.capFile()) {
         capture_file_.capFile()->finfo_selected = fi;
 
@@ -1218,7 +1210,7 @@ void MainWindow::setMenusForSelectedTreeRow(field_info *fi) {
         }
 
         char *tmp_field = proto_construct_match_selected_string(fi, capture_file_.capFile()->edt);
-        field_filter = QString(tmp_field);
+        field_filter = tmp_field;
         wmem_free(NULL, tmp_field);
 
         field_id = fi->hfinfo->id;
@@ -1227,7 +1219,7 @@ void MainWindow::setMenusForSelectedTreeRow(field_info *fi) {
             field_id = proto_registrar_get_parent(fi->hfinfo->id);
         }
 
-        if (field_id >= 0 && !proto_is_private(field_id)) {
+        if (field_id >= 0) {
             can_open_url = true;
             main_ui_->actionContextWikiProtocolPage->setData(field_id);
             main_ui_->actionContextFilterFieldReference->setData(field_id);
@@ -1243,56 +1235,39 @@ void MainWindow::setMenusForSelectedTreeRow(field_info *fi) {
         }
     }
 
-    main_ui_->menuConversationFilter->clear();
-    for (GList *color_list_entry = color_conv_filter_list; color_list_entry; color_list_entry = g_list_next(color_list_entry)) {
-        color_conversation_filter_t* color_filter = (color_conversation_filter_t *)color_list_entry->data;
-        QAction *conv_action = main_ui_->menuConversationFilter->addAction(color_filter->display_name);
-
-        bool conv_enable = false;
-        QString conv_filter;
-        if (capture_file_.capFile() && capture_file_.capFile()->edt) {
-            conv_enable = color_filter->is_filter_valid(&capture_file_.capFile()->edt->pi);
-            conv_filter = color_filter->build_filter_string(&capture_file_.capFile()->edt->pi);
-        }
-        conv_action->setEnabled(conv_enable);
-        conv_action->setData(conv_filter);
-        connect(conv_action, SIGNAL(triggered()), this, SLOT(applyConversationFilter()));
-    }
-
-    proto_tree_->colorizeMenu()->clear();
-    int i = 1;
-    foreach (QAction *cc_action, cc_actions) {
-        QAction *colorize_action = proto_tree_->colorizeMenu()->addAction(cc_action->icon(), cc_action->text());
-        colorize_action->setProperty(color_number_property_, i++);
-        colorize_action->setData(field_filter);
-        colorize_action->setEnabled(!field_filter.isEmpty());
-        connect(colorize_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
-    }
-
-    QAction *conv_rule_action = proto_tree_->colorizeMenu()->addAction(main_ui_->actionViewColorizeNewConversationRule->text());
-    conv_rule_action->setData(field_filter);
-    conv_rule_action->setEnabled(!field_filter.isEmpty());
-    connect(conv_rule_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
-
-//    set_menu_sensitivity(ui_manager_tree_view_menu, "/TreeViewPopup/ResolveName",
-//                         frame_selected && (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
-//                                            gbl_resolv_flags.transport_name || gbl_resolv_flags.concurrent_dns));
-
+    // Always enable / disable the following items.
     main_ui_->actionFileExportPacketBytes->setEnabled(have_field_info);
-    main_ui_->actionContextShowLinkedPacketInNewWindow->setEnabled(is_framenum);
 
     main_ui_->actionCopyAllVisibleItems->setEnabled(capture_file_.capFile() != NULL);
     main_ui_->actionCopyAllVisibleSelectedTreeItems->setEnabled(can_match_selected);
-
     main_ui_->actionEditCopyDescription->setEnabled(can_match_selected);
     main_ui_->actionEditCopyFieldName->setEnabled(can_match_selected);
     main_ui_->actionEditCopyValue->setEnabled(can_match_selected);
     main_ui_->actionEditCopyAsFilter->setEnabled(can_match_selected);
 
+    main_ui_->actionViewExpandSubtrees->setEnabled(have_subtree);
+
     main_ui_->actionGoGoToLinkedPacket->setEnabled(is_framenum);
 
     main_ui_->actionAnalyzeCreateAColumn->setEnabled(can_match_selected);
 
+    main_ui_->actionContextShowLinkedPacketInNewWindow->setEnabled(is_framenum);
+
+    main_ui_->actionContextWikiProtocolPage->setEnabled(can_open_url);
+    main_ui_->actionContextFilterFieldReference->setEnabled(can_open_url);
+
+
+    // Only enable / disable the following items if we have focus so that we
+    // don't clobber anything we may have set in setMenusForSelectedPacket.
+    if (!proto_tree_ || !proto_tree_->hasFocus()) return;
+
+    emit packetInfoChanged(capture_file_.packetInfo());
+    emit fieldFilterChanged(field_filter);
+
+//    set_menu_sensitivity(ui_manager_tree_view_menu, "/TreeViewPopup/ResolveName",
+//                         frame_selected && (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
+//                                            gbl_resolv_flags.transport_name || gbl_resolv_flags.concurrent_dns));
+
     main_ui_->actionAnalyzeAAFSelected->setEnabled(can_match_selected);
     main_ui_->actionAnalyzeAAFNotSelected->setEnabled(can_match_selected);
     main_ui_->actionAnalyzeAAFAndSelected->setEnabled(can_match_selected);
@@ -1306,11 +1281,6 @@ void MainWindow::setMenusForSelectedTreeRow(field_info *fi) {
     main_ui_->actionAnalyzePAFOrSelected->setEnabled(can_match_selected);
     main_ui_->actionAnalyzePAFAndNotSelected->setEnabled(can_match_selected);
     main_ui_->actionAnalyzePAFOrNotSelected->setEnabled(can_match_selected);
-
-    main_ui_->actionViewExpandSubtrees->setEnabled(have_subtree);
-
-    main_ui_->actionContextWikiProtocolPage->setEnabled(can_open_url);
-    main_ui_->actionContextFilterFieldReference->setEnabled(can_open_url);
 }
 
 void MainWindow::interfaceSelectionChanged()
@@ -1332,30 +1302,43 @@ void MainWindow::captureFilterSyntaxChanged(bool valid)
     interfaceSelectionChanged();
 }
 
-void MainWindow::startInterfaceCapture(bool valid)
+void MainWindow::startInterfaceCapture(bool valid, const QString capture_filter)
 {
     capture_filter_valid_ = valid;
+    main_welcome_->setCaptureFilter(capture_filter);
+    // The interface tree will update the selected interfaces via its timer
+    // so no need to do anything here.
     startCapture();
 }
 
 void MainWindow::redissectPackets()
 {
-    if (capture_file_.capFile())
+    if (capture_file_.capFile()) {
         cf_redissect_packets(capture_file_.capFile());
-    main_ui_->statusBar->expertUpdate();
+        main_ui_->statusBar->expertUpdate();
+    }
 
     proto_free_deregistered_fields();
 }
 
-void MainWindow::fieldsChanged()
+void MainWindow::checkDisplayFilter()
 {
-    color_filters_reload();
-    tap_listeners_dfilter_recompile();
-
     if (!df_combo_box_->checkDisplayFilter()) {
         g_free(CaptureFile::globalCapFile()->dfilter);
         CaptureFile::globalCapFile()->dfilter = NULL;
     }
+}
+
+void MainWindow::fieldsChanged()
+{
+    gchar *err_msg = NULL;
+    if (!color_filters_reload(&err_msg, color_filter_add_cb)) {
+        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
+        g_free(err_msg);
+    }
+    tap_listeners_dfilter_recompile();
+
+    emit checkDisplayFilter();
 
     if (have_custom_cols(&CaptureFile::globalCapFile()->cinfo)) {
         // Recreate packet list columns according to new/changed/deleted fields
@@ -1365,12 +1348,41 @@ void MainWindow::fieldsChanged()
     emit reloadFields();
 }
 
+void MainWindow::reloadLuaPlugins()
+{
+#ifdef HAVE_LUA
+    if (wsApp->isReloadingLua())
+        return;
+
+    wsApp->setReloadingLua(true);
+
+    wslua_reload_plugins(NULL, NULL);
+    funnel_statistics_reload_menus();
+    reloadDynamicMenus();
+    closePacketDialogs();
+
+    // Preferences may have been deleted so close all widgets using prefs
+    proto_tree_->closeContextMenu();
+    main_ui_->preferenceEditorFrame->animatedHide();
+
+    char *gdp_path, *dp_path;
+    wsApp->readConfigurationFiles(&gdp_path, &dp_path, true);
+
+    prefs_apply_all();
+    fieldsChanged();
+    redissectPackets();
+
+    wsApp->setReloadingLua(false);
+    SimpleDialog::displayQueuedMessages();
+#endif
+}
+
 void MainWindow::showAccordionFrame(AccordionFrame *show_frame, bool toggle)
 {
     QList<AccordionFrame *>frame_list = QList<AccordionFrame *>()
             << main_ui_->goToFrame << main_ui_->searchFrame
             << main_ui_->addressEditorFrame << main_ui_->columnEditorFrame
-            << main_ui_->preferenceEditorFrame;
+            << main_ui_->preferenceEditorFrame << main_ui_->filterExpressionFrame;
 
     frame_list.removeAll(show_frame);
     foreach (AccordionFrame *af, frame_list) af->animatedHide();
@@ -1490,6 +1502,12 @@ void MainWindow::on_actionDisplayFilterExpression_triggered()
     dfe_dialog->show();
 }
 
+void MainWindow::on_actionNewDisplayFilterExpression_triggered()
+{
+    main_ui_->filterExpressionFrame->addExpression(df_combo_box_->lineEdit()->text());
+    showAccordionFrame(main_ui_->filterExpressionFrame);
+}
+
 // On Qt4 + OS X with unifiedTitleAndToolBarOnMac set it's possible to make
 // the main window obnoxiously wide.
 
@@ -1549,7 +1567,8 @@ void MainWindow::on_actionFileImportFromHexDump_triggered()
 }
 
 void MainWindow::on_actionFileClose_triggered() {
-    if (testCaptureFileClose())
+    QString before_what(tr(" before closing the file"));
+    if (testCaptureFileClose(before_what))
         main_ui_->mainStack->setCurrentWidget(main_welcome_);
 }
 
@@ -1565,7 +1584,13 @@ void MainWindow::on_actionFileSaveAs_triggered()
 
 void MainWindow::on_actionFileSetListFiles_triggered()
 {
-    file_set_dialog_.exec();
+    if (!file_set_dialog_) {
+        file_set_dialog_ = new FileSetDialog(this);
+        connect(file_set_dialog_, SIGNAL(fileSetOpenCaptureFile(QString)),
+                this, SLOT(openCaptureFile(QString)));
+    }
+
+    file_set_dialog_->show();
 }
 
 void MainWindow::on_actionFileSetNextFile_triggered()
@@ -1627,7 +1652,7 @@ void MainWindow::on_actionFileExportPacketBytes_triggered()
     file_name = QFileDialog::getSaveFileName(this,
                                              wsApp->windowTitleString(tr("Export Selected Packet Bytes")),
                                              wsApp->lastOpenDir().canonicalPath(),
-                                             tr("Raw data (*.bin *.dat *.raw);;Any File (*.*)")
+                                             tr("Raw data (*.bin *.dat *.raw);;All Files (" ALL_FILES_WILDCARD ")")
                                              );
 
     if (file_name.length() > 0) {
@@ -1641,12 +1666,12 @@ void MainWindow::on_actionFileExportPacketBytes_triggered()
             open_failure_alert_box(file_name.toUtf8().constData(), errno, TRUE);
             return;
         }
-        if (write(fd, data_p, capture_file_.capFile()->finfo_selected->length) < 0) {
+        if (ws_write(fd, data_p, capture_file_.capFile()->finfo_selected->length) < 0) {
             write_failure_alert_box(file_name.toUtf8().constData(), errno);
-            ::close(fd);
+            ws_close(fd);
             return;
         }
-        if (::close(fd) < 0) {
+        if (ws_close(fd) < 0) {
             write_failure_alert_box(file_name.toUtf8().constData(), errno);
             return;
         }
@@ -1655,6 +1680,13 @@ void MainWindow::on_actionFileExportPacketBytes_triggered()
         wsApp->setLastOpenDir(&file_name);
     }
 }
+
+void MainWindow::on_actionContextShowPacketBytes_triggered()
+{
+    ShowPacketBytesDialog *spbd = new ShowPacketBytesDialog(*this, capture_file_);
+    spbd->show();
+}
+
 void MainWindow::on_actionFileExportPDU_triggered()
 {
     ExportPDUDialog *exportpdu_dialog = new ExportPDUDialog(this);
@@ -1691,12 +1723,11 @@ void MainWindow::on_actionFileExportSSLSessionKeys_triggered()
         return;
     }
 
-    save_title.append(wsApp->windowTitleString(tr("Export SSL Session Keys (%1 key%2").
-            arg(keylist_len).arg(plurality(keylist_len, "", "s"))));
+    save_title.append(wsApp->windowTitleString(tr("Export SSL Session Keys (%Ln key(s))", "", keylist_len)));
     file_name = QFileDialog::getSaveFileName(this,
                                              save_title,
                                              wsApp->lastOpenDir().canonicalPath(),
-                                             tr("SSL Session Keys (*.keys *.txt);;Any File (*.*)")
+                                             tr("SSL Session Keys (*.keys *.txt);;All Files (" ALL_FILES_WILDCARD ")")
                                              );
     if (file_name.length() > 0) {
         gchar *keylist;
@@ -1715,11 +1746,11 @@ void MainWindow::on_actionFileExportSSLSessionKeys_triggered()
          */
         if (ws_write(fd, keylist, (unsigned int)strlen(keylist)) < 0) {
             write_failure_alert_box(file_name.toUtf8().constData(), errno);
-            ::close(fd);
+            ws_close(fd);
             g_free(keylist);
             return;
         }
-        if (::close(fd) < 0) {
+        if (ws_close(fd) < 0) {
             write_failure_alert_box(file_name.toUtf8().constData(), errno);
             g_free(keylist);
             return;
@@ -1785,21 +1816,23 @@ void MainWindow::actionEditCopyTriggered(MainWindow::CopySelected selection_type
 
     if (!capture_file_.capFile()) return;
 
+    field_info *finfo_selected = capture_file_.capFile()->finfo_selected;
+
     switch(selection_type) {
     case CopySelectedDescription:
-        if (capture_file_.capFile()->finfo_selected->rep &&
-                strlen (capture_file_.capFile()->finfo_selected->rep->representation) > 0) {
-            clip.append(capture_file_.capFile()->finfo_selected->rep->representation);
+        if (finfo_selected && finfo_selected->rep
+                && strlen (finfo_selected->rep->representation) > 0) {
+            clip.append(finfo_selected->rep->representation);
         }
         break;
     case CopySelectedFieldName:
-        if (capture_file_.capFile()->finfo_selected->hfinfo->abbrev != 0) {
-            clip.append(capture_file_.capFile()->finfo_selected->hfinfo->abbrev);
+        if (finfo_selected && finfo_selected->hfinfo->abbrev != 0) {
+            clip.append(finfo_selected->hfinfo->abbrev);
         }
         break;
     case CopySelectedValue:
-        if (capture_file_.capFile()->edt != 0) {
-            gchar* field_str = get_node_field_value(capture_file_.capFile()->finfo_selected, capture_file_.capFile()->edt);
+        if (finfo_selected && capture_file_.capFile()->edt != 0) {
+            gchar* field_str = get_node_field_value(finfo_selected, capture_file_.capFile()->edt);
             clip.append(field_str);
             g_free(field_str);
         }
@@ -1814,11 +1847,12 @@ void MainWindow::actionEditCopyTriggered(MainWindow::CopySelected selection_type
 
         break;
     case CopyAllVisibleSelectedTreeItems:
-        clip.append(proto_tree_->currentItem()->text(0));
-        clip.append("\n");
-
-        recursiveCopyProtoTreeItems(proto_tree_->currentItem(), clip, 1);
+        if (proto_tree_->selectedItems().count() > 0) {
+            clip.append(proto_tree_->currentItem()->text(0));
+            clip.append("\n");
 
+            recursiveCopyProtoTreeItems(proto_tree_->currentItem(), clip, 1);
+        }
         break;
     }
 
@@ -1874,6 +1908,9 @@ void MainWindow::on_actionEditFindPacket_triggered()
     previous_focus_ = wsApp->focusWidget();
     connect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
     showAccordionFrame(main_ui_->searchFrame, true);
+    if (main_ui_->searchFrame->isVisible()) {
+        main_ui_->searchFrame->setFocus();
+    }
 }
 
 void MainWindow::on_actionEditFindNext_triggered()
@@ -1888,17 +1925,23 @@ void MainWindow::on_actionEditFindPrevious_triggered()
 
 void MainWindow::on_actionEditMarkPacket_triggered()
 {
+    freeze();
     packet_list_->markFrame();
+    thaw();
 }
 
 void MainWindow::on_actionEditMarkAllDisplayed_triggered()
 {
+    freeze();
     packet_list_->markAllDisplayedFrames(true);
+    thaw();
 }
 
 void MainWindow::on_actionEditUnmarkAllDisplayed_triggered()
 {
+    freeze();
     packet_list_->markAllDisplayedFrames(false);
+    thaw();
 }
 
 void MainWindow::on_actionEditNextMark_triggered()
@@ -1915,17 +1958,23 @@ void MainWindow::on_actionEditPreviousMark_triggered()
 
 void MainWindow::on_actionEditIgnorePacket_triggered()
 {
+    freeze();
     packet_list_->ignoreFrame();
+    thaw();
 }
 
 void MainWindow::on_actionEditIgnoreAllDisplayed_triggered()
 {
+    freeze();
     packet_list_->ignoreAllDisplayedFrames(true);
+    thaw();
 }
 
 void MainWindow::on_actionEditUnignoreAllDisplayed_triggered()
 {
+    freeze();
     packet_list_->ignoreAllDisplayedFrames(false);
+    thaw();
 }
 
 void MainWindow::on_actionEditSetTimeReference_triggered()
@@ -1955,6 +2004,7 @@ void MainWindow::on_actionEditTimeShift_triggered()
     TimeShiftDialog ts_dialog(this, capture_file_.capFile());
     connect(this, SIGNAL(setCaptureFile(capture_file*)),
             &ts_dialog, SLOT(setCaptureFile(capture_file*)));
+    connect(&ts_dialog, SIGNAL(timeShifted()), packet_list_, SLOT(applyTimeShift()));
     ts_dialog.exec();
 }
 
@@ -2054,13 +2104,14 @@ void MainWindow::setTimestampFormat(QAction *action)
     if (recent.gui_time_format != tsf) {
         timestamp_set_type(tsf);
         recent.gui_time_format = tsf;
+
+        if (packet_list_) {
+            packet_list_->resetColumns();
+        }
         if (capture_file_.capFile()) {
             /* This call adjusts column width */
             cf_timestamp_auto_precision(capture_file_.capFile());
         }
-        if (packet_list_) {
-            packet_list_->columnsChanged();
-        }
     }
 }
 
@@ -2076,13 +2127,14 @@ void MainWindow::setTimestampPrecision(QAction *action)
         /* the actual precision will be set in packet_list_queue_draw() below */
         timestamp_set_precision(tsp);
         recent.gui_time_precision = tsp;
+
+        if (packet_list_) {
+            packet_list_->resetColumns();
+        }
         if (capture_file_.capFile()) {
             /* This call adjusts column width */
             cf_timestamp_auto_precision(capture_file_.capFile());
         }
-        if (packet_list_) {
-            packet_list_->columnsChanged();
-        }
     }
 }
 
@@ -2095,13 +2147,13 @@ void MainWindow::on_actionViewTimeDisplaySecondsWithHoursAndMinutes_triggered(bo
     }
     timestamp_set_seconds_type(recent.gui_seconds_format);
 
+    if (packet_list_) {
+        packet_list_->resetColumns();
+    }
     if (capture_file_.capFile()) {
         /* This call adjusts column width */
         cf_timestamp_auto_precision(capture_file_.capFile());
     }
-    if (packet_list_) {
-        packet_list_->columnsChanged();
-    }
 }
 
 void MainWindow::on_actionViewEditResolvedName_triggered()
@@ -2124,7 +2176,7 @@ void MainWindow::setNameResolution()
     gbl_resolv_flags.transport_name = main_ui_->actionViewNameResolutionTransport->isChecked() ? TRUE : FALSE;
 
     if (packet_list_) {
-        packet_list_->columnsChanged();
+        packet_list_->resetColumns();
     }
 }
 
@@ -2175,62 +2227,68 @@ void MainWindow::on_actionViewNormalSize_triggered()
 
 void MainWindow::on_actionViewColorizePacketList_triggered(bool checked) {
     recent.packet_list_colorize = checked;
-    color_filters_enable(checked);
+    packet_list_enable_color(checked);
     packet_list_->packetListModel()->resetColorized();
-    packet_list_->update();
 }
 
 void MainWindow::on_actionViewColoringRules_triggered()
 {
     ColoringRulesDialog coloring_rules_dialog(this);
-
+    connect(&coloring_rules_dialog, SIGNAL(accepted()),
+            packet_list_, SLOT(recolorPackets()));
     coloring_rules_dialog.exec();
 }
 
 // actionViewColorizeConversation1 - 10
 void MainWindow::colorizeConversation(bool create_rule)
 {
-    QAction *cc_action = qobject_cast<QAction *>(sender());
-    if (!cc_action) return;
+    QAction *colorize_action = qobject_cast<QAction *>(sender());
+    if (!colorize_action) return;
 
     if (capture_file_.capFile() && capture_file_.capFile()->current_frame) {
-        packet_info *pi = &capture_file_.capFile()->edt->pi;
-        guint8 cc_num = cc_action->data().toUInt();
+        packet_info *pi = capture_file_.packetInfo();
+        guint8 cc_num = colorize_action->data().toUInt();
         gchar *filter = NULL;
 
-        const color_conversation_filter_t *color_filter = find_color_conversation_filter("tcp");
+        const conversation_filter_t *color_filter = find_conversation_filter("tcp");
         if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
             filter = color_filter->build_filter_string(pi);
         if (filter == NULL) {
-            color_filter = find_color_conversation_filter("udp");
+            color_filter = find_conversation_filter("udp");
             if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
                 filter = color_filter->build_filter_string(pi);
         }
         if (filter == NULL) {
-            color_filter = find_color_conversation_filter("ip");
+            color_filter = find_conversation_filter("ip");
             if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
                 filter = color_filter->build_filter_string(pi);
         }
         if (filter == NULL) {
-            color_filter = find_color_conversation_filter("ipv6");
+            color_filter = find_conversation_filter("ipv6");
             if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
                 filter = color_filter->build_filter_string(pi);
         }
         if (filter == NULL) {
-            color_filter = find_color_conversation_filter("eth");
+            color_filter = find_conversation_filter("eth");
             if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
                 filter = color_filter->build_filter_string(pi);
         }
-        if( filter == NULL ) {
+        if (filter == NULL) {
             main_ui_->statusBar->pushTemporaryStatus(tr("Unable to build conversation filter."));
             return;
         }
 
         if (create_rule) {
             ColoringRulesDialog coloring_rules_dialog(this, filter);
+            connect(&coloring_rules_dialog, SIGNAL(accepted()),
+                    packet_list_, SLOT(recolorPackets()));
             coloring_rules_dialog.exec();
         } else {
-            color_filters_set_tmp(cc_num, filter, FALSE);
+            gchar *err_msg = NULL;
+            if (!color_filters_set_tmp(cc_num, filter, FALSE, &err_msg)) {
+                simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
+                g_free(err_msg);
+            }
             packet_list_->recolorPackets();
         }
     }
@@ -2239,22 +2297,36 @@ void MainWindow::colorizeConversation(bool create_rule)
 
 void MainWindow::colorizeWithFilter()
 {
-    QAction *colorize_action = qobject_cast<QAction *>(sender());
-    if (!colorize_action) return;
+    QByteArray filter;
+    int color_number = -1;
 
-    QString filter = colorize_action->data().toString();
-    if (filter.isEmpty()) return;
+    ConversationAction *conv_action = qobject_cast<ConversationAction *>(sender());
+    if (conv_action) {
+        filter = conv_action->filter();
+        color_number = conv_action->colorNumber();
+    } else {
+        ColorizeAction *colorize_action = qobject_cast<ColorizeAction *>(sender());
+        if (colorize_action) {
+            filter = colorize_action->filter();
+            color_number = colorize_action->colorNumber();
+        }
+    }
 
-    bool ok = false;
-    int color_number = colorize_action->property(color_number_property_).toInt(&ok);
+    if (filter.isEmpty()) return;
 
-    if (ok) {
+    if (color_number > 0) {
         // Assume "Color X"
-        color_filters_set_tmp(color_number, filter.toUtf8().constData(), FALSE);
+        gchar *err_msg = NULL;
+        if (!color_filters_set_tmp(color_number, filter.constData(), FALSE, &err_msg)) {
+            simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
+            g_free(err_msg);
+        }
         packet_list_->recolorPackets();
     } else {
         // New coloring rule
         ColoringRulesDialog coloring_rules_dialog(window(), filter);
+        connect(&coloring_rules_dialog, SIGNAL(accepted()),
+                packet_list_, SLOT(recolorPackets()));
         coloring_rules_dialog.exec();
     }
     main_ui_->actionViewColorizeResetColorization->setEnabled(tmp_color_filters_used());
@@ -2262,12 +2334,16 @@ void MainWindow::colorizeWithFilter()
 
 void MainWindow::on_actionViewColorizeResetColorization_triggered()
 {
-    color_filters_reset_tmp();
+    gchar *err_msg = NULL;
+    if (!color_filters_reset_tmp(&err_msg)) {
+        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
+        g_free(err_msg);
+    }
     packet_list_->recolorPackets();
     setMenusForSelectedPacket();
 }
 
-void MainWindow::on_actionViewColorizeNewConversationRule_triggered()
+void MainWindow::on_actionViewColorizeNewColoringRule_triggered()
 {
     colorizeConversation(true);
 }
@@ -2309,6 +2385,24 @@ void MainWindow::openPacketDialog(bool from_reference)
     }
 }
 
+void MainWindow::on_actionViewInternalsConversationHashTables_triggered()
+{
+    ConversationHashTablesDialog *conversation_hash_tables_dlg = new ConversationHashTablesDialog(this);
+    conversation_hash_tables_dlg->show();
+}
+
+void MainWindow::on_actionViewInternalsDissectorTables_triggered()
+{
+    DissectorTablesDialog *dissector_tables_dlg = new DissectorTablesDialog(this);
+    dissector_tables_dlg->show();
+}
+
+void MainWindow::on_actionViewInternalsSupportedProtocols_triggered()
+{
+    SupportedProtocolsDialog *supported_protocols_dlg = new SupportedProtocolsDialog(this);
+    supported_protocols_dlg->show();
+}
+
 void MainWindow::on_actionViewShowPacketInNewWindow_triggered()
 {
     openPacketDialog();
@@ -2322,9 +2416,36 @@ void MainWindow::on_actionContextShowLinkedPacketInNewWindow_triggered()
 
 void MainWindow::on_actionViewReload_triggered()
 {
-    cf_reload(CaptureFile::globalCapFile());
+    capture_file *cf = CaptureFile::globalCapFile();
+
+    if (cf->unsaved_changes) {
+        QString before_what(tr(" before reloading the file"));
+        if (!testCaptureFileClose(before_what, Reload))
+            return;
+    }
+
+    cf_reload(cf);
+}
+
+void MainWindow::on_actionViewReload_as_File_Format_or_Capture_triggered()
+{
+    capture_file *cf = CaptureFile::globalCapFile();
+
+    if (cf->unsaved_changes) {
+        QString before_what(tr(" before reloading the file"));
+        if (!testCaptureFileClose(before_what, Reload))
+            return;
+    }
+
+    if (cf->open_type == WTAP_TYPE_AUTO)
+        cf->open_type = open_info_name_to_type("MIME Files Format");
+    else /* TODO: This should be latest format chosen by user */
+        cf->open_type = WTAP_TYPE_AUTO;
+
+    cf_reload(cf);
 }
 
+
 // Expand / collapse slots in proto_tree
 
 // Go Menu
@@ -2383,8 +2504,7 @@ void MainWindow::on_actionAnalyzeCreateAColumn_triggered()
 {
     gint colnr = 0;
 
-    if ( capture_file_.capFile() != 0 && capture_file_.capFile()->finfo_selected != 0 )
-    {
+    if (capture_file_.capFile() != 0 && capture_file_.capFile()->finfo_selected != 0) {
         colnr = column_prefs_add_custom(COL_CUSTOM, capture_file_.capFile()->finfo_selected->hfinfo->name,
                     capture_file_.capFile()->finfo_selected->hfinfo->abbrev,0);
 
@@ -2397,14 +2517,20 @@ void MainWindow::on_actionAnalyzeCreateAColumn_triggered()
 
 void MainWindow::applyConversationFilter()
 {
-    QAction *cfa = qobject_cast<QAction*>(sender());
-    if (!cfa) return;
+    ConversationAction *conv_action = qobject_cast<ConversationAction*>(sender());
+    if (!conv_action) return;
+
+    packet_info *pinfo = capture_file_.packetInfo();
+    if (!pinfo) return;
+
+    QByteArray conv_filter = conv_action->filter();
+    if (conv_filter.isEmpty()) return;
 
-    QString new_filter = cfa->data().toString();
-    if (new_filter.isEmpty()) return;
+    if (conv_action->isFilterValid(pinfo)) {
 
-    df_combo_box_->lineEdit()->setText(new_filter);
-    df_combo_box_->applyDisplayFilter();
+        df_combo_box_->lineEdit()->setText(conv_filter);
+        df_combo_box_->applyDisplayFilter();
+    }
 }
 
 // XXX We could probably create the analyze and prepare actions
@@ -2498,37 +2624,14 @@ void MainWindow::on_actionAnalyzeDecodeAs_triggered()
     wsApp->flushAppSignals();
 }
 
-#ifdef HAVE_LUA
 void MainWindow::on_actionAnalyzeReloadLuaPlugins_triggered()
 {
-    if (wsApp->isReloadingLua())
-        return;
-
-    wsApp->setReloadingLua(true);
-
-    wslua_reload_plugins(NULL, NULL);
-    funnel_statistics_reload_menus();
-    reloadDynamicMenus();
-    closePacketDialogs();
-
-    // Preferences may have been deleted so close all widgets using prefs
-    proto_tree_->closeContextMenu();
-    main_ui_->preferenceEditorFrame->animatedHide();
-
-    char *gdp_path, *dp_path;
-    (void) wsApp->readConfigurationFiles(&gdp_path, &dp_path);
-
-    fieldsChanged();
-    redissectPackets();
-
-    wsApp->setReloadingLua(false);
-    SimpleDialog::displayQueuedMessages();
+    reloadLuaPlugins();
 }
-#endif
 
 void MainWindow::openFollowStreamDialog(follow_type_t type) {
     FollowStreamDialog *fsd = new FollowStreamDialog(*this, capture_file_, type);
-    connect(fsd, SIGNAL(updateFilter(QString&, bool)), this, SLOT(filterPackets(QString&, bool)));
+    connect(fsd, SIGNAL(updateFilter(QString, bool)), this, SLOT(filterPackets(QString, bool)));
     connect(fsd, SIGNAL(goToPacket(int)), packet_list_, SLOT(goToPacket(int)));
 
     fsd->show();
@@ -2550,11 +2653,16 @@ void MainWindow::on_actionAnalyzeFollowSSLStream_triggered()
     openFollowStreamDialog(FOLLOW_SSL);
 }
 
+void MainWindow::on_actionAnalyzeFollowHTTPStream_triggered()
+{
+    openFollowStreamDialog(FOLLOW_HTTP);
+}
+
 void MainWindow::openSCTPAllAssocsDialog()
 {
     SCTPAllAssocsDialog *sctp_dialog = new SCTPAllAssocsDialog(this, capture_file_.capFile());
-    connect(sctp_dialog, SIGNAL(filterPackets(QString&,bool)),
-            this, SLOT(filterPackets(QString&,bool)));
+    connect(sctp_dialog, SIGNAL(filterPackets(QString,bool)),
+            this, SLOT(filterPackets(QString,bool)));
     connect(this, SIGNAL(setCaptureFile(capture_file*)),
             sctp_dialog, SLOT(setCaptureFile(capture_file*)));
     sctp_dialog->fillTable();
@@ -2580,8 +2688,8 @@ void MainWindow::on_actionSCTPShowAllAssociations_triggered()
 void MainWindow::on_actionSCTPAnalyseThisAssociation_triggered()
 {
     SCTPAssocAnalyseDialog *sctp_analyse = new SCTPAssocAnalyseDialog(this, NULL, capture_file_.capFile());
-    connect(sctp_analyse, SIGNAL(filterPackets(QString&,bool)),
-            this, SLOT(filterPackets(QString&,bool)));
+    connect(sctp_analyse, SIGNAL(filterPackets(QString,bool)),
+            this, SLOT(filterPackets(QString,bool)));
 
     if (sctp_analyse->isMinimized() == true)
     {
@@ -2661,7 +2769,9 @@ void MainWindow::openTcpStreamDialog(int graph_type)
             packet_list_, SLOT(goToPacket(int)));
     connect(this, SIGNAL(setCaptureFile(capture_file*)),
             stream_dialog, SLOT(setCaptureFile(capture_file*)));
-    stream_dialog->show();
+    if (stream_dialog->result() == QDialog::Accepted) {
+        stream_dialog->show();
+    }
 }
 
 void MainWindow::on_actionStatisticsTcpStreamStevens_triggered()
@@ -2941,8 +3051,8 @@ void MainWindow::openVoipCallsDialog(bool all_flows)
     VoipCallsDialog *voip_calls_dialog = new VoipCallsDialog(*this, capture_file_, all_flows);
     connect(voip_calls_dialog, SIGNAL(goToPacket(int)),
             packet_list_, SLOT(goToPacket(int)));
-    connect(voip_calls_dialog, SIGNAL(updateFilter(QString&, bool)),
-            this, SLOT(filterPackets(QString&, bool)));
+    connect(voip_calls_dialog, SIGNAL(updateFilter(QString, bool)),
+            this, SLOT(filterPackets(QString, bool)));
     voip_calls_dialog->show();
 }
 
@@ -2970,6 +3080,58 @@ void MainWindow::on_actionTelephonyISUPMessages_triggered()
     openStatisticsTreeDialog("isup_msg");
 }
 
+// -z mac-lte,stat
+void MainWindow::statCommandLteMacStatistics(const char *arg, void *)
+{
+    LteMacStatisticsDialog *lte_mac_stats_dlg = new LteMacStatisticsDialog(*this, capture_file_, arg);
+    connect(lte_mac_stats_dlg, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
+            this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
+    lte_mac_stats_dlg->show();
+}
+
+void MainWindow::on_actionTelephonyLteMacStatistics_triggered()
+{
+    statCommandLteMacStatistics(NULL, NULL);
+}
+
+void MainWindow::statCommandLteRlcStatistics(const char *arg, void *)
+{
+    LteRlcStatisticsDialog *lte_rlc_stats_dlg = new LteRlcStatisticsDialog(*this, capture_file_, arg);
+    connect(lte_rlc_stats_dlg, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
+            this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
+    // N.B. It is necessary for the RLC Statistics window to launch the RLC graph in this way, to ensure
+    // that the goToPacket() signal/slot connection gets set up...
+    connect(lte_rlc_stats_dlg, SIGNAL(launchRLCGraph(bool, guint16, guint8, guint16, guint16, guint8)),
+            this, SLOT(launchRLCGraph(bool, guint16, guint8, guint16, guint16, guint8)));
+
+    lte_rlc_stats_dlg->show();
+}
+
+void MainWindow::on_actionTelephonyLteRlcStatistics_triggered()
+{
+    statCommandLteRlcStatistics(NULL, NULL);
+}
+
+void MainWindow::launchRLCGraph(bool channelKnown,
+                                guint16 ueid, guint8 rlcMode,
+                                guint16 channelType, guint16 channelId, guint8 direction)
+{
+    LteRlcGraphDialog *lrg_dialog = new LteRlcGraphDialog(*this, capture_file_, channelKnown);
+    connect(lrg_dialog, SIGNAL(goToPacket(int)), packet_list_, SLOT(goToPacket(int)));
+    // This is a bit messy, but wanted to hide these parameters from users of
+    // on_actionTelephonyLteRlcGraph_triggered().
+    if (channelKnown) {
+        lrg_dialog->setChannelInfo(ueid, rlcMode, channelType, channelId, direction);
+    }
+    lrg_dialog->show();
+}
+
+void MainWindow::on_actionTelephonyLteRlcGraph_triggered()
+{
+    // We don't yet know the channel.
+    launchRLCGraph(false, 0, 0, 0, 0, 0);
+}
+
 void MainWindow::on_actionTelephonyMtp3Summary_triggered()
 {
     Mtp3SummaryDialog *mtp3s_dialog = new Mtp3SummaryDialog(*this, capture_file_);
@@ -2983,8 +3145,8 @@ void MainWindow::on_actionTelephonyRTPStreams_triggered()
             packet_list_, SLOT(redrawVisiblePackets()));
     connect(rtp_stream_dialog, SIGNAL(goToPacket(int)),
             packet_list_, SLOT(goToPacket(int)));
-    connect(rtp_stream_dialog, SIGNAL(updateFilter(QString&, bool)),
-            this, SLOT(filterPackets(QString&, bool)));
+    connect(rtp_stream_dialog, SIGNAL(updateFilter(QString, bool)),
+            this, SLOT(filterPackets(QString, bool)));
     rtp_stream_dialog->show();
 }
 
@@ -3018,33 +3180,33 @@ void MainWindow::on_actionTelephonySipFlows_triggered()
 
 // Bluetooth Menu
 
-void MainWindow::on_actionATT_Server_Attributes_triggered()
+void MainWindow::on_actionBluetoothATT_Server_Attributes_triggered()
 {
     BluetoothAttServerAttributesDialog *bluetooth_att_sever_attributes_dialog = new BluetoothAttServerAttributesDialog(*this, capture_file_);
     connect(bluetooth_att_sever_attributes_dialog, SIGNAL(goToPacket(int)),
             packet_list_, SLOT(goToPacket(int)));
-    connect(bluetooth_att_sever_attributes_dialog, SIGNAL(updateFilter(QString&, bool)),
-            this, SLOT(filterPackets(QString&, bool)));
+    connect(bluetooth_att_sever_attributes_dialog, SIGNAL(updateFilter(QString, bool)),
+            this, SLOT(filterPackets(QString, bool)));
     bluetooth_att_sever_attributes_dialog->show();
 }
 
-void MainWindow::on_actionDevices_triggered()
+void MainWindow::on_actionBluetoothDevices_triggered()
 {
     BluetoothDevicesDialog *bluetooth_devices_dialog = new BluetoothDevicesDialog(*this, capture_file_);
     connect(bluetooth_devices_dialog, SIGNAL(goToPacket(int)),
             packet_list_, SLOT(goToPacket(int)));
-    connect(bluetooth_devices_dialog, SIGNAL(updateFilter(QString&, bool)),
-            this, SLOT(filterPackets(QString&, bool)));
+    connect(bluetooth_devices_dialog, SIGNAL(updateFilter(QString, bool)),
+            this, SLOT(filterPackets(QString, bool)));
     bluetooth_devices_dialog->show();
 }
 
-void MainWindow::on_actionHCI_Summary_triggered()
+void MainWindow::on_actionBluetoothHCI_Summary_triggered()
 {
     BluetoothHciSummaryDialog *bluetooth_hci_summary_dialog = new BluetoothHciSummaryDialog(*this, capture_file_);
     connect(bluetooth_hci_summary_dialog, SIGNAL(goToPacket(int)),
             packet_list_, SLOT(goToPacket(int)));
-    connect(bluetooth_hci_summary_dialog, SIGNAL(updateFilter(QString&, bool)),
-            this, SLOT(filterPackets(QString&, bool)));
+    connect(bluetooth_hci_summary_dialog, SIGNAL(updateFilter(QString, bool)),
+            this, SLOT(filterPackets(QString, bool)));
     bluetooth_hci_summary_dialog->show();
 }
 
@@ -3175,9 +3337,67 @@ void MainWindow::on_actionGoGoToLinkedPacket_triggered()
     packet_list_->goToPacket(packet_num);
 }
 
+// gtk/main_menubar.c:goto_conversation_frame
+void MainWindow::goToConversationFrame(bool go_next) {
+    gchar     *filter       = NULL;
+    dfilter_t *dfcode       = NULL;
+    gboolean   found_packet = FALSE;
+    packet_info *pi = &(capture_file_.capFile()->edt->pi);
+    conversation_filter_t* conv_filter;
+
+    /* Try to build a conversation
+     * filter in the order TCP, UDP, IP, Ethernet and apply the
+     * coloring */
+    conv_filter = find_conversation_filter("tcp");
+    if ((conv_filter != NULL) && (conv_filter->is_filter_valid(pi)))
+        filter = conv_filter->build_filter_string(pi);
+    conv_filter = find_conversation_filter("udp");
+    if ((conv_filter != NULL) && (conv_filter->is_filter_valid(pi)))
+        filter = conv_filter->build_filter_string(pi);
+    conv_filter = find_conversation_filter("ip");
+    if ((conv_filter != NULL) && (conv_filter->is_filter_valid(pi)))
+        filter = conv_filter->build_filter_string(pi);
+    conv_filter = find_conversation_filter("ipv6");
+    if ((conv_filter != NULL) && (conv_filter->is_filter_valid(pi)))
+        filter = conv_filter->build_filter_string(pi);
+
+    if (filter == NULL) {
+        main_ui_->statusBar->pushTemporaryStatus(tr("Unable to build conversation filter."));
+        g_free(filter);
+        return;
+    }
+
+    if (!dfilter_compile(filter, &dfcode, NULL)) {
+        /* The attempt failed; report an error. */
+        main_ui_->statusBar->pushTemporaryStatus(tr("Error compiling filter for this conversation."));
+        g_free(filter);
+        return;
+    }
+
+    found_packet = cf_find_packet_dfilter(capture_file_.capFile(), dfcode, go_next ? SD_FORWARD : SD_BACKWARD);
+
+    if (!found_packet) {
+        /* We didn't find a packet */
+        main_ui_->statusBar->pushTemporaryStatus(tr("No previous/next packet in conversation."));
+    }
+
+    dfilter_free(dfcode);
+    g_free(filter);
+}
+
+void MainWindow::on_actionGoNextConversationPacket_triggered()
+{
+    goToConversationFrame(true);
+}
+
+void MainWindow::on_actionGoPreviousConversationPacket_triggered()
+{
+    goToConversationFrame(false);
+}
+
 void MainWindow::on_actionGoAutoScroll_toggled(bool checked)
 {
-    packet_list_->setAutoScroll(checked);
+    packet_list_->setVerticalAutoScroll(checked);
 }
 
 void MainWindow::resetPreviousFocus() {
@@ -3243,7 +3463,7 @@ void MainWindow::on_actionCaptureStart_triggered()
 
     /* XXX - will closing this remove a temporary file? */
     QString before_what(tr(" before starting a new capture"));
-    if (testCaptureFileClose(FALSE, before_what)) {
+    if (testCaptureFileClose(before_what)) {
         startCapture();
     } else {
         // simply clicking the button sets it to 'checked' even though we've
@@ -3260,8 +3480,11 @@ void MainWindow::on_actionCaptureStop_triggered()
 
 void MainWindow::on_actionCaptureRestart_triggered()
 {
+    QString before_what(tr(" before restarting the capture"));
+    if (!testCaptureFileClose(before_what, Restart))
+        return;
+
 /* TODO: GTK use only this: capture_restart(&cap_session_); */
-    captureStop();
     startCapture();
 }
 
@@ -3301,26 +3524,49 @@ void MainWindow::on_actionStatisticsProtocolHierarchy_triggered()
 #ifdef HAVE_LIBPCAP
 void MainWindow::on_actionCaptureOptions_triggered()
 {
-    connect(&capture_interfaces_dialog_, SIGNAL(setFilterValid(bool)), this, SLOT(startInterfaceCapture(bool)));
-    capture_interfaces_dialog_.SetTab(0);
-    capture_interfaces_dialog_.updateInterfaces();
-
-    if (capture_interfaces_dialog_.isMinimized() == true)
-    {
-        capture_interfaces_dialog_.showNormal();
-    }
-    else
-    {
-        capture_interfaces_dialog_.show();
+    if (!capture_interfaces_dialog_) {
+        capture_interfaces_dialog_ = new CaptureInterfacesDialog(this);
+
+        connect(capture_interfaces_dialog_, SIGNAL(startCapture()), this, SLOT(startCapture()));
+        connect(capture_interfaces_dialog_, SIGNAL(stopCapture()), this, SLOT(stopCapture()));
+
+        connect(capture_interfaces_dialog_, SIGNAL(getPoints(int,PointList*)),
+                this->main_welcome_->getInterfaceTree(), SLOT(getPoints(int,PointList*)));
+        // Changes in interface selections or capture filters should be propagated
+        // to the main welcome screen where they will be applied to the global
+        // capture options.
+        connect(capture_interfaces_dialog_, SIGNAL(interfaceListChanged()),
+                this->main_welcome_->getInterfaceTree(), SLOT(interfaceListChanged()));
+        connect(capture_interfaces_dialog_, SIGNAL(interfacesChanged()),
+                this->main_welcome_, SLOT(interfaceSelected()));
+        connect(capture_interfaces_dialog_, SIGNAL(interfacesChanged()),
+                this->main_welcome_->getInterfaceTree(), SLOT(updateSelectedInterfaces()));
+        connect(capture_interfaces_dialog_, SIGNAL(interfacesChanged()),
+                this->main_welcome_->getInterfaceTree(), SLOT(updateToolTips()));
+        connect(capture_interfaces_dialog_, SIGNAL(captureFilterTextEdited(QString)),
+                this->main_welcome_, SLOT(setCaptureFilterText(QString)));
+
+        connect(capture_interfaces_dialog_, SIGNAL(setFilterValid(bool, const QString)),
+                this, SLOT(startInterfaceCapture(bool, const QString)));
+    }
+    capture_interfaces_dialog_->SetTab(0);
+    capture_interfaces_dialog_->updateInterfaces();
+
+    if (capture_interfaces_dialog_->isMinimized()) {
+        capture_interfaces_dialog_->showNormal();
+    } else {
+        capture_interfaces_dialog_->show();
     }
 
-    capture_interfaces_dialog_.raise();
-    capture_interfaces_dialog_.activateWindow();
+    capture_interfaces_dialog_->raise();
+    capture_interfaces_dialog_->activateWindow();
 }
 
 void MainWindow::on_actionCaptureRefreshInterfaces_triggered()
 {
+    main_ui_->actionCaptureRefreshInterfaces->setEnabled(false);
     wsApp->refreshLocalInterfaces();
+    main_ui_->actionCaptureRefreshInterfaces->setEnabled(true);
 }
 #endif
 
@@ -3330,21 +3576,16 @@ void MainWindow::externalMenuItem_triggered()
     QVariant v;
     ext_menubar_t * entry = NULL;
 
-    if ( QObject::sender() != NULL)
-    {
+    if (QObject::sender()) {
         triggerAction = (QAction *)QObject::sender();
         v = triggerAction->data();
 
-        if ( v.canConvert<void *>())
-        {
+        if (v.canConvert<void *>()) {
             entry = (ext_menubar_t *)v.value<void *>();
 
-            if ( entry->type == EXT_MENUBAR_ITEM )
-            {
+            if (entry->type == EXT_MENUBAR_ITEM) {
                 entry->callback(EXT_MENUBAR_QT_GUI, (gpointer) ((void *)main_ui_), entry->user_data);
-            }
-            else
-            {
+            } else {
                 QDesktopServices::openUrl(QUrl(QString((gchar *)entry->user_data)));
             }
         }
@@ -3353,8 +3594,7 @@ void MainWindow::externalMenuItem_triggered()
 
 void MainWindow::gotoFrame(int packet_num)
 {
-    if ( packet_num > 0 )
-    {
+    if (packet_num > 0) {
         packet_list_->goToPacket(packet_num);
     }
 }
@@ -3362,8 +3602,7 @@ void MainWindow::gotoFrame(int packet_num)
 #ifdef HAVE_EXTCAP
 void MainWindow::extcap_options_finished(int result)
 {
-    if ( result == QDialog::Accepted )
-    {
+    if (result == QDialog::Accepted) {
         startCapture();
     }
     this->main_welcome_->getInterfaceTree()->interfaceListChanged();
@@ -3373,8 +3612,7 @@ void MainWindow::showExtcapOptionsDialog(QString &device_name)
 {
     ExtcapOptionsDialog * extcap_options_dialog = ExtcapOptionsDialog::createForDevice(device_name, this);
     /* The dialog returns null, if the given device name is not a valid extcap device */
-    if ( extcap_options_dialog != NULL )
-    {
+    if (extcap_options_dialog) {
         connect(extcap_options_dialog, SIGNAL(finished(int)),
                 this, SLOT(extcap_options_finished(int)));
         extcap_options_dialog->show();
@@ -3475,6 +3713,10 @@ void MainWindow::on_actionContextFilterFieldReference_triggered()
     QDesktopServices::openUrl(dfref_url);
 }
 
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
 /*
  * Editor modelines
  *