diff --git a/src/img/img/imgNavigator.cc b/src/img/img/imgNavigator.cc index b9ce6bb92..8eb7dee63 100644 --- a/src/img/img/imgNavigator.cc +++ b/src/img/img/imgNavigator.cc @@ -51,7 +51,7 @@ Navigator::Navigator (QWidget *parent) img::Object * Navigator::setup (lay::Dispatcher *root, img::Object *img) { - mp_view = new lay::LayoutView (0, false, root, this, "img_navigator_view", lay::LayoutView::LV_Naked + lay::LayoutView::LV_NoZoom + lay::LayoutView::LV_NoServices + lay::LayoutView::LV_NoGrid); + mp_view = new lay::LayoutViewWidget (0, false, root, this, lay::LayoutView::LV_Naked + lay::LayoutView::LV_NoZoom + lay::LayoutView::LV_NoServices + lay::LayoutView::LV_NoGrid); tl_assert (mp_view->widget ()); mp_view->widget ()->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding); mp_view->widget ()->setMinimumWidth (100); diff --git a/src/lay/lay/layApplication.cc b/src/lay/lay/layApplication.cc index 530ca037f..1632461e0 100644 --- a/src/lay/lay/layApplication.cc +++ b/src/lay/lay/layApplication.cc @@ -1290,7 +1290,7 @@ lay::LayoutView * ApplicationBase::create_view (db::Manager &manager) { // create a new view - lay::LayoutView *view = new lay::LayoutView (&manager, lay::ApplicationBase::instance ()->is_editable (), dispatcher (), 0 /*parent*/); + lay::LayoutView *view = new lay::LayoutView (&manager, lay::ApplicationBase::instance ()->is_editable (), dispatcher ()); // set initial attributes view->set_synchronous (m_sync_mode); @@ -1583,6 +1583,10 @@ GuiApplication::shutdown () } } + while (! (tl_widgets = topLevelWidgets ()).empty ()) { + delete tl_widgets [0]; + } + if (mp_recorder) { delete mp_recorder; mp_recorder = 0; diff --git a/src/lay/lay/layFillDialog.cc b/src/lay/lay/layFillDialog.cc index 2104b9a9b..1d8a31471 100644 --- a/src/lay/lay/layFillDialog.cc +++ b/src/lay/lay/layFillDialog.cc @@ -63,10 +63,10 @@ public: menu_entries.push_back (lay::menu_item ("fill_tool::show", "fill_tool:edit_mode", "edit_menu.utils_menu.end", tl::to_string (QObject::tr ("Fill Tool")))); } - virtual lay::Plugin *create_plugin (db::Manager *, lay::Dispatcher *root, lay::LayoutViewBase *view) const + virtual lay::Plugin *create_plugin (db::Manager *, lay::LayoutViewBase *view) const { if (lay::has_gui ()) { - return new FillDialog (root, view); + return new FillDialog (view); } else { return 0; } @@ -78,9 +78,9 @@ static tl::RegisteredClass config_decl (new FillDialogPl // ------------------------------------------------------------ -FillDialog::FillDialog (lay::Dispatcher *main, LayoutViewBase *view) +FillDialog::FillDialog (LayoutViewBase *view) : QDialog (view->widget ()), - lay::Plugin (main), + lay::Plugin (view), Ui::FillDialog (), mp_view (view) { diff --git a/src/lay/lay/layFillDialog.h b/src/lay/lay/layFillDialog.h index faa06851a..c3afebe68 100644 --- a/src/lay/lay/layFillDialog.h +++ b/src/lay/lay/layFillDialog.h @@ -76,7 +76,7 @@ class LAY_PUBLIC FillDialog Q_OBJECT public: - FillDialog (lay::Dispatcher *root, lay::LayoutViewBase *view); + FillDialog (lay::LayoutViewBase *view); ~FillDialog (); public slots: diff --git a/src/lay/lay/layMainWindow.cc b/src/lay/lay/layMainWindow.cc index 914ea0066..17d9af300 100644 --- a/src/lay/lay/layMainWindow.cc +++ b/src/lay/lay/layMainWindow.cc @@ -2578,7 +2578,7 @@ MainWindow::clone_current_view () } // create a new view - view = new lay::LayoutView (current_view (), &m_manager, lay::ApplicationBase::instance ()->is_editable (), dispatcher (), mp_view_stack); + view = new lay::LayoutViewWidget (current_view (), &m_manager, lay::ApplicationBase::instance ()->is_editable (), dispatcher (), mp_view_stack); add_view (view); // set initial attributes @@ -3389,7 +3389,7 @@ int MainWindow::do_create_view () { // create a new view - lay::LayoutView *view = new lay::LayoutView (&m_manager, lay::ApplicationBase::instance ()->is_editable (), dispatcher (), mp_view_stack); + lay::LayoutViewWidget *view = new lay::LayoutViewWidget (&m_manager, lay::ApplicationBase::instance ()->is_editable (), dispatcher (), mp_view_stack); add_view (view); // set initial attributes diff --git a/src/lay/lay/layNavigator.cc b/src/lay/lay/layNavigator.cc index b55ccdec3..ea338d1ef 100644 --- a/src/lay/lay/layNavigator.cc +++ b/src/lay/lay/layNavigator.cc @@ -655,7 +655,7 @@ Navigator::attach_view (LayoutView *view) if (mp_source_view) { - mp_view = new LayoutView (0, false, mp_source_view, this, "navigator", LayoutView::LV_Naked + LayoutView::LV_NoZoom + LayoutView::LV_NoServices + LayoutView::LV_NoGrid); + mp_view = new LayoutViewWidget (0, false, mp_source_view, this, LayoutView::LV_Naked + LayoutView::LV_NoZoom + LayoutView::LV_NoServices + LayoutView::LV_NoGrid); tl_assert (mp_view->widget ()); mp_view->widget ()->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding); mp_view->widget ()->setMinimumWidth (100); diff --git a/src/laybasic/laybasic/layAbstractMenu.cc b/src/laybasic/laybasic/layAbstractMenu.cc index 22d181dd7..3666b0157 100644 --- a/src/laybasic/laybasic/layAbstractMenu.cc +++ b/src/laybasic/laybasic/layAbstractMenu.cc @@ -1540,9 +1540,11 @@ AbstractMenu::insert_separator (const std::string &p, const std::string &name) void AbstractMenu::insert_menu (const std::string &p, const std::string &name, Action *action) { - if (! action->menu ()) { +#if defined(HAVE_QT) + if (! action->menu () && mp_dispatcher && mp_dispatcher->menu_parent_widget ()) { action->set_menu (new QMenu (), true); } +#endif typedef std::vector::iterator > > path_type; tl::Extractor extr (p.c_str ()); diff --git a/src/laybasic/laybasic/layLayoutViewBase.cc b/src/laybasic/laybasic/layLayoutViewBase.cc index 4e5b86646..89f087a31 100644 --- a/src/laybasic/laybasic/layLayoutViewBase.cc +++ b/src/laybasic/laybasic/layLayoutViewBase.cc @@ -514,6 +514,16 @@ LayoutViewBase::~LayoutViewBase () mp_canvas = 0; } +void LayoutViewBase::unregister_plugin (lay::Plugin *pi) +{ + for (std::vector::iterator p = mp_plugins.begin (); p != mp_plugins.end (); ++p) { + if (pi == *p) { + mp_plugins.erase (p); + break; + } + } +} + void LayoutViewBase::resize (unsigned int width, unsigned int height) { mp_canvas->resize (width, height); diff --git a/src/laybasic/laybasic/layLayoutViewBase.h b/src/laybasic/laybasic/layLayoutViewBase.h index 99456135a..7ad6ba773 100644 --- a/src/laybasic/laybasic/layLayoutViewBase.h +++ b/src/laybasic/laybasic/layLayoutViewBase.h @@ -2670,6 +2670,11 @@ public: return const_cast (this)->get_ui (); } + /** + * @brief Unregisters the given plugin + */ + void unregister_plugin (lay::Plugin *pi); + private: // event handlers used to connect to the layout object's events void signal_hier_changed (); diff --git a/src/laybasic/laybasic/layPlugin.cc b/src/laybasic/laybasic/layPlugin.cc index 3a28117d5..85efb510c 100644 --- a/src/laybasic/laybasic/layPlugin.cc +++ b/src/laybasic/laybasic/layPlugin.cc @@ -324,7 +324,9 @@ Plugin::Plugin (Plugin *parent, bool standalone) Plugin::~Plugin () { - // .. nothing yet .. + if (mp_parent) { + mp_parent->unregister_plugin (this); + } } void diff --git a/src/laybasic/laybasic/layPlugin.h b/src/laybasic/laybasic/layPlugin.h index 5ea38a6e2..7fb074a42 100644 --- a/src/laybasic/laybasic/layPlugin.h +++ b/src/laybasic/laybasic/layPlugin.h @@ -695,6 +695,14 @@ public: */ Dispatcher *dispatcher (); + /** + * @brief Notifies the plugin that a child plugin got deleted + */ + virtual void unregister_plugin (lay::Plugin * /*plugin*/) + { + // .. this implementation does nothing .. + } + /** * @brief Menu command handler * diff --git a/src/layui/layui/layBrowser.cc b/src/layui/layui/layBrowser.cc index 27a32a324..3c07bc345 100644 --- a/src/layui/layui/layBrowser.cc +++ b/src/layui/layui/layBrowser.cc @@ -23,6 +23,7 @@ #if defined(HAVE_QT) #include +#include #include "layBrowser.h" #include "layLayoutViewBase.h" diff --git a/src/layview/layview/gsiDeclLayLayoutView_qt.cc b/src/layview/layview/gsiDeclLayLayoutView_qt.cc index a5a95d6c3..d4c56aa74 100644 --- a/src/layview/layview/gsiDeclLayLayoutView_qt.cc +++ b/src/layview/layview/gsiDeclLayLayoutView_qt.cc @@ -39,31 +39,44 @@ namespace gsi { #if defined(HAVE_QTBINDINGS) -static lay::LayoutView *new_view (QWidget *parent, bool editable, db::Manager *manager, unsigned int options) +static lay::LayoutViewWidget *new_view_widget (QWidget *parent, bool editable, db::Manager *manager, unsigned int options) { - lay::LayoutView *lv = new lay::LayoutView (manager, editable, 0 /*plugin parent*/, parent, "view", options); + lay::LayoutView *lv = new lay::LayoutViewWidget (manager, editable, 0 /*plugin parent*/, parent, "view", options); if (parent) { // transfer ownership to the parent lv->keep (); } return lv; } -#endif -static lay::LayoutView *new_view2 (bool editable, db::Manager *manager, unsigned int options) +static lay::LayoutView *get_view (lay::LayoutViewWidget *lv) { - return new lay::LayoutView (manager, editable, 0 /*plugin parent*/, 0 /*parent*/, "view", options); + return lv; } -extern LAYBASIC_PUBLIC Class decl_LayoutViewBase; +static QFrame *layer_control_frame (lay::LayoutViewWidget *lv) +{ + return lv->layer_control_frame (); +} -Class decl_LayoutView (decl_LayoutViewBase, "lay", "LayoutView", -#if defined(HAVE_QTBINDINGS) - gsi::constructor ("new", &new_view, gsi::arg ("parent"), 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" +static QFrame *hierarchy_control_frame (lay::LayoutViewWidget *lv) +{ + return lv->hierarchy_control_frame (); +} + +static QFrame *libraries_frame (lay::LayoutViewWidget *lv) +{ + return lv->libraries_frame (); +} + +static QFrame *bookmarks_frame (lay::LayoutViewWidget *lv) +{ + return lv->bookmarks_frame (); +} + +Class decl_LayoutView (QT_EXTERNAL_BASE (QFrame), "lay", "LayoutViewWidget", + gsi::constructor ("new", &new_view_widget, gsi::arg ("parent"), gsi::arg ("editable", false), gsi::arg ("manager", (db::Manager *) 0, "nil"), gsi::arg ("options", (unsigned int) 0), + "@brief Creates a standalone view widget\n" "\n" "@param parent The parent widget in which to embed the view\n" "@param editable True to make the view editable\n" @@ -73,8 +86,53 @@ Class decl_LayoutView (decl_LayoutViewBase, "lay", "LayoutView" "This constructor has been introduced in version 0.25.\n" "It has been enhanced with the arguments in version 0.27.\n" ) + + gsi::method_ext ("layer_control_frame", &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_ext ("hierarchy_control_frame", &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_ext ("libraries_frame", &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_ext ("bookmarks_frame", &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" + ) + + gsi::method_ext ("view", &get_view, + "@brief Gets the embedded view object.\n" + ), + "This object produces a widget which embeds a LayoutView. This widget can be used inside Qt widget hierarchies.\n" + "To access the \\LayoutView object within, use \\view.\n" + "\n" + "This class has been introduced in version 0.28." +); #endif - gsi::constructor ("new", &new_view2, gsi::arg ("editable", false), gsi::arg ("manager", (db::Manager *) 0, "nil"), gsi::arg ("options", (unsigned int) 0), + +static lay::LayoutView *new_view (bool editable, db::Manager *manager, unsigned int options) +{ + return new lay::LayoutView (manager, editable, 0 /*plugin parent*/, options); +} + +extern LAYBASIC_PUBLIC Class decl_LayoutViewBase; + +Class decl_LayoutView (decl_LayoutViewBase, "lay", "LayoutView", + gsi::constructor ("new", &new_view, 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, " @@ -87,41 +145,6 @@ Class decl_LayoutView (decl_LayoutViewBase, "lay", "LayoutView" "This constructor has been introduced in version 0.25.\n" "It has been enhanced with the arguments in version 0.27.\n" ) + -#if defined(HAVE_QTBINDINGS) - gsi::method ("layer_control_frame", static_cast (&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", static_cast (&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", static_cast (&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", static_cast (&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" - ) + - gsi::method ("widget", &lay::LayoutView::widget, - "@brief Gets the QWidget object for the layout view\n" - "\n" - "This method has been introduced in version 0.28 where LayoutView is no longer derived from QWidget directly.\n" - ) + -#endif gsi::method ("current", &lay::LayoutView::current, "@brief Returns the current view\n" "The current view is the one that is shown in the current tab. Returns nil if no layout is loaded.\n" diff --git a/src/layview/layview/layLayoutView_qt.cc b/src/layview/layview/layLayoutView_qt.cc index ebe5cd73b..c78708fff 100644 --- a/src/layview/layview/layLayoutView_qt.cc +++ b/src/layview/layview/layLayoutView_qt.cc @@ -47,6 +47,7 @@ #include "tlLog.h" #include "tlAssert.h" #include "tlExceptions.h" +#include "tlStaticObjects.h" #include "layLayoutView.h" #include "layViewOp.h" #include "layViewObject.h" @@ -187,13 +188,18 @@ void LayoutViewSignalConnector::max_hier_changed (int i) mp_view->max_hier_changed (i); } +void LayoutViewSignalConnector::app_terminated () +{ + mp_view->close (); +} + // ------------------------------------------------------------- const int timer_interval = 10; static LayoutView *ms_current = 0; -LayoutView::LayoutView (db::Manager *manager, bool editable, lay::Plugin *plugin_parent, QWidget *parent, const char *name, unsigned int options) +LayoutView::LayoutView (db::Manager *manager, bool editable, lay::Plugin *plugin_parent, unsigned int options) : LayoutViewBase (this, manager, editable, plugin_parent, options), mp_widget (0), dm_setup_editor_option_pages (this, &LayoutView::do_setup_editor_options_pages) @@ -201,10 +207,10 @@ LayoutView::LayoutView (db::Manager *manager, bool editable, lay::Plugin *plugin // ensures the deferred method scheduler is present tl::DeferredMethodScheduler::instance (); - init_ui (parent, name); + init_ui (); } -LayoutView::LayoutView (lay::LayoutView *source, db::Manager *manager, bool editable, lay::Plugin *plugin_parent, QWidget *parent, const char *name, unsigned int options) +LayoutView::LayoutView (lay::LayoutView *source, db::Manager *manager, bool editable, lay::Plugin *plugin_parent, unsigned int options) : LayoutViewBase (this, source, manager, editable, plugin_parent, options), mp_widget (0), dm_setup_editor_option_pages (this, &LayoutView::do_setup_editor_options_pages) @@ -212,13 +218,38 @@ LayoutView::LayoutView (lay::LayoutView *source, db::Manager *manager, bool edit // ensures the deferred method scheduler is present tl::DeferredMethodScheduler::instance (); - init_ui (parent, name); + init_ui (); bookmarks (source->bookmarks ()); - set_active_cellview_index (source->active_cellview_index ()); + LayoutView::set_active_cellview_index (source->active_cellview_index ()); } -bool +LayoutView::LayoutView (db::Manager *manager, bool editable, lay::Plugin *plugin_parent, LayoutViewFrame *widget, unsigned int options) + : LayoutViewBase (this, manager, editable, plugin_parent, options), + mp_widget (widget), + dm_setup_editor_option_pages (this, &LayoutView::do_setup_editor_options_pages) +{ + // ensures the deferred method scheduler is present + tl::DeferredMethodScheduler::instance (); + + init_ui (); +} + +LayoutView::LayoutView (lay::LayoutView *source, db::Manager *manager, bool editable, lay::Plugin *plugin_parent, LayoutViewFrame *widget, unsigned int options) + : LayoutViewBase (this, source, manager, editable, plugin_parent, options), + mp_widget (widget), + dm_setup_editor_option_pages (this, &LayoutView::do_setup_editor_options_pages) +{ + // ensures the deferred method scheduler is present + tl::DeferredMethodScheduler::instance (); + + init_ui (); + + bookmarks (source->bookmarks ()); + LayoutView::set_active_cellview_index (source->active_cellview_index ()); +} + +bool LayoutView::event_filter (QObject *obj, QEvent *event, bool &taken) { if (obj == mp_min_hier_spbx || obj == mp_max_hier_spbx) { @@ -242,14 +273,13 @@ LayoutView::event_filter (QObject *obj, QEvent *event, bool &taken) } void -LayoutView::init_ui (QWidget *parent, const char *name) +LayoutView::init_ui () { m_activated = true; m_always_show_source = false; m_always_show_ld = true; m_always_show_layout_index = false; - mp_widget = 0; mp_connector = 0; mp_timer = 0; mp_left_frame = 0; @@ -265,14 +295,13 @@ LayoutView::init_ui (QWidget *parent, const char *name) mp_min_hier_spbx = 0; mp_max_hier_spbx = 0; - if (lay::has_gui ()) { - - mp_widget = new LayoutViewFrame (parent, this); - mp_widget->setObjectName (QString::fromUtf8 (name)); + if (mp_widget) { canvas ()->init_ui (mp_widget); mp_connector = new LayoutViewSignalConnector (mp_widget, this); + QObject::connect (mp_widget, SIGNAL (destroyed ()), mp_connector, SLOT (widget_destroyed ())); + QObject::connect (qApp, SIGNAL (destroyed ()), mp_connector, SLOT (app_destroyed ())); QVBoxLayout *vbl = new QVBoxLayout (mp_widget); vbl->setContentsMargins (0, 0, 0, 0); @@ -384,14 +413,20 @@ LayoutView::init_ui (QWidget *parent, const char *name) mp_timer->start (timer_interval); } - + config_setup (); finish (); } LayoutView::~LayoutView () +{ + close (); +} + +void LayoutView::close() { close_event (); + close_event.clear (); if (ms_current == this) { ms_current = 0; @@ -428,11 +463,6 @@ LayoutView::~LayoutView () } mp_bookmarks_frame = 0; mp_bookmarks_view = 0; - - if (mp_widget) { - delete mp_widget; - mp_widget = 0; - } } void @@ -480,6 +510,19 @@ void LayoutView::side_panel_destroyed (QObject *sender) } } +void LayoutView::app_destroyed () +{ + close (); +} + +void LayoutView::widget_destroyed (QObject *sender) +{ + if (sender == mp_widget) { + mp_widget = 0; + close (); + } +} + void LayoutView::set_current () { set_current (this); diff --git a/src/layview/layview/layLayoutView_qt.h b/src/layview/layview/layLayoutView_qt.h index af49052f8..c8acc7a55 100644 --- a/src/layview/layview/layLayoutView_qt.h +++ b/src/layview/layview/layLayoutView_qt.h @@ -89,7 +89,7 @@ class EditorOptionsPages; /** * @brief A custom QFrame that acts as the central widget for the LayoutView */ -class LayoutViewFrame +class LAYVIEW_PUBLIC LayoutViewFrame : public QFrame { Q_OBJECT @@ -181,7 +181,7 @@ public: typedef lay::LayoutViewBase::cell_path_type cell_path_type; -private slots: +public slots: void active_cellview_changed (int index); void active_library_changed (int index); void side_panel_destroyed (); @@ -191,6 +191,7 @@ private slots: void select_cell_dispatch (const cell_path_type &path, int cellview_index); void min_hier_changed (int i); void max_hier_changed (int i); + void app_terminated (); void timer (); @@ -212,12 +213,12 @@ public: /** * @brief Constructor */ - LayoutView (db::Manager *mgr, bool editable, lay::Plugin *plugin_parent, QWidget *parent = 0, const char *name = "view", unsigned int options = (unsigned int) LV_Normal); + LayoutView (db::Manager *mgr, bool editable, lay::Plugin *plugin_parent, unsigned int options = (unsigned int) LV_Normal); /** * @brief Constructor (clone from another view) */ - 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); + LayoutView (lay::LayoutView *source, db::Manager *mgr, bool editable, lay::Plugin *plugin_parent, unsigned int options = (unsigned int) LV_Normal); /** * @brief Destructor @@ -707,6 +708,8 @@ public: void deactivate_all_browsers (); + void close (); + private: friend class LayoutViewSignalConnector; friend class LayoutViewFrame; @@ -732,6 +735,8 @@ private: void active_library_changed (int index); void side_panel_destroyed (QObject *sender); + void widget_destroyed (QObject *sender); + void app_destroyed (); void layer_tab_changed (); void layer_order_changed (); void min_hier_changed (int i); @@ -740,10 +745,20 @@ private: bool event_filter (QObject *obj, QEvent *ev, bool &taken); QSize size_hint () const; - void init_ui (QWidget *parent, const char *name); + void init_ui (); void do_setup_editor_options_pages (); protected: + /** + * @brief Constructor with widget + */ + LayoutView (db::Manager *mgr, bool editable, lay::Plugin *plugin_parent, LayoutViewFrame *widget, unsigned int options = (unsigned int) LV_Normal); + + /** + * @brief Constructor (clone from another view) with widget + */ + LayoutView (lay::LayoutView *source, db::Manager *mgr, bool editable, lay::Plugin *plugin_parent, LayoutViewFrame *widget, unsigned int options = (unsigned int) LV_Normal); + void activate (); void deactivate (); @@ -775,6 +790,35 @@ private: using LayoutViewBase::ui; }; +/** + * @brief The layout view widget + * + * This is a LayoutView which actually is a widget. It can be used in a widget tree + * but only created if a QApplication is present. + */ +class LAYVIEW_PUBLIC LayoutViewWidget + : public LayoutViewFrame, public LayoutView +{ +public: + /** + * @brief Constructor + */ + LayoutViewWidget (db::Manager *mgr, bool editable, lay::Plugin *plugin_parent, QWidget *parent = 0, unsigned int options = (unsigned int) LV_Normal) + : LayoutViewFrame (parent, this), LayoutView (mgr, editable, plugin_parent, this, options) + { + // .. nothing yet .. + } + + /** + * @brief Constructor (clone from another view) + */ + LayoutViewWidget (lay::LayoutView *source, db::Manager *mgr, bool editable, lay::Plugin *plugin_parent, QWidget *parent = 0, unsigned int options = (unsigned int) LV_Normal) + : LayoutViewFrame (parent, this), LayoutView (source, mgr, editable, plugin_parent, this, options) + { + // .. nothing yet .. + } +}; + } #endif diff --git a/src/plugins/tools/bool/lay_plugin/layBooleanOperationsPlugin.cc b/src/plugins/tools/bool/lay_plugin/layBooleanOperationsPlugin.cc index f8ccfd1ba..56c311fd7 100644 --- a/src/plugins/tools/bool/lay_plugin/layBooleanOperationsPlugin.cc +++ b/src/plugins/tools/bool/lay_plugin/layBooleanOperationsPlugin.cc @@ -39,8 +39,8 @@ class BooleanOperationsPlugin : public lay::Plugin { public: - BooleanOperationsPlugin (Plugin *parent, lay::LayoutViewBase *view) - : lay::Plugin (parent), mp_view (view) + BooleanOperationsPlugin (lay::LayoutViewBase *view) + : lay::Plugin (view), mp_view (view) { m_boolean_cva = -1; m_boolean_cvb = -1; @@ -494,9 +494,9 @@ public: // .. nothing yet .. } - lay::Plugin *create_plugin (db::Manager *, lay::Dispatcher *root, lay::LayoutViewBase *view) const + lay::Plugin *create_plugin (db::Manager *, lay::Dispatcher *, lay::LayoutViewBase *view) const { - return new BooleanOperationsPlugin (root, view); + return new BooleanOperationsPlugin (view); } }; diff --git a/src/plugins/tools/diff/lay_plugin/layDiffPlugin.cc b/src/plugins/tools/diff/lay_plugin/layDiffPlugin.cc index 4740f8a5e..87b5738c8 100644 --- a/src/plugins/tools/diff/lay_plugin/layDiffPlugin.cc +++ b/src/plugins/tools/diff/lay_plugin/layDiffPlugin.cc @@ -27,6 +27,8 @@ #include "layLayoutViewBase.h" #include "layUtils.h" +#include + namespace lay { @@ -34,20 +36,19 @@ class DiffPlugin : public lay::Plugin { public: - DiffPlugin (Plugin *parent, lay::LayoutViewBase *view) - : lay::Plugin (parent), mp_view (view) + DiffPlugin (lay::LayoutViewBase *view) + : lay::Plugin (view), mp_view (view) { if (lay::has_gui ()) { mp_dialog = new lay::DiffToolDialog (0); - } else { - mp_dialog = 0; } } ~DiffPlugin () { - delete mp_dialog; - mp_dialog = 0; + if (mp_dialog) { + delete mp_dialog.data (); + } } void menu_activated (const std::string &symbol) @@ -65,7 +66,7 @@ public: private: lay::LayoutViewBase *mp_view; - lay::DiffToolDialog *mp_dialog; + QPointer mp_dialog; }; class DiffPluginDeclaration @@ -108,9 +109,9 @@ public: // .. nothing yet .. } - lay::Plugin *create_plugin (db::Manager *, lay::Dispatcher *root, lay::LayoutViewBase *view) const + lay::Plugin *create_plugin (db::Manager *, lay::Dispatcher *, lay::LayoutViewBase *view) const { - return new DiffPlugin (root, view); + return new DiffPlugin (view); } }; diff --git a/src/plugins/tools/view_25d/lay_plugin/layD25View.cc b/src/plugins/tools/view_25d/lay_plugin/layD25View.cc index 529001fba..ba1b49639 100644 --- a/src/plugins/tools/view_25d/lay_plugin/layD25View.cc +++ b/src/plugins/tools/view_25d/lay_plugin/layD25View.cc @@ -40,7 +40,7 @@ namespace lay const double initial_elevation = 15.0; -D25View::D25View (lay::Dispatcher *root, LayoutViewBase *view) +D25View::D25View (Dispatcher *root, LayoutViewBase *view) : lay::Browser (root, view, "d25_view"), dm_rerun_macro (this, &D25View::rerun_macro), dm_fit (this, &D25View::fit) diff --git a/src/plugins/tools/xor/lay_plugin/layXORPlugin.cc b/src/plugins/tools/xor/lay_plugin/layXORPlugin.cc index 919078f59..32f066403 100644 --- a/src/plugins/tools/xor/lay_plugin/layXORPlugin.cc +++ b/src/plugins/tools/xor/lay_plugin/layXORPlugin.cc @@ -29,6 +29,8 @@ #include "layLayoutView.h" #include "layUtils.h" +#include + namespace lay { @@ -36,20 +38,19 @@ class XORPlugin : public lay::Plugin { public: - XORPlugin (Plugin *parent, lay::LayoutViewBase *view) - : lay::Plugin (parent), mp_view (view) + XORPlugin (lay::LayoutViewBase *view) + : lay::Plugin (view), mp_view (view) { if (lay::has_gui ()) { mp_dialog = new lay::XORToolDialog (0); - } else { - mp_dialog = 0; } } ~XORPlugin () { - delete mp_dialog; - mp_dialog = 0; + if (mp_dialog) { + delete mp_dialog.data (); + } } void menu_activated (const std::string &symbol) @@ -67,7 +68,7 @@ public: private: lay::LayoutViewBase *mp_view; - lay::XORToolDialog *mp_dialog; + QPointer mp_dialog; }; class XORPluginDeclaration @@ -116,9 +117,9 @@ public: // .. nothing yet .. } - lay::Plugin *create_plugin (db::Manager *, lay::Dispatcher *root, lay::LayoutViewBase *view) const + lay::Plugin *create_plugin (db::Manager *, lay::Dispatcher *, lay::LayoutViewBase *view) const { - return new XORPlugin (root, view); + return new XORPlugin (view); } }; diff --git a/testdata/klayout_main/main.rb b/testdata/klayout_main/main.rb index 2f54e511a..0de2bdf55 100644 --- a/testdata/klayout_main/main.rb +++ b/testdata/klayout_main/main.rb @@ -183,6 +183,14 @@ class KLayoutMain_TestClass < TestBase end + def test_11 + + # Headless LayoutView (GUI enabled) + out = `#{self.klayout_bin} -z -rd input=#{File.join(File.dirname(__FILE__), "test1.gds")} -r #{File.join(File.dirname(__FILE__), "test10.rb")} 2>&1` + assert_equal(out, "(0,0;8,8)\n") + + end + end load("test_epilogue.rb")