From 75fe4f60f665ae5c2a9e7c2f0fd0f25dc297496b Mon Sep 17 00:00:00 2001 From: Kacper Donat Date: Sun, 9 Jun 2024 18:00:03 +0200 Subject: [PATCH] Gui: Split declaration and definition of ToolBarAreaWidget In order to support targeting ToolBarAreaWidgets via the QSS we need to make it a proper QObject using Q_OBJECT macro, which must be placed in header files. --- src/Gui/ToolBarManager.cpp | 236 ++++++++++++++----------------------- src/Gui/ToolBarManager.h | 70 ++++++++++- 2 files changed, 159 insertions(+), 147 deletions(-) diff --git a/src/Gui/ToolBarManager.cpp b/src/Gui/ToolBarManager.cpp index 04876e39b3..b52197c307 100644 --- a/src/Gui/ToolBarManager.cpp +++ b/src/Gui/ToolBarManager.cpp @@ -164,165 +164,111 @@ QList ToolBarItem::getItems() const } // ----------------------------------------------------------- - -namespace Gui { - -class ToolBarAreaWidget : public QWidget +ToolBarAreaWidget::ToolBarAreaWidget(QWidget* parent, + ToolBarArea area, + const ParameterGrp::handle& hParam, + boost::signals2::scoped_connection& conn, + QTimer* timer) + : QWidget(parent) + , _sizingTimer(timer) + , _hParam(hParam) + , _conn(conn) + , _area(area) { - using inherited = QWidget; + _layout = new QHBoxLayout(this); + _layout->setContentsMargins(QMargins()); +} -public: - ToolBarAreaWidget(QWidget *parent, - ToolBarArea area, - const ParameterGrp::handle& hParam, - boost::signals2::scoped_connection &conn, - QTimer *timer = nullptr) - : QWidget(parent) - , _sizingTimer(timer) - , _hParam(hParam) - , _conn(conn) - , _area(area) - { - _layout = new QHBoxLayout(this); - _layout->setContentsMargins(QMargins()); +void ToolBarAreaWidget::addWidget(QWidget* widget) +{ + // if widget already exist don't do anything + if (_layout->indexOf(widget) >= 0) { + return; } - void addWidget(QWidget *widget) - { - // if widget already exist don't do anything - if (_layout->indexOf(widget) >= 0) { - return; - } + _layout->addWidget(widget); + adjustParent(); - _layout->addWidget(widget); - adjustParent(); + QString name = widget->objectName(); - QString name = widget->objectName(); - - if (!name.isEmpty()) { - Base::ConnectionBlocker block(_conn); - _hParam->SetInt(widget->objectName().toUtf8().constData(), _layout->count() - 1); - } - } - - void insertWidget(int index, QWidget *widget) - { - int currentIndex = _layout->indexOf(widget); - - // we are inserting widget at the same place, this is no-op - if (currentIndex == index) { - return; - } - - // widget already exists in the area, we need to first remove it and then recreate - if (currentIndex > 0) { - _layout->removeWidget(widget); - } - - _layout->insertWidget(index, widget); - - adjustParent(); - saveState(); - } - - void adjustParent() - { - if (_sizingTimer) { - _sizingTimer->start(10); - } - } - - void removeWidget(QWidget *widget) - { - _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; - } - - int count() const - { - return _layout->count(); - } - - int indexOf(QWidget *widget) const - { - return _layout->indexOf(widget); - } - - ToolBarArea area() const - { - return _area; - } - - template - void foreachToolBar(FuncT &&func) - { - for (int i = 0, c = _layout->count(); i < c; ++i) { - auto toolbar = qobject_cast(widgetAt(i)); - - if (!toolbar || toolbar->objectName().isEmpty() - || toolbar->objectName().startsWith(QStringLiteral("*"))) { - continue; - } - - func(toolbar, i, this); - } - } - - void saveState() - { + if (!name.isEmpty()) { Base::ConnectionBlocker block(_conn); + _hParam->SetInt(widget->objectName().toUtf8().constData(), _layout->count() - 1); + } +} - for (auto &v : _hParam->GetIntMap()) { - _hParam->RemoveInt(v.first.c_str()); - } +void ToolBarAreaWidget::insertWidget(int index, QWidget* widget) +{ + int currentIndex = _layout->indexOf(widget); - foreachToolBar([this](QToolBar *toolbar, int idx, ToolBarAreaWidget*) { - _hParam->SetInt(toolbar->objectName().toUtf8().constData(), idx); - }); + // we are inserting widget at the same place, this is no-op + if (currentIndex == index) { + return; } - void restoreState(const std::map &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(QString::fromUtf8(name.c_str())); - - if (widget) { - widget->setVisible(visible); - } - } + // widget already exists in the area, we need to first remove it and then recreate + if (currentIndex > 0) { + _layout->removeWidget(widget); } -private: - QHBoxLayout *_layout; - QPointer _sizingTimer; - ParameterGrp::handle _hParam; - boost::signals2::scoped_connection &_conn; - ToolBarArea _area; -}; + _layout->insertWidget(index, widget); + + adjustParent(); + saveState(); +} + +void ToolBarAreaWidget::removeWidget(QWidget* widget) +{ + _layout->removeWidget(widget); + + QString name = widget->objectName(); + if (!name.isEmpty()) { + Base::ConnectionBlocker block(_conn); + _hParam->RemoveInt(name.toUtf8().constData()); + } + + adjustParent(); +} + +void ToolBarAreaWidget::adjustParent() +{ + if (_sizingTimer) { + _sizingTimer->start(10); + } +} + +void ToolBarAreaWidget::saveState() +{ + Base::ConnectionBlocker block(_conn); + + for (auto &v : _hParam->GetIntMap()) { + _hParam->RemoveInt(v.first.c_str()); + } + + foreachToolBar([this](QToolBar *toolbar, int idx, ToolBarAreaWidget*) { + _hParam->SetInt(toolbar->objectName().toUtf8().constData(), idx); + }); +} + +void ToolBarAreaWidget::restoreState(const std::map& 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(QString::fromUtf8(name.c_str())); + + if (widget) { + widget->setVisible(visible); + } + } +} -} // namespace Gui // ----------------------------------------------------------- diff --git a/src/Gui/ToolBarManager.h b/src/Gui/ToolBarManager.h index 5f26693911..5f7e34679a 100644 --- a/src/Gui/ToolBarManager.h +++ b/src/Gui/ToolBarManager.h @@ -29,6 +29,9 @@ #include #include +#include +#include +#include #include #include @@ -37,7 +40,6 @@ class QAction; class QLayout; class QMenu; class QMouseEvent; -class QToolBar; namespace Gui { @@ -54,7 +56,71 @@ enum class ToolBarArea { StatusBarToolBarArea, }; -class ToolBarAreaWidget; +class ToolBarAreaWidget : public QWidget +{ + Q_OBJECT + using inherited = QWidget; + +public: + ToolBarAreaWidget(QWidget *parent, + ToolBarArea area, + const ParameterGrp::handle& hParam, + boost::signals2::scoped_connection &conn, + QTimer *timer = nullptr); + + void addWidget(QWidget *widget); + void insertWidget(int index, QWidget *widget); + void removeWidget(QWidget *widget); + + void 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 *widget) const + { + return _layout->indexOf(widget); + } + + ToolBarArea area() const + { + return _area; + } + + template + void foreachToolBar(FuncT &&func) + { + for (int i = 0, count = _layout->count(); i < count; ++i) { + auto toolbar = qobject_cast(widgetAt(i)); + + if (!toolbar || toolbar->objectName().isEmpty() + || toolbar->objectName().startsWith(QStringLiteral("*"))) { + continue; + } + + func(toolbar, i, this); + } + } + + void saveState(); + void restoreState(const std::map &toolbars); + +private: + QHBoxLayout *_layout; + QPointer _sizingTimer; + ParameterGrp::handle _hParam; + boost::signals2::scoped_connection &_conn; + ToolBarArea _area; +}; class GuiExport ToolBarItem {