mirror of https://github.com/KLayout/klayout.git
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:
parent
0248834afb
commit
3c53950eaa
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 ());
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
|
|
@ -324,7 +324,9 @@ Plugin::Plugin (Plugin *parent, bool standalone)
|
|||
|
||||
Plugin::~Plugin ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
if (mp_parent) {
|
||||
mp_parent->unregister_plugin (this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#if defined(HAVE_QT)
|
||||
|
||||
#include <QDialog>
|
||||
#include <QApplication>
|
||||
|
||||
#include "layBrowser.h"
|
||||
#include "layLayoutViewBase.h"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
Loading…
Reference in New Issue