1/*
2
3 This file is part of the KDE project, module kfile.
4 SPDX-FileCopyrightText: 2000 Geert Jansen <jansen@kde.org>
5 SPDX-FileCopyrightText: 2000 Kurt Granroth <granroth@kde.org>
6 SPDX-FileCopyrightText: 1997 Christoph Neerfeld <chris@kde.org>
7 SPDX-FileCopyrightText: 2002 Carsten Pfeiffer <pfeiffer@kde.org>
8
9 SPDX-License-Identifier: LGPL-2.0-only
10*/
11
12#include "kiconbutton.h"
13
14#include <QEvent>
15#include <QFileInfo>
16#include <QStyleOptionButton>
17#include <QStylePainter>
18
19#include <KLocalizedString>
20#include <KStyleExtensions>
21
22#include "kicondialog.h"
23
24class KIconButtonPrivate
25{
26public:
27 KIconButtonPrivate(KIconButton *qq, KIconLoader *loader);
28 ~KIconButtonPrivate();
29
30 KIconDialog *dialog();
31
32 // slots
33 void _k_slotChangeIcon();
34 void _k_newIconName(const QString &);
35
36 KIconButton *q;
37
38 int iconSize;
39 int buttonIconSize;
40 bool m_bStrictIconSize;
41
42 bool mbUser;
43 KIconLoader::Group mGroup;
44 KIconLoader::Context mContext;
45
46 QString mIcon;
47 KIconDialog *mpDialog;
48 KIconLoader *mpLoader;
49
50 QStyle::ControlElement ce_iconButton = QStyle::ControlElement(0);
51};
52
53/*
54 * KIconButton: A "choose icon" pushbutton.
55 */
56
57KIconButton::KIconButton(QWidget *parent)
58 : QPushButton(parent)
59 , d(new KIconButtonPrivate(this, KIconLoader::global()))
60{
61 QPushButton::setIconSize(QSize(48, 48));
62}
63
64KIconButtonPrivate::KIconButtonPrivate(KIconButton *qq, KIconLoader *loader)
65 : q(qq)
66{
67 m_bStrictIconSize = false;
68 iconSize = 0; // let KIconLoader choose the default
69 buttonIconSize = -1; // When buttonIconSize is -1, iconSize will be used for the button
70
71 mGroup = KIconLoader::Desktop;
72 mContext = KIconLoader::Application;
73 mbUser = false;
74
75 mpLoader = loader;
76 mpDialog = nullptr;
77 QObject::connect(sender: q, signal: &KIconButton::clicked, context: q, slot: [this]() {
78 _k_slotChangeIcon();
79 });
80
81 ce_iconButton = KStyleExtensions::customControlElement(QStringLiteral("CE_IconButton"), widget: q);
82
83 q->setToolTip(i18nc("@info:tooltip", "Select Icon…"));
84}
85
86KIconButtonPrivate::~KIconButtonPrivate()
87{
88 delete mpDialog;
89}
90
91KIconDialog *KIconButtonPrivate::dialog()
92{
93 if (!mpDialog) {
94 mpDialog = new KIconDialog(q);
95 QObject::connect(sender: mpDialog, signal: &KIconDialog::newIconName, context: q, slot: [this](const QString &iconName) {
96 _k_newIconName(iconName);
97 });
98 }
99
100 return mpDialog;
101}
102
103KIconButton::~KIconButton() = default;
104
105void KIconButton::setStrictIconSize(bool b)
106{
107 d->m_bStrictIconSize = b;
108}
109
110bool KIconButton::strictIconSize() const
111{
112 return d->m_bStrictIconSize;
113}
114
115void KIconButton::setIconSize(int size)
116{
117 if (d->buttonIconSize == -1) {
118 QPushButton::setIconSize(QSize(size, size));
119 }
120
121 d->iconSize = size;
122}
123
124int KIconButton::iconSize() const
125{
126 return d->iconSize;
127}
128
129void KIconButton::setButtonIconSize(int size)
130{
131 QPushButton::setIconSize(QSize(size, size));
132 d->buttonIconSize = size;
133}
134
135int KIconButton::buttonIconSize() const
136{
137 return QPushButton::iconSize().height();
138}
139
140void KIconButton::setIconType(KIconLoader::Group group, KIconLoader::Context context, bool user)
141{
142 d->mGroup = group;
143 d->mContext = context;
144 d->mbUser = user;
145}
146
147void KIconButton::setIcon(const QString &icon)
148{
149 d->mIcon = icon;
150 setIcon(QIcon::fromTheme(name: d->mIcon));
151
152 if (d->mbUser) {
153 d->dialog()->setCustomLocation(QFileInfo(d->mpLoader->iconPath(name: d->mIcon, group_or_size: d->mGroup, canReturnNull: true)).absolutePath());
154 }
155}
156
157void KIconButton::setIcon(const QIcon &icon)
158{
159 QPushButton::setIcon(icon);
160}
161
162void KIconButton::resetIcon()
163{
164 d->mIcon.clear();
165 setIcon(QIcon());
166}
167
168const QString &KIconButton::icon() const
169{
170 return d->mIcon;
171}
172
173void KIconButton::paintEvent(QPaintEvent *event)
174{
175 if (d->ce_iconButton) {
176 QStylePainter painter(this);
177
178 QStyleOptionButton opt;
179 initStyleOption(option: &opt);
180
181 painter.drawControl(ce: d->ce_iconButton, opt);
182 return;
183 }
184
185 return QPushButton::paintEvent(event);
186}
187
188void KIconButton::changeEvent(QEvent *event)
189{
190 QWidget::changeEvent(event);
191 if (event->type() == QEvent::StyleChange) {
192 d->ce_iconButton = KStyleExtensions::customControlElement(QStringLiteral("CE_IconButton"), widget: this);
193 }
194}
195
196void KIconButtonPrivate::_k_slotChangeIcon()
197{
198 dialog()->setup(group: mGroup, context: mContext, strictIconSize: m_bStrictIconSize, iconSize, user: mbUser);
199 dialog()->setSelectedIcon(mIcon);
200 dialog()->showDialog();
201}
202
203void KIconButtonPrivate::_k_newIconName(const QString &name)
204{
205 if (name.isEmpty()) {
206 return;
207 }
208
209 q->setIcon(QIcon::fromTheme(name));
210 mIcon = name;
211
212 if (mbUser) {
213 mpDialog->setCustomLocation(QFileInfo(mpLoader->iconPath(name: mIcon, group_or_size: mGroup, canReturnNull: true)).absolutePath());
214 }
215
216 Q_EMIT q->iconChanged(icon: name);
217}
218
219#include "moc_kiconbutton.cpp"
220

source code of kiconthemes/src/widgets/kiconbutton.cpp