diff options
author | ck <qt-info@nokia.com> | 2009-12-09 14:47:26 (GMT) |
---|---|---|
committer | ck <qt-info@nokia.com> | 2009-12-09 14:51:48 (GMT) |
commit | bc8e87016cfeb4a63151425bcd0f69f21a5fc1c1 (patch) | |
tree | e7d4becf90164311a0b1a4131f67bf1679fb73e6 /tools | |
parent | 445f8bbd9709b712fa253fe1833bbf9416429603 (diff) | |
download | Qt-bc8e87016cfeb4a63151425bcd0f69f21a5fc1c1.zip Qt-bc8e87016cfeb4a63151425bcd0f69f21a5fc1c1.tar.gz Qt-bc8e87016cfeb4a63151425bcd0f69f21a5fc1c1.tar.bz2 |
Assistant: Make doc file watching work for the intended use case.
The QFileSystemWatcher signals the changing of a file several times,
with the first one coming too early. As a result, we are likely
checking a file that is not yet fully constructed.
The workaround/solution is to delay reacting to the change until
after the (hopefully) last signal from the QFileSystemWatcher.
Reviewed-by: kh1
Diffstat (limited to 'tools')
-rw-r--r-- | tools/assistant/tools/assistant/helpenginewrapper.cpp | 53 | ||||
-rw-r--r-- | tools/assistant/tools/assistant/helpenginewrapper.h | 23 |
2 files changed, 75 insertions, 1 deletions
diff --git a/tools/assistant/tools/assistant/helpenginewrapper.cpp b/tools/assistant/tools/assistant/helpenginewrapper.cpp index 899954c..79a25ec 100644 --- a/tools/assistant/tools/assistant/helpenginewrapper.cpp +++ b/tools/assistant/tools/assistant/helpenginewrapper.cpp @@ -45,6 +45,7 @@ #include <QtCore/QFileInfo> #include <QtCore/QFileSystemWatcher> +#include <QtCore/QTimer> #include <QtHelp/QHelpContentModel> #include <QtHelp/QHelpEngine> #include <QtHelp/QHelpIndexModel> @@ -646,9 +647,28 @@ void HelpEngineWrapper::assertDocFilesWatched() == m_helpEngine->registeredDocumentations().count()); } +TimeoutForwarder::TimeoutForwarder(const QString &fileName) + : m_fileName(fileName) +{ + TRACE_OBJ +} + +void TimeoutForwarder::forward() +{ + TRACE_OBJ + HelpEngineWrapper::instance().qchFileChanged(m_fileName, true); +} + void HelpEngineWrapper::qchFileChanged(const QString &fileName) { TRACE_OBJ + qchFileChanged(fileName, false); +} + +void HelpEngineWrapper::qchFileChanged(const QString &fileName, bool fromTimeout) +{ + TRACE_OBJ + /* * We don't use QHelpEngineCore::namespaceName(fileName), because the file * may not exist anymore or contain a different namespace. @@ -665,9 +685,39 @@ void HelpEngineWrapper::qchFileChanged(const QString &fileName) * We can't do an assertion here, because QFileSystemWatcher may send the * signal more than once. */ - if (ns.isEmpty()) + if (ns.isEmpty()) { + m_recentQchUpdates.remove(fileName); + return; + } + + /* + * Since the QFileSystemWatcher typically sends the signal more than once, + * we repeatedly delay our reaction a bit until we think the last signal + * was sent. + */ + + QMap<QString, RecentSignal>::Iterator it = m_recentQchUpdates.find(fileName); + const QDateTime &now = QDateTime::currentDateTime(); + + // Case 1: This is the first recent signal for the file. + if (it == m_recentQchUpdates.end()) { + QSharedPointer<TimeoutForwarder> forwarder(new TimeoutForwarder(fileName)); + m_recentQchUpdates.insert(fileName, RecentSignal(now, forwarder)); + QTimer::singleShot(UpdateGracePeriod, forwarder.data(), SLOT(forward())); + return; + } + + // Case 2: The last signal for this file has not expired yet. + if (it.value().first > now.addMSecs(-UpdateGracePeriod)) { + if (!fromTimeout) + it.value().first = now; + else + QTimer::singleShot(UpdateGracePeriod, it.value().second.data(), + SLOT(forward())); return; + } + // Case 3: The last signal for this file has expired. if (m_helpEngine->unregisterDocumentation(ns)) { if (!QFileInfo(fileName).exists() || !m_helpEngine->registerDocumentation(fileName)) { @@ -678,6 +728,7 @@ void HelpEngineWrapper::qchFileChanged(const QString &fileName) } m_helpEngine->setupData(); } + m_recentQchUpdates.erase(it); } QT_END_NAMESPACE diff --git a/tools/assistant/tools/assistant/helpenginewrapper.h b/tools/assistant/tools/assistant/helpenginewrapper.h index f827d95..348479e 100644 --- a/tools/assistant/tools/assistant/helpenginewrapper.h +++ b/tools/assistant/tools/assistant/helpenginewrapper.h @@ -42,8 +42,11 @@ #ifndef HELPENGINEWRAPPER_H #define HELPENGINEWRAPPER_H +#include <QtCore/QDateTime> #include <QtCore/QMap> #include <QtCore/QObject> +#include <QtCore/QPair> +#include <QtCore/QSharedPointer> #include <QtCore/QString> #include <QtCore/QStringList> #include <QtCore/QUrl> @@ -67,6 +70,20 @@ enum { ShowLastPages = 2 }; + +class TimeoutForwarder : public QObject +{ + Q_OBJECT +public: + TimeoutForwarder(const QString &fileName); +private slots: + void forward(); +private: + friend class HelpEngineWrapper; + + const QString m_fileName; +}; + class HelpEngineWrapper : public QObject { Q_OBJECT @@ -197,13 +214,19 @@ private slots: void qchFileChanged(const QString &fileName); private: + friend class TimeoutForwarder; + HelpEngineWrapper(const QString &collectionFile); void initFileSystemWatchers(); void assertDocFilesWatched(); + void qchFileChanged(const QString &fileName, bool fromTimeout); + static const int UpdateGracePeriod = 2000; static HelpEngineWrapper *helpEngineWrapper; QHelpEngine * const m_helpEngine; QFileSystemWatcher * const m_qchWatcher; + typedef QPair<QDateTime, QSharedPointer<TimeoutForwarder> > RecentSignal; + QMap<QString, RecentSignal> m_recentQchUpdates; }; QT_END_NAMESPACE |