KIconThemes

kicondialog.cpp
1 /* vi: ts=8 sts=4 sw=4
2 
3  This file is part of the KDE project, module kfile.
4  SPDX-FileCopyrightText: 2000 Geert Jansen <[email protected]>
5  SPDX-FileCopyrightText: 2000 Kurt Granroth <[email protected]>
6  SPDX-FileCopyrightText: 1997 Christoph Neerfeld <[email protected]>
7  SPDX-FileCopyrightText: 2002 Carsten Pfeiffer <[email protected]>
8  SPDX-FileCopyrightText: 2021 Kai Uwe Broulik <[email protected]>
9 
10  SPDX-License-Identifier: LGPL-2.0-only
11 */
12 
13 #include "kicondialog.h"
14 #include "kicondialog_p.h"
15 #include "kicondialogmodel_p.h"
16 
17 #include <KLazyLocalizedString>
18 #include <KLocalizedString>
19 #include <KStandardAction>
20 
21 #include <QAbstractListModel>
22 #include <QApplication>
23 #include <QComboBox>
24 #include <QDialogButtonBox>
25 #include <QFileInfo>
26 #include <QGraphicsOpacityEffect>
27 #include <QLabel>
28 #include <QPainter>
29 #include <QScrollBar>
30 #include <QStandardItemModel> // for manipulatig QComboBox
31 #include <QStandardPaths>
32 #include <QSvgRenderer>
33 #include <QVector>
34 
35 #include <algorithm>
36 #include <math.h>
37 
38 static const int s_edgePad = 3;
39 
40 KIconDialogModel::KIconDialogModel(QObject *parent)
41  : QAbstractListModel(parent)
42 {
43 }
44 
45 KIconDialogModel::~KIconDialogModel() = default;
46 
47 qreal KIconDialogModel::devicePixelRatio() const
48 {
49  return m_dpr;
50 }
51 
52 void KIconDialogModel::setDevicePixelRatio(qreal dpr)
53 {
54  m_dpr = dpr;
55 }
56 
57 QSize KIconDialogModel::iconSize() const
58 {
59  return m_iconSize;
60 }
61 
62 void KIconDialogModel::setIconSize(const QSize &iconSize)
63 {
64  m_iconSize = iconSize;
65 }
66 
67 void KIconDialogModel::load(const QStringList &paths)
68 {
69  beginResetModel();
70 
71  m_data.clear();
72  m_data.reserve(paths.count());
73 
74  for (const QString &path : paths) {
75  const QFileInfo fi(path);
76 
77  KIconDialogModelData item;
78  item.name = fi.completeBaseName();
79  item.path = path;
80  // pixmap is created on demand
81 
82  m_data.append(item);
83  }
84 
85  endResetModel();
86 }
87 
88 int KIconDialogModel::rowCount(const QModelIndex &parent) const
89 {
90  if (parent.isValid()) {
91  return 0;
92  }
93  return m_data.count();
94 }
95 
96 QVariant KIconDialogModel::data(const QModelIndex &index, int role) const
97 {
98  if (!checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid)) {
99  return QVariant();
100  }
101 
102  const auto &item = m_data.at(index.row());
103 
104  switch (role) {
105  case Qt::DisplayRole:
106  return item.name;
107  case Qt::DecorationRole:
108  if (item.pixmap.isNull()) {
109  const_cast<KIconDialogModel *>(this)->loadPixmap(index);
110  }
111  return item.pixmap;
112  case Qt::ToolTipRole:
113  return item.name;
114  case PathRole:
115  return item.path;
116  }
117 
118  return QVariant();
119 }
120 
121 void KIconDialogModel::loadPixmap(const QModelIndex &index)
122 {
123  Q_ASSERT(index.isValid());
124 
125  auto &item = m_data[index.row()];
126  Q_ASSERT(item.pixmap.isNull());
127 
128  const auto dpr = devicePixelRatio();
129  const auto canvasIconWidth = iconSize().width();
130  const auto canvasIconHeight = iconSize().height();
131 
132  QImage img;
133 
134  if (item.path.endsWith(QLatin1String(".svg"), Qt::CaseInsensitive) || item.path.endsWith(QLatin1String(".svgz"), Qt::CaseInsensitive)) {
135  QSvgRenderer renderer(item.path);
136  if (renderer.isValid()) {
137  img = QImage(canvasIconWidth * dpr, canvasIconHeight * dpr, QImage::Format_ARGB32_Premultiplied);
138  img.setDevicePixelRatio(dpr);
139  img.fill(Qt::transparent);
140 
141  QPainter p(&img);
142  // FIXME why do I need to specify bounds for it to not crop the SVG on dpr > 1?
143  renderer.render(&p, QRect(0, 0, canvasIconWidth, canvasIconHeight));
144  }
145  } else {
146  img.load(item.path);
147 
148  if (!img.isNull()) {
149  if (img.width() > canvasIconWidth || img.height() > canvasIconHeight) {
150  if (img.width() / (float)canvasIconWidth > img.height() / (float)canvasIconHeight) {
151  int height = (int)(((float)canvasIconWidth / img.width()) * img.height());
152  img = img.scaled(canvasIconWidth, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
153  } else {
154  int width = (int)(((float)canvasIconHeight / img.height()) * img.width());
155  img = img.scaled(width, canvasIconHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
156  }
157  }
158 
159  if (/*uniformIconSize &&*/ (img.width() != canvasIconWidth || img.height() != canvasIconHeight)) {
160  // Image is smaller than desired. Draw onto a transparent QImage of the required dimensions.
161  // (Unpleasant glitches occur if we break the uniformIconSizes() contract).
162  QImage paddedImage =
163  QImage(canvasIconWidth * img.devicePixelRatioF(), canvasIconHeight * img.devicePixelRatioF(), QImage::Format_ARGB32_Premultiplied);
164  paddedImage.setDevicePixelRatio(img.devicePixelRatioF());
165  paddedImage.fill(0);
166  QPainter painter(&paddedImage);
167  painter.drawImage((canvasIconWidth - img.width()) / 2, (canvasIconHeight - img.height()) / 2, img);
168  img = paddedImage;
169  }
170  }
171  }
172 
173  if (!img.isNull()) {
174  item.pixmap = QPixmap::fromImage(img);
175  }
176 }
177 
178 /**
179  * Qt allocates very little horizontal space for the icon name,
180  * even if the gridSize width is large. This delegate allocates
181  * the gridSize width (minus some padding) for the icon and icon name.
182  */
183 class KIconCanvasDelegate : public QAbstractItemDelegate
184 {
185  Q_OBJECT
186 public:
187  KIconCanvasDelegate(QListView *parent, QAbstractItemDelegate *defaultDelegate);
188  ~KIconCanvasDelegate() override
189  {
190  }
191  void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
192  QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
193 
194 private:
195  QAbstractItemDelegate *m_defaultDelegate = nullptr;
196 };
197 
198 KIconCanvasDelegate::KIconCanvasDelegate(QListView *parent, QAbstractItemDelegate *defaultDelegate)
199  : QAbstractItemDelegate(parent)
200 {
201  m_defaultDelegate = defaultDelegate;
202 }
203 
204 void KIconCanvasDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
205 {
206  auto *canvas = static_cast<QListView *>(parent());
207  const int gridWidth = canvas->gridSize().width();
208  QStyleOptionViewItem newOption = option;
209  newOption.displayAlignment = Qt::AlignHCenter | Qt::AlignTop;
210  newOption.features.setFlag(QStyleOptionViewItem::WrapText);
211  // Manipulate the width available.
212  newOption.rect.setX((option.rect.x() / gridWidth) * gridWidth + s_edgePad);
213  newOption.rect.setY(option.rect.y() + s_edgePad);
214  newOption.rect.setWidth(gridWidth - 2 * s_edgePad);
215  newOption.rect.setHeight(option.rect.height() - 2 * s_edgePad);
216  m_defaultDelegate->paint(painter, newOption, index);
217 }
218 
219 QSize KIconCanvasDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
220 {
221  auto *canvas = static_cast<QListView *>(parent());
222 
223  // TODO can we set wrap text and display alignment somewhere globally?
224  QStyleOptionViewItem newOption = option;
225  newOption.displayAlignment = Qt::AlignHCenter | Qt::AlignTop;
226  newOption.features.setFlag(QStyleOptionViewItem::WrapText);
227 
228  QSize size = m_defaultDelegate->sizeHint(newOption, index);
229  const int gridWidth = canvas->gridSize().width();
230  const int gridHeight = canvas->gridSize().height();
231  size.setWidth(gridWidth - 2 * s_edgePad);
232  size.setHeight(gridHeight - 2 * s_edgePad);
233  QFontMetrics metrics(option.font);
234  size.setHeight(gridHeight + metrics.height() * 3);
235  return size;
236 }
237 
238 // TODO KF6 remove and override KIconDialog::showEvent()
239 class ShowEventFilter : public QObject
240 {
241 public:
242  explicit ShowEventFilter(QObject *parent)
243  : QObject(parent)
244  {
245  }
246  ~ShowEventFilter() override
247  {
248  }
249 
250 private:
251  bool eventFilter(QObject *watched, QEvent *event) override
252  {
253  if (event->type() == QEvent::Show) {
254  KIconDialog *q = static_cast<KIconDialog *>(parent());
255  q->d->showIcons();
256  q->d->ui.searchLine->setFocus();
257  }
258 
259  return QObject::eventFilter(watched, event);
260  }
261 };
262 
263 /*
264  * KIconDialog: Dialog for selecting icons. Both system and user
265  * specified icons can be chosen.
266  */
267 
269  : QDialog(parent)
270  , d(new KIconDialogPrivate(this))
271 {
272  setModal(true);
273 
274  d->mpLoader = KIconLoader::global();
275  d->init();
276 
277  installEventFilter(new ShowEventFilter(this));
278 }
279 
281  : QDialog(parent)
282  , d(new KIconDialogPrivate(this))
283 {
284  setModal(true);
285 
286  d->mpLoader = loader;
287  d->init();
288 
289  installEventFilter(new ShowEventFilter(this));
290 }
291 
292 void KIconDialogPrivate::init()
293 {
294  mGroupOrSize = KIconLoader::Desktop;
295  mContext = KIconLoader::Any;
296 
297  ui.setupUi(q);
298 
299  auto updatePlaceholder = [this] {
300  updatePlaceholderLabel();
301  };
302  QObject::connect(proxyModel, &QSortFilterProxyModel::modelReset, q, updatePlaceholder);
303  QObject::connect(proxyModel, &QSortFilterProxyModel::rowsInserted, q, updatePlaceholder);
304  QObject::connect(proxyModel, &QSortFilterProxyModel::rowsRemoved, q, updatePlaceholder);
305 
306  QAction *findAction = KStandardAction::find(ui.searchLine, qOverload<>(&QWidget::setFocus), q);
307  q->addAction(findAction);
308 
310 
311  static const KLazyLocalizedString context_text[] = {
312  kli18n("All"),
313  kli18n("Actions"),
314  kli18n("Applications"),
315  kli18n("Categories"),
316  kli18n("Devices"),
317  kli18n("Emblems"),
318  kli18n("Emotes"),
319  kli18n("Mimetypes"),
320  kli18n("Places"),
321  kli18n("Status"),
322  };
323  static const KIconLoader::Context context_id[] = {
334  };
335  const int cnt = sizeof(context_text) / sizeof(context_text[0]);
336  for (int i = 0; i < cnt; ++i) {
337  if (mpLoader->hasContext(context_id[i])) {
338  ui.contextCombo->addItem(context_text[i].toString(), context_id[i]);
339  if (i == 0) {
340  ui.contextCombo->insertSeparator(i + 1);
341  }
342  }
343  }
344  ui.contextCombo->insertSeparator(ui.contextCombo->count());
345  ui.contextCombo->addItem(i18nc("Other icons", "Other"));
346  ui.contextCombo->setMaxVisibleItems(ui.contextCombo->count());
347  ui.contextCombo->setFixedSize(ui.contextCombo->sizeHint());
348 
349  QObject::connect(ui.contextCombo, qOverload<int>(&QComboBox::activated), q, [this]() {
350  const auto currentData = ui.contextCombo->currentData();
351  if (currentData.isValid()) {
352  mContext = static_cast<KIconLoader::Context>(ui.contextCombo->currentData().toInt());
353  } else {
354  mContext = static_cast<KIconLoader::Context>(-1);
355  }
356  showIcons();
357  });
358 
359  auto *delegate = new KIconCanvasDelegate(ui.canvas, ui.canvas->itemDelegate());
360  ui.canvas->setItemDelegate(delegate);
361 
362  ui.canvas->setModel(proxyModel);
363 
364  QObject::connect(ui.canvas, &QAbstractItemView::activated, q, [this]() {
365  custom.clear();
366  q->slotOk();
367  });
368 
369  // You can't just stack widgets on top of each other in Qt Designer
370  auto *placeholderLayout = new QVBoxLayout(ui.canvas);
371 
372  placeholderLabel = new QLabel();
373  QFont placeholderLabelFont;
374  // To match the size of a level 2 Heading/KTitleWidget
375  placeholderLabelFont.setPointSize(qRound(placeholderLabelFont.pointSize() * 1.3));
376  placeholderLabel->setFont(placeholderLabelFont);
377  placeholderLabel->setTextInteractionFlags(Qt::NoTextInteraction);
378  placeholderLabel->setWordWrap(true);
379  placeholderLabel->setAlignment(Qt::AlignCenter);
380 
381  // Match opacity of QML placeholder label component
382  auto *effect = new QGraphicsOpacityEffect(placeholderLabel);
383  effect->setOpacity(0.5);
384  placeholderLabel->setGraphicsEffect(effect);
385 
386  updatePlaceholderLabel();
387 
388  placeholderLayout->addWidget(placeholderLabel);
389  placeholderLayout->setAlignment(placeholderLabel, Qt::AlignCenter);
390 
391  // TODO I bet there is a KStandardAction for that?
392  browseButton = new QPushButton(QIcon::fromTheme(QStringLiteral("folder-open")), i18n("Browse…"));
393  // TODO does this have implicatons? I just want the "Browse" button on the left side :)
394  ui.buttonBox->addButton(browseButton, QDialogButtonBox::HelpRole);
395  QObject::connect(browseButton, &QPushButton::clicked, q, [this] {
396  browse();
397  });
398 
399  QObject::connect(ui.buttonBox, &QDialogButtonBox::accepted, q, &KIconDialog::slotOk);
401 
402  q->adjustSize();
403 }
404 
405 KIconDialog::~KIconDialog() = default;
406 
407 static bool sortByFileName(const QString &path1, const QString &path2)
408 {
409  const QString fileName1 = path1.mid(path1.lastIndexOf(QLatin1Char('/')) + 1);
410  const QString fileName2 = path2.mid(path2.lastIndexOf(QLatin1Char('/')) + 1);
411  return QString::compare(fileName1, fileName2, Qt::CaseInsensitive) < 0;
412 }
413 
414 void KIconDialogPrivate::showIcons()
415 {
416  QStringList filelist;
417  if (isSystemIconsContext()) {
418  if (m_bStrictIconSize) {
419  filelist = mpLoader->queryIcons(mGroupOrSize, mContext);
420  } else {
421  filelist = mpLoader->queryIconsByContext(mGroupOrSize, mContext);
422  }
423  } else if (!customLocation.isEmpty()) {
424  filelist = mpLoader->queryIconsByDir(customLocation);
425  } else {
426  // List PNG files found directly in the kiconload search paths.
427  const QStringList pngNameFilter(QStringLiteral("*.png"));
428  for (const QString &relDir : KIconLoader::global()->searchPaths()) {
430  for (const QString &dir : dirs) {
431  const auto files = QDir(dir).entryList(pngNameFilter);
432  for (const QString &fileName : files) {
433  filelist << dir + QLatin1Char('/') + fileName;
434  }
435  }
436  }
437  }
438 
439  std::sort(filelist.begin(), filelist.end(), sortByFileName);
440 
441  // The KIconCanvas has uniformItemSizes set which really expects
442  // all added icons to be the same size, otherwise weirdness ensues :)
443  // Ensure all SVGs are scaled to the desired size and that as few icons
444  // need to be padded as possible by specifying a sensible size.
445  if (mGroupOrSize < -1) {
446  // mGroupOrSize can be -1 if NoGroup is chosen.
447  // Explicit size.
448  ui.canvas->setIconSize(QSize(-mGroupOrSize, -mGroupOrSize));
449  } else {
450  // Icon group.
451  int groupSize = mpLoader->currentSize(static_cast<KIconLoader::Group>(mGroupOrSize));
452  ui.canvas->setIconSize(QSize(groupSize, groupSize));
453  }
454 
455  // Try to make room for three lines of text...
456  QFontMetrics metrics(ui.canvas->font());
457  const int frameHMargin = ui.canvas->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr, ui.canvas) + 1;
458  const int lineCount = 3;
459  ui.canvas->setGridSize(QSize(100, ui.canvas->iconSize().height() + lineCount * metrics.height() + 3 * frameHMargin));
460 
461  // Set a minimum size of 6x3 icons
462  const int columnCount = 6;
463  const int rowCount = 3;
464  QStyleOption opt;
465  opt.initFrom(ui.canvas);
466  int width = columnCount * ui.canvas->gridSize().width();
467  width += ui.canvas->verticalScrollBar()->sizeHint().width() + 1;
468  width += 2 * ui.canvas->frameWidth();
469  if (ui.canvas->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt, ui.canvas)) {
470  width += ui.canvas->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &opt, ui.canvas);
471  }
472  int height = rowCount * ui.canvas->gridSize().height() + 1;
473  height += 2 * ui.canvas->frameWidth();
474 
475  ui.canvas->setMinimumSize(QSize(width, height));
476 
477  model->setIconSize(ui.canvas->iconSize());
478  model->setDevicePixelRatio(q->devicePixelRatioF());
479  model->load(filelist);
480 
481  if (!pendingSelectedIcon.isEmpty()) {
482  selectIcon(pendingSelectedIcon);
483  pendingSelectedIcon.clear();
484  }
485 }
486 
487 bool KIconDialogPrivate::selectIcon(const QString &iconName)
488 {
489  for (int i = 0; i < proxyModel->rowCount(); ++i) {
490  const QModelIndex idx = proxyModel->index(i, 0);
491 
492  QString name = idx.data(KIconDialogModel::PathRole).toString();
493  if (!name.isEmpty() && isSystemIconsContext()) {
494  const QFileInfo fi(name);
495  name = fi.completeBaseName();
496  }
497 
498  if (iconName == name) {
499  ui.canvas->setCurrentIndex(idx);
500  return true;
501  }
502  }
503 
504  return false;
505 }
506 
508 {
509  d->m_bStrictIconSize = b;
510 }
511 
513 {
514  return d->m_bStrictIconSize;
515 }
516 
518 {
519  // see KIconLoader, if you think this is weird
520  if (size == 0) {
521  d->mGroupOrSize = KIconLoader::Desktop; // default Group
522  } else {
523  d->mGroupOrSize = -size; // yes, KIconLoader::queryIconsByContext is weird
524  }
525 }
526 
528 {
529  // 0 or any other value ==> mGroupOrSize is a group, so we return 0
530  return (d->mGroupOrSize < 0) ? -d->mGroupOrSize : 0;
531 }
532 
534 {
535  // TODO Update live when dialog is already open
536  d->pendingSelectedIcon = iconName;
537 }
538 
539 void KIconDialog::setup(KIconLoader::Group group, KIconLoader::Context context, bool strictIconSize, int iconSize, bool user, bool lockUser, bool lockCustomDir)
540 {
541  d->m_bStrictIconSize = strictIconSize;
542  d->m_bLockUser = lockUser;
543  d->m_bLockCustomDir = lockCustomDir;
544  if (iconSize == 0) {
545  if (group == KIconLoader::NoGroup) {
546  // NoGroup has numeric value -1, which should
547  // not really be used with KIconLoader::queryIcons*(...);
548  // pick a proper group.
549  d->mGroupOrSize = KIconLoader::Small;
550  } else {
551  d->mGroupOrSize = group;
552  }
553  } else {
554  d->mGroupOrSize = -iconSize;
555  }
556 
557  if (user) {
558  d->ui.contextCombo->setCurrentIndex(d->ui.contextCombo->count() - 1);
559  } else {
560  d->setContext(context);
561  }
562 
563  d->ui.contextCombo->setEnabled(!user || !lockUser);
564 
565  // Disable "Other" entry when user is locked
566  auto *model = qobject_cast<QStandardItemModel *>(d->ui.contextCombo->model());
567  auto *otherItem = model->item(model->rowCount() - 1);
568  auto flags = otherItem->flags();
569  flags.setFlag(Qt::ItemIsEnabled, !lockUser);
570  otherItem->setFlags(flags);
571 
572  // Only allow browsing when explicitly allowed and user icons are allowed
573  // An app may not expect a path when asking only about system icons
574  d->browseButton->setVisible(!lockCustomDir && (!user || !lockUser));
575 }
576 
577 void KIconDialogPrivate::setContext(KIconLoader::Context context)
578 {
579  mContext = context;
580  const int index = ui.contextCombo->findData(context);
581  if (index > -1) {
582  ui.contextCombo->setCurrentIndex(index);
583  }
584 }
585 
586 void KIconDialogPrivate::updatePlaceholderLabel()
587 {
588  if (proxyModel->rowCount() > 0) {
589  placeholderLabel->hide();
590  return;
591  }
592 
593  if (!ui.searchLine->text().isEmpty()) {
594  placeholderLabel->setText(i18n("No icons matching the search"));
595  } else {
596  placeholderLabel->setText(i18n("No icons in this category"));
597  }
598 
599  placeholderLabel->show();
600 }
601 
603 {
604  d->customLocation = location;
605 }
606 
608 {
609  if (exec() == Accepted) {
610  if (!d->custom.isEmpty()) {
611  return d->custom;
612  }
613 
614  const QString name = d->ui.canvas->currentIndex().data(KIconDialogModel::PathRole).toString();
615  if (name.isEmpty() || !d->ui.contextCombo->currentData().isValid()) {
616  return name;
617  }
618 
619  QFileInfo fi(name);
620  return fi.completeBaseName();
621  }
622 
623  return QString();
624 }
625 
627 {
628  setModal(false);
629  show();
630 }
631 
632 void KIconDialog::slotOk()
633 {
634  QString name;
635  if (!d->custom.isEmpty()) {
636  name = d->custom;
637  } else {
638  name = d->ui.canvas->currentIndex().data(KIconDialogModel::PathRole).toString();
639  if (!name.isEmpty() && d->isSystemIconsContext()) {
640  const QFileInfo fi(name);
641  name = fi.completeBaseName();
642  }
643  }
644 
645  Q_EMIT newIconName(name);
646  QDialog::accept();
647 }
648 
650  KIconLoader::Context context,
651  bool strictIconSize,
652  int iconSize,
653  bool user,
654  QWidget *parent,
655  const QString &title)
656 {
657  KIconDialog dlg(parent);
658  dlg.setup(group, context, strictIconSize, iconSize, user);
659  if (!title.isEmpty()) {
660  dlg.setWindowTitle(title);
661  }
662 
663  return dlg.openDialog();
664 }
665 
666 void KIconDialogPrivate::browse()
667 {
668  if (browseDialog) {
669  browseDialog.data()->show();
670  browseDialog.data()->raise();
671  return;
672  }
673 
674  // Create a file dialog to select an ICO, PNG, XPM or SVG file,
675  // with the image previewer shown.
676  QFileDialog *dlg = new QFileDialog(q, i18n("Select Icon"), QString(), i18n("*.ico *.png *.xpm *.svg *.svgz|Icon Files (*.ico *.png *.xpm *.svg *.svgz)"));
677  // TODO This was deliberately modal before, why? Or just because "window modal" wasn't a thing?
680  QObject::connect(dlg, &QFileDialog::fileSelected, q, [this](const QString &path) {
681  if (!path.isEmpty()) {
682  custom = path;
683  if (isSystemIconsContext()) {
684  customLocation = QFileInfo(custom).absolutePath();
685  }
686  q->slotOk();
687  }
688  });
689  browseDialog = dlg;
690  dlg->show();
691 }
692 
693 bool KIconDialogPrivate::isSystemIconsContext() const
694 {
695  return ui.contextCombo->currentData().isValid();
696 }
697 
698 #include "kicondialog.moc"
699 #include "moc_kicondialog.cpp"
700 #include "moc_kicondialogmodel_p.cpp"
Q_OBJECTQ_OBJECT
@ MimeType
An icon that represents a mime type (or file type).
Definition: kiconloader.h:92
@ StatusIcon
An icon that represents an event.
Definition: kiconloader.h:99
AlignHCenter
QString openDialog()
exec()utes this modal dialog and returns the name of the selected icon, or QString() if the dialog wa...
void setCustomLocation(const QString &location)
Sets the location of the custom icon directory.
DisplayRole
QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags)
Format_ARGB32_Premultiplied
int height() const const
virtual void reject()
CaseInsensitive
void fill(uint pixelValue)
Q_EMITQ_EMIT
int count(const T &value) const const
void setPointSize(int pointSize)
WindowModal
void setIconSize(int size)
Sets the size of the icons to be shown / selected.
void clicked(bool checked)
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const const=0
An icon selection dialog.
Definition: kicondialog.h:32
int pointSize() const const
QIcon fromTheme(const QString &name)
void setup(KIconLoader::Group group, KIconLoader::Context context=KIconLoader::Application, bool strictIconSize=false, int iconSize=0, bool user=false, bool lockUser=false, bool lockCustomDir=false)
Allows you to set the same parameters as in the class method getIcon(), as well as two additional par...
QImage scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const const
void initFrom(const QWidget *widget)
@ Place
An icon that represents a location (e.g. 'home', 'trash').
Definition: kiconloader.h:98
@ Emote
An icon that expresses an emotion.
Definition: kiconloader.h:96
int width() const const
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
void setModal(bool modal)
@ Small
Small icons, e.g. for buttons.
Definition: kiconloader.h:137
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
bool load(QIODevice *device, const char *format)
@ Desktop
Desktop icons.
Definition: kiconloader.h:129
void setWidth(int width)
~KIconDialog() override
Destructs the dialog.
void setDevicePixelRatio(qreal scaleFactor)
@ Any
Some icon with unknown purpose.
Definition: kiconloader.h:82
void setStrictIconSize(bool policy)
Sets a strict icon size policy for allowed icons.
virtual bool eventFilter(QObject *watched, QEvent *event)
QVariant data(int role) const const
@ NoGroup
No group.
Definition: kiconloader.h:127
NoTextInteraction
bool strictIconSize() const
Returns true if a strict icon size policy is set.
void fileSelected(const QString &file)
IgnoreAspectRatio
ItemIsEnabled
@ Category
An icon that represents a category.
Definition: kiconloader.h:94
QString i18n(const char *text, const TYPE &arg...)
@ Action
An action icon (e.g. 'save', 'print').
Definition: kiconloader.h:83
char * toString(const T &value)
void showDialog()
show()s this dialog and emits a newIconName(const QString&) signal when successful.
void installEventFilter(QObject *filterObj)
void textChanged(const QString &text)
bool isEmpty() const const
void setWindowModality(Qt::WindowModality windowModality)
void setWindowTitle(const QString &)
bool isNull() const const
static KIconLoader * global()
Returns the global icon loader initialized with the application name.
virtual void accept()
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
virtual int exec()
void setFilterFixedString(const QString &pattern)
void setFileMode(QFileDialog::FileMode mode)
QAction * find(const QObject *recvr, const char *slot, QObject *parent)
bool isValid() const const
void activated(const QModelIndex &index)
PM_FocusFrameHMargin
void show()
int row() const const
QString completeBaseName() const const
SH_ScrollView_FrameOnlyAroundContents
qreal devicePixelRatioF() const const
@ Application
An icon that represents an application.
Definition: kiconloader.h:84
@ Device
An icon that represents a device.
Definition: kiconloader.h:85
KIOFILEWIDGETS_EXPORT QString dir(const QString &fileClass)
void rowsInserted(const QModelIndex &parent, int first, int last)
void rowsRemoved(const QModelIndex &parent, int first, int last)
static QString getIcon(KIconLoader::Group group=KIconLoader::Desktop, KIconLoader::Context context=KIconLoader::Application, bool strictIconSize=false, int iconSize=0, bool user=false, QWidget *parent=nullptr, const QString &title=QString())
Pops up the dialog an lets the user select an icon.
QString name(StandardShortcut id)
KStandardDirs * dirs()
QStringList locateAll(QStandardPaths::StandardLocation type, const QString &fileName, QStandardPaths::LocateOptions options)
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const const=0
int iconSize() const
Returns the icon size set via setIconSize() or 0, if the default icon size will be used.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QList::iterator begin()
void setSelectedIcon(const QString &iconName)
Sets the icon that is initially selected in the dialog.
Context
Defines the context of the icon.
Definition: kiconloader.h:81
Group
The group of the icon.
Definition: kiconloader.h:125
QChar * data()
int compare(const QString &other, Qt::CaseSensitivity cs) const const
@ Emblem
An icon that adds information to an existing icon.
Definition: kiconloader.h:95
QStringList entryList(QDir::Filters filters, QDir::SortFlags sort) const const
QList::iterator end()
SmoothTransformation
QString mid(int position, int n) const const
void setFocus()
void activated(int index)
QObject * parent() const const
void setHeight(int height)
transparent
QString toString() const const
KIconDialog(QWidget *parent=nullptr)
Constructs an icon selection dialog using the global icon loader.
int width() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Wed Aug 17 2022 03:55:39 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.