|
|
@ -14,29 +14,44 @@ |
|
|
|
|
|
|
|
|
|
|
|
#include <cassert> |
|
|
|
#include <cassert> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//! Store string lists.
|
|
|
|
|
|
|
|
/** Abstract storage interface to string lists, such as bookmarks. */ |
|
|
|
class Storage: public QObject { |
|
|
|
class Storage: public QObject { |
|
|
|
Q_OBJECT; |
|
|
|
Q_OBJECT; |
|
|
|
Q_SIGNALS: |
|
|
|
Q_SIGNALS: |
|
|
|
|
|
|
|
//! Emitted if file content has changed.
|
|
|
|
void changed(); |
|
|
|
void changed(); |
|
|
|
public: |
|
|
|
public: |
|
|
|
Storage() {} |
|
|
|
Storage() {} |
|
|
|
|
|
|
|
/*! @return true if readable or writable */ |
|
|
|
bool valid() { |
|
|
|
bool valid() { |
|
|
|
return readable() || writeable(); |
|
|
|
return readable() || writeable(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/*! @return true if valid */ |
|
|
|
operator bool() { |
|
|
|
operator bool() { |
|
|
|
return valid(); |
|
|
|
return valid(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/*! @return true if storage object already exists */ |
|
|
|
virtual bool readable() = 0; |
|
|
|
virtual bool readable() = 0; |
|
|
|
|
|
|
|
/*! @return true if storage object exists or could be created */ |
|
|
|
virtual bool writeable() = 0; |
|
|
|
virtual bool writeable() = 0; |
|
|
|
|
|
|
|
/*! @return storage content as string list */ |
|
|
|
virtual QStringList read() = 0; |
|
|
|
virtual QStringList read() = 0; |
|
|
|
|
|
|
|
//! Writes storage content from string list.
|
|
|
|
virtual bool write(const QStringList& out) = 0; |
|
|
|
virtual bool write(const QStringList& out) = 0; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//! Implement @ref Storage for files.
|
|
|
|
class FileStorage: public Storage { |
|
|
|
class FileStorage: public Storage { |
|
|
|
Q_OBJECT; |
|
|
|
Q_OBJECT; |
|
|
|
public: |
|
|
|
public: |
|
|
|
|
|
|
|
/*! @param file full path to storage file */ |
|
|
|
FileStorage(QString file): _file(file) { |
|
|
|
FileStorage(QString file): _file(file) { |
|
|
|
if (valid()) setupWatcher(); |
|
|
|
_watcher.addPath(QFileInfo(_file).absolutePath()); |
|
|
|
|
|
|
|
assert(connect(&_watcher, SIGNAL(directoryChanged(const QString&)), |
|
|
|
|
|
|
|
SLOT(setupWatcher()))); |
|
|
|
|
|
|
|
assert(connect(&_watcher, SIGNAL(fileChanged(const QString&)), |
|
|
|
|
|
|
|
SIGNAL(changed()))); |
|
|
|
} |
|
|
|
} |
|
|
|
bool readable() { |
|
|
|
bool readable() { |
|
|
|
return QFileInfo(_file).exists(); |
|
|
|
return QFileInfo(_file).exists(); |
|
|
@ -66,21 +81,10 @@ class FileStorage: public Storage { |
|
|
|
} |
|
|
|
} |
|
|
|
private Q_SLOTS: |
|
|
|
private Q_SLOTS: |
|
|
|
void setupWatcher() { |
|
|
|
void setupWatcher() { |
|
|
|
if (!_watcher) { |
|
|
|
_watcher.removePaths(_watcher.files()); |
|
|
|
_watcher = new QFileSystemWatcher(this); |
|
|
|
if (readable()) _watcher.addPath(_file.fileName()); |
|
|
|
_watcher->addPath(QFileInfo(_file).absolutePath()); |
|
|
|
|
|
|
|
assert(connect(_watcher, SIGNAL(directoryChanged(const QString&)), |
|
|
|
|
|
|
|
SLOT(setupWatcher()))); |
|
|
|
|
|
|
|
assert(connect(_watcher, SIGNAL(fileChanged(const QString&)), |
|
|
|
|
|
|
|
SIGNAL(changed()))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (readable()) { |
|
|
|
|
|
|
|
_watcher->removePaths(_watcher->files()); |
|
|
|
|
|
|
|
_watcher->addPath(_file.fileName()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
private: |
|
|
|
private: |
|
|
|
QFile _file; |
|
|
|
QFile _file; |
|
|
|
QFileSystemWatcher* _watcher; |
|
|
|
QFileSystemWatcher _watcher; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|