src/hbcore/image/hbicon.cpp
changeset 0 16d8024aca5e
child 1 f7ac710697a9
equal deleted inserted replaced
-1:000000000000 0:16d8024aca5e
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbCore module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 
       
    26 #include "hbicon.h"
       
    27 #include "hbicon_p.h"
       
    28 #include "hbiconanimator.h"
       
    29 #include "hbbadgeicon_p.h"
       
    30 #include "hbiconloader_p.h"
       
    31 
       
    32 #include <QObject>
       
    33 #include <QPainter>
       
    34 #include <QVariant>
       
    35 
       
    36 /*!
       
    37     @stable
       
    38     @hbcore
       
    39     \class HbIcon
       
    40     \brief HbIcon is a paintable instance of an icon. The term icon means any piece of
       
    41     graphics that can be drawn. This class is not intended to be derived from.
       
    42 
       
    43     For more information on image and icon classes and general notes about
       
    44     graphics memory usage see \ref graph_mem_usage "this page".
       
    45 
       
    46     This class implements copy-on-write semantics, so copy constructor and assignment operator
       
    47     only perform shallow copy and are fast. A deep copy is done if the icon state is changed.
       
    48 
       
    49     Supported formats and file extensions are the following.
       
    50 
       
    51     - SVG-T (.svg)
       
    52     - Externalized QPicture (.qpic)
       
    53     - PNG (.png)
       
    54     - XPM (.xpm)
       
    55     - JPG (.jpg)
       
    56     - Frame animations (.axml)
       
    57 
       
    58     An icon is defined by its name. The filename should be same as the logical name of the icon,
       
    59     accompanied with the file extension.
       
    60 
       
    61     E.g. logical name of the icon is "frame". Assuming the icon file is in SVG-T format,
       
    62     the filename should be "frame.svg".
       
    63 
       
    64     If the given icon name is a logical icon name and not an absolute filename,
       
    65     it is searched in the icon locations of the theming framework.
       
    66 
       
    67     An absolute icon filename can point e.g. in application's resource file.
       
    68 
       
    69     The icon can be resized with method HbIcon::setSize.
       
    70     When resizing, by default the aspect ratio of the icon is preserved.
       
    71     To change this, define the aspect ratio mode parameter in the method HbIcon::paint(). 
       
    72 
       
    73     An icon itself can be a combination of existing icons; in this case the main icon is
       
    74     "badged" with smaller icons to form a distinct icon. You can badge icons in this way
       
    75     with the HbIcon::addBadge method, specifying the location where the badge should be drawn
       
    76     and a second HbIcon to draw at the indicated location. To prevent possible recursion , 
       
    77     you can't badge an icon with a badge icon that is itself badged, however.
       
    78 	
       
    79     Scaled instances of the icons are shared by the framework
       
    80     to decrease memory consumption.
       
    81 
       
    82     A brief example of how to create an icon and use it.
       
    83 
       
    84     \snippet{clock/clockworldview.cpp,1}
       
    85 
       
    86     This class provides built-in support for icon animations.
       
    87     Supported formats are the following.
       
    88 
       
    89     - GIF (.gif)
       
    90     - MNG (.mng)
       
    91 
       
    92     The formats mentioned above contain all the animation information inside a single file.
       
    93     They are pixel formats, so the quality of resizing the animations is not good.
       
    94 
       
    95     Icon animations can also be constructed from separate frame icons.
       
    96     The frames are defined in separate files, which can be in any format supported by HbIcon.
       
    97     The animation frame information for the icon is defined using class HbIconAnimationManager.
       
    98     The animated icon can be then constructed normally with its name.
       
    99 
       
   100     As default the icon animation is started automatically when the icon is painted for the first time.
       
   101     This can be disabled with flag HbIcon::NoAutoStartAnimation.
       
   102 
       
   103     An example of how to define a frame-by-frame animation and construct an icon using it.
       
   104     
       
   105     \dontinclude ultimatecodesnippet/ultimatecodesnippet.cpp
       
   106     \skip frame-by-frame
       
   107     \until }
       
   108 */
       
   109 
       
   110 /*!
       
   111   \enum HbIcon::Flag
       
   112 
       
   113   \b DoNotCache \b (0x01) Icon pixmap is not cached in the system wide icon pixmap cache.
       
   114          Setting this flag improves cache performance for other icons, if this icon does
       
   115          not need to be cached for being able to load it faster next time.
       
   116 
       
   117   \b ResolutionCorrected \b (0x02) This flag is useful for making icon sizes automatically
       
   118          adapt to different screen resolutions (DPI values) and zoom factors used in the user 
       
   119          interface. The current display resolution (DPI value) and zoom factor are taken
       
   120          in consideration when defining the default size of the icon. This affects on what default
       
   121          size is reported for the icon and also in which size the icon is rendered if its size is
       
   122          not set explicitly. The default DPI value is 144 and the default zoom factor 1.0.
       
   123          When this flag is set, the corrected default size of icon is defined as:
       
   124 
       
   125          Corrected default size = original default size * current DPI value / default DPI 
       
   126          value * current zoom factor
       
   127 
       
   128          \note Currently this flag has an effect on vector icons only.
       
   129          \note If the icon size is set explicitly this flag has no effect.
       
   130 
       
   131   \b NoAutoStartAnimation \b (0x04) This flag disables automatic starting of the icon animation
       
   132          when the icon is painted for the first time. The client can then control the animation with
       
   133          startAnimation() and stopAnimation() methods in class HbIconAnimator.
       
   134          If the icon is not animated this flag has no effect.
       
   135 
       
   136   \b Colorized \b (0x08) This flag enables the usage of the color that is set via
       
   137          setColor(). If this flag is not set then the color that is set with setColor() is
       
   138          ignored, unless the icon refers some theme graphics. For icons coming from the
       
   139          theme this flag can be left unset because they will still be colorized properly
       
   140          if the logical icon name indicates that the icon is a mono icon. Therefore this
       
   141          flag is only relevant for icons loaded from regular files.
       
   142 */
       
   143 
       
   144 /*!
       
   145   \enum HbIcon::MirroringMode
       
   146 
       
   147   \b Default This is the default mirroring mode. The icon is mirrored in right-to-left
       
   148          layout if its name is listed in the icon framework's configuration list of mirrored icons.
       
   149 
       
   150   \b Forced Forces horizontal mirroring of the icon. As default, the system
       
   151          automatically mirrors the icon pixmap based on a predefined configuration,
       
   152          when required for the purpose of a mirrored layout.
       
   153          This mirroring mode explicitly forces the icon pixmap to be mirrored,
       
   154          regardless of the layout direction.
       
   155 
       
   156   \b Prevented Prevents horizontal mirroring of the icon. As default, the system
       
   157          automatically mirrors the icon pixmap based on a predefined configuration,
       
   158          when required for the purpose of a mirrored layout.
       
   159          This mirroring mode explicitly prevents the icon pixmap from being mirrored,
       
   160          regardless of the layout direction.
       
   161 
       
   162   \b LayoutDirection This mirroring mode automatically mirrors the icon pixmap
       
   163          in a right-to-left layout.
       
   164 */
       
   165 
       
   166 // Must be initialized dynamically because QIcon cannot be constructed 
       
   167 // when static variables are constructed.
       
   168 static HbIconPrivate *shared_null = 0;
       
   169 
       
   170 static const int iconMetaType = qRegisterMetaType<HbIcon>();
       
   171 
       
   172 /*!
       
   173 This constructor is used for shared_null instance only
       
   174 \internal
       
   175 */
       
   176 HbIconPrivate::HbIconPrivate() :
       
   177     engine( new HbIconEngine(QString()) ),
       
   178     qicon(engine),
       
   179     badgeInfo(0)
       
   180 {
       
   181     ref.ref(); // Need to do extra ref so the shared null does not get destructed
       
   182 }
       
   183 
       
   184 /*!
       
   185 \internal
       
   186 */
       
   187 HbIconPrivate::HbIconPrivate( const QIcon &qicon ) :
       
   188     engine(0),
       
   189     qicon(qicon),
       
   190     badgeInfo(0)
       
   191 {
       
   192 }
       
   193 
       
   194 /*!
       
   195 \internal
       
   196 */
       
   197 HbIconPrivate::HbIconPrivate( const QString &iconName ) :
       
   198     engine( new HbIconEngine(iconName) ),
       
   199     qicon(engine),
       
   200     badgeInfo(0)
       
   201 {
       
   202 }
       
   203 
       
   204 /*!
       
   205 \internal
       
   206 */
       
   207 HbIconPrivate::HbIconPrivate( const HbIconPrivate &other ) :
       
   208     QSharedData( other ),
       
   209     size( other.size ),
       
   210     engine(0),
       
   211     qicon(),
       
   212     badgeInfo(0)
       
   213 {
       
   214     if ( other.engine ) {
       
   215         engine = new HbIconEngine( *other.engine );
       
   216         // Have to instantiate a temporary QIcon because 
       
   217         // QIcon's copy constructor shares the engine.
       
   218         QIcon temp(engine);
       
   219         qicon = temp;
       
   220     } else {
       
   221         // Copy constructed from qicon - so just copy the qicon.
       
   222         qicon = other.qicon;
       
   223         if ( other.badgeInfo ) {
       
   224             badgeInfo = new HbBadgeIcon(*other.badgeInfo);
       
   225         }   
       
   226     }
       
   227 }
       
   228 
       
   229 /*!
       
   230 \internal
       
   231 */
       
   232 HbIconPrivate::~HbIconPrivate()
       
   233 {
       
   234     delete badgeInfo;
       
   235 
       
   236     if (engine) {
       
   237         engine->setAnimator(0);
       
   238     }
       
   239     // engine is deleted by QIcon destructor.
       
   240 }
       
   241 
       
   242 /*!
       
   243 \internal
       
   244 */
       
   245 void HbIconPrivate::clear()
       
   246 {
       
   247     if (badgeInfo) {
       
   248         badgeInfo->removeAllBadges();
       
   249     }
       
   250     if (engine) {
       
   251         engine->clear();
       
   252         size = QSizeF();
       
   253     } else {
       
   254         qicon = QIcon();
       
   255     }
       
   256 }
       
   257 
       
   258 /*!
       
   259 \internal
       
   260 */
       
   261 void HbIconPrivate::removeAllBadges()
       
   262 {
       
   263     if ( engine ) {
       
   264         engine->removeAllBadges();
       
   265     } else if ( badgeInfo ) {
       
   266         badgeInfo->removeAllBadges();
       
   267     }
       
   268 }
       
   269 
       
   270 /*!
       
   271 \internal
       
   272 */
       
   273 bool HbIconPrivate::isBadged() const
       
   274 {
       
   275     if ( engine ) {
       
   276         return engine->isBadged();
       
   277     } else if ( badgeInfo ) {
       
   278         return badgeInfo->isBadged();
       
   279     } 
       
   280     return false;
       
   281 }
       
   282 
       
   283 /*!
       
   284 \internal
       
   285 */
       
   286 QDataStream &operator>>(QDataStream &stream, HbIconPrivate &icon)
       
   287 {
       
   288     stream >> icon.size;
       
   289     int enginePtr = 0;
       
   290     stream >> enginePtr;
       
   291     if (enginePtr) {
       
   292         icon.engine = new HbIconEngine(stream);
       
   293     } else {
       
   294         stream >> icon.qicon;
       
   295     }
       
   296 
       
   297     return stream;
       
   298 }
       
   299 
       
   300 /*!
       
   301 \internal
       
   302 */
       
   303 QDataStream &operator<<(QDataStream &stream, const HbIconPrivate &icon)
       
   304 {
       
   305     stream << icon.size;
       
   306     // Put the engine pointer in stream to see if it exists
       
   307     stream << (qptrdiff)(icon.engine);
       
   308     // If the icon has engine, externalize it in the stream
       
   309     if (icon.engine) {
       
   310         icon.engine->externalize(stream);
       
   311     } else {
       
   312         stream << icon.qicon;
       
   313     }
       
   314 
       
   315     return stream;
       
   316 }
       
   317 
       
   318 /*!
       
   319 \internal
       
   320 */
       
   321 bool HbIconPrivate::addBadge(Qt::Alignment align,
       
   322                       const HbIcon& icon,
       
   323                       int z)
       
   324 {
       
   325     if ( icon.isBadged() ) {
       
   326         return false;
       
   327     } else if ( engine ) {
       
   328         engine->addBadge(align, icon, z);
       
   329     } else {
       
   330         if ( !badgeInfo ) {
       
   331             badgeInfo = new HbBadgeIcon();
       
   332         }
       
   333         badgeInfo->addBadge(align, icon, z);
       
   334     }
       
   335     return true;
       
   336 }
       
   337 
       
   338 /*!
       
   339 \internal
       
   340  */
       
   341 bool HbIconPrivate::removeBadge(const HbIcon& badge)
       
   342 {
       
   343     bool result = false;
       
   344 
       
   345     if ( engine ) {
       
   346         result = engine->removeBadge(badge);
       
   347     } else if ( badgeInfo ) {
       
   348         result = badgeInfo->removeBadge(badge);
       
   349     }
       
   350 
       
   351     return result;
       
   352 }
       
   353 
       
   354 /*! Default constructor. If this constructor is used, the icon name needs to be set
       
   355 * by calling HbIcon::setIconName.
       
   356 */
       
   357 HbIcon::HbIcon()
       
   358 {
       
   359     // Construct shared_null if not done yet.
       
   360     if ( !shared_null ) {
       
   361         shared_null = new HbIconPrivate;
       
   362     }
       
   363     d = shared_null;
       
   364 }
       
   365 
       
   366 /*! Constructs a new icon with the icon name \a iconName.
       
   367 */
       
   368 HbIcon::HbIcon( const QString &iconName )
       
   369 {
       
   370     d = new HbIconPrivate(iconName);
       
   371 }
       
   372 
       
   373 /*! Constructs a new icon to be a copy of the given QIcon.
       
   374 * Due to the limitations listed below, this constructor should be used only for
       
   375 * compatibility reasons if a QIcon instance needs to be passed as a parameter
       
   376 * to a method taking a HbIcon parameter.
       
   377 * \note If this constructor is used, there are the following limitations in the HbIcon methods.
       
   378 * - HbIcon::defaultSize() always returns QSizeF().
       
   379 * - HbIcon::paint() ignores the parameter aspectRatioMode and converts the given QRectF to QRect.
       
   380 * This method should only be used if absolute necessary, as this is not ideal for hardware accelerated environment.
       
   381 */
       
   382 HbIcon::HbIcon( const QIcon &icon )
       
   383 {
       
   384     d = new HbIconPrivate(icon);
       
   385 }
       
   386 
       
   387 /*!
       
   388 * Copy constructs a new icon using the \a other icon.
       
   389 * Copy-on-write semantics is used, so this only does a shallow copy.
       
   390 */
       
   391 HbIcon::HbIcon( const HbIcon &other ) :
       
   392     d( other.d )
       
   393 {
       
   394 }
       
   395 
       
   396 /*!
       
   397 * Assigns the \a other icon to this icon and returns a reference to
       
   398 * this icon. Copy-on-write semantics is used, so this only does a shallow copy.
       
   399 */
       
   400 HbIcon &HbIcon::operator=( const HbIcon &other )
       
   401 {
       
   402     if ( &other != this ) {
       
   403         d = other.d;
       
   404     }
       
   405     return *this;
       
   406 }
       
   407 
       
   408 /*!
       
   409 * Destroys the icon.
       
   410 */
       
   411 HbIcon::~HbIcon()
       
   412 {
       
   413 }
       
   414 
       
   415 /*!
       
   416 * Returns true if either
       
   417 * - Icon was not copy constructed from QIcon and it does not have the any icon names set.
       
   418 * - Icon was copy constructed from QIcon and QIcon::isNull returns true.
       
   419 * \note Even a non-null icon might not be able to create valid pixmaps,
       
   420 * e.g. if the file does not exist or cannot be read.
       
   421 */
       
   422 bool HbIcon::isNull() const
       
   423 {
       
   424     if (d->engine) {
       
   425         return d->engine->isNull();
       
   426     } else {
       
   427         return d->qicon.isNull();
       
   428     }
       
   429 }
       
   430 
       
   431 /*!
       
   432 * Clears the icon. After this it is same as a default constructed HbIcon.
       
   433 * Calling this method is faster than assigning a default constructed HbIcon to this icon.
       
   434 */
       
   435 void HbIcon::clear()
       
   436 {
       
   437     // A NULL icon is always cleared - save some time not detaching from it
       
   438     if ( d.constData() != shared_null ) {
       
   439         d.detach();
       
   440         d->clear();
       
   441     }
       
   442 }
       
   443 
       
   444 /*!
       
   445 * Indicates whether or not the icon is badged.
       
   446 * returns true if this icon is bearing a badge.
       
   447 */
       
   448 bool HbIcon::isBadged() const
       
   449 {
       
   450     return d->isBadged();
       
   451 }
       
   452 
       
   453 /*!
       
   454 * Returns the the default icon pixmap in state QIcon::Normal and mode QIcon::Off.
       
   455 *
       
   456 * \note This method should be used only if it is necessary to get hold of the pixel data
       
   457 * of the pixmap. It slows down hardware accelerated rendering. In normal use cases, this
       
   458 * method is not needed. HbIcon::size() can be used to retrieve the size of the icon
       
   459 * and HbIcon::paint() to paint the icon.
       
   460 */
       
   461 QPixmap HbIcon::pixmap()
       
   462 {
       
   463     if (d->engine) {
       
   464         return d->engine->pixmap( d->size.toSize(), QIcon::Normal, QIcon::Off );
       
   465     }
       
   466 
       
   467     return QPixmap();
       
   468 }
       
   469 
       
   470 /*!
       
   471 * Sets the new color that is used to colorize mono icons.
       
   472 *
       
   473 * \param  color to be set
       
   474 *
       
   475 * This setting will be ignored for regular files when the HbIcon::Colorized flag
       
   476 * is not set.  This does not apply to theme elements, for them the color is
       
   477 * always taken into account when the logical graphics name indicates that it is
       
   478 * a mono icon.
       
   479 * 
       
   480 * Note that if a widget css defines a color for an icon primitive then the style will take
       
   481 * care of calling setColor() with the correct color from the theme whenever the theme
       
   482 * changes. Typical examples of such widgets are the itemviews (e.g. list, grid). Therefore
       
   483 * mono icons shown in such widgets will automatically be colorized with a theme-specific
       
   484 * color if the icon is either a mono icon coming from the theme or the icon has the
       
   485 * HbIcon::Colorized flag set.
       
   486 *
       
   487 * \warning Currently this method makes use of pixmap() routine in case of NVG icons. 
       
   488 * pixmap() slows down the hardware accelerated rendering.  
       
   489 * 
       
   490 * \sa HbIcon::color(), HbIcon::Colorized
       
   491 */
       
   492 void HbIcon::setColor(const QColor &color)
       
   493 {
       
   494     if (d->engine) {
       
   495         if (color != d->engine->color()) {
       
   496             d.detach();
       
   497             d->engine->setColor(color);
       
   498         }
       
   499     }
       
   500 }
       
   501 
       
   502 /*!
       
   503 * brief  Returns the color of the Icon.
       
   504 * \sa HbIcon::setColor()
       
   505 */
       
   506 QColor HbIcon::color() const
       
   507 {
       
   508     if (d->engine) {
       
   509         return d->engine->color();
       
   510     } else {
       
   511         return QColor();
       
   512     }
       
   513 }
       
   514 
       
   515 /*!
       
   516 * Returns the name of the icon.
       
   517 * This icon name is used if there is no name set separately for the specified icon mode and state.
       
   518 * \sa HbIcon::setIconName()
       
   519 */
       
   520 QString HbIcon::iconName() const
       
   521 {
       
   522     if (d->engine) {
       
   523         return d->engine->iconName();
       
   524     } else {
       
   525         return QString();
       
   526     }
       
   527 }
       
   528 
       
   529 /*!
       
   530 * Sets the name of the icon.
       
   531 * This icon name is used if there is no name set separately for the specified icon mode and state.
       
   532 * \sa HbIcon::iconName()
       
   533 */
       
   534 void HbIcon::setIconName( const QString &iconName )
       
   535 {
       
   536     if (d->engine && d->engine->iconName() != iconName) {
       
   537         d.detach();
       
   538         d->engine->setIconName(iconName);
       
   539     } else {
       
   540         // Icon was earlier copy constructed from QIcon, but now its name is set,
       
   541         // so it becomes a 'real' HbIcon.
       
   542         d.detach();
       
   543         d->engine = new HbIconEngine(iconName);
       
   544         d->engine->setSize(d->size);
       
   545         // Have to instantiate a temporary QIcon because 
       
   546         // QIcon's assignment operator shares the engine.
       
   547         QIcon temp(d->engine);
       
   548         d->qicon = temp;
       
   549     }
       
   550 }
       
   551 
       
   552 /*!
       
   553 * Returns the name of the icon in the specified \a mode and \a state.
       
   554 * If there is no icon name set for the specified \a mode and \a state,
       
   555 * the icon name set without these parameters is returned.
       
   556 * \sa HbIcon::setIconName()
       
   557 */
       
   558 QString HbIcon::iconName( QIcon::Mode mode, QIcon::State state ) const
       
   559 {
       
   560     QString ret;
       
   561 
       
   562     if (d->engine) {
       
   563         ret = d->engine->iconName( mode, state );
       
   564         if ( ret.isEmpty() ) {
       
   565             ret = d->engine->iconName();
       
   566         }
       
   567     }
       
   568 
       
   569     return ret;
       
   570 }
       
   571 
       
   572 /*!
       
   573 * Sets the name of the icon in the specified \a mode and \a state.
       
   574 * \note Passing an empty \a iconName removes the icon name definition specific to
       
   575 * the given mode and state.
       
   576 * \sa HbIcon::iconName()
       
   577 */
       
   578 void HbIcon::setIconName( const QString &iconName, QIcon::Mode mode, QIcon::State state )
       
   579 {
       
   580     if ( d->engine && d->engine->iconName(mode, state) != iconName) {
       
   581         d.detach();
       
   582         d->engine->setIconName(iconName, mode, state);
       
   583     }
       
   584 }
       
   585 
       
   586 /*! Paints the icon in the given \a painter with the specified drawing parameters.
       
   587 * \note If the constructor HbIcon::HbIcon(const QIcon &icon) is used, the parameter
       
   588 * \a aspectRatioMode is ignored and Qt::KeepAspectRatio is used. Also in that case the icon
       
   589 * is not scaled exactly to the given size but the best size match returned by the QIcon 
       
   590 * instance is used.
       
   591 */
       
   592 void HbIcon::paint( QPainter *painter,
       
   593                     const QRectF &rect,
       
   594                     Qt::AspectRatioMode aspectRatioMode,
       
   595                     Qt::Alignment alignment,
       
   596                     QIcon::Mode mode,
       
   597                     QIcon::State state) const
       
   598 {
       
   599     if ( !rect.isEmpty() && d.constData() != shared_null ) {
       
   600         if ( d->engine ) {
       
   601             d->engine->paint( painter, rect, aspectRatioMode, alignment, mode, state );
       
   602         } else {
       
   603             // This HbIcon was copy constructed from QIcon and 
       
   604             // we cannot use HbIconEngine for painting.
       
   605             QSizeF size = this->size();
       
   606             if ( !size.isValid() ) {
       
   607                 // If size is not set, have to use rect size because QIcon
       
   608                 // does not provide defaultSize information.
       
   609                 size = rect.size();
       
   610             }
       
   611             
       
   612             QPixmap pixmap = d->qicon.pixmap( size.toSize(), mode, state );
       
   613             QSizeF pixmapSize = pixmap.size();
       
   614             // Adjust the alignment
       
   615             QPointF topLeft = rect.topLeft();            
       
   616 
       
   617             if ( alignment & Qt::AlignRight ) {
       
   618                 topLeft.setX( rect.right() - pixmapSize.width() );
       
   619             } else if ( alignment & Qt::AlignHCenter ) {
       
   620                 topLeft.setX( topLeft.x() + (rect.width() - pixmapSize.width()) / 2 );
       
   621             }
       
   622 
       
   623             if ( alignment & Qt::AlignBottom ) {
       
   624                 topLeft.setY( rect.bottom() - pixmapSize.height() );
       
   625             } else if ( alignment & Qt::AlignVCenter ) {
       
   626                 topLeft.setY( topLeft.y() + (rect.height() - pixmapSize.height()) / 2 );
       
   627             }
       
   628 
       
   629             painter->drawPixmap( topLeft, pixmap, pixmap.rect() );
       
   630 
       
   631             // Draw the badges on this icon
       
   632             if ( d->badgeInfo ) {
       
   633                 d->badgeInfo->paint(painter, rect, mode, state, false);
       
   634             }
       
   635         }
       
   636     }
       
   637 }
       
   638 
       
   639 /*! Returns the current size of the icon.
       
   640 * \sa HbIcon::setSize(), HbIcon::defaultSize()
       
   641 */
       
   642 QSizeF HbIcon::size() const
       
   643 {
       
   644     if ((static_cast<int>(flags()) & HbIcon::ResolutionCorrected)) {
       
   645         if (d->size.isValid()) {
       
   646             return d->size;
       
   647         } else { 
       
   648             QSizeF defSize(defaultSize());
       
   649             HbIconLoader::global()->applyResolutionCorrection(defSize);
       
   650             return defSize;
       
   651         }
       
   652     } else if (d->size.isValid()) {
       
   653         return d->size;
       
   654     }
       
   655     return defaultSize();
       
   656 }    
       
   657 
       
   658 /*! Returns the default size of the icon.
       
   659 */
       
   660 QSizeF HbIcon::defaultSize() const
       
   661 {
       
   662     // Default constructed icon?
       
   663     if ( d.constData() == shared_null ) {
       
   664         return QSizeF();
       
   665     }
       
   666 
       
   667     // Do not cache default size in this class,
       
   668     // because it may change when icon definitions change.
       
   669     else if (d->engine) {
       
   670         return d->engine->defaultSize();
       
   671     }
       
   672     // Constructed from QIcon
       
   673     else {
       
   674         QList<QSize> sizes = d->qicon.availableSizes();
       
   675         if (sizes.count()) {
       
   676             return QSizeF(sizes.at(0));
       
   677         } else {
       
   678             return QSizeF();
       
   679         }
       
   680     }
       
   681 }
       
   682 
       
   683 /*! Sets the \a height of the icon. Its width is computed using the aspect ratio of the icon.
       
   684 */
       
   685 void HbIcon::setHeight( qreal height ) 
       
   686 {
       
   687     QSizeF size = defaultSize();
       
   688     if ( size.height() > 0 ) {
       
   689         qreal ar = size.width() / size.height();
       
   690         setSize( QSizeF( ar * height , height) );
       
   691     }
       
   692 }
       
   693 
       
   694 /*! Sets the \a width of the icon. Its height is computed using the aspect ratio of the icon.
       
   695 */
       
   696 void HbIcon::setWidth( qreal width )
       
   697 {
       
   698     QSizeF size = defaultSize();
       
   699     if ( size.width() > 0 ) {
       
   700         qreal ar = size.height() / size.width();
       
   701         setSize( QSizeF( width, ar * width ) );
       
   702     }
       
   703 }
       
   704 
       
   705 /*! Returns the width of the icon.
       
   706 */
       
   707 qreal HbIcon::width() const 
       
   708 {
       
   709     return size().width();
       
   710 }
       
   711 
       
   712 /*! Returns the height of the icon.
       
   713 */
       
   714 qreal HbIcon::height() const
       
   715 {
       
   716     return size().height();
       
   717 }
       
   718 
       
   719 /*! Returns the mirroring mode set for the icon.
       
   720 * \sa HbIcon::setMirroringMode()
       
   721 */
       
   722 HbIcon::MirroringMode HbIcon::mirroringMode() const
       
   723 {
       
   724     if (d->engine) {
       
   725         return d->engine->mirroringMode();
       
   726     } else {
       
   727         return HbIcon::Default;
       
   728     }
       
   729 }
       
   730 
       
   731 /*! Sets the mirroring \a mode for the icon.
       
   732 * \sa HbIcon::mirroringMode()
       
   733 */
       
   734 void HbIcon::setMirroringMode( HbIcon::MirroringMode mode )
       
   735 {
       
   736     if (d->engine) {
       
   737         if ( mode != d->engine->mirroringMode() ) {
       
   738             d.detach();
       
   739             d->engine->setMirroringMode(mode);
       
   740         }
       
   741     }
       
   742 }
       
   743 
       
   744 
       
   745 /*! Returns the flags set for the icon.
       
   746 */
       
   747 HbIcon::Flags HbIcon::flags() const
       
   748 {
       
   749     if (d->engine) {
       
   750         return d->engine->flags();
       
   751     } else {
       
   752         return ( HbIcon::Flags )0;
       
   753     }
       
   754 }
       
   755 
       
   756 /*! Sets the flags for the icon.
       
   757 */
       
   758 void HbIcon::setFlags(HbIcon::Flags flags)
       
   759 {
       
   760     if (d->engine) {
       
   761         if (flags != d->engine->flags()) {
       
   762             d.detach();
       
   763             d->engine->setFlags(flags);
       
   764         }
       
   765     }
       
   766 }
       
   767 
       
   768 /*! Sets the size for the icon. Without calling this method, the icon uses its default size.
       
   769 * \sa HbIcon::size(), HbIcon::defaultSize()
       
   770 */
       
   771 void HbIcon::setSize( const QSizeF &size )
       
   772 {
       
   773     if ( size != d->size ) {
       
   774         d.detach();
       
   775 
       
   776         d->size = size;
       
   777         if (d->engine) {
       
   778             d->engine->setSize(size);
       
   779         }
       
   780     }
       
   781 }
       
   782 
       
   783 /*!
       
   784 * Returns the icon as a QVariant.
       
   785 */
       
   786 HbIcon::operator QVariant() const
       
   787 {
       
   788     return QVariant::fromValue(*this);
       
   789 }
       
   790 
       
   791 /*!
       
   792 * Returns a reference to a QIcon instance representing this icon.
       
   793 * \note The returned reference is valid only for the life time of this HbIcon instance.
       
   794 */
       
   795 QIcon & HbIcon::qicon() const
       
   796 {
       
   797     return d->qicon;
       
   798 }
       
   799 
       
   800 /*!
       
   801 * Equality operator. It compares the icon names for all the state and mode combinations.
       
   802 * The sizes set for the icons are not used for the comparison.
       
   803 */
       
   804 bool HbIcon::operator==( const HbIcon &other ) const
       
   805 {
       
   806     return !( *this != other );
       
   807 }
       
   808 
       
   809 /*!
       
   810 * Inequality operator. It compares the icon names for all the state and mode combinations.
       
   811 * The sizes set for the icons are not used for the comparison.
       
   812 */
       
   813 bool HbIcon::operator!=( const HbIcon &other ) const
       
   814 {
       
   815     // NULL icons are equal
       
   816     if ( isNull() && other.isNull() ) {
       
   817         if ( d->badgeInfo && other.d->badgeInfo ) {
       
   818             if ( d->badgeInfo->badges() != other.d->badgeInfo->badges() ) {
       
   819                 return true;
       
   820             }
       
   821         }
       
   822         return false;
       
   823     }
       
   824     
       
   825     const HbIconEngine *engine1 = d->engine;
       
   826     const HbIconEngine *engine2 = other.d->engine;
       
   827 
       
   828     // If both icons do not have engines, they are unequal.
       
   829     // An icon does not have an engine if it is constructed with a QIcon.
       
   830     if ( !engine1 || !engine2 ) {
       
   831         return true;   
       
   832     }
       
   833 
       
   834     if ( engine1->iconName() != engine2->iconName() ||
       
   835          engine1->iconName( QIcon::Normal, QIcon::Off )    != engine2->iconName( QIcon::Normal, QIcon::Off ) ||
       
   836          engine1->iconName( QIcon::Normal, QIcon::On )     != engine2->iconName( QIcon::Normal, QIcon::On ) ||
       
   837          engine1->iconName( QIcon::Disabled, QIcon::Off )  != engine2->iconName( QIcon::Disabled, QIcon::Off ) ||
       
   838          engine1->iconName( QIcon::Disabled, QIcon::On )   != engine2->iconName( QIcon::Disabled, QIcon::On ) ||
       
   839          engine1->iconName( QIcon::Active, QIcon::Off )    != engine2->iconName( QIcon::Active, QIcon::Off ) ||
       
   840          engine1->iconName( QIcon::Active, QIcon::On )     != engine2->iconName( QIcon::Active, QIcon::On ) ||
       
   841          engine1->iconName( QIcon::Selected, QIcon::Off )  != engine2->iconName( QIcon::Selected, QIcon::Off ) ||
       
   842          engine1->iconName( QIcon::Selected, QIcon::On )   != engine2->iconName( QIcon::Selected, QIcon::On ) ) {
       
   843 
       
   844         return true;
       
   845     }
       
   846 
       
   847     // If they have different badges, they are unequal
       
   848     if ( engine1->badges() != engine2->badges() ) {
       
   849         return true;
       
   850     }
       
   851 
       
   852     if ( engine1->color() != engine2->color() )
       
   853         return true;
       
   854     else
       
   855         return false;
       
   856 }
       
   857 
       
   858 /*!
       
   859  * Adds a badge icon to the existing icon. The badge icons
       
   860  * are drawn relative to the alignment you specify with the
       
   861  * z-order you provide.
       
   862  */
       
   863 bool HbIcon::addBadge( Qt::Alignment alignment,
       
   864               const HbIcon& badge,
       
   865               int z )
       
   866 {
       
   867     d.detach();
       
   868     return d->addBadge(alignment, badge, z);
       
   869 }
       
   870 
       
   871 /*!
       
   872  * Removes badge icon(s) from the icon.
       
   873  */
       
   874 bool HbIcon::removeBadge( const HbIcon& badge )
       
   875 {
       
   876     d.detach();
       
   877     return d->removeBadge( badge );
       
   878 }
       
   879 
       
   880 /*!
       
   881   Remove all badge icons from this icon
       
   882 */
       
   883 void HbIcon::removeAllBadges()
       
   884 {
       
   885     d.detach();
       
   886     d->removeAllBadges();
       
   887 }
       
   888 
       
   889 /*!
       
   890 * Externalizes the \a icon information in a data \a stream. It can be transferred to other process and
       
   891 * the icon can be reconstructed from the stream there.
       
   892 */
       
   893 QDataStream &operator<<(QDataStream &stream, const HbIcon &icon)
       
   894 {
       
   895     return stream << *icon.d.data();
       
   896 }
       
   897 
       
   898 /*!
       
   899 * Internalizes the \a icon information from a data \a stream and reconstructs the icon.
       
   900 * The streamed icon data can be transferred to another process and used from there.
       
   901 */
       
   902 QDataStream &operator>>(QDataStream &stream, HbIcon &icon)
       
   903 {
       
   904     icon.d.detach();
       
   905     return stream >> *icon.d.data();
       
   906 }
       
   907 
       
   908 /*!
       
   909     Clears the icon data (e.g. QPixmaps that are stored internally) but does not
       
   910     touch the settings, e.g. the size, state, flags, unlike clear().
       
   911 
       
   912     The call is simply forwarded to the underlying HbIconEngine. This function
       
   913     has no effect when the icon was constructed from a QIcon.
       
   914 
       
   915     \internal
       
   916 */
       
   917 void HbIconPrivate::clearStoredIconContent()
       
   918 {
       
   919     if (engine) {
       
   920         engine->clearStoredIconContent();
       
   921     }
       
   922 }