Qt: Lazily create dialogs.
authorGerald Combs <gerald@wireshark.org>
Thu, 31 Mar 2016 00:24:44 +0000 (17:24 -0700)
committerGerald Combs <gerald@wireshark.org>
Sat, 2 Apr 2016 00:26:26 +0000 (00:26 +0000)
According to the Visual Studio 2013 profiler here, we spend about 4% of
our startup time creating the Capture Interfaces dialog. Hold off on
doing that until the user wants to see the dialog. Do the same for the
File Set dialog.

While we're here, make sure MainWindow has fewer children when setupUi
is called. setupUi calls connectSlotsByName, which iterates over all
child objects.

Change-Id: I253e6dc5b7e73a6cb7b7036637e336f449449c4a
Reviewed-on: https://code.wireshark.org/review/14732
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Gerald Combs <gerald@wireshark.org>
ui/qt/main_window.cpp
ui/qt/main_window.h
ui/qt/main_window_slots.cpp

index d7c23374a3228d0dad559a72b1ba99f11406e4a3..9ab411a1287e4fdf9baf98b4e305e46ef0510670 100644 (file)
 #include "ui/preference_utils.h"
 
 #include "byte_view_tab.h"
+#ifdef HAVE_LIBPCAP
+#include "capture_interfaces_dialog.h"
+#endif
 #include "conversation_colorize_action.h"
 #include "display_filter_edit.h"
 #include "export_dissection_dialog.h"
+#include "file_set_dialog.h"
 #include "funnel_statistics.h"
 #include "import_text_dialog.h"
 #include "packet_list.h"
@@ -263,18 +267,20 @@ MainWindow::MainWindow(QWidget *parent) :
     QMainWindow(parent),
     main_ui_(new Ui::MainWindow),
     cur_layout_(QVector<unsigned>()),
-    df_combo_box_(new DisplayFilterCombo()),
+    df_combo_box_(NULL),
     packet_list_(NULL),
     proto_tree_(NULL),
     previous_focus_(NULL),
+    file_set_dialog_(NULL),
     show_hide_actions_(NULL),
     time_display_actions_(NULL),
     time_precision_actions_(NULL),
-    funnel_statistics_(new FunnelStatistics(this, capture_file_)),
+    funnel_statistics_(NULL),
     freeze_focus_(NULL),
     capture_stopping_(false),
     capture_filter_valid_(false),
 #ifdef HAVE_LIBPCAP
+    capture_interfaces_dialog_(NULL),
     info_data_(),
 #endif
 #ifdef _WIN32
@@ -293,6 +299,10 @@ MainWindow::MainWindow(QWidget *parent) :
 #ifdef HAVE_LIBPCAP
     capture_session_init(&cap_session_, CaptureFile::globalCapFile());
 #endif
+
+    // setpUi calls QMetaObject::connectSlotsByName(this). connectSlotsByName
+    // iterates over *all* of our children, looking for matching "on_" slots.
+    // The fewer children we have at this point the better.
     main_ui_->setupUi(this);
     setWindowIcon(wsApp->normalIcon());
     setTitlebarForCaptureFile();
@@ -327,11 +337,7 @@ MainWindow::MainWindow(QWidget *parent) :
     connect(wsApp, SIGNAL(updateRecentItemStatus(const QString &, qint64, bool)), this, SLOT(updateRecentFiles()));
     updateRecentFiles();
 
-#ifdef HAVE_LIBPCAP
-    connect(&capture_interfaces_dialog_, SIGNAL(startCapture()), this, SLOT(startCapture()));
-    connect(&capture_interfaces_dialog_, SIGNAL(stopCapture()), this, SLOT(stopCapture()));
-#endif
-
+    df_combo_box_ = new DisplayFilterCombo();
     const DisplayFilterEdit *df_edit = dynamic_cast<DisplayFilterEdit *>(df_combo_box_->lineEdit());
     connect(df_edit, SIGNAL(pushFilterSyntaxStatus(const QString&)),
             main_ui_->statusBar, SLOT(pushFilterStatus(const QString&)));
@@ -343,6 +349,7 @@ MainWindow::MainWindow(QWidget *parent) :
             this, SLOT(showPreferencesDialog(PreferencesDialog::PreferencesPane)));
     connect(wsApp, SIGNAL(preferencesChanged()), df_edit, SLOT(checkFilter()));
 
+    funnel_statistics_ = new FunnelStatistics(this, capture_file_);
     connect(df_edit, SIGNAL(textChanged(QString)), funnel_statistics_, SLOT(displayFilterTextChanged(QString)));
     connect(funnel_statistics_, SIGNAL(setDisplayFilter(QString)), df_edit, SLOT(setText(QString)));
     connect(funnel_statistics_, SIGNAL(applyDisplayFilter()), df_combo_box_, SLOT(applyDisplayFilter()));
@@ -352,10 +359,6 @@ MainWindow::MainWindow(QWidget *parent) :
 
     initMainToolbarIcons();
 
-    // In Qt4 multiple toolbars and "pretty" are mutually exculsive on OS X. If
-    // unifiedTitleAndToolBarOnMac is enabled everything ends up in the same row.
-    // https://bugreports.qt-project.org/browse/QTBUG-22433
-    // This property is obsolete in Qt5 so this issue may be fixed in that version.
     main_ui_->displayFilterToolBar->insertWidget(main_ui_->actionDisplayFilterExpression, df_combo_box_);
 
     wireless_frame_ = new WirelessFrame(this);
@@ -637,9 +640,6 @@ MainWindow::MainWindow(QWidget *parent) :
     connect(main_ui_->statusBar, SIGNAL(editCaptureComment()),
             this, SLOT(on_actionStatisticsCaptureFileProperties_triggered()));
 
-    connect(&file_set_dialog_, SIGNAL(fileSetOpenCaptureFile(QString)),
-            this, SLOT(openCaptureFile(QString)));
-
 #ifdef HAVE_LIBPCAP
     QTreeWidget *iface_tree = findChild<QTreeWidget *>("interfaceTree");
     if (iface_tree) {
@@ -654,22 +654,7 @@ MainWindow::MainWindow(QWidget *parent) :
                 this, SLOT(showExtcapOptionsDialog(QString&)));
 #endif
 
-    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)));
-#endif
+#endif // HAVE_LIBPCAP
 
     /* Create plugin_if hooks */
     plugin_if_register_gui_cb(PLUGIN_IF_FILTER_ACTION_APPLY, plugin_if_mainwindow_apply_filter);
@@ -808,7 +793,7 @@ void MainWindow::closeEvent(QCloseEvent *event) {
     }
 
 #ifdef HAVE_LIBPCAP
-    capture_interfaces_dialog_.close();
+    if (capture_interfaces_dialog_) capture_interfaces_dialog_->close();
 #endif
     // Make sure we kill any open dumpcap processes.
     delete main_welcome_;
index f21e7cd9a63fae1e36d538ed990d5c7339f09e37..235011fe5731cb8c5158a5db1b48934ce52365c2 100644 (file)
 #include "capture_file.h"
 #include "capture_file_dialog.h"
 #include "capture_file_properties_dialog.h"
-#include "capture_interfaces_dialog.h"
 #include "display_filter_combo.h"
-#include "file_set_dialog.h"
 #include "filter_action.h"
 #include "follow_stream_dialog.h"
 #include "preferences_dialog.h"
 
 class AccordionFrame;
 class ByteViewTab;
+class CaptureInterfacesDialog;
+class FileSetDialog;
 class FunnelStatistics;
 class MainWelcome;
 class PacketList;
@@ -143,7 +143,7 @@ private:
     PacketList *packet_list_;
     ProtoTree *proto_tree_;
     QWidget *previous_focus_;
-    FileSetDialog file_set_dialog_;
+    FileSetDialog *file_set_dialog_;
     ByteViewTab *byte_view_tab_;
     QWidget empty_pane_;
     QActionGroup *show_hide_actions_;
@@ -159,7 +159,7 @@ private:
     bool capture_filter_valid_;
 #ifdef HAVE_LIBPCAP
     capture_session cap_session_;
-    CaptureInterfacesDialog capture_interfaces_dialog_;
+    CaptureInterfacesDialog *capture_interfaces_dialog_;
     info_data_t info_data_;
 #endif
 
index 83c7d8149e71ac64c59edb3842d6e0f91b02fbf2..f543890d040763505c23f1090478524654519862 100644 (file)
@@ -83,6 +83,9 @@
 #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"
 #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"
@@ -656,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());
 }
@@ -736,7 +742,9 @@ 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);
 
@@ -1576,7 +1584,13 @@ void MainWindow::on_actionFileSaveAs_triggered()
 
 void MainWindow::on_actionFileSetListFiles_triggered()
 {
-    file_set_dialog_.show();
+    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()
@@ -3510,22 +3524,42 @@ void MainWindow::on_actionStatisticsProtocolHierarchy_triggered()
 #ifdef HAVE_LIBPCAP
 void MainWindow::on_actionCaptureOptions_triggered()
 {
-    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() == 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()