diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index 5e6db2fd7e..0aab06ac90 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -6,9 +6,11 @@ #include #include +#include #include #include #include +#include #include #include @@ -315,34 +317,12 @@ bool ContentSelectorModel::ContentModel::setData(const QModelIndex& index, const bool ContentSelectorModel::ContentModel::insertRows(int position, int rows, const QModelIndex& parent) { - if (parent.isValid()) - return false; - - beginInsertRows(parent, position, position + rows - 1); - { - for (int row = 0; row < rows; ++row) - mFiles.insert(position, new EsmFile); - } - endInsertRows(); - - return true; + return false; } bool ContentSelectorModel::ContentModel::removeRows(int position, int rows, const QModelIndex& parent) { - if (parent.isValid()) - return false; - - beginRemoveRows(parent, position, position + rows - 1); - { - for (int row = 0; row < rows; ++row) - delete mFiles.takeAt(position); - } - endRemoveRows(); - - // at this point we know that drag and drop has finished. - checkForLoadOrderErrors(); - return true; + return false; } Qt::DropActions ContentSelectorModel::ContentModel::supportedDropActions() const @@ -358,13 +338,14 @@ QStringList ContentSelectorModel::ContentModel::mimeTypes() const QMimeData* ContentSelectorModel::ContentModel::mimeData(const QModelIndexList& indexes) const { QByteArray encodedData; + QDataStream stream(&encodedData, QIODevice::WriteOnly); for (const QModelIndex& index : indexes) { if (!index.isValid()) continue; - encodedData.append(item(index.row())->encodedData()); + stream << index.row(); } QMimeData* mimeData = new QMimeData(); @@ -396,26 +377,31 @@ bool ContentSelectorModel::ContentModel::dropMimeData( QByteArray encodedData = data->data(mMimeType); QDataStream stream(&encodedData, QIODevice::ReadOnly); + std::vector toMove; while (!stream.atEnd()) { - - QString value; - QStringList values; - QStringList gamefiles; - - for (int i = 0; i < EsmFile::FileProperty_GameFile; ++i) - { - stream >> value; - values << value; - } - - stream >> gamefiles; - - insertRows(beginRow, 1); - - QModelIndex idx = index(beginRow++, 0, QModelIndex()); - setData(idx, QStringList() << values << gamefiles, Qt::EditRole); + int sourceRow; + stream >> sourceRow; + toMove.emplace_back(mFiles.at(sourceRow)); } + int minRow = mFiles.size(); + int maxRow = 0; + for (EsmFile* file : toMove) + { + int from = mFiles.indexOf(file); + int to = beginRow; + if (from < beginRow) + to--; + else if (from > beginRow) + beginRow++; + minRow = std::min(minRow, std::min(to, from)); + maxRow = std::max(maxRow, std::max(to, from)); + mFiles.move(from, to); + } + + dataChanged(index(minRow, 0), index(maxRow, 0)); + // at this point we know that drag and drop has finished. + checkForLoadOrderErrors(); return true; } @@ -566,6 +552,7 @@ void ContentSelectorModel::ContentModel::clearFiles() if (filesCount > 0) { beginRemoveRows(QModelIndex(), 0, filesCount - 1); + qDeleteAll(mFiles); mFiles.clear(); endRemoveRows(); } @@ -688,7 +675,7 @@ void ContentSelectorModel::ContentModel::checkForLoadOrderErrors() { for (int row = 0; row < mFiles.count(); ++row) { - EsmFile* file = item(row); + EsmFile* file = mFiles.at(row); bool isRowInError = checkForLoadOrderErrors(file, row).count() != 0; if (isRowInError) { @@ -765,13 +752,8 @@ bool ContentSelectorModel::ContentModel::setCheckState(const QString& filepath, if (!file) return false; - Qt::CheckState state = Qt::Unchecked; - if (checkState) - { - state = Qt::Checked; mCheckedFiles.insert(file); - } else mCheckedFiles.erase(file); @@ -781,7 +763,7 @@ bool ContentSelectorModel::ContentModel::setCheckState(const QString& filepath, refreshModel(); // if we're checking an item, ensure all "upstream" files (dependencies) are checked as well. - if (state == Qt::Checked) + if (checkState) { for (const QString& upstreamName : file->gameFiles()) { @@ -796,7 +778,7 @@ bool ContentSelectorModel::ContentModel::setCheckState(const QString& filepath, } } // otherwise, if we're unchecking an item (or the file is a game file) ensure all downstream files are unchecked. - if (state == Qt::Unchecked) + else { for (const EsmFile* downstreamFile : mFiles) { diff --git a/components/contentselector/model/esmfile.cpp b/components/contentselector/model/esmfile.cpp index 39a33e710e..e4280baef7 100644 --- a/components/contentselector/model/esmfile.cpp +++ b/components/contentselector/model/esmfile.cpp @@ -1,10 +1,5 @@ #include "esmfile.hpp" -#include -#include - -int ContentSelectorModel::EsmFile::sPropertyCount = 7; - ContentSelectorModel::EsmFile::EsmFile(const QString& fileName, ModelItem* parent) : ModelItem(parent) , mFileName(fileName) @@ -46,17 +41,6 @@ void ContentSelectorModel::EsmFile::setDescription(const QString& description) mDescription = description; } -QByteArray ContentSelectorModel::EsmFile::encodedData() const -{ - QByteArray encodedData; - QDataStream stream(&encodedData, QIODevice::WriteOnly); - - stream << mFileName << mAuthor << mVersion << mModified.toString(Qt::ISODate) << mPath << mDescription - << mGameFiles; - - return encodedData; -} - bool ContentSelectorModel::EsmFile::isGameFile() const { return (mGameFiles.size() == 0) diff --git a/components/contentselector/model/esmfile.hpp b/components/contentselector/model/esmfile.hpp index cf0e086362..606cc3d319 100644 --- a/components/contentselector/model/esmfile.hpp +++ b/components/contentselector/model/esmfile.hpp @@ -64,10 +64,6 @@ namespace ContentSelectorModel } bool isGameFile() const; - QByteArray encodedData() const; - - public: - static int sPropertyCount; private: QString mTooltipTemlate = tr( diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp index 3f75b82487..00c32e272d 100644 --- a/components/contentselector/view/contentselector.cpp +++ b/components/contentselector/view/contentselector.cpp @@ -108,6 +108,7 @@ void ContentSelectorView::ContentSelector::buildAddonView() connect(ui->addonView, &QTableView::activated, this, &ContentSelector::slotAddonTableItemActivated); connect(mContentModel, &ContentSelectorModel::ContentModel::dataChanged, this, &ContentSelector::signalAddonDataChanged); + connect(mContentModel, &ContentSelectorModel::ContentModel::dataChanged, this, &ContentSelector::slotRowsMoved); buildContextMenu(); } @@ -331,3 +332,8 @@ void ContentSelectorView::ContentSelector::slotSearchFilterTextChanged(const QSt { ui->addonView->setDragEnabled(newText.isEmpty()); } + +void ContentSelectorView::ContentSelector::slotRowsMoved() +{ + ui->addonView->selectionModel()->clearSelection(); +} \ No newline at end of file diff --git a/components/contentselector/view/contentselector.hpp b/components/contentselector/view/contentselector.hpp index 48377acb86..2b739645ba 100644 --- a/components/contentselector/view/contentselector.hpp +++ b/components/contentselector/view/contentselector.hpp @@ -85,6 +85,7 @@ namespace ContentSelectorView void slotUncheckMultiSelectedItems(); void slotCopySelectedItemsPaths(); void slotSearchFilterTextChanged(const QString& newText); + void slotRowsMoved(); }; }