1 /***************************************************************************
2  *   Copyright (C) 2020 by Simone Gaiarin <simgunz@gmail.com>              *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  ***************************************************************************/
9 
10 #include <QAction>
11 #include <QHBoxLayout>
12 #include <QLabel>
13 #include <QLayout>
14 #include <QList>
15 #include <QToolBar>
16 #include <QToolButton>
17 #include <QVBoxLayout>
18 #include <QWidget>
19 
20 #include "actionbar.h"
21 
22 class ActionBarWidget : public QWidget
23 {
24     Q_OBJECT
25 
26 public:
27     explicit ActionBarWidget(QToolBar *parent);
28     void recreateButtons(const QList<QAction *> &actions);
29 
30 private slots:
31     void onOrientationChanged(Qt::Orientation orientation);
32 };
33 
ActionBarWidget(QToolBar * parent)34 ActionBarWidget::ActionBarWidget(QToolBar *parent)
35     : QWidget::QWidget(parent)
36 {
37     QLayout *layout;
38     if (parent->orientation() == Qt::Vertical) {
39         layout = new QVBoxLayout();
40     } else {
41         layout = new QHBoxLayout();
42     }
43     setLayout(layout);
44     connect(parent, &QToolBar::orientationChanged, this, &ActionBarWidget::onOrientationChanged);
45 }
46 
recreateButtons(const QList<QAction * > & actions)47 void ActionBarWidget::recreateButtons(const QList<QAction *> &actions)
48 {
49     QToolBar *parentToolbar = qobject_cast<QToolBar *>(parentWidget());
50     if (!parentToolbar) {
51         return;
52     }
53     for (auto &toolButton : findChildren<QToolButton *>()) {
54         layout()->removeWidget(toolButton);
55         delete toolButton;
56     }
57     for (const auto &action : actions) {
58         QToolButton *toolButton = new QToolButton(this);
59         toolButton->setAutoRaise(true);
60         toolButton->setFocusPolicy(Qt::NoFocus);
61         toolButton->setIconSize(parentToolbar->iconSize());
62         toolButton->setToolButtonStyle(parentToolbar->toolButtonStyle());
63         toolButton->setDefaultAction(action);
64         layout()->addWidget(toolButton);
65         layout()->setAlignment(toolButton, Qt::AlignCenter);
66         connect(parentToolbar, &QToolBar::iconSizeChanged, toolButton, &QToolButton::setIconSize);
67         connect(parentToolbar, &QToolBar::toolButtonStyleChanged, toolButton, &QToolButton::setToolButtonStyle);
68     }
69 }
70 
onOrientationChanged(Qt::Orientation orientation)71 void ActionBarWidget::onOrientationChanged(Qt::Orientation orientation)
72 {
73     QLayout *newLayout;
74     if (orientation == Qt::Vertical) {
75         newLayout = new QVBoxLayout();
76     } else {
77         newLayout = new QHBoxLayout();
78     }
79     QLayout *oldLayout = layout();
80     for (auto &toolButton : findChildren<QToolButton *>()) {
81         oldLayout->removeWidget(toolButton);
82         newLayout->addWidget(toolButton);
83         newLayout->setAlignment(toolButton, Qt::AlignCenter);
84     }
85     delete oldLayout;
86     setLayout(newLayout);
87 }
88 
ActionBar(QObject * parent)89 ActionBar::ActionBar(QObject *parent)
90     : QWidgetAction(parent)
91 {
92 }
93 
createWidget(QWidget * parent)94 QWidget *ActionBar::createWidget(QWidget *parent)
95 {
96     QToolBar *parentToolbar = qobject_cast<QToolBar *>(parent);
97     if (!parentToolbar) {
98         return new QWidget();
99     }
100     ActionBarWidget *widget = new ActionBarWidget(parentToolbar);
101     widget->recreateButtons(m_actions);
102     return widget;
103 }
104 
addAction(QAction * action)105 void ActionBar::addAction(QAction *action)
106 {
107     m_actions.append(action);
108 }
109 
insertAction(int pos,QAction * action)110 void ActionBar::insertAction(int pos, QAction *action)
111 {
112     m_actions.insert(pos, action);
113 }
114 
removeAction(QAction * action)115 void ActionBar::removeAction(QAction *action)
116 {
117     m_actions.removeAll(action);
118 }
119 
recreateWidgets()120 void ActionBar::recreateWidgets()
121 {
122     const auto widgets = createdWidgets();
123     for (auto *widget : widgets) {
124         auto *actionBarWidget = qobject_cast<ActionBarWidget *>(widget);
125         if (actionBarWidget) {
126             actionBarWidget->recreateButtons(m_actions);
127         }
128     }
129 }
130 
131 #include "actionbar.moc"
132