void TCellKeyframeSelection::copyCellsKeyframes() {
  TCellKeyframeData *data = new TCellKeyframeData();
  // Copy cells
  int r0, c0, r1, c1;
  m_cellSelection->getSelectedCells(r0, c0, r1, c1);
  if (!isEmpty()) {
    int colCount = c1 - c0 + 1;
    int rowCount = r1 - r0 + 1;
    if (colCount <= 0 || rowCount <= 0) return;
    TXsheet *xsh        = m_xsheetHandle->getXsheet();
    TCellData *cellData = new TCellData();
    cellData->setCells(xsh, r0, c0, r1, c1);
    data->setCellData(cellData);
  }
  // Copy keyframes
  if (!isEmpty()) {
    QClipboard *clipboard       = QApplication::clipboard();
    TXsheet *xsh                = m_xsheetHandle->getXsheet();
    TKeyframeData *keyframeData = new TKeyframeData();
    TKeyframeData::Position startPos(r0, c0);
    keyframeData->setKeyframes(m_keyframeSelection->getSelection(), xsh,
                               startPos);
    data->setKeyframeData(keyframeData);
  }
  // Set the cliboard
  QClipboard *clipboard = QApplication::clipboard();
  clipboard->setMimeData(data, QClipboard::Clipboard);
}
void TKeyframeSelection::pasteKeyframesWithShift(int r0, int r1, int c0,
                                                 int c1) {
  unselectLockedColumn();

  // Retrieve keyframes to paste
  QClipboard *clipboard = QApplication::clipboard();
  const TKeyframeData *data =
      dynamic_cast<const TKeyframeData *>(clipboard->mimeData());
  if (!data) {
    const TCellKeyframeData *cellKeyframeData =
        dynamic_cast<const TCellKeyframeData *>(clipboard->mimeData());
    if (cellKeyframeData) data = cellKeyframeData->getKeyframeData();
  }
  if (!data) return;

  // Retrieve corresponding old keyframes
  std::set<TKeyframeSelection::Position> positions(m_positions);
  data->getKeyframes(positions);

  TKeyframeData *oldData = new TKeyframeData();
  TXsheet *xsh           = TApp::instance()->getCurrentXsheet()->getXsheet();
  oldData->setKeyframes(positions, xsh);

  bool isShift = shiftKeyframesWithoutUndo(r0, r1, c0, c1, false);
  bool isPaste = pasteKeyframesWithoutUndo(data, &m_positions);
  if (!isPaste && !isShift) {
    delete oldData;
    return;
  }

  TKeyframeData *newData = new TKeyframeData();
  newData->setKeyframes(m_positions, xsh);
  TKeyframeSelection *selection = new TKeyframeSelection(m_positions);
  TUndoManager::manager()->add(
      new PasteKeyframesUndo(selection, newData, oldData, r0, r1, c0, c1));
  TApp::instance()->getCurrentScene()->setDirtyFlag(true);
  TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
}
void TKeyframeSelection::deleteKeyframesWithShift(int r0, int r1, int c0,
                                                  int c1) {
  unselectLockedColumn();

  TKeyframeData *data = new TKeyframeData();
  TXsheet *xsh        = TApp::instance()->getCurrentXsheet()->getXsheet();
  data->setKeyframes(m_positions, xsh);
  if (m_positions.empty()) {
    delete data;
    return;
  }
  TKeyframeSelection *selection = new TKeyframeSelection(m_positions);
  bool deleteKeyFrame           = deleteKeyframesWithoutUndo(&m_positions);
  bool isShift = shiftKeyframesWithoutUndo(r0, r1, c0, c1, true);
  if (!deleteKeyFrame && !isShift) {
    delete selection;
    delete data;
    return;
  }
  TUndoManager::manager()->add(
      new DeleteKeyframesUndo(selection, data, r0, r1, c0, c1));
  TApp::instance()->getCurrentScene()->setDirtyFlag(true);
  TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
}