RevisionControlObserver::RevisionControlObserver(QAbstractItemView* view) :
QObject(view),
m_pendingItemStatesUpdate(false),
+ m_revisionedDirectory(false),
m_view(view),
m_dirLister(0),
m_dolphinModel(0),
m_dirLister = m_dolphinModel->dirLister();
connect(m_dirLister, SIGNAL(completed()),
this, SLOT(delayedDirectoryVerification()));
- // TODO:
- // connect(m_dirLister, SIGNAL(refreshItems(const QList<QPair<KFileItem,KFileItem>>&)),
- // this, SLOT(refreshItems()));
-
+
// The verification timer specifies the timeout until the shown directory
// is checked whether it is versioned. Per default it is assumed that users
// don't iterate through versioned directories and a high timeout is used
}
revisionControlUrl.addPath(m_plugin->fileName());
- KFileItem item = m_dirLister->findByUrl(revisionControlUrl);
- if (item.isNull()) {
+ const KFileItem item = m_dirLister->findByUrl(revisionControlUrl);
+ if (item.isNull() && m_revisionedDirectory) {
// The directory is not versioned. Reset the verification timer to a higher
// value, so that browsing through non-versioned directories is not slown down
// by an immediate verification.
m_dirVerificationTimer->setInterval(500);
- } else {
- // The directory is versioned. Assume that the user will further browse through
- // versioned directories and decrease the verification timer.
- m_dirVerificationTimer->setInterval(100);
+ m_revisionedDirectory = false;
+ disconnect(m_dirLister, SIGNAL(refreshItems(const QList<QPair<KFileItem,KFileItem>>&)),
+ this, SLOT(delayedDirectoryVerification()));
+ disconnect(m_dirLister, SIGNAL(newItems(const KFileItemList&)),
+ this, SLOT(delayedDirectoryVerification()));
+ } else if (!item.isNull()) {
+ if (!m_revisionedDirectory) {
+ // The directory is versioned. Assume that the user will further browse through
+ // versioned directories and decrease the verification timer.
+ m_dirVerificationTimer->setInterval(100);
+ m_revisionedDirectory = true;
+ connect(m_dirLister, SIGNAL(refreshItems(const QList<QPair<KFileItem,KFileItem>>&)),
+ this, SLOT(delayedDirectoryVerification()));
+ connect(m_dirLister, SIGNAL(newItems(const KFileItemList&)),
+ this, SLOT(delayedDirectoryVerification()));
+ }
updateItemStates();
}
}
};
bool m_pendingItemStatesUpdate;
+ bool m_revisionedDirectory;
QAbstractItemView* m_view;
KDirLister* m_dirLister;
{
}
+#include "revisioncontrolplugin.moc"
+
// ----------------------------------------------------------------------------
SubversionPlugin::SubversionPlugin() :
const QDateTime versionedTimeStamp = info.timeStamp;
if (localTimeStamp > versionedTimeStamp) {
- if (info.size != item.size()) {
+ if ((info.size != item.size()) || !equalRevisionContent(item.name())) {
return RevisionControlPlugin::EditingRevision;
}
- // TODO: a comparison of the content is required
} else if (localTimeStamp < versionedTimeStamp) {
- if (info.size != item.size()) {
+ if ((info.size != item.size()) || !equalRevisionContent(item.name())) {
return RevisionControlPlugin::UpdateRequiredRevision;
}
- // TODO: a comparison of the content is required
}
return RevisionControlPlugin::LatestRevision;
}
return RevisionControlPlugin::LocalRevision;
}
+
+QList<QAction*> SubversionPlugin::contextMenuActions(const KFileItemList& items) const
+{
+ Q_UNUSED(items);
+ // TODO...
+ return QList<QAction*>();
+}
+
+bool SubversionPlugin::equalRevisionContent(const QString& name) const
+{
+ QFile localFile(m_directory + '/' + name);
+ if (!localFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ return false;
+ }
+
+ QFile revisionedFile(m_directory + "/.svn/text-base/" + name + ".svn-base");
+ if (!revisionedFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ return false;
+ }
+
+ QTextStream localText(&localFile);
+ QTextStream revisionedText(&revisionedFile);
+ while (!localText.atEnd() && !revisionedText.atEnd()) {
+ if (localText.readLine() != revisionedText.readLine()) {
+ return false;
+ }
+ }
+
+ return localText.atEnd() && revisionedText.atEnd();
+}
+
#include <QDateTime>
#include <QString>
+#include <QObject>
class KFileItem;
+class KFileItemList;
+class QAction;
/**
* @brief Base class for revision control plugins.
*
* Enables the file manager to show the revision state
- * of a revisioned file.
+ * of a revisioned file. The methods
+ * RevisionControlPlugin::beginRetrieval(),
+ * RevisionControlPlugin::endRetrieval() and
+ * RevisionControlPlugin::revisionState() are invoked
+ * from a separate thread to assure that the GUI thread
+ * won't be blocked. All other methods are invoked in the
+ * scope of the GUI thread.
*/
-class LIBDOLPHINPRIVATE_EXPORT RevisionControlPlugin
+class LIBDOLPHINPRIVATE_EXPORT RevisionControlPlugin : public QObject
{
+ Q_OBJECT
+
public:
enum RevisionState
{
* in beginInfoRetrieval().
*/
virtual RevisionState revisionState(const KFileItem& item) = 0;
+
+ /**
+ * Returns the list of actions that should be shown in the context menu
+ * for the files \p items. If an action cannot be applied to the list
+ * of files, it is recommended to disable the action instead of removing it
+ * from the returned list. If an action triggers a change of the revisions,
+ * the signal RevisionControlPlugin::revisionStatesChanged() must be emitted.
+ */
+ virtual QList<QAction*> contextMenuActions(const KFileItemList& items) const = 0;
+signals:
+ /**
+ * Should be emitted when the revision state of files has been changed
+ * after the last retrieval. The file manager will be triggered to
+ * update the revision states of the directory \p directory by invoking
+ * RevisionControlPlugin::beginRetrieval(),
+ * RevisionControlPlugin::revisionState() and
+ * RevisionControlPlugin::endRetrieval().
+ */
+ void revisionStatesChanged(const QString& directory);
};
virtual bool beginRetrieval(const QString& directory);
virtual void endRetrieval();
virtual RevisionControlPlugin::RevisionState revisionState(const KFileItem& item);
+ virtual QList<QAction*> contextMenuActions(const KFileItemList& items) const;
+
+private:
+ /**
+ * Returns true, if the content of the local file \p name is equal to the
+ * content of the revisioned file.
+ */
+ bool equalRevisionContent(const QString& name) const;
private:
struct RevisionInfo