Some refactoring: global editor option pages are requested from the plugins explicitly. So the generic editor options are not added automatically.

This commit is contained in:
Matthias Koefferlein 2026-02-02 00:09:29 +01:00
parent f0de3013cb
commit a6eb598abd
22 changed files with 146 additions and 63 deletions

View File

@ -138,6 +138,15 @@ PluginDeclaration::create_plugin (db::Manager *manager, lay::Dispatcher *, lay::
return new ant::Service (manager, view);
}
std::vector<std::string>
PluginDeclaration::additional_editor_options_pages () const
{
std::vector<std::string> names;
// TODO: provide in a central place instead of borrowing from the edt module
names.push_back ("GenericEditorOptions");
return names;
}
bool
PluginDeclaration::menu_activated (const std::string &symbol) const
{

View File

@ -54,6 +54,8 @@ public:
virtual void uninitialize (lay::Dispatcher *);
virtual bool menu_activated (const std::string &symbol) const;
virtual std::vector<std::string> additional_editor_options_pages () const;
void register_annotation_template (const ant::Template &t, lay::Plugin *plugin = 0);
void unregister_annotation_template (const std::string &category, lay::Plugin *plugin = 0);

View File

@ -1060,7 +1060,7 @@ ConnectionToolboxWidget::configure (const std::string &name, const std::string &
// Registrations
// unspecific editor options - used for all plugins that want it
static tl::RegisteredClass<lay::EditorOptionsPageFactoryBase> s_factory_generic (new lay::EditorOptionsPageFactory<EditorOptionsGeneric> (), 0);
static tl::RegisteredClass<lay::EditorOptionsPageFactoryBase> s_factory_generic (new lay::EditorOptionsPageFactory<EditorOptionsGeneric> ("GenericEditorOptions"), 0);
static tl::RegisteredClass<lay::EditorOptionsPageFactoryBase> s_factory_texts (new lay::EditorOptionsPageFactory<edt::EditorOptionsText> ("edt::Service(Texts)"), 0);
static tl::RegisteredClass<lay::EditorOptionsPageFactoryBase> s_factory_paths (new lay::EditorOptionsPageFactory<edt::EditorOptionsPath> ("edt::Service(Paths)"), 0);

View File

@ -52,7 +52,6 @@ namespace Ui
namespace lay
{
class PluginDeclaration;
class Dispatcher;
class LayoutViewBase;
class Plugin;

View File

@ -142,6 +142,13 @@ public:
}
}
virtual std::vector<std::string> additional_editor_options_pages () const
{
std::vector<std::string> names;
names.push_back ("GenericEditorOptions");
return names;
}
private:
std::string m_title;
std::string m_mouse_mode;
@ -408,6 +415,13 @@ public:
return true;
}
virtual std::vector<std::string> additional_editor_options_pages () const
{
std::vector<std::string> names;
names.push_back ("GenericEditorOptions");
return names;
}
private:
std::string m_title;
std::string m_mouse_mode;

View File

@ -2070,7 +2070,7 @@ Service::commit_recent ()
auto pages = eo_pages->editor_options_pages ();
for (auto op = pages.begin (); op != pages.end (); ++op) {
if ((*op)->plugin_declaration () == plugin_declaration ()) {
if ((*op)->for_plugin_declaration (plugin_declaration ())) {
(*op)->commit_recent (view ());
}
}

View File

@ -85,7 +85,7 @@ ShapeEditService::config_recent_for_layer (const db::LayerProperties &lp, int cv
auto pages = eo_pages->editor_options_pages ();
for (auto op = pages.begin (); op != pages.end (); ++op) {
if ((*op)->plugin_declaration () == plugin_declaration ()) {
if ((*op)->for_plugin_declaration (plugin_declaration ())) {
(*op)->config_recent_for_layer (dispatcher (), lp, cv_index);
}
}

View File

@ -62,6 +62,15 @@ PluginDeclaration::get_options (std::vector < std::pair<std::string, std::string
options.push_back (std::pair<std::string, std::string> (cfg_images_visible, "true"));
}
std::vector<std::string>
PluginDeclaration::additional_editor_options_pages () const
{
std::vector<std::string> names;
// TODO: provide in a central place instead of borrowing from the edt module
names.push_back ("GenericEditorOptions");
return names;
}
static tl::RegisteredClass<lay::PluginDeclaration> config_decl (new img::PluginDeclaration (), 4000, "img::Plugin");
}

View File

@ -39,6 +39,7 @@ public:
virtual lay::Plugin *create_plugin (db::Manager *manager, lay::Dispatcher *, lay::LayoutViewBase *view) const;
virtual bool implements_editable (std::string &title) const;
virtual void get_options (std::vector < std::pair<std::string, std::string> > &options) const;
virtual std::vector<std::string> additional_editor_options_pages () const;
};
}

View File

@ -41,13 +41,13 @@ EditorOptionsPageCollection::EditorOptionsPageCollection ()
// EditorOptionsPage implementation
EditorOptionsPage::EditorOptionsPage (lay::LayoutViewBase *view, lay::Dispatcher *dispatcher)
: mp_owner (0), m_active (true), m_focus_page (false), m_modal_page (false), m_toolbox_widget (false), mp_plugin_declaration (0), mp_dispatcher (0), mp_view (0)
: mp_owner (0), m_active (true), m_focus_page (false), m_modal_page (false), m_toolbox_widget (false), mp_dispatcher (0), mp_view (0)
{
init (view, dispatcher);
}
EditorOptionsPage::EditorOptionsPage ()
: mp_owner (0), m_active (true), m_focus_page (false), m_modal_page (false), m_toolbox_widget (false), mp_plugin_declaration (0), mp_dispatcher (0), mp_view (0)
: mp_owner (0), m_active (true), m_focus_page (false), m_modal_page (false), m_toolbox_widget (false), mp_dispatcher (0), mp_view (0)
{
// .. nothing yet ..
}

View File

@ -27,6 +27,8 @@
#include "tlObject.h"
#include <set>
namespace db
{
struct LayerProperties;
@ -110,8 +112,22 @@ public:
*/
int show ();
const lay::PluginDeclaration *plugin_declaration () const { return mp_plugin_declaration; }
void set_plugin_declaration (const lay::PluginDeclaration *pd) { mp_plugin_declaration = pd; }
bool for_plugin_declaration (const lay::PluginDeclaration *pd)
{
return m_plugin_declarations.find (pd) != m_plugin_declarations.end ();
}
void set_plugin_declaration (const lay::PluginDeclaration *pd)
{
m_plugin_declarations.clear ();
m_plugin_declarations.insert (pd);
}
void set_plugin_declarations (const std::vector<const lay::PluginDeclaration *> &pd)
{
m_plugin_declarations.clear ();
m_plugin_declarations.insert (pd.begin (), pd.end ());
}
void init (lay::LayoutViewBase *view, lay::Dispatcher *dispatcher);
@ -136,7 +152,7 @@ private:
bool m_active;
bool m_focus_page;
bool m_modal_page, m_toolbox_widget;
const lay::PluginDeclaration *mp_plugin_declaration;
std::set<const lay::PluginDeclaration *> m_plugin_declarations;
lay::Dispatcher *mp_dispatcher;
lay::LayoutViewBase *mp_view;
@ -150,33 +166,42 @@ private:
*
* We will use it later to provide a registration-based specialized factory
* for Qt-enabled option pages, which we should not link here.
*
* A factory has a name - if the name matches a plugin name,
* the factory is automatically requested to create a page for
* that plugin.
*
* Otherwise, plugins can request additional pages through
* "additional_editor_options_pages". This is a list of names
* (not plugin names) of page factories. These factories will
* be called to provide additional pages then.
*/
class LAYBASIC_PUBLIC EditorOptionsPageFactoryBase
{
public:
EditorOptionsPageFactoryBase (const char *plugin_name)
: m_plugin_name (plugin_name)
EditorOptionsPageFactoryBase (const char *name)
: m_name (name)
{
// .. nothing yet ..
}
EditorOptionsPageFactoryBase ()
: m_plugin_name ()
: m_name ()
{
// .. nothing yet ..
}
virtual ~EditorOptionsPageFactoryBase () { }
const std::string &plugin_name () const
const std::string &name () const
{
return m_plugin_name;
return m_name;
}
virtual lay::EditorOptionsPage *create_page (lay::LayoutViewBase *view, lay::Dispatcher *dispatcher) = 0;
private:
std::string m_plugin_name;
std::string m_name;
};
/**

View File

@ -400,7 +400,7 @@ LayoutViewBase::init (db::Manager *mgr)
mp_canvas = new lay::LayoutCanvas (this);
create_plugins ();
LayoutViewBase::create_plugins ();
}
void

View File

@ -147,11 +147,6 @@ public:
{
return new MouseTracker (view);
}
virtual bool enable_catchall_editor_options_pages () const
{
return false;
}
};
static tl::RegisteredClass<lay::PluginDeclaration> tracker_decl (new MouseTrackerDeclaration (), -1000, "laybasic::MouseTrackerPlugin");

View File

@ -462,6 +462,14 @@ public:
{
return new MoveService (view);
}
virtual std::vector<std::string> additional_editor_options_pages () const
{
std::vector<std::string> names;
// TODO: provide in a central place instead of borrowing from the edt module
names.push_back ("GenericEditorOptions");
return names;
}
};
static tl::RegisteredClass<lay::PluginDeclaration> move_service_decl (new MoveServiceDeclaration (), -970, "laybasic::MoveServicePlugin");

View File

@ -342,7 +342,7 @@ PluginDeclaration::get_editor_options_pages (std::vector<lay::EditorOptionsPage
auto reg = tl::Registrar<lay::EditorOptionsPageFactoryBase>::get_instance ();
for (auto i = reg->begin (); i != reg->end (); ++i) {
lay::EditorOptionsPage *page = 0;
if (i->plugin_name () == n) {
if (i->name () == n) {
page = i->create_page (view, dispatcher);
if (page) {
page->set_plugin_declaration (this);
@ -355,18 +355,28 @@ PluginDeclaration::get_editor_options_pages (std::vector<lay::EditorOptionsPage
}
void
PluginDeclaration::get_catchall_editor_options_pages (std::vector<lay::EditorOptionsPage *> &pages, lay::LayoutViewBase *view, lay::Dispatcher *dispatcher)
PluginDeclaration::get_additional_editor_options_pages (std::vector<EditorOptionsPage *> &pages, LayoutViewBase *view, Dispatcher *dispatcher, const std::map<std::string, std::vector<const lay::PluginDeclaration *> > &names)
{
std::set<std::string> names_seen;
auto reg = tl::Registrar<lay::EditorOptionsPageFactoryBase>::get_instance ();
for (auto i = reg->begin (); i != reg->end (); ++i) {
lay::EditorOptionsPage *page = 0;
if (i->plugin_name ().empty ()) {
page = i->create_page (view, dispatcher);
auto n = names.find (i->name ());
if (n != names.end ()) {
names_seen.insert (i->name ());
lay::EditorOptionsPage *page = i->create_page (view, dispatcher);
if (page) {
page->set_plugin_declarations (n->second);
pages.push_back (page);
}
}
}
for (auto i = names.begin (); i != names.end (); ++i) {
if (names_seen.find (i->first) == names_seen.end ()) {
tl::warn << tl::to_string (tr ("Cannot find additional editor options page: ")) << i->first;
}
}
}
// ----------------------------------------------------------------

View File

@ -344,26 +344,19 @@ public:
virtual void get_editor_options_pages (std::vector<lay::EditorOptionsPage *> &pages, lay::LayoutViewBase *view, lay::Dispatcher *dispatcher) const;
/**
* @brief Gets the "catchall" editor options pages
*
* These are editor options pages not associated with a specific plugin.
*
* The new pages are returned in the "pages" vector. The layout view will take ownership of these pages.
*
* The implementation collects pages registered through editor options page factories.
* @brief Gets pages created from registered factories by name
*/
static void get_catchall_editor_options_pages (std::vector<lay::EditorOptionsPage *> &pages, lay::LayoutViewBase *view, lay::Dispatcher *dispatcher);
static void get_additional_editor_options_pages (std::vector<lay::EditorOptionsPage *> &pages, lay::LayoutViewBase *view, lay::Dispatcher *dispatcher, const std::map<std::string, std::vector<const lay::PluginDeclaration *> > &names);
/**
* @brief Gets a value indicating whether "catchall" editor options pages shall be included
* @brief Returns a list of editor options pages that the plugin wants to inherit
*
* "catchall" editor options pages are ones that are unspecific and render a null "plugin_declaration".
* A plugin can choose to include these pages if it listens to global configuration events.
* Otherwise it should return false here to suppress these pages.
* In addition to providing pages through "get_editor_options_pages", the plugin can request pages
* from globally registered factories by name.
*/
virtual bool enable_catchall_editor_options_pages () const
virtual std::vector<std::string> additional_editor_options_pages () const
{
return true;
return std::vector<std::string> ();
}
/**

View File

@ -332,11 +332,6 @@ public:
{
return new SelectionService (view);
}
virtual bool enable_catchall_editor_options_pages () const
{
return false;
}
};
static tl::RegisteredClass<lay::PluginDeclaration> selection_service_decl (new SelectionServiceDeclaration (), -980, "laybasic::SelectionServicePlugin");

View File

@ -297,11 +297,6 @@ public:
{
return new ZoomService (view);
}
virtual bool enable_catchall_editor_options_pages () const
{
return false;
}
};
static tl::RegisteredClass<lay::PluginDeclaration> zoom_service_decl (new ZoomServiceDeclaration (), -990, "laybasic::ZoomServicePlugin");

View File

@ -313,6 +313,16 @@ public:
m_options.push_back (std::make_pair (name, default_value));
}
void add_editor_options_page_by_name (const std::string &name)
{
m_additional_editor_options_pages.push_back (name);
}
virtual std::vector<std::string> additional_editor_options_pages () const
{
return m_additional_editor_options_pages;
}
void has_tool_entry (bool f)
{
m_implements_mouse_mode = f;
@ -335,6 +345,7 @@ public:
private:
std::vector<std::pair<std::string, std::string> > m_options;
std::vector<std::string> m_additional_editor_options_pages;
std::vector<lay::MenuEntry> m_menu_entries;
bool m_implements_mouse_mode;
std::string m_mouse_mode_title;
@ -474,6 +485,21 @@ Class<gsi::PluginFactoryBase> decl_PluginFactory ("lay", "PluginFactory",
"be set using \"set_config\" from \\MainWindow. This scheme also works without registering the configuration options, but "
"doing so has the advantage that it is guaranteed that a variable with this keys exists and has the given default value initially."
) +
method ("add_editor_options_page_by_name", &gsi::PluginFactoryBase::add_editor_options_page_by_name, gsi::arg ("name"),
"@brief Requests an additional editor options page from the standard pool.\n"
"This method needs to be called in the initializer of the plugin factory class and before the 'register' call."
"It requests an additional editor options page from the standard pool. 'name' specifies which page is added.\n"
"\n"
"As of now, only 'GenericEditorOptions' is available to provide the basic grid and angle constraints settings. If you "
"wish to enable that page for the plugin, use:\n"
"\n"
"@code\n"
"add_editor_options_page_by_name(\"GenericEditorOptions\")\n"
"@/code\n"
"\n"
"This method has been introduced in version 0.30.6. Before this method was introduced, the generic editor options were "
"always added."
) +
#if defined(HAVE_QTBINDINGS)
method ("add_editor_options_page", &PluginFactoryBase::add_editor_options_page, gsi::arg ("page"),
"@brief Adds the given editor options page\n"

View File

@ -50,10 +50,17 @@ void
EditorOptionsFrame::populate (LayoutViewBase *view)
{
std::vector<lay::EditorOptionsPage *> editor_options_pages;
std::map<std::string, std::vector<const lay::PluginDeclaration *> > additional_pages;
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
cls->get_editor_options_pages (editor_options_pages, view, view->dispatcher ());
std::vector<std::string> ap = cls->additional_editor_options_pages ();
for (auto i = ap.begin (); i != ap.end (); ++i) {
additional_pages [*i].push_back (cls.operator-> ());
}
}
lay::PluginDeclaration::get_catchall_editor_options_pages (editor_options_pages, view, view->dispatcher ());
lay::PluginDeclaration::get_additional_editor_options_pages (editor_options_pages, view, view->dispatcher (), additional_pages);
for (std::vector<lay::EditorOptionsPage *>::const_iterator op = editor_options_pages.begin (); op != editor_options_pages.end (); ++op) {
(*op)->activate (false);

View File

@ -98,8 +98,7 @@ EditorOptionsPages::editor_options_pages (const lay::PluginDeclaration *plugin_d
{
std::vector<lay::EditorOptionsPage *> pages;
for (auto p = m_pages.begin (); p != m_pages.end (); ++p) {
if (p->plugin_declaration () == plugin_declaration ||
(p->plugin_declaration () == 0 && plugin_declaration->enable_catchall_editor_options_pages ())) {
if (p->for_plugin_declaration (plugin_declaration)) {
pages.push_back (const_cast<lay::EditorOptionsPage *> (p.operator-> ()));
}
}
@ -164,18 +163,9 @@ EditorOptionsPages::activate (const lay::Plugin *plugin)
m_update_enabled = false;
for (auto op = m_pages.begin (); op != m_pages.end (); ++op) {
bool is_active = false;
if (op->plugin_declaration () == 0) {
is_active = (plugin && plugin->plugin_declaration ()->enable_catchall_editor_options_pages ());
} else if (plugin && plugin->plugin_declaration () == op->plugin_declaration ()) {
is_active = true;
}
BEGIN_PROTECTED
op->activate (is_active);
op->activate (plugin && op->for_plugin_declaration (plugin->plugin_declaration ()));
END_PROTECTED
}
m_update_enabled = true;

View File

@ -867,6 +867,11 @@ LayoutView *LayoutView::current ()
void LayoutView::create_plugins (const lay::PluginDeclaration *except_this)
{
LayoutViewBase::create_plugins (except_this);
if (mp_editor_options_frame) {
mp_editor_options_frame->populate (this);
}
dm_setup_editor_option_pages ();
}