From c03f2b03b23d56efe1845b74be7275c49b19e65c Mon Sep 17 00:00:00 2001
From: Thomas Hartmann <Thomas.Hartmann@nokia.com>
Date: Thu, 15 Jul 2010 16:40:19 +0200
Subject: [PATCH] QmlJS::IContextPane adapting the interface

closing windows with escape is now stacked again
---
 src/libs/qmljs/qmljsicontextpane.h         |  1 +
 src/plugins/qmldesigner/qmlcontextpane.cpp | 71 +++++++++++++++-------
 src/plugins/qmldesigner/qmlcontextpane.h   |  3 +-
 src/plugins/qmljseditor/qmljseditor.cpp    |  6 +-
 4 files changed, 57 insertions(+), 24 deletions(-)

diff --git a/src/libs/qmljs/qmljsicontextpane.h b/src/libs/qmljs/qmljsicontextpane.h
index 34b42f1269f..299ba5ea3af 100644
--- a/src/libs/qmljs/qmljsicontextpane.h
+++ b/src/libs/qmljs/qmljsicontextpane.h
@@ -54,6 +54,7 @@ public:
     virtual ~IContextPane() {}
     virtual void apply(TextEditor::BaseTextEditorEditable *editor, Document::Ptr doc, const QmlJS::Snapshot &snapshot, AST::Node *node, bool update) = 0;
     virtual void setEnabled(bool) = 0;
+    virtual QWidget* widget() = 0;
 };
 
 } // namespace QmlJS
diff --git a/src/plugins/qmldesigner/qmlcontextpane.cpp b/src/plugins/qmldesigner/qmlcontextpane.cpp
index ca07a3adf9c..52defaba5d0 100644
--- a/src/plugins/qmldesigner/qmlcontextpane.cpp
+++ b/src/plugins/qmldesigner/qmlcontextpane.cpp
@@ -11,6 +11,7 @@
 #include <qmljs/qmljslookupcontext.h>
 #include <qmljs/qmljsinterpreter.h>
 #include <qmljs/qmljsbind.h>
+#include <qmljs/qmljsscopebuilder.h>
 #include <texteditor/basetexteditor.h>
 #include <texteditor/tabsettings.h>
 #include <colorwidget.h>
@@ -85,6 +86,8 @@ void QmlContextPane::apply(TextEditor::BaseTextEditorEditable *editor, Document:
         scopeObject =  scopeObject->prototype(lookupContext->context());
     }
 
+    //qDebug() << prototypes;
+
     setEnabled(doc->isParsedCorrectly());
     m_editor = editor;
     contextWidget()->setParent(editor->widget()->parentWidget());
@@ -127,9 +130,9 @@ void QmlContextPane::apply(TextEditor::BaseTextEditorEditable *editor, Document:
         rect.moveTo(reg.boundingRect().topLeft());
         reg = reg.intersect(rect);
 
-        if (name.contains("Text")) {
+        if (name.contains("Text") || name.contains("Rectangle") || name.contains("Image")) {
             m_node = 0;
-            PropertyReader propertyReader(doc.data(), initializer);
+            PropertyReader propertyReader(doc, initializer);
             QTextCursor tc(editor->editor()->document());
             tc.setPosition(offset); 
             QPoint p1 = editor->editor()->mapToParent(editor->editor()->viewport()->mapToParent(editor->editor()->cursorRect(tc).topLeft()) - QPoint(0, contextWidget()->height() + 10));
@@ -140,12 +143,13 @@ void QmlContextPane::apply(TextEditor::BaseTextEditorEditable *editor, Document:
                 offset = QPoint(400 - reg.boundingRect().width() + 10 ,0);
             QPoint p3 = editor->editor()->mapToParent(editor->editor()->viewport()->mapToParent(reg.boundingRect().topRight()) + offset);
             p2.setX(p1.x());
+            contextWidget()->setType(name);
             if (!update)
                 contextWidget()->activate(p3 , p1, p2);
             else
                 contextWidget()->rePosition(p3 , p1, p2);
             m_blockWriting = true;
-            contextWidget()->setType(name);
+            contextWidget()->setPath(doc->path());
             contextWidget()->setProperties(&propertyReader);
             m_blockWriting = false;
             m_doc = doc;
@@ -183,37 +187,48 @@ void QmlContextPane::setProperty(const QString &propertyName, const QVariant &va
         Utils::ChangeSet changeSet;
         Rewriter rewriter(m_doc->source(), &changeSet, m_propertyOrder);
 
-        int line = 1;
+        int line = -1;
+        int endLine;
+
 
-        PropertyReader propertyReader(m_doc.data(), initializer);
+        Rewriter::BindingType bindingType = Rewriter::ScriptBinding;
+
+        if (stringValue.contains("{") && stringValue.contains("}"))
+            bindingType = Rewriter::ObjectBinding;
+
+        PropertyReader propertyReader(m_doc, initializer);
         if (propertyReader.hasProperty(propertyName)) {
-            rewriter.changeProperty(initializer, propertyName, stringValue, Rewriter::ScriptBinding);
+            rewriter.changeProperty(initializer, propertyName, stringValue, bindingType);
         } else {
-            rewriter.addBinding(initializer, propertyName, stringValue, Rewriter::ScriptBinding);
-            int column;
-            m_editor->convertPosition(changeSet.operationList().first().pos1, &line, &column); //get line
+            rewriter.addBinding(initializer, propertyName, stringValue, bindingType);
         }
 
-        QTextCursor tc(m_editor->editor()->document());
+        int column;
+        m_editor->convertPosition(changeSet.operationList().first().pos1, &line, &column); //get line
+        m_editor->convertPosition(changeSet.operationList().first().pos1 + changeSet.operationList().first().length1, &endLine, &column); //get line
+
+        QTextCursor tc = m_editor->editor()->textCursor();
         tc.beginEditBlock();
-        int cursorPostion = tc.position();
         changeSet.apply(&tc);
 
         if (line > 0) {
+            qDebug() << line;
             TextEditor::TabSettings ts = m_editor->editor()->tabSettings();
             QmlJSIndenter indenter;
             indenter.setTabSize(ts.m_tabSize);
             indenter.setIndentSize(ts.m_indentSize);
-            QTextBlock start = m_editor->editor()->document()->findBlockByNumber(line);
-            QTextBlock end = m_editor->editor()->document()->findBlockByNumber(line);
 
-            if (end.isValid()) {
-                const int indent = indenter.indentForBottomLine(m_editor->editor()->document()->begin(), end.next(), QChar::Null);
-                ts.indentLine(start, indent);
+            for (int i=line;i<=endLine;i++) {
+                QTextBlock start = m_editor->editor()->document()->findBlockByNumber(i);
+                QTextBlock end = m_editor->editor()->document()->findBlockByNumber(i);
+
+                if (end.isValid()) {
+                    const int indent = indenter.indentForBottomLine(m_editor->editor()->document()->begin(), end.next(), QChar::Null);
+                    ts.indentLine(start, indent);
+                }
             }
         }
         tc.endEditBlock();
-        tc.setPosition(cursorPostion);
     }
 }
 
@@ -229,7 +244,7 @@ void QmlContextPane::removeProperty(const QString &propertyName)
         else if (objectBinding)
             initializer = objectBinding->initializer;
 
-        PropertyReader propertyReader(m_doc.data(), initializer);
+        PropertyReader propertyReader(m_doc, initializer);
         if (propertyReader.hasProperty(propertyName)) {
             Utils::ChangeSet changeSet;
             Rewriter rewriter(m_doc->source(), &changeSet, m_propertyOrder);
@@ -247,6 +262,12 @@ void QmlContextPane::setEnabled(bool b)
 }
 
 
+QWidget* QmlContextPane::widget()
+{
+    return contextWidget();
+}
+
+
 void QmlContextPane::onPropertyChanged(const QString &name, const QVariant &value)
 {
     if (m_blockWriting)
@@ -258,7 +279,7 @@ void QmlContextPane::onPropertyChanged(const QString &name, const QVariant &valu
     m_doc.clear(); //the document is outdated
 }
 
-void QmlContextPane::onPropertyRemovedAndChange(const QString &remove, const QString &change, const QVariant &value)
+void QmlContextPane::onPropertyRemovedAndChange(const QString &remove, const QString &change, const QVariant &value, bool removeFirst)
 {
     if (m_blockWriting)
         return;
@@ -269,8 +290,14 @@ void QmlContextPane::onPropertyRemovedAndChange(const QString &remove, const QSt
     QTextCursor tc(m_editor->editor()->document());
     tc.beginEditBlock();
 
-    removeProperty(remove);
-    setProperty(change, value);
+    if (removeFirst) {
+        removeProperty(remove);
+        setProperty(change, value);
+    } else {
+        setProperty(change, value);
+        removeProperty(remove);
+    }
+
 
     tc.endEditBlock();
 
@@ -284,7 +311,7 @@ ContextPaneWidget* QmlContextPane::contextWidget()
         m_widget = new ContextPaneWidget;
         connect(m_widget.data(), SIGNAL(propertyChanged(QString,QVariant)), this, SLOT(onPropertyChanged(QString,QVariant)));
         connect(m_widget.data(), SIGNAL(removeProperty(QString)), this, SLOT(onPropertyRemoved(QString)));
-        connect(m_widget.data(), SIGNAL(removeAndChangeProperty(QString,QString,QVariant)), this, SLOT(onPropertyRemovedAndChange(QString,QString,QVariant)));
+        connect(m_widget.data(), SIGNAL(removeAndChangeProperty(QString,QString,QVariant, bool)), this, SLOT(onPropertyRemovedAndChange(QString,QString,QVariant, bool)));
     }
     return m_widget.data();
 }
diff --git a/src/plugins/qmldesigner/qmlcontextpane.h b/src/plugins/qmldesigner/qmlcontextpane.h
index a2b799042b7..f04e69b201e 100644
--- a/src/plugins/qmldesigner/qmlcontextpane.h
+++ b/src/plugins/qmldesigner/qmlcontextpane.h
@@ -32,11 +32,12 @@ public:
    void setProperty(const QString &propertyName, const QVariant &value);
    void removeProperty(const QString &propertyName);
    void setEnabled(bool);
+   QWidget* widget();
 
 public slots:
        void onPropertyChanged(const QString &, const QVariant &);
        void onPropertyRemoved(const QString &);
-       void onPropertyRemovedAndChange(const QString &, const QString &, const QVariant &);
+       void onPropertyRemovedAndChange(const QString &, const QString &, const QVariant &, bool removeFirst = true);
 private:
     ContextPaneWidget* contextWidget();
     QWeakPointer<ContextPaneWidget> m_widget;
diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp
index 21ff1abfe66..aecb16390ea 100644
--- a/src/plugins/qmljseditor/qmljseditor.cpp
+++ b/src/plugins/qmljseditor/qmljseditor.cpp
@@ -1306,7 +1306,11 @@ bool QmlJSTextEditor::event(QEvent *e)
     switch (e->type()) {
     case QEvent::ShortcutOverride:
         if (static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape && m_contextPane) {
-            m_contextPane->apply(editableInterface(),  m_semanticInfo.document, m_semanticInfo.snapshot, 0, false);
+            if ((m_contextPane) && m_contextPane->widget()->isVisible()) {
+                m_contextPane->apply(editableInterface(),  m_semanticInfo.document, m_semanticInfo.snapshot, 0, false);
+                e->accept();
+                return true;
+            }
         }
         break;
     default:
-- 
GitLab