Kirigami2

icon.cpp
1 /*
2  * SPDX-FileCopyrightText: 2011 Marco Martin <[email protected]>
3  * SPDX-FileCopyrightText: 2014 Aleix Pol Gonzalez <[email protected]>
4  *
5  * SPDX-License-Identifier: LGPL-2.0-or-later
6  */
7 
8 #include "icon.h"
9 #include "libkirigami/platformtheme.h"
10 #include "scenegraph/managedtexturenode.h"
11 
12 #include "loggingcategory.h"
13 #include <QBitmap>
14 #include <QDebug>
15 #include <QGuiApplication>
16 #include <QIcon>
17 #include <QNetworkReply>
18 #include <QPainter>
19 #include <QQuickImageProvider>
20 #include <QQuickWindow>
21 #include <QSGSimpleTextureNode>
22 #include <QSGTexture>
23 #include <QScreen>
24 
25 #include <cmath>
26 
27 Q_GLOBAL_STATIC(ImageTexturesCache, s_iconImageCache)
28 
29 Icon::Icon(QQuickItem *parent)
30  : QQuickItem(parent)
31  , m_changed(false)
32  , m_active(false)
33  , m_selected(false)
34  , m_isMask(false)
35 {
36  setFlag(ItemHasContents, true);
37  // Using 32 because Icon used to redefine implicitWidth and implicitHeight and hardcode them to 32
38  setImplicitSize(32, 32);
39  // FIXME: not necessary anymore
41  connect(this, &QQuickItem::enabledChanged, this, &QQuickItem::polish);
42  connect(this, &QQuickItem::smoothChanged, this, &QQuickItem::polish);
43 }
44 
45 Icon::~Icon()
46 {
47 }
48 
49 void Icon::setSource(const QVariant &icon)
50 {
51  if (m_source == icon) {
52  return;
53  }
54  m_source = icon;
55  m_monochromeHeuristics.clear();
56 
57  if (!m_theme) {
58  m_theme = static_cast<Kirigami::PlatformTheme *>(qmlAttachedPropertiesObject<Kirigami::PlatformTheme>(this, true));
59  Q_ASSERT(m_theme);
60 
61  connect(m_theme, &Kirigami::PlatformTheme::colorsChanged, this, &QQuickItem::polish);
62  }
63 
64  if (icon.type() == QVariant::String) {
65  const QString iconSource = icon.toString();
66  updateIsMaskHeuristic(iconSource);
67  Q_EMIT isMaskChanged();
68  }
69 
70  if (m_networkReply) {
71  // if there was a network query going on, interrupt it
72  m_networkReply->close();
73  }
74  m_loadedImage = QImage();
75  setStatus(Loading);
76 
77  polish();
78  Q_EMIT sourceChanged();
79  Q_EMIT validChanged();
80 }
81 
82 QVariant Icon::source() const
83 {
84  return m_source;
85 }
86 
87 void Icon::setActive(const bool active)
88 {
89  if (active == m_active) {
90  return;
91  }
92  m_active = active;
93  polish();
94  Q_EMIT activeChanged();
95 }
96 
97 bool Icon::active() const
98 {
99  return m_active;
100 }
101 
102 bool Icon::valid() const
103 {
104  // TODO: should this be return m_status == Ready?
105  // Consider an empty URL invalid, even though isNull() will say false
106  if (m_source.canConvert<QUrl>() && m_source.toUrl().isEmpty()) {
107  return false;
108  }
109 
110  return !m_source.isNull();
111 }
112 
113 void Icon::setSelected(const bool selected)
114 {
115  if (selected == m_selected) {
116  return;
117  }
118  m_selected = selected;
119  polish();
120  Q_EMIT selectedChanged();
121 }
122 
123 bool Icon::selected() const
124 {
125  return m_selected;
126 }
127 
128 void Icon::setIsMask(bool mask)
129 {
130  if (m_isMask == mask) {
131  return;
132  }
133 
134  m_isMask = mask;
135  m_isMaskHeuristic = mask;
136  polish();
137  Q_EMIT isMaskChanged();
138 }
139 
140 bool Icon::isMask() const
141 {
142  return m_isMask || m_isMaskHeuristic;
143 }
144 
145 void Icon::setColor(const QColor &color)
146 {
147  if (m_color == color) {
148  return;
149  }
150 
151  m_color = color;
152  polish();
153  Q_EMIT colorChanged();
154 }
155 
156 QColor Icon::color() const
157 {
158  return m_color;
159 }
160 
161 QSGNode *Icon::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData * /*data*/)
162 {
163  if (m_source.isNull() || qFuzzyIsNull(width()) || qFuzzyIsNull(height())) {
164  delete node;
165  return Q_NULLPTR;
166  }
167 
168  if (m_changed || node == nullptr) {
169  const QSize itemSize(width(), height());
170  QRect nodeRect(QPoint(0, 0), itemSize);
171 
172  ManagedTextureNode *mNode = dynamic_cast<ManagedTextureNode *>(node);
173  if (!mNode) {
174  delete node;
175  mNode = new ManagedTextureNode;
176  }
177  if (itemSize.width() != 0 && itemSize.height() != 0) {
178  mNode->setTexture(s_iconImageCache->loadTexture(window(), m_icon, QQuickWindow::TextureCanUseAtlas));
179  if (m_icon.size() != itemSize) {
180  // At this point, the image will already be scaled, but we need to output it in
181  // the correct aspect ratio, painted centered in the viewport. So:
182  QRect destination(QPoint(0, 0), m_icon.size().scaled(itemSize, Qt::KeepAspectRatio));
183  destination.moveCenter(nodeRect.center());
184  nodeRect = destination;
185  }
186  }
187  mNode->setRect(nodeRect);
188  node = mNode;
189  if (smooth()) {
191  }
192  m_changed = false;
193  }
194 
195  return node;
196 }
197 
198 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
199 void Icon::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
200 {
201  QQuickItem::geometryChanged(newGeometry, oldGeometry);
202 #else
203 void Icon::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
204 {
205  QQuickItem::geometryChange(newGeometry, oldGeometry);
206 #endif
207  if (newGeometry.size() != oldGeometry.size()) {
208  polish();
209  }
210 }
211 
212 void Icon::handleRedirect(QNetworkReply *reply)
213 {
214  QNetworkAccessManager *qnam = reply->manager();
215  if (reply->error() != QNetworkReply::NoError) {
216  return;
217  }
218  const QUrl possibleRedirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
219  if (!possibleRedirectUrl.isEmpty()) {
220  const QUrl redirectUrl = reply->url().resolved(possibleRedirectUrl);
221  if (redirectUrl == reply->url()) {
222  // no infinite redirections thank you very much
223  reply->deleteLater();
224  return;
225  }
226  reply->deleteLater();
227  QNetworkRequest request(possibleRedirectUrl);
229  m_networkReply = qnam->get(request);
230  connect(m_networkReply.data(), &QNetworkReply::finished, this, [this]() {
231  handleFinished(m_networkReply);
232  });
233  }
234 }
235 
236 void Icon::handleFinished(QNetworkReply *reply)
237 {
238  if (!reply) {
239  return;
240  }
241 
242  reply->deleteLater();
244  handleRedirect(reply);
245  return;
246  }
247 
248  m_loadedImage = QImage();
249 
250  const QString filename = reply->url().fileName();
251  if (!m_loadedImage.load(reply, filename.mid(filename.indexOf(QLatin1Char('.'))).toLatin1().constData())) {
252  qCWarning(KirigamiLog) << "received broken image" << reply->url();
253 
254  // broken image from data, inform the user of this with some useful broken-image thing...
255  const QIcon icon = QIcon::fromTheme(m_fallback);
256  m_loadedImage = icon.pixmap(window(), icon.actualSize(size().toSize()), iconMode(), QIcon::On).toImage();
257  }
258 
259  polish();
260 }
261 
262 void Icon::updatePolish()
263 {
265 
266  if (m_source.isNull()) {
267  setStatus(Ready);
268  updatePaintedGeometry();
269  update();
270  return;
271  }
272 
273  const QSize itemSize(width(), height());
274  if (itemSize.width() != 0 && itemSize.height() != 0) {
276  ? 1
277  : (window() ? window()->effectiveDevicePixelRatio() : qGuiApp->devicePixelRatio());
278  const QSize size = itemSize * multiplier;
279 
280  switch (m_source.type()) {
281  case QVariant::Pixmap:
282  m_icon = m_source.value<QPixmap>().toImage();
283  break;
284  case QVariant::Image:
285  m_icon = m_source.value<QImage>();
286  break;
287  case QVariant::Bitmap:
288  m_icon = m_source.value<QBitmap>().toImage();
289  break;
290  case QVariant::Icon: {
291  const QIcon icon = m_source.value<QIcon>();
292  m_icon = icon.pixmap(window(), icon.actualSize(itemSize), iconMode(), QIcon::On).toImage();
293  break;
294  }
295  case QVariant::Url:
296  case QVariant::String:
297  m_icon = findIcon(size);
298  break;
299  case QVariant::Brush:
300  // todo: fill here too?
301  case QVariant::Color:
302  m_icon = QImage(size, QImage::Format_Alpha8);
303  m_icon.fill(m_source.value<QColor>());
304  break;
305  default:
306  break;
307  }
308 
309  if (m_icon.isNull()) {
310  m_icon = QImage(size, QImage::Format_Alpha8);
311  m_icon.fill(Qt::transparent);
312  }
313 
314  const QColor tintColor = //
315  !m_color.isValid() || m_color == Qt::transparent //
316  ? (m_selected ? m_theme->highlightedTextColor() : m_theme->textColor())
317  : m_color;
318 
319  // TODO: initialize m_isMask with icon.isMask()
320  if (tintColor.alpha() > 0 && (isMask() || guessMonochrome(m_icon))) {
321  QPainter p(&m_icon);
322  p.setCompositionMode(QPainter::CompositionMode_SourceIn);
323  p.fillRect(m_icon.rect(), tintColor);
324  p.end();
325  }
326  }
327  m_changed = true;
328  updatePaintedGeometry();
329  update();
330 }
331 
332 QImage Icon::findIcon(const QSize &size)
333 {
334  QImage img;
335  QString iconSource = m_source.toString();
336 
337  if (iconSource.startsWith(QLatin1String("image://"))) {
339  ? (window() ? window()->effectiveDevicePixelRatio() : qGuiApp->devicePixelRatio())
340  : 1;
341  QUrl iconUrl(iconSource);
342  QString iconProviderId = iconUrl.host();
343  // QUrl path has the "/" prefix while iconId does not
344  QString iconId = iconUrl.path().remove(0, 1);
345 
347  QQuickImageProvider *imageProvider = dynamic_cast<QQuickImageProvider *>(qmlEngine(this)->imageProvider(iconProviderId));
348  if (!imageProvider) {
349  return img;
350  }
351  switch (imageProvider->imageType()) {
353  img = imageProvider->requestImage(iconId, &actualSize, size * multiplier);
354  if (!img.isNull()) {
355  setStatus(Ready);
356  }
357  break;
359  img = imageProvider->requestPixmap(iconId, &actualSize, size * multiplier).toImage();
360  if (!img.isNull()) {
361  setStatus(Ready);
362  }
363  break;
365  if (!m_loadedImage.isNull()) {
366  setStatus(Ready);
367  return m_loadedImage.scaled(size, Qt::KeepAspectRatio, smooth() ? Qt::SmoothTransformation : Qt::FastTransformation);
368  }
369  QQuickAsyncImageProvider *provider = dynamic_cast<QQuickAsyncImageProvider *>(imageProvider);
370  auto response = provider->requestImageResponse(iconId, size * multiplier);
371  connect(response, &QQuickImageResponse::finished, this, [iconId, response, this]() {
372  if (response->errorString().isEmpty()) {
373  QQuickTextureFactory *textureFactory = response->textureFactory();
374  if (textureFactory) {
375  m_loadedImage = textureFactory->image();
376  delete textureFactory;
377  }
378  if (m_loadedImage.isNull()) {
379  // broken image from data, inform the user of this with some useful broken-image thing...
380  const QIcon icon = QIcon::fromTheme(m_fallback);
381  m_loadedImage = icon.pixmap(window(), icon.actualSize(QSize(width(), height())), iconMode(), QIcon::On).toImage();
382  setStatus(Error);
383  } else {
384  setStatus(Ready);
385  }
386  polish();
387  }
388  response->deleteLater();
389  });
390  // Temporary icon while we wait for the real image to load...
391  const QIcon icon = QIcon::fromTheme(m_placeholder);
392  img = icon.pixmap(window(), icon.actualSize(size), iconMode(), QIcon::On).toImage();
393  break;
394  }
396  QQuickTextureFactory *textureFactory = imageProvider->requestTexture(iconId, &actualSize, size * multiplier);
397  if (textureFactory) {
398  img = textureFactory->image();
399  }
400  if (img.isNull()) {
401  // broken image from data, or the texture factory wasn't healthy, inform the user of this with some useful broken-image thing...
402  const QIcon icon = QIcon::fromTheme(m_fallback);
403  img = icon.pixmap(window(), icon.actualSize(QSize(width(), height())), iconMode(), QIcon::On).toImage();
404  setStatus(Error);
405  } else {
406  setStatus(Ready);
407  }
408  break;
409  }
411  // will have to investigate this more
412  setStatus(Error);
413  break;
414  }
415  } else if (iconSource.startsWith(QLatin1String("http://")) || iconSource.startsWith(QLatin1String("https://"))) {
416  if (!m_loadedImage.isNull()) {
417  setStatus(Ready);
418  return m_loadedImage.scaled(size, Qt::KeepAspectRatio, smooth() ? Qt::SmoothTransformation : Qt::FastTransformation);
419  }
420  const auto url = m_source.toUrl();
421  QQmlEngine *engine = qmlEngine(this);
422  QNetworkAccessManager *qnam;
423  if (engine && (qnam = engine->networkAccessManager()) && (!m_networkReply || m_networkReply->url() != url)) {
424  QNetworkRequest request(url);
426  m_networkReply = qnam->get(request);
427  connect(m_networkReply.data(), &QNetworkReply::finished, this, [this]() {
428  handleFinished(m_networkReply);
429  });
430  }
431  // Temporary icon while we wait for the real image to load...
432  const QIcon icon = QIcon::fromTheme(m_placeholder);
433  img = icon.pixmap(window(), icon.actualSize(size), iconMode(), QIcon::On).toImage();
434  } else {
435  if (iconSource.startsWith(QLatin1String("qrc:/"))) {
436  iconSource = iconSource.mid(3);
437  } else if (iconSource.startsWith(QLatin1String("file:/"))) {
438  iconSource = QUrl(iconSource).path();
439  }
440 
441  QIcon icon;
442  const bool isPath = iconSource.contains(QLatin1String("/"));
443  if (isPath) {
444  icon = QIcon(iconSource);
445  } else {
446  if (icon.isNull()) {
447  icon = m_theme->iconFromTheme(iconSource, m_color);
448  if (m_isMaskHeuristic && icon.name() != iconSource) {
449  updateIsMaskHeuristic(icon.name());
450  if (!m_isMaskHeuristic) {
451  Q_EMIT isMaskChanged();
452  }
453  }
454  }
455  }
456  if (!icon.isNull()) {
457  img = icon.pixmap(window(), icon.actualSize(window(), size), iconMode(), QIcon::On).toImage();
458 
459  setStatus(Ready);
460  /*const QColor tintColor = !m_color.isValid() || m_color == Qt::transparent ? (m_selected ? m_theme->highlightedTextColor() : m_theme->textColor())
461  : m_color;
462 
463  if (m_isMask || icon.isMask() || iconSource.endsWith(QLatin1String("-symbolic")) || iconSource.endsWith(QLatin1String("-symbolic-rtl")) ||
464  iconSource.endsWith(QLatin1String("-symbolic-ltr")) || guessMonochrome(img)) { //
465  QPainter p(&img);
466  p.setCompositionMode(QPainter::CompositionMode_SourceIn);
467  p.fillRect(img.rect(), tintColor);
468  p.end();
469  }*/
470  }
471  }
472 
473  if (!iconSource.isEmpty() && img.isNull()) {
474  setStatus(Error);
475  const QIcon icon = QIcon::fromTheme(m_fallback);
476  img = icon.pixmap(window(), icon.actualSize(size), iconMode(), QIcon::On).toImage();
477  }
478  return img;
479 }
480 
481 QIcon::Mode Icon::iconMode() const
482 {
483  if (!isEnabled()) {
484  return QIcon::Disabled;
485  } else if (m_selected) {
486  return QIcon::Selected;
487  } else if (m_active) {
488  return QIcon::Active;
489  }
490  return QIcon::Normal;
491 }
492 
493 bool Icon::guessMonochrome(const QImage &img)
494 {
495  // don't try for too big images
496  if (img.width() >= 256 || m_theme->supportsIconColoring()) {
497  return false;
498  }
499  // round size to a standard size. hardcode as we can't use KIconLoader
500  int stdSize;
501  if (img.width() <= 16) {
502  stdSize = 16;
503  } else if (img.width() <= 22) {
504  stdSize = 22;
505  } else if (img.width() <= 24) {
506  stdSize = 24;
507  } else if (img.width() <= 32) {
508  stdSize = 32;
509  } else if (img.width() <= 48) {
510  stdSize = 48;
511  } else if (img.width() <= 64) {
512  stdSize = 64;
513  } else {
514  stdSize = 128;
515  }
516 
517  auto findIt = m_monochromeHeuristics.constFind(stdSize);
518  if (findIt != m_monochromeHeuristics.constEnd()) {
519  return findIt.value();
520  }
521 
522  QHash<int, int> dist;
523  int transparentPixels = 0;
524  int saturatedPixels = 0;
525  for (int x = 0; x < img.width(); x++) {
526  for (int y = 0; y < img.height(); y++) {
527  QColor color = QColor::fromRgba(qUnpremultiply(img.pixel(x, y)));
528  if (color.alpha() < 100) {
529  ++transparentPixels;
530  continue;
531  } else if (color.saturation() > 84) {
532  ++saturatedPixels;
533  }
534  dist[qGray(color.rgb())]++;
535  }
536  }
537 
538  QMultiMap<int, int> reverseDist;
539  auto it = dist.constBegin();
540  qreal entropy = 0;
541  while (it != dist.constEnd()) {
542  reverseDist.insert(it.value(), it.key());
543  qreal probability = qreal(it.value()) / qreal(img.size().width() * img.size().height() - transparentPixels);
544  entropy -= probability * log(probability) / log(255);
545  ++it;
546  }
547 
548  // Arbitrarily low values of entropy and colored pixels
549  m_monochromeHeuristics[stdSize] = saturatedPixels <= (img.size().width() * img.size().height() - transparentPixels) * 0.3 && entropy <= 0.3;
550  return m_monochromeHeuristics[stdSize];
551 }
552 
553 QString Icon::fallback() const
554 {
555  return m_fallback;
556 }
557 
558 void Icon::setFallback(const QString &fallback)
559 {
560  if (m_fallback != fallback) {
561  m_fallback = fallback;
562  Q_EMIT fallbackChanged(fallback);
563  }
564 }
565 
567 {
568  return m_placeholder;
569 }
570 
571 void Icon::setPlaceholder(const QString &placeholder)
572 {
573  if (m_placeholder != placeholder) {
574  m_placeholder = placeholder;
575  Q_EMIT placeholderChanged(placeholder);
576  }
577 }
578 
579 void Icon::setStatus(Status status)
580 {
581  if (status == m_status) {
582  return;
583  }
584 
585  m_status = status;
586  Q_EMIT statusChanged();
587 }
588 
590 {
591  return m_status;
592 }
593 
594 qreal Icon::paintedWidth() const
595 {
596  return m_paintedWidth;
597 }
598 
599 qreal Icon::paintedHeight() const
600 {
601  return m_paintedHeight;
602 }
603 
604 void Icon::updatePaintedGeometry()
605 {
606  qreal newWidth = 0.0;
607  qreal newHeight = 0.0;
608  if (!m_icon.width() || !m_icon.height()) {
609  newWidth = newHeight = 0.0;
610  } else {
611  const qreal w = widthValid() ? width() : m_icon.size().width();
612  const qreal widthScale = w / m_icon.size().width();
613  const qreal h = heightValid() ? height() : m_icon.size().height();
614  const qreal heightScale = h / m_icon.size().height();
615  if (widthScale <= heightScale) {
616  newWidth = w;
617  newHeight = widthScale * m_icon.size().height();
618  } else if (heightScale < widthScale) {
619  newWidth = heightScale * m_icon.size().width();
620  newHeight = h;
621  }
622  }
623  if (newWidth != m_paintedWidth || newHeight != m_paintedHeight) {
624  m_paintedWidth = newWidth;
625  m_paintedHeight = newHeight;
626  Q_EMIT paintedAreaChanged();
627  }
628 }
629 
630 void Icon::updateIsMaskHeuristic(const QString &iconSource)
631 {
632  m_isMaskHeuristic = (iconSource.endsWith(QLatin1String("-symbolic")) //
633  || iconSource.endsWith(QLatin1String("-symbolic-rtl")) //
634  || iconSource.endsWith(QLatin1String("-symbolic-ltr")));
635 }
636 
637 void Icon::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
638 {
640  polish();
641  }
642  QQuickItem::itemChange(change, value);
643 }
644 
645 #include "moc_icon.cpp"
bool isNull() const const
Status
This enum indicates the current status of the icon.
Definition: icon.h:185
void paletteChanged(const QPalette &palette)
int devicePixelRatio() const const
virtual void updatePolish()
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const const
QString name() const const
void enabledChanged()
int height() const const
QUrl toUrl() const const
QNetworkReply::NetworkError error() const const
AA_UseHighDpiPixmaps
QRgb rgb() const const
bool valid
This property specifies whether the icon's source is valid and is being used.
Definition: icon.h:103
QIcon fromTheme(const QString &name)
void setRect(const QRectF &r)
int width() const const
QColor fromRgba(QRgb rgba)
void polish()
virtual QQmlImageProviderBase::ImageType imageType() const const override
QNetworkReply * get(const QNetworkRequest &request)
QString placeholder
This property holds the name of an icon from the icon theme to show while the icon set in source is b...
Definition: icon.h:81
Q_GLOBAL_STATIC(Internal::StaticControl, s_instance) class ControlPrivate
QNetworkAccessManager * manager() const const
QUrl url() const const
int saturation() const const
bool isMask
This property sets whether this icon will be treated as a mask.
Definition: icon.h:131
virtual QQuickTextureFactory * requestTexture(const QString &id, QSize *size, const QSize &requestedSize)
void deleteLater()
virtual QQuickImageResponse * requestImageResponse(const QString &id, const QSize &requestedSize)=0
bool selected
This property sets whether the icon will use the QIcon.Selected mode, resulting in a graphical effec...
Definition: icon.h:119
KeepAspectRatio
QRgb pixel(int x, int y) const const
QColor color
This property holds the color to use when drawing the icon.
Definition: icon.h:144
bool isEmpty() const const
int height() const const
QVariant::Type type() const const
QHash::const_iterator constBegin() const const
virtual void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
QHash::const_iterator constEnd() const const
virtual QImage image() const const
bool isNull() const const
bool isEmpty() const const
QString fileName(QUrl::ComponentFormattingOptions options) const const
bool isNull() const const
QCoreApplication * instance()
Q_SCRIPTABLE CaptureState status()
int alpha() const const
bool active
This property sets whether the icon will use the QIcon.Active mode, resulting in a graphical effect ...
Definition: icon.h:98
virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
void clear()
bool testAttribute(Qt::ApplicationAttribute attribute)
QSize size() const const
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
typename QMap< Key, T >::iterator insert(const Key &key, const T &value)
QUrl resolved(const QUrl &relative) const const
QImage toImage() const const
QString & remove(int position, int n)
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
QVariant attribute(QNetworkRequest::Attribute code) const const
QAction * actualSize(const QObject *recvr, const char *slot, QObject *parent)
QString fallback
This property holds the name of an icon from the icon theme as a fallback for when an icon set with t...
Definition: icon.h:66
QString path(QUrl::ComponentFormattingOptions options) const const
qreal paintedWidth
This property holds the width of the painted area in pixels.
Definition: icon.h:168
QNetworkAccessManager * networkAccessManager() const const
QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) const const
virtual QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
void update(Part *part, const QByteArray &data, qint64 dataSize)
bool isValid() const const
Icon::Status status
This property specifies the status of the icon.
Definition: icon.h:156
qreal paintedHeight
This property holds the height of the painted area in pixels.
Definition: icon.h:180
QSizeF size() const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
KJOBWIDGETS_EXPORT QWidget * window(KJob *job)
CompositionMode_SourceIn
SmoothTransformation
void smoothChanged(bool)
QString mid(int position, int n) const const
QVariant source
This property holds the source of this icon.
Definition: icon.h:57
QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) const const
void setFiltering(QSGTexture::Filtering filtering)
transparent
virtual QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize)
QString toString() const const
int width() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Fri Dec 1 2023 04:01:53 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.