Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef MENUBAR_COMMAND_H
Toshihiro Shimizu 890ddd
#define MENUBAR_COMMAND_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <vector></vector>
Toshihiro Shimizu 890ddd
#include <map></map>
Toshihiro Shimizu 890ddd
#include <string></string>
Toshihiro Shimizu 890ddd
#include "tcommon.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <qaction></qaction>
Toshihiro Shimizu 890ddd
#include <qmenu></qmenu>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#undef DVAPI
Toshihiro Shimizu 890ddd
#undef DVVAR
Toshihiro Shimizu 890ddd
#ifdef TOONZQT_EXPORTS
Toshihiro Shimizu 890ddd
#define DVAPI DV_EXPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_EXPORT_VAR
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define DVAPI DV_IMPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_IMPORT_VAR
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// forward declaration
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
class QAction;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// base class
Toshihiro Shimizu 890ddd
//
Shinya Kitaoka 120a6e
class DVAPI CommandHandlerInterface {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  virtual ~CommandHandlerInterface() {}
Shinya Kitaoka 120a6e
  virtual void execute() = 0;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// command identifier (e.g. "copy"). They are NOT command names (e.g. "&Copy")
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
typedef const char *CommandId;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
enum CommandType {
Shinya Kitaoka 120a6e
  UndefinedCommandType = 0,
Shinya Kitaoka 120a6e
  RightClickMenuCommandType,
Shinya Kitaoka 120a6e
  MenuFileCommandType,
Shinya Kitaoka 120a6e
  MenuEditCommandType,
Shinya Kitaoka 120a6e
  MenuScanCleanupCommandType,
Shinya Kitaoka 120a6e
  MenuLevelCommandType,
Shinya Kitaoka 120a6e
  MenuXsheetCommandType,
Shinya Kitaoka 120a6e
  MenuCellsCommandType,
Shinya Kitaoka 120a6e
  MenuViewCommandType,
Shinya Kitaoka 120a6e
  MenuWindowsCommandType,
Shinya Kitaoka 120a6e
  PlaybackCommandType,
Shinya Kitaoka 120a6e
  RGBACommandType,
Shinya Kitaoka 120a6e
  FillCommandType,
Shinya Kitaoka 120a6e
  ToolCommandType,
Shinya Kitaoka 120a6e
  ToolModifierCommandType,
Shinya Kitaoka 120a6e
  ZoomCommandType,
Shinya Kitaoka 120a6e
  MiscCommandType,
Shinya Kitaoka 120a6e
  MenuCommandType
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class AuxActionsCreator {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  AuxActionsCreator();
Shinya Kitaoka 120a6e
  virtual ~AuxActionsCreator(){};
Shinya Kitaoka 120a6e
  virtual void createActions(QObject *parent) = 0;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class AuxActionsCreatorManager {
Shinya Kitaoka 120a6e
  bool m_auxActionsCreated;
Shinya Kitaoka 120a6e
  std::vector<auxactionscreator *=""> m_auxActionsCreators;</auxactionscreator>
Shinya Kitaoka 120a6e
  AuxActionsCreatorManager();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  static AuxActionsCreatorManager *instance();
Shinya Kitaoka 120a6e
  void addAuxActionsCreator(AuxActionsCreator *auxActionsCreator);
Shinya Kitaoka 120a6e
  void createAuxActions(QObject *parent);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// command manager:
Toshihiro Shimizu 890ddd
//    setExecutor(id, executor)
Toshihiro Shimizu 890ddd
//    setAction(id, qaction)
Toshihiro Shimizu 890ddd
//    execute(qaction)/
Toshihiro Shimizu 890ddd
//
Shinya Kitaoka 120a6e
class DVAPI CommandManager {  // singleton
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  class Node {
Shinya Kitaoka 120a6e
  public:
Shinya Kitaoka 120a6e
    std::string m_id;
Shinya Kitaoka 120a6e
    CommandType m_type;
Shinya Kitaoka 120a6e
    QAction *m_qaction;
Shinya Kitaoka 120a6e
    CommandHandlerInterface *m_handler;
Shinya Kitaoka 120a6e
    bool m_enabled;
Shinya Kitaoka 120a6e
    QString m_onText,
Shinya Kitaoka 120a6e
        m_offText;  // for toggle commands. e.g. show/hide something
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    Node(CommandId id)
Shinya Kitaoka 120a6e
        : m_id(id)
Shinya Kitaoka 120a6e
        , m_type(UndefinedCommandType)
Shinya Kitaoka 120a6e
        , m_qaction(0)
Shinya Kitaoka 120a6e
        , m_handler(0)
Shinya Kitaoka 120a6e
        , m_enabled(true) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ~Node() {
Shinya Kitaoka 120a6e
      if (m_handler) delete m_handler;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<std::string, *="" node=""> m_idTable;</std::string,>
Shinya Kitaoka 120a6e
  std::map<qaction *="" *,="" node=""> m_qactionTable;</qaction>
Shinya Kitaoka 120a6e
  std::map<std::string, *="" node=""> m_shortcutTable;</std::string,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  CommandManager();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Node *getNode(CommandId id, bool createIfNeeded = true);
Shinya Kitaoka 120a6e
  void setShortcut(CommandId id, QAction *action, std::string shortcutString);
Shinya Kitaoka 120a6e
  void createAuxActions();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  static CommandManager *instance();
Shinya Kitaoka 120a6e
  ~CommandManager();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void setHandler(CommandId id, CommandHandlerInterface *handler);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void define(CommandId id, CommandType type, std::string defaultShortcutString,
Shinya Kitaoka 120a6e
              QAction *action);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QAction *createAction(const char *id, const char *name,
Shinya Kitaoka 120a6e
                        const char *defaultShortcut);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void getActions(CommandType type, std::vector<qaction *=""> &actions);</qaction>
Shinya Kitaoka 120a6e
  QAction *getActionFromShortcut(std::string shortcutString);
Shinya Kitaoka 120a6e
  std::string getShortcutFromAction(QAction *action);
Shinya Kitaoka 120a6e
  std::string getShortcutFromId(CommandId id);
Shinya Kitaoka 120a6e
  int getKeyFromShortcut(const std::string &shortcut);
Shinya Kitaoka 120a6e
  int getKeyFromId(CommandId id);
Jeremy Bullock e8903b
  void setShortcut(QAction *action, std::string shortcutString,
Jeremy Bullock e8903b
                   bool keepDefault = true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QAction *getAction(CommandId id, bool createIfNeeded = false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // createAction creates a new indepenent QAction with text and shortcut
Shinya Kitaoka 120a6e
  // if the action is a toggle action (e.g. show/hide something) the text is
Shinya Kitaoka 120a6e
  // controlled by state
Shinya Kitaoka 120a6e
  // you can use createAction() for context menu
Shinya Kitaoka 120a6e
  QAction *createAction(CommandId id, QObject *parent = 0, bool state = true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void execute(QAction *action);
Shinya Kitaoka 120a6e
  /*! If action is defined in m_qactionTable recall \b execute(action),
Shinya Kitaoka 120a6e
   * otherwise recall execute(menuAction).*/
Shinya Kitaoka 120a6e
  void execute(QAction *action, QAction *menuAction);
Shinya Kitaoka 120a6e
  void execute(CommandId id);
Shinya Kitaoka 120a6e
  void enable(CommandId id, bool enabled);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // if id is a toggle (e.g. a checkable menu item) then set its status;
Shinya Kitaoka 120a6e
  // note: this will trigger any associated handler
Shinya Kitaoka 120a6e
  void setChecked(CommandId id, bool checked);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // use setToggleTexts for toggle commands that have two names according to the
Shinya Kitaoka 120a6e
  // current status. e.g. show/hide something
Shinya Kitaoka 120a6e
  void setToggleTexts(CommandId id, const QString &onText,
Shinya Kitaoka 120a6e
                      const QString &offText);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string getIdFromAction(QAction *action);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// CommandHandlerHelper = target + method
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Shinya Kitaoka d1f6c4
class CommandHandlerHelper final : public CommandHandlerInterface {
Shinya Kitaoka 120a6e
  T *m_target;
Shinya Kitaoka 120a6e
  void (T::*m_method)();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  CommandHandlerHelper(T *target, void (T::*method)())
Shinya Kitaoka 120a6e
      : m_target(target), m_method(method) {}
Shinya Kitaoka 473e70
  void execute() override { (m_target->*m_method)(); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class r="" t,="" typename=""></class>
Shinya Kitaoka d1f6c4
class CommandHandlerHelper2 final : public CommandHandlerInterface {
Shinya Kitaoka 120a6e
  T *m_target;
Shinya Kitaoka 120a6e
  void (T::*m_method)(R value);
Shinya Kitaoka 120a6e
  R m_value;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  CommandHandlerHelper2(T *target, void (T::*method)(R), R value)
Shinya Kitaoka 120a6e
      : m_target(target), m_method(method), m_value(value) {}
Shinya Kitaoka 473e70
  void execute() override { (m_target->*m_method)(m_value); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Shinya Kitaoka 120a6e
inline void setCommandHandler(CommandId id, T *target, void (T::*method)()) {
Shinya Kitaoka 120a6e
  CommandManager::instance()->setHandler(
Shinya Kitaoka 120a6e
      id, new CommandHandlerHelper<t>(target, method));</t>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class DVAPI MenuItemHandler : public QObject {
Shinya Kitaoka 120a6e
  Q_OBJECT
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  MenuItemHandler(CommandId cmdId);
Shinya Kitaoka 120a6e
  virtual ~MenuItemHandler(){};
Shinya Kitaoka 120a6e
  virtual void execute() = 0;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Shinya Kitaoka d1f6c4
class OpenPopupCommandHandler final : public MenuItemHandler {
Shinya Kitaoka 120a6e
  T *m_popup;
Shinya Kitaoka 120a6e
  CommandId m_id;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  OpenPopupCommandHandler(CommandId cmdId)
Shinya Kitaoka 120a6e
      : MenuItemHandler(cmdId), m_popup(0) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void execute() override {
Shinya Kitaoka 120a6e
    if (!m_popup) m_popup = new T();
Shinya Kitaoka 120a6e
    m_popup->show();
Shinya Kitaoka 120a6e
    m_popup->raise();
Shinya Kitaoka 120a6e
    m_popup->activateWindow();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class DVAPI DVAction final : public QAction {
Shinya Kitaoka 120a6e
  Q_OBJECT
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  DVAction(const QString &text, QObject *parent);
Shinya Kitaoka 120a6e
  DVAction(const QIcon &icon, const QString &text, QObject *parent);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public slots:
Shinya Kitaoka 120a6e
  void onTriggered();
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class DVAPI DVMenuAction final : public QMenu {
Shinya Kitaoka 120a6e
  Q_OBJECT
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int m_triggeredActionIndex;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  DVMenuAction(const QString &text, QWidget *parent, QList<qstring> actions);</qstring>
Shinya Kitaoka 120a6e
  void setActions(QList<qstring> actions);</qstring>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int getTriggeredActionIndex() { return m_triggeredActionIndex; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public slots:
Shinya Kitaoka 120a6e
  void onTriggered(QAction *action);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // MENUBAR_COMMAND_H