From 8eedde33c5d024badce40d440af981f51cfee504 Mon Sep 17 00:00:00 2001
From: mae <qt-info@nokia.com>
Date: Fri, 9 Apr 2010 12:59:20 +0200
Subject: [PATCH] Implement tooltips for snippets

---
 share/qtcreator/snippets/qml.xml              |  6 +-
 .../qmljseditor/qmljscodecompletion.cpp       | 19 +++--
 src/plugins/texteditor/completionwidget.cpp   | 82 ++++++++++++++++++-
 src/plugins/texteditor/completionwidget.h     |  5 ++
 4 files changed, 100 insertions(+), 12 deletions(-)

diff --git a/share/qtcreator/snippets/qml.xml b/share/qtcreator/snippets/qml.xml
index f856c204c43..9a116470ef3 100644
--- a/share/qtcreator/snippets/qml.xml
+++ b/share/qtcreator/snippets/qml.xml
@@ -65,9 +65,9 @@
 </snippet>
 
 <snippet>PropertyChanges {
-        target: <tab>name</tab>
-        <tab/>
-    }
+    target: <tab>name</tab>
+    <tab/>
+}
 </snippet>
 
 <snippet description="with targets">NumberAnimation { targets: [<tab>name</tab>]; properties: "<tab>name</tab>"; duration: <tab>200</tab> }
diff --git a/src/plugins/qmljseditor/qmljscodecompletion.cpp b/src/plugins/qmljseditor/qmljscodecompletion.cpp
index 1f6c187d334..61ebb7911cc 100644
--- a/src/plugins/qmljseditor/qmljscodecompletion.cpp
+++ b/src/plugins/qmljseditor/qmljscodecompletion.cpp
@@ -888,26 +888,31 @@ void CodeCompletion::updateSnippets()
                             item.data = QVariant::fromValue(data);
 
 
-                            QString tooltip = data;
-                            tooltip.replace(QRegExp("\n\\s*"), QLatin1String(" "));
+                            QString infotip = data;
+                            while (infotip.size() && infotip.at(infotip.size()-1).isSpace())
+                                infotip.chop(1);
+                            infotip.replace(QLatin1Char('\n'), QLatin1String("<br>"));
+                            infotip.replace(QLatin1Char(' '), QLatin1String("&nbsp;"));
                             {
                                 QString s = QLatin1String("<nobr>");
                                 int count = 0;
-                                for (int i = 0; i < tooltip.count(); ++i) {
-                                    if (tooltip.at(i) != QChar::ObjectReplacementCharacter) {
-                                        s += tooltip.at(i);
+                                for (int i = 0; i < infotip.count(); ++i) {
+                                    if (infotip.at(i) != QChar::ObjectReplacementCharacter) {
+                                        s += infotip.at(i);
                                         continue;
                                     }
                                     if (++count % 2) {
                                         s += QLatin1String("<b>");
                                     } else {
+                                        if (infotip.at(i-1) == QChar::ObjectReplacementCharacter)
+                                            s += QLatin1String("...");
                                         s += QLatin1String("</b>");
                                     }
                                 }
-                                tooltip = s;
+                                infotip = s;
                             }
 
-                            item.details = tooltip; // ###TODO this should not be the normal tooltip
+                            item.details = infotip;
 
                             item.icon = icon;
                             m_snippets.append(item);
diff --git a/src/plugins/texteditor/completionwidget.cpp b/src/plugins/texteditor/completionwidget.cpp
index b102793b6de..8c2e1811581 100644
--- a/src/plugins/texteditor/completionwidget.cpp
+++ b/src/plugins/texteditor/completionwidget.cpp
@@ -40,6 +40,8 @@
 #include <QtGui/QKeyEvent>
 #include <QtGui/QVBoxLayout>
 #include <QtGui/QScrollBar>
+#include <QtGui/QLabel>
+#include <QtGui/QStylePainter>
 
 #include <limits.h>
 
@@ -68,6 +70,41 @@ private:
     QList<CompletionItem> m_items;
 };
 
+
+class CompletionInfoFrame : public QLabel {
+public:
+
+    CompletionInfoFrame(QWidget *parent = 0) :
+            QLabel(parent, Qt::ToolTip | Qt::WindowStaysOnTopHint)
+    {
+        setFocusPolicy(Qt::NoFocus);
+        setAttribute(Qt::WA_DeleteOnClose);
+        setAutoFillBackground(true);
+        setBackgroundRole(QPalette::ToolTipBase);
+        setMargin(1 + style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, 0, this));
+        setIndent(1);
+    }
+
+    void paintEvent(QPaintEvent *e) {
+        QStylePainter p(this);
+        QStyleOptionFrame opt;
+        opt.init(this);
+        p.drawPrimitive(QStyle::PE_PanelTipLabel, opt);
+        p.end();
+        QLabel::paintEvent(e);
+    }
+    void resizeEvent(QResizeEvent *e)
+    {
+        QStyleHintReturnMask frameMask;
+        QStyleOption option;
+        option.init(this);
+        if (style()->styleHint(QStyle::SH_ToolTip_Mask, &option, this, &frameMask))
+            setMask(frameMask.region);
+        QLabel::resizeEvent(e);
+    }
+};
+
+
 } // namespace Internal
 } // namespace TextEditor
 
@@ -97,7 +134,7 @@ QVariant AutoCompletionModel::data(const QModelIndex &index, int role) const
         return itemAt(index).text;
     } else if (role == Qt::DecorationRole) {
         return itemAt(index).icon;
-    } else if (role == Qt::ToolTipRole) {
+    } else if (role == Qt::WhatsThisRole) {
         return itemAt(index).details;
     }
 
@@ -211,7 +248,6 @@ void CompletionWidget::updatePositionAndSize(int startPos)
     setGeometry(pos.x(), pos.y(), width, height);
 }
 
-
 CompletionListView::CompletionListView(CompletionSupport *support, ITextEditable *editor, CompletionWidget *completionWidget)
     : QListView(completionWidget),
       m_blockFocusOut(false),
@@ -237,14 +273,56 @@ CompletionListView::CompletionListView(CompletionSupport *support, ITextEditable
     if (verticalScrollBar())
         verticalScrollBar()->setAttribute(Qt::WA_MacMiniSize);
 #endif
+
 }
 
 CompletionListView::~CompletionListView()
 {
 }
 
+void CompletionListView::maybeShowInfoTip()
+{
+    QModelIndex current = currentIndex();
+    if (!current.isValid())
+        return;
+    QString infoTip = current.data(Qt::WhatsThisRole).toString();
+
+    if (infoTip.isEmpty()) {
+        delete m_infoFrame.data();
+        return;
+    }
+
+    if (m_infoFrame.isNull())
+        m_infoFrame = new CompletionInfoFrame(this);
+
+
+    QRect r = rectForIndex(current);
+    m_infoFrame->move(
+            (parentWidget()->mapToGlobal(
+                    parentWidget()->rect().topRight() + QPoint(2, 0))).x(),
+            mapToGlobal(r.topRight()).y() - verticalOffset()
+            );
+    m_infoFrame->setText(infoTip);
+    m_infoFrame->adjustSize();
+    m_infoFrame->show();
+}
+
+void CompletionListView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
+{
+    QListView::currentChanged(current, previous);
+    if (isVisible())
+        maybeShowInfoTip();
+}
+
+
 bool CompletionListView::event(QEvent *e)
 {
+    if (e->type() == QEvent::Show) {
+        bool b = QListView::event(e);
+        maybeShowInfoTip();
+        return b;
+    }
+
     if (m_blockFocusOut)
         return QListView::event(e);
 
diff --git a/src/plugins/texteditor/completionwidget.h b/src/plugins/texteditor/completionwidget.h
index e7663b425be..ef1087955e6 100644
--- a/src/plugins/texteditor/completionwidget.h
+++ b/src/plugins/texteditor/completionwidget.h
@@ -43,6 +43,7 @@ namespace Internal {
 class AutoCompletionModel;
 class CompletionSupport;
 class CompletionListView;
+class CompletionInfoFrame;
 
 /* The completion widget is responsible for showing a list of possible completions.
    It is only used by the CompletionSupport.
@@ -89,6 +90,8 @@ signals:
 protected:
     bool event(QEvent *e);
 
+    void currentChanged(const QModelIndex &current, const QModelIndex &previous);
+
 private:
     friend class CompletionWidget;
 
@@ -98,6 +101,7 @@ private:
     void setCompletionItems(const QList<TextEditor::CompletionItem> &completionitems);
     void keyboardSearch(const QString &search);
     void closeList(const QModelIndex &index);
+    void maybeShowInfoTip();
 
     bool m_blockFocusOut;
     bool m_quickFix;
@@ -106,6 +110,7 @@ private:
     CompletionWidget *m_completionWidget;
     AutoCompletionModel *m_model;
     CompletionSupport *m_support;
+    QPointer<CompletionInfoFrame> m_infoFrame;
 };
 
 } // namespace Internal
-- 
GitLab