1 /*
2     This file is part of the KDE libraries
3     SPDX-FileCopyrightText: 2004 Felix Berger <felixberger@beldesign.de>
4 
5     SPDX-License-Identifier: LGPL-2.0-only
6 */
7 
8 #include "ktoolbarlabelaction.h"
9 
10 #include <QApplication>
11 #include <QLabel>
12 #include <QPointer>
13 #include <QToolBar>
14 
15 class KToolBarLabelActionPrivate
16 {
17 public:
18     QPointer<QAction> buddy;
19     QPointer<QLabel> label;
20 };
21 
KToolBarLabelAction(const QString & text,QObject * parent)22 KToolBarLabelAction::KToolBarLabelAction(const QString &text, QObject *parent)
23     : QWidgetAction(parent)
24     , d(new KToolBarLabelActionPrivate)
25 {
26     setText(text);
27     d->label = nullptr;
28 }
29 
KToolBarLabelAction(QAction * buddy,const QString & text,QObject * parent)30 KToolBarLabelAction::KToolBarLabelAction(QAction *buddy, const QString &text, QObject *parent)
31     : QWidgetAction(parent)
32     , d(new KToolBarLabelActionPrivate)
33 {
34     setBuddy(buddy);
35     setText(text);
36 
37     d->label = nullptr;
38 }
39 
40 KToolBarLabelAction::~KToolBarLabelAction() = default;
41 
setBuddy(QAction * buddy)42 void KToolBarLabelAction::setBuddy(QAction *buddy)
43 {
44     d->buddy = buddy;
45 
46     QList<QLabel *> labels;
47     const auto associatedWidgets = this->associatedWidgets();
48     for (QWidget *widget : associatedWidgets) {
49         if (QToolBar *toolBar = qobject_cast<QToolBar *>(widget)) {
50             if (QLabel *label = qobject_cast<QLabel *>(toolBar->widgetForAction(this))) {
51                 labels.append(label);
52             }
53         }
54     }
55     const auto buddysAssociatedWidgets = buddy->associatedWidgets();
56     for (QWidget *widget : buddysAssociatedWidgets) {
57         if (QToolBar *toolBar = qobject_cast<QToolBar *>(widget)) {
58             QWidget *newBuddy = toolBar->widgetForAction(buddy);
59             for (QLabel *label : std::as_const(labels)) {
60                 label->setBuddy(newBuddy);
61             }
62             return;
63         }
64     }
65 }
66 
buddy() const67 QAction *KToolBarLabelAction::buddy() const
68 {
69     return d->buddy;
70 }
71 
event(QEvent * event)72 bool KToolBarLabelAction::event(QEvent *event)
73 {
74     if (event->type() == QEvent::ActionChanged) {
75         if (d->label && text() != d->label->text()) {
76             Q_EMIT textChanged(text());
77             d->label->setText(text());
78         }
79     }
80 
81     return QWidgetAction::event(event);
82 }
83 
eventFilter(QObject * watched,QEvent * event)84 bool KToolBarLabelAction::eventFilter(QObject *watched, QEvent *event)
85 {
86     if (d->label && d->buddy && event->type() == QEvent::PolishRequest && watched == d->label) {
87         const auto buddysAssociatedWidgets = d->buddy->associatedWidgets();
88         for (QWidget *widget : buddysAssociatedWidgets) {
89             if (QToolBar *toolBar = qobject_cast<QToolBar *>(widget)) {
90                 QWidget *newBuddy = toolBar->widgetForAction(d->buddy);
91                 d->label->setBuddy(newBuddy);
92             }
93         }
94     }
95 
96     return QWidgetAction::eventFilter(watched, event);
97 }
98 
createWidget(QWidget * _parent)99 QWidget *KToolBarLabelAction::createWidget(QWidget *_parent)
100 {
101     QToolBar *parent = qobject_cast<QToolBar *>(_parent);
102     if (!parent) {
103         return QWidgetAction::createWidget(_parent);
104     }
105     if (!d->label) {
106         d->label = new QLabel(parent);
107 
108         // These lines were copied from Konqueror's KonqDraggableLabel class in
109         // konq_misc.cc
110         d->label->setBackgroundRole(QPalette::Button);
111         d->label->setAlignment((QApplication::isRightToLeft() ? Qt::AlignRight : Qt::AlignLeft) | Qt::AlignVCenter);
112         d->label->adjustSize();
113         d->label->setText(text());
114         d->label->installEventFilter(this);
115     }
116 
117     return d->label;
118 }
119