summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Koehne <kai.koehne@nokia.com>2010-07-12 14:45:22 +0200
committerKai Koehne <kai.koehne@nokia.com>2010-07-12 14:46:29 +0200
commit94264617bfdda8fbfc31921dc9ba49ffff84eaeb (patch)
tree4dad96ce1030152c538f71feb6fea87478c69f35
parent9d803829ebf186dcf8c78205ac3582fb472996e9 (diff)
downloadqt-creator-94264617bfdda8fbfc31921dc9ba49ffff84eaeb.tar.gz
QmlJSEditor: Use QmlOutline model also in combo box
The drop down combo box and the Outline in the sidebar now share the same model.
-rw-r--r--src/plugins/qmljseditor/qmljseditor.cpp99
-rw-r--r--src/plugins/qmljseditor/qmljseditor.h10
-rw-r--r--src/plugins/qmljseditor/qmljsoutline.cpp83
-rw-r--r--src/plugins/qmljseditor/qmljsoutline.h7
-rw-r--r--src/plugins/qmljseditor/qmloutlinemodel.cpp2
-rw-r--r--src/plugins/qmljseditor/qmloutlinemodel.h3
6 files changed, 102 insertions, 102 deletions
diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp
index 1d51d1be33..9142231c5c 100644
--- a/src/plugins/qmljseditor/qmljseditor.cpp
+++ b/src/plugins/qmljseditor/qmljseditor.cpp
@@ -32,6 +32,7 @@
#include "qmljshighlighter.h"
#include "qmljseditorplugin.h"
#include "qmljsmodelmanager.h"
+#include "qmloutlinemodel.h"
#include <qmljs/qmljsindenter.h>
#include <qmljs/qmljsinterpreter.h>
@@ -70,9 +71,11 @@
#include <QtGui/QMenu>
#include <QtGui/QComboBox>
+#include <QtGui/QHeaderView>
#include <QtGui/QInputDialog>
#include <QtGui/QMainWindow>
#include <QtGui/QToolBar>
+#include <QtGui/QTreeView>
enum {
UPDATE_DOCUMENT_DEFAULT_INTERVAL = 50,
@@ -612,6 +615,7 @@ QString QmlJSEditorEditable::preferredMode() const
QmlJSTextEditor::QmlJSTextEditor(QWidget *parent) :
TextEditor::BaseTextEditor(parent),
m_methodCombo(0),
+ m_outlineModel(new QmlOutlineModel(this)),
m_modelManager(0),
m_contextPane(0)
{
@@ -688,6 +692,16 @@ bool QmlJSTextEditor::isOutdated() const
return false;
}
+QmlOutlineModel *QmlJSTextEditor::outlineModel() const
+{
+ return m_outlineModel;
+}
+
+QModelIndex QmlJSTextEditor::outlineModelIndex() const
+{
+ return m_outlineModelIndex;
+}
+
Core::IEditor *QmlJSEditorEditable::duplicate(QWidget *parent)
{
QmlJSTextEditor *newEditor = new QmlJSTextEditor(parent);
@@ -794,33 +808,37 @@ void QmlJSTextEditor::modificationChanged(bool changed)
m_modelManager->fileChangedOnDisk(file()->fileName());
}
-void QmlJSTextEditor::jumpToMethod(int index)
+void QmlJSTextEditor::jumpToMethod(int /*index*/)
{
- if (index > 0 && index <= m_semanticInfo.declarations.size()) { // indexes are 1-based
- Declaration d = m_semanticInfo.declarations.at(index - 1);
- gotoLine(d.startLine, d.startColumn - 1);
- setFocus();
- }
+ QModelIndex index = m_methodCombo->view()->currentIndex();
+ AST::SourceLocation location = index.data(QmlOutlineModel::SourceLocationRole).value<AST::SourceLocation>();
+
+ QTextCursor cursor = textCursor();
+ cursor.setPosition(location.offset);
+ setTextCursor(cursor);
+
+ setFocus();
}
void QmlJSTextEditor::updateMethodBoxIndex()
{
- int line = 0, column = 0;
- convertPosition(position(), &line, &column);
+ m_outlineModelIndex = indexForPosition(position());
+ emit outlineModelIndexChanged(m_outlineModelIndex);
- int currentSymbolIndex = 0;
+ QModelIndex comboIndex = m_outlineModelIndex;
- int index = 0;
- while (index < m_semanticInfo.declarations.size()) {
- const Declaration &d = m_semanticInfo.declarations.at(index++);
+ if (comboIndex.isValid()) {
+ bool blocked = m_methodCombo->blockSignals(true);
- if (line < d.startLine)
- break;
- else
- currentSymbolIndex = index;
+ // There is no direct way to select a non-root item
+ m_methodCombo->setRootModelIndex(comboIndex.parent());
+ m_methodCombo->setCurrentIndex(comboIndex.row());
+ m_methodCombo->setRootModelIndex(QModelIndex());
+
+ updateMethodBoxToolTip();
+ m_methodCombo->blockSignals(blocked);
}
- m_methodCombo->setCurrentIndex(currentSymbolIndex);
updateUses();
}
@@ -983,6 +1001,14 @@ void QmlJSTextEditor::createToolBar(QmlJSEditorEditable *editable)
{
m_methodCombo = new QComboBox;
m_methodCombo->setMinimumContentsLength(22);
+ m_methodCombo->setModel(m_outlineModel);
+
+ QTreeView *treeView = new QTreeView;
+ treeView->header()->hide();
+ treeView->setItemsExpandable(false);
+ m_methodCombo->setView(treeView);
+ treeView->expandAll();
+
//m_methodCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
// Make the combo box prefer to expand
@@ -1332,15 +1358,14 @@ void QmlJSTextEditor::updateSemanticInfo(const SemanticInfo &semanticInfo)
FindDeclarations findDeclarations;
m_semanticInfo.declarations = findDeclarations(doc->ast());
- QStringList items;
- items.append(tr("<Select Symbol>"));
+ m_outlineModel->update(doc);
+ updateMethodBoxIndex();
- foreach (Declaration decl, m_semanticInfo.declarations)
- items.append(decl.text);
+ QTreeView *treeView = static_cast<QTreeView*>(m_methodCombo->view());
+ treeView->expandAll();
+ // ComboBox only let's you select top level indexes for a QAbstractItemModel!
+ // therefore we've to fake a treeview by listview + indentation
- m_methodCombo->clear();
- m_methodCombo->addItems(items);
- updateMethodBoxIndex();
if (m_contextPane) {
Node *newNode = m_semanticInfo.declaringMember(position());
if (newNode) {
@@ -1355,8 +1380,6 @@ void QmlJSTextEditor::updateSemanticInfo(const SemanticInfo &semanticInfo)
appendExtraSelectionsForMessages(&selections, doc->diagnosticMessages(), document());
appendExtraSelectionsForMessages(&selections, m_semanticInfo.semanticMessages, document());
setExtraSelections(CodeWarningsSelection, selections);
-
- emit semanticInfoUpdated(semanticInfo);
}
void QmlJSTextEditor::onCursorPositionChanged()
@@ -1372,6 +1395,30 @@ void QmlJSTextEditor::onCursorPositionChanged()
}
}
+QModelIndex QmlJSTextEditor::indexForPosition(unsigned cursorPosition, const QModelIndex &rootIndex) const
+{
+ QModelIndex lastIndex = rootIndex;
+
+
+ const int rowCount = m_outlineModel->rowCount(rootIndex);
+ for (int i = 0; i < rowCount; ++i) {
+ QModelIndex childIndex = m_outlineModel->index(i, 0, rootIndex);
+ AST::SourceLocation location = childIndex.data(QmlOutlineModel::SourceLocationRole).value<AST::SourceLocation>();
+
+ if ((cursorPosition >= location.offset)
+ && (cursorPosition <= location.offset + location.length)) {
+ lastIndex = childIndex;
+ break;
+ }
+ }
+
+ if (lastIndex != rootIndex) {
+ // recurse
+ lastIndex = indexForPosition(cursorPosition, lastIndex);
+ }
+ return lastIndex;
+}
+
SemanticHighlighter::Source QmlJSTextEditor::currentSource(bool force)
{
int line = 0, column = 0;
diff --git a/src/plugins/qmljseditor/qmljseditor.h b/src/plugins/qmljseditor/qmljseditor.h
index 0239050713..49910dbf54 100644
--- a/src/plugins/qmljseditor/qmljseditor.h
+++ b/src/plugins/qmljseditor/qmljseditor.h
@@ -35,6 +35,7 @@
#include <texteditor/basetexteditor.h>
#include <QtCore/QWaitCondition>
+#include <QtCore/QModelIndex>
#include <QtCore/QMutex>
#include <QtCore/QThread>
@@ -58,6 +59,7 @@ class Highlighter;
namespace Internal {
class QmlJSTextEditor;
+class QmlOutlineModel;
class QmlJSEditorEditable : public TextEditor::BaseTextEditorEditable
{
@@ -214,12 +216,15 @@ public:
int documentRevision() const;
bool isOutdated() const;
+ QmlOutlineModel *outlineModel() const;
+ QModelIndex outlineModelIndex() const;
+
public slots:
void followSymbolUnderCursor();
virtual void setFontSettings(const TextEditor::FontSettings &);
signals:
- void semanticInfoUpdated(const QmlJSEditor::Internal::SemanticInfo &semanticInfo);
+ void outlineModelIndexChanged(const QModelIndex &index);
private slots:
void onDocumentUpdated(QmlJS::Document::Ptr doc);
@@ -266,6 +271,7 @@ private:
QString wordUnderCursor() const;
SemanticHighlighter::Source currentSource(bool force = false);
+ QModelIndex indexForPosition(unsigned cursorPosition, const QModelIndex &rootIndex = QModelIndex()) const;
const Core::Context m_context;
@@ -273,6 +279,8 @@ private:
QTimer *m_updateUsesTimer;
QTimer *m_semanticRehighlightTimer;
QComboBox *m_methodCombo;
+ QmlOutlineModel *m_outlineModel;
+ QModelIndex m_outlineModelIndex;
QmlJS::ModelManagerInterface *m_modelManager;
QTextCharFormat m_occurrencesFormat;
QTextCharFormat m_occurrencesUnusedFormat;
diff --git a/src/plugins/qmljseditor/qmljsoutline.cpp b/src/plugins/qmljseditor/qmljsoutline.cpp
index a95c0842c9..a283ed8d16 100644
--- a/src/plugins/qmljseditor/qmljsoutline.cpp
+++ b/src/plugins/qmljseditor/qmljsoutline.cpp
@@ -4,6 +4,7 @@
#include <coreplugin/ifile.h>
#include <QtGui/QVBoxLayout>
+#include <QDebug>
using namespace QmlJS;
enum {
@@ -29,8 +30,7 @@ QmlJSOutlineTreeView::QmlJSOutlineTreeView(QWidget *parent) :
QmlJSOutlineWidget::QmlJSOutlineWidget(QWidget *parent) :
TextEditor::IOutlineWidget(parent),
- m_treeView(new QmlJSOutlineTreeView()),
- m_model(new QmlOutlineModel),
+ m_treeView(new QmlJSOutlineTreeView(this)),
m_enableCursorSync(true),
m_blockCursorSync(false)
{
@@ -41,91 +41,40 @@ QmlJSOutlineWidget::QmlJSOutlineWidget(QWidget *parent) :
layout->addWidget(m_treeView);
setLayout(layout);
-
- m_treeView->setModel(m_model);
-
- connect(m_treeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- this, SLOT(updateSelectionInText(QItemSelection)));
}
void QmlJSOutlineWidget::setEditor(QmlJSTextEditor *editor)
{
m_editor = editor;
- connect(m_editor.data(), SIGNAL(semanticInfoUpdated(QmlJSEditor::Internal::SemanticInfo)),
- this, SLOT(updateOutline(QmlJSEditor::Internal::SemanticInfo)));
- connect(m_editor.data(), SIGNAL(cursorPositionChanged()),
- this, SLOT(updateSelectionInTree()));
+ m_treeView->setModel(m_editor.data()->outlineModel());
+ connect(m_treeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+ this, SLOT(updateSelectionInText(QItemSelection)));
- updateOutline(m_editor.data()->semanticInfo());
+ connect(m_editor.data(), SIGNAL(outlineModelIndexChanged(QModelIndex)),
+ this, SLOT(updateSelectionInTree(QModelIndex)));
+ connect(m_editor.data()->outlineModel(), SIGNAL(updated()),
+ this, SLOT(modelUpdated()));
}
void QmlJSOutlineWidget::setCursorSynchronization(bool syncWithCursor)
{
m_enableCursorSync = syncWithCursor;
if (m_enableCursorSync)
- updateSelectionInTree();
+ updateSelectionInTree(m_editor.data()->outlineModelIndex());
}
-void QmlJSOutlineWidget::updateOutline(const QmlJSEditor::Internal::SemanticInfo &semanticInfo)
+void QmlJSOutlineWidget::modelUpdated()
{
- Document::Ptr doc = semanticInfo.document;
-
- if (!doc) {
- return;
- }
-
- if (!m_editor
- || m_editor.data()->file()->fileName() != doc->fileName()
- || m_editor.data()->documentRevision() != doc->editorRevision()) {
- return;
- }
-
- if (doc->ast()
- && m_model) {
-
- // got a correctly parsed (or recovered) file.
-
- if (QmlOutlineModel *qmlModel = qobject_cast<QmlOutlineModel*>(m_model)) {
- qmlModel->update(doc);
- }
- } else {
- // TODO: Maybe disable view?
- }
-
m_treeView->expandAll();
+ updateSelectionInTree(m_editor.data()->outlineModelIndex());
}
-QModelIndex QmlJSOutlineWidget::indexForPosition(const QModelIndex &rootIndex, int cursorPosition)
-{
- if (!rootIndex.isValid())
- return QModelIndex();
-
- AST::SourceLocation location = rootIndex.data(QmlOutlineModel::SourceLocationRole).value<AST::SourceLocation>();
-
- if (!offsetInsideLocation(cursorPosition, location)) {
- return QModelIndex();
- }
-
- const int rowCount = rootIndex.model()->rowCount(rootIndex);
- for (int i = 0; i < rowCount; ++i) {
- QModelIndex childIndex = rootIndex.child(i, 0);
- QModelIndex resultIndex = indexForPosition(childIndex, cursorPosition);
- if (resultIndex.isValid())
- return resultIndex;
- }
-
- return rootIndex;
-}
-
-void QmlJSOutlineWidget::updateSelectionInTree()
+void QmlJSOutlineWidget::updateSelectionInTree(const QModelIndex &index)
{
if (!syncCursor())
return;
- int absoluteCursorPos = m_editor.data()->textCursor().position();
- QModelIndex index = indexForPosition(m_model->index(0, 0), absoluteCursorPos);
-
m_blockCursorSync = true;
m_treeView->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect);
m_treeView->scrollTo(index);
@@ -150,12 +99,6 @@ void QmlJSOutlineWidget::updateSelectionInText(const QItemSelection &selection)
}
}
-bool QmlJSOutlineWidget::offsetInsideLocation(quint32 offset, const QmlJS::AST::SourceLocation &location)
-{
- return ((offset >= location.offset)
- && (offset <= location.offset + location.length));
-}
-
bool QmlJSOutlineWidget::syncCursor()
{
return m_enableCursorSync && !m_blockCursorSync;
diff --git a/src/plugins/qmljseditor/qmljsoutline.h b/src/plugins/qmljseditor/qmljsoutline.h
index 14441eff86..c42685dd8d 100644
--- a/src/plugins/qmljseditor/qmljsoutline.h
+++ b/src/plugins/qmljseditor/qmljsoutline.h
@@ -37,18 +37,15 @@ public:
virtual void setCursorSynchronization(bool syncWithCursor);
private slots:
- void updateOutline(const QmlJSEditor::Internal::SemanticInfo &semanticInfo);
- void updateSelectionInTree();
+ void modelUpdated();
+ void updateSelectionInTree(const QModelIndex &index);
void updateSelectionInText(const QItemSelection &selection);
private:
- QModelIndex indexForPosition(const QModelIndex &rootIndex, int cursorPosition);
- bool offsetInsideLocation(quint32 offset, const QmlJS::AST::SourceLocation &location);
bool syncCursor();
private:
QmlJSOutlineTreeView *m_treeView;
- QAbstractItemModel *m_model;
QWeakPointer<QmlJSTextEditor> m_editor;
bool m_enableCursorSync;
diff --git a/src/plugins/qmljseditor/qmloutlinemodel.cpp b/src/plugins/qmljseditor/qmloutlinemodel.cpp
index e0d7129640..33e2269cf9 100644
--- a/src/plugins/qmljseditor/qmloutlinemodel.cpp
+++ b/src/plugins/qmljseditor/qmloutlinemodel.cpp
@@ -124,6 +124,8 @@ void QmlOutlineModel::update(QmlJS::Document::Ptr doc)
QmlOutlineModelSync syncModel(this);
syncModel(doc);
+
+ emit updated();
}
QModelIndex QmlOutlineModel::enterElement(const QString &type, const AST::SourceLocation &sourceLocation)
diff --git a/src/plugins/qmljseditor/qmloutlinemodel.h b/src/plugins/qmljseditor/qmloutlinemodel.h
index 67c2628f0d..e5065238d9 100644
--- a/src/plugins/qmljseditor/qmloutlinemodel.h
+++ b/src/plugins/qmljseditor/qmloutlinemodel.h
@@ -27,6 +27,9 @@ public:
QModelIndex enterProperty(const QString &name, const QmlJS::AST::SourceLocation &location);
void leaveProperty();
+signals:
+ void updated();
+
private:
QStandardItem *enterNode(const QmlJS::AST::SourceLocation &location);
void leaveNode();