1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Designer of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include "iconselector_p.h"
30#include "qdesigner_utils_p.h"
31#include "qtresourcemodel_p.h"
32#include "qtresourceview_p.h"
33#include "iconloader_p.h"
34#include "formwindowbase_p.h"
35
36#include <abstractdialoggui_p.h>
37#include <QtDesigner/abstractformeditor.h>
38#include <QtDesigner/abstractresourcebrowser.h>
39#include <QtDesigner/abstractlanguage.h>
40#include <QtDesigner/abstractintegration.h>
41#include <QtDesigner/qextensionmanager.h>
42
43#include <QtWidgets/qtoolbutton.h>
44#include <QtWidgets/qcombobox.h>
45#include <QtWidgets/qaction.h>
46#include <QtWidgets/qdialogbuttonbox.h>
47#include <QtWidgets/qpushbutton.h>
48#include <QtWidgets/qdialog.h>
49#include <QtWidgets/qmenu.h>
50#include <QtWidgets/qapplication.h>
51#include <QtWidgets/qboxlayout.h>
52#include <QtGui/qimagereader.h>
53#include <QtWidgets/qdialogbuttonbox.h>
54#include <QtWidgets/qlineedit.h>
55#include <QtWidgets/qlabel.h>
56#include <QtGui/qvalidator.h>
57#include <QtCore/qdebug.h>
58#include <QtCore/qvector.h>
59
60
61QT_BEGIN_NAMESPACE
62
63namespace qdesigner_internal {
64
65// -------------------- LanguageResourceDialogPrivate
66class LanguageResourceDialogPrivate {
67 LanguageResourceDialog *q_ptr;
68 Q_DECLARE_PUBLIC(LanguageResourceDialog)
69
70public:
71 LanguageResourceDialogPrivate(QDesignerResourceBrowserInterface *rb);
72 void init(LanguageResourceDialog *p);
73
74 void setCurrentPath(const QString &filePath);
75 QString currentPath() const;
76
77 void slotAccepted();
78 void slotPathChanged(const QString &);
79
80private:
81 void setOkButtonEnabled(bool v) { m_dialogButtonBox->button(which: QDialogButtonBox::Ok)->setEnabled(v); }
82 static bool checkPath(const QString &p);
83
84 QDesignerResourceBrowserInterface *m_browser;
85 QDialogButtonBox *m_dialogButtonBox;
86};
87
88LanguageResourceDialogPrivate::LanguageResourceDialogPrivate(QDesignerResourceBrowserInterface *rb) :
89 q_ptr(nullptr),
90 m_browser(rb),
91 m_dialogButtonBox(new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel))
92{
93 setOkButtonEnabled(false);
94}
95
96void LanguageResourceDialogPrivate::init(LanguageResourceDialog *p)
97{
98 q_ptr = p;
99 QLayout *layout = new QVBoxLayout(p);
100 layout->addWidget(w: m_browser);
101 layout->addWidget(w: m_dialogButtonBox);
102 QObject::connect(sender: m_dialogButtonBox, SIGNAL(accepted()), receiver: p, SLOT(slotAccepted()));
103 QObject::connect(sender: m_dialogButtonBox, signal: &QDialogButtonBox::rejected, receiver: p, slot: &QDialog::reject);
104 QObject::connect(sender: m_browser, SIGNAL(currentPathChanged(QString)), receiver: p, SLOT(slotPathChanged(QString)));
105 QObject::connect(sender: m_browser, SIGNAL(pathActivated(QString)), receiver: p, SLOT(slotAccepted()));
106 p->setModal(true);
107 p->setWindowTitle(LanguageResourceDialog::tr(s: "Choose Resource"));
108 p->setWindowFlags(p->windowFlags() & ~Qt::WindowContextHelpButtonHint);
109 setOkButtonEnabled(false);
110}
111
112void LanguageResourceDialogPrivate::setCurrentPath(const QString &filePath)
113{
114 m_browser->setCurrentPath(filePath);
115 setOkButtonEnabled(checkPath(p: filePath));
116}
117
118QString LanguageResourceDialogPrivate::currentPath() const
119{
120 return m_browser->currentPath();
121}
122
123bool LanguageResourceDialogPrivate::checkPath(const QString &p)
124{
125 return p.isEmpty() ? false : IconSelector::checkPixmap(fileName: p, cm: IconSelector::CheckFast);
126}
127
128void LanguageResourceDialogPrivate::slotAccepted()
129{
130 if (checkPath(p: currentPath()))
131 q_ptr->accept();
132}
133
134void LanguageResourceDialogPrivate::slotPathChanged(const QString &p)
135{
136 setOkButtonEnabled(checkPath(p));
137}
138
139// ------------ LanguageResourceDialog
140LanguageResourceDialog::LanguageResourceDialog(QDesignerResourceBrowserInterface *rb, QWidget *parent) :
141 QDialog(parent),
142 d_ptr(new LanguageResourceDialogPrivate(rb))
143{
144 d_ptr->init( p: this);
145}
146
147LanguageResourceDialog::~LanguageResourceDialog() = default;
148
149void LanguageResourceDialog::setCurrentPath(const QString &filePath)
150{
151 d_ptr->setCurrentPath(filePath);
152}
153
154QString LanguageResourceDialog::currentPath() const
155{
156 return d_ptr->currentPath();
157}
158
159LanguageResourceDialog* LanguageResourceDialog::create(QDesignerFormEditorInterface *core, QWidget *parent)
160{
161 if (QDesignerLanguageExtension *lang = qt_extension<QDesignerLanguageExtension *>(manager: core->extensionManager(), object: core))
162 if (QDesignerResourceBrowserInterface *rb = lang->createResourceBrowser(parentWidget: nullptr))
163 return new LanguageResourceDialog(rb, parent);
164 if (QDesignerResourceBrowserInterface *rb = core->integration()->createResourceBrowser(parent: nullptr))
165 return new LanguageResourceDialog(rb, parent);
166 return nullptr;
167}
168
169// ------------ IconSelectorPrivate
170
171static inline QPixmap emptyPixmap()
172{
173 QImage img(16, 16, QImage::Format_ARGB32_Premultiplied);
174 img.fill(pixel: 0);
175 return QPixmap::fromImage(image: img);
176}
177
178class IconSelectorPrivate
179{
180 IconSelector *q_ptr = nullptr;
181 Q_DECLARE_PUBLIC(IconSelector)
182public:
183 IconSelectorPrivate() = default;
184
185 void slotStateActivated();
186 void slotSetActivated();
187 void slotSetResourceActivated();
188 void slotSetFileActivated();
189 void slotResetActivated();
190 void slotResetAllActivated();
191 void slotUpdate();
192
193 QVector<QPair<QPair<QIcon::Mode, QIcon::State>, QString> > m_stateToName; // could be static map
194
195 QMap<QPair<QIcon::Mode, QIcon::State>, int> m_stateToIndex;
196 QMap<int, QPair<QIcon::Mode, QIcon::State> > m_indexToState;
197
198 const QIcon m_emptyIcon;
199 QComboBox *m_stateComboBox = nullptr;
200 QToolButton *m_iconButton = nullptr;
201 QAction *m_resetAction = nullptr;
202 QAction *m_resetAllAction = nullptr;
203 PropertySheetIconValue m_icon;
204 DesignerIconCache *m_iconCache = nullptr;
205 DesignerPixmapCache *m_pixmapCache = nullptr;
206 QtResourceModel *m_resourceModel = nullptr;
207 QDesignerFormEditorInterface *m_core = nullptr;
208};
209
210void IconSelectorPrivate::slotUpdate()
211{
212 QIcon icon;
213 if (m_iconCache)
214 icon = m_iconCache->icon(value: m_icon);
215
216 QMap<QPair<QIcon::Mode, QIcon::State>, PropertySheetPixmapValue> paths = m_icon.paths();
217 for (auto itIndex = m_stateToIndex.cbegin(), end = m_stateToIndex.cend(); itIndex != end; ++itIndex) {
218 const QPair<QIcon::Mode, QIcon::State> state = itIndex.key();
219 const PropertySheetPixmapValue pixmap = paths.value(akey: state);
220 const int index = itIndex.value();
221
222 QIcon pixmapIcon = QIcon(icon.pixmap(w: 16, h: 16, mode: state.first, state: state.second));
223 if (pixmapIcon.isNull())
224 pixmapIcon = m_emptyIcon;
225 m_stateComboBox->setItemIcon(index, icon: pixmapIcon);
226 QFont font = q_ptr->font();
227 if (!pixmap.path().isEmpty())
228 font.setBold(true);
229 m_stateComboBox->setItemData(index, value: font, role: Qt::FontRole);
230 }
231
232 QPair<QIcon::Mode, QIcon::State> state = m_indexToState.value(akey: m_stateComboBox->currentIndex());
233 PropertySheetPixmapValue currentPixmap = paths.value(akey: state);
234 m_resetAction->setEnabled(!currentPixmap.path().isEmpty());
235 m_resetAllAction->setEnabled(!paths.isEmpty());
236 m_stateComboBox->update();
237}
238
239void IconSelectorPrivate::slotStateActivated()
240{
241 slotUpdate();
242}
243
244void IconSelectorPrivate::slotSetActivated()
245{
246 QPair<QIcon::Mode, QIcon::State> state = m_indexToState.value(akey: m_stateComboBox->currentIndex());
247 const PropertySheetPixmapValue pixmap = m_icon.pixmap(mode: state.first, state: state.second);
248 // Default to resource
249 const PropertySheetPixmapValue::PixmapSource ps = pixmap.path().isEmpty() ? PropertySheetPixmapValue::ResourcePixmap : pixmap.pixmapSource(core: m_core);
250 switch (ps) {
251 case PropertySheetPixmapValue::LanguageResourcePixmap:
252 case PropertySheetPixmapValue::ResourcePixmap:
253 slotSetResourceActivated();
254 break;
255 case PropertySheetPixmapValue::FilePixmap:
256 slotSetFileActivated();
257 break;
258 }
259}
260
261// Choose a pixmap from resource; use language-dependent resource browser if present
262QString IconSelector::choosePixmapResource(QDesignerFormEditorInterface *core, QtResourceModel *resourceModel, const QString &oldPath, QWidget *parent)
263{
264 Q_UNUSED(resourceModel);
265 QString rc;
266
267 if (LanguageResourceDialog* ldlg = LanguageResourceDialog::create(core, parent)) {
268 ldlg->setCurrentPath(oldPath);
269 if (ldlg->exec() == QDialog::Accepted)
270 rc = ldlg->currentPath();
271 delete ldlg;
272 } else {
273 QtResourceViewDialog dlg(core, parent);
274 dlg.setResourceEditingEnabled(core->integration()->hasFeature(f: QDesignerIntegration::ResourceEditorFeature));
275
276 dlg.selectResource(path: oldPath);
277 if (dlg.exec() == QDialog::Accepted)
278 rc = dlg.selectedResource();
279 }
280 return rc;
281}
282
283void IconSelectorPrivate::slotSetResourceActivated()
284{
285 const QPair<QIcon::Mode, QIcon::State> state = m_indexToState.value(akey: m_stateComboBox->currentIndex());
286
287 PropertySheetPixmapValue pixmap = m_icon.pixmap(mode: state.first, state: state.second);
288 const QString oldPath = pixmap.path();
289 const QString newPath = IconSelector::choosePixmapResource(core: m_core, resourceModel: m_resourceModel, oldPath, parent: q_ptr);
290 if (newPath.isEmpty() || newPath == oldPath)
291 return;
292 const PropertySheetPixmapValue newPixmap = PropertySheetPixmapValue(newPath);
293 if (newPixmap != pixmap) {
294 m_icon.setPixmap(mode: state.first, state: state.second, path: newPixmap);
295 slotUpdate();
296 emit q_ptr->iconChanged(icon: m_icon);
297 }
298}
299
300// Helpers for choosing image files: Check for valid image.
301bool IconSelector::checkPixmap(const QString &fileName, CheckMode cm, QString *errorMessage)
302{
303 const QFileInfo fi(fileName);
304 if (!fi.exists() || !fi.isFile() || !fi.isReadable()) {
305 if (errorMessage)
306 *errorMessage = tr(s: "The pixmap file '%1' cannot be read.").arg(a: fileName);
307 return false;
308 }
309 QImageReader reader(fileName);
310 if (!reader.canRead()) {
311 if (errorMessage)
312 *errorMessage = tr(s: "The file '%1' does not appear to be a valid pixmap file: %2")
313 .arg(args: fileName, args: reader.errorString());
314 return false;
315 }
316 if (cm == CheckFast)
317 return true;
318
319 const QImage image = reader.read();
320 if (image.isNull()) {
321 if (errorMessage)
322 *errorMessage = tr(s: "The file '%1' could not be read: %2")
323 .arg(args: fileName, args: reader.errorString());
324 return false;
325 }
326 return true;
327}
328
329// Helpers for choosing image files: Return an image filter for QFileDialog, courtesy of StyledButton
330static QString imageFilter()
331{
332 QString filter = QApplication::translate(context: "IconSelector", key: "All Pixmaps (");
333 const auto supportedImageFormats = QImageReader::supportedImageFormats();
334 const QString jpeg = QStringLiteral("JPEG");
335 const int count = supportedImageFormats.count();
336 for (int i = 0; i< count; ++i) {
337 if (i)
338 filter += QLatin1Char(' ');
339 filter += QStringLiteral("*.");
340 const QString outputFormat = QString::fromUtf8(str: supportedImageFormats.at(i));
341 if (outputFormat != jpeg)
342 filter += outputFormat.toLower();
343 else
344 filter += QStringLiteral("jpg *.jpeg");
345 }
346 filter += QLatin1Char(')');
347 return filter;
348}
349
350// Helpers for choosing image files: Choose a file
351QString IconSelector::choosePixmapFile(const QString &directory, QDesignerDialogGuiInterface *dlgGui,QWidget *parent)
352{
353 QString errorMessage;
354 QString newPath;
355 do {
356 const QString title = tr(s: "Choose a Pixmap");
357 static const QString filter = imageFilter();
358 newPath = dlgGui->getOpenImageFileName(parent, caption: title, dir: directory, filter);
359 if (newPath.isEmpty())
360 break;
361 if (checkPixmap(fileName: newPath, cm: CheckFully, errorMessage: &errorMessage))
362 break;
363 dlgGui->message(parent, context: QDesignerDialogGuiInterface::ResourceEditorMessage, icon: QMessageBox::Warning, title: tr(s: "Pixmap Read Error"), text: errorMessage);
364 } while(true);
365 return newPath;
366}
367
368void IconSelectorPrivate::slotSetFileActivated()
369{
370 QPair<QIcon::Mode, QIcon::State> state = m_indexToState.value(akey: m_stateComboBox->currentIndex());
371
372 PropertySheetPixmapValue pixmap = m_icon.pixmap(mode: state.first, state: state.second);
373 const QString newPath = IconSelector::choosePixmapFile(directory: pixmap.path(), dlgGui: m_core->dialogGui(), parent: q_ptr);
374 if (!newPath.isEmpty()) {
375 const PropertySheetPixmapValue newPixmap = PropertySheetPixmapValue(newPath);
376 if (!(newPixmap == pixmap)) {
377 m_icon.setPixmap(mode: state.first, state: state.second, path: newPixmap);
378 slotUpdate();
379 emit q_ptr->iconChanged(icon: m_icon);
380 }
381 }
382}
383
384void IconSelectorPrivate::slotResetActivated()
385{
386 QPair<QIcon::Mode, QIcon::State> state = m_indexToState.value(akey: m_stateComboBox->currentIndex());
387
388 PropertySheetPixmapValue pixmap = m_icon.pixmap(mode: state.first, state: state.second);
389 const PropertySheetPixmapValue newPixmap;
390 if (!(newPixmap == pixmap)) {
391 m_icon.setPixmap(mode: state.first, state: state.second, path: newPixmap);
392 slotUpdate();
393 emit q_ptr->iconChanged(icon: m_icon);
394 }
395}
396
397void IconSelectorPrivate::slotResetAllActivated()
398{
399 const PropertySheetIconValue newIcon;
400 if (!(m_icon == newIcon)) {
401 m_icon = newIcon;
402 slotUpdate();
403 emit q_ptr->iconChanged(icon: m_icon);
404 }
405}
406
407// ------------- IconSelector
408IconSelector::IconSelector(QWidget *parent) :
409 QWidget(parent), d_ptr(new IconSelectorPrivate())
410{
411 d_ptr->q_ptr = this;
412
413 d_ptr->m_stateComboBox = new QComboBox(this);
414
415 QHBoxLayout *l = new QHBoxLayout(this);
416 d_ptr->m_iconButton = new QToolButton(this);
417 d_ptr->m_iconButton->setText(tr(s: "..."));
418 d_ptr->m_iconButton->setPopupMode(QToolButton::MenuButtonPopup);
419 l->addWidget(d_ptr->m_stateComboBox);
420 l->addWidget(d_ptr->m_iconButton);
421 l->setContentsMargins(QMargins());
422
423 d_ptr->m_stateToName << qMakePair(x: qMakePair(x: QIcon::Normal, y: QIcon::Off), y: tr(s: "Normal Off") );
424 d_ptr->m_stateToName << qMakePair(x: qMakePair(x: QIcon::Normal, y: QIcon::On), y: tr(s: "Normal On") );
425 d_ptr->m_stateToName << qMakePair(x: qMakePair(x: QIcon::Disabled, y: QIcon::Off), y: tr(s: "Disabled Off") );
426 d_ptr->m_stateToName << qMakePair(x: qMakePair(x: QIcon::Disabled, y: QIcon::On), y: tr(s: "Disabled On") );
427 d_ptr->m_stateToName << qMakePair(x: qMakePair(x: QIcon::Active, y: QIcon::Off), y: tr(s: "Active Off") );
428 d_ptr->m_stateToName << qMakePair(x: qMakePair(x: QIcon::Active, y: QIcon::On), y: tr(s: "Active On") );
429 d_ptr->m_stateToName << qMakePair(x: qMakePair(x: QIcon::Selected, y: QIcon::Off), y: tr(s: "Selected Off") );
430 d_ptr->m_stateToName << qMakePair(x: qMakePair(x: QIcon::Selected, y: QIcon::On), y: tr(s: "Selected On") );
431
432 QMenu *setMenu = new QMenu(this);
433
434 QAction *setResourceAction = new QAction(tr(s: "Choose Resource..."), this);
435 QAction *setFileAction = new QAction(tr(s: "Choose File..."), this);
436 d_ptr->m_resetAction = new QAction(tr(s: "Reset"), this);
437 d_ptr->m_resetAllAction = new QAction(tr(s: "Reset All"), this);
438 d_ptr->m_resetAction->setEnabled(false);
439 d_ptr->m_resetAllAction->setEnabled(false);
440 //d_ptr->m_resetAction->setIcon(createIconSet(QString::fromUtf8("resetproperty.png")));
441
442 setMenu->addAction(action: setResourceAction);
443 setMenu->addAction(action: setFileAction);
444 setMenu->addSeparator();
445 setMenu->addAction(action: d_ptr->m_resetAction);
446 setMenu->addAction(action: d_ptr->m_resetAllAction);
447
448 int index = 0;
449 QStringList items;
450 for (const auto &item : qAsConst(t&: d_ptr->m_stateToName)) {
451 const QPair<QIcon::Mode, QIcon::State> state = item.first;
452 const QString name = item.second;
453
454 items.append(t: name);
455 d_ptr->m_stateToIndex[state] = index;
456 d_ptr->m_indexToState[index] = state;
457 index++;
458 }
459 d_ptr->m_stateComboBox->addItems(texts: items);
460
461 d_ptr->m_iconButton->setMenu(setMenu);
462
463 connect(sender: d_ptr->m_stateComboBox, SIGNAL(activated(int)), receiver: this, SLOT(slotStateActivated()));
464 connect(sender: d_ptr->m_iconButton, SIGNAL(clicked()), receiver: this, SLOT(slotSetActivated()));
465 connect(sender: setResourceAction, SIGNAL(triggered()), receiver: this, SLOT(slotSetResourceActivated()));
466 connect(sender: setFileAction, SIGNAL(triggered()), receiver: this, SLOT(slotSetFileActivated()));
467 connect(sender: d_ptr->m_resetAction, SIGNAL(triggered()), receiver: this, SLOT(slotResetActivated()));
468 connect(sender: d_ptr->m_resetAllAction, SIGNAL(triggered()), receiver: this, SLOT(slotResetAllActivated()));
469
470 d_ptr->slotUpdate();
471}
472
473IconSelector::~IconSelector() = default;
474
475void IconSelector::setIcon(const PropertySheetIconValue &icon)
476{
477 if (d_ptr->m_icon == icon)
478 return;
479
480 d_ptr->m_icon = icon;
481 d_ptr->slotUpdate();
482}
483
484PropertySheetIconValue IconSelector::icon() const
485{
486 return d_ptr->m_icon;
487}
488
489void IconSelector::setFormEditor(QDesignerFormEditorInterface *core)
490{
491 d_ptr->m_core = core;
492 d_ptr->m_resourceModel = core->resourceModel();
493 d_ptr->slotUpdate();
494}
495
496void IconSelector::setIconCache(DesignerIconCache *iconCache)
497{
498 d_ptr->m_iconCache = iconCache;
499 connect(sender: iconCache, SIGNAL(reloaded()), receiver: this, SLOT(slotUpdate()));
500 d_ptr->slotUpdate();
501}
502
503void IconSelector::setPixmapCache(DesignerPixmapCache *pixmapCache)
504{
505 d_ptr->m_pixmapCache = pixmapCache;
506 connect(sender: pixmapCache, SIGNAL(reloaded()), receiver: this, SLOT(slotUpdate()));
507 d_ptr->slotUpdate();
508}
509
510// --- IconThemeEditor
511
512// Validator for theme line edit, accepts empty or non-blank strings.
513class BlankSuppressingValidator : public QValidator {
514public:
515 explicit BlankSuppressingValidator(QObject * parent = nullptr) : QValidator(parent) {}
516
517 State validate(QString &input, int &pos) const override
518 {
519 const int blankPos = input.indexOf(c: QLatin1Char(' '));
520 if (blankPos != -1) {
521 pos = blankPos;
522 return Invalid;
523 }
524 return Acceptable;
525 }
526};
527
528struct IconThemeEditorPrivate {
529 IconThemeEditorPrivate();
530
531 const QPixmap m_emptyPixmap;
532 QLineEdit *m_themeLineEdit;
533 QLabel *m_themeLabel;
534};
535
536IconThemeEditorPrivate::IconThemeEditorPrivate() :
537 m_emptyPixmap(emptyPixmap()),
538 m_themeLineEdit(new QLineEdit),
539 m_themeLabel(new QLabel)
540{
541}
542
543IconThemeEditor::IconThemeEditor(QWidget *parent, bool wantResetButton) :
544 QWidget (parent), d(new IconThemeEditorPrivate)
545{
546 QHBoxLayout *mainHLayout = new QHBoxLayout;
547 mainHLayout->setContentsMargins(QMargins());
548
549 // Vertically center theme preview label
550 d->m_themeLabel->setPixmap(d->m_emptyPixmap);
551
552 QVBoxLayout *themeLabelVLayout = new QVBoxLayout;
553 d->m_themeLabel->setMargin(1);
554 themeLabelVLayout->setContentsMargins(QMargins());
555 themeLabelVLayout->addSpacerItem(spacerItem: new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
556 themeLabelVLayout->addWidget(d->m_themeLabel);
557 themeLabelVLayout->addSpacerItem(spacerItem: new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
558 mainHLayout->addLayout(layout: themeLabelVLayout);
559
560 d->m_themeLineEdit = new QLineEdit;
561 d->m_themeLineEdit->setValidator(new BlankSuppressingValidator(d->m_themeLineEdit));
562 connect(sender: d->m_themeLineEdit, signal: &QLineEdit::textChanged, receiver: this, slot: &IconThemeEditor::slotChanged);
563 connect(sender: d->m_themeLineEdit, signal: &QLineEdit::textEdited, receiver: this, slot: &IconThemeEditor::edited);
564 mainHLayout->addWidget(d->m_themeLineEdit);
565
566 if (wantResetButton) {
567 QToolButton *themeResetButton = new QToolButton;
568 themeResetButton->setIcon(createIconSet(QStringLiteral("resetproperty.png")));
569 connect(sender: themeResetButton, signal: &QAbstractButton::clicked, receiver: this, slot: &IconThemeEditor::reset);
570 mainHLayout->addWidget(themeResetButton);
571 }
572
573 setLayout(mainHLayout);
574 setFocusProxy(d->m_themeLineEdit);
575}
576
577IconThemeEditor::~IconThemeEditor() = default;
578
579void IconThemeEditor::reset()
580{
581 d->m_themeLineEdit->clear();
582 emit edited(QString());
583}
584
585void IconThemeEditor::slotChanged(const QString &theme)
586{
587 updatePreview(theme);
588}
589
590void IconThemeEditor::updatePreview(const QString &t)
591{
592 // Update preview label with icon.
593 if (t.isEmpty() || !QIcon::hasThemeIcon(name: t)) { // Empty
594 if (d->m_themeLabel->pixmap(Qt::ReturnByValue).cacheKey() != d->m_emptyPixmap.cacheKey())
595 d->m_themeLabel->setPixmap(d->m_emptyPixmap);
596 } else {
597 const QIcon icon = QIcon::fromTheme(name: t);
598 d->m_themeLabel->setPixmap(icon.pixmap(size: d->m_emptyPixmap.size()));
599 }
600}
601
602QString IconThemeEditor::theme() const
603{
604 return d->m_themeLineEdit->text();
605}
606
607void IconThemeEditor::setTheme(const QString &t)
608{
609 d->m_themeLineEdit->setText(t);
610}
611
612} // qdesigner_internal
613
614QT_END_NAMESPACE
615
616#include "moc_iconselector_p.cpp"
617

source code of qttools/src/designer/src/lib/shared/iconselector.cpp