summaryrefslogtreecommitdiff
path: root/src/plugins/qmljseditor/qmljseditor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/qmljseditor/qmljseditor.cpp')
-rw-r--r--src/plugins/qmljseditor/qmljseditor.cpp99
1 files changed, 73 insertions, 26 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;