aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Schulz <david.schulz@qt.io>2018-09-28 13:37:11 +0200
committerDavid Schulz <david.schulz@qt.io>2018-10-10 09:05:04 +0000
commit2730fd4c489f81762eac9088552c8e2f06b9eb77 (patch)
tree6e1d403ea8ad0b82822c4f9178d37183bfc78af3
parentfd186bed20ba6e475bade1fac8f909ce86aa18a4 (diff)
Editor: Do not access a text document from another thread
Task-number: QTCREATORBUG-21192 Change-Id: I5c327f268da2364f1fc4f671993e8498cd0b7421 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
-rw-r--r--src/plugins/texteditor/codeassist/documentcontentcompletion.cpp76
1 files changed, 38 insertions, 38 deletions
diff --git a/src/plugins/texteditor/codeassist/documentcontentcompletion.cpp b/src/plugins/texteditor/codeassist/documentcontentcompletion.cpp
index cdb69be9b9..44572146f1 100644
--- a/src/plugins/texteditor/codeassist/documentcontentcompletion.cpp
+++ b/src/plugins/texteditor/codeassist/documentcontentcompletion.cpp
@@ -46,14 +46,14 @@ class DocumentContentCompletionProcessor : public IAssistProcessor
{
public:
DocumentContentCompletionProcessor(const QString &snippetGroupId);
+ ~DocumentContentCompletionProcessor() override;
IAssistProposal *perform(const AssistInterface *interface) override;
- bool running() final { return m_running; }
+ bool running() final { return m_watcher.isRunning(); }
private:
- TextEditor::SnippetAssistCollector m_snippetCollector;
- IAssistProposal *createProposal(const AssistInterface *interface);
- bool m_running = false;
+ QString m_snippetGroup;
+ QFutureWatcher<QStringList> m_watcher;
};
DocumentContentCompletionProvider::DocumentContentCompletionProvider(const QString &snippetGroup)
@@ -71,45 +71,39 @@ IAssistProcessor *DocumentContentCompletionProvider::createProcessor() const
}
DocumentContentCompletionProcessor::DocumentContentCompletionProcessor(const QString &snippetGroupId)
- : m_snippetCollector(snippetGroupId, QIcon(":/texteditor/images/snippet.png"))
+ : m_snippetGroup(snippetGroupId)
{ }
-IAssistProposal *DocumentContentCompletionProcessor::perform(const AssistInterface *interface)
+DocumentContentCompletionProcessor::~DocumentContentCompletionProcessor()
{
- Utils::onResultReady(Utils::runAsync(
- &DocumentContentCompletionProcessor::createProposal, this, interface),
- [this](IAssistProposal *proposal){
- m_running = false;
- setAsyncProposalAvailable(proposal);
- });
- m_running = true;
- return nullptr;
+ if (m_watcher.isRunning())
+ m_watcher.cancel();
}
-static void generateProposalItems(const QString &text, QSet<QString> &words,
- QList<AssistProposalItemInterface *> &items)
+static void createProposal(QFutureInterface<QStringList> &future, const QString text)
{
- static const QRegularExpression wordRE("([a-zA-Z_][a-zA-Z0-9_]{2,})");
+ const QRegularExpression wordRE("([a-zA-Z_][a-zA-Z0-9_]{2,})");
- QRegularExpressionMatch match;
- int index = text.indexOf(wordRE, 0, &match);
- while (index >= 0) {
+ QSet<QString> words;
+ QRegularExpressionMatchIterator it = wordRE.globalMatch(text);
+ while (it.hasNext()) {
+ if (future.isCanceled())
+ return;
+ QRegularExpressionMatch match = it.next();
const QString &word = match.captured();
- if (!words.contains(word)) {
- auto item = new AssistProposalItem();
- item->setText(word);
- items.append(item);
+ if (!words.contains(word))
words.insert(word);
- }
- index += word.size();
- index = text.indexOf(wordRE, index, &match);
}
+
+ future.reportResult(words.toList());
}
-IAssistProposal *DocumentContentCompletionProcessor::createProposal(
- const AssistInterface *interface)
+IAssistProposal *DocumentContentCompletionProcessor::perform(const AssistInterface *interface)
{
QScopedPointer<const AssistInterface> assistInterface(interface);
+ if (running())
+ return nullptr;
+
int pos = interface->position();
QChar chr;
@@ -126,14 +120,20 @@ IAssistProposal *DocumentContentCompletionProcessor::createProposal(
return nullptr;
}
- QSet<QString> words;
- QList<AssistProposalItemInterface *> items = m_snippetCollector.collect();
- QTextBlock block = interface->textDocument()->firstBlock();
+ const QString text = interface->textDocument()->toPlainText();
- while (block.isValid()) {
- generateProposalItems(block.text(), words, items);
- block = block.next();
- }
-
- return new GenericProposal(pos, items);
+ m_watcher.setFuture(Utils::runAsync(&createProposal, text));
+ QObject::connect(&m_watcher, &QFutureWatcher<QStringList>::resultReadyAt,
+ &m_watcher, [this, pos](int index){
+ const TextEditor::SnippetAssistCollector snippetCollector(
+ m_snippetGroup, QIcon(":/texteditor/images/snippet.png"));
+ QList<AssistProposalItemInterface *> items = snippetCollector.collect();
+ for (const QString &word : m_watcher.resultAt(index)) {
+ auto item = new AssistProposalItem();
+ item->setText(word);
+ items.append(item);
+ }
+ setAsyncProposalAvailable(new GenericProposal(pos, items));
+ });
+ return nullptr;
}