From 5d3de598e7a5ba6896705dcbb8aa4b1b1c354839 Mon Sep 17 00:00:00 2001 From: PaddleStroke Date: Mon, 5 Feb 2024 18:53:30 +0100 Subject: [PATCH] Core: Introduce Tab-Bar workbench selector --- src/Gui/Action.cpp | 122 ++++----- src/Gui/Action.h | 23 +- src/Gui/CMakeLists.txt | 2 + .../PreferencePages/DlgSettingsWorkbenches.ui | 68 ++++- .../DlgSettingsWorkbenchesImp.cpp | 66 +++-- .../DlgSettingsWorkbenchesImp.h | 1 - src/Gui/WorkbenchManager.cpp | 9 + src/Gui/WorkbenchManager.h | 2 + src/Gui/WorkbenchSelector.cpp | 248 ++++++++++++++++++ src/Gui/WorkbenchSelector.h | 74 ++++++ 10 files changed, 504 insertions(+), 111 deletions(-) create mode 100644 src/Gui/WorkbenchSelector.cpp create mode 100644 src/Gui/WorkbenchSelector.h diff --git a/src/Gui/Action.cpp b/src/Gui/Action.cpp index 55961557ea..d6423d359a 100644 --- a/src/Gui/Action.cpp +++ b/src/Gui/Action.cpp @@ -60,6 +60,7 @@ #include "Widgets.h" #include "Workbench.h" #include "WorkbenchManager.h" +#include "WorkbenchSelector.h" #include "ShortcutManager.h" #include "Tools.h" @@ -614,43 +615,6 @@ void ActionGroup::onHovered (QAction *act) } -// -------------------------------------------------------------------- - -WorkbenchComboBox::WorkbenchComboBox(QWidget* parent) : QComboBox(parent) -{ -} - -void WorkbenchComboBox::showPopup() -{ - int rows = count(); - if (rows > 0) { - int height = view()->sizeHintForRow(0); - int maxHeight = QApplication::primaryScreen()->size().height(); - view()->setMinimumHeight(qMin(height * rows, maxHeight/2)); - } - - QComboBox::showPopup(); -} - -void WorkbenchComboBox::refreshList(QList actionList) -{ - clear(); - - for (QAction* action : actionList) { - QIcon icon = action->icon(); - if (icon.isNull()) { - this->addItem(action->text()); - } - else { - this->addItem(icon, action->text()); - } - - if (action->isChecked()) { - this->setCurrentIndex(this->count() - 1); - } - } -} - /* TRANSLATOR Gui::WorkbenchGroup */ WorkbenchGroup::WorkbenchGroup ( Command* pcCmd, QObject * parent ) : ActionGroup( pcCmd, parent ) @@ -667,37 +631,29 @@ WorkbenchGroup::WorkbenchGroup ( Command* pcCmd, QObject * parent ) void WorkbenchGroup::addTo(QWidget *widget) { - auto setupBox = [&](WorkbenchComboBox* box) { - box->setIconSize(QSize(16, 16)); - box->setToolTip(toolTip()); - box->setStatusTip(action()->statusTip()); - box->setWhatsThis(action()->whatsThis()); - box->refreshList(actions()); - connect(this, &WorkbenchGroup::workbenchListRefreshed, box, &WorkbenchComboBox::refreshList); - connect(groupAction(), &QActionGroup::triggered, box, [this, box](QAction* action) { - box->setCurrentIndex(actions().indexOf(action)); - }); - connect(box, qOverload(&WorkbenchComboBox::activated), this, [this](int index) { - actions()[index]->trigger(); - }); - }; - if (widget->inherits("QToolBar")) { - auto* box = new WorkbenchComboBox(widget); - setupBox(box); + if (widget->inherits("QToolBar") || widget->inherits("QMenuBar")) { + ParameterGrp::handle hGrp; + hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches"); + QWidget* wbSel; + if (hGrp->GetInt("WorkbenchSelectorType", 0) == 0) { + wbSel = new WorkbenchComboBox(this, widget); + } + else { + wbSel = new WorkbenchTabWidget(this, widget); + } - qobject_cast(widget)->addWidget(box); - } - else if (widget->inherits("QMenuBar")) { - auto* box = new WorkbenchComboBox(widget); - setupBox(box); - - bool left = WorkbenchSwitcher::isLeftCorner(WorkbenchSwitcher::getValue()); - qobject_cast(widget)->setCornerWidget(box, left ? Qt::TopLeftCorner : Qt::TopRightCorner); + if (widget->inherits("QToolBar")) { + qobject_cast(widget)->addWidget(wbSel); + } + else { + bool left = WorkbenchSwitcher::isLeftCorner(WorkbenchSwitcher::getValue()); + qobject_cast(widget)->setCornerWidget(wbSel, left ? Qt::TopLeftCorner : Qt::TopRightCorner); + } } else if (widget->inherits("QMenu")) { auto menu = qobject_cast(widget); menu = menu->addMenu(action()->text()); - menu->addActions(actions()); + menu->addActions(getEnabledWbActions()); connect(this, &WorkbenchGroup::workbenchListRefreshed, this, [menu](QList actions) { menu->clear(); @@ -715,11 +671,10 @@ void WorkbenchGroup::refreshWorkbenchList() groupAction()->removeAction(action); delete action; } + enabledWbsActions.clear(); + disabledWbsActions.clear(); - std::string activeWbName = ""; - Workbench* activeWB = WorkbenchManager::instance()->active(); - if (activeWB) - activeWbName = activeWB->name(); + std::string activeWbName = WorkbenchManager::instance()->activeName(); // Create action list of enabled wb int index = 0; @@ -741,12 +696,33 @@ void WorkbenchGroup::refreshWorkbenchList() if (wbName.toStdString() == activeWbName) { action->setChecked(true); } + enabledWbsActions.push_back(action); + index++; + } + // Also create action list of disabled wbs + QStringList disabled_wbs_list = DlgSettingsWorkbenchesImp::getDisabledWorkbenches(); + for (const auto& wbName : disabled_wbs_list) { + QString name = Application::Instance->workbenchMenuText(wbName); + QPixmap px = Application::Instance->workbenchIcon(wbName); + QString tip = Application::Instance->workbenchToolTip(wbName); + + QAction* action = groupAction()->addAction(name); + action->setCheckable(true); + action->setData(QVariant(index)); // set the index + action->setObjectName(wbName); + action->setIcon(px); + action->setToolTip(tip); + action->setStatusTip(tr("Select the '%1' workbench").arg(name)); + if (wbName.toStdString() == activeWbName) { + action->setChecked(true); + } + disabledWbsActions.push_back(action); index++; } // Signal to the widgets (WorkbenchComboBox & menu) to update the wb list - workbenchListRefreshed(actions()); + workbenchListRefreshed(enabledWbsActions); } void WorkbenchGroup::onWorkbenchActivated(const QString& name) @@ -772,6 +748,16 @@ void WorkbenchGroup::onWorkbenchActivated(const QString& name) } } +QList WorkbenchGroup::getEnabledWbActions() const +{ + return enabledWbsActions; +} + +QList WorkbenchGroup::getDisabledWbActions() const +{ + return disabledWbsActions; +} + // -------------------------------------------------------------------- class RecentFilesAction::Private: public ParameterGrp::ObserverType diff --git a/src/Gui/Action.h b/src/Gui/Action.h index 8b2e45cdfb..54f83c4acd 100644 --- a/src/Gui/Action.h +++ b/src/Gui/Action.h @@ -153,7 +153,6 @@ public: int checkedAction() const; void setCheckedAction(int); -protected: QActionGroup* groupAction() const { return _group; } @@ -180,22 +179,6 @@ private: Q_DISABLE_COPY(ActionGroup) }; -// -------------------------------------------------------------------- -class GuiExport WorkbenchComboBox : public QComboBox -{ - Q_OBJECT - -public: - explicit WorkbenchComboBox(QWidget* parent=nullptr); - void showPopup() override; - -public Q_SLOTS: - void refreshList(QList); - -private: - Q_DISABLE_COPY(WorkbenchComboBox) -}; - /** * The WorkbenchGroup class represents a list of workbenches. When it is added * to a menu a submenu gets created, if added to a toolbar a combo box gets created. @@ -216,6 +199,9 @@ public: void slotActivateWorkbench(const char*); + QList getEnabledWbActions() const; + QList getDisabledWbActions() const; + Q_SIGNALS: void workbenchListRefreshed(QList); @@ -223,6 +209,9 @@ protected Q_SLOTS: void onWorkbenchActivated(const QString&); private: + QList enabledWbsActions; + QList disabledWbsActions; + Q_DISABLE_COPY(WorkbenchGroup) }; diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index c280270158..f17d4afc86 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -1041,6 +1041,7 @@ SET(Widget_CPP_SRCS WidgetFactory.cpp Widgets.cpp Window.cpp + WorkbenchSelector.cpp ) SET(Widget_HPP_SRCS FileDialog.h @@ -1061,6 +1062,7 @@ SET(Widget_HPP_SRCS WidgetFactory.h Widgets.h Window.h + WorkbenchSelector.h ) SET(Widget_SRCS ${Widget_CPP_SRCS} diff --git a/src/Gui/PreferencePages/DlgSettingsWorkbenches.ui b/src/Gui/PreferencePages/DlgSettingsWorkbenches.ui index 3f26834f83..6bed2929e4 100644 --- a/src/Gui/PreferencePages/DlgSettingsWorkbenches.ui +++ b/src/Gui/PreferencePages/DlgSettingsWorkbenches.ui @@ -75,6 +75,39 @@ after FreeCAD launches + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Workbench selector type: + + + + + + + Choose the workbench selector widget type (restart required). + + + + + + 6 @@ -111,7 +144,40 @@ after FreeCAD launches - + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Workbench selector items style: + + + + + + + Customize how the items are displayed. + + + + + + If checked, application will remember which workbench is active for each tab of the viewport diff --git a/src/Gui/PreferencePages/DlgSettingsWorkbenchesImp.cpp b/src/Gui/PreferencePages/DlgSettingsWorkbenchesImp.cpp index c621a26cd9..2a873b9c12 100644 --- a/src/Gui/PreferencePages/DlgSettingsWorkbenchesImp.cpp +++ b/src/Gui/PreferencePages/DlgSettingsWorkbenchesImp.cpp @@ -249,7 +249,6 @@ DlgSettingsWorkbenchesImp::DlgSettingsWorkbenchesImp( QWidget* parent ) connect(ui->wbList->model(), &QAbstractItemModel::rowsMoved, this, &DlgSettingsWorkbenchesImp::wbItemMoved); connect(ui->AutoloadModuleCombo, qOverload(&QComboBox::activated), this, &DlgSettingsWorkbenchesImp::onStartWbChanged); - connect(ui->WorkbenchSelectorPosition, qOverload(&QComboBox::activated), this, &DlgSettingsWorkbenchesImp::onWbSelectorChanged); connect(ui->CheckBox_WbByTab, &QCheckBox::toggled, this, &DlgSettingsWorkbenchesImp::onWbByTabToggled); } @@ -355,19 +354,16 @@ void DlgSettingsWorkbenchesImp::resetSettingsToDefaults() { ParameterGrp::handle hGrp; hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches"); - //reset "Ordered" parameter hGrp->RemoveASCII("Ordered"); - //reset "Disabled" parameter hGrp->RemoveASCII("Disabled"); + hGrp->RemoveASCII("WorkbenchSelectorType"); + hGrp->RemoveASCII("WorkbenchSelectorItem"); hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General"); - //reset "BackgroundAutoloadModules" parameter hGrp->RemoveASCII("BackgroundAutoloadModules"); - //reset "AutoloadModule" parameter hGrp->RemoveASCII("AutoloadModule"); hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow"); - //reset "WSPosition" parameter hGrp->RemoveASCII("WSPosition"); if (ui->WorkbenchSelectorPosition->currentIndex() != WorkbenchSwitcher::getIndex()) { requireRestart(); @@ -504,20 +500,57 @@ void DlgSettingsWorkbenchesImp::changeEvent(QEvent *e) void DlgSettingsWorkbenchesImp::saveWorkbenchSelector() { //save workbench selector position + int prevIndex = WorkbenchSwitcher::getIndex(); auto index = ui->WorkbenchSelectorPosition->currentIndex(); - WorkbenchSwitcher::setIndex(index); + 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(); + if (prevIndex != index) { + hGrp->SetInt("WorkbenchSelectorType", index); + requireRestart(); + } + + // save workbench selector items style + prevIndex = hGrp->GetInt("WorkbenchSelectorItem", 0); + index = ui->WorkbenchSelectorItem->currentIndex(); + if (prevIndex != index) { + hGrp->SetInt("WorkbenchSelectorItem", index); + requireRestart(); + } } void DlgSettingsWorkbenchesImp::loadWorkbenchSelector() { - QSignalBlocker sigblk(ui->WorkbenchSelectorPosition); - //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"); + int widgetTypeIndex = hGrp->GetInt("WorkbenchSelectorType", 0); + ui->WorkbenchSelectorType->clear(); + ui->WorkbenchSelectorType->addItem(tr("ComboBox")); + ui->WorkbenchSelectorType->addItem(tr("TabBar")); + ui->WorkbenchSelectorType->setCurrentIndex(widgetTypeIndex); + + // workbench selector items style + int itemStyleIndex = hGrp->GetInt("WorkbenchSelectorItem", 0); + ui->WorkbenchSelectorItem->clear(); + ui->WorkbenchSelectorItem->addItem(tr("Icon & Text")); + ui->WorkbenchSelectorItem->addItem(tr("Icon")); + ui->WorkbenchSelectorItem->addItem(tr("Text")); + ui->WorkbenchSelectorItem->setCurrentIndex(itemStyleIndex); } void DlgSettingsWorkbenchesImp::wbToggled(const QString& wbName, bool enabled) @@ -618,21 +651,6 @@ void DlgSettingsWorkbenchesImp::onStartWbChanged(int index) } } -void DlgSettingsWorkbenchesImp::onWbSelectorChanged(int index) -{ - Q_UNUSED(index); - /** - * TODO: move the following code somewhere else so that the restart request isn't asked - * everytime the WorkbenchSwitcher is changed but only when the value that will be saved in - * the parameter is actually different from the current one. - * The code, as is now, will request the restart even if the use selects again the same value - * that is already saved in the parameters - */ - if (ui->WorkbenchSelectorPosition->currentIndex() != WorkbenchSwitcher::getIndex()) { - requireRestart(); - } -} - void DlgSettingsWorkbenchesImp::onWbByTabToggled(bool val) { Q_UNUSED(val); diff --git a/src/Gui/PreferencePages/DlgSettingsWorkbenchesImp.h b/src/Gui/PreferencePages/DlgSettingsWorkbenchesImp.h index 6c2f6d7c9f..433281df71 100644 --- a/src/Gui/PreferencePages/DlgSettingsWorkbenchesImp.h +++ b/src/Gui/PreferencePages/DlgSettingsWorkbenchesImp.h @@ -56,7 +56,6 @@ public: protected Q_SLOTS: void wbToggled(const QString& wbName, bool enabled); void wbItemMoved(); - void onWbSelectorChanged(int index); void onStartWbChanged(int index); void onWbByTabToggled(bool val); diff --git a/src/Gui/WorkbenchManager.cpp b/src/Gui/WorkbenchManager.cpp index af9dc5dbda..3828e826a0 100644 --- a/src/Gui/WorkbenchManager.cpp +++ b/src/Gui/WorkbenchManager.cpp @@ -127,6 +127,15 @@ Workbench* WorkbenchManager::active() const return _activeWorkbench; } +std::string WorkbenchManager::activeName() const +{ + std::string activeWbName = ""; + if (_activeWorkbench) { + activeWbName = _activeWorkbench->name(); + } + return activeWbName; +} + std::list WorkbenchManager::workbenches() const { std::list wb; diff --git a/src/Gui/WorkbenchManager.h b/src/Gui/WorkbenchManager.h index f5818c1fb8..40f68e8497 100644 --- a/src/Gui/WorkbenchManager.h +++ b/src/Gui/WorkbenchManager.h @@ -61,6 +61,8 @@ public: bool activate(const std::string& name, const std::string& className); /** Returns the active workbench. */ Workbench* active() const; + /** Returns the name of the active workbench. */ + std::string activeName() const; /** Returns a list of all created workbench objects. */ std::list workbenches() const; diff --git a/src/Gui/WorkbenchSelector.cpp b/src/Gui/WorkbenchSelector.cpp new file mode 100644 index 0000000000..5df2ebe20b --- /dev/null +++ b/src/Gui/WorkbenchSelector.cpp @@ -0,0 +1,248 @@ +/*************************************************************************** + * Copyright (c) 2024 Pierre-Louis Boyer * + * * + * 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_ +# include +# include +# include +# include +# include +#endif + +#include "Action.h" +#include "BitmapFactory.h" +#include "Command.h" +#include "PreferencePages/DlgSettingsWorkbenchesImp.h" +#include "DlgPreferencesImp.h" +#include "MainWindow.h" +#include "WorkbenchManager.h" +#include "WorkbenchSelector.h" + + +using namespace Gui; + +WorkbenchComboBox::WorkbenchComboBox(WorkbenchGroup* aGroup, QWidget* parent) : QComboBox(parent) +{ + setIconSize(QSize(16, 16)); + setToolTip(aGroup->toolTip()); + setStatusTip(aGroup->action()->statusTip()); + setWhatsThis(aGroup->action()->whatsThis()); + refreshList(aGroup->getEnabledWbActions()); + connect(aGroup, &WorkbenchGroup::workbenchListRefreshed, this, &WorkbenchComboBox::refreshList); + connect(aGroup->groupAction(), &QActionGroup::triggered, this, [this, aGroup](QAction* action) { + setCurrentIndex(aGroup->actions().indexOf(action)); + }); + connect(this, qOverload(&WorkbenchComboBox::activated), aGroup, [aGroup](int index) { + aGroup->actions()[index]->trigger(); + }); +} + +void WorkbenchComboBox::showPopup() +{ + int rows = count(); + if (rows > 0) { + int height = view()->sizeHintForRow(0); + int maxHeight = QApplication::primaryScreen()->size().height(); + view()->setMinimumHeight(qMin(height * rows, maxHeight/2)); + } + + QComboBox::showPopup(); +} + +void WorkbenchComboBox::refreshList(QList actionList) +{ + clear(); + + ParameterGrp::handle hGrp; + hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches"); + int itemStyleIndex = hGrp->GetInt("WorkbenchSelectorItem", 0); + + for (QAction* action : actionList) { + QIcon icon = action->icon(); + if (icon.isNull() || itemStyleIndex == 2) { + addItem(action->text()); + } + else if (itemStyleIndex == 1) { + addItem(icon, QString::fromLatin1("")); + } + else { + addItem(icon, action->text()); + } + + if (action->isChecked()) { + this->setCurrentIndex(this->count() - 1); + } + } +} + + +WorkbenchTabWidget::WorkbenchTabWidget(WorkbenchGroup* aGroup, QWidget* parent) + : QTabBar(parent) + , wbActionGroup(aGroup) +{ + setToolTip(aGroup->toolTip()); + setStatusTip(aGroup->action()->statusTip()); + setWhatsThis(aGroup->action()->whatsThis()); + + QAction* moreAction = new QAction(this); + menu = new QMenu(this); + moreAction->setMenu(menu); + connect(moreAction, &QAction::triggered, [this]() { + menu->popup(QCursor::pos()); + }); + connect(menu, &QMenu::aboutToHide, this, [this]() { + // if the more tab did not triggered a disabled workbench, make sure we reselect the correct tab. + std::string activeWbName = WorkbenchManager::instance()->activeName(); + for (int i = 0; i < count(); ++i) { + if (wbActionGroup->actions()[i]->objectName().toStdString() == activeWbName) { + setCurrentIndex(i); + break; + } + } + }); + + if (parent->inherits("QToolBar")) { + // set the initial orientation. We cannot do updateLayoutAndTabOrientation(false); + // because on init the toolbar area is always TopToolBarArea. + ParameterGrp::handle hGrp; + hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches"); + std::string orientation = hGrp->GetASCII("TabBarOrientation", "North"); + + this->setShape(orientation == "North" ? QTabBar::RoundedNorth : + orientation == "South" ? QTabBar::RoundedSouth : + orientation == "East" ? QTabBar::RoundedEast : + QTabBar::RoundedWest); + } + + setDocumentMode(true); + setUsesScrollButtons(true); + setDrawBase(true); + setObjectName(QString::fromLatin1("WbTabBar")); + setIconSize(QSize(16, 16)); + + refreshList(aGroup->getEnabledWbActions()); + connect(aGroup, &WorkbenchGroup::workbenchListRefreshed, this, &WorkbenchTabWidget::refreshList); + connect(aGroup->groupAction(), &QActionGroup::triggered, this, [this, aGroup](QAction* action) { + int index = std::min(aGroup->actions().indexOf(action), this->count() - 1); + setCurrentIndex(index); + }); + connect(this, qOverload(&QTabBar::tabBarClicked), aGroup, [aGroup, moreAction](int index) { + if (index < aGroup->getEnabledWbActions().size()) { + aGroup->actions()[index]->trigger(); + } + else { + moreAction->trigger(); + } + }); + + if (parent->inherits("QToolBar")) { + // Connect toolbar orientation changed + QToolBar* tb = qobject_cast(parent); + connect(tb, &QToolBar::topLevelChanged, this, &WorkbenchTabWidget::updateLayoutAndTabOrientation); + } +} + +void WorkbenchTabWidget::refreshList(QList actionList) +{ + // tabs->clear() (QTabBar has no clear) + for (int i = count() - 1; i >= 0; --i) { + removeTab(i); + } + + ParameterGrp::handle hGrp; + hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches"); + int itemStyleIndex = hGrp->GetInt("WorkbenchSelectorItem", 0); + + for (QAction* action : actionList) { + QIcon icon = action->icon(); + if (icon.isNull() || itemStyleIndex == 2) { + addTab(action->text()); + } + else if (itemStyleIndex == 1) { + addTab(icon, QString::fromLatin1("")); + } + else { + addTab(icon, action->text()); + } + + if (action->isChecked()) { + setCurrentIndex(count() - 1); + } + } + + QIcon icon = Gui::BitmapFactory().iconFromTheme("list-add"); + if (itemStyleIndex == 2) { + addTab(tr("More")); + } + else if (itemStyleIndex == 1) { + addTab(icon, QString::fromLatin1("")); + } + else { + addTab(icon, tr("More")); + } + + buildPrefMenu(); +} + +void WorkbenchTabWidget::updateLayoutAndTabOrientation(bool floating) +{ + if (!parentWidget()->inherits("QToolBar") || floating) { + return; + } + + ParameterGrp::handle hGrp = App::GetApplication() + .GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches"); + + QToolBar* tb = qobject_cast(parentWidget()); + Qt::ToolBarArea area = getMainWindow()->toolBarArea(tb); + + if (area == Qt::LeftToolBarArea || area == Qt::RightToolBarArea) { + setShape(area == Qt::LeftToolBarArea ? QTabBar::RoundedWest : QTabBar::RoundedEast); + hGrp->SetASCII("TabBarOrientation", area == Qt::LeftToolBarArea ? "West" : "East"); + } + else { + setShape(area == Qt::TopToolBarArea ? QTabBar::RoundedNorth : QTabBar::RoundedSouth); + hGrp->SetASCII("TabBarOrientation", area == Qt::TopToolBarArea ? "North" : "South"); + } +} + +void WorkbenchTabWidget::buildPrefMenu() +{ + menu->clear(); + + // Add disabled workbenches, sorted alphabetically. + menu->addActions(wbActionGroup->getDisabledWbActions()); + + menu->addSeparator(); + + QAction* preferencesAction = menu->addAction(tr("Preferences")); + connect(preferencesAction, &QAction::triggered, this, [this]() { + Gui::Dialog::DlgPreferencesImp cDlg(getMainWindow()); + cDlg.activateGroupPage(QString::fromUtf8("Workbenches"), 0); + cDlg.exec(); + }); +} + +#include "moc_WorkbenchSelector.cpp" diff --git a/src/Gui/WorkbenchSelector.h b/src/Gui/WorkbenchSelector.h new file mode 100644 index 0000000000..f5bd696955 --- /dev/null +++ b/src/Gui/WorkbenchSelector.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (c) 2024 Pierre-Louis Boyer * + * * + * 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_WORKBENCHSELECTOR_H +#define GUI_WORKBENCHSELECTOR_H + +#include +#include +#include +#include + +namespace Gui +{ +class WorkbenchGroup; + +class GuiExport WorkbenchComboBox : public QComboBox +{ + Q_OBJECT + +public: + explicit WorkbenchComboBox(WorkbenchGroup* aGroup, QWidget* parent = nullptr); + void showPopup() override; + +public Q_SLOTS: + void refreshList(QList); + +private: + Q_DISABLE_COPY(WorkbenchComboBox) +}; + + +class GuiExport WorkbenchTabWidget : public QTabBar +{ + Q_OBJECT + +public: + explicit WorkbenchTabWidget(WorkbenchGroup* aGroup, QWidget* parent = nullptr); + + void updateLayoutAndTabOrientation(bool); + void buildPrefMenu(); + +public Q_SLOTS: + void refreshList(QList); + +private: + WorkbenchGroup* wbActionGroup; + QMenu* menu; +}; + + + +} // namespace Gui + +#endif // GUI_WORKBENCHSELECTOR_H