Audacity 3.2.0
MenuHelper.cpp
Go to the documentation of this file.
1#include "MenuHelper.h"
2#include "PluginManager.h"
3#include "EffectManager.h"
5#include "BatchCommands.h"
7
8#include "XMLFileReader.h"
9
10namespace {
11
12using EffectsMenuGroups = std::vector<std::pair<TranslatableString, std::vector<TranslatableString>>>;
13
15{
16 std::vector<const PluginDescriptor*> plugins;
17
18 std::function<bool(const PluginDescriptor*)> filter;
19 std::function<bool(const PluginDescriptor*, const PluginDescriptor*)> compare;
20 std::function<void(MenuHelper::Group&, std::vector<const PluginDescriptor*>&)> add;
21};
22
23enum class GroupBy
24{
26 Type,
28};
29
30enum class SortBy
31{
32 Name,
35};
36
38{
40 {
41 std::optional<std::string> textContent;
42 std::vector<TranslatableString>& effects;
43
44 EffectsHandler(std::vector<TranslatableString>& effects) : effects(effects) { }
45
46 bool HandleXMLTag(const std::string_view& tag, const AttributesList& attrs) override { return true; }
47 void HandleXMLContent(const std::string_view& text) override { textContent = text; }
48 void HandleXMLEndTag(const std::string_view& tag) override
49 {
50 if(textContent.has_value() && tag == "Effect")
51 effects.emplace_back(TranslatableString { *textContent, {} });
52 textContent.reset();
53 }
54 XMLTagHandler* HandleXMLChild(const std::string_view& tag) override
55 {
56 if(tag == "Effect")
57 return this;
58 return nullptr;
59 }
60
61 };
62
64 {
65 std::optional<std::string> textContent;
66 std::unique_ptr<EffectsHandler> effectsHandler;
67 std::pair<TranslatableString, std::vector<TranslatableString>>& group;
68
69 GroupHandler(std::pair<TranslatableString, std::vector<TranslatableString>>& group) : group(group) { }
70
71 bool HandleXMLTag(const std::string_view& tag, const AttributesList& attrs) override { return true; }
72 void HandleXMLContent(const std::string_view& text) override { textContent = text; }
73 void HandleXMLEndTag(const std::string_view& tag) override
74 {
75 if(textContent.has_value() && tag == "Name")
76 group.first = TranslatableString { *textContent, { } };
77 textContent.reset();
78 }
79 XMLTagHandler* HandleXMLChild(const std::string_view& tag) override
80 {
81 if(tag == "Effects")
82 {
83 effectsHandler = std::make_unique<EffectsHandler>(group.second);
84 return &*effectsHandler;
85 }
86 if(tag == "Name")
87 return this;
88
89 return nullptr;
90 }
91 };
92
94 std::unique_ptr<GroupHandler> groupHandler;
95
96 EffectsMenuGroupsHandler(EffectsMenuGroups& groups) : groups(groups) { }
97
98 bool HandleXMLTag(const std::string_view& tag, const AttributesList& attrs) override { return true; }
99
100 XMLTagHandler* HandleXMLChild(const std::string_view& tag) override
101 {
102 if(tag == "Group")
103 {
104 groups.resize(groups.size() + 1);
105 groupHandler = std::make_unique<GroupHandler>(groups.back());
106 return &*groupHandler;
107 }
108 return nullptr;
109 }
110};
111
113{
114 EffectsMenuGroups result;
116
117 XMLFileReader reader;
118 reader.Parse(&handler, path);
119 return result;
120}
121
122// Some weird special case stuff just for Noise Reduction so that there is
123// more informative help
125{
126 if ( plug->GetSymbol().Msgid() == XO( "Noise Reduction" ) )
127 return ( batchflags | NoiseReductionTimeSelectedFlag() ) & ~TimeSelectedFlag();
128 return batchflags;
129}
130
131
133 MenuHelper::Group &table,
135 const PluginIDs & plugs,
136 const std::vector<CommandFlag> & flags,
137 void (*onMenuCommand)(const CommandContext&))
138{
139 const int namesCnt = (int) names.size();
140
141 int groupCnt = namesCnt;
142 for (int i = 0; i < namesCnt; i++)
143 {
144 // compare full translations not msgids!
145 while (i + 1 < namesCnt && names[i].Translation() == names[i + 1].Translation())
146 {
147 i++;
148 groupCnt--;
149 }
150 }
151
152 using namespace MenuRegistry;
153
154 for (int i = 0; i < namesCnt; i++)
155 {
156 // compare full translations not msgids!
157 if (i + 1 < namesCnt && names[i].Translation() == names[i + 1].Translation())
158 {
159 // collect a sub-menu for like-named items
160 const auto name = names[i];
161 const auto translation = name.Translation();
162 auto subMenu = Menu("", name);
163 // compare full translations not msgids!
164 while (i < namesCnt && names[i].Translation() == translation)
165 {
166 const PluginDescriptor *plug =
167 PluginManager::Get().GetPlugin(plugs[i]);
168 if( plug->GetPluginType() == PluginTypeEffect )
169 subMenu->push_back( Command( plug->GetID(),
170 Verbatim( plug->GetPath() ),
171 onMenuCommand,
172 flags[i],
173 Options{}
174 .IsEffect()
176 .Parameter( plugs[i] ) ) );
177
178 i++;
179 }
180 table.push_back(move(subMenu));
181 i--;
182 }
183 else
184 {
185 // collect one item
186 const PluginDescriptor *plug =
187 PluginManager::Get().GetPlugin(plugs[i]);
188 if( plug->GetPluginType() == PluginTypeEffect )
189 table.push_back( Command(
190 plug->GetID(),
191 names[i],
192 onMenuCommand,
193 flags[i],
194 Options{}
195 .IsEffect()
197 .Parameter( plugs[i] ) ) );
198 }
199 }
200}
201
203 MenuHelper::Group &table,
204 std::vector<const PluginDescriptor*> & plugs,
205 CommandFlag batchflags,
206 SortBy sortBy,
207 void (*onMenuCommand)(const CommandContext&))
208{
209 size_t pluginCnt = plugs.size();
210
211 TranslatableStrings groupNames;
212 PluginIDs groupPlugs;
213 std::vector<CommandFlag> groupFlags;
214
215 for (size_t i = 0; i < pluginCnt; i++)
216 {
217 const PluginDescriptor *plug = plugs[i];
218
219 auto name = plug->GetSymbol().Msgid();
220
221 if (plug->IsEffectInteractive())
222 name += XO("...");
223
224 TranslatableString group;
225 if (sortBy == SortBy::PublisherName/* wxT("sortby:publisher:name")*/)
226 {
227 group = EffectManager::Get().GetVendorName(plug->GetID());
228 }
229 else if (sortBy == SortBy::TypeName /*wxT("sortby:type:name")*/)
230 {
232 }
233
234 if (plug->IsEffectDefault())
235 {
236 group = {};
237 }
238
239 groupNames.push_back(
240 group.empty()
241 ? name
242 : XO("%s: %s").Format( group, name )
243 );
244
245 groupPlugs.push_back(plug->GetID());
246 groupFlags.push_back(FixBatchFlags( batchflags, plug ) );
247 }
248
249 if (groupNames.size() > 0)
250 {
252 table, groupNames, groupPlugs, groupFlags,
253 onMenuCommand);
254 }
255}
256
258 const EffectsMenuGroups& list,
259 CommandFlag batchflags,
260 void (*onMenuCommand)(const CommandContext&)) -> auto
261{
262 return [=](MenuHelper::Group& items, std::vector<const PluginDescriptor*>& plugs)
263 {
264 for(auto& p : list)
265 {
266 TranslatableStrings groupNames;
267 PluginIDs groupPlugs;
268 std::vector<CommandFlag> groupFlags;
269
270 auto srcNames = p.second;
271 std::sort(srcNames.begin(), srcNames.end(), TranslationLess);
272
273 for(auto& name : srcNames)
274 {
275 auto it = std::find_if(plugs.begin(), plugs.end(), [&name](const PluginDescriptor* other)
276 {
277 return name == other->GetSymbol().Msgid();
278 });
279 if(it == plugs.end())
280 continue;
281
282 auto plug = *it;
283 if(plug->IsEffectInteractive())
284 groupNames.push_back(name + XO("..."));
285 else
286 groupNames.push_back( name );
287
288 groupPlugs.push_back(plug->GetID());
289 groupFlags.push_back(FixBatchFlags( batchflags, plug ) );
290 }
291
292 if (!groupNames.empty())
293 {
294 using namespace MenuRegistry;
295 if (p.first.empty()) {
296 auto temp = Items("");
298 groupNames, groupPlugs, groupFlags,
299 onMenuCommand);
300 items.push_back(move(temp));
301 }
302 else {
303 auto temp = Menu("", p.first);
305 groupNames, groupPlugs, groupFlags,
306 onMenuCommand);
307 items.push_back(move(temp));
308 }
309 }
310 }
311 };
312}
313
315 MenuHelper::Group& table,
316 std::vector<const PluginDescriptor*>& plugs,
317 CommandFlag batchflags,
318 GroupBy groupBy,
319 void (*onMenuCommand)(const CommandContext&))
320{
321 using namespace MenuRegistry;
322
323 const auto UnknownGroupName = XO("Unknown");
324 auto& effectManager = EffectManager::Get();
325
326 std::vector<TranslatableString> path;
327
328 auto *parentTable = &table;
329 std::vector<TranslatableString> names;
330 PluginIDs group;
331 std::vector<CommandFlag> flags;
332
333 auto doAddGroup = [&]
334 {
335 using namespace MenuRegistry;
336 if(names.empty())
337 return;
338
339 const auto inSubmenu = !path.empty() && (names.size() > 1);
340 const auto label = inSubmenu ? path.back() : TranslatableString{};
341 if (label.empty()) {
342 auto items = Items("");
343 AddEffectMenuItemGroup(*items, names, group, flags, onMenuCommand);
344 parentTable->push_back(move(items));
345 }
346 else {
347 auto items = Menu("", label);
348 AddEffectMenuItemGroup(*items, names, group, flags, onMenuCommand);
349 parentTable->push_back(move(items));
350 }
351
352 names.clear();
353 group.clear();
354 flags.clear();
355 };
356
357 for(auto plug : plugs)
358 {
359 if(groupBy == GroupBy::Publisher)
360 {
361 const auto vendorName = effectManager.GetVendorName(plug->GetID());
362 if(path.empty() || path[0] != vendorName)
363 {
364 doAddGroup();
365 path = { vendorName };
366 }
367 }
368 else if(groupBy == GroupBy::Type)
369 {
370 const auto effectFamilyName = effectManager.GetEffectFamilyName(plug->GetID());
371 if(path.empty() || path[0] != effectFamilyName)
372 {
373 doAddGroup();
374 path = { effectFamilyName };
375 }
376 }
377 else if(groupBy == GroupBy::TypePublisher)
378 {
379 const auto effectFamilyName = effectManager.GetEffectFamilyName(plug->GetID());
380 const auto vendorName = effectManager.GetVendorName(plug->GetID());
381 if(path.empty() || path[0] != effectFamilyName)
382 {
383 doAddGroup();
384 path = { effectFamilyName, vendorName };
385 auto menu = Menu("", effectFamilyName);
386 parentTable = menu.get();
387 table.push_back(move(menu));
388 }
389 else if(path[1] != vendorName)
390 {
391 doAddGroup();
392 path[1] = vendorName;
393 }
394 }
395
396 group.push_back(plug->GetID());
397 names.push_back(plug->GetSymbol().Msgid());
398 flags.push_back(FixBatchFlags( batchflags, plug ) );
399 }
400 doAddGroup();
401}
402
404{
405 return
406 std::make_pair( a->GetSymbol().Translation(), a->GetPath() ) <
407 std::make_pair( b->GetSymbol().Translation(), b->GetPath() );
408}
409
411 const PluginDescriptor *a, const PluginDescriptor *b)
412{
413 auto &em = EffectManager::Get();
414
415 auto akey = em.GetVendorName(a->GetID());
416 auto bkey = em.GetVendorName(b->GetID());
417
418 if (akey.empty())
419 akey = XO("Uncategorized");
420 if (bkey.empty())
421 bkey = XO("Uncategorized");
422
423 return
424 std::make_tuple(
425 akey.Translation(), a->GetSymbol().Translation(), a->GetPath() ) <
426 std::make_tuple(
427 bkey.Translation(), b->GetSymbol().Translation(), b->GetPath() );
428}
429
431 const PluginDescriptor *a, const PluginDescriptor *b)
432{
433 auto &em = EffectManager::Get();
434 auto akey = em.GetVendorName(a->GetID());
435 auto bkey = em.GetVendorName(b->GetID());
436
437 if (a->IsEffectDefault())
438 akey = {};
439 if (b->IsEffectDefault())
440 bkey = {};
441
442 return
443 std::make_tuple(
444 akey.Translation(), a->GetSymbol().Translation(), a->GetPath() ) <
445 std::make_tuple(
446 bkey.Translation(), b->GetSymbol().Translation(), b->GetPath() );
447}
448
450 const PluginDescriptor *a, const PluginDescriptor *b)
451{
452 auto &em = EffectManager::Get();
453 auto akey = em.GetEffectFamilyName(a->GetID());
454 auto bkey = em.GetEffectFamilyName(b->GetID());
455
456 if (akey.empty())
457 akey = XO("Uncategorized");
458 if (bkey.empty())
459 bkey = XO("Uncategorized");
460
461 if (a->IsEffectDefault())
462 akey = {};
463 if (b->IsEffectDefault())
464 bkey = {};
465
466 return
467 std::make_tuple(
468 akey.Translation(), a->GetSymbol().Translation(), a->GetPath() ) <
469 std::make_tuple(
470 bkey.Translation(), b->GetSymbol().Translation(), b->GetPath() );
471}
472
474{
475 auto &em = EffectManager::Get();
476 auto akey = em.GetEffectFamilyName(a->GetID());
477 auto bkey = em.GetEffectFamilyName(b->GetID());
478
479 if (akey.empty())
480 akey = XO("Uncategorized");
481 if (bkey.empty())
482 bkey = XO("Uncategorized");
483
484 return
485 std::make_tuple(
486 akey.Translation(), a->GetSymbol().Translation(), a->GetPath() ) <
487 std::make_tuple(
488 bkey.Translation(), b->GetSymbol().Translation(), b->GetPath() );
489}
490
492{
493 auto &em = EffectManager::Get();
494 auto aType = em.GetEffectFamilyName(a->GetID());
495 auto bType = em.GetEffectFamilyName(b->GetID());
496 auto aVendor = em.GetVendorName(a->GetID());
497 auto bVendor = em.GetVendorName(b->GetID());
498
499 if (aType.empty())
500 aType = XO("Uncategorized");
501 if (bType.empty())
502 bType = XO("Uncategorized");
503 if (aVendor.empty())
504 aVendor = XO("Unknown");
505 if (bVendor.empty())
506 bVendor = XO("Unknown");
507
508 return
509 std::make_tuple(
510 aType.Translation(), aVendor.Translation(), a->GetSymbol().Translation(), a->GetPath() ) <
511 std::make_tuple(
512 bType.Translation(), bVendor.Translation(), b->GetSymbol().Translation(), b->GetPath() );
513}
514
516{
517 if( PluginManager::Get().IsPluginLoaded(plug->GetID()) && EffectManager::Get().IsHidden(plug->GetID()) )
518 return false;
519 if ( !plug->IsEnabled() ){
520 return false;// don't add to menus!
521 }
522 return true;
523}
524
526{
527 if (plug->IsEffectDefault())
528 return true;
529 return false;
530}
531
533{
534 if(IsDefaultPlugin(plug))
535 return true;
536 auto applicationResourcePath = wxFileName(FileNames::ResourcesDir());
537 auto pluginPath = wxFileName(plug->GetPath());
538 pluginPath.MakeAbsolute();
539 return pluginPath.GetPath().StartsWith(applicationResourcePath.GetPath());
540}
541
542auto MakeGroupsFilter(const EffectsMenuGroups& list) -> auto
543{
544 return [=](const PluginDescriptor* plug)
545 {
546 if(!IsEnabledPlugin(plug))
547 return false;
548
549 for(auto& p : list)
550 {
551 for(auto& name : p.second)
552 {
553 if(name == plug->GetSymbol().Msgid())
554 return true;
555 }
556 }
557 return false;
558 };
559}
560
561}
562
565 EffectType type,
566 CommandFlag batchflags,
567 const wxString& groupby,
568 void (*onMenuCommand)(const CommandContext&),
569 std::function<bool(const PluginDescriptor&)> pred)
570{
572
573 std::vector<MenuSectionBuilder> sections;
574
575 auto MakeAddSortedItems = [=](SortBy sortby)
576 {
577 return [=](Group& items, std::vector<const PluginDescriptor*>& plugins)
578 {
579 return AddSortedEffectMenuItems(items, plugins, batchflags, sortby, onMenuCommand);
580 };
581 };
582
583 auto MakeAddGroupedItems = [=](GroupBy groupBy)
584 {
585 return [=](Group& items, std::vector<const PluginDescriptor*>& plugins)
586 {
587 return AddGroupedEffectMenuItems(items, plugins, batchflags, groupBy, onMenuCommand);
588 };
589 };
590
591 auto DefaultFilter = [](auto plug) { return IsEnabledPlugin(plug) && IsDefaultPlugin(plug); };
592 if(groupby == "default")
593 {
594 if(type == EffectTypeProcess)
595 {
596 static auto effectMenuDefaults = [] {
597 wxFileName path = wxFileName(FileNames::ResourcesDir(), wxT("EffectsMenuDefaults.xml"));
598 return LoadEffectsMenuGroups(path.GetFullPath());
599 }();
600 static auto groupsFilter = MakeGroupsFilter(effectMenuDefaults);
601
602 sections.emplace_back(
603 MenuSectionBuilder {
604 {},
605 [=](auto plug) { return IsBundledPlugin(plug) && groupsFilter(plug); },
606 nullptr,
607 MakeAddGroupItems(effectMenuDefaults, batchflags, onMenuCommand)
608 });
609 sections.emplace_back(
610 MenuSectionBuilder {
611 {},
614 MakeAddGroupedItems(GroupBy::Publisher)
615 });
616 }
617 else//Generators/Analyzers
618 {
619 sections.emplace_back(
620 MenuSectionBuilder {
621 {},
622 [](auto plug){ return IsEnabledPlugin(plug) && IsBundledPlugin(plug); } ,
624 MakeAddSortedItems(SortBy::Name)
625 });
626 sections.emplace_back(
627 MenuSectionBuilder {
628 {},
631 MakeAddGroupedItems(GroupBy::Publisher)
632 });
633 }
634 }
635 else if(groupby == "sortby:publisher:name")
636 {
637 sections.emplace_back(
638 MenuSectionBuilder {
639 {},
640 DefaultFilter,
642 MakeAddSortedItems(SortBy::PublisherName)
643 });
644 sections.emplace_back(
645 MenuSectionBuilder {
646 {},
649 MakeAddSortedItems(SortBy::PublisherName)
650 });
651 }
652 else if(groupby == "sortby:type:name")
653 {
654 sections.emplace_back(
655 MenuSectionBuilder {
656 {},
657 DefaultFilter,
659 MakeAddSortedItems(SortBy::TypeName)
660 });
661 sections.emplace_back(
662 MenuSectionBuilder {
663 {},
666 MakeAddSortedItems(SortBy::TypeName)
667 });
668 }
669 else if(groupby == "groupby:publisher")
670 {
671 sections.emplace_back(
672 MenuSectionBuilder {
673 {},
674 DefaultFilter,
676 MakeAddGroupedItems(GroupBy::Publisher)
677 });
678 sections.emplace_back(
679 MenuSectionBuilder {
680 {},
683 MakeAddGroupedItems(GroupBy::Publisher)
684 });
685 }
686 else if(groupby == "groupby:type")
687 {
688 sections.emplace_back(
689 MenuSectionBuilder {
690 {},
691 DefaultFilter,
693 MakeAddGroupedItems(GroupBy::Type)
694 });
695 sections.emplace_back(
696 MenuSectionBuilder {
697 {},
700 MakeAddGroupedItems(GroupBy::Type)
701 });
702 }
703 else if(groupby == "groupby:type:publisher")
704 {
705 sections.emplace_back(
706 MenuSectionBuilder {
707 {},
708 DefaultFilter,
710 MakeAddGroupedItems(GroupBy::Type)
711 });
712 sections.push_back(
713 MenuSectionBuilder {
714 {},
717 MakeAddGroupedItems(GroupBy::TypePublisher)
718 });
719 }
720 else //if(groupby == "sortby:name")
721 {
722 sections.emplace_back(
723 MenuSectionBuilder {
724 {},
725 DefaultFilter,
727 MakeAddSortedItems(SortBy::Name)
728 });
729 sections.emplace_back(
730 MenuSectionBuilder {
731 {},
734 MakeAddSortedItems(SortBy::Name)
735 });
736 }
737 for(auto& plugin : pm.EffectsOfType(type))
738 {
739 if(pred && !pred(plugin))
740 continue;
741
742 for(auto& section : sections)
743 {
744 if(section.filter(&plugin))
745 {
746 section.plugins.push_back(&plugin);
747 break;
748 }
749 }
750 }
751
752 for(auto& section : sections)
753 {
754 if(section.compare != nullptr)
755 std::sort(section.plugins.begin(), section.plugins.end(), section.compare);
756
757 if (menuItems.empty()) {
758 auto group = MenuRegistry::Items("");
759 section.add(*group, section.plugins);
760 if (group->empty())
761 continue;
762 menuItems.push_back(move(group));
763 }
764 else {
765 auto group = MenuRegistry::Section("");
766 section.add(*group, section.plugins);
767 if (group->empty())
768 continue;
769 menuItems.push_back(move(group));
770 }
771 }
772}
wxT("CloseDown"))
std::bitset< NCommandFlags > CommandFlag
Definition: CommandFlag.h:30
const ReservedCommandFlag & NoiseReductionTimeSelectedFlag()
EffectType
@ EffectTypeProcess
XO("Cut/Copy/Paste")
@ PluginTypeEffect
wxArrayString PluginIDs
wxString name
Definition: TagsEditor.cpp:166
TranslatableString label
Definition: TagsEditor.cpp:165
static TranslatableStrings names
Definition: TagsEditor.cpp:153
bool TranslationLess(const TranslatableString &a, const TranslatableString &b)
A commonly needed sort comparator, which depends on the language setting.
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
std::vector< TranslatableString > TranslatableStrings
std::vector< Attribute > AttributesList
Definition: XMLTagHandler.h:40
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
const TranslatableString & Msgid() const
const wxString Translation() const
static EffectManager & Get()
TranslatableString GetVendorName(const PluginID &ID)
TranslatableString GetEffectFamilyName(const PluginID &ID)
bool IsHidden(const PluginID &ID)
Abstract base class used in importing a file.
const ComponentInterfaceSymbol & GetSymbol() const
PluginType GetPluginType() const
bool IsEffectDefault() const
bool IsEffectInteractive() const
const wxString & GetID() const
bool IsEnabled() const
const PluginPath & GetPath() const
PluginManager maintains a list of all plug ins. That covers modules, effects, generators,...
Definition: PluginManager.h:51
Range EffectsOfType(EffectType type)
const PluginDescriptor * GetPlugin(const PluginID &ID) const
static PluginManager & Get()
Holds a msgid for the translation catalog; may also bind format arguments.
Reads a file and passes the results through an XMLTagHandler.
Definition: XMLFileReader.h:19
bool Parse(XMLTagHandler *baseHandler, const FilePath &fname)
This class is an interface which should be implemented by classes which wish to be able to load and s...
Definition: XMLTagHandler.h:42
FILES_API FilePath ResourcesDir()
void PopulateEffectsMenu(Group &menuItems, EffectType type, CommandFlag batchflags, const wxString &groupby, void(*onMenuCommand)(const CommandContext &), std::function< bool(const PluginDescriptor &)> pred={})
Definition: MenuHelper.cpp:563
constexpr auto Section
Definition: MenuRegistry.h:436
constexpr auto Items
Definition: MenuRegistry.h:427
constexpr auto Command
Definition: MenuRegistry.h:456
constexpr auto Menu
Items will appear in a main toolbar menu or in a sub-menu.
Definition: MenuRegistry.h:445
EffectsMenuGroups LoadEffectsMenuGroups(const wxString &path)
Definition: MenuHelper.cpp:112
bool IsDefaultPlugin(const PluginDescriptor *plug)
Definition: MenuHelper.cpp:525
bool CompareEffectsByTypeAndName(const PluginDescriptor *a, const PluginDescriptor *b)
Definition: MenuHelper.cpp:449
bool ComapareEffectsByTypeAndPublisher(const PluginDescriptor *a, const PluginDescriptor *b)
Definition: MenuHelper.cpp:491
void AddSortedEffectMenuItems(MenuHelper::Group &table, std::vector< const PluginDescriptor * > &plugs, CommandFlag batchflags, SortBy sortBy, void(*onMenuCommand)(const CommandContext &))
Definition: MenuHelper.cpp:202
bool CompareEffectsByPublisherAndName(const PluginDescriptor *a, const PluginDescriptor *b)
Definition: MenuHelper.cpp:430
bool CompareEffectsByPublisher(const PluginDescriptor *a, const PluginDescriptor *b)
Definition: MenuHelper.cpp:410
bool CompareEffectsByName(const PluginDescriptor *a, const PluginDescriptor *b)
Definition: MenuHelper.cpp:403
void AddGroupedEffectMenuItems(MenuHelper::Group &table, std::vector< const PluginDescriptor * > &plugs, CommandFlag batchflags, GroupBy groupBy, void(*onMenuCommand)(const CommandContext &))
Definition: MenuHelper.cpp:314
bool IsEnabledPlugin(const PluginDescriptor *plug)
Definition: MenuHelper.cpp:515
void AddEffectMenuItemGroup(MenuHelper::Group &table, const TranslatableStrings &names, const PluginIDs &plugs, const std::vector< CommandFlag > &flags, void(*onMenuCommand)(const CommandContext &))
Definition: MenuHelper.cpp:132
CommandFlag FixBatchFlags(CommandFlag batchflags, const PluginDescriptor *plug)
Definition: MenuHelper.cpp:124
bool IsBundledPlugin(const PluginDescriptor *plug)
Definition: MenuHelper.cpp:532
auto MakeAddGroupItems(const EffectsMenuGroups &list, CommandFlag batchflags, void(*onMenuCommand)(const CommandContext &)) -> auto
Definition: MenuHelper.cpp:257
auto MakeGroupsFilter(const EffectsMenuGroups &list) -> auto
Definition: MenuHelper.cpp:542
std::vector< std::pair< TranslatableString, std::vector< TranslatableString > > > EffectsMenuGroups
Definition: MenuHelper.cpp:12
bool CompareEffectsByType(const PluginDescriptor *a, const PluginDescriptor *b)
Definition: MenuHelper.cpp:473
auto push_back(Arg &&arg) -> std::enable_if_t< Traits< Base, Derived > ::template enables_item_type_v< Arg >, void >
Definition: Composite.h:105
Options && AllowInMacros(int value=1) &&
Definition: MenuRegistry.h:69
Options && IsEffect(bool value=true) &&
Definition: MenuRegistry.h:50
Options && Parameter(const CommandParameter &value) &&
Definition: MenuRegistry.h:52
Has variadic and range constructors that check types.
Definition: Registry.h:292
XMLTagHandler * HandleXMLChild(const std::string_view &tag) override
Definition: MenuHelper.cpp:54
bool HandleXMLTag(const std::string_view &tag, const AttributesList &attrs) override
Definition: MenuHelper.cpp:46
bool HandleXMLTag(const std::string_view &tag, const AttributesList &attrs) override
Definition: MenuHelper.cpp:71
XMLTagHandler * HandleXMLChild(const std::string_view &tag) override
Definition: MenuHelper.cpp:79
std::pair< TranslatableString, std::vector< TranslatableString > > & group
Definition: MenuHelper.cpp:67
GroupHandler(std::pair< TranslatableString, std::vector< TranslatableString > > &group)
Definition: MenuHelper.cpp:69
XMLTagHandler * HandleXMLChild(const std::string_view &tag) override
Definition: MenuHelper.cpp:100
bool HandleXMLTag(const std::string_view &tag, const AttributesList &attrs) override
Definition: MenuHelper.cpp:98
std::function< bool(const PluginDescriptor *)> filter
Definition: MenuHelper.cpp:18
std::function< bool(const PluginDescriptor *, const PluginDescriptor *)> compare
Definition: MenuHelper.cpp:19
std::vector< const PluginDescriptor * > plugins
Definition: MenuHelper.cpp:16
std::function< void(MenuHelper::Group &, std::vector< const PluginDescriptor * > &)> add
Definition: MenuHelper.cpp:20