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);
}
Exemple #4
0
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;
  }
}
Exemple #9
0
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();
}