Fix icon loading in style sheets.
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>
Mon, 27 Feb 2012 11:38:04 +0000 (12:38 +0100)
committerQt by Nokia <qt-info@nokia.com>
Mon, 27 Feb 2012 17:30:38 +0000 (18:30 +0100)
QIcon was moved to QtWidgets, while the parser is still in QtGui.
Introduce a QCss::IconValue struct that contains the icon data
and convert to QIcon in widgets.

Change-Id: I09ac8a12a4b02bdca91ee2e8fcc28c86b5a001e7
Reviewed-by: Morten Johan Sørvig <morten.sorvig@nokia.com>
src/gui/text/qcssparser.cpp
src/gui/text/qcssparser_p.h
src/widgets/styles/qstylesheetstyle.cpp

index 3807045..fd01934 100644 (file)
@@ -1272,11 +1272,9 @@ void ValueExtractor::extractFont()
     extractFont(&f, &dummy);
 }
 
-bool ValueExtractor::extractImage(QIcon *icon, Qt::Alignment *a, QSize *size)
+bool ValueExtractor::extractImage(QCss::IconValue *icon, Qt::Alignment *a, QSize *size)
 {
     bool hit = false;
-#if 0
-    // ### Qt5
     for (int i = 0; i < declarations.count(); ++i) {
         const Declaration &decl = declarations.at(i);
         switch (decl.d->propertyId) {
@@ -1297,7 +1295,6 @@ bool ValueExtractor::extractImage(QIcon *icon, Qt::Alignment *a, QSize *size)
         }
         hit = true;
     }
-#endif
     return hit;
 }
 
@@ -1646,30 +1643,27 @@ void Declaration::borderImageValue(QString *image, int *cuts,
         *h = *v;
 }
 
-#if 0
-// ### Qt 5
-QIcon Declaration::iconValue() const
+IconValue Declaration::iconValue() const
 {
     if (d->parsed.isValid())
-        return qvariant_cast<QIcon>(d->parsed);
+        return qvariant_cast<IconValue>(d->parsed);
 
-    QIcon icon;
+    IconValue icon;
     for (int i = 0; i < d->values.count();) {
         const Value &value = d->values.at(i++);
         if (value.type != Value::Uri)
             break;
-        QString uri = value.variant.toString();
-        QIcon::Mode mode = QIcon::Normal;
-        QIcon::State state = QIcon::Off;
+        IconValue::IconEntry entry;
+        entry.uri = value.variant.toString();
         for (int j = 0; j < 2; j++) {
             if (i != d->values.count() && d->values.at(i).type == Value::KnownIdentifier) {
                 switch (d->values.at(i).variant.toInt()) {
-                case Value_Disabled: mode = QIcon::Disabled; break;
-                case Value_Active: mode = QIcon::Active; break;
-                case Value_Selected: mode = QIcon::Selected; break;
-                case Value_Normal: mode = QIcon::Normal; break;
-                case Value_On: state = QIcon::On; break;
-                case Value_Off: state = QIcon::Off; break;
+                case Value_Disabled: entry.mode = IconValue::Disabled; break;
+                case Value_Active: entry.mode = IconValue::Active; break;
+                case Value_Selected: entry.mode = IconValue::Selected; break;
+                case Value_Normal: entry.mode = IconValue::Normal; break;
+                case Value_On: entry.state = IconValue::On; break;
+                case Value_Off: entry.state = IconValue::Off; break;
                 default: break;
                 }
                 ++i;
@@ -1677,12 +1671,7 @@ QIcon Declaration::iconValue() const
                 break;
             }
         }
-
-        // QIcon is soo broken
-        if (icon.isNull())
-            icon = QIcon(uri);
-        else
-            icon.addPixmap(uri, mode, state);
+        icon.entries.push_back(entry);
 
         if (i == d->values.count())
             break;
@@ -1691,10 +1680,9 @@ QIcon Declaration::iconValue() const
             i++;
     }
 
-    d->parsed = QVariant::fromValue<QIcon>(icon);
+    d->parsed = QVariant::fromValue<QCss::IconValue>(icon);
     return icon;
 }
-#endif
 
 ///////////////////////////////////////////////////////////////////////////////
 // Selector
index d50b87d..b19fd83 100644 (file)
@@ -411,6 +411,22 @@ struct BorderData {
     BrushData color;
 };
 
+struct Q_GUI_EXPORT IconValue
+{
+    enum Mode { Normal, Disabled, Active, Selected }; // In sync with QIcon.
+    enum State { On, Off };
+
+    struct Q_GUI_EXPORT IconEntry
+    {
+        IconEntry() : mode(Normal) , state(On) {}
+
+        Mode mode;
+        State state;
+        QString uri;
+    };
+
+    QList<IconEntry> entries;
+};
 
 // 1. StyleRule - x:hover, y:clicked > z:checked { prop1: value1; prop2: value2; }
 // 2. QVector<Selector> - x:hover, y:clicked z:checked
@@ -455,7 +471,7 @@ struct Q_GUI_EXPORT Declaration
     QSize sizeValue() const;
     QRect rectValue() const;
     QString uriValue() const;
-//    QIcon iconValue() const;
+    IconValue iconValue() const;
 
     void borderImageValue(QString *image, int *cuts, TileMode *h, TileMode *v) const;
 };
@@ -582,7 +598,7 @@ struct Q_GUI_EXPORT ValueExtractor
     bool extractOutline(int *borders, QBrush *colors, BorderStyle *Styles, QSize *radii, int *offsets);
     bool extractPalette(QBrush *fg, QBrush *sfg, QBrush *sbg, QBrush *abg);
     int  extractStyleFeatures();
-    bool extractImage(QIcon *icon, Qt::Alignment *a, QSize *size);
+    bool extractImage(QCss::IconValue *icon, Qt::Alignment *a, QSize *size);
 
     int lengthValue(const Declaration &decl);
 
@@ -842,6 +858,7 @@ QT_END_NAMESPACE
 Q_DECLARE_METATYPE( QCss::BackgroundData )
 Q_DECLARE_METATYPE( QCss::LengthData )
 Q_DECLARE_METATYPE( QCss::BorderData )
+Q_DECLARE_METATYPE( QCss::IconValue )
 
 
 #endif // QT_NO_CSSPARSER
index 30c6ed5..5c0ee25 100644 (file)
@@ -860,6 +860,19 @@ static QStyle::StandardPixmap subControlIcon(int pe)
     return QStyle::SP_CustomBase;
 }
 
+static inline QIcon cssIconValueToIcon(const QCss::IconValue &iconValue)
+{
+    if (iconValue.entries.isEmpty())
+        return QIcon();
+    QIcon icon = QIcon(iconValue.entries.first().uri);
+    for (int i = 1; i < iconValue.entries.size(); ++i) {
+        const QCss::IconValue::IconEntry &entry = iconValue.entries.at(i);
+        icon.addPixmap(entry.uri, static_cast<QIcon::Mode>(entry.mode),
+                       static_cast<QIcon::State>(entry.state));
+    }
+    return icon;
+}
+
 QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QWidget *widget)
 : features(0), hasFont(false), pal(0), b(0), bg(0), bd(0), ou(0), geo(0), p(0), img(0), clipset(0)
 {
@@ -919,11 +932,11 @@ QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QWidget
     if (v.extractPalette(&fg, &sfg, &sbg, &abg))
         pal = new QStyleSheetPaletteData(fg, sfg, sbg, abg);
 
-    QIcon icon;
     alignment = Qt::AlignCenter;
     QSize size;
-    if (v.extractImage(&icon, &alignment, &size))
-        img = new QStyleSheetImageData(icon, alignment, size);
+    QCss::IconValue iconValue;
+    if (v.extractImage(&iconValue, &alignment, &size))
+        img = new QStyleSheetImageData(cssIconValueToIcon(iconValue), alignment, size);
 
     int adj = -255;
     hasFont = v.extractFont(&font, &adj);