Merge branch 'app-refactoring' into doc-args

This commit is contained in:
Matthias Koefferlein
2020-03-15 21:32:39 +01:00
171 changed files with 4419 additions and 5346 deletions
+155
View File
@@ -0,0 +1,155 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LayoutStatisticsForm</class>
<widget class="QDialog" name="LayoutStatisticsForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>584</width>
<height>546</height>
</rect>
</property>
<property name="windowTitle">
<string>Layout Statistics</string>
</property>
<layout class="QGridLayout">
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="1" column="0" colspan="2">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QFrame" name="frame5">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>81</width>
<height>31</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="ok_button">
<property name="text">
<string>Close</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Show properties of ...</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="layout_cbx">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="lay::BrowserPanel" name="browser" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Ignored">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>lay::BrowserPanel</class>
<extends>QWidget</extends>
<header>layBrowserPanel.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>ok_button</sender>
<signal>clicked()</signal>
<receiver>LayoutStatisticsForm</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>182</x>
<y>334</y>
</hint>
<hint type="destinationlabel">
<x>163</x>
<y>178</y>
</hint>
</hints>
</connection>
</connections>
</ui>
+130
View File
@@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SelectCellViewForm</class>
<widget class="QDialog" name="SelectCellViewForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>544</width>
<height>167</height>
</rect>
</property>
<property name="windowTitle">
<string>Select Layout</string>
</property>
<layout class="QVBoxLayout">
<property name="spacing">
<number>8</number>
</property>
<property name="margin">
<number>8</number>
</property>
<item>
<widget class="QFrame" name="frame5_2">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="title_lbl">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Text</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QListWidget" name="cvs_lb">
<property name="selectionMode">
<enum>QAbstractItemView::MultiSelection</enum>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="select_all_pb">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select All</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame5">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>4</number>
</property>
<item row="0" column="0">
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>91</width>
<height>31</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="ok_button">
<property name="text">
<string>OK</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QPushButton" name="cancel_button">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
+132 -3
View File
@@ -402,19 +402,148 @@ static LayerPropertiesConstIteratorWrapper each_layer2 (lay::LayoutView *view, u
return LayerPropertiesConstIteratorWrapper (view->begin_layers (list_index));
}
static lay::LayoutView *new_view ()
static lay::LayoutView *new_view (QWidget *parent, bool editable, db::Manager *manager, unsigned int options)
{
return new lay::LayoutView (0, false, 0);
lay::LayoutView *lv = new lay::LayoutView (manager, editable, 0 /*plugin parent*/, parent, "view", options);
if (parent) {
// transfer ownership to the parent
lv->keep ();
}
return lv;
}
Class<lay::LayoutView> decl_LayoutView (QT_EXTERNAL_BASE (QWidget) "lay", "LayoutView",
gsi::constructor ("new", &new_view,
gsi::constructor ("new", &new_view, gsi::arg ("parent", (QWidget *) 0, "nil"), gsi::arg ("editable", false), gsi::arg ("manager", (db::Manager *) 0, "nil"), gsi::arg ("options", (unsigned int) 0),
"@brief Creates a standalone view\n"
"\n"
"This constructor is for special purposes only. To create a view in the context of a main window, "
"use \\MainWindow#create_view and related methods.\n"
"\n"
"@param parent The parent widget in which to embed the view\n"
"@param editable True to make the view editable\n"
"@param manager The \\Manager object to enable undo/redo\n"
"@param options A combination of the values in the LV_... constants\n"
"\n"
"This constructor has been introduced in version 0.25.\n"
"It has been enhanced with the arguments in version 0.27.\n"
) +
gsi::constant ("LV_NoLayers", (unsigned int) lay::LayoutView::LV_NoLayers,
"@brief With this option, no layers view will be provided (see \\layer_control_frame)\n"
"Use this value with the constructor's 'options' argument.\n"
"\n"
"This constant has been introduced in version 0.27.\n"
) +
gsi::constant ("LV_NoHierarchyPanel", (unsigned int) lay::LayoutView::LV_NoHierarchyPanel,
"@brief With this option, no cell hierarchy view will be provided (see \\hierarchy_control_frame)\n"
"Use this value with the constructor's 'options' argument.\n"
"\n"
"This constant has been introduced in version 0.27.\n"
) +
gsi::constant ("LV_NoLibrariesView", (unsigned int) lay::LayoutView::LV_NoLibrariesView,
"@brief With this option, no library view will be provided (see \\libraries_frame)\n"
"Use this value with the constructor's 'options' argument.\n"
"\n"
"This constant has been introduced in version 0.27.\n"
) +
gsi::constant ("LV_NoBookmarksView", (unsigned int) lay::LayoutView::LV_NoBookmarksView,
"@brief With this option, no bookmarks view will be provided (see \\bookmarks_frame)\n"
"Use this value with the constructor's 'options' argument.\n"
"\n"
"This constant has been introduced in version 0.27.\n"
) +
gsi::constant ("LV_Naked", (unsigned int) lay::LayoutView::LV_Naked,
"@brief With this option, no separate views will be provided\n"
"Use this value with the constructor's 'options' argument.\n"
"This option is basically equivalent to using \\LV_NoLayers+\\LV_NoHierarchyPanel+\\LV_NoLibrariesView+\\LV_NoBookmarksView\n"
"\n"
"This constant has been introduced in version 0.27.\n"
) +
gsi::constant ("LV_NoZoom", (unsigned int) lay::LayoutView::LV_NoZoom,
"@brief With this option, zooming is disabled\n"
"Use this value with the constructor's 'options' argument.\n"
"\n"
"This constant has been introduced in version 0.27.\n"
) +
gsi::constant ("LV_NoGrid", (unsigned int) lay::LayoutView::LV_NoGrid,
"@brief With this option, the grid background is not shown\n"
"Use this value with the constructor's 'options' argument.\n"
"\n"
"This constant has been introduced in version 0.27.\n"
) +
gsi::constant ("LV_NoMove", (unsigned int) lay::LayoutView::LV_NoMove,
"@brief With this option, move operations are not supported\n"
"Use this value with the constructor's 'options' argument.\n"
"\n"
"This constant has been introduced in version 0.27.\n"
) +
gsi::constant ("LV_NoTracker", (unsigned int) lay::LayoutView::LV_NoTracker,
"@brief With this option, mouse position tracking is not supported\n"
"Use this value with the constructor's 'options' argument.\n"
"This option is not useful currently as no mouse tracking support is provided.\n"
"\n"
"This constant has been introduced in version 0.27.\n"
) +
gsi::constant ("LV_NoSelection", (unsigned int) lay::LayoutView::LV_NoSelection,
"@brief With this option, objects cannot be selected\n"
"Use this value with the constructor's 'options' argument.\n"
"\n"
"This constant has been introduced in version 0.27.\n"
) +
gsi::constant ("LV_NoPlugins", (unsigned int) lay::LayoutView::LV_NoPlugins,
"@brief With this option, all plugins are disabled\n"
"Use this value with the constructor's 'options' argument.\n"
"\n"
"This constant has been introduced in version 0.27.\n"
) +
gsi::constant ("LV_NoServices", (unsigned int) lay::LayoutView::LV_NoServices,
"@brief This option disables all services except the ones for pure viewing\n"
"Use this value with the constructor's 'options' argument.\n"
"With this option, all manipulation features are disabled, except zooming.\n"
"It is equivalent to \\LV_NoMove + \\LV_NoTracker + \\LV_NoSelection + \\LV_NoPlugins.\n"
"\n"
"This constant has been introduced in version 0.27.\n"
) +
#if defined(HAVE_QTBINDINGS)
gsi::method ("layer_control_frame", &lay::LayoutView::layer_control_frame,
"@brief Gets the layer control side widget\n"
"A 'side widget' is a widget attached to the view. It does not have a parent, so you can "
"embed it into a different context. Please note that with embedding through 'setParent' it will be "
"destroyed when your parent widget gets destroyed. It will be lost then to the view.\n"
"\n"
"The side widget can be configured through the views configuration interface.\n"
"\n"
"This method has been introduced in version 0.27\n"
) +
gsi::method ("hierarchy_control_frame", &lay::LayoutView::hierarchy_control_frame,
"@brief Gets the cell view (hierarchy view) side widget\n"
"For details about side widgets see \\layer_control_frame.\n"
"\n"
"This method has been introduced in version 0.27\n"
) +
gsi::method ("libraries_frame", &lay::LayoutView::libraries_frame,
"@brief Gets the library view side widget\n"
"For details about side widgets see \\layer_control_frame.\n"
"\n"
"This method has been introduced in version 0.27\n"
) +
gsi::method ("bookmarks_frame", &lay::LayoutView::bookmarks_frame,
"@brief Gets the bookmarks side widget\n"
"For details about side widgets see \\layer_control_frame.\n"
"\n"
"This method has been introduced in version 0.27\n"
) +
#endif
gsi::method ("call_menu", &lay::LayoutView::menu_activated,
"@brief Calls the menu item with the provided symbol.\n"
"To obtain all symbols, use get_menu_symbols.\n"
"\n"
"This method has been introduced in version 0.27."
) +
gsi::method ("menu_symbols", &lay::LayoutView::menu_symbols,
"@brief Gets all available menu symbols (see \\call_menu).\n"
"NOTE: currently this method delivers a superset of all available symbols. Depending on the context, no all symbols may trigger actual functionality.\n"
"\n"
"This method has been introduced in version 0.27."
) +
gsi::method ("current", &lay::LayoutView::current,
"@brief Returns the current view\n"
+60 -42
View File
@@ -25,6 +25,34 @@
#include "gsiSignals.h"
#include "layAbstractMenu.h"
namespace {
// The Action stub to allow reimplementation of the triggered method
class ActionStub
: public lay::Action
{
public:
virtual void triggered ()
{
if (triggered_cb.can_issue ()) {
triggered_cb.issue<lay::Action> (&lay::Action::triggered);
}
on_triggered_event ();
}
gsi::Callback triggered_cb;
tl::Event on_triggered_event;
};
}
namespace tl
{
template <> struct type_traits<ActionStub> : public type_traits<void> {
typedef tl::false_tag has_copy_constructor;
};
}
namespace gsi
{
@@ -58,7 +86,14 @@ static std::map<std::string, bool> unpack_menu_items_hidden (const std::string &
return kb;
}
static lay::AbstractMenu *new_menu ()
{
return new lay::AbstractMenu (0);
}
Class<lay::AbstractMenu> decl_AbstractMenu ("lay", "AbstractMenu",
// for test purposes mainly:
constructor ("new", &new_menu, "@hide") +
method ("pack_key_binding", &pack_key_binding, gsi::arg ("path_to_keys"),
"@brief Serializes a key binding definition into a single string\n"
"The serialized format is used by the 'key-bindings' config key. "
@@ -87,26 +122,26 @@ Class<lay::AbstractMenu> decl_AbstractMenu ("lay", "AbstractMenu",
"\n"
"This method has been introduced in version 0.26."
) +
method ("action", &lay::AbstractMenu::action, gsi::arg ("path"),
"@brief Get the reference to a Action object associated with the given path\n"
method ("action", (lay::Action *(lay::AbstractMenu::*) (const std::string &path)) &lay::AbstractMenu::action, gsi::arg ("path"),
"@brief Gets the reference to a Action object associated with the given path\n"
"\n"
"@param path The path to the item. This must be a valid path.\n"
"@return A reference to a Action object associated with this path\n"
"@param path The path to the item.\n"
"@return A reference to a Action object associated with this path or nil if the path is not valid\n"
) +
method ("items", &lay::AbstractMenu::items, gsi::arg ("path"),
"@brief Get the subitems for a given submenu\n"
"@brief Gets the subitems for a given submenu\n"
"\n"
"@param path The path to the submenu\n"
"@return A vector or path strings for the child items or an empty vector if the path is not valid or the item does not have children\n"
) +
method ("is_menu?", &lay::AbstractMenu::is_menu, gsi::arg ("path"),
"@brief Query if an item is a menu\n"
"@brief Returns true if the item is a menu\n"
"\n"
"@param path The path to the item\n"
"@return false if the path is not valid or is not a menu\n"
) +
method ("is_separator?", &lay::AbstractMenu::is_separator, gsi::arg ("path"),
"@brief Query if an item is a separator\n"
"@brief Returns true if the item is a separator\n"
"\n"
"@param path The path to the item\n"
"@return false if the path is not valid or is not a separator\n"
@@ -114,13 +149,13 @@ Class<lay::AbstractMenu> decl_AbstractMenu ("lay", "AbstractMenu",
"This method has been introduced in version 0.19.\n"
) +
method ("is_valid?", &lay::AbstractMenu::is_valid, gsi::arg ("path"),
"@brief Query if a path is a valid one\n"
"@brief Returns true if the path is a valid one\n"
"\n"
"@param path The path to check\n"
"@return false if the path is not a valid path to an item\n"
) +
method ("insert_item", (void (lay::AbstractMenu::*) (const std::string &, const std::string &, const lay::Action &)) &lay::AbstractMenu::insert_item, gsi::arg ("path"), gsi::arg ("name"), gsi::arg ("action"),
"@brief Insert a new item before the one given by the path\n"
"@brief Inserts a new item before the one given by the path\n"
"\n"
"The Action object passed as the third parameter references the handler which both implements the "
"action to perform and the menu item's appearance such as title, icon and keyboard shortcut.\n"
@@ -130,13 +165,13 @@ Class<lay::AbstractMenu> decl_AbstractMenu ("lay", "AbstractMenu",
"@param action The Action object to insert\n"
) +
method ("insert_separator", &lay::AbstractMenu::insert_separator, gsi::arg ("path"), gsi::arg ("name"),
"@brief Insert a new separator before the item given by the path\n"
"@brief Inserts a new separator before the item given by the path\n"
"\n"
"@param path The path to the item before which to insert the separator\n"
"@param name The name of the separator to insert \n"
) +
method ("insert_menu", (void (lay::AbstractMenu::*) (const std::string &, const std::string &, const std::string &)) &lay::AbstractMenu::insert_menu, gsi::arg ("path"), gsi::arg ("name"), gsi::arg ("title"),
"@brief Insert a new submenu before the item given by the path\n"
"@brief Inserts a new submenu before the item given by the path\n"
"\n"
"The title string optionally encodes the key shortcut and icon resource\n"
"in the form <text>[\"(\"<shortcut>\")\"][\"<\"<icon-resource>\">\"].\n"
@@ -146,17 +181,17 @@ Class<lay::AbstractMenu> decl_AbstractMenu ("lay", "AbstractMenu",
"@param title The title of the submenu to insert\n"
) +
method ("delete_item", &lay::AbstractMenu::delete_item, gsi::arg ("path"),
"@brief Delete the item given by the path\n"
"@brief Deletes the item given by the path\n"
"\n"
"@param path The path to the item to delete\n"
) +
method ("group", &lay::AbstractMenu::group, gsi::arg ("group"),
"@brief Get the group members\n"
"@brief Gets the group members\n"
"\n"
"@param group The group name\n"
"@param A vector of all members (by path) of the group\n"
),
"@brief The abstract menu class\n"
"@brief An abstraction for the application menues\n"
"\n"
"The abstract menu is a class that stores a main menu and several popup menus\n"
"in a generic form such that they can be manipulated and converted into GUI objects.\n"
@@ -275,17 +310,17 @@ Class<lay::Action> decl_ActionBase ("lay", "ActionBase",
"This method has been introduced in version 0.25.\n"
) +
method ("checkable=", &lay::Action::set_checkable, gsi::arg ("checkable"),
"@brief Make the item(s) checkable or not\n"
"@brief Makes the item(s) checkable or not\n"
"\n"
"@param checkable true to make the item checkable\n"
) +
method ("enabled=", &lay::Action::set_enabled, gsi::arg ("enabled"),
"@brief Enable or disable the action\n"
"@brief Enables or disables the action\n"
"\n"
"@param enabled true to enable the item\n"
) +
method ("visible=", &lay::Action::set_visible, gsi::arg ("visible"),
"@brief Show or hide\n"
"@brief Sets the item's visibility\n"
"\n"
"@param visible true to make the item visible\n"
) +
@@ -296,29 +331,29 @@ Class<lay::Action> decl_ActionBase ("lay", "ActionBase",
"This attribute has been introduced in version 0.25\n"
) +
method ("checked=", &lay::Action::set_checked, gsi::arg ("checked"),
"@brief Check or uncheck\n"
"@brief Checks or unchecks the item\n"
"\n"
"@param checked true to make the item checked\n"
) +
method ("icon=", &lay::Action::set_icon, gsi::arg ("file"),
"@brief Set the icon to the given picture\n"
"@brief Sets the icon to the given image file\n"
"\n"
"@param file The image file to load for the icon\n"
"\n"
"Passing an empty string will reset the icon\n"
"Passing an empty string will reset the icon.\n"
) +
method ("icon_text=", &lay::Action::set_icon_text, gsi::arg ("icon_text"),
"@brief Set the icon's text \n"
"@brief Sets the icon's text\n"
"\n"
"If an icon text is set, this will be used for the text below the icon.\n"
"If no icon text is set, the normal text will be used for the icon.\n"
"Passing an empty string will reset the icon's text.\n"
) +
method ("icon_text", &lay::Action::get_icon_text,
"@brief Get the icon's text\n"
"@brief Gets the icon's text\n"
) +
method ("tool_tip=", &lay::Action::set_tool_tip, gsi::arg ("text"),
"@brief Set the tool tip text \n"
"@brief Sets the tool tip text\n"
"\n"
"The tool tip text is displayed in the tool tip window of the menu entry.\n"
"This is in particular useful for entries in the tool bar."
@@ -326,34 +361,17 @@ Class<lay::Action> decl_ActionBase ("lay", "ActionBase",
"This method has been added in version 0.22.\n"
) +
method ("tool_tip", &lay::Action::get_tool_tip,
"@brief Get the tool tip text\n"
"@brief Gets the tool tip text.\n"
"\n"
"This method has been added in version 0.22.\n"
) +
method ("trigger", &lay::Action::trigger,
"@brief Trigger the action programmatically"
"@brief Triggers the action programmatically"
),
"@hide\n"
"@alias Action\n"
);
// The Action stub to allow reimplementation of the triggered method
class ActionStub
: public lay::Action
{
public:
virtual void triggered ()
{
if (triggered_cb.can_issue ()) {
triggered_cb.issue<lay::Action> (&lay::Action::triggered);
}
on_triggered_event ();
}
gsi::Callback triggered_cb;
tl::Event on_triggered_event;
};
Class<ActionStub> decl_Action (decl_ActionBase, "lay", "Action",
gsi::callback ("triggered", &ActionStub::triggered, &ActionStub::triggered_cb,
"@brief This method is called if the menu item is selected"
+85 -43
View File
@@ -56,14 +56,14 @@ namespace gsi
// of the factory, this hack is a quick but dirty workaround.
static bool s_in_create_plugin = false;
static lay::LayoutView *sp_view = 0;
static lay::PluginRoot *sp_root = 0;
static lay::Dispatcher *sp_dispatcher = 0;
class PluginBase
: public lay::Plugin, public lay::ViewService
{
public:
PluginBase ()
: lay::Plugin (sp_root), lay::ViewService (sp_view ? sp_view->view_object_widget () : 0)
: lay::Plugin (sp_dispatcher), lay::ViewService (sp_view ? sp_view->view_object_widget () : 0)
{
if (! s_in_create_plugin) {
throw tl::Exception (tl::to_string (QObject::tr ("A PluginBase object can only be created in the PluginFactory's create_plugin method")));
@@ -334,7 +334,7 @@ public:
}
}
virtual void initialize (lay::PluginRoot *root)
virtual void initialize (lay::Dispatcher *root)
{
if (f_initialize.can_issue ()) {
f_initialize.issue<lay::PluginDeclaration> (&lay::PluginDeclaration::initialize, root);
@@ -343,7 +343,7 @@ public:
}
}
virtual void uninitialize (lay::PluginRoot *root)
virtual void uninitialize (lay::Dispatcher *root)
{
if (f_uninitialize.can_issue ()) {
f_uninitialize.issue<lay::PluginDeclaration> (&lay::PluginDeclaration::uninitialize, root);
@@ -352,7 +352,7 @@ public:
}
}
virtual lay::Plugin *create_plugin (db::Manager *manager, lay::PluginRoot *root, lay::LayoutView *view) const
virtual lay::Plugin *create_plugin (db::Manager *manager, lay::Dispatcher *root, lay::LayoutView *view) const
{
if (f_create_plugin.can_issue ()) {
return create_plugin_gsi (manager, root, view);
@@ -361,22 +361,22 @@ public:
}
}
virtual gsi::PluginBase *create_plugin_gsi (db::Manager *manager, lay::PluginRoot *root, lay::LayoutView *view) const
virtual gsi::PluginBase *create_plugin_gsi (db::Manager *manager, lay::Dispatcher *root, lay::LayoutView *view) const
{
// TODO: this is a hack. See notes above at s_in_create_plugin
s_in_create_plugin = true;
sp_view = view;
sp_root = root;
sp_dispatcher = root;
gsi::PluginBase *ret = 0;
try {
ret = f_create_plugin.issue<PluginFactoryBase, gsi::PluginBase *, db::Manager *, lay::PluginRoot *, lay::LayoutView *> (&PluginFactoryBase::create_plugin_gsi, manager, root, view);
ret = f_create_plugin.issue<PluginFactoryBase, gsi::PluginBase *, db::Manager *, lay::Dispatcher *, lay::LayoutView *> (&PluginFactoryBase::create_plugin_gsi, manager, root, view);
s_in_create_plugin = false;
sp_view = 0;
sp_root = 0;
sp_dispatcher = 0;
} catch (...) {
s_in_create_plugin = false;
sp_view = 0;
sp_root = 0;
sp_dispatcher = 0;
}
return ret;
@@ -394,17 +394,36 @@ public:
void add_menu_entry1 (const std::string &menu_name, const std::string &insert_pos)
{
m_menu_entries.push_back (lay::MenuEntry (menu_name, insert_pos));
m_menu_entries.push_back (lay::separator (menu_name, insert_pos));
}
void add_menu_entry2 (const std::string &symbol, const std::string &menu_name, const std::string &insert_pos, const std::string &title)
{
m_menu_entries.push_back (lay::MenuEntry (symbol, menu_name, insert_pos, title));
m_menu_entries.push_back (lay::menu_item (symbol, menu_name, insert_pos, title));
}
void add_menu_entry_copy (const std::string &symbol, const std::string &menu_name, const std::string &insert_pos, const std::string &copy_from)
{
m_menu_entries.push_back (lay::menu_item_copy (symbol, menu_name, insert_pos, copy_from));
}
void add_submenu (const std::string &menu_name, const std::string &insert_pos, const std::string &title)
{
m_menu_entries.push_back (lay::submenu (menu_name, insert_pos, title));
}
void add_config_menu_item (const std::string &menu_name, const std::string &insert_pos, const std::string &title, const std::string &cname, const std::string &cvalue)
{
m_menu_entries.push_back (lay::config_menu_item (menu_name, insert_pos, title, cname, cvalue));
}
void add_menu_entry3 (const std::string &symbol, const std::string &menu_name, const std::string &insert_pos, const std::string &title, bool sub_menu)
{
m_menu_entries.push_back (lay::MenuEntry (symbol, menu_name, insert_pos, title, sub_menu));
if (sub_menu) {
m_menu_entries.push_back (lay::submenu (symbol, menu_name, insert_pos, title));
} else {
m_menu_entries.push_back (lay::menu_item (symbol, menu_name, insert_pos, title));
}
}
void add_option (const std::string &name, const std::string &default_value)
@@ -491,21 +510,21 @@ Class<gsi::PluginFactoryBase> decl_PluginFactory ("lay", "PluginFactory",
"If this method was handling the menu event, it should return true. This indicates that the event "
"will not be propagated to other plugins hence avoiding duplicate calls.\n"
) +
callback ("initialized", &gsi::PluginFactoryBase::initialize, &gsi::PluginFactoryBase::f_initialize, gsi::arg ("root"),
callback ("initialized", &gsi::PluginFactoryBase::initialize, &gsi::PluginFactoryBase::f_initialize, gsi::arg ("dispatcher"),
"@brief Gets called when the plugin singleton is initialized, i.e. when the application has been started.\n"
"@param root The reference to the \\MainWindow object\n"
"@param dispatcher The reference to the \\MainWindow object\n"
) +
callback ("uninitialized", &gsi::PluginFactoryBase::uninitialize, &gsi::PluginFactoryBase::f_uninitialize, gsi::arg ("root"),
callback ("uninitialized", &gsi::PluginFactoryBase::uninitialize, &gsi::PluginFactoryBase::f_uninitialize, gsi::arg ("dispatcher"),
"@brief Gets called when the application shuts down and the plugin is unregistered\n"
"This event can be used to free resources allocated with this factory singleton.\n"
"@param root The reference to the \\MainWindow object\n"
"@param dispatcher The reference to the \\MainWindow object\n"
) +
factory_callback ("create_plugin", &gsi::PluginFactoryBase::create_plugin_gsi, &gsi::PluginFactoryBase::f_create_plugin, gsi::arg ("manager"), gsi::arg ("root"), gsi::arg ("view"),
factory_callback ("create_plugin", &gsi::PluginFactoryBase::create_plugin_gsi, &gsi::PluginFactoryBase::f_create_plugin, gsi::arg ("manager"), gsi::arg ("dispatcher"), gsi::arg ("view"),
"@brief Creates the plugin\n"
"This is the basic functionality that the factory must provide. This method must create a plugin of the "
"specific type.\n"
"@param manager The database manager object responsible for handling database transactions\n"
"@param root The reference to the \\MainWindow object\n"
"@param dispatcher The reference to the \\MainWindow object\n"
"@param view The \\LayoutView that is plugin is created for\n"
"@return The new \\Plugin implementation object\n"
) +
@@ -527,10 +546,33 @@ Class<gsi::PluginFactoryBase> decl_PluginFactory ("lay", "PluginFactory",
"@param insert_pos The position where to create the entry\n"
"@param title The title string for the item. The title can contain a keyboard shortcut in round braces after the title text, i.e. \"My Menu Item(F12)\"\n"
) +
method ("add_menu_entry", &gsi::PluginFactoryBase::add_menu_entry3, gsi::arg ("symbol"), gsi::arg ("menu_name"), gsi::arg ("insert_pos"), gsi::arg ("title"), gsi::arg ("sub_menu"),
method ("#add_menu_entry", &gsi::PluginFactoryBase::add_menu_entry3, gsi::arg ("symbol"), gsi::arg ("menu_name"), gsi::arg ("insert_pos"), gsi::arg ("title"), gsi::arg ("sub_menu"),
"@brief Specifies a menu item or sub-menu\n"
"Similar to the previous form of \"add_menu_entry\", but this version allows also to create sub-menus by setting the "
"last parameter to \"true\""
"last parameter to \"true\".\n"
"\n"
"With version 0.27 it's more convenient to use \\add_submenu."
) +
method ("add_menu_item_clone", &gsi::PluginFactoryBase::add_menu_entry_copy, gsi::arg ("symbol"), gsi::arg ("menu_name"), gsi::arg ("insert_pos"), gsi::arg ("copy_from"),
"@brief Specifies a menu item as a clone of another one\n"
"Using this method, a menu item can be made a clone of another entry (given as path by 'copy_from').\n"
"The new item will share the \\Action object with the original one, so manipulating the action will change both the original entry "
"and the new entry.\n"
"\n"
"This method has been introduced in version 0.27."
) +
method ("add_submenu", &gsi::PluginFactoryBase::add_submenu, gsi::arg ("menu_name"), gsi::arg ("insert_pos"), gsi::arg ("title"),
"@brief Specifies a menu item or sub-menu\n"
"\n"
"This method has been introduced in version 0.27."
) +
method ("add_config_menu_item", &gsi::PluginFactoryBase::add_config_menu_item, gsi::arg ("menu_name"), gsi::arg ("insert_pos"), gsi::arg ("title"), gsi::arg ("cname"), gsi::arg ("cvalue"),
"@brief Adds a configuration menu item\n"
"\n"
"Menu items created this way will send a configuration request with 'cname' as the configuration parameter name "
"and 'cvalue' as the configuration parameter value.\n"
"\n"
"This method has been introduced in version 0.27."
) +
method ("add_option", &gsi::PluginFactoryBase::add_option, gsi::arg ("name"), gsi::arg ("default_value"),
"@brief Specifies configuration variables.\n"
@@ -588,7 +630,7 @@ Class<gsi::PluginFactoryBase> decl_PluginFactory ("lay", "PluginFactory",
" end\n"
" \n"
" # Create a new plugin instance of the custom type\n"
" def create_plugin(manager, root, view)\n"
" def create_plugin(manager, dispatcher, view)\n"
" return PluginTest.new\n"
" end\n"
"\n"
@@ -816,22 +858,22 @@ Class<gsi::ButtonStateNamespace> decl_ButtonState ("lay", "ButtonState",
);
static std::vector<std::string>
get_config_names (lay::PluginRoot *root)
get_config_names (lay::Dispatcher *dispatcher)
{
std::vector<std::string> names;
root->get_config_names (names);
dispatcher->get_config_names (names);
return names;
}
static lay::PluginRoot *config_root_instance ()
static lay::Dispatcher *dispatcher_instance ()
{
return lay::PluginRoot::instance ();
return lay::Dispatcher::instance ();
}
static tl::Variant get_config (lay::PluginRoot *root, const std::string &name)
static tl::Variant get_config (lay::Dispatcher *dispatcher, const std::string &name)
{
std::string value;
if (root->config_get (name, value)) {
if (dispatcher->config_get (name, value)) {
return tl::Variant (value);
} else {
return tl::Variant ();
@@ -839,33 +881,33 @@ static tl::Variant get_config (lay::PluginRoot *root, const std::string &name)
}
/**
* @brief Exposes the PluginRoot interface
* @brief Exposes the Dispatcher interface
*
* This interface is intentionally not derived from Plugin. It is used currently to
* identify the plugin root node for configuration. The Plugin nature of this interface
* identify the dispatcher node for configuration. The Plugin nature of this interface
* is somewhat artificial and may be removed later.
*
* TODO: this is a duplicate of the respective methods in LayoutView and Application.
* This is intentional since we don't want to spend the only derivation path on this.
* Once there is a mixin concept, provide a path through that concept.
*/
Class<lay::PluginRoot> decl_PluginRoot ("lay", "PluginRoot",
method ("clear_config", &lay::PluginRoot::clear_config,
Class<lay::Dispatcher> decl_Dispatcher ("lay", "Dispatcher",
method ("clear_config", &lay::Dispatcher::clear_config,
"@brief Clears the configuration parameters\n"
) +
method ("instance", &config_root_instance,
"@brief Gets the singleton instance of the PluginRoot object\n"
method ("instance", &dispatcher_instance,
"@brief Gets the singleton instance of the Dispatcher object\n"
"\n"
"@return The instance\n"
) +
method ("write_config", &lay::PluginRoot::write_config, gsi::arg ("file_name"),
method ("write_config", &lay::Dispatcher::write_config, gsi::arg ("file_name"),
"@brief Writes configuration to a file\n"
"@return A value indicating whether the operation was successful\n"
"\n"
"If the configuration file cannot be written, false \n"
"is returned but no exception is thrown.\n"
) +
method ("read_config", &lay::PluginRoot::read_config, gsi::arg ("file_name"),
method ("read_config", &lay::Dispatcher::read_config, gsi::arg ("file_name"),
"@brief Reads the configuration from a file\n"
"@return A value indicating whether the operation was successful\n"
"\n"
@@ -880,7 +922,7 @@ Class<lay::PluginRoot> decl_PluginRoot ("lay", "PluginRoot",
"\n"
"@return The value of the parameter or nil if there is no such parameter\n"
) +
method ("set_config", (void (lay::PluginRoot::*) (const std::string &, const std::string &)) &lay::PluginRoot::config_set, gsi::arg ("name"), gsi::arg ("value"),
method ("set_config", (void (lay::Dispatcher::*) (const std::string &, const std::string &)) &lay::Dispatcher::config_set, gsi::arg ("name"), gsi::arg ("value"),
"@brief Set a local configuration parameter with the given name to the given value\n"
"\n"
"@param name The name of the configuration parameter to set\n"
@@ -900,14 +942,14 @@ Class<lay::PluginRoot> decl_PluginRoot ("lay", "PluginRoot",
"This method returns the names of all known configuration parameters. These names can be used to "
"get and set configuration parameter values.\n"
) +
method ("commit_config", &lay::PluginRoot::config_end,
method ("commit_config", &lay::Dispatcher::config_end,
"@brief Commits the configuration settings\n"
"\n"
"Some configuration options are queued for performance reasons and become active only after 'commit_config' has been called. "
"After a sequence of \\set_config calls, this method should be called to activate the "
"settings made by these calls.\n"
),
"@brief Root of the configuration space in the plugin context\n"
"@brief Root of the configuration space in the plugin context and menu dispatcher\n"
"\n"
"This class provides access to the root configuration space in the context "
"of plugin programming. You can use this class to obtain configuration parameters "
@@ -915,12 +957,12 @@ Class<lay::PluginRoot> decl_PluginRoot ("lay", "PluginRoot",
"preferred way of plugin configuration is through \\Plugin#configure.\n"
"\n"
"Currently, the application object provides an identical entry point for configuration modification. "
"For example, \"Application::instance.set_config\" is identical to \"PluginRoot::instance.set_config\". "
"Hence there is little motivation for the PluginRoot class currently and "
"For example, \"Application::instance.set_config\" is identical to \"Dispatcher::instance.set_config\". "
"Hence there is little motivation for the Dispatcher class currently and "
"this interface may be modified or removed in the future."
"\n"
"\n"
"This class has been introduced in version 0.25.\n"
"This class has been introduced in version 0.25 as 'PluginRoot'.\n"
"It is renamed and enhanced as 'Dispatcher' in 0.27."
);
}
File diff suppressed because it is too large Load Diff
+123 -214
View File
@@ -50,10 +50,9 @@ class QMenu;
namespace lay
{
class AbstractMenuProvider;
class Action;
class AbstractMenu;
class PluginRoot;
class Dispatcher;
/**
* @brief A utility function to convert the packed key binding in the cfg_key_bindings string to a vector
@@ -76,115 +75,54 @@ LAYBASIC_PUBLIC std::vector<std::pair<std::string, bool> > unpack_menu_items_hid
LAYBASIC_PUBLIC std::string pack_menu_items_hidden (const std::vector<std::pair<std::string, bool> > &unpacked);
/**
* @brief A helper class that does reference counting for the QAction object
*/
class ActionHandle
: public QObject
{
Q_OBJECT
public:
ActionHandle (QWidget *parent);
ActionHandle (QAction *action, bool owned = true);
ActionHandle (QMenu *menu, bool owned = true);
~ActionHandle ();
void add_ref ();
void remove_ref ();
QAction *ptr () const;
QMenu *menu () const;
void set_visible (bool v);
void set_hidden (bool h);
bool is_visible () const;
bool is_hidden () const;
bool is_effective_visible () const;
void set_default_shortcut (const std::string &sc);
void set_shortcut (const std::string &sc);
std::string get_default_shortcut () const;
std::string get_shortcut() const;
QKeySequence get_key_sequence () const;
QKeySequence get_key_sequence_for (const std::string &sc) const;
protected slots:
void destroyed (QObject *obj);
private:
QMenu *mp_menu;
QAction *mp_action;
int m_ref_count;
bool m_owned;
bool m_visible;
bool m_hidden;
std::string m_default_shortcut;
QKeySequence m_default_key_sequence;
std::string m_shortcut;
QKeySequence m_key_sequence;
bool m_no_key_sequence;
// no copying
ActionHandle (const ActionHandle &);
ActionHandle &operator= (const ActionHandle &);
};
/**
* @brief A QAction proxy
* @brief The basic Action object
*
* This class is provided to be better suited to automation because it provides the corresponding interfaces
* and allows implementing the "trigger" event by reimplementation of the slot (after being connected).
* In addition, by acting as a proxy, it can act as a reference to a QAction object created by Qt itself (i.e.
* within a QMenu).
* To reimplement the "triggered" method, derive a class from Action and reimplement "triggered". Then
* pass a reference to this object to "insert_item" of AbstractMenu and store away the derived object.
* This object then will receive the triggered events, although the menu holds a pure Action object.
* This works since the basic object is the QAction to which both the derived object and the Action
* point to. A triggered event will be forwarded from this QAction to all referencing Action objects.
* An "action" is the target of a menu action. It allows reimplementing the "triggered" method
* to implement a specific action. The action encapsulates a QAction object.
*
* Use this object in "insert_item" of AbstractMenu.
*
* This object is typically owned by the AbstractMenu and cannot be copied or assigned.
*/
class LAYBASIC_PUBLIC Action
: public QObject
: public QObject,
public tl::Object,
public gsi::ObjectBase
{
Q_OBJECT
public:
/**
* @brief The default constructor
*
* This constructor creates an QAction object internally which is owned by the Action object.
* @brief The main constructor
*/
Action ();
Action ();
/**
* @brief The copy constructor
*
* This constructor creates an QAction object internally which is owned by the Action object.
* @brief Creates an action from the given QAction
* If "owned" is true, the QAction will become owned by the Action object.
*/
Action (const Action &action);
Action (QAction *action, bool owned = true);
/**
* @brief Create an action with the given title (icon, keyboard shortcut)
* @brief Creates an action from the given QMenu
* If "owned" is true, the QAction will become owned by the Action object.
*/
Action (QMenu *menu, bool owned = true);
/**
* @brief Creates an action with the given title (icon, keyboard shortcut)
*
* The title will optionally encode the shortcut and/or icon resource.
* The format of the title string is: <text>["("shortcut")"]["<"icon-resource">"]
*
* @param title The title string encoding icon and keyboard shortcut if applicable.
*/
Action (const std::string &title);
Action (const std::string &title);
/**
* @brief Creates a new free action
* This constructor wil create a new action with it's own QAction object
* under the given parent.
* @brief Destructor
*/
static Action create_free_action (QWidget *parent);
/**
* @brief Assignement
*/
Action &operator= (const Action &action);
/**
* @brief The destructor
*/
~Action ();
~Action ();
/**
* @brief Set the title
@@ -309,7 +247,7 @@ public:
void set_separator (bool s);
/**
* @brief Set the tool tip text
* @brief Set the tool tip text
*
* @param text The text to display in the tool tip
*/
@@ -325,7 +263,7 @@ public:
void set_icon (const std::string &filename);
/**
* @brief Set the icon's text
* @brief Set the icon's text
*
* If an icon text is set, this will be used for the text below the icon.
* If no icon text is set, the normal text will be used for the icon.
@@ -333,7 +271,7 @@ public:
*/
void set_icon_text (const std::string &icon_text);
/**
/**
* @brief Set the action's QObject name (for testing for example)
*/
void set_object_name (const std::string &name);
@@ -344,12 +282,12 @@ public:
void add_to_exclusive_group (lay::AbstractMenu *menu, const std::string &group_name);
/**
* @brief Get the tool tip text
* @brief Get the tool tip text
*/
std::string get_tool_tip () const;
/**
* @brief Get the icon's text
* @brief Get the icon's text
*/
std::string get_icon_text () const;
@@ -376,72 +314,76 @@ public:
QMenu *menu () const;
/**
* @brief Compares two action objects
*
* Two action objects are equal when they refer to the same ActionHandle.
* @brief Gets the dispatcher object this action is connected to
*/
bool operator== (const Action &other) const
Dispatcher *dispatcher () const
{
return mp_handle == other.mp_handle;
return mp_dispatcher;
}
public slots:
void triggered_slot ();
protected slots:
void destroyed (QObject *obj);
void qaction_triggered ();
private:
friend class AbstractMenu;
friend struct AbstractMenuItem;
ActionHandle *mp_handle;
QMenu *mp_menu;
QAction *mp_action;
lay::Dispatcher *mp_dispatcher;
bool m_owned;
bool m_visible;
bool m_hidden;
std::string m_default_shortcut;
QKeySequence m_default_key_sequence;
std::string m_shortcut;
std::string m_symbol;
QKeySequence m_key_sequence;
bool m_no_key_sequence;
/**
* @brief The proxy constructor
*
* This constructor takes a QAction object that it will refer to.
* If the Action is copied, the copy will refer to the same QAction.
* The QAction object is deleted if the last Action referring to QAction is deleted.
*/
Action (ActionHandle *action);
void set_dispatcher (Dispatcher *dispatcher);
QKeySequence get_key_sequence () const;
QKeySequence get_key_sequence_for (const std::string &sc) const;
// no copying
Action (const Action &);
Action &operator= (const Action &);
};
/**
* @brief A specialisation for the Action to issue a "configure" request on "triggered"
*
* When this action is triggered, a "configure" request is issued to the PluginRoot instance
* When this action is triggered, a "configure" request is issued to the Dispatcher instance
* (which is the root of the configuration hierarchy). The name and value is given by the
* respective parameters passed to the constructor or set with the write accessors.
*/
class LAYBASIC_PUBLIC ConfigureAction
: public Action,
public tl::Object
: public Action
{
public:
enum type { setter_type = 0, boolean_type = 1, choice_type = 2 };
/**
* @brief The default constructor
*
* @param pr The reference to the plugin root object which receives the configure request
*/
ConfigureAction (lay::PluginRoot *pr);
ConfigureAction ();
/**
* @brief Create an configure action with the given name and value
*
* @param pr The reference to the plugin root object which receives the configure request
* @param cname The name of the configuration parameter to set
* @param cvalue The value to set "cname" to
*
* The value can be "?" in which case the configuration action describes
* a boolean parameter which is mapped to a checkable action.
*/
ConfigureAction (lay::PluginRoot *pr, const std::string &cname, const std::string &value);
ConfigureAction (const std::string &cname, const std::string &value);
/**
* @brief Create an configure action with the given title (icon, keyboard shortcut), name and value
*
* The format of the title string is: <text>["("shortcut")"]["<"icon-resource">"]
*
* @param pr The reference to the plugin root object which receives the configure request
* @param title The title string encoding icon and keyboard shortcut if applicable.
* @param cname The name of the configuration parameter to set
* @param cvalue The value to set "cname" to
@@ -449,7 +391,7 @@ public:
* The value can be "?" in which case the configuration action describes
* a boolean parameter which is mapped to a checkable action.
*/
ConfigureAction (lay::PluginRoot *pr, const std::string &title, const std::string &cname, const std::string &value);
ConfigureAction (const std::string &title, const std::string &cname, const std::string &value);
/**
* @brief Destructor
@@ -498,76 +440,20 @@ public:
protected:
virtual void triggered ();
void reg ();
void unreg ();
private:
ConfigureAction (const ConfigureAction &action);
ConfigureAction &operator= (const ConfigureAction &action);
lay::PluginRoot *m_pr;
std::string m_cname, m_cvalue;
type m_type;
};
/**
* @brief A menu layout entry for static initialisation
*
* These objects act as the "source" for creating the initial AbstractLayout setup.
*/
struct LAYBASIC_PUBLIC MenuLayoutEntry {
MenuLayoutEntry (const char *_name,
const std::string &_title,
const std::pair<std::string, std::string> &_kv_pair)
: name (_name), title (_title), slot (0), kv_pair (_kv_pair), submenu (0)
{ }
MenuLayoutEntry (const char *_name,
const std::string &_title,
const char *_slot,
const MenuLayoutEntry *_submenu = 0)
: name (_name), title (_title), slot (_slot), submenu (_submenu)
{ }
MenuLayoutEntry (const char *_name,
const std::string &_title,
const MenuLayoutEntry *_submenu = 0)
: name (_name), title (_title), slot (0), submenu (_submenu)
{ }
MenuLayoutEntry (const char *_name)
: name (_name), slot (0), submenu (0)
{ }
MenuLayoutEntry ()
: name (0), slot (0), submenu (0)
{ }
static MenuLayoutEntry separator (const char *name)
{
return MenuLayoutEntry (name);
}
static MenuLayoutEntry last ()
{
return MenuLayoutEntry ();
}
const char *name;
std::string title;
const char *slot;
std::pair<std::string, std::string> kv_pair;
const MenuLayoutEntry *submenu;
};
/**
* @brief One item in the abstract menu
*/
struct LAYBASIC_PUBLIC AbstractMenuItem
{
AbstractMenuItem ();
AbstractMenuItem (lay::Dispatcher *dispatcher);
// No copy constructor semantics because we don't need it (we use list's) and Action does not provide one.
AbstractMenuItem (const AbstractMenuItem &);
@@ -575,7 +461,12 @@ struct LAYBASIC_PUBLIC AbstractMenuItem
/**
* @brief Internal method used to set up the item
*/
void setup_item (const std::string &pn, const std::string &n, const Action &a);
void setup_item (const std::string &pn, const std::string &n, Action *a);
Dispatcher *dispatcher () const
{
return mp_dispatcher;
}
const std::string &name () const
{
@@ -587,18 +478,23 @@ struct LAYBASIC_PUBLIC AbstractMenuItem
return m_groups;
}
void set_action (const Action &a, bool copy_properties);
void set_action (Action *a, bool copy_properties);
void set_action_title (const std::string &t);
const Action &action () const
Action *action ()
{
return m_action;
return mp_action.get ();
}
QMenu *menu () const
const Action *action () const
{
return m_action.menu ();
return mp_action.get ();
}
QMenu *menu ()
{
return mp_action->menu ();
}
void set_has_submenu ();
@@ -618,9 +514,10 @@ struct LAYBASIC_PUBLIC AbstractMenuItem
std::list <AbstractMenuItem> children;
private:
tl::shared_ptr<Action> mp_action;
Dispatcher *mp_dispatcher;
bool m_has_submenu;
bool m_remove_on_empty;
Action m_action;
std::string m_name;
std::string m_basename;
std::set<std::string> m_groups;
@@ -636,11 +533,6 @@ private:
* Each item can be associated with a Action, which delivers a title, enabled/disable state etc.
* The Action is either provided when new entries are inserted or created upon initialisation.
*
* An abstract menu is initialised from a initialisation sequence given by a list of
* MenuLayoutEntry objects terminated with a MenuLayoutEntry::last() item.
* Each of these entries may provide a submenu. Beside for initialisation, these entries
* are not used further.
*
* The abstract menu class provides methods to manipulate the menu structure (the state of the
* menu items, their title and shortcut key is provided and manipulated through the Action object).
*
@@ -684,18 +576,13 @@ public:
/**
* @brief Create the abstract menu object attached to the given main window
*/
AbstractMenu (AbstractMenuProvider *provider);
AbstractMenu (Dispatcher *dispatcher);
/**
* @brief Destroy the abstract menu object
*/
~AbstractMenu ();
/**
* @brief Initialise from a sequence of MenuLayoutEntry objects
*/
void init (const MenuLayoutEntry *layout);
/**
* @brief Rebuild the QMenu's and refill the QMenuBar object
*/
@@ -729,7 +616,12 @@ public:
* @param path The path to the item. This must be a valid path.
* @return The action object
*/
Action action (const std::string &path) const;
Action *action (const std::string &path);
/**
* @brief Get the Action object for a given item (const version)
*/
const Action *action(const std::string &path) const;
/**
* @brief Get the subitems for a given submenu
@@ -772,8 +664,10 @@ public:
* @param path The path to the item before which to insert the new item
* @param name The name of the item to insert
* @param action The action associated with the item
*
* NOTE: the abstract menu will take ownership of the Action object.
*/
void insert_item (const std::string &path, const std::string &name, const Action &action);
void insert_item (const std::string &path, const std::string &name, Action *action);
/**
* @brief Insert a new separator before the one item by the path
@@ -793,7 +687,7 @@ public:
* @param name The name of the submenu to insert
* @param action The action associated with the submenu
*/
void insert_menu (const std::string &path, const std::string &name, const Action &action);
void insert_menu (const std::string &path, const std::string &name, Action *action);
/**
* @brief Insert a new submenu before the item given by the path
@@ -824,7 +718,7 @@ public:
/**
* @brief Delete the items referring to the given action
*/
void delete_items (const Action &action);
void delete_items (Action *action);
/**
* @brief Get the group members
@@ -834,6 +728,21 @@ public:
*/
std::vector<std::string> group (const std::string &name) const;
/**
* @brief Get the group members as Action objects
*
* @param group The group name
* @param A vector of all members (as actions) of the group
*/
std::vector<Action *> group_actions(const std::string &name);
/**
* @brief Get the configure actions for a given configuration name
*
* @param The configuration actions for this given configuration name
*/
std::vector<lay::ConfigureAction *> configure_actions (const std::string &name);
/**
* @brief Get the detached menu
*
@@ -873,29 +782,21 @@ signals:
private:
friend class Action;
std::vector<std::pair<AbstractMenuItem *, std::list<AbstractMenuItem>::iterator> > find_item (const std::string &path);
std::vector<std::pair<AbstractMenuItem *, std::list<AbstractMenuItem>::iterator> > find_item (tl::Extractor &extr);
const AbstractMenuItem *find_item_exact (const std::string &path) const;
AbstractMenuItem *find_item_exact (const std::string &path);
void transfer (const MenuLayoutEntry *layout, AbstractMenuItem &item);
void build (QMenu *menu, std::list<AbstractMenuItem> &items);
void build (QToolBar *tbar, std::list<AbstractMenuItem> &items);
void collect_group (std::vector<std::string> &grp, const std::string &name, const AbstractMenuItem &item) const;
void collect_configure_actions (std::vector<ConfigureAction *> &ca, AbstractMenuItem &item);
void emit_changed ();
/**
* @brief Create a action from a string
*
* The format of the string is: <text>["("shortcut")"]["<"icon-resource">"]
*
* @param s The title, key and icon resource string in the format given above
* @param parent The widget to which to attach the QAction object
* @return The ActionHandle object created
*/
static ActionHandle *create_action (const std::string &s);
AbstractMenuProvider *mp_provider;
Dispatcher *mp_dispatcher;
AbstractMenuItem m_root;
tl::stable_vector<QMenu> m_helper_menu_items;
std::map<std::string, QActionGroup *> m_action_groups;
std::map<std::string, std::vector<ConfigureAction *> > m_config_action_by_name;
bool m_config_actions_valid;
};
}
@@ -907,6 +808,14 @@ namespace tl
typedef tl::false_tag has_default_constructor;
};
template <> struct type_traits<lay::AbstractMenuItem> : public type_traits<void> {
typedef tl::false_tag has_copy_constructor;
typedef tl::false_tag has_default_constructor;
};
template <> struct type_traits<lay::Action> : public type_traits<void> {
typedef tl::false_tag has_copy_constructor;
};
}
#endif
@@ -1,106 +0,0 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2020 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef HDR_layAbstractMenuProvider
#define HDR_layAbstractMenuProvider
#include "laybasicCommon.h"
#include <string>
class QWidget;
namespace lay
{
class AbstractMenu;
class Action;
class ConfigureAction;
/**
* @brief An interface for the supplier of the abstract menu object
*/
class LAYBASIC_PUBLIC AbstractMenuProvider
{
public:
/**
* @brief Constructor
*/
AbstractMenuProvider ();
/**
* @brief Destructor
*/
virtual ~AbstractMenuProvider ();
/**
* @brief Gets the AbstractMenu object
*/
virtual AbstractMenu *menu () = 0;
/**
* @brief Gets the parent widget
*/
virtual QWidget *menu_parent_widget () = 0;
/**
* @brief Get the action for a slot
*/
virtual lay::Action &action_for_slot (const char *slot) = 0;
/**
* @brief Create a configuration action with the given title, parameter name and value
*
* The action will be owned by the main window but can be deleted to remove the action from the main window.
*/
virtual lay::Action *create_config_action (const std::string &title, const std::string &cname, const std::string &cvalue) = 0;
/**
* @brief Create a configuration action with the given parameter name and value
*
* The action will be owned by the main window but can be deleted to remove the action from the main window.
* This version is provided for applications, where the title is set later.
*/
virtual lay::Action *create_config_action (const std::string &cname, const std::string &cvalue) = 0;
/**
* @brief Register a configuration action with the given name
*/
virtual void register_config_action (const std::string &name, lay::ConfigureAction *action) = 0;
/**
* @brief Unregister a configuration action with the given name
*/
virtual void unregister_config_action (const std::string &name, lay::ConfigureAction *action) = 0;
/**
* @brief Gets the singleton instance of the AbstractMenuProvider object
*/
static AbstractMenuProvider *instance ();
};
}
#endif
+26 -24
View File
@@ -24,7 +24,6 @@
#include "layBookmarksView.h"
#include "layLayoutView.h"
#include "layAbstractMenu.h"
#include "layAbstractMenuProvider.h"
#include "laybasicConfig.h"
@@ -134,26 +133,6 @@ BookmarksView::follow_selection (bool f)
m_follow_selection = f;
}
void
BookmarksView::init_menu (lay::AbstractMenu &menu)
{
MenuLayoutEntry context_menu [] = {
MenuLayoutEntry ("follow_selection", tl::to_string (QObject::tr ("Follow Selection")), std::make_pair (cfg_bookmarks_follow_selection, "?")),
MenuLayoutEntry::separator ("ops_group"),
MenuLayoutEntry ("manage_bookmarks", tl::to_string (QObject::tr ("Manage Bookmarks")), SLOT (cm_manage_bookmarks ())),
MenuLayoutEntry ("load_bookmarks", tl::to_string (QObject::tr ("Load Bookmarks")), SLOT (cm_load_bookmarks ())),
MenuLayoutEntry ("save_bookmarks", tl::to_string (QObject::tr ("Save Bookmarks")), SLOT (cm_save_bookmarks ())),
MenuLayoutEntry::last ()
};
MenuLayoutEntry main_menu [] = {
MenuLayoutEntry ("@bookmarks_context_menu", "", context_menu),
MenuLayoutEntry::last ()
};
menu.init (main_menu);
}
void
BookmarksView::set_background_color (QColor c)
{
@@ -182,11 +161,9 @@ BookmarksView::refresh ()
void
BookmarksView::context_menu (const QPoint &p)
{
tl_assert (lay::AbstractMenuProvider::instance () != 0);
QListView *bm_list = dynamic_cast<QListView *> (sender ());
if (bm_list) {
QMenu *ctx_menu = lay::AbstractMenuProvider::instance ()->menu ()->detached_menu ("bookmarks_context_menu");
QMenu *ctx_menu = mp_view->menu ()->detached_menu ("bookmarks_context_menu");
ctx_menu->exec (bm_list->mapToGlobal (p));
}
}
@@ -207,5 +184,30 @@ BookmarksView::bookmark_triggered (const QModelIndex &index)
}
}
// ------------------------------------------------------------
// Declaration of the "plugin" for the menu entries
class BookmarksViewPluginDeclaration
: public lay::PluginDeclaration
{
public:
virtual void get_menu_entries (std::vector<lay::MenuEntry> &menu_entries) const
{
std::string at;
at = ".end";
menu_entries.push_back (lay::submenu ("@bookmarks_context_menu", at, std::string ()));
at = "@bookmarks_context_menu.end";
menu_entries.push_back (lay::config_menu_item ("follow_selection", at, tl::to_string (QObject::tr ("Follow Selection")), cfg_bookmarks_follow_selection, "?")),
menu_entries.push_back (lay::separator ("ops_group", at));
menu_entries.push_back (lay::menu_item ("cm_manage_bookmarks", "manage_bookmarks", at, tl::to_string (QObject::tr ("Manage Bookmarks"))));
menu_entries.push_back (lay::menu_item ("cm_load_bookmarks", "load_bookmarks", at, tl::to_string (QObject::tr ("Load Bookmarks"))));
menu_entries.push_back (lay::menu_item ("cm_save_bookmarks", "save_bookmarks", at, tl::to_string (QObject::tr ("Save Bookmarks"))));
}
};
static tl::RegisteredClass<lay::PluginDeclaration> config_decl (new BookmarksViewPluginDeclaration (), -7, "BookmarksViewPlugin");
}
-2
View File
@@ -59,8 +59,6 @@ public:
void refresh ();
static void init_menu (lay::AbstractMenu &menu);
public slots:
void bookmark_triggered (const QModelIndex &index);
void current_bookmark_changed (const QModelIndex &index);
@@ -76,10 +76,10 @@ public:
virtual void get_menu_entries (std::vector<lay::MenuEntry> &menu_entries) const
{
lay::PluginDeclaration::get_menu_entries (menu_entries);
menu_entries.push_back (lay::MenuEntry ("browse_instances::show", "browse_instances", "tools_menu.end", tl::to_string (QObject::tr ("Browse Instances"))));
menu_entries.push_back (lay::menu_item ("browse_instances::show", "browse_instances", "tools_menu.end", tl::to_string (QObject::tr ("Browse Instances"))));
}
virtual lay::Plugin *create_plugin (db::Manager *, lay::PluginRoot *root, lay::LayoutView *view) const
virtual lay::Plugin *create_plugin (db::Manager *, lay::Dispatcher *root, lay::LayoutView *view) const
{
return new BrowseInstancesForm (root, view);
}
@@ -175,7 +175,7 @@ BrowseInstancesConfigPage::BrowseInstancesConfigPage (QWidget *parent)
}
void
BrowseInstancesConfigPage::setup (lay::PluginRoot *root)
BrowseInstancesConfigPage::setup (lay::Dispatcher *root)
{
std::string value;
@@ -221,7 +221,7 @@ BrowseInstancesConfigPage::window_changed (int m)
}
void
BrowseInstancesConfigPage::commit (lay::PluginRoot *root)
BrowseInstancesConfigPage::commit (lay::Dispatcher *root)
{
double dim = 1.0;
tl::from_string (tl::to_string (le_window->text ()), dim);
@@ -289,7 +289,7 @@ private:
// ------------------------------------------------------------
BrowseInstancesForm::BrowseInstancesForm (lay::PluginRoot *root, lay::LayoutView *vw)
BrowseInstancesForm::BrowseInstancesForm (lay::Dispatcher *root, lay::LayoutView *vw)
: lay::Browser (root, vw),
Ui::BrowseInstancesForm (),
m_cv_index (0),
@@ -46,8 +46,8 @@ class BrowseInstancesConfigPage
public:
BrowseInstancesConfigPage (QWidget *parent);
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
public slots:
void context_changed (int);
@@ -64,7 +64,7 @@ public:
enum mode_type { ToCellView = 0, AnyTop, Parent };
enum window_type { DontChange = 0, FitCell, FitMarker, Center, CenterSize };
BrowseInstancesForm (lay::PluginRoot *root, lay::LayoutView *view);
BrowseInstancesForm (lay::Dispatcher *root, lay::LayoutView *view);
~BrowseInstancesForm ();
bool eventFilter (QObject *watched, QEvent *event);
+6 -6
View File
@@ -76,11 +76,11 @@ public:
virtual void get_menu_entries (std::vector<lay::MenuEntry> &menu_entries) const
{
lay::PluginDeclaration::get_menu_entries (menu_entries);
menu_entries.push_back (lay::MenuEntry ("browser_group", "tools_menu.end"));
menu_entries.push_back (lay::MenuEntry ("browse_shapes::show", "browse_shapes", "tools_menu.end", tl::to_string (QObject::tr ("Browse Shapes"))));
menu_entries.push_back (lay::separator ("browser_group", "tools_menu.end"));
menu_entries.push_back (lay::menu_item ("browse_shapes::show", "browse_shapes", "tools_menu.end", tl::to_string (QObject::tr ("Browse Shapes"))));
}
virtual lay::Plugin *create_plugin (db::Manager *, lay::PluginRoot *root, lay::LayoutView *view) const
virtual lay::Plugin *create_plugin (db::Manager *, lay::Dispatcher *root, lay::LayoutView *view) const
{
return new BrowseShapesForm (root, view);
}
@@ -177,7 +177,7 @@ BrowseShapesConfigPage::BrowseShapesConfigPage (QWidget *parent)
}
void
BrowseShapesConfigPage::setup (lay::PluginRoot *root)
BrowseShapesConfigPage::setup (lay::Dispatcher *root)
{
std::string value;
@@ -228,7 +228,7 @@ BrowseShapesConfigPage::window_changed (int m)
}
void
BrowseShapesConfigPage::commit (lay::PluginRoot *root)
BrowseShapesConfigPage::commit (lay::Dispatcher *root)
{
double dim = 1.0;
tl::from_string (tl::to_string (le_window->text ()), dim);
@@ -388,7 +388,7 @@ private:
// ------------------------------------------------------------
BrowseShapesForm::BrowseShapesForm (lay::PluginRoot *root, lay::LayoutView *vw)
BrowseShapesForm::BrowseShapesForm (lay::Dispatcher *root, lay::LayoutView *vw)
: lay::Browser (root, vw),
Ui::BrowseShapesForm (),
m_cv_index (-1),
+3 -3
View File
@@ -45,8 +45,8 @@ class BrowseShapesConfigPage
public:
BrowseShapesConfigPage (QWidget *parent);
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
public slots:
void context_changed (int);
@@ -63,7 +63,7 @@ public:
enum mode_type { ToCellView = 0, AnyTop, Local };
enum window_type { DontChange = 0, FitCell, FitMarker, Center, CenterSize };
BrowseShapesForm (lay::PluginRoot *root, lay::LayoutView *view);
BrowseShapesForm (lay::Dispatcher *root, lay::LayoutView *view);
~BrowseShapesForm ();
bool eventFilter (QObject *watched, QEvent *event);
+2 -2
View File
@@ -32,9 +32,9 @@ namespace lay
{
#if QT_VERSION >= 0x050000
Browser::Browser (lay::PluginRoot *root, lay::LayoutView *view, const char *name, Qt::WindowFlags fl)
Browser::Browser (lay::Dispatcher *root, lay::LayoutView *view, const char *name, Qt::WindowFlags fl)
#else
Browser::Browser (lay::PluginRoot *root, lay::LayoutView *view, const char *name, Qt::WFlags fl)
Browser::Browser (lay::Dispatcher *root, lay::LayoutView *view, const char *name, Qt::WFlags fl)
#endif
// TODO: clarify whether to keep the browsers as separate (potentially hidden) windows
: QDialog (0 /*view*/, fl),
+5 -5
View File
@@ -36,7 +36,7 @@ namespace lay
{
class LayoutView;
class PluginRoot;
class Dispatcher;
class LAYBASIC_PUBLIC Browser
: public QDialog,
@@ -47,9 +47,9 @@ public:
* @brief Constructor
*/
#if QT_VERSION >= 0x050000
Browser (lay::PluginRoot *root, lay::LayoutView *view, const char *name = "", Qt::WindowFlags fl = Qt::Window /*adds minimize button for example*/);
Browser (lay::Dispatcher *root, lay::LayoutView *view, const char *name = "", Qt::WindowFlags fl = Qt::Window /*adds minimize button for example*/);
#else
Browser (lay::PluginRoot *root, lay::LayoutView *view, const char *name = "", Qt::WFlags fl = Qt::Window /*adds minimize button for example*/);
Browser (lay::Dispatcher *root, lay::LayoutView *view, const char *name = "", Qt::WFlags fl = Qt::Window /*adds minimize button for example*/);
#endif
/**
@@ -101,7 +101,7 @@ public:
/**
* @brief Returns the pointer to the root configuration object
*/
lay::PluginRoot *root ()
lay::Dispatcher *root ()
{
return mp_root;
}
@@ -133,7 +133,7 @@ public:
private:
bool m_active;
lay::LayoutView *mp_view;
lay::PluginRoot *mp_root;
lay::Dispatcher *mp_root;
void closeEvent (QCloseEvent *);
void accept ();
@@ -76,12 +76,12 @@ CellSelectionForm::CellSelectionForm (QWidget *parent, lay::LayoutView *view, co
mp_case_sensitive->setChecked (true);
mp_case_sensitive->setText (tr ("Case sensitive search"));
if (lay::PluginRoot::instance ()) {
if (lay::Dispatcher::instance ()) {
bool cs = true;
lay::PluginRoot::instance ()->config_get (cfg_cell_selection_search_case_sensitive, cs);
lay::Dispatcher::instance ()->config_get (cfg_cell_selection_search_case_sensitive, cs);
mp_case_sensitive->setChecked (cs);
bool ue = true;
lay::PluginRoot::instance ()->config_get (cfg_cell_selection_search_use_expressions, ue);
lay::Dispatcher::instance ()->config_get (cfg_cell_selection_search_use_expressions, ue);
mp_use_regular_expressions->setChecked (ue);
}
@@ -285,9 +285,9 @@ CellSelectionForm::reject ()
void
CellSelectionForm::store_config ()
{
if (lay::PluginRoot::instance ()) {
lay::PluginRoot::instance ()->config_set (cfg_cell_selection_search_case_sensitive, mp_case_sensitive->isChecked ());
lay::PluginRoot::instance ()->config_set (cfg_cell_selection_search_use_expressions, mp_use_regular_expressions->isChecked ());
if (lay::Dispatcher::instance ()) {
lay::Dispatcher::instance ()->config_set (cfg_cell_selection_search_case_sensitive, mp_case_sensitive->isChecked ());
lay::Dispatcher::instance ()->config_set (cfg_cell_selection_search_use_expressions, mp_use_regular_expressions->isChecked ());
}
}
@@ -28,6 +28,7 @@
#include "ui_ConfigurationDialog.h"
#include "layConfigurationDialog.h"
#include "layPlugin.h"
#include "layDispatcher.h"
#include "tlLog.h"
@@ -36,7 +37,7 @@ namespace lay
// -------------------------------------------------------------
ConfigurationDialog::ConfigurationDialog (QWidget *parent, lay::PluginRoot *root, const std::string &plugin_name, const char *name)
ConfigurationDialog::ConfigurationDialog (QWidget *parent, lay::Dispatcher *root, const std::string &plugin_name, const char *name)
: QDialog (parent),
mp_root (root)
{
@@ -56,7 +57,7 @@ ConfigurationDialog::ConfigurationDialog (QWidget *parent, lay::PluginRoot *root
}
}
ConfigurationDialog::ConfigurationDialog (QWidget *parent, lay::PluginRoot *root, lay::PluginDeclaration *decl, const char *name)
ConfigurationDialog::ConfigurationDialog (QWidget *parent, lay::Dispatcher *root, lay::PluginDeclaration *decl, const char *name)
: QDialog (parent),
mp_root (root)
{
@@ -38,7 +38,7 @@ namespace Ui
namespace lay
{
class PluginRoot;
class Dispatcher;
class ConfigPage;
class PluginDeclaration;
@@ -48,8 +48,8 @@ class LAYBASIC_PUBLIC ConfigurationDialog
Q_OBJECT
public:
ConfigurationDialog (QWidget *parent, lay::PluginRoot *root, lay::PluginDeclaration *decl, const char *name = "");
ConfigurationDialog (QWidget *parent, lay::PluginRoot *root, const std::string &plugin_name, const char *name = "");
ConfigurationDialog (QWidget *parent, lay::Dispatcher *root, lay::PluginDeclaration *decl, const char *name = "");
ConfigurationDialog (QWidget *parent, lay::Dispatcher *root, const std::string &plugin_name, const char *name = "");
~ConfigurationDialog ();
void commit ();
@@ -58,7 +58,7 @@ public slots:
virtual void ok_clicked ();
private:
lay::PluginRoot *mp_root;
lay::Dispatcher *mp_root;
std::vector <lay::ConfigPage *> m_config_pages;
Ui::ConfigurationDialog *mp_ui;
+229
View File
@@ -0,0 +1,229 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2020 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "layDispatcher.h"
#include "tlXMLParser.h"
#include "tlXMLWriter.h"
namespace lay
{
// ----------------------------------------------------------------
// Dispatcher implementation
static Dispatcher *ms_dispatcher_instance = 0;
Dispatcher::Dispatcher (Plugin *parent, bool standalone)
: Plugin (parent, standalone),
m_menu (this)
{
if (! parent && ! ms_dispatcher_instance) {
ms_dispatcher_instance = this;
}
}
Dispatcher::~Dispatcher ()
{
if (ms_dispatcher_instance == this) {
ms_dispatcher_instance = 0;
}
}
bool
Dispatcher::configure (const std::string &name, const std::string &value)
{
std::vector<lay::ConfigureAction *> ca = m_menu.configure_actions (name);
for (std::vector<lay::ConfigureAction *>::const_iterator a = ca.begin (); a != ca.end (); ++a) {
(*a)->configure (value);
}
return false;
}
// Writing and Reading of configuration
struct ConfigGetAdaptor
{
ConfigGetAdaptor (const std::string &name)
: mp_owner (0), m_done (false), m_name (name)
{
// .. nothing yet ..
}
std::string operator () () const
{
std::string s;
mp_owner->config_get (m_name, s);
return s;
}
bool at_end () const
{
return m_done;
}
void start (const lay::Dispatcher &owner)
{
mp_owner = &owner;
m_done = false;
}
void next ()
{
m_done = true;
}
private:
const lay::Dispatcher *mp_owner;
bool m_done;
std::string m_name;
};
struct ConfigGetNullAdaptor
{
ConfigGetNullAdaptor ()
{
// .. nothing yet ..
}
std::string operator () () const
{
return std::string ();
}
bool at_end () const
{
return true;
}
void start (const lay::Dispatcher & /*owner*/) { }
void next () { }
};
struct ConfigNamedSetAdaptor
{
ConfigNamedSetAdaptor ()
{
// .. nothing yet ..
}
void operator () (lay::Dispatcher &w, tl::XMLReaderState &reader, const std::string &name) const
{
tl::XMLObjTag<std::string> tag;
w.config_set (name, *reader.back (tag));
}
};
struct ConfigSetAdaptor
{
ConfigSetAdaptor (const std::string &name)
: m_name (name)
{
// .. nothing yet ..
}
void operator () (lay::Dispatcher &w, tl::XMLReaderState &reader) const
{
tl::XMLObjTag<std::string> tag;
w.config_set (m_name, *reader.back (tag));
}
private:
std::string m_name;
};
// the configuration file's XML structure is built dynamically
static tl::XMLStruct<lay::Dispatcher>
config_structure (const lay::Dispatcher *plugin)
{
tl::XMLElementList body;
std::string n_with_underscores;
std::vector <std::string> names;
plugin->get_config_names (names);
for (std::vector <std::string>::const_iterator n = names.begin (); n != names.end (); ++n) {
body.append (tl::XMLMember<std::string, lay::Dispatcher, ConfigGetAdaptor, ConfigSetAdaptor, tl::XMLStdConverter <std::string> > (
ConfigGetAdaptor (*n), ConfigSetAdaptor (*n), *n));
// for compatibility, provide an alternative with underscores (i.e. 0.20->0.21 because of default_grids)
n_with_underscores.clear ();
for (const char *c = n->c_str (); *c; ++c) {
n_with_underscores += (*c == '-' ? '_' : *c);
}
body.append (tl::XMLMember<std::string, lay::Dispatcher, ConfigGetNullAdaptor, ConfigSetAdaptor, tl::XMLStdConverter <std::string> > (
ConfigGetNullAdaptor (), ConfigSetAdaptor (*n), n_with_underscores));
}
// add a wildcard member to read all others unspecifically into the repository
body.append (tl::XMLWildcardMember<std::string, lay::Dispatcher, ConfigNamedSetAdaptor, tl::XMLStdConverter <std::string> > (ConfigNamedSetAdaptor ()));
return tl::XMLStruct<lay::Dispatcher> ("config", body);
}
bool
Dispatcher::write_config (const std::string &config_file)
{
try {
tl::OutputStream os (config_file, tl::OutputStream::OM_Plain);
config_structure (this).write (os, *this);
return true;
} catch (...) {
return false;
}
}
bool
Dispatcher::read_config (const std::string &config_file)
{
std::auto_ptr<tl::XMLFileSource> file;
try {
file.reset (new tl::XMLFileSource (config_file));
} catch (...) {
return false;
}
try {
config_structure (this).parse (*file, *this);
} catch (tl::Exception &ex) {
std::string msg = tl::to_string (QObject::tr ("Problem reading config file ")) + config_file + ": " + ex.msg ();
throw tl::Exception (msg);
}
config_end ();
return true;
}
Dispatcher *
Dispatcher::instance ()
{
return ms_dispatcher_instance;
}
}
+156
View File
@@ -0,0 +1,156 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2020 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef HDR_layDispatcher
#define HDR_layDispatcher
#include "laybasicCommon.h"
#include "tlTypeTraits.h"
#include "tlObject.h"
#include "layPlugin.h"
#include <map>
#include <string>
#include <vector>
namespace lay
{
class AbstractMenu;
class Action;
class ConfigureAction;
/**
* @brief The central menu event and configuration dispatcher class
*
* This class acts as the top level dispatcher for plugin events and the menu configuration.
*
*/
class LAYBASIC_PUBLIC Dispatcher
: public Plugin
{
public:
/**
* @brief The constructor
*
* @param parent Usually 0, but a dispatcher may have parents. In this case, the dispatcher is not the actual dispatcher, but the real plugin chain's root is.
* @param standalone The standalone flag passed to the plugin constructor.
*/
Dispatcher (Plugin *parent, bool standalone = false);
/**
* @brief Destructor
*/
~Dispatcher ();
/**
* @brief Write configuration to a file
*
* If the configuration file cannot be written, false
* is returned but no exception is thrown.
*
* @return false, if an error occurred.
*/
bool write_config (const std::string &config_file);
/**
* @brief Read the configuration from a file
*
* This method siletly does nothing, if the config file does not
* exist. If it does and an error occurred, the error message is printed
* on stderr. In both cases, false is returned.
*
* @return false, if an error occurred.
*/
bool read_config (const std::string &config_file);
/**
* @brief The singleton instance of the plugin root
*/
static Dispatcher *instance ();
/**
* @brief Notifies the plugin root that a new plugin class has been registered
*
* This method is called when a plugin is loaded dynamically during runtime.
*/
virtual void plugin_registered (lay::PluginDeclaration * /*cls*/) { }
/**
* @brief Notifies the plugin root that a plugin class is about to be removed
*/
virtual void plugin_removed (lay::PluginDeclaration * /*cls*/) { }
/**
* @brief Selects the given mode
*
* The implementation is supposed to select the given mode on all related plugins.
*/
virtual void select_mode (int /*mode*/) { }
/**
* @brief Gets the parent widget
*/
virtual QWidget *menu_parent_widget () { return 0; }
/**
* @brief Returns true, if the dispatcher supplies a user interface
*/
virtual bool has_ui () { return menu_parent_widget () != 0; }
/**
* @brief Gets the AbstractMenu object
*
* This will deliver the actual menu - the one that is the root dispatcher's menu
*/
AbstractMenu *menu ()
{
return (dispatcher () == this) ? &m_menu : dispatcher ()->menu ();
}
protected:
// capture the configuration events so we can change the value of the configuration actions
virtual bool configure (const std::string &name, const std::string &value);
private:
Dispatcher (const Dispatcher &);
Dispatcher &operator= (const Dispatcher &);
lay::AbstractMenu m_menu;
};
}
namespace tl
{
// disable copy ctor for Dispatcher
template <> struct type_traits<lay::Dispatcher> : public type_traits<void> {
typedef tl::false_tag has_copy_constructor;
typedef tl::false_tag has_default_constructor;
};
}
#endif
@@ -52,7 +52,7 @@ struct CurrentStyleOp
EditLineStylesForm::EditLineStylesForm (lay::LayoutView *view, const lay::LineStyles &styles)
: QDialog (view), db::Object (0),
m_selected (-1), m_styles (styles), mp_view (view)
m_selected (-1), m_styles (styles), m_manager (true), mp_view (view)
{
m_selection_changed_enabled = false;
+1 -1
View File
@@ -52,7 +52,7 @@ struct CurrentPatternOp
EditStipplesForm::EditStipplesForm (lay::LayoutView *view, const lay::DitherPattern &pattern)
: QDialog (view), db::Object (0),
m_selected (-1), m_pattern (pattern), mp_view (view)
m_selected (-1), m_pattern (pattern), m_manager (true), mp_view (view)
{
m_selection_changed_enabled = false;
+3 -3
View File
@@ -105,7 +105,7 @@ GridNetPluginDeclaration::config_page (QWidget *parent, std::string &title) cons
}
lay::Plugin *
GridNetPluginDeclaration::create_plugin (db::Manager *, lay::PluginRoot *, lay::LayoutView *view) const
GridNetPluginDeclaration::create_plugin (db::Manager *, Dispatcher *, lay::LayoutView *view) const
{
return new lay::GridNet (view);
}
@@ -134,7 +134,7 @@ GridNetConfigPage::~GridNetConfigPage ()
}
void
GridNetConfigPage::setup (lay::PluginRoot *root)
GridNetConfigPage::setup (lay::Dispatcher *root)
{
std::string value;
@@ -176,7 +176,7 @@ GridNetConfigPage::setup (lay::PluginRoot *root)
}
void
GridNetConfigPage::commit (lay::PluginRoot *root)
GridNetConfigPage::commit (lay::Dispatcher *root)
{
root->config_set (cfg_grid_visible, mp_ui->grid_group->isChecked ());
root->config_set (cfg_grid_show_ruler, mp_ui->show_ruler->isChecked ());
+3 -3
View File
@@ -44,7 +44,7 @@ class GridNetPluginDeclaration
public:
virtual void get_options (std::vector < std::pair<std::string, std::string> > &options) const;
virtual lay::ConfigPage *config_page (QWidget *parent, std::string &title) const;
virtual lay::Plugin *create_plugin (db::Manager *, lay::PluginRoot *, lay::LayoutView *view) const;
virtual lay::Plugin *create_plugin (db::Manager *, lay::Dispatcher *, lay::LayoutView *view) const;
};
class GridNetConfigPage
@@ -56,8 +56,8 @@ public:
GridNetConfigPage (QWidget *parent);
~GridNetConfigPage ();
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
private:
Ui::GridNetConfigPage *mp_ui;
@@ -46,7 +46,6 @@
#include "layCellTreeModel.h"
#include "layLayoutView.h"
#include "layAbstractMenu.h"
#include "layAbstractMenuProvider.h"
#include "layDialogs.h"
#include "tlExceptions.h"
#include "laybasicConfig.h"
@@ -194,52 +193,6 @@ HCPCellTreeWidget::mouseReleaseEvent (QMouseEvent *event)
const int max_cellviews_in_split_mode = 5;
void
HierarchyControlPanel::init_menu (lay::AbstractMenu &menu)
{
MenuLayoutEntry sorting_menu [] = {
MenuLayoutEntry ("by_name", tl::to_string (QObject::tr ("By Name")), std::make_pair (cfg_cell_list_sorting, "?by-name")),
MenuLayoutEntry ("by_area", tl::to_string (QObject::tr ("By Area - Small To Large")), std::make_pair (cfg_cell_list_sorting, "?by-area")),
MenuLayoutEntry ("by_area", tl::to_string (QObject::tr ("By Area - Large To Small")), std::make_pair (cfg_cell_list_sorting, "?by-area-reverse")),
MenuLayoutEntry::last ()
};
MenuLayoutEntry context_menu [] = {
MenuLayoutEntry ("flat_mode", tl::to_string (QObject::tr ("Flat Cell List")), std::make_pair (cfg_flat_cell_list, "?")),
MenuLayoutEntry ("split_mode", tl::to_string (QObject::tr ("Split Mode")), std::make_pair (cfg_split_cell_list, "?")),
MenuLayoutEntry ("sorting", tl::to_string (QObject::tr ("Sorting")), sorting_menu),
MenuLayoutEntry::separator ("operations_group"),
MenuLayoutEntry ("new_cell:edit:edit_mode", tl::to_string (QObject::tr ("New Cell")), SLOT (cm_new_cell ())),
MenuLayoutEntry ("delete_cell:edit:edit_mode", tl::to_string (QObject::tr ("Delete Cell")), SLOT (cm_cell_delete ())),
MenuLayoutEntry ("rename_cell:edit:edit_mode", tl::to_string (QObject::tr ("Rename Cell")), SLOT (cm_cell_rename ())),
MenuLayoutEntry ("replace_cell:edit:edit_mode", tl::to_string (QObject::tr ("Replace Cell")), SLOT (cm_cell_replace ())),
MenuLayoutEntry ("flatten_cell:edit:edit_mode", tl::to_string (QObject::tr ("Flatten Cell")), SLOT (cm_cell_flatten ())),
MenuLayoutEntry ("cell_user_properties", tl::to_string (QObject::tr ("User Properties")), SLOT (cm_cell_user_properties ())),
MenuLayoutEntry::separator ("clipboard_group:edit_mode"),
MenuLayoutEntry ("copy:edit_mode", tl::to_string (QObject::tr ("Copy")), SLOT (cm_cell_copy ())),
MenuLayoutEntry ("cut:edit_mode", tl::to_string (QObject::tr ("Cut")), SLOT (cm_cell_cut ())),
MenuLayoutEntry ("paste:edit_mode", tl::to_string (QObject::tr ("Paste")), SLOT (cm_cell_paste ())),
MenuLayoutEntry::separator ("select_group"),
MenuLayoutEntry ("show_as_top", tl::to_string (QObject::tr ("Show As New Top")), SLOT (cm_cell_select ())),
MenuLayoutEntry::separator ("visibility_group"),
MenuLayoutEntry ("hide_cell", tl::to_string (QObject::tr ("Hide")), SLOT (cm_cell_hide ())),
MenuLayoutEntry ("show_cell", tl::to_string (QObject::tr ("Show")), SLOT (cm_cell_show ())),
MenuLayoutEntry ("show_all", tl::to_string (QObject::tr ("Show All")), SLOT (cm_cell_show_all ())),
MenuLayoutEntry::separator ("utils_group"),
MenuLayoutEntry ("open_current", tl::to_string (QObject::tr ("Where Am I?")), SLOT (cm_open_current_cell ())),
MenuLayoutEntry::separator ("file_group"),
MenuLayoutEntry ("save_cell_as:hide_vo", tl::to_string (QObject::tr ("Save Selected Cells As")), SLOT (cm_save_current_cell_as ())),
MenuLayoutEntry::last ()
};
MenuLayoutEntry main_menu [] = {
MenuLayoutEntry ("@hcp_context_menu", "", context_menu),
MenuLayoutEntry::last ()
};
menu.init (main_menu);
}
HierarchyControlPanel::HierarchyControlPanel (lay::LayoutView *view, QWidget *parent, const char *name)
: QFrame (parent),
m_enable_cb (true),
@@ -370,12 +323,10 @@ HierarchyControlPanel::event (QEvent *e)
void
HierarchyControlPanel::context_menu (const QPoint &p)
{
tl_assert (lay::AbstractMenuProvider::instance () != 0);
QTreeView *cell_list = dynamic_cast<QTreeView *> (sender ());
if (cell_list) {
set_active_celltree_from_sender ();
QMenu *ctx_menu = lay::AbstractMenuProvider::instance ()->menu ()->detached_menu ("hcp_context_menu");
QMenu *ctx_menu = mp_view->menu ()->detached_menu ("hcp_context_menu");
ctx_menu->exec (cell_list->mapToGlobal (p));
}
}
@@ -632,14 +583,14 @@ HierarchyControlPanel::double_clicked (const QModelIndex &index)
BEGIN_PROTECTED
if (index.isValid ()) {
set_active_celltree_from_sender ();
mp_view->manager ()->transaction (tl::to_string (QObject::tr ("Show or hide cell")));
mp_view->transaction (tl::to_string (QObject::tr ("Show or hide cell")));
CellTreeItem *item = (CellTreeItem *) index.internalPointer ();
if (mp_view->is_cell_hidden (item->cell_or_pcell_index (), m_active_index)) {
mp_view->show_cell (item->cell_or_pcell_index (), m_active_index);
} else {
mp_view->hide_cell (item->cell_or_pcell_index (), m_active_index);
}
mp_view->manager ()->commit ();
mp_view->commit ();
}
END_PROTECTED
}
@@ -1085,14 +1036,14 @@ HierarchyControlPanel::cut ()
}
}
mp_view->manager ()->transaction (tl::to_string (QObject::tr ("Cut Cells")));
mp_view->transaction (tl::to_string (QObject::tr ("Cut Cells")));
if (cut_mode == 1) {
layout.prune_cells (cells_to_delete);
} else {
layout.delete_cells (cells_to_delete);
}
layout.cleanup ();
mp_view->manager ()->commit ();
mp_view->commit ();
// If one of the cells in the path was deleted, establish a valid path
@@ -1202,4 +1153,57 @@ HierarchyControlPanel::paste ()
}
}
// ------------------------------------------------------------
// Declaration of the "plugin" for the menu entries
class HierarchyControlPanelPluginDeclaration
: public lay::PluginDeclaration
{
public:
virtual void get_menu_entries (std::vector<lay::MenuEntry> &menu_entries) const
{
std::string at;
at = ".end";
menu_entries.push_back (lay::submenu ("@hcp_context_menu", at, std::string ()));
at = "@hcp_context_menu.end";
menu_entries.push_back (lay::config_menu_item ("flat_mode", at, tl::to_string (QObject::tr ("Flat Cell List")), cfg_flat_cell_list, "?")),
menu_entries.push_back (lay::config_menu_item ("split_mode", at, tl::to_string (QObject::tr ("Split Mode")), cfg_split_cell_list, "?")),
menu_entries.push_back (lay::submenu ("sorting", at, tl::to_string (QObject::tr ("Sorting"))));
{
std::string at = "@hcp_context_menu.sorting.end";
menu_entries.push_back (lay::config_menu_item ("by_name", at, tl::to_string (QObject::tr ("By Name")), cfg_cell_list_sorting, "?by-name"));
menu_entries.push_back (lay::config_menu_item ("by_area", at, tl::to_string (QObject::tr ("By Area - Small To Large")), cfg_cell_list_sorting, "?by-area"));
menu_entries.push_back (lay::config_menu_item ("by_area_reverse", at, tl::to_string (QObject::tr ("By Area - Large To Small")), cfg_cell_list_sorting, "?by-area-reverse"));
}
menu_entries.push_back (lay::separator ("operations_group", at));
menu_entries.push_back (lay::menu_item ("cm_new_cell", "new_cell:edit:edit_mode", at, tl::to_string (QObject::tr ("New Cell"))));
menu_entries.push_back (lay::menu_item ("cm_cell_delete", "delete_cell:edit:edit_mode", at, tl::to_string (QObject::tr ("Delete Cell"))));
menu_entries.push_back (lay::menu_item ("cm_cell_rename", "rename_cell:edit:edit_mode", at, tl::to_string (QObject::tr ("Rename Cell"))));
menu_entries.push_back (lay::menu_item ("cm_cell_replace", "replace_cell:edit:edit_mode", at, tl::to_string (QObject::tr ("Replace Cell"))));
menu_entries.push_back (lay::menu_item ("cm_cell_flatten", "flatten_cell:edit:edit_mode", at, tl::to_string (QObject::tr ("Flatten Cell"))));
menu_entries.push_back (lay::menu_item ("cm_cell_user_properties", "cell_user_properties", at, tl::to_string (QObject::tr ("User Properties"))));
menu_entries.push_back (lay::separator ("clipboard_group:edit_mode", at));
menu_entries.push_back (lay::menu_item ("cm_cell_copy", "copy:edit_mode", at, tl::to_string (QObject::tr ("Copy"))));
menu_entries.push_back (lay::menu_item ("cm_cell_cut", "cut:edit_mode", at, tl::to_string (QObject::tr ("Cut"))));
menu_entries.push_back (lay::menu_item ("cm_cell_paste", "paste:edit_mode", at, tl::to_string (QObject::tr ("Paste"))));
menu_entries.push_back (lay::separator ("select_group", at));
menu_entries.push_back (lay::menu_item ("cm_cell_select", "show_as_top", at, tl::to_string (QObject::tr ("Show As New Top"))));
menu_entries.push_back (lay::separator ("visibility_group", at));
menu_entries.push_back (lay::menu_item ("cm_cell_hide", "hide_cell", at, tl::to_string (QObject::tr ("Hide"))));
menu_entries.push_back (lay::menu_item ("cm_cell_show", "show_cell", at, tl::to_string (QObject::tr ("Show"))));
menu_entries.push_back (lay::menu_item ("cm_cell_show_all", "show_all", at, tl::to_string (QObject::tr ("Show All"))));
menu_entries.push_back (lay::separator ("utils_group", at));
menu_entries.push_back (lay::menu_item ("cm_open_current_cell", "open_current", at, tl::to_string (QObject::tr ("Where Am I?"))));
menu_entries.push_back (lay::separator ("file_group", at));
menu_entries.push_back (lay::menu_item ("cm_save_current_cell_as", "save_cell_as:hide_vo", at, tl::to_string (QObject::tr ("Save Selected Cells As"))));
}
};
static tl::RegisteredClass<lay::PluginDeclaration> config_decl (new HierarchyControlPanelPluginDeclaration (), -8, "HierarchyControlPanelPlugin");
} // namespace lay
@@ -116,11 +116,6 @@ public:
*/
~HierarchyControlPanel ();
/**
* @brief Perform the cell control panel's initialisations on the main menu
*/
static void init_menu (lay::AbstractMenu &menu);
/**
* @brief The sizeHint implementation for Qt layout management
*/
+169 -160
View File
@@ -33,7 +33,6 @@
#include "laybasicConfig.h"
#include "layDialogs.h"
#include "layLayoutCanvas.h"
#include "layAbstractMenuProvider.h"
#include "layAbstractMenu.h"
#include "tlExceptions.h"
#include "tlInternational.h"
@@ -229,86 +228,6 @@ LCPTreeWidget::expand_all ()
// --------------------------------------------------------------------
// LayerControlPanel implementation
void
LayerControlPanel::init_menu (lay::AbstractMenu &menu)
{
MenuLayoutEntry sort_by_menu [] = {
MenuLayoutEntry ("sort_ild", tl::to_string (QObject::tr ("Layout Index, Layer And Datatype")), SLOT (cm_lv_sort_by_ild ())),
MenuLayoutEntry ("sort_idl", tl::to_string (QObject::tr ("Layout Index, Datatype And Layer")), SLOT (cm_lv_sort_by_idl ())),
MenuLayoutEntry ("sort_ldi", tl::to_string (QObject::tr ("Layer, Datatype And Layout Index")), SLOT (cm_lv_sort_by_ldi ())),
MenuLayoutEntry ("sort_dli", tl::to_string (QObject::tr ("Datatype, Layer And Layout Index")), SLOT (cm_lv_sort_by_dli ())),
MenuLayoutEntry ("sort_name", tl::to_string (QObject::tr ("Name")), SLOT (cm_lv_sort_by_name ())),
MenuLayoutEntry::last ()
};
MenuLayoutEntry regroup_menu [] = {
MenuLayoutEntry ("grp_i", tl::to_string (QObject::tr ("By Layout Index")), SLOT (cm_lv_regroup_by_index ())),
MenuLayoutEntry ("grp_d", tl::to_string (QObject::tr ("By Datatype")), SLOT (cm_lv_regroup_by_datatype ())),
MenuLayoutEntry ("grp_l", tl::to_string (QObject::tr ("By Layer")), SLOT (cm_lv_regroup_by_layer ())),
MenuLayoutEntry ("flatten", tl::to_string (QObject::tr ("Flatten")), SLOT (cm_lv_regroup_flatten ())),
MenuLayoutEntry::last ()
};
MenuLayoutEntry tab_menu [] = {
MenuLayoutEntry ("new_tab", tl::to_string (QObject::tr ("New Tab")), SLOT (cm_lv_new_tab ())),
MenuLayoutEntry ("remove_tab", tl::to_string (QObject::tr ("Remove Tab")), SLOT (cm_lv_remove_tab ())),
MenuLayoutEntry ("rename_tab", tl::to_string (QObject::tr ("Rename Tab")), SLOT (cm_lv_rename_tab ())),
MenuLayoutEntry::last ()
};
MenuLayoutEntry context_menu [] = {
MenuLayoutEntry ("select_all", tl::to_string (QObject::tr ("Select All")), SLOT (cm_lv_select_all ())),
// It is not sure, whether "expandAll" destabilizes the tree widget:
// MenuLayoutEntry ("expand_all", tl::to_string (QObject::tr ("Expand All")), SLOT (cm_lv_expand_all ())),
MenuLayoutEntry::separator ("tab_group"),
MenuLayoutEntry ("tab_menu", tl::to_string (QObject::tr ("Tabs")), tab_menu),
MenuLayoutEntry::separator ("visibility_group"),
MenuLayoutEntry ("hide", tl::to_string (QObject::tr ("Hide")), SLOT (cm_lv_hide ())),
MenuLayoutEntry ("hide_all", tl::to_string (QObject::tr ("Hide All")), SLOT (cm_lv_hide_all ())),
MenuLayoutEntry ("show", tl::to_string (QObject::tr ("Show")), SLOT (cm_lv_show ())),
MenuLayoutEntry ("show_all", tl::to_string (QObject::tr ("Show All")), SLOT (cm_lv_show_all ())),
MenuLayoutEntry ("show_only", tl::to_string (QObject::tr ("Show Only Selected")), SLOT (cm_lv_show_only ())),
MenuLayoutEntry ("valid", tl::to_string (QObject::tr ("Make Valid")), SLOT (cm_lv_make_valid ())),
MenuLayoutEntry ("invvalid", tl::to_string (QObject::tr ("Make Invalid")), SLOT (cm_lv_make_invalid ())),
MenuLayoutEntry ("rename", tl::to_string (QObject::tr ("Rename")), SLOT (cm_lv_rename ())),
MenuLayoutEntry::separator ("options_group"),
MenuLayoutEntry ("hide_empty_layers", tl::to_string (QObject::tr ("Hide Empty Layers")), std::make_pair (cfg_hide_empty_layers, "?")),
MenuLayoutEntry ("test_shapes_in_view", tl::to_string (QObject::tr ("Test For Shapes In View")), std::make_pair (cfg_test_shapes_in_view, "?")),
MenuLayoutEntry::separator ("source_group"),
MenuLayoutEntry ("select_source", tl::to_string (QObject::tr ("Select Source")), SLOT (cm_lv_source ())),
MenuLayoutEntry::separator ("sort_group"),
MenuLayoutEntry ("sort_menu", tl::to_string (QObject::tr ("Sort By")), sort_by_menu),
MenuLayoutEntry::separator ("view_group"),
MenuLayoutEntry ("del", tl::to_string (QObject::tr ("Delete Layer Entry")), SLOT (cm_lv_delete ())),
MenuLayoutEntry ("insert", tl::to_string (QObject::tr ("Insert Layer Entry")), SLOT (cm_lv_insert ())),
MenuLayoutEntry ("add_others", tl::to_string (QObject::tr ("Add Other Layer Entries")), SLOT (cm_lv_add_missing ())),
MenuLayoutEntry ("clean_up", tl::to_string (QObject::tr ("Clean Up Layer Entries")), SLOT (cm_lv_remove_unused ())),
MenuLayoutEntry::separator ("grouping_group"),
MenuLayoutEntry ("group", tl::to_string (QObject::tr ("Group")), SLOT (cm_lv_group ())),
MenuLayoutEntry ("ungroup", tl::to_string (QObject::tr ("Ungroup")), SLOT (cm_lv_ungroup ())),
MenuLayoutEntry ("regroup_menu", tl::to_string (QObject::tr ("Regroup Layer Entries")), regroup_menu),
MenuLayoutEntry::separator ("copy_paste_group"),
MenuLayoutEntry ("copy", tl::to_string (QObject::tr ("Copy")), SLOT (cm_lv_copy ())),
MenuLayoutEntry ("cut", tl::to_string (QObject::tr ("Cut")), SLOT (cm_lv_cut ())),
MenuLayoutEntry ("paste", tl::to_string (QObject::tr ("Paste")), SLOT (cm_lv_paste ())),
MenuLayoutEntry::last ()
};
MenuLayoutEntry lcp_context_menu [] = {
MenuLayoutEntry ("@lcp_context_menu", "", context_menu),
MenuLayoutEntry::last ()
};
menu.init (lcp_context_menu);
MenuLayoutEntry lcp_tab_context_menu [] = {
MenuLayoutEntry ("@lcp_tabs_context_menu", "", tab_menu),
MenuLayoutEntry::last ()
};
menu.init (lcp_tab_context_menu);
}
LayerControlPanel::LayerControlPanel (lay::LayoutView *view, db::Manager *manager, QWidget *parent, const char *name)
: QFrame (parent),
db::Object (manager),
@@ -496,7 +415,9 @@ void
LayerControlPanel::recover ()
{
cancel_updates ();
manager ()->clear ();
if (manager ()) {
manager ()->clear ();
}
}
void
@@ -504,13 +425,13 @@ LayerControlPanel::cm_delete ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Delete layer views")));
transaction (tl::to_string (QObject::tr ("Delete layer views")));
do_delete ();
manager ()->commit ();
commit ();
END_PROTECTED_CLEANUP {
recover ();
manager ()->commit ();
commit ();
}
}
@@ -535,7 +456,7 @@ LayerControlPanel::do_delete ()
mp_view->delete_layer (*s);
}
if (manager ()->transacting ()) {
if (transacting ()) {
manager ()->queue (this, new LayerSelectionClearOp ());
}
@@ -553,7 +474,7 @@ LayerControlPanel::cm_remove_unused ()
begin_updates ();
manager ()->transaction (tl::to_string (QObject::tr ("Clean up views")));
transaction (tl::to_string (QObject::tr ("Clean up views")));
bool any_deleted;
do {
@@ -577,7 +498,7 @@ LayerControlPanel::cm_remove_unused ()
} while (any_deleted);
manager ()->commit ();
commit ();
end_updates ();
@@ -592,9 +513,9 @@ LayerControlPanel::cm_add_missing ()
BEGIN_PROTECTED_CLEANUP
begin_updates ();
manager ()->transaction (tl::to_string (QObject::tr ("Add other views")));
transaction (tl::to_string (QObject::tr ("Add other views")));
mp_view->add_missing_layers ();
manager ()->commit ();
commit ();
end_updates ();
END_PROTECTED_CLEANUP { recover (); }
@@ -618,18 +539,18 @@ LayerControlPanel::cm_insert ()
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Insert views")));
transaction (tl::to_string (QObject::tr ("Insert views")));
props.set_source (tl::to_string (n));
mp_view->init_layer_properties (props);
const LayerPropertiesNode &lp = mp_view->insert_layer (sel, props);
if (manager ()->transacting ()) {
if (transacting ()) {
manager ()->queue (this, new LayerSelectionClearOp ());
}
mp_layer_list->set_current (sel);
manager ()->commit ();
commit ();
emit order_changed ();
@@ -656,7 +577,7 @@ LayerControlPanel::cm_group ()
begin_updates ();
manager ()->transaction (tl::to_string (QObject::tr ("Group layer views")));
transaction (tl::to_string (QObject::tr ("Group layer views")));
lay::LayerPropertiesNode node;
for (std::vector<lay::LayerPropertiesConstIterator>::const_iterator s = sel.begin (); s != sel.end (); ++s) {
@@ -678,11 +599,11 @@ LayerControlPanel::cm_group ()
mp_view->insert_layer (ins_pos, node);
if (manager ()->transacting ()) {
if (transacting ()) {
manager ()->queue (this, new LayerSelectionClearOp ());
}
manager ()->commit ();
commit ();
end_updates ();
@@ -705,7 +626,7 @@ LayerControlPanel::cm_ungroup ()
begin_updates ();
manager ()->transaction (tl::to_string (QObject::tr ("Ungroup layer views")));
transaction (tl::to_string (QObject::tr ("Ungroup layer views")));
lay::LayerPropertiesNode node = *sel;
@@ -720,12 +641,12 @@ LayerControlPanel::cm_ungroup ()
mp_view->insert_layer (ins_pos, c->flat ());
}
if (manager ()->transacting ()) {
if (transacting ()) {
manager ()->queue (this, new LayerSelectionClearOp ());
}
set_selection (std::vector<lay::LayerPropertiesConstIterator> ()); // clear selection
manager ()->commit ();
commit ();
end_updates ();
@@ -870,7 +791,7 @@ LayerControlPanel::paste ()
}
}
if (manager ()->transacting ()) {
if (transacting ()) {
manager ()->queue (this, new LayerSelectionClearOp ());
}
@@ -904,9 +825,9 @@ LayerControlPanel::cm_source ()
props.set_source (tl::to_string (n));
manager ()->transaction (tl::to_string (QObject::tr ("Select source")));
transaction (tl::to_string (QObject::tr ("Select source")));
mp_view->set_properties (sel, props);
manager ()->commit ();
commit ();
END_PROTECTED_CLEANUP { recover (); }
@@ -937,9 +858,9 @@ LayerControlPanel::cm_rename ()
props.set_name (tl::to_string (n));
manager ()->transaction (tl::to_string (QObject::tr ("Rename layer")));
transaction (tl::to_string (QObject::tr ("Rename layer")));
mp_view->set_properties (sel, props);
manager ()->commit ();
commit ();
END_PROTECTED_CLEANUP { recover (); }
@@ -953,7 +874,7 @@ LayerControlPanel::cm_show_only ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Show selected layers")));
transaction (tl::to_string (QObject::tr ("Show selected layers")));
std::vector<lay::LayerPropertiesConstIterator> sel = mp_view->selected_layers ();
std::set<lay::LayerPropertiesConstIterator> sel_set (sel.begin (), sel.end ());
@@ -996,7 +917,7 @@ LayerControlPanel::cm_show_only ()
}
}
manager ()->commit ();
commit ();
END_PROTECTED_CLEANUP { recover (); }
}
@@ -1006,7 +927,7 @@ LayerControlPanel::cm_show ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Show layer")));
transaction (tl::to_string (QObject::tr ("Show layer")));
std::vector<lay::LayerPropertiesConstIterator> sel = mp_view->selected_layers ();
@@ -1016,7 +937,7 @@ LayerControlPanel::cm_show ()
mp_view->set_properties (*l, props);
}
manager ()->commit ();
commit ();
END_PROTECTED_CLEANUP { recover (); }
}
@@ -1026,7 +947,7 @@ LayerControlPanel::cm_show_all ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Show all layers")));
transaction (tl::to_string (QObject::tr ("Show all layers")));
for (lay::LayerPropertiesConstIterator l = mp_view->begin_layers (); ! l.at_end (); ++l) {
lay::LayerProperties props (*l);
@@ -1034,7 +955,7 @@ LayerControlPanel::cm_show_all ()
mp_view->set_properties (l, props);
}
manager ()->commit ();
commit ();
END_PROTECTED_CLEANUP { recover (); }
}
@@ -1044,7 +965,7 @@ LayerControlPanel::cm_rename_tab ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Rename layer tab")));
transaction (tl::to_string (QObject::tr ("Rename layer tab")));
bool ok = false;
QString n = QInputDialog::getText (this,
@@ -1060,7 +981,7 @@ LayerControlPanel::cm_rename_tab ()
end_updates ();
}
manager ()->commit ();
commit ();
END_PROTECTED_CLEANUP { recover (); }
}
@@ -1070,7 +991,7 @@ LayerControlPanel::cm_remove_tab ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Remove layer tab")));
transaction (tl::to_string (QObject::tr ("Remove layer tab")));
if (mp_view->layer_lists () == 1) {
throw tl::Exception (tl::to_string (QObject::tr ("Cannot remove last layer tab")));
@@ -1080,7 +1001,7 @@ LayerControlPanel::cm_remove_tab ()
mp_view->delete_layer_list (mp_view->current_layer_list ());
end_updates ();
manager ()->commit ();
commit ();
emit order_changed ();
@@ -1092,13 +1013,13 @@ LayerControlPanel::cm_new_tab ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("New layer tab")));
transaction (tl::to_string (QObject::tr ("New layer tab")));
begin_updates ();
mp_view->insert_layer_list (mp_view->current_layer_list () + 1, mp_view->get_properties ());
end_updates ();
manager ()->commit ();
commit ();
emit order_changed ();
@@ -1110,7 +1031,7 @@ LayerControlPanel::cm_make_valid ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Make layer valid")));
transaction (tl::to_string (QObject::tr ("Make layer valid")));
std::vector<lay::LayerPropertiesConstIterator> sel = mp_view->selected_layers ();
@@ -1120,7 +1041,7 @@ LayerControlPanel::cm_make_valid ()
mp_view->set_properties (*l, props);
}
manager ()->commit ();
commit ();
END_PROTECTED_CLEANUP { recover (); }
}
@@ -1130,7 +1051,7 @@ LayerControlPanel::cm_make_invalid ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Make layer invalid")));
transaction (tl::to_string (QObject::tr ("Make layer invalid")));
std::vector<lay::LayerPropertiesConstIterator> sel = mp_view->selected_layers ();
@@ -1140,7 +1061,7 @@ LayerControlPanel::cm_make_invalid ()
mp_view->set_properties (*l, props);
}
manager ()->commit ();
commit ();
END_PROTECTED_CLEANUP { recover (); }
}
@@ -1150,7 +1071,7 @@ LayerControlPanel::cm_hide ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Hide layer")));
transaction (tl::to_string (QObject::tr ("Hide layer")));
std::vector<lay::LayerPropertiesConstIterator> sel = mp_view->selected_layers ();
@@ -1160,7 +1081,7 @@ LayerControlPanel::cm_hide ()
mp_view->set_properties (*l, props);
}
manager ()->commit ();
commit ();
END_PROTECTED_CLEANUP { recover (); }
}
@@ -1170,7 +1091,7 @@ LayerControlPanel::cm_hide_all ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Hide all layers")));
transaction (tl::to_string (QObject::tr ("Hide all layers")));
for (lay::LayerPropertiesConstIterator l = mp_view->begin_layers (); ! l.at_end (); ++l) {
if (l.parent ().is_null ()) {
@@ -1182,7 +1103,7 @@ LayerControlPanel::cm_hide_all ()
}
}
manager ()->commit ();
commit ();
END_PROTECTED_CLEANUP { recover (); }
}
@@ -1214,7 +1135,7 @@ LayerControlPanel::set_selection (const std::vector<lay::LayerPropertiesConstIte
mp_layer_list->set_selection (new_sel);
// :TODO: save selection for undo? Currently we just clear it.
if (manager ()->transacting ()) {
if (transacting ()) {
manager ()->queue (this, new LayerSelectionClearOp ());
}
@@ -1304,9 +1225,9 @@ LayerControlPanel::cm_regroup_flatten ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Flatten layers")));
transaction (tl::to_string (QObject::tr ("Flatten layers")));
regroup_layers (RegroupFlatten);
manager ()->commit ();
commit ();
emit order_changed ();
@@ -1318,9 +1239,9 @@ LayerControlPanel::cm_regroup_by_index ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Regroup layers")));
transaction (tl::to_string (QObject::tr ("Regroup layers")));
regroup_layers (RegroupByIndex);
manager ()->commit ();
commit ();
emit order_changed ();
@@ -1332,9 +1253,9 @@ LayerControlPanel::cm_regroup_by_datatype ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Regroup layers")));
transaction (tl::to_string (QObject::tr ("Regroup layers")));
regroup_layers (RegroupByDatatype);
manager ()->commit ();
commit ();
emit order_changed ();
@@ -1346,9 +1267,9 @@ LayerControlPanel::cm_regroup_by_layer ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Regroup layers")));
transaction (tl::to_string (QObject::tr ("Regroup layers")));
regroup_layers (RegroupByLayer);
manager ()->commit ();
commit ();
emit order_changed ();
@@ -1360,9 +1281,9 @@ LayerControlPanel::cm_sort_by_name ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Sort layers")));
transaction (tl::to_string (QObject::tr ("Sort layers")));
sort_layers (ByName);
manager ()->commit ();
commit ();
emit order_changed ();
@@ -1374,9 +1295,9 @@ LayerControlPanel::cm_sort_by_ild ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Sort layers")));
transaction (tl::to_string (QObject::tr ("Sort layers")));
sort_layers (ByIndexLayerDatatype);
manager ()->commit ();
commit ();
emit order_changed ();
@@ -1388,9 +1309,9 @@ LayerControlPanel::cm_sort_by_idl ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Sort layers")));
transaction (tl::to_string (QObject::tr ("Sort layers")));
sort_layers (ByIndexDatatypeLayer);
manager ()->commit ();
commit ();
emit order_changed ();
@@ -1402,9 +1323,9 @@ LayerControlPanel::cm_sort_by_ldi ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Sort layers")));
transaction (tl::to_string (QObject::tr ("Sort layers")));
sort_layers (ByLayerDatatypeIndex);
manager ()->commit ();
commit ();
emit order_changed ();
@@ -1416,9 +1337,9 @@ LayerControlPanel::cm_sort_by_dli ()
{
BEGIN_PROTECTED_CLEANUP
manager ()->transaction (tl::to_string (QObject::tr ("Sort layers")));
transaction (tl::to_string (QObject::tr ("Sort layers")));
sort_layers (ByDatatypeLayerIndex);
manager ()->commit ();
commit ();
emit order_changed ();
@@ -1684,9 +1605,7 @@ LayerControlPanel::cm_expand_all ()
void
LayerControlPanel::tab_context_menu (const QPoint &p)
{
tl_assert (lay::AbstractMenuProvider::instance () != 0);
QMenu *ctx_menu = lay::AbstractMenuProvider::instance ()->menu ()->detached_menu ("lcp_tabs_context_menu");
QMenu *ctx_menu = mp_view->menu ()->detached_menu ("lcp_tabs_context_menu");
if (ctx_menu) {
ctx_menu->exec (mp_tab_bar->mapToGlobal (p));
}
@@ -1695,9 +1614,7 @@ LayerControlPanel::tab_context_menu (const QPoint &p)
void
LayerControlPanel::context_menu (const QPoint &p)
{
tl_assert (lay::AbstractMenuProvider::instance () != 0);
QMenu *ctx_menu = lay::AbstractMenuProvider::instance ()->menu ()->detached_menu ("lcp_context_menu");
QMenu *ctx_menu = mp_view->menu ()->detached_menu ("lcp_context_menu");
if (ctx_menu) {
ctx_menu->exec (mp_layer_list->mapToGlobal (p));
}
@@ -1725,14 +1642,14 @@ LayerControlPanel::double_clicked (const QModelIndex &index, Qt::KeyboardModifie
props.set_visible (! props.visible (false));
if (props.visible (false)) {
manager ()->transaction (tl::to_string (QObject::tr ("Show layer")));
transaction (tl::to_string (QObject::tr ("Show layer")));
} else {
manager ()->transaction (tl::to_string (QObject::tr ("Hide layer")));
transaction (tl::to_string (QObject::tr ("Hide layer")));
}
mp_view->set_properties (item, props);
manager ()->commit ();
commit ();
}
@@ -2213,9 +2130,9 @@ LayerControlPanel::up_clicked ()
BEGIN_PROTECTED_CLEANUP
if (mp_view) {
mp_view->manager ()->transaction (tl::to_string (QObject::tr ("Move up")));
mp_view->transaction (tl::to_string (QObject::tr ("Move up")));
do_move (1 /*up*/);
mp_view->manager ()->commit ();
mp_view->commit ();
}
END_PROTECTED_CLEANUP { recover (); }
@@ -2227,9 +2144,9 @@ LayerControlPanel::down_clicked ()
BEGIN_PROTECTED_CLEANUP
if (mp_view) {
mp_view->manager ()->transaction (tl::to_string (QObject::tr ("Move down")));
mp_view->transaction (tl::to_string (QObject::tr ("Move down")));
do_move (0 /*down*/);
mp_view->manager ()->commit ();
mp_view->commit ();
}
END_PROTECTED_CLEANUP { recover (); }
@@ -2241,9 +2158,9 @@ LayerControlPanel::downdown_clicked ()
BEGIN_PROTECTED_CLEANUP
if (mp_view) {
mp_view->manager ()->transaction (tl::to_string (QObject::tr ("Move fully down")));
mp_view->transaction (tl::to_string (QObject::tr ("Move fully down")));
do_move (2 /*downdown*/);
mp_view->manager ()->commit ();
mp_view->commit ();
}
END_PROTECTED_CLEANUP { recover (); }
@@ -2255,9 +2172,9 @@ LayerControlPanel::upup_clicked ()
BEGIN_PROTECTED_CLEANUP
if (mp_view) {
mp_view->manager ()->transaction (tl::to_string (QObject::tr ("Move fully up")));
mp_view->transaction (tl::to_string (QObject::tr ("Move fully up")));
do_move (3 /*upup*/);
mp_view->manager ()->commit ();
mp_view->commit ();
}
END_PROTECTED_CLEANUP { recover (); }
@@ -2393,4 +2310,96 @@ LayerControlPanel::do_move (int mode)
mp_view->set_selected_layers (new_sel);
}
// ------------------------------------------------------------
// Declaration of the "plugin" for the menu entries
class LayerControlPanelPluginDeclaration
: public lay::PluginDeclaration
{
public:
virtual void get_menu_entries (std::vector<lay::MenuEntry> &menu_entries) const
{
std::string at;
at = ".end";
menu_entries.push_back (lay::submenu ("@lcp_context_menu", at, std::string ()));
at = "@lcp_context_menu.end";
menu_entries.push_back (lay::menu_item ("cm_lv_select_all", "select_all", at, tl::to_string (QObject::tr ("Select All"))));
// It is not sure, whether "expandAll" destabilizes the tree widget:
// menu_entries.push_back (lay::menu_item ("cm_lv_expand_all", "expand_all", at, tl::to_string (QObject::tr ("Expand All")));
menu_entries.push_back (lay::separator ("tab_group", at));
menu_entries.push_back (lay::submenu ("tab_menu", at, tl::to_string (QObject::tr ("Tabs"))));
{
std::string at = "@lcp_context_menu.tab_menu.end";
menu_entries.push_back (lay::menu_item ("cm_lv_new_tab", "new_tab", at, tl::to_string (QObject::tr ("New Tab"))));
menu_entries.push_back (lay::menu_item ("cm_lv_remove_tab", "remove_tab", at, tl::to_string (QObject::tr ("Remove Tab"))));
menu_entries.push_back (lay::menu_item ("cm_lv_rename_tab", "rename_tab", at, tl::to_string (QObject::tr ("Rename Tab"))));
}
menu_entries.push_back (lay::separator ("visibility_group", at));
menu_entries.push_back (lay::menu_item ("cm_lv_hide", "hide", at, tl::to_string (QObject::tr ("Hide"))));
menu_entries.push_back (lay::menu_item ("cm_lv_hide_all", "hide_all", at, tl::to_string (QObject::tr ("Hide All"))));
menu_entries.push_back (lay::menu_item ("cm_lv_show", "show", at, tl::to_string (QObject::tr ("Show"))));
menu_entries.push_back (lay::menu_item ("cm_lv_show_all", "show_all", at, tl::to_string (QObject::tr ("Show All"))));
menu_entries.push_back (lay::menu_item ("cm_lv_show_only", "show_only", at, tl::to_string (QObject::tr ("Show Only Selected"))));
menu_entries.push_back (lay::menu_item ("cm_lv_make_valid", "valid", at, tl::to_string (QObject::tr ("Make Valid"))));
menu_entries.push_back (lay::menu_item ("cm_lv_make_invalid", "invvalid", at, tl::to_string (QObject::tr ("Make Invalid"))));
menu_entries.push_back (lay::menu_item ("cm_lv_rename", "rename", at, tl::to_string (QObject::tr ("Rename"))));
menu_entries.push_back (lay::separator ("options_group", at));
menu_entries.push_back (lay::config_menu_item ("hide_empty_layers", at, tl::to_string (QObject::tr ("Hide Empty Layers")), cfg_hide_empty_layers, "?"));
menu_entries.push_back (lay::config_menu_item ("test_shapes_in_view", at, tl::to_string (QObject::tr ("Test For Shapes In View")), cfg_test_shapes_in_view, "?"));
menu_entries.push_back (lay::separator ("source_group", at));
menu_entries.push_back (lay::menu_item ("cm_lv_source", "select_source", at, tl::to_string (QObject::tr ("Select Source"))));
menu_entries.push_back (lay::separator ("sort_group", at));
menu_entries.push_back (lay::submenu ("sort_menu", at, tl::to_string (QObject::tr ("Sort By"))));
{
std::string at = "@lcp_context_menu.sort_menu.end";
menu_entries.push_back (lay::menu_item ("cm_lv_sort_by_ild", "sort_ild", at, tl::to_string (QObject::tr ("Layout Index, Layer And Datatype"))));
menu_entries.push_back (lay::menu_item ("cm_lv_sort_by_idl", "sort_idl", at, tl::to_string (QObject::tr ("Layout Index, Datatype And Layer"))));
menu_entries.push_back (lay::menu_item ("cm_lv_sort_by_ldi", "sort_ldi", at, tl::to_string (QObject::tr ("Layer, Datatype And Layout Index"))));
menu_entries.push_back (lay::menu_item ("cm_lv_sort_by_dli", "sort_dli", at, tl::to_string (QObject::tr ("Datatype, Layer And Layout Index"))));
menu_entries.push_back (lay::menu_item ("cm_lv_sort_by_name", "sort_name", at, tl::to_string (QObject::tr ("Name"))));
}
menu_entries.push_back (lay::separator ("view_group", at));
menu_entries.push_back (lay::menu_item ("cm_lv_delete", "del", at, tl::to_string (QObject::tr ("Delete Layer Entry"))));
menu_entries.push_back (lay::menu_item ("cm_lv_insert", "insert", at, tl::to_string (QObject::tr ("Insert Layer Entry"))));
menu_entries.push_back (lay::menu_item ("cm_lv_add_missing", "add_others", at, tl::to_string (QObject::tr ("Add Other Layer Entries"))));
menu_entries.push_back (lay::menu_item ("cm_lv_remove_unused", "clean_up", at, tl::to_string (QObject::tr ("Clean Up Layer Entries"))));
menu_entries.push_back (lay::separator ("grouping_group", at));
menu_entries.push_back (lay::menu_item ("cm_lv_group", "group", at, tl::to_string (QObject::tr ("Group"))));
menu_entries.push_back (lay::menu_item ("cm_lv_ungroup", "ungroup", at, tl::to_string (QObject::tr ("Ungroup"))));
menu_entries.push_back (lay::submenu ("regroup_menu", at, tl::to_string (QObject::tr ("Regroup Layer Entries"))));
{
std::string at = "@lcp_context_menu.regroup_menu.end";
menu_entries.push_back (lay::menu_item ("cm_lv_regroup_by_index", "grp_i", at, tl::to_string (QObject::tr ("By Layout Index"))));
menu_entries.push_back (lay::menu_item ("cm_lv_regroup_by_datatype", "grp_d", at, tl::to_string (QObject::tr ("By Datatype"))));
menu_entries.push_back (lay::menu_item ("cm_lv_regroup_by_layer", "grp_l", at, tl::to_string (QObject::tr ("By Layer"))));
menu_entries.push_back (lay::menu_item ("cm_lv_regroup_flatten", "flatten", at, tl::to_string (QObject::tr ("Flatten"))));
}
menu_entries.push_back (lay::separator ("copy_paste_group", at));
menu_entries.push_back (lay::menu_item ("cm_lv_copy", "copy", at, tl::to_string (QObject::tr ("Copy"))));
menu_entries.push_back (lay::menu_item ("cm_lv_cut", "cut", at, tl::to_string (QObject::tr ("Cut"))));
menu_entries.push_back (lay::menu_item ("cm_lv_paste", "paste", at, tl::to_string (QObject::tr ("Paste"))));
at = ".end";
menu_entries.push_back (lay::submenu ("@lcp_tabs_context_menu", at, std::string ()));
{
std::string at = "@lcp_tabs_context_menu.end";
menu_entries.push_back (lay::menu_item ("cm_lv_new_tab", "new_tab", at, tl::to_string (QObject::tr ("New Tab"))));
menu_entries.push_back (lay::menu_item ("cm_lv_remove_tab", "remove_tab", at, tl::to_string (QObject::tr ("Remove Tab"))));
menu_entries.push_back (lay::menu_item ("cm_lv_rename_tab", "rename_tab", at, tl::to_string (QObject::tr ("Rename Tab"))));
}
}
};
static tl::RegisteredClass<lay::PluginDeclaration> config_decl (new LayerControlPanelPluginDeclaration (), -9, "LayerControlPanelPlugin");
} // namespace lay
@@ -138,11 +138,6 @@ public:
*/
bool has_focus () const;
/**
* @brief Perform the layer control panel's initialisations on the main menu
*/
static void init_menu (lay::AbstractMenu &menu);
/**
* @brief Tell, if there is something to copy
*/
@@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/st" >
<file alias="tree.stxml">tree.stxml</file>
<file alias="st_plus_node.png">images/st_plus_node.png</file>
</qresource>
</RCC>
@@ -0,0 +1,848 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2020 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "layLayoutStatisticsForm.h"
#include "layLayoutView.h"
#include "tlInternational.h"
#include "tlString.h"
#include "tlExpression.h"
#include "tlTimer.h"
#include "dbLayoutQuery.h"
#include "dbCellGraphUtils.h"
#include <set>
#include <sstream>
#include <QBuffer>
#include <QResource>
#include <QFileInfo>
#include <QDomElement>
#include <QDomDocument>
#include <QXmlStreamWriter>
#include <QTextStream>
#if QT_VERSION >= 0x050000
# include <QUrlQuery>
#endif
namespace lay
{
/**
* @brief A comparison operator to sort layers by layer and datatype and then by name
*/
struct CompareLDName
{
CompareLDName (const db::Layout &l)
: mp_layout (&l)
{
// .. nothing yet ..
}
bool operator() (unsigned int a, unsigned int b)
{
if (mp_layout->is_valid_layer (a) && mp_layout->is_valid_layer (b)) {
const db::LayerProperties &lp_a = mp_layout->get_properties (a);
const db::LayerProperties &lp_b = mp_layout->get_properties (b);
if (lp_a.layer != lp_b.layer) {
return lp_a.layer < lp_b.layer;
}
if (lp_a.datatype != lp_b.datatype) {
return lp_a.datatype < lp_b.datatype;
}
if (lp_a.name != lp_b.name) {
return lp_a.name < lp_b.name;
}
}
return false;
}
private:
const db::Layout *mp_layout;
};
/**
* @brief A comparison operator to sort layers by name and then by layer and datatype
*/
struct CompareNameLD
{
CompareNameLD (const db::Layout &l)
: mp_layout (&l)
{
// .. nothing yet ..
}
bool operator() (unsigned int a, unsigned int b)
{
if (mp_layout->is_valid_layer (a) && mp_layout->is_valid_layer (b)) {
const db::LayerProperties &lp_a = mp_layout->get_properties (a);
const db::LayerProperties &lp_b = mp_layout->get_properties (b);
if (lp_a.name != lp_b.name) {
return lp_a.name < lp_b.name;
}
if (lp_a.layer != lp_b.layer) {
return lp_a.layer < lp_b.layer;
}
if (lp_a.datatype != lp_b.datatype) {
return lp_a.datatype < lp_b.datatype;
}
}
return false;
}
private:
const db::Layout *mp_layout;
};
static std::string format_tech_name (const std::string &s)
{
if (s.empty ()) {
return s;
} else {
return " ('" + s + "')";
}
}
// ------------------------------------------------------------
/**
* @brief A template processor for creating HTML pages from a template
*
* TODO: this is just a first step and far from being complete.
* The template processor is used from the browser page by using an extension .stxml.
* It reads a XML file from a resource path ":/st/<path>" and converts it into HTML.
*/
class StatisticsTemplateProcessor
{
public:
StatisticsTemplateProcessor (const QUrl &url, const db::Layout *layout)
: mp_layout (layout)
{
QResource res (QString::fromUtf8 (":/st/") + url.path ());
if (res.isCompressed ()) {
m_temp = qUncompress ((const unsigned char *)res.data (), (int)res.size ());
} else {
m_temp = QByteArray ((const char *)res.data (), (int)res.size ());
}
#if QT_VERSION >= 0x050000
QList<QPair<QString, QString> > queryItems = QUrlQuery (url.query ()).queryItems ();
#else
QList<QPair<QString, QString> > queryItems = url.queryItems ();
#endif
for (QList<QPair<QString, QString> >::const_iterator q = queryItems.begin (); q != queryItems.end (); ++q) {
m_top_eval.set_var (tl::to_string (q->first), tl::to_string (q->second));
}
}
bool process ();
const QByteArray &get () const
{
return m_output.buffer ();
}
private:
QByteArray m_temp;
QBuffer m_output;
tl::Eval m_top_eval;
const db::Layout *mp_layout;
void process (const QDomElement &element, tl::Eval &eval, QXmlStreamWriter &writer);
void process_child_nodes (const QDomElement &element, tl::Eval &eval, QXmlStreamWriter &writer);
};
bool
StatisticsTemplateProcessor::process ()
{
m_output.open (QIODevice::WriteOnly);
bool ret_value = false;
try
{
tl::SelfTimer timer (tl::verbosity () > 21, "StatisticsForm: create content");
QDomDocument doc;
doc.setContent (m_temp, true);
QXmlStreamWriter writer (&m_output);
writer.writeStartDocument (QString::fromUtf8 ("1.0"));
process (doc.documentElement (), m_top_eval, writer);
writer.writeEndDocument ();
ret_value = true;
} catch (tl::Exception &ex) {
tl::error << ex.msg ();
QTextStream writer (&m_output);
writer << tl::to_string (QObject::tr ("ERROR: evaluating template: ")).c_str () << ex.msg ().c_str ();
}
m_output.close ();
return ret_value;
}
void
StatisticsTemplateProcessor::process_child_nodes (const QDomElement &element, tl::Eval &eval, QXmlStreamWriter &writer)
{
if (element.isNull ()) {
return;
}
for (QDomNode n = element.firstChild (); ! n.isNull (); n = n.nextSibling ()) {
if (n.isElement ()) {
process (n.toElement (), eval, writer);
} else if (n.isCDATASection ()) {
writer.writeCDATA (tl::to_qstring (eval.interpolate (tl::to_string (n.toCDATASection ().data ()))));
} else if (n.isCharacterData ()) {
QString t;
QTextStream s (&t);
while (true) {
s << n.toCharacterData ().data ();
QDomNode nn = n.nextSibling ();
if (nn.isNull () || ! nn.isCharacterData ()) {
break;
}
n = nn;
}
writer.writeCharacters (tl::to_qstring (eval.interpolate (tl::to_string (t))));
}
}
}
void
StatisticsTemplateProcessor::process (const QDomElement &element, tl::Eval &eval, QXmlStreamWriter &writer)
{
static QString template_namespace_uri = QString::fromUtf8 ("www.klayout.org/layout-statistics-template");
static QString template_cmd_if = QString::fromUtf8 ("if");
static QString template_cmd_true = QString::fromUtf8 ("true");
static QString template_cmd_false = QString::fromUtf8 ("false");
static QString template_cmd_eval = QString::fromUtf8 ("eval");
static QString template_cmd_query = QString::fromUtf8 ("query");
static QString template_cmd_begin = QString::fromUtf8 ("begin");
static QString template_cmd_end = QString::fromUtf8 ("end");
static QString template_cmd_max = QString::fromUtf8 ("max");
static QString template_cmd_each = QString::fromUtf8 ("each");
static QString template_value_true = QString::fromUtf8 ("true");
static QString template_value_empty_query = QString::fromUtf8 ("");
static QString template_name_expr = QString::fromUtf8 ("expr");
static QString template_name_max = QString::fromUtf8 ("max");
if (element.namespaceURI () == template_namespace_uri) {
if (element.localName () == template_cmd_eval) {
tl::Expression expr;
eval.parse (expr, tl::to_string (element.attribute (template_name_expr, template_value_true)));
expr.execute ();
} else if (element.localName () == template_cmd_if) {
QDomElement true_node, false_node;
for (QDomNode n = element.firstChild (); ! n.isNull (); n = n.nextSibling ()) {
QDomElement e = n.toElement ();
if (! e.isNull () && e.namespaceURI () == template_namespace_uri) {
if (e.localName () == template_cmd_true) {
true_node = e;
} else if (e.localName () == template_cmd_false) {
false_node = e;
}
}
}
if (true_node.isNull () && false_node.isNull ()) {
true_node = element;
}
tl::Expression expr;
eval.parse (expr, tl::to_string (element.attribute (template_name_expr, template_value_true)));
tl::Variant value = expr.execute ();
if (value.to_bool ()) {
if (! true_node.isNull ()) {
process (true_node, eval, writer);
}
} else {
if (! false_node.isNull ()) {
process (false_node, eval, writer);
}
}
} else if (element.localName () == template_cmd_query) {
QDomElement begin_node, end_node, each_node, max_node;
for (QDomNode n = element.firstChild (); ! n.isNull (); n = n.nextSibling ()) {
QDomElement e = n.toElement ();
if (! e.isNull () && e.namespaceURI () == template_namespace_uri) {
if (e.localName () == template_cmd_begin) {
begin_node = e;
} else if (e.localName () == template_cmd_end) {
end_node = e;
} else if (e.localName () == template_cmd_max) {
max_node = e;
} else if (e.localName () == template_cmd_each) {
each_node = e;
}
}
}
if (begin_node.isNull () && end_node.isNull () && max_node.isNull () && each_node.isNull ()) {
each_node = element;
}
unsigned long max_count = std::numeric_limits<unsigned long>::max ();
QString max_attr = element.attribute (template_name_max, QString ());
if (! max_attr.isNull ()) {
tl::Expression expr;
eval.parse (expr, tl::to_string (max_attr));
tl::Variant max = expr.execute ();
if (max.can_convert_to_ulong ()) {
max_count = max.to_ulong ();
}
}
db::LayoutQuery q (tl::to_string (element.attribute (template_name_expr, template_value_empty_query)));
db::LayoutQueryIterator qi (q, mp_layout, &eval);
process_child_nodes (begin_node, qi.eval (), writer);
for ( ; !qi.at_end (); ++qi) {
if (max_count == 0) {
process_child_nodes (max_node, qi.eval (), writer);
break;
} else {
--max_count;
process_child_nodes (each_node, qi.eval (), writer);
}
}
process_child_nodes (end_node, qi.eval (), writer);
}
} else {
writer.writeStartElement (element.nodeName ());
if (element.hasAttributes ()) {
// Hint: attribute nodes are not children of the elements ..
QDomNamedNodeMap attributes = element.attributes ();
for (int i = 0; i < attributes.count (); ++i) {
QDomAttr a = attributes.item (i).toAttr ();
if (! a.isNull ()) {
writer.writeAttribute (a.nodeName (), tl::to_qstring (eval.interpolate (tl::to_string (a.value ()))));
}
}
}
process_child_nodes (element, eval, writer);
writer.writeEndElement ();
}
}
// ------------------------------------------------------------
class ShapeStatistics
{
public:
ShapeStatistics ()
{
// .. nothing yet ..
}
void compute (const db::Shapes &shapes)
{
for (db::Shapes::shape_iterator i = shapes.begin (db::ShapeIterator::All); ! i.at_end (); ++i) {
size_t n = 1;
if (i.in_array ()) {
n = i.array ().array_size ();
m_count [i.array ().type ()] += 1;
i.finish_array ();
}
m_count [i->type ()] += n;
}
}
void operator*= (size_t f)
{
for (std::map<db::Shape::object_type, size_t>::iterator c = m_count.begin (); c != m_count.end (); ++c) {
c->second *= f;
}
}
void operator+= (const ShapeStatistics &other)
{
for (std::map<db::Shape::object_type, size_t>::const_iterator c = other.m_count.begin (); c != other.m_count.end (); ++c) {
m_count [c->first] += c->second;
}
}
size_t count (db::Shape::object_type t) const
{
std::map<db::Shape::object_type, size_t>::const_iterator c = m_count.find (t);
if (c != m_count.end ()) {
return c->second;
} else {
return 0;
}
}
size_t box_total () const
{
return count (db::Shape::Box) + count (db::Shape::BoxArrayMember) + count (db::Shape::ShortBox) + count (db::Shape::ShortBoxArrayMember);
}
size_t box_single () const
{
return count (db::Shape::Box) + count (db::Shape::ShortBox);
}
size_t box_array () const
{
return count (db::Shape::BoxArray) + count (db::Shape::ShortBoxArray);
}
size_t polygon_total () const
{
return count (db::Shape::Polygon) + count (db::Shape::PolygonRef) + count (db::Shape::PolygonPtrArrayMember)
+ count (db::Shape::SimplePolygon) + count (db::Shape::SimplePolygonRef) + count (db::Shape::SimplePolygonPtrArrayMember);
}
size_t polygon_single () const
{
return count (db::Shape::Polygon) + count (db::Shape::PolygonRef)
+ count (db::Shape::SimplePolygon) + count (db::Shape::SimplePolygonRef);
}
size_t polygon_array () const
{
return count (db::Shape::PolygonPtrArray) + count (db::Shape::SimplePolygonPtrArray);
}
size_t path_total () const
{
return count (db::Shape::Path) + count (db::Shape::PathRef) + count (db::Shape::PathPtrArrayMember);
}
size_t path_single () const
{
return count (db::Shape::Path) + count (db::Shape::PathRef);
}
size_t path_array () const
{
return count (db::Shape::PathPtrArray);
}
size_t text_total () const
{
return count (db::Shape::Text) + count (db::Shape::TextRef) + count (db::Shape::TextPtrArrayMember);
}
size_t text_single () const
{
return count (db::Shape::Text) + count (db::Shape::TextRef);
}
size_t text_array () const
{
return count (db::Shape::TextPtrArray);
}
size_t edge_total () const
{
return count (db::Shape::Edge);
}
size_t user_total () const
{
return count (db::Shape::UserObject);
}
private:
std::map<db::Shape::object_type, size_t> m_count;
};
// ------------------------------------------------------------
class StatisticsSource
: public lay::BrowserSource
{
public:
StatisticsSource (const lay::LayoutHandleRef &h)
: m_h (h)
{
// .. nothing yet ..
}
std::string get (const std::string &url);
private:
const lay::LayoutHandleRef m_h;
};
std::string
StatisticsSource::get (const std::string &url)
{
static QString s_per_layer_stat_path_ld = QString::fromUtf8 ("per-layer-stat-ld");
static QString s_per_layer_stat_path_name = QString::fromUtf8 ("per-layer-stat-name");
QUrl qurl (tl::to_qstring (url));
QFileInfo fi (qurl.path ());
if (fi.suffix () == QString::fromUtf8 ("stxml")) {
StatisticsTemplateProcessor tp (qurl, &m_h->layout ());
tp.process ();
std::string r = tp.get ().constData ();
return r;
} else if (fi.baseName () == s_per_layer_stat_path_ld || fi.baseName () == s_per_layer_stat_path_name) {
// This is the default top level page
// TODO: handle other input as well
const db::Layout &layout = m_h->layout ();
std::ostringstream os;
os.imbue (std::locale ("C"));
std::vector <unsigned int> layers;
for (unsigned int i = 0; i < layout.layers (); ++i) {
if (layout.is_valid_layer (i)) {
layers.push_back (i);
}
}
if (fi.baseName () == s_per_layer_stat_path_ld) {
std::sort (layers.begin (), layers.end (), CompareLDName (layout));
} else {
std::sort (layers.begin (), layers.end (), CompareNameLD (layout));
}
os << "<html>" << std::endl
<< "<body>" << std::endl
<< "<h2>" << tl::to_string (QObject::tr ("Detailed Layer Statistics for '")) << m_h->name () << "'</h2>" << std::endl
<< "<p>" << std::endl
<< "<table cellspacing=\"5\" cellpadding=\"5\">" << std::endl
<< "<tr>" << std::endl
<< "<th bgcolor=\"#f0f0f0\">" << tl::to_string (QObject::tr ("Layer")) << "</th>" << std::endl
<< "<th colspan=\"3\" bgcolor=\"#f0f0f0\">" << tl::to_string (QObject::tr ("Boxes")) << "</th>" << std::endl
<< "<th colspan=\"3\" bgcolor=\"#f0f0f0\">" << tl::to_string (QObject::tr ("Polygons")) << "</th>" << std::endl
<< "<th colspan=\"3\" bgcolor=\"#f0f0f0\">" << tl::to_string (QObject::tr ("Paths")) << "</th>" << std::endl
<< "<th colspan=\"3\" bgcolor=\"#f0f0f0\">" << tl::to_string (QObject::tr ("Texts")) << "</th>" << std::endl
<< "<th bgcolor=\"#f0f0f0\">" << tl::to_string (QObject::tr ("Edges")) << "</th>" << std::endl
<< "<th bgcolor=\"#f0f0f0\">" << tl::to_string (QObject::tr ("User objects")) << "</th>" << std::endl
<< "</tr>" << std::endl
<< "<tr>" << std::endl
<< "<th></th>" << std::endl
<< "<th>" << tl::to_string (QObject::tr ("(total)")) << "</th><th>" << tl::to_string (QObject::tr ("(single)")) << "</th><th>" << tl::to_string (QObject::tr ("(arrays)")) << "</th>" << std::endl
<< "<th>" << tl::to_string (QObject::tr ("(total)")) << "</th><th>" << tl::to_string (QObject::tr ("(single)")) << "</th><th>" << tl::to_string (QObject::tr ("(arrays)")) << "</th>" << std::endl
<< "<th>" << tl::to_string (QObject::tr ("(total)")) << "</th><th>" << tl::to_string (QObject::tr ("(single)")) << "</th><th>" << tl::to_string (QObject::tr ("(arrays)")) << "</th>" << std::endl
<< "<th>" << tl::to_string (QObject::tr ("(total)")) << "</th><th>" << tl::to_string (QObject::tr ("(single)")) << "</th><th>" << tl::to_string (QObject::tr ("(arrays)")) << "</th>" << std::endl
<< "<th>" << tl::to_string (QObject::tr ("(total)")) << "</th>" << std::endl
<< "<th>" << tl::to_string (QObject::tr ("(total)")) << "</th>" << std::endl
<< "</tr>" << std::endl
;
db::CellCounter cc (&layout);
tl::RelativeProgress progress (tl::to_string (QObject::tr ("Collecting statistics")), layers.size () * layout.cells (), 100000);
for (std::vector <unsigned int>::const_iterator l = layers.begin (); l != layers.end (); ++l) {
ShapeStatistics st_hier;
ShapeStatistics st_flat;
for (db::Layout::top_down_const_iterator c = layout.begin_top_down (); c != layout.end_top_down (); ++c) {
ShapeStatistics st;
st.compute (layout.cell (*c).shapes (*l));
st_hier += st;
st *= cc.weight (*c);
st_flat += st;
++progress;
}
os << "<tr>" << std::endl
<< "<td>" << layout.get_properties (*l).to_string () << "</td>" << std::endl
// Boxes (total, single, array)
<< "<td>" << st_hier.box_total () << "<br></br>" << st_flat.box_total () << "</td>" << std::endl
<< "<td>" << st_hier.box_single () << "<br></br>" << st_flat.box_single () << "</td>" << std::endl
<< "<td>" << st_hier.box_array () << "<br></br>" << st_flat.box_array () << "</td>" << std::endl
// Polygons (total, single, array)
<< "<td>" << st_hier.polygon_total () << "<br></br>" << st_flat.polygon_total () << "</td>" << std::endl
<< "<td>" << st_hier.polygon_single () << "<br></br>" << st_flat.polygon_single () << "</td>" << std::endl
<< "<td>" << st_hier.polygon_array () << "<br></br>" << st_flat.polygon_array () << "</td>" << std::endl
// Paths (total, single, array)
<< "<td>" << st_hier.path_total () << "<br></br>" << st_flat.path_total () << "</td>" << std::endl
<< "<td>" << st_hier.path_single () << "<br></br>" << st_flat.path_single () << "</td>" << std::endl
<< "<td>" << st_hier.path_array () << "<br></br>" << st_flat.path_array () << "</td>" << std::endl
// Texts (total, single, array)
<< "<td>" << st_hier.text_total () << "<br></br>" << st_flat.text_total () << "</td>" << std::endl
<< "<td>" << st_hier.text_single () << "<br></br>" << st_flat.text_single () << "</td>" << std::endl
<< "<td>" << st_hier.text_array () << "<br></br>" << st_flat.text_array () << "</td>" << std::endl
// Edges (total)
<< "<td>" << st_hier.edge_total () << "<br></br>" << st_flat.edge_total () << "</td>" << std::endl
// User objects (total)
<< "<td>" << st_hier.user_total () << "<br></br>" << st_flat.user_total () << "</td>" << std::endl
// ...
<< "<td>" << tl::to_string (QObject::tr ("(hier)")) << "<br></br>" << tl::to_string (QObject::tr ("(flat)")) << "</td>" << std::endl
<< "</tr>" << std::endl
;
}
os << "</table>" << std::endl
<< "</p>" << std::endl
<< tl::to_string (QObject::tr ("<h4>Note</h4>"
"<p>"
"\"(hier)\" is the object count where each cell counts once. "
"\"(flat)\" is the \"as if flat\" count where the cells count as many times as they are seen from the top cells."
"</p>"
"<p>"
"\"(total)\" is the effective number of shapes. \"(single)\" are the single shapes. "
"\"(arrays)\" is the number of shape arrays where each array counts as one, but contributes many individual shapes to \"(total)\"."
"</p>"
))
<< "</body>" << std::endl
<< "</html>";
return os.str ();
} else {
// This is the default top level page
// TODO: handle other input as well
const db::Layout &layout = m_h->layout ();
std::ostringstream os;
os.imbue (std::locale ("C"));
size_t num_cells = layout.cells ();
size_t num_layers = 0;
for (unsigned int i = 0; i < layout.layers (); ++i) {
if (layout.is_valid_layer (i)) {
++num_layers;
}
}
os << "<html>" << std::endl
<< "<body>" << std::endl
<< "<h2>" << tl::to_string (QObject::tr ("Common Statistics For '")) << m_h->name () << "'</h2>" << std::endl
<< "<p>" << std::endl
<< "<table>" << std::endl
<< "<tr>"
<< "<td>" << tl::to_string (QObject::tr ("Path")) << ":&nbsp;</td><td>" << m_h->filename () << "</td>"
<< "</tr>" << std::endl
<< "<tr>"
<< "<td>" << tl::to_string (QObject::tr ("Technology")) << ":&nbsp;</td><td>" << m_h->technology ()->description () << format_tech_name (m_h->tech_name ()) << "</td>"
<< "</tr>" << std::endl
<< "<tr>"
<< "<td>" << tl::to_string (QObject::tr ("Database unit")) << ":&nbsp;</td><td>" << tl::sprintf ("%.12g ", layout.dbu ()) << tl::to_string (QObject::tr ("micron")) << "</td>"
<< "</tr>" << std::endl
<< "<tr>"
<< "<td>" << tl::to_string (QObject::tr ("Number of cells")) << ":&nbsp;</td><td>" << num_cells << "</td>"
<< "</tr>" << std::endl
<< "<tr>"
<< "<td>" << tl::to_string (QObject::tr ("Number of layers")) << ":&nbsp;</td><td>" << num_layers << "</td>"
<< "</tr>" << std::endl;
for (db::Layout::meta_info_iterator meta = layout.begin_meta (); meta != layout.end_meta (); ++meta) {
os << "<tr><td>" << meta->description << "</td><td>" << meta->value << "</td></tr>" << std::endl;
}
os << "</table>" << std::endl
<< "<h2>" << tl::to_string (QObject::tr ("Top Cells")) << "</h2>" << std::endl
<< "<table>" << std::endl;
for (db::Layout::top_down_const_iterator tc = layout.begin_top_down (); tc != layout.end_top_cells (); ++tc) {
os << "<tr><td>" << layout.cell_name (*tc) << "</td></tr>" << std::endl;
}
os << "</table>" << std::endl;
os << "</p>" << std::endl;
std::vector <unsigned int> layers_with_oasis_names;
std::vector <unsigned int> layers_sorted_by_ld;
layers_sorted_by_ld.reserve (num_layers);
for (unsigned int i = 0; i < layout.layers (); ++i) {
if (layout.is_valid_layer (i)) {
layers_sorted_by_ld.push_back (i);
const db::LayerProperties &lp = layout.get_properties (i);
if (! lp.name.empty ()) {
layers_with_oasis_names.push_back (i);
}
}
}
std::sort (layers_sorted_by_ld.begin (), layers_sorted_by_ld.end (), CompareLDName (layout));
std::sort (layers_with_oasis_names.begin (), layers_with_oasis_names.end (), CompareNameLD (layout));
if (! layers_sorted_by_ld.empty ()) {
os << "<h2>" << tl::to_string (QObject::tr ("Layers (sorted by layer and datatype)")) << "</h2>" << std::endl
<< "<p><a href=\"" << tl::to_string (s_per_layer_stat_path_ld) << "\">Detailed layer statistics</a></p>" << std::endl
<< "<p>" << std::endl
<< "<table>" << std::endl
<< "<tr><td><b>" << tl::to_string (QObject::tr ("Layer/Datatype")) << "</b>&nbsp;&nbsp;</td>";
if (! layers_with_oasis_names.empty ()) {
os << "<td><b>" << tl::to_string (QObject::tr ("Layer name")) << "</b></td>";
}
os << "</tr>" << std::endl;
for (std::vector <unsigned int>::const_iterator i = layers_sorted_by_ld.begin (); i != layers_sorted_by_ld.end (); ++i) {
if (layout.is_valid_layer (*i)) {
const db::LayerProperties &lp = layout.get_properties (*i);
os << "<tr>"
<< "<td>" << tl::sprintf ("%d/%d", lp.layer, lp.datatype) << "</td>";
if (! layers_with_oasis_names.empty ()) {
os << "<td>" << lp.name << "</td>";
}
os << "</tr>" << std::endl;
}
}
os << "</table>" << std::endl;
os << "</p>" << std::endl;
}
if (! layers_with_oasis_names.empty ()) {
os << "<h2>" << tl::to_string (QObject::tr ("Layers (sorted by layer names)")) << "</h2>" << std::endl
<< "<p><a href=\"" << tl::to_string (s_per_layer_stat_path_name) << "\">Detailed layer statistics</a></p>" << std::endl
<< "<p>" << std::endl
<< "<table>" << std::endl
<< "<tr><td><b>" << tl::to_string (QObject::tr ("Layer name")) << "</b>&nbsp;&nbsp;</td><td><b>" << tl::to_string (QObject::tr ("Layer/Datatype")) << "</b></td></tr>" << std::endl;
for (std::vector <unsigned int>::const_iterator i = layers_with_oasis_names.begin (); i != layers_with_oasis_names.end (); ++i) {
if (layout.is_valid_layer (*i)) {
const db::LayerProperties &lp = layout.get_properties (*i);
if (! lp.name.empty ()) {
os << "<tr>"
<< "<td>" << lp.name << "</td>"
<< "<td>" << tl::sprintf ("%d/%d", lp.layer, lp.datatype) << "</td>"
<< "</tr>" << std::endl;
}
}
}
os << "</table>" << std::endl;
os << "</p>" << std::endl;
}
os << "</body>" << std::endl
<< "</html>" << std::endl;
;
return os.str ();
}
}
// ------------------------------------------------------------
LayoutStatisticsForm::LayoutStatisticsForm (QWidget *parent, lay::LayoutView *view, const char *name)
: QDialog (parent), Ui::LayoutStatisticsForm (), mp_source (0)
{
setObjectName (QString::fromUtf8 (name));
Ui::LayoutStatisticsForm::setupUi (this);
// collect the distinct layout handles
std::set <lay::LayoutHandle *> handles;
for (unsigned int n = 0; n < view->cellviews (); ++n) {
handles.insert (view->cellview (n).operator-> ());
}
m_handles.reserve (handles.size ());
for (unsigned int n = 0; n < view->cellviews (); ++n) {
lay::LayoutHandle *h = view->cellview (n).operator-> ();
if (handles.find (h) != handles.end ()) {
m_handles.push_back (h);
handles.erase (h);
layout_cbx->addItem (tl::to_qstring (h->name ()));
}
}
layout_cbx->setCurrentIndex (view->active_cellview_index ());
connect (layout_cbx, SIGNAL (activated (int)), this, SLOT (layout_selected (int)));
layout_selected (layout_cbx->currentIndex ());
}
LayoutStatisticsForm::~LayoutStatisticsForm ()
{
browser->set_source (0);
if (mp_source != 0) {
delete mp_source;
mp_source = 0;
}
}
void
LayoutStatisticsForm::layout_selected (int index)
{
if (index >= int (m_handles.size ()) || index < 0) {
return;
}
browser->set_source (0);
if (mp_source != 0) {
delete mp_source;
}
mp_source = new StatisticsSource (m_handles [index]);
browser->set_source (mp_source);
browser->set_home ("int:index");
browser->home ();
}
}
@@ -21,31 +21,38 @@
*/
#include "layAbstractMenuProvider.h"
#ifndef HDR_layLayoutStatisticsForm
#define HDR_layLayoutStatisticsForm
namespace lay
#include <QDialog>
#include "ui_LayoutStatistics.h"
#include "layCellView.h"
#include <vector>
namespace lay {
class LayoutView;
class StatisticsSource;
class LayoutStatisticsForm
: public QDialog, private Ui::LayoutStatisticsForm
{
Q_OBJECT
static AbstractMenuProvider *ms_instance = 0;
public:
LayoutStatisticsForm (QWidget *parent, lay::LayoutView *view, const char *name);
~LayoutStatisticsForm ();
AbstractMenuProvider::AbstractMenuProvider ()
{
if (! ms_instance) {
ms_instance = this;
}
}
public slots:
void layout_selected (int);
AbstractMenuProvider::~AbstractMenuProvider ()
{
if (ms_instance == this) {
ms_instance = 0;
}
}
AbstractMenuProvider *AbstractMenuProvider::instance ()
{
return ms_instance;
}
private:
std::vector <lay::LayoutHandleRef> m_handles;
StatisticsSource *mp_source;
};
}
#endif
File diff suppressed because it is too large Load Diff
+22 -13
View File
@@ -31,12 +31,15 @@
#include <set>
#include <list>
#include <string>
#include <memory>
#include <QFrame>
#include <QImage>
#include "layLayerProperties.h"
#include "layAbstractMenu.h"
#include "layAnnotationShapes.h"
#include "layDispatcher.h"
#include "layLayoutCanvas.h"
#include "layColorPalette.h"
#include "layStipplePalette.h"
@@ -78,6 +81,7 @@ class SelectionService;
class MoveService;
class Browser;
class ColorButton;
class ConfigureAction;
/**
* @brief Stores a layer reference to create layers which have been added by some action
@@ -154,7 +158,7 @@ struct LAYBASIC_PUBLIC LayerDisplayProperties
class LAYBASIC_PUBLIC LayoutView
: public QFrame,
public lay::Editables,
public lay::Plugin
public lay::Dispatcher
{
Q_OBJECT
@@ -192,7 +196,7 @@ public:
/**
* @brief Constructor (clone from another view)
*/
LayoutView (lay::LayoutView *source, db::Manager *mgr, bool editable, lay::PluginRoot *root, QWidget *parent = 0, const char *name = "view", unsigned int options = (unsigned int) LV_Normal);
LayoutView (lay::LayoutView *source, db::Manager *mgr, bool editable, lay::Plugin *plugin_parent, QWidget *parent = 0, const char *name = "view", unsigned int options = (unsigned int) LV_Normal);
/**
* @brief Destructor
@@ -1655,11 +1659,6 @@ public:
*/
static unsigned int intrinsic_mouse_modes (std::vector<std::string> *descriptions);
/**
* @brief Perform the layout view's initialisations on the main menu
*/
static void init_menu (lay::AbstractMenu &menu);
/**
* @brief Updates the menu for the given view
* If the view is 0, the menu shall be updated to reflect "no view active"
@@ -2006,7 +2005,7 @@ public:
* PD is the type of the declaration.
*/
template <class PD>
void create_plugin (lay::PluginRoot *root)
void create_plugin ()
{
for (std::vector<lay::Plugin *>::const_iterator p = mp_plugins.begin (); p != mp_plugins.end (); ++p) {
if (dynamic_cast <const PD *> ((*p)->plugin_declaration ()) != 0) {
@@ -2015,7 +2014,7 @@ public:
}
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
if (dynamic_cast <const PD *> (&*cls) != 0) {
create_plugin (root, &*cls);
create_plugin (&*cls);
break;
}
}
@@ -2504,7 +2503,7 @@ public:
*
* If plugins already exist, they are deleted and created again
*/
void create_plugins (lay::PluginRoot *root, const lay::PluginDeclaration *except_this = 0);
void create_plugins (const lay::PluginDeclaration *except_this = 0);
public slots:
/**
@@ -2666,6 +2665,7 @@ public slots:
void layer_order_changed ();
void timer ();
void menu_activated (const std::string &symbol);
static std::vector<std::string> menu_symbols ();
void deactivate_all_browsers ();
void min_hier_changed (int i);
void max_hier_changed (int i);
@@ -2684,7 +2684,7 @@ public slots:
private slots:
void active_cellview_changed (int index);
void active_library_changed (int index);
void goto_bookmark ();
void side_panel_destroyed ();
signals:
/**
@@ -2885,7 +2885,8 @@ private:
bool m_active_cellview_changed_event_enabled;
tl::DeferredMethod<lay::LayoutView> dm_prop_changed;
void init (db::Manager *mgr, lay::PluginRoot *root, QWidget *parent);
void init (db::Manager *mgr, QWidget *parent);
void init_menu ();
void do_prop_changed ();
void do_redraw (int layer);
@@ -2918,6 +2919,11 @@ private:
void init_layer_properties (LayerProperties &props, const LayerPropertiesList &lp_list) const;
void merge_dither_pattern (lay::LayerPropertiesList &props);
void do_cm_duplicate (bool interactive);
void do_cm_paste (bool interactive);
void cm_new_cell ();
void cm_reload ();
// overrides Editables method to display a message
void signal_selection_changed ();
@@ -2925,10 +2931,13 @@ private:
void showEvent (QShowEvent *);
void hideEvent (QHideEvent *);
lay::Plugin *create_plugin (lay::PluginRoot *root, const lay::PluginDeclaration *cls);
lay::Plugin *create_plugin (const lay::PluginDeclaration *cls);
std::list<lay::CellView>::iterator cellview_iter (int cv_index);
std::list<lay::CellView>::const_iterator cellview_iter (int cv_index) const;
// implementation of Dispatcher
virtual QWidget *menu_parent_widget ();
};
}
@@ -24,6 +24,7 @@
#include "layLayoutViewConfigPages.h"
#include "laybasicConfig.h"
#include "layConverters.h"
#include "layDispatcher.h"
#include "ui_LayoutViewConfigPage.h"
#include "ui_LayoutViewConfigPage1.h"
@@ -74,7 +75,7 @@ LayoutViewConfigPage::~LayoutViewConfigPage ()
}
void
LayoutViewConfigPage::setup (lay::PluginRoot *root)
LayoutViewConfigPage::setup (lay::Dispatcher *root)
{
lay::ColorConverter cc;
QColor color;
@@ -84,7 +85,7 @@ LayoutViewConfigPage::setup (lay::PluginRoot *root)
}
void
LayoutViewConfigPage::commit (lay::PluginRoot *root)
LayoutViewConfigPage::commit (lay::Dispatcher *root)
{
lay::ColorConverter cc;
root->config_set (cfg_background_color, mp_ui->bkgnd_color_pb->get_color (), cc);
@@ -107,7 +108,7 @@ LayoutViewConfigPage1::~LayoutViewConfigPage1 ()
}
void
LayoutViewConfigPage1::setup (lay::PluginRoot *root)
LayoutViewConfigPage1::setup (lay::Dispatcher *root)
{
lay::ColorConverter cc;
@@ -152,7 +153,7 @@ LayoutViewConfigPage1::setup (lay::PluginRoot *root)
}
void
LayoutViewConfigPage1::commit (lay::PluginRoot *root)
LayoutViewConfigPage1::commit (lay::Dispatcher *root)
{
lay::ColorConverter cc;
@@ -192,7 +193,7 @@ LayoutViewConfigPage2a::~LayoutViewConfigPage2a ()
}
void
LayoutViewConfigPage2a::setup (lay::PluginRoot *root)
LayoutViewConfigPage2a::setup (lay::Dispatcher *root)
{
QColor color;
root->config_get (cfg_cell_box_color, color, ColorConverter ());
@@ -238,7 +239,7 @@ LayoutViewConfigPage2a::setup (lay::PluginRoot *root)
}
void
LayoutViewConfigPage2a::commit (lay::PluginRoot *root)
LayoutViewConfigPage2a::commit (lay::Dispatcher *root)
{
root->config_set (cfg_cell_box_text_transform, mp_ui->cell_xform_text_cbx->isChecked ());
root->config_set (cfg_cell_box_text_font, mp_ui->cell_font_cb->currentIndex ());
@@ -274,7 +275,7 @@ LayoutViewConfigPage2b::~LayoutViewConfigPage2b ()
}
void
LayoutViewConfigPage2b::setup (lay::PluginRoot *root)
LayoutViewConfigPage2b::setup (lay::Dispatcher *root)
{
QColor color;
root->config_get (cfg_text_color, color, ColorConverter ());
@@ -307,7 +308,7 @@ LayoutViewConfigPage2b::setup (lay::PluginRoot *root)
}
void
LayoutViewConfigPage2b::commit (lay::PluginRoot *root)
LayoutViewConfigPage2b::commit (lay::Dispatcher *root)
{
root->config_set (cfg_text_color, mp_ui->text_color_pb->get_color (), ColorConverter ());
root->config_set (cfg_apply_text_trans, mp_ui->text_apply_trans_cbx->isChecked ());
@@ -339,7 +340,7 @@ LayoutViewConfigPage2c::~LayoutViewConfigPage2c ()
}
void
LayoutViewConfigPage2c::setup (lay::PluginRoot *root)
LayoutViewConfigPage2c::setup (lay::Dispatcher *root)
{
QColor color;
root->config_get (cfg_sel_color, color, lay::ColorConverter ());
@@ -375,7 +376,7 @@ LayoutViewConfigPage2c::setup (lay::PluginRoot *root)
}
void
LayoutViewConfigPage2c::commit (lay::PluginRoot *root)
LayoutViewConfigPage2c::commit (lay::Dispatcher *root)
{
lay::ColorConverter cc;
root->config_set (cfg_sel_color, mp_ui->color_pb->get_color (), cc);
@@ -405,7 +406,7 @@ LayoutViewConfigPage3a::~LayoutViewConfigPage3a ()
}
void
LayoutViewConfigPage3a::setup (lay::PluginRoot *root)
LayoutViewConfigPage3a::setup (lay::Dispatcher *root)
{
bool flag = true;
@@ -418,7 +419,7 @@ LayoutViewConfigPage3a::setup (lay::PluginRoot *root)
}
void
LayoutViewConfigPage3a::commit (lay::PluginRoot *root)
LayoutViewConfigPage3a::commit (lay::Dispatcher *root)
{
root->config_set (cfg_fit_new_cell, mp_ui->fit_new_cell_cbx->isChecked ());
root->config_set (cfg_full_hier_new_cell, mp_ui->full_hier_new_cell_cbx->isChecked ());
@@ -442,7 +443,7 @@ LayoutViewConfigPage3b::~LayoutViewConfigPage3b ()
}
void
LayoutViewConfigPage3b::setup (lay::PluginRoot *root)
LayoutViewConfigPage3b::setup (lay::Dispatcher *root)
{
bool flag = true;
double pd = 0.0;
@@ -462,7 +463,7 @@ LayoutViewConfigPage3b::setup (lay::PluginRoot *root)
}
void
LayoutViewConfigPage3b::commit (lay::PluginRoot *root)
LayoutViewConfigPage3b::commit (lay::Dispatcher *root)
{
root->config_set (cfg_mouse_wheel_mode, mp_ui->alt_mouse_wheel_mode_cbx->isChecked () ? 1 : 0);
@@ -501,7 +502,7 @@ LayoutViewConfigPage3c::~LayoutViewConfigPage3c ()
}
void
LayoutViewConfigPage3c::setup (lay::PluginRoot *root)
LayoutViewConfigPage3c::setup (lay::Dispatcher *root)
{
bool flag = true;
@@ -512,7 +513,7 @@ LayoutViewConfigPage3c::setup (lay::PluginRoot *root)
}
void
LayoutViewConfigPage3c::commit (lay::PluginRoot *root)
LayoutViewConfigPage3c::commit (lay::Dispatcher *root)
{
root->config_set (cfg_dbu_units, mp_ui->dbu_units_cbx->isChecked ());
root->config_set (cfg_abs_units, mp_ui->abs_units_cbx->isChecked ());
@@ -535,7 +536,7 @@ LayoutViewConfigPage3f::~LayoutViewConfigPage3f ()
}
void
LayoutViewConfigPage3f::setup (lay::PluginRoot *root)
LayoutViewConfigPage3f::setup (lay::Dispatcher *root)
{
int workers = 1;
bool flag = true;
@@ -567,7 +568,7 @@ LayoutViewConfigPage3f::setup (lay::PluginRoot *root)
}
void
LayoutViewConfigPage3f::commit (lay::PluginRoot *root)
LayoutViewConfigPage3f::commit (lay::Dispatcher *root)
{
root->config_set (cfg_drawing_workers, mp_ui->drawing_workers_spbx->value ());
@@ -618,7 +619,7 @@ static QToolButton * (Ui::LayoutViewConfigPage4::*cfg4_buttons []) = {
LayoutViewConfigPage4::LayoutViewConfigPage4 (QWidget *parent)
: lay::ConfigPage (parent),
m_edit_order_changed_disabled (false)
m_manager (true), m_edit_order_changed_disabled (false)
{
// install the manager at db::Object
manager (&m_manager);
@@ -654,7 +655,7 @@ LayoutViewConfigPage4::set_edit_order (bool edit_order)
}
void
LayoutViewConfigPage4::setup (lay::PluginRoot *root)
LayoutViewConfigPage4::setup (lay::Dispatcher *root)
{
m_manager.clear ();
@@ -678,7 +679,7 @@ LayoutViewConfigPage4::setup (lay::PluginRoot *root)
}
void
LayoutViewConfigPage4::commit (lay::PluginRoot *root)
LayoutViewConfigPage4::commit (lay::Dispatcher *root)
{
root->config_set (cfg_color_palette, m_palette.to_string ());
}
@@ -876,7 +877,7 @@ LayoutViewConfigPage5::~LayoutViewConfigPage5 ()
}
void
LayoutViewConfigPage5::setup (lay::PluginRoot *root)
LayoutViewConfigPage5::setup (lay::Dispatcher *root)
{
std::string lyp_file;
root->config_get (cfg_default_lyp_file, lyp_file);
@@ -901,7 +902,7 @@ LayoutViewConfigPage5::setup (lay::PluginRoot *root)
}
void
LayoutViewConfigPage5::commit (lay::PluginRoot *root)
LayoutViewConfigPage5::commit (lay::Dispatcher *root)
{
if (mp_ui->lyp_file_gbx->isChecked ()) {
root->config_set (cfg_default_lyp_file, tl::to_string (mp_ui->lyp_file_le->text ()));
@@ -952,7 +953,7 @@ static QToolButton * (Ui::LayoutViewConfigPage6::*cfg6_buttons []) = {
LayoutViewConfigPage6::LayoutViewConfigPage6 (QWidget *parent)
: lay::ConfigPage (parent),
m_edit_order_changed_disabled (false)
m_manager (true), m_edit_order_changed_disabled (false)
{
// install the manager at db::Object
manager (&m_manager);
@@ -988,7 +989,7 @@ LayoutViewConfigPage6::set_edit_order (bool edit_order)
}
void
LayoutViewConfigPage6::setup (lay::PluginRoot *root)
LayoutViewConfigPage6::setup (lay::Dispatcher *root)
{
m_manager.clear ();
@@ -1016,7 +1017,7 @@ LayoutViewConfigPage6::setup (lay::PluginRoot *root)
}
void
LayoutViewConfigPage6::commit (lay::PluginRoot *root)
LayoutViewConfigPage6::commit (lay::Dispatcher *root)
{
if (m_palette.stipples () == 0) {
throw tl::Exception (tl::to_string (QObject::tr ("No stipples set")));
@@ -1239,7 +1240,7 @@ static QToolButton * (Ui::LayoutViewConfigPage6a::*cfg6a_buttons []) = {
};
LayoutViewConfigPage6a::LayoutViewConfigPage6a (QWidget *parent)
: lay::ConfigPage (parent)
: lay::ConfigPage (parent), m_manager (true)
{
// install the manager at db::Object
manager (&m_manager);
@@ -1266,7 +1267,7 @@ LayoutViewConfigPage6a::~LayoutViewConfigPage6a ()
}
void
LayoutViewConfigPage6a::setup (lay::PluginRoot *root)
LayoutViewConfigPage6a::setup (lay::Dispatcher *root)
{
m_manager.clear ();
@@ -1289,7 +1290,7 @@ LayoutViewConfigPage6a::setup (lay::PluginRoot *root)
}
void
LayoutViewConfigPage6a::commit (lay::PluginRoot *root)
LayoutViewConfigPage6a::commit (lay::Dispatcher *root)
{
if (m_palette.styles () == 0) {
throw tl::Exception (tl::to_string (QObject::tr ("No styles set")));
@@ -1440,7 +1441,7 @@ LayoutViewConfigPage7::~LayoutViewConfigPage7 ()
}
void
LayoutViewConfigPage7::setup (lay::PluginRoot *root)
LayoutViewConfigPage7::setup (lay::Dispatcher *root)
{
int oversampling = 1;
root->config_get (cfg_bitmap_oversampling, oversampling);
@@ -1466,7 +1467,7 @@ LayoutViewConfigPage7::setup (lay::PluginRoot *root)
}
void
LayoutViewConfigPage7::commit (lay::PluginRoot *root)
LayoutViewConfigPage7::commit (lay::Dispatcher *root)
{
root->config_set (cfg_bitmap_oversampling, mp_ui->oversampling->currentIndex () + 1);
root->config_set (cfg_default_font_size, mp_ui->default_font_size->currentIndex ());
@@ -67,8 +67,8 @@ public:
LayoutViewConfigPage (QWidget *parent);
~LayoutViewConfigPage ();
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
private:
Ui::LayoutViewConfigPage *mp_ui;
@@ -83,8 +83,8 @@ public:
LayoutViewConfigPage1 (QWidget *parent);
~LayoutViewConfigPage1 ();
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
private:
Ui::LayoutViewConfigPage1 *mp_ui;
@@ -99,8 +99,8 @@ public:
LayoutViewConfigPage2a (QWidget *parent);
~LayoutViewConfigPage2a ();
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
private:
Ui::LayoutViewConfigPage2a *mp_ui;
@@ -115,8 +115,8 @@ public:
LayoutViewConfigPage2b (QWidget *parent);
~LayoutViewConfigPage2b ();
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
private:
Ui::LayoutViewConfigPage2b *mp_ui;
@@ -131,8 +131,8 @@ public:
LayoutViewConfigPage2c (QWidget *parent);
~LayoutViewConfigPage2c ();
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
private:
Ui::LayoutViewConfigPage2c *mp_ui;
@@ -147,8 +147,8 @@ public:
LayoutViewConfigPage3a (QWidget *parent);
~LayoutViewConfigPage3a ();
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
private:
Ui::LayoutViewConfigPage3a *mp_ui;
@@ -163,8 +163,8 @@ public:
LayoutViewConfigPage3b (QWidget *parent);
~LayoutViewConfigPage3b ();
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
private:
Ui::LayoutViewConfigPage3b *mp_ui;
@@ -179,8 +179,8 @@ public:
LayoutViewConfigPage3c (QWidget *parent);
~LayoutViewConfigPage3c ();
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
private:
Ui::LayoutViewConfigPage3c *mp_ui;
@@ -195,8 +195,8 @@ public:
LayoutViewConfigPage3f (QWidget *parent);
~LayoutViewConfigPage3f ();
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
private:
Ui::LayoutViewConfigPage3f *mp_ui;
@@ -212,8 +212,8 @@ public:
LayoutViewConfigPage4 (QWidget *parent);
~LayoutViewConfigPage4 ();
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
virtual void undo (db::Op *op);
virtual void redo (db::Op *op);
@@ -244,8 +244,8 @@ public:
LayoutViewConfigPage5 (QWidget *parent);
~LayoutViewConfigPage5 ();
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
public slots:
void browse_clicked ();
@@ -264,8 +264,8 @@ public:
LayoutViewConfigPage6 (QWidget *parent);
~LayoutViewConfigPage6 ();
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
virtual void undo (db::Op *op);
virtual void redo (db::Op *op);
@@ -298,8 +298,8 @@ public:
LayoutViewConfigPage6a (QWidget *parent);
~LayoutViewConfigPage6a ();
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
virtual void undo (db::Op *op);
virtual void redo (db::Op *op);
@@ -329,8 +329,8 @@ public:
LayoutViewConfigPage7 (QWidget *parent);
~LayoutViewConfigPage7 ();
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
private:
Ui::LayoutViewConfigPage7 *mp_ui;
+25 -23
View File
@@ -48,7 +48,6 @@
#include "layCellTreeModel.h"
#include "layLayoutView.h"
#include "layAbstractMenu.h"
#include "layAbstractMenuProvider.h"
#include "layDialogs.h"
#include "tlExceptions.h"
#include "laybasicConfig.h"
@@ -196,25 +195,6 @@ LibraryTreeWidget::mouseReleaseEvent (QMouseEvent *event)
const int max_cellviews_in_split_mode = 5;
void
LibrariesView::init_menu (lay::AbstractMenu &menu)
{
MenuLayoutEntry context_menu [] = {
#if 0
// doesn't make sense for many libs
MenuLayoutEntry ("split_mode", tl::to_string (QObject::tr ("Split Mode")), std::make_pair (cfg_split_lib_views, "?")),
#endif
MenuLayoutEntry::last ()
};
MenuLayoutEntry main_menu [] = {
MenuLayoutEntry ("@lib_context_menu", "", context_menu),
MenuLayoutEntry::last ()
};
menu.init (main_menu);
}
LibrariesView::LibrariesView (lay::LayoutView *view, QWidget *parent, const char *name)
: QFrame (parent),
m_enable_cb (true),
@@ -338,11 +318,9 @@ LibrariesView::event (QEvent *e)
void
LibrariesView::context_menu (const QPoint &p)
{
tl_assert (lay::AbstractMenuProvider::instance () != 0);
QTreeView *cell_list = dynamic_cast<QTreeView *> (sender ());
if (cell_list) {
QMenu *ctx_menu = lay::AbstractMenuProvider::instance ()->menu ()->detached_menu ("lib_context_menu");
QMenu *ctx_menu = mp_view->menu ()->detached_menu ("lib_context_menu");
ctx_menu->exec (cell_list->mapToGlobal (p));
}
}
@@ -819,4 +797,28 @@ LibrariesView::has_focus () const
return m_active_index >= 0 && m_active_index < int (mp_cell_lists.size ()) && mp_cell_lists [m_active_index]->hasFocus ();
}
// ------------------------------------------------------------
// Declaration of the "plugin" for the menu entries
class LibraryViewPluginDeclaration
: public lay::PluginDeclaration
{
public:
virtual void get_menu_entries (std::vector<lay::MenuEntry> &menu_entries) const
{
std::string at;
at = ".end";
menu_entries.push_back (lay::submenu ("@lib_context_menu", at, std::string ()));
at = "@lib_context_menu.end";
#if 0
// doesn't make sense for many libs
menu_entries.push_back (lay::config_menu_item ("split_mode", at, tl::to_string (QObject::tr ("Split Mode")), cfg_split_lib_views, "?")),
#endif
}
};
static tl::RegisteredClass<lay::PluginDeclaration> config_decl (new LibraryViewPluginDeclaration (), -7, "LibraryViewPlugin");
} // namespace lay
-5
View File
@@ -114,11 +114,6 @@ public:
*/
~LibrariesView ();
/**
* @brief Perform the cell control panel's initialisations on the main menu
*/
static void init_menu (lay::AbstractMenu &menu);
/**
* @brief The sizeHint implementation for Qt layout management
*/
@@ -197,7 +197,7 @@ LoadLayoutOptionsDialog::update ()
}
bool
LoadLayoutOptionsDialog::edit_global_options (lay::PluginRoot *config_root, db::Technologies *technologies)
LoadLayoutOptionsDialog::edit_global_options (lay::Dispatcher *config_root, db::Technologies *technologies)
{
m_opt_array.clear ();
m_tech_array.clear ();
@@ -52,7 +52,7 @@ namespace lay
{
class LayoutView;
class PluginRoot;
class Dispatcher;
class FileDialog;
class LAYBASIC_PUBLIC LoadLayoutOptionsDialog
@@ -64,7 +64,7 @@ public:
LoadLayoutOptionsDialog (QWidget *parent, const std::string &title);
~LoadLayoutOptionsDialog ();
bool edit_global_options (lay::PluginRoot *config_root, db::Technologies *technologies);
bool edit_global_options (lay::Dispatcher *dispatcher, db::Technologies *technologies);
bool get_options (db::LoadLayoutOptions &options);
void show_always (bool sa)
+2 -1
View File
@@ -22,6 +22,7 @@
#include "layNetExportDialog.h"
#include "layPlugin.h"
#include "layDispatcher.h"
#include "layQtTools.h"
#include "tlExceptions.h"
@@ -165,7 +166,7 @@ END_PROTECTED
}
int
NetExportDialog::exec_dialog (lay::PluginRoot *plugin_root)
NetExportDialog::exec_dialog (lay::Dispatcher *plugin_root)
{
std::string v;
plugin_root->config_get (cfg_l2ndb_export_net_cell_prefix, v);
+2 -2
View File
@@ -39,7 +39,7 @@ namespace Ui
namespace lay
{
class PluginRoot;
class Dispatcher;
/**
* @brief A dialog showing the details of a net
@@ -74,7 +74,7 @@ public:
void set_start_layer_number (int ln);
int start_layer_number ();
int exec_dialog (lay::PluginRoot *mp_plugin_root);
int exec_dialog (lay::Dispatcher *mp_plugin_root);
protected:
void accept ();
+7 -7
View File
@@ -23,8 +23,8 @@
#include "laybasicCommon.h"
#include "layNetlistBrowserDialog.h"
#include "layConverters.h"
#include "layDispatcher.h"
#include <set>
@@ -105,7 +105,7 @@ NetlistBrowserConfigPage::NetlistBrowserConfigPage (QWidget *parent)
}
void
NetlistBrowserConfigPage::setup (lay::PluginRoot *root)
NetlistBrowserConfigPage::setup (lay::Dispatcher *root)
{
// window mode
lay::NetlistBrowserConfig::net_window_type wmode = lay::NetlistBrowserConfig::FitNet;
@@ -133,7 +133,7 @@ NetlistBrowserConfigPage::window_changed (int m)
}
void
NetlistBrowserConfigPage::commit (lay::PluginRoot *root)
NetlistBrowserConfigPage::commit (lay::Dispatcher *root)
{
double dim = 1.0;
tl::from_string (tl::to_string (le_window->text ()), dim);
@@ -195,7 +195,7 @@ NetlistBrowserConfigPage2::color_button_clicked ()
}
void
NetlistBrowserConfigPage2::setup (lay::PluginRoot *root)
NetlistBrowserConfigPage2::setup (lay::Dispatcher *root)
{
bool cycle_enabled = false;
root->config_get (cfg_l2ndb_marker_cycle_colors_enabled, cycle_enabled);
@@ -287,7 +287,7 @@ NetlistBrowserConfigPage2::update_colors ()
}
void
NetlistBrowserConfigPage2::commit (lay::PluginRoot *root)
NetlistBrowserConfigPage2::commit (lay::Dispatcher *root)
{
root->config_set (cfg_l2ndb_marker_cycle_colors_enabled, cycle_colors_cb->isChecked ());
root->config_set (cfg_l2ndb_marker_cycle_colors, m_palette.to_string ());
@@ -373,10 +373,10 @@ public:
virtual void get_menu_entries (std::vector<lay::MenuEntry> &menu_entries) const
{
lay::PluginDeclaration::get_menu_entries (menu_entries);
menu_entries.push_back (lay::MenuEntry ("netlist_browser::show", "browse_netlists", "tools_menu.end", tl::to_string (QObject::tr ("Netlist Browser"))));
menu_entries.push_back (lay::menu_item ("netlist_browser::show", "browse_netlists", "tools_menu.end", tl::to_string (QObject::tr ("Netlist Browser"))));
}
virtual lay::Plugin *create_plugin (db::Manager *, lay::PluginRoot *root, lay::LayoutView *view) const
virtual lay::Plugin *create_plugin (db::Manager *, lay::Dispatcher *root, lay::LayoutView *view) const
{
return new lay::NetlistBrowserDialog (root, view);
}
+4 -4
View File
@@ -50,8 +50,8 @@ class NetlistBrowserConfigPage
public:
NetlistBrowserConfigPage (QWidget *parent);
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
public slots:
void window_changed (int);
@@ -66,8 +66,8 @@ class NetlistBrowserConfigPage2
public:
NetlistBrowserConfigPage2 (QWidget *parent);
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
public slots:
void color_button_clicked ();
@@ -56,7 +56,7 @@ extern const std::string cfg_l2ndb_max_shapes_highlighted;
extern const std::string cfg_l2ndb_show_all;
extern const std::string cfg_l2ndb_window_state;
NetlistBrowserDialog::NetlistBrowserDialog (lay::PluginRoot *root, lay::LayoutView *vw)
NetlistBrowserDialog::NetlistBrowserDialog (lay::Dispatcher *root, lay::LayoutView *vw)
: lay::Browser (root, vw),
lay::ViewService (vw->view_object_widget ()),
Ui::NetlistBrowserDialog (),
@@ -76,7 +76,7 @@ NetlistBrowserDialog::NetlistBrowserDialog (lay::PluginRoot *root, lay::LayoutVi
{
Ui::NetlistBrowserDialog::setupUi (this);
browser_page->set_plugin_root (root);
browser_page->set_dispatcher (root);
if (view ()) {
view ()->cellviews_changed_event.add (this, &NetlistBrowserDialog::cellviews_changed);
@@ -132,7 +132,7 @@ NetlistBrowserDialog::configure_clicked ()
{
release_mouse ();
lay::ConfigurationDialog config_dialog (this, lay::PluginRoot::instance (), "NetlistBrowserPlugin");
lay::ConfigurationDialog config_dialog (this, lay::Dispatcher::instance (), "NetlistBrowserPlugin");
config_dialog.exec ();
}
@@ -747,8 +747,8 @@ NetlistBrowserDialog::deactivated ()
{
release_mouse ();
if (lay::PluginRoot::instance ()) {
lay::PluginRoot::instance ()->config_set (cfg_l2ndb_window_state, lay::save_dialog_state (this, false /*don't store the section sizes*/).c_str ());
if (lay::Dispatcher::instance ()) {
lay::Dispatcher::instance ()->config_set (cfg_l2ndb_window_state, lay::save_dialog_state (this, false /*don't store the section sizes*/).c_str ());
}
browser_page->set_l2ndb (0);
@@ -41,7 +41,7 @@ class NetlistBrowserDialog
Q_OBJECT
public:
NetlistBrowserDialog (lay::PluginRoot *root, lay::LayoutView *view);
NetlistBrowserDialog (lay::Dispatcher *root, lay::LayoutView *view);
~NetlistBrowserDialog ();
void load (int lay_index, int cv_index);
@@ -219,7 +219,7 @@ NetlistBrowserPage::is_netlist_mode ()
}
void
NetlistBrowserPage::set_plugin_root (lay::PluginRoot *pr)
NetlistBrowserPage::set_dispatcher (lay::Dispatcher *pr)
{
mp_plugin_root = pr;
}
@@ -42,7 +42,7 @@ namespace lay
{
class LayoutView;
class PluginRoot;
class Dispatcher;
class Marker;
class NetInfoDialog;
class LayerPropertiesConstIterator;
@@ -76,7 +76,7 @@ public:
/**
* @brief Sets the plugin root object for this object
*/
void set_plugin_root (lay::PluginRoot *pr);
void set_dispatcher (lay::Dispatcher *pr);
/**
* @brief Attaches the page to a view
@@ -199,7 +199,7 @@ private:
bool m_use_original_colors;
lay::LayoutView *mp_view;
unsigned int m_cv_index;
lay::PluginRoot *mp_plugin_root;
lay::Dispatcher *mp_plugin_root;
tl::weak_ptr<db::LayoutToNetlist> mp_database;
std::vector<void *> m_history;
size_t m_history_ptr;
+193 -257
View File
@@ -21,7 +21,6 @@
*/
#include "layAbstractMenuProvider.h"
#include "laybasicCommon.h"
#include "tlException.h"
@@ -30,6 +29,7 @@
#include "tlLog.h"
#include "layPlugin.h"
#include "layDispatcher.h"
#include "tlExceptions.h"
#include "tlClassRegistry.h"
@@ -56,8 +56,8 @@ PluginDeclaration::PluginDeclaration ()
PluginDeclaration::~PluginDeclaration ()
{
if (PluginRoot::instance ()) {
PluginRoot::instance ()->plugin_removed (this);
if (Dispatcher::instance ()) {
Dispatcher::instance ()->plugin_removed (this);
}
}
@@ -69,61 +69,82 @@ PluginDeclaration::toggle_editable_enabled ()
END_PROTECTED
}
void
PluginDeclaration::generic_menu ()
std::vector<std::string>
PluginDeclaration::menu_symbols ()
{
BEGIN_PROTECTED
std::vector<std::string> symbols;
QAction *action = dynamic_cast <QAction *> (sender ());
tl_assert (action);
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
std::string symbol = tl::to_string (action->data ().toString ());
std::vector<lay::MenuEntry> menu_entries;
cls->get_menu_entries (menu_entries);
// Global handler: give the declaration a chance to handle the menu request globally
if (menu_activated (symbol)) {
return;
}
// Forward the request to the plugin root which will propagate it down to the plugins
lay::PluginRoot::instance ()->menu_activated (symbol);
END_PROTECTED
}
void
PluginDeclaration::mode_triggered ()
{
BEGIN_PROTECTED
QAction *action = dynamic_cast<QAction *> (sender ());
if (action) {
int mode = action->data ().toInt ();
if (lay::PluginRoot::instance ()) {
lay::PluginRoot::instance ()->select_mode (mode);
for (std::vector<lay::MenuEntry>::const_iterator m = menu_entries.begin (); m != menu_entries.end (); ++m) {
if (! m->symbol.empty ()) {
symbols.push_back (m->symbol);
}
}
action->setChecked (true);
}
END_PROTECTED
std::sort (symbols.begin (), symbols.end ());
symbols.erase (std::unique (symbols.begin (), symbols.end ()), symbols.end ());
return symbols;
}
void
PluginDeclaration::init_menu ()
namespace {
class GenericMenuAction
: public Action
{
if (! lay::AbstractMenuProvider::instance () || ! lay::AbstractMenuProvider::instance ()->menu ()) {
return;
public:
GenericMenuAction (Dispatcher *dispatcher, const std::string &title, const std::string &symbol)
: Action (title), mp_dispatcher (dispatcher), m_symbol (symbol)
{ }
void triggered ()
{
if (mp_dispatcher) {
mp_dispatcher->menu_activated (m_symbol);
}
}
lay::AbstractMenu &menu = *lay::AbstractMenuProvider::instance ()->menu ();
private:
Dispatcher *mp_dispatcher;
std::string m_symbol;
};
// pre-initialize to allow multiple init_menu calls
m_editable_mode_action = lay::Action ();
m_mouse_mode_action = lay::Action ();
m_menu_actions.clear ();
class ModeAction
: public Action
{
public:
ModeAction (Dispatcher *dispatcher, const std::string &title, int mode)
: Action (title), mp_dispatcher (dispatcher), m_mode (mode)
{ }
void triggered ()
{
if (mp_dispatcher) {
mp_dispatcher->select_mode (m_mode);
set_checked (true);
}
}
private:
Dispatcher *mp_dispatcher;
int m_mode;
};
}
void
PluginDeclaration::init_menu (lay::Dispatcher *dispatcher)
{
lay::AbstractMenu &menu = *dispatcher->menu ();
mp_editable_mode_action.reset ((Action *) 0);
mp_mouse_mode_action.reset ((Action *) 0);
std::string title;
@@ -141,13 +162,12 @@ PluginDeclaration::init_menu ()
title = tab + 1;
}
m_editable_mode_action = Action (title);
gtf::action_connect (m_editable_mode_action.qaction (), SIGNAL (triggered ()), this, SLOT (toggle_editable_enabled ()));
m_editable_mode_action.qaction ()->setData (id ());
m_editable_mode_action.set_checkable (true);
m_editable_mode_action.set_checked (m_editable_enabled);
mp_editable_mode_action.reset (new Action (title));
gtf::action_connect (mp_editable_mode_action->qaction (), SIGNAL (triggered ()), this, SLOT (toggle_editable_enabled ()));
mp_editable_mode_action->set_checkable (true);
mp_editable_mode_action->set_checked (m_editable_enabled);
menu.insert_item ("edit_menu.select_menu.end", name, m_editable_mode_action);
menu.insert_item ("edit_menu.select_menu.end", name, mp_editable_mode_action.get ());
}
@@ -157,67 +177,98 @@ PluginDeclaration::init_menu ()
for (std::vector<lay::MenuEntry>::const_iterator m = menu_entries.begin (); m != menu_entries.end (); ++m) {
if (m->title.empty ()) {
if (! m->copy_from.empty ()) {
menu.insert_item (m->insert_pos, m->menu_name, menu.action (m->copy_from));
} else if (m->separator) {
menu.insert_separator (m->insert_pos, m->menu_name);
} else if (m->sub_menu) {
menu.insert_menu (m->insert_pos, m->menu_name, m->title);
} else {
if (m->sub_menu) {
menu.insert_menu (m->insert_pos, m->menu_name, m->title);
Action *action = 0;
if (! m->cname.empty ()) {
action = new ConfigureAction (m->title, m->cname, m->cvalue);
} else {
action = new GenericMenuAction (dispatcher, m->title, m->symbol);
}
Action action (m->title);
action.qaction ()->setData (QVariant (tl::to_qstring (m->symbol)));
gtf::action_connect (action.qaction (), SIGNAL (triggered ()), this, SLOT (generic_menu ()));
menu.insert_item (m->insert_pos, m->menu_name, action);
m_menu_actions.push_back (action);
menu.insert_item (m->insert_pos, m->menu_name, action);
m_menu_actions.push_back (action);
if (! m->exclusive_group.empty ()) {
action->add_to_exclusive_group (&menu, m->exclusive_group);
}
if (m->checkable) {
action->set_checkable (true);
}
}
}
// Fill the mode menu file items from the mouse modes
// Fill the mode menu file items from the mouse modes
std::vector<std::pair<std::string, std::pair<std::string, int> > > modes;
title = std::string ();
if (implements_mouse_mode (title)) {
modes.push_back (std::make_pair (title, std::make_pair ("edit_menu.mode_menu.end;@toolbar.end_modes", id ())));
}
// the primary mouse modes (special for LayoutView)
implements_primary_mouse_modes (modes);
for (std::vector<std::pair<std::string, std::pair<std::string, int> > >::const_iterator m = modes.begin (); m != modes.end (); ++m) {
// extract first part, which is the name, separated by a tab from the title.
std::string name = tl::sprintf ("mode_%d", id ());
std::string name;
if (m->second.second <= 0) {
name = tl::sprintf ("mode_i%d", 1 - m->second.second);
} else {
name = tl::sprintf ("mode_%d", m->second.second);
}
std::string title = m->first;
const char *tab = strchr (title.c_str (), '\t');
if (tab) {
name = std::string (title, 0, tab - title.c_str ());
title = std::string (tab + 1);
}
m_mouse_mode_action = Action (title);
m_mouse_mode_action.add_to_exclusive_group (&menu, "mouse_mode_exclusive_group");
mp_mouse_mode_action.reset (new ModeAction (dispatcher, title, m->second.second));
mp_mouse_mode_action->add_to_exclusive_group (&menu, "mouse_mode_exclusive_group");
mp_mouse_mode_action->set_checkable (true);
m_mouse_mode_action.set_checkable (true);
m_mouse_mode_action.qaction ()->setData (QVariant (id ()));
menu.insert_item ("edit_menu.mode_menu.end", name, m_mouse_mode_action);
menu.insert_item ("@toolbar.end_modes", name, m_mouse_mode_action);
gtf::action_connect (m_mouse_mode_action.qaction (), SIGNAL (triggered ()), this, SLOT (mode_triggered ()));
menu.insert_item (m->second.first, name + ":mode_group", mp_mouse_mode_action.get ());
}
}
void
PluginDeclaration::remove_menu_items ()
PluginDeclaration::remove_menu_items (Dispatcher *dispatcher)
{
if (! lay::AbstractMenuProvider::instance () || ! lay::AbstractMenuProvider::instance ()->menu ()) {
return;
}
lay::AbstractMenu *menu = dispatcher->menu ();
menu->delete_items (mp_editable_mode_action.get ());
menu->delete_items (mp_mouse_mode_action.get ());
lay::AbstractMenu *menu = lay::AbstractMenuProvider::instance ()->menu ();
menu->delete_items (m_editable_mode_action);
menu->delete_items (m_mouse_mode_action);
for (std::vector <lay::Action>::const_iterator a = m_menu_actions.begin (); a != m_menu_actions.end (); ++a) {
std::vector<lay::Action *> actions;
for (tl::weak_collection <lay::Action>::iterator a = m_menu_actions.begin (); a != m_menu_actions.end (); ++a) {
if (a.operator-> ()) {
actions.push_back (a.operator-> ());
}
}
for (std::vector<lay::Action *>::const_iterator a = actions.begin (); a != actions.end (); ++a) {
menu->delete_items (*a);
}
m_menu_actions.clear ();
}
void
@@ -225,7 +276,9 @@ PluginDeclaration::set_editable_enabled (bool f)
{
if (f != m_editable_enabled) {
m_editable_enabled = f;
m_editable_mode_action.set_checked (f);
if (mp_editable_mode_action.get ()) {
mp_editable_mode_action->set_checked (f);
}
editable_enabled_changed_event ();
}
}
@@ -233,9 +286,9 @@ PluginDeclaration::set_editable_enabled (bool f)
void
PluginDeclaration::register_plugin ()
{
if (PluginRoot::instance ()) {
PluginRoot::instance ()->plugin_registered (this);
initialize (PluginRoot::instance ());
if (Dispatcher::instance ()) {
Dispatcher::instance ()->plugin_registered (this);
initialize (Dispatcher::instance ());
}
}
@@ -365,23 +418,26 @@ Plugin::get_config_names (std::vector<std::string> &names) const
}
}
PluginRoot *
Plugin::plugin_root ()
{
PluginRoot *pr = plugin_root_maybe_null ();
tl_assert (pr != 0);
return pr;
}
PluginRoot *
Plugin::plugin_root_maybe_null ()
Dispatcher *
Plugin::dispatcher ()
{
Plugin *p = this;
while (p->mp_parent) {
p = p->mp_parent;
}
return dynamic_cast<PluginRoot *> (p);
return dynamic_cast<Dispatcher *> (p);
}
Dispatcher *
Plugin::dispatcher_maybe_null ()
{
Plugin *p = this;
while (p->mp_parent) {
p = p->mp_parent;
}
return dynamic_cast<Dispatcher *> (p);
}
void
@@ -431,188 +487,68 @@ Plugin::do_config_set (const std::string &name, const std::string &value, bool f
return false;
}
// ----------------------------------------------------------------
// PluginRoot implementation
// ---------------------------------------------------------------------------------------------------
// Menu item generators
static PluginRoot *ms_root_instance = 0;
PluginRoot::PluginRoot (bool standalone)
: Plugin (0, standalone)
MenuEntry separator (const std::string &menu_name, const std::string &insert_pos)
{
ms_root_instance = this;
MenuEntry e;
e.menu_name = menu_name;
e.insert_pos = insert_pos;
e.separator = true;
return e;
}
PluginRoot::~PluginRoot ()
MenuEntry menu_item (const std::string &symbol, const std::string &menu_name, const std::string &insert_pos, const std::string &title)
{
if (ms_root_instance == this) {
ms_root_instance = 0;
}
MenuEntry e;
e.symbol = symbol;
e.menu_name = menu_name;
e.insert_pos = insert_pos;
e.title = title;
return e;
}
// Writing and Reading of configuration
struct ConfigGetAdaptor
MenuEntry menu_item_copy (const std::string &symbol, const std::string &menu_name, const std::string &insert_pos, const std::string &copy_from)
{
ConfigGetAdaptor (const std::string &name)
: mp_owner (0), m_done (false), m_name (name)
{
// .. nothing yet ..
}
std::string operator () () const
{
std::string s;
mp_owner->config_get (m_name, s);
return s;
}
bool at_end () const
{
return m_done;
}
void start (const lay::PluginRoot &owner)
{
mp_owner = &owner;
m_done = false;
}
void next ()
{
m_done = true;
}
private:
const lay::PluginRoot *mp_owner;
bool m_done;
std::string m_name;
};
struct ConfigGetNullAdaptor
{
ConfigGetNullAdaptor ()
{
// .. nothing yet ..
}
std::string operator () () const
{
return std::string ();
}
bool at_end () const
{
return true;
}
void start (const lay::PluginRoot & /*owner*/) { }
void next () { }
};
struct ConfigNamedSetAdaptor
{
ConfigNamedSetAdaptor ()
{
// .. nothing yet ..
}
void operator () (lay::PluginRoot &w, tl::XMLReaderState &reader, const std::string &name) const
{
tl::XMLObjTag<std::string> tag;
w.config_set (name, *reader.back (tag));
}
};
struct ConfigSetAdaptor
{
ConfigSetAdaptor (const std::string &name)
: m_name (name)
{
// .. nothing yet ..
}
void operator () (lay::PluginRoot &w, tl::XMLReaderState &reader) const
{
tl::XMLObjTag<std::string> tag;
w.config_set (m_name, *reader.back (tag));
}
private:
std::string m_name;
};
// the configuration file's XML structure is built dynamically
static tl::XMLStruct<lay::PluginRoot>
config_structure (const lay::PluginRoot *plugin)
{
tl::XMLElementList body;
std::string n_with_underscores;
std::vector <std::string> names;
plugin->get_config_names (names);
for (std::vector <std::string>::const_iterator n = names.begin (); n != names.end (); ++n) {
body.append (tl::XMLMember<std::string, lay::PluginRoot, ConfigGetAdaptor, ConfigSetAdaptor, tl::XMLStdConverter <std::string> > (
ConfigGetAdaptor (*n), ConfigSetAdaptor (*n), *n));
// for compatibility, provide an alternative with underscores (i.e. 0.20->0.21 because of default_grids)
n_with_underscores.clear ();
for (const char *c = n->c_str (); *c; ++c) {
n_with_underscores += (*c == '-' ? '_' : *c);
}
body.append (tl::XMLMember<std::string, lay::PluginRoot, ConfigGetNullAdaptor, ConfigSetAdaptor, tl::XMLStdConverter <std::string> > (
ConfigGetNullAdaptor (), ConfigSetAdaptor (*n), n_with_underscores));
}
// add a wildcard member to read all others unspecifically into the repository
body.append (tl::XMLWildcardMember<std::string, lay::PluginRoot, ConfigNamedSetAdaptor, tl::XMLStdConverter <std::string> > (ConfigNamedSetAdaptor ()));
return tl::XMLStruct<lay::PluginRoot> ("config", body);
MenuEntry e;
e.symbol = symbol;
e.menu_name = menu_name;
e.insert_pos = insert_pos;
e.copy_from = copy_from;
return e;
}
bool
PluginRoot::write_config (const std::string &config_file)
MenuEntry submenu (const std::string &menu_name, const std::string &insert_pos, const std::string &title)
{
try {
tl::OutputStream os (config_file, tl::OutputStream::OM_Plain);
config_structure (this).write (os, *this);
return true;
} catch (...) {
return false;
}
MenuEntry e;
e.menu_name = menu_name;
e.insert_pos = insert_pos;
e.title = title;
e.sub_menu = true;
return e;
}
bool
PluginRoot::read_config (const std::string &config_file)
MenuEntry submenu (const std::string &symbol, const std::string &menu_name, const std::string &insert_pos, const std::string &title)
{
std::auto_ptr<tl::XMLFileSource> file;
try {
file.reset (new tl::XMLFileSource (config_file));
} catch (...) {
return false;
}
try {
config_structure (this).parse (*file, *this);
} catch (tl::Exception &ex) {
std::string msg = tl::to_string (QObject::tr ("Problem reading config file ")) + config_file + ": " + ex.msg ();
throw tl::Exception (msg);
}
config_end ();
return true;
MenuEntry e;
e.symbol = symbol;
e.menu_name = menu_name;
e.insert_pos = insert_pos;
e.title = title;
e.sub_menu = true;
return e;
}
PluginRoot *
PluginRoot::instance ()
MenuEntry config_menu_item (const std::string &menu_name, const std::string &insert_pos, const std::string &title, const std::string &cname, const std::string &cvalue)
{
return ms_root_instance;
MenuEntry e;
e.menu_name = menu_name;
e.insert_pos = insert_pos;
e.title = title;
e.cname = cname;
e.cvalue = cvalue;
return e;
}
}
+104 -123
View File
@@ -47,7 +47,7 @@ namespace lay
{
class Plugin;
class PluginRoot;
class Dispatcher;
class LayoutView;
class Browser;
class ViewService;
@@ -77,7 +77,7 @@ public:
* The implementation is supposed to fetch the configuration from the
* Plugin object provided and load the widgets accordingly.
*/
virtual void setup (PluginRoot * /*root*/)
virtual void setup (Dispatcher * /*root*/)
{
// the default implementation does nothing.
}
@@ -89,7 +89,7 @@ public:
* throw exceptions if the configuration something is invalid)
* and commit the changes through
*/
virtual void commit (PluginRoot * /*root*/)
virtual void commit (Dispatcher * /*root*/)
{
// the default implementation does nothing.
}
@@ -98,42 +98,83 @@ public:
/**
* @brief A menu entry declaration
* See separator, menu_item, submenu and config_menu_item below.
*/
struct LAYBASIC_PUBLIC MenuEntry
{
/**
* @brief A declaration for a separator
*
* @param menu_name The name of the menu item (see layAbstractMenu.h)
* @param insert_pos The position where to insert (see layAbstractMenu.h)
*/
MenuEntry (const std::string &menu_name_, const std::string &insert_pos_)
: menu_name (menu_name_), insert_pos (insert_pos_), sub_menu (false)
{
// ..
}
/**
* @brief A declaration for a menu entry
*
* @param symbol The symbol to send when this menu item is selected
* @param menu_name The name of the menu item (see layAbstractMenu.h)
* @param insert_pos The position where to insert (see layAbstractMenu.h)
* @param title The title to display plus optional icon resource and keyboard shortcut. The format of the string is: <text>["("shortcut")"]["<"icon-resource">"][{"tool-tip"}].
*/
MenuEntry (const std::string &symbol_, const std::string &menu_name_, const std::string &insert_pos_, const std::string &title_, bool sub_menu_ = false)
: menu_name (menu_name_), symbol (symbol_), insert_pos (insert_pos_), title (title_), sub_menu (sub_menu_)
{
// ..
}
MenuEntry () : sub_menu (false), checkable (false), separator (false) { }
std::string menu_name;
std::string symbol;
std::string insert_pos;
std::string title;
std::string copy_from;
std::string cname;
std::string cvalue;
std::string exclusive_group;
bool sub_menu;
bool checkable;
bool separator;
};
/**
* @brief Creates a separator menu entry
*
* @param menu_name The name of the menu item (see layAbstractMenu.h)
* @param insert_pos The position where to insert (see layAbstractMenu.h)
*/
LAYBASIC_PUBLIC MenuEntry separator (const std::string &menu_name, const std::string &insert_pos);
/**
* @brief Creates a normal menu entry
*
* @param symbol The symbol to send when this menu item is selected
* @param menu_name The name of the menu item (see layAbstractMenu.h)
* @param insert_pos The position where to insert (see layAbstractMenu.h)
* @param title The title to display plus optional icon resource and keyboard shortcut. The format of the string is: <text>["("shortcut")"]["<"icon-resource">"][{"tool-tip"}].
*/
LAYBASIC_PUBLIC MenuEntry menu_item (const std::string &symbol, const std::string &menu_name, const std::string &insert_pos, const std::string &title);
/**
* @brief Creates a menu entry as a linked copy from another one
*
* @param symbol The symbol to send when this menu item is selected
* @param menu_name The name of the menu item (see layAbstractMenu.h)
* @param insert_pos The position where to insert (see layAbstractMenu.h)
* @param copy_from The path of the item where to copy from (must exist)
*/
LAYBASIC_PUBLIC MenuEntry menu_item_copy (const std::string &symbol, const std::string &menu_name, const std::string &insert_pos, const std::string &copy_from);
/**
* @brief Creates a submenu entry
*
* @param menu_name The name of the menu item (see layAbstractMenu.h)
* @param insert_pos The position where to insert (see layAbstractMenu.h)
* @param title The title to display plus optional icon resource and keyboard shortcut. The format of the string is: <text>["("shortcut")"]["<"icon-resource">"][{"tool-tip"}].
*/
LAYBASIC_PUBLIC MenuEntry submenu (const std::string &menu_name, const std::string &insert_pos, const std::string &title);
/**
* @brief Creates a submenu entry
*
* @param symbol The symbol to send when this menu item is selected
* @param menu_name The name of the menu item (see layAbstractMenu.h)
* @param insert_pos The position where to insert (see layAbstractMenu.h)
* @param title The title to display plus optional icon resource and keyboard shortcut. The format of the string is: <text>["("shortcut")"]["<"icon-resource">"][{"tool-tip"}].
*/
LAYBASIC_PUBLIC MenuEntry submenu (const std::string &symbol, const std::string &menu_name, const std::string &insert_pos, const std::string &title);
/**
* @brief Creates a configuration entry
*
* @param menu_name The name of the menu item (see layAbstractMenu.h)
* @param insert_pos The position where to insert (see layAbstractMenu.h)
* @param title The title to display plus optional icon resource and keyboard shortcut. The format of the string is: <text>["("shortcut")"]["<"icon-resource">"][{"tool-tip"}].
* @param cname The name of the configuration item
* @param cvalue The value to set for the configuration item (optional for boolean configuration items)
*/
LAYBASIC_PUBLIC MenuEntry config_menu_item (const std::string &menu_name, const std::string &insert_pos, const std::string &title, const std::string &cname, const std::string &cvalue = std::string ());
/**
* @brief The configuration declaration
*
@@ -238,7 +279,7 @@ public:
* Reimplementation of this method offers a chance to initialize static resources such as
* dialogs etc.
*/
virtual void initialize (lay::PluginRoot * /*root*/)
virtual void initialize (lay::Dispatcher * /*dispatcher*/)
{
// .. the default implementation does nothing ..
}
@@ -251,7 +292,7 @@ public:
* While initialize is called before any configuration is loaded, "initialized" will be
* called after the pugin system has been initially configured.
*/
virtual void initialized (lay::PluginRoot * /*root*/)
virtual void initialized (lay::Dispatcher * /*dispatcher*/)
{
// .. the default implementation does nothing ..
}
@@ -259,7 +300,7 @@ public:
/**
* @brief Uninitialize the plugin
*/
virtual void uninitialize (lay::PluginRoot * /*root*/)
virtual void uninitialize (lay::Dispatcher * /*dispatcher*/)
{
// .. the default implementation does nothing ..
}
@@ -270,7 +311,7 @@ public:
* If the plugin wants to prevent the application from closing, it may return false
* in this method.
*/
virtual bool can_exit (lay::PluginRoot * /*root*/) const
virtual bool can_exit (lay::Dispatcher * /*dispatcher*/) const
{
return true;
}
@@ -292,7 +333,7 @@ public:
* This method may return 0 for "dummy" plugins that just register menu entries
* or configuration options.
*/
virtual lay::Plugin *create_plugin (db::Manager * /*manager*/, lay::PluginRoot * /*plugin_root*/, lay::LayoutView * /*view*/) const
virtual lay::Plugin *create_plugin (db::Manager * /*manager*/, lay::Dispatcher * /*dispatcher*/, lay::LayoutView * /*view*/) const
{
return 0;
}
@@ -322,6 +363,17 @@ public:
{
return false;
}
/**
* @brief Specifies the primary mouse modes
*
* These are built-in modes from the LayoutView. This method is intended for
* the LayoutView's standard modes only.
*/
virtual void implements_primary_mouse_modes (std::vector<std::pair<std::string, std::pair<std::string, int> > > & /*modes*/)
{
// .. nothing yet ..
}
/**
* @brief Returns the technology component provider
@@ -354,14 +406,22 @@ public:
* @brief Creates the menu resources for this plugin
*
* This method will create the menu resources for the plugin and perform the
* required connect operations.
* required connect operations. The dispatcher provides the menu and the
* event endpoints.
*/
void init_menu ();
void init_menu (lay::Dispatcher *dispatcher);
/**
* @brief Gets the available menu symbols from all plugins
*
* This does not mean all symbols will be available.
*/
static std::vector<std::string> menu_symbols ();
/**
* @brief Removes the menu resources associated with this plugin
*/
void remove_menu_items ();
void remove_menu_items (lay::Dispatcher *dispatcher);
/**
* @brief Enables this editable part of the plugin
@@ -397,7 +457,7 @@ public:
}
/**
* @brief Notifies that plugin root that a new plugin was registered
* @brief Notifies that dispatcher that a new plugin was registered
*
* This method must be called when a plugin is dynamically created. It is important
* that when this method is called, the menu items and other properties are set already.
@@ -411,14 +471,12 @@ public:
private slots:
void toggle_editable_enabled ();
void generic_menu ();
void mode_triggered ();
private:
int m_id;
std::vector <lay::Action> m_menu_actions;
lay::Action m_editable_mode_action;
lay::Action m_mouse_mode_action;
tl::weak_ptr<lay::Action> mp_editable_mode_action;
tl::weak_ptr<lay::Action> mp_mouse_mode_action;
tl::weak_collection<lay::Action> m_menu_actions;
bool m_editable_enabled;
};
@@ -634,17 +692,17 @@ public:
void get_config_names (std::vector<std::string> &names) const;
/**
* @brief Gets the plugin root (the parent plugin not having another parent)
* @brief Gets the dispatcher (the top level end of the plugin chain)
* The returned pointer is guaranteed to be non-zero.
*/
PluginRoot *plugin_root ();
Dispatcher *dispatcher ();
/**
* @brief Gets the plugin root (the parent plugin not having another parent)
* @brief Gets the dispatcher (the top level end of the plugin chain)
* This version may return null, if the plugin is instantiated without a
* root.
*/
PluginRoot *plugin_root_maybe_null ();
Dispatcher *dispatcher_maybe_null ();
/**
* @brief Menu command handler
@@ -790,78 +848,6 @@ private:
bool m_standalone;
};
/**
* @brief The plugin root element
*
* The first (root) object must be derived from this class.
* This class offers the full "plugin" functionality like
* configuration interface etc. but cannot have a parent.
*/
class LAYBASIC_PUBLIC PluginRoot
: public Plugin
{
public:
/**
* @brief The constructor
*/
PluginRoot (bool standalone = false);
/**
* @brief Destructor
*/
~PluginRoot ();
/**
* @brief Write configuration to a file
*
* If the configuration file cannot be written, false
* is returned but no exception is thrown.
*
* @return false, if an error occurred.
*/
bool write_config (const std::string &config_file);
/**
* @brief Read the configuration from a file
*
* This method siletly does nothing, if the config file does not
* exist. If it does and an error occurred, the error message is printed
* on stderr. In both cases, false is returned.
*
* @return false, if an error occurred.
*/
bool read_config (const std::string &config_file);
/**
* @brief The singleton instance of the plugin root
*/
static PluginRoot *instance ();
/**
* @brief Notifies the plugin root that a new plugin class has been registered
*
* This method is called when a plugin is loaded dynamically during runtime.
*/
virtual void plugin_registered (lay::PluginDeclaration * /*cls*/) { }
/**
* @brief Notifies the plugin root that a plugin class is about to be removed
*/
virtual void plugin_removed (lay::PluginDeclaration * /*cls*/) { }
/**
* @brief Selects the given mode
*
* The implementation is supposed to select the given mode on all related plugins.
*/
virtual void select_mode (int /*mode*/) { }
private:
PluginRoot (const PluginRoot &);
PluginRoot &operator= (const PluginRoot &);
};
/**
* @brief A handy function for implementing the configure method
*
@@ -885,11 +871,6 @@ inline bool test_and_set (T &target, const T &source)
namespace tl
{
// disable copy ctor for PluginRoot
template <> struct type_traits<lay::PluginRoot> : public type_traits<void> {
typedef tl::false_tag has_copy_constructor;
};
// disable copy ctor for Plugin
template <> struct type_traits<lay::Plugin> : public type_traits<void> {
typedef tl::false_tag has_copy_constructor;
@@ -230,7 +230,7 @@ SaveLayoutOptionsDialog::update ()
}
bool
SaveLayoutOptionsDialog::edit_global_options (lay::PluginRoot *config_root, db::Technologies *technologies)
SaveLayoutOptionsDialog::edit_global_options (lay::Dispatcher *config_root, db::Technologies *technologies)
{
m_opt_array.clear ();
m_tech_array.clear ();
@@ -46,7 +46,6 @@ namespace lay
{
class LayoutView;
class PluginRoot;
class LAYBASIC_PUBLIC SaveLayoutAsOptionsDialog
: public QDialog, private Ui::SaveLayoutAsOptionsDialog
@@ -80,7 +79,7 @@ public:
SaveLayoutOptionsDialog (QWidget *parent, const std::string &title);
~SaveLayoutOptionsDialog ();
bool edit_global_options (lay::PluginRoot *config_root, db::Technologies *technologies);
bool edit_global_options (lay::Dispatcher *dispatcher, db::Technologies *technologies);
bool get_options (db::SaveLayoutOptions &options);
public slots:
@@ -0,0 +1,136 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2020 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "laySelectCellViewForm.h"
#include "layCellView.h"
#include "layLayoutView.h"
namespace lay
{
// ------------------------------------------------------------
SelectCellViewForm::SelectCellViewForm (QWidget *parent, lay::LayoutView *view, const std::string &title, bool single)
: QDialog (parent), Ui::SelectCellViewForm ()
{
setObjectName (QString::fromUtf8 ("select_cv"));
Ui::SelectCellViewForm::setupUi (this);
if (single) {
cvs_lb->setSelectionMode (QAbstractItemView::SingleSelection);
}
// signals and slots connections
connect( ok_button, SIGNAL( clicked() ), this, SLOT( accept() ) );
connect( cancel_button, SIGNAL( clicked() ), this, SLOT( reject() ) );
connect( select_all_pb, SIGNAL( clicked() ), this, SLOT( select_all() ) );
if (single) {
select_all_pb->hide ();
}
for (unsigned int i = 0; i < view->cellviews (); ++i) {
tell_cellview (view->cellview (i));
}
set_title (title);
}
void
SelectCellViewForm::set_selection (int sel)
{
for (int i = 0; i < int (cvs_lb->count ()); ++i) {
cvs_lb->setItemSelected (cvs_lb->item (i), false);
}
if (sel >= 0 && sel < int (cvs_lb->count ())) {
cvs_lb->setCurrentItem (cvs_lb->item (sel));
cvs_lb->setItemSelected (cvs_lb->item (sel), true);
}
}
void
SelectCellViewForm::set_title (const std::string &title)
{
title_lbl->setText (tl::to_qstring (title));
}
void
SelectCellViewForm::set_caption (const std::string &caption)
{
setWindowTitle (tl::to_qstring (caption));
}
void
SelectCellViewForm::tell_cellview (const lay::CellView &cv)
{
cvs_lb->addItem (tl::to_qstring (cv->name ()));
cvs_lb->setCurrentItem (0);
cvs_lb->setItemSelected (cvs_lb->item (0), true);
}
bool
SelectCellViewForm::all_selected () const
{
for (int i = 0; i < int (cvs_lb->count ()); ++i) {
if (! cvs_lb->isItemSelected (cvs_lb->item (i))) {
return false;
}
}
return true;
}
std::vector <int>
SelectCellViewForm::selected_cellviews () const
{
std::vector <int> res;
for (int i = 0; i < int (cvs_lb->count ()); ++i) {
if (cvs_lb->isItemSelected (cvs_lb->item (i))) {
res.push_back (i);
}
}
return res;
}
int
SelectCellViewForm::selected_cellview () const
{
for (int i = 0; i < int (cvs_lb->count ()); ++i) {
if (cvs_lb->isItemSelected (cvs_lb->item (i))) {
return i;
}
}
return -1;
}
void
SelectCellViewForm::select_all ()
{
cvs_lb->clearSelection (); // without this, not all items may be selected in "selectAll"
cvs_lb->selectAll ();
}
}
@@ -0,0 +1,92 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2020 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef HDR_SelectCellViewForm
#define HDR_SelectCellViewForm
#include "laybasicCommon.h"
#include <string>
#include <vector>
#include <QDialog>
#include "ui_SelectCellViewForm.h"
namespace lay
{
class CellView;
class LayoutView;
class LAYBASIC_PUBLIC SelectCellViewForm
: public QDialog, private Ui::SelectCellViewForm
{
Q_OBJECT
public:
SelectCellViewForm (QWidget *parent, lay::LayoutView *view, const std::string &title, bool single = false);
/**
* @brief Set the selection to a single selection
*/
void set_selection (int sel);
/**
* @brief Set the title
*/
void set_title (const std::string &title);
/**
* @brief Set the caption
*/
void set_caption (const std::string &caption);
/**
* @brief This method must be called on all cv's before setup () to make the cv's known
*/
void tell_cellview (const lay::CellView &cv);
/**
* @brief Obtain the selected cellview's index (with changes)
*/
std::vector <int> selected_cellviews () const;
/**
* @brief Obtain the selected cellview's index (in single selection mode)
*/
int selected_cellview () const;
/**
* @brief Return true, if all cellviews are selected
*/
bool all_selected () const;
public slots:
virtual void select_all ();
};
}
#endif
+1 -1
View File
@@ -44,7 +44,7 @@ namespace db
namespace lay
{
class PluginRoot;
class Dispatcher;
class LayoutHandle;
/**
+7 -6
View File
@@ -24,6 +24,7 @@
#include "layTipDialog.h"
#include "laybasicConfig.h"
#include "layPlugin.h"
#include "layDispatcher.h"
#include "layDialogs.h"
#include "layQtTools.h"
@@ -134,8 +135,8 @@ TipDialog::do_exec_dialog (button_type *button)
mp_res = button;
std::string th;
if (lay::PluginRoot::instance ()) {
lay::PluginRoot::instance ()->config_get (cfg_tip_window_hidden, th);
if (lay::Dispatcher::instance ()) {
lay::Dispatcher::instance ()->config_get (cfg_tip_window_hidden, th);
}
// test if we need to show this window
@@ -172,8 +173,8 @@ TipDialog::accept ()
if (mp_ui->dont_show_cbx->isChecked ()) {
std::string th;
if (lay::PluginRoot::instance ()) {
lay::PluginRoot::instance ()->config_get (cfg_tip_window_hidden, th);
if (lay::Dispatcher::instance ()) {
lay::Dispatcher::instance ()->config_get (cfg_tip_window_hidden, th);
}
if (! th.empty ()) {
@@ -183,8 +184,8 @@ TipDialog::accept ()
th += "=";
th += tl::to_string (int (*mp_res));
if (lay::PluginRoot::instance ()) {
lay::PluginRoot::instance ()->config_set (cfg_tip_window_hidden, th);
if (lay::Dispatcher::instance ()) {
lay::Dispatcher::instance ()->config_set (cfg_tip_window_hidden, th);
}
}
+2 -2
View File
@@ -197,7 +197,7 @@ DitherPatternSelectionButton::update_menu ()
lay::DitherPattern patterns;
std::string s;
lay::PluginRoot::instance ()->config_get (cfg_stipple_palette, s);
lay::Dispatcher::instance ()->config_get (cfg_stipple_palette, s);
lay::StipplePalette palette;
palette.from_string (s);
@@ -831,7 +831,7 @@ ColorButton::build_color_menu (QMenu *menu, QObject *receiver, const char *brows
try {
std::string s;
lay::PluginRoot::instance ()->config_get (cfg_color_palette, s);
lay::Dispatcher::instance ()->config_get (cfg_color_palette, s);
lay::ColorPalette palette;
palette.from_string (s);
+11 -5
View File
@@ -71,7 +71,9 @@ FORMS = \
NetlistBrowserConfigPage2.ui \
NetlistBrowserDialog.ui \
NetInfoDialog.ui \
NetExportDialog.ui
NetExportDialog.ui \
SelectCellViewForm.ui \
LayoutStatistics.ui
RESOURCES = \
laybasicResources.qrc
@@ -86,7 +88,6 @@ SOURCES = \
gsiDeclLayPlugin.cc \
gsiDeclLayStream.cc \
layAbstractMenu.cc \
layAbstractMenuProvider.cc \
layAnnotationShapes.cc \
layBitmap.cc \
layBitmapRenderer.cc \
@@ -178,12 +179,14 @@ SOURCES = \
layNetlistBrowserTreeModel.cc \
layLibrariesView.cc \
layBookmarksView.cc \
layGenericSyntaxHighlighter.cc
layGenericSyntaxHighlighter.cc \
layDispatcher.cc \
laySelectCellViewForm.cc \
layLayoutStatisticsForm.cc
HEADERS = \
gtf.h \
layAbstractMenu.h \
layAbstractMenuProvider.h \
layAnnotationShapes.h \
layBitmap.h \
layBitmapRenderer.h \
@@ -277,7 +280,10 @@ HEADERS = \
layNetlistBrowserTreeModel.h \
layLibrariesView.h \
layBookmarksView.h \
layGenericSyntaxHighlighter.h
layGenericSyntaxHighlighter.h \
layDispatcher.h \
laySelectCellViewForm.h \
layLayoutStatisticsForm.h
INCLUDEPATH += $$TL_INC $$GSI_INC $$DB_INC $$RDB_INC $$LYM_INC
DEPENDPATH += $$TL_INC $$GSI_INC $$DB_INC $$RDB_INC $$LYM_INC
+10 -9
View File
@@ -26,6 +26,7 @@
#include "dbLayout.h"
#include "layConverters.h"
#include "layDispatcher.h"
#include <set>
@@ -133,7 +134,7 @@ MarkerBrowserConfigPage::MarkerBrowserConfigPage (QWidget *parent)
}
void
MarkerBrowserConfigPage::setup (lay::PluginRoot *root)
MarkerBrowserConfigPage::setup (lay::Dispatcher *root)
{
// context mode
rdb::context_mode_type cmode = rdb::DatabaseTop;
@@ -166,7 +167,7 @@ MarkerBrowserConfigPage::window_changed (int m)
}
void
MarkerBrowserConfigPage::commit (lay::PluginRoot *root)
MarkerBrowserConfigPage::commit (lay::Dispatcher *root)
{
double dim = 1.0;
tl::from_string (tl::to_string (le_window->text ()), dim);
@@ -190,7 +191,7 @@ MarkerBrowserConfigPage2::MarkerBrowserConfigPage2 (QWidget *parent)
}
void
MarkerBrowserConfigPage2::setup (lay::PluginRoot *root)
MarkerBrowserConfigPage2::setup (lay::Dispatcher *root)
{
// marker color
QColor color;
@@ -227,7 +228,7 @@ MarkerBrowserConfigPage2::setup (lay::PluginRoot *root)
}
void
MarkerBrowserConfigPage2::commit (lay::PluginRoot *root)
MarkerBrowserConfigPage2::commit (lay::Dispatcher *root)
{
QColor color (color_pb->get_color ());
root->config_set (cfg_rdb_marker_color, color, lay::ColorConverter ());
@@ -295,13 +296,13 @@ public:
virtual void get_menu_entries (std::vector<lay::MenuEntry> &menu_entries) const
{
lay::PluginDeclaration::get_menu_entries (menu_entries);
menu_entries.push_back (lay::MenuEntry ("marker_browser::show", "browse_markers", "tools_menu.end", tl::to_string (QObject::tr ("Marker Browser"))));
menu_entries.push_back (lay::MenuEntry ("marker_browser::show", "shapes_to_markers", "tools_menu.end", tl::to_string (QObject::tr ("Shapes To Markers")), true));
menu_entries.push_back (lay::MenuEntry ("marker_browser::scan_layers", "scan_layers", "tools_menu.shapes_to_markers.end", tl::to_string (QObject::tr ("Hierarchical"))));
menu_entries.push_back (lay::MenuEntry ("marker_browser::scan_layers_flat", "scan_layers_flat", "tools_menu.shapes_to_markers.end", tl::to_string (QObject::tr ("Flat"))));
menu_entries.push_back (lay::menu_item ("marker_browser::show", "browse_markers", "tools_menu.end", tl::to_string (QObject::tr ("Marker Browser"))));
menu_entries.push_back (lay::submenu ("marker_browser::show", "shapes_to_markers", "tools_menu.end", tl::to_string (QObject::tr ("Shapes To Markers"))));
menu_entries.push_back (lay::menu_item ("marker_browser::scan_layers", "scan_layers", "tools_menu.shapes_to_markers.end", tl::to_string (QObject::tr ("Hierarchical"))));
menu_entries.push_back (lay::menu_item ("marker_browser::scan_layers_flat", "scan_layers_flat", "tools_menu.shapes_to_markers.end", tl::to_string (QObject::tr ("Flat"))));
}
virtual lay::Plugin *create_plugin (db::Manager *, lay::PluginRoot *root, lay::LayoutView *view) const
virtual lay::Plugin *create_plugin (db::Manager *, lay::Dispatcher *root, lay::LayoutView *view) const
{
return new rdb::MarkerBrowserDialog (root, view);
}
+4 -4
View File
@@ -47,8 +47,8 @@ class MarkerBrowserConfigPage
public:
MarkerBrowserConfigPage (QWidget *parent);
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
public slots:
void window_changed (int);
@@ -63,8 +63,8 @@ class MarkerBrowserConfigPage2
public:
MarkerBrowserConfigPage2 (QWidget *parent);
virtual void setup (lay::PluginRoot *root);
virtual void commit (lay::PluginRoot *root);
virtual void setup (lay::Dispatcher *root);
virtual void commit (lay::Dispatcher *root);
};
class MarkerBrowserContextModeConverter
@@ -54,7 +54,7 @@ extern std::string cfg_rdb_marker_vertex_size;
extern std::string cfg_rdb_marker_halo;
extern std::string cfg_rdb_marker_dither_pattern;
MarkerBrowserDialog::MarkerBrowserDialog (lay::PluginRoot *root, lay::LayoutView *vw)
MarkerBrowserDialog::MarkerBrowserDialog (lay::Dispatcher *root, lay::LayoutView *vw)
: lay::Browser (root, vw),
Ui::MarkerBrowserDialog (),
m_context (rdb::AnyCell),
@@ -70,7 +70,7 @@ MarkerBrowserDialog::MarkerBrowserDialog (lay::PluginRoot *root, lay::LayoutView
{
Ui::MarkerBrowserDialog::setupUi (this);
browser_frame->set_plugin_root (root);
browser_frame->set_dispatcher (root);
if (view ()) {
view ()->cellviews_changed_event.add (this, &MarkerBrowserDialog::cellviews_changed);
@@ -122,7 +122,7 @@ MarkerBrowserDialog::~MarkerBrowserDialog ()
void
MarkerBrowserDialog::configure_clicked ()
{
lay::ConfigurationDialog config_dialog (this, lay::PluginRoot::instance (), "MarkerBrowserPlugin");
lay::ConfigurationDialog config_dialog (this, lay::Dispatcher::instance (), "MarkerBrowserPlugin");
config_dialog.exec ();
}
@@ -703,8 +703,8 @@ MarkerBrowserDialog::update_content ()
void
MarkerBrowserDialog::deactivated ()
{
if (lay::PluginRoot::instance ()) {
lay::PluginRoot::instance ()->config_set (cfg_rdb_window_state, lay::save_dialog_state (this).c_str ());
if (lay::Dispatcher::instance ()) {
lay::Dispatcher::instance ()->config_set (cfg_rdb_window_state, lay::save_dialog_state (this).c_str ());
}
browser_frame->set_rdb (0);
@@ -38,7 +38,7 @@ class MarkerBrowserDialog
Q_OBJECT
public:
MarkerBrowserDialog (lay::PluginRoot *root, lay::LayoutView *view);
MarkerBrowserDialog (lay::Dispatcher *root, lay::LayoutView *view);
~MarkerBrowserDialog ();
void load (int rdb_index, int cv_index);
@@ -1603,7 +1603,7 @@ MarkerBrowserPage::~MarkerBrowserPage ()
}
void
MarkerBrowserPage::set_plugin_root (lay::PluginRoot *pr)
MarkerBrowserPage::set_dispatcher (lay::Dispatcher *pr)
{
mp_plugin_root = pr;
}
+3 -3
View File
@@ -37,7 +37,7 @@ namespace lay
{
class LayoutView;
class DMarker;
class PluginRoot;
class Dispatcher;
}
namespace rdb
@@ -68,7 +68,7 @@ public:
/**
* @brief Sets the plugin root object for this object
*/
void set_plugin_root (lay::PluginRoot *pr);
void set_dispatcher (lay::Dispatcher *pr);
/**
* @brief Attach the page to a view
@@ -206,7 +206,7 @@ private:
Qt::SortOrder m_marker_list_sort_order;
int m_directory_tree_sorted_section;
Qt::SortOrder m_directory_tree_sort_order;
lay::PluginRoot *mp_plugin_root;
lay::Dispatcher *mp_plugin_root;
tl::DeferredMethod<MarkerBrowserPage> dm_rerun_macro;
void release_markers ();
@@ -51,57 +51,57 @@ TEST(1)
EXPECT_EQ (menu_to_string (menu), "");
try {
EXPECT_EQ (menu.action ("n1").get_title (), "");
EXPECT_EQ (menu.action ("n1")->get_title (), "");
EXPECT_EQ (true, false);
} catch (...) {
}
EXPECT_EQ (menu.is_valid ("n1"), false);
menu.insert_menu ("end", "n1", lay::Action ("title:n1"));
menu.insert_menu ("end", "n1", new lay::Action ("title:n1"));
EXPECT_EQ (menu_to_string (menu), "(n1)");
EXPECT_EQ (tl::join (menu.items (""), ","), "n1");
EXPECT_EQ (menu.is_menu ("n1"), true);
EXPECT_EQ (menu.action ("n1").get_title (), "title:n1");
EXPECT_EQ (menu.action ("n1")->get_title (), "title:n1");
EXPECT_EQ (menu.is_valid ("n1"), true);
EXPECT_EQ (menu.is_valid ("n2"), false);
menu.insert_menu ("end", "n2", lay::Action ("title:n2"));
menu.insert_menu ("end", "n2", new lay::Action ("title:n2"));
EXPECT_EQ (menu_to_string (menu), "(n1,n2)");
EXPECT_EQ (tl::join (menu.items (""), ","), "n1,n2");
EXPECT_EQ (menu.is_menu ("n2"), true);
EXPECT_EQ (menu.action ("n2").get_title (), "title:n2");
EXPECT_EQ (menu.action ("n2")->get_title (), "title:n2");
EXPECT_EQ (menu.is_valid ("n2"), true);
menu.insert_menu ("end", "n1", lay::Action ("title:n1"));
menu.insert_menu ("end", "n1", new lay::Action ("title:n1"));
EXPECT_EQ (menu_to_string (menu), "(n2,n1)");
EXPECT_EQ (menu.is_menu ("n1"), true);
EXPECT_EQ (menu.action ("n1").get_title (), "title:n1");
EXPECT_EQ (menu.action ("n1")->get_title (), "title:n1");
menu.insert_item ("n1.begin", "c1", lay::Action ("title:c1"));
menu.insert_item ("n1.begin", "c1", new lay::Action ("title:c1"));
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c1))");
EXPECT_EQ (tl::join (menu.items ("n1"), ","), "n1.c1");
EXPECT_EQ (menu.action ("n1.c1").get_title (), "title:c1");
EXPECT_EQ (menu.action ("n1.c1")->get_title (), "title:c1");
menu.insert_item ("n1.end", "c2", lay::Action ("title:c2"));
menu.insert_item ("n1.end", "c2", new lay::Action ("title:c2"));
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c1,n1.c2))");
EXPECT_EQ (tl::join (menu.items ("n1"), ","), "n1.c1,n1.c2");
EXPECT_EQ (menu.is_menu ("n1.c2"), false);
EXPECT_EQ (menu.action ("n1.c2").get_title (), "title:c2");
EXPECT_EQ (menu.action ("n1.c2")->get_title (), "title:c2");
menu.insert_item ("n1.begin", "c1", lay::Action ("title:c1a"));
menu.insert_item ("n1.begin", "c1", new lay::Action ("title:c1a"));
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c1,n1.c2))");
EXPECT_EQ (tl::join (menu.items ("n1"), ","), "n1.c1,n1.c2");
EXPECT_EQ (menu.action ("n1.c1").get_title (), "title:c1a");
EXPECT_EQ (menu.action ("n1.c1")->get_title (), "title:c1a");
menu.insert_item ("n1.c1", "c3", lay::Action ("title:c3"));
menu.insert_item ("n1.c1", "c3", new lay::Action ("title:c3"));
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c3,n1.c1,n1.c2))");
menu.insert_item ("n1.c1+", "c4", lay::Action ("title:c4"));
menu.insert_item ("n1.c1+", "c4", new lay::Action ("title:c4"));
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c3,n1.c1,n1.c4,n1.c2))");
EXPECT_EQ (menu.action ("n1.c4").get_title (), "title:c4");
EXPECT_EQ (menu.action ("n1.c4")->get_title (), "title:c4");
menu.delete_item ("n1.c1");
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c3,n1.c4,n1.c2))");
@@ -109,11 +109,11 @@ TEST(1)
menu.delete_item ("n1");
EXPECT_EQ (menu_to_string (menu), "(n2)");
menu.insert_item ("n1>end(title).end", "c1", lay::Action ("title:c1"));
menu.insert_item ("n1>end(title).end", "c1", new lay::Action ("title:c1"));
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c1))");
EXPECT_EQ (menu.action ("n1.c1").get_title (), "title:c1");
EXPECT_EQ (menu.action ("n1.c1")->get_title (), "title:c1");
menu.insert_item ("n1>end(title).end", "c2", lay::Action ("title:c2"));
menu.insert_item ("n1>end(title).end", "c2", new lay::Action ("title:c2"));
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c1,n1.c2))");
menu.delete_item ("n1.c1");
@@ -128,10 +128,64 @@ TEST(1)
menu.clear_menu ("n1");
EXPECT_EQ (menu_to_string (menu), "(n2)");
menu.insert_menu ("end", "n1", lay::Action ("title:n1"));
menu.insert_item ("n1.begin", "c1", lay::Action ("title:c1"));
menu.insert_item ("n1.end", "c2", lay::Action ("title:c2"));
menu.insert_menu ("end", "n1", new lay::Action ("title:n1"));
menu.insert_item ("n1.begin", "c1", new lay::Action ("title:c1"));
menu.insert_item ("n1.end", "c2", new lay::Action ("title:c2"));
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c1,n1.c2))");
menu.clear_menu ("n1");
EXPECT_EQ (menu_to_string (menu), "(n2,n1)");
}
TEST(2_ActionReferences)
{
tl::weak_ptr<lay::Action> action (new lay::Action ("title:n1"));
{
lay::AbstractMenu menu (0);
EXPECT_EQ (menu_to_string (menu), "");
EXPECT_EQ (menu.action ("s1.n1") == 0, true);
EXPECT_EQ (menu.action ("s1") == 0, true);
menu.insert_menu ("end", "s1", "submenu1");
menu.insert_menu ("end", "s2", "submenu2");
menu.insert_item ("s1.end", "n1", action.get ());
menu.insert_item ("s2.end", "n1", action.get ());
EXPECT_EQ (menu_to_string (menu), "(s1(s1.n1),s2(s2.n1))");
EXPECT_EQ (menu.action ("s1.n1") == action.get (), true);
EXPECT_EQ (menu.action ("s2.n1") == action.get (), true);
}
// the action is deleted because it's owned by the menu
EXPECT_EQ (action.get () == 0, true);
}
TEST(3_ActionReferences)
{
tl::weak_ptr<lay::Action> action (new lay::Action ("title:n1"));
{
lay::AbstractMenu menu (0);
EXPECT_EQ (menu_to_string (menu), "");
EXPECT_EQ (menu.action ("s1.n1") == 0, true);
EXPECT_EQ (menu.action ("s1") == 0, true);
menu.insert_menu ("end", "s1", "submenu1");
menu.insert_menu ("end", "s2", "submenu2");
menu.insert_item ("s1.end", "n1", action.get ());
menu.insert_item ("s2.end", "n1", action.get ());
EXPECT_EQ (menu_to_string (menu), "(s1(s1.n1),s2(s2.n1))");
menu.delete_item ("s2");
EXPECT_EQ (menu.action ("s1.n1") != 0, true);
EXPECT_EQ (menu.action ("s1.n1") == action.get (), true);
EXPECT_EQ (menu.action ("s2.n1") == 0, true);
}
// the action is deleted because it's owned by the menu
EXPECT_EQ (action.get () == 0, true);
}
@@ -104,7 +104,7 @@ db::DUserObject us (const Sh &sh)
TEST(1)
{
db::Manager m;
db::Manager m (true);
lay::AnnotationShapes s (&m);
db::DBox b_empty;
@@ -205,7 +205,7 @@ void read_testdata (lay::AnnotationShapes &shapes, unsigned int what = 0xff)
TEST(2)
{
db::Manager m;
db::Manager m (true);
lay::AnnotationShapes shapes (&m);
read_testdata (shapes, 0x1);
@@ -244,7 +244,7 @@ TEST(2)
TEST(3)
{
db::Manager m;
db::Manager m (true);
lay::AnnotationShapes shapes (&m);
read_testdata (shapes, 0x4);
@@ -283,7 +283,7 @@ TEST(3)
TEST(4)
{
db::Manager m;
db::Manager m (true);
lay::AnnotationShapes shapes (&m);
read_testdata (shapes, 0x4);
@@ -333,7 +333,7 @@ TEST(4)
TEST(5)
{
db::Manager m;
db::Manager m (true);
lay::AnnotationShapes shapes (&m);
read_testdata (shapes, 0x4);
@@ -369,7 +369,7 @@ TEST(5)
TEST(6)
{
db::Manager m;
db::Manager m (true);
lay::AnnotationShapes shapes (&m);
read_testdata (shapes, 0x10);
@@ -396,7 +396,7 @@ TEST(6)
TEST(7)
{
db::Manager m;
db::Manager m (true);
lay::AnnotationShapes shapes (&m);
read_testdata (shapes, 0x10);
@@ -1303,7 +1303,7 @@ TEST (16)
{
lay::LayerPropertiesList list;
db::Manager mgr;
db::Manager mgr (true);
lay::LayoutView view (&mgr, is_editable (), 0);
list.attach_view (&view, 0);
@@ -1355,7 +1355,7 @@ TEST (17)
{
lay::LayerPropertiesList list;
db::Manager mgr;
db::Manager mgr (true);
lay::LayoutView view (&mgr, is_editable (), 0);
list.attach_view (&view, 0);
@@ -1422,7 +1422,7 @@ TEST (18)
{
lay::LayerPropertiesList list;
db::Manager mgr;
db::Manager mgr (true);
lay::LayoutView view (&mgr, is_editable (), 0);
list.attach_view (&view, 0);
@@ -1490,7 +1490,7 @@ TEST (19)
{
lay::LayerPropertiesList list;
db::Manager mgr;
db::Manager mgr (true);
lay::LayoutView view (&mgr, is_editable (), 0);
list.attach_view (&view, 0);
@@ -1559,7 +1559,7 @@ TEST (20)
{
lay::LayerPropertiesList list;
db::Manager mgr;
db::Manager mgr (true);
lay::LayoutView view (&mgr, is_editable (), 0);
list.attach_view (&view, 0);
@@ -1631,7 +1631,7 @@ TEST (21)
{
lay::LayerPropertiesList list;
db::Manager mgr;
db::Manager mgr (true);
lay::LayoutView view (&mgr, is_editable (), 0);
list.attach_view (&view, 0);
+1 -1
View File
@@ -27,7 +27,7 @@
TEST(1)
{
db::Manager mgr;
db::Manager mgr (true);
lay::LayoutView view (&mgr, is_editable (), 0);
int cv1 = view.create_layout ("", true, false);
+2 -2
View File
@@ -14,9 +14,9 @@ SOURCES = \
layParsedLayerSource.cc \
layRenderer.cc \
laySnap.cc \
layAbstractMenu.cc \
layNetlistBrowserModelTests.cc \
layNetlistBrowserTreeModelTests.cc
layNetlistBrowserTreeModelTests.cc \
layAbstractMenuTests.cc
INCLUDEPATH += $$TL_INC $$LAYBASIC_INC $$DB_INC $$GSI_INC $$OUT_PWD/../laybasic
DEPENDPATH += $$TL_INC $$LAYBASIC_INC $$DB_INC $$GSI_INC $$OUT_PWD/../laybasic