* 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>
266 lines
9.3 KiB
C++
266 lines
9.3 KiB
C++
/***************************************************************************
|
|
* Copyright (c) 2024 Pierre-Louis Boyer <development[at]Ondsel.com> *
|
|
* *
|
|
* 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 <QAbstractItemView>
|
|
# include <QActionGroup>
|
|
# include <QApplication>
|
|
# include <QMenuBar>
|
|
# include <QScreen>
|
|
# include <QStatusBar>
|
|
# include <QToolBar>
|
|
#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<int>(&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<QAction*> 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 + 1);
|
|
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 = aGroup->actions().indexOf(action) + 1;
|
|
if (index > this->count() - 1) {
|
|
index = 0;
|
|
}
|
|
setCurrentIndex(index);
|
|
});
|
|
connect(this, qOverload<int>(&QTabBar::tabBarClicked), aGroup, [aGroup, moreAction](int index) {
|
|
if(index == 0) {
|
|
moreAction->trigger();
|
|
}
|
|
else if (index <= aGroup->getEnabledWbActions().size()) {
|
|
aGroup->actions()[index - 1]->trigger();
|
|
}
|
|
});
|
|
|
|
if (parent->inherits("QToolBar")) {
|
|
// Connect toolbar orientation changed
|
|
QToolBar* tb = qobject_cast<QToolBar*>(parent);
|
|
connect(tb, &QToolBar::topLevelChanged, this, &WorkbenchTabWidget::updateLayoutAndTabOrientation);
|
|
}
|
|
}
|
|
|
|
void WorkbenchTabWidget::refreshList(QList<QAction*> 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);
|
|
|
|
QIcon icon = Gui::BitmapFactory().iconFromTheme("list-add");
|
|
if (itemStyleIndex == 2) {
|
|
addTab(QString::fromLatin1("+"));
|
|
}
|
|
else {
|
|
addTab(icon, QString::fromLatin1(""));
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
buildPrefMenu();
|
|
}
|
|
|
|
void WorkbenchTabWidget::updateLayoutAndTabOrientation(bool floating)
|
|
{
|
|
auto parent = parentWidget();
|
|
if (!parent || !parent->inherits("QToolBar")) {
|
|
return;
|
|
}
|
|
|
|
ParameterGrp::handle hGrp = App::GetApplication()
|
|
.GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches");
|
|
|
|
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);
|
|
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, []() {
|
|
Gui::Dialog::DlgPreferencesImp cDlg(getMainWindow());
|
|
cDlg.activateGroupPage(QString::fromUtf8("Workbenches"), 0);
|
|
cDlg.exec();
|
|
});
|
|
}
|
|
|
|
#include "moc_WorkbenchSelector.cpp"
|