Commit 998064ad authored by Erik Verbruggen's avatar Erik Verbruggen
Browse files

Added a snapshot to the DUI editor.

parent e2c06d5d
......@@ -35,11 +35,10 @@
#include "qmljsnodepool_p.h"
using namespace DuiEditor;
using namespace DuiEditor::Internal;
using namespace QmlJS;
DuiDocument::DuiDocument(const QString &fileName)
: _engine(0), _pool(0), _program(0), _fileName(fileName)
: _engine(0), _pool(0), _program(0), _fileName(fileName), _parsedCorrectly(false)
{
}
......@@ -84,10 +83,10 @@ bool DuiDocument::parse()
lexer.setCode(_source, /*line = */ 1);
bool parsed = parser.parse();
_parsedCorrectly = parser.parse();
_program = parser.ast();
_diagnosticMessages = parser.diagnosticMessages();
return parsed;
return _parsedCorrectly;
}
Snapshot::Snapshot()
......
......@@ -33,13 +33,14 @@
#include <QtCore/QMap>
#include <QtCore/QString>
#include "duieditor_global.h"
#include "qmljsengine_p.h"
#include "qmljsastfwd_p.h"
namespace DuiEditor {
namespace Internal {
class DuiDocument
class DUIEDITOR_EXPORT DuiDocument
{
public:
typedef QSharedPointer<DuiDocument> Ptr;
......@@ -58,6 +59,11 @@ public:
void setSource(const QString &source);
bool parse();
bool isParsedCorrectly() const
{ return _parsedCorrectly; }
QString fileName() const { return _fileName; }
private:
QmlJS::Engine *_engine;
QmlJS::NodePool *_pool;
......@@ -65,16 +71,26 @@ private:
QList<QmlJS::DiagnosticMessage> _diagnosticMessages;
QString _fileName;
QString _source;
bool _parsedCorrectly;
};
class Snapshot: public QMap<QString, DuiDocument>
class DUIEDITOR_EXPORT Snapshot: protected QMap<QString, DuiDocument::Ptr>
{
public:
Snapshot();
~Snapshot();
void insert(const DuiDocument::Ptr &document)
{ QMap<QString, DuiDocument::Ptr>::insert(document->fileName(), document); }
typedef QMapIterator<QString, DuiDocument::Ptr> Iterator;
Iterator iterator() const
{ return Iterator(*this); }
DuiDocument::Ptr document(const QString &fileName) const
{ return value(fileName); }
};
} // end of namespace Internal
} // emd of namespace DuiEditor
#endif // DUIDOCUMENT_H
......@@ -32,6 +32,7 @@
#include "duihighlighter.h"
#include "duieditorplugin.h"
#include "duidocument.h"
#include "duimodelmanager.h"
#include "rewriter_p.h"
......@@ -41,6 +42,7 @@
#include <coreplugin/icore.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <extensionsystem/pluginmanager.h>
#include <texteditor/basetextdocument.h>
#include <texteditor/fontsettings.h>
#include <texteditor/textblockiterator.h>
......@@ -369,7 +371,8 @@ ScriptEditor::ScriptEditor(const Context &context,
QWidget *parent) :
TextEditor::BaseTextEditor(parent),
m_context(context),
m_methodCombo(0)
m_methodCombo(0),
m_modelManager(0)
{
setParenthesesMatchingEnabled(true);
setMarksVisible(true);
......@@ -386,6 +389,13 @@ ScriptEditor::ScriptEditor(const Context &context,
connect(this, SIGNAL(textChanged()), this, SLOT(updateDocument()));
baseTextDocument()->setSyntaxHighlighter(new DuiHighlighter);
m_modelManager = ExtensionSystem::PluginManager::instance()->getObject<DuiModelManagerInterface>();
if (m_modelManager) {
connect(m_modelManager, SIGNAL(documentUpdated(DuiDocument::Ptr)),
this, SLOT(onDocumentUpdated(DuiDocument::Ptr)));
}
}
ScriptEditor::~ScriptEditor()
......@@ -428,17 +438,21 @@ void ScriptEditor::updateDocumentNow()
m_updateDocumentTimer->stop();
const QString fileName = file()->fileName();
const QString source = toPlainText();
DuiDocument::Ptr doc = DuiDocument::create(fileName);
doc->setSource(source);
bool parsed = doc->parse();
m_document = doc;
m_modelManager->updateSourceFiles(QStringList() << fileName);
}
void ScriptEditor::onDocumentUpdated(DuiDocument::Ptr doc)
{
if (file()->fileName() != doc->fileName())
return;
m_document = doc;
FindIdDeclarations updateIds;
m_ids = updateIds(doc->program());
if (parsed) {
if (doc->isParsedCorrectly()) {
FindDeclarations findDeclarations;
m_declarations = findDeclarations(doc->program());
......@@ -454,7 +468,7 @@ void ScriptEditor::updateDocumentNow()
m_methodCombo->clear();
m_methodCombo->addItems(items);
updateMethodBoxIndex();
}
}
QList<QTextEdit::ExtraSelection> selections;
......
......@@ -46,6 +46,9 @@ namespace Core {
}
namespace DuiEditor {
class DuiModelManagerInterface;
namespace Internal {
class DuiHighlighter;
......@@ -112,6 +115,8 @@ public slots:
virtual void setFontSettings(const TextEditor::FontSettings &);
private slots:
void onDocumentUpdated(DuiDocument::Ptr doc);
void updateDocument();
void updateDocumentNow();
void jumpToMethod(int index);
......@@ -142,6 +147,7 @@ private:
QMap<QString, QList<QmlJS::AST::SourceLocation> > m_ids; // ### use QMultiMap
QList<QmlJS::DiagnosticMessage> m_diagnosticMessages;
DuiDocument::Ptr m_document;
DuiModelManagerInterface *m_modelManager;
};
} // namespace Internal
......
TEMPLATE = lib
TARGET = DuiEditor
include(../../qtcreatorplugin.pri)
include(duieditor_dependencies.pri)
include(parser/parser.pri)
include(rewriter/rewriter.pri)
INCLUDEPATH += parser rewriter
DEFINES += DUIEDITOR_LIBRARY
INCLUDEPATH += parser \
rewriter
HEADERS += duieditor.h \
duieditorfactory.h \
duieditorplugin.h \
duihighlighter.h \
duieditoractionhandler.h \
duicodecompletion.h \
duieditorconstants.h \
duihoverhandler.h \
duidocument.h \
duicompletionvisitor.h
duieditorfactory.h \
duieditorplugin.h \
duihighlighter.h \
duieditoractionhandler.h \
duicodecompletion.h \
duieditorconstants.h \
duihoverhandler.h \
duidocument.h \
duicompletionvisitor.h \
duimodelmanagerinterface.h \
duieditor_global.h \
duimodelmanager.h
SOURCES += duieditor.cpp \
duieditorfactory.cpp \
duieditorplugin.cpp \
duihighlighter.cpp \
duieditoractionhandler.cpp \
duicodecompletion.cpp \
duihoverhandler.cpp \
duidocument.cpp \
duicompletionvisitor.cpp
duieditorfactory.cpp \
duieditorplugin.cpp \
duihighlighter.cpp \
duieditoractionhandler.cpp \
duicodecompletion.cpp \
duihoverhandler.cpp \
duidocument.cpp \
duicompletionvisitor.cpp \
duimodelmanagerinterface.cpp \
duimodelmanager.cpp
RESOURCES += duieditor.qrc
#ifndef DUIEDITOR_GLOBAL_H
#define DUIEDITOR_GLOBAL_H
#include <QtGlobal>
#if defined(DUIEDITOR_LIBRARY)
# define DUIEDITOR_EXPORT Q_DECL_EXPORT
#else
# define DUIEDITOR_EXPORT Q_DECL_IMPORT
#endif
#endif // DUIEDITOR_GLOBAL_H
......@@ -36,6 +36,7 @@ namespace Constants {
const char * const M_CONTEXT = "DUI Editor.ContextMenu";
const char * const RUN_SEP = "DuiEditor.Run.Separator";
const char * const C_DUIEDITOR = "QML Editor";
const char * const TASK_INDEX = "DuiEditor.TaskIndex";
const char * const C_DUIEDITOR_MIMETYPE = "application/x-dui";
......
......@@ -35,6 +35,7 @@
#include "duieditorfactory.h"
#include "duicodecompletion.h"
#include "duihoverhandler.h"
#include "duimodelmanager.h"
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
......@@ -62,6 +63,7 @@ using namespace DuiEditor::Constants;
DuiEditorPlugin *DuiEditorPlugin::m_instance = 0;
DuiEditorPlugin::DuiEditorPlugin() :
m_modelManager(0),
m_wizard(0),
m_editor(0),
m_actionHandler(0),
......@@ -85,6 +87,10 @@ bool DuiEditorPlugin::initialize(const QStringList & /*arguments*/, QString *err
Core::ICore *core = Core::ICore::instance();
if (!core->mimeDatabase()->addMimeTypes(QLatin1String(":/duieditor/DuiEditor.mimetypes.xml"), error_message))
return false;
m_modelManager = new DuiModelManager(this);
addAutoReleasedObject(m_modelManager);
m_scriptcontext << core->uniqueIDManager()->uniqueIdentifier(DuiEditor::Constants::C_DUIEDITOR);
m_context = m_scriptcontext;
m_context << core->uniqueIDManager()->uniqueIdentifier(TextEditor::Constants::C_TEXTEDITOR);
......
......@@ -38,6 +38,9 @@ class TextEditorActionHandler;
} // namespace TextEditor
namespace DuiEditor {
class DuiModelManagerInterface;
namespace Internal {
class DuiEditorFactory;
......@@ -70,6 +73,7 @@ private:
Context m_context;
Context m_scriptcontext;
DuiModelManagerInterface *m_modelManager;
TextEditor::TextFileWizard *m_wizard;
DuiEditorFactory *m_editor;
TextEditor::TextEditorActionHandler *m_actionHandler;
......
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include <QFile>
#include <QtConcurrentRun>
#include <qtconcurrent/runextensions.h>
#include <QTextStream>
#include <coreplugin/icore.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <texteditor/itexteditor.h>
#include "duieditorconstants.h"
#include "duimodelmanager.h"
using namespace DuiEditor;
using namespace DuiEditor::Internal;
DuiModelManager::DuiModelManager(QObject *parent):
DuiModelManagerInterface(parent),
m_core(Core::ICore::instance())
{
m_synchronizer.setCancelOnWait(true);
qRegisterMetaType<DuiDocument::Ptr>("DuiDocument::Ptr");
connect(this, SIGNAL(documentUpdated(DuiDocument::Ptr)), this, SLOT(onDocumentUpdated(DuiDocument::Ptr)));
}
Snapshot DuiModelManager::snapshot() const
{
return _snapshot;
}
void DuiModelManager::updateSourceFiles(const QStringList &files)
{
refreshSourceFiles(files);
}
QFuture<void> DuiModelManager::refreshSourceFiles(const QStringList &sourceFiles)
{
if (! sourceFiles.isEmpty()) {
const QMap<QString, QString> workingCopy = buildWorkingCopyList();
QFuture<void> result = QtConcurrent::run(&DuiModelManager::parse,
workingCopy, sourceFiles,
this);
if (m_synchronizer.futures().size() > 10) {
QList<QFuture<void> > futures = m_synchronizer.futures();
m_synchronizer.clearFutures();
foreach (QFuture<void> future, futures) {
if (! (future.isFinished() || future.isCanceled()))
m_synchronizer.addFuture(future);
}
}
m_synchronizer.addFuture(result);
if (sourceFiles.count() > 1) {
m_core->progressManager()->addTask(result, tr("Indexing"),
DuiEditor::Constants::TASK_INDEX,
Core::ProgressManager::CloseOnSuccess);
}
return result;
}
return QFuture<void>();
}
QMap<QString, QString> DuiModelManager::buildWorkingCopyList()
{
QMap<QString, QString> workingCopy;
Core::EditorManager *editorManager = m_core->editorManager();
foreach (Core::IEditor *editor, editorManager->openedEditors()) {
const QString key = editor->file()->fileName();
if (TextEditor::ITextEditor *textEditor = qobject_cast<TextEditor::ITextEditor*>(editor)) {
workingCopy[key] = textEditor->contents();
}
}
return workingCopy;
}
void DuiModelManager::emitDocumentUpdated(DuiDocument::Ptr doc)
{ emit documentUpdated(doc); }
void DuiModelManager::onDocumentUpdated(DuiDocument::Ptr doc)
{
_snapshot.insert(doc);
}
void DuiModelManager::parse(QFutureInterface<void> &future,
QMap<QString, QString> workingCopy,
QStringList files,
DuiModelManager *modelManager)
{
future.setProgressRange(0, files.size() + 1);
for (int i = 0; i < files.size(); ++i) {
future.setProgressValue(i);
const QString fileName = files.at(i);
QString contents;
if (workingCopy.contains(fileName)) {
contents = workingCopy.value(fileName);
} else {
QFile inFile(fileName);
if (inFile.open(QIODevice::ReadOnly)) {
QTextStream ins(&inFile);
contents = ins.readAll();
inFile.close();
}
}
DuiDocument::Ptr doc = DuiDocument::create(fileName);
doc->setSource(contents);
doc->parse();
modelManager->emitDocumentUpdated(doc);
}
future.setProgressValue(files.size() + 1);
}
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef DUIMODELMANAGER_H
#define DUIMODELMANAGER_H
#include <QFuture>
#include <QFutureSynchronizer>
#include "duidocument.h"
#include "duimodelmanagerinterface.h"
namespace Core {
class ICore;
}
namespace DuiEditor {
namespace Internal {
class DuiModelManager: public DuiModelManagerInterface
{
Q_OBJECT
public:
DuiModelManager(QObject *parent = 0);
virtual Snapshot snapshot() const;
virtual void updateSourceFiles(const QStringList &files);
void emitDocumentUpdated(DuiDocument::Ptr doc);
Q_SIGNALS:
void projectPathChanged(const QString &projectPath);
void documentUpdated(DuiDocument::Ptr doc);
void aboutToRemoveFiles(const QStringList &files);
private Q_SLOTS:
// this should be executed in the GUI thread.
void onDocumentUpdated(DuiDocument::Ptr doc);
protected:
QFuture<void> refreshSourceFiles(const QStringList &sourceFiles);
QMap<QString, QString> buildWorkingCopyList();
static void parse(QFutureInterface<void> &future,
QMap<QString, QString> workingCopy,
QStringList files,
DuiModelManager *modelManager);
private:
Core::ICore *m_core;
Snapshot _snapshot;
QFutureSynchronizer<void> m_synchronizer;
};
} // namespace Internal
} // namespace DuiEditor
#endif // DUIMODELMANAGER_H
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "duimodelmanagerinterface.h"
using namespace DuiEditor;
DuiModelManagerInterface::DuiModelManagerInterface(QObject *parent):
QObject(parent)
{
}
DuiModelManagerInterface::~DuiModelManagerInterface()
{
}
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in