From ddf360d4a9718ae5a80f4a266515a76348198d3c Mon Sep 17 00:00:00 2001
From: Thomas Hartmann <Thomas.Hartmann@nokia.com>
Date: Fri, 10 Dec 2010 15:33:20 +0100
Subject: [PATCH] QMlDesigner.navigator: visualize unknown types

Types unknown to the metasystem get the red line now and a questionmark icon.
---
 .../itemlibrary/images/item-default-icon.png  | Bin 590 -> 317 bytes
 .../itemlibrary/images/item-invalid-icon.png  | Bin 0 -> 603 bytes
 .../components/itemlibrary/itemlibrary.qrc    |   1 +
 .../navigator/navigatortreemodel.cpp          |   8 ++
 .../navigator/navigatortreeview.cpp           |  80 +++++++++++++++++-
 5 files changed, 86 insertions(+), 3 deletions(-)
 create mode 100644 src/plugins/qmldesigner/components/itemlibrary/images/item-invalid-icon.png

diff --git a/src/plugins/qmldesigner/components/itemlibrary/images/item-default-icon.png b/src/plugins/qmldesigner/components/itemlibrary/images/item-default-icon.png
index 82c6ef1a41e2c6a28ba85619640e97ad993ba09d..5000ba2600f3170f9ee490509d7e7afdcff06ede 100644
GIT binary patch
delta 230
zcmV<C02%+z1ib=~Uw;e=3?meHRl@WD006y7L_t(Y$F-C}4uv2LL<izA*m4<<%b~o2
zA*JnK{Ae_W2tsGc;=P6rxEP~4=P()(0W*V{p{nQE0s!l}euAp%1A0wL=`Yx}ts726
zRq!=SFPND@M6cjaf>H{IsB0kKdo8_b7VP`}sR-T@-Xs`-zh4SQ;nfzYDss-45npRd
zYtOp{$J3t`Kcnl-f|kE!NHBZ)o4{iFo1l~ei}<7WB4Q`7n*J2b?EOO^A|}f{1s2u3
g#)S~nYQX^T1N4B0<PH%|ivR!s07*qoM6N<$g8H^-bN~PV

delta 505
zcmV<V0S5lP0?q`GUw;G!2{|(nAG_8700GWPL_t(Y$F-F)Z`x24g})aJPL*PpAw^UO
zs#Hz|Q@TYR(j}?{QUqOCqV7@uOqIRL-V9ZQnz70+KqX69@q$#4z-4Om{QNppMUh-=
z9;j!u?>pz7^L(#`=XqKP!KR3!2&EKCDYVv$XBI%S*<6cMYkwUheTZ(i`$u3j8X1#I
zDVGvIgk?&sltN0GO1zdp7=}nGjT%}>pj0aHa(^G!b<tWg9*^nY-ZGobQqOLs71Zl>
zS|=yG*xN%#5xHEBR|f~YKRu;Vsch!J&gFQ0c*t}*<@4nwzwYk=cwVj2Znb!Oe9Whd
zi}f88i$${8EPvno{RKI|(DxboK91wyI?j3mN+~j#3_%bunM~FmKx^3mNh!G-47eK%
zV($xu0@X@|APD$5pPM^K`p)zDJn!0Vgb;kYxiNR}cl7@S*Kz1{Iy~Cm=Iiw}zVDk0
zBn?ud(ctmU4qvXWRw9o@l(bu(xGv91C5FDgGI>lOsd9VUwgH%@T<X$@(l+Cd@tBY2
z=PNI{n1e736AOh9*tU&jS>^&-YoaJhEPT4V%ZIZw-W(m73#4_w354f)x>l<hXS)h|
vy&hXp6#W<SMMS25DC3CA<+4t@;7#xw0;%0?Bs27W00000NkvXXu0mjf4gKzV

diff --git a/src/plugins/qmldesigner/components/itemlibrary/images/item-invalid-icon.png b/src/plugins/qmldesigner/components/itemlibrary/images/item-invalid-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..e87fd3a0b51714e9f2fe5057022a81cd40d86401
GIT binary patch
literal 603
zcmV-h0;K(kP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp)
z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ign@
z3?dux@$Mu500G-cL_t(Y$E}skYTG~*g})g|mN7V~v7s$7g)B_z1C+c%$tF;`>Z0%0
zO&5l)+D++GbW==B?6?FAnouOo&+Wo;h@DE7>>ilS%;nBG_uM<9Mx&7^r8pGcdz^DP
z=Ma(my%6C1{CuyZBJwEdLyX7c)djQJtZ{N<OljhW2%9E$&S8w%nRpFdCur@EwU#{3
zK?E&A9p`o`h=Auoz}a-VvH!K-=ePIV9jf5vWWw3yC0M($|9ZLPt{||tf_AILs~{jr
zQ@)&@l4cnJ;DGl@!ke2Lz7GbNeH5(gtD=ZSzfYQFE0cksVD>BscoK${WzZGv!r=Cn
zA6j#DbhLT2o`cmepeqJ7EE}NA7^Wip>~@iY{WgIsYx(6Iwy6SR3|@q^VC%Qe-(Fvn
z#4(eTlgj%4Q^9)l%kXZoAc$i=b-PdzSE|4mQyTaoNoYqAAA3DIH78$hvoCuB262o7
zv{JOa=g&SDl(7d0tYxlO;i=ZO->$F@dw`{Ld^<jVWO!`_*4oOzTq&Y<n<xyMUmzlQ
zU(M}lr^Cg3&WkXl)!+xzb=YgAkis7&0yY1Fdk@@>e)b|HdCuov51VD!1|<r;_qBef
pyjV@4t6KAaKn;gO*=6t{_zNyD?k;Xsuk8Q;002ovPDHLkV1f_P5_SLp

literal 0
HcmV?d00001

diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc
index e4d27b04769..1343c939885 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc
@@ -8,6 +8,7 @@
         <file>qml/Selector.qml</file>
 
         <file>images/item-default-icon.png</file>
+        <file>images/item-invalid-icon.png</file>
     </qresource>
 </RCC>
 
diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp
index 804e45a0c76..bfd424755e9 100644
--- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp
+++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp
@@ -189,6 +189,10 @@ NavigatorTreeModel::ItemRow NavigatorTreeModel::createItemRow(const ModelNode &n
     idItem->setDropEnabled(dropEnabled);
     idItem->setEditable(true);
     idItem->setData(hash, NavigatorRole);
+    if (node.metaInfo().isValid())
+        idItem->setToolTip(node.type());
+    else
+        idItem->setToolTip(tr("unkown item: ") + node.type());
 
 #    ifdef _LOCK_ITEMS_
     QStandardItem *lockItem = new QStandardItem;
@@ -233,6 +237,10 @@ void NavigatorTreeModel::updateItemRow(const ModelNode &node, ItemRow items)
 
     items.idItem->setText(node.id());
     items.visibilityItem->setCheckState(node.auxiliaryData("invisible").toBool() ? Qt::Unchecked : Qt::Checked);
+    if (node.metaInfo().isValid())
+        items.idItem->setToolTip(node.type());
+    else
+        items.idItem->setToolTip(tr("unkown item: ") + node.type());
 
     blockItemChangedSignal(blockSignal);
 }
diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreeview.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreeview.cpp
index c914a26a0a1..49468353ac2 100644
--- a/src/plugins/qmldesigner/components/navigator/navigatortreeview.cpp
+++ b/src/plugins/qmldesigner/components/navigator/navigatortreeview.cpp
@@ -29,6 +29,8 @@
 
 #include "navigatortreeview.h"
 
+#include <qmath.h>
+
 #include "navigatorview.h"
 #include "navigatortreemodel.h"
 #include "navigatorwidget.h"
@@ -37,6 +39,58 @@
 #include <nodeproperty.h>
 #include "metainfo.h"
 #include <QLineEdit>
+#include <QPen>
+#include <QPixmapCache>
+
+
+static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
+{
+    const qreal radiusBase = qMax(qreal(1), maxRadius);
+
+    QString key = QLatin1String("WaveUnderline-Bauhaus");
+
+    QPixmap pixmap;
+    if (QPixmapCache::find(key, pixmap))
+        return pixmap;
+
+    const qreal halfPeriod = qMax(qreal(2), qreal(radiusBase * 1.61803399)); // the golden ratio
+    const int width = qCeil(100 / (2 * halfPeriod)) * (2 * halfPeriod);
+    const int radius = qFloor(radiusBase);
+
+    QPainterPath path;
+
+    qreal xs = 0;
+    qreal ys = radius;
+
+    while (xs < width) {
+        xs += halfPeriod;
+        ys = -ys;
+        path.quadTo(xs - halfPeriod / 2, ys, xs, 0);
+    }
+
+    pixmap = QPixmap(width, radius * 2);
+    pixmap.fill(Qt::transparent);
+    {
+        QPen wavePen = pen;
+        wavePen.setCapStyle(Qt::SquareCap);
+
+        // This is to protect against making the line too fat, as happens on Mac OS X
+        // due to it having a rather thick width for the regular underline.
+        const qreal maxPenWidth = .8 * radius;
+        if (wavePen.widthF() > maxPenWidth)
+            wavePen.setWidth(maxPenWidth);
+
+        QPainter imgPainter(&pixmap);
+        imgPainter.setPen(wavePen);
+        imgPainter.setRenderHint(QPainter::Antialiasing);
+        imgPainter.translate(0, radius);
+        imgPainter.drawPath(path);
+    }
+
+    QPixmapCache::insert(key, pixmap);
+
+    return pixmap;
+}
 
 namespace QmlDesigner {
 
@@ -169,7 +223,8 @@ void NameItemDelegate::paint(QPainter *painter,
     QPoint displayStringOffset;
 
     painter->save();
-
+    QFontMetrics fm(option.font);
+    int width;
     if (index.data(Qt::UserRole).isValid()) {
 
         int pixmapSide = 16;
@@ -196,6 +251,8 @@ void NameItemDelegate::paint(QPainter *painter,
         // if the library was also empty, use the default icon
         if (icon.isNull())
             icon = QIcon(QLatin1String(":/ItemLibrary/images/item-default-icon.png"));
+        if (!node.metaInfo().isValid())
+            icon = QIcon(QLatin1String(":/ItemLibrary/images/item-invalid-icon.png"));
 
         // If no icon is present, leave an empty space of 24 pixels anyway
         QPixmap pixmap = icon.pixmap(pixmapSide, pixmapSide);
@@ -207,16 +264,33 @@ void NameItemDelegate::paint(QPainter *painter,
 
         // Check text length does not exceed available space
         int extraSpace=12+pixmapSide;
-        QFontMetrics fm(option.font);
+
         displayString = fm.elidedText(displayString,Qt::ElideMiddle,option.rect.width()-extraSpace);
         displayStringOffset = QPoint(5+pixmapSide,-5);
+        width = fm.width(displayString);
     }
     else {
         displayString = index.data(Qt::DisplayRole).toString();
         displayStringOffset = QPoint(0, -2);
     }
 
-    painter->drawText(option.rect.bottomLeft()+displayStringOffset,displayString);
+    QPoint pos = option.rect.bottomLeft() + displayStringOffset;
+    painter->drawText(pos, displayString);
+
+    ModelNode node = m_TreeModel->nodeForIndex(index);
+
+    if (!node.isValid() ||!node.metaInfo().isValid()) {
+        painter->translate(0, pos.y() + 1);
+        QPen pen;
+        pen.setColor(Qt::red);
+
+        const qreal underlineOffset = fm.underlinePos();
+        const QPixmap wave = generateWavyPixmap(qMax(underlineOffset, pen.widthF()), pen);
+        const int descent = fm.descent();
+
+        painter->setBrushOrigin(painter->brushOrigin().x(), 0);
+        painter->fillRect(pos.x(), 0, qCeil(width), qMin(wave.height(), descent), wave);
+    }
 
     painter->restore();
 }
-- 
GitLab