/****************************************************************************+ −
**+ −
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).+ −
** All rights reserved.+ −
** Contact: Nokia Corporation (qt-info@nokia.com)+ −
**+ −
** This file is part of the QtGui module of the Qt Toolkit.+ −
**+ −
** $QT_BEGIN_LICENSE:LGPL$+ −
** No Commercial Usage+ −
** This file contains pre-release code and may not be distributed.+ −
** You may use this file in accordance with the terms and conditions+ −
** contained in the Technology Preview License Agreement accompanying+ −
** this package.+ −
**+ −
** GNU Lesser General Public License Usage+ −
** Alternatively, this file may be used under the terms of the GNU Lesser+ −
** General Public License version 2.1 as published by the Free Software+ −
** Foundation and appearing in the file LICENSE.LGPL included in the+ −
** packaging of this file. Please review the following information to+ −
** ensure the GNU Lesser General Public License version 2.1 requirements+ −
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.+ −
**+ −
** In addition, as a special exception, Nokia gives you certain additional+ −
** rights. These rights are described in the Nokia Qt LGPL Exception+ −
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.+ −
**+ −
** If you have questions regarding the use of this file, please contact+ −
** Nokia at qt-info@nokia.com.+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
** $QT_END_LICENSE$+ −
**+ −
****************************************************************************/+ −
+ −
#include "qicon.h"+ −
#include "qicon_p.h"+ −
#include "qiconengine.h"+ −
#include "qiconengineplugin.h"+ −
#include "private/qfactoryloader_p.h"+ −
#include "private/qiconloader_p.h"+ −
#include "qapplication.h"+ −
#include "qstyleoption.h"+ −
#include "qpainter.h"+ −
#include "qfileinfo.h"+ −
#include "qstyle.h"+ −
#include "qpixmapcache.h"+ −
#include "qvariant.h"+ −
#include "qcache.h"+ −
#include "qdebug.h"+ −
#include "private/qguiplatformplugin_p.h"+ −
+ −
#ifdef Q_WS_MAC+ −
#include <private/qt_mac_p.h>+ −
#include <private/qt_cocoa_helpers_mac_p.h>+ −
#endif+ −
+ −
#ifdef Q_WS_X11+ −
#include "private/qt_x11_p.h"+ −
#include "private/qkde_p.h"+ −
#endif+ −
+ −
#ifndef QT_NO_ICON+ −
QT_BEGIN_NAMESPACE+ −
+ −
/*!+ −
\enum QIcon::Mode+ −
+ −
This enum type describes the mode for which a pixmap is intended+ −
to be used. The currently defined modes are:+ −
+ −
\value Normal+ −
Display the pixmap when the user is+ −
not interacting with the icon, but the+ −
functionality represented by the icon is available.+ −
\value Disabled+ −
Display the pixmap when the+ −
functionality represented by the icon is not available.+ −
\value Active+ −
Display the pixmap when the+ −
functionality represented by the icon is available and+ −
the user is interacting with the icon, for example, moving the+ −
mouse over it or clicking it.+ −
\value Selected+ −
Display the pixmap when the item represented by the icon is+ −
selected.+ −
*/+ −
+ −
/*!+ −
\enum QIcon::State+ −
+ −
This enum describes the state for which a pixmap is intended to be+ −
used. The \e state can be:+ −
+ −
\value Off Display the pixmap when the widget is in an "off" state+ −
\value On Display the pixmap when the widget is in an "on" state+ −
*/+ −
+ −
static QBasicAtomicInt serialNumCounter = Q_BASIC_ATOMIC_INITIALIZER(1);+ −
+ −
static void qt_cleanup_icon_cache();+ −
typedef QCache<QString, QIcon> IconCache;+ −
Q_GLOBAL_STATIC_WITH_INITIALIZER(IconCache, qtIconCache, qAddPostRoutine(qt_cleanup_icon_cache))+ −
+ −
static void qt_cleanup_icon_cache()+ −
{+ −
qtIconCache()->clear();+ −
}+ −
+ −
QIconPrivate::QIconPrivate()+ −
: engine(0), ref(1),+ −
serialNum(serialNumCounter.fetchAndAddRelaxed(1)),+ −
detach_no(0),+ −
engine_version(2),+ −
v1RefCount(0)+ −
{+ −
}+ −
+ −
QPixmapIconEngine::QPixmapIconEngine()+ −
{+ −
}+ −
+ −
QPixmapIconEngine::QPixmapIconEngine(const QPixmapIconEngine &other)+ −
: QIconEngineV2(other), pixmaps(other.pixmaps)+ −
{+ −
}+ −
+ −
QPixmapIconEngine::~QPixmapIconEngine()+ −
{+ −
}+ −
+ −
void QPixmapIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state)+ −
{+ −
QSize pixmapSize = rect.size();+ −
#if defined(Q_WS_MAC)+ −
pixmapSize *= qt_mac_get_scalefactor();+ −
#endif+ −
painter->drawPixmap(rect, pixmap(pixmapSize, mode, state));+ −
}+ −
+ −
static inline int area(const QSize &s) { return s.width() * s.height(); }+ −
+ −
// returns the smallest of the two that is still larger than or equal to size.+ −
static QPixmapIconEngineEntry *bestSizeMatch( const QSize &size, QPixmapIconEngineEntry *pa, QPixmapIconEngineEntry *pb)+ −
{+ −
int s = area(size);+ −
if (pa->size == QSize() && pa->pixmap.isNull()) {+ −
pa->pixmap = QPixmap(pa->fileName);+ −
pa->size = pa->pixmap.size();+ −
}+ −
int a = area(pa->size);+ −
if (pb->size == QSize() && pb->pixmap.isNull()) {+ −
pb->pixmap = QPixmap(pb->fileName);+ −
pb->size = pb->pixmap.size();+ −
}+ −
int b = area(pb->size);+ −
int res = a;+ −
if (qMin(a,b) >= s)+ −
res = qMin(a,b);+ −
else+ −
res = qMax(a,b);+ −
if (res == a)+ −
return pa;+ −
return pb;+ −
}+ −
+ −
QPixmapIconEngineEntry *QPixmapIconEngine::tryMatch(const QSize &size, QIcon::Mode mode, QIcon::State state)+ −
{+ −
QPixmapIconEngineEntry *pe = 0;+ −
for (int i = 0; i < pixmaps.count(); ++i)+ −
if (pixmaps.at(i).mode == mode && pixmaps.at(i).state == state) {+ −
if (pe)+ −
pe = bestSizeMatch(size, &pixmaps[i], pe);+ −
else+ −
pe = &pixmaps[i];+ −
}+ −
return pe;+ −
}+ −
+ −
+ −
QPixmapIconEngineEntry *QPixmapIconEngine::bestMatch(const QSize &size, QIcon::Mode mode, QIcon::State state, bool sizeOnly)+ −
{+ −
QPixmapIconEngineEntry *pe = tryMatch(size, mode, state);+ −
while (!pe){+ −
QIcon::State oppositeState = (state == QIcon::On) ? QIcon::Off : QIcon::On;+ −
if (mode == QIcon::Disabled || mode == QIcon::Selected) {+ −
QIcon::Mode oppositeMode = (mode == QIcon::Disabled) ? QIcon::Selected : QIcon::Disabled;+ −
if ((pe = tryMatch(size, QIcon::Normal, state)))+ −
break;+ −
if ((pe = tryMatch(size, QIcon::Active, state)))+ −
break;+ −
if ((pe = tryMatch(size, mode, oppositeState)))+ −
break;+ −
if ((pe = tryMatch(size, QIcon::Normal, oppositeState)))+ −
break;+ −
if ((pe = tryMatch(size, QIcon::Active, oppositeState)))+ −
break;+ −
if ((pe = tryMatch(size, oppositeMode, state)))+ −
break;+ −
if ((pe = tryMatch(size, oppositeMode, oppositeState)))+ −
break;+ −
} else {+ −
QIcon::Mode oppositeMode = (mode == QIcon::Normal) ? QIcon::Active : QIcon::Normal;+ −
if ((pe = tryMatch(size, oppositeMode, state)))+ −
break;+ −
if ((pe = tryMatch(size, mode, oppositeState)))+ −
break;+ −
if ((pe = tryMatch(size, oppositeMode, oppositeState)))+ −
break;+ −
if ((pe = tryMatch(size, QIcon::Disabled, state)))+ −
break;+ −
if ((pe = tryMatch(size, QIcon::Selected, state)))+ −
break;+ −
if ((pe = tryMatch(size, QIcon::Disabled, oppositeState)))+ −
break;+ −
if ((pe = tryMatch(size, QIcon::Selected, oppositeState)))+ −
break;+ −
}+ −
+ −
if (!pe)+ −
return pe;+ −
}+ −
+ −
if (sizeOnly ? (pe->size.isNull() || !pe->size.isValid()) : pe->pixmap.isNull()) {+ −
pe->pixmap = QPixmap(pe->fileName);+ −
if (!pe->pixmap.isNull())+ −
pe->size = pe->pixmap.size();+ −
}+ −
+ −
return pe;+ −
}+ −
+ −
QPixmap QPixmapIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state)+ −
{+ −
QPixmap pm;+ −
QPixmapIconEngineEntry *pe = bestMatch(size, mode, state, false);+ −
if (pe)+ −
pm = pe->pixmap;+ −
+ −
if (pm.isNull()) {+ −
int idx = pixmaps.count();+ −
while (--idx >= 0) {+ −
if (pe == &pixmaps[idx]) {+ −
pixmaps.remove(idx);+ −
break;+ −
}+ −
}+ −
if (pixmaps.isEmpty())+ −
return pm;+ −
else+ −
return pixmap(size, mode, state);+ −
}+ −
+ −
QSize actualSize = pm.size();+ −
if (!actualSize.isNull() && (actualSize.width() > size.width() || actualSize.height() > size.height()))+ −
actualSize.scale(size, Qt::KeepAspectRatio);+ −
+ −
QString key = QLatin1String("$qt_icon_")+ −
+ QString::number(pm.cacheKey())+ −
+ QString::number(pe->mode)+ −
+ QString::number(QApplication::palette().cacheKey())+ −
+ QLatin1Char('_')+ −
+ QString::number(actualSize.width())+ −
+ QLatin1Char('_')+ −
+ QString::number(actualSize.height())+ −
+ QLatin1Char('_');+ −
+ −
+ −
if (mode == QIcon::Active) {+ −
if (QPixmapCache::find(key + QString::number(mode), pm))+ −
return pm; // horray+ −
if (QPixmapCache::find(key + QString::number(QIcon::Normal), pm)) {+ −
QStyleOption opt(0);+ −
opt.palette = QApplication::palette();+ −
QPixmap active = QApplication::style()->generatedIconPixmap(QIcon::Active, pm, &opt);+ −
if (pm.cacheKey() == active.cacheKey())+ −
return pm;+ −
}+ −
}+ −
+ −
if (!QPixmapCache::find(key + QString::number(mode), pm)) {+ −
if (pm.size() != actualSize)+ −
pm = pm.scaled(actualSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);+ −
if (pe->mode != mode && mode != QIcon::Normal) {+ −
QStyleOption opt(0);+ −
opt.palette = QApplication::palette();+ −
QPixmap generated = QApplication::style()->generatedIconPixmap(mode, pm, &opt);+ −
if (!generated.isNull())+ −
pm = generated;+ −
}+ −
QPixmapCache::insert(key + QString::number(mode), pm);+ −
}+ −
return pm;+ −
}+ −
+ −
QSize QPixmapIconEngine::actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state)+ −
{+ −
QSize actualSize;+ −
if (QPixmapIconEngineEntry *pe = bestMatch(size, mode, state, true))+ −
actualSize = pe->size;+ −
+ −
if (actualSize.isNull())+ −
return actualSize;+ −
+ −
if (!actualSize.isNull() && (actualSize.width() > size.width() || actualSize.height() > size.height()))+ −
actualSize.scale(size, Qt::KeepAspectRatio);+ −
return actualSize;+ −
}+ −
+ −
void QPixmapIconEngine::addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state)+ −
{+ −
if (!pixmap.isNull()) {+ −
QPixmapIconEngineEntry *pe = tryMatch(pixmap.size(), mode, state);+ −
if(pe && pe->size == pixmap.size()) {+ −
pe->pixmap = pixmap;+ −
pe->fileName.clear();+ −
} else {+ −
pixmaps += QPixmapIconEngineEntry(pixmap, mode, state);+ −
}+ −
}+ −
}+ −
+ −
void QPixmapIconEngine::addFile(const QString &fileName, const QSize &_size, QIcon::Mode mode, QIcon::State state)+ −
{+ −
if (!fileName.isEmpty()) {+ −
QSize size = _size;+ −
QPixmap pixmap;+ −
+ −
QString abs = fileName;+ −
if (fileName.at(0) != QLatin1Char(':'))+ −
abs = QFileInfo(fileName).absoluteFilePath();+ −
+ −
for (int i = 0; i < pixmaps.count(); ++i) {+ −
if (pixmaps.at(i).mode == mode && pixmaps.at(i).state == state) {+ −
QPixmapIconEngineEntry *pe = &pixmaps[i];+ −
if(size == QSize()) {+ −
pixmap = QPixmap(abs);+ −
size = pixmap.size();+ −
}+ −
if (pe->size == QSize() && pe->pixmap.isNull()) {+ −
pe->pixmap = QPixmap(pe->fileName);+ −
pe->size = pe->pixmap.size();+ −
}+ −
if(pe->size == size) {+ −
pe->pixmap = pixmap;+ −
pe->fileName = abs;+ −
return;+ −
}+ −
}+ −
}+ −
QPixmapIconEngineEntry e(abs, size, mode, state);+ −
e.pixmap = pixmap;+ −
pixmaps += e;+ −
}+ −
}+ −
+ −
QString QPixmapIconEngine::key() const+ −
{+ −
return QLatin1String("QPixmapIconEngine");+ −
}+ −
+ −
QIconEngineV2 *QPixmapIconEngine::clone() const+ −
{+ −
return new QPixmapIconEngine(*this);+ −
}+ −
+ −
bool QPixmapIconEngine::read(QDataStream &in)+ −
{+ −
int num_entries;+ −
QPixmap pm;+ −
QString fileName;+ −
QSize sz;+ −
uint mode;+ −
uint state;+ −
+ −
in >> num_entries;+ −
for (int i=0; i < num_entries; ++i) {+ −
if (in.atEnd()) {+ −
pixmaps.clear();+ −
return false;+ −
}+ −
in >> pm;+ −
in >> fileName;+ −
in >> sz;+ −
in >> mode;+ −
in >> state;+ −
if (pm.isNull()) {+ −
addFile(fileName, sz, QIcon::Mode(mode), QIcon::State(state));+ −
} else {+ −
QPixmapIconEngineEntry pe(fileName, sz, QIcon::Mode(mode), QIcon::State(state));+ −
pe.pixmap = pm;+ −
pixmaps += pe;+ −
}+ −
}+ −
return true;+ −
}+ −
+ −
bool QPixmapIconEngine::write(QDataStream &out) const+ −
{+ −
int num_entries = pixmaps.size();+ −
out << num_entries;+ −
for (int i=0; i < num_entries; ++i) {+ −
if (pixmaps.at(i).pixmap.isNull())+ −
out << QPixmap(pixmaps.at(i).fileName);+ −
else+ −
out << pixmaps.at(i).pixmap;+ −
out << pixmaps.at(i).fileName;+ −
out << pixmaps.at(i).size;+ −
out << (uint) pixmaps.at(i).mode;+ −
out << (uint) pixmaps.at(i).state;+ −
}+ −
return true;+ −
}+ −
+ −
void QPixmapIconEngine::virtual_hook(int id, void *data)+ −
{+ −
switch (id) {+ −
case QIconEngineV2::AvailableSizesHook: {+ −
QIconEngineV2::AvailableSizesArgument &arg =+ −
*reinterpret_cast<QIconEngineV2::AvailableSizesArgument*>(data);+ −
arg.sizes.clear();+ −
for (int i = 0; i < pixmaps.size(); ++i) {+ −
QPixmapIconEngineEntry &pe = pixmaps[i];+ −
if (pe.size == QSize() && pe.pixmap.isNull()) {+ −
pe.pixmap = QPixmap(pe.fileName);+ −
pe.size = pe.pixmap.size();+ −
}+ −
if (pe.mode == arg.mode && pe.state == arg.state && !pe.size.isEmpty())+ −
arg.sizes.push_back(pe.size);+ −
}+ −
break;+ −
}+ −
default:+ −
QIconEngineV2::virtual_hook(id, data);+ −
}+ −
}+ −
+ −
#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)+ −
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,+ −
(QIconEngineFactoryInterface_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive))+ −
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loaderV2,+ −
(QIconEngineFactoryInterfaceV2_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive))+ −
#endif+ −
+ −
+ −
+ −
/*!+ −
\class QIcon+ −
+ −
\brief The QIcon class provides scalable icons in different modes+ −
and states.+ −
+ −
\ingroup painting+ −
\ingroup shared+ −
+ −
+ −
A QIcon can generate smaller, larger, active, and disabled pixmaps+ −
from the set of pixmaps it is given. Such pixmaps are used by Qt+ −
widgets to show an icon representing a particular action.+ −
+ −
The simplest use of QIcon is to create one from a QPixmap file or+ −
resource, and then use it, allowing Qt to work out all the required+ −
icon styles and sizes. For example:+ −
+ −
\snippet doc/src/snippets/code/src_gui_image_qicon.cpp 0+ −
+ −
To undo a QIcon, simply set a null icon in its place:+ −
+ −
\snippet doc/src/snippets/code/src_gui_image_qicon.cpp 1+ −
+ −
Use the QImageReader::supportedImageFormats() and+ −
QImageWriter::supportedImageFormats() functions to retrieve a+ −
complete list of the supported file formats.+ −
+ −
When you retrieve a pixmap using pixmap(QSize, Mode, State), and no+ −
pixmap for this given size, mode and state has been added with+ −
addFile() or addPixmap(), then QIcon will generate one on the+ −
fly. This pixmap generation happens in a QIconEngineV2. The default+ −
engine scales pixmaps down if required, but never up, and it uses+ −
the current style to calculate a disabled appearance. By using+ −
custom icon engines, you can customize every aspect of generated+ −
icons. With QIconEnginePluginV2 it is possible to register different+ −
icon engines for different file suffixes, making it possible for+ −
third parties to provide additional icon engines to those included+ −
with Qt.+ −
+ −
\note Since Qt 4.2, an icon engine that supports SVG is included.+ −
+ −
\section1 Making Classes that Use QIcon+ −
+ −
If you write your own widgets that have an option to set a small+ −
pixmap, consider allowing a QIcon to be set for that pixmap. The+ −
Qt class QToolButton is an example of such a widget.+ −
+ −
Provide a method to set a QIcon, and when you draw the icon, choose+ −
whichever pixmap is appropriate for the current state of your widget.+ −
For example:+ −
\snippet doc/src/snippets/code/src_gui_image_qicon.cpp 2+ −
+ −
You might also make use of the \c Active mode, perhaps making your+ −
widget \c Active when the mouse is over the widget (see \l+ −
QWidget::enterEvent()), while the mouse is pressed pending the+ −
release that will activate the function, or when it is the currently+ −
selected item. If the widget can be toggled, the "On" mode might be+ −
used to draw a different icon.+ −
+ −
\img icon.png QIcon+ −
+ −
\sa {fowler}{GUI Design Handbook: Iconic Label}, {Icons Example}+ −
*/+ −
+ −
+ −
/*!+ −
Constructs a null icon.+ −
*/+ −
QIcon::QIcon()+ −
: d(0)+ −
{+ −
}+ −
+ −
/*!+ −
Constructs an icon from a \a pixmap.+ −
*/+ −
QIcon::QIcon(const QPixmap &pixmap)+ −
:d(0)+ −
{+ −
addPixmap(pixmap);+ −
}+ −
+ −
/*!+ −
Constructs a copy of \a other. This is very fast.+ −
*/+ −
QIcon::QIcon(const QIcon &other)+ −
:d(other.d)+ −
{+ −
if (d)+ −
d->ref.ref();+ −
}+ −
+ −
/*!+ −
Constructs an icon from the file with the given \a fileName. The+ −
file will be loaded on demand.+ −
+ −
If \a fileName contains a relative path (e.g. the filename only)+ −
the relevant file must be found relative to the runtime working+ −
directory.+ −
+ −
The file name can be either refer to an actual file on disk or to+ −
one of the application's embedded resources. See the+ −
\l{resources.html}{Resource System} overview for details on how to+ −
embed images and other resource files in the application's+ −
executable.+ −
+ −
Use the QImageReader::supportedImageFormats() and+ −
QImageWriter::supportedImageFormats() functions to retrieve a+ −
complete list of the supported file formats.+ −
*/+ −
QIcon::QIcon(const QString &fileName)+ −
: d(0)+ −
{+ −
addFile(fileName);+ −
}+ −
+ −
+ −
/*!+ −
Creates an icon with a specific icon \a engine. The icon takes+ −
ownership of the engine.+ −
*/+ −
QIcon::QIcon(QIconEngine *engine)+ −
:d(new QIconPrivate)+ −
{+ −
d->engine_version = 1;+ −
d->engine = engine;+ −
d->v1RefCount = new QAtomicInt(1);+ −
}+ −
+ −
/*!+ −
Creates an icon with a specific icon \a engine. The icon takes+ −
ownership of the engine.+ −
*/+ −
QIcon::QIcon(QIconEngineV2 *engine)+ −
:d(new QIconPrivate)+ −
{+ −
d->engine_version = 2;+ −
d->engine = engine;+ −
}+ −
+ −
/*!+ −
Destroys the icon.+ −
*/+ −
QIcon::~QIcon()+ −
{+ −
if (d && !d->ref.deref())+ −
delete d;+ −
}+ −
+ −
/*!+ −
Assigns the \a other icon to this icon and returns a reference to+ −
this icon.+ −
*/+ −
QIcon &QIcon::operator=(const QIcon &other)+ −
{+ −
if (other.d)+ −
other.d->ref.ref();+ −
if (d && !d->ref.deref())+ −
delete d;+ −
d = other.d;+ −
return *this;+ −
}+ −
+ −
/*!+ −
Returns the icon as a QVariant.+ −
*/+ −
QIcon::operator QVariant() const+ −
{+ −
return QVariant(QVariant::Icon, this);+ −
}+ −
+ −
/*! \obsolete+ −
+ −
Returns a number that identifies the contents of this+ −
QIcon object. Distinct QIcon objects can have+ −
the same serial number if they refer to the same contents+ −
(but they don't have to). Also, the serial number of+ −
a QIcon object may change during its lifetime.+ −
+ −
Use cacheKey() instead.+ −
+ −
A null icon always has a serial number of 0.+ −
+ −
Serial numbers are mostly useful in conjunction with caching.+ −
+ −
\sa QPixmap::serialNumber()+ −
*/+ −
+ −
int QIcon::serialNumber() const+ −
{+ −
return d ? d->serialNum : 0;+ −
}+ −
+ −
/*!+ −
Returns a number that identifies the contents of this QIcon+ −
object. Distinct QIcon objects can have the same key if+ −
they refer to the same contents.+ −
\since 4.3+ −
+ −
The cacheKey() will change when the icon is altered via+ −
addPixmap() or addFile().+ −
+ −
Cache keys are mostly useful in conjunction with caching.+ −
+ −
\sa QPixmap::cacheKey()+ −
*/+ −
qint64 QIcon::cacheKey() const+ −
{+ −
if (!d)+ −
return 0;+ −
return (((qint64) d->serialNum) << 32) | ((qint64) (d->detach_no));+ −
}+ −
+ −
/*!+ −
Returns a pixmap with the requested \a size, \a mode, and \a+ −
state, generating one if necessary. The pixmap might be smaller than+ −
requested, but never larger.+ −
+ −
\sa actualSize(), paint()+ −
*/+ −
QPixmap QIcon::pixmap(const QSize &size, Mode mode, State state) const+ −
{+ −
if (!d)+ −
return QPixmap();+ −
return d->engine->pixmap(size, mode, state);+ −
}+ −
+ −
/*!+ −
\fn QPixmap QIcon::pixmap(int w, int h, Mode mode = Normal, State state = Off) const+ −
+ −
\overload+ −
+ −
Returns a pixmap of size QSize(\a w, \a h). The pixmap might be smaller than+ −
requested, but never larger.+ −
*/+ −
+ −
/*!+ −
\fn QPixmap QIcon::pixmap(int extent, Mode mode = Normal, State state = Off) const+ −
+ −
\overload+ −
+ −
Returns a pixmap of size QSize(\a extent, \a extent). The pixmap might be smaller+ −
than requested, but never larger.+ −
*/+ −
+ −
/*! Returns the actual size of the icon for the requested \a size, \a+ −
mode, and \a state. The result might be smaller than requested, but+ −
never larger.+ −
+ −
\sa pixmap(), paint()+ −
*/+ −
QSize QIcon::actualSize(const QSize &size, Mode mode, State state) const+ −
{+ −
if (!d)+ −
return QSize();+ −
return d->engine->actualSize(size, mode, state);+ −
}+ −
+ −
+ −
/*!+ −
Uses the \a painter to paint the icon with specified \a alignment,+ −
required \a mode, and \a state into the rectangle \a rect.+ −
+ −
\sa actualSize(), pixmap()+ −
*/+ −
void QIcon::paint(QPainter *painter, const QRect &rect, Qt::Alignment alignment, Mode mode, State state) const+ −
{+ −
if (!d || !painter)+ −
return;+ −
QRect alignedRect = QStyle::alignedRect(painter->layoutDirection(), alignment, d->engine->actualSize(rect.size(), mode, state), rect);+ −
d->engine->paint(painter, alignedRect, mode, state);+ −
}+ −
+ −
/*!+ −
\fn void QIcon::paint(QPainter *painter, int x, int y, int w, int h, Qt::Alignment alignment,+ −
Mode mode, State state) const+ −
+ −
\overload+ −
+ −
Paints the icon into the rectangle QRect(\a x, \a y, \a w, \a h).+ −
*/+ −
+ −
/*!+ −
Returns true if the icon is empty; otherwise returns false.+ −
+ −
An icon is empty if it has neither a pixmap nor a filename.+ −
+ −
Note: Even a non-null icon might not be able to create valid+ −
pixmaps, eg. if the file does not exist or cannot be read.+ −
*/+ −
bool QIcon::isNull() const+ −
{+ −
return !d;+ −
}+ −
+ −
/*!\internal+ −
*/+ −
bool QIcon::isDetached() const+ −
{+ −
return !d || d->ref == 1;+ −
}+ −
+ −
/*! \internal+ −
*/+ −
void QIcon::detach()+ −
{+ −
if (d) {+ −
if (d->ref != 1) {+ −
QIconPrivate *x = new QIconPrivate;+ −
if (d->engine_version > 1) {+ −
QIconEngineV2 *engine = static_cast<QIconEngineV2 *>(d->engine);+ −
x->engine = engine->clone();+ −
} else {+ −
x->engine = d->engine;+ −
x->v1RefCount = d->v1RefCount;+ −
x->v1RefCount->ref();+ −
}+ −
x->engine_version = d->engine_version;+ −
if (!d->ref.deref())+ −
delete d;+ −
d = x;+ −
}+ −
++d->detach_no;+ −
}+ −
}+ −
+ −
/*!+ −
Adds \a pixmap to the icon, as a specialization for \a mode and+ −
\a state.+ −
+ −
Custom icon engines are free to ignore additionally added+ −
pixmaps.+ −
+ −
\sa addFile()+ −
*/+ −
void QIcon::addPixmap(const QPixmap &pixmap, Mode mode, State state)+ −
{+ −
if (pixmap.isNull())+ −
return;+ −
if (!d) {+ −
d = new QIconPrivate;+ −
d->engine = new QPixmapIconEngine;+ −
} else {+ −
detach();+ −
}+ −
d->engine->addPixmap(pixmap, mode, state);+ −
}+ −
+ −
+ −
/*! Adds an image from the file with the given \a fileName to the+ −
icon, as a specialization for \a size, \a mode and \a state. The+ −
file will be loaded on demand. Note: custom icon engines are free+ −
to ignore additionally added pixmaps.+ −
+ −
If \a fileName contains a relative path (e.g. the filename only)+ −
the relevant file must be found relative to the runtime working+ −
directory.+ −
+ −
The file name can be either refer to an actual file on disk or to+ −
one of the application's embedded resources. See the+ −
\l{resources.html}{Resource System} overview for details on how to+ −
embed images and other resource files in the application's+ −
executable.+ −
+ −
Use the QImageReader::supportedImageFormats() and+ −
QImageWriter::supportedImageFormats() functions to retrieve a+ −
complete list of the supported file formats.+ −
+ −
Note: When you add a non-empty filename to a QIcon, the icon becomes+ −
non-null, even if the file doesn't exist or points to a corrupt file.+ −
+ −
\sa addPixmap()+ −
*/+ −
void QIcon::addFile(const QString &fileName, const QSize &size, Mode mode, State state)+ −
{+ −
if (fileName.isEmpty())+ −
return;+ −
if (!d) {+ −
#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)+ −
QFileInfo info(fileName);+ −
QString suffix = info.suffix();+ −
if (!suffix.isEmpty()) {+ −
// first try version 2 engines..+ −
if (QIconEngineFactoryInterfaceV2 *factory = qobject_cast<QIconEngineFactoryInterfaceV2*>(loaderV2()->instance(suffix))) {+ −
if (QIconEngine *engine = factory->create(fileName)) {+ −
d = new QIconPrivate;+ −
d->engine = engine;+ −
}+ −
}+ −
// ..then fall back and try to load version 1 engines+ −
if (!d) {+ −
if (QIconEngineFactoryInterface *factory = qobject_cast<QIconEngineFactoryInterface*>(loader()->instance(suffix))) {+ −
if (QIconEngine *engine = factory->create(fileName)) {+ −
d = new QIconPrivate;+ −
d->engine = engine;+ −
d->engine_version = 1;+ −
d->v1RefCount = new QAtomicInt(1);+ −
}+ −
}+ −
}+ −
}+ −
#endif+ −
// ...then fall back to the default engine+ −
if (!d) {+ −
d = new QIconPrivate;+ −
d->engine = new QPixmapIconEngine;+ −
}+ −
} else {+ −
detach();+ −
}+ −
d->engine->addFile(fileName, size, mode, state);+ −
}+ −
+ −
/*!+ −
\since 4.5+ −
+ −
Returns a list of available icon sizes for the specified \a mode and+ −
\a state.+ −
*/+ −
QList<QSize> QIcon::availableSizes(Mode mode, State state) const+ −
{+ −
if (!d || !d->engine || d->engine_version < 2)+ −
return QList<QSize>();+ −
QIconEngineV2 *engine = static_cast<QIconEngineV2*>(d->engine);+ −
return engine->availableSizes(mode, state);+ −
}+ −
+ −
/*!+ −
\since 4.6+ −
+ −
Sets the search paths for icon themes to \a paths.+ −
\sa themeSearchPaths(), fromTheme(), setThemeName()+ −
*/+ −
void QIcon::setThemeSearchPaths(const QStringList &paths)+ −
{+ −
QIconLoader::instance()->setThemeSearchPath(paths);+ −
}+ −
+ −
/*!+ −
\since 4.6+ −
+ −
Returns the search paths for icon themes.+ −
+ −
The default value will depend on the platform:+ −
+ −
On X11, the search path will use the XDG_DATA_DIRS environment+ −
variable if available.+ −
+ −
By default all platforms will have the resource directory+ −
\c{:\icons} as a fallback. You can use "rcc -project" to generate a+ −
resource file from your icon theme.+ −
+ −
\sa setThemeSearchPaths(), fromTheme(), setThemeName()+ −
*/+ −
QStringList QIcon::themeSearchPaths()+ −
{+ −
return QIconLoader::instance()->themeSearchPaths();+ −
}+ −
+ −
/*!+ −
\since 4.6+ −
+ −
Sets the current icon theme to \a name.+ −
+ −
The \a name should correspond to a directory name in the+ −
themeSearchPath() containing an index.theme+ −
file describing it's contents.+ −
+ −
\sa themeSearchPaths(), themeName()+ −
*/+ −
void QIcon::setThemeName(const QString &name)+ −
{+ −
QIconLoader::instance()->setThemeName(name);+ −
}+ −
+ −
/*!+ −
\since 4.6+ −
+ −
Returns the name of the current icon theme.+ −
+ −
On X11, the current icon theme depends on your desktop+ −
settings. On other platforms it is not set by default.+ −
+ −
\sa setThemeName(), themeSearchPaths(), fromTheme(),+ −
hasThemeIcon()+ −
*/+ −
QString QIcon::themeName()+ −
{+ −
return QIconLoader::instance()->themeName();+ −
}+ −
+ −
/*!+ −
\since 4.6+ −
+ −
Returns the QIcon corresponding to \a name in the current+ −
icon theme. If no such icon is found in the current theme+ −
\a fallback is return instead.+ −
+ −
The lastest version of the freedesktop icon specification and naming+ −
spesification can be obtained here:+ −
http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html+ −
http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html+ −
+ −
To fetch an icon from the current icon theme:+ −
+ −
\snippet doc/src/snippets/code/src_gui_image_qicon.cpp 3+ −
+ −
Or if you want to provide a guaranteed fallback for platforms that+ −
do not support theme icons, you can use the second argument:+ −
+ −
\snippet doc/src/snippets/code/src_gui_image_qicon.cpp 4+ −
+ −
\note By default, only X11 will support themed icons. In order to+ −
use themed icons on Mac and Windows, you will have to bundle a+ −
compliant theme in one of your themeSearchPaths() and set the+ −
appropriate themeName().+ −
+ −
\sa themeName(), setThemeName(), themeSearchPaths()+ −
*/+ −
QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback)+ −
{+ −
QIcon icon;+ −
+ −
if (qtIconCache()->contains(name)) {+ −
icon = *qtIconCache()->object(name);+ −
} else {+ −
QIcon *cachedIcon = new QIcon(new QIconLoaderEngine(name));+ −
qtIconCache()->insert(name, cachedIcon);+ −
icon = *cachedIcon;+ −
}+ −
+ −
// Note the qapp check is to allow lazy loading of static icons+ −
// Supporting fallbacks will not work for this case.+ −
if (qApp && icon.availableSizes().isEmpty())+ −
return fallback;+ −
+ −
return icon;+ −
}+ −
+ −
/*!+ −
\since 4.6+ −
+ −
Returns true if there is an icon available for \a name in the+ −
current icon theme, otherwise returns false.+ −
+ −
\sa themeSearchPaths(), fromTheme(), setThemeName()+ −
*/+ −
bool QIcon::hasThemeIcon(const QString &name)+ −
{+ −
QIcon icon = fromTheme(name);+ −
+ −
return !icon.isNull();+ −
}+ −
+ −
+ −
/*****************************************************************************+ −
QIcon stream functions+ −
*****************************************************************************/+ −
#if !defined(QT_NO_DATASTREAM)+ −
/*!+ −
\fn QDataStream &operator<<(QDataStream &stream, const QIcon &icon)+ −
\relates QIcon+ −
\since 4.2+ −
+ −
Writes the given \a icon to the given \a stream as a PNG+ −
image. If the icon contains more than one image, all images will+ −
be written to the stream. Note that writing the stream to a file+ −
will not produce a valid image file.+ −
*/+ −
+ −
QDataStream &operator<<(QDataStream &s, const QIcon &icon)+ −
{+ −
if (s.version() >= QDataStream::Qt_4_3) {+ −
if (icon.isNull()) {+ −
s << QString();+ −
} else {+ −
if (icon.d->engine_version > 1) {+ −
QIconEngineV2 *engine = static_cast<QIconEngineV2 *>(icon.d->engine);+ −
s << engine->key();+ −
engine->write(s);+ −
} else {+ −
// not really supported+ −
qWarning("QIcon: Cannot stream QIconEngine. Use QIconEngineV2 instead.");+ −
}+ −
}+ −
} else if (s.version() == QDataStream::Qt_4_2) {+ −
if (icon.isNull()) {+ −
s << 0;+ −
} else {+ −
QPixmapIconEngine *engine = static_cast<QPixmapIconEngine *>(icon.d->engine);+ −
int num_entries = engine->pixmaps.size();+ −
s << num_entries;+ −
for (int i=0; i < num_entries; ++i) {+ −
s << engine->pixmaps.at(i).pixmap;+ −
s << engine->pixmaps.at(i).fileName;+ −
s << engine->pixmaps.at(i).size;+ −
s << (uint) engine->pixmaps.at(i).mode;+ −
s << (uint) engine->pixmaps.at(i).state;+ −
}+ −
}+ −
} else {+ −
s << QPixmap(icon.pixmap(22,22));+ −
}+ −
return s;+ −
}+ −
+ −
/*!+ −
\fn QDataStream &operator>>(QDataStream &stream, QIcon &icon)+ −
\relates QIcon+ −
\since 4.2+ −
+ −
Reads an image, or a set of images, from the given \a stream into+ −
the given \a icon.+ −
*/+ −
+ −
QDataStream &operator>>(QDataStream &s, QIcon &icon)+ −
{+ −
if (s.version() >= QDataStream::Qt_4_3) {+ −
icon = QIcon();+ −
QString key;+ −
s >> key;+ −
if (key == QLatin1String("QPixmapIconEngine")) {+ −
icon.d = new QIconPrivate;+ −
QIconEngineV2 *engine = new QPixmapIconEngine;+ −
icon.d->engine = engine;+ −
engine->read(s);+ −
} else if (key == QLatin1String("QIconLoaderEngine")) {+ −
icon.d = new QIconPrivate;+ −
QIconEngineV2 *engine = new QIconLoaderEngine();+ −
icon.d->engine = engine;+ −
engine->read(s);+ −
#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)+ −
} else if (QIconEngineFactoryInterfaceV2 *factory = qobject_cast<QIconEngineFactoryInterfaceV2*>(loaderV2()->instance(key))) {+ −
if (QIconEngineV2 *engine= factory->create()) {+ −
icon.d = new QIconPrivate;+ −
icon.d->engine = engine;+ −
engine->read(s);+ −
}+ −
#endif+ −
}+ −
} else if (s.version() == QDataStream::Qt_4_2) {+ −
icon = QIcon();+ −
int num_entries;+ −
QPixmap pm;+ −
QString fileName;+ −
QSize sz;+ −
uint mode;+ −
uint state;+ −
+ −
s >> num_entries;+ −
for (int i=0; i < num_entries; ++i) {+ −
s >> pm;+ −
s >> fileName;+ −
s >> sz;+ −
s >> mode;+ −
s >> state;+ −
if (pm.isNull())+ −
icon.addFile(fileName, sz, QIcon::Mode(mode), QIcon::State(state));+ −
else+ −
icon.addPixmap(pm, QIcon::Mode(mode), QIcon::State(state));+ −
}+ −
} else {+ −
QPixmap pm;+ −
s >> pm;+ −
icon.addPixmap(pm);+ −
}+ −
return s;+ −
}+ −
+ −
#endif //QT_NO_DATASTREAM+ −
+ −
+ −
#ifdef QT3_SUPPORT+ −
+ −
static int widths[2] = { 22, 32 };+ −
static int heights[2] = { 22, 32 };+ −
+ −
static QSize pixmapSizeHelper(QIcon::Size which)+ −
{+ −
int i = 0;+ −
if (which == QIcon::Large)+ −
i = 1;+ −
return QSize(widths[i], heights[i]);+ −
}+ −
+ −
/*!+ −
\enum QIcon::Size+ −
\compat+ −
+ −
\value Small Use QStyle::pixelMetric(QStyle::PM_SmallIconSize) instead.+ −
\value Large Use QStyle::pixelMetric(QStyle::PM_LargeIconSize) instead.+ −
\value Automatic N/A.+ −
*/+ −
+ −
/*!+ −
Use pixmap(QSize(...), \a mode, \a state), where the first+ −
argument is an appropriate QSize instead of a \l Size value.+ −
+ −
\sa pixmapSize()+ −
*/+ −
QPixmap QIcon::pixmap(Size size, Mode mode, State state) const+ −
{ return pixmap(pixmapSizeHelper(size), mode, state); }+ −
+ −
/*!+ −
Use pixmap(QSize(...), mode, \a state), where the first argument+ −
is an appropriate QSize instead of a \l Size value, and the+ −
second argument is QIcon::Normal or QIcon::Disabled, depending on+ −
the value of \a enabled.+ −
+ −
\sa pixmapSize()+ −
*/+ −
QPixmap QIcon::pixmap(Size size, bool enabled, State state) const+ −
{ return pixmap(pixmapSizeHelper(size), enabled ? Normal : Disabled, state); }+ −
+ −
/*!+ −
Use one of the other pixmap() overloads.+ −
*/+ −
QPixmap QIcon::pixmap() const+ −
{ return pixmap(pixmapSizeHelper(Small), Normal, Off); }+ −
+ −
/*!+ −
The pixmap() function now takes a QSize instead of a QIcon::Size,+ −
so there is no need for this function in new code.+ −
*/+ −
void QIcon::setPixmapSize(Size which, const QSize &size)+ −
{+ −
int i = 0;+ −
if (which == Large)+ −
i = 1;+ −
widths[i] = size.width();+ −
heights[i] = size.height();+ −
}+ −
+ −
/*!+ −
Use QStyle::pixelMetric() with QStyle::PM_SmallIconSize or+ −
QStyle::PM_LargeIconSize as the first argument, depending on \a+ −
which.+ −
*/+ −
QSize QIcon::pixmapSize(Size which)+ −
{+ −
return pixmapSizeHelper(which);+ −
}+ −
+ −
/*!+ −
\fn void QIcon::reset(const QPixmap &pixmap, Size size)+ −
+ −
Use the constructor that takes a QPixmap and operator=().+ −
*/+ −
+ −
/*!+ −
\fn void QIcon::setPixmap(const QPixmap &pixmap, Size size, Mode mode, State state)+ −
+ −
Use addPixmap(\a pixmap, \a mode, \a state) instead. The \a size+ −
parameter is ignored.+ −
*/+ −
+ −
/*!+ −
\fn void QIcon::setPixmap(const QString &fileName, Size size, Mode mode, State state)+ −
+ −
Use addFile(\a fileName, \a mode, \a state) instead. The \a size+ −
parameter is ignored.+ −
*/+ −
+ −
#endif // QT3_SUPPORT+ −
+ −
/*!+ −
\fn DataPtr &QIcon::data_ptr()+ −
\internal+ −
*/+ −
+ −
/*!+ −
\typedef QIcon::DataPtr+ −
\internal+ −
*/+ −
+ −
QT_END_NAMESPACE+ −
#endif //QT_NO_ICON+ −