forked from osmocom/wireshark
239 lines
7.5 KiB
C++
239 lines
7.5 KiB
C++
/* main_window_layout.cpp
|
|
*
|
|
* Wireshark - Network traffic analyzer
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
* Copyright 1998 Gerald Combs
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include <ui/qt/main_window.h>
|
|
#include <ui/qt/widgets/additional_toolbar.h>
|
|
|
|
#include "ui/recent.h"
|
|
|
|
#include "epan/prefs.h"
|
|
|
|
#include <QSplitter>
|
|
#include <QVector>
|
|
#include <QList>
|
|
#include <QWidget>
|
|
#include <QRect>
|
|
#include <QAction>
|
|
#include <QToolBar>
|
|
|
|
#include <ui/qt/packet_list.h>
|
|
#include <ui/qt/proto_tree.h>
|
|
#include <ui/qt/byte_view_tab.h>
|
|
|
|
/*
|
|
* The generated Ui_MainWindow::setupUi() can grow larger than our configured limit,
|
|
* so turn off -Wframe-larger-than= for ui_main_window.h.
|
|
*/
|
|
DIAG_OFF(frame-larger-than=)
|
|
#include <ui_main_window.h>
|
|
DIAG_ON(frame-larger-than=)
|
|
|
|
void MainWindow::showWelcome()
|
|
{
|
|
main_ui_->mainStack->setCurrentWidget(welcome_page_);
|
|
}
|
|
|
|
void MainWindow::showCapture()
|
|
{
|
|
main_ui_->mainStack->setCurrentWidget( &master_split_);
|
|
}
|
|
|
|
QWidget* MainWindow::getLayoutWidget(layout_pane_content_e type) {
|
|
switch (type) {
|
|
case layout_pane_content_none:
|
|
return &empty_pane_;
|
|
case layout_pane_content_plist:
|
|
return packet_list_;
|
|
case layout_pane_content_pdetails:
|
|
return proto_tree_;
|
|
case layout_pane_content_pbytes:
|
|
return byte_view_tab_;
|
|
default:
|
|
g_assert_not_reached();
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
// A new layout should be applied when it differs from the old layout AND
|
|
// at the following times:
|
|
// - At startup
|
|
// - When the preferences change
|
|
// - When the profile changes
|
|
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
|
|
<< recent.packet_list_show
|
|
<< recent.tree_view_show
|
|
<< recent.byte_view_show;
|
|
|
|
if (cur_layout_ == new_layout) return;
|
|
|
|
QSplitter *parents[3];
|
|
|
|
// Reparent all widgets and add them back in the proper order below.
|
|
// This hides each widget as well.
|
|
packet_list_->freeze(); // Clears tree and byte view tabs.
|
|
packet_list_->setParent(main_ui_->mainStack);
|
|
proto_tree_->setParent(main_ui_->mainStack);
|
|
byte_view_tab_->setParent(main_ui_->mainStack);
|
|
empty_pane_.setParent(main_ui_->mainStack);
|
|
extra_split_.setParent(main_ui_->mainStack);
|
|
|
|
// XXX We should try to preserve geometries if we can, e.g. by
|
|
// checking to see if the layout type is the same.
|
|
switch(prefs.gui_layout_type) {
|
|
case(layout_type_2):
|
|
case(layout_type_1):
|
|
extra_split_.setOrientation(Qt::Horizontal);
|
|
/* Fall Through */
|
|
case(layout_type_5):
|
|
master_split_.setOrientation(Qt::Vertical);
|
|
break;
|
|
|
|
case(layout_type_4):
|
|
case(layout_type_3):
|
|
extra_split_.setOrientation(Qt::Vertical);
|
|
/* Fall Through */
|
|
case(layout_type_6):
|
|
master_split_.setOrientation(Qt::Horizontal);
|
|
break;
|
|
|
|
default:
|
|
g_assert_not_reached();
|
|
}
|
|
|
|
switch(prefs.gui_layout_type) {
|
|
case(layout_type_5):
|
|
case(layout_type_6):
|
|
parents[0] = &master_split_;
|
|
parents[1] = &master_split_;
|
|
parents[2] = &master_split_;
|
|
break;
|
|
case(layout_type_2):
|
|
case(layout_type_4):
|
|
parents[0] = &master_split_;
|
|
parents[1] = &extra_split_;
|
|
parents[2] = &extra_split_;
|
|
break;
|
|
case(layout_type_1):
|
|
case(layout_type_3):
|
|
parents[0] = &extra_split_;
|
|
parents[1] = &extra_split_;
|
|
parents[2] = &master_split_;
|
|
break;
|
|
default:
|
|
g_assert_not_reached();
|
|
}
|
|
|
|
if (parents[0] == &extra_split_) {
|
|
master_split_.addWidget(&extra_split_);
|
|
}
|
|
|
|
parents[0]->addWidget(getLayoutWidget(prefs.gui_layout_content_1));
|
|
|
|
if (parents[2] == &extra_split_) {
|
|
master_split_.addWidget(&extra_split_);
|
|
}
|
|
|
|
parents[1]->addWidget(getLayoutWidget(prefs.gui_layout_content_2));
|
|
parents[2]->addWidget(getLayoutWidget(prefs.gui_layout_content_3));
|
|
|
|
const QList<QWidget *> ms_children = master_split_.findChildren<QWidget *>();
|
|
|
|
extra_split_.setVisible(ms_children.contains(&extra_split_));
|
|
packet_list_->setVisible(ms_children.contains(packet_list_) && recent.packet_list_show);
|
|
proto_tree_->setVisible(ms_children.contains(proto_tree_) && recent.tree_view_show);
|
|
byte_view_tab_->setVisible(ms_children.contains(byte_view_tab_) && recent.byte_view_show);
|
|
|
|
packet_list_->thaw(true);
|
|
cur_layout_ = new_layout;
|
|
}
|
|
|
|
// The recent layout geometry should be applied after the layout has been
|
|
// applied AND at the following times:
|
|
// - At startup
|
|
// - When the profile changes
|
|
void MainWindow::applyRecentPaneGeometry()
|
|
{
|
|
// XXX This shrinks slightly each time the application is run. For some
|
|
// reason the master_split_ geometry is two pixels shorter when
|
|
// saveWindowGeometry is invoked.
|
|
|
|
// This is also an awful lot of trouble to go through to reuse the GTK+
|
|
// pane settings. We might want to add gui.geometry_main_master_sizes
|
|
// and gui.geometry_main_extra_sizes and save QSplitter::saveState in
|
|
// each.
|
|
|
|
// Force a geometry recalculation
|
|
QWidget *cur_w = main_ui_->mainStack->currentWidget();
|
|
showCapture();
|
|
QRect geom = main_ui_->mainStack->geometry();
|
|
QList<int> master_sizes = master_split_.sizes();
|
|
QList<int> extra_sizes = extra_split_.sizes();
|
|
main_ui_->mainStack->setCurrentWidget(cur_w);
|
|
|
|
int master_last_size = master_split_.orientation() == Qt::Vertical ? geom.height() : geom.width();
|
|
master_last_size -= master_split_.handleWidth() * (master_sizes.length() - 1);
|
|
|
|
int extra_last_size = extra_split_.orientation() == Qt::Vertical ? geom.height() : geom.width();
|
|
extra_last_size -= extra_split_.handleWidth();
|
|
|
|
if (recent.gui_geometry_main_upper_pane > 0) {
|
|
master_sizes[0] = recent.gui_geometry_main_upper_pane;
|
|
master_last_size -= recent.gui_geometry_main_upper_pane;
|
|
} else {
|
|
master_sizes[0] = master_last_size / master_sizes.length();
|
|
master_last_size -= master_last_size / master_sizes.length();
|
|
}
|
|
|
|
if (recent.gui_geometry_main_lower_pane > 0) {
|
|
if (master_sizes.length() > 2) {
|
|
master_sizes[1] = recent.gui_geometry_main_lower_pane;
|
|
master_last_size -= recent.gui_geometry_main_lower_pane;
|
|
} else if (extra_sizes.length() > 0) {
|
|
extra_sizes[0] = recent.gui_geometry_main_lower_pane;
|
|
extra_last_size -= recent.gui_geometry_main_lower_pane;
|
|
extra_sizes.last() = extra_last_size;
|
|
}
|
|
} else {
|
|
if (master_sizes.length() > 2) {
|
|
master_sizes[1] = master_last_size / 2;
|
|
master_last_size -= master_last_size / 2;
|
|
} else {
|
|
extra_sizes[0] = extra_last_size / 2;
|
|
extra_last_size -= extra_last_size / 2;
|
|
extra_sizes.last() = extra_last_size;
|
|
}
|
|
}
|
|
|
|
master_sizes.last() = master_last_size;
|
|
|
|
master_split_.setSizes(master_sizes);
|
|
extra_split_.setSizes(extra_sizes);
|
|
}
|
|
|
|
/*
|
|
* Editor modelines
|
|
*
|
|
* Local Variables:
|
|
* c-basic-offset: 4
|
|
* tab-width: 8
|
|
* indent-tabs-mode: nil
|
|
* End:
|
|
*
|
|
* ex: set shiftwidth=4 tabstop=8 expandtab:
|
|
* :indentSize=4:tabSize=8:noTabs=true:
|
|
*/
|