Commit 2396f34f authored by Orgad Shaneh's avatar Orgad Shaneh Committed by hjk

VCS: Generalize selections preserving on model refresh

Default implementation is between O(n) (for identical models) to
O(n*m) (for disjoint models). If sort order is known, this
can be reduced to O(n+m), like in Git implementation.

Change-Id: I44662a22961311cb882601d20efa9d445f74748b
Reviewed-by: default avatarTobias Hunger <tobias.hunger@digia.com>
Reviewed-by: default avatarhjk <qthjk@ovi.com>
parent 01084aaa
......@@ -45,6 +45,36 @@
namespace Git {
namespace Internal {
class GitSubmitFileModel : public VcsBase::SubmitFileModel
{
public:
GitSubmitFileModel(QObject *parent = 0) : VcsBase::SubmitFileModel(parent)
{ }
virtual void updateSelections(SubmitFileModel *source)
{
int j = 0;
for (int i = 0; i < rowCount() && j < source->rowCount(); ++i) {
CommitData::StateFilePair stateFile = stateFilePair(i);
for (; j < source->rowCount(); ++j) {
CommitData::StateFilePair sourceStateFile = stateFilePair(j);
if (stateFile == sourceStateFile) {
setChecked(i, source->checked(j));
break;
} else if (stateFile < sourceStateFile) {
break;
}
}
}
}
private:
CommitData::StateFilePair stateFilePair(int row)
{
return CommitData::StateFilePair(static_cast<FileStates>(extraData(row).toInt()), file(row));
}
};
/* The problem with git is that no diff can be obtained to for a random
* multiselection of staged/unstaged files; it requires the --cached
* option for staged files. So, we sort apart the diff file lists
......@@ -63,25 +93,6 @@ GitSubmitEditorWidget *GitSubmitEditor::submitEditorWidget()
return static_cast<GitSubmitEditorWidget *>(widget());
}
static void mergeFileModels(VcsBase::SubmitFileModel *model, const VcsBase::SubmitFileModel *source)
{
int j = 0;
for (int i = 0; i < model->rowCount() && j < source->rowCount(); ++i) {
CommitData::StateFilePair stateFile(
static_cast<FileStates>(model->extraData(i).toInt()), model->file(i));
for (; j < source->rowCount(); ++j) {
CommitData::StateFilePair sourceStateFile(
static_cast<FileStates>(source->extraData(j).toInt()), source->file(j));
if (stateFile == sourceStateFile) {
model->setChecked(i, source->checked(j));
break;
} else if (stateFile < sourceStateFile) {
break;
}
}
}
}
void GitSubmitEditor::setCommitData(const CommitData &d)
{
GitSubmitEditorWidget *w = submitEditorWidget();
......@@ -92,8 +103,7 @@ void GitSubmitEditor::setCommitData(const CommitData &d)
m_commitEncoding = d.commitEncoding;
m_workingDirectory = d.panelInfo.repository;
VcsBase::SubmitFileModel *oldModel = m_model;
m_model = new VcsBase::SubmitFileModel(this);
m_model = new GitSubmitFileModel(this);
if (!d.files.isEmpty()) {
for (QList<CommitData::StateFilePair>::const_iterator it = d.files.constBegin();
it != d.files.constEnd(); ++it) {
......@@ -112,10 +122,6 @@ void GitSubmitEditor::setCommitData(const CommitData &d)
QVariant(static_cast<int>(state)));
}
}
if (oldModel) {
mergeFileModels(m_model, oldModel);
delete oldModel;
}
setFileModel(m_model, d.panelInfo.repository);
}
......
......@@ -150,4 +150,28 @@ unsigned int SubmitFileModel::filterFiles(const QStringList &filter)
return rc;
}
/*! Updates user selections from \a source model.
*
* Assumption: Both model are sorted with the same order, and there
* are no duplicate entries.
*/
void SubmitFileModel::updateSelections(SubmitFileModel *source)
{
Q_ASSERT(source);
int rows = rowCount();
int sourceRows = source->rowCount();
int lastMatched = 0;
for (int i = 0; i < rows; ++i) {
// Since both models are sorted with the same order, there is no need
// to test rows earlier than latest match found
for (int j = lastMatched; j < sourceRows; ++j) {
if (file(i) == source->file(j) && state(i) == source->state(j)) {
setChecked(i, source->checked(j));
lastMatched = j + 1; // No duplicates, start on next entry
break;
}
}
}
}
} // namespace VcsBase
......@@ -65,6 +65,8 @@ public:
// Filter for entries contained in the filter list. Returns the
// number of deleted entries.
unsigned int filterFiles(const QStringList &filter);
virtual void updateSelections(SubmitFileModel *source);
};
} // namespace VcsBase
......
......@@ -479,6 +479,11 @@ QStringList VcsBaseSubmitEditor::checkedFiles() const
void VcsBaseSubmitEditor::setFileModel(SubmitFileModel *m, const QString &repositoryDirectory)
{
Q_ASSERT(m);
if (SubmitFileModel *oldModel = d->m_widget->fileModel()) {
m->updateSelections(oldModel);
delete oldModel;
}
d->m_widget->setFileModel(m);
QSet<QString> uniqueSymbols;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment