Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonzqt/addfxcontextmenu.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzQt includes
Toshihiro Shimizu 890ddd
#include "toonzqt/fxselection.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/toonzfolders.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheethandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tcolumnhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tframehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tfxhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/fxcommand.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheet.h"
Toshihiro Shimizu 890ddd
#include "toonz/fxdag.h"
Toshihiro Shimizu 890ddd
#include "toonz/tapplication.h"
Toshihiro Shimizu 890ddd
#include "tw/stringtable.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzBase includes
Toshihiro Shimizu 890ddd
#include "texternfx.h"
Toshihiro Shimizu 890ddd
#include "tmacrofx.h"
Toshihiro Shimizu 890ddd
#include "tfxattributes.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
#include "tsystem.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 <qstack></qstack>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "pluginhost.h"
Toshihiro Shimizu 890ddd
#include <map></map>
Toshihiro Shimizu 890ddd
#include <string></string>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
std::map<std::string, *="" plugininformation=""> plugin_dict_;</std::string,>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
TFx *createFxByName(std::string fxId) {
Shinya Kitaoka 120a6e
  if (fxId.find("_ext_") == 0) return TExternFx::create(fxId.substr(5));
Shinya Kitaoka 120a6e
  if (fxId.find("_plg_") == 0) {
Shinya Kitaoka 120a6e
    std::string id = fxId.substr(5);
Shinya Kitaoka 120a6e
    std::map<std::string, *="" plugininformation="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
        plugin_dict_.find(id);
Shinya Kitaoka 120a6e
    if (it != plugin_dict_.end()) {
Shinya Kitaoka 120a6e
      RasterFxPluginHost *plugin = new RasterFxPluginHost(it->second);
Shinya Kitaoka 120a6e
      plugin->notify();
Shinya Kitaoka 120a6e
      return plugin;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return NULL;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    return TFx::create(fxId);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFx *createPresetFxByName(TFilePath path) {
Shinya Kitaoka 120a6e
  std::string id = path.getParentDir().getName();
Shinya Kitaoka 120a6e
  TFx *fx        = createFxByName(id);
Shinya Kitaoka 120a6e
  if (fx) {
Shinya Kitaoka 120a6e
    TIStream is(path);
Shinya Kitaoka 120a6e
    fx->loadPreset(is);
Shinya Kitaoka 120a6e
    fx->setName(path.getWideName());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return fx;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFx *createMacroFxByPath(TFilePath path, TXsheet *xsheet) {
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    TIStream is(path);
Shinya Kitaoka 120a6e
    TPersist *p = 0;
Shinya Kitaoka 120a6e
    is >> p;
Shinya Kitaoka 120a6e
    TMacroFx *fx = dynamic_cast<tmacrofx *="">(p);</tmacrofx>
Shinya Kitaoka 120a6e
    if (!fx) return 0;
Shinya Kitaoka 120a6e
    fx->setName(path.getWideName());
Shinya Kitaoka 120a6e
    // Assign a unic ID to each fx in the macro!
Shinya Kitaoka 120a6e
    if (!xsheet) return fx;
Shinya Kitaoka 120a6e
    FxDag *fxDag = xsheet->getFxDag();
Shinya Kitaoka 120a6e
    if (!fxDag) return fx;
Shinya Kitaoka 120a6e
    std::vector<tfxp> fxs;</tfxp>
Shinya Kitaoka 120a6e
    fxs = fx->getFxs();
Shinya Kitaoka 120a6e
    QMap<std::wstring, std::wstring=""> oldNewId;</std::wstring,>
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 0; i < (int)fxs.size(); i++) {
Shinya Kitaoka 120a6e
      std::wstring oldId = fxs[i]->getFxId();
Shinya Kitaoka 120a6e
      fxDag->assignUniqueId(fxs[i].getPointer());
Shinya Kitaoka 120a6e
      std::wstring newId = fxs[i]->getFxId();
Shinya Kitaoka 120a6e
      oldNewId[oldId]    = newId;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // cambiando l'id degli effetti interni di una macro si rompono i legami
Shinya Kitaoka 120a6e
      // tra il nome della porta
Shinya Kitaoka 120a6e
      // e la porta a cui e' legato: devo cambiare i nomei delle porte e
Shinya Kitaoka 120a6e
      // rimapparli all'interno della macro
Shinya Kitaoka 120a6e
      int j;
Shinya Kitaoka 120a6e
      for (j = 0; j < fx->getInputPortCount(); j++) {
Shinya Kitaoka 120a6e
        QString inputName = QString::fromStdString(fx->getInputPortName(j));
Shinya Kitaoka 120a6e
        if (inputName.endsWith(QString::fromStdWString(oldId))) {
Shinya Kitaoka 120a6e
          QString newInputName = inputName;
Shinya Kitaoka 120a6e
          newInputName.replace(QString::fromStdWString(oldId),
Shinya Kitaoka 120a6e
                               QString::fromStdWString(newId));
Shinya Kitaoka 120a6e
          fx->renamePort(inputName.toStdString(), newInputName.toStdString());
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    return fx;
Shinya Kitaoka 120a6e
  } catch (...) {
Shinya Kitaoka 120a6e
    return 0;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFx *createFx(QAction *action, TXsheetHandle *xshHandle) {
Shinya Kitaoka 120a6e
  TXsheet *xsh = xshHandle->getXsheet();
Shinya Kitaoka 120a6e
  QString text = action->data().toString();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (text.isEmpty()) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFx *fx = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFilePath path = TFilePath(text.toStdWString());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (TFileStatus(path).doesExist() &&
Shinya Kitaoka 120a6e
      TFileStatus(path.getParentDir()).isDirectory()) {
Shinya Kitaoka 120a6e
    std::string folder = path.getParentDir().getName();
Shinya Kitaoka 120a6e
    if (folder == "macroFx")  // have to load a Macro
Shinya Kitaoka 120a6e
      fx = createMacroFxByPath(path, xsh);
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      folder = path.getParentDir().getParentDir().getName();
Shinya Kitaoka 120a6e
      if (folder == "presets")  // have to load a preset
Shinya Kitaoka 120a6e
        fx = createPresetFxByName(path);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    fx = createFxByName(text.toStdString());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return fx;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//***************************************************
Toshihiro Shimizu 890ddd
//
Shinya Kitaoka 120a6e
// AddFxContextMenu
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//***************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
AddFxContextMenu::AddFxContextMenu()
Shinya Kitaoka 120a6e
    : QObject(), m_app(0), m_currentCursorScenePos(0, 0), m_againCommand(0) {
Shinya Kitaoka 120a6e
  m_fxListPath = TFilePath(ToonzFolder::getProfileFolder() + "layouts" + "fxs" +
Shinya Kitaoka 120a6e
                           "fxs.lst");
Shinya Kitaoka 120a6e
  m_presetPath = TFilePath(ToonzFolder::getFxPresetFolder() + "presets");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_insertMenu         = new QMenu(tr("Insert FX"), 0);
Shinya Kitaoka 120a6e
  m_insertActionGroup  = new QActionGroup(m_insertMenu);
Shinya Kitaoka 120a6e
  m_addMenu            = new QMenu(tr("Add FX"), 0);
Shinya Kitaoka 120a6e
  m_addActionGroup     = new QActionGroup(m_addMenu);
Shinya Kitaoka 120a6e
  m_replaceMenu        = new QMenu(tr("Replace FX"), 0);
Shinya Kitaoka 120a6e
  m_replaceActionGroup = new QActionGroup(m_replaceMenu);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  connect(m_insertActionGroup, SIGNAL(triggered(QAction *)), this,
Shinya Kitaoka 120a6e
          SLOT(onInsertFx(QAction *)));
Shinya Kitaoka 120a6e
  connect(m_addActionGroup, SIGNAL(triggered(QAction *)), this,
Shinya Kitaoka 120a6e
          SLOT(onAddFx(QAction *)));
Shinya Kitaoka 120a6e
  connect(m_replaceActionGroup, SIGNAL(triggered(QAction *)), this,
Shinya Kitaoka 120a6e
          SLOT(onReplaceFx(QAction *)));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  fillMenus();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------
Shinya Kitaoka 120a6e
static void clear_all_plugins() {
Shinya Kitaoka 120a6e
  for (std::map<std::string, *="" plugininformation="">::iterator it =</std::string,>
Shinya Kitaoka 120a6e
           plugin_dict_.begin();
Shinya Kitaoka 120a6e
       it != plugin_dict_.end(); ++it) {
Shinya Kitaoka 120a6e
    it->second->release();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  plugin_dict_.clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
AddFxContextMenu::~AddFxContextMenu() { clear_all_plugins(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void AddFxContextMenu::setApplication(TApplication *app) {
Shinya Kitaoka 120a6e
  m_app = app;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (TFxHandle *fxHandle = app->getCurrentFx()) {
Shinya Kitaoka 120a6e
    connect(fxHandle, SIGNAL(fxPresetSaved()), this, SLOT(onFxPresetHandled()));
Shinya Kitaoka 120a6e
    connect(fxHandle, SIGNAL(fxPresetRemoved()), this,
Shinya Kitaoka 120a6e
            SLOT(onFxPresetHandled()));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void AddFxContextMenu::fillMenus() {
Shinya Kitaoka 120a6e
  loadFxs();
Shinya Kitaoka 120a6e
  loadMacro();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------
Toshihiro Shimizu 890ddd
Campbell Barton ccd505
static void scan_all_plugins(const std::string &basedir, QObject *listener) {
Shinya Kitaoka 120a6e
  // clear_all_plugins();
Shinya Kitaoka 120a6e
  new PluginLoadController(basedir, listener);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void AddFxContextMenu::result(PluginInformation *pi) {
Shinya Kitaoka 120a6e
  /* slot receives PluginInformation on the main thread たぶん */
Shinya Kitaoka 120a6e
  printf("AddFxContextMenu::result() pi:%p\n", pi);
Shinya Kitaoka 120a6e
  /* addfxcontextmenu.cpp の dict に登録する */
Shinya Kitaoka 120a6e
  if (pi)
Shinya Kitaoka 120a6e
    plugin_dict_.insert(
Shinya Kitaoka 120a6e
        std::pair<std::string, *="" plugininformation="">(pi->desc_->id_, pi));</std::string,>
Shinya Kitaoka 120a6e
  // RasterFxPluginHost* plug = new RasterFxPluginHost(pi);
Shinya Kitaoka 120a6e
  // pi->handler_->create(plug);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void AddFxContextMenu::fixup() { loadFxPluginGroup(); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void AddFxContextMenu::loadFxs() {
Shinya Kitaoka 120a6e
  TIStream is(m_fxListPath);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    std::string tagName;
Shinya Kitaoka 120a6e
    if (is.matchTag(tagName) && tagName == "fxs") {
Shinya Kitaoka 120a6e
      loadFxGroup(&is);
Shinya Kitaoka 120a6e
      is.closeChild();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } catch (...) {
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  scan_all_plugins("", this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void AddFxContextMenu::loadFxPluginGroup() {
Shinya Kitaoka 120a6e
  QString groupName = QString::fromStdString("Plugins");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 2a7129
  std::unique_ptr<qmenu> insertFxGroup(new QMenu(groupName, m_insertMenu));</qmenu>
Shinya Kitaoka 2a7129
  std::unique_ptr<qmenu> addFxGroup(new QMenu(groupName, m_addMenu));</qmenu>
Shinya Kitaoka 2a7129
  std::unique_ptr<qmenu> replaceFxGroup(new QMenu(groupName, m_replaceMenu));</qmenu>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  loadFxPlugins(insertFxGroup.get(), addFxGroup.get(), replaceFxGroup.get());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!insertFxGroup->isEmpty()) m_insertMenu->addMenu(insertFxGroup.release());
Shinya Kitaoka 120a6e
  if (!addFxGroup->isEmpty()) m_addMenu->addMenu(addFxGroup.release());
Shinya Kitaoka 120a6e
  if (!replaceFxGroup->isEmpty())
Shinya Kitaoka 120a6e
    m_replaceMenu->addMenu(replaceFxGroup.release());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void AddFxContextMenu::loadFxGroup(TIStream *is) {
Shinya Kitaoka 120a6e
  while (!is->eos()) {
Shinya Kitaoka 120a6e
    std::string tagName;
Shinya Kitaoka 120a6e
    if (is->matchTag(tagName)) {
Shinya Kitaoka 120a6e
      QString groupName = QString::fromStdString(tagName);
Shinya Kitaoka 120a6e
Shinya Kitaoka 2a7129
      std::unique_ptr<qmenu> insertFxGroup(new QMenu(groupName, m_insertMenu));</qmenu>
Shinya Kitaoka 2a7129
      std::unique_ptr<qmenu> addFxGroup(new QMenu(groupName, m_addMenu));</qmenu>
Shinya Kitaoka 2a7129
      std::unique_ptr<qmenu> replaceFxGroup(</qmenu>
Shinya Kitaoka 2a7129
          new QMenu(groupName, m_replaceMenu));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      loadFx(is, insertFxGroup.get(), addFxGroup.get(), replaceFxGroup.get());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (!insertFxGroup->isEmpty())
Shinya Kitaoka 120a6e
        m_insertMenu->addMenu(insertFxGroup.release());
Shinya Kitaoka 120a6e
      if (!addFxGroup->isEmpty()) m_addMenu->addMenu(addFxGroup.release());
Shinya Kitaoka 120a6e
      if (!replaceFxGroup->isEmpty())
Shinya Kitaoka 120a6e
        m_replaceMenu->addMenu(replaceFxGroup.release());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      is->closeChild();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------
Shinya Kitaoka 120a6e
void AddFxContextMenu::loadFxPlugins(QMenu *insertFxGroup, QMenu *addFxGroup,
Shinya Kitaoka 120a6e
                                     QMenu *replaceFxGroup) {
Shinya Kitaoka 120a6e
  // list vendors
Shinya Kitaoka 120a6e
  std::vector<std::string> vendors;</std::string>
Shinya Kitaoka 120a6e
  for (auto &&plugin : plugin_dict_) {
Shinya Kitaoka 120a6e
    PluginDescription *desc = plugin.second->desc_;
Shinya Kitaoka 120a6e
    vendors.push_back(desc->vendor_);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  std::sort(std::begin(vendors), std::end(vendors));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // add vendor folders
Shinya Kitaoka 120a6e
  std::map<std::string, *="" qmenu=""> insVendors;</std::string,>
Shinya Kitaoka 120a6e
  std::map<std::string, *="" qmenu=""> addVendors;</std::string,>
Shinya Kitaoka 120a6e
  std::map<std::string, *="" qmenu=""> repVendors;</std::string,>
Shinya Kitaoka 120a6e
  for (std::string vendor : vendors) {
Shinya Kitaoka 120a6e
    std::map<std::string, *="" qmenu="">::iterator v = insVendors.find(vendor);</std::string,>
Shinya Kitaoka 120a6e
    if (v == insVendors.end()) {
Shinya Kitaoka 120a6e
      QString vendorQStr = QString::fromStdString(vendor);
Shinya Kitaoka 120a6e
      insVendors.insert(
Shinya Kitaoka 120a6e
          std::make_pair(vendor, insertFxGroup->addMenu(vendorQStr)));
Shinya Kitaoka 120a6e
      addVendors.insert(
Shinya Kitaoka 120a6e
          std::make_pair(vendor, addFxGroup->addMenu(vendorQStr)));
Shinya Kitaoka 120a6e
      repVendors.insert(
Shinya Kitaoka 120a6e
          std::make_pair(vendor, replaceFxGroup->addMenu(vendorQStr)));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // add actions
Shinya Kitaoka 120a6e
  for (auto &&plugin : plugin_dict_) {
Shinya Kitaoka 120a6e
    PluginDescription *desc = plugin.second->desc_;
Shinya Kitaoka 120a6e
    QString label           = QString::fromStdString(desc->name_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    QAction *insertAction  = new QAction(label, insertFxGroup);
Shinya Kitaoka 120a6e
    QAction *addAction     = new QAction(label, addFxGroup);
Shinya Kitaoka 120a6e
    QAction *replaceAction = new QAction(label, replaceFxGroup);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    insertAction->setData(
Shinya Kitaoka 120a6e
        QVariant("_plg_" + QString::fromStdString(desc->id_)));
Shinya Kitaoka 120a6e
    addAction->setData(QVariant("_plg_" + QString::fromStdString(desc->id_)));
Shinya Kitaoka 120a6e
    replaceAction->setData(
Shinya Kitaoka 120a6e
        QVariant("_plg_" + QString::fromStdString(desc->id_)));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    (*insVendors.find(desc->vendor_)).second->addAction(insertAction);
Shinya Kitaoka 120a6e
    (*addVendors.find(desc->vendor_)).second->addAction(addAction);
Shinya Kitaoka 120a6e
    (*repVendors.find(desc->vendor_)).second->addAction(replaceAction);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_insertActionGroup->addAction(insertAction);
Shinya Kitaoka 120a6e
    m_addActionGroup->addAction(addAction);
Shinya Kitaoka 120a6e
    m_replaceActionGroup->addAction(replaceAction);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // sort actions
Shinya Kitaoka 120a6e
  auto const comp = [](QAction *lhs, QAction *rhs) {
Shinya Kitaoka 120a6e
    return lhs->text() < rhs->text();
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (auto &&ins : insVendors) {
Shinya Kitaoka 120a6e
    QList<qaction *=""> actions = ins.second->actions();</qaction>
Shinya Kitaoka 120a6e
    ins.second->clear();
Shinya Kitaoka 120a6e
    qSort(actions.begin(), actions.end(), comp);
Shinya Kitaoka 120a6e
    ins.second->addActions(actions);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (auto &&ins : addVendors) {
Shinya Kitaoka 120a6e
    QList<qaction *=""> actions = ins.second->actions();</qaction>
Shinya Kitaoka 120a6e
    ins.second->clear();
Shinya Kitaoka 120a6e
    qSort(actions.begin(), actions.end(), comp);
Shinya Kitaoka 120a6e
    ins.second->addActions(actions);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (auto &&ins : repVendors) {
Shinya Kitaoka 120a6e
    QList<qaction *=""> actions = ins.second->actions();</qaction>
Shinya Kitaoka 120a6e
    ins.second->clear();
Shinya Kitaoka 120a6e
    qSort(actions.begin(), actions.end(), comp);
Shinya Kitaoka 120a6e
    ins.second->addActions(actions);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void AddFxContextMenu::loadFx(TIStream *is, QMenu *insertFxGroup,
Shinya Kitaoka 120a6e
                              QMenu *addFxGroup, QMenu *replaceFxGroup) {
Shinya Kitaoka 120a6e
  while (!is->eos()) {
Shinya Kitaoka 120a6e
    std::string fxName;
Shinya Kitaoka 120a6e
    *is >> fxName;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!fxName.empty()) {
Shinya Kitaoka 120a6e
      if (!loadPreset(fxName, insertFxGroup, addFxGroup, replaceFxGroup)) {
Shinya Kitaoka 120a6e
        QString translatedName =
Shinya Kitaoka 120a6e
            QString::fromStdWString(TStringTable::translate(fxName));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        QAction *insertAction  = new QAction(translatedName, insertFxGroup);
Shinya Kitaoka 120a6e
        QAction *addAction     = new QAction(translatedName, addFxGroup);
Shinya Kitaoka 120a6e
        QAction *replaceAction = new QAction(translatedName, replaceFxGroup);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        insertAction->setData(QVariant(QString::fromStdString(fxName)));
Shinya Kitaoka 120a6e
        addAction->setData(QVariant(QString::fromStdString(fxName)));
Shinya Kitaoka 120a6e
        replaceAction->setData(QVariant(QString::fromStdString(fxName)));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        insertFxGroup->addAction(insertAction);
Shinya Kitaoka 120a6e
        addFxGroup->addAction(addAction);
Shinya Kitaoka 120a6e
        replaceFxGroup->addAction(replaceAction);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        m_insertActionGroup->addAction(insertAction);
Shinya Kitaoka 120a6e
        m_addActionGroup->addAction(addAction);
Shinya Kitaoka 120a6e
        m_replaceActionGroup->addAction(replaceAction);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool AddFxContextMenu::loadPreset(const std::string &name, QMenu *insertFxGroup,
Shinya Kitaoka 120a6e
                                  QMenu *addFxGroup, QMenu *replaceFxGroup) {
Shinya Kitaoka 120a6e
  TFilePath presetsFilepath(m_presetPath + name);
Shinya Kitaoka 120a6e
  if (TFileStatus(presetsFilepath).isDirectory()) {
Shinya Kitaoka 120a6e
    TFilePathSet presets = TSystem::readDirectory(presetsFilepath, false);
Shinya Kitaoka 120a6e
    if (!presets.empty()) {
Shinya Kitaoka 120a6e
      QMenu *inserMenu =
Shinya Kitaoka 120a6e
          new QMenu(QString::fromStdWString(TStringTable::translate(name)),
Shinya Kitaoka 120a6e
                    insertFxGroup);
Shinya Kitaoka 120a6e
      insertFxGroup->addMenu(inserMenu);
Shinya Kitaoka 120a6e
      QMenu *addMenu = new QMenu(
Shinya Kitaoka 120a6e
          QString::fromStdWString(TStringTable::translate(name)), addFxGroup);
Shinya Kitaoka 120a6e
      addFxGroup->addMenu(addMenu);
Shinya Kitaoka 120a6e
      QMenu *replaceMenu =
Shinya Kitaoka 120a6e
          new QMenu(QString::fromStdWString(TStringTable::translate(name)),
Shinya Kitaoka 120a6e
                    replaceFxGroup);
Shinya Kitaoka 120a6e
      replaceFxGroup->addMenu(replaceMenu);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // This is a workaround to set the bold style to the first element of this
Shinya Kitaoka 120a6e
      // menu
Shinya Kitaoka 120a6e
      // Setting a font directly to a QAction is not enought; style sheet
Shinya Kitaoka 120a6e
      // definitions
Shinya Kitaoka 120a6e
      // preval over QAction font settings.
Shinya Kitaoka 120a6e
      inserMenu->setObjectName("fxMenu");
Shinya Kitaoka 120a6e
      addMenu->setObjectName("fxMenu");
Shinya Kitaoka 120a6e
      replaceMenu->setObjectName("fxMenu");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      QAction *insertAction = new QAction(
Shinya Kitaoka 120a6e
          QString::fromStdWString(TStringTable::translate(name)), inserMenu);
Shinya Kitaoka 120a6e
      QAction *addAction = new QAction(
Shinya Kitaoka 120a6e
          QString::fromStdWString(TStringTable::translate(name)), addMenu);
Shinya Kitaoka 120a6e
      QAction *replaceAction = new QAction(
Shinya Kitaoka 120a6e
          QString::fromStdWString(TStringTable::translate(name)), replaceMenu);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      insertAction->setCheckable(true);
Shinya Kitaoka 120a6e
      addAction->setCheckable(true);
Shinya Kitaoka 120a6e
      replaceAction->setCheckable(true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      insertAction->setData(QVariant(QString::fromStdString(name)));
Shinya Kitaoka 120a6e
      addAction->setData(QVariant(QString::fromStdString(name)));
Shinya Kitaoka 120a6e
      replaceAction->setData(QVariant(QString::fromStdString(name)));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      inserMenu->addAction(insertAction);
Shinya Kitaoka 120a6e
      addMenu->addAction(addAction);
Shinya Kitaoka 120a6e
      replaceMenu->addAction(replaceAction);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      m_insertActionGroup->addAction(insertAction);
Shinya Kitaoka 120a6e
      m_addActionGroup->addAction(addAction);
Shinya Kitaoka 120a6e
      m_replaceActionGroup->addAction(replaceAction);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      for (TFilePathSet::iterator it2 = presets.begin(); it2 != presets.end();
Shinya Kitaoka 120a6e
           ++it2) {
Shinya Kitaoka 120a6e
        TFilePath presetName = *it2;
Shinya Kitaoka 120a6e
        QString qPresetName = QString::fromStdWString(presetName.getWideName());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        insertAction  = new QAction(qPresetName, inserMenu);
Shinya Kitaoka 120a6e
        addAction     = new QAction(qPresetName, addMenu);
Shinya Kitaoka 120a6e
        replaceAction = new QAction(qPresetName, replaceMenu);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        insertAction->setData(
Shinya Kitaoka 120a6e
            QVariant(QString::fromStdWString(presetName.getWideString())));
Shinya Kitaoka 120a6e
        addAction->setData(
Shinya Kitaoka 120a6e
            QVariant(QString::fromStdWString(presetName.getWideString())));
Shinya Kitaoka 120a6e
        replaceAction->setData(
Shinya Kitaoka 120a6e
            QVariant(QString::fromStdWString(presetName.getWideString())));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        inserMenu->addAction(insertAction);
Shinya Kitaoka 120a6e
        addMenu->addAction(addAction);
Shinya Kitaoka 120a6e
        replaceMenu->addAction(replaceAction);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        m_insertActionGroup->addAction(insertAction);
Shinya Kitaoka 120a6e
        m_addActionGroup->addAction(addAction);
Shinya Kitaoka 120a6e
        m_replaceActionGroup->addAction(replaceAction);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void AddFxContextMenu::loadMacro() {
Shinya Kitaoka 120a6e
  TFilePath macroDir = m_presetPath + TFilePath("macroFx");
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    if (TFileStatus(macroDir).isDirectory()) {
Shinya Kitaoka 120a6e
      TFilePathSet macros = TSystem::readDirectory(macroDir);
Shinya Kitaoka 120a6e
      if (macros.empty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      QMenu *insertMacroMenu  = new QMenu("Macro", m_insertMenu);
Shinya Kitaoka 120a6e
      QMenu *addMacroMenu     = new QMenu("Macro", m_addMenu);
Shinya Kitaoka 120a6e
      QMenu *replaceMacroMenu = new QMenu("Macro", m_replaceMenu);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      m_insertMenu->addMenu(insertMacroMenu);
Shinya Kitaoka 120a6e
      m_addMenu->addMenu(addMacroMenu);
Shinya Kitaoka 120a6e
      m_replaceMenu->addMenu(replaceMacroMenu);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      for (TFilePathSet::iterator it = macros.begin(); it != macros.end();
Shinya Kitaoka 120a6e
           ++it) {
Shinya Kitaoka 120a6e
        TFilePath macroPath = *it;
Shinya Kitaoka 120a6e
        QString name        = QString::fromStdWString(macroPath.getWideName());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        QAction *insertAction  = new QAction(name, insertMacroMenu);
Shinya Kitaoka 120a6e
        QAction *addAction     = new QAction(name, addMacroMenu);
Shinya Kitaoka 120a6e
        QAction *replaceAction = new QAction(name, replaceMacroMenu);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        insertAction->setData(
Shinya Kitaoka 120a6e
            QVariant(QString::fromStdWString(macroPath.getWideString())));
Shinya Kitaoka 120a6e
        addAction->setData(
Shinya Kitaoka 120a6e
            QVariant(QString::fromStdWString(macroPath.getWideString())));
Shinya Kitaoka 120a6e
        replaceAction->setData(
Shinya Kitaoka 120a6e
            QVariant(QString::fromStdWString(macroPath.getWideString())));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        insertMacroMenu->addAction(insertAction);
Shinya Kitaoka 120a6e
        addMacroMenu->addAction(addAction);
Shinya Kitaoka 120a6e
        replaceMacroMenu->addAction(replaceAction);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        m_insertActionGroup->addAction(insertAction);
Shinya Kitaoka 120a6e
        m_addActionGroup->addAction(addAction);
Shinya Kitaoka 120a6e
        m_replaceActionGroup->addAction(replaceAction);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } catch (...) {
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void AddFxContextMenu::onInsertFx(QAction *action) {
Shinya Kitaoka 120a6e
  if (action->isCheckable() && action->isChecked()) action->setChecked(false);
Shinya Kitaoka 120a6e
  TFx *fx = createFx(action, m_app->getCurrentXsheet());
Shinya Kitaoka 120a6e
  if (fx) {
Shinya Kitaoka 120a6e
    QList<tfxp> fxs               = m_selection->getFxs();</tfxp>
Shinya Kitaoka 120a6e
    QList<tfxcommand::link> links = m_selection->getLinks();</tfxcommand::link>
Shinya Kitaoka 120a6e
    TFxCommand::insertFx(fx, fxs, links, m_app,
Shinya Kitaoka 120a6e
                         m_app->getCurrentColumn()->getColumnIndex(),
Shinya Kitaoka 120a6e
                         m_app->getCurrentFrame()->getFrameIndex());
Shinya Kitaoka 120a6e
    m_app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    // memorize the latest operation
Shinya Kitaoka 120a6e
    m_app->getCurrentFx()->setPreviousActionString(QString("I ") +
Shinya Kitaoka 120a6e
                                                   action->data().toString());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void AddFxContextMenu::onAddFx(QAction *action) {
Shinya Kitaoka 120a6e
  if (action->isCheckable() && action->isChecked()) action->setChecked(false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFx *fx = createFx(action, m_app->getCurrentXsheet());
Shinya Kitaoka 120a6e
  if (fx) {
Shinya Kitaoka 120a6e
    QList<tfxp> fxs = m_selection->getFxs();</tfxp>
Shinya Kitaoka 120a6e
    // try to add node at cursor position
Shinya Kitaoka 120a6e
    if (m_currentCursorScenePos.x() != 0 || m_currentCursorScenePos.y() != 0) {
Shinya Kitaoka 120a6e
      fx->getAttributes()->setDagNodePos(
Shinya Kitaoka 120a6e
          TPointD(m_currentCursorScenePos.x(), m_currentCursorScenePos.y()));
Shinya Kitaoka 120a6e
      m_currentCursorScenePos.setX(0);
Shinya Kitaoka 120a6e
      m_currentCursorScenePos.setY(0);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TFxCommand::addFx(fx, fxs, m_app,
Shinya Kitaoka 120a6e
                      m_app->getCurrentColumn()->getColumnIndex(),
Shinya Kitaoka 120a6e
                      m_app->getCurrentFrame()->getFrameIndex());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    // memorize the latest operation
Shinya Kitaoka 120a6e
    m_app->getCurrentFx()->setPreviousActionString(QString("A ") +
Shinya Kitaoka 120a6e
                                                   action->data().toString());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void AddFxContextMenu::onReplaceFx(QAction *action) {
Shinya Kitaoka 120a6e
  if (action->isCheckable() && action->isChecked()) action->setChecked(false);
Shinya Kitaoka 120a6e
  TFx *fx = createFx(action, m_app->getCurrentXsheet());
Shinya Kitaoka 120a6e
  if (fx) {
Shinya Kitaoka 120a6e
    QList<tfxp> fxs = m_selection->getFxs();</tfxp>
Shinya Kitaoka 120a6e
    TFxCommand::replaceFx(fx, fxs, m_app->getCurrentXsheet(),
Shinya Kitaoka 120a6e
                          m_app->getCurrentFx());
Shinya Kitaoka 120a6e
    m_app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    // memorize the latest operation
Shinya Kitaoka 120a6e
    m_app->getCurrentFx()->setPreviousActionString(QString("R ") +
Shinya Kitaoka 120a6e
                                                   action->data().toString());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void AddFxContextMenu::onFxPresetHandled() {
Shinya Kitaoka 120a6e
  m_insertMenu->clear();
Shinya Kitaoka 120a6e
  m_addMenu->clear();
Shinya Kitaoka 120a6e
  m_replaceMenu->clear();
Shinya Kitaoka 120a6e
  fillMenus();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------
Toshihiro Shimizu 890ddd
/*! repeat the last fx creation command done in the schematic.
Shinya Kitaoka 120a6e
    arrgument "command" is sum of the ids of available commands(Insert, Add,
Shinya Kitaoka 120a6e
   Replace)
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
QAction *AddFxContextMenu::getAgainCommand(int command) {
Shinya Kitaoka 120a6e
  QString commandName = m_app->getCurrentFx()->getPreviousActionString();
Shinya Kitaoka 120a6e
  // return if the last action is not registered
Shinya Kitaoka 120a6e
  if (commandName.isEmpty()) return 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // classify action by commandName
Shinya Kitaoka 120a6e
  Commands com;
Shinya Kitaoka 120a6e
  QString commandStr;
Shinya Kitaoka 120a6e
  if (commandName.startsWith("I ")) {
Shinya Kitaoka 120a6e
    com        = Insert;
Shinya Kitaoka 120a6e
    commandStr = tr("Insert ");
Shinya Kitaoka 120a6e
  } else if (commandName.startsWith("A ")) {
Shinya Kitaoka 120a6e
    com        = Add;
Shinya Kitaoka 120a6e
    commandStr = tr("Add ");
Shinya Kitaoka 120a6e
  } else if (commandName.startsWith("R ")) {
Shinya Kitaoka 120a6e
    com        = Replace;
Shinya Kitaoka 120a6e
    commandStr = tr("Replace ");
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // return if the action is not available
Shinya Kitaoka 120a6e
  if (!(command & com)) return 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QString fxStr = commandName.right(commandName.size() - 2);
Shinya Kitaoka 120a6e
  QString translatedCommandName =
Shinya Kitaoka 120a6e
      commandStr +
Shinya Kitaoka 120a6e
      QString::fromStdWString(TStringTable::translate(fxStr.toStdString()));
Shinya Kitaoka 120a6e
  // return the action if the command is the exactly same
Shinya Kitaoka 120a6e
  if (m_againCommand && translatedCommandName == m_againCommand->text())
Shinya Kitaoka 120a6e
    return m_againCommand;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // create an action
Shinya Kitaoka 120a6e
  if (!m_againCommand) {
Shinya Kitaoka 120a6e
    m_againCommand = new QAction(translatedCommandName, 0);
Shinya Kitaoka 120a6e
    m_againCommand->setData(QVariant(fxStr));
Shinya Kitaoka 120a6e
    connect(m_againCommand, SIGNAL(triggered()), this, SLOT(onAgainCommand()));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // compare the m_againCommand's name and commandName
Shinya Kitaoka 120a6e
  else if (translatedCommandName != m_againCommand->text()) {
Shinya Kitaoka 120a6e
    // change the action name
Shinya Kitaoka 120a6e
    m_againCommand->setText(translatedCommandName);
Shinya Kitaoka 120a6e
    m_againCommand->setData(QVariant(fxStr));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return m_againCommand;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------
Toshihiro Shimizu 890ddd
/*! change the command behavior according to the command name
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
void AddFxContextMenu::onAgainCommand() {
Shinya Kitaoka 120a6e
  // TODO: 日本語インタフェースの場合、対応が必要 2016/1/8 shun_iwasawa
Shinya Kitaoka 120a6e
  if (m_againCommand->text().startsWith("Insert")) {
Shinya Kitaoka 120a6e
    onInsertFx(m_againCommand);
Shinya Kitaoka 120a6e
  } else if (m_againCommand->text().startsWith("Add")) {
Shinya Kitaoka 120a6e
    onAddFx(m_againCommand);
Shinya Kitaoka 120a6e
  } else if (m_againCommand->text().startsWith("Replace")) {
Shinya Kitaoka 120a6e
    onReplaceFx(m_againCommand);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}