Gui: support toolbar drag and drop to status bar and menu bar (#13571)
* Gui: support toolbar drag and drop to status bar and menu bar Closes FreeCAD/FreeCAD#12979 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Gui: improve toolbar handling in status and menu bar * Gui: fix workbench tab bar orientation in status or menu bar * Gui: remove workbench toolbar position settings --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -36,7 +36,6 @@
|
||||
# include <QToolBar>
|
||||
# include <QToolButton>
|
||||
# include <QToolTip>
|
||||
# include <QMenuBar>
|
||||
#endif
|
||||
|
||||
#include <Base/Exception.h>
|
||||
@@ -55,7 +54,6 @@
|
||||
#include "Macro.h"
|
||||
#include "MainWindow.h"
|
||||
#include "PythonEditor.h"
|
||||
#include "UserSettings.h"
|
||||
#include "WhatsThis.h"
|
||||
#include "Widgets.h"
|
||||
#include "Workbench.h"
|
||||
@@ -631,7 +629,7 @@ WorkbenchGroup::WorkbenchGroup ( Command* pcCmd, QObject * parent )
|
||||
|
||||
void WorkbenchGroup::addTo(QWidget *widget)
|
||||
{
|
||||
if (widget->inherits("QToolBar") || widget->inherits("QMenuBar")) {
|
||||
if (widget->inherits("QToolBar")) {
|
||||
ParameterGrp::handle hGrp;
|
||||
hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches");
|
||||
QWidget* wbSel;
|
||||
@@ -642,13 +640,7 @@ void WorkbenchGroup::addTo(QWidget *widget)
|
||||
wbSel = new WorkbenchTabWidget(this, widget);
|
||||
}
|
||||
|
||||
if (widget->inherits("QToolBar")) {
|
||||
qobject_cast<QToolBar*>(widget)->addWidget(wbSel);
|
||||
}
|
||||
else {
|
||||
bool left = WorkbenchSwitcher::isLeftCorner(WorkbenchSwitcher::getValue());
|
||||
qobject_cast<QMenuBar*>(widget)->setCornerWidget(wbSel, left ? Qt::TopLeftCorner : Qt::TopRightCorner);
|
||||
}
|
||||
static_cast<QToolBar*>(widget)->addWidget(wbSel);
|
||||
}
|
||||
else if (widget->inherits("QMenu")) {
|
||||
auto menu = qobject_cast<QMenu*>(widget);
|
||||
|
||||
@@ -1217,7 +1217,6 @@ SET(FreeCADGui_CPP_SRCS
|
||||
ManualAlignment.cpp
|
||||
StartupProcess.cpp
|
||||
TransactionObject.cpp
|
||||
UserSettings.cpp
|
||||
)
|
||||
SET(FreeCADGui_SRCS
|
||||
Application.h
|
||||
@@ -1255,7 +1254,6 @@ SET(FreeCADGui_SRCS
|
||||
ManualAlignment.h
|
||||
StartupProcess.h
|
||||
TransactionObject.h
|
||||
UserSettings.h
|
||||
${FreeCADGui_SDK_MOC_HDRS}
|
||||
)
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
# include <QLabel>
|
||||
# include <QMdiSubWindow>
|
||||
# include <QMenu>
|
||||
# include <QMenuBar>
|
||||
# include <QMessageBox>
|
||||
# include <QMimeData>
|
||||
# include <QPainter>
|
||||
@@ -789,7 +790,19 @@ bool MainWindow::updateDAGView(bool show)
|
||||
|
||||
QMenu* MainWindow::createPopupMenu ()
|
||||
{
|
||||
QMenu* menu = QMainWindow::createPopupMenu();
|
||||
QMenu *menu = new QMenu(this);
|
||||
populateDockWindowMenu(menu);
|
||||
menu->addSeparator();
|
||||
populateToolBarMenu(menu);
|
||||
QMenu *undockMenu = new QMenu(menu);
|
||||
ToolBarManager::getInstance()->populateUndockMenu(undockMenu);
|
||||
if (undockMenu->actions().isEmpty()) {
|
||||
delete undockMenu;
|
||||
}
|
||||
else {
|
||||
menu->addMenu(undockMenu);
|
||||
}
|
||||
menu->addSeparator();
|
||||
Workbench* wb = WorkbenchManager::instance()->active();
|
||||
if (wb) {
|
||||
MenuItem item;
|
||||
@@ -1406,26 +1419,41 @@ void MainWindow::onToolBarMenuAboutToShow()
|
||||
{
|
||||
auto menu = static_cast<QMenu*>(sender());
|
||||
menu->clear();
|
||||
QList<QToolBar*> dock = this->findChildren<QToolBar*>();
|
||||
for (const auto & it : dock) {
|
||||
if (it->parentWidget() == this) {
|
||||
QAction* action = it->toggleViewAction();
|
||||
action->setToolTip(tr("Toggles this toolbar"));
|
||||
action->setStatusTip(tr("Toggles this toolbar"));
|
||||
action->setWhatsThis(tr("Toggles this toolbar"));
|
||||
menu->addAction(action);
|
||||
}
|
||||
}
|
||||
populateToolBarMenu(menu);
|
||||
|
||||
menu->addSeparator();
|
||||
|
||||
Application::Instance->commandManager().getCommandByName("Std_ToggleToolBarLock")->addTo(menu);
|
||||
}
|
||||
|
||||
void MainWindow::populateToolBarMenu(QMenu *menu)
|
||||
{
|
||||
QList<QToolBar*> toolbars = this->findChildren<QToolBar*>();
|
||||
for (const auto & toolbar : toolbars) {
|
||||
if (auto parent = toolbar->parentWidget()) {
|
||||
if (parent == this
|
||||
|| parent == statusBar()
|
||||
|| parent->parentWidget() == statusBar()
|
||||
|| parent->parentWidget() == menuBar()) {
|
||||
QAction* action = toolbar->toggleViewAction();
|
||||
action->setToolTip(tr("Toggles this toolbar"));
|
||||
action->setStatusTip(tr("Toggles this toolbar"));
|
||||
action->setWhatsThis(tr("Toggles this toolbar"));
|
||||
menu->addAction(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onDockWindowMenuAboutToShow()
|
||||
{
|
||||
auto menu = static_cast<QMenu*>(sender());
|
||||
menu->clear();
|
||||
populateDockWindowMenu(menu);
|
||||
}
|
||||
|
||||
void MainWindow::populateDockWindowMenu(QMenu *menu)
|
||||
{
|
||||
QList<QDockWidget*> dock = this->findChildren<QDockWidget*>();
|
||||
for (auto & it : dock) {
|
||||
QAction* action = it->toggleViewAction();
|
||||
|
||||
@@ -308,6 +308,9 @@ private:
|
||||
bool updateComboView(bool show);
|
||||
bool updateDAGView(bool show);
|
||||
|
||||
void populateToolBarMenu(QMenu *);
|
||||
void populateDockWindowMenu(QMenu *);
|
||||
|
||||
static void renderDevBuildWarning(QPainter &painter, const QPoint startPosition, const QSize maxSize);
|
||||
|
||||
private Q_SLOTS:
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include "Application.h"
|
||||
#include "Command.h"
|
||||
#include "MainWindow.h"
|
||||
#include "UserSettings.h"
|
||||
|
||||
|
||||
using namespace Gui;
|
||||
@@ -288,8 +287,6 @@ void MenuManager::setup(MenuItem* menuItems) const
|
||||
}
|
||||
}
|
||||
|
||||
setupMenuBarCornerWidgets();
|
||||
|
||||
// hide all menus which we don't need for the moment
|
||||
for (QList<QAction*>::Iterator it = actions.begin(); it != actions.end(); ++it) {
|
||||
(*it)->setVisible(false);
|
||||
@@ -366,41 +363,6 @@ void MenuManager::setup(MenuItem* item, QMenu* menu) const
|
||||
}
|
||||
}
|
||||
|
||||
void MenuManager::setupMenuBarCornerWidgets() const
|
||||
{
|
||||
/*Note: currently only workbench selector uses corner widget.*/
|
||||
QMenuBar* menuBar = getMainWindow()->menuBar();
|
||||
std::string pos = WorkbenchSwitcher::getValue();
|
||||
|
||||
bool showLeftWidget = false;
|
||||
bool showRightWidget = false;
|
||||
|
||||
//Right corner widget
|
||||
if (WorkbenchSwitcher::isRightCorner(pos)) {
|
||||
//add workbench selector to menubar right corner widget.
|
||||
if (!menuBar->cornerWidget(Qt::TopRightCorner)) {
|
||||
Application::Instance->commandManager().addTo("Std_Workbench", menuBar);
|
||||
}
|
||||
showRightWidget = true;
|
||||
}
|
||||
//Left corner widget
|
||||
else if (WorkbenchSwitcher::isLeftCorner(pos)) {
|
||||
//add workbench selector to menubar left corner widget.
|
||||
if (!menuBar->cornerWidget(Qt::TopLeftCorner)) {
|
||||
Application::Instance->commandManager().addTo("Std_Workbench", menuBar);
|
||||
}
|
||||
showLeftWidget = true;
|
||||
}
|
||||
|
||||
// Set visibility of corner widget
|
||||
if (QWidget* right = menuBar->cornerWidget(Qt::TopRightCorner)) {
|
||||
right->setVisible(showRightWidget);
|
||||
}
|
||||
if (QWidget* left = menuBar->cornerWidget(Qt::TopLeftCorner)) {
|
||||
left->setVisible(showLeftWidget);
|
||||
}
|
||||
}
|
||||
|
||||
void MenuManager::retranslate() const
|
||||
{
|
||||
QMenuBar* menuBar = getMainWindow()->menuBar();
|
||||
|
||||
@@ -79,7 +79,6 @@ class GuiExport MenuManager
|
||||
public:
|
||||
/** Sets up the menus of a given workbench. */
|
||||
void setup(MenuItem*) const;
|
||||
void setupMenuBarCornerWidgets() const;
|
||||
/// sets up a context menu out of item
|
||||
void setupContextMenu(MenuItem* item, QMenu &menu) const;
|
||||
void retranslate() const;
|
||||
|
||||
@@ -14,6 +14,75 @@
|
||||
<string>Available Workbenches</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="4" column="0">
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="WorkbenchSelectorItemLabel">
|
||||
<property name="text">
|
||||
<string>Workbench selector items style:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="WorkbenchSelectorItem">
|
||||
<property name="toolTip">
|
||||
<string>Customize how the items are displayed.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="ListWidgetDragBugFix" name="wbList"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="WorkbenchSelectorTypeLabel">
|
||||
<property name="text">
|
||||
<string>Workbench selector type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="WorkbenchSelectorType">
|
||||
<property name="toolTip">
|
||||
<string>Choose the workbench selector widget type (restart required).</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="noteLabel">
|
||||
<property name="sizePolicy">
|
||||
@@ -37,8 +106,24 @@ Currently, your system has the following workbenches:</p></body><
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="ListWidgetDragBugFix" name="wbList"/>
|
||||
<item row="5" column="0">
|
||||
<widget class="Gui::PrefCheckBox" name="CheckBox_WbByTab">
|
||||
<property name="toolTip">
|
||||
<string>If checked, application will remember which workbench is active for each tab of the viewport</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remember active workbench by tab</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>SaveWBbyTab</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>View</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<layout class="QHBoxLayout">
|
||||
@@ -74,142 +159,20 @@ after FreeCAD launches</string>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="WorkbenchSelectorTypeLabel">
|
||||
<property name="text">
|
||||
<string>Workbench selector type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="WorkbenchSelectorType">
|
||||
<property name="toolTip">
|
||||
<string>Choose the workbench selector widget type (restart required).</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="WorkbenchSelectorPositionLabel">
|
||||
<property name="text">
|
||||
<string>Workbench selector position:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="WorkbenchSelectorPosition">
|
||||
<property name="toolTip">
|
||||
<string>Customize where the workbench selector appears (restart required).
|
||||
|
||||
'Toolbar': In the toolbars, as a movable toolbar.
|
||||
'Left Corner': In the menu bar, on the left corner.
|
||||
'Right Corner': In the menu bar, on the right corner.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="WorkbenchSelectorItemLabel">
|
||||
<property name="text">
|
||||
<string>Workbench selector items style:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="WorkbenchSelectorItem">
|
||||
<property name="toolTip">
|
||||
<string>Customize how the items are displayed.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="Gui::PrefCheckBox" name="CheckBox_WbByTab">
|
||||
<property name="toolTip">
|
||||
<string>If checked, application will remember which workbench is active for each tab of the viewport</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remember active workbench by tab</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>SaveWBbyTab</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>View</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ListWidgetDragBugFix</class>
|
||||
<extends>QListWidget</extends>
|
||||
<header>ListWidgetDragBugFix.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>Gui::PrefCheckBox</class>
|
||||
<extends>QCheckBox</extends>
|
||||
<header>Gui/PrefWidgets.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ListWidgetDragBugFix</class>
|
||||
<extends>QListWidget</extends>
|
||||
<header>ListWidgetDragBugFix.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#endif
|
||||
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/UserSettings.h>
|
||||
#include <Gui/Workbench.h>
|
||||
#include <Gui/WorkbenchManager.h>
|
||||
|
||||
@@ -365,9 +364,6 @@ void DlgSettingsWorkbenchesImp::resetSettingsToDefaults()
|
||||
|
||||
hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow");
|
||||
hGrp->RemoveASCII("WSPosition");
|
||||
if (ui->WorkbenchSelectorPosition->currentIndex() != WorkbenchSwitcher::getIndex()) {
|
||||
requireRestart();
|
||||
}
|
||||
|
||||
//finally reset all the parameters associated to Gui::Pref* widgets
|
||||
PreferencePage::resetSettingsToDefaults();
|
||||
@@ -499,19 +495,11 @@ void DlgSettingsWorkbenchesImp::changeEvent(QEvent *e)
|
||||
|
||||
void DlgSettingsWorkbenchesImp::saveWorkbenchSelector()
|
||||
{
|
||||
//save workbench selector position
|
||||
int prevIndex = WorkbenchSwitcher::getIndex();
|
||||
auto index = ui->WorkbenchSelectorPosition->currentIndex();
|
||||
if (prevIndex != index) {
|
||||
WorkbenchSwitcher::setIndex(index);
|
||||
requireRestart();
|
||||
}
|
||||
|
||||
//save workbench selector type
|
||||
ParameterGrp::handle hGrp;
|
||||
hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches");
|
||||
prevIndex = hGrp->GetInt("WorkbenchSelectorType", 0);
|
||||
index = ui->WorkbenchSelectorType->currentIndex();
|
||||
int prevIndex = hGrp->GetInt("WorkbenchSelectorType", 0);
|
||||
int index = ui->WorkbenchSelectorType->currentIndex();
|
||||
if (prevIndex != index) {
|
||||
hGrp->SetInt("WorkbenchSelectorType", index);
|
||||
requireRestart();
|
||||
@@ -528,13 +516,6 @@ void DlgSettingsWorkbenchesImp::saveWorkbenchSelector()
|
||||
|
||||
void DlgSettingsWorkbenchesImp::loadWorkbenchSelector()
|
||||
{
|
||||
//workbench selector position combobox setup
|
||||
ui->WorkbenchSelectorPosition->clear();
|
||||
ui->WorkbenchSelectorPosition->addItem(tr("Toolbar"));
|
||||
ui->WorkbenchSelectorPosition->addItem(tr("Left corner"));
|
||||
ui->WorkbenchSelectorPosition->addItem(tr("Right corner"));
|
||||
ui->WorkbenchSelectorPosition->setCurrentIndex(WorkbenchSwitcher::getIndex());
|
||||
|
||||
//workbench selector type setup
|
||||
ParameterGrp::handle hGrp;
|
||||
hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches");
|
||||
|
||||
@@ -21,18 +21,29 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#include "Selection.h"
|
||||
#include <boost/signals2/connection.hpp>
|
||||
#ifndef _PreComp_
|
||||
# include <QAction>
|
||||
# include <QApplication>
|
||||
# include <QHBoxLayout>
|
||||
# include <QMenuBar>
|
||||
# include <QMouseEvent>
|
||||
# include <QPointer>
|
||||
# include <QStatusBar>
|
||||
# include <QToolBar>
|
||||
# include <QToolButton>
|
||||
# include <QPointer>
|
||||
#endif
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
#include <Base/Tools.h>
|
||||
|
||||
#include "ToolBarManager.h"
|
||||
#include "Application.h"
|
||||
#include "Command.h"
|
||||
#include "MainWindow.h"
|
||||
#include "OverlayWidgets.h"
|
||||
|
||||
|
||||
using namespace Gui;
|
||||
@@ -154,6 +165,135 @@ QList<ToolBarItem*> ToolBarItem::getItems() const
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
namespace Gui {
|
||||
|
||||
class ToolBarArea : public QWidget
|
||||
{
|
||||
using inherited = QWidget;
|
||||
public:
|
||||
ToolBarArea(QWidget *parent,
|
||||
ParameterGrp::handle hParam,
|
||||
boost::signals2::scoped_connection &conn,
|
||||
QTimer *timer = nullptr)
|
||||
: QWidget(parent)
|
||||
, _sizingTimer(timer)
|
||||
, _hParam(hParam)
|
||||
, _conn(conn)
|
||||
{
|
||||
_layout = new QHBoxLayout(this);
|
||||
_layout->setMargin(0);
|
||||
}
|
||||
|
||||
void addWidget(QWidget *w)
|
||||
{
|
||||
if (_layout->indexOf(w) < 0) {
|
||||
_layout->addWidget(w);
|
||||
adjustParent();
|
||||
QString name = w->objectName();
|
||||
if (!name.isEmpty()) {
|
||||
Base::ConnectionBlocker block(_conn);
|
||||
_hParam->SetInt(w->objectName().toUtf8().constData(), _layout->count()-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void insertWidget(int idx, QWidget *w)
|
||||
{
|
||||
int index = _layout->indexOf(w);
|
||||
if (index == idx)
|
||||
return;
|
||||
if (index > 0)
|
||||
_layout->removeWidget(w);
|
||||
_layout->insertWidget(idx, w);
|
||||
adjustParent();
|
||||
saveState();
|
||||
}
|
||||
|
||||
void adjustParent()
|
||||
{
|
||||
if (_sizingTimer) {
|
||||
_sizingTimer->start(10);
|
||||
}
|
||||
}
|
||||
|
||||
void removeWidget(QWidget *w)
|
||||
{
|
||||
_layout->removeWidget(w);
|
||||
QString name = w->objectName();
|
||||
if (!name.isEmpty()) {
|
||||
Base::ConnectionBlocker block(_conn);
|
||||
_hParam->RemoveInt(name.toUtf8().constData());
|
||||
}
|
||||
adjustParent();
|
||||
}
|
||||
|
||||
QWidget *widgetAt(int index) const
|
||||
{
|
||||
auto item = _layout->itemAt(index);
|
||||
return item ? item->widget() : nullptr;
|
||||
}
|
||||
|
||||
int count() const
|
||||
{
|
||||
return _layout->count();
|
||||
}
|
||||
|
||||
int indexOf(QWidget *w) const
|
||||
{
|
||||
return _layout->indexOf(w);
|
||||
}
|
||||
|
||||
template<class FuncT>
|
||||
void foreachToolBar(FuncT &&func)
|
||||
{
|
||||
for (int i = 0, c = _layout->count(); i < c; ++i) {
|
||||
auto toolbar = qobject_cast<QToolBar*>(widgetAt(i));
|
||||
if (!toolbar || toolbar->objectName().isEmpty()
|
||||
|| toolbar->objectName().startsWith(QStringLiteral("*")))
|
||||
continue;
|
||||
func(toolbar, i, this);
|
||||
}
|
||||
}
|
||||
|
||||
void saveState()
|
||||
{
|
||||
Base::ConnectionBlocker block(_conn);
|
||||
for (auto &v : _hParam->GetIntMap()) {
|
||||
_hParam->RemoveInt(v.first.c_str());
|
||||
}
|
||||
foreachToolBar([this](QToolBar *toolbar, int idx, ToolBarArea*) {
|
||||
_hParam->SetInt(toolbar->objectName().toUtf8().constData(), idx);
|
||||
});
|
||||
};
|
||||
|
||||
void restoreState(const std::map<int, QToolBar*> &toolbars)
|
||||
{
|
||||
for (const auto &[index, toolbar] : toolbars) {
|
||||
bool visible = toolbar->isVisible();
|
||||
getMainWindow()->removeToolBar(toolbar);
|
||||
toolbar->setOrientation(Qt::Horizontal);
|
||||
insertWidget(index, toolbar);
|
||||
toolbar->setVisible(visible);
|
||||
}
|
||||
|
||||
for (const auto &[name, visible] : _hParam->GetBoolMap()) {
|
||||
auto widget = findChild<QWidget*>(QString::fromUtf8(name.c_str()));
|
||||
if (widget)
|
||||
widget->setVisible(visible);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
QHBoxLayout *_layout;
|
||||
QPointer<QTimer> _sizingTimer;
|
||||
ParameterGrp::handle _hParam;
|
||||
boost::signals2::scoped_connection &_conn;
|
||||
};
|
||||
|
||||
} // namespace Gui
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
ToolBarManager* ToolBarManager::_instance=nullptr;
|
||||
|
||||
ToolBarManager* ToolBarManager::getInstance()
|
||||
@@ -169,7 +309,100 @@ void ToolBarManager::destruct()
|
||||
_instance = nullptr;
|
||||
}
|
||||
|
||||
ToolBarManager::ToolBarManager() = default;
|
||||
ToolBarManager::ToolBarManager()
|
||||
{
|
||||
hGeneral = App::GetApplication().GetUserParameter().GetGroup(
|
||||
"BaseApp/Preferences/General");
|
||||
|
||||
hStatusBar = App::GetApplication().GetUserParameter().GetGroup(
|
||||
"BaseApp/MainWindow/StatusBar");
|
||||
|
||||
hMenuBarRight = App::GetApplication().GetUserParameter().GetGroup(
|
||||
"BaseApp/MainWindow/MenuBarRight");
|
||||
hMenuBarLeft = App::GetApplication().GetUserParameter().GetGroup(
|
||||
"BaseApp/MainWindow/MenuBarLeft");
|
||||
|
||||
hPref = App::GetApplication().GetUserParameter().GetGroup(
|
||||
"BaseApp/MainWindow/Toolbars");
|
||||
|
||||
if (auto sb = getMainWindow()->statusBar()) {
|
||||
sb->installEventFilter(this);
|
||||
statusBarArea = new ToolBarArea(sb, hStatusBar, connParam);
|
||||
statusBarArea->setObjectName(QStringLiteral("StatusBarArea"));
|
||||
sb->insertPermanentWidget(2, statusBarArea);
|
||||
statusBarArea->show();
|
||||
}
|
||||
|
||||
if (auto mb = getMainWindow()->menuBar()) {
|
||||
mb->installEventFilter(this);
|
||||
menuBarLeftArea = new ToolBarArea(mb, hMenuBarLeft, connParam, &menuBarTimer);
|
||||
menuBarLeftArea->setObjectName(QStringLiteral("MenuBarLeftArea"));
|
||||
mb->setCornerWidget(menuBarLeftArea, Qt::TopLeftCorner);
|
||||
menuBarLeftArea->show();
|
||||
menuBarRightArea = new ToolBarArea(mb, hMenuBarRight, connParam, &menuBarTimer);
|
||||
menuBarRightArea->setObjectName(QStringLiteral("MenuBarRightArea"));
|
||||
mb->setCornerWidget(menuBarRightArea, Qt::TopRightCorner);
|
||||
menuBarRightArea->show();
|
||||
}
|
||||
|
||||
sizeTimer.setSingleShot(true);
|
||||
connect(&sizeTimer, &QTimer::timeout, [this]{
|
||||
setupToolBarIconSize();
|
||||
});
|
||||
|
||||
resizeTimer.setSingleShot(true);
|
||||
connect(&resizeTimer, &QTimer::timeout, [this]{
|
||||
for (const auto &[toolbar, guard] : resizingToolbars) {
|
||||
if (guard) {
|
||||
setToolBarIconSize(toolbar);
|
||||
}
|
||||
}
|
||||
resizingToolbars.clear();
|
||||
});
|
||||
|
||||
auto refreshParams = [this](const char *name) {
|
||||
bool sizeChanged = false;
|
||||
if (!name || boost::equals(name, "ToolbarIconSize")) {
|
||||
_toolBarIconSize = hGeneral->GetInt("ToolbarIconSize", 24);
|
||||
sizeChanged = true;
|
||||
}
|
||||
if (!name || boost::equals(name, "StatusBarIconSize")) {
|
||||
_statusBarIconSize = hGeneral->GetInt("StatusBarIconSize", 0);
|
||||
sizeChanged = true;
|
||||
}
|
||||
if (!name || boost::equals(name, "MenuBarIconSize")) {
|
||||
_menuBarIconSize = hGeneral->GetInt("MenuBarIconSize", 0);
|
||||
sizeChanged = true;
|
||||
}
|
||||
if (sizeChanged) {
|
||||
sizeTimer.start(100);
|
||||
}
|
||||
};
|
||||
|
||||
refreshParams(nullptr);
|
||||
connParam = App::GetApplication().GetUserParameter().signalParamChanged.connect(
|
||||
[this, refreshParams](ParameterGrp *hParam, ParameterGrp::ParamType, const char *name, const char *) {
|
||||
if (hParam == hGeneral && name) {
|
||||
refreshParams(name);
|
||||
}
|
||||
if (hParam == hPref
|
||||
|| hParam == hStatusBar
|
||||
|| hParam == hMenuBarRight
|
||||
|| hParam == hMenuBarLeft)
|
||||
timer.start(100);
|
||||
});
|
||||
timer.setSingleShot(true);
|
||||
connect(&timer, &QTimer::timeout, [this]{
|
||||
onTimer();
|
||||
});
|
||||
|
||||
menuBarTimer.setSingleShot(true);
|
||||
QObject::connect(&menuBarTimer, &QTimer::timeout, [] {
|
||||
if (auto menuBar = getMainWindow()->menuBar()) {
|
||||
menuBar->adjustSize();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ToolBarManager::~ToolBarManager() = default;
|
||||
|
||||
@@ -199,6 +432,49 @@ QPointer<QWidget> createActionWidget()
|
||||
}
|
||||
}
|
||||
|
||||
int ToolBarManager::toolBarIconSize(QWidget *widget) const
|
||||
{
|
||||
int s = _toolBarIconSize;
|
||||
if (widget) {
|
||||
if (widget->parentWidget() == statusBarArea) {
|
||||
if (_statusBarIconSize > 0)
|
||||
s = _statusBarIconSize;
|
||||
else
|
||||
s *= 0.6;
|
||||
}
|
||||
else if (widget->parentWidget() == menuBarLeftArea
|
||||
|| widget->parentWidget() == menuBarRightArea) {
|
||||
if (_menuBarIconSize > 0)
|
||||
s = _menuBarIconSize;
|
||||
else
|
||||
s *= 0.6;
|
||||
}
|
||||
}
|
||||
return std::max(s, 5);
|
||||
}
|
||||
|
||||
void ToolBarManager::setupToolBarIconSize()
|
||||
{
|
||||
int s = toolBarIconSize();
|
||||
getMainWindow()->setIconSize(QSize(s, s));
|
||||
// Most of the the toolbar will have explicit icon size, so the above call
|
||||
// to QMainWindow::setIconSize() will have no effect. We need to explicitly
|
||||
// change the icon size.
|
||||
for (auto toolbar : getMainWindow()->findChildren<QToolBar*>()) {
|
||||
setToolBarIconSize(toolbar);
|
||||
}
|
||||
}
|
||||
|
||||
void ToolBarManager::setToolBarIconSize(QToolBar *toolbar)
|
||||
{
|
||||
int s = toolBarIconSize(toolbar);
|
||||
toolbar->setIconSize(QSize(s, s));
|
||||
if (toolbar->parentWidget() == menuBarLeftArea)
|
||||
menuBarLeftArea->adjustParent();
|
||||
else if (toolbar->parentWidget() == menuBarRightArea)
|
||||
menuBarRightArea->adjustParent();
|
||||
}
|
||||
|
||||
void ToolBarManager::setup(ToolBarItem* toolBarItems)
|
||||
{
|
||||
if (!toolBarItems)
|
||||
@@ -212,8 +488,6 @@ void ToolBarManager::setup(ToolBarItem* toolBarItems)
|
||||
int max_width = getMainWindow()->width();
|
||||
int top_width = 0;
|
||||
|
||||
ParameterGrp::handle hPref = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
|
||||
->GetGroup("MainWindow")->GetGroup("Toolbars");
|
||||
bool nameAsToolTip = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
|
||||
->GetGroup("Preferences")->GetGroup("MainWindow")->GetBool("ToolBarNameAsToolTip",true);
|
||||
QList<ToolBarItem*> items = toolBarItems->getItems();
|
||||
@@ -291,7 +565,6 @@ void ToolBarManager::setup(ToolBarItem* toolBarItems)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// hide all unneeded toolbars
|
||||
for (QList<QToolBar*>::Iterator it = toolbars.begin(); it != toolbars.end(); ++it) {
|
||||
// make sure that the main window has the focus when hiding the toolbar with
|
||||
@@ -313,10 +586,8 @@ void ToolBarManager::setup(ToolBarItem* toolBarItems)
|
||||
(*it)->toggleViewAction()->setVisible(false);
|
||||
}
|
||||
|
||||
hPref = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
|
||||
->GetGroup("Preferences")->GetGroup("General");
|
||||
bool lockToolBars = hPref->GetBool("LockToolBars", false);
|
||||
setMovable(!lockToolBars);
|
||||
setMovable(!areToolBarsLocked());
|
||||
restoreState();
|
||||
}
|
||||
|
||||
void ToolBarManager::setup(ToolBarItem* item, QToolBar* toolbar) const
|
||||
@@ -357,6 +628,11 @@ void ToolBarManager::setup(ToolBarItem* item, QToolBar* toolbar) const
|
||||
}
|
||||
}
|
||||
|
||||
void ToolBarManager::onTimer()
|
||||
{
|
||||
restoreState();
|
||||
}
|
||||
|
||||
void ToolBarManager::saveState() const
|
||||
{
|
||||
auto ignoreSave = [](QAction* action) {
|
||||
@@ -377,9 +653,6 @@ void ToolBarManager::saveState() const
|
||||
return value == ToolBarItem::DefaultVisibility::Unavailable;
|
||||
};
|
||||
|
||||
ParameterGrp::handle hPref = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
|
||||
->GetGroup("MainWindow")->GetGroup("Toolbars");
|
||||
|
||||
QList<QToolBar*> toolbars = toolBars();
|
||||
for (QStringList::ConstIterator it = this->toolbarNames.begin(); it != this->toolbarNames.end(); ++it) {
|
||||
QToolBar* toolbar = findToolBar(toolbars, *it);
|
||||
@@ -396,19 +669,326 @@ void ToolBarManager::saveState() const
|
||||
|
||||
void ToolBarManager::restoreState() const
|
||||
{
|
||||
ParameterGrp::handle hPref = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
|
||||
->GetGroup("MainWindow")->GetGroup("Toolbars");
|
||||
|
||||
std::map<int, QToolBar*> sbToolBars;
|
||||
std::map<int, QToolBar*> mbRightToolBars;
|
||||
std::map<int, QToolBar*> mbLeftToolBars;
|
||||
QList<QToolBar*> toolbars = toolBars();
|
||||
for (QStringList::ConstIterator it = this->toolbarNames.begin(); it != this->toolbarNames.end(); ++it) {
|
||||
QToolBar* toolbar = findToolBar(toolbars, *it);
|
||||
if (toolbar) {
|
||||
QByteArray toolbarName = toolbar->objectName().toUtf8();
|
||||
toolbar->setVisible(hPref->GetBool(toolbarName.constData(), toolbar->isVisible()));
|
||||
if (getToolbarPolicy(toolbar) != ToolBarItem::DefaultVisibility::Unavailable) {
|
||||
toolbar->setVisible(hPref->GetBool(toolbarName.constData(), toolbar->isVisible()));
|
||||
}
|
||||
|
||||
int idx = hStatusBar->GetInt(toolbarName, -1);
|
||||
if (idx >= 0) {
|
||||
sbToolBars[idx] = toolbar;
|
||||
continue;
|
||||
}
|
||||
idx = hMenuBarLeft->GetInt(toolbarName, -1);
|
||||
if (idx >= 0) {
|
||||
mbLeftToolBars[idx] = toolbar;
|
||||
continue;
|
||||
}
|
||||
idx = hMenuBarRight->GetInt(toolbarName, -1);
|
||||
if (idx >= 0) {
|
||||
mbRightToolBars[idx] = toolbar;
|
||||
continue;
|
||||
}
|
||||
if (toolbar->parentWidget() != getMainWindow()) {
|
||||
getMainWindow()->addToolBar(toolbar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setMovable(!areToolBarsLocked());
|
||||
|
||||
statusBarArea->restoreState(sbToolBars);
|
||||
menuBarRightArea->restoreState(mbRightToolBars);
|
||||
menuBarLeftArea->restoreState(mbLeftToolBars);
|
||||
}
|
||||
|
||||
bool ToolBarManager::addToolBarToArea(QObject *source, QMouseEvent *ev)
|
||||
{
|
||||
auto statusBar = getMainWindow()->statusBar();
|
||||
if (!statusBar || !statusBar->isVisible())
|
||||
statusBar = nullptr;
|
||||
|
||||
auto menuBar = getMainWindow()->menuBar();
|
||||
if (!menuBar || !menuBar->isVisible()) {
|
||||
if (!statusBar)
|
||||
return false;
|
||||
menuBar = nullptr;
|
||||
}
|
||||
|
||||
auto tb = qobject_cast<QToolBar*>(source);
|
||||
if (!tb || !tb->isFloating())
|
||||
return false;
|
||||
|
||||
static QPointer<OverlayDragFrame> tbPlaceholder;
|
||||
static QPointer<ToolBarArea> lastArea;
|
||||
static int tbIndex = -1;
|
||||
if (ev->type() == QEvent::MouseMove) {
|
||||
if (tb->orientation() != Qt::Horizontal
|
||||
|| ev->buttons() != Qt::LeftButton) {
|
||||
if (tbIndex >= 0) {
|
||||
if (lastArea) {
|
||||
lastArea->removeWidget(tbPlaceholder);
|
||||
lastArea = nullptr;
|
||||
}
|
||||
tbPlaceholder->hide();
|
||||
tbIndex = -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ev->type() == QEvent::MouseButtonRelease && ev->button() != Qt::LeftButton)
|
||||
return false;
|
||||
|
||||
QPoint pos = QCursor::pos();
|
||||
ToolBarArea *area = nullptr;
|
||||
if (statusBar) {
|
||||
QRect rect(statusBar->mapToGlobal(QPoint(0,0)), statusBar->size());
|
||||
if (rect.contains(pos))
|
||||
area = statusBarArea;
|
||||
}
|
||||
if (!area) {
|
||||
if (!menuBar) {
|
||||
return false;
|
||||
}
|
||||
QRect rect(menuBar->mapToGlobal(QPoint(0,0)), menuBar->size());
|
||||
if (rect.contains(pos)) {
|
||||
if (pos.x() - rect.left() < menuBar->width()/2) {
|
||||
area = menuBarLeftArea;
|
||||
}
|
||||
else {
|
||||
area = menuBarRightArea;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tbPlaceholder) {
|
||||
if (lastArea) {
|
||||
lastArea->removeWidget(tbPlaceholder);
|
||||
lastArea = nullptr;
|
||||
}
|
||||
tbPlaceholder->hide();
|
||||
tbIndex = -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int idx = 0;
|
||||
for (int c = area->count(); idx < c ;++idx) {
|
||||
auto w = area->widgetAt(idx);
|
||||
if (!w || w->isHidden())
|
||||
continue;
|
||||
int p = w->mapToGlobal(w->rect().center()).x();
|
||||
if (pos.x() < p)
|
||||
break;
|
||||
}
|
||||
if (tbIndex >= 0 && tbIndex == idx-1)
|
||||
idx = tbIndex;
|
||||
if (ev->type() == QEvent::MouseMove) {
|
||||
if (!tbPlaceholder) {
|
||||
tbPlaceholder = new OverlayDragFrame(getMainWindow());
|
||||
tbPlaceholder->hide();
|
||||
tbIndex = -1;
|
||||
}
|
||||
if (tbIndex != idx) {
|
||||
tbIndex = idx;
|
||||
tbPlaceholder->setSizePolicy(tb->sizePolicy());
|
||||
tbPlaceholder->setMinimumWidth(tb->minimumWidth());
|
||||
tbPlaceholder->resize(tb->size());
|
||||
area->insertWidget(idx, tbPlaceholder);
|
||||
lastArea = area;
|
||||
tbPlaceholder->adjustSize();
|
||||
tbPlaceholder->show();
|
||||
}
|
||||
} else {
|
||||
tbIndex = idx;
|
||||
QTimer::singleShot(10, tb, [tb,this]() {
|
||||
if (!lastArea)
|
||||
return;
|
||||
else {
|
||||
tbPlaceholder->hide();
|
||||
QSignalBlocker block(tb);
|
||||
lastArea->removeWidget(tbPlaceholder);
|
||||
getMainWindow()->removeToolBar(tb);
|
||||
tb->setOrientation(Qt::Horizontal);
|
||||
lastArea->insertWidget(tbIndex, tb);
|
||||
tb->setVisible(true);
|
||||
lastArea = nullptr;
|
||||
}
|
||||
tb->topLevelChanged(false);
|
||||
tbIndex = -1;
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ToolBarManager::populateUndockMenu(QMenu *menu, ToolBarArea *area)
|
||||
{
|
||||
menu->setTitle(tr("Undock toolbars"));
|
||||
auto tooltip = QObject::tr("Undock from status bar");
|
||||
auto addMenuUndockItem = [&](QToolBar *toolbar, int, ToolBarArea *area) {
|
||||
auto *action = toolbar->toggleViewAction();
|
||||
auto undockAction = new QAction(menu);
|
||||
undockAction->setText(action->text());
|
||||
undockAction->setToolTip(tooltip);
|
||||
menu->addAction(undockAction);
|
||||
QObject::connect(undockAction, &QAction::triggered, [area, toolbar, this]() {
|
||||
if (toolbar->parentWidget() == getMainWindow()) {
|
||||
return;
|
||||
}
|
||||
auto pos = toolbar->mapToGlobal(QPoint(0, 0));
|
||||
QSignalBlocker blocker(toolbar);
|
||||
area->removeWidget(toolbar);
|
||||
getMainWindow()->addToolBar(toolbar);
|
||||
toolbar->setWindowFlags(Qt::Tool
|
||||
| Qt::FramelessWindowHint
|
||||
| Qt::X11BypassWindowManagerHint);
|
||||
toolbar->move(pos.x(), pos.y()-toolbar->height()-10);
|
||||
toolbar->adjustSize();
|
||||
toolbar->setVisible(true);
|
||||
toolbar->topLevelChanged(true);
|
||||
});
|
||||
};
|
||||
if (area)
|
||||
area->foreachToolBar(addMenuUndockItem);
|
||||
else {
|
||||
statusBarArea->foreachToolBar(addMenuUndockItem);
|
||||
menuBarLeftArea->foreachToolBar(addMenuUndockItem);
|
||||
menuBarRightArea->foreachToolBar(addMenuUndockItem);
|
||||
}
|
||||
}
|
||||
|
||||
bool ToolBarManager::showContextMenu(QObject *source)
|
||||
{
|
||||
QMenu menu;
|
||||
QMenu menuUndock;
|
||||
QHBoxLayout *layout = nullptr;
|
||||
ToolBarArea *area;
|
||||
if (getMainWindow()->statusBar() == source) {
|
||||
area = statusBarArea;
|
||||
for (auto l : source->findChildren<QHBoxLayout*>()) {
|
||||
if(l->indexOf(area) >= 0) {
|
||||
layout = l;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (getMainWindow()->menuBar() == source) {
|
||||
QPoint pos = QCursor::pos();
|
||||
QRect rect(menuBarLeftArea->mapToGlobal(QPoint(0,0)), menuBarLeftArea->size());
|
||||
if (rect.contains(pos)) {
|
||||
area = menuBarLeftArea;
|
||||
}
|
||||
else {
|
||||
rect = QRect(menuBarRightArea->mapToGlobal(QPoint(0,0)), menuBarRightArea->size());
|
||||
if (rect.contains(pos)) {
|
||||
area = menuBarRightArea;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto addMenuVisibleItem = [&](QToolBar *toolbar, int, ToolBarArea *) {
|
||||
auto action = toolbar->toggleViewAction();
|
||||
if ((action->isVisible() || toolbar->isVisible()) && action->text().size()) {
|
||||
action->setVisible(true);
|
||||
menu.addAction(action);
|
||||
}
|
||||
};
|
||||
|
||||
if (layout) {
|
||||
for (int i = 0, c = layout->count(); i < c; ++i) {
|
||||
auto widget = layout->itemAt(i)->widget();
|
||||
if (!widget || widget == area
|
||||
|| widget->objectName().isEmpty()
|
||||
|| widget->objectName().startsWith(QStringLiteral("*")))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QString name = widget->windowTitle();
|
||||
if (name.isEmpty()) {
|
||||
name = widget->objectName();
|
||||
name.replace(QLatin1Char('_'), QLatin1Char(' '));
|
||||
name = name.simplified();
|
||||
}
|
||||
QAction *action = new QAction(&menu);
|
||||
action->setText(name);
|
||||
action->setCheckable(true);
|
||||
action->setChecked(widget->isVisible());
|
||||
menu.addAction(action);
|
||||
|
||||
auto onToggle = [widget, this](bool visible) {
|
||||
onToggleStatusBarWidget(widget, visible);
|
||||
};
|
||||
QObject::connect(action, &QAction::triggered, onToggle);
|
||||
}
|
||||
}
|
||||
|
||||
area->foreachToolBar(addMenuVisibleItem);
|
||||
populateUndockMenu(&menuUndock, area);
|
||||
|
||||
if (menuUndock.actions().size()) {
|
||||
menu.addSeparator();
|
||||
menu.addMenu(&menuUndock);
|
||||
}
|
||||
menu.exec(QCursor::pos());
|
||||
return true;
|
||||
}
|
||||
|
||||
void ToolBarManager::onToggleStatusBarWidget(QWidget *widget, bool visible)
|
||||
{
|
||||
Base::ConnectionBlocker block(connParam);
|
||||
widget->setVisible(visible);
|
||||
hStatusBar->SetBool(widget->objectName().toUtf8().constData(), widget->isVisible());
|
||||
}
|
||||
|
||||
bool ToolBarManager::eventFilter(QObject *source, QEvent *ev)
|
||||
{
|
||||
bool res = false;
|
||||
switch(ev->type()) {
|
||||
case QEvent::Show:
|
||||
case QEvent::Hide:
|
||||
if (auto toolbar = qobject_cast<QToolBar*>(source)) {
|
||||
auto parent = toolbar->parentWidget();
|
||||
if (parent == menuBarLeftArea || parent == menuBarRightArea) {
|
||||
menuBarTimer.start(10);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QEvent::MouseButtonRelease: {
|
||||
auto mev = static_cast<QMouseEvent*>(ev);
|
||||
if (mev->button() == Qt::RightButton) {
|
||||
if (showContextMenu(source)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case QEvent::MouseMove:
|
||||
res = addToolBarToArea(source, static_cast<QMouseEvent*>(ev));
|
||||
break;
|
||||
case QEvent::ParentChange:
|
||||
if (auto toolbar = qobject_cast<QToolBar*>(source)) {
|
||||
resizingToolbars[toolbar] = toolbar;
|
||||
resizeTimer.start(100);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void ToolBarManager::retranslate() const
|
||||
@@ -424,24 +1004,12 @@ void ToolBarManager::retranslate() const
|
||||
|
||||
bool Gui::ToolBarManager::areToolBarsLocked() const
|
||||
{
|
||||
auto hPref = App::GetApplication()
|
||||
.GetUserParameter()
|
||||
.GetGroup("BaseApp")
|
||||
->GetGroup("Preferences")
|
||||
->GetGroup("General");
|
||||
|
||||
return hPref->GetBool("LockToolBars", false);
|
||||
return hGeneral->GetBool("LockToolBars", false);
|
||||
}
|
||||
|
||||
void Gui::ToolBarManager::setToolBarsLocked(bool locked) const
|
||||
{
|
||||
auto hPref = App::GetApplication()
|
||||
.GetUserParameter()
|
||||
.GetGroup("BaseApp")
|
||||
->GetGroup("Preferences")
|
||||
->GetGroup("General");
|
||||
|
||||
hPref->SetBool("LockToolBars", locked);
|
||||
hGeneral->SetBool("LockToolBars", locked);
|
||||
|
||||
setMovable(!locked);
|
||||
}
|
||||
@@ -475,12 +1043,19 @@ QAction* ToolBarManager::findAction(const QList<QAction*>& acts, const QString&
|
||||
|
||||
QList<QToolBar*> ToolBarManager::toolBars() const
|
||||
{
|
||||
QWidget* mw = getMainWindow();
|
||||
auto mw = getMainWindow();
|
||||
QList<QToolBar*> tb;
|
||||
QList<QToolBar*> bars = getMainWindow()->findChildren<QToolBar*>();
|
||||
for (QList<QToolBar*>::Iterator it = bars.begin(); it != bars.end(); ++it) {
|
||||
if ((*it)->parentWidget() == mw)
|
||||
auto parent = (*it)->parentWidget();
|
||||
if (parent == mw
|
||||
|| parent == mw->statusBar()
|
||||
|| parent == statusBarArea
|
||||
|| parent == menuBarLeftArea
|
||||
|| parent == menuBarRightArea) {
|
||||
tb.push_back(*it);
|
||||
(*it)->installEventFilter(const_cast<ToolBarManager*>(this));
|
||||
}
|
||||
}
|
||||
|
||||
return tb;
|
||||
@@ -507,13 +1082,11 @@ void ToolBarManager::setState(const QList<QString>& names, State state)
|
||||
|
||||
void ToolBarManager::setState(const QString& name, State state)
|
||||
{
|
||||
ParameterGrp::handle hPref = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->GetGroup("MainWindow")->GetGroup("Toolbars");
|
||||
|
||||
auto visibility = [hPref, name](bool defaultvalue) {
|
||||
auto visibility = [this, name](bool defaultvalue) {
|
||||
return hPref->GetBool(name.toStdString().c_str(), defaultvalue);
|
||||
};
|
||||
|
||||
auto saveVisibility = [hPref, name](bool value) {
|
||||
auto saveVisibility = [this, name](bool value) {
|
||||
hPref->SetBool(name.toStdString().c_str(), value);
|
||||
};
|
||||
|
||||
@@ -574,3 +1147,5 @@ void ToolBarManager::setState(const QString& name, State state)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_ToolBarManager.cpp"
|
||||
|
||||
@@ -25,14 +25,23 @@
|
||||
#define GUI_TOOLBARMANAGER_H
|
||||
|
||||
#include <string>
|
||||
#include <boost_signals2.hpp>
|
||||
|
||||
#include <QStringList>
|
||||
#include <QTimer>
|
||||
|
||||
#include <FCGlobal.h>
|
||||
#include <Base/Parameter.h>
|
||||
|
||||
class QAction;
|
||||
class QMenu;
|
||||
class QMouseEvent;
|
||||
class QToolBar;
|
||||
|
||||
namespace Gui {
|
||||
|
||||
class ToolBarArea;
|
||||
|
||||
class GuiExport ToolBarItem
|
||||
{
|
||||
public:
|
||||
@@ -83,8 +92,9 @@ private:
|
||||
* @see MenuManager
|
||||
* @author Werner Mayer
|
||||
*/
|
||||
class GuiExport ToolBarManager
|
||||
class GuiExport ToolBarManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
enum class State {
|
||||
@@ -109,6 +119,11 @@ public:
|
||||
void setState(const QList<QString>& names, State state);
|
||||
void setState(const QString& name, State state);
|
||||
|
||||
int toolBarIconSize(QWidget *widget=nullptr) const;
|
||||
void setupToolBarIconSize();
|
||||
|
||||
void populateUndockMenu(QMenu *menu, ToolBarArea *area = nullptr);
|
||||
|
||||
protected:
|
||||
void setup(ToolBarItem*, QToolBar*) const;
|
||||
|
||||
@@ -116,6 +131,14 @@ protected:
|
||||
|
||||
ToolBarItem::DefaultVisibility getToolbarPolicy(const QToolBar *) const;
|
||||
|
||||
bool addToolBarToArea(QObject *source, QMouseEvent *ev);
|
||||
bool showContextMenu(QObject *source);
|
||||
void onToggleStatusBarWidget(QWidget *widget, bool visible);
|
||||
void setToolBarIconSize(QToolBar *toolbar);
|
||||
void onTimer();
|
||||
|
||||
bool eventFilter(QObject *source, QEvent *ev) override;
|
||||
|
||||
/** Returns a list of all currently existing toolbars. */
|
||||
QList<QToolBar*> toolBars() const;
|
||||
QToolBar* findToolBar(const QList<QToolBar*>&, const QString&) const;
|
||||
@@ -126,6 +149,25 @@ protected:
|
||||
private:
|
||||
QStringList toolbarNames;
|
||||
static ToolBarManager* _instance;
|
||||
|
||||
QTimer timer;
|
||||
QTimer menuBarTimer;
|
||||
QTimer sizeTimer;
|
||||
QTimer resizeTimer;
|
||||
boost::signals2::scoped_connection connParam;
|
||||
ToolBarArea *statusBarArea = nullptr;
|
||||
ToolBarArea *menuBarLeftArea = nullptr;
|
||||
ToolBarArea *menuBarRightArea = nullptr;
|
||||
ParameterGrp::handle hGeneral;
|
||||
ParameterGrp::handle hPref;
|
||||
ParameterGrp::handle hStatusBar;
|
||||
ParameterGrp::handle hMenuBarLeft;
|
||||
ParameterGrp::handle hMenuBarRight;
|
||||
std::map<QToolBar*, QPointer<QToolBar>> resizingToolbars;
|
||||
int _toolBarIconSize = 0;
|
||||
int _statusBarIconSize = 0;
|
||||
int _menuBarIconSize = 0;
|
||||
mutable bool restored = false;
|
||||
};
|
||||
|
||||
} // namespace Gui
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2022 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#endif
|
||||
|
||||
|
||||
#include "UserSettings.h"
|
||||
#include <App/Application.h>
|
||||
|
||||
|
||||
using namespace Gui;
|
||||
|
||||
namespace {
|
||||
|
||||
ParameterGrp::handle getWSParameter()
|
||||
{
|
||||
return App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::string WorkbenchSwitcher::getValue()
|
||||
{
|
||||
return getWSParameter()->GetASCII("WSPosition", "WSToolbar");
|
||||
}
|
||||
|
||||
bool WorkbenchSwitcher::isLeftCorner(const std::string& value)
|
||||
{
|
||||
return (value == "WSLeftCorner");
|
||||
}
|
||||
|
||||
bool WorkbenchSwitcher::isRightCorner(const std::string& value)
|
||||
{
|
||||
return (value == "WSRightCorner");
|
||||
}
|
||||
|
||||
bool WorkbenchSwitcher::isToolbar(const std::string& value)
|
||||
{
|
||||
return (value == "WSToolbar");
|
||||
}
|
||||
|
||||
QVector<std::string> WorkbenchSwitcher::values()
|
||||
{
|
||||
QVector<std::string> wsPositions;
|
||||
wsPositions << "WSToolbar" << "WSLeftCorner" << "WSRightCorner";
|
||||
return wsPositions;
|
||||
}
|
||||
|
||||
int WorkbenchSwitcher::getIndex()
|
||||
{
|
||||
auto hGrp = getWSParameter();
|
||||
std::string pos = hGrp->GetASCII("WSPosition", "WSToolbar");
|
||||
auto wsPositions = values();
|
||||
int index = std::max(0, static_cast<int>(wsPositions.indexOf(pos)));
|
||||
return index;
|
||||
}
|
||||
|
||||
void WorkbenchSwitcher::setIndex(int index)
|
||||
{
|
||||
auto wsPositions = values();
|
||||
auto hGrp = getWSParameter();
|
||||
if (index >= 0 && index < wsPositions.size()) {
|
||||
hGrp->SetASCII("WSPosition", wsPositions[index].c_str());
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2022 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef GUI_USERSETTINGS_H
|
||||
#define GUI_USERSETTINGS_H
|
||||
|
||||
#include <FCGlobal.h>
|
||||
#include <string>
|
||||
#include <QVector>
|
||||
|
||||
namespace Gui {
|
||||
|
||||
class GuiExport WorkbenchSwitcher
|
||||
{
|
||||
public:
|
||||
static bool isLeftCorner(const std::string&);
|
||||
static bool isRightCorner(const std::string&);
|
||||
static bool isToolbar(const std::string&);
|
||||
static std::string getValue();
|
||||
static int getIndex();
|
||||
static void setIndex(int);
|
||||
|
||||
private:
|
||||
static QVector<std::string> values();
|
||||
};
|
||||
|
||||
} // namespace Gui
|
||||
|
||||
#endif // GUI_USERSETTINGS_H
|
||||
@@ -41,7 +41,6 @@
|
||||
#include "Selection.h"
|
||||
#include "ToolBarManager.h"
|
||||
#include "ToolBoxManager.h"
|
||||
#include "UserSettings.h"
|
||||
#include "Window.h"
|
||||
|
||||
#include <App/Application.h>
|
||||
@@ -797,11 +796,9 @@ ToolBarItem* StdWorkbench::setupToolBars() const
|
||||
*clipboard << "Std_Cut" << "Std_Copy" << "Std_Paste";
|
||||
|
||||
// Workbench switcher
|
||||
if (WorkbenchSwitcher::isToolbar(WorkbenchSwitcher::getValue())) {
|
||||
auto wb = new ToolBarItem(root);
|
||||
wb->setCommand("Workbench");
|
||||
*wb << "Std_Workbench";
|
||||
}
|
||||
auto wb = new ToolBarItem(root);
|
||||
wb->setCommand("Workbench");
|
||||
*wb << "Std_Workbench";
|
||||
|
||||
// Macro
|
||||
auto macro = new ToolBarItem( root, ToolBarItem::DefaultVisibility::Hidden);
|
||||
|
||||
@@ -27,7 +27,9 @@
|
||||
# include <QAbstractItemView>
|
||||
# include <QActionGroup>
|
||||
# include <QApplication>
|
||||
# include <QMenuBar>
|
||||
# include <QScreen>
|
||||
# include <QStatusBar>
|
||||
# include <QToolBar>
|
||||
#endif
|
||||
|
||||
@@ -208,15 +210,30 @@ void WorkbenchTabWidget::refreshList(QList<QAction*> actionList)
|
||||
|
||||
void WorkbenchTabWidget::updateLayoutAndTabOrientation(bool floating)
|
||||
{
|
||||
if (!parentWidget()->inherits("QToolBar") || floating) {
|
||||
auto parent = parentWidget();
|
||||
if (!parent || !parent->inherits("QToolBar")) {
|
||||
return;
|
||||
}
|
||||
|
||||
ParameterGrp::handle hGrp = App::GetApplication()
|
||||
.GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches");
|
||||
|
||||
QToolBar* tb = qobject_cast<QToolBar*>(parentWidget());
|
||||
Qt::ToolBarArea area = getMainWindow()->toolBarArea(tb);
|
||||
Qt::ToolBarArea area;
|
||||
parent = parent->parentWidget();
|
||||
|
||||
if (floating) {
|
||||
area = Qt::TopToolBarArea;
|
||||
}
|
||||
else if (parent && parent->parentWidget() == getMainWindow()->statusBar()) {
|
||||
area = Qt::BottomToolBarArea;
|
||||
}
|
||||
else if (parent && parent->parentWidget() == getMainWindow()->menuBar()) {
|
||||
area = Qt::TopToolBarArea;
|
||||
}
|
||||
else {
|
||||
QToolBar* tb = qobject_cast<QToolBar*>(parentWidget());
|
||||
area = getMainWindow()->toolBarArea(tb);
|
||||
}
|
||||
|
||||
if (area == Qt::LeftToolBarArea || area == Qt::RightToolBarArea) {
|
||||
setShape(area == Qt::LeftToolBarArea ? QTabBar::RoundedWest : QTabBar::RoundedEast);
|
||||
|
||||
@@ -66,7 +66,7 @@ def onRestore(active):
|
||||
|
||||
isConnected(i)
|
||||
|
||||
if i.objectName() and not i.isFloating():
|
||||
if i.objectName() and i.parentWidget() == mw and not i.isFloating():
|
||||
toolbars[i.objectName()] = i
|
||||
else:
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user