Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
#include "tfilepath_io.h"
Toshihiro Shimizu 890ddd
#include "tfunctorinvoker.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzBase incudes
Toshihiro Shimizu 890ddd
#include "tunit.h"
Toshihiro Shimizu 890ddd
#include "tparamcontainer.h"
Toshihiro Shimizu 890ddd
#include "tparamset.h"
Toshihiro Shimizu 890ddd
#include "tmacrofx.h"
Toshihiro Shimizu 890ddd
#include "tparamchange.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzExt includes
Toshihiro Shimizu 890ddd
#include "ext/plasticskeleton.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/tstageobjecttree.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheet.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheethandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/fxdag.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshzeraryfxcolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/tcolumnfx.h"
Toshihiro Shimizu 890ddd
#include "toonz/tfxhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tobjecthandle.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzQt includes
Toshihiro Shimizu 890ddd
#include "toonzqt/functionviewer.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/dvdialog.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/gutil.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/plasticvertexselection.h"
Toshihiro Shimizu 890ddd
#include "tw/stringtable.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qmenu></qmenu>
Toshihiro Shimizu 890ddd
#include <qaction></qaction>
Toshihiro Shimizu 890ddd
#include <qfiledialog></qfiledialog>
Toshihiro Shimizu 890ddd
#include <qmouseevent></qmouseevent>
Toshihiro Shimizu 890ddd
#include <qmetaobject></qmetaobject>
Toshihiro Shimizu 890ddd
#include <qcolor></qcolor>
Shinya Kitaoka 120a6e
#include <qapplication>  // for drag&drop</qapplication>
Toshihiro Shimizu 890ddd
#include <qdrag></qdrag>
Toshihiro Shimizu 890ddd
#include <qmimedata></qmimedata>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonzqt/functiontreeviewer.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*************************************************************************************
Toshihiro Shimizu 890ddd
//    ChannelGroup specialization  definition
Toshihiro Shimizu 890ddd
//*************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class ParamChannelGroup final : public FunctionTreeModel::ParamWrapper,
Shinya Kitaoka d1f6c4
                                public FunctionTreeModel::ChannelGroup {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ParamChannelGroup(TParam *param, const std::wstring &fxId,
Shinya Kitaoka 120a6e
                    std::string ¶mName);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  void refresh() override;
Shinya Kitaoka 473e70
  void *getInternalPointer() const override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class StageObjectChannelGroup final : public FunctionTreeModel::ChannelGroup {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TStageObject *m_stageObject;  //!< (not owned) Referenced stage object
Shinya Kitaoka 120a6e
  FunctionTreeModel::ChannelGroup
Shinya Kitaoka 120a6e
      *m_plasticGroup;  //!< (not owned) Eventual plastic channels group
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  StageObjectChannelGroup(TStageObject *pegbar);
Shinya Kitaoka 120a6e
  ~StageObjectChannelGroup();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  QString getShortName() const override;
Shinya Kitaoka 473e70
  QString getLongName() const override;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  QString getIdName() const override;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  void *getInternalPointer() const override {
Shinya Kitaoka 120a6e
    return static_cast<void *="">(m_stageObject);</void>
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TStageObject *getStageObject() const { return m_stageObject; }
Shinya Kitaoka 473e70
  QVariant data(int role) const override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class SkVDChannelGroup final : public FunctionTreeModel::ChannelGroup {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  StageObjectChannelGroup *m_stageObjectGroup;  //!< Parent stage object group
Shinya Kitaoka 120a6e
  const QString *m_vxName;                      //!< The associated vertex name
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  SkVDChannelGroup(const QString *vxName, StageObjectChannelGroup *stageGroup)
Shinya Kitaoka 120a6e
      : ChannelGroup(*vxName)
Shinya Kitaoka 120a6e
      , m_stageObjectGroup(stageGroup)
Shinya Kitaoka 120a6e
      , m_vxName(vxName) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 38fd86
  QString getShortName() const override {
Shinya Kitaoka 38fd86
    return m_stageObjectGroup->getShortName();
Shinya Kitaoka 38fd86
  }
Shinya Kitaoka 473e70
  QString getLongName() const override { return *m_vxName; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  void *getInternalPointer() const override { return (void *)m_vxName; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  static inline bool compareStr(const TreeModel::Item *item,
Shinya Kitaoka 120a6e
                                const QString &str) {
Shinya Kitaoka 120a6e
    const QString &thisStr =
Shinya Kitaoka 120a6e
        static_cast<const *="" skvdchannelgroup="">(item)->getLongName();</const>
Shinya Kitaoka 120a6e
    return (QString::localeAwareCompare(thisStr, str) < 0);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  QVariant data(int role) const override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// ChannelGroup
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FunctionTreeModel::ChannelGroup::ChannelGroup(const QString &name)
Shinya Kitaoka 120a6e
    : m_name(name), m_showFilter(ShowAllChannels) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FunctionTreeModel::ChannelGroup::~ChannelGroup() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool FunctionTreeModel::ChannelGroup::isActive() const {
Shinya Kitaoka 120a6e
  // Analyze children. If one is active, this is active too.
Shinya Kitaoka 120a6e
  int c, childCount = getChildCount();
Shinya Kitaoka 120a6e
  for (c = 0; c != childCount; ++c)
Shinya Kitaoka 120a6e
    if (static_cast<item *="">(getChild(c))->isActive()) return true;</item>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool FunctionTreeModel::ChannelGroup::isAnimated() const {
Shinya Kitaoka 120a6e
  // Same for the animated feature, this is animate if any of its children is.
Shinya Kitaoka 120a6e
  int c, childCount = getChildCount();
Shinya Kitaoka 120a6e
  for (c = 0; c != childCount; ++c)
Shinya Kitaoka 120a6e
    if (static_cast<item *="">(getChild(c))->isAnimated()) return true;</item>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QVariant FunctionTreeModel::ChannelGroup::data(int role) const {
Shinya Kitaoka 120a6e
  if (role == Qt::DisplayRole)
Shinya Kitaoka 120a6e
    return getLongName();
Shinya Kitaoka 120a6e
  else if (role == Qt::DecorationRole) {
Shinya Kitaoka 120a6e
    bool animated = isAnimated();
Shinya Kitaoka 120a6e
    bool active   = isActive();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (active) {
shun_iwasawa 3cc41f
      static QIcon folderAnimOpen(":Resources/folderanim_open.svg");
shun_iwasawa 3cc41f
      static QIcon folderAnimClose(":Resources/folderanim_close.svg");
shun_iwasawa 3cc41f
      static QIcon folderOpen(":Resources/folder_open.svg");
shun_iwasawa 3cc41f
      static QIcon folderClose(":Resources/folder_close.svg");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      return animated ? isOpen() ? folderAnimOpen : folderAnimClose
Shinya Kitaoka 120a6e
                      : isOpen() ? folderOpen : folderClose;
Shinya Kitaoka 120a6e
    } else {
shun_iwasawa 3cc41f
      static QIcon folderAnimOpen(":Resources/folderanim_open_off.svg");
shun_iwasawa 3cc41f
      static QIcon folderAnimClose(":Resources/folderanim_close_off.svg");
shun_iwasawa 3cc41f
      static QIcon folderOpen(":Resources/folder_open_off.svg");
shun_iwasawa 3cc41f
      static QIcon folderClose(":Resources/folder_close_off.svg");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      return animated ? isOpen() ? folderAnimOpen : folderAnimClose
Shinya Kitaoka 120a6e
                      : isOpen() ? folderOpen : folderClose;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return Item::data(role);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! \todo     This is \a not recursive - I guess it should be...?
Shinya Kitaoka 120a6e
void FunctionTreeModel::ChannelGroup::applyShowFilter() {
Shinya Kitaoka 120a6e
  int i, itemCount = getChildCount();
Shinya Kitaoka 120a6e
  for (i = 0; i < itemCount; i++) {
Shinya Kitaoka 120a6e
    FunctionTreeModel::Channel *channel =
Shinya Kitaoka 120a6e
        dynamic_cast<functiontreemodel::channel *="">(getChild(i));</functiontreemodel::channel>
Shinya Kitaoka 120a6e
    /*--- ChannelGroupの内部も同じフィルタで更新する ---*/
Shinya Kitaoka 120a6e
    if (!channel) {
Shinya Kitaoka 120a6e
      FunctionTreeModel::ChannelGroup *channelGroup =
Shinya Kitaoka 120a6e
          dynamic_cast<functiontreemodel::channelgroup *="">(getChild(i));</functiontreemodel::channelgroup>
Shinya Kitaoka 120a6e
      if (!channelGroup) continue;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      channelGroup->setShowFilter(m_showFilter);
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    bool showItem = (m_showFilter == ShowAllChannels) ||
Shinya Kitaoka 120a6e
                    channel->getParam()->hasKeyframes();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    QModelIndex modelIndex = createIndex();
Shinya Kitaoka 120a6e
    getModel()->setRowHidden(i, modelIndex, !showItem);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (!showItem) channel->setIsActive(false);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeModel::ChannelGroup::setShowFilter(ShowFilter showFilter) {
Shinya Kitaoka 120a6e
  m_showFilter = showFilter;
Shinya Kitaoka 120a6e
  applyShowFilter();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QString FunctionTreeModel::ChannelGroup::getIdName() const {
Shinya Kitaoka 120a6e
  QString tmpName = QString(m_name);
Shinya Kitaoka 120a6e
  tmpName.remove(QChar(' '), Qt::CaseInsensitive);
Shinya Kitaoka 120a6e
  tmpName = tmpName.toLower();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  FunctionTreeModel::ChannelGroup *parentGroup =
Shinya Kitaoka 120a6e
      dynamic_cast<functiontreemodel::channelgroup *="">(getParent());</functiontreemodel::channelgroup>
Shinya Kitaoka 120a6e
  if (parentGroup) {
Shinya Kitaoka 120a6e
    return parentGroup->getIdName() + QString(".") + tmpName;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return tmpName;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeModel::ChannelGroup::setChildrenAllActive(bool active) {
Shinya Kitaoka 120a6e
  for (int i = 0; i < getChildCount(); i++) {
Shinya Kitaoka 120a6e
    // for Channel
Shinya Kitaoka 120a6e
    FunctionTreeModel::Channel *channel =
Shinya Kitaoka 120a6e
        dynamic_cast<functiontreemodel::channel *="">(getChild(i));</functiontreemodel::channel>
Shinya Kitaoka 120a6e
    if (channel) {
Shinya Kitaoka 120a6e
      channel->setIsActive(active);
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    // for ChannelGroup
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      FunctionTreeModel::ChannelGroup *channelGroup =
Shinya Kitaoka 120a6e
          dynamic_cast<functiontreemodel::channelgroup *="">(getChild(i));</functiontreemodel::channelgroup>
Shinya Kitaoka 120a6e
      if (channelGroup) {
Shinya Kitaoka 120a6e
        channelGroup->setChildrenAllActive(active);
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// StageObjectChannelGroup
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
StageObjectChannelGroup::StageObjectChannelGroup(TStageObject *stageObject)
Shinya Kitaoka 120a6e
    : m_stageObject(stageObject), m_plasticGroup() {
Shinya Kitaoka 120a6e
  m_stageObject->addRef();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
StageObjectChannelGroup::~StageObjectChannelGroup() {
Shinya Kitaoka 120a6e
  m_stageObject->release();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QVariant StageObjectChannelGroup::data(int role) const {
Shinya Kitaoka 120a6e
  if (role == Qt::DisplayRole) {
Shinya Kitaoka 120a6e
    std::string name = m_stageObject->getName();
Shinya Kitaoka 120a6e
    std::string id   = m_stageObject->getId().toString();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    return (name == id) ? QString::fromStdString(name)
Shinya Kitaoka 120a6e
                        : QString::fromStdString(id + " (" + name + ")");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  } else if (role == Qt::ForegroundRole) {
Shinya Kitaoka 120a6e
    FunctionTreeModel *model = dynamic_cast<functiontreemodel *="">(getModel());</functiontreemodel>
Shinya Kitaoka 120a6e
    if (!model)
Toshihiro Shimizu 890ddd
#if QT_VERSION >= 0x050000
Shinya Kitaoka 120a6e
      return QColor(Qt::black);
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
      return Qt::black;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    FunctionTreeView *view = dynamic_cast<functiontreeview *="">(model->getView());</functiontreeview>
Shinya Kitaoka 120a6e
    if (!view || !model->getCurrentStageObject())
Toshihiro Shimizu 890ddd
#if QT_VERSION >= 0x050000
Shinya Kitaoka 120a6e
      return QColor(Qt::black);
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
      return Qt::black;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    TStageObjectId currentId = model->getCurrentStageObject()->getId();
Shinya Kitaoka 120a6e
    return m_stageObject->getId() == currentId ? view->getCurrentTextColor()
Shinya Kitaoka 120a6e
                                               : view->getTextColor();
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return ChannelGroup::data(role);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QString StageObjectChannelGroup::getShortName() const {
Shinya Kitaoka 120a6e
  return QString::fromStdString(m_stageObject->getName());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QString StageObjectChannelGroup::getLongName() const {
Shinya Kitaoka 120a6e
  return QString::fromStdString(m_stageObject->getFullName());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QString StageObjectChannelGroup::getIdName() const {
Shinya Kitaoka 120a6e
  return QString::fromStdString(m_stageObject->getId().toString()).toLower();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// FxChannelGroup
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FxChannelGroup::FxChannelGroup(TFx *fx) : m_fx(fx) {
Shinya Kitaoka 120a6e
  if (m_fx) m_fx->addRef();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FxChannelGroup::~FxChannelGroup() {
Shinya Kitaoka 120a6e
  if (m_fx) m_fx->release();
Shinya Kitaoka 120a6e
  m_fx = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QString FxChannelGroup::getShortName() const {
Shinya Kitaoka 120a6e
  return QString::fromStdWString(m_fx->getFxId());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QString FxChannelGroup::getLongName() const {
Shinya Kitaoka 120a6e
  return QString::fromStdWString(m_fx->getFxId());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QVariant FxChannelGroup::data(int role) const {
Shinya Kitaoka 120a6e
  if (role == Qt::DecorationRole) {
Shinya Kitaoka 120a6e
    bool isAnimated                 = false;
Shinya Kitaoka 120a6e
    TParamContainer *paramContainer = m_fx->getParams();
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 0; i < paramContainer->getParamCount(); i++) {
Shinya Kitaoka 120a6e
      if (!paramContainer->getParam(i)->hasKeyframes()) continue;
Shinya Kitaoka 120a6e
      isAnimated = true;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    bool isOneChildActive = false;
Shinya Kitaoka 120a6e
    for (i = 0; i < getChildCount(); i++) {
Shinya Kitaoka 120a6e
      FunctionTreeModel::Channel *channel =
Shinya Kitaoka 120a6e
          dynamic_cast<functiontreemodel::channel *="">(getChild(i));</functiontreemodel::channel>
Shinya Kitaoka 120a6e
      if (!channel || !channel->isActive()) continue;
Shinya Kitaoka 120a6e
      isOneChildActive = true;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (isOneChildActive) {
shun_iwasawa 3cc41f
      static QIcon folderAnimOpen(":Resources/folderanim_open.svg");
shun_iwasawa 3cc41f
      static QIcon folderAnimClose(":Resources/folderanim_close.svg");
shun_iwasawa 3cc41f
      static QIcon folderOpen(":Resources/folder_open.svg");
shun_iwasawa 3cc41f
      static QIcon folderClose(":Resources/folder_close.svg");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      return isAnimated ? isOpen() ? folderAnimOpen : folderAnimClose
Shinya Kitaoka 120a6e
                        : isOpen() ? folderOpen : folderClose;
Shinya Kitaoka 120a6e
    } else {
shun_iwasawa 3cc41f
      static QIcon folderAnimOpen(":Resources/folderanim_open_off.svg");
shun_iwasawa 3cc41f
      static QIcon folderAnimClose(":Resources/folderanim_close_off.svg");
shun_iwasawa 3cc41f
      static QIcon folderOpen(":Resources/folder_open_off.svg");
shun_iwasawa 3cc41f
      static QIcon folderClose(":Resources/folder_close_off.svg");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      return isAnimated ? isOpen() ? folderAnimOpen : folderAnimClose
Shinya Kitaoka 120a6e
                        : isOpen() ? folderOpen : folderClose;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else if (role == Qt::DisplayRole) {
Shinya Kitaoka 120a6e
    std::wstring name = m_fx->getName();
Shinya Kitaoka 120a6e
    std::wstring id   = m_fx->getFxId();
Shinya Kitaoka 120a6e
    if (name == id)
Shinya Kitaoka 120a6e
      return QString::fromStdWString(name);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      return QString::fromStdWString(id + L" (" + name + L")");
Shinya Kitaoka 120a6e
  } else if (role == Qt::ForegroundRole) {
Shinya Kitaoka 120a6e
    FunctionTreeModel *model = dynamic_cast<functiontreemodel *="">(getModel());</functiontreemodel>
Shinya Kitaoka 120a6e
    if (!model)
Toshihiro Shimizu 890ddd
#if QT_VERSION >= 0x050000
Shinya Kitaoka 120a6e
      return QColor(Qt::black);
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
      return Qt::black;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    FunctionTreeView *view = dynamic_cast<functiontreeview *="">(model->getView());</functiontreeview>
Shinya Kitaoka 120a6e
    if (!view)
Toshihiro Shimizu 890ddd
#if QT_VERSION >= 0x050000
Shinya Kitaoka 120a6e
      return QColor(Qt::black);
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
      return Qt::black;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    TFx *currentFx = model->getCurrentFx();
Shinya Kitaoka 120a6e
    return m_fx == currentFx ? view->getCurrentTextColor()
Shinya Kitaoka 120a6e
                             : view->getTextColor();
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return Item::data(role);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QString FxChannelGroup::getIdName() const {
Shinya Kitaoka 120a6e
  return QString::fromStdWString(m_fx->getFxId()).toLower();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FxChannelGroup::refresh() {
Shinya Kitaoka 120a6e
  TMacroFx *macroFx = dynamic_cast<tmacrofx *="">(m_fx);</tmacrofx>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int i, childrenCount = getChildCount();
Shinya Kitaoka 120a6e
  for (i = 0; i < childrenCount; ++i) {
Shinya Kitaoka 120a6e
    FunctionTreeModel::ParamWrapper *wrap =
Shinya Kitaoka 120a6e
        dynamic_cast<functiontreemodel::paramwrapper *="">(getChild(i));</functiontreemodel::paramwrapper>
Shinya Kitaoka 120a6e
    assert(wrap);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TParam *param = 0;
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      TParamContainer *paramContainer = 0;
Shinya Kitaoka 120a6e
      if (macroFx) {
Shinya Kitaoka 120a6e
        const std::wstring &fxId = wrap->getFxId();
Shinya Kitaoka 120a6e
        TFx *subFx               = macroFx->getFxById(fxId);
Shinya Kitaoka 120a6e
        if (!subFx) continue;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        paramContainer = subFx->getParams();
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        paramContainer = m_fx->getParams();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      param = paramContainer->getParam(wrap->getParam()->getName());
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    assert(param);
Shinya Kitaoka 120a6e
    wrap->setParam(param);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ParamChannelGroup *paramGroup = dynamic_cast<paramchannelgroup *="">(wrap);</paramchannelgroup>
Shinya Kitaoka 120a6e
    if (paramGroup) paramGroup->refresh();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// ParamChannelGroup
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ParamChannelGroup::ParamChannelGroup(TParam *param, const std::wstring &fxId,
Shinya Kitaoka 120a6e
                                     std::string ¶mName)
Shinya Kitaoka 120a6e
    : ParamWrapper(param, fxId)
Shinya Kitaoka 120a6e
    , ChannelGroup(
Shinya Kitaoka 120a6e
          param->hasUILabel()
Shinya Kitaoka 120a6e
              ? QString::fromStdString(param->getUILabel())
Shinya Kitaoka 120a6e
              : QString::fromStdWString(TStringTable::translate(paramName))) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void *ParamChannelGroup::getInternalPointer() const {
Shinya Kitaoka 120a6e
  return this->m_param.getPointer();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ParamChannelGroup::refresh() {
Shinya Kitaoka 120a6e
  TParamSet *paramSet = dynamic_cast<tparamset *="">(m_param.getPointer());</tparamset>
Shinya Kitaoka 120a6e
  if (!paramSet) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int c, childrenCount = getChildCount();
Shinya Kitaoka 120a6e
  for (c = 0; c < childrenCount; ++c) {
Shinya Kitaoka 120a6e
    FunctionTreeModel::ParamWrapper *wrap =
Shinya Kitaoka 120a6e
        dynamic_cast<functiontreemodel::paramwrapper *="">(getChild(c));</functiontreemodel::paramwrapper>
Shinya Kitaoka 120a6e
    assert(wrap);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TParamP currentParam = wrap->getParam();
Shinya Kitaoka 120a6e
    assert(currentParam);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    int p = paramSet->getParamIdx(wrap->getParam()->getName());
Shinya Kitaoka 120a6e
    assert(p < paramSet->getParamCount());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TParamP param = paramSet->getParam(p);
Shinya Kitaoka 120a6e
    wrap->setParam(param);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// SkVDChannelGroup
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QVariant SkVDChannelGroup::data(int role) const {
Shinya Kitaoka 120a6e
  if (role == Qt::ForegroundRole) {
Shinya Kitaoka 120a6e
    // Check whether current selection is a PlasticVertex one - in case, paint
Shinya Kitaoka 120a6e
    // it red
Shinya Kitaoka 120a6e
    // if this group refers to current vertex
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (PlasticVertexSelection *vxSel =
Shinya Kitaoka 120a6e
            dynamic_cast<plasticvertexselection *="">(TSelection::getCurrent()))</plasticvertexselection>
Shinya Kitaoka 120a6e
      if (TStageObject *obj = static_cast<functiontreemodel *="">(getModel())</functiontreemodel>
Shinya Kitaoka 120a6e
                                  ->getCurrentStageObject())
Shinya Kitaoka 120a6e
        if (obj == m_stageObjectGroup->m_stageObject)
Shinya Kitaoka 120a6e
          if (const SkDP &sd = obj->getPlasticSkeletonDeformation()) {
Shinya Kitaoka 120a6e
            int vIdx = *vxSel;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
            if (vIdx >= 0 &&
Shinya Kitaoka 120a6e
                sd->skeleton(vxSel->skeletonId())->vertex(vIdx).name() ==
Shinya Kitaoka 120a6e
                    getLongName())
Toshihiro Shimizu 890ddd
#if QT_VERSION >= 0x050000
Shinya Kitaoka 120a6e
              return QColor(Qt::red);
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
              return Qt::red;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
          }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if QT_VERSION >= 0x050000
Shinya Kitaoka 120a6e
    return QColor(Qt::black);
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
    return Qt::black;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return ChannelGroup::data(role);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// Channel
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FunctionTreeModel::Channel::Channel(FunctionTreeModel *model,
Shinya Kitaoka 120a6e
                                    TDoubleParam *param,
Shinya Kitaoka 120a6e
                                    std::string paramNamePref,
Shinya Kitaoka 120a6e
                                    std::wstring fxId)
Shinya Kitaoka 120a6e
    : ParamWrapper(param, fxId)
Shinya Kitaoka 120a6e
    , m_model(model)
Shinya Kitaoka 120a6e
    , m_group(0)
Shinya Kitaoka 120a6e
    , m_isActive(false)
Shinya Kitaoka 120a6e
    , m_paramNamePref(paramNamePref) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FunctionTreeModel::Channel::~Channel() {
Shinya Kitaoka 120a6e
  m_model->onChannelDestroyed(this);
Shinya Kitaoka 120a6e
  if (m_isActive) getParam()->removeObserver(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void *FunctionTreeModel::Channel::getInternalPointer() const {
Shinya Kitaoka 120a6e
  return this->m_param.getPointer();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool FunctionTreeModel::Channel::isAnimated() const {
Shinya Kitaoka 120a6e
  return m_param->hasKeyframes();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QVariant FunctionTreeModel::Channel::data(int role) const {
Shinya Kitaoka 120a6e
  if (role == Qt::DecorationRole) {
shun_iwasawa 3cc41f
    static QIcon paramAnimOn(":Resources/paramanim_on.svg");
shun_iwasawa 3cc41f
    static QIcon paramAnimOff(":Resources/paramanim_off.svg");
shun_iwasawa 3cc41f
    static QIcon paramOn(":Resources/param_on.svg");
shun_iwasawa 3cc41f
    static QIcon paramOff(":Resources/param_off.svg");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    return m_param->hasKeyframes() ? isActive() ? paramAnimOn : paramAnimOff
Shinya Kitaoka 120a6e
                                   : isActive() ? paramOn : paramOff;
Shinya Kitaoka 120a6e
  } else if (role == Qt::DisplayRole) {
Shinya Kitaoka 120a6e
    if (m_param->hasUILabel()) {
Shinya Kitaoka 120a6e
      return QString::fromStdString(m_param->getUILabel());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    std::string name            = m_paramNamePref + m_param->getName();
Shinya Kitaoka 120a6e
    std::wstring translatedName = TStringTable::translate(name);
Shinya Kitaoka 120a6e
    if (m_fxId.size() > 0)
Shinya Kitaoka 120a6e
      return QString::fromStdWString(translatedName + L" (" + m_fxId + L")");
Shinya Kitaoka 120a6e
    return QString::fromStdWString(translatedName);
Shinya Kitaoka 120a6e
  } else if (role == Qt::ForegroundRole) {
Shinya Kitaoka 120a6e
    // 130221 iwasawa
Shinya Kitaoka 120a6e
    FunctionTreeView *view = dynamic_cast<functiontreeview *="">(m_model->m_view);</functiontreeview>
Shinya Kitaoka 120a6e
    if (!view)
Toshihiro Shimizu 890ddd
#if QT_VERSION >= 0x050000
Shinya Kitaoka 120a6e
      return QColor(Qt::black);
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
      return Qt::black;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    return (isCurrent()) ? view->getCurrentTextColor() : view->getTextColor();
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return TreeModel::Item::data(role);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QString FunctionTreeModel::Channel::getShortName() const {
Shinya Kitaoka 120a6e
  if (m_param->hasUILabel()) {
Shinya Kitaoka 120a6e
    return QString::fromStdString(m_param->getUILabel());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  std::string name            = m_paramNamePref + m_param->getName();
Shinya Kitaoka 120a6e
  std::wstring translatedName = TStringTable::translate(name);
Shinya Kitaoka 120a6e
  return QString::fromStdWString(translatedName);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QString FunctionTreeModel::Channel::getLongName() const {
Shinya Kitaoka 120a6e
  QString name                = getShortName();
Shinya Kitaoka 120a6e
  if (getChannelGroup()) name = getChannelGroup()->getLongName() + " " + name;
Shinya Kitaoka 120a6e
  return name;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeModel::Channel::setParam(const TParamP ¶m) {
Shinya Kitaoka 120a6e
  if (param.getPointer() == m_param.getPointer()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TParamP oldParam = m_param;
Shinya Kitaoka 120a6e
  m_param          = param;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_isActive) {
Shinya Kitaoka 120a6e
    oldParam->removeObserver(this);
Shinya Kitaoka 120a6e
    param->addObserver(this);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! in order to show the expression name in the tooltip
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
QString FunctionTreeModel::Channel::getExprRefName() const {
Shinya Kitaoka 120a6e
  QString tmpName = QString(QString::fromStdWString(
Shinya Kitaoka 120a6e
      TStringTable::translate(m_paramNamePref + m_param->getName())));
Shinya Kitaoka 120a6e
  /*--- stage
Shinya Kitaoka 120a6e
   * objectパラメータの場合、TableにあわせてtmpNameを代表的なExpression名にする---*/
Shinya Kitaoka 120a6e
  StageObjectChannelGroup *stageGroup =
Shinya Kitaoka 120a6e
      dynamic_cast<stageobjectchannelgroup *="">(m_group);</stageobjectchannelgroup>
Shinya Kitaoka 120a6e
  if (stageGroup) {
Shinya Kitaoka 120a6e
    if (tmpName == "N/S")
Shinya Kitaoka 120a6e
      tmpName = "ns";
Shinya Kitaoka 120a6e
    else if (tmpName == "E/W")
Shinya Kitaoka 120a6e
      tmpName = "ew";
Shinya Kitaoka 120a6e
    else if (tmpName == "Z")
Shinya Kitaoka 120a6e
      tmpName = "z";
Shinya Kitaoka 120a6e
    else if (tmpName == "Rotation")
Shinya Kitaoka 120a6e
      tmpName = "rot";
Shinya Kitaoka 120a6e
    else if (tmpName == "Scale H")
Shinya Kitaoka 120a6e
      tmpName = "sx";
Shinya Kitaoka 120a6e
    else if (tmpName == "Scale V")
Shinya Kitaoka 120a6e
      tmpName = "sy";
Shinya Kitaoka 120a6e
    else if (tmpName == "Shear H")
Shinya Kitaoka 120a6e
      tmpName = "shx";
Shinya Kitaoka 120a6e
    else if (tmpName == "Shear V")
Shinya Kitaoka 120a6e
      tmpName = "shy";
Shinya Kitaoka 120a6e
    else if (tmpName == "posPath")
Shinya Kitaoka 120a6e
      tmpName = "path";
Shinya Kitaoka 120a6e
    else if (tmpName == "Scale")
Shinya Kitaoka 120a6e
      tmpName = "sc";
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      tmpName = tmpName.toLower();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    return stageGroup->getIdName() + QString(".") + tmpName;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
shun_iwasawa b08910
  // expression for fx parameters
shun_iwasawa b08910
  // see txsheetexpr.cpp for generation of actual tokens
shun_iwasawa b08910
Shinya Kitaoka 120a6e
  tmpName.remove(QChar(' '), Qt::CaseInsensitive);
Shinya Kitaoka 120a6e
  tmpName.remove(QChar('/'));
shun_iwasawa b08910
  tmpName.remove(QChar('-'));
Shinya Kitaoka 120a6e
  tmpName = tmpName.toLower();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  FunctionTreeModel::ChannelGroup *parentGroup =
Shinya Kitaoka 120a6e
      dynamic_cast<functiontreemodel::channelgroup *="">(getParent());</functiontreemodel::channelgroup>
Shinya Kitaoka 120a6e
  if (parentGroup) {
Shinya Kitaoka 120a6e
    return QString("fx.") + parentGroup->getIdName() + QString(".") + tmpName;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return "";
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void FunctionTreeModel::Channel::setIsActive(bool active) {
Shinya Kitaoka 120a6e
  if (active == m_isActive) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_isActive = active;
Shinya Kitaoka 120a6e
  m_model->refreshActiveChannels();
Shinya Kitaoka 120a6e
  if (m_isActive) {
Shinya Kitaoka 120a6e
    getParam()->addObserver(this);
Shinya Kitaoka 120a6e
    /*--- これが最初にVisibleにしたChannelの場合 ---*/
Shinya Kitaoka 120a6e
    if (!m_model->m_currentChannel) {
Shinya Kitaoka 120a6e
      setIsCurrent(true);
Shinya Kitaoka 120a6e
      m_model->emitCurveSelected(getParam());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    getParam()->removeObserver(this);
Shinya Kitaoka 120a6e
    if (isCurrent()) {
Shinya Kitaoka 120a6e
      setIsCurrent(false);
Shinya Kitaoka 120a6e
      m_model->emitCurveSelected(0);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_model->emitDataChanged(this);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
bool FunctionTreeModel::Channel::isCurrent() const {
Shinya Kitaoka 120a6e
  return m_model->m_currentChannel == this;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void FunctionTreeModel::Channel::setIsCurrent(bool current) {
Shinya Kitaoka 120a6e
  Channel *oldCurrent = m_model->m_currentChannel;
Shinya Kitaoka 120a6e
  if (current) {
Shinya Kitaoka 120a6e
    // this channel must become the current
Shinya Kitaoka 120a6e
    if (oldCurrent == this) return;  // already it is: nothing to do
Shinya Kitaoka 120a6e
    m_model->m_currentChannel = this;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // change the current fx if the FxChannelGroup is clicked
Shinya Kitaoka 120a6e
    FxChannelGroup *fxGroup = dynamic_cast<fxchannelgroup *="">(m_group);</fxchannelgroup>
Shinya Kitaoka 120a6e
    if (fxGroup && m_model->getFxHandle()) {
Shinya Kitaoka 120a6e
      m_model->getFxHandle()->setFx(fxGroup->getFx());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    // or, change the current object if the stageObjectChannelGroup is clicked
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      StageObjectChannelGroup *stageObjectGroup =
Shinya Kitaoka 120a6e
          dynamic_cast<stageobjectchannelgroup *="">(m_group);</stageobjectchannelgroup>
Shinya Kitaoka 120a6e
      if (stageObjectGroup && m_model->getObjectHandle()) {
Shinya Kitaoka 120a6e
        m_model->getObjectHandle()->setObjectId(
Shinya Kitaoka 120a6e
            stageObjectGroup->getStageObject()->getId());
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // the current channel must be active
Shinya Kitaoka 120a6e
    if (!m_isActive) {
Shinya Kitaoka 120a6e
      m_isActive = true;
Shinya Kitaoka 120a6e
      m_model->refreshActiveChannels();
Shinya Kitaoka 120a6e
      getParam()->addObserver(this);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    // refresh the old current (if !=0) and the new one
Shinya Kitaoka 120a6e
    if (oldCurrent) m_model->emitDataChanged(oldCurrent);
Shinya Kitaoka 120a6e
    m_model->emitDataChanged(this);
Shinya Kitaoka 120a6e
    m_model->emitCurveSelected(getParam());
Shinya Kitaoka 120a6e
    // scroll the column to ensure visible the current channel
Shinya Kitaoka 120a6e
    m_model->emitCurrentChannelChanged(this);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    // this channel is not the current anymore
Shinya Kitaoka 120a6e
    if (oldCurrent != this) return;  // it was not: nothing to do
Shinya Kitaoka 120a6e
    m_model->m_currentChannel = 0;
Shinya Kitaoka 120a6e
    // refresh the channel
Shinya Kitaoka 120a6e
    m_model->emitDataChanged(this);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool FunctionTreeModel::Channel::isHidden() const {
Shinya Kitaoka 120a6e
  return getChannelGroup()->getShowFilter() ==
Shinya Kitaoka 120a6e
             ChannelGroup::ShowAnimatedChannels &&
Shinya Kitaoka 120a6e
         !getParam()->hasKeyframes();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeModel::Channel::onChange(const TParamChange &ch) {
Shinya Kitaoka 120a6e
  m_model->onChange(ch);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// FunctionTreeModel
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FunctionTreeModel::FunctionTreeModel(FunctionTreeView *parent)
Shinya Kitaoka 120a6e
    : TreeModel(parent)
Shinya Kitaoka 120a6e
    , m_currentChannel(0)
Shinya Kitaoka 120a6e
    , m_stageObjects(0)
Shinya Kitaoka 120a6e
    , m_fxs(0)
Shinya Kitaoka 120a6e
    , m_currentStageObject(0)
Shinya Kitaoka 120a6e
    , m_currentFx(0)
Shinya Kitaoka 120a6e
    , m_paramsChanged(false) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FunctionTreeModel::~FunctionTreeModel() {
Shinya Kitaoka 120a6e
  // I must delete items here (not in TreeModel::~TreeModel()).
Shinya Kitaoka 120a6e
  // Channel::~Channel() refers to the model, which should be alive.
Shinya Kitaoka 120a6e
  setRootItem(0);
Shinya Kitaoka 120a6e
  if (m_currentFx) m_currentFx->release();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeModel::refreshData(TXsheet *xsh) {
Shinya Kitaoka 120a6e
  m_activeChannels.clear();
Shinya Kitaoka 120a6e
  Channel *currentChannel = m_currentChannel;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  beginRefresh();
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    if (!getRootItem()) {
Shinya Kitaoka 120a6e
      setRootItem(new ChannelGroup("Root"));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (xsh) {
Shinya Kitaoka 120a6e
        getRootItem()->appendChild(m_stageObjects = new ChannelGroup("Stage"));
Shinya Kitaoka 120a6e
        getRootItem()->appendChild(m_fxs = new ChannelGroup("FX"));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        assert(getRootItem()->getChildCount() == 2);
Shinya Kitaoka 120a6e
        assert(getRootItem()->getChild(0) == m_stageObjects);
Shinya Kitaoka 120a6e
        assert(getRootItem()->getChild(1) == m_fxs);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (xsh) {
Shinya Kitaoka 120a6e
      refreshStageObjects(xsh);
Shinya Kitaoka 120a6e
      refreshFxs(xsh);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    refreshActiveChannels();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  endRefresh();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_currentChannel != currentChannel) emit curveSelected(0);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void FunctionTreeModel::refreshStageObjects(TXsheet *xsh) {
Shinya Kitaoka 120a6e
  static const int channelIds[TStageObject::T_ChannelCount] = {
Shinya Kitaoka 120a6e
      TStageObject::T_X,      TStageObject::T_Y,      TStageObject::T_Z,
Shinya Kitaoka 120a6e
      TStageObject::T_SO,     TStageObject::T_Path,   TStageObject::T_Angle,
Shinya Kitaoka 120a6e
      TStageObject::T_ScaleX, TStageObject::T_ScaleY, TStageObject::T_Scale,
Shinya Kitaoka 120a6e
      TStageObject::T_ShearX, TStageObject::T_ShearY};  // Explicitly ordered
Shinya Kitaoka 120a6e
                                                        // channels
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Retrieve all (not-empty) root stage objects, and add them in the tree model
Shinya Kitaoka 120a6e
  QList<treemodel::item *=""> newItems;</treemodel::item>
Shinya Kitaoka 120a6e
  TStageObjectTree *ptree = xsh->getStageObjectTree();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int i, iCount = ptree->getStageObjectCount();
Shinya Kitaoka 120a6e
  for (i = 0; i < iCount; ++i) {
Shinya Kitaoka 120a6e
    TStageObject *pegbar = ptree->getStageObject(i);
Shinya Kitaoka 120a6e
    TStageObjectId id    = pegbar->getId();
Shinya Kitaoka 120a6e
    if (id.isColumn() && xsh->isColumnEmpty(id.getIndex())) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    newItems.push_back(new StageObjectChannelGroup(pegbar));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*--- newItemsの中で、これまでのChildrenに無いものだけ
Shinya Kitaoka 120a6e
  m_stageObjectsの子に追加。既に有るものはnewChildrenから除外---*/
Shinya Kitaoka 120a6e
  m_stageObjects->setChildren(newItems);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Add channels to the NEW stage entries (see the above call to setChildren())
Shinya Kitaoka 120a6e
  iCount = newItems.size();
Shinya Kitaoka 120a6e
  for (i = 0; i < iCount; ++i) {
Shinya Kitaoka 120a6e
    StageObjectChannelGroup *pegbarItem =
Shinya Kitaoka 120a6e
        dynamic_cast<stageobjectchannelgroup *="">(newItems[i]);</stageobjectchannelgroup>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TStageObject *stageObject = pegbarItem->getStageObject();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Add the standard stage object channels
Shinya Kitaoka 120a6e
    int j, jCount = TStageObject::T_ChannelCount;
Shinya Kitaoka 120a6e
    // making each channel of pegbar
Shinya Kitaoka 120a6e
    for (j = 0; j < jCount; ++j) {
Shinya Kitaoka 120a6e
      TDoubleParam *param =
Shinya Kitaoka 120a6e
          stageObject->getParam((TStageObject::Channel)channelIds[j]);
Shinya Kitaoka 120a6e
      Channel *channel = new Channel(this, param);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      pegbarItem->appendChild(channel);
Shinya Kitaoka 120a6e
      channel->setChannelGroup(pegbarItem);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    pegbarItem->applyShowFilter();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // As plastic deformations are stored in stage objects, refresh them if
Shinya Kitaoka 120a6e
  // necessary
Shinya Kitaoka 120a6e
  refreshPlasticDeformations();
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void FunctionTreeModel::refreshFxs(TXsheet *xsh) {
Shinya Kitaoka 120a6e
  std::vector<tfx *=""> fxs;</tfx>
Shinya Kitaoka 120a6e
  xsh->getFxDag()->getFxs(fxs);
Shinya Kitaoka 120a6e
  for (int i = 0; i < xsh->getColumnCount(); i++) {
Shinya Kitaoka 120a6e
    TXshZeraryFxColumn *zc =
Shinya Kitaoka 120a6e
        dynamic_cast<txshzeraryfxcolumn *="">(xsh->getColumn(i));</txshzeraryfxcolumn>
Shinya Kitaoka 120a6e
    if (!zc) continue;
Shinya Kitaoka 120a6e
    fxs.push_back(zc->getZeraryColumnFx()->getZeraryFx());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // sort items by fxId
Shinya Kitaoka 120a6e
  for (int j = 1; j < (int)fxs.size(); j++) {
Shinya Kitaoka 120a6e
    int index = j;
Shinya Kitaoka 120a6e
    while (index > 0 &&
Shinya Kitaoka 120a6e
           QString::localeAwareCompare(
Shinya Kitaoka 120a6e
               QString::fromStdWString(fxs[index - 1]->getFxId()),
Shinya Kitaoka 120a6e
               QString::fromStdWString(fxs[index]->getFxId())) > 0) {
Shinya Kitaoka 120a6e
      std::swap(fxs[index - 1], fxs[index]);
Shinya Kitaoka 120a6e
      index = index - 1;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QList<treemodel::item *=""> newItems;</treemodel::item>
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < (int)fxs.size(); i++) {
Shinya Kitaoka 120a6e
    TFx *fx = fxs[i];
Shinya Kitaoka 120a6e
    if (!fx) continue;
Shinya Kitaoka 120a6e
    TParamContainer *params = fx->getParams();
Shinya Kitaoka 120a6e
    bool hasChannel         = false;
Shinya Kitaoka 120a6e
    int j;
Shinya Kitaoka 120a6e
    for (j = 0; j < params->getParamCount(); j++)
Shinya Kitaoka 120a6e
      if (0 != dynamic_cast<tdoubleparam *="">(params->getParam(j)) ||</tdoubleparam>
Shinya Kitaoka 120a6e
          0 != dynamic_cast<tpointparam *="">(params->getParam(j)) ||</tpointparam>
Shinya Kitaoka 120a6e
          0 != dynamic_cast<trangeparam *="">(params->getParam(j)) ||</trangeparam>
Shinya Kitaoka 120a6e
          0 != dynamic_cast<tpixelparam *="">(params->getParam(j))) {</tpixelparam>
Shinya Kitaoka 120a6e
        hasChannel = true;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    if (hasChannel) newItems.push_back(new FxChannelGroup(fxs[i]));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_fxs->setChildren(newItems);
Shinya Kitaoka 120a6e
  // Add channels to new fxs (only for those actually added: see setChildren())
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < (int)newItems.size(); i++) {
Shinya Kitaoka 120a6e
    TreeModel::Item *item  = newItems[i];
Shinya Kitaoka 120a6e
    FxChannelGroup *fxItem = dynamic_cast<fxchannelgroup *="">(item);</fxchannelgroup>
Shinya Kitaoka 120a6e
    assert(fxItem);
Shinya Kitaoka 120a6e
    if (!fxItem) continue;
Shinya Kitaoka 120a6e
    TFx *fx = fxItem->getFx();
Shinya Kitaoka 120a6e
    assert(fx);
Shinya Kitaoka 120a6e
    if (!fx) continue;
Shinya Kitaoka 120a6e
    TMacroFx *macroFx = dynamic_cast<tmacrofx *="">(fx);</tmacrofx>
Shinya Kitaoka 120a6e
    if (macroFx) {
Shinya Kitaoka 120a6e
      const std::vector<tfxp> ¯oFxs = macroFx->getFxs();</tfxp>
Shinya Kitaoka 120a6e
      int j;
Shinya Kitaoka 120a6e
      for (j = 0; j < (int)macroFxs.size(); j++) {
Shinya Kitaoka 120a6e
        TParamContainer *params = macroFxs[j]->getParams();
Shinya Kitaoka 120a6e
        addChannels(macroFxs[j].getPointer(), fxItem, params);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      TParamContainer *params = fx->getParams();
Shinya Kitaoka 120a6e
      addChannels(fx, fxItem, params);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    fxItem->applyShowFilter();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void FunctionTreeModel::refreshPlasticDeformations() {
Shinya Kitaoka 120a6e
  // Refresh ALL stage object items (including OLD ones)
Shinya Kitaoka 120a6e
  int i, iCount = m_stageObjects->getChildCount();
Shinya Kitaoka 120a6e
  for (i = 0; i < iCount; ++i) {
Shinya Kitaoka 120a6e
    // Add the eventual Plastic channels group
Shinya Kitaoka 120a6e
    StageObjectChannelGroup *stageItem =
Shinya Kitaoka 120a6e
        static_cast<stageobjectchannelgroup *="">(m_stageObjects->getChild(i));</stageobjectchannelgroup>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TStageObject *stageObject = stageItem->getStageObject();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    const PlasticSkeletonDeformationP &sd =
Shinya Kitaoka 120a6e
        stageObject->getPlasticSkeletonDeformation();
Shinya Kitaoka 120a6e
    FunctionTreeModel::ChannelGroup *&plasticGroup = stageItem->m_plasticGroup;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (sd || plasticGroup) {
Shinya Kitaoka 120a6e
      if (!plasticGroup) {
Shinya Kitaoka 120a6e
        // Add a group
Shinya Kitaoka 120a6e
        plasticGroup = new ChannelGroup("Plastic Skeleton");
Shinya Kitaoka 120a6e
        stageItem->appendChild(plasticGroup);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Prepare each vertex deformation
Shinya Kitaoka 120a6e
      QList<treemodel::item *=""> plasticItems;</treemodel::item>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (sd) {
Shinya Kitaoka 120a6e
        SkD::vd_iterator vdt, vdEnd;
Shinya Kitaoka 120a6e
        sd->vertexDeformations(vdt, vdEnd);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        for (; vdt != vdEnd; ++vdt) {
Shinya Kitaoka 120a6e
          const QString *str = (*vdt).first;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          QList<treemodel::item *="">::iterator it =</treemodel::item>
Shinya Kitaoka 120a6e
              std::lower_bound(plasticItems.begin(), plasticItems.end(), *str,
Shinya Kitaoka 120a6e
                               SkVDChannelGroup::compareStr);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          plasticItems.insert(it, new SkVDChannelGroup(str, stageItem));
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        // Add the channel corresponding to the skeleton id
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          Channel *skelIdsChannel =
Shinya Kitaoka 120a6e
              new Channel(this, sd->skeletonIdsParam().getPointer());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          plasticItems.insert(plasticItems.begin(), skelIdsChannel);
Shinya Kitaoka 120a6e
          skelIdsChannel->setChannelGroup(plasticGroup);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (plasticItems.empty()) plasticGroup->setIsOpen(false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Add the vertex deformations group (this needs to be done BEFORE adding
Shinya Kitaoka 120a6e
      // the actual
Shinya Kitaoka 120a6e
      // channels, seemingly due to a limitation in the TreeModel
Shinya Kitaoka 120a6e
      // implementation)
Shinya Kitaoka 120a6e
      plasticGroup->setChildren(plasticItems);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      int pi,
Shinya Kitaoka 120a6e
          piCount =
Shinya Kitaoka 120a6e
              plasticItems.size();  // NOTE: plasticItems now stores only PART
Shinya Kitaoka 120a6e
      for (pi = 0; pi != piCount;
Shinya Kitaoka 120a6e
           ++pi)  // of the specified items - those considered
Shinya Kitaoka 120a6e
      {           // 'new' by internal pointer comparison...
Shinya Kitaoka 120a6e
        SkVDChannelGroup *vxGroup =
Shinya Kitaoka 120a6e
            dynamic_cast<skvdchannelgroup *="">(plasticItems[pi]);</skvdchannelgroup>
Shinya Kitaoka 120a6e
        if (!vxGroup) continue;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        SkVD *skvd =
Shinya Kitaoka 120a6e
            sd->vertexDeformation(vxGroup->ChannelGroup::getShortName());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        for (int k = 0; k < SkVD::PARAMS_COUNT; ++k) {
Shinya Kitaoka 120a6e
          // Add channel in the vertex deformation
Shinya Kitaoka 120a6e
          Channel *channel = new Channel(this, skvd->m_params[k].getPointer());
Shinya Kitaoka 120a6e
          channel->setChannelGroup(vxGroup);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
          vxGroup->appendChild(channel);
Shinya Kitaoka 120a6e
        }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        vxGroup->applyShowFilter();
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      plasticGroup->applyShowFilter();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeModel::addParameter(ChannelGroup *group,
Shinya Kitaoka 120a6e
                                     const std::string &prefixString,
Shinya Kitaoka 120a6e
                                     const std::wstring &fxId, TParam *param) {
Shinya Kitaoka 120a6e
  if (TDoubleParam *dp = dynamic_cast<tdoubleparam *="">(param)) {</tdoubleparam>
Shinya Kitaoka 120a6e
    Channel *channel = new Channel(this, dp, prefixString, fxId);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    group->appendChild(channel);
Shinya Kitaoka 120a6e
    channel->setChannelGroup(group);
Shinya Kitaoka 120a6e
  } else if (dynamic_cast<tpointparam *="">(param) ||</tpointparam>
Shinya Kitaoka 120a6e
             dynamic_cast<trangeparam *="">(param) ||</trangeparam>
Shinya Kitaoka 120a6e
             dynamic_cast<tpixelparam *="">(param)) {</tpixelparam>
Shinya Kitaoka 120a6e
    TParamSet *paramSet = dynamic_cast<tparamset *="">(param);</tparamset>
Shinya Kitaoka 120a6e
    assert(paramSet);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    std::string paramName = prefixString + param->getName();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ChannelGroup *paramChannel = new ParamChannelGroup(param, fxId, paramName);
Shinya Kitaoka 120a6e
    group->appendChild(paramChannel);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TPixelParam *pixParam = dynamic_cast<tpixelparam *="">(param);</tpixelparam>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    int p, paramCount = paramSet->getParamCount();
Shinya Kitaoka 120a6e
    for (p = 0; p != paramCount; ++p) {
Shinya Kitaoka 120a6e
      TDoubleParam *dp =
Shinya Kitaoka 120a6e
          dynamic_cast<tdoubleparam *="">(paramSet->getParam(p).getPointer());</tdoubleparam>
Shinya Kitaoka 120a6e
      if (!dp ||
Shinya Kitaoka 120a6e
          (pixParam && !pixParam->isMatteEnabled() && p == paramCount - 1))
Shinya Kitaoka 120a6e
        continue;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      Channel *channel = new Channel(this, dp, "", fxId);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      paramChannel->appendChild(channel);
Shinya Kitaoka 120a6e
      channel->setChannelGroup(group);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeModel::addChannels(TFx *fx, ChannelGroup *groupItem,
Shinya Kitaoka 120a6e
                                    TParamContainer *params) {
Shinya Kitaoka 120a6e
  FxChannelGroup *fxItem = static_cast<fxchannelgroup *="">(groupItem);</fxchannelgroup>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::wstring fxId = L"";
Shinya Kitaoka 120a6e
  TMacroFx *macro   = dynamic_cast<tmacrofx *="">(fxItem->getFx());</tmacrofx>
Shinya Kitaoka 120a6e
  if (macro) fxId   = fx->getFxId();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const std::string ¶mNamePref = fx->getFxType() + ".";
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int p, pCount = params->getParamCount();
Shinya Kitaoka 120a6e
  for (p = 0; p != pCount; ++p)
Shinya Kitaoka 120a6e
    addParameter(fxItem, paramNamePref, fxId, params->getParam(p));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeModel::addActiveChannels(TreeModel::Item *item) {
Shinya Kitaoka 120a6e
  assert(item);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (Channel *channel = dynamic_cast<channel *="">(item)) {</channel>
Shinya Kitaoka 120a6e
    if (channel->isActive()) m_activeChannels.push_back(channel);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    for (int i = 0; i < item->getChildCount(); i++)
Shinya Kitaoka 120a6e
      addActiveChannels(item->getChild(i));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeModel::refreshActiveChannels() {
Shinya Kitaoka 120a6e
  m_activeChannels.clear();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_stageObjects) addActiveChannels(m_stageObjects);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_fxs) addActiveChannels(m_fxs);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeModel::onChannelDestroyed(Channel *channel) {
Shinya Kitaoka 120a6e
  if (channel == m_currentChannel) m_currentChannel = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FunctionTreeModel::Channel *FunctionTreeModel::getActiveChannel(
Shinya Kitaoka 120a6e
    int index) const {
Shinya Kitaoka 120a6e
  if (index < 0 || index >= (int)m_activeChannels.size())
Shinya Kitaoka 120a6e
    return 0;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return m_activeChannels[index];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int FunctionTreeModel::getColumnIndexByCurve(TDoubleParam *param) const {
Shinya Kitaoka 120a6e
  for (int i = 0; i < (int)m_activeChannels.size(); i++) {
Shinya Kitaoka 120a6e
    if (m_activeChannels[i]->getParam() == param) return i;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FunctionTreeModel::ChannelGroup *FunctionTreeModel::getStageObjectChannel(
Shinya Kitaoka 120a6e
    int index) const {
Shinya Kitaoka 120a6e
  if (index < 0 || index >= (int)m_stageObjects->getChildCount())
Shinya Kitaoka 120a6e
    return 0;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return dynamic_cast<functiontreemodel::channelgroup *="">(</functiontreemodel::channelgroup>
Shinya Kitaoka 120a6e
        m_stageObjects->getChild(index));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FunctionTreeModel::ChannelGroup *FunctionTreeModel::getFxChannel(
Shinya Kitaoka 120a6e
    int index) const {
Shinya Kitaoka 120a6e
  if (index < 0 || index >= (int)m_fxs->getChildCount())
Shinya Kitaoka 120a6e
    return 0;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return dynamic_cast<functiontreemodel::channelgroup *="">(</functiontreemodel::channelgroup>
Shinya Kitaoka 120a6e
        m_fxs->getChild(index));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeModel::onChange(const TParamChange &tpc) {
Shinya Kitaoka 120a6e
  if (!m_paramsChanged) {
Shinya Kitaoka 120a6e
    m_paramsChanged = true;
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
    struct Func final : public TFunctorInvoker::BaseFunctor {
Shinya Kitaoka 120a6e
      FunctionTreeModel *m_obj;
Campbell Barton f2b2c4
      // Use a copy of 'TParamChange' since callers declare
Campbell Barton f2b2c4
      // and free this value on the stack,
Campbell Barton f2b2c4
      // so we can't ensure its valid later on when the notifier executes.
Campbell Barton f2b2c4
      const TParamChange m_tpc;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      Func(FunctionTreeModel *obj, const TParamChange *tpc)
Campbell Barton f2b2c4
          : m_obj(obj), m_tpc(*tpc) {}
Campbell Barton f2b2c4
      void operator()() override { m_obj->onParamChange(m_tpc.m_dragging); }
Shinya Kitaoka 120a6e
    };
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    QMetaObject::invokeMethod(TFunctorInvoker::instance(), "invoke",
Shinya Kitaoka 120a6e
                              Qt::QueuedConnection,
Shinya Kitaoka 120a6e
                              Q_ARG(void *, new Func(this, &tpc)));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeModel::onParamChange(bool isDragging) {
Shinya Kitaoka 120a6e
  m_paramsChanged = false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  emit curveChanged(isDragging);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeModel::resetAll() {
Toshihiro Shimizu 890ddd
#if QT_VERSION >= 0x050000
Shinya Kitaoka 120a6e
  beginResetModel();
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  m_activeChannels.clear();
Campbell Barton 6e785f
Campbell Barton 6e785f
  TreeModel::Item *root_item = getRootItem();
Campbell Barton 6e785f
  setRootItem_NoFree(NULL);
Campbell Barton 6e785f
Shinya Kitaoka 120a6e
  m_stageObjects = 0;
Shinya Kitaoka 120a6e
  m_fxs          = 0;
Toshihiro Shimizu 890ddd
#if QT_VERSION < 0x050000
Shinya Kitaoka 120a6e
  reset();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  beginRefresh();
Shinya Kitaoka 120a6e
  refreshActiveChannels();
Shinya Kitaoka 120a6e
  endRefresh();
Toshihiro Shimizu 890ddd
Campbell Barton 6e785f
  // postpone until after refresh,
Campbell Barton 6e785f
  // since its members are used for reference.
Campbell Barton 6e785f
  delete root_item;
Campbell Barton 6e785f
Shinya Kitaoka 120a6e
  m_currentChannel = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if QT_VERSION >= 0x050000
Shinya Kitaoka 120a6e
  endResetModel();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeModel::setCurrentFx(TFx *fx) {
Shinya Kitaoka 120a6e
  TZeraryColumnFx *zcfx = dynamic_cast<tzerarycolumnfx *="">(fx);</tzerarycolumnfx>
Shinya Kitaoka 120a6e
  if (zcfx) fx          = zcfx->getZeraryFx();
Shinya Kitaoka 120a6e
  if (fx != m_currentFx) {
Shinya Kitaoka 120a6e
    if (fx) fx->addRef();
Shinya Kitaoka 120a6e
    if (m_currentFx) m_currentFx->release();
Shinya Kitaoka 120a6e
    m_currentFx = fx;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeModel::applyShowFilters() {
Shinya Kitaoka 120a6e
  // WARNING: This is implemented BAD - notice that the get*() functions below
Shinya Kitaoka 120a6e
  //          DO NOT ACTUALLY RETURN CHANNELS, but rather the child
Shinya Kitaoka 120a6e
  //          ChannelGROUPS!
Shinya Kitaoka 120a6e
  //
Shinya Kitaoka 120a6e
  //          This means that these show filters are presumably applied only to
Shinya Kitaoka 120a6e
  //          the FIRST LEVEL OF PARAMETERS...!
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_stageObjects) {
Shinya Kitaoka 120a6e
    int so, soCount = m_stageObjects->getChildCount();
Shinya Kitaoka 120a6e
    for (so = 0; so != soCount; ++so)
Shinya Kitaoka 120a6e
      getStageObjectChannel(so)->applyShowFilter();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_fxs) {
Shinya Kitaoka 120a6e
    int fx, fxCount = m_fxs->getChildCount();
Shinya Kitaoka 120a6e
    for (fx = 0; fx != fxCount; ++fx) getFxChannel(fx)->applyShowFilter();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeModel::addParameter(TParam *parameter,
Shinya Kitaoka 120a6e
                                     const TFilePath &folder) {
Shinya Kitaoka 120a6e
  struct locals {
Shinya Kitaoka 120a6e
    static void locateExistingRoot(ChannelGroup *&root, TFilePath &fp) {
Shinya Kitaoka 120a6e
      std::wstring firstName;
Shinya Kitaoka 120a6e
      TFilePath tempFp;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      while (!fp.isEmpty()) {
Shinya Kitaoka 120a6e
        // Get the path's first name
Shinya Kitaoka 120a6e
        fp.split(firstName, tempFp);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        // Search a matching channel group in root's children
Shinya Kitaoka 120a6e
        int c, cCount = root->getChildCount();
Shinya Kitaoka 120a6e
        for (c = 0; c != cCount; ++c) {
Shinya Kitaoka 120a6e
          if (ChannelGroup *group =
Shinya Kitaoka 120a6e
                  dynamic_cast<channelgroup *="">(root->getChild(c))) {</channelgroup>
Shinya Kitaoka 120a6e
            if (group->getShortName().toStdWString() == firstName) {
Shinya Kitaoka 120a6e
              root = group, fp = tempFp;
Shinya Kitaoka 120a6e
              break;
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        if (c == cCount) break;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    static void addFolders(ChannelGroup *&group, TFilePath &fp) {
Shinya Kitaoka 120a6e
      std::wstring firstName;
Shinya Kitaoka 120a6e
      TFilePath tempFp;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      while (!fp.isEmpty()) {
Shinya Kitaoka 120a6e
        fp.split(firstName, tempFp);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        ChannelGroup *newGroup =
Shinya Kitaoka 120a6e
            new ChannelGroup(QString::fromStdWString(firstName));
Shinya Kitaoka 120a6e
        group->appendChild(newGroup);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        group = newGroup, fp = tempFp;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  };  // locals
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Search for the furthest existing channel group chain leading to our folder
Shinya Kitaoka 120a6e
  ChannelGroup *group = static_cast<channelgroup *="">(getRootItem());</channelgroup>
Shinya Kitaoka 120a6e
  assert(group);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFilePath path = folder;
Shinya Kitaoka 120a6e
  locals::locateExistingRoot(group, path);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // If the chain interrupts prematurely, create new groups up to the required
Shinya Kitaoka 120a6e
  // folder
Shinya Kitaoka 120a6e
  if (!path.isEmpty()) locals::addFolders(group, path);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(path.isEmpty());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Add the parameter to the last group
Shinya Kitaoka 120a6e
  addParameter(group, "", L"", parameter);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// FunctionTreeView
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FunctionTreeView::FunctionTreeView(FunctionViewer *parent)
Shinya Kitaoka 120a6e
    : TreeView(parent), m_scenePath(), m_clickedItem(0), m_draggingChannel(0) {
Shinya Kitaoka 120a6e
  assert(parent);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  setModel(new FunctionTreeModel(this));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  setObjectName("FunctionEditorTree");
Shinya Kitaoka 120a6e
  setSelectionMode(QAbstractItemView::NoSelection);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  connect(this, SIGNAL(pressed(const QModelIndex &)), this,
Shinya Kitaoka 120a6e
          SLOT(onActivated(const QModelIndex &)));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  setFocusPolicy(Qt::NoFocus);
Shinya Kitaoka 120a6e
  setIndentation(14);
Shinya Kitaoka 120a6e
  setAlternatingRowColors(true);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void FunctionTreeView::onActivated(const QModelIndex &index) {
Shinya Kitaoka 120a6e
  enum {
Shinya Kitaoka 120a6e
    NO_CHANNELS       = 0x0,
Shinya Kitaoka 120a6e
    ACTIVE_CHANNELS   = 0x1,
Shinya Kitaoka 120a6e
    INACTIVE_CHANNELS = 0x2,
Shinya Kitaoka 120a6e
    HAS_CHANNELS      = ACTIVE_CHANNELS | INACTIVE_CHANNELS
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!index.isValid()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  FunctionTreeModel *ftModel = (FunctionTreeModel *)model();
Shinya Kitaoka 120a6e
  if (!ftModel) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<functiontreemodel::channel *=""> childChannels;</functiontreemodel::channel>
Shinya Kitaoka 120a6e
  std::vector<functiontreemodel::channelgroup *=""> channelGroups;</functiontreemodel::channelgroup>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Scan for already active children - to decide whether to activate or
Shinya Kitaoka 120a6e
  // deactivate them
Shinya Kitaoka 120a6e
  int activeFlag = NO_CHANNELS;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TreeModel::Item *item =
Shinya Kitaoka 120a6e
      static_cast<treemodel::item *="">(index.internalPointer());</treemodel::item>
Shinya Kitaoka 120a6e
  if (item) {
Shinya Kitaoka 120a6e
    int c, cCount = item->getChildCount();
Shinya Kitaoka 120a6e
    for (c = 0; c != cCount; ++c) {
Shinya Kitaoka 120a6e
      FunctionTreeModel::Channel *channel =
Shinya Kitaoka 120a6e
          dynamic_cast<functiontreemodel::channel *="">(item->getChild(c));</functiontreemodel::channel>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (!channel) {
Shinya Kitaoka 120a6e
        FunctionTreeModel::ChannelGroup *channelGroup =
Shinya Kitaoka 120a6e
            dynamic_cast<functiontreemodel::channelgroup *="">(item->getChild(c));</functiontreemodel::channelgroup>
Shinya Kitaoka 120a6e
        if (!channelGroup) continue;
Shinya Kitaoka 120a6e
        channelGroups.push_back(channelGroup);
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (channel->isHidden()) continue;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      childChannels.push_back(channel);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      activeFlag |= (channel->isActive() ? ACTIVE_CHANNELS : INACTIVE_CHANNELS);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Open the item (ie show children) if it was closed AND not all its children
Shinya Kitaoka 120a6e
  // were active
Shinya Kitaoka 120a6e
  bool someInactiveChannels = (activeFlag != ACTIVE_CHANNELS);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (someInactiveChannels && !isExpanded(index)) {
Shinya Kitaoka 120a6e
    setExpanded(index, true);
Shinya Kitaoka 120a6e
    ftModel->onExpanded(index);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (item) {
Shinya Kitaoka 120a6e
    if (!childChannels.empty()) {
Shinya Kitaoka 120a6e
      // Activate child channels if there is some inactive channel - deactivate
Shinya Kitaoka 120a6e
      // otherwise
Shinya Kitaoka 120a6e
      int c, cCount = childChannels.size();
Shinya Kitaoka 120a6e
      for (c = 0; c != cCount; ++c)
Shinya Kitaoka 120a6e
        childChannels[c]->setIsActive(someInactiveChannels);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      for (int i = 0; i < (int)channelGroups.size(); i++)
Shinya Kitaoka 120a6e
        channelGroups[i]->setChildrenAllActive(someInactiveChannels);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      update();
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      // There was no child channel. Try to activate children groups.
Shinya Kitaoka 120a6e
      int c, cCount = item->getChildCount();
Shinya Kitaoka 120a6e
      for (c = 0; c != cCount; ++c)
Shinya Kitaoka 120a6e
        onActivated(item->getChild(c)->createIndex());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeView::onClick(TreeModel::Item *item, const QPoint &itemPos,
Shinya Kitaoka 120a6e
                               QMouseEvent *e) {
Shinya Kitaoka 120a6e
  m_draggingChannel = 0;
Shinya Kitaoka 120a6e
  FunctionTreeModel::Channel *channel =
Shinya Kitaoka 120a6e
      dynamic_cast<functiontreemodel::channel *="">(item);</functiontreemodel::channel>
Shinya Kitaoka 120a6e
  FxChannelGroup *fxChannelGroup = dynamic_cast<fxchannelgroup *="">(item);</fxchannelgroup>
Shinya Kitaoka 120a6e
  StageObjectChannelGroup *stageObjectChannelGroup =
Shinya Kitaoka 120a6e
      dynamic_cast<stageobjectchannelgroup *="">(item);</stageobjectchannelgroup>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_clickedItem = channel;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (channel) {
Shinya Kitaoka 120a6e
    fxChannelGroup = dynamic_cast<fxchannelgroup *="">(channel->getParent());</fxchannelgroup>
Shinya Kitaoka 120a6e
    stageObjectChannelGroup =
Shinya Kitaoka 120a6e
        dynamic_cast<stageobjectchannelgroup *="">(channel->getParent());</stageobjectchannelgroup>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    int x = itemPos.x();
Shinya Kitaoka 120a6e
    if (x >= 20)
Shinya Kitaoka 120a6e
      channel->setIsCurrent(true);
Shinya Kitaoka 120a6e
    else if (0 <= x && x < 20) {
Shinya Kitaoka 120a6e
      channel->setIsActive(
Shinya Kitaoka 120a6e
          (e->button() == Qt::RightButton) ? true : !channel->isActive());
Shinya Kitaoka 120a6e
      update();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (fxChannelGroup) {
Shinya Kitaoka 120a6e
    TFx *fx = fxChannelGroup->getFx();
Shinya Kitaoka 120a6e
    emit switchCurrentFx(fx);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (stageObjectChannelGroup) {
Shinya Kitaoka 120a6e
    TStageObject *obj = stageObjectChannelGroup->getStageObject();
Shinya Kitaoka 120a6e
    emit switchCurrentObject(obj);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeView::onMidClick(TreeModel::Item *item, const QPoint &itemPos,
Shinya Kitaoka 120a6e
                                  QMouseEvent *e) {
Shinya Kitaoka 120a6e
  FunctionTreeModel::Channel *channel =
Shinya Kitaoka 120a6e
      dynamic_cast<functiontreemodel::channel *="">(item);</functiontreemodel::channel>
Shinya Kitaoka 120a6e
  if (channel && e->button() == Qt::MidButton) {
Shinya Kitaoka 120a6e
    m_draggingChannel   = channel;
Shinya Kitaoka 120a6e
    m_dragStartPosition = e->pos();
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    m_draggingChannel = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeView::onDrag(TreeModel::Item *item, const QPoint &itemPos,
Shinya Kitaoka 120a6e
                              QMouseEvent *e) {
Shinya Kitaoka 120a6e
  // middle drag of the channel item can retrieve expression name
Shinya Kitaoka 120a6e
  if ((e->buttons() & Qt::MidButton) && m_draggingChannel &&
Shinya Kitaoka 120a6e
      (e->pos() - m_dragStartPosition).manhattanLength() >=
Shinya Kitaoka 120a6e
          QApplication::startDragDistance()) {
Shinya Kitaoka 120a6e
    QDrag *drag         = new QDrag(this);
Shinya Kitaoka 120a6e
    QMimeData *mimeData = new QMimeData;
Shinya Kitaoka 120a6e
    mimeData->setText(m_draggingChannel->getExprRefName());
Shinya Kitaoka 120a6e
    drag->setMimeData(mimeData);
Shinya Kitaoka 120a6e
    static const QPixmap cursorPixmap(":Resources/dragcursor_exp_text.png");
Shinya Kitaoka 120a6e
    drag->setDragCursor(cursorPixmap, Qt::MoveAction);
Shinya Kitaoka 120a6e
    Qt::DropAction dropAction = drag->exec();
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  FunctionTreeModel::Channel *channel =
Shinya Kitaoka 120a6e
      dynamic_cast<functiontreemodel::channel *="">(item);</functiontreemodel::channel>
Shinya Kitaoka 120a6e
  if (!channel || !m_clickedItem) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // i0: item under the current cursor position
Shinya Kitaoka 120a6e
  // i1: clicked item
Shinya Kitaoka 120a6e
  QModelIndex i0 = channel->createIndex(), i1 = m_clickedItem->createIndex();
Shinya Kitaoka 120a6e
  if (!i0.isValid() || !i1.isValid() || i0.parent() != i1.parent()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (i0.row() > i1.row()) tswap(i0, i1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  FunctionTreeModel *md = static_cast<functiontreemodel *="">(model());</functiontreemodel>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool active = m_clickedItem->isActive();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int row = i0.row(); row <= i1.row(); ++row) {
Shinya Kitaoka 120a6e
    if (isRowHidden(row, i0.parent())) continue;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    QModelIndex index = md->index(row, 0, i0.parent());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TreeModel::Item *chItem =
Shinya Kitaoka 120a6e
        static_cast<treemodel::item *="">(index.internalPointer());</treemodel::item>
Shinya Kitaoka 120a6e
    FunctionTreeModel::Channel *ch =
Shinya Kitaoka 120a6e
        dynamic_cast<functiontreemodel::channel *="">(chItem);</functiontreemodel::channel>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (ch && ch->isActive() != active) {
Shinya Kitaoka 120a6e
      ch->setIsActive(active);
Shinya Kitaoka 120a6e
      update();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeView::onRelease() { m_clickedItem = 0; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeView::openContextMenu(TreeModel::Item *item,
Shinya Kitaoka 120a6e
                                       const QPoint &globalPos) {
Shinya Kitaoka 120a6e
  if (FunctionTreeModel::Channel *channel =
Shinya Kitaoka 120a6e
          dynamic_cast<functiontreemodel::channel *="">(item))</functiontreemodel::channel>
Shinya Kitaoka 120a6e
    openContextMenu(channel, globalPos);
Shinya Kitaoka 120a6e
  else if (FunctionTreeModel::ChannelGroup *group =
Shinya Kitaoka 120a6e
               dynamic_cast<functiontreemodel::channelgroup *="">(item))</functiontreemodel::channelgroup>
Shinya Kitaoka 120a6e
    openContextMenu(group, globalPos);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeView::openContextMenu(FunctionTreeModel::Channel *channel,
Shinya Kitaoka 120a6e
                                       const QPoint &globalPos) {
Shinya Kitaoka 120a6e
  assert(channel);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QWidget *pw = dynamic_cast<qwidget *="">(parentWidget());</qwidget>
Shinya Kitaoka 120a6e
  if (!pw) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  FunctionViewer *fv = dynamic_cast<functionviewer *="">(pw->parentWidget());</functionviewer>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!fv) {
Shinya Kitaoka 120a6e
    assert(fv);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QMenu menu;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QAction saveCurveAction(tr("Save Curve"), 0);
Shinya Kitaoka 120a6e
  QAction loadCurveAction(tr("Load Curve"), 0);
Shinya Kitaoka 120a6e
  QAction exportDataAction(tr("Export Data"), 0);
Shinya Kitaoka 120a6e
  menu.addAction(&saveCurveAction);
Shinya Kitaoka 120a6e
  menu.addAction(&loadCurveAction);
Shinya Kitaoka 120a6e
  menu.addAction(&exportDataAction);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QAction *action = menu.exec(globalPos);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TDoubleParam *curve = channel->getParam();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (action == &saveCurveAction)
Shinya Kitaoka 120a6e
    fv->emitIoCurve((int)FunctionViewer::eSaveCurve, curve, "");
Shinya Kitaoka 120a6e
  else if (action == &loadCurveAction)
Shinya Kitaoka 120a6e
    fv->emitIoCurve((int)FunctionViewer::eLoadCurve, curve, "");
Shinya Kitaoka 120a6e
  else if (action == &exportDataAction)
Shinya Kitaoka 120a6e
    fv->emitIoCurve((int)FunctionViewer::eExportCurve, curve,
Shinya Kitaoka 120a6e
                    channel->getLongName().toStdString());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeView::openContextMenu(FunctionTreeModel::ChannelGroup *group,
Shinya Kitaoka 120a6e
                                       const QPoint &globalPos) {
Shinya Kitaoka 120a6e
  assert(group);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QMenu menu;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QAction showAnimateOnly(tr("Show Animated Only"), 0);
Shinya Kitaoka 120a6e
  QAction showAll(tr("Show All"), 0);
Shinya Kitaoka 120a6e
  menu.addAction(&showAnimateOnly);
Shinya Kitaoka 120a6e
  menu.addAction(&showAll);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // execute menu
Shinya Kitaoka 120a6e
  QAction *action = menu.exec(globalPos);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (action != &showAll && action != &showAnimateOnly) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  FunctionTreeModel::ChannelGroup::ShowFilter showFilter =
Shinya Kitaoka 120a6e
      (action == &showAll)
Shinya Kitaoka 120a6e
          ? FunctionTreeModel::ChannelGroup::ShowAllChannels
Shinya Kitaoka 120a6e
          : FunctionTreeModel::ChannelGroup::ShowAnimatedChannels;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  expand(group->createIndex());
Shinya Kitaoka 120a6e
  group->setShowFilter(showFilter);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionTreeView::updateAll() {
Shinya Kitaoka 120a6e
  FunctionTreeModel *functionTreeModel =
Shinya Kitaoka 120a6e
      dynamic_cast<functiontreemodel *="">(model());</functiontreemodel>
Shinya Kitaoka 120a6e
  assert(functionTreeModel);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  functionTreeModel->applyShowFilters();
Shinya Kitaoka 120a6e
  update();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! show all the animated channels when the scene switched
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
void FunctionTreeView::displayAnimatedChannels() {
Shinya Kitaoka 120a6e
  FunctionTreeModel *functionTreeModel =
Shinya Kitaoka 120a6e
      dynamic_cast<functiontreemodel *="">(model());</functiontreemodel>
Shinya Kitaoka 120a6e
  assert(functionTreeModel);
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < functionTreeModel->getStageObjectsChannelCount(); i++)
Shinya Kitaoka 120a6e
    functionTreeModel->getStageObjectChannel(i)->displayAnimatedChannels();
Shinya Kitaoka 120a6e
  for (i = 0; i < functionTreeModel->getFxsChannelCount(); i++)
Shinya Kitaoka 120a6e
    functionTreeModel->getFxChannel(i)->displayAnimatedChannels();
Shinya Kitaoka 120a6e
  update();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! show all the animated channels when the scene switched
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
void FunctionTreeModel::ChannelGroup::displayAnimatedChannels() {
Shinya Kitaoka 120a6e
  int itemCount = getChildCount();
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < itemCount; i++) {
Shinya Kitaoka 120a6e
    FunctionTreeModel::Channel *channel =
Shinya Kitaoka 120a6e
        dynamic_cast<functiontreemodel::channel *="">(getChild(i));</functiontreemodel::channel>
Shinya Kitaoka 120a6e
    if (!channel) {
Shinya Kitaoka 120a6e
      FunctionTreeModel::ChannelGroup *channelGroup =
Shinya Kitaoka 120a6e
          dynamic_cast<functiontreemodel::channelgroup *="">(getChild(i));</functiontreemodel::channelgroup>
Shinya Kitaoka 120a6e
      if (!channelGroup) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      channelGroup->displayAnimatedChannels();
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    channel->setIsActive(channel->getParam()->hasKeyframes());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}