Rework needed for LayoutView management

The application got unstable on exit under various conditions
(e.g. LayoutView created in script). Reason was the ownership
management of LayoutView which interfered with Qt widget
lifetime management.

The solution now is based on a clean widget/view hierarchy
and a consistent plugin parent/child relationship.

In addition, a new class is enabled which allows creating
a true QWidget (rather QFrame) for a LayoutView again.
This commit is contained in:
Matthias Koefferlein 2022-09-02 00:47:21 +02:00
parent 0248834afb
commit 3c53950eaa
20 changed files with 259 additions and 107 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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<lay::PluginDeclaration> 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)
{

View File

@ -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:

View File

@ -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

View File

@ -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);

View File

@ -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<std::pair<AbstractMenuItem *, std::list<AbstractMenuItem>::iterator > > path_type;
tl::Extractor extr (p.c_str ());

View File

@ -514,6 +514,16 @@ LayoutViewBase::~LayoutViewBase ()
mp_canvas = 0;
}
void LayoutViewBase::unregister_plugin (lay::Plugin *pi)
{
for (std::vector<lay::Plugin *>::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);

View File

@ -2670,6 +2670,11 @@ public:
return const_cast<LayoutViewBase *> (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 ();

View File

@ -324,7 +324,9 @@ Plugin::Plugin (Plugin *parent, bool standalone)
Plugin::~Plugin ()
{
// .. nothing yet ..
if (mp_parent) {
mp_parent->unregister_plugin (this);
}
}
void

View File

@ -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
*

View File

@ -23,6 +23,7 @@
#if defined(HAVE_QT)
#include <QDialog>
#include <QApplication>
#include "layBrowser.h"
#include "layLayoutViewBase.h"

View File

@ -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<lay::LayoutViewBase> decl_LayoutViewBase;
static QFrame *layer_control_frame (lay::LayoutViewWidget *lv)
{
return lv->layer_control_frame ();
}
Class<lay::LayoutView> 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<lay::LayoutView> 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<lay::LayoutView> 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<lay::LayoutViewBase> decl_LayoutViewBase;
Class<lay::LayoutView> 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<lay::LayoutView> 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<QWidget *(lay::LayoutView::*) ()> (&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<QWidget *(lay::LayoutView::*) ()> (&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<QWidget *(lay::LayoutView::*) ()> (&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<QWidget *(lay::LayoutView::*) ()> (&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"

View File

@ -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);

View File

@ -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

View File

@ -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);
}
};

View File

@ -27,6 +27,8 @@
#include "layLayoutViewBase.h"
#include "layUtils.h"
#include <QPointer>
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<lay::DiffToolDialog> 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);
}
};

View File

@ -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)

View File

@ -29,6 +29,8 @@
#include "layLayoutView.h"
#include "layUtils.h"
#include <QPointer>
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<lay::XORToolDialog> 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);
}
};

View File

@ -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")