| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | /**************************************************************************
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** This file is part of Qt Creator | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2011-01-11 16:28:15 +01:00
										 |  |  | ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-06-17 00:01:27 +10:00
										 |  |  | ** Contact: Nokia Corporation (qt-info@nokia.com) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2010-12-17 16:01:08 +01:00
										 |  |  | ** No Commercial Usage | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2010-12-17 16:01:08 +01:00
										 |  |  | ** This file contains pre-release code and may not be distributed. | 
					
						
							|  |  |  | ** You may use this file in accordance with the terms and conditions | 
					
						
							|  |  |  | ** contained in the Technology Preview License Agreement accompanying | 
					
						
							|  |  |  | ** this package. | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | ** | 
					
						
							|  |  |  | ** GNU Lesser General Public License Usage | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** Alternatively, this file may be used under the terms of the GNU Lesser | 
					
						
							|  |  |  | ** General Public License version 2.1 as published by the Free Software | 
					
						
							|  |  |  | ** Foundation and appearing in the file LICENSE.LGPL included in the | 
					
						
							|  |  |  | ** packaging of this file.  Please review the following information to | 
					
						
							|  |  |  | ** ensure the GNU Lesser General Public License version 2.1 requirements | 
					
						
							|  |  |  | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2010-12-17 16:01:08 +01:00
										 |  |  | ** In addition, as a special exception, Nokia gives you certain additional | 
					
						
							|  |  |  | ** rights.  These rights are described in the Nokia Qt LGPL Exception | 
					
						
							|  |  |  | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** If you have questions regarding the use of this file, please contact | 
					
						
							|  |  |  | ** Nokia at qt-info@nokia.com. | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | ** | 
					
						
							|  |  |  | **************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-15 17:20:03 +01:00
										 |  |  | #include "qmljseditor.h"
 | 
					
						
							| 
									
										
										
										
											2010-11-02 11:10:27 +01:00
										 |  |  | #include "qmljseditoreditable.h"
 | 
					
						
							| 
									
										
										
										
											2010-01-15 17:20:03 +01:00
										 |  |  | #include "qmljseditorconstants.h"
 | 
					
						
							| 
									
										
										
										
											2010-02-15 12:27:25 +01:00
										 |  |  | #include "qmljshighlighter.h"
 | 
					
						
							| 
									
										
										
										
											2010-01-15 17:20:03 +01:00
										 |  |  | #include "qmljseditorplugin.h"
 | 
					
						
							| 
									
										
										
										
											2010-09-16 12:57:07 +02:00
										 |  |  | #include "qmljsquickfix.h"
 | 
					
						
							|  |  |  | #include "qmloutlinemodel.h"
 | 
					
						
							| 
									
										
										
										
											2010-09-24 14:05:34 +02:00
										 |  |  | #include "qmljsfindreferences.h"
 | 
					
						
							| 
									
										
										
										
											2010-11-02 11:10:27 +01:00
										 |  |  | #include "qmljssemantichighlighter.h"
 | 
					
						
							| 
									
										
										
										
											2010-11-05 14:27:16 +01:00
										 |  |  | #include "qmljsindenter.h"
 | 
					
						
							| 
									
										
										
										
											2010-11-08 16:11:26 +01:00
										 |  |  | #include "qmljsautocompleter.h"
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-16 11:16:22 +02:00
										 |  |  | #include <qmljs/qmljsbind.h>
 | 
					
						
							| 
									
										
										
										
											2010-11-16 14:39:54 +01:00
										 |  |  | #include <qmljs/qmljsevaluate.h>
 | 
					
						
							| 
									
										
										
										
											2010-02-01 16:12:19 +01:00
										 |  |  | #include <qmljs/qmljsdocument.h>
 | 
					
						
							| 
									
										
										
										
											2010-07-07 13:09:30 +02:00
										 |  |  | #include <qmljs/qmljsicontextpane.h>
 | 
					
						
							| 
									
										
										
										
											2010-07-16 10:42:26 +02:00
										 |  |  | #include <qmljs/qmljslookupcontext.h>
 | 
					
						
							| 
									
										
										
										
											2010-11-11 10:05:05 +01:00
										 |  |  | #include <qmljs/qmljsmodelmanagerinterface.h>
 | 
					
						
							| 
									
										
										
										
											2010-01-15 13:39:54 +01:00
										 |  |  | #include <qmljs/parser/qmljsastvisitor_p.h>
 | 
					
						
							|  |  |  | #include <qmljs/parser/qmljsast_p.h>
 | 
					
						
							|  |  |  | #include <qmljs/parser/qmljsengine_p.h>
 | 
					
						
							| 
									
										
										
										
											2009-09-11 14:42:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-11 10:05:05 +01:00
										 |  |  | #include <qmljstools/qmljsqtstylecodeformatter.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | #include <coreplugin/actionmanager/actionmanager.h>
 | 
					
						
							| 
									
										
										
										
											2010-03-18 10:59:06 +01:00
										 |  |  | #include <coreplugin/actionmanager/actioncontainer.h>
 | 
					
						
							| 
									
										
										
										
											2010-11-02 16:53:56 +01:00
										 |  |  | #include <coreplugin/uniqueidmanager.h>
 | 
					
						
							| 
									
										
										
										
											2010-03-18 10:59:06 +01:00
										 |  |  | #include <coreplugin/actionmanager/command.h>
 | 
					
						
							| 
									
										
										
										
											2010-07-14 12:21:23 +02:00
										 |  |  | #include <coreplugin/editormanager/editormanager.h>
 | 
					
						
							| 
									
										
										
										
											2010-01-15 17:41:12 +01:00
										 |  |  | #include <coreplugin/icore.h>
 | 
					
						
							|  |  |  | #include <coreplugin/mimedatabase.h>
 | 
					
						
							| 
									
										
										
										
											2009-09-04 16:51:11 +02:00
										 |  |  | #include <extensionsystem/pluginmanager.h>
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | #include <texteditor/basetextdocument.h>
 | 
					
						
							|  |  |  | #include <texteditor/fontsettings.h>
 | 
					
						
							| 
									
										
										
										
											2010-10-29 15:20:10 +02:00
										 |  |  | #include <texteditor/tabsettings.h>
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | #include <texteditor/texteditorconstants.h>
 | 
					
						
							|  |  |  | #include <texteditor/texteditorsettings.h>
 | 
					
						
							| 
									
										
										
										
											2010-07-09 14:47:18 +02:00
										 |  |  | #include <texteditor/syntaxhighlighter.h>
 | 
					
						
							| 
									
										
										
										
											2010-08-05 10:44:50 +02:00
										 |  |  | #include <texteditor/refactoroverlay.h>
 | 
					
						
							| 
									
										
										
										
											2010-09-29 16:58:30 +02:00
										 |  |  | #include <texteditor/tooltip/tooltip.h>
 | 
					
						
							| 
									
										
										
										
											2010-03-16 16:51:45 +01:00
										 |  |  | #include <qmldesigner/qmldesignerconstants.h>
 | 
					
						
							| 
									
										
										
										
											2010-11-11 10:05:05 +01:00
										 |  |  | #include <projectexplorer/projectexplorerconstants.h>
 | 
					
						
							| 
									
										
										
										
											2009-12-02 17:59:27 +01:00
										 |  |  | #include <utils/changeset.h>
 | 
					
						
							| 
									
										
										
										
											2009-05-14 16:37:17 +02:00
										 |  |  | #include <utils/uncommentselection.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-15 17:41:12 +01:00
										 |  |  | #include <QtCore/QFileInfo>
 | 
					
						
							| 
									
										
										
										
											2010-09-16 12:57:07 +02:00
										 |  |  | #include <QtCore/QSignalMapper>
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | #include <QtCore/QTimer>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <QtGui/QMenu>
 | 
					
						
							|  |  |  | #include <QtGui/QComboBox>
 | 
					
						
							| 
									
										
										
										
											2010-07-12 14:45:22 +02:00
										 |  |  | #include <QtGui/QHeaderView>
 | 
					
						
							| 
									
										
										
										
											2009-05-05 15:33:39 +02:00
										 |  |  | #include <QtGui/QInputDialog>
 | 
					
						
							| 
									
										
										
										
											2009-05-05 16:18:36 +02:00
										 |  |  | #include <QtGui/QMainWindow>
 | 
					
						
							| 
									
										
										
										
											2009-07-16 17:34:04 +02:00
										 |  |  | #include <QtGui/QToolBar>
 | 
					
						
							| 
									
										
										
										
											2010-07-12 14:45:22 +02:00
										 |  |  | #include <QtGui/QTreeView>
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | enum { | 
					
						
							| 
									
										
										
										
											2010-09-08 12:52:17 +02:00
										 |  |  |     UPDATE_DOCUMENT_DEFAULT_INTERVAL = 100, | 
					
						
							| 
									
										
										
										
											2010-07-12 17:03:49 +02:00
										 |  |  |     UPDATE_USES_DEFAULT_INTERVAL = 150, | 
					
						
							| 
									
										
										
										
											2010-12-16 12:05:48 +01:00
										 |  |  |     UPDATE_OUTLINE_INTERVAL = 500 // msecs after new semantic info has been arrived / cursor has moved
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-11 11:22:26 +02:00
										 |  |  | using namespace QmlJS; | 
					
						
							|  |  |  | using namespace QmlJS::AST; | 
					
						
							| 
									
										
										
										
											2010-11-02 11:10:27 +01:00
										 |  |  | using namespace QmlJSEditor; | 
					
						
							| 
									
										
										
										
											2010-01-25 14:18:53 +01:00
										 |  |  | using namespace QmlJSEditor::Internal; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-14 16:06:42 +02:00
										 |  |  | namespace { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-06 17:26:29 +02:00
										 |  |  | class FindIdDeclarations: protected Visitor | 
					
						
							| 
									
										
										
										
											2009-05-04 18:58:36 +02:00
										 |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2010-01-26 14:14:01 +01:00
										 |  |  |     typedef QHash<QString, QList<AST::SourceLocation> > Result; | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-26 14:14:01 +01:00
										 |  |  |     Result operator()(Document::Ptr doc) | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         _ids.clear(); | 
					
						
							|  |  |  |         _maybeIds.clear(); | 
					
						
							| 
									
										
										
										
											2010-01-26 14:14:01 +01:00
										 |  |  |         if (doc && doc->qmlProgram()) | 
					
						
							|  |  |  |             doc->qmlProgram()->accept(this); | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         return _ids; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-05-04 18:58:36 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     QString asString(AST::UiQualifiedId *id) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QString text; | 
					
						
							|  |  |  |         for (; id; id = id->next) { | 
					
						
							|  |  |  |             if (id->name) | 
					
						
							|  |  |  |                 text += id->name->asString(); | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 text += QLatin1Char('?'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (id->next) | 
					
						
							|  |  |  |                 text += QLatin1Char('.'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return text; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void accept(AST::Node *node) | 
					
						
							|  |  |  |     { AST::Node::acceptChild(node, this); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     using Visitor::visit; | 
					
						
							|  |  |  |     using Visitor::endVisit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(AST::UiScriptBinding *node) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (asString(node->qualifiedId) == QLatin1String("id")) { | 
					
						
							|  |  |  |             if (AST::ExpressionStatement *stmt = AST::cast<AST::ExpressionStatement*>(node->statement)) { | 
					
						
							|  |  |  |                 if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(stmt->expression)) { | 
					
						
							|  |  |  |                     if (idExpr->name) { | 
					
						
							|  |  |  |                         const QString id = idExpr->name->asString(); | 
					
						
							|  |  |  |                         QList<AST::SourceLocation> *locs = &_ids[id]; | 
					
						
							|  |  |  |                         locs->append(idExpr->firstSourceLocation()); | 
					
						
							|  |  |  |                         locs->append(_maybeIds.value(id)); | 
					
						
							|  |  |  |                         _maybeIds.remove(id); | 
					
						
							|  |  |  |                         return false; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         accept(node->statement); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(AST::IdentifierExpression *node) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (node->name) { | 
					
						
							|  |  |  |             const QString name = node->name->asString(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (_ids.contains(name)) | 
					
						
							|  |  |  |                 _ids[name].append(node->identifierToken); | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 _maybeIds[name].append(node->identifierToken); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-05-04 18:58:36 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     Result _ids; | 
					
						
							|  |  |  |     Result _maybeIds; | 
					
						
							| 
									
										
										
										
											2009-05-04 18:58:36 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | class FindDeclarations: protected Visitor | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     QList<Declaration> _declarations; | 
					
						
							|  |  |  |     int _depth; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     QList<Declaration> operator()(AST::Node *node) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         _depth = -1; | 
					
						
							|  |  |  |         _declarations.clear(); | 
					
						
							|  |  |  |         accept(node); | 
					
						
							|  |  |  |         return _declarations; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     using Visitor::visit; | 
					
						
							|  |  |  |     using Visitor::endVisit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QString asString(AST::UiQualifiedId *id) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QString text; | 
					
						
							|  |  |  |         for (; id; id = id->next) { | 
					
						
							|  |  |  |             if (id->name) | 
					
						
							|  |  |  |                 text += id->name->asString(); | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 text += QLatin1Char('?'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (id->next) | 
					
						
							|  |  |  |                 text += QLatin1Char('.'); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         return text; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     void accept(AST::Node *node) | 
					
						
							|  |  |  |     { AST::Node::acceptChild(node, this); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void init(Declaration *decl, AST::UiObjectMember *member) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         const SourceLocation first = member->firstSourceLocation(); | 
					
						
							|  |  |  |         const SourceLocation last = member->lastSourceLocation(); | 
					
						
							|  |  |  |         decl->startLine = first.startLine; | 
					
						
							|  |  |  |         decl->startColumn = first.startColumn; | 
					
						
							|  |  |  |         decl->endLine = last.startLine; | 
					
						
							|  |  |  |         decl->endColumn = last.startColumn + last.length; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-19 10:31:42 +01:00
										 |  |  |     void init(Declaration *decl, AST::ExpressionNode *expressionNode) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         const SourceLocation first = expressionNode->firstSourceLocation(); | 
					
						
							|  |  |  |         const SourceLocation last = expressionNode->lastSourceLocation(); | 
					
						
							|  |  |  |         decl->startLine = first.startLine; | 
					
						
							|  |  |  |         decl->startColumn = first.startColumn; | 
					
						
							|  |  |  |         decl->endLine = last.startLine; | 
					
						
							|  |  |  |         decl->endColumn = last.startColumn + last.length; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     virtual bool visit(AST::UiObjectDefinition *node) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ++_depth; | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         Declaration decl; | 
					
						
							|  |  |  |         init(&decl, node); | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         decl.text.fill(QLatin1Char(' '), _depth); | 
					
						
							|  |  |  |         if (node->qualifiedTypeNameId) | 
					
						
							|  |  |  |             decl.text.append(asString(node->qualifiedTypeNameId)); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             decl.text.append(QLatin1Char('?')); | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         _declarations.append(decl); | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         return true; // search for more bindings
 | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     virtual void endVisit(AST::UiObjectDefinition *) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         --_depth; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     virtual bool visit(AST::UiObjectBinding *node) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ++_depth; | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         Declaration decl; | 
					
						
							|  |  |  |         init(&decl, node); | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         decl.text.fill(QLatin1Char(' '), _depth); | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         decl.text.append(asString(node->qualifiedId)); | 
					
						
							|  |  |  |         decl.text.append(QLatin1String(": ")); | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         if (node->qualifiedTypeNameId) | 
					
						
							|  |  |  |             decl.text.append(asString(node->qualifiedTypeNameId)); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             decl.text.append(QLatin1Char('?')); | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         _declarations.append(decl); | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         return true; // search for more bindings
 | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     virtual void endVisit(AST::UiObjectBinding *) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         --_depth; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-19 10:31:42 +01:00
										 |  |  |     virtual bool visit(AST::UiScriptBinding *) | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         ++_depth; | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-19 10:31:42 +01:00
										 |  |  | #if 0 // ### ignore script bindings for now.
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         Declaration decl; | 
					
						
							|  |  |  |         init(&decl, node); | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         decl.text.fill(QLatin1Char(' '), _depth); | 
					
						
							|  |  |  |         decl.text.append(asString(node->qualifiedId)); | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         _declarations.append(decl); | 
					
						
							| 
									
										
										
										
											2010-01-19 10:31:42 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         return false; // more more bindings in this subtree.
 | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-30 17:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     virtual void endVisit(AST::UiScriptBinding *) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         --_depth; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-01-19 10:31:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(AST::FunctionExpression *) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(AST::FunctionDeclaration *ast) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (! ast->name) | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Declaration decl; | 
					
						
							|  |  |  |         init(&decl, ast); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         decl.text.fill(QLatin1Char(' '), _depth); | 
					
						
							|  |  |  |         decl.text += ast->name->asString(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         decl.text += QLatin1Char('('); | 
					
						
							|  |  |  |         for (FormalParameterList *it = ast->formals; it; it = it->next) { | 
					
						
							|  |  |  |             if (it->name) | 
					
						
							|  |  |  |                 decl.text += it->name->asString(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (it->next) | 
					
						
							|  |  |  |                 decl.text += QLatin1String(", "); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         decl.text += QLatin1Char(')'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         _declarations.append(decl); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(AST::VariableDeclaration *ast) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (! ast->name) | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Declaration decl; | 
					
						
							|  |  |  |         decl.text.fill(QLatin1Char(' '), _depth); | 
					
						
							|  |  |  |         decl.text += ast->name->asString(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const SourceLocation first = ast->identifierToken; | 
					
						
							|  |  |  |         decl.startLine = first.startLine; | 
					
						
							|  |  |  |         decl.startColumn = first.startColumn; | 
					
						
							|  |  |  |         decl.endLine = first.startLine; | 
					
						
							|  |  |  |         decl.endColumn = first.startColumn + first.length; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         _declarations.append(decl); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-25 14:18:53 +01:00
										 |  |  | class CreateRanges: protected AST::Visitor | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QTextDocument *_textDocument; | 
					
						
							|  |  |  |     QList<Range> _ranges; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     QList<Range> operator()(QTextDocument *textDocument, Document::Ptr doc) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         _textDocument = textDocument; | 
					
						
							|  |  |  |         _ranges.clear(); | 
					
						
							| 
									
										
										
										
											2010-02-08 21:37:59 +01:00
										 |  |  |         if (doc && doc->ast() != 0) | 
					
						
							|  |  |  |             doc->ast()->accept(this); | 
					
						
							| 
									
										
										
										
											2010-01-25 14:18:53 +01:00
										 |  |  |         return _ranges; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							|  |  |  |     using AST::Visitor::visit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(AST::UiObjectBinding *ast) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-10-27 11:11:36 +02:00
										 |  |  |         if (ast->initializer && ast->initializer->lbraceToken.length) | 
					
						
							| 
									
										
										
										
											2010-01-28 16:29:45 +01:00
										 |  |  |             _ranges.append(createRange(ast, ast->initializer)); | 
					
						
							| 
									
										
										
										
											2010-01-25 14:18:53 +01:00
										 |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(AST::UiObjectDefinition *ast) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-10-27 11:11:36 +02:00
										 |  |  |         if (ast->initializer && ast->initializer->lbraceToken.length) | 
					
						
							| 
									
										
										
										
											2010-01-28 16:29:45 +01:00
										 |  |  |             _ranges.append(createRange(ast, ast->initializer)); | 
					
						
							| 
									
										
										
										
											2010-01-25 14:18:53 +01:00
										 |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-02 16:36:14 +01:00
										 |  |  |     virtual bool visit(AST::FunctionExpression *ast) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         _ranges.append(createRange(ast)); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(AST::FunctionDeclaration *ast) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         _ranges.append(createRange(ast)); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-28 16:29:45 +01:00
										 |  |  |     Range createRange(AST::UiObjectMember *member, AST::UiObjectInitializer *ast) | 
					
						
							| 
									
										
										
										
											2010-01-25 14:18:53 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |         Range range; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-28 16:29:45 +01:00
										 |  |  |         range.ast = member; | 
					
						
							| 
									
										
										
										
											2010-01-25 14:18:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         range.begin = QTextCursor(_textDocument); | 
					
						
							| 
									
										
										
										
											2010-06-14 14:52:43 +02:00
										 |  |  |         range.begin.setPosition(member->firstSourceLocation().begin()); | 
					
						
							| 
									
										
										
										
											2010-01-25 14:18:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         range.end = QTextCursor(_textDocument); | 
					
						
							| 
									
										
										
										
											2010-01-28 16:29:45 +01:00
										 |  |  |         range.end.setPosition(ast->rbraceToken.end()); | 
					
						
							| 
									
										
										
										
											2010-01-25 14:18:53 +01:00
										 |  |  |         return range; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-02-02 16:36:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Range createRange(AST::FunctionExpression *ast) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         Range range; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         range.ast = ast; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         range.begin = QTextCursor(_textDocument); | 
					
						
							|  |  |  |         range.begin.setPosition(ast->lbraceToken.begin()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         range.end = QTextCursor(_textDocument); | 
					
						
							|  |  |  |         range.end.setPosition(ast->rbraceToken.end()); | 
					
						
							| 
									
										
										
										
											2010-02-08 21:37:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-02 16:36:14 +01:00
										 |  |  |         return range; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-25 14:18:53 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-01 16:12:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | class CollectASTNodes: protected AST::Visitor | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     QList<AST::UiQualifiedId *> qualifiedIds; | 
					
						
							|  |  |  |     QList<AST::IdentifierExpression *> identifiers; | 
					
						
							|  |  |  |     QList<AST::FieldMemberExpression *> fieldMembers; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void accept(AST::Node *node) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (node) | 
					
						
							|  |  |  |             node->accept(this); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							|  |  |  |     using AST::Visitor::visit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(AST::UiQualifiedId *ast) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qualifiedIds.append(ast); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(AST::IdentifierExpression *ast) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         identifiers.append(ast); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual bool visit(AST::FieldMemberExpression *ast) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         fieldMembers.append(ast); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-25 14:18:53 +01:00
										 |  |  | } // end of anonymous namespace
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-02 16:36:14 +01:00
										 |  |  | AST::Node *SemanticInfo::declaringMember(int cursorPosition) const | 
					
						
							| 
									
										
										
										
											2010-02-01 16:12:19 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-02-02 16:36:14 +01:00
										 |  |  |     AST::Node *declaringMember = 0; | 
					
						
							| 
									
										
										
										
											2010-02-01 16:12:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (int i = ranges.size() - 1; i != -1; --i) { | 
					
						
							|  |  |  |         const Range &range = ranges.at(i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (range.begin.isNull() || range.end.isNull()) { | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } else if (cursorPosition >= range.begin.position() && cursorPosition <= range.end.position()) { | 
					
						
							|  |  |  |             declaringMember = range.ast; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return declaringMember; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-20 14:59:38 +02:00
										 |  |  | QmlJS::AST::Node *SemanticInfo::declaringMemberNoProperties(int cursorPosition) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |    AST::Node *node = declaringMember(cursorPosition); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    if (UiObjectDefinition *objectDefinition = cast<UiObjectDefinition*>(node)) { | 
					
						
							|  |  |  |        QString name = objectDefinition->qualifiedTypeNameId->name->asString(); | 
					
						
							|  |  |  |        if (!name.isNull() && name.at(0).isLower()) { | 
					
						
							|  |  |  |            QList<AST::Node *> path = astPath(cursorPosition); | 
					
						
							|  |  |  |            if (path.size() > 1) | 
					
						
							|  |  |  |                return path.at(path.size() - 2); | 
					
						
							|  |  |  |        } else if (name.contains("GradientStop")) { | 
					
						
							|  |  |  |            QList<AST::Node *> path = astPath(cursorPosition); | 
					
						
							|  |  |  |            if (path.size() > 2) | 
					
						
							|  |  |  |                return path.at(path.size() - 3); | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |    } else if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(node)) { | 
					
						
							|  |  |  |        QString name = objectBinding->qualifiedTypeNameId->name->asString(); | 
					
						
							|  |  |  |        if (name.contains("Gradient")) { | 
					
						
							|  |  |  |            QList<AST::Node *> path = astPath(cursorPosition); | 
					
						
							|  |  |  |            if (path.size() > 1) | 
					
						
							|  |  |  |                return path.at(path.size() - 2); | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    return node; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-19 10:16:33 +01:00
										 |  |  | QList<AST::Node *> SemanticInfo::astPath(int cursorPosition) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QList<AST::Node *> path; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (const Range &range, ranges) { | 
					
						
							|  |  |  |         if (range.begin.isNull() || range.end.isNull()) { | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } else if (cursorPosition >= range.begin.position() && cursorPosition <= range.end.position()) { | 
					
						
							|  |  |  |             path += range.ast; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return path; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-26 10:50:00 +02:00
										 |  |  | LookupContext::Ptr SemanticInfo::lookupContext(const QList<QmlJS::AST::Node *> &path) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-09-08 10:11:44 +02:00
										 |  |  |     Q_ASSERT(! m_context.isNull()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_context.isNull()) | 
					
						
							|  |  |  |         return LookupContext::create(document, snapshot, path); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-26 10:50:00 +02:00
										 |  |  |     return LookupContext::create(document, snapshot, *m_context, path); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-16 11:16:22 +02:00
										 |  |  | static bool importContainsCursor(UiImport *importAst, unsigned cursorPosition) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return cursorPosition >= importAst->firstSourceLocation().begin() | 
					
						
							|  |  |  |            && cursorPosition <= importAst->lastSourceLocation().end(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-02 13:18:56 +01:00
										 |  |  | AST::Node *SemanticInfo::nodeUnderCursor(int pos) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (! document) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const unsigned cursorPosition = pos; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-16 15:29:37 +02:00
										 |  |  |     foreach (const Interpreter::ImportInfo &import, document->bind()->imports()) { | 
					
						
							|  |  |  |         if (importContainsCursor(import.ast(), cursorPosition)) | 
					
						
							|  |  |  |             return import.ast(); | 
					
						
							| 
									
										
										
										
											2010-07-16 11:16:22 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-02 13:18:56 +01:00
										 |  |  |     CollectASTNodes nodes; | 
					
						
							|  |  |  |     nodes.accept(document->ast()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (AST::UiQualifiedId *q, nodes.qualifiedIds) { | 
					
						
							|  |  |  |         if (cursorPosition >= q->identifierToken.begin()) { | 
					
						
							|  |  |  |             for (AST::UiQualifiedId *tail = q; tail; tail = tail->next) { | 
					
						
							|  |  |  |                 if (! tail->next && cursorPosition <= tail->identifierToken.end()) | 
					
						
							|  |  |  |                     return q; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (AST::IdentifierExpression *id, nodes.identifiers) { | 
					
						
							|  |  |  |         if (cursorPosition >= id->identifierToken.begin() && cursorPosition <= id->identifierToken.end()) | 
					
						
							|  |  |  |             return id; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (AST::FieldMemberExpression *mem, nodes.fieldMembers) { | 
					
						
							|  |  |  |         if (mem->name && cursorPosition >= mem->identifierToken.begin() && cursorPosition <= mem->identifierToken.end()) | 
					
						
							|  |  |  |             return mem; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-08 10:11:44 +02:00
										 |  |  | bool SemanticInfo::isValid() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (document && m_context) | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-26 14:14:01 +01:00
										 |  |  | int SemanticInfo::revision() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (document) | 
					
						
							| 
									
										
										
										
											2010-07-07 17:52:02 +02:00
										 |  |  |         return document->editorRevision(); | 
					
						
							| 
									
										
										
										
											2010-01-26 14:14:01 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | QmlJSTextEditorWidget::QmlJSTextEditorWidget(QWidget *parent) : | 
					
						
							|  |  |  |     TextEditor::BaseTextEditorWidget(parent), | 
					
						
							| 
									
										
										
										
											2010-07-13 11:24:16 +02:00
										 |  |  |     m_outlineCombo(0), | 
					
						
							| 
									
										
										
										
											2010-07-12 14:45:22 +02:00
										 |  |  |     m_outlineModel(new QmlOutlineModel(this)), | 
					
						
							| 
									
										
										
										
											2010-07-07 13:09:30 +02:00
										 |  |  |     m_modelManager(0), | 
					
						
							| 
									
										
										
										
											2010-08-24 15:13:50 +02:00
										 |  |  |     m_contextPane(0), | 
					
						
							| 
									
										
										
										
											2010-09-24 14:05:34 +02:00
										 |  |  |     m_updateSelectedElements(false), | 
					
						
							| 
									
										
										
										
											2010-09-29 19:35:25 +02:00
										 |  |  |     m_findReferences(new FindReferences(this)) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-11-02 11:10:27 +01:00
										 |  |  |     qRegisterMetaType<QmlJSEditor::SemanticInfo>("QmlJSEditor::SemanticInfo"); | 
					
						
							| 
									
										
										
										
											2010-02-16 10:36:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     m_semanticHighlighter = new SemanticHighlighter(this); | 
					
						
							|  |  |  |     m_semanticHighlighter->start(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     setParenthesesMatchingEnabled(true); | 
					
						
							|  |  |  |     setMarksVisible(true); | 
					
						
							|  |  |  |     setCodeFoldingSupported(true); | 
					
						
							| 
									
										
										
										
											2010-11-05 14:27:16 +01:00
										 |  |  |     setIndenter(new Indenter); | 
					
						
							| 
									
										
										
										
											2010-11-08 16:11:26 +01:00
										 |  |  |     setAutoCompleter(new AutoCompleter); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     m_updateDocumentTimer = new QTimer(this); | 
					
						
							|  |  |  |     m_updateDocumentTimer->setInterval(UPDATE_DOCUMENT_DEFAULT_INTERVAL); | 
					
						
							|  |  |  |     m_updateDocumentTimer->setSingleShot(true); | 
					
						
							|  |  |  |     connect(m_updateDocumentTimer, SIGNAL(timeout()), this, SLOT(updateDocumentNow())); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-14 16:30:48 +01:00
										 |  |  |     m_updateUsesTimer = new QTimer(this); | 
					
						
							|  |  |  |     m_updateUsesTimer->setInterval(UPDATE_USES_DEFAULT_INTERVAL); | 
					
						
							|  |  |  |     m_updateUsesTimer->setSingleShot(true); | 
					
						
							|  |  |  |     connect(m_updateUsesTimer, SIGNAL(timeout()), this, SLOT(updateUsesNow())); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-01 15:47:52 +02:00
										 |  |  |     m_semanticRehighlightTimer = new QTimer(this); | 
					
						
							|  |  |  |     m_semanticRehighlightTimer->setInterval(UPDATE_DOCUMENT_DEFAULT_INTERVAL); | 
					
						
							|  |  |  |     m_semanticRehighlightTimer->setSingleShot(true); | 
					
						
							| 
									
										
										
										
											2010-04-06 11:57:08 +02:00
										 |  |  |     connect(m_semanticRehighlightTimer, SIGNAL(timeout()), this, SLOT(forceSemanticRehighlight())); | 
					
						
							| 
									
										
										
										
											2010-04-01 15:47:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     connect(this, SIGNAL(textChanged()), this, SLOT(updateDocument())); | 
					
						
							| 
									
										
										
										
											2010-08-30 12:10:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-14 16:30:48 +01:00
										 |  |  |     connect(this, SIGNAL(textChanged()), this, SLOT(updateUses())); | 
					
						
							| 
									
										
										
										
											2010-08-30 12:10:44 +02:00
										 |  |  |     connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateUses())); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-13 11:18:42 +02:00
										 |  |  |     m_updateOutlineTimer = new QTimer(this); | 
					
						
							|  |  |  |     m_updateOutlineTimer->setInterval(UPDATE_OUTLINE_INTERVAL); | 
					
						
							|  |  |  |     m_updateOutlineTimer->setSingleShot(true); | 
					
						
							|  |  |  |     connect(m_updateOutlineTimer, SIGNAL(timeout()), this, SLOT(updateOutlineNow())); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-13 11:24:16 +02:00
										 |  |  |     m_updateOutlineIndexTimer = new QTimer(this); | 
					
						
							|  |  |  |     m_updateOutlineIndexTimer->setInterval(UPDATE_OUTLINE_INTERVAL); | 
					
						
							|  |  |  |     m_updateOutlineIndexTimer->setSingleShot(true); | 
					
						
							|  |  |  |     connect(m_updateOutlineIndexTimer, SIGNAL(timeout()), this, SLOT(updateOutlineIndexNow())); | 
					
						
							| 
									
										
										
										
											2010-07-12 17:03:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-27 10:32:04 +02:00
										 |  |  |     m_cursorPositionTimer  = new QTimer(this); | 
					
						
							| 
									
										
										
										
											2010-09-08 16:34:49 +02:00
										 |  |  |     m_cursorPositionTimer->setInterval(UPDATE_OUTLINE_INTERVAL); | 
					
						
							| 
									
										
										
										
											2010-08-27 10:32:04 +02:00
										 |  |  |     m_cursorPositionTimer->setSingleShot(true); | 
					
						
							|  |  |  |     connect(m_cursorPositionTimer, SIGNAL(timeout()), this, SLOT(updateCursorPositionNow())); | 
					
						
							| 
									
										
										
										
											2010-08-05 10:44:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 12:27:25 +01:00
										 |  |  |     baseTextDocument()->setSyntaxHighlighter(new Highlighter(document())); | 
					
						
							| 
									
										
										
										
											2010-12-20 18:10:50 +01:00
										 |  |  |     baseTextDocument()->setCodec(QTextCodec::codecForName("UTF-8")); // qml files are defined to be utf-8
 | 
					
						
							| 
									
										
										
										
											2009-09-04 16:51:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 13:49:00 +01:00
										 |  |  |     m_modelManager = ExtensionSystem::PluginManager::instance()->getObject<ModelManagerInterface>(); | 
					
						
							| 
									
										
										
										
											2010-07-07 13:09:30 +02:00
										 |  |  |     m_contextPane = ExtensionSystem::PluginManager::instance()->getObject<QmlJS::IContextPane>(); | 
					
						
							| 
									
										
										
										
											2010-08-13 13:59:41 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_contextPane) { | 
					
						
							| 
									
										
										
										
											2010-07-07 13:09:30 +02:00
										 |  |  |         connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(onCursorPositionChanged())); | 
					
						
							| 
									
										
										
										
											2010-08-13 13:59:41 +02:00
										 |  |  |         connect(m_contextPane, SIGNAL(closed()), this, SLOT(showTextMarker())); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-07-13 11:25:45 +02:00
										 |  |  |     m_oldCursorPosition = -1; | 
					
						
							| 
									
										
										
										
											2009-09-04 16:51:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (m_modelManager) { | 
					
						
							| 
									
										
										
										
											2010-03-16 16:34:33 +01:00
										 |  |  |         m_semanticHighlighter->setModelManager(m_modelManager); | 
					
						
							| 
									
										
										
										
											2010-01-18 16:15:23 +01:00
										 |  |  |         connect(m_modelManager, SIGNAL(documentUpdated(QmlJS::Document::Ptr)), | 
					
						
							|  |  |  |                 this, SLOT(onDocumentUpdated(QmlJS::Document::Ptr))); | 
					
						
							| 
									
										
										
										
											2010-10-15 10:09:40 +02:00
										 |  |  |         connect(m_modelManager, SIGNAL(libraryInfoUpdated(QString,QmlJS::LibraryInfo)), | 
					
						
							| 
									
										
										
										
											2011-01-12 13:58:24 +01:00
										 |  |  |                 this, SLOT(forceSemanticRehighlightIfCurrentEditor())); | 
					
						
							| 
									
										
										
										
											2010-04-16 12:42:12 +02:00
										 |  |  |         connect(this->document(), SIGNAL(modificationChanged(bool)), this, SLOT(modificationChanged(bool))); | 
					
						
							| 
									
										
										
										
											2009-09-04 16:51:11 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-02-16 10:36:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-02 11:10:27 +01:00
										 |  |  |     connect(m_semanticHighlighter, SIGNAL(changed(QmlJSEditor::SemanticInfo)), | 
					
						
							|  |  |  |             this, SLOT(updateSemanticInfo(QmlJSEditor::SemanticInfo))); | 
					
						
							| 
									
										
										
										
											2010-03-17 18:41:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-01 16:29:45 +01:00
										 |  |  |     connect(this, SIGNAL(refactorMarkerClicked(TextEditor::RefactorMarker)), | 
					
						
							|  |  |  |             SLOT(onRefactorMarkerClicked(TextEditor::RefactorMarker))); | 
					
						
							| 
									
										
										
										
											2010-08-05 10:44:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-07 13:56:39 +02:00
										 |  |  |     setRequestMarkEnabled(true); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | QmlJSTextEditorWidget::~QmlJSTextEditorWidget() | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-10 10:34:10 +01:00
										 |  |  |     hideContextPane(); | 
					
						
							| 
									
										
										
										
											2010-02-16 10:36:09 +01:00
										 |  |  |     m_semanticHighlighter->abort(); | 
					
						
							|  |  |  |     m_semanticHighlighter->wait(); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | SemanticInfo QmlJSTextEditorWidget::semanticInfo() const | 
					
						
							| 
									
										
										
										
											2010-02-02 15:01:42 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     return m_semanticInfo; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | int QmlJSTextEditorWidget::editorRevision() const | 
					
						
							| 
									
										
										
										
											2010-02-02 15:01:42 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     return document()->revision(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | bool QmlJSTextEditorWidget::isOutdated() const | 
					
						
							| 
									
										
										
										
											2010-06-03 15:49:29 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-13 10:45:20 +02:00
										 |  |  |     if (m_semanticInfo.revision() != editorRevision()) | 
					
						
							| 
									
										
										
										
											2010-06-03 15:49:29 +02:00
										 |  |  |         return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | QmlOutlineModel *QmlJSTextEditorWidget::outlineModel() const | 
					
						
							| 
									
										
										
										
											2010-07-12 14:45:22 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     return m_outlineModel; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | QModelIndex QmlJSTextEditorWidget::outlineModelIndex() | 
					
						
							| 
									
										
										
										
											2010-07-12 14:45:22 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-12 16:40:15 +02:00
										 |  |  |     if (!m_outlineModelIndex.isValid()) { | 
					
						
							|  |  |  |         m_outlineModelIndex = indexForPosition(position()); | 
					
						
							|  |  |  |         emit outlineModelIndexChanged(m_outlineModelIndex); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-07-12 14:45:22 +02:00
										 |  |  |     return m_outlineModelIndex; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-15 17:20:03 +01:00
										 |  |  | Core::IEditor *QmlJSEditorEditable::duplicate(QWidget *parent) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |     QmlJSTextEditorWidget *newEditor = new QmlJSTextEditorWidget(parent); | 
					
						
							|  |  |  |     newEditor->duplicateFrom(editorWidget()); | 
					
						
							| 
									
										
										
										
											2010-01-15 17:20:03 +01:00
										 |  |  |     QmlJSEditorPlugin::instance()->initializeEditor(newEditor); | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |     return newEditor->editor(); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-15 17:20:03 +01:00
										 |  |  | QString QmlJSEditorEditable::id() const | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-15 17:20:03 +01:00
										 |  |  |     return QLatin1String(QmlJSEditor::Constants::C_QMLJSEDITOR_ID); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-15 17:41:12 +01:00
										 |  |  | bool QmlJSEditorEditable::open(const QString &fileName) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |     bool b = TextEditor::BaseTextEditor::open(fileName); | 
					
						
							|  |  |  |     editorWidget()->setMimeType(Core::ICore::instance()->mimeDatabase()->findByFile(QFileInfo(fileName)).type()); | 
					
						
							| 
									
										
										
										
											2010-01-15 17:41:12 +01:00
										 |  |  |     return b; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::updateDocument() | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     m_updateDocumentTimer->start(UPDATE_DOCUMENT_DEFAULT_INTERVAL); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::updateDocumentNow() | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     // ### move in the parser thread.
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     m_updateDocumentTimer->stop(); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     const QString fileName = file()->fileName(); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-16 13:08:59 +02:00
										 |  |  |     m_modelManager->updateSourceFiles(QStringList() << fileName, false); | 
					
						
							| 
									
										
										
										
											2009-09-04 16:51:11 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-23 16:11:58 +01:00
										 |  |  | static void appendExtraSelectionsForMessages( | 
					
						
							|  |  |  |         QList<QTextEdit::ExtraSelection> *selections, | 
					
						
							|  |  |  |         const QList<DiagnosticMessage> &messages, | 
					
						
							|  |  |  |         const QTextDocument *document) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     foreach (const DiagnosticMessage &d, messages) { | 
					
						
							|  |  |  |         const int line = d.loc.startLine; | 
					
						
							|  |  |  |         const int column = qMax(1U, d.loc.startColumn); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QTextEdit::ExtraSelection sel; | 
					
						
							|  |  |  |         QTextCursor c(document->findBlockByNumber(line - 1)); | 
					
						
							|  |  |  |         sel.cursor = c; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         sel.cursor.setPosition(c.position() + column - 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (d.loc.length == 0) { | 
					
						
							|  |  |  |             if (sel.cursor.atBlockEnd()) | 
					
						
							|  |  |  |                 sel.cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor); | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 sel.cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             sel.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, d.loc.length); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (d.isWarning()) | 
					
						
							|  |  |  |             sel.format.setUnderlineColor(Qt::darkYellow); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             sel.format.setUnderlineColor(Qt::red); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         sel.format.setUnderlineStyle(QTextCharFormat::WaveUnderline); | 
					
						
							|  |  |  |         sel.format.setToolTip(d.message); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         selections->append(sel); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::onDocumentUpdated(QmlJS::Document::Ptr doc) | 
					
						
							| 
									
										
										
										
											2009-09-04 16:51:11 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-03-31 14:55:05 +02:00
										 |  |  |     if (file()->fileName() != doc->fileName() | 
					
						
							| 
									
										
										
										
											2010-07-07 17:52:02 +02:00
										 |  |  |             || doc->editorRevision() != document()->revision()) { | 
					
						
							| 
									
										
										
										
											2010-01-25 14:18:53 +01:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-30 16:57:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-26 12:09:07 +01:00
										 |  |  |     if (doc->ast()) { | 
					
						
							|  |  |  |         // got a correctly parsed (or recovered) file.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-02 11:10:27 +01:00
										 |  |  |         const SemanticHighlighterSource source = currentSource(/*force = */ true); | 
					
						
							| 
									
										
										
										
											2010-02-16 10:36:09 +01:00
										 |  |  |         m_semanticHighlighter->rehighlight(source); | 
					
						
							| 
									
										
										
										
											2010-02-23 16:11:58 +01:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2010-03-31 14:55:05 +02:00
										 |  |  |         // show parsing errors
 | 
					
						
							| 
									
										
										
										
											2010-02-23 16:11:58 +01:00
										 |  |  |         QList<QTextEdit::ExtraSelection> selections; | 
					
						
							|  |  |  |         appendExtraSelectionsForMessages(&selections, doc->diagnosticMessages(), document()); | 
					
						
							|  |  |  |         setExtraSelections(CodeWarningsSelection, selections); | 
					
						
							| 
									
										
										
										
											2009-09-04 16:51:11 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::modificationChanged(bool changed) | 
					
						
							| 
									
										
										
										
											2010-04-16 12:42:12 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (!changed && m_modelManager) | 
					
						
							|  |  |  |         m_modelManager->fileChangedOnDisk(file()->fileName()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::jumpToOutlineElement(int /*index*/) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-13 11:24:16 +02:00
										 |  |  |     QModelIndex index = m_outlineCombo->view()->currentIndex(); | 
					
						
							| 
									
										
										
										
											2010-08-25 13:21:38 +02:00
										 |  |  |     AST::SourceLocation location = m_outlineModel->sourceLocation(index); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!location.isValid()) | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2010-07-12 14:45:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-14 12:21:23 +02:00
										 |  |  |     Core::EditorManager *editorManager = Core::EditorManager::instance(); | 
					
						
							|  |  |  |     editorManager->cutForwardNavigationHistory(); | 
					
						
							|  |  |  |     editorManager->addCurrentPositionToNavigationHistory(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-12 14:45:22 +02:00
										 |  |  |     QTextCursor cursor = textCursor(); | 
					
						
							|  |  |  |     cursor.setPosition(location.offset); | 
					
						
							|  |  |  |     setTextCursor(cursor); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     setFocus(); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::updateOutlineNow() | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-19 11:39:41 +02:00
										 |  |  |     if (!m_semanticInfo.document) | 
					
						
							| 
									
										
										
										
											2010-07-13 11:18:42 +02:00
										 |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-19 11:39:41 +02:00
										 |  |  |     if (m_semanticInfo.document->editorRevision() != editorRevision()) { | 
					
						
							| 
									
										
										
										
											2010-07-13 11:18:42 +02:00
										 |  |  |         m_updateOutlineTimer->start(); | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-07-13 11:18:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-19 11:39:41 +02:00
										 |  |  |     m_outlineModel->update(m_semanticInfo); | 
					
						
							| 
									
										
										
										
											2010-07-14 13:01:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     QTreeView *treeView = static_cast<QTreeView*>(m_outlineCombo->view()); | 
					
						
							|  |  |  |     treeView->expandAll(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-13 11:24:16 +02:00
										 |  |  |     updateOutlineIndexNow(); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::updateOutlineIndexNow() | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-13 11:24:16 +02:00
										 |  |  |     if (m_updateOutlineTimer->isActive()) | 
					
						
							| 
									
										
										
										
											2010-07-13 11:25:45 +02:00
										 |  |  |         return; // updateOutlineNow will call this function soon anyway
 | 
					
						
							| 
									
										
										
										
											2010-07-13 11:24:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-13 11:18:42 +02:00
										 |  |  |     if (!m_outlineModel->document()) | 
					
						
							| 
									
										
										
										
											2010-07-12 17:03:49 +02:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-13 11:18:42 +02:00
										 |  |  |     if (m_outlineModel->document()->editorRevision() != editorRevision()) { | 
					
						
							| 
									
										
										
										
											2010-07-13 11:24:16 +02:00
										 |  |  |         m_updateOutlineIndexTimer->start(); | 
					
						
							| 
									
										
										
										
											2010-07-12 17:03:49 +02:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-12 16:40:15 +02:00
										 |  |  |     m_outlineModelIndex = QModelIndex(); // invalidate
 | 
					
						
							|  |  |  |     QModelIndex comboIndex = outlineModelIndex(); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-12 14:45:22 +02:00
										 |  |  |     if (comboIndex.isValid()) { | 
					
						
							| 
									
										
										
										
											2010-07-13 11:24:16 +02:00
										 |  |  |         bool blocked = m_outlineCombo->blockSignals(true); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-12 14:45:22 +02:00
										 |  |  |         // There is no direct way to select a non-root item
 | 
					
						
							| 
									
										
										
										
											2010-07-13 11:24:16 +02:00
										 |  |  |         m_outlineCombo->setRootModelIndex(comboIndex.parent()); | 
					
						
							|  |  |  |         m_outlineCombo->setCurrentIndex(comboIndex.row()); | 
					
						
							|  |  |  |         m_outlineCombo->setRootModelIndex(QModelIndex()); | 
					
						
							| 
									
										
										
										
											2010-07-12 14:45:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-13 11:24:16 +02:00
										 |  |  |         m_outlineCombo->blockSignals(blocked); | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-01-14 16:30:48 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-08 13:36:08 +02:00
										 |  |  | static UiQualifiedId *qualifiedTypeNameId(Node *m) | 
					
						
							| 
									
										
										
										
											2010-08-05 10:44:50 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (UiObjectDefinition *def = cast<UiObjectDefinition *>(m)) | 
					
						
							|  |  |  |         return def->qualifiedTypeNameId; | 
					
						
							|  |  |  |     else if (UiObjectBinding *binding = cast<UiObjectBinding *>(m)) | 
					
						
							|  |  |  |         return binding->qualifiedTypeNameId; | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::updateCursorPositionNow() | 
					
						
							| 
									
										
										
										
											2010-08-05 10:44:50 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-10-04 14:32:50 +02:00
										 |  |  |     if (m_contextPane && document() && semanticInfo().isValid() | 
					
						
							|  |  |  |             && document()->revision() == semanticInfo().document->editorRevision()) | 
					
						
							| 
									
										
										
										
											2010-08-27 10:37:15 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-08-05 10:44:50 +02:00
										 |  |  |         Node *oldNode = m_semanticInfo.declaringMemberNoProperties(m_oldCursorPosition); | 
					
						
							|  |  |  |         Node *newNode = m_semanticInfo.declaringMemberNoProperties(position()); | 
					
						
							| 
									
										
										
										
											2010-08-13 17:20:33 +02:00
										 |  |  |         if (oldNode != newNode && m_oldCursorPosition != -1) | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |             m_contextPane->apply(editor(), semanticInfo().document, LookupContext::Ptr(),newNode, false); | 
					
						
							|  |  |  |         if (m_contextPane->isAvailable(editor(), semanticInfo().document, newNode) && | 
					
						
							| 
									
										
										
										
											2010-08-05 15:35:52 +02:00
										 |  |  |             !m_contextPane->widget()->isVisible()) { | 
					
						
							| 
									
										
										
										
											2010-11-01 16:29:45 +01:00
										 |  |  |             QList<TextEditor::RefactorMarker> markers; | 
					
						
							| 
									
										
										
										
											2010-08-05 10:44:50 +02:00
										 |  |  |             if (UiObjectMember *m = newNode->uiObjectMemberCast()) { | 
					
						
							| 
									
										
										
										
											2010-09-08 16:34:49 +02:00
										 |  |  |                 const int start = qualifiedTypeNameId(m)->identifierToken.begin(); | 
					
						
							| 
									
										
										
										
											2010-08-05 10:44:50 +02:00
										 |  |  |                 for (UiQualifiedId *q = qualifiedTypeNameId(m); q; q = q->next) { | 
					
						
							|  |  |  |                     if (! q->next) { | 
					
						
							|  |  |  |                         const int end = q->identifierToken.end(); | 
					
						
							| 
									
										
										
										
											2010-09-08 16:34:49 +02:00
										 |  |  |                         if (position() >= start && position() <= end) { | 
					
						
							| 
									
										
										
										
											2010-11-01 16:29:45 +01:00
										 |  |  |                             TextEditor::RefactorMarker marker; | 
					
						
							| 
									
										
										
										
											2010-09-08 16:34:49 +02:00
										 |  |  |                             QTextCursor tc(document()); | 
					
						
							|  |  |  |                             tc.setPosition(end); | 
					
						
							|  |  |  |                             marker.cursor = tc; | 
					
						
							|  |  |  |                             marker.tooltip = tr("Show Qt Quick ToolBar"); | 
					
						
							|  |  |  |                             markers.append(marker); | 
					
						
							|  |  |  |                         } else { | 
					
						
							| 
									
										
										
										
											2010-11-01 16:29:45 +01:00
										 |  |  |                              QList<TextEditor::RefactorMarker> markers; | 
					
						
							| 
									
										
										
										
											2010-09-08 16:34:49 +02:00
										 |  |  |                              setRefactorMarkers(markers); | 
					
						
							|  |  |  |                         } | 
					
						
							| 
									
										
										
										
											2010-08-05 10:44:50 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             setRefactorMarkers(markers); | 
					
						
							| 
									
										
										
										
											2010-09-01 11:54:35 +02:00
										 |  |  |         } else if (oldNode != newNode) { | 
					
						
							| 
									
										
										
										
											2010-11-01 16:29:45 +01:00
										 |  |  |             QList<TextEditor::RefactorMarker> markers; | 
					
						
							| 
									
										
										
										
											2010-08-13 13:59:41 +02:00
										 |  |  |             setRefactorMarkers(markers); | 
					
						
							| 
									
										
										
										
											2010-08-05 10:44:50 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         m_oldCursorPosition = position(); | 
					
						
							| 
									
										
										
										
											2010-08-27 10:37:15 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         setSelectedElements(); | 
					
						
							| 
									
										
										
										
											2010-08-05 10:44:50 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::showTextMarker() | 
					
						
							| 
									
										
										
										
											2010-08-13 13:59:41 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     m_oldCursorPosition = -1; | 
					
						
							|  |  |  |     updateCursorPositionNow(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::updateUses() | 
					
						
							| 
									
										
										
										
											2010-01-14 16:30:48 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     m_updateUsesTimer->start(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | bool QmlJSTextEditorWidget::updateSelectedElements() const | 
					
						
							| 
									
										
										
										
											2010-08-24 15:13:50 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     return m_updateSelectedElements; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::setUpdateSelectedElements(bool value) | 
					
						
							| 
									
										
										
										
											2010-08-24 15:13:50 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     m_updateSelectedElements = value; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::renameId(const QString &oldId, const QString &newId) | 
					
						
							| 
									
										
										
										
											2010-09-30 14:25:20 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     Utils::ChangeSet changeSet; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (const AST::SourceLocation &loc, m_semanticInfo.idLocations.value(oldId)) { | 
					
						
							|  |  |  |         changeSet.replace(loc.begin(), loc.end(), newId); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QTextCursor tc = textCursor(); | 
					
						
							|  |  |  |     changeSet.apply(&tc); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::updateUsesNow() | 
					
						
							| 
									
										
										
										
											2010-01-14 16:30:48 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-26 14:14:01 +01:00
										 |  |  |     if (document()->revision() != m_semanticInfo.revision()) { | 
					
						
							| 
									
										
										
										
											2010-01-14 16:30:48 +01:00
										 |  |  |         updateUses(); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_updateUsesTimer->stop(); | 
					
						
							| 
									
										
										
										
											2009-05-04 18:58:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     QList<QTextEdit::ExtraSelection> selections; | 
					
						
							| 
									
										
										
										
											2010-01-26 14:14:01 +01:00
										 |  |  |     foreach (const AST::SourceLocation &loc, m_semanticInfo.idLocations.value(wordUnderCursor())) { | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         if (! loc.isValid()) | 
					
						
							|  |  |  |             continue; | 
					
						
							| 
									
										
										
										
											2009-05-05 10:46:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         QTextEdit::ExtraSelection sel; | 
					
						
							| 
									
										
										
										
											2010-01-14 16:30:48 +01:00
										 |  |  |         sel.format = m_occurrencesFormat; | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         sel.cursor = textCursor(); | 
					
						
							|  |  |  |         sel.cursor.setPosition(loc.begin()); | 
					
						
							|  |  |  |         sel.cursor.setPosition(loc.end(), QTextCursor::KeepAnchor); | 
					
						
							|  |  |  |         selections.append(sel); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-05-04 18:58:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     setExtraSelections(CodeSemanticsSelection, selections); | 
					
						
							| 
									
										
										
										
											2010-07-08 11:34:51 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SelectedElement: protected Visitor | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-27 11:57:06 +02:00
										 |  |  |     unsigned m_cursorPositionStart; | 
					
						
							|  |  |  |     unsigned m_cursorPositionEnd; | 
					
						
							|  |  |  |     QList<UiObjectMember *> m_selectedMembers; | 
					
						
							|  |  |  |     LookupContext::Ptr m_lookupContext; | 
					
						
							| 
									
										
										
										
											2010-07-08 11:34:51 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     SelectedElement() | 
					
						
							| 
									
										
										
										
											2010-07-27 11:57:06 +02:00
										 |  |  |         : m_cursorPositionStart(0), m_cursorPositionEnd(0) {} | 
					
						
							| 
									
										
										
										
											2010-07-08 11:34:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-26 10:50:00 +02:00
										 |  |  |     QList<UiObjectMember *> operator()(LookupContext::Ptr lookupContext, unsigned startPosition, unsigned endPosition) | 
					
						
							| 
									
										
										
										
											2010-07-08 11:34:51 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-08-26 10:50:00 +02:00
										 |  |  |         m_lookupContext = lookupContext; | 
					
						
							| 
									
										
										
										
											2010-07-27 11:57:06 +02:00
										 |  |  |         m_cursorPositionStart = startPosition; | 
					
						
							|  |  |  |         m_cursorPositionEnd = endPosition; | 
					
						
							|  |  |  |         m_selectedMembers.clear(); | 
					
						
							| 
									
										
										
										
											2010-08-26 10:50:00 +02:00
										 |  |  |         Node::accept(lookupContext->document()->qmlProgram(), this); | 
					
						
							| 
									
										
										
										
											2010-07-27 11:57:06 +02:00
										 |  |  |         return m_selectedMembers; | 
					
						
							| 
									
										
										
										
											2010-07-08 11:34:51 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							| 
									
										
										
										
											2010-07-13 16:13:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-27 11:57:06 +02:00
										 |  |  |     bool isSelectable(UiObjectMember *member) const | 
					
						
							| 
									
										
										
										
											2010-07-13 16:13:26 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         UiQualifiedId *id = 0; | 
					
						
							|  |  |  |         if (UiObjectDefinition *def = cast<UiObjectDefinition *>(member)) | 
					
						
							|  |  |  |             id = def->qualifiedTypeNameId; | 
					
						
							|  |  |  |         else if (UiObjectBinding *binding = cast<UiObjectBinding *>(member)) | 
					
						
							|  |  |  |             id = binding->qualifiedTypeNameId; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (id) { | 
					
						
							|  |  |  |             QString name = id->name->asString(); | 
					
						
							|  |  |  |             if (!name.isEmpty() && name.at(0).isUpper()) { | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-24 15:13:50 +02:00
										 |  |  |     inline UiObjectInitializer *initializer(UiObjectMember *member) const | 
					
						
							| 
									
										
										
										
											2010-07-08 11:34:51 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         if (UiObjectDefinition *def = cast<UiObjectDefinition *>(member)) | 
					
						
							|  |  |  |             return def->initializer; | 
					
						
							|  |  |  |         else if (UiObjectBinding *binding = cast<UiObjectBinding *>(member)) | 
					
						
							|  |  |  |             return binding->initializer; | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-24 15:13:50 +02:00
										 |  |  |     inline bool isIdBinding(UiObjectMember *member) const | 
					
						
							| 
									
										
										
										
											2010-07-08 11:34:51 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         if (UiScriptBinding *script = cast<UiScriptBinding *>(member)) { | 
					
						
							|  |  |  |             if (! script->qualifiedId) | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             else if (! script->qualifiedId->name) | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             else if (script->qualifiedId->next) | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             const QString propertyName = script->qualifiedId->name->asString(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (propertyName == QLatin1String("id")) | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-24 15:13:50 +02:00
										 |  |  |     inline bool containsCursor(unsigned begin, unsigned end) | 
					
						
							| 
									
										
										
										
											2010-07-12 17:18:05 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-07-27 11:57:06 +02:00
										 |  |  |         return m_cursorPositionStart >= begin && m_cursorPositionEnd <= end; | 
					
						
							| 
									
										
										
										
											2010-07-12 17:18:05 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-24 15:13:50 +02:00
										 |  |  |     inline bool intersectsCursor(unsigned begin, unsigned end) | 
					
						
							| 
									
										
										
										
											2010-07-12 17:18:05 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-07-27 11:57:06 +02:00
										 |  |  |         return (m_cursorPositionEnd >= begin && m_cursorPositionStart <= end); | 
					
						
							| 
									
										
										
										
											2010-07-12 17:18:05 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-24 15:13:50 +02:00
										 |  |  |     inline bool isRangeSelected() const | 
					
						
							| 
									
										
										
										
											2010-07-15 10:53:49 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-07-27 11:57:06 +02:00
										 |  |  |         return (m_cursorPositionStart != m_cursorPositionEnd); | 
					
						
							| 
									
										
										
										
											2010-07-15 10:53:49 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-24 15:13:50 +02:00
										 |  |  |     void postVisit(Node *ast) | 
					
						
							| 
									
										
										
										
											2010-07-08 11:34:51 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-07-27 11:57:06 +02:00
										 |  |  |         if (!isRangeSelected() && !m_selectedMembers.isEmpty()) | 
					
						
							| 
									
										
										
										
											2010-07-12 17:18:05 +02:00
										 |  |  |             return; // nothing to do, we already have the results.
 | 
					
						
							| 
									
										
										
										
											2010-07-08 11:34:51 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (UiObjectMember *member = ast->uiObjectMemberCast()) { | 
					
						
							|  |  |  |             unsigned begin = member->firstSourceLocation().begin(); | 
					
						
							|  |  |  |             unsigned end = member->lastSourceLocation().end(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-15 10:53:49 +02:00
										 |  |  |             if ((isRangeSelected() && intersectsCursor(begin, end)) | 
					
						
							|  |  |  |             || (!isRangeSelected() && containsCursor(begin, end))) | 
					
						
							| 
									
										
										
										
											2010-07-12 17:18:05 +02:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2011-01-18 17:17:17 +01:00
										 |  |  |                 if (initializer(member) && isSelectable(member)) { | 
					
						
							| 
									
										
										
										
											2010-07-27 11:57:06 +02:00
										 |  |  |                     m_selectedMembers << member; | 
					
						
							|  |  |  |                     // move start towards end; this facilitates multiselection so that root is usually ignored.
 | 
					
						
							|  |  |  |                     m_cursorPositionStart = qMin(end, m_cursorPositionEnd); | 
					
						
							| 
									
										
										
										
											2010-07-08 11:34:51 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::setSelectedElements() | 
					
						
							| 
									
										
										
										
											2010-07-08 11:34:51 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-08-24 15:13:50 +02:00
										 |  |  |     if (!m_updateSelectedElements) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-08 11:34:51 +02:00
										 |  |  |     QTextCursor tc = textCursor(); | 
					
						
							| 
									
										
										
										
											2010-07-12 17:18:05 +02:00
										 |  |  |     QString wordAtCursor; | 
					
						
							|  |  |  |     QList<int> offsets; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unsigned startPos; | 
					
						
							|  |  |  |     unsigned endPos; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (tc.hasSelection()) { | 
					
						
							|  |  |  |         startPos = tc.selectionStart(); | 
					
						
							|  |  |  |         endPos = tc.selectionEnd(); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         tc.movePosition(QTextCursor::StartOfWord); | 
					
						
							|  |  |  |         tc.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         startPos = textCursor().position(); | 
					
						
							|  |  |  |         endPos = textCursor().position(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-07-08 11:34:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-04 14:32:50 +02:00
										 |  |  |     if (m_semanticInfo.isValid()) { | 
					
						
							| 
									
										
										
										
											2010-07-12 17:18:05 +02:00
										 |  |  |         SelectedElement selectedMembers; | 
					
						
							| 
									
										
										
										
											2010-08-26 10:50:00 +02:00
										 |  |  |         QList<UiObjectMember *> members = selectedMembers(m_semanticInfo.lookupContext(), | 
					
						
							| 
									
										
										
										
											2010-07-27 11:57:06 +02:00
										 |  |  |                                                           startPos, endPos); | 
					
						
							| 
									
										
										
										
											2010-07-12 17:18:05 +02:00
										 |  |  |         if (!members.isEmpty()) { | 
					
						
							|  |  |  |             foreach(UiObjectMember *m, members) { | 
					
						
							|  |  |  |                 offsets << m->firstSourceLocation().begin(); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-07-08 11:34:51 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-07-12 17:18:05 +02:00
										 |  |  |     wordAtCursor = tc.selectedText(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     emit selectedElementsChanged(offsets, wordAtCursor); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::updateFileName() | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::renameIdUnderCursor() | 
					
						
							| 
									
										
										
										
											2009-05-05 15:33:39 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     const QString id = wordUnderCursor(); | 
					
						
							|  |  |  |     bool ok = false; | 
					
						
							|  |  |  |     const QString newId = QInputDialog::getText(Core::ICore::instance()->mainWindow(), | 
					
						
							|  |  |  |                                                 tr("Rename..."), | 
					
						
							|  |  |  |                                                 tr("New id:"), | 
					
						
							|  |  |  |                                                 QLineEdit::Normal, | 
					
						
							|  |  |  |                                                 id, &ok); | 
					
						
							|  |  |  |     if (ok) { | 
					
						
							| 
									
										
										
										
											2010-09-30 14:25:20 +02:00
										 |  |  |         renameId(id, newId); | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-05-05 15:33:39 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::setFontSettings(const TextEditor::FontSettings &fs) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |     TextEditor::BaseTextEditorWidget::setFontSettings(fs); | 
					
						
							| 
									
										
										
										
											2010-02-15 12:27:25 +01:00
										 |  |  |     Highlighter *highlighter = qobject_cast<Highlighter*>(baseTextDocument()->syntaxHighlighter()); | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     if (!highlighter) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-27 17:38:22 +02:00
										 |  |  |     highlighter->setFormats(fs.toTextCharFormats(highlighterFormatCategories())); | 
					
						
							| 
									
										
										
										
											2010-02-15 12:27:25 +01:00
										 |  |  |     highlighter->rehighlight(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-14 16:30:48 +01:00
										 |  |  |     m_occurrencesFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_OCCURRENCES)); | 
					
						
							| 
									
										
										
										
											2010-02-15 12:27:25 +01:00
										 |  |  |     m_occurrencesUnusedFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_OCCURRENCES_UNUSED)); | 
					
						
							|  |  |  |     m_occurrencesUnusedFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline); | 
					
						
							|  |  |  |     m_occurrencesUnusedFormat.setUnderlineColor(m_occurrencesUnusedFormat.foreground().color()); | 
					
						
							|  |  |  |     m_occurrencesUnusedFormat.clearForeground(); | 
					
						
							|  |  |  |     m_occurrencesUnusedFormat.setToolTip(tr("Unused variable")); | 
					
						
							|  |  |  |     m_occurrenceRenameFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_OCCURRENCES_RENAME)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // only set the background, we do not want to modify foreground properties set by the syntax highlighter or the link
 | 
					
						
							| 
									
										
										
										
											2010-01-14 16:30:48 +01:00
										 |  |  |     m_occurrencesFormat.clearForeground(); | 
					
						
							| 
									
										
										
										
											2010-02-15 12:27:25 +01:00
										 |  |  |     m_occurrenceRenameFormat.clearForeground(); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-15 12:27:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | QString QmlJSTextEditorWidget::wordUnderCursor() const | 
					
						
							| 
									
										
										
										
											2009-05-05 15:33:39 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     QTextCursor tc = textCursor(); | 
					
						
							| 
									
										
										
										
											2010-03-25 14:47:14 +01:00
										 |  |  |     const QChar ch = characterAt(tc.position() - 1); | 
					
						
							|  |  |  |     // make sure that we're not at the start of the next word.
 | 
					
						
							|  |  |  |     if (ch.isLetterOrNumber() || ch == QLatin1Char('_')) | 
					
						
							|  |  |  |         tc.movePosition(QTextCursor::Left); | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     tc.movePosition(QTextCursor::StartOfWord); | 
					
						
							|  |  |  |     tc.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor); | 
					
						
							| 
									
										
										
										
											2010-03-25 14:47:14 +01:00
										 |  |  |     const QString word = tc.selectedText(); | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     return word; | 
					
						
							| 
									
										
										
										
											2009-05-05 15:33:39 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | bool QmlJSTextEditorWidget::isClosingBrace(const QList<Token> &tokens) const | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-16 12:38:47 +01:00
										 |  |  |     if (tokens.size() == 1) { | 
					
						
							| 
									
										
										
										
											2010-01-19 12:54:17 +01:00
										 |  |  |         const Token firstToken = tokens.first(); | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-19 12:54:17 +01:00
										 |  |  |         return firstToken.is(Token::RightBrace) || firstToken.is(Token::RightBracket); | 
					
						
							| 
									
										
										
										
											2009-11-16 12:38:47 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-16 12:38:47 +01:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | TextEditor::BaseTextEditor *QmlJSTextEditorWidget::createEditor() | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-15 17:20:03 +01:00
										 |  |  |     QmlJSEditorEditable *editable = new QmlJSEditorEditable(this); | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     createToolBar(editable); | 
					
						
							|  |  |  |     return editable; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 15:58:02 +01:00
										 |  |  | void QmlJSTextEditorWidget::createToolBar(QmlJSEditorEditable *editor) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-13 11:24:16 +02:00
										 |  |  |     m_outlineCombo = new QComboBox; | 
					
						
							|  |  |  |     m_outlineCombo->setMinimumContentsLength(22); | 
					
						
							|  |  |  |     m_outlineCombo->setModel(m_outlineModel); | 
					
						
							| 
									
										
										
										
											2010-07-12 14:45:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     QTreeView *treeView = new QTreeView; | 
					
						
							|  |  |  |     treeView->header()->hide(); | 
					
						
							|  |  |  |     treeView->setItemsExpandable(false); | 
					
						
							| 
									
										
										
										
											2010-07-12 15:49:03 +02:00
										 |  |  |     treeView->setRootIsDecorated(false); | 
					
						
							| 
									
										
										
										
											2010-07-13 11:24:16 +02:00
										 |  |  |     m_outlineCombo->setView(treeView); | 
					
						
							| 
									
										
										
										
											2010-07-12 14:45:22 +02:00
										 |  |  |     treeView->expandAll(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-13 11:24:16 +02:00
										 |  |  |     //m_outlineCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     // Make the combo box prefer to expand
 | 
					
						
							| 
									
										
										
										
											2010-07-13 11:24:16 +02:00
										 |  |  |     QSizePolicy policy = m_outlineCombo->sizePolicy(); | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     policy.setHorizontalPolicy(QSizePolicy::Expanding); | 
					
						
							| 
									
										
										
										
											2010-07-13 11:24:16 +02:00
										 |  |  |     m_outlineCombo->setSizePolicy(policy); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-13 11:25:45 +02:00
										 |  |  |     connect(m_outlineCombo, SIGNAL(activated(int)), this, SLOT(jumpToOutlineElement(int))); | 
					
						
							| 
									
										
										
										
											2010-07-13 11:24:16 +02:00
										 |  |  |     connect(this, SIGNAL(cursorPositionChanged()), m_updateOutlineIndexTimer, SLOT(start())); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     connect(file(), SIGNAL(changed()), this, SLOT(updateFileName())); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 15:58:02 +01:00
										 |  |  |     editor->insertExtraToolBarWidget(TextEditor::BaseTextEditor::Left, m_outlineCombo); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | TextEditor::BaseTextEditorWidget::Link QmlJSTextEditorWidget::findLinkAt(const QTextCursor &cursor, bool /*resolveTarget*/) | 
					
						
							| 
									
										
										
										
											2009-09-11 14:42:50 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-02-01 16:14:34 +01:00
										 |  |  |     const SemanticInfo semanticInfo = m_semanticInfo; | 
					
						
							| 
									
										
										
										
											2010-09-08 10:11:44 +02:00
										 |  |  |     if (! semanticInfo.isValid()) | 
					
						
							|  |  |  |         return Link(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-02 13:18:56 +01:00
										 |  |  |     const unsigned cursorPosition = cursor.position(); | 
					
						
							| 
									
										
										
										
											2010-02-01 16:14:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-02 13:18:56 +01:00
										 |  |  |     AST::Node *node = semanticInfo.nodeUnderCursor(cursorPosition); | 
					
						
							| 
									
										
										
										
											2010-02-01 16:14:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-16 11:16:22 +02:00
										 |  |  |     if (AST::UiImport *importAst = cast<AST::UiImport *>(node)) { | 
					
						
							|  |  |  |         // if it's a file import, link to the file
 | 
					
						
							| 
									
										
										
										
											2010-09-16 15:29:37 +02:00
										 |  |  |         foreach (const Interpreter::ImportInfo &import, semanticInfo.document->bind()->imports()) { | 
					
						
							|  |  |  |             if (import.ast() == importAst && import.type() == Interpreter::ImportInfo::FileImport) { | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |                 BaseTextEditorWidget::Link link(import.name()); | 
					
						
							| 
									
										
										
										
											2010-07-16 11:16:22 +02:00
										 |  |  |                 link.begin = importAst->firstSourceLocation().begin(); | 
					
						
							|  |  |  |                 link.end = importAst->lastSourceLocation().end(); | 
					
						
							|  |  |  |                 return link; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return Link(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-26 10:50:00 +02:00
										 |  |  |     LookupContext::Ptr lookupContext = semanticInfo.lookupContext(semanticInfo.astPath(cursorPosition)); | 
					
						
							| 
									
										
										
										
											2010-11-16 14:39:54 +01:00
										 |  |  |     Evaluate evaluator(lookupContext->context()); | 
					
						
							|  |  |  |     const Interpreter::Value *value = evaluator.reference(node); | 
					
						
							| 
									
										
										
										
											2010-02-08 12:50:10 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     QString fileName; | 
					
						
							|  |  |  |     int line = 0, column = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (! (value && value->getSourceLocation(&fileName, &line, &column))) | 
					
						
							|  |  |  |         return Link(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |     BaseTextEditorWidget::Link link; | 
					
						
							| 
									
										
										
										
											2010-02-08 12:50:10 +01:00
										 |  |  |     link.fileName = fileName; | 
					
						
							|  |  |  |     link.line = line; | 
					
						
							|  |  |  |     link.column = column - 1; // adjust the column
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-02 13:18:56 +01:00
										 |  |  |     if (AST::UiQualifiedId *q = AST::cast<AST::UiQualifiedId *>(node)) { | 
					
						
							|  |  |  |         for (AST::UiQualifiedId *tail = q; tail; tail = tail->next) { | 
					
						
							|  |  |  |             if (! tail->next && cursorPosition <= tail->identifierToken.end()) { | 
					
						
							|  |  |  |                 link.begin = tail->identifierToken.begin(); | 
					
						
							|  |  |  |                 link.end = tail->identifierToken.end(); | 
					
						
							| 
									
										
										
										
											2010-02-01 16:14:34 +01:00
										 |  |  |                 return link; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-02 13:18:56 +01:00
										 |  |  |     } else if (AST::IdentifierExpression *id = AST::cast<AST::IdentifierExpression *>(node)) { | 
					
						
							|  |  |  |         link.begin = id->firstSourceLocation().begin(); | 
					
						
							|  |  |  |         link.end = id->lastSourceLocation().end(); | 
					
						
							|  |  |  |         return link; | 
					
						
							| 
									
										
										
										
											2010-02-01 16:14:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-02 13:18:56 +01:00
										 |  |  |     } else if (AST::FieldMemberExpression *mem = AST::cast<AST::FieldMemberExpression *>(node)) { | 
					
						
							|  |  |  |         link.begin = mem->lastSourceLocation().begin(); | 
					
						
							|  |  |  |         link.end = mem->lastSourceLocation().end(); | 
					
						
							|  |  |  |         return link; | 
					
						
							| 
									
										
										
										
											2010-02-01 16:14:34 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-02 13:18:56 +01:00
										 |  |  |     return Link(); | 
					
						
							| 
									
										
										
										
											2009-09-11 14:42:50 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::followSymbolUnderCursor() | 
					
						
							| 
									
										
										
										
											2010-02-08 12:50:10 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     openLink(findLinkAt(textCursor())); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::findUsages() | 
					
						
							| 
									
										
										
										
											2010-09-24 14:05:34 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     m_findReferences->findUsages(file()->fileName(), textCursor().position()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::showContextPane() | 
					
						
							| 
									
										
										
										
											2010-08-04 13:50:15 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-10-04 14:32:50 +02:00
										 |  |  |     if (m_contextPane && m_semanticInfo.isValid()) { | 
					
						
							| 
									
										
										
										
											2010-08-04 13:50:15 +02:00
										 |  |  |         Node *newNode = m_semanticInfo.declaringMemberNoProperties(position()); | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |         m_contextPane->apply(editor(), m_semanticInfo.document, m_semanticInfo.lookupContext(), newNode, false, true); | 
					
						
							| 
									
										
										
										
											2010-08-04 13:50:15 +02:00
										 |  |  |         m_oldCursorPosition = position(); | 
					
						
							| 
									
										
										
										
											2010-11-01 16:29:45 +01:00
										 |  |  |         QList<TextEditor::RefactorMarker> markers; | 
					
						
							| 
									
										
										
										
											2010-08-05 15:35:52 +02:00
										 |  |  |         setRefactorMarkers(markers); | 
					
						
							| 
									
										
										
										
											2010-08-04 13:50:15 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::performQuickFix(int index) | 
					
						
							| 
									
										
										
										
											2010-09-16 12:57:07 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     TextEditor::QuickFixOperation::Ptr op = m_quickFixes.at(index); | 
					
						
							|  |  |  |     op->perform(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::contextMenuEvent(QContextMenuEvent *e) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-09 17:35:20 +01:00
										 |  |  |     QMenu *menu = new QMenu(); | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-16 12:57:07 +02:00
										 |  |  |     QMenu *refactoringMenu = new QMenu(tr("Refactoring"), menu); | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-16 12:57:07 +02:00
										 |  |  |     // Conditionally add the rename-id action:
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     const QString id = wordUnderCursor(); | 
					
						
							| 
									
										
										
										
											2010-01-26 14:14:01 +01:00
										 |  |  |     const QList<AST::SourceLocation> &locations = m_semanticInfo.idLocations.value(id); | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     if (! locations.isEmpty()) { | 
					
						
							| 
									
										
										
										
											2010-09-16 12:57:07 +02:00
										 |  |  |         QAction *a = refactoringMenu->addAction(tr("Rename id '%1'...").arg(id)); | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |         connect(a, SIGNAL(triggered()), this, SLOT(renameIdUnderCursor())); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-16 12:57:07 +02:00
										 |  |  |     // Add other refactoring actions:
 | 
					
						
							|  |  |  |     QmlJSQuickFixCollector *quickFixCollector = QmlJSEditorPlugin::instance()->quickFixCollector(); | 
					
						
							|  |  |  |     QSignalMapper mapper; | 
					
						
							|  |  |  |     connect(&mapper, SIGNAL(mapped(int)), this, SLOT(performQuickFix(int))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (! isOutdated()) { | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |         if (quickFixCollector->startCompletion(editor()) != -1) { | 
					
						
							| 
									
										
										
										
											2010-09-16 12:57:07 +02:00
										 |  |  |             m_quickFixes = quickFixCollector->quickFixes(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             for (int index = 0; index < m_quickFixes.size(); ++index) { | 
					
						
							|  |  |  |                 TextEditor::QuickFixOperation::Ptr op = m_quickFixes.at(index); | 
					
						
							|  |  |  |                 QAction *action = refactoringMenu->addAction(op->description()); | 
					
						
							|  |  |  |                 mapper.setMapping(action, index); | 
					
						
							|  |  |  |                 connect(action, SIGNAL(triggered()), &mapper, SLOT(map())); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     refactoringMenu->setEnabled(!refactoringMenu->isEmpty()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (Core::ActionContainer *mcontext = Core::ICore::instance()->actionManager()->actionContainer(QmlJSEditor::Constants::M_CONTEXT)) { | 
					
						
							|  |  |  |         QMenu *contextMenu = mcontext->menu(); | 
					
						
							|  |  |  |         foreach (QAction *action, contextMenu->actions()) { | 
					
						
							|  |  |  |             menu->addAction(action); | 
					
						
							|  |  |  |             if (action->objectName() == QmlJSEditor::Constants::M_REFACTORING_MENU_INSERTION_POINT) | 
					
						
							|  |  |  |                 menu->addMenu(refactoringMenu); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 17:35:20 +01:00
										 |  |  |     appendStandardContextMenuActions(menu); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 13:56:06 +02:00
										 |  |  |     menu->exec(e->globalPos()); | 
					
						
							|  |  |  |     menu->deleteLater(); | 
					
						
							| 
									
										
										
										
											2010-09-16 12:57:07 +02:00
										 |  |  |     quickFixCollector->cleanup(); | 
					
						
							|  |  |  |     m_quickFixes.clear(); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:21:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | bool QmlJSTextEditorWidget::event(QEvent *e) | 
					
						
							| 
									
										
										
										
											2010-07-07 13:09:30 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     switch (e->type()) { | 
					
						
							|  |  |  |     case QEvent::ShortcutOverride: | 
					
						
							|  |  |  |         if (static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape && m_contextPane) { | 
					
						
							| 
									
										
										
										
											2010-07-20 15:01:06 +02:00
										 |  |  |             if (hideContextPane()) { | 
					
						
							| 
									
										
										
										
											2010-07-15 16:40:19 +02:00
										 |  |  |                 e->accept(); | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-07-07 13:09:30 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |     return BaseTextEditorWidget::event(e); | 
					
						
							| 
									
										
										
										
											2010-07-07 13:09:30 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::wheelEvent(QWheelEvent *event) | 
					
						
							| 
									
										
										
										
											2010-07-07 13:09:30 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-20 15:01:06 +02:00
										 |  |  |     bool visible = false; | 
					
						
							|  |  |  |     if (m_contextPane && m_contextPane->widget()->isVisible()) | 
					
						
							|  |  |  |         visible = true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |     BaseTextEditorWidget::wheelEvent(event); | 
					
						
							| 
									
										
										
										
											2010-07-20 15:01:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-04 14:32:50 +02:00
										 |  |  |     if (visible) { | 
					
						
							|  |  |  |         LookupContext::Ptr lookupContext; | 
					
						
							|  |  |  |         if (m_semanticInfo.isValid()) | 
					
						
							|  |  |  |             lookupContext = m_semanticInfo.lookupContext(); | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |         m_contextPane->apply(editor(), semanticInfo().document, QmlJS::LookupContext::Ptr(), m_semanticInfo.declaringMemberNoProperties(m_oldCursorPosition), false, true); | 
					
						
							| 
									
										
										
										
											2010-10-04 14:32:50 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-07-20 15:01:06 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::resizeEvent(QResizeEvent *event) | 
					
						
							| 
									
										
										
										
											2010-07-20 15:01:06 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |     BaseTextEditorWidget::resizeEvent(event); | 
					
						
							| 
									
										
										
										
											2010-07-20 15:01:06 +02:00
										 |  |  |     hideContextPane(); | 
					
						
							| 
									
										
										
										
											2010-07-07 13:09:30 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |  void QmlJSTextEditorWidget::scrollContentsBy(int dx, int dy) | 
					
						
							| 
									
										
										
										
											2010-07-20 15:01:06 +02:00
										 |  |  |  { | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |      BaseTextEditorWidget::scrollContentsBy(dx, dy); | 
					
						
							| 
									
										
										
										
											2010-07-20 15:01:06 +02:00
										 |  |  |      hideContextPane(); | 
					
						
							|  |  |  |  } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::unCommentSelection() | 
					
						
							| 
									
										
										
										
											2009-05-14 16:37:17 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-05 11:06:05 +02:00
										 |  |  |     Utils::unCommentSelection(this); | 
					
						
							| 
									
										
										
										
											2009-05-14 16:37:17 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::forceSemanticRehighlight() | 
					
						
							| 
									
										
										
										
											2010-04-06 11:57:08 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     m_semanticHighlighter->rehighlight(currentSource(/* force = */ true)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSEditor::QmlJSTextEditorWidget::forceSemanticRehighlightIfCurrentEditor() | 
					
						
							| 
									
										
										
										
											2011-01-12 13:58:24 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     Core::EditorManager *editorManager = Core::EditorManager::instance(); | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |     if (editorManager->currentEditor() == editor()) | 
					
						
							| 
									
										
										
										
											2011-01-12 13:58:24 +01:00
										 |  |  |         forceSemanticRehighlight(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::semanticRehighlight() | 
					
						
							| 
									
										
										
										
											2010-02-16 10:36:09 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     m_semanticHighlighter->rehighlight(currentSource()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo) | 
					
						
							| 
									
										
										
										
											2010-02-16 10:36:09 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     if (semanticInfo.revision() != document()->revision()) { | 
					
						
							|  |  |  |         // got outdated semantic info
 | 
					
						
							|  |  |  |         semanticRehighlight(); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_semanticInfo = semanticInfo; | 
					
						
							|  |  |  |     Document::Ptr doc = semanticInfo.document; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // create the ranges
 | 
					
						
							|  |  |  |     CreateRanges createRanges; | 
					
						
							|  |  |  |     m_semanticInfo.ranges = createRanges(document(), doc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Refresh the ids
 | 
					
						
							|  |  |  |     FindIdDeclarations updateIds; | 
					
						
							|  |  |  |     m_semanticInfo.idLocations = updateIds(doc); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-05 15:35:52 +02:00
										 |  |  |     FindDeclarations findDeclarations; | 
					
						
							|  |  |  |     m_semanticInfo.declarations = findDeclarations(doc->ast()); | 
					
						
							| 
									
										
										
										
											2010-02-16 10:36:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-05 15:35:52 +02:00
										 |  |  |     if (m_contextPane) { | 
					
						
							|  |  |  |         Node *newNode = m_semanticInfo.declaringMemberNoProperties(position()); | 
					
						
							|  |  |  |         if (newNode) { | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |             m_contextPane->apply(editor(), semanticInfo.document, LookupContext::Ptr(), newNode, true); | 
					
						
							| 
									
										
										
										
											2010-09-08 16:34:49 +02:00
										 |  |  |             m_cursorPositionTimer->start(); //update text marker
 | 
					
						
							| 
									
										
										
										
											2010-07-07 13:09:30 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-02-16 10:36:09 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-19 11:39:41 +02:00
										 |  |  |     // update outline
 | 
					
						
							|  |  |  |     m_updateOutlineTimer->start(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-16 10:36:09 +01:00
										 |  |  |     // update warning/error extra selections
 | 
					
						
							|  |  |  |     QList<QTextEdit::ExtraSelection> selections; | 
					
						
							|  |  |  |     appendExtraSelectionsForMessages(&selections, doc->diagnosticMessages(), document()); | 
					
						
							|  |  |  |     appendExtraSelectionsForMessages(&selections, m_semanticInfo.semanticMessages, document()); | 
					
						
							|  |  |  |     setExtraSelections(CodeWarningsSelection, selections); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::onRefactorMarkerClicked(const TextEditor::RefactorMarker &) | 
					
						
							| 
									
										
										
										
											2010-08-05 10:44:50 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     showContextPane(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | void QmlJSTextEditorWidget::onCursorPositionChanged() | 
					
						
							| 
									
										
										
										
											2010-07-07 13:09:30 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-08-27 10:32:04 +02:00
										 |  |  |     m_cursorPositionTimer->start(); | 
					
						
							| 
									
										
										
										
											2010-07-07 13:09:30 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | QModelIndex QmlJSTextEditorWidget::indexForPosition(unsigned cursorPosition, const QModelIndex &rootIndex) const | 
					
						
							| 
									
										
										
										
											2010-07-12 14:45:22 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     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); | 
					
						
							| 
									
										
										
										
											2010-08-25 13:21:38 +02:00
										 |  |  |         AST::SourceLocation location = m_outlineModel->sourceLocation(childIndex); | 
					
						
							| 
									
										
										
										
											2010-07-12 14:45:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if ((cursorPosition >= location.offset) | 
					
						
							|  |  |  |               && (cursorPosition <= location.offset + location.length)) { | 
					
						
							|  |  |  |             lastIndex = childIndex; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-07-07 13:09:30 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-07-12 14:45:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (lastIndex != rootIndex) { | 
					
						
							|  |  |  |         // recurse
 | 
					
						
							|  |  |  |         lastIndex = indexForPosition(cursorPosition, lastIndex); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return lastIndex; | 
					
						
							| 
									
										
										
										
											2010-02-16 10:36:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | bool QmlJSTextEditorWidget::hideContextPane() | 
					
						
							| 
									
										
										
										
											2010-07-20 15:01:06 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     bool b = (m_contextPane) && m_contextPane->widget()->isVisible(); | 
					
						
							| 
									
										
										
										
											2010-10-04 14:32:50 +02:00
										 |  |  |     if (b) { | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |         m_contextPane->apply(editor(), semanticInfo().document, LookupContext::Ptr(), 0, false); | 
					
						
							| 
									
										
										
										
											2010-10-04 14:32:50 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-07-20 15:01:06 +02:00
										 |  |  |     return b; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | QVector<QString> QmlJSTextEditorWidget::highlighterFormatCategories() | 
					
						
							| 
									
										
										
										
											2010-10-27 17:38:22 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |         NumberFormat, | 
					
						
							|  |  |  |         StringFormat, | 
					
						
							|  |  |  |         TypeFormat, | 
					
						
							|  |  |  |         KeywordFormat, | 
					
						
							|  |  |  |         LabelFormat, | 
					
						
							|  |  |  |         CommentFormat, | 
					
						
							|  |  |  |         VisualWhitespace, | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     static QVector<QString> categories; | 
					
						
							|  |  |  |     if (categories.isEmpty()) { | 
					
						
							|  |  |  |         categories << QLatin1String(TextEditor::Constants::C_NUMBER) | 
					
						
							|  |  |  |                 << QLatin1String(TextEditor::Constants::C_STRING) | 
					
						
							|  |  |  |                 << QLatin1String(TextEditor::Constants::C_TYPE) | 
					
						
							|  |  |  |                 << QLatin1String(TextEditor::Constants::C_KEYWORD) | 
					
						
							|  |  |  |                 << QLatin1String(TextEditor::Constants::C_FIELD) | 
					
						
							|  |  |  |                 << QLatin1String(TextEditor::Constants::C_COMMENT) | 
					
						
							|  |  |  |                 << QLatin1String(TextEditor::Constants::C_VISUAL_WHITESPACE); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return categories; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  | SemanticHighlighterSource QmlJSTextEditorWidget::currentSource(bool force) | 
					
						
							| 
									
										
										
										
											2010-02-16 10:36:09 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     int line = 0, column = 0; | 
					
						
							|  |  |  |     convertPosition(position(), &line, &column); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const Snapshot snapshot = m_modelManager->snapshot(); | 
					
						
							|  |  |  |     const QString fileName = file()->fileName(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QString code; | 
					
						
							|  |  |  |     if (force || m_semanticInfo.revision() != document()->revision()) | 
					
						
							|  |  |  |         code = toPlainText(); // get the source code only when needed.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const unsigned revision = document()->revision(); | 
					
						
							| 
									
										
										
										
											2010-11-02 11:10:27 +01:00
										 |  |  |     SemanticHighlighterSource source(snapshot, fileName, code, | 
					
						
							| 
									
										
										
										
											2010-02-16 10:36:09 +01:00
										 |  |  |                                        line, column, revision); | 
					
						
							|  |  |  |     source.force = force; | 
					
						
							|  |  |  |     return source; | 
					
						
							|  |  |  | } |