Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tools/imagegrouping.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzTools includes
Toshihiro Shimizu 890ddd
#include "tools/strokeselection.h"
Toshihiro Shimizu 890ddd
#include "tools/tool.h"
Toshihiro Shimizu 890ddd
#include "tools/toolhandle.h"
Toshihiro Shimizu 890ddd
#include "tools/toolutils.h"
Toshihiro Shimizu 890ddd
#include "vectorselectiontool.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzQt includes
Toshihiro Shimizu 890ddd
#include "toonzqt/tselectionhandle.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/selectioncommandids.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/tscenehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelhandle.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "tundo.h"
Toshihiro Shimizu 890ddd
#include "tthreadmessage.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qmenu></qmenu>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void groupWithoutUndo(TVectorImage *vimg, StrokeSelection *selection) {
Shinya Kitaoka 120a6e
  int count = 0, fromStroke = -1, lastSelected = -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int i = 0; i < (int)vimg->getStrokeCount(); i++)
Shinya Kitaoka 120a6e
    if (selection->isSelected(i)) {
Shinya Kitaoka 120a6e
      if (fromStroke == -1)
Shinya Kitaoka 120a6e
        fromStroke = i;
Shinya Kitaoka 120a6e
      else if (lastSelected != i - 1)  // non sono contigui gli stroke
Shinya Kitaoka 120a6e
                                       // selezionati: faccio affiorare quelli
Shinya Kitaoka 120a6e
                                       // sotto
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        int j = 0;
Shinya Kitaoka 120a6e
        for (j = 0; j < count; j++) selection->select(fromStroke + j, false);
Shinya Kitaoka 120a6e
        vimg->moveStrokes(fromStroke, count, i);
Shinya Kitaoka 120a6e
        fromStroke = i - count;
Shinya Kitaoka 120a6e
        for (j = 0; j < count; j++) selection->select(fromStroke + j, true);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      lastSelected = i;
Shinya Kitaoka 120a6e
      count++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(count > 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  vimg->group(fromStroke, count);
Shinya Kitaoka 120a6e
  TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ungroupWithoutUndo(TVectorImage *vimg, StrokeSelection *selection) {
Shinya Kitaoka 120a6e
  for (int i = 0; i < (int)vimg->getStrokeCount();)
Shinya Kitaoka 120a6e
    if (selection->isSelected(i)) {
Shinya Kitaoka 120a6e
      if (!vimg->isStrokeGrouped(i)) {
Shinya Kitaoka 120a6e
        i++;
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      i += vimg->ungroup(i);
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      i++;
Shinya Kitaoka 120a6e
  TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// GroupUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class GroupUndo final : public ToolUtils::TToolUndo {
Shinya Kitaoka 2a7129
  std::unique_ptr<strokeselection> m_selection;</strokeselection>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  GroupUndo(TXshSimpleLevel *level, const TFrameId &frameId,
Shinya Kitaoka 120a6e
            StrokeSelection *selection)
Shinya Kitaoka 120a6e
      : ToolUtils::TToolUndo(level, frameId), m_selection(selection) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    if (image) ungroupWithoutUndo(image.getPointer(), m_selection.get());
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
    if (image) groupWithoutUndo(image.getPointer(), m_selection.get());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override { return sizeof(*this); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  QString getToolName() override { return QObject::tr("Group"); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// UngroupUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class UngroupUndo final : public ToolUtils::TToolUndo {
Shinya Kitaoka 2a7129
  std::unique_ptr<strokeselection> m_selection;</strokeselection>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  UngroupUndo(TXshSimpleLevel *level, const TFrameId &frameId,
Shinya Kitaoka 120a6e
              StrokeSelection *selection)
Shinya Kitaoka 120a6e
      : ToolUtils::TToolUndo(level, frameId), m_selection(selection) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    if (image) groupWithoutUndo(image.getPointer(), m_selection.get());
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
    if (image) ungroupWithoutUndo(image.getPointer(), m_selection.get());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override { return sizeof(*this); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  QString getToolName() override { return QObject::tr("Ungroup"); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// MoveGroupUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class MoveGroupUndo final : public ToolUtils::TToolUndo {
Shinya Kitaoka 120a6e
  UCHAR m_moveType;
Shinya Kitaoka 120a6e
  int m_refStroke, m_count, m_moveBefore;
Shinya Kitaoka 120a6e
  std::vector<std::pair<tstroke *,="" int="">> m_selectedGroups;</std::pair<tstroke>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  MoveGroupUndo(TXshSimpleLevel *level, const TFrameId &frameId, UCHAR moveType,
Shinya Kitaoka 120a6e
                int refStroke, int count, int moveBefore,
Shinya Kitaoka 120a6e
                const std::vector<std::pair<tstroke *,="" int="">> &selectedGroups)</std::pair<tstroke>
Shinya Kitaoka 120a6e
      : ToolUtils::TToolUndo(level, frameId)
Shinya Kitaoka 120a6e
      , m_moveType(moveType)
Shinya Kitaoka 120a6e
      , m_refStroke(refStroke)
Shinya Kitaoka 120a6e
      , m_count(count)
Shinya Kitaoka 120a6e
      , m_moveBefore(moveBefore)
Shinya Kitaoka 120a6e
      , m_selectedGroups(selectedGroups) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~MoveGroupUndo() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    int refStroke;
Shinya Kitaoka 120a6e
    int moveBefore;
Shinya Kitaoka 120a6e
    switch (m_moveType) {
Shinya Kitaoka 120a6e
    case TGroupCommand::FRONT:
Shinya Kitaoka 120a6e
      refStroke  = m_moveBefore - m_count;
Shinya Kitaoka 120a6e
      moveBefore = m_refStroke;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case TGroupCommand::FORWARD:
Shinya Kitaoka 120a6e
      refStroke  = m_moveBefore - m_count;
Shinya Kitaoka 120a6e
      moveBefore = m_refStroke;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case TGroupCommand::BACK:
Shinya Kitaoka 120a6e
      refStroke  = m_moveBefore;
Shinya Kitaoka 120a6e
      moveBefore = m_refStroke + m_count;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case TGroupCommand::BACKWARD:
Shinya Kitaoka 120a6e
      refStroke  = m_moveBefore;
Shinya Kitaoka 120a6e
      moveBefore = m_refStroke + m_count;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    default:
Shinya Kitaoka 120a6e
      assert(!"group move not defined!");
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    if (!image) return;
Shinya Kitaoka 120a6e
    QMutexLocker lock(image->getMutex());
Shinya Kitaoka 120a6e
    image->moveStrokes(refStroke, m_count, moveBefore);
Shinya Kitaoka 120a6e
    StrokeSelection *selection = dynamic_cast<strokeselection *="">(</strokeselection>
Shinya Kitaoka 120a6e
        TTool::getApplication()->getCurrentSelection()->getSelection());
Shinya Kitaoka 120a6e
    if (selection) {  // Se la selezione corrente e' la StrokeSelection
Shinya Kitaoka 120a6e
      // seleziono gli stroke che ho modificato con l'undo
Shinya Kitaoka 120a6e
      selection->selectNone();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      for (int i = 0; i < (int)m_selectedGroups.size(); i++) {
Shinya Kitaoka 120a6e
        int index = image->getStrokeIndex(m_selectedGroups[i].first);
Shinya Kitaoka 120a6e
        if (index == -1) continue;
Shinya Kitaoka 120a6e
        for (int j = index; j < index + m_selectedGroups[i].second; j++)
Shinya Kitaoka 120a6e
          selection->select(j, true);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    TTool::getApplication()->getCurrentScene()->notifySceneChanged();
Shinya Kitaoka 120a6e
    notifyImageChanged();
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
    if (!image) return;
Shinya Kitaoka 120a6e
    QMutexLocker lock(image->getMutex());
Shinya Kitaoka 120a6e
    image->moveStrokes(m_refStroke, m_count, m_moveBefore);
Shinya Kitaoka 120a6e
    StrokeSelection *selection = dynamic_cast<strokeselection *="">(</strokeselection>
Shinya Kitaoka 120a6e
        TTool::getApplication()->getCurrentSelection()->getSelection());
Shinya Kitaoka 120a6e
    if (selection) {  // Se la selezione corrente e' la StrokeSelection
Shinya Kitaoka 120a6e
      // seleziono gli stroke che ho modificato con il redo
Shinya Kitaoka 120a6e
      selection->selectNone();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      for (int i = 0; i < (int)m_selectedGroups.size(); i++) {
Shinya Kitaoka 120a6e
        int index = image->getStrokeIndex(m_selectedGroups[i].first);
Shinya Kitaoka 120a6e
        if (index == -1) continue;
Shinya Kitaoka 120a6e
        for (int j = index; j < index + m_selectedGroups[i].second; j++)
Shinya Kitaoka 120a6e
          selection->select(j, true);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    TTool::getApplication()->getCurrentScene()->notifySceneChanged();
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override { return sizeof(*this); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  QString getToolName() override { return QObject::tr("Move Group"); }
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
// TGroupCommand
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
std::vector<std::pair<tstroke *,="" int="">> getSelectedGroups(TVectorImage *vimg,</std::pair<tstroke>
Shinya Kitaoka 120a6e
                                                         StrokeSelection *sel) {
Shinya Kitaoka 120a6e
  UINT i, j;
Shinya Kitaoka 120a6e
  std::vector<std::pair<tstroke *,="" int="">> ret;</std::pair<tstroke>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < vimg->getStrokeCount(); i++)
Shinya Kitaoka 120a6e
    if (sel->isSelected(i)) {
Shinya Kitaoka 120a6e
      if (vimg->isStrokeGrouped(i)) {
Shinya Kitaoka 120a6e
        for (j = i + 1; j < vimg->getStrokeCount() && vimg->sameSubGroup(i, j);
Shinya Kitaoka 120a6e
             j++)
Shinya Kitaoka 120a6e
          if (!sel->isSelected(j))
Shinya Kitaoka 120a6e
            return std::vector<std::pair<tstroke *,="" int="">>();</std::pair<tstroke>
Shinya Kitaoka 120a6e
        ret.push_back(std::pair<tstroke *,="" int="">(vimg->getStroke(i), j - i));</tstroke>
Shinya Kitaoka 120a6e
        i = j - 1;
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        ret.push_back(std::pair<tstroke *,="" int="">(vimg->getStroke(i), 1));</tstroke>
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namepsace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UCHAR TGroupCommand::getGroupingOptions() {
Shinya Kitaoka 120a6e
  TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Shinya Kitaoka 120a6e
  if (!tool) return 0;
Shinya Kitaoka 120a6e
  TVectorImage *vimg = dynamic_cast<tvectorimage *="">(tool->getImage(false));</tvectorimage>
Shinya Kitaoka 120a6e
  if (!vimg) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  UCHAR mask = 0;
Shinya Kitaoka 120a6e
  int count  = 0;
Shinya Kitaoka 120a6e
  UINT i, j;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // spostamento: si possono  spostare solo gruppi interi  oppure  stroke   non
Shinya Kitaoka 120a6e
  // gruppate
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<std::pair<tstroke *,="" int="">> strokeIndexes =</std::pair<tstroke>
Shinya Kitaoka 120a6e
      getSelectedGroups(vimg, m_sel);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
  //spostamento: si puo' spostare solo un gruppo(e uno solo per volta) oppure
Shinya Kitaoka 120a6e
una stroke singola  non gruppata
Toshihiro Shimizu 890ddd
for (i=0; i<vimg->getStrokeCount(); i++)</vimg->
Shinya Kitaoka 120a6e
  if (m_sel->isSelected(i))
Toshihiro Shimizu 890ddd
  {
Shinya Kitaoka 120a6e
          if (strokeIndex != -1)
Shinya Kitaoka 120a6e
                  {
Shinya Kitaoka 120a6e
                  if (!vimg->isStrokeGrouped(i) ||
Shinya Kitaoka 120a6e
!vimg->sameSubGroup(strokeIndex, i))
Shinya Kitaoka 120a6e
                          break;
Shinya Kitaoka 120a6e
                  }
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
                  {
Shinya Kitaoka 120a6e
                  strokeIndex = i;
Shinya Kitaoka 120a6e
                  if (vimg->isStrokeGrouped(i))
Shinya Kitaoka 120a6e
                          {
Shinya Kitaoka 120a6e
                          for (j=0; j<vimg->getStrokeCount(); j++)</vimg->
Shinya Kitaoka 120a6e
                                  if (!m_sel->isSelected(j) &&
Shinya Kitaoka 120a6e
vimg->sameSubGroup(i, j))
Shinya Kitaoka 120a6e
                                          break;//non tutto il gruppo e'
Shinya Kitaoka 120a6e
selezionato
Shinya Kitaoka 120a6e
                          if (j<vimg->getStrokeCount())</vimg->
Shinya Kitaoka 120a6e
                                  break;
Shinya Kitaoka 120a6e
                          }
Shinya Kitaoka 120a6e
                  }
Shinya Kitaoka 120a6e
          count++;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
   */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (strokeIndexes.empty()) return 0;  // no stroke selected
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int strokeIndex = vimg->getStrokeIndex(strokeIndexes[0].first);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (strokeIndexes.size() > 1 || strokeIndex > 0) {
Shinya Kitaoka 120a6e
    mask |= BACK;
Shinya Kitaoka 120a6e
    mask |= BACKWARD;
Toshihiro Shimizu 890ddd
  }
Shinya Kitaoka 120a6e
  if (strokeIndexes.size() > 1 ||
Shinya Kitaoka 120a6e
      strokeIndex + strokeIndexes[0].second - 1 <
Shinya Kitaoka 120a6e
          (int)vimg->getStrokeCount() - 1) {
Shinya Kitaoka 120a6e
    mask |= FRONT;
Shinya Kitaoka 120a6e
    mask |= FORWARD;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
if (i == vimg->getStrokeCount())
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
  if (strokeIndex+count<(int)vimg->getStrokeCount())
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
          mask |= FRONT;
Shinya Kitaoka 120a6e
          mask |= FORWARD;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  if (strokeIndex>0)
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
          mask |= BACK;
Shinya Kitaoka 120a6e
          mask |= BACKWARD;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // PER l'UNGROUP: si ungruppa solo se tutti gli stroke selezionati stanno nel
Shinya Kitaoka 120a6e
  // gruppo (anche piu' gruppi insieme)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < vimg->getStrokeCount(); i++) {
Shinya Kitaoka 120a6e
    if (m_sel->isSelected(i)) {
Shinya Kitaoka 120a6e
      if (!vimg->isStrokeGrouped(i)) break;
Shinya Kitaoka 120a6e
      for (j = 0; j < vimg->getStrokeCount(); j++)
Shinya Kitaoka 120a6e
        if (!m_sel->isSelected(j) && vimg->sameSubGroup(i, j)) break;
Shinya Kitaoka 120a6e
      if (j < vimg->getStrokeCount()) break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (i == vimg->getStrokeCount()) mask |= UNGROUP;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // PER il GROUP: si raggruppa solo  se:
Shinya Kitaoka 120a6e
  // //almeno una delle  stroke selezionate non fa parte di gruppi o e' di un
Shinya Kitaoka 120a6e
  // gruppo diverso
Shinya Kitaoka 120a6e
  // e se c'e' una stroke di un gruppo, allora tutto il gruppo della stroke e'
Shinya Kitaoka 120a6e
  // selezionato
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool groupingMakesSense = false;
Shinya Kitaoka 120a6e
  int refStroke           = -1;
Shinya Kitaoka 120a6e
  for (i = 0; i < vimg->getStrokeCount(); i++)
Shinya Kitaoka 120a6e
    if (m_sel->isSelected(i)) {
Shinya Kitaoka 120a6e
      if (vimg->isStrokeGrouped(i)) {
Shinya Kitaoka 120a6e
        if (refStroke == -1)
Shinya Kitaoka 120a6e
          refStroke = i;
Shinya Kitaoka 120a6e
        else if (!vimg->sameSubGroup(refStroke, i))
Shinya Kitaoka 120a6e
          groupingMakesSense = true;  // gli storke selezionati non sono gia'
Shinya Kitaoka 120a6e
                                      // tutti dello stesso gruppo
Shinya Kitaoka 120a6e
        for (j = 0; j < vimg->getStrokeCount(); j++)
Shinya Kitaoka 120a6e
          if (!m_sel->isSelected(j) && vimg->sameGroup(i, j)) return mask;
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        groupingMakesSense = true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (groupingMakesSense) mask |= GROUP;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return mask;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef NUOVO
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UCHAR TGroupCommand::getGroupingOptions() {
Shinya Kitaoka 120a6e
  TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Shinya Kitaoka 120a6e
  if (!tool) return 0;
Shinya Kitaoka 120a6e
  TVectorImage *vimg = dynamic_cast<tvectorimage *="">(tool->getImage(false));</tvectorimage>
Shinya Kitaoka 120a6e
  if (!vimg) return 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int strokeIndex = -1;
Shinya Kitaoka 120a6e
  UCHAR mask      = 0;
Shinya Kitaoka 120a6e
  int count       = 0;
Shinya Kitaoka 120a6e
  UINT i, j;
Shinya Kitaoka 120a6e
  bool valid = true;
Shinya Kitaoka 120a6e
  // spostamento: si puo' spostare solo un gruppo(e uno solo per volta) oppure
Shinya Kitaoka 120a6e
  // una stroke singola  non gruppata
Shinya Kitaoka 120a6e
  std::vector<pair<int, int="">> groups;</pair<int,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < vimg->getStrokeCount() && valid;)
Shinya Kitaoka 120a6e
    if (m_sel->isSelected(i)) {
Shinya Kitaoka 120a6e
      strokeIndex = i;
Shinya Kitaoka 120a6e
      count       = 1;
Shinya Kitaoka 120a6e
      if (vimg->isStrokeGrouped(i)) {
Shinya Kitaoka 120a6e
        for (j = i + 1; j < vimg->getStrokeCount() && valid; j++)
Shinya Kitaoka 120a6e
          if (m_sel->isSelected(j) && vimg->sameSubGroup(i, j))
Shinya Kitaoka 120a6e
            count++;
Shinya Kitaoka 120a6e
          else if (!m_sel->isSelected(j) && vimg->sameSubGroup(i, j))
Shinya Kitaoka 120a6e
            valid = false;  // non tutto il gruppo e' selezionato
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      groups.push_back(pair<int, int="">(strokeIndex, count));</int,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      i = i + count;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (groups.empty()) return 0;  // no stroke selected
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!valid) return 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (strokeIndex + count < (int)vimg->getStrokeCount()) {
Shinya Kitaoka 120a6e
    mask |= FRONT;
Shinya Kitaoka 120a6e
    mask |= FORWARD;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (strokeIndex > 0) {
Shinya Kitaoka 120a6e
    mask |= BACK;
Shinya Kitaoka 120a6e
    mask |= BACKWARD;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // PER l'UNGROUP: si ungruppa solo se tutti gli stroke selezionati stanno nel
Shinya Kitaoka 120a6e
  // gruppo (anche piu' gruppi insieme)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < vimg->getStrokeCount(); i++) {
Shinya Kitaoka 120a6e
    if (m_sel->isSelected(i)) {
Shinya Kitaoka 120a6e
      if (!vimg->isStrokeGrouped(i)) break;
Shinya Kitaoka 120a6e
      for (j = 0; j < vimg->getStrokeCount(); j++)
Shinya Kitaoka 120a6e
        if (!m_sel->isSelected(j) && vimg->sameSubGroup(i, j)) break;
Shinya Kitaoka 120a6e
      if (j < vimg->getStrokeCount()) break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (i == vimg->getStrokeCount()) mask |= UNGROUP;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // PER il GROUP: si raggruppa solo  se:
Shinya Kitaoka 120a6e
  // //almeno una delle  stroke selezionate non fa parte di gruppi o e' di un
Shinya Kitaoka 120a6e
  // gruppo diverso
Shinya Kitaoka 120a6e
  // e se c'e' una stroke di un gruppo, allora tutto il gruppo della stroke e'
Shinya Kitaoka 120a6e
  // selezionato
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool groupingMakesSense = false;
Shinya Kitaoka 120a6e
  int refStroke           = -1;
Shinya Kitaoka 120a6e
  for (i = 0; i < vimg->getStrokeCount(); i++)
Shinya Kitaoka 120a6e
    if (m_sel->isSelected(i)) {
Shinya Kitaoka 120a6e
      if (vimg->isStrokeGrouped(i)) {
Shinya Kitaoka 120a6e
        if (refStroke == -1)
Shinya Kitaoka 120a6e
          refStroke = i;
Shinya Kitaoka 120a6e
        else if (!vimg->sameSubGroup(refStroke, i))
Shinya Kitaoka 120a6e
          groupingMakesSense = true;  // gli storke selezionati non sono gia'
Shinya Kitaoka 120a6e
                                      // tutti dello stesso gruppo
Shinya Kitaoka 120a6e
        for (j = 0; j < vimg->getStrokeCount(); j++)
Shinya Kitaoka 120a6e
          if (!m_sel->isSelected(j) && vimg->sameGroup(i, j)) return mask;
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        groupingMakesSense = true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (groupingMakesSense) mask |= GROUP;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return mask;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGroupCommand::group() {
Shinya Kitaoka 120a6e
  if (!(getGroupingOptions() & GROUP)) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Shinya Kitaoka 120a6e
  if (!tool) return;
Shinya Kitaoka 120a6e
  TVectorImage *vimg = (TVectorImage *)tool->getImage(true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!vimg) return;
Shinya Kitaoka 120a6e
  QMutexLocker lock(vimg->getMutex());
Shinya Kitaoka 120a6e
  groupWithoutUndo(vimg, m_sel);
Shinya Kitaoka 120a6e
  TXshSimpleLevel *level =
Shinya Kitaoka 120a6e
      TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
Shinya Kitaoka 120a6e
  TUndoManager::manager()->add(
Shinya Kitaoka 120a6e
      new GroupUndo(level, tool->getCurrentFid(), new StrokeSelection(*m_sel)));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGroupCommand::enterGroup() {
Shinya Kitaoka 120a6e
  TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Shinya Kitaoka 120a6e
  if (!tool) return;
Shinya Kitaoka 120a6e
  TVectorImage *vimg = (TVectorImage *)tool->getImage(true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!vimg) return;
Shinya Kitaoka 120a6e
  int index = -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int i = 0; i < (int)vimg->getStrokeCount(); i++)
Shinya Kitaoka 120a6e
    if (m_sel->isSelected(i)) {
Shinya Kitaoka 120a6e
      index = i;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (index == -1) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!vimg->canEnterGroup(index)) return;
Shinya Kitaoka 120a6e
  vimg->enterGroup(index);
Shinya Kitaoka 120a6e
  TSelection *selection = TSelection::getCurrent();
Shinya Kitaoka 120a6e
  if (selection) selection->selectNone();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TTool::getApplication()->getCurrentScene()->notifySceneChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGroupCommand::exitGroup() {
Shinya Kitaoka 120a6e
  TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Shinya Kitaoka 120a6e
  if (!tool) return;
Shinya Kitaoka 120a6e
  TVectorImage *vimg = (TVectorImage *)tool->getImage(true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!vimg) return;
Shinya Kitaoka 120a6e
  vimg->exitGroup();
Shinya Kitaoka 120a6e
  TTool::getApplication()->getCurrentScene()->notifySceneChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGroupCommand::ungroup() {
Shinya Kitaoka 120a6e
  if (!(getGroupingOptions() & UNGROUP)) return;
Shinya Kitaoka 120a6e
  TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Shinya Kitaoka 120a6e
  if (!tool) return;
Shinya Kitaoka 120a6e
  TVectorImage *vimg = (TVectorImage *)tool->getImage(true);
Shinya Kitaoka 120a6e
  if (!vimg) return;
Shinya Kitaoka 120a6e
  QMutexLocker lock(vimg->getMutex());
Shinya Kitaoka 120a6e
  ungroupWithoutUndo(vimg, m_sel);
Shinya Kitaoka 120a6e
  TXshSimpleLevel *level =
Shinya Kitaoka 120a6e
      TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
Shinya Kitaoka 120a6e
  TUndoManager::manager()->add(new UngroupUndo(level, tool->getCurrentFid(),
Shinya Kitaoka 120a6e
                                               new StrokeSelection(*m_sel)));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Shinya Kitaoka 120a6e
void computeMovingBounds(TVectorImage*vimg, int fromIndex, int toIndex,
Shinya Kitaoka 120a6e
int&lower, int& upper)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
lower = 0;
Toshihiro Shimizu 890ddd
upper = vimg->getStrokeCount();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int refDepth = vimg->getGroupDepth(fromIndex)-1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
if (refDepth==0)
Toshihiro Shimizu 890ddd
  return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
int i;
Toshihiro Shimizu 890ddd
for (i=fromIndex-1; i>=0; i--)
Toshihiro Shimizu 890ddd
  if (vimg->getCommonGroupDepth(fromIndex, i)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
    lower = i+1;
Toshihiro Shimizu 890ddd
    break;
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
for (i=fromIndex+1; i<vimg->getStrokeCount(); i++)</vimg->
Toshihiro Shimizu 890ddd
  if (vimg->getCommonGroupDepth(fromIndex, i)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
    upper = i;
Toshihiro Shimizu 890ddd
    break;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int commonDepth(TVectorImage *vimg, int index1, int count, int index2) {
Shinya Kitaoka 120a6e
  int i, ret = 1000;
Shinya Kitaoka 120a6e
  for (i = index1; i < index1 + count; i++)
Shinya Kitaoka 120a6e
    ret = std::min(ret, vimg->getCommonGroupDepth(i, index2));
Shinya Kitaoka 120a6e
  return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Shinya Kitaoka 120a6e
bool cantMove1(TVectorImage* vimg, int refStroke, int count, int moveBefore,
Shinya Kitaoka 120a6e
bool rev)
Shinya Kitaoka 120a6e
  {
Toshihiro Shimizu 890ddd
  if (moveBefore<(int)vimg->getStrokeCount() && moveBefore>0 &&
Shinya Kitaoka 120a6e
             vimg->getCommonGroupDepth(moveBefore-1,
Shinya Kitaoka 120a6e
moveBefore)>commonDepth(vimg, refStroke, count, moveBefore) &&
Shinya Kitaoka 120a6e
             vimg->getCommonGroupDepth(moveBefore-1,
Shinya Kitaoka 120a6e
moveBefore)>commonDepth(vimg, refStroke, count, moveBefore-1))
Toshihiro Shimizu 890ddd
    return true;
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  int prev = (rev)?moveBefore:moveBefore-1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (refStroke>0 && commonDepth(vimg, refStroke, count,
Shinya Kitaoka 120a6e
refStroke-1)>commonDepth(vimg, refStroke, count, prev))
Toshihiro Shimizu 890ddd
    return true;
Shinya Kitaoka 120a6e
  if (refStroke+count<(int)vimg->getStrokeCount() && commonDepth(vimg,
Shinya Kitaoka 120a6e
refStroke, count, refStroke+count)>commonDepth(vimg, refStroke, count, prev))
Toshihiro Shimizu 890ddd
    return true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  return false;
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
/*
Toshihiro Shimizu 890ddd
  int i, refStroke=-1, count=0;
Toshihiro Shimizu 890ddd
  for (i=0; i<(int)vimg->getStrokeCount(); i++)
Toshihiro Shimizu 890ddd
    if(m_sel->isSelected(i))
Toshihiro Shimizu 890ddd
      {
Toshihiro Shimizu 890ddd
      assert(refStroke==-1 || i==0  || m_sel->isSelected(i-1));
Toshihiro Shimizu 890ddd
      if (refStroke==-1)
Toshihiro Shimizu 890ddd
        refStroke = i;
Toshihiro Shimizu 890ddd
      count++;
Toshihiro Shimizu 890ddd
      }
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  if(count==0) return;
Toshihiro Shimizu 890ddd
  */
Toshihiro Shimizu 890ddd
shun-iwasawa 27b0cf
static int doMoveGroup(
shun-iwasawa 27b0cf
    UCHAR moveType, TVectorImage *vimg,
shun-iwasawa 27b0cf
    const std::vector<std::pair<tstroke *,="" int="">> &selectedGroups, int index) {</std::pair<tstroke>
Shinya Kitaoka 120a6e
  int refStroke = vimg->getStrokeIndex(selectedGroups[index].first);
Shinya Kitaoka 120a6e
  int count     = selectedGroups[index].second;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int moveBefore;
Shinya Kitaoka 120a6e
  switch (moveType) {
Shinya Kitaoka 120a6e
  case TGroupCommand::FRONT:
Shinya Kitaoka 120a6e
    moveBefore = vimg->getStrokeCount();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    while (moveBefore >= refStroke + count + 1 &&
Shinya Kitaoka 120a6e
           !vimg->canMoveStrokes(refStroke, count, moveBefore))
Shinya Kitaoka 120a6e
      moveBefore--;
Shinya Kitaoka 120a6e
    if (moveBefore == refStroke + count) return -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case TGroupCommand::FORWARD:
Shinya Kitaoka 120a6e
    moveBefore = refStroke + count + 1;
Shinya Kitaoka 120a6e
    while (moveBefore <= (int)vimg->getStrokeCount() &&
Shinya Kitaoka 120a6e
           !vimg->canMoveStrokes(refStroke, count, moveBefore))
Shinya Kitaoka 120a6e
      moveBefore++;
Shinya Kitaoka 120a6e
    if (moveBefore == vimg->getStrokeCount() + 1) return -1;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case TGroupCommand::BACK:
Shinya Kitaoka 120a6e
    moveBefore = 0;
Shinya Kitaoka 120a6e
    while (moveBefore <= refStroke - 1 &&
Shinya Kitaoka 120a6e
           !vimg->canMoveStrokes(refStroke, count, moveBefore))
Shinya Kitaoka 120a6e
      moveBefore++;
Shinya Kitaoka 120a6e
    if (moveBefore == refStroke) return -1;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case TGroupCommand::BACKWARD:
Shinya Kitaoka 120a6e
    moveBefore = refStroke - 1;
Shinya Kitaoka 120a6e
    while (moveBefore >= 0 &&
Shinya Kitaoka 120a6e
           !vimg->canMoveStrokes(refStroke, count, moveBefore))
Shinya Kitaoka 120a6e
      moveBefore--;
Shinya Kitaoka 120a6e
    if (moveBefore == -1) return -1;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    assert(false);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  vimg->moveStrokes(refStroke, count, moveBefore);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TXshSimpleLevel *level =
Shinya Kitaoka 120a6e
      TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
Shinya Kitaoka 120a6e
  TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Shinya Kitaoka 120a6e
  TUndoManager::manager()->add(new MoveGroupUndo(level, tool->getCurrentFid(),
Shinya Kitaoka 120a6e
                                                 moveType, refStroke, count,
Shinya Kitaoka 120a6e
                                                 moveBefore, selectedGroups));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return moveBefore;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGroupCommand::moveGroup(UCHAR moveType) {
Shinya Kitaoka 120a6e
  TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Shinya Kitaoka 120a6e
  if (!tool) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TVectorImage *vimg = (TVectorImage *)tool->getImage(true);
Shinya Kitaoka 120a6e
  if (!vimg) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<std::pair<tstroke *,="" int="">> selectedGroups =</std::pair<tstroke>
Shinya Kitaoka 120a6e
      getSelectedGroups(vimg, m_sel);
Shinya Kitaoka 120a6e
  if (selectedGroups.empty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int i, j;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TUndoManager::manager()->beginBlock();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  switch (moveType) {
Shinya Kitaoka 120a6e
  case TGroupCommand::FRONT:
Shinya Kitaoka 120a6e
  case TGroupCommand::BACKWARD:
Shinya Kitaoka 120a6e
    i = 0;
Shinya Kitaoka 120a6e
    if (moveType == TGroupCommand::BACKWARD &&
Shinya Kitaoka 120a6e
        vimg->getStrokeIndex(selectedGroups[i].first) ==
Shinya Kitaoka 120a6e
            0)  // tutti i gruppi adiacenti gia in fondo non possono essere
Shinya Kitaoka 120a6e
                // backwardati
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      i++;
Shinya Kitaoka 120a6e
      while (i < (int)selectedGroups.size() &&
Shinya Kitaoka 120a6e
             vimg->getStrokeIndex(selectedGroups[i - 1].first) +
Shinya Kitaoka 120a6e
                     selectedGroups[i - 1].second - 1 ==
Shinya Kitaoka 120a6e
                 vimg->getStrokeIndex(selectedGroups[i].first) - 1)
Shinya Kitaoka 120a6e
        i++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (; i <= (int)selectedGroups.size() - 1; i++)
Shinya Kitaoka 120a6e
      doMoveGroup(moveType, vimg, selectedGroups,
Shinya Kitaoka 120a6e
                  i);  // vimg->getStrokeIndex(selectedGroups[i].first),
Shinya Kitaoka 120a6e
                       // selectedGroups[i].second);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TGroupCommand::BACK:
Shinya Kitaoka 120a6e
  case TGroupCommand::FORWARD:
Shinya Kitaoka 120a6e
    i = selectedGroups.size() - 1;
Shinya Kitaoka 120a6e
    if (moveType == TGroupCommand::FORWARD &&
Shinya Kitaoka 120a6e
        vimg->getStrokeIndex(selectedGroups[i].first) +
Shinya Kitaoka 120a6e
                selectedGroups[i].second - 1 ==
Shinya Kitaoka 120a6e
            vimg->getStrokeCount() - 1)  // tutti i gruppi adiacenti gia in cime
Shinya Kitaoka 120a6e
                                         // non possono essere forwardati
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      i--;
Shinya Kitaoka 120a6e
      while (i >= 0 &&
Shinya Kitaoka 120a6e
             vimg->getStrokeIndex(selectedGroups[i + 1].first) - 1 ==
Shinya Kitaoka 120a6e
                 vimg->getStrokeIndex(selectedGroups[i].first) +
Shinya Kitaoka 120a6e
                     selectedGroups[i].second - 1)
Shinya Kitaoka 120a6e
        i--;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (; i >= 0; i--) doMoveGroup(moveType, vimg, selectedGroups, i);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    assert(false);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TUndoManager::manager()->endBlock();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_sel->selectNone();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < (int)selectedGroups.size(); i++) {
Shinya Kitaoka 120a6e
    int index = vimg->getStrokeIndex(selectedGroups[i].first);
Shinya Kitaoka 120a6e
    for (j = index; j < index + selectedGroups[i].second; j++)
Shinya Kitaoka 120a6e
      m_sel->select(j, true);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  tool->notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGroupCommand::addMenuItems(QMenu *menu) {
Shinya Kitaoka 120a6e
  UCHAR optionMask = getGroupingOptions();
Shinya Kitaoka 120a6e
  if (optionMask == 0) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  CommandManager *cm = CommandManager::instance();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (optionMask & TGroupCommand::GROUP)
Shinya Kitaoka 120a6e
    menu->addAction(cm->getAction(MI_Group));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (optionMask & TGroupCommand::UNGROUP)
Shinya Kitaoka 120a6e
    menu->addAction(cm->getAction(MI_Ungroup));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (optionMask & (TGroupCommand::GROUP | TGroupCommand::UNGROUP) &&
Shinya Kitaoka 120a6e
      optionMask & (TGroupCommand::FORWARD | TGroupCommand::BACKWARD))
Shinya Kitaoka 120a6e
    menu->addSeparator();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (optionMask & TGroupCommand::FORWARD) {
Shinya Kitaoka 120a6e
    menu->addAction(cm->getAction(MI_BringToFront));
Shinya Kitaoka 120a6e
    menu->addAction(cm->getAction(MI_BringForward));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (optionMask & TGroupCommand::BACKWARD) {
Shinya Kitaoka 120a6e
    menu->addAction(cm->getAction(MI_SendBack));
Shinya Kitaoka 120a6e
    menu->addAction(cm->getAction(MI_SendBackward));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  menu->addSeparator();
Toshihiro Shimizu 890ddd
}