diff --git a/src/plugins/qmldesigner/components/propertyeditor/colorwidget.cpp b/src/plugins/qmldesigner/components/propertyeditor/colorwidget.cpp
index 8c716350dbd19d0ce02717226afae0f6950e4bec..6db5a6e28b6a722f7165fd7ee8ebbd40eab941ea 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/colorwidget.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/colorwidget.cpp
@@ -40,6 +40,9 @@
 #include <nodelistproperty.h>
 #include <variantproperty.h>
 #include <qmlobjectnode.h>
+#include <qmlitemnode.h>
+#include <QGradient>
+#include <metainfo.h>
 
 namespace QmlDesigner {
 
@@ -47,6 +50,7 @@ namespace QmlDesigner {
         qmlRegisterType<QmlDesigner::ColorButton>("Bauhaus",1,0,"ColorButton");
         qmlRegisterType<QmlDesigner::HueControl>("Bauhaus",1,0,"HueControl");
         qmlRegisterType<QmlDesigner::ColorBox>("Bauhaus",1,0,"ColorBox");
+        qmlRegisterType<QmlDesigner::GradientLine>("Bauhaus",1,0,"GradientLine");
     }
 
     void ColorButton::paintEvent(QPaintEvent *event)
@@ -65,7 +69,17 @@ namespace QmlDesigner {
         else
             p.setBrush(Qt::transparent);
         p.setPen(Qt::black);
-        p.drawRect(r);
+
+        if (!m_noColor) {
+            p.drawRect(r);
+        } else {
+            p.fillRect(r, Qt::white);
+            p.fillRect(0, 0, width() /2, height() /2, QColor(Qt::gray));
+            p.fillRect(width() /2, height() /2, width() /2, height() /2, QColor(Qt::gray));
+            p.setBrush(Qt::transparent);
+            p.drawRect(r);
+        }
+
 
         QVector<QPointF> points;
         if (isChecked()) {
@@ -198,4 +212,265 @@ namespace QmlDesigner {
         p.drawRect(QRect(0, 0, width() - 1, height() -1).adjusted(4, 4, -4, -4));
     }
 
+void GradientLine::setItemNode(const QVariant &itemNode)
+{
+
+    if (!itemNode.value<ModelNode>().isValid() || !QmlItemNode(itemNode.value<ModelNode>()).hasNodeParent())
+        return;
+    m_itemNode = itemNode.value<ModelNode>();
+    setup();
+    emit itemNodeChanged();
+}
+
+static inline QColor invertColor(const QColor color)
+{
+    QColor c = color.toHsv();
+    c.setHsv(c.hue(), c.saturation(), 255 - c.value());
+    return c;
+}
+
+void GradientLine::setupGradient()
+{
+    ModelNode modelNode = m_itemNode.modelNode();
+    m_colorList.clear();
+    m_stops.clear();
+
+    if (modelNode.hasProperty(m_gradientName)) { //gradient exists
+
+        ModelNode gradientNode = modelNode.nodeProperty(m_gradientName).modelNode();
+        QList<ModelNode> stopList = gradientNode.nodeListProperty("stops").toModelNodeList();
+
+        foreach (const ModelNode &stopNode, stopList) {
+            QmlObjectNode stopObjectNode = stopNode;
+            if (stopObjectNode.isValid()) {
+                m_stops << stopObjectNode.instanceValue("position").toReal();
+                m_colorList << stopObjectNode.instanceValue("color").value<QColor>();
+            }
+        }
+    } else {
+        m_colorList << m_activeColor << QColor(Qt::black);
+        m_stops << 0 << 1;
+    }
+
+    updateGradient();
+}
+
+bool GradientLine::event(QEvent *event)
+{
+    if (event->type() == QEvent::ShortcutOverride)
+        if (static_cast<QKeyEvent*>(event)->matches(QKeySequence::Delete)) {
+            event->accept();
+            return true;
+    }
+
+    return QWidget::event(event);
+}
+
+void GradientLine::keyPressEvent(QKeyEvent * event)
+{
+    if (event->matches(QKeySequence::Delete)) {
+        if ((currentColorIndex()) != 0 && (currentColorIndex() < m_stops.size() - 1)) {
+            m_dragActive = false;
+            m_stops.removeAt(currentColorIndex());
+            m_colorList.removeAt(currentColorIndex());
+            updateGradient();
+            setCurrentIndex(0);
+            //delete item
+        }
+    } else {
+       QWidget::keyPressEvent(event);
+    }
+}
+
+void GradientLine::paintEvent(QPaintEvent *event)
+{
+    QWidget::paintEvent(event);
+    QPainter p(this);
+
+    QPen pen(Qt::black);
+    pen.setWidth(1);
+    p.setPen(pen);
+
+    QLinearGradient linearGradient(QPointF(2, 0), QPointF(width() -2, 0));
+
+    for (int i =0; i < m_stops.size(); i++)
+         linearGradient.setColorAt(m_stops.at(i), m_colorList.at(i));
+
+    p.setBrush(linearGradient);
+    p.drawRoundedRect(8, 30, width() - 16, height() - 32, 5, 5);
+
+    for (int i =0; i < m_colorList.size(); i++) {
+        int localYOffset = 0;
+        QColor arrowColor(Qt::black);
+        if (i == currentColorIndex()) {
+            localYOffset = m_yOffset;
+            arrowColor = QColor("#cdcdcd");
+        }
+        p.setPen(arrowColor);
+        if (i == 0 || i == (m_colorList.size() - 1))
+            localYOffset = 0;
+
+        int pos = qreal((width() - 20)) * m_stops.at(i) + 10;
+        p.setBrush(arrowColor);
+        QVector<QPointF> points;
+        points.append(QPointF(pos, 28 + localYOffset)); //triangle
+        points.append(QPointF(pos - 4, 22 + localYOffset));
+        points.append(QPointF(pos + 4, 22 + localYOffset));
+        p.drawPolygon(points);
+
+        if (i == currentColorIndex())
+            p.fillRect(pos - 6, 9 + localYOffset, 13, 13, invertColor(m_colorList.at(i)));
+
+        p.fillRect(pos - 4, 11 + localYOffset, 9, 9, m_colorList.at(i));
+    }
+}
+
+void GradientLine::mousePressEvent(QMouseEvent *event)
+{
+    if (event->button() == Qt::LeftButton) {
+        int xPos = event->pos().x();
+        int yPos = event->pos().y();
+
+        int draggedIndex = -1;
+        m_create = false;
+        m_dragActive = false;
+        if ((yPos > 10) && (yPos < 30))
+            for (int i =0; i < m_stops.size(); i++) {
+            int pos = qreal((width() - 20)) * m_stops.at(i) + 10;
+            if (((xPos + 5) > pos) && ((xPos - 5) < pos)) {
+                draggedIndex = i;
+                m_dragActive = true;
+                m_dragStart = event->pos();
+                setCurrentIndex(draggedIndex);
+                update();
+            }
+        }
+        if (draggedIndex == -1)
+            m_create = true;
+    }
+    setFocus(Qt::MouseFocusReason);
+    event->accept();
+    //QWidget::mousePressEvent(event);
+}
+
+void GradientLine::mouseReleaseEvent(QMouseEvent *event)
+{
+    if (event->button() == Qt::LeftButton) {
+        if (m_dragActive == false && m_create) {
+            qreal stopPos = qreal(event->pos().x() - 10) / qreal((width() - 20));
+            int index = -1;
+            for (int i =0; i < m_stops.size() - 1; i++) {
+                if ((stopPos > m_stops.at(i)) && (index == -1))
+                    index = i +1;
+            }
+            if (index != -1 && m_itemNode.isInBaseState()) { //creating of items only in base state
+                m_stops.insert(index, stopPos);
+                m_colorList.insert(index, QColor(Qt::white));
+                setCurrentIndex(index);
+                updateGradient();
+            }
+        }
+    }
+    m_dragActive = false;
+    m_yOffset = 0;
+    update();
+    updateGradient();
+    event->accept();
+    //QWidget::mouseReleaseEvent(event);
+}
+
+void GradientLine::mouseMoveEvent(QMouseEvent *event)
+{
+    if (m_dragActive) {
+        int xDistance = event->pos().x() - m_dragStart.x();
+        qreal distance = qreal(xDistance) / qreal((width() - 20));
+        qreal newStop  = m_stops.at(currentColorIndex()) + distance;
+        if ((newStop >=0) && (newStop <= 1))
+            m_stops[currentColorIndex()] = newStop;
+        m_yOffset += event->pos().y() - m_dragStart.y();
+        if (m_yOffset > 0 || !m_itemNode.isInBaseState()) { //deleting only in base state
+            m_yOffset = 0;         
+        } else if ((m_yOffset < - 12) && (currentColorIndex()) != 0 && (currentColorIndex() < m_stops.size() - 1)) {
+            m_yOffset = 0;
+            m_dragActive = false;
+            m_stops.removeAt(currentColorIndex());
+            m_colorList.removeAt(currentColorIndex());
+            updateGradient();
+            setCurrentIndex(0);
+            //delete item
+        }
+
+        int xPos = event->pos().x();
+        int pos = qreal((width() - 20)) * m_stops.at(currentColorIndex()) + 10;
+        if (!(((xPos + 5) > pos) && ((xPos - 5) < pos))) { //still on top of the item?
+            m_dragActive = false; //abort drag
+            m_yOffset = 0;
+        }
+        m_dragStart = event->pos();
+        update();
+    }
+
+    QWidget::mouseMoveEvent(event);
+}
+
+void GradientLine::setup()
+{    
+
+}
+
+static inline QColor normalizeColor(const QColor &color)
+{
+    QColor newColor = QColor(color.name());
+    newColor.setAlpha(color.alpha());
+    return newColor;
+}
+
+static inline qreal roundReal(qreal real)
+{
+    int i = real * 100;
+    return qreal(i) / 100;
+}
+
+void GradientLine::updateGradient()
+{
+    if (!active())
+        return;
+    RewriterTransaction transaction;
+    if (!m_itemNode.isValid())
+        return;
+
+    if (!m_itemNode.modelNode().metaInfo().hasProperty(m_gradientName))
+        return;
+
+    ModelNode modelNode = m_itemNode.modelNode();
+
+    if (m_itemNode.isInBaseState()) {
+        if (modelNode.hasProperty(m_gradientName))
+            modelNode.removeProperty(m_gradientName);
+
+        ModelNode gradientNode = modelNode.view()->createModelNode("Qt/Gradient", 4, 6);
+
+
+        for (int i = 0;i < m_stops.size(); i++) {
+            ModelNode gradientStopNode = modelNode.view()->createModelNode("Qt/GradientStop", 4, 6);
+            gradientStopNode.variantProperty("position") = roundReal(m_stops.at(i));
+            gradientStopNode.variantProperty("color") = normalizeColor(m_colorList.at(i));
+            gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode);
+        }
+        modelNode.nodeProperty(m_gradientName).reparentHere(gradientNode);
+    } else { //state
+        if  (!modelNode.hasProperty(m_gradientName)) {
+            qWarning(" GradientLine::updateGradient: no gradient in state");
+            return;
+        }
+        ModelNode gradientNode = modelNode.nodeProperty(m_gradientName).modelNode();
+        QList<ModelNode> stopList = gradientNode.nodeListProperty("stops").toModelNodeList();
+        for (int i = 0;i < m_stops.size(); i++) {            
+            QmlObjectNode stopObjectNode = stopList.at(i);
+            stopObjectNode.setVariantProperty("position", roundReal(m_stops.at(i)));
+            stopObjectNode.setVariantProperty("color", normalizeColor(m_colorList.at(i)));
+        }
+    }
+}
+
 }
diff --git a/src/plugins/qmldesigner/components/propertyeditor/colorwidget.h b/src/plugins/qmldesigner/components/propertyeditor/colorwidget.h
index baba3e3ab394cef8d8457e8ae6c88cb07ee2b585..67645d6ee52c0c47ce893eed57ac73a673089e25 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/colorwidget.h
+++ b/src/plugins/qmldesigner/components/propertyeditor/colorwidget.h
@@ -38,6 +38,7 @@
 #include <modelnode.h>
 #include <qdeclarative.h>
 #include <propertyeditorvalue.h>
+#include <qmlitemnode.h>
 
 QT_BEGIN_NAMESPACE
 class QtColorButton;
@@ -51,10 +52,12 @@ class ColorButton : public QToolButton {
 Q_OBJECT
 
 Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
+Q_PROPERTY(bool noColor READ noColor WRITE setNoColor)
+
 
 public:
 
-    ColorButton(QWidget *parent = 0) : QToolButton (parent), m_colorString("#ffffff")
+    ColorButton(QWidget *parent = 0) : QToolButton (parent), m_colorString("#ffffff"), m_noColor(false)
     {
     }
 
@@ -73,6 +76,9 @@ public:
         return m_colorString;
     }
 
+    bool noColor() const { return m_noColor; }
+    void setNoColor(bool f) { m_noColor = f; update(); }
+
 signals:
     void colorChanged();
 
@@ -80,6 +86,7 @@ protected:
     void paintEvent(QPaintEvent *event);
 private:
     QString m_colorString;
+    bool m_noColor;
 };
 
 inline QString properName(const QColor &color)
@@ -342,10 +349,106 @@ private:
     QPixmap m_cache;
 };
 
+class GradientLine : public QWidget {
+
+    Q_OBJECT
+    Q_PROPERTY(QColor activeColor READ activeColor WRITE setActiveColor NOTIFY activeColorChanged)
+    Q_PROPERTY(QVariant itemNode READ itemNode WRITE setItemNode NOTIFY itemNodeChanged)
+    Q_PROPERTY(QString gradientName READ gradientName WRITE setGradientName NOTIFY gradientNameChanged)
+    Q_PROPERTY(bool active READ active WRITE setActive)
+
+public:
+    GradientLine(QWidget *parent = 0) : QWidget(parent), m_gradientName("gradient"), m_activeColor(Qt::black), m_dragActive(false), m_yOffset(0), m_create(false), m_active(false)
+    {
+        setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+        setFocusPolicy(Qt::StrongFocus);
+        setFixedHeight(50);
+        setMinimumWidth(160);
+        resize(160, 50);
+        m_colorList << m_activeColor << QColor(Qt::white);
+        m_stops << 0 << 1;
+        updateGradient();
+        setCurrentIndex(0);
+    }
+
+
+    QVariant itemNode() const { return QVariant::fromValue(m_itemNode.modelNode()); }
+    void setItemNode(const QVariant &itemNode);
+    QString gradientName() const { return m_gradientName; }
+    void setGradientName(const QString &newName)
+    {
+        if (newName == m_gradientName)
+            return;
+        m_gradientName = newName;
+        setup();
+        emit gradientNameChanged();
+    }
+
+    QColor activeColor() const { return m_activeColor; }
+    void setActiveColor(const QColor &newColor)
+    {
+        if (newColor.name() == m_activeColor.name() && newColor.alpha() == m_activeColor.alpha())
+            return;
+
+        m_activeColor = newColor;
+        m_colorList.removeAt(currentColorIndex());
+        m_colorList.insert(currentColorIndex(), m_activeColor);
+        updateGradient();
+        update();
+    }
+
+    bool active() const { return m_active; }
+    void setActive(bool a) { m_active = a; }
+
+public slots:
+    void setupGradient();
+
+signals:
+    void activeColorChanged();
+    void itemNodeChanged();
+    void gradientNameChanged();
+protected:
+    bool GradientLine::event(QEvent *event);
+    void keyPressEvent(QKeyEvent * event);
+    void paintEvent(QPaintEvent *event);
+    void mousePressEvent(QMouseEvent *);
+    void mouseReleaseEvent(QMouseEvent *);
+    void mouseMoveEvent(QMouseEvent *);    
+
+private:
+    void setup();
+    void updateGradient();
+    int currentColorIndex() const { return m_colorIndex; }
+    void setCurrentIndex(int i)
+    {
+        if (i == m_colorIndex)
+            return;
+        m_colorIndex = i;
+        setActiveColor(m_colorList.at(i));
+        emit activeColorChanged();
+        update();
+    }
+
+    QColor m_activeColor;
+    QmlItemNode m_itemNode;
+    QString m_gradientName;
+    QList<QColor> m_colorList;
+    QList<qreal> m_stops;
+    int m_colorIndex;
+    bool m_dragActive;
+    QPoint m_dragStart;
+    int m_yOffset;
+    bool m_create;
+    bool m_active;
+};
+
 
 class ColorWidget {
+
 public:
     static void registerDeclarativeTypes();
+
+
 };