- the subversion test plugin is at least capable of indicating the revision state for files
svn path=/trunk/KDE/kdebase/apps/; revision=999489
const QModelIndex dirIndex = proxyModel->mapToSource(index);
const QModelIndex revisionIndex = dolphinModel->index(dirIndex.row(), DolphinModel::Revision);
const QVariant data = dolphinModel->data(revisionIndex, Qt::DecorationRole);
- const DolphinModel::RevisionState state = static_cast<DolphinModel::RevisionState>(data.toInt());
+ const RevisionControlPlugin::RevisionState state = static_cast<RevisionControlPlugin::RevisionState>(data.toInt());
- if (state != DolphinModel::LocalRevision) {
+ if (state != RevisionControlPlugin::LocalRevision) {
// TODO: extend KFileItemDelegate to be able to get the icon boundaries
const QRect iconRect(option.rect.x(), option.rect.y(),
KIconLoader::SizeSmall, KIconLoader::SizeSmall);
}
}
-QPixmap DolphinFileItemDelegate::emblemForState(DolphinModel::RevisionState state, const QSize& size)
+QPixmap DolphinFileItemDelegate::emblemForState(RevisionControlPlugin::RevisionState state, const QSize& size)
{
// TODO #1: all icons that are use here will be replaced by revision control emblems provided by the
// Oxygen team before KDE 4.4
// TODO #2: cache the icons
switch (state) {
- case DolphinModel::LatestRevision:
+ case RevisionControlPlugin::LatestRevision:
return KIcon("dialog-ok-apply").pixmap(size);
- break;
-
- case DolphinModel::ConflictingRevision:
+ case RevisionControlPlugin::ConflictingRevision:
+ return KIcon("application-exit").pixmap(size);
+ case RevisionControlPlugin::UpdateRequiredRevision:
+ return KIcon("rating").pixmap(size);
+ case RevisionControlPlugin::EditingRevision:
return KIcon("emblem-important").pixmap(size);
- break;
-
- // ...
-
default:
break;
}
const DolphinModel* dolphinModel,
const QModelIndex& index);
- static QPixmap emblemForState(DolphinModel::RevisionState state, const QSize& size);
+ static QPixmap emblemForState(RevisionControlPlugin::RevisionState state, const QSize& size);
private:
bool m_hasMinimizedNameColumn;
// TODO: remove data again when items are deleted...
const QPersistentModelIndex key = index;
- const RevisionState state = static_cast<RevisionState>(value.toInt());
- if (m_revisionHash.value(key, LocalRevision) != state) {
+ const RevisionControlPlugin::RevisionState state = static_cast<RevisionControlPlugin::RevisionState>(value.toInt());
+ if (m_revisionHash.value(key, RevisionControlPlugin::LocalRevision) != state) {
if (!m_hasRevisionData) {
connect(this, SIGNAL(rowsRemoved (const QModelIndex&, int, int)),
this, SLOT(slotRowsRemoved(const QModelIndex&, int, int)));
case Qt::DecorationRole:
if (index.column() == DolphinModel::Revision) {
- return m_revisionHash.value(index, LocalRevision);
+ return m_revisionHash.value(index, RevisionControlPlugin::LocalRevision);
}
break;
case Qt::DisplayRole:
if (index.column() == DolphinModel::Revision) {
- switch (m_revisionHash.value(index, LocalRevision)) {
- case LatestRevision:
+ switch (m_revisionHash.value(index, RevisionControlPlugin::LocalRevision)) {
+ case RevisionControlPlugin::LatestRevision:
return i18nc("@item::intable", "Latest");
-
- case LocalRevision:
+ case RevisionControlPlugin::EditingRevision:
+ return i18nc("@item::intable", "Editing");
+ case RevisionControlPlugin::UpdateRequiredRevision:
+ return i18nc("@item::intable", "Update required");
+ case RevisionControlPlugin::LocalRevision:
default:
return i18nc("@item::intable", "Local");
}
#define DOLPHINMODEL_H
#include <kdirmodel.h>
+#include <revisioncontrolplugin.h>
#include <libdolphin_export.h>
#include <QHash>
ExtraColumnCount
};
- enum RevisionState {
- LocalRevision,
- LatestRevision,
- ConflictingRevision
- // TODO...
- };
-
DolphinModel(QObject* parent = 0);
virtual ~DolphinModel();
private:
bool m_hasRevisionData;
- QHash<QPersistentModelIndex, RevisionState> m_revisionHash;
+ QHash<QPersistentModelIndex, RevisionControlPlugin::RevisionState> m_revisionHash;
static const char* m_others;
};
#include <QAbstractProxyModel>
#include <QAbstractItemView>
-#include <QListView>
#include <QTimer>
/**
void RevisionControlObserver::applyUpdatedItemStates()
{
- // Updating items with non-uniform item sizes is a serious bottleneck
- // in QListView. Temporary disable the non-uniform item sizes.
- QListView* listView = qobject_cast<QListView*>(m_view);
- bool uniformSizes = true;
- if (listView != 0) {
- uniformSizes = listView->uniformItemSizes();
- //listView->setUniformItemSizes(true); TODO: does not work as well as in KFilePreviewGenerator
- }
+ // QAbstractItemModel::setData() triggers a bottleneck in combination with QListView
+ // (a detailed description of the root cause is given in the class KFilePreviewGenerator
+ // from kdelibs). To bypass this bottleneck, the signals of the model are temporary blocked.
+ // This works as the update of the data does not require a relayout of the views used in Dolphin.
+ const bool signalsBlocked = m_dolphinModel->signalsBlocked();
+ m_dolphinModel->blockSignals(true);
const QList<ItemState> itemStates = m_updateItemStatesThread->itemStates();
foreach (const ItemState& itemState, itemStates) {
Qt::DecorationRole);
}
- if (listView != 0) {
- listView->setUniformItemSizes(uniformSizes);
- }
-
- m_view->viewport()->repaint(); // TODO: this should not be necessary, as DolphinModel::setData() calls dataChanged()
+ m_dolphinModel->blockSignals(signalsBlocked);
+ m_view->viewport()->repaint();
if (m_pendingItemStatesUpdate) {
m_pendingItemStatesUpdate = false;
{
Q_ASSERT(directory.endsWith('/'));
m_directory = directory;
+ const QString path = directory + ".svn/text-base/";
- QFile file(directory + ".svn/entries");
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- return false;
- }
-
- QTextStream in(&file);
+ QDir dir(path);
+ const QFileInfoList fileInfoList = dir.entryInfoList();
+ const int size = fileInfoList.size();
QString fileName;
- QString line;
- while (!in.atEnd()) {
- fileName = line;
- line = in.readLine();
- const bool isRevisioned = !line.isEmpty() &&
- ((line == QLatin1String("dir")) ||
- (line == QLatin1String("file")));
- if (isRevisioned) {
- RevisionInfo info; // TODO
+ for (int i = 0; i < size; ++i) {
+ fileName = fileInfoList.at(i).fileName();
+ // Remove the ".svn-base" postfix to be able to compare the filenames
+ // in a fast way in SubversionPlugin::revisionState().
+ fileName.chop(sizeof(".svn-base") / sizeof(char) - 1);
+ if (!fileName.isEmpty()) {
+ RevisionInfo info;
+ info.size = fileInfoList.at(i).size();
+ info.timeStamp = fileInfoList.at(i).lastModified();
m_revisionInfoHash.insert(fileName, info);
}
}
- return true;
+ return size > 0;
}
void SubversionPlugin::endRetrieval()
RevisionControlPlugin::RevisionState SubversionPlugin::revisionState(const KFileItem& item)
{
const QString name = item.name();
- if (m_revisionInfoHash.contains(name)) {
- // TODO...
- return RevisionControlPlugin::LatestRevision;
+ if (item.isDir()) {
+ QFile file(m_directory + name + "/.svn");
+ if (file.open(QIODevice::ReadOnly)) {
+ file.close();
+ // TODO...
+ return RevisionControlPlugin::LatestRevision;
+ }
+ } else if (m_revisionInfoHash.contains(name)) {
+ const RevisionInfo info = m_revisionInfoHash.value(item.name());
+ const QDateTime localTimeStamp = item.time(KFileItem::ModificationTime).dateTime();
+ const QDateTime versionedTimeStamp = info.timeStamp;
+
+ if (localTimeStamp > versionedTimeStamp) {
+ if (info.size != item.size()) {
+ return RevisionControlPlugin::EditingRevision;
+ }
+ // TODO: a comparison of the content is required
+ } else if (localTimeStamp < versionedTimeStamp) {
+ if (info.size != item.size()) {
+ return RevisionControlPlugin::UpdateRequiredRevision;
+ }
+ // TODO: a comparison of the content is required
+ }
+ return RevisionControlPlugin::LatestRevision;
}
return RevisionControlPlugin::LocalRevision;
{
LocalRevision,
LatestRevision,
+ UpdateRequiredRevision,
+ EditingRevision,
ConflictingRevision
// TODO...
};
private:
struct RevisionInfo
{
- // TODO...
+ quint64 size;
QDateTime timeStamp;
};