Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tools/strokeselection.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzTools includes
Toshihiro Shimizu 890ddd
#include "tools/imagegrouping.h"
Toshihiro Shimizu 890ddd
#include "tools/toolhandle.h"
Toshihiro Shimizu 890ddd
#include "tools/tool.h"
Toshihiro Shimizu 890ddd
#include "tools/toolutils.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzQt includes
Toshihiro Shimizu 890ddd
#include "toonzqt/selectioncommandids.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/imageutils.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/tselectionhandle.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/strokesdata.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/rasterimagedata.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/dvdialog.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/tpalettehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/palettecontroller.h"
Toshihiro Shimizu 890ddd
#include "toonz/tobjecthandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tscenehandle.h"
Martin van Zijl 712163
#include "toonz/txsheethandle.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/tcenterlinevectorizer.h"
Toshihiro Shimizu 890ddd
#include "toonz/stage.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobject.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzscene.h"
Toshihiro Shimizu 890ddd
#include "toonz/sceneproperties.h"
manongjohn 6939a3
#include "toonz/tframehandle.h"
manongjohn 6939a3
#include "toonz/txsheethandle.h"
manongjohn 6939a3
#include "toonz/tstageobject.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tthreadmessage.h"
Toshihiro Shimizu 890ddd
#include "tundo.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "tcolorstyles.h"
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qapplication></qapplication>
Toshihiro Shimizu 890ddd
#include <qclipboard></qclipboard>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void vectorizeToonzImageData(const TVectorImageP &image,
Shinya Kitaoka 120a6e
                             const ToonzImageData *tiData,
Shinya Kitaoka 120a6e
                             std::set<int> &indexes, TPalette *palette,</int>
Shinya Kitaoka 120a6e
                             const VectorizerConfiguration &config) {
Shinya Kitaoka 120a6e
  if (!tiData) return;
Shinya Kitaoka 120a6e
  QApplication::setOverrideCursor(Qt::WaitCursor);
Shinya Kitaoka 120a6e
  TRasterP ras;
Shinya Kitaoka 120a6e
  std::vector<trectd> rects;</trectd>
Shinya Kitaoka 120a6e
  std::vector<tstroke> strokes;</tstroke>
Shinya Kitaoka 120a6e
  std::vector<tstroke> originalStrokes;</tstroke>
Shinya Kitaoka 120a6e
  TAffine affine;
Shinya Kitaoka 120a6e
  double dpiX, dpiY;
Shinya Kitaoka 120a6e
  tiData->getData(ras, dpiX, dpiY, rects, strokes, originalStrokes, affine,
Shinya Kitaoka 120a6e
                  image->getPalette());
Shinya Kitaoka 120a6e
  TRasterCM32P rasCM = ras;
Shinya Kitaoka 120a6e
  TToonzImageP ti(rasCM, rasCM->getBounds());
Shinya Kitaoka 120a6e
  VectorizerCore vc;
Shinya Kitaoka 120a6e
  TVectorImageP vi = vc.vectorize(ti, config, palette);
Shinya Kitaoka 120a6e
  assert(vi);
Shinya Kitaoka 120a6e
  vi->setPalette(palette);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TScale sc(dpiX / Stage::inch, dpiY / Stage::inch);
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  TRectD selectionBounds;
Shinya Kitaoka 120a6e
  for (i = 0; i < (int)rects.size(); i++) selectionBounds += rects[i];
Shinya Kitaoka 120a6e
  for (i = 0; i < (int)strokes.size(); i++)
Shinya Kitaoka 120a6e
    selectionBounds += strokes[i].getBBox();
Shinya Kitaoka 120a6e
  TTranslation tr(selectionBounds.getP00());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < (int)vi->getStrokeCount(); i++) {
Shinya Kitaoka 120a6e
    TStroke *stroke = vi->getStroke(i);
Shinya Kitaoka 120a6e
    stroke->transform(sc.inv() * affine * tr, true);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UINT oldImageSize = image->getStrokeCount();
Shinya Kitaoka 120a6e
  image->mergeImage(vi, TAffine());
Shinya Kitaoka 120a6e
  UINT newImageSize = image->getStrokeCount();
Shinya Kitaoka 120a6e
  indexes.clear();
Shinya Kitaoka 120a6e
  for (UINT sI = oldImageSize; sI < newImageSize; sI++) indexes.insert(sI);
Shinya Kitaoka 120a6e
  QApplication::restoreOverrideCursor();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void copyStrokesWithoutUndo(TVectorImageP image, std::set<int> &indexes) {</int>
Shinya Kitaoka 120a6e
  QClipboard *clipboard = QApplication::clipboard();
Shinya Kitaoka 120a6e
  StrokesData *data     = new StrokesData();
Shinya Kitaoka 120a6e
  data->setImage(image, indexes);
Shinya Kitaoka 120a6e
  clipboard->setMimeData(data, QClipboard::Clipboard);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool pasteStrokesWithoutUndo(TVectorImageP image, std::set<int> &outIndexes,</int>
Shinya Kitaoka 120a6e
                             TSceneHandle *sceneHandle, bool insert = true) {
Shinya Kitaoka 120a6e
  QMutexLocker lock(image->getMutex());
Shinya Kitaoka 120a6e
  QClipboard *clipboard = QApplication::clipboard();
Shinya Kitaoka 120a6e
  const StrokesData *stData =
Shinya Kitaoka 120a6e
      dynamic_cast<const *="" strokesdata="">(clipboard->mimeData());</const>
Shinya Kitaoka 120a6e
  const ToonzImageData *tiData =
Shinya Kitaoka 120a6e
      dynamic_cast<const *="" toonzimagedata="">(clipboard->mimeData());</const>
Shinya Kitaoka 120a6e
  const FullColorImageData *fciData =
Shinya Kitaoka 120a6e
      dynamic_cast<const *="" fullcolorimagedata="">(clipboard->mimeData());</const>
Shinya Kitaoka 120a6e
  std::set<int> indexes = outIndexes;</int>
Shinya Kitaoka 120a6e
  if (stData)
Shinya Kitaoka 120a6e
    stData->getImage(image, indexes, insert);
Shinya Kitaoka 120a6e
  else if (tiData) {
Shinya Kitaoka 120a6e
    ToonzScene *scene = sceneHandle->getScene();
Shinya Kitaoka 120a6e
    assert(scene);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    const VectorizerParameters *vParams =
Shinya Kitaoka 120a6e
        scene->getProperties()->getVectorizerParameters();
Shinya Kitaoka 120a6e
    assert(vParams);
Shinya Kitaoka 120a6e
Shinya Kitaoka 2a7129
    std::unique_ptr<vectorizerconfiguration> config(</vectorizerconfiguration>
Shinya Kitaoka 120a6e
        vParams->getCurrentConfiguration(0.0));
Shinya Kitaoka 120a6e
    vectorizeToonzImageData(image, tiData, indexes, image->getPalette(),
Shinya Kitaoka 120a6e
                            *config);
Shinya Kitaoka 120a6e
  } else if (fciData) {
Shinya Kitaoka 120a6e
    DVGui::error(QObject::tr(
Shinya Kitaoka 120a6e
        "The copied selection cannot be pasted in the current drawing."));
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  StrokeSelection *selection = dynamic_cast<strokeselection *="">(</strokeselection>
Shinya Kitaoka 120a6e
      TTool::getApplication()->getCurrentSelection()->getSelection());
Shinya Kitaoka 120a6e
  if (selection) selection->notifyView();
Shinya Kitaoka 120a6e
  outIndexes = indexes;  // outIndexes is a reference  to current  selection, so
Shinya Kitaoka 120a6e
                         // the notifyImageChanged could reset it!
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void deleteStrokesWithoutUndo(TVectorImageP image, std::set<int> &indexes) {</int>
Shinya Kitaoka 120a6e
  QMutexLocker lock(image->getMutex());
Shinya Kitaoka 120a6e
  std::vector<int> indexesV(indexes.begin(), indexes.end());</int>
Shinya Kitaoka 120a6e
  TRectD bbox;
Shinya Kitaoka 120a6e
  UINT i = 0;
Shinya Kitaoka 120a6e
  for (; i < indexesV.size(); i++)
Shinya Kitaoka 120a6e
    bbox += image->getStroke(indexesV[i])->getBBox();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<tfilledregioninf> regions;</tfilledregioninf>
Shinya Kitaoka 120a6e
  ImageUtils::getFillingInformationOverlappingArea(image, regions, bbox);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TVectorImageP other = image->splitImage(indexesV, true);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  indexes.clear();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
Shinya Kitaoka 120a6e
  StrokeSelection *selection = dynamic_cast<strokeselection *="">(</strokeselection>
Shinya Kitaoka 120a6e
      TTool::getApplication()->getCurrentSelection()->getSelection());
Shinya Kitaoka 120a6e
  if (selection) selection->notifyView();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void cutStrokesWithoutUndo(TVectorImageP image, std::set<int> &indexes) {</int>
Shinya Kitaoka 120a6e
  copyStrokesWithoutUndo(image, indexes);
Shinya Kitaoka 120a6e
  deleteStrokesWithoutUndo(image, indexes);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// CopyStrokesUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class CopyStrokesUndo final : public TUndo {
Shinya Kitaoka 120a6e
  QMimeData *m_oldData;
Shinya Kitaoka 120a6e
  QMimeData *m_newData;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  CopyStrokesUndo(QMimeData *oldData, QMimeData *newData)
Shinya Kitaoka 120a6e
      : m_oldData(oldData), m_newData(newData) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    QClipboard *clipboard = QApplication::clipboard();
Shinya Kitaoka 120a6e
    clipboard->setMimeData(cloneData(m_oldData), QClipboard::Clipboard);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    QClipboard *clipboard = QApplication::clipboard();
Shinya Kitaoka 120a6e
    clipboard->setMimeData(cloneData(m_newData), QClipboard::Clipboard);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override { return sizeof(*this); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// PasteStrokesUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Martin van Zijl 712163
class PasteStrokesUndo final : public ToolUtils::TToolUndo {
Shinya Kitaoka 120a6e
  std::set<int> m_indexes;</int>
Shinya Kitaoka 120a6e
  QMimeData *m_oldData;
Shinya Kitaoka 120a6e
  TSceneHandle *m_sceneHandle;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  PasteStrokesUndo(TXshSimpleLevel *level, const TFrameId &frameId,
Shinya Kitaoka 120a6e
                   std::set<int> &indexes, TPaletteP oldPalette,</int>
Martin van Zijl 712163
                   TSceneHandle *sceneHandle, bool createdFrame,
Martin van Zijl 712163
                   bool createdLevel)
Martin van Zijl 712163
      : TToolUndo(level, frameId, createdFrame, createdLevel, oldPalette)
Shinya Kitaoka 120a6e
      , m_indexes(indexes)
Shinya Kitaoka 120a6e
      , m_sceneHandle(sceneHandle) {
Shinya Kitaoka 120a6e
    QClipboard *clipboard = QApplication::clipboard();
Shinya Kitaoka 120a6e
    m_oldData             = cloneData(clipboard->mimeData());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~PasteStrokesUndo() { delete m_oldData; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Se la selezione corrente e' la stroke selection devo svuotarla,
Shinya Kitaoka 120a6e
    // altrimenti puo' rimanere selezionato uno stroke che non esiste piu'.
Shinya Kitaoka 120a6e
    StrokeSelection *selection = dynamic_cast<strokeselection *="">(</strokeselection>
Shinya Kitaoka 120a6e
        TTool::getApplication()->getCurrentSelection()->getSelection());
Shinya Kitaoka 120a6e
    if (selection) selection->selectNone();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::set<int> indexes = m_indexes;</int>
Shinya Kitaoka 120a6e
    deleteStrokesWithoutUndo(image, indexes);
Martin van Zijl 712163
Martin van Zijl 712163
    removeLevelAndFrameIfNeeded();
Martin van Zijl 712163
Martin van Zijl 712163
    TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
Martin van Zijl 712163
    notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Martin van Zijl 712163
    insertLevelAndFrameIfNeeded();
Martin van Zijl 712163
Shinya Kitaoka 120a6e
    TVectorImageP image   = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    std::set<int> indexes = m_indexes;</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    QClipboard *clipboard = QApplication::clipboard();
Shinya Kitaoka 120a6e
    QMimeData *data       = cloneData(clipboard->mimeData());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    clipboard->setMimeData(cloneData(m_oldData), QClipboard::Clipboard);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    pasteStrokesWithoutUndo(image, indexes, m_sceneHandle);
Shinya Kitaoka 120a6e
    TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    clipboard->setMimeData(data, QClipboard::Clipboard);
Martin van Zijl 712163
Martin van Zijl 712163
    TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
Martin van Zijl 712163
    notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override { return sizeof(*this); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class RemoveEndpointsUndo final : public TUndo {
Shinya Kitaoka 120a6e
  TXshSimpleLevelP m_level;
Shinya Kitaoka 120a6e
  TFrameId m_frameId;
Shinya Kitaoka 120a6e
  std::vector<std::pair<int, *="" tstroke="">> m_strokes;</std::pair<int,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  RemoveEndpointsUndo(TXshSimpleLevel *level, const TFrameId &frameId,
Shinya Kitaoka 120a6e
                      std::vector<std::pair<int, *="" tstroke="">> strokes)</std::pair<int,>
Shinya Kitaoka 120a6e
      : m_level(level)
Shinya Kitaoka 120a6e
      , m_frameId(frameId)
Shinya Kitaoka 120a6e
      , m_strokes(strokes)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~RemoveEndpointsUndo() {
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 0; i < (int)m_strokes.size(); i++) delete m_strokes[i].second;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    TVectorImageP vi = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 0; i < (int)m_strokes.size(); i++) {
Shinya Kitaoka 120a6e
      TStroke *newS = new TStroke(*(m_strokes[i].second));
Shinya Kitaoka 120a6e
      newS->setId(m_strokes[i].second->getId());
Shinya Kitaoka 120a6e
      vi->restoreEndpoints(m_strokes[i].first, newS);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    StrokeSelection *selection = dynamic_cast<strokeselection *="">(</strokeselection>
Shinya Kitaoka 120a6e
        TTool::getApplication()->getCurrentSelection()->getSelection());
Shinya Kitaoka 120a6e
    if (selection) selection->selectNone();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    TVectorImageP vi = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    for (i = 0; i < (int)m_strokes.size(); i++) {
Shinya Kitaoka 120a6e
      TStroke *s = vi->removeEndpoints(m_strokes[i].first);
Shinya Kitaoka 120a6e
      delete s;
Shinya Kitaoka 120a6e
      // assert(s==m_strokes[i].second);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override { return sizeof(*this); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// DeleteFramesUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class DeleteStrokesUndo : public TUndo {
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  TXshSimpleLevelP m_level;
Shinya Kitaoka 120a6e
  TFrameId m_frameId;
Shinya Kitaoka 120a6e
  std::set<int> m_indexes;</int>
Shinya Kitaoka 120a6e
  QMimeData *m_data;
Shinya Kitaoka 120a6e
  TSceneHandle *m_sceneHandle;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  DeleteStrokesUndo(TXshSimpleLevel *level, const TFrameId &frameId,
Shinya Kitaoka 120a6e
                    std::set<int> indexes, QMimeData *data,</int>
Shinya Kitaoka 120a6e
                    TSceneHandle *sceneHandle)
Shinya Kitaoka 120a6e
      : m_level(level)
Shinya Kitaoka 120a6e
      , m_frameId(frameId)
Shinya Kitaoka 120a6e
      , m_indexes(indexes)
Shinya Kitaoka 120a6e
      , m_data(data)
Shinya Kitaoka 120a6e
      , m_sceneHandle(sceneHandle) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~DeleteStrokesUndo() { delete m_data; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    QClipboard *clipboard = QApplication::clipboard();
Shinya Kitaoka 120a6e
    QMimeData *oldData    = cloneData(clipboard->mimeData());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    clipboard->setMimeData(cloneData(m_data), QClipboard::Clipboard);
Shinya Kitaoka 120a6e
    std::set<int> indexes = m_indexes;</int>
Shinya Kitaoka 120a6e
    TVectorImageP image   = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    pasteStrokesWithoutUndo(image, indexes, m_sceneHandle, false);
Shinya Kitaoka 120a6e
    TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    clipboard->setMimeData(oldData, QClipboard::Clipboard);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    TVectorImageP image   = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    std::set<int> indexes = m_indexes;</int>
Shinya Kitaoka 120a6e
    deleteStrokesWithoutUndo(image, indexes);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override { return sizeof(*this); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// CutStrokesUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class CutStrokesUndo final : public DeleteStrokesUndo {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  CutStrokesUndo(TXshSimpleLevel *level, const TFrameId &frameId,
Shinya Kitaoka 120a6e
                 std::set<int> indexes, QMimeData *data,</int>
Shinya Kitaoka 120a6e
                 TSceneHandle *sceneHandle)
Shinya Kitaoka 120a6e
      : DeleteStrokesUndo(level, frameId, indexes, data, sceneHandle) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~CutStrokesUndo() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    TVectorImageP image   = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    std::set<int> indexes = m_indexes;</int>
Shinya Kitaoka 120a6e
    cutStrokesWithoutUndo(image, indexes);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// StrokeSelection ctor/dtor
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
StrokeSelection::StrokeSelection()
Shinya Kitaoka 120a6e
    : m_groupCommand(new TGroupCommand())
Shinya Kitaoka 120a6e
    , m_sceneHandle()
Shinya Kitaoka 120a6e
    , m_updateSelectionBBox(false) {
Shinya Kitaoka 120a6e
  m_groupCommand->setSelection(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
StrokeSelection::~StrokeSelection() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
StrokeSelection::StrokeSelection(const StrokeSelection &other)
Shinya Kitaoka 120a6e
    : m_vi(other.m_vi)
Shinya Kitaoka 120a6e
    , m_indexes(other.m_indexes)
Shinya Kitaoka 120a6e
    , m_groupCommand(new TGroupCommand())
Shinya Kitaoka 120a6e
    , m_sceneHandle(other.m_sceneHandle)
Shinya Kitaoka 120a6e
    , m_updateSelectionBBox(other.m_updateSelectionBBox) {
Shinya Kitaoka 120a6e
  m_groupCommand->setSelection(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
StrokeSelection &StrokeSelection::operator=(const StrokeSelection &other) {
Shinya Kitaoka 120a6e
  m_vi                  = other.m_vi;
Shinya Kitaoka 120a6e
  m_indexes             = other.m_indexes;
Shinya Kitaoka 120a6e
  m_sceneHandle         = other.m_sceneHandle;
Shinya Kitaoka 120a6e
  m_updateSelectionBBox = other.m_updateSelectionBBox;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void StrokeSelection::select(int index, bool on) {
Shinya Kitaoka 120a6e
  if (on)
Shinya Kitaoka 120a6e
    m_indexes.insert(index);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_indexes.erase(index);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void StrokeSelection::toggle(int index) {
Shinya Kitaoka 120a6e
  std::set<int>::iterator it = m_indexes.find(index);</int>
Shinya Kitaoka 120a6e
  if (it == m_indexes.end())
Shinya Kitaoka 120a6e
    m_indexes.insert(index);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_indexes.erase(it);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// removeEndpoints
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void StrokeSelection::removeEndpoints() {
Shinya Kitaoka 120a6e
  if (!m_vi) return;
Shinya Kitaoka 120a6e
  if (m_indexes.empty()) return;
Shinya Kitaoka 120a6e
manongjohn 6939a3
  if (!isEditable()) {
manongjohn 6939a3
    DVGui::error(
manongjohn 6939a3
        QObject::tr("The selection cannot be updated. It is not editable."));
manongjohn 6939a3
    return;
manongjohn 6939a3
  }
manongjohn 6939a3
Shinya Kitaoka 120a6e
  std::vector<std::pair<int, *="" tstroke="">> undoData;</std::pair<int,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_vi->findRegions();
otakuto 158f9f
  for (auto const &e : m_indexes) {
otakuto 158f9f
    TStroke *s = m_vi->removeEndpoints(e);
otakuto 158f9f
    if (s) undoData.push_back(std::pair<int, *="" tstroke="">(e, s));</int,>
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Shinya Kitaoka 120a6e
  TXshSimpleLevel *level =
Shinya Kitaoka 120a6e
      TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
Shinya Kitaoka 120a6e
  if (!undoData.empty())
Shinya Kitaoka 120a6e
    TUndoManager::manager()->add(
Shinya Kitaoka 120a6e
        new RemoveEndpointsUndo(level, tool->getCurrentFid(), undoData));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_updateSelectionBBox = true;
Shinya Kitaoka 120a6e
  tool->notifyImageChanged();
Shinya Kitaoka 120a6e
  m_updateSelectionBBox = false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Martin van Zijl d1006d
//=============================================================================
Martin van Zijl d1006d
//
Martin van Zijl d1006d
// selectAll
Martin van Zijl d1006d
//
Martin van Zijl d1006d
//-----------------------------------------------------------------------------
Martin van Zijl d1006d
Martin van Zijl d1006d
void StrokeSelection::selectAll() {
Martin van Zijl d1006d
  if (!m_vi) return;
Martin van Zijl d1006d
Martin van Zijl d1006d
  int sCount = int(m_vi->getStrokeCount());
Martin van Zijl d1006d
Martin van Zijl d1006d
  for (int s = 0; s < sCount; ++s) {
manongjohn 6939a3
    m_indexes.insert(s);
Martin van Zijl d1006d
  }
Martin van Zijl d1006d
Martin van Zijl d1006d
  StrokeSelection *selection = dynamic_cast<strokeselection *="">(</strokeselection>
Martin van Zijl d1006d
      TTool::getApplication()->getCurrentSelection()->getSelection());
Martin van Zijl d1006d
  if (selection) selection->notifyView();
Martin van Zijl d1006d
}
Martin van Zijl d1006d
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// deleteStrokes
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void StrokeSelection::deleteStrokes() {
Shinya Kitaoka 120a6e
  if (!m_vi) return;
Shinya Kitaoka 120a6e
  if (m_indexes.empty()) return;
Shinya Kitaoka 120a6e
  TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Shinya Kitaoka 120a6e
  if (!tool) return;
Shinya Kitaoka 120a6e
manongjohn 6939a3
  if (!isEditable()) {
manongjohn 6939a3
    DVGui::error(
manongjohn 6939a3
        QObject::tr("The selection cannot be deleted. It is not editable."));
manongjohn 6939a3
    return;
manongjohn 6939a3
  }
manongjohn 6939a3
Shinya Kitaoka 120a6e
  bool isSpline = tool->getApplication()->getCurrentObject()->isSpline();
Shinya Kitaoka 120a6e
  TUndo *undo;
Shinya Kitaoka 120a6e
  if (isSpline)
Shinya Kitaoka 120a6e
    undo = new ToolUtils::UndoPath(
Shinya Kitaoka 120a6e
        tool->getXsheet()->getStageObject(tool->getObjectId())->getSpline());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  StrokesData *data = new StrokesData();
Shinya Kitaoka 120a6e
  data->setImage(m_vi, m_indexes);
Shinya Kitaoka 120a6e
  std::set<int> oldIndexes = m_indexes;</int>
Shinya Kitaoka 120a6e
  deleteStrokesWithoutUndo(m_vi, m_indexes);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!isSpline) {
Shinya Kitaoka 120a6e
    TXshSimpleLevel *level =
Shinya Kitaoka 120a6e
        TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
Shinya Kitaoka 120a6e
    TUndoManager::manager()->add(new DeleteStrokesUndo(
Shinya Kitaoka 120a6e
        level, tool->getCurrentFid(), oldIndexes, data, m_sceneHandle));
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    assert(undo);
Shinya Kitaoka 120a6e
    if (undo) TUndoManager::manager()->add(undo);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// StrokeSelection::copy()
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void StrokeSelection::copy() {
Shinya Kitaoka 120a6e
  if (m_indexes.empty()) return;
Shinya Kitaoka 120a6e
  QClipboard *clipboard = QApplication::clipboard();
Shinya Kitaoka 120a6e
  QMimeData *oldData    = cloneData(clipboard->mimeData());
Shinya Kitaoka 120a6e
  copyStrokesWithoutUndo(m_vi, m_indexes);
Shinya Kitaoka 120a6e
  QMimeData *newData = cloneData(clipboard->mimeData());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // TUndoManager::manager()->add(new CopyStrokesUndo(oldData, newData));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// StrokeSelection::paste()
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void StrokeSelection::paste() {
Shinya Kitaoka 120a6e
  TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Shinya Kitaoka 120a6e
  if (!tool) return;
manongjohn 6939a3
  if (!isEditable()) {
manongjohn 6939a3
    DVGui::error(
manongjohn 6939a3
        QObject::tr("The selection cannot be pasted. It is not editable."));
manongjohn 6939a3
    return;
manongjohn 6939a3
  }
manongjohn 6939a3
Shinya Kitaoka 120a6e
  if (TTool::getApplication()->getCurrentObject()->isSpline()) {
Shinya Kitaoka 120a6e
    const StrokesData *stData = dynamic_cast<const *="" strokesdata="">(</const>
Shinya Kitaoka 120a6e
        QApplication::clipboard()->mimeData());
Shinya Kitaoka 120a6e
    if (!stData) return;
Shinya Kitaoka 120a6e
    TVectorImageP splineImg = tool->getImage(true);
Shinya Kitaoka 120a6e
    TVectorImageP img       = stData->m_image;
Shinya Kitaoka 120a6e
    if (!splineImg || !img) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    QMutexLocker lock(splineImg->getMutex());
Shinya Kitaoka 120a6e
    TUndo *undo = new ToolUtils::UndoPath(
Shinya Kitaoka 120a6e
        tool->getXsheet()->getStageObject(tool->getObjectId())->getSpline());
Shinya Kitaoka 120a6e
    while (splineImg->getStrokeCount() > 0) splineImg->deleteStroke(0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TStroke *stroke = img->getStroke(0);
Shinya Kitaoka 120a6e
    splineImg->addStroke(new TStroke(*stroke), false);
Shinya Kitaoka 120a6e
    TUndoManager::manager()->add(undo);
Shinya Kitaoka 120a6e
    tool->notifyImageChanged();
Shinya Kitaoka 120a6e
    tool->invalidate();
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TVectorImageP tarImg = tool->touchImage();
Shinya Kitaoka 120a6e
  if (!tarImg) return;
Shinya Kitaoka 120a6e
  TPaletteP palette       = tarImg->getPalette();
Shinya Kitaoka 120a6e
  TPaletteP oldPalette    = new TPalette();
Shinya Kitaoka 120a6e
  if (palette) oldPalette = palette->clone();
Shinya Kitaoka 120a6e
  bool isPaste = pasteStrokesWithoutUndo(tarImg, m_indexes, m_sceneHandle);
Shinya Kitaoka 120a6e
  if (isPaste) {
Shinya Kitaoka 120a6e
    TXshSimpleLevel *level =
Shinya Kitaoka 120a6e
        TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
Shinya Kitaoka 120a6e
    TUndoManager::manager()->add(new PasteStrokesUndo(
Martin van Zijl 712163
        level, tool->getCurrentFid(), m_indexes, oldPalette, m_sceneHandle,
Martin van Zijl 712163
        tool->m_isFrameCreated, tool->m_isLevelCreated));
Shinya Kitaoka 120a6e
    m_updateSelectionBBox = isPaste;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  tool->notifyImageChanged();
Shinya Kitaoka 120a6e
  tool->getApplication()
Shinya Kitaoka 120a6e
      ->getPaletteController()
Shinya Kitaoka 120a6e
      ->getCurrentLevelPalette()
Shinya Kitaoka 120a6e
      ->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  m_updateSelectionBBox = false;
Shinya Kitaoka 120a6e
  tool->invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// StrokeSelection::cut()
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void StrokeSelection::cut() {
Shinya Kitaoka 120a6e
  if (m_indexes.empty()) return;
Shinya Kitaoka 120a6e
  TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Shinya Kitaoka 120a6e
  if (!tool) return;
Shinya Kitaoka 120a6e
manongjohn 6939a3
  if (!isEditable()) {
manongjohn 6939a3
    DVGui::error(
manongjohn 6939a3
        QObject::tr("The selection cannot be deleted. It is not editable."));
manongjohn 6939a3
    return;
manongjohn 6939a3
  }
manongjohn 6939a3
Shinya Kitaoka 120a6e
  bool isSpline = tool->getApplication()->getCurrentObject()->isSpline();
Shinya Kitaoka 120a6e
  TUndo *undo;
Shinya Kitaoka 120a6e
  if (isSpline)
Shinya Kitaoka 120a6e
    undo = new ToolUtils::UndoPath(
Shinya Kitaoka 120a6e
        tool->getXsheet()->getStageObject(tool->getObjectId())->getSpline());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  StrokesData *data = new StrokesData();
Shinya Kitaoka 120a6e
  data->setImage(m_vi, m_indexes);
Shinya Kitaoka 120a6e
  std::set<int> oldIndexes = m_indexes;</int>
Shinya Kitaoka 120a6e
  cutStrokesWithoutUndo(m_vi, m_indexes);
Shinya Kitaoka 120a6e
  if (!isSpline) {
Shinya Kitaoka 120a6e
    TXshSimpleLevel *level =
Shinya Kitaoka 120a6e
        tool->getApplication()->getCurrentLevel()->getSimpleLevel();
Shinya Kitaoka 120a6e
    TUndoManager::manager()->add(new CutStrokesUndo(
Shinya Kitaoka 120a6e
        level, tool->getCurrentFid(), oldIndexes, data, m_sceneHandle));
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    assert(undo);
Shinya Kitaoka 120a6e
    if (undo) TUndoManager::manager()->add(undo);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// enableCommands
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void StrokeSelection::enableCommands() {
Shinya Kitaoka 120a6e
  enableCommand(this, MI_Clear, &StrokeSelection::deleteStrokes);
Shinya Kitaoka 120a6e
  enableCommand(this, MI_Cut, &StrokeSelection::cut);
Shinya Kitaoka 120a6e
  enableCommand(this, MI_Copy, &StrokeSelection::copy);
Shinya Kitaoka 120a6e
  enableCommand(this, MI_Paste, &StrokeSelection::paste);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  enableCommand(m_groupCommand.get(), MI_Group, &TGroupCommand::group);
Shinya Kitaoka 120a6e
  enableCommand(m_groupCommand.get(), MI_Ungroup, &TGroupCommand::ungroup);
Shinya Kitaoka 120a6e
  enableCommand(m_groupCommand.get(), MI_BringToFront, &TGroupCommand::front);
Shinya Kitaoka 120a6e
  enableCommand(m_groupCommand.get(), MI_BringForward, &TGroupCommand::forward);
Shinya Kitaoka 120a6e
  enableCommand(m_groupCommand.get(), MI_SendBack, &TGroupCommand::back);
Shinya Kitaoka 120a6e
  enableCommand(m_groupCommand.get(), MI_SendBackward,
Shinya Kitaoka 120a6e
                &TGroupCommand::backward);
Shinya Kitaoka 120a6e
  enableCommand(m_groupCommand.get(), MI_EnterGroup,
Shinya Kitaoka 120a6e
                &TGroupCommand::enterGroup);
Shinya Kitaoka 120a6e
  enableCommand(m_groupCommand.get(), MI_ExitGroup, &TGroupCommand::exitGroup);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  enableCommand(this, MI_RemoveEndpoints, &StrokeSelection::removeEndpoints);
Martin van Zijl d1006d
  enableCommand(this, MI_SelectAll, &StrokeSelection::selectAll);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class UndoSetStrokeStyle final : public TUndo {
Shinya Kitaoka 120a6e
  TVectorImageP m_image;
Shinya Kitaoka 120a6e
  std::vector<int> m_strokeIndexes;</int>
Shinya Kitaoka 120a6e
  std::vector<int> m_oldStyles;</int>
Shinya Kitaoka 120a6e
  int m_newStyle;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  UndoSetStrokeStyle(TVectorImageP image, int newStyle)
Shinya Kitaoka 120a6e
      : m_image(image), m_newStyle(newStyle) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void addStroke(TStroke *stroke) {
Shinya Kitaoka 120a6e
    m_strokeIndexes.push_back(m_image->getStrokeIndex(stroke));
Shinya Kitaoka 120a6e
    m_oldStyles.push_back(stroke->getStyle());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    UINT size = m_strokeIndexes.size();
Shinya Kitaoka 120a6e
    assert(size == m_oldStyles.size());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (UINT i = 0; i != size; i++) {
Shinya Kitaoka 120a6e
      int index = m_strokeIndexes[i];
Shinya Kitaoka 120a6e
      if (index != -1 && index < (int)m_image->getStrokeCount())
Shinya Kitaoka 120a6e
        m_image->getStroke(index)->setStyle(m_oldStyles[i]);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    UINT size = m_strokeIndexes.size();
Shinya Kitaoka 120a6e
    assert(size == m_oldStyles.size());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (UINT i = 0; i != size; i++) {
Shinya Kitaoka 120a6e
      int index = m_strokeIndexes[i];
Shinya Kitaoka 120a6e
      if (index != -1 && index < (int)m_image->getStrokeCount())
Shinya Kitaoka 120a6e
        m_image->getStroke(index)->setStyle(m_newStyle);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override {
Shinya Kitaoka 120a6e
    return sizeof(*this) +
Shinya Kitaoka 120a6e
           m_strokeIndexes.capacity() * sizeof(m_strokeIndexes[0]) +
Shinya Kitaoka 120a6e
           m_oldStyles.capacity() * sizeof(m_oldStyles[0]);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// changeColorStyle
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void StrokeSelection::changeColorStyle(int styleIndex) {
Shinya Kitaoka 120a6e
  TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Shinya Kitaoka 120a6e
  if (!tool) return;
Shinya Kitaoka 120a6e
  TVectorImageP img(tool->getImage(true));
Shinya Kitaoka 120a6e
  if (!img) return;
Shinya Kitaoka 120a6e
  TPalette *palette = img->getPalette();
Shinya Kitaoka 120a6e
  TColorStyle *cs   = palette->getStyle(styleIndex);
Shinya Kitaoka 120a6e
  if (!cs->isStrokeStyle()) return;
Shinya Kitaoka 120a6e
  if (m_indexes.empty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UndoSetStrokeStyle *undo = new UndoSetStrokeStyle(img, styleIndex);
Shinya Kitaoka 120a6e
  std::set<int>::iterator it;</int>
Shinya Kitaoka 120a6e
  for (it = m_indexes.begin(); it != m_indexes.end(); ++it) {
Shinya Kitaoka 120a6e
    int index = *it;
Shinya Kitaoka 120a6e
    assert(0 <= index && index < (int)img->getStrokeCount());
Shinya Kitaoka 120a6e
    TStroke *stroke = img->getStroke(index);
Shinya Kitaoka 120a6e
    undo->addStroke(stroke);
Shinya Kitaoka 120a6e
    stroke->setStyle(styleIndex);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  tool->notifyImageChanged();
Shinya Kitaoka 120a6e
  TUndoManager::manager()->add(undo);
Toshihiro Shimizu 890ddd
}
manongjohn 6939a3
manongjohn 6939a3
//-----------------------------------------------------------------------------
manongjohn 6939a3
manongjohn 6939a3
bool StrokeSelection::isEditable() {
manongjohn 6939a3
  TTool::Application *app = TTool::getApplication();
manongjohn 6939a3
  TXshSimpleLevel *level  = app->getCurrentLevel()->getSimpleLevel();
manongjohn 6939a3
manongjohn 6939a3
  TFrameHandle *frame = app->getCurrentFrame();
manongjohn 6939a3
  bool filmstrip      = frame->isEditingLevel();
manongjohn 6939a3
manongjohn 6939a3
  if (level) {
manongjohn 6939a3
    if (level->isReadOnly()) return false;
manongjohn 6939a3
manongjohn 6939a3
    TFrameId frameId = app->getCurrentTool()->getTool()->getCurrentFid();
manongjohn 6939a3
    if (level->isFrameReadOnly(frameId)) return false;
manongjohn 6939a3
  }
manongjohn 6939a3
manongjohn 6939a3
  if (!filmstrip) {
manongjohn 6939a3
    int colIndex = app->getCurrentTool()->getTool()->getColumnIndex();
manongjohn 6939a3
    int rowIndex = frame->getFrame();
manongjohn 6939a3
    if (app->getCurrentTool()->getTool()->isColumnLocked(colIndex))
manongjohn 6939a3
      return false;
manongjohn 6939a3
manongjohn 6939a3
    TXsheet *xsh      = app->getCurrentXsheet()->getXsheet();
manongjohn 6939a3
    TStageObject *obj = xsh->getStageObject(TStageObjectId::ColumnId(colIndex));
manongjohn 6939a3
    // Test for Mesh-deformed levels
manongjohn 6939a3
    const TStageObjectId &parentId = obj->getParent();
manongjohn 6939a3
    if (parentId.isColumn() && obj->getParentHandle()[0] != 'H') {
manongjohn 6939a3
      TXshSimpleLevel *parentSl =
manongjohn 6939a3
          xsh->getCell(rowIndex, parentId.getIndex()).getSimpleLevel();
manongjohn 6939a3
      if (parentSl && parentSl->getType() == MESH_XSHLEVEL) return false;
manongjohn 6939a3
    }
manongjohn 6939a3
  }
manongjohn 6939a3
manongjohn 6939a3
  return true;
manongjohn 6939a3
}