diff --git a/sublime/idealbuttonbarwidget.h b/sublime/idealbuttonbarwidget.h --- a/sublime/idealbuttonbarwidget.h +++ b/sublime/idealbuttonbarwidget.h @@ -47,6 +47,8 @@ QAction* addWidget(IdealDockWidget *widget, Area* area, View *view); + + void addAction(QAction *action); void removeAction(QAction* action); Qt::Orientation orientation() const; @@ -64,21 +66,28 @@ void saveShowState(); bool lastShowState(); + void loadOrderSettings(); + void saveOrderSettings(); + private Q_SLOTS: void showWidget(bool checked); void buttonPressed(bool state); signals: void emptyChanged(); -protected: - void actionEvent(QActionEvent *event) override; - private: + void applyOrderToLayout(); + void takeOrderFromLayout(); + + IdealToolButton* button(const QString& id); + QString id(const IdealToolButton* button); + Qt::DockWidgetArea _area; IdealController *_controller; QWidget *_corner; bool _showState; + QStringList _buttonsOrder; }; } diff --git a/sublime/idealbuttonbarwidget.cpp b/sublime/idealbuttonbarwidget.cpp --- a/sublime/idealbuttonbarwidget.cpp +++ b/sublime/idealbuttonbarwidget.cpp @@ -71,6 +71,10 @@ refreshText(); } + QString id() { + return m_dock->view()->document()->documentSpecifier(); + } + private: bool eventFilter(QObject * watched, QEvent * event) override { @@ -134,26 +138,69 @@ dock->setView(view); dock->setDockWidgetArea(_area); - bool wasEmpty = actions().isEmpty(); - auto action = new ToolViewAction(dock, this); addAction(action); - if(wasEmpty) - emit emptyChanged(); return action; } QWidget* IdealButtonBarWidget::corner() { return _corner; } -void IdealButtonBarWidget::removeAction(QAction * widgetAction) +void IdealButtonBarWidget::addAction(QAction* qaction) +{ + QWidget::addAction(qaction); + + auto action = dynamic_cast(qaction); + if (!action || action->button()) + return; + + bool wasEmpty = isEmpty(); + + IdealToolButton *button = new IdealToolButton(_area); + //apol: here we set the usual width of a button for the vertical toolbars as the minimumWidth + //this is done because otherwise when we remove all the buttons and re-add new ones we get all + //the screen flickering. This is solved by not defaulting to a smaller width when it's empty + int w = button->sizeHint().width(); + if (orientation() == Qt::Vertical && w > minimumWidth()) + setMinimumWidth(w); + + action->setButton(button); + button->setDefaultAction(action); + + Q_ASSERT(action->dockWidget()); + + connect(action, &QAction::toggled, this, static_cast(&IdealButtonBarWidget::showWidget)); + connect(button, &IdealToolButton::clicked, this, &IdealButtonBarWidget::buttonPressed); + connect(button, &IdealToolButton::customContextMenuRequested, + action->dockWidget(), &IdealDockWidget::contextMenuRequested); + + QString buttonId = id(button); + if (!_buttonsOrder.contains(buttonId)) { + if (_area == Qt::BottomDockWidgetArea) + _buttonsOrder.push_front(buttonId); + else + _buttonsOrder.push_back(buttonId); + } + applyOrderToLayout(); + + if (wasEmpty) { + emit emptyChanged(); + } +} + +void IdealButtonBarWidget::removeAction(QAction* widgetAction) { + QWidget::removeAction(widgetAction); + auto action = dynamic_cast(widgetAction); delete action->button(); delete action; + + if(layout()->isEmpty()) + emit emptyChanged(); } bool IdealButtonBarWidget::isEmpty() @@ -177,6 +224,66 @@ return _showState; } +QString IdealButtonBarWidget::id(const IdealToolButton* button) +{ + foreach (QAction* a, actions()) { + auto tva = dynamic_cast(a); + if (tva && tva->button() == button) + return tva->id(); + } + + return QString(); +} + +IdealToolButton* Sublime::IdealButtonBarWidget::button(const QString& id) +{ + foreach (QAction* a, actions()) { + auto tva = dynamic_cast(a); + if (tva && tva->id() == id) + return tva->button(); + } + + return nullptr; +} + +void IdealButtonBarWidget::loadOrderSettings() +{ + KConfigGroup config = KSharedConfig::openConfig()->group("UI"); + _buttonsOrder = config.readEntry(QStringLiteral("(%1) Tool Views Order").arg(_area), QStringList()); + + applyOrderToLayout(); +} + +void IdealButtonBarWidget::saveOrderSettings() +{ + takeOrderFromLayout(); + + KConfigGroup config = KSharedConfig::openConfig()->group("UI"); + config.writeEntry(QStringLiteral("(%1) Tool Views Order").arg(_area), _buttonsOrder); +} + +void IdealButtonBarWidget::applyOrderToLayout() +{ + foreach(auto a, actions()) { + if (auto tva = dynamic_cast(a)) + layout()->removeWidget(tva->button()); + } + + foreach(auto id, _buttonsOrder) { + if (auto b = button(id)) + layout()->addWidget(b); + } +} + +void IdealButtonBarWidget::takeOrderFromLayout() +{ + _buttonsOrder.clear(); + for (int i = 0; i < layout()->count(); ++i) { + if (auto button = dynamic_cast(layout()->itemAt(i)->widget())) + _buttonsOrder += id(button); + } +} + Qt::Orientation IdealButtonBarWidget::orientation() const { if (_area == Qt::LeftDockWidgetArea || _area == Qt::RightDockWidgetArea) @@ -228,63 +335,6 @@ button->setChecked(checked); } - -void IdealButtonBarWidget::actionEvent(QActionEvent *event) -{ - auto action = dynamic_cast(event->action()); - if (!action) - return; - - switch (event->type()) { - case QEvent::ActionAdded: { - bool wasEmpty = isEmpty(); - if (!action->button()) { - IdealToolButton *button = new IdealToolButton(_area); - //apol: here we set the usual width of a button for the vertical toolbars as the minimumWidth - //this is done because otherwise when we remove all the buttons and re-add new ones we get all - //the screen flickering. This is solved by not defaulting to a smaller width when it's empty - int w = button->sizeHint().width(); - if(orientation()==Qt::Vertical && w>minimumWidth()) - setMinimumWidth(w); - action->setButton(button); - button->setDefaultAction(action); - - Q_ASSERT(action->dockWidget()); - - layout()->addWidget(button); - connect(action, &QAction::toggled, this, static_cast(&IdealButtonBarWidget::showWidget)); - connect(button, &IdealToolButton::clicked, this, &IdealButtonBarWidget::buttonPressed); - connect(button, &IdealToolButton::customContextMenuRequested, - action->dockWidget(), &IdealDockWidget::contextMenuRequested); - if ( wasEmpty ) { - emit emptyChanged(); - } - } - } break; - - case QEvent::ActionRemoved: { - IdealToolButton *button = action->button(); - if (button) { - for (int index = 0; index < layout()->count(); ++index) { - if (QLayoutItem *item = layout()->itemAt(index)) { - if (item->widget() == button) { - action->disconnect(this); - delete layout()->takeAt(index); - break; - } - } - } - } - if(layout()->isEmpty()) { - emit emptyChanged(); - } - } break; - - default: - break; - } -} - IdealDockWidget * IdealButtonBarWidget::widgetForAction(QAction *_action) const { return dynamic_cast(_action)->dockWidget(); diff --git a/sublime/mainwindow_p.cpp b/sublime/mainwindow_p.cpp --- a/sublime/mainwindow_p.cpp +++ b/sublime/mainwindow_p.cpp @@ -522,6 +522,15 @@ void MainWindowPrivate::viewAdded(Sublime::AreaIndex *index, Sublime::View *view) { + static bool orderIsLoaded = false; + + if (!orderIsLoaded) { + orderIsLoaded = true; + idealController->leftBarWidget->loadOrderSettings(); + idealController->bottomBarWidget->loadOrderSettings(); + idealController->rightBarWidget->loadOrderSettings(); + } + if(m_leftTabbarCornerWidget) { m_leftTabbarCornerWidget->hide(); m_leftTabbarCornerWidget->setParent(nullptr); @@ -571,6 +580,15 @@ void MainWindowPrivate::aboutToRemoveView(Sublime::AreaIndex *index, Sublime::View *view) { + static bool orderIsSaved = false; + + if (!orderIsSaved) { + orderIsSaved = true; + idealController->leftBarWidget->saveOrderSettings(); + idealController->bottomBarWidget->saveOrderSettings(); + idealController->rightBarWidget->saveOrderSettings(); + } + QSplitter *splitter = m_indexSplitters[index]; if (!splitter) return;