bool SourceFileModel::dropSourceFiles(QMimeData const *data, Qt::DropAction action, int row, QModelIndex const &parent) { if (action != Qt::MoveAction) return QAbstractItemModel::dropMimeData(data, action, row, 0, parent); auto encoded = data->data(mtx::gui::MimeTypes::MergeSourceFileModelItem); QDataStream stream{&encoded, QIODevice::ReadOnly}; while (!stream.atEnd()) { quint64 value; stream >> value; auto sourceFile = m_sourceFileMap[value]; auto sourceIdx = indexFromSourceFile(sourceFile.get()); if (!sourceIdx.isValid()) continue; auto sourceParent = sourceIdx.parent(); auto sourceParentItem = sourceParent.isValid() ? itemFromIndex(sourceParent) : invisibleRootItem(); auto rowItems = sourceParentItem->takeRow(sourceIdx.row()); if (!parent.isValid()) { if ((sourceParent == parent) && (sourceIdx.row() < row)) --row; invisibleRootItem()->insertRow(row, rowItems); ++row; } else { auto parentFile = fromIndex(parent); Q_ASSERT(parentFile); if (sourceFile->isAdditionalPart()) row = std::min(row, parentFile->m_additionalParts.size()); else row = std::max(row, parentFile->m_additionalParts.size()); if ((sourceParent == parent) && (sourceIdx.row() < row)) --row; itemFromIndex(parent)->insertRow(row, rowItems); ++row; } updateSourceFileLists(); } return false; }
bool SourceFileModel::dropSourceFiles(QMimeData const *data, Qt::DropAction action, int row, QModelIndex const &parent) { if (action != Qt::MoveAction) return QAbstractItemModel::dropMimeData(data, action, row, 0, parent); mxinfo(boost::format("dropMimeData row %1% parent %2%/%3%\n") % row % parent.row() % parent.column()); auto encoded = data->data(MIME_TYPE); QDataStream stream{&encoded, QIODevice::ReadOnly}; while (!stream.atEnd()) { quint64 value; stream >> value; auto sourceFile = m_sourceFileMap[value]; auto sourceIdx = indexFromSourceFile(sourceFile.get()); if (!sourceIdx.isValid()) continue; mxinfo(boost::format(" val %|1$08x| ptr %2% idx %3%/%4%\n") % value % sourceFile.get() % sourceIdx.row() % sourceIdx.column()); auto sourceParent = sourceIdx.parent(); auto sourceParentItem = sourceParent.isValid() ? itemFromIndex(sourceParent) : invisibleRootItem(); auto priorRow = row; auto rowItems = sourceParentItem->takeRow(sourceIdx.row()); if (!parent.isValid()) { if ((sourceParent == parent) && (sourceIdx.row() < row)) --row; mxinfo(boost::format("tried moving case 1 from %1% row %2% to new parent %3% row %4% new row %5%\n") % dumpIdx(sourceIdx.parent()) % sourceIdx.row() % dumpIdx(parent) % priorRow % (row + 1)); invisibleRootItem()->insertRow(row, rowItems); ++row; } else { auto parentFile = fromIndex(parent); Q_ASSERT(parentFile); if (sourceFile->isAdditionalPart()) row = std::min(row, parentFile->m_additionalParts.size()); else row = std::max(row, parentFile->m_additionalParts.size()); if ((sourceParent == parent) && (sourceIdx.row() < row)) --row; mxinfo(boost::format("tried moving case 2 from %1% row %2% to new parent %3% row %4% new row %5%\n") % dumpIdx(sourceIdx.parent()) % sourceIdx.row() % dumpIdx(parent) % priorRow % (row + 1)); itemFromIndex(parent)->insertRow(row, rowItems); ++row; } updateSourceFileLists(); } return false; }
void SourceFileModel::moveSourceFilesUpOrDown(QList<SourceFile *> files, bool up) { sortSourceFiles(files, !up); // qDebug() << "move up?" << up << "files" << files; auto couldNotBeMoved = QHash<SourceFile *, bool>{}; auto isSelected = QHash<SourceFile *, bool>{}; auto const direction = up ? -1 : +1; auto const topRows = rowCount(); for (auto const &file : files) { isSelected[file] = true; if (!file->isRegular() && isSelected[file->m_appendedTo]) continue; auto idx = indexFromSourceFile(file); Q_ASSERT(idx.isValid()); auto targetRow = idx.row() + direction; if (couldNotBeMoved[fromIndex(idx.sibling(targetRow, 0)).get()]) { couldNotBeMoved[file] = true; continue; } if (file->isRegular()) { if (!((0 <= targetRow) && (targetRow < topRows))) { couldNotBeMoved[file] = true; continue; } // qDebug() << "top level: would like to move" << idx.row() << "to" << targetRow; insertRow(targetRow, takeRow(idx.row())); continue; } auto parentItem = itemFromIndex(idx.parent()); auto const appendedAdditionalRows = countAppendedAndAdditionalParts(parentItem); auto const additionalPartsRows = appendedAdditionalRows.first; auto const appendedRows = appendedAdditionalRows.second; auto const lowerLimit = (file->isAdditionalPart() ? 0 : additionalPartsRows); auto const upperLimit = (file->isAdditionalPart() ? 0 : appendedRows) + additionalPartsRows; if ((lowerLimit <= targetRow) && (targetRow < upperLimit)) { // qDebug() << "appended level normal: would like to move" << idx.row() << "to" << targetRow; parentItem->insertRow(targetRow, parentItem->takeRow(idx.row())); continue; } auto parentIdx = parentItem->index(); Q_ASSERT(parentIdx.isValid()); auto newParentRow = parentIdx.row() + direction; if ((0 > newParentRow) || (rowCount() <= newParentRow)) { // qDebug() << "appended, cannot move further"; couldNotBeMoved[file] = true; continue; } auto newParent = fromIndex(index(newParentRow, 0)); auto newParentItem = itemFromIndex(index(newParentRow, 0)); auto rowItems = parentItem->takeRow(idx.row()); auto newParentNumbers = countAppendedAndAdditionalParts(newParentItem); targetRow = up && file->isAdditionalPart() ? newParentNumbers.first : up ? newParentNumbers.first + newParentNumbers.second : !up && file->isAdditionalPart() ? 0 : newParentNumbers.first; Q_ASSERT(!!newParent); // qDebug() << "appended level cross: would like to move" << idx.row() << "from" << file->m_appendedTo << "to" << newParent.get() << "as" << targetRow; newParentItem->insertRow(targetRow, rowItems); file->m_appendedTo = newParent.get(); } updateSourceFileLists(); }