5#include <iconloader_p.h>
6#include <iconselector_p.h>
7#include <qdesigner_utils_p.h>
9#include <QtDesigner/abstractformeditor.h>
11#include <QtWidgets/qapplication.h>
12#include <QtWidgets/qlabel.h>
13#include <QtWidgets/qtoolbutton.h>
14#include <QtWidgets/qboxlayout.h>
15#include <QtWidgets/qlineedit.h>
16#include <QtWidgets/qdialogbuttonbox.h>
17#include <QtWidgets/qpushbutton.h>
18#include <QtWidgets/qfiledialog.h>
19#include <QtWidgets/qmenu.h>
21#include <QtGui/qaction.h>
22#if QT_CONFIG(clipboard)
23#include <QtGui/qclipboard.h>
25#include <QtGui/qevent.h>
29using namespace Qt::StringLiterals;
38 QVBoxLayout *layout =
new QVBoxLayout(topLevel);
39 QLabel *label =
new QLabel(labelText, topLevel);
40 QDialogButtonBox *buttons =
new QDialogButtonBox(topLevel);
41 buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
42 QObject::connect(buttons, &QDialogButtonBox::accepted, topLevel, &QDialog::accept);
43 QObject::connect(buttons, &QDialogButtonBox::rejected, topLevel, &QDialog::reject);
45 layout->addWidget(label);
46 layout->addWidget(themeEditor);
47 layout->addWidget(buttons);
53 setWindowTitle(tr(
"Set Icon From XDG Theme"));
54 m_editor =
new IconThemeEditor(
this);
55 createIconThemeDialog(
this, tr(
"Select icon name from XDG theme:"), m_editor);
58std::optional<QString>
IconThemeDialog::getTheme(QWidget *parent,
const QString &theme)
61 dlg.m_editor->setTheme(theme);
62 if (dlg.exec() == QDialog::Accepted)
63 return dlg.m_editor->theme();
70 setWindowTitle(tr(
"Set Icon From Theme"));
71 m_editor =
new IconThemeEnumEditor(
this);
72 createIconThemeDialog(
this, tr(
"Select icon name from theme:"), m_editor);
78 dlg.m_editor->setThemeEnum(theme);
79 if (dlg.exec() == QDialog::Accepted)
80 return dlg.m_editor->themeEnum();
84PixmapEditor::PixmapEditor(QDesignerFormEditorInterface *core, QWidget *parent) :
86 m_iconThemeModeEnabled(
false),
88 m_pixmapLabel(
new QLabel(
this)),
89 m_pathLabel(
new QLabel(
this)),
90 m_button(
new QToolButton(
this)),
91 m_resourceAction(
new QAction(tr(
"Choose Resource..."),
this)),
92 m_fileAction(
new QAction(tr(
"Choose File..."),
this)),
93 m_themeEnumAction(
new QAction(tr(
"Set Icon From Theme..."),
this)),
94 m_themeAction(
new QAction(tr(
"Set Icon From XDG Theme..."),
this)),
95 m_copyAction(
new QAction(createIconSet(QIcon::ThemeIcon::EditCopy,
"editcopy.png"_L1),
96 tr(
"Copy Path"),
this)),
97 m_pasteAction(
new QAction(createIconSet(QIcon::ThemeIcon::EditPaste,
"editpaste.png"_L1),
98 tr(
"Paste Path"),
this)),
99 m_layout(
new QHBoxLayout(
this)),
100 m_pixmapCache(
nullptr)
102 m_layout->addWidget(m_pixmapLabel);
103 m_layout->addWidget(m_pathLabel);
104 m_button->setText(tr(
"..."));
105 m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
106 m_button->setFixedWidth(30);
107 m_button->setPopupMode(QToolButton::MenuButtonPopup);
108 m_layout->addWidget(m_button);
109 m_layout->setContentsMargins(QMargins());
110 m_layout->setSpacing(0);
111 m_pixmapLabel->setFixedWidth(ICON_SIZE.width());
112 m_pixmapLabel->setAlignment(Qt::AlignCenter);
113 m_pathLabel->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed));
114 m_themeAction->setVisible(
false);
115 m_themeEnumAction->setVisible(
false);
117 QMenu *menu =
new QMenu(
this);
118 menu->addAction(m_resourceAction);
119 menu->addAction(m_fileAction);
120 menu->addAction(m_themeEnumAction);
121 menu->addAction(m_themeAction);
123 m_button->setMenu(menu);
124 m_button->setText(tr(
"..."));
126 connect(m_button, &QAbstractButton::clicked,
this, &PixmapEditor::defaultActionActivated);
127 connect(m_resourceAction, &QAction::triggered,
this, &PixmapEditor::resourceActionActivated);
128 connect(m_fileAction, &QAction::triggered,
this, &PixmapEditor::fileActionActivated);
129 connect(m_themeEnumAction, &QAction::triggered,
this, &PixmapEditor::themeEnumActionActivated);
130 connect(m_themeAction, &QAction::triggered,
this, &PixmapEditor::themeActionActivated);
131#if QT_CONFIG(clipboard)
132 connect(m_copyAction, &QAction::triggered,
this, &PixmapEditor::copyActionActivated);
133 connect(m_pasteAction, &QAction::triggered,
this, &PixmapEditor::pasteActionActivated);
135 setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored));
136 setFocusProxy(m_button);
138#if QT_CONFIG(clipboard)
139 connect(QApplication::clipboard(), &QClipboard::dataChanged,
140 this, &PixmapEditor::clipboardDataChanged);
141 clipboardDataChanged();
147 m_pixmapCache = cache;
152 if (m_iconThemeModeEnabled == enabled)
154 m_iconThemeModeEnabled = enabled;
155 m_themeAction->setVisible(enabled);
156 m_themeEnumAction->setVisible(enabled);
161 m_layout->setSpacing(spacing);
178 return tr(
"[Theme] %1").arg(t);
183 return tr(
"[Theme] %1 (missing)").arg(t);
194 m_pathLabel->setText(displayText(m_themeEnum, m_theme, m_path));
197 case State::MissingXdgTheme:
198 case State::MissingThemeEnum:
199 m_pixmapLabel->setPixmap(m_defaultPixmap);
200 m_copyAction->setEnabled(
false);
202 case State::ThemeEnum:
203 m_pixmapLabel->setPixmap(QIcon::fromTheme(
static_cast<QIcon::ThemeIcon>(m_themeEnum)).pixmap(ICON_SIZE));
204 m_copyAction->setEnabled(
true);
206 case State::XdgTheme:
207 m_pixmapLabel->setPixmap(QIcon::fromTheme(m_theme).pixmap(ICON_SIZE));
208 m_copyAction->setEnabled(
true);
211 case State::PathFallback:
213 auto pixmap = m_pixmapCache->pixmap(PropertySheetPixmapValue(m_path));
214 m_pixmapLabel->setPixmap(QIcon(pixmap).pixmap(ICON_SIZE));
216 m_copyAction->setEnabled(
true);
223 m_defaultPixmap = icon.pixmap(ICON_SIZE);
224 if (state() == State::Empty)
225 m_pixmapLabel->setPixmap(m_defaultPixmap);
230 setDefaultPixmapIcon(QIcon(pixmap));
236 menu.addAction(m_copyAction);
237 menu.addAction(m_pasteAction);
238 menu.exec(event->globalPos());
244 if (m_iconThemeModeEnabled) {
245 themeEnumActionActivated();
249 const PropertySheetPixmapValue::PixmapSource ps = m_path.isEmpty()
250 ? PropertySheetPixmapValue::ResourcePixmap
251 : PropertySheetPixmapValue::getPixmapSource(m_core, m_path);
253 case PropertySheetPixmapValue::LanguageResourcePixmap:
254 case PropertySheetPixmapValue::ResourcePixmap:
255 resourceActionActivated();
257 case PropertySheetPixmapValue::FilePixmap:
258 fileActionActivated();
265 const QString oldPath = m_path;
266 const QString newPath = IconSelector::choosePixmapResource(m_core, m_core->resourceModel(),
268 if (!newPath.isEmpty() && newPath != oldPath) {
272 emit pathChanged(newPath);
278 const QString newPath = IconSelector::choosePixmapFile(m_path, m_core->dialogGui(),
this);
279 if (!newPath.isEmpty() && newPath != m_path) {
283 emit pathChanged(newPath);
289 const auto newThemeO = IconThemeEnumDialog::getTheme(
this, {});
290 if (newThemeO.has_value()) {
291 const int newTheme = newThemeO.value();
292 if (newTheme != m_themeEnum) {
296 emit themeEnumChanged(newTheme);
303 const auto newThemeO = IconThemeDialog::getTheme(
this, m_theme);
304 if (newThemeO.has_value()) {
305 const QString newTheme = newThemeO.value();
306 if (newTheme != m_theme) {
310 emit themeChanged(newTheme);
318 if (themeEnum != -1) {
319 if (QIcon::hasThemeIcon(
static_cast<QIcon::ThemeIcon>(themeEnum)))
320 return State::ThemeEnum;
321 return path.isEmpty() ? State::MissingThemeEnum : State::PathFallback;
323 if (!xdgTheme.isEmpty()) {
324 if (QIcon::hasThemeIcon(xdgTheme))
325 return State::XdgTheme;
326 return path.isEmpty() ? State::MissingXdgTheme : State::PathFallback;
328 return path.isEmpty() ? State::Empty : State::Path;
333 return stateFromData(m_themeEnum, m_theme, m_path);
336QString
PixmapEditor::displayText(
int themeEnum,
const QString &xdgTheme,
const QString &path)
338 switch (stateFromData(themeEnum, xdgTheme, path)) {
339 case State::ThemeEnum:
340 return msgThemeIcon(IconThemeEnumEditor::iconName(themeEnum));
341 case State::MissingThemeEnum:
342 return msgMissingThemeIcon(IconThemeEnumEditor::iconName(themeEnum));
343 case State::XdgTheme:
344 return msgThemeIcon(xdgTheme);
345 case State::MissingXdgTheme:
346 return msgMissingThemeIcon(xdgTheme);
348 return QFileInfo(path).fileName();
349 case State::PathFallback:
350 return tr(
"%1 (fallback)").arg(QFileInfo(path).fileName());
359 const auto &paths = icon.paths();
360 const auto &it = paths.constFind({QIcon::Normal, QIcon::Off});
361 const QString path = it != paths.constEnd() ? it.value().path() : QString{};
362 return displayText(icon.themeEnum(), icon.theme(), path);
365#if QT_CONFIG(clipboard)
void setTheme(const QString &theme)
void setDefaultPixmap(const QPixmap &pixmap)
void setSpacing(int spacing)
void setPixmapCache(DesignerPixmapCache *cache)
void setDefaultPixmapIcon(const QIcon &icon)
void setIconThemeModeEnabled(bool enabled)
void contextMenuEvent(QContextMenuEvent *event) override
This event handler, for event event, can be reimplemented in a subclass to receive widget context men...
Combined button and popup list for selecting options.
Auxiliary methods to store/retrieve settings.
static void createIconThemeDialog(QDialog *topLevel, const QString &labelText, QWidget *themeEditor)
static constexpr QSize ICON_SIZE