1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
// ************************************************************************** //
//
// BornAgain: simulate and fit scattering at grazing incidence
//
//! @file GUI/coregui/Views/CommonWidgets/DocksController.cpp
//! @brief Implements class DocksController
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
// ************************************************************************** //
#include "GUI/coregui/Views/CommonWidgets/DocksController.h"
#include "Base/Utils/Assert.h"
#include "GUI/coregui/utils/GUIHelpers.h"
#include <QAbstractItemView>
#include <QAction>
#include <QDockWidget>
#include <QTimer>
#include <fancymainwindow.h>
DocksController::DocksController(Manhattan::FancyMainWindow* mainWindow)
: QObject(mainWindow), m_mainWindow(mainWindow)
{
m_mainWindow->setDocumentMode(true);
m_mainWindow->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::South);
m_mainWindow->setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
m_mainWindow->setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
}
void DocksController::addWidget(int id, QWidget* widget, Qt::DockWidgetArea area)
{
if (m_docks.find(id) != m_docks.end())
throw GUIHelpers::Error("DocksController::addWidget() -> Error. "
"Attempt to add widget id twice");
auto dock = m_mainWindow->addDockForWidget(widget);
m_docks[id] = DockWidgetInfo(dock, widget, area);
QList<QAbstractItemView*> frames = widget->findChildren<QAbstractItemView*>();
for (int i = 0; i < frames.count(); ++i)
frames[i]->setFrameStyle(QFrame::NoFrame);
}
void DocksController::onResetLayout()
{
m_mainWindow->setTrackingEnabled(false);
QList<QDockWidget*> dockWidgetList = m_mainWindow->dockWidgets();
for (QDockWidget* dockWidget : dockWidgetList) {
dockWidget->setFloating(false);
m_mainWindow->removeDockWidget(dockWidget);
}
for (auto& it : m_docks)
m_mainWindow->addDockWidget(it.second.area(), it.second.dock());
// Fixes issue: https://bugreports.qt.io/browse/QTBUG-65592
#if QT_VERSION >= 0x050600
dockWidgetList = m_mainWindow->dockWidgets();
if (dockWidgetList.size() > 0)
m_mainWindow->resizeDocks({dockWidgetList.first()}, {10}, Qt::Horizontal);
#endif
for (QDockWidget* dockWidget : dockWidgetList)
dockWidget->show();
m_mainWindow->setTrackingEnabled(true);
}
QDockWidget* DocksController::findDock(int id)
{
return get_info(id).dock();
}
QDockWidget* DocksController::findDock(QWidget* widget)
{
for (auto& it : m_docks)
if (it.second.widget() == widget)
return it.second.dock();
throw GUIHelpers::Error("DocksController::findDock() -> Can't find dock for widget");
}
//! Show docks with id's from the list. Other docks will be hidden.
void DocksController::show_docks(const std::vector<int>& docks_to_show)
{
for (auto& it : m_docks) {
if (std::find(docks_to_show.begin(), docks_to_show.end(), it.first) != docks_to_show.end())
it.second.dock()->show();
else
it.second.dock()->hide();
}
}
//! A hack to request update of QDockWidget size if its child (e.g. InfoWidget) wants it.
//! The problem bypassed here is that there is no direct method to QMainWindow to recalculate
//! position of splitters surrounding given QDockWidget. So our child QWidget requests here
//! the change of Min/Max size of QDockWidget, this will trigger recalculation of QDockWidget
//! layout and will force QDockWidget to respect sizeHints provided by ChildWidget. Later (in one
//! single timer shot) we return min/max sizes of QDockWidget back to re-enable splitters
//! functionality.
void DocksController::setDockHeightForWidget(int height)
{
QWidget* widget = qobject_cast<QWidget*>(sender());
ASSERT(widget);
QDockWidget* dock = findDock(widget);
ASSERT(dock);
m_dock_info.m_dock = dock;
m_dock_info.m_min_size = dock->minimumSize();
m_dock_info.m_max_size = dock->maximumSize();
if (height > 0) {
if (dock->height() < height)
dock->setMinimumHeight(height);
else
dock->setMaximumHeight(height);
}
QTimer::singleShot(1, this, &DocksController::dockToMinMaxSizes);
}
void DocksController::dockToMinMaxSizes()
{
ASSERT(m_dock_info.m_dock);
m_dock_info.m_dock->setMinimumSize(m_dock_info.m_min_size);
m_dock_info.m_dock->setMaximumSize(m_dock_info.m_max_size);
m_dock_info.m_dock = nullptr;
}
void DocksController::onWidgetCloseRequest()
{
QWidget* widget = qobject_cast<QWidget*>(sender());
ASSERT(widget);
QDockWidget* dock = findDock(widget);
ASSERT(dock);
dock->toggleViewAction()->trigger();
}
Manhattan::FancyMainWindow* DocksController::mainWindow()
{
return m_mainWindow;
}
DockWidgetInfo DocksController::get_info(int id)
{
if (m_docks.find(id) == m_docks.end())
throw GUIHelpers::Error("DocksController::addWidget() -> Error. Non existing id.");
return m_docks[id];
}
|