diff --git a/apps/opencs/model/world/infocollection.cpp b/apps/opencs/model/world/infocollection.cpp index a508d28f3..560be8131 100644 --- a/apps/opencs/model/world/infocollection.cpp +++ b/apps/opencs/model/world/infocollection.cpp @@ -97,7 +97,8 @@ bool CSMWorld::InfoCollection::reorderRows (int baseIndex, const std::vector + #include "idtablebase.hpp" #include "columns.hpp" +namespace +{ + QString toLower(const QString &str) + { + return QString::fromUtf8(Misc::StringUtils::lowerCase(str.toStdString()).c_str()); + } +} + CSMWorld::InfoTableProxyModel::InfoTableProxyModel(CSMWorld::UniversalId::Type type, QObject *parent) : IdTableProxyModel(parent), mType(type), - mSourceModel(NULL) + mSourceModel(NULL), + mInfoColumnId(type == UniversalId::Type_TopicInfos ? Columns::ColumnId_Topic : + Columns::ColumnId_Journal) { Q_ASSERT(type == UniversalId::Type_TopicInfos || type == UniversalId::Type_JournalInfos); } @@ -15,44 +27,53 @@ void CSMWorld::InfoTableProxyModel::setSourceModel(QAbstractItemModel *sourceMod { IdTableProxyModel::setSourceModel(sourceModel); mSourceModel = dynamic_cast(sourceModel); - connect(mSourceModel, - SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), - this, - SLOT(modelDataChanged(const QModelIndex &, const QModelIndex &))); - mFirstRowCache.clear(); + if (mSourceModel != NULL) + { + connect(mSourceModel, + SIGNAL(rowsInserted(const QModelIndex &, int, int)), + this, + SLOT(modelRowsChanged(const QModelIndex &, int, int))); + connect(mSourceModel, + SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + this, + SLOT(modelRowsChanged(const QModelIndex &, int, int))); + mFirstRowCache.clear(); + } } bool CSMWorld::InfoTableProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { QModelIndex first = mSourceModel->index(getFirstInfoRow(left.row()), left.column()); QModelIndex second = mSourceModel->index(getFirstInfoRow(right.row()), right.column()); + + // If both indexes are belonged to the same Topic/Journal, compare their original rows only + if (first.row() == second.row()) + { + return sortOrder() == Qt::AscendingOrder ? left.row() < right.row() : right.row() < left.row(); + } return IdTableProxyModel::lessThan(first, second); } int CSMWorld::InfoTableProxyModel::getFirstInfoRow(int currentRow) const { - Columns::ColumnId columnId = Columns::ColumnId_Topic; - if (mType == UniversalId::Type_JournalInfos) - { - columnId = Columns::ColumnId_Journal; - } - - int column = mSourceModel->findColumnIndex(columnId); - QString info = mSourceModel->data(mSourceModel->index(currentRow, column)).toString(); + int row = currentRow; + int column = mSourceModel->findColumnIndex(mInfoColumnId); + QString info = toLower(mSourceModel->data(mSourceModel->index(row, column)).toString()); if (mFirstRowCache.contains(info)) { return mFirstRowCache[info]; } - while (--currentRow >= 0 && - mSourceModel->data(mSourceModel->index(currentRow, column)) == info); + while (--row >= 0 && + toLower(mSourceModel->data(mSourceModel->index(row, column)).toString()) == info); + ++row; - mFirstRowCache[info] = currentRow + 1; - return currentRow + 1; + mFirstRowCache[info] = row; + return row; } -void CSMWorld::InfoTableProxyModel::modelDataChanged(const QModelIndex &/*topLeft*/, const QModelIndex &/*bottomRight*/) +void CSMWorld::InfoTableProxyModel::modelRowsChanged(const QModelIndex &/*parent*/, int /*start*/, int /*end*/) { mFirstRowCache.clear(); } diff --git a/apps/opencs/model/world/infotableproxymodel.hpp b/apps/opencs/model/world/infotableproxymodel.hpp index 322831626..28d6017b3 100644 --- a/apps/opencs/model/world/infotableproxymodel.hpp +++ b/apps/opencs/model/world/infotableproxymodel.hpp @@ -4,6 +4,7 @@ #include #include "idtableproxymodel.hpp" +#include "columns.hpp" #include "universalid.hpp" namespace CSMWorld @@ -16,6 +17,8 @@ namespace CSMWorld UniversalId::Type mType; IdTableBase *mSourceModel; + Columns::ColumnId mInfoColumnId; + ///< Contains ID for Topic or Journal ID mutable QHash mFirstRowCache; @@ -31,7 +34,7 @@ namespace CSMWorld virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const; private slots: - void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + void modelRowsChanged(const QModelIndex &parent, int start, int end); }; } diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index 0ec701a65..d757d5bbe 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -9,6 +9,8 @@ #include #include +#include + #include "../../model/doc/document.hpp" #include "../../model/world/data.hpp" @@ -128,17 +130,24 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) { int row = mProxyModel->mapToSource ( mProxyModel->index (selectedRows.begin()->row(), 0)).row(); + QString curData = mModel->data(mModel->index(row, column)).toString(); - if (row>0 && mModel->data (mModel->index (row, column))== - mModel->data (mModel->index (row-1, column))) + if (row > 0) { - menu.addAction (mMoveUpAction); + QString prevData = mModel->data(mModel->index(row - 1, column)).toString(); + if (Misc::StringUtils::ciEqual(curData.toStdString(), prevData.toStdString())) + { + menu.addAction(mMoveUpAction); + } } - if (rowrowCount()-1 && mModel->data (mModel->index (row, column))== - mModel->data (mModel->index (row+1, column))) + if (row < mModel->rowCount() - 1) { - menu.addAction (mMoveDownAction); + QString nextData = mModel->data(mModel->index(row + 1, column)).toString(); + if (Misc::StringUtils::ciEqual(curData.toStdString(), nextData.toStdString())) + { + menu.addAction(mMoveDownAction); + } } } }