From 1abcb79b5050587b6296bb31dfd999424f5e3f56 Mon Sep 17 00:00:00 2001 From: David Faure Date: Sat, 25 Nov 2017 23:04:41 +0100 Subject: [PATCH] Dict Engine: cache available dicts This makes the config dialog more responsive when opening it multiple times, and minimizes network traffic. The equality check at the beginning of sourceRequestEvent was completely wrong, if the source (DataContainer) was deleted-because-unused then we need to proceed with the request even if it's the same as the previous request. And if the request is ongoing then DataEngine doesn't call us again, it connects to the existing source... --- dataengines/dict/dictengine.cpp | 26 ++++++++++++++++++++------ dataengines/dict/dictengine.h | 3 +++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/dataengines/dict/dictengine.cpp b/dataengines/dict/dictengine.cpp index 3ed1f56d8..59ea6851e 100644 --- a/dataengines/dict/dictengine.cpp +++ b/dataengines/dict/dictengine.cpp @@ -152,6 +152,7 @@ void DictEngine::getDicts() ret += m_tcpSocket->readAll(); } + QVariantMap *availableDicts = new QVariantMap; const QList retLines = ret.split('\n'); for (const QByteArray &curr : retLines) { if (curr.startsWith("554")) { @@ -175,14 +176,15 @@ void DictEngine::getDicts() description.chop(1); } setData(QStringLiteral("list-dictionaries"), id, description); // this is additive + availableDicts->insert(id, description); } } + m_availableDictsCache.insert(m_serverName, availableDicts); m_tcpSocket->disconnectFromHost(); } - void DictEngine::socketClosed() { if (m_tcpSocket) { @@ -195,10 +197,6 @@ bool DictEngine::sourceRequestEvent(const QString &query) { // FIXME: this is COMPLETELY broken .. it can only look up one query at a time! // a DataContainer subclass that does the look up should probably be made - if (m_currentQuery == query) { - return false; - } - if (m_tcpSocket) { m_tcpSocket->abort(); //stop if lookup is in progress and new query is requested m_tcpSocket->deleteLater(); @@ -232,7 +230,23 @@ bool DictEngine::sourceRequestEvent(const QString &query) if (m_currentWord.simplified().isEmpty()) { setData(m_currentQuery, m_dictName, QString()); } else { - setData(m_currentQuery, m_dictName, QString()); + if (m_currentWord == QLatin1String("list-dictionaries")) { + // Use cache if available + QVariantMap *dicts = m_availableDictsCache.object(m_serverName); + if (dicts) { + for (auto it = dicts->constBegin(); it != dicts->constEnd(); ++it) { + setData(m_currentQuery, it.key(), it.value()); + } + return true; + } + } + + // We need to do this in order to create the DataContainer immediately in DataEngine + // so it can connect to updates. Not sure why DataEnginePrivate::requestSource + // doesn't create the DataContainer when sourceRequestEvent returns true, by doing + // source(sourceName) instead of source(sourceName, false), but well, I'm too scared to change that. + setData(m_currentQuery, QVariant()); + m_tcpSocket = new QTcpSocket(this); connect(m_tcpSocket, &QTcpSocket::disconnected, this, &DictEngine::socketClosed); diff --git a/dataengines/dict/dictengine.h b/dataengines/dict/dictengine.h index 1d1c2e98a..99d531374 100644 --- a/dataengines/dict/dictengine.h +++ b/dataengines/dict/dictengine.h @@ -20,6 +20,8 @@ #define DICTENGINE_H #include #include +#include +#include class QTcpSocket; /** @@ -53,6 +55,7 @@ class DictEngine: public Plasma::DataEngine QString m_currentQuery; QString m_dictName; QString m_serverName; + QCache m_availableDictsCache; };