Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/palettecmd.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/tpalettehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheethandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/studiopalette.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheet.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshcolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshcell.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelcolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsimplelevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/cleanupcolorstyles.h"
Toshihiro Shimizu 890ddd
#include "toonz/studiopalette.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzscene.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzimageutils.h"
Toshihiro Shimizu 890ddd
#include "toonz/cleanupcolorstyles.h"
Toshihiro Shimizu 890ddd
#include "toonz/preferences.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "tcolorstyles.h"
Toshihiro Shimizu 890ddd
#include "tundo.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "ttoonzimage.h"
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include "tcolorutils.h"
Toshihiro Shimizu 890ddd
#include "tropcm.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tregion.h"
Toshihiro Shimizu 890ddd
#include "tlevel_io.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "historytypes.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// tcg includes
Toshihiro Shimizu 890ddd
#include "tcg/boost/range_utility.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// boost includes
Toshihiro Shimizu 890ddd
#include <boost bind.hpp=""></boost>
Toshihiro Shimizu 890ddd
#include <boost counting_range.hpp="" range=""></boost>
Toshihiro Shimizu 890ddd
#include <boost adaptor="" range="" transformed.hpp=""></boost>
Toshihiro Shimizu 890ddd
#include <boost adaptor="" filtered.hpp="" range=""></boost>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void findPaletteLevels(set<txshsimplelevel *=""> &levels, int &rowIndex,</txshsimplelevel>
Shinya Kitaoka 120a6e
                       int &columnIndex, TPalette *palette, TXsheet *xsheet) {
Shinya Kitaoka 120a6e
  rowIndex = columnIndex = -1;
Shinya Kitaoka 120a6e
  int columnCount        = xsheet->getColumnCount();
Shinya Kitaoka 120a6e
  int c;
Shinya Kitaoka 120a6e
  for (c = 0; c < columnCount; c++) {
Shinya Kitaoka 120a6e
    TXshColumn *column = xsheet->getColumn(c);
Shinya Kitaoka 120a6e
    if (!column || column->isEmpty()) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TXshLevelColumn *levelColumn = column->getLevelColumn();
Shinya Kitaoka 120a6e
    if (!levelColumn || levelColumn->isEmpty()) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int r0, r1;
Shinya Kitaoka 120a6e
    if (!column->getRange(r0, r1)) continue;
Shinya Kitaoka 120a6e
    int r;
Shinya Kitaoka 120a6e
    for (r = r0; r <= r1; r++) {
Shinya Kitaoka 120a6e
      TXshCell cell = levelColumn->getCell(r);
Shinya Kitaoka 120a6e
      if (cell.isEmpty()) continue;
Shinya Kitaoka 120a6e
      TXshSimpleLevel *level = cell.getSimpleLevel();
Shinya Kitaoka 120a6e
      if (!level || level->getPalette() != palette) continue;
Shinya Kitaoka 120a6e
      levels.insert(level);
Shinya Kitaoka 120a6e
      if (rowIndex < 0) {
Shinya Kitaoka 120a6e
        rowIndex    = r;
Shinya Kitaoka 120a6e
        columnIndex = c;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
bool isStyleUsed(const TVectorImageP vi, int styleId) {
Shinya Kitaoka 120a6e
  int strokeCount = vi->getStrokeCount();
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = strokeCount - 1; i >= 0; i--) {
Shinya Kitaoka 120a6e
    TStroke *stroke = vi->getStroke(i);
Shinya Kitaoka 120a6e
    if (stroke && stroke->getStyle() == styleId) return true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  int regionCount = vi->getRegionCount();
Shinya Kitaoka 120a6e
  for (i = 0; i < regionCount; i++) {
Shinya Kitaoka 120a6e
    TRegion *region = vi->getRegion(i);
Shinya Kitaoka 120a6e
    if (region || region->getStyle() != styleId) return true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool isStyleUsed(const TToonzImageP vi, int styleId) {
Shinya Kitaoka 120a6e
  TRasterCM32P ras = vi->getRaster();
Shinya Kitaoka 120a6e
  for (int y = 0; y < ras->getLy(); y++) {
Shinya Kitaoka 120a6e
    TPixelCM32 *pix = ras->pixels(y), *endPix = pix + ras->getLx();
Shinya Kitaoka 120a6e
    while (pix < endPix) {
Shinya Kitaoka 120a6e
      if (pix->getPaint() == styleId) return true;
Shinya Kitaoka 120a6e
      if (pix->getInk() == styleId) return true;
Shinya Kitaoka 120a6e
      pix++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*! Return true if one style is used. */
Shinya Kitaoka 120a6e
bool areStylesUsed(const TImageP image, const std::vector<int> styleIds) {</int>
Shinya Kitaoka 120a6e
  int j;
Shinya Kitaoka 120a6e
  for (j = 0; j < (int)styleIds.size(); j++)
Shinya Kitaoka 120a6e
    if (isStyleUsed(image, styleIds[j])) return true;
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool isStyleUsed(const TImageP image, int styleId) {
Shinya Kitaoka 120a6e
  TVectorImageP vi = image;
Shinya Kitaoka 120a6e
  TToonzImageP ti  = image;
Shinya Kitaoka 120a6e
  if (vi) return isStyleUsed(vi, styleId);
Shinya Kitaoka 120a6e
  if (ti) return isStyleUsed(ti, styleId);
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*! Return true if one style is used. */
Shinya Kitaoka 120a6e
bool areStylesUsed(const set<txshsimplelevel *=""> levels,</txshsimplelevel>
Shinya Kitaoka 120a6e
                   const std::vector<int> styleIds) {</int>
Shinya Kitaoka 120a6e
  for (auto const level : levels) {
Shinya Kitaoka 120a6e
    std::vector<tframeid> fids;</tframeid>
Shinya Kitaoka 120a6e
    level->getFids(fids);
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 0; i < (int)fids.size(); i++) {
Shinya Kitaoka 120a6e
      TImageP image = level->getFrame(fids[i], true);
Shinya Kitaoka 120a6e
      if (areStylesUsed(image, styleIds)) return true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// arrangeStyles
Toshihiro Shimizu 890ddd
// srcPage : {a0,a1,...an } ==> dstPage : {b,b+1,...b+n-1}
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*! \namespace PaletteCmd
Shinya Kitaoka 120a6e
                \brief Provides a collection of methods to manage \b TPalette.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class ArrangeStylesUndo final : public TUndo {
Shinya Kitaoka 120a6e
  TPaletteHandle *m_paletteHandle;
Shinya Kitaoka 120a6e
  TPaletteP m_palette;
Shinya Kitaoka 120a6e
  int m_dstPageIndex;
Shinya Kitaoka 120a6e
  int m_dstIndexInPage;
Shinya Kitaoka 120a6e
  int m_srcPageIndex;
Shinya Kitaoka 120a6e
  std::set<int> m_srcIndicesInPage;</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ArrangeStylesUndo(TPaletteHandle *paletteHandle, int dstPageIndex,
Shinya Kitaoka 120a6e
                    int dstIndexInPage, int srcPageIndex,
Shinya Kitaoka 120a6e
                    const std::set<int> &srcIndicesInPage)</int>
Shinya Kitaoka 120a6e
      : m_paletteHandle(paletteHandle)
Shinya Kitaoka 120a6e
      , m_dstPageIndex(dstPageIndex)
Shinya Kitaoka 120a6e
      , m_dstIndexInPage(dstIndexInPage)
Shinya Kitaoka 120a6e
      , m_srcPageIndex(srcPageIndex)
Shinya Kitaoka 120a6e
      , m_srcIndicesInPage(srcIndicesInPage) {
Shinya Kitaoka 120a6e
    m_palette = m_paletteHandle->getPalette();
Shinya Kitaoka 120a6e
    assert(m_palette);
Shinya Kitaoka 120a6e
    assert(0 <= dstPageIndex && dstPageIndex < m_palette->getPageCount());
Shinya Kitaoka 120a6e
    assert(0 <= srcPageIndex && srcPageIndex < m_palette->getPageCount());
Shinya Kitaoka 120a6e
    TPalette::Page *dstPage = m_palette->getPage(dstPageIndex);
Shinya Kitaoka 120a6e
    assert(dstPage);
Shinya Kitaoka 120a6e
    assert(0 <= dstIndexInPage && dstIndexInPage <= dstPage->getStyleCount());
Shinya Kitaoka 120a6e
    assert(!srcIndicesInPage.empty());
Shinya Kitaoka 120a6e
    TPalette::Page *srcPage = m_palette->getPage(srcPageIndex);
Shinya Kitaoka 120a6e
    assert(srcPage);
Shinya Kitaoka 120a6e
    assert(0 <= *srcIndicesInPage.begin() &&
Shinya Kitaoka 120a6e
           *srcIndicesInPage.rbegin() < srcPage->getStyleCount());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    TPalette::Page *srcPage = m_palette->getPage(m_srcPageIndex);
Shinya Kitaoka 120a6e
    assert(srcPage);
Shinya Kitaoka 120a6e
    TPalette::Page *dstPage = m_palette->getPage(m_dstPageIndex);
Shinya Kitaoka 120a6e
    assert(dstPage);
Shinya Kitaoka 120a6e
    std::vector<int> styles;</int>
Shinya Kitaoka 120a6e
    int count = m_srcIndicesInPage.size();
Shinya Kitaoka 120a6e
    int h     = m_dstIndexInPage;
Shinya Kitaoka 120a6e
    std::set<int>::const_iterator i;</int>
Shinya Kitaoka 120a6e
    for (i = m_srcIndicesInPage.begin(); i != m_srcIndicesInPage.end(); ++i) {
Shinya Kitaoka 120a6e
      if (srcPage == dstPage && (*i) <= h)
Shinya Kitaoka 120a6e
        h--;
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    assert(h + count - 1 <= dstPage->getStyleCount());
Shinya Kitaoka 120a6e
    int k;
Shinya Kitaoka 120a6e
    for (k = 0; k < count; k++) {
Shinya Kitaoka 120a6e
      styles.push_back(dstPage->getStyleId(h));
Shinya Kitaoka 120a6e
      dstPage->removeStyle(h);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    k = 0;
Shinya Kitaoka 120a6e
    for (i = m_srcIndicesInPage.begin(); i != m_srcIndicesInPage.end();
Shinya Kitaoka 120a6e
         ++i, ++k)
Shinya Kitaoka 120a6e
      srcPage->insertStyle(*i, styles[k]);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    TPalette::Page *srcPage = m_palette->getPage(m_srcPageIndex);
Shinya Kitaoka 120a6e
    assert(srcPage);
Shinya Kitaoka 120a6e
    TPalette::Page *dstPage = m_palette->getPage(m_dstPageIndex);
Shinya Kitaoka 120a6e
    assert(dstPage);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::vector<int> styles;</int>
Shinya Kitaoka 120a6e
    std::set<int>::const_reverse_iterator i;</int>
Shinya Kitaoka 120a6e
    std::vector<int>::iterator j;</int>
Shinya Kitaoka 120a6e
    int k = m_dstIndexInPage;
Shinya Kitaoka 120a6e
    for (i = m_srcIndicesInPage.rbegin(); i != m_srcIndicesInPage.rend(); ++i) {
Shinya Kitaoka 120a6e
      int index = *i;
Shinya Kitaoka 120a6e
      if (m_dstPageIndex == m_srcPageIndex && index < k) k--;
Shinya Kitaoka 120a6e
      styles.push_back(srcPage->getStyleId(index));
Shinya Kitaoka 120a6e
      srcPage->removeStyle(index);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (j = styles.begin(); j != styles.end(); ++j)
Shinya Kitaoka 120a6e
      dstPage->insertStyle(k, *j);
Shinya Kitaoka 120a6e
    m_palette->setDirtyFlag(true);
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override {
Shinya Kitaoka 120a6e
    return sizeof *this + m_srcIndicesInPage.size() * sizeof(int);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  QString getHistoryString() override {
Shinya Kitaoka 120a6e
    return QObject::tr("Arrange Styles  in Palette %1")
Shinya Kitaoka 120a6e
        .arg(QString::fromStdWString(m_palette->getPaletteName()));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getHistoryType() override { return HistoryType::Palette; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PaletteCmd::arrangeStyles(TPaletteHandle *paletteHandle, int dstPageIndex,
Shinya Kitaoka 120a6e
                               int dstIndexInPage, int srcPageIndex,
Shinya Kitaoka 120a6e
                               const std::set<int> &srcIndicesInPage) {</int>
Shinya Kitaoka 120a6e
  if (dstPageIndex == srcPageIndex &&
Shinya Kitaoka 120a6e
      dstIndexInPage == *srcIndicesInPage.begin())
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  ArrangeStylesUndo *undo =
Shinya Kitaoka 120a6e
      new ArrangeStylesUndo(paletteHandle, dstPageIndex, dstIndexInPage,
Shinya Kitaoka 120a6e
                            srcPageIndex, srcIndicesInPage);
Shinya Kitaoka 120a6e
  undo->redo();
Shinya Kitaoka 120a6e
  TUndoManager::manager()->add(undo);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Shinya Kitaoka 120a6e
// CreateStyle
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class CreateStyleUndo final : public TUndo {
Shinya Kitaoka 120a6e
  TPaletteHandle *m_paletteHandle;
Shinya Kitaoka 120a6e
  TPaletteP m_palette;
Shinya Kitaoka 120a6e
  int m_pageIndex;
Shinya Kitaoka 120a6e
  int m_styleId;
Shinya Kitaoka 120a6e
  TColorStyle *m_style;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  CreateStyleUndo(TPaletteHandle *paletteHandle, int pageIndex, int styleId)
Shinya Kitaoka 120a6e
      : m_paletteHandle(paletteHandle)
Shinya Kitaoka 120a6e
      , m_pageIndex(pageIndex)
Shinya Kitaoka 120a6e
      , m_styleId(styleId) {
Shinya Kitaoka 120a6e
    m_palette = m_paletteHandle->getPalette();
Shinya Kitaoka 120a6e
    m_style   = m_palette->getStyle(m_styleId)->clone();
Shinya Kitaoka 120a6e
    assert(m_palette);
Shinya Kitaoka 120a6e
    assert(0 <= pageIndex && pageIndex < m_palette->getPageCount());
Shinya Kitaoka 120a6e
    assert(0 <= styleId && styleId < m_palette->getStyleCount());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    TPalette::Page *page = m_palette->getPage(m_pageIndex);
Shinya Kitaoka 120a6e
    assert(page);
Shinya Kitaoka 120a6e
    int indexInPage = page->search(m_styleId);
Shinya Kitaoka 120a6e
    assert(indexInPage >= 0);
Shinya Kitaoka 120a6e
    page->removeStyle(indexInPage);
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    TPalette::Page *page = m_palette->getPage(m_pageIndex);
Shinya Kitaoka 120a6e
    assert(page);
Shinya Kitaoka 120a6e
    assert(m_palette->getStylePage(m_styleId) == 0);
Shinya Kitaoka 120a6e
    int indexInPage = page->addStyle(m_styleId);
Shinya Kitaoka 120a6e
    if (indexInPage == -1) {
Shinya Kitaoka 120a6e
      indexInPage = page->getStyleCount();
Shinya Kitaoka 120a6e
      page->insertStyle(indexInPage, m_style->getMainColor());
Shinya Kitaoka 120a6e
      assert(m_styleId == page->getStyleId(indexInPage));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    m_palette->getStyle(m_styleId)->setMainColor(m_style->getMainColor());
Shinya Kitaoka 120a6e
    m_palette->getStyle(m_styleId)->setName(m_style->getName());
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getSize() const override { return sizeof *this; }
Shinya Kitaoka 473e70
  QString getHistoryString() override {
Shinya Kitaoka 120a6e
    return QObject::tr("Create Style#%1  in Palette %2")
Shinya Kitaoka 120a6e
        .arg(QString::number(m_styleId))
Shinya Kitaoka 120a6e
        .arg(QString::fromStdWString(m_palette->getPaletteName()));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getHistoryType() override { return HistoryType::Palette; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PaletteCmd::createStyle(TPaletteHandle *paletteHandle,
Shinya Kitaoka 120a6e
                             TPalette::Page *page) {
Shinya Kitaoka 120a6e
  int index         = paletteHandle->getStyleIndex();
Shinya Kitaoka 120a6e
  TPalette *palette = paletteHandle->getPalette();
Shinya Kitaoka 120a6e
  int newIndex;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int UnpagedId = palette->getFirstUnpagedStyle();
Shinya Kitaoka 120a6e
  if (UnpagedId != -1 && !palette->isCleanupPalette()) {
Shinya Kitaoka 120a6e
    if (index == -1)
Shinya Kitaoka 120a6e
      palette->getStyle(UnpagedId)->setMainColor(TPixel32::Black);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      palette->getStyle(UnpagedId)->setMainColor(
Shinya Kitaoka 120a6e
          palette->getStyle(index)->getMainColor());
Shinya Kitaoka 120a6e
    newIndex = page->addStyle(UnpagedId);
Shinya Kitaoka 120a6e
  } else if (!palette->isCleanupPalette()) {
Shinya Kitaoka 120a6e
    if (index == -1)
Shinya Kitaoka 120a6e
      newIndex = page->addStyle(TPixel32::Black);
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      TColorStyle *style          = palette->getStyle(index);
Shinya Kitaoka 120a6e
      TCleanupStyle *cleanupStyle = dynamic_cast<tcleanupstyle *="">(style);</tcleanupstyle>
Shinya Kitaoka 120a6e
      if ((cleanupStyle || index == 0) && palette->isCleanupPalette()) {
Shinya Kitaoka 120a6e
        TColorCleanupStyle *newCleanupStyle = new TColorCleanupStyle();
Shinya Kitaoka 120a6e
        if (cleanupStyle) {
Shinya Kitaoka 120a6e
          int i;
Shinya Kitaoka 120a6e
          for (i = 0; i < cleanupStyle->getParamCount(); i++)
Shinya Kitaoka 120a6e
            newCleanupStyle->setColorParamValue(
Shinya Kitaoka 120a6e
                i, cleanupStyle->getColorParamValue(i));
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        newIndex = page->addStyle(newCleanupStyle);
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        newIndex = page->addStyle(style->getMainColor());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else /*- CleanupPaletteの場合 -*/
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    newIndex = page->addStyle(new TColorCleanupStyle(TPixel32::Red));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  int newStyleId = page->getStyleId(newIndex);
Shinya Kitaoka 120a6e
  /*-  StudioPalette上でStyleを追加した場合、GlobalNameを自動で割り振る -*/
Shinya Kitaoka 120a6e
  if (palette->getGlobalName() != L"") {
Shinya Kitaoka 120a6e
    TColorStyle *cs = palette->getStyle(newStyleId);
Shinya Kitaoka 120a6e
    std::wstring gname =
Shinya Kitaoka 120a6e
        L"-" + palette->getGlobalName() + L"-" + std::to_wstring(newStyleId);
Shinya Kitaoka 120a6e
    cs->setGlobalName(gname);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  page->getStyle(newIndex)->setName(
Shinya Kitaoka 120a6e
      QString("color_%1").arg(newStyleId).toStdWString());
Shinya Kitaoka 120a6e
  paletteHandle->setStyleIndex(newStyleId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  palette->setDirtyFlag(true);
Shinya Kitaoka 120a6e
  paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  TUndoManager::manager()->add(new CreateStyleUndo(
Shinya Kitaoka 120a6e
      paletteHandle, page->getIndex(), page->getStyleId(newIndex)));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// addStyles
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// AddStylesUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class AddStylesUndo final : public TUndo {
Shinya Kitaoka 120a6e
  TPaletteP m_palette;
Shinya Kitaoka 120a6e
  int m_pageIndex;
Shinya Kitaoka 120a6e
  int m_indexInPage;
Shinya Kitaoka 120a6e
  std::vector<std::pair<tcolorstyle *,="" int="">> m_styles;</std::pair<tcolorstyle>
Shinya Kitaoka 120a6e
  TPaletteHandle *m_paletteHandle;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  // creare DOPO l'inserimento
Shinya Kitaoka 120a6e
  AddStylesUndo(const TPaletteP &palette, int pageIndex, int indexInPage,
Shinya Kitaoka 120a6e
                int count, TPaletteHandle *paletteHandle)
Shinya Kitaoka 120a6e
      : m_palette(palette)
Shinya Kitaoka 120a6e
      , m_pageIndex(pageIndex)
Shinya Kitaoka 120a6e
      , m_indexInPage(indexInPage)
Shinya Kitaoka 120a6e
      , m_paletteHandle(paletteHandle) {
Shinya Kitaoka 120a6e
    assert(m_palette);
Shinya Kitaoka 120a6e
    assert(0 <= m_pageIndex && m_pageIndex < m_palette->getPageCount());
Shinya Kitaoka 120a6e
    TPalette::Page *page = m_palette->getPage(m_pageIndex);
Shinya Kitaoka 120a6e
    assert(page);
Shinya Kitaoka 120a6e
    assert(0 <= indexInPage && indexInPage + count <= page->getStyleCount());
Shinya Kitaoka 120a6e
    for (int i = 0; i < count; i++) {
Shinya Kitaoka 120a6e
      std::pair<tcolorstyle *,="" int=""> p;</tcolorstyle>
Shinya Kitaoka 120a6e
      p.second = page->getStyleId(m_indexInPage + i);
Shinya Kitaoka 120a6e
      p.first  = m_palette->getStyle(p.second)->clone();
Shinya Kitaoka 120a6e
      m_styles.push_back(p);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  ~AddStylesUndo() {
Shinya Kitaoka 120a6e
    for (int i = 0; i < (int)m_styles.size(); i++) delete m_styles[i].first;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    TPalette::Page *page = m_palette->getPage(m_pageIndex);
Shinya Kitaoka 120a6e
    assert(page);
Shinya Kitaoka 120a6e
    int count = m_styles.size();
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = count - 1; i >= 0; i--) page->removeStyle(m_indexInPage + i);
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    TPalette::Page *page = m_palette->getPage(m_pageIndex);
Shinya Kitaoka 120a6e
    assert(page);
Shinya Kitaoka 120a6e
    for (int i = 0; i < (int)m_styles.size(); i++) {
Shinya Kitaoka 120a6e
      TColorStyle *cs = m_styles[i].first->clone();
Shinya Kitaoka 120a6e
      int styleId     = m_styles[i].second;
Shinya Kitaoka 120a6e
      assert(m_palette->getStylePage(styleId) == 0);
Shinya Kitaoka 120a6e
      m_palette->setStyle(styleId, cs);
Shinya Kitaoka 120a6e
      page->insertStyle(m_indexInPage + i, styleId);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getSize() const override {
Shinya Kitaoka 120a6e
    return sizeof *this + m_styles.size() * sizeof(TColorStyle);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  QString getHistoryString() override {
Shinya Kitaoka 120a6e
    return QObject::tr("Add Style  to Palette %1")
Shinya Kitaoka 120a6e
        .arg(QString::fromStdWString(m_palette->getPaletteName()));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getHistoryType() override { return HistoryType::Palette; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*- ドラッグ&ドロップ時に呼ばれる -*/
Toshihiro Shimizu 890ddd
void PaletteCmd::addStyles(TPaletteHandle *paletteHandle, int pageIndex,
Shinya Kitaoka 120a6e
                           int indexInPage,
Shinya Kitaoka 120a6e
                           const std::vector<tcolorstyle *=""> &styles) {</tcolorstyle>
Shinya Kitaoka 120a6e
  TPalette *palette = paletteHandle->getPalette();
Shinya Kitaoka 120a6e
  assert(0 <= pageIndex && pageIndex < palette->getPageCount());
Shinya Kitaoka 120a6e
  TPalette::Page *page = palette->getPage(pageIndex);
Shinya Kitaoka 120a6e
  assert(page);
Shinya Kitaoka 120a6e
  assert(0 <= indexInPage && indexInPage <= page->getStyleCount());
Shinya Kitaoka 120a6e
  int count = styles.size();
Shinya Kitaoka 120a6e
  for (int i = 0; i < count; i++) {
Shinya Kitaoka 120a6e
    page->insertStyle(indexInPage + i, styles[i]->clone());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*-- StudioPaletteから持ち込んだ場合、その元の名前をoriginalNameに入れる
Shinya Kitaoka 120a6e
     * --*/
Shinya Kitaoka 120a6e
    if (styles[i]->getGlobalName() != L"") {
Shinya Kitaoka 120a6e
      /*--
Shinya Kitaoka 120a6e
       * もし元のStyleにOriginalNameが無ければ(コピー元がStudioPaletteからということ)--*/
Shinya Kitaoka 120a6e
      if (styles[i]->getOriginalName() == L"") {
Shinya Kitaoka 120a6e
        /*-- 元のStyleの名前をペースト先のOriginalNameに入れる --*/
Shinya Kitaoka 120a6e
        page->getStyle(indexInPage + i)->setOriginalName(styles[i]->getName());
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    /*--
Shinya Kitaoka 120a6e
     * それ以外の場合は、clone()でそれぞれの名前をコピーしているので、そのままでOK
Shinya Kitaoka 120a6e
     * --*/
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TUndoManager::manager()->add(
Shinya Kitaoka 120a6e
      new AddStylesUndo(palette, pageIndex, indexInPage, count, paletteHandle));
Shinya Kitaoka 120a6e
  palette->setDirtyFlag(true);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// eraseStyles
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void eraseStylesInLevels(const set<txshsimplelevel *=""> &levels,</txshsimplelevel>
Shinya Kitaoka 120a6e
                         const std::vector<int> styleIds) {</int>
Shinya Kitaoka 120a6e
  for (auto const level : levels) {
Shinya Kitaoka 120a6e
    std::vector<tframeid> fids;</tframeid>
Shinya Kitaoka 120a6e
    level->getFids(fids);
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 0; i < (int)fids.size(); i++) {
Shinya Kitaoka 120a6e
      TImageP image    = level->getFrame(fids[i], true);
Shinya Kitaoka 120a6e
      TVectorImageP vi = image;
Shinya Kitaoka 120a6e
      TToonzImageP ti  = image;
Shinya Kitaoka 120a6e
      if (vi)
Shinya Kitaoka 120a6e
        vi->eraseStyleIds(styleIds);
Shinya Kitaoka 120a6e
      else if (ti)
Shinya Kitaoka 120a6e
        TRop::eraseStyleIds(ti.getPointer(), styleIds);
Shinya Kitaoka 120a6e
    }
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
void PaletteCmd::eraseStyles(const std::set<txshsimplelevel *=""> &levels,</txshsimplelevel>
Shinya Kitaoka 120a6e
                             const std::vector<int> &styleIds) {</int>
Shinya Kitaoka 120a6e
  typedef std::pair<const std::vector<tvectorimagep="" txshsimplelevelp,="">></const>
Shinya Kitaoka 120a6e
      LevelImages;
Shinya Kitaoka 120a6e
Shinya Kitaoka d1f6c4
  struct Undo final : public TUndo {
Shinya Kitaoka 120a6e
    std::set<txshsimplelevel *=""> m_levels;</txshsimplelevel>
Shinya Kitaoka 120a6e
    std::vector<int> m_styleIds;</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    mutable std::map<txshsimplelevelp, std::vector<tvectorimagep="">></txshsimplelevelp,>
Shinya Kitaoka 120a6e
        m_imagesByLevel;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  public:
Shinya Kitaoka 120a6e
    Undo(const std::set<txshsimplelevel *=""> &levels,</txshsimplelevel>
Shinya Kitaoka 120a6e
         const std::vector<int> &styleIds)</int>
Shinya Kitaoka 120a6e
        : m_levels(levels), m_styleIds(styleIds) {
Shinya Kitaoka 120a6e
      tcg::substitute(m_imagesByLevel,
Shinya Kitaoka 120a6e
                      levels | boost::adaptors::filtered(isVector) |
Shinya Kitaoka 120a6e
                          boost::adaptors::transformed(toEmptyLevelImages));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    bool isValid() const { return !m_levels.empty(); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
    void redo() const override {
Shinya Kitaoka 120a6e
      std::for_each(m_imagesByLevel.begin(), m_imagesByLevel.end(),
Shinya Kitaoka 120a6e
                    cloneImages);
Shinya Kitaoka 120a6e
      eraseStylesInLevels(m_levels, m_styleIds);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
    void undo() const override {
Shinya Kitaoka 120a6e
      std::for_each(m_imagesByLevel.begin(), m_imagesByLevel.end(),
Shinya Kitaoka 120a6e
                    restoreImages);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
    int getSize() const override { return 10 << 20; }  // At max 10 per 100 MB
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  private:
Shinya Kitaoka 120a6e
    static bool isVector(const TXshSimpleLevel *level) {
Shinya Kitaoka 120a6e
      return (assert(level), level->getType() == PLI_XSHLEVEL);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    static LevelImages toEmptyLevelImages(TXshSimpleLevel *level) {
Shinya Kitaoka 120a6e
      return LevelImages(level, std::vector<tvectorimagep>());</tvectorimagep>
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    static void copyStrokeIds(const TVectorImage &src, TVectorImage &dst) {
Shinya Kitaoka 120a6e
      UINT s, sCount = src.getStrokeCount();
Shinya Kitaoka 120a6e
      for (s = 0; s != sCount; ++s)
Shinya Kitaoka 120a6e
        dst.getStroke(s)->setId(src.getStroke(s)->getId());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    static TVectorImageP cloneImage(const TXshSimpleLevel &level, int f) {
Shinya Kitaoka 120a6e
      TVectorImageP src = static_cast<tvectorimagep>(</tvectorimagep>
Shinya Kitaoka 120a6e
          level.getFrame(level.getFrameId(f), false));
Shinya Kitaoka 120a6e
      TVectorImageP dst = src->clone();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      copyStrokeIds(*src, *dst);
Shinya Kitaoka 120a6e
      return dst;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    static void cloneImages(LevelImages &levelImages) {
Shinya Kitaoka 120a6e
      tcg::substitute(
Shinya Kitaoka 120a6e
          levelImages.second,
Shinya Kitaoka 120a6e
          boost::counting_range(0, levelImages.first->getFrameCount()) |
Shinya Kitaoka 120a6e
              boost::adaptors::transformed(boost::bind(
Shinya Kitaoka 120a6e
                  cloneImage, boost::cref(*levelImages.first), _1)));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    static void restoreImage(const TXshSimpleLevelP &level, int f,
Shinya Kitaoka 120a6e
                             const TVectorImageP &vi) {
Shinya Kitaoka 120a6e
      level->setFrame(level->getFrameId(f), vi.getPointer());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    static void restoreImages(LevelImages &levelImages) {
Shinya Kitaoka 120a6e
      int f, fCount = std::min(levelImages.first->getFrameCount(),
Shinya Kitaoka 120a6e
                               int(levelImages.second.size()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      for (f = 0; f != fCount; ++f)
Shinya Kitaoka 120a6e
        restoreImage(levelImages.first, f, levelImages.second[f]);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  };  // Undo
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (levels.empty() || styleIds.empty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::auto_ptr<tundo> undo(new Undo(levels, styleIds));</tundo>
Shinya Kitaoka 120a6e
  if (static_cast<undo &="">(*undo).isValid()) {</undo>
Shinya Kitaoka 120a6e
    undo->redo();
Shinya Kitaoka 120a6e
    TUndoManager::manager()->add(undo.release());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// addPage
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class AddPageUndo final : public TUndo {
Shinya Kitaoka 120a6e
  TPaletteHandle *m_paletteHandle;
Shinya Kitaoka 120a6e
  TPaletteP m_palette;
Shinya Kitaoka 120a6e
  int m_pageIndex;
Shinya Kitaoka 120a6e
  std::wstring m_pageName;
Shinya Kitaoka 120a6e
  std::vector<std::pair<tcolorstyle *,="" int="">> m_styles;</std::pair<tcolorstyle>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  // creare DOPO l'inserimento
Shinya Kitaoka 120a6e
  AddPageUndo(TPaletteHandle *paletteHandle, int pageIndex,
Shinya Kitaoka 120a6e
              std::wstring pageName)
Shinya Kitaoka 120a6e
      : m_paletteHandle(paletteHandle)
Shinya Kitaoka 120a6e
      , m_pageIndex(pageIndex)
Shinya Kitaoka 120a6e
      , m_pageName(pageName) {
Shinya Kitaoka 120a6e
    m_palette = m_paletteHandle->getPalette();
Shinya Kitaoka 120a6e
    assert(m_palette);
Shinya Kitaoka 120a6e
    assert(0 <= m_pageIndex && m_pageIndex < m_palette->getPageCount());
Shinya Kitaoka 120a6e
    TPalette::Page *page = m_palette->getPage(m_pageIndex);
Shinya Kitaoka 120a6e
    assert(page);
Shinya Kitaoka 120a6e
    for (int i = 0; i < page->getStyleCount(); i++) {
Shinya Kitaoka 120a6e
      std::pair<tcolorstyle *,="" int=""> p;</tcolorstyle>
Shinya Kitaoka 120a6e
      p.first  = page->getStyle(i)->clone();
Shinya Kitaoka 120a6e
      p.second = page->getStyleId(i);
Shinya Kitaoka 120a6e
      m_styles.push_back(p);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  ~AddPageUndo() {
Shinya Kitaoka 120a6e
    for (int i = 0; i < (int)m_styles.size(); i++) delete m_styles[i].first;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    m_palette->erasePage(m_pageIndex);
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    TPalette::Page *page = m_palette->addPage(m_pageName);
Shinya Kitaoka 120a6e
    assert(page);
Shinya Kitaoka 120a6e
    assert(page->getIndex() == m_pageIndex);
Shinya Kitaoka 120a6e
    for (int i = 0; i < (int)m_styles.size(); i++) {
Shinya Kitaoka 120a6e
      TColorStyle *cs = m_styles[i].first->clone();
Shinya Kitaoka 120a6e
      int styleId     = m_styles[i].second;
Shinya Kitaoka 120a6e
      assert(m_palette->getStylePage(styleId) == 0);
Shinya Kitaoka 120a6e
      m_palette->setStyle(styleId, cs);
Shinya Kitaoka 120a6e
      page->addStyle(styleId);
Shinya Kitaoka 120a6e
    };
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getSize() const override {
Shinya Kitaoka 120a6e
    return sizeof *this + m_styles.size() * sizeof(TColorStyle);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  QString getHistoryString() override {
Shinya Kitaoka 120a6e
    return QObject::tr("Add Page %1 to Palette %2")
Shinya Kitaoka 120a6e
        .arg(QString::fromStdWString(m_pageName))
Shinya Kitaoka 120a6e
        .arg(QString::fromStdWString(m_palette->getPaletteName()));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getHistoryType() override { return HistoryType::Palette; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PaletteCmd::addPage(TPaletteHandle *paletteHandle, std::wstring name,
Shinya Kitaoka 120a6e
                         bool withUndo) {
Shinya Kitaoka 120a6e
  TPalette *palette = paletteHandle->getPalette();
Shinya Kitaoka 120a6e
  if (name == L"")
Shinya Kitaoka 120a6e
    name = L"page " + std::to_wstring(palette->getPageCount() + 1);
Shinya Kitaoka 120a6e
  TPalette::Page *page = palette->addPage(name);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  palette->setDirtyFlag(true);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  if (withUndo)
Shinya Kitaoka 120a6e
    TUndoManager::manager()->add(
Shinya Kitaoka 120a6e
        new AddPageUndo(paletteHandle, page->getIndex(), name));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// destroyPage
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class DestroyPageUndo final : public TUndo {
Shinya Kitaoka 120a6e
  TPaletteHandle *m_paletteHandle;
Shinya Kitaoka 120a6e
  TPaletteP m_palette;
Shinya Kitaoka 120a6e
  int m_pageIndex;
Shinya Kitaoka 120a6e
  std::wstring m_pageName;
Shinya Kitaoka 120a6e
  std::vector<int> m_styles;</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  DestroyPageUndo(TPaletteHandle *paletteHandle, int pageIndex)
Shinya Kitaoka 120a6e
      : m_paletteHandle(paletteHandle), m_pageIndex(pageIndex) {
Shinya Kitaoka 120a6e
    m_palette = m_paletteHandle->getPalette();
Shinya Kitaoka 120a6e
    assert(m_palette);
Shinya Kitaoka 120a6e
    assert(0 <= pageIndex && pageIndex < m_palette->getPageCount());
Shinya Kitaoka 120a6e
    assert(m_palette->getPageCount() > 1);
Shinya Kitaoka 120a6e
    TPalette::Page *page = m_palette->getPage(m_pageIndex);
Shinya Kitaoka 120a6e
    assert(page);
Shinya Kitaoka 120a6e
    m_pageName = page->getName();
Shinya Kitaoka 120a6e
    m_styles.resize(page->getStyleCount());
Shinya Kitaoka 120a6e
    for (int i    = 0; i < page->getStyleCount(); i++)
Shinya Kitaoka 120a6e
      m_styles[i] = page->getStyleId(i);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    TPalette::Page *page = m_palette->addPage(m_pageName);
Shinya Kitaoka 120a6e
    m_palette->movePage(page, m_pageIndex);
Shinya Kitaoka 120a6e
    for (int i = 0; i < (int)m_styles.size(); i++) page->addStyle(m_styles[i]);
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    m_palette->erasePage(m_pageIndex);
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getSize() const override { return sizeof *this; }
Shinya Kitaoka 473e70
  QString getHistoryString() override {
Shinya Kitaoka 120a6e
    return QObject::tr("Delete Page %1 from Palette %2")
Shinya Kitaoka 120a6e
        .arg(QString::fromStdWString(m_pageName))
Shinya Kitaoka 120a6e
        .arg(QString::fromStdWString(m_palette->getPaletteName()));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getHistoryType() override { return HistoryType::Palette; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PaletteCmd::destroyPage(TPaletteHandle *paletteHandle, int pageIndex) {
Shinya Kitaoka 120a6e
  TPalette *palette = paletteHandle->getPalette();
Shinya Kitaoka 120a6e
  assert(0 <= pageIndex && pageIndex < palette->getPageCount());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TUndoManager::manager()->add(new DestroyPageUndo(paletteHandle, pageIndex));
Shinya Kitaoka 120a6e
  palette->erasePage(pageIndex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  palette->setDirtyFlag(true);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  paletteHandle->notifyPaletteChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
// ReferenceImage
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
// SetReferenceImageUndo
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class SetReferenceImageUndo final : public TUndo {
Shinya Kitaoka 120a6e
  TPaletteP m_palette;
Shinya Kitaoka 120a6e
  TPaletteP m_oldPalette, m_newPalette;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TPaletteHandle *m_paletteHandle;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  SetReferenceImageUndo(TPaletteP palette, TPaletteHandle *paletteHandle)
Shinya Kitaoka 120a6e
      : m_palette(palette)
Shinya Kitaoka 120a6e
      , m_oldPalette(palette->clone())
Shinya Kitaoka 120a6e
      , m_paletteHandle(paletteHandle) {}
Shinya Kitaoka 473e70
  void onAdd() override { m_newPalette = m_palette->clone(); }
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    m_palette->assign(m_oldPalette.getPointer());
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    m_palette->assign(m_newPalette.getPointer());
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getSize() const override { return sizeof(*this) + sizeof(TPalette) * 2; }
Shinya Kitaoka 473e70
  QString getHistoryString() override {
Shinya Kitaoka 120a6e
    return QObject::tr("Load Color Model %1  to Palette %2")
Shinya Kitaoka 120a6e
        .arg(QString::fromStdString(
Shinya Kitaoka 120a6e
            m_newPalette->getRefImgPath().getLevelName()))
Shinya Kitaoka 120a6e
        .arg(QString::fromStdWString(m_palette->getPaletteName()));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getHistoryType() override { return HistoryType::Palette; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
// loadRefImage
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int loadRefImage(TPaletteHandle *paletteHandle,
Shinya Kitaoka 120a6e
                 PaletteCmd::ColorModelPltBehavior pltBehavior,
Shinya Kitaoka 120a6e
                 TPaletteP levelPalette, const TFilePath &_fp, int &frame,
Shinya Kitaoka 120a6e
                 ToonzScene *scene, const std::vector<int> &frames) {</int>
Shinya Kitaoka 120a6e
  bool paletteAlreadyLoaded = false;
Shinya Kitaoka 120a6e
  TFilePath fp              = scene->decodeFilePath(_fp);
Shinya Kitaoka 120a6e
  if (_fp == TFilePath()) {
Shinya Kitaoka 120a6e
    paletteAlreadyLoaded = true;
Shinya Kitaoka 120a6e
    fp                   = levelPalette->getRefImgPath();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TImageP img;
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    TLevelReaderP lr(fp);
Shinya Kitaoka 120a6e
    if (fp != TFilePath() && lr) {
Shinya Kitaoka 120a6e
      TLevelP level = lr->loadInfo();
Shinya Kitaoka 120a6e
      if (level && level->getFrameCount() > 0) {
Shinya Kitaoka 120a6e
        TLevel::Iterator it;
Shinya Kitaoka 120a6e
        if (!paletteAlreadyLoaded) {
Shinya Kitaoka 120a6e
          std::vector<tframeid> fids;</tframeid>
Shinya Kitaoka 120a6e
          for (it = level->begin(); it != level->end(); ++it) {
Shinya Kitaoka 120a6e
            if (it->first == -1 || it->first == -2) {
Shinya Kitaoka 120a6e
              assert(level->getFrameCount() == 1);
Shinya Kitaoka 120a6e
              fids.push_back(0);
Shinya Kitaoka 120a6e
              break;
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
            // if the frame list is empty, store all fids of the level
Shinya Kitaoka 120a6e
            if (frames.empty()) {
Shinya Kitaoka 120a6e
              fids.push_back(it->first);
Shinya Kitaoka 120a6e
              continue;
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
            // if the frame list is specified, load only the frames matches with
Shinya Kitaoka 120a6e
            // the list
Shinya Kitaoka 120a6e
            else {
Shinya Kitaoka 120a6e
              std::vector<int>::const_iterator framesIt;</int>
Shinya Kitaoka 120a6e
              for (framesIt = frames.begin(); framesIt != frames.end();
Shinya Kitaoka 120a6e
                   framesIt++) {
Shinya Kitaoka 120a6e
                if (it->first.getNumber() == *framesIt) {
Shinya Kitaoka 120a6e
                  fids.push_back(it->first);
Shinya Kitaoka 120a6e
                  break;
Shinya Kitaoka 120a6e
                }
Shinya Kitaoka 120a6e
              }
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          levelPalette->setRefLevelFids(fids);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (frame <= 0) frame = level->begin()->first.getNumber();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        const TLevel::Table *table = level->getTable();
Shinya Kitaoka 120a6e
        TFrameId fid(frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (table->find(fid) != table->end()) {
Shinya Kitaoka 120a6e
          img = lr->getFrameReader(fid)->load();
Shinya Kitaoka 120a6e
          if (img && img->getPalette() == 0) {
Shinya Kitaoka 120a6e
            if (paletteAlreadyLoaded || level->getPalette() != 0)
Shinya Kitaoka 120a6e
              img->setPalette(level->getPalette());
Shinya Kitaoka 120a6e
            else if ((fp.getType() == "tzp" || fp.getType() == "tzu"))
Shinya Kitaoka 120a6e
              img->setPalette(ToonzImageUtils::loadTzPalette(
Shinya Kitaoka 120a6e
                  fp.withType("plt").withNoFrame()));
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      img = levelPalette->getRefImg();
Shinya Kitaoka 120a6e
  } catch (TException &e) {
Shinya Kitaoka 120a6e
    std::wcout << L"error: " << e.getMessage() << std::endl;
Shinya Kitaoka 120a6e
  } catch (...) {
Shinya Kitaoka 120a6e
    std::cout << "error for other reasons" << std::endl;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!img) return 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (paletteAlreadyLoaded) {
Shinya Kitaoka 120a6e
    img->setPalette(0);
Shinya Kitaoka 120a6e
    levelPalette->setRefImgPath(_fp);
Shinya Kitaoka 120a6e
    return 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TUndo *undo = new SetReferenceImageUndo(levelPalette, paletteHandle);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (pltBehavior != PaletteCmd::ReplaceColorModelPlt)  // ret==1 or 3)
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    TPaletteP imagePalette;
Shinya Kitaoka 120a6e
    if (TRasterImageP ri = img) {
Shinya Kitaoka 120a6e
      TRaster32P raster = ri->getRaster();
Shinya Kitaoka 120a6e
      if (raster) {
Shinya Kitaoka 120a6e
        std::set<tpixel32> colors;</tpixel32>
Shinya Kitaoka 120a6e
        int colorCount = 256;
Shinya Kitaoka 120a6e
        if (Preferences::instance()
Shinya Kitaoka 120a6e
                ->getPaletteTypeOnLoadRasterImageAsColorModel() == 0)
Shinya Kitaoka 120a6e
          /*-- 全ての異なるピクセルの色を別のStyleにする --*/
Shinya Kitaoka 120a6e
          TColorUtils::buildPrecisePalette(colors, raster, colorCount);
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          /*-- 似ている色をまとめて1つのStyleにする --*/
Shinya Kitaoka 120a6e
          TColorUtils::buildPalette(colors, raster, colorCount);
Shinya Kitaoka 120a6e
        colors.erase(TPixel::Black);  // il nero viene messo dal costruttore
Shinya Kitaoka 120a6e
                                      // della TPalette
Shinya Kitaoka 120a6e
        int pageIndex = 0;
Shinya Kitaoka 120a6e
        if (pltBehavior == PaletteCmd::KeepColorModelPlt)
Shinya Kitaoka 120a6e
          imagePalette = new TPalette();
Shinya Kitaoka 120a6e
        else {
Shinya Kitaoka 120a6e
          imagePalette = levelPalette->clone();
Shinya Kitaoka 120a6e
          /*- Add new page and store color model's styles in it -*/
Shinya Kitaoka 120a6e
          pageIndex =
Shinya Kitaoka 120a6e
              imagePalette->addPage(QObject::tr("color model").toStdWString())
Shinya Kitaoka 120a6e
                  ->getIndex();
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        std::set<tpixel32>::const_iterator it = colors.begin();</tpixel32>
Shinya Kitaoka 120a6e
        for (; it != colors.end(); ++it)
Shinya Kitaoka 120a6e
          imagePalette->getPage(pageIndex)->addStyle(*it);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      imagePalette = img->getPalette();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (imagePalette) {
Shinya Kitaoka 120a6e
      std::wstring gName = levelPalette->getGlobalName();
Shinya Kitaoka 120a6e
      // Se sto caricando un reference image su una studio palette
Shinya Kitaoka 120a6e
      if (!gName.empty()) {
Shinya Kitaoka 120a6e
        imagePalette->setGlobalName(gName);
Shinya Kitaoka 120a6e
        StudioPalette::instance()->setStylesGlobalNames(
Shinya Kitaoka 120a6e
            imagePalette.getPointer());
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      // voglio evitare di sostituire una palette con pochi colori ad una con
Shinya Kitaoka 120a6e
      // tanti colori
Shinya Kitaoka 120a6e
      /*--
Shinya Kitaoka 120a6e
       * ColorModelの色数が少ないのにOverwriteしようとした場合は、余分の分だけStyleが追加される
Shinya Kitaoka 120a6e
       * --*/
Shinya Kitaoka 120a6e
      while (imagePalette->getStyleCount() < levelPalette->getStyleCount()) {
Shinya Kitaoka 120a6e
        int index = imagePalette->getStyleCount();
Shinya Kitaoka 120a6e
        assert(index < levelPalette->getStyleCount());
Shinya Kitaoka 120a6e
        TColorStyle *style = levelPalette->getStyle(index)->clone();
Shinya Kitaoka 120a6e
        imagePalette->addStyle(style);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      levelPalette->assign(imagePalette.getPointer());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  img->setPalette(0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  levelPalette->setRefImgPath(_fp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TUndoManager::manager()->add(undo);
Shinya Kitaoka 120a6e
  paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
// loadReferenceImage
Shinya Kitaoka 120a6e
// load frames specified in frames. if frames is empty, then load all frames of
Shinya Kitaoka 120a6e
// the level.
Toshihiro Shimizu 890ddd
// return values -- 2: failed_to_get_palette, 1: failed_to_get_image, 0: OK
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int PaletteCmd::loadReferenceImage(TPaletteHandle *paletteHandle,
Shinya Kitaoka 120a6e
                                   ColorModelPltBehavior pltBehavior,
Shinya Kitaoka 120a6e
                                   const TFilePath &_fp, int &frame,
Shinya Kitaoka 120a6e
                                   ToonzScene *scene,
Shinya Kitaoka 120a6e
                                   const std::vector<int> &frames) {</int>
Shinya Kitaoka 120a6e
  TPaletteP levelPalette = paletteHandle->getPalette();
Shinya Kitaoka 120a6e
  if (!levelPalette) return 2;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int ret = loadRefImage(paletteHandle, pltBehavior, levelPalette, _fp, frame,
Shinya Kitaoka 120a6e
                         scene, frames);
Shinya Kitaoka 120a6e
  if (ret != 0) return ret;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // when choosing replace(Keep the destination palette), dirty flag is
Shinya Kitaoka 120a6e
  // unchanged
Shinya Kitaoka 120a6e
  if (pltBehavior != ReplaceColorModelPlt) levelPalette->setDirtyFlag(true);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
// removeReferenceImage
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PaletteCmd::removeReferenceImage(TPaletteHandle *paletteHandle) {
Shinya Kitaoka 120a6e
  TPaletteP levelPalette = paletteHandle->getPalette();
Shinya Kitaoka 120a6e
  if (!levelPalette) return;
Shinya Kitaoka 120a6e
  TUndo *undo = new SetReferenceImageUndo(levelPalette, paletteHandle);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  levelPalette->setRefImg(TImageP());
Shinya Kitaoka 120a6e
  levelPalette->setRefImgPath(TFilePath());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<tframeid> fids;</tframeid>
Shinya Kitaoka 120a6e
  levelPalette->setRefLevelFids(fids);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  levelPalette->setDirtyFlag(true);
Shinya Kitaoka 120a6e
  paletteHandle->notifyPaletteChanged();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TUndoManager::manager()->add(undo);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// MovePage
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class MovePageUndo final : public TUndo {
Shinya Kitaoka 120a6e
  TPaletteHandle *m_paletteHandle;
Shinya Kitaoka 120a6e
  TPaletteP m_palette;
Shinya Kitaoka 120a6e
  int m_srcIndex;
Shinya Kitaoka 120a6e
  int m_dstIndex;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  MovePageUndo(TPaletteHandle *paletteHandle, int srcIndex, int dstIndex)
Shinya Kitaoka 120a6e
      : m_paletteHandle(paletteHandle)
Shinya Kitaoka 120a6e
      , m_srcIndex(srcIndex)
Shinya Kitaoka 120a6e
      , m_dstIndex(dstIndex) {
Shinya Kitaoka 120a6e
    m_palette = m_paletteHandle->getPalette();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    m_palette->movePage(m_palette->getPage(m_dstIndex), m_srcIndex);
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    m_palette->movePage(m_palette->getPage(m_srcIndex), m_dstIndex);
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getSize() const override { return sizeof *this; }
Shinya Kitaoka 473e70
  QString getHistoryString() override { return QObject::tr("Move Page"); }
Shinya Kitaoka 473e70
  int getHistoryType() override { return HistoryType::Palette; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PaletteCmd::movePalettePage(TPaletteHandle *paletteHandle, int srcIndex,
Shinya Kitaoka 120a6e
                                 int dstIndex) {
Shinya Kitaoka 120a6e
  TPaletteP palette = paletteHandle->getPalette();
Shinya Kitaoka 120a6e
  palette->movePage(palette->getPage(srcIndex), dstIndex);
Shinya Kitaoka 120a6e
  TUndoManager::manager()->add(
Shinya Kitaoka 120a6e
      new MovePageUndo(paletteHandle, srcIndex, dstIndex));
Shinya Kitaoka 120a6e
  paletteHandle->notifyPaletteChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// RenamePage
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class RenamePageUndo final : public TUndo {
Shinya Kitaoka 120a6e
  TPaletteHandle *m_paletteHandle;
Shinya Kitaoka 120a6e
  TPaletteP m_palette;
Shinya Kitaoka 120a6e
  int m_pageIndex;
Shinya Kitaoka 120a6e
  std::wstring m_newName;
Shinya Kitaoka 120a6e
  std::wstring m_oldName;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  RenamePageUndo(TPaletteHandle *paletteHandle, int pageIndex,
Shinya Kitaoka 120a6e
                 const std::wstring &newName)
Shinya Kitaoka 120a6e
      : m_paletteHandle(paletteHandle)
Shinya Kitaoka 120a6e
      , m_pageIndex(pageIndex)
Shinya Kitaoka 120a6e
      , m_newName(newName) {
Shinya Kitaoka 120a6e
    m_palette = m_paletteHandle->getPalette();
Shinya Kitaoka 120a6e
    m_oldName = m_palette->getPage(pageIndex)->getName();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    TPalette::Page *page = m_palette->getPage(m_pageIndex);
Shinya Kitaoka 120a6e
    assert(page);
Shinya Kitaoka 120a6e
    page->setName(m_oldName);
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    TPalette::Page *page = m_palette->getPage(m_pageIndex);
Shinya Kitaoka 120a6e
    assert(page);
Shinya Kitaoka 120a6e
    page->setName(m_newName);
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getSize() const override { return sizeof *this; }
Shinya Kitaoka 473e70
  QString getHistoryString() override {
Shinya Kitaoka 120a6e
    return QObject::tr("Rename Page  %1 > %2")
Shinya Kitaoka 120a6e
        .arg(QString::fromStdWString(m_oldName))
Shinya Kitaoka 120a6e
        .arg(QString::fromStdWString(m_newName));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getHistoryType() override { return HistoryType::Palette; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void PaletteCmd::renamePalettePage(TPaletteHandle *paletteHandle, int pageIndex,
Shinya Kitaoka 120a6e
                                   const std::wstring &newName) {
Shinya Kitaoka 120a6e
  if (!paletteHandle) return;
Shinya Kitaoka 120a6e
  TPalette *palette = paletteHandle->getPalette();
Shinya Kitaoka 120a6e
  if (!palette) return;
Shinya Kitaoka 120a6e
  if (pageIndex < 0 || pageIndex >= palette->getPageCount()) return;
Shinya Kitaoka 120a6e
  RenamePageUndo *undo = new RenamePageUndo(paletteHandle, pageIndex, newName);
Shinya Kitaoka 120a6e
  paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  TPalette::Page *page = palette->getPage(pageIndex);
Shinya Kitaoka 120a6e
  assert(page);
Shinya Kitaoka 120a6e
  page->setName(newName);
Shinya Kitaoka 120a6e
  palette->setDirtyFlag(true);
Shinya Kitaoka 120a6e
  paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  TUndoManager::manager()->add(undo);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// RenamePaletteStyle
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class RenamePaletteStyleUndo final : public TUndo {
Shinya Kitaoka 120a6e
  TPaletteHandle *m_paletteHandle;  // Usato nell'undo e nel redo per lanciare
Shinya Kitaoka 120a6e
                                    // la notifica di cambiamento
Shinya Kitaoka 120a6e
  int m_styleId;
Shinya Kitaoka 120a6e
  TPaletteP m_palette;
Shinya Kitaoka 120a6e
  std::wstring m_newName;
Shinya Kitaoka 120a6e
  std::wstring m_oldName;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  RenamePaletteStyleUndo(TPaletteHandle *paletteHandle,
Shinya Kitaoka 120a6e
                         const std::wstring &newName)
Shinya Kitaoka 120a6e
      : m_paletteHandle(paletteHandle), m_newName(newName) {
Shinya Kitaoka 120a6e
    m_palette = paletteHandle->getPalette();
Shinya Kitaoka 120a6e
    assert(m_palette);
Shinya Kitaoka 120a6e
    m_styleId          = paletteHandle->getStyleIndex();
Shinya Kitaoka 120a6e
    TColorStyle *style = m_palette->getStyle(m_styleId);
Shinya Kitaoka 120a6e
    assert(style);
Shinya Kitaoka 120a6e
    m_oldName = style->getName();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    TColorStyle *style = m_palette->getStyle(m_styleId);
Shinya Kitaoka 120a6e
    assert(style);
Shinya Kitaoka 120a6e
    style->setName(m_oldName);
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyColorStyleChanged(false);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    TColorStyle *style = m_palette->getStyle(m_styleId);
Shinya Kitaoka 120a6e
    assert(style);
Shinya Kitaoka 120a6e
    style->setName(m_newName);
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyColorStyleChanged(false);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getSize() const override { return sizeof *this; }
Shinya Kitaoka 473e70
  QString getHistoryString() override {
Shinya Kitaoka 120a6e
    return QObject::tr("Rename Style#%1 in Palette%2  : %3 > %4")
Shinya Kitaoka 120a6e
        .arg(QString::number(m_styleId))
Shinya Kitaoka 120a6e
        .arg(QString::fromStdWString(m_palette->getPaletteName()))
Shinya Kitaoka 120a6e
        .arg(QString::fromStdWString(m_oldName))
Shinya Kitaoka 120a6e
        .arg(QString::fromStdWString(m_newName));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getHistoryType() override { return HistoryType::Palette; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void PaletteCmd::renamePaletteStyle(TPaletteHandle *paletteHandle,
Shinya Kitaoka 120a6e
                                    const std::wstring &newName) {
Shinya Kitaoka 120a6e
  if (!paletteHandle) return;
Shinya Kitaoka 120a6e
  TPalette *palette = paletteHandle->getPalette();
Shinya Kitaoka 120a6e
  if (!palette) return;
Shinya Kitaoka 120a6e
  TColorStyle *style = paletteHandle->getStyle();
Shinya Kitaoka 120a6e
  if (!style) return;
Shinya Kitaoka 120a6e
  if (style->getName() == newName) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  RenamePaletteStyleUndo *undo =
Shinya Kitaoka 120a6e
      new RenamePaletteStyleUndo(paletteHandle, newName);
Shinya Kitaoka 120a6e
  style->setName(newName);
Shinya Kitaoka 120a6e
  palette->setDirtyFlag(true);
Shinya Kitaoka 120a6e
  paletteHandle->notifyColorStyleChanged(false);
Shinya Kitaoka 120a6e
  TUndoManager::manager()->add(undo);
Toshihiro Shimizu 890ddd
}
shun_iwasawa 48c671
shun_iwasawa 48c671
//=============================================================================
shun_iwasawa 48c671
// organizePaletteStyle
shun_iwasawa 48c671
// called in ColorModelViewer::pick() - move selected style to the first page
shun_iwasawa 48c671
//-----------------------------------------------------------------------------
shun_iwasawa 48c671
void PaletteCmd::organizePaletteStyle(TPaletteHandle *paletteHandle, int styleId){
shun_iwasawa 48c671
  if (!paletteHandle) return;
shun_iwasawa 48c671
  TPalette *palette = paletteHandle->getPalette();
shun_iwasawa 48c671
  if (!palette) return;
shun_iwasawa 48c671
  // if the style is already in the first page, then do nothing
shun_iwasawa 48c671
  TPalette::Page* page = palette->getStylePage(styleId);
shun_iwasawa 48c671
  if (!page || page->getIndex() == 0) return;
shun_iwasawa 48c671
shun_iwasawa 48c671
  int indexInPage = page->search(styleId);
shun_iwasawa 48c671
shun_iwasawa 48c671
  /* 
shun_iwasawa 48c671
    just call arrangeStyles as tentative implementation.
shun_iwasawa 48c671
    TODO: store the picked position into the style name somehow
shun_iwasawa 48c671
  */
shun_iwasawa 48c671
  arrangeStyles(paletteHandle, 0, palette->getPage(0)->getStyleCount(),
shun_iwasawa 48c671
    page->getIndex(), { indexInPage });
shun_iwasawa 48c671
 
shun_iwasawa 48c671
}