void SourceFileModel::updateSourceFileLists() { for (auto const &sourceFile : *m_sourceFiles) { sourceFile->m_additionalParts.clear(); sourceFile->m_appendedFiles.clear(); } m_sourceFiles->clear(); for (auto row = 0, numRows = rowCount(); row < numRows; ++row) { auto idx = index(row, 0, QModelIndex{}); auto sourceFile = fromIndex(idx); Q_ASSERT(sourceFile); *m_sourceFiles << sourceFile; for (auto appendedRow = 0, numAppendedRows = rowCount(idx); appendedRow < numAppendedRows; ++appendedRow) { auto appendedSourceFile = fromIndex(index(appendedRow, 0, idx)); Q_ASSERT(appendedSourceFile); appendedSourceFile->m_appendedTo = sourceFile.get(); if (appendedSourceFile->isAppended()) sourceFile->m_appendedFiles << appendedSourceFile; else sourceFile->m_additionalParts << appendedSourceFile; } } // TODO: SourceFileModel::updateSourceFileLists move dropped additional parts to end of additional parts sub-list dumpSourceFiles("updateSourceFileLists END"); }
Qt::ItemFlags SourceFileModel::flags(QModelIndex const &index) const { auto actualFlags = QStandardItemModel::flags(index) & ~Qt::ItemIsDropEnabled & ~Qt::ItemIsDragEnabled; // If both appended files/additional parts and non-appended files // have been selected then those cannot be dragged & dropped at the // same time. if (m_nonAppendedSelected && (m_appendedSelected | m_additionalPartSelected)) return actualFlags; // Everyting else can be at least dragged. actualFlags |= Qt::ItemIsDragEnabled; auto indexSourceFile = fromIndex(index); // Appended files/additional parts can only be dropped onto // non-appended files (meaning on model indexes that are valid) – // but only on top level items (meaning the parent index is // invalid). if ((m_appendedSelected | m_additionalPartSelected) && index.isValid() && !index.parent().isValid()) actualFlags |= Qt::ItemIsDropEnabled; // Non-appended files can only be dropped onto the root note (whose // index isn't valid). else if (m_nonAppendedSelected && !index.isValid()) actualFlags |= Qt::ItemIsDropEnabled; return actualFlags; }
void SourceFileModel::updateSelectionStatus() { m_nonAppendedSelected = false; m_appendedSelected = false; m_additionalPartSelected = false; auto selectionModel = qobject_cast<QItemSelectionModel *>(QObject::sender()); Q_ASSERT(selectionModel); Util::withSelectedIndexes(selectionModel, [this](QModelIndex const &selectedIndex) { auto sourceFile = fromIndex(selectedIndex); Q_ASSERT(!!sourceFile); if (sourceFile->isRegular()) m_nonAppendedSelected = true; else if (sourceFile->isAppended()) m_appendedSelected = true; else if (sourceFile->isAdditionalPart()) m_additionalPartSelected = true; }); mxinfo(boost::format("file sel changed nonApp %1% app %2% addPart %3%\n") % m_nonAppendedSelected % m_appendedSelected % m_additionalPartSelected); }
void moveToString(int move, char s[]) { strcpy(s, getSquareFromIndex(fromIndex(move))); strcat(s, getSquareFromIndex(toIndex(move))); int type = moveType(move); if (type == simplePromotionQueen || type == capturePromotionQueen) { //promotion strcat(s, "q"); } }
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; }
std::pair<int, int> SourceFileModel::countAppendedAndAdditionalParts(QStandardItem *parentItem) { auto numbers = std::make_pair(0, 0); for (auto row = 0, numRows = parentItem->rowCount(); row < numRows; ++row) { auto sourceFile = fromIndex(parentItem->child(row)->index()); Q_ASSERT(!!sourceFile); if (sourceFile->isAdditionalPart()) ++numbers.first; else ++numbers.second; } return numbers; }
void SourceFileModel::appendFilesAndTracks(QModelIndex const &fileToAppendToIdx, QList<SourceFilePtr> const &files) { auto actualIdx = Util::toTopLevelIdx(fileToAppendToIdx); if (files.isEmpty() || !actualIdx.isValid()) return; auto fileToAppendTo = fromIndex(actualIdx); auto itemToAppendTo = itemFromIndex(actualIdx); Q_ASSERT(fileToAppendTo && itemToAppendTo); for (auto const &file : files) { file->m_appended = true; file->m_appendedTo = fileToAppendTo.get(); createAndAppendRow(itemToAppendTo, file); fileToAppendTo->m_appendedFiles << file; } for (auto const &file : files) m_tracksModel->appendTracks(fileToAppendTo.get(), file->m_tracks); }
void SourceFileModel::addAdditionalParts(QModelIndex const &fileToAddToIdx, QStringList const &fileNames) { auto actualIdx = Util::toTopLevelIdx(fileToAddToIdx); if (fileNames.isEmpty() || !actualIdx.isValid()) return; auto fileToAddTo = fromIndex(actualIdx); auto itemToAddTo = itemFromIndex(actualIdx); Q_ASSERT(fileToAddTo && itemToAddTo); auto actualFileNames = QStringList{}; std::copy_if(fileNames.begin(), fileNames.end(), std::back_inserter(actualFileNames), [&fileToAddTo](QString const &fileName) -> bool { if (fileToAddTo->m_fileName == fileName) return false; for (auto additionalPart : fileToAddTo->m_additionalParts) if (additionalPart->m_fileName == fileName) return false; return true; }); if (actualFileNames.isEmpty()) return; mtx::sort::naturally(actualFileNames.begin(), actualFileNames.end()); for (auto &fileName : actualFileNames) { auto additionalPart = std::make_shared<SourceFile>(fileName); additionalPart->m_additionalPart = true; additionalPart->m_appendedTo = fileToAddTo.get(); createAndAppendRow(itemToAddTo, additionalPart, fileToAddTo->m_additionalParts.size()); fileToAddTo->m_additionalParts << additionalPart; } }
MoveIterator GameBoard::possibleMoves () const noexcept { MoveIterator it; if (m_bigboard.getWon () != Color::NONE) return it; if (m_lastTurn != Square::SQUARE_NONE) { const Board& board = m_boards[toIndex (m_lastTurn)]; Board::playerset set = board.getFreeFields (); for (BoardIndex field = 0; set.any () && field < 9; field++, set >>= 1) { if (!set.test (0)) continue; Square fieldS = fromIndex (field); if (history.history[history.moves - 1].move.bigboard == fieldS) continue; it.moves[it.moveCount++] = { m_lastTurn, fieldS}; } } else { for(BoardIndex boardidx = 0; boardidx < 9; boardidx++)
void SourceFileModel::updateSelectionStatus() { m_nonAppendedSelected = false; m_appendedSelected = false; m_additionalPartSelected = false; auto selectionModel = qobject_cast<QItemSelectionModel *>(QObject::sender()); Q_ASSERT(selectionModel); Util::withSelectedIndexes(selectionModel, [this](QModelIndex const &selectedIndex) { auto sourceFile = fromIndex(selectedIndex); if (!sourceFile) return; if (sourceFile->isRegular()) m_nonAppendedSelected = true; else if (sourceFile->isAppended()) m_appendedSelected = true; else if (sourceFile->isAdditionalPart()) m_additionalPartSelected = true; }); }
void Move::getNotation(unsigned long move, char* buf) { int piece = pieceMoving(move); int from = fromIndex(move); int to = toIndex(move); int capturePiece = capture(move); int type = moveType(move); int bufSize = 0; // add the piece notation switch (piece) { case W_KING: { if (type == SHORT_CASTLE) { strcpy(buf, "0-0"); return; } if (type == LONG_CASTLE) { strcpy(buf, "0-0-0"); return; } buf[bufSize] = 'K'; bufSize++; break; } case B_KING: { if (type == SHORT_CASTLE) { strcpy(buf, "0-0"); return; } if (type == LONG_CASTLE) { strcpy(buf, "0-0-0"); return; } buf[bufSize] = 'K'; bufSize++; break; } case W_QUEEN: case B_QUEEN: buf[bufSize] = 'Q'; bufSize++; break; case W_ROOK: case B_ROOK: buf[bufSize] = 'R'; bufSize++; break; case W_BISHOP: case B_BISHOP: buf[bufSize] = 'B'; bufSize++; break; case W_KNIGHT: case B_KNIGHT: buf[bufSize] = 'N'; bufSize++; break; } char abcdefgh[] = "abcdefgh"; // the move is a capture if (capturePiece != 0) { if ((piece == W_PAWN) || (piece == B_PAWN)) { buf[bufSize] = abcdefgh[from % 16]; bufSize++; } buf[bufSize] = 'x'; bufSize++; } // find the row buf[bufSize] = abcdefgh[to % 16]; bufSize++; // add the rank buf[bufSize] = (to / 16 + 1) + 48; bufSize++; // add promotion switch (type) { case PROMOTION_QUEEN: strncpy(&buf[bufSize], "=Q", 2); bufSize += 2; break; case PROMOTION_ROOK: strncpy(&buf[bufSize], "=R", 2); bufSize += 2; break; case PROMOTION_BISHOP: strncpy(&buf[bufSize], "=B", 2); bufSize += 2; break; case PROMOTION_KNIGHT: strncpy(&buf[bufSize], "=N", 2); bufSize += 2; break; } buf[bufSize] = '\0'; }
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(); }