Qt: Lazily create dialogs.

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>
This commit is contained in:
Gerald Combs 2016-03-30 17:24:44 -07:00
parent e6a65afd3e
commit a2c042471b
3 changed files with 69 additions and 50 deletions

View File

@ -47,9 +47,13 @@
#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_;

View File

@ -53,15 +53,15 @@
#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

View 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"
@ -100,6 +103,7 @@
#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_) {
capture_interfaces_dialog_ = new CaptureInterfacesDialog(this);
if (capture_interfaces_dialog_.isMinimized() == true)
{
capture_interfaces_dialog_.showNormal();
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)));
}
else
{
capture_interfaces_dialog_.show();
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()