Action.hpp
Go to the documentation of this file.
1 #pragma once
2 #include <score/document/DocumentContext.hpp>
3 #include <score/plugins/StringFactoryKey.hpp>
4 
5 #include <QAction>
6 #include <QPointer>
7 #include <QString>
8 
9 #include <memory>
10 
26 namespace score
27 {
28 struct DocumentContext;
29 class ActionGroup;
30 class ActionManager;
31 using ActionGroupKey = StringKey<ActionGroup>;
32 
40 class SCORE_LIB_BASE_EXPORT ActionGroup
41 {
42 public:
43  ActionGroup(QString prettyName, ActionGroupKey key);
44 
49  QString prettyName() const;
50 
51  ActionGroupKey key() const;
52 
53 private:
54  QString m_name;
55  ActionGroupKey m_key;
56 };
57 class Action;
59 
78 class SCORE_LIB_BASE_EXPORT Action
79 {
80 public:
81  Action(
82  QAction* act, QString text, ActionKey key, ActionGroupKey k,
83  const QKeySequence& defaultShortcut);
84  Action(
85  QAction* act, QString text, ActionKey key, ActionGroupKey k,
86  const QKeySequence& defaultShortcut, const QKeySequence& defaultShortcut2);
87 
88  Action(
89  QAction* act, QString text, const char* key, const char* group_key,
90  const QKeySequence& defaultShortcut);
91 
92  ActionKey key() const;
93 
94  QAction* action() const;
95 
96  QKeySequence shortcut();
97  void setShortcut(const QKeySequence& shortcut);
98 
99  QKeySequence defaultShortcut();
100 
101 private:
102  void updateTexts();
103 
104  QPointer<QAction> m_impl{};
105  QString m_text;
106  ActionKey m_key;
107  ActionGroupKey m_groupKey;
108  QKeySequence m_default;
109  QKeySequence m_current;
110 };
111 
112 template <typename Action_T>
114 {
115 };
116 
132 {
133 private:
134  inline bool canAddAction(const ActionKey& other) const noexcept
135  {
136  for(auto& act : container)
137  if(act.key() == other)
138  return false;
139  return true;
140  }
141 
142 public:
143  std::vector<Action> container;
144 
145  template <typename Action_T>
146  void add(QAction* ptr)
147  {
148  SCORE_ASSERT(canAddAction(MetaAction<Action_T>::key()));
149  container.emplace_back(MetaAction<Action_T>::make(ptr));
150  }
151 };
152 
165 struct SCORE_LIB_BASE_EXPORT ActionCondition
166 {
168 
169  virtual ~ActionCondition();
170 
177  virtual void action(ActionManager& mgr, MaybeDocument);
178 
187  void setEnabled(score::ActionManager& mgr, bool b);
188 
194  template <typename Action_T>
195  void add()
196  {
197  SCORE_ASSERT(canAddAction(MetaAction<Action_T>::key()));
198  m_actions.emplace_back(MetaAction<Action_T>::key());
199  }
200 
201  StringKey<ActionCondition> key() const;
202 
203 private:
204  inline bool canAddAction(const ActionKey& other) const noexcept
205  {
206  for(const auto& act : m_actions)
207  if(act == other)
208  return false;
209  return true;
210  }
212  std::vector<ActionKey> m_actions;
213 };
214 
220 struct SCORE_LIB_BASE_EXPORT DocumentActionCondition : public ActionCondition
221 {
222  using ActionCondition::ActionCondition;
224 };
225 
231 struct SCORE_LIB_BASE_EXPORT EnableActionIfDocument final
232  : public DocumentActionCondition
233 {
235  : DocumentActionCondition{static_key()}
236  {
237  }
238 
240 
241  static StringKey<ActionCondition> static_key()
242  {
243  return StringKey<ActionCondition>{"EnableActionIfDocument"};
244  }
245 
246  void action(ActionManager& mgr, MaybeDocument doc) override;
247 };
248 
254 struct SCORE_LIB_BASE_EXPORT FocusActionCondition : public ActionCondition
255 {
256  using ActionCondition::ActionCondition;
258 };
259 
265 struct SCORE_LIB_BASE_EXPORT SelectionActionCondition : public ActionCondition
266 {
267  using ActionCondition::ActionCondition;
269 };
270 
277 struct SCORE_LIB_BASE_EXPORT CustomActionCondition
278  : public QObject
279  , public ActionCondition
280 {
281  W_OBJECT(CustomActionCondition)
282 
283 public:
284  using ActionCondition::ActionCondition;
286 
287  void changed(bool b) E_SIGNAL(SCORE_LIB_BASE_EXPORT, changed, b)
288 };
289 
291 
292 template <typename T>
294 template <typename T>
296 template <typename T>
298 
312 #define SCORE_DECLARE_SELECTED_OBJECT_CONDITION(Type) \
313  namespace score \
314  { \
315  template <> \
316  class EnableWhenSelectionContains<Type> final \
317  : public score::SelectionActionCondition \
318  { \
319  public: \
320  EnableWhenSelectionContains() \
321  : score::SelectionActionCondition{static_key()} \
322  { \
323  } \
324  \
325  static score::ActionConditionKey static_key() \
326  { \
327  return score::ActionConditionKey{"SelectedObjectIs" #Type}; \
328  } \
329  \
330  private: \
331  void action(score::ActionManager& mgr, score::MaybeDocument doc) override \
332  { \
333  if(!doc) \
334  { \
335  setEnabled(mgr, false); \
336  return; \
337  } \
338  \
339  const auto& sel = doc->selectionStack.currentSelection(); \
340  auto res = ossia::any_of( \
341  sel, [](auto obj) { return bool(dynamic_cast<const Type*>(obj.data())); }); \
342  \
343  setEnabled(mgr, res); \
344  } \
345  }; \
346  }
347 
361 #define SCORE_DECLARE_FOCUSED_OBJECT_CONDITION(Type) \
362  namespace score \
363  { \
364  template <> \
365  class EnableWhenFocusedObjectIs<Type> final : public score::FocusActionCondition \
366  { \
367  public: \
368  static score::ActionConditionKey static_key() \
369  { \
370  return score::ActionConditionKey{"FocusedObjectIs" #Type}; \
371  } \
372  \
373  EnableWhenFocusedObjectIs() \
374  : score::FocusActionCondition{static_key()} \
375  { \
376  } \
377  \
378  private: \
379  void action(score::ActionManager& mgr, score::MaybeDocument doc) override \
380  { \
381  if(!doc) \
382  { \
383  setEnabled(mgr, false); \
384  return; \
385  } \
386  \
387  auto obj = doc->focus.get(); \
388  if(!obj) \
389  { \
390  setEnabled(mgr, false); \
391  return; \
392  } \
393  \
394  if(dynamic_cast<const Type*>(obj)) \
395  { \
396  setEnabled(mgr, true); \
397  } \
398  } \
399  }; \
400  }
401 
415 #define SCORE_DECLARE_DOCUMENT_CONDITION(Type) \
416  namespace score \
417  { \
418  template <> \
419  class EnableWhenDocumentIs<Type> final : public score::DocumentActionCondition \
420  { \
421  public: \
422  static score::ActionConditionKey static_key() \
423  { \
424  return score::ActionConditionKey{"DocumentIs" #Type}; \
425  } \
426  EnableWhenDocumentIs() \
427  : score::DocumentActionCondition{static_key()} \
428  { \
429  } \
430  \
431  private: \
432  void action(score::ActionManager& mgr, score::MaybeDocument doc) override \
433  { \
434  if(!doc) \
435  { \
436  setEnabled(mgr, false); \
437  return; \
438  } \
439  auto model = score::IDocument::try_get<Type>(doc->document); \
440  setEnabled(mgr, bool(model)); \
441  } \
442  }; \
443  }
444 }
445 
446 #define SCORE_DECLARE_ACTION(ActionName, Text, Group, Shortcut) \
447  namespace Actions \
448  { \
449  struct ActionName; \
450  } \
451  namespace score \
452  { \
453  template <> \
454  struct MetaAction<Actions::ActionName> \
455  { \
456  static score::Action make(QAction* ptr) \
457  { \
458  return score::Action{ \
459  ptr, QObject::tr(Text), key(), score::ActionGroupKey{#Group}, Shortcut}; \
460  } \
461  \
462  static score::ActionKey key() \
463  { \
464  return score::ActionKey{#ActionName}; \
465  } \
466  }; \
467  }
468 
469 #define SCORE_DECLARE_ACTION_2S(ActionName, Text, Group, Shortcut1, Shortcut2) \
470  namespace Actions \
471  { \
472  struct ActionName; \
473  } \
474  namespace score \
475  { \
476  template <> \
477  struct MetaAction<Actions::ActionName> \
478  { \
479  static score::Action make(QAction* ptr) \
480  { \
481  return score::Action{ptr, QObject::tr(Text), \
482  key(), score::ActionGroupKey{#Group}, \
483  Shortcut1, Shortcut2}; \
484  } \
485  \
486  static score::ActionKey key() \
487  { \
488  return score::ActionKey{#ActionName}; \
489  } \
490  }; \
491  }
Base class for IdentifiedObject.
Definition: IdentifiedObjectAbstract.hpp:16
The ActionGroup class A semantic group of actions : for instance, all the actions related to audio re...
Definition: Action.hpp:41
The Action class.
Definition: Action.hpp:79
The ActionManager class.
Definition: ActionManager.hpp:19
Definition: Action.hpp:297
Definition: Action.hpp:295
Definition: Action.hpp:293
Base toolkit upon which the software is built.
Definition: Application.cpp:90
The ActionCondition struct.
Definition: Action.hpp:166
void add()
add Register an action for this condition.
Definition: Action.hpp:195
The ActionContainer struct.
Definition: Action.hpp:132
The CustomActionCondition struct.
Definition: Action.hpp:280
The DocumentActionCondition struct.
Definition: Action.hpp:221
Definition: DocumentContext.hpp:18
The EnableActionIfDocument struct.
Definition: Action.hpp:233
The FocusActionCondition struct.
Definition: Action.hpp:255
Definition: Action.hpp:114
The SelectionActionCondition struct.
Definition: Action.hpp:266