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