WIP: basic availability of LayoutView as separate component

- The deferred method scheduler is now automatically created
  when required and when there is a QApplication
- QApplication and related have argv constructors
This commit is contained in:
Matthias Koefferlein 2018-06-03 00:54:58 +02:00
parent 40b2e9a1a5
commit bfbd8732f3
11 changed files with 106 additions and 45 deletions

View File

@ -991,6 +991,27 @@ GSI_QTCORE_PUBLIC gsi::Class<QCoreApplication> &qtdecl_QCoreApplication () { ret
class QCoreApplication_Adaptor : public QCoreApplication, public qt_gsi::QtObjectBase
{
public:
static QCoreApplication *ctor_QCoreApplication_Adaptor_args(const std::vector<std::string> &args)
{
// QCoreApplication needs static sources, so we give it some.
static char **argv = 0;
static std::vector<std::string> args_copy;
static int argc = 0;
if (argv != 0) {
throw tl::Exception(tl::to_string(QObject::tr("QCoreApplication cannot be instantiated twice")));
}
argv = new char *[args.size ()];
args_copy = args;
argc = int (args.size ());
for (std::vector<std::string>::const_iterator a = args_copy.begin (); a != args_copy.end (); ++a) {
argv[a - args_copy.begin ()] = (char *) a->c_str ();
}
return new QCoreApplication_Adaptor (argc, argv);
}
QCoreApplication_Adaptor (int &argc, char **argv) : QCoreApplication (argc, argv) { }
virtual ~QCoreApplication_Adaptor();
@ -1503,6 +1524,8 @@ static gsi::Methods methods_QCoreApplication_Adaptor () {
}
gsi::Class<QCoreApplication_Adaptor> decl_QCoreApplication_Adaptor (qtdecl_QCoreApplication (), "QtCore", "QCoreApplication",
gsi::constructor("new", &QCoreApplication_Adaptor::ctor_QCoreApplication_Adaptor_args, gsi::arg ("argv"), "@brief Creates a new QCoreApplication object\n\n@param argv The command line arguments to pass to Qt")
+
methods_QCoreApplication_Adaptor (),
"@qt\n@brief Binding of QCoreApplication");

View File

@ -53,12 +53,6 @@ static void _call_smo (const qt_gsi::GenericStaticMethod *, gsi::SerialArgs &, g
ret.write<const QMetaObject &> (QGuiApplication::staticMetaObject);
}
static QGuiApplication *ctor_QGuiApplication()
{
static char *(dummy_argv[]) = { (char *)"undefined_application" };
int argc = 1;
return new QGuiApplication (argc, dummy_argv);
}
// double QGuiApplication::devicePixelRatio()
@ -902,8 +896,6 @@ static gsi::Methods methods_QGuiApplication () {
gsi::Class<QCoreApplication> &qtdecl_QCoreApplication ();
qt_gsi::QtNativeClass<QGuiApplication> decl_QGuiApplication (qtdecl_QCoreApplication (), "QtGui", "QGuiApplication_Native",
gsi::constructor("new_app", &ctor_QGuiApplication, "@brief Creates a new QGuiApplication object\n\nThis implementation is provided for test purposes only. It is not required usually to create a QGuiApplication object. Use the object provided by QGuiApplication::instance instead.")
+
methods_QGuiApplication (),
"@hide\n@alias QGuiApplication");
@ -915,6 +907,27 @@ GSI_QTGUI_PUBLIC gsi::Class<QGuiApplication> &qtdecl_QGuiApplication () { return
class QGuiApplication_Adaptor : public QGuiApplication, public qt_gsi::QtObjectBase
{
public:
static QGuiApplication *ctor_QGuiApplication_Adaptor_args(const std::vector<std::string> &args)
{
// QGuiApplication needs static sources, so we give it some.
static char **argv = 0;
static std::vector<std::string> args_copy;
static int argc = 0;
if (argv != 0) {
throw tl::Exception(tl::to_string(QObject::tr("QGuiApplication cannot be instantiated twice")));
}
argv = new char *[args.size ()];
args_copy = args;
argc = int (args.size ());
for (std::vector<std::string>::const_iterator a = args_copy.begin (); a != args_copy.end (); ++a) {
argv[a - args_copy.begin ()] = (char *) a->c_str ();
}
return new QGuiApplication_Adaptor (argc, argv);
}
QGuiApplication_Adaptor (int &argc, char **argv) : QGuiApplication (argc, argv) { }
virtual ~QGuiApplication_Adaptor();
@ -1694,6 +1707,8 @@ static gsi::Methods methods_QGuiApplication_Adaptor () {
}
gsi::Class<QGuiApplication_Adaptor> decl_QGuiApplication_Adaptor (qtdecl_QGuiApplication (), "QtGui", "QGuiApplication",
gsi::constructor("new", &QGuiApplication_Adaptor::ctor_QGuiApplication_Adaptor_args, gsi::arg ("argv"), "@brief Creates a new QGuiApplication object\n\n@param argv The command line arguments to pass to Qt")
+
methods_QGuiApplication_Adaptor (),
"@qt\n@brief Binding of QGuiApplication");

View File

@ -53,12 +53,6 @@ static void _call_smo (const qt_gsi::GenericStaticMethod *, gsi::SerialArgs &, g
ret.write<const QMetaObject &> (QApplication::staticMetaObject);
}
static QApplication *ctor_QApplication()
{
static char *(dummy_argv[]) = { (char *)"undefined_application" };
int argc = 1;
return new QApplication (argc, dummy_argv);
}
// bool QApplication::autoSipEnabled()
@ -1158,8 +1152,6 @@ static gsi::Methods methods_QApplication () {
gsi::Class<QGuiApplication> &qtdecl_QGuiApplication ();
qt_gsi::QtNativeClass<QApplication> decl_QApplication (qtdecl_QGuiApplication (), "QtWidgets", "QApplication_Native",
gsi::constructor("new_app", &ctor_QApplication, "@brief Creates a new QApplication object\n\nThis implementation is provided for test purposes only. It is not required usually to create a QApplication object. Use the object provided by QApplication::instance instead.")
+
methods_QApplication (),
"@hide\n@alias QApplication");
@ -1171,6 +1163,27 @@ GSI_QTWIDGETS_PUBLIC gsi::Class<QApplication> &qtdecl_QApplication () { return d
class QApplication_Adaptor : public QApplication, public qt_gsi::QtObjectBase
{
public:
static QApplication *ctor_QApplication_Adaptor_args(const std::vector<std::string> &args)
{
// QApplication needs static sources, so we give it some.
static char **argv = 0;
static std::vector<std::string> args_copy;
static int argc = 0;
if (argv != 0) {
throw tl::Exception(tl::to_string(QObject::tr("QApplication cannot be instantiated twice")));
}
argv = new char *[args.size ()];
args_copy = args;
argc = int (args.size ());
for (std::vector<std::string>::const_iterator a = args_copy.begin (); a != args_copy.end (); ++a) {
argv[a - args_copy.begin ()] = (char *) a->c_str ();
}
return new QApplication_Adaptor (argc, argv);
}
QApplication_Adaptor (int &argc, char **argv) : QApplication (argc, argv) { }
virtual ~QApplication_Adaptor();
@ -1978,6 +1991,8 @@ static gsi::Methods methods_QApplication_Adaptor () {
}
gsi::Class<QApplication_Adaptor> decl_QApplication_Adaptor (qtdecl_QApplication (), "QtWidgets", "QApplication",
gsi::constructor("new", &QApplication_Adaptor::ctor_QApplication_Adaptor_args, gsi::arg ("argv"), "@brief Creates a new QApplication object\n\n@param argv The command line arguments to pass to Qt")
+
methods_QApplication_Adaptor (),
"@qt\n@brief Binding of QApplication");

View File

@ -1348,10 +1348,6 @@ GuiApplication::GuiApplication (int &argc, char **argv)
#if QT_VERSION >= 0x040500
setAttribute (Qt::AA_DontShowIconsInMenus, false);
#endif
// only a GUI-enabled application runs an event loop and can have a deferred
// method scheduler therefore.
mp_dm_scheduler.reset (new tl::DeferredMethodScheduler ());
}
GuiApplication::~GuiApplication ()
@ -1533,8 +1529,8 @@ GuiApplication::process_events_impl (QEventLoop::ProcessEventsFlags flags, bool
{
if (mp_mw) {
if (silent) {
mp_dm_scheduler->enable (false);
if (silent && tl::DeferredMethodScheduler::instance ()) {
tl::DeferredMethodScheduler::instance ()->enable (false);
}
#if QT_VERSION < 0x050000
@ -1549,8 +1545,8 @@ GuiApplication::process_events_impl (QEventLoop::ProcessEventsFlags flags, bool
}
mp_mw->enter_busy_mode (false);
if (silent) {
mp_dm_scheduler->enable (true);
if (silent && tl::DeferredMethodScheduler::instance ()) {
tl::DeferredMethodScheduler::instance ()->enable (true);
}
}

View File

@ -48,11 +48,6 @@ namespace gtf
class Recorder;
}
namespace tl
{
class DeferredMethodScheduler;
}
namespace lym
{
class MacroCollection;
@ -476,7 +471,6 @@ protected:
private:
MainWindow *mp_mw;
gtf::Recorder *mp_recorder;
std::auto_ptr<tl::DeferredMethodScheduler> mp_dm_scheduler;
};
/**

View File

@ -461,6 +461,9 @@ MainWindow::MainWindow (QApplication *app, const char *name)
m_busy (false),
mp_app (app)
{
// ensures the deferred method scheduler is present
tl::DeferredMethodScheduler::instance ();
setObjectName (QString::fromUtf8 (name));
if (mw_instance != 0) {

View File

@ -23,6 +23,8 @@
#include "gsiDecl.h"
#include "gsiSignals.h"
#include "gsiQtGuiExternals.h"
#include "gsiQtWidgetsExternals.h" // for Qt5
#include "rdb.h"
#include "layLayoutView.h"
#include "layDitherPattern.h"
@ -367,7 +369,7 @@ static lay::LayoutView *new_view ()
return new lay::LayoutView (0, false, 0);
}
Class<lay::LayoutView> decl_LayoutView ("lay", "LayoutView",
Class<lay::LayoutView> decl_LayoutView (QT_EXTERNAL_BASE (QWidget) "lay", "LayoutView",
gsi::constructor ("new", &new_view,
"@brief Creates a standalone view\n"
"\n"

View File

@ -255,6 +255,9 @@ LayoutView::LayoutView (db::Manager *manager, bool editable, lay::PluginRoot *ro
m_annotation_shapes (manager),
dm_prop_changed (this, &LayoutView::do_prop_changed)
{
// ensures the deferred method scheduler is present
tl::DeferredMethodScheduler::instance ();
setObjectName (QString::fromUtf8 (name));
init (manager, root, parent);
}
@ -267,6 +270,9 @@ LayoutView::LayoutView (lay::LayoutView *source, db::Manager *manager, bool edit
m_annotation_shapes (manager),
dm_prop_changed (this, &LayoutView::do_prop_changed)
{
// ensures the deferred method scheduler is present
tl::DeferredMethodScheduler::instance ();
setObjectName (QString::fromUtf8 (name));
m_annotation_shapes = source->m_annotation_shapes;

View File

@ -2223,6 +2223,12 @@ PythonModule::PythonModule ()
PythonModule::~PythonModule ()
{
PYAObjectBase::clear_callbacks_cache ();
// the Python objects were probably deleted by Python itself as it exited -
// don't try to delete them again.
mp_module.release ();
mp_base_class.release ();
delete_module ();
}

View File

@ -34,8 +34,8 @@ namespace tl
static DeferredMethodScheduler *s_inst = 0;
DeferredMethodScheduler::DeferredMethodScheduler ()
: QObject (0),
DeferredMethodScheduler::DeferredMethodScheduler (QObject *parent)
: QObject (parent),
m_disabled (0), m_scheduled (false)
{
connect (&m_timer, SIGNAL (timeout ()), this, SLOT (timer ()));
@ -60,8 +60,9 @@ DeferredMethodScheduler::~DeferredMethodScheduler ()
DeferredMethodScheduler *
DeferredMethodScheduler::instance ()
{
// NOTE: this is not locked intentionally. The instance is shut down once in the application shortly before it
// will terminate and it is created initially before any threads start.
if (! s_inst && qApp) {
new DeferredMethodScheduler (qApp);
}
return s_inst;
}

View File

@ -71,16 +71,6 @@ class TL_PUBLIC DeferredMethodScheduler
{
Q_OBJECT
public:
/**
* @brief Constructor
*/
DeferredMethodScheduler ();
/**
* @brief Destructor
*/
~DeferredMethodScheduler ();
/**
* @brief The singleton instance of the scheduler
*/
@ -129,6 +119,16 @@ private slots:
void timer ();
private:
/**
* @brief Constructor
*/
DeferredMethodScheduler (QObject *parent);
/**
* @brief Destructor
*/
~DeferredMethodScheduler ();
int m_disabled;
bool m_scheduled;
std::list<DeferredMethodBase *> m_methods;