forked from qt-creator/qt-creator
DocumentModel: Keep sorted on renames
Keep the document model sorted on document renames. This effects the "Open Documents" views and more. Task-number: QTCREATORBUG-21565 Change-Id: I2c546eb56ebee0a5fa1169060b85fce454b8e571 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -49,6 +49,34 @@ static Core::Internal::DocumentModelPrivate *d;
|
|||||||
namespace Core {
|
namespace Core {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
bool compare(const DocumentModel::Entry *e1, const DocumentModel::Entry *e2)
|
||||||
|
{
|
||||||
|
const int cmp = e1->plainDisplayName().localeAwareCompare(e2->plainDisplayName());
|
||||||
|
return (cmp < 0) || (cmp == 0 && e1->fileName() < e2->fileName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a pair of indices. The first is the index that needs to be removed or -1 if no removal
|
||||||
|
// is necessary. The second is the index to add the entry into, or -1 if no addition is necessary.
|
||||||
|
// If the entry does not need to be moved, then (-1, -1) will be returned as no action is needed.
|
||||||
|
std::pair<int, int> positionEntry(const QList<DocumentModel::Entry *> &list,
|
||||||
|
DocumentModel::Entry *entry)
|
||||||
|
{
|
||||||
|
const int to_remove = list.indexOf(entry);
|
||||||
|
|
||||||
|
const QList<DocumentModel::Entry *> toSort
|
||||||
|
= Utils::filtered(list, [entry](DocumentModel::Entry *e) { return e != entry; });
|
||||||
|
|
||||||
|
const auto begin = std::begin(toSort);
|
||||||
|
const auto end = std::end(toSort);
|
||||||
|
const auto to_insert
|
||||||
|
= static_cast<int>(std::distance(begin, std::lower_bound(begin, end, entry, &compare)));
|
||||||
|
if (to_remove == to_insert)
|
||||||
|
return std::make_pair(-1, -1);
|
||||||
|
return std::make_pair(to_remove, to_insert);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
DocumentModelPrivate::~DocumentModelPrivate()
|
DocumentModelPrivate::~DocumentModelPrivate()
|
||||||
{
|
{
|
||||||
qDeleteAll(m_entries);
|
qDeleteAll(m_entries);
|
||||||
@@ -91,18 +119,13 @@ void DocumentModelPrivate::addEntry(DocumentModel::Entry *entry)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int index;
|
auto positions = positionEntry(m_entries, entry);
|
||||||
const QString displayName = entry->plainDisplayName();
|
// Do not remove anything (new entry), insert somewhere:
|
||||||
for (index = 0; index < m_entries.count(); ++index) {
|
QTC_CHECK(positions.first == -1 && positions.second >= 0);
|
||||||
int cmp = displayName.localeAwareCompare(m_entries.at(index)->plainDisplayName());
|
|
||||||
if (cmp < 0)
|
int row = positions.second + 1/*<no document>*/;
|
||||||
break;
|
|
||||||
if (cmp == 0 && fileName < m_entries.at(index)->fileName())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
int row = index + 1/*<no document>*/;
|
|
||||||
beginInsertRows(QModelIndex(), row, row);
|
beginInsertRows(QModelIndex(), row, row);
|
||||||
m_entries.insert(index, entry);
|
m_entries.insert(positions.second, entry);
|
||||||
disambiguateDisplayNames(entry);
|
disambiguateDisplayNames(entry);
|
||||||
if (!fixedPath.isEmpty())
|
if (!fixedPath.isEmpty())
|
||||||
m_entryByFixedPath[fixedPath] = entry;
|
m_entryByFixedPath[fixedPath] = entry;
|
||||||
@@ -321,10 +344,27 @@ void DocumentModelPrivate::itemChanged()
|
|||||||
}
|
}
|
||||||
if (!found && !fixedPath.isEmpty())
|
if (!found && !fixedPath.isEmpty())
|
||||||
m_entryByFixedPath[fixedPath] = entry;
|
m_entryByFixedPath[fixedPath] = entry;
|
||||||
|
|
||||||
if (!disambiguateDisplayNames(m_entries.at(idx.value()))) {
|
if (!disambiguateDisplayNames(m_entries.at(idx.value()))) {
|
||||||
QModelIndex mindex = index(idx.value() + 1/*<no document>*/, 0);
|
QModelIndex mindex = index(idx.value() + 1/*<no document>*/, 0);
|
||||||
emit dataChanged(mindex, mindex);
|
emit dataChanged(mindex, mindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure the entries stay sorted:
|
||||||
|
auto positions = positionEntry(m_entries, entry);
|
||||||
|
if (positions.first >= 0 && positions.second >= 0) {
|
||||||
|
// Entry did move: remove and add it again.
|
||||||
|
beginRemoveRows(QModelIndex(), positions.first + 1, positions.first + 1);
|
||||||
|
m_entries.removeAt(positions.first);
|
||||||
|
endRemoveRows();
|
||||||
|
|
||||||
|
beginInsertRows(QModelIndex(), positions.second + 1, positions.second + 1);
|
||||||
|
m_entries.insert(positions.second, entry);
|
||||||
|
endInsertRows();
|
||||||
|
} else {
|
||||||
|
// Nothing to remove or add: The entry did not move.
|
||||||
|
QTC_CHECK(positions.first == -1 && positions.second == -1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentModelPrivate::addEditor(IEditor *editor, bool *isNewDocument)
|
void DocumentModelPrivate::addEditor(IEditor *editor, bool *isNewDocument)
|
||||||
|
Reference in New Issue
Block a user