Merge pull request #13721 from kadet1090/more-at-the-end
Gui: Move more button to the end WB TabBar
This commit is contained in:
@@ -627,20 +627,29 @@ WorkbenchGroup::WorkbenchGroup ( Command* pcCmd, QObject * parent )
|
||||
this, &WorkbenchGroup::onWorkbenchActivated);
|
||||
}
|
||||
|
||||
QAction* WorkbenchGroup::getOrCreateAction(const QString& wbName) {
|
||||
if (!actionByWorkbenchName.contains(wbName)) {
|
||||
actionByWorkbenchName[wbName] = new QAction;
|
||||
}
|
||||
|
||||
return actionByWorkbenchName[wbName];
|
||||
}
|
||||
|
||||
void WorkbenchGroup::addTo(QWidget *widget)
|
||||
{
|
||||
if (widget->inherits("QToolBar")) {
|
||||
ParameterGrp::handle hGrp;
|
||||
hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches");
|
||||
QWidget* wbSel;
|
||||
|
||||
QWidget* workbenchSelectorWidget;
|
||||
if (hGrp->GetInt("WorkbenchSelectorType", 0) == 0) {
|
||||
wbSel = new WorkbenchComboBox(this, widget);
|
||||
workbenchSelectorWidget = new WorkbenchComboBox(this, widget);
|
||||
}
|
||||
else {
|
||||
wbSel = new WorkbenchTabWidget(this, widget);
|
||||
workbenchSelectorWidget = new WorkbenchTabWidget(this, widget);
|
||||
}
|
||||
|
||||
static_cast<QToolBar*>(widget)->addWidget(wbSel);
|
||||
static_cast<QToolBar*>(widget)->addWidget(workbenchSelectorWidget);
|
||||
}
|
||||
else if (widget->inherits("QMenu")) {
|
||||
auto menu = qobject_cast<QMenu*>(widget);
|
||||
@@ -656,13 +665,13 @@ void WorkbenchGroup::addTo(QWidget *widget)
|
||||
|
||||
void WorkbenchGroup::refreshWorkbenchList()
|
||||
{
|
||||
QStringList enabled_wbs_list = DlgSettingsWorkbenchesImp::getEnabledWorkbenches();
|
||||
QStringList enabledWbNames = DlgSettingsWorkbenchesImp::getEnabledWorkbenches();
|
||||
|
||||
// Clear the actions.
|
||||
for (QAction* action : actions()) {
|
||||
groupAction()->removeAction(action);
|
||||
delete action;
|
||||
}
|
||||
|
||||
enabledWbsActions.clear();
|
||||
disabledWbsActions.clear();
|
||||
|
||||
@@ -670,12 +679,16 @@ void WorkbenchGroup::refreshWorkbenchList()
|
||||
|
||||
// Create action list of enabled wb
|
||||
int index = 0;
|
||||
for (const auto& wbName : enabled_wbs_list) {
|
||||
for (const auto& wbName : enabledWbNames) {
|
||||
QString name = Application::Instance->workbenchMenuText(wbName);
|
||||
QPixmap px = Application::Instance->workbenchIcon(wbName);
|
||||
QString tip = Application::Instance->workbenchToolTip(wbName);
|
||||
|
||||
QAction* action = groupAction()->addAction(name);
|
||||
QAction* action = getOrCreateAction(wbName);
|
||||
|
||||
groupAction()->addAction(action);
|
||||
|
||||
action->setText(name);
|
||||
action->setCheckable(true);
|
||||
action->setData(QVariant(index)); // set the index
|
||||
action->setObjectName(wbName);
|
||||
@@ -693,13 +706,17 @@ void WorkbenchGroup::refreshWorkbenchList()
|
||||
}
|
||||
|
||||
// Also create action list of disabled wbs
|
||||
QStringList disabled_wbs_list = DlgSettingsWorkbenchesImp::getDisabledWorkbenches();
|
||||
for (const auto& wbName : disabled_wbs_list) {
|
||||
QStringList disabledWbNames = DlgSettingsWorkbenchesImp::getDisabledWorkbenches();
|
||||
for (const auto& wbName : disabledWbNames) {
|
||||
QString name = Application::Instance->workbenchMenuText(wbName);
|
||||
QPixmap px = Application::Instance->workbenchIcon(wbName);
|
||||
QString tip = Application::Instance->workbenchToolTip(wbName);
|
||||
|
||||
QAction* action = groupAction()->addAction(name);
|
||||
QAction* action = getOrCreateAction(wbName);
|
||||
|
||||
groupAction()->addAction(action);
|
||||
|
||||
action->setText(name);
|
||||
action->setCheckable(true);
|
||||
action->setData(QVariant(index)); // set the index
|
||||
action->setObjectName(wbName);
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <QAction>
|
||||
#include <QComboBox>
|
||||
#include <QKeySequence>
|
||||
#include <QMap>
|
||||
#include <FCGlobal.h>
|
||||
|
||||
namespace Gui
|
||||
@@ -188,13 +189,16 @@ class GuiExport WorkbenchGroup : public ActionGroup
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QAction* getOrCreateAction(const QString& wbName);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates an action for the command \a pcCmd to load the workbench \a name
|
||||
* when it gets activated.
|
||||
*/
|
||||
WorkbenchGroup (Command* pcCmd, QObject * parent);
|
||||
void addTo (QWidget * widget) override;
|
||||
WorkbenchGroup(Command* pcCmd, QObject* parent);
|
||||
|
||||
void addTo(QWidget * widget) override;
|
||||
void refreshWorkbenchList();
|
||||
|
||||
void slotActivateWorkbench(const char*);
|
||||
@@ -212,6 +216,8 @@ private:
|
||||
QList<QAction*> enabledWbsActions;
|
||||
QList<QAction*> disabledWbsActions;
|
||||
|
||||
QMap<QString, QAction*> actionByWorkbenchName;
|
||||
|
||||
Q_DISABLE_COPY(WorkbenchGroup)
|
||||
};
|
||||
|
||||
|
||||
@@ -167,11 +167,13 @@ QList<ToolBarItem*> ToolBarItem::getItems() const
|
||||
|
||||
namespace Gui {
|
||||
|
||||
class ToolBarArea : public QWidget
|
||||
class ToolBarAreaWidget : public QWidget
|
||||
{
|
||||
using inherited = QWidget;
|
||||
|
||||
public:
|
||||
ToolBarArea(QWidget *parent,
|
||||
ToolBarAreaWidget(QWidget *parent,
|
||||
ToolBarArea area,
|
||||
const ParameterGrp::handle& hParam,
|
||||
boost::signals2::scoped_connection &conn,
|
||||
QTimer *timer = nullptr)
|
||||
@@ -179,34 +181,45 @@ public:
|
||||
, _sizingTimer(timer)
|
||||
, _hParam(hParam)
|
||||
, _conn(conn)
|
||||
, _area(area)
|
||||
{
|
||||
_layout = new QHBoxLayout(this);
|
||||
_layout->setContentsMargins(QMargins());
|
||||
}
|
||||
|
||||
void addWidget(QWidget *w)
|
||||
void addWidget(QWidget *widget)
|
||||
{
|
||||
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);
|
||||
}
|
||||
if (_layout->indexOf(widget) > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
_layout->addWidget(widget);
|
||||
adjustParent();
|
||||
|
||||
QString name = widget->objectName();
|
||||
|
||||
if (!name.isEmpty()) {
|
||||
Base::ConnectionBlocker block(_conn);
|
||||
_hParam->SetInt(widget->objectName().toUtf8().constData(), _layout->count() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void insertWidget(int idx, QWidget *w)
|
||||
void insertWidget(int index, QWidget *widget)
|
||||
{
|
||||
int index = _layout->indexOf(w);
|
||||
if (index == idx) {
|
||||
int currentIndex = _layout->indexOf(widget);
|
||||
|
||||
// we are inserting widget at the same place, this is no-op
|
||||
if (currentIndex == index) {
|
||||
return;
|
||||
}
|
||||
if (index > 0) {
|
||||
_layout->removeWidget(w);
|
||||
|
||||
// widget already exists in the area, we need to first remove it and then recreate
|
||||
if (currentIndex > 0) {
|
||||
_layout->removeWidget(widget);
|
||||
}
|
||||
_layout->insertWidget(idx, w);
|
||||
|
||||
_layout->insertWidget(index, widget);
|
||||
|
||||
adjustParent();
|
||||
saveState();
|
||||
}
|
||||
@@ -218,20 +231,23 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void removeWidget(QWidget *w)
|
||||
void removeWidget(QWidget *widget)
|
||||
{
|
||||
_layout->removeWidget(w);
|
||||
QString name = w->objectName();
|
||||
_layout->removeWidget(widget);
|
||||
|
||||
QString name = widget->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;
|
||||
}
|
||||
|
||||
@@ -240,9 +256,14 @@ public:
|
||||
return _layout->count();
|
||||
}
|
||||
|
||||
int indexOf(QWidget *w) const
|
||||
int indexOf(QWidget *widget) const
|
||||
{
|
||||
return _layout->indexOf(w);
|
||||
return _layout->indexOf(widget);
|
||||
}
|
||||
|
||||
ToolBarArea area() const
|
||||
{
|
||||
return _area;
|
||||
}
|
||||
|
||||
template<class FuncT>
|
||||
@@ -250,10 +271,12 @@ public:
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -261,10 +284,12 @@ public:
|
||||
void saveState()
|
||||
{
|
||||
Base::ConnectionBlocker block(_conn);
|
||||
|
||||
for (auto &v : _hParam->GetIntMap()) {
|
||||
_hParam->RemoveInt(v.first.c_str());
|
||||
}
|
||||
foreachToolBar([this](QToolBar *toolbar, int idx, ToolBarArea*) {
|
||||
|
||||
foreachToolBar([this](QToolBar *toolbar, int idx, ToolBarAreaWidget*) {
|
||||
_hParam->SetInt(toolbar->objectName().toUtf8().constData(), idx);
|
||||
});
|
||||
}
|
||||
@@ -281,17 +306,19 @@ public:
|
||||
|
||||
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;
|
||||
ToolBarArea _area;
|
||||
};
|
||||
|
||||
} // namespace Gui
|
||||
@@ -343,10 +370,10 @@ void ToolBarManager::setupStatusBar()
|
||||
{
|
||||
if (auto sb = getMainWindow()->statusBar()) {
|
||||
sb->installEventFilter(this);
|
||||
statusBarArea = new ToolBarArea(sb, hStatusBar, connParam);
|
||||
statusBarArea->setObjectName(QStringLiteral("StatusBarArea"));
|
||||
sb->insertPermanentWidget(2, statusBarArea);
|
||||
statusBarArea->show();
|
||||
statusBarAreaWidget = new ToolBarAreaWidget(sb, ToolBarArea::StatusBarToolBarArea, hStatusBar, connParam);
|
||||
statusBarAreaWidget->setObjectName(QStringLiteral("StatusBarArea"));
|
||||
sb->insertPermanentWidget(2, statusBarAreaWidget);
|
||||
statusBarAreaWidget->show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,14 +381,14 @@ void ToolBarManager::setupMenuBar()
|
||||
{
|
||||
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();
|
||||
menuBarLeftAreaWidget = new ToolBarAreaWidget(mb, ToolBarArea::LeftMenuToolBarArea, hMenuBarLeft, connParam, &menuBarTimer);
|
||||
menuBarLeftAreaWidget->setObjectName(QStringLiteral("MenuBarLeftArea"));
|
||||
mb->setCornerWidget(menuBarLeftAreaWidget, Qt::TopLeftCorner);
|
||||
menuBarLeftAreaWidget->show();
|
||||
menuBarRightAreaWidget = new ToolBarAreaWidget(mb, ToolBarArea::RightMenuToolBarArea, hMenuBarRight, connParam, &menuBarTimer);
|
||||
menuBarRightAreaWidget->setObjectName(QStringLiteral("MenuBarRightArea"));
|
||||
mb->setCornerWidget(menuBarRightAreaWidget, Qt::TopRightCorner);
|
||||
menuBarRightAreaWidget->show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,6 +467,38 @@ void ToolBarManager::setupMenuBarTimer()
|
||||
});
|
||||
}
|
||||
|
||||
ToolBarArea ToolBarManager::toolBarArea(QWidget *widget) const
|
||||
{
|
||||
if (auto toolBar = qobject_cast<QToolBar*>(widget)) {
|
||||
if (toolBar->isFloating()) {
|
||||
return ToolBarArea::NoToolBarArea;
|
||||
}
|
||||
|
||||
auto qtToolBarArea = getMainWindow()->toolBarArea(toolBar);
|
||||
switch (qtToolBarArea) {
|
||||
case Qt::LeftToolBarArea:
|
||||
return ToolBarArea::LeftToolBarArea;
|
||||
case Qt::RightToolBarArea:
|
||||
return ToolBarArea::RightToolBarArea;
|
||||
case Qt::TopToolBarArea:
|
||||
return ToolBarArea::TopToolBarArea;
|
||||
case Qt::BottomToolBarArea:
|
||||
return ToolBarArea::BottomToolBarArea;
|
||||
default:
|
||||
// no-op
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &areaWidget : { statusBarAreaWidget, menuBarLeftAreaWidget, menuBarRightAreaWidget }) {
|
||||
if (areaWidget->indexOf(widget) >= 0) {
|
||||
return areaWidget->area();
|
||||
}
|
||||
}
|
||||
|
||||
return ToolBarArea::NoToolBarArea;
|
||||
}
|
||||
|
||||
namespace {
|
||||
QPointer<QWidget> createActionWidget()
|
||||
{
|
||||
@@ -470,7 +529,7 @@ int ToolBarManager::toolBarIconSize(QWidget *widget) const
|
||||
{
|
||||
int s = _toolBarIconSize;
|
||||
if (widget) {
|
||||
if (widget->parentWidget() == statusBarArea) {
|
||||
if (widget->parentWidget() == statusBarAreaWidget) {
|
||||
if (_statusBarIconSize > 0) {
|
||||
s = _statusBarIconSize;
|
||||
}
|
||||
@@ -478,8 +537,8 @@ int ToolBarManager::toolBarIconSize(QWidget *widget) const
|
||||
s *= 0.6;
|
||||
}
|
||||
}
|
||||
else if (widget->parentWidget() == menuBarLeftArea
|
||||
|| widget->parentWidget() == menuBarRightArea) {
|
||||
else if (widget->parentWidget() == menuBarLeftAreaWidget
|
||||
|| widget->parentWidget() == menuBarRightAreaWidget) {
|
||||
if (_menuBarIconSize > 0) {
|
||||
s = _menuBarIconSize;
|
||||
}
|
||||
@@ -508,11 +567,11 @@ void ToolBarManager::setToolBarIconSize(QToolBar *toolbar)
|
||||
{
|
||||
int s = toolBarIconSize(toolbar);
|
||||
toolbar->setIconSize(QSize(s, s));
|
||||
if (toolbar->parentWidget() == menuBarLeftArea) {
|
||||
menuBarLeftArea->adjustParent();
|
||||
if (toolbar->parentWidget() == menuBarLeftAreaWidget) {
|
||||
menuBarLeftAreaWidget->adjustParent();
|
||||
}
|
||||
else if (toolbar->parentWidget() == menuBarRightArea) {
|
||||
menuBarRightArea->adjustParent();
|
||||
else if (toolbar->parentWidget() == menuBarRightAreaWidget) {
|
||||
menuBarRightAreaWidget->adjustParent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -750,9 +809,9 @@ void ToolBarManager::restoreState() const
|
||||
|
||||
setMovable(!areToolBarsLocked());
|
||||
|
||||
statusBarArea->restoreState(sbToolBars);
|
||||
menuBarRightArea->restoreState(mbRightToolBars);
|
||||
menuBarLeftArea->restoreState(mbLeftToolBars);
|
||||
statusBarAreaWidget->restoreState(sbToolBars);
|
||||
menuBarRightAreaWidget->restoreState(mbRightToolBars);
|
||||
menuBarLeftAreaWidget->restoreState(mbLeftToolBars);
|
||||
}
|
||||
|
||||
bool ToolBarManager::addToolBarToArea(QObject *source, QMouseEvent *ev)
|
||||
@@ -776,7 +835,7 @@ bool ToolBarManager::addToolBarToArea(QObject *source, QMouseEvent *ev)
|
||||
}
|
||||
|
||||
static QPointer<OverlayDragFrame> tbPlaceholder;
|
||||
static QPointer<ToolBarArea> lastArea;
|
||||
static QPointer<ToolBarAreaWidget> lastArea;
|
||||
static int tbIndex = -1;
|
||||
if (ev->type() == QEvent::MouseMove) {
|
||||
if (tb->orientation() != Qt::Horizontal
|
||||
@@ -798,11 +857,11 @@ bool ToolBarManager::addToolBarToArea(QObject *source, QMouseEvent *ev)
|
||||
}
|
||||
|
||||
QPoint pos = QCursor::pos();
|
||||
ToolBarArea *area = nullptr;
|
||||
ToolBarAreaWidget *area = nullptr;
|
||||
if (statusBar) {
|
||||
QRect rect(statusBar->mapToGlobal(QPoint(0,0)), statusBar->size());
|
||||
if (rect.contains(pos)) {
|
||||
area = statusBarArea;
|
||||
area = statusBarAreaWidget;
|
||||
}
|
||||
}
|
||||
if (!area) {
|
||||
@@ -812,10 +871,10 @@ bool ToolBarManager::addToolBarToArea(QObject *source, QMouseEvent *ev)
|
||||
QRect rect(menuBar->mapToGlobal(QPoint(0,0)), menuBar->size());
|
||||
if (rect.contains(pos)) {
|
||||
if (pos.x() - rect.left() < menuBar->width()/2) {
|
||||
area = menuBarLeftArea;
|
||||
area = menuBarLeftAreaWidget;
|
||||
}
|
||||
else {
|
||||
area = menuBarRightArea;
|
||||
area = menuBarRightAreaWidget;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -833,11 +892,11 @@ bool ToolBarManager::addToolBarToArea(QObject *source, QMouseEvent *ev)
|
||||
|
||||
int idx = 0;
|
||||
for (int c = area->count(); idx < c ;++idx) {
|
||||
auto w = area->widgetAt(idx);
|
||||
if (!w || w->isHidden()) {
|
||||
auto widget = area->widgetAt(idx);
|
||||
if (!widget || widget->isHidden()) {
|
||||
continue;
|
||||
}
|
||||
int p = w->mapToGlobal(w->rect().center()).x();
|
||||
int p = widget->mapToGlobal(widget->rect().center()).x();
|
||||
if (pos.x() < p) {
|
||||
break;
|
||||
}
|
||||
@@ -886,40 +945,60 @@ bool ToolBarManager::addToolBarToArea(QObject *source, QMouseEvent *ev)
|
||||
return false;
|
||||
}
|
||||
|
||||
void ToolBarManager::populateUndockMenu(QMenu *menu, ToolBarArea *area)
|
||||
void ToolBarManager::populateUndockMenu(QMenu *menu, ToolBarAreaWidget *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 tooltip = QObject::tr("Undock from toolbar area");
|
||||
|
||||
auto addMenuUndockItem = [&](QToolBar *toolbar, int, ToolBarAreaWidget *area) {
|
||||
auto toggleViewAction = toolbar->toggleViewAction();
|
||||
auto undockAction = new QAction(menu);
|
||||
undockAction->setText(action->text());
|
||||
|
||||
undockAction->setText(toggleViewAction->text());
|
||||
undockAction->setToolTip(tooltip);
|
||||
|
||||
menu->addAction(undockAction);
|
||||
QObject::connect(undockAction, &QAction::triggered, [area, toolbar]() {
|
||||
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);
|
||||
auto yOffset = toolbar->height();
|
||||
|
||||
// if widget is on the bottom move it up instead
|
||||
if (area->area() == Gui::ToolBarArea::StatusBarToolBarArea) {
|
||||
yOffset *= -1;
|
||||
}
|
||||
|
||||
{
|
||||
// Block signals caused by manually floating the widget
|
||||
QSignalBlocker blocker(toolbar);
|
||||
|
||||
area->removeWidget(toolbar);
|
||||
getMainWindow()->addToolBar(toolbar);
|
||||
|
||||
// this will make toolbar floating, there is no better way to do that.
|
||||
toolbar->setWindowFlags(Qt::Tool
|
||||
| Qt::FramelessWindowHint
|
||||
| Qt::X11BypassWindowManagerHint);
|
||||
toolbar->move(pos.x(), pos.y() + yOffset);
|
||||
toolbar->adjustSize();
|
||||
toolbar->setVisible(true);
|
||||
}
|
||||
|
||||
// but don't block actual information about widget being floated
|
||||
Q_EMIT toolbar->topLevelChanged(true);
|
||||
});
|
||||
};
|
||||
if (area) {
|
||||
|
||||
if (area) {
|
||||
area->foreachToolBar(addMenuUndockItem);
|
||||
}
|
||||
else {
|
||||
statusBarArea->foreachToolBar(addMenuUndockItem);
|
||||
menuBarLeftArea->foreachToolBar(addMenuUndockItem);
|
||||
menuBarRightArea->foreachToolBar(addMenuUndockItem);
|
||||
statusBarAreaWidget->foreachToolBar(addMenuUndockItem);
|
||||
menuBarLeftAreaWidget->foreachToolBar(addMenuUndockItem);
|
||||
menuBarRightAreaWidget->foreachToolBar(addMenuUndockItem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -928,13 +1007,13 @@ bool ToolBarManager::showContextMenu(QObject *source)
|
||||
QMenu menu;
|
||||
QMenu menuUndock;
|
||||
QLayout* layout = nullptr;
|
||||
ToolBarArea* area = nullptr;
|
||||
ToolBarAreaWidget* area = nullptr;
|
||||
if (getMainWindow()->statusBar() == source) {
|
||||
area = statusBarArea;
|
||||
area = statusBarAreaWidget;
|
||||
layout = findLayoutOfObject(source, area);
|
||||
}
|
||||
else if (getMainWindow()->menuBar() == source) {
|
||||
area = findToolBarArea();
|
||||
area = findToolBarAreaWidget();
|
||||
if (!area) {
|
||||
return false;
|
||||
}
|
||||
@@ -943,7 +1022,7 @@ bool ToolBarManager::showContextMenu(QObject *source)
|
||||
return false;
|
||||
}
|
||||
|
||||
auto addMenuVisibleItem = [&](QToolBar *toolbar, int, ToolBarArea *) {
|
||||
auto addMenuVisibleItem = [&](QToolBar *toolbar, int, ToolBarAreaWidget *) {
|
||||
auto action = toolbar->toggleViewAction();
|
||||
if ((action->isVisible() || toolbar->isVisible()) && action->text().size()) {
|
||||
action->setVisible(true);
|
||||
@@ -979,18 +1058,19 @@ QLayout* ToolBarManager::findLayoutOfObject(QObject* source, QWidget* area) cons
|
||||
return layout;
|
||||
}
|
||||
|
||||
ToolBarArea* ToolBarManager::findToolBarArea() const
|
||||
ToolBarAreaWidget* ToolBarManager::findToolBarAreaWidget() const
|
||||
{
|
||||
ToolBarArea* area = nullptr;
|
||||
ToolBarAreaWidget* area = nullptr;
|
||||
|
||||
QPoint pos = QCursor::pos();
|
||||
QRect rect(menuBarLeftArea->mapToGlobal(QPoint(0,0)), menuBarLeftArea->size());
|
||||
QRect rect(menuBarLeftAreaWidget->mapToGlobal(QPoint(0,0)), menuBarLeftAreaWidget->size());
|
||||
if (rect.contains(pos)) {
|
||||
area = menuBarLeftArea;
|
||||
area = menuBarLeftAreaWidget;
|
||||
}
|
||||
else {
|
||||
rect = QRect(menuBarRightArea->mapToGlobal(QPoint(0,0)), menuBarRightArea->size());
|
||||
rect = QRect(menuBarRightAreaWidget->mapToGlobal(QPoint(0,0)), menuBarRightAreaWidget->size());
|
||||
if (rect.contains(pos)) {
|
||||
area = menuBarRightArea;
|
||||
area = menuBarRightAreaWidget;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1042,7 +1122,7 @@ bool ToolBarManager::eventFilter(QObject *source, QEvent *ev)
|
||||
case QEvent::Hide:
|
||||
if (auto toolbar = qobject_cast<QToolBar*>(source)) {
|
||||
auto parent = toolbar->parentWidget();
|
||||
if (parent == menuBarLeftArea || parent == menuBarRightArea) {
|
||||
if (parent == menuBarLeftAreaWidget || parent == menuBarRightAreaWidget) {
|
||||
menuBarTimer.start(10);
|
||||
}
|
||||
}
|
||||
@@ -1130,9 +1210,9 @@ QList<QToolBar*> ToolBarManager::toolBars() const
|
||||
auto parent = it->parentWidget();
|
||||
if (parent == mw
|
||||
|| parent == mw->statusBar()
|
||||
|| parent == statusBarArea
|
||||
|| parent == menuBarLeftArea
|
||||
|| parent == menuBarRightArea) {
|
||||
|| parent == statusBarAreaWidget
|
||||
|| parent == menuBarLeftAreaWidget
|
||||
|| parent == menuBarRightAreaWidget) {
|
||||
tb.push_back(it);
|
||||
it->installEventFilter(const_cast<ToolBarManager*>(this));
|
||||
}
|
||||
|
||||
@@ -41,7 +41,20 @@ class QToolBar;
|
||||
|
||||
namespace Gui {
|
||||
|
||||
class ToolBarArea;
|
||||
// Qt treats area as Flag so in theory toolbar could be in multiple areas at once.
|
||||
// We don't do that here so simple enum should suffice.
|
||||
enum GuiExport ToolBarArea {
|
||||
NoToolBarArea,
|
||||
LeftToolBarArea,
|
||||
RightToolBarArea,
|
||||
TopToolBarArea,
|
||||
BottomToolBarArea,
|
||||
LeftMenuToolBarArea,
|
||||
RightMenuToolBarArea,
|
||||
StatusBarToolBarArea,
|
||||
};
|
||||
|
||||
class ToolBarAreaWidget;
|
||||
|
||||
class GuiExport ToolBarItem
|
||||
{
|
||||
@@ -123,7 +136,9 @@ public:
|
||||
int toolBarIconSize(QWidget *widget=nullptr) const;
|
||||
void setupToolBarIconSize();
|
||||
|
||||
void populateUndockMenu(QMenu *menu, ToolBarArea *area = nullptr);
|
||||
void populateUndockMenu(QMenu *menu, ToolBarAreaWidget *area = nullptr);
|
||||
|
||||
ToolBarArea toolBarArea(QWidget* toolBar) const;
|
||||
|
||||
protected:
|
||||
void setup(ToolBarItem*, QToolBar*) const;
|
||||
@@ -158,7 +173,7 @@ private:
|
||||
void setupMenuBarTimer();
|
||||
void addToMenu(QLayout* layout, QWidget* area, QMenu* menu);
|
||||
QLayout* findLayoutOfObject(QObject* source, QWidget* area) const;
|
||||
ToolBarArea* findToolBarArea() const;
|
||||
ToolBarAreaWidget* findToolBarAreaWidget() const;
|
||||
|
||||
private:
|
||||
QStringList toolbarNames;
|
||||
@@ -169,9 +184,9 @@ private:
|
||||
QTimer sizeTimer;
|
||||
QTimer resizeTimer;
|
||||
boost::signals2::scoped_connection connParam;
|
||||
ToolBarArea *statusBarArea = nullptr;
|
||||
ToolBarArea *menuBarLeftArea = nullptr;
|
||||
ToolBarArea *menuBarRightArea = nullptr;
|
||||
ToolBarAreaWidget *statusBarAreaWidget = nullptr;
|
||||
ToolBarAreaWidget *menuBarLeftAreaWidget = nullptr;
|
||||
ToolBarAreaWidget *menuBarRightAreaWidget = nullptr;
|
||||
ParameterGrp::handle hGeneral;
|
||||
ParameterGrp::handle hPref;
|
||||
ParameterGrp::handle hStatusBar;
|
||||
|
||||
@@ -31,16 +31,18 @@
|
||||
# include <QScreen>
|
||||
# include <QStatusBar>
|
||||
# include <QToolBar>
|
||||
# include <QLayout>
|
||||
# include <QTimer>
|
||||
#endif
|
||||
|
||||
#include "Base/Tools.h"
|
||||
#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"
|
||||
#include "ToolBarManager.h"
|
||||
|
||||
|
||||
using namespace Gui;
|
||||
@@ -77,17 +79,18 @@ 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);
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches");
|
||||
|
||||
auto itemStyle = static_cast<WorkbenchItemStyle>(hGrp->GetInt("WorkbenchSelectorItem", 0));
|
||||
|
||||
for (QAction* action : actionList) {
|
||||
QIcon icon = action->icon();
|
||||
if (icon.isNull() || itemStyleIndex == 2) {
|
||||
|
||||
if (icon.isNull() || itemStyle == WorkbenchItemStyle::TextOnly) {
|
||||
addItem(action->text());
|
||||
}
|
||||
else if (itemStyleIndex == 1) {
|
||||
addItem(icon, QString::fromLatin1(""));
|
||||
else if (itemStyle == WorkbenchItemStyle::IconOnly) {
|
||||
addItem(icon, {}); // empty string to ensure that only icon is displayed
|
||||
}
|
||||
else {
|
||||
addItem(icon, action->text());
|
||||
@@ -101,156 +104,307 @@ void WorkbenchComboBox::refreshList(QList<QAction*> actionList)
|
||||
|
||||
|
||||
WorkbenchTabWidget::WorkbenchTabWidget(WorkbenchGroup* aGroup, QWidget* parent)
|
||||
: QTabBar(parent)
|
||||
: QWidget(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();
|
||||
}
|
||||
});
|
||||
tabBar = new QTabBar(this);
|
||||
moreButton = new QToolButton(this);
|
||||
layout = new QBoxLayout(QBoxLayout::LeftToRight, this);
|
||||
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->addWidget(tabBar);
|
||||
layout->addWidget(moreButton);
|
||||
layout->setAlignment(moreButton, Qt::AlignCenter);
|
||||
|
||||
setLayout(layout);
|
||||
|
||||
moreButton->setIcon(Gui::BitmapFactory().iconFromTheme("list-add"));
|
||||
moreButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
||||
moreButton->setPopupMode(QToolButton::InstantPopup);
|
||||
moreButton->setMenu(new QMenu(moreButton));
|
||||
moreButton->setObjectName(QString::fromLatin1("WbTabBarMore"));
|
||||
|
||||
if (parent->inherits("QToolBar")) {
|
||||
// Connect toolbar orientation changed
|
||||
QToolBar* tb = qobject_cast<QToolBar*>(parent);
|
||||
connect(tb, &QToolBar::topLevelChanged, this, &WorkbenchTabWidget::updateLayoutAndTabOrientation);
|
||||
// when toolbar is created it is not yet placed in its designated area
|
||||
// therefore we need to wait a bit and then update layout when it is ready
|
||||
// this is prone to race conditions, but Qt does not supply any event that
|
||||
// informs us about toolbar changing its placement.
|
||||
//
|
||||
// previous implementation saved that information to user settings and
|
||||
// restored last layout but this creates issues when default workbench has
|
||||
// different layout than last visited one
|
||||
QTimer::singleShot(500, [this]() { updateLayout(); });
|
||||
}
|
||||
|
||||
tabBar->setDocumentMode(true);
|
||||
tabBar->setUsesScrollButtons(true);
|
||||
tabBar->setDrawBase(true);
|
||||
tabBar->setIconSize(QSize(16, 16));
|
||||
|
||||
updateWorkbenchList();
|
||||
|
||||
connect(aGroup, &WorkbenchGroup::workbenchListRefreshed, this, &WorkbenchTabWidget::updateWorkbenchList);
|
||||
connect(aGroup->groupAction(), &QActionGroup::triggered, this, &WorkbenchTabWidget::handleWorkbenchSelection);
|
||||
connect(tabBar, &QTabBar::currentChanged, this, &WorkbenchTabWidget::handleTabChange);
|
||||
|
||||
if (auto toolBar = qobject_cast<QToolBar*>(parent)) {
|
||||
connect(toolBar, &QToolBar::topLevelChanged, this, &WorkbenchTabWidget::updateLayout);
|
||||
connect(toolBar, &QToolBar::orientationChanged, this, &WorkbenchTabWidget::updateLayout);
|
||||
}
|
||||
}
|
||||
|
||||
void WorkbenchTabWidget::refreshList(QList<QAction*> actionList)
|
||||
inline Qt::LayoutDirection WorkbenchTabWidget::direction() const
|
||||
{
|
||||
// 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();
|
||||
return _direction;
|
||||
}
|
||||
|
||||
void WorkbenchTabWidget::updateLayoutAndTabOrientation(bool floating)
|
||||
void WorkbenchTabWidget::setDirection(Qt::LayoutDirection direction)
|
||||
{
|
||||
auto parent = parentWidget();
|
||||
if (!parent || !parent->inherits("QToolBar")) {
|
||||
_direction = direction;
|
||||
|
||||
Q_EMIT directionChanged(direction);
|
||||
}
|
||||
|
||||
inline int WorkbenchTabWidget::temporaryWorkbenchTabIndex() const
|
||||
{
|
||||
if (direction() == Qt::RightToLeft) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nextTabIndex = tabBar->count();
|
||||
|
||||
return temporaryWorkbenchAction ? nextTabIndex - 1 : nextTabIndex;
|
||||
}
|
||||
|
||||
QAction* WorkbenchTabWidget::workbenchActivateActionByTabIndex(int tabIndex) const
|
||||
{
|
||||
if (temporaryWorkbenchAction && tabIndex == temporaryWorkbenchTabIndex()) {
|
||||
return temporaryWorkbenchAction;
|
||||
}
|
||||
|
||||
auto it = tabIndexToAction.find(tabIndex);
|
||||
|
||||
if (it != tabIndexToAction.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int WorkbenchTabWidget::tabIndexForWorkbenchActivateAction(QAction* workbenchActivateAction) const
|
||||
{
|
||||
if (workbenchActivateAction == temporaryWorkbenchAction) {
|
||||
return temporaryWorkbenchTabIndex();
|
||||
}
|
||||
|
||||
return actionToTabIndex.at(workbenchActivateAction);
|
||||
}
|
||||
|
||||
void WorkbenchTabWidget::updateLayout()
|
||||
{
|
||||
if (!parentWidget()) {
|
||||
setToolBarArea(Gui::ToolBarArea::TopToolBarArea);
|
||||
return;
|
||||
}
|
||||
|
||||
ParameterGrp::handle hGrp = App::GetApplication()
|
||||
.GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches");
|
||||
if (auto toolBar = qobject_cast<QToolBar*>(parentWidget())) {
|
||||
setSizePolicy(toolBar->sizePolicy());
|
||||
tabBar->setSizePolicy(toolBar->sizePolicy());
|
||||
|
||||
Qt::ToolBarArea area;
|
||||
parent = parent->parentWidget();
|
||||
if (toolBar->isFloating()) {
|
||||
setToolBarArea(toolBar->orientation() == Qt::Horizontal ? Gui::ToolBarArea::TopToolBarArea : Gui::ToolBarArea::LeftToolBarArea);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (floating) {
|
||||
area = Qt::TopToolBarArea;
|
||||
auto toolBarArea = Gui::ToolBarManager::getInstance()->toolBarArea(parentWidget());
|
||||
|
||||
setToolBarArea(toolBarArea);
|
||||
|
||||
tabBar->setSelectionBehaviorOnRemove(
|
||||
direction() == Qt::LeftToRight
|
||||
? QTabBar::SelectLeftTab
|
||||
: QTabBar::SelectRightTab
|
||||
);
|
||||
}
|
||||
|
||||
void WorkbenchTabWidget::handleWorkbenchSelection(QAction* selectedWorkbenchAction)
|
||||
{
|
||||
if (wbActionGroup->getDisabledWbActions().contains(selectedWorkbenchAction)) {
|
||||
if (temporaryWorkbenchAction == selectedWorkbenchAction) {
|
||||
return;
|
||||
}
|
||||
|
||||
setTemporaryWorkbenchTab(selectedWorkbenchAction);
|
||||
}
|
||||
else if (parent && parent->parentWidget() == getMainWindow()->statusBar()) {
|
||||
area = Qt::BottomToolBarArea;
|
||||
|
||||
updateLayout();
|
||||
|
||||
tabBar->setCurrentIndex(tabIndexForWorkbenchActivateAction(selectedWorkbenchAction));
|
||||
}
|
||||
|
||||
void WorkbenchTabWidget::setTemporaryWorkbenchTab(QAction* workbenchActivateAction)
|
||||
{
|
||||
auto temporaryTabIndex = temporaryWorkbenchTabIndex();
|
||||
|
||||
if (temporaryWorkbenchAction) {
|
||||
temporaryWorkbenchAction = nullptr;
|
||||
tabBar->removeTab(temporaryTabIndex);
|
||||
}
|
||||
else if (parent && parent->parentWidget() == getMainWindow()->menuBar()) {
|
||||
area = Qt::TopToolBarArea;
|
||||
|
||||
temporaryWorkbenchAction = workbenchActivateAction;
|
||||
|
||||
if (!workbenchActivateAction) {
|
||||
return;
|
||||
}
|
||||
|
||||
addWorkbenchTab(workbenchActivateAction, temporaryTabIndex);
|
||||
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void WorkbenchTabWidget::handleTabChange(int selectedTabIndex)
|
||||
{
|
||||
// Prevents from rapid workbench changes on initialization as this can cause
|
||||
// some serious race conditions.
|
||||
if (isInitializing) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto workbenchActivateAction = workbenchActivateActionByTabIndex(selectedTabIndex)) {
|
||||
workbenchActivateAction->trigger();
|
||||
}
|
||||
|
||||
if (selectedTabIndex != temporaryWorkbenchTabIndex()) {
|
||||
setTemporaryWorkbenchTab(nullptr);
|
||||
}
|
||||
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void WorkbenchTabWidget::updateWorkbenchList()
|
||||
{
|
||||
if (isInitializing) {
|
||||
return;
|
||||
}
|
||||
|
||||
// As clearing and adding tabs can cause changing current tab in QTabBar.
|
||||
// This in turn will cause workbench to change, so we need to prevent
|
||||
// processing of such events until the QTabBar is fully prepared.
|
||||
Base::StateLocker lock(isInitializing);
|
||||
|
||||
actionToTabIndex.clear();
|
||||
tabIndexToAction.clear();
|
||||
|
||||
// tabs->clear() (QTabBar has no clear)
|
||||
for (int i = tabBar->count() - 1; i >= 0; --i) {
|
||||
tabBar->removeTab(i);
|
||||
}
|
||||
|
||||
for (QAction* action : wbActionGroup->getEnabledWbActions()) {
|
||||
addWorkbenchTab(action);
|
||||
}
|
||||
|
||||
if (temporaryWorkbenchAction != nullptr) {
|
||||
setTemporaryWorkbenchTab(temporaryWorkbenchAction);
|
||||
}
|
||||
|
||||
buildPrefMenu();
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
int WorkbenchTabWidget::addWorkbenchTab(QAction* action, int tabIndex)
|
||||
{
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches");
|
||||
auto itemStyle = static_cast<WorkbenchItemStyle>(hGrp->GetInt("WorkbenchSelectorItem", 0));
|
||||
|
||||
// if tabIndex is negative we assume that tab must be placed at the end of tabBar (default behavior)
|
||||
if (tabIndex < 0) {
|
||||
tabIndex = tabBar->count();
|
||||
}
|
||||
|
||||
// for the maps we consider order in which tabs have been added
|
||||
// that's why here we use tabBar->count() instead of tabIndex
|
||||
actionToTabIndex[action] = tabBar->count();
|
||||
tabIndexToAction[tabBar->count()] = action;
|
||||
|
||||
QIcon icon = action->icon();
|
||||
if (icon.isNull() || itemStyle == WorkbenchItemStyle::TextOnly) {
|
||||
tabBar->insertTab(tabIndex, action->text());
|
||||
}
|
||||
else if (itemStyle == IconOnly) {
|
||||
tabBar->insertTab(tabIndex, icon, {}); // empty string to ensure only icon is displayed
|
||||
}
|
||||
else {
|
||||
QToolBar* tb = qobject_cast<QToolBar*>(parentWidget());
|
||||
area = getMainWindow()->toolBarArea(tb);
|
||||
tabBar->insertTab(tabIndex, icon, action->text());
|
||||
}
|
||||
|
||||
if (area == Qt::LeftToolBarArea || area == Qt::RightToolBarArea) {
|
||||
setShape(area == Qt::LeftToolBarArea ? QTabBar::RoundedWest : QTabBar::RoundedEast);
|
||||
hGrp->SetASCII("TabBarOrientation", area == Qt::LeftToolBarArea ? "West" : "East");
|
||||
tabBar->setTabToolTip(tabIndex, action->toolTip());
|
||||
|
||||
if (action->isChecked()) {
|
||||
tabBar->setCurrentIndex(tabIndex);
|
||||
}
|
||||
else {
|
||||
setShape(area == Qt::TopToolBarArea ? QTabBar::RoundedNorth : QTabBar::RoundedSouth);
|
||||
hGrp->SetASCII("TabBarOrientation", area == Qt::TopToolBarArea ? "North" : "South");
|
||||
|
||||
return tabIndex;
|
||||
}
|
||||
|
||||
void WorkbenchTabWidget::setToolBarArea(Gui::ToolBarArea area)
|
||||
{
|
||||
switch (area) {
|
||||
case Gui::ToolBarArea::LeftToolBarArea:
|
||||
case Gui::ToolBarArea::RightToolBarArea: {
|
||||
setDirection(Qt::LeftToRight);
|
||||
layout->setDirection(direction() == Qt::LeftToRight ? QBoxLayout::TopToBottom : QBoxLayout::BottomToTop);
|
||||
tabBar->setShape(area == Gui::ToolBarArea::LeftToolBarArea ? QTabBar::RoundedWest : QTabBar::RoundedEast);
|
||||
break;
|
||||
}
|
||||
|
||||
case Gui::ToolBarArea::TopToolBarArea:
|
||||
case Gui::ToolBarArea::BottomToolBarArea:
|
||||
case Gui::ToolBarArea::LeftMenuToolBarArea:
|
||||
case Gui::ToolBarArea::RightMenuToolBarArea:
|
||||
case Gui::ToolBarArea::StatusBarToolBarArea: {
|
||||
bool isTop =
|
||||
area == Gui::ToolBarArea::TopToolBarArea ||
|
||||
area == Gui::ToolBarArea::LeftMenuToolBarArea ||
|
||||
area == Gui::ToolBarArea::RightMenuToolBarArea;
|
||||
|
||||
bool isRightAligned =
|
||||
area == Gui::ToolBarArea::RightMenuToolBarArea ||
|
||||
area == Gui::ToolBarArea::StatusBarToolBarArea;
|
||||
|
||||
setDirection(isRightAligned ? Qt::RightToLeft : Qt::LeftToRight);
|
||||
layout->setDirection(direction() == Qt::LeftToRight ? QBoxLayout::LeftToRight : QBoxLayout::RightToLeft);
|
||||
tabBar->setShape(isTop ? QTabBar::RoundedNorth : QTabBar::RoundedSouth);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// no-op
|
||||
break;
|
||||
}
|
||||
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void WorkbenchTabWidget::buildPrefMenu()
|
||||
{
|
||||
auto menu = moreButton->menu();
|
||||
|
||||
menu->clear();
|
||||
|
||||
// Add disabled workbenches, sorted alphabetically.
|
||||
menu->addActions(wbActionGroup->getDisabledWbActions());
|
||||
for (auto action : wbActionGroup->getDisabledWbActions()) {
|
||||
if (action->text() == QString::fromLatin1("<none>")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
menu->addAction(action);
|
||||
}
|
||||
|
||||
menu->addSeparator();
|
||||
|
||||
@@ -262,4 +416,11 @@ void WorkbenchTabWidget::buildPrefMenu()
|
||||
});
|
||||
}
|
||||
|
||||
void WorkbenchTabWidget::adjustSize()
|
||||
{
|
||||
QWidget::adjustSize();
|
||||
|
||||
parentWidget()->adjustSize();
|
||||
}
|
||||
|
||||
#include "moc_WorkbenchSelector.cpp"
|
||||
|
||||
@@ -27,12 +27,22 @@
|
||||
#include <QComboBox>
|
||||
#include <QTabBar>
|
||||
#include <QMenu>
|
||||
#include <QToolButton>
|
||||
#include <QLayout>
|
||||
#include <FCGlobal.h>
|
||||
#include <Gui/ToolBarManager.h>
|
||||
#include <map>
|
||||
|
||||
namespace Gui
|
||||
{
|
||||
class WorkbenchGroup;
|
||||
|
||||
enum WorkbenchItemStyle {
|
||||
IconAndText = 0,
|
||||
IconOnly = 1,
|
||||
TextOnly = 2
|
||||
};
|
||||
|
||||
class GuiExport WorkbenchComboBox : public QComboBox
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -49,22 +59,55 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class GuiExport WorkbenchTabWidget : public QTabBar
|
||||
class GuiExport WorkbenchTabWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(Qt::LayoutDirection direction READ direction WRITE setDirection NOTIFY directionChanged)
|
||||
|
||||
int addWorkbenchTab(QAction* workbenchActivateAction, int index = -1);
|
||||
|
||||
void setTemporaryWorkbenchTab(QAction* workbenchActivateAction);
|
||||
int temporaryWorkbenchTabIndex() const;
|
||||
|
||||
QAction* workbenchActivateActionByTabIndex(int tabIndex) const;
|
||||
int tabIndexForWorkbenchActivateAction(QAction* workbenchActivateAction) const;
|
||||
|
||||
public:
|
||||
explicit WorkbenchTabWidget(WorkbenchGroup* aGroup, QWidget* parent = nullptr);
|
||||
|
||||
void updateLayoutAndTabOrientation(bool);
|
||||
void setToolBarArea(Gui::ToolBarArea area);
|
||||
void buildPrefMenu();
|
||||
|
||||
Qt::LayoutDirection direction() const;
|
||||
void setDirection(Qt::LayoutDirection direction);
|
||||
|
||||
void adjustSize();
|
||||
|
||||
public Q_SLOTS:
|
||||
void refreshList(QList<QAction*>);
|
||||
void handleWorkbenchSelection(QAction* selectedWorkbenchAction);
|
||||
void handleTabChange(int selectedTabIndex);
|
||||
|
||||
void updateLayout();
|
||||
void updateWorkbenchList();
|
||||
|
||||
Q_SIGNALS:
|
||||
void directionChanged(const Qt::LayoutDirection&);
|
||||
|
||||
private:
|
||||
bool isInitializing = false;
|
||||
|
||||
WorkbenchGroup* wbActionGroup;
|
||||
QMenu* menu;
|
||||
QToolButton* moreButton;
|
||||
QTabBar* tabBar;
|
||||
QBoxLayout* layout;
|
||||
|
||||
Qt::LayoutDirection _direction = Qt::LeftToRight;
|
||||
|
||||
// this action is used for workbenches that are typically disabled
|
||||
QAction* temporaryWorkbenchAction = nullptr;
|
||||
|
||||
std::map<QAction*, int> actionToTabIndex;
|
||||
std::map<int, QAction*> tabIndexToAction;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user