First steps towards fix. Needs review.

The patch is based on splitting the application class into
two incarnations - one for GUI capability and one without.

GSI binding happens dynamically based on the mode chosen.
We can do so because the application class is the first one
to become active and can decide the mode by itself.

In general, the application class carries too much functionality
and splitting is a task for the future. Right now, the functionality
is inside the base class and the derived classes basically only
configure the base class.

A better design would be to drop the QApplication inheritance in
the RBA::Application class hierarchy and provide access to the
QApplication object through qapp_gui getter.
This commit is contained in:
Matthias Koefferlein 2017-12-25 00:51:06 +01:00
parent 395643b427
commit 53d2557ba5
14 changed files with 513 additions and 346 deletions

View File

@ -901,7 +901,7 @@ XORToolDialog::run_xor ()
bool summarize = mp_ui->summarize_cb->isChecked ();
// TODO: make this a user interface feature later
bool process_el = lay::Application::instance ()->special_app_flag ("ALWAYS_DO_XOR");
bool process_el = lay::ApplicationBase::instance ()->special_app_flag ("ALWAYS_DO_XOR");
int cv_index_a = mp_ui->layouta->current_cv_index ();
int cv_index_b = mp_ui->layoutb->current_cv_index ();
@ -1384,7 +1384,7 @@ XORToolDialog::run_xor ()
// If the output mode is database, ask whether to keep the data collected so far.
// If the answer is yes, remove the RDB.
// Don't ask if the application has exit (window was closed)
if (lay::Application::instance ()->main_window () && !lay::Application::instance ()->main_window ()->exited ()) {
if (lay::ApplicationBase::instance ()->main_window () && !lay::ApplicationBase::instance ()->main_window ()->exited ()) {
QMessageBox msgbox (QMessageBox::Question,
QObject::tr ("Keep Data For Cancelled Job"),
QObject::tr ("The job has been cancelled. Keep the data collected so far?"),

View File

@ -227,14 +227,19 @@ klayout_main_cont (int &argc, char **argv)
}
}
lay::Application app (argc, argv, non_ui_mode);
std::auto_ptr<lay::ApplicationBase> app;
if (non_ui_mode) {
app.reset (new lay::NonGuiApplication (argc, argv));
} else {
app.reset (new lay::GuiApplication (argc, argv));
}
QString locale = QLocale::system ().name ();
/* TODO: this kills valgrind
QTranslator translator;
if (translator.load (QString::fromUtf8 ("klayout_") + locale)) {
app.installTranslator (&translator);
if (app->qapp () && translator.load (QString::fromUtf8 ("klayout_") + locale)) {
app->qapp ()->installTranslator (&translator);
}
*/
@ -242,18 +247,18 @@ klayout_main_cont (int &argc, char **argv)
QTextCodec::setCodecForTr (QTextCodec::codecForName ("utf8"));
#endif
if (app.has_gui ()) {
if (app->has_gui ()) {
BEGIN_PROTECTED_CLEANUP
result = app.run ();
result = app->run ();
END_PROTECTED_CLEANUP {
result = 1;
}
} else {
result = app.run ();
result = app->run ();
}
} catch (tl::ExitException &ex) {

View File

@ -61,167 +61,207 @@ void crash_me (int reason)
}
}
static std::string arch (lay::Application *)
template <class C>
static std::string arch (C *)
{
return tl::arch_string ();
}
Class<lay::Application> decl_Application (QT_EXTERNAL_BASE (QApplication) "Application",
method ("instance", &lay::Application::instance,
"@brief Return the singleton instance of the application\n"
"\n"
"There is exactly one instance of the application. This instance can be obtained with this "
"method."
) +
method ("crash_me", &crash_me, "@hide") +
method ("symname", &lay::get_symbol_name_from_address, "@hide") +
method ("is_editable?", &lay::Application::is_editable,
"@brief Returns true if the application is in editable mode\n"
) +
// TODO: basically this method belongs to PluginRoot (aka MainWindow).
// There is separate declaration for PluginRoot which we have to synchronize
// with this method.
method ("get_config", &lay::Application::get_config,
"@brief Gets the value for a configuration parameter\n"
"\n"
"@args name\n"
"@param name The name of the configuration parameter whose value shall be obtained (a string)\n"
"\n"
"@return The value of the parameter\n"
"\n"
"This method returns the value of the given configuration parameter. If the parameter is not "
"known, an exception will be thrown. Use \\get_config_names to obtain a list of all configuration "
"parameter names available.\n"
"\n"
"Configuration parameters are always stored as strings. The actual format of this string is specific "
"to the configuration parameter. The values delivered by this method correspond to the values stored "
"in the configuration file "
) +
// TODO: basically this method belongs to PluginRoot (aka MainWindow).
// There is separate declaration for PluginRoot which we have to synchronize
// with this method.
method ("get_config_names", &lay::Application::get_config_names,
"@brief Gets the configuration parameter names\n"
"\n"
"@return A list of configuration parameter names\n"
"\n"
"This method returns the names of all known configuration parameters. These names can be used to "
"get and set configuration parameter values."
) +
// TODO: basically this method belongs to PluginRoot (aka MainWindow).
// There is separate declaration for PluginRoot which we have to synchronize
// with this method.
method ("set_config", &lay::Application::set_config,
"@brief Sets a configuration parameter with the given name to the given value\n"
"\n"
"@args name, value\n"
"@param name The name of the configuration parameter to set\n"
"@param value The value to which to set the configuration parameter\n"
"\n"
"This method sets the configuration parameter with the given name to the given value. "
"Values can only be strings. Numerical values have to be converted into strings first. "
"The actual format of the value depends on the configuration parameter. The name must "
"be one of the names returned by \\get_config_names."
"\n"
"It is possible to write an arbitrary name/value pair into the configuration database which then is "
"written to the configuration file."
) +
// TODO: basically this method belongs to PluginRoot (aka MainWindow).
// There is separate declaration for PluginRoot which we have to synchronize
// with this method.
method ("commit_config", &lay::Application::config_end,
"@brief Commits the configuration settings\n"
"\n"
"Some configuration options are queued for performance reasons and become active only after 'commit_config' has been called. "
"After a sequence of \\set_config calls, this method should be called to activate the "
"settings made by these calls.\n"
"\n"
"This method has been introduced in version 0.25.\n"
) +
// TODO: basically this method belongs to PluginRoot (aka MainWindow).
// There is separate declaration for PluginRoot which we have to synchronize
// with this method.
method ("write_config", &lay::Application::write_config,
"@brief Writes configuration to a file\n"
"@args file_name\n"
"@return A value indicating whether the operation was successful\n"
"\n"
"If the configuration file cannot be written, \n"
"is returned but no exception is thrown.\n"
) +
// TODO: basically this method belongs to PluginRoot (aka MainWindow).
// There is separate declaration for PluginRoot which we have to synchronize
// with this method.
method ("read_config", &lay::Application::read_config,
"@brief Reads the configuration from a file\n"
"@args file_name\n"
"@return A value indicating whether the operation was successful\n"
"\n"
"This method siletly does nothing, if the config file does not\n"
"exist. If it does and an error occured, the error message is printed\n"
"on stderr. In both cases, false is returned.\n"
) +
method ("main_window", &lay::Application::main_window,
"@brief Returns a reference to the main window\n"
"\n"
"@return A object reference to the main window object."
) +
method ("execute|#exec", &lay::Application::exec,
"@brief Executes the application's main loop\n"
"\n"
"This method must be called in order to execute the application in the main "
"script if a script is provided."
) +
method ("process_events", (void (lay::Application::*)()) &lay::Application::process_events,
"@brief Processes pending events\n"
"\n"
"This method processes pending events and dispatches them internally. Calling this "
"method periodically during a long operation keeps the application 'alive'"
) +
method ("application_data_path", &lay::Application::appdata_path,
"@brief Returns the application's data path (where the configuration file is stored for example)\n"
"\n"
"This method has been added in version 0.22."
) +
method ("inst_path", &lay::Application::inst_path,
"@brief Returns the application's installation path (where the executable is located)\n"
"\n"
"This method has been added in version 0.18. Version 0.22 offers the method \\klayout_path which "
"delivers all components of the search path."
) +
method ("klayout_path", &lay::Application::klayout_path,
"@brief Returns the KLayout path (search path for KLayout components)\n"
"\n"
"The result is an array containing the components of the path.\n"
"\n"
"This method has been added in version 0.22."
) +
method ("exit", &lay::Application::exit,
"@args result\n"
"@brief Ends the application with the given exit status\n"
"\n"
"This method should be called instead of simply shutting down the process. It performs some "
"important cleanup without which the process might crash. If the result code is 0 (success), "
"the configuration file will be updated unless that has been disabled by the -nc command line switch."
"\n"
"This method has been added in version 0.22."
) +
method ("version", &lay::Application::version,
"@brief Returns the application's version string\n"
) +
method_ext ("arch", &arch,
"@brief Returns the architecture string\n"
"This method has been introduced in version 0.25."
)
,
template <class C>
static gsi::Methods application_methods ()
{
return
method<int> ("crash_me", &crash_me, "@hide") +
method<QString, const QString &, size_t> ("symname", &lay::get_symbol_name_from_address, "@hide") +
method<C, bool> ("is_editable?", &C::is_editable,
"@brief Returns true if the application is in editable mode\n"
) +
// TODO: basically this method belongs to PluginRoot (aka MainWindow).
// There is separate declaration for PluginRoot which we have to synchronize
// with this method.
method<C, std::string, const std::string &> ("get_config", &C::get_config,
"@brief Gets the value for a configuration parameter\n"
"\n"
"@args name\n"
"@param name The name of the configuration parameter whose value shall be obtained (a string)\n"
"\n"
"@return The value of the parameter\n"
"\n"
"This method returns the value of the given configuration parameter. If the parameter is not "
"known, an exception will be thrown. Use \\get_config_names to obtain a list of all configuration "
"parameter names available.\n"
"\n"
"Configuration parameters are always stored as strings. The actual format of this string is specific "
"to the configuration parameter. The values delivered by this method correspond to the values stored "
"in the configuration file "
) +
// TODO: basically this method belongs to PluginRoot (aka MainWindow).
// There is separate declaration for PluginRoot which we have to synchronize
// with this method.
method<C, std::vector<std::string> > ("get_config_names", &C::get_config_names,
"@brief Gets the configuration parameter names\n"
"\n"
"@return A list of configuration parameter names\n"
"\n"
"This method returns the names of all known configuration parameters. These names can be used to "
"get and set configuration parameter values."
) +
// TODO: basically this method belongs to PluginRoot (aka MainWindow).
// There is separate declaration for PluginRoot which we have to synchronize
// with this method.
method<C, const std::string &, const std::string &> ("set_config", &C::set_config,
"@brief Sets a configuration parameter with the given name to the given value\n"
"\n"
"@args name, value\n"
"@param name The name of the configuration parameter to set\n"
"@param value The value to which to set the configuration parameter\n"
"\n"
"This method sets the configuration parameter with the given name to the given value. "
"Values can only be strings. Numerical values have to be converted into strings first. "
"The actual format of the value depends on the configuration parameter. The name must "
"be one of the names returned by \\get_config_names."
"\n"
"It is possible to write an arbitrary name/value pair into the configuration database which then is "
"written to the configuration file."
) +
// TODO: basically this method belongs to PluginRoot (aka MainWindow).
// There is separate declaration for PluginRoot which we have to synchronize
// with this method.
method<C> ("commit_config", &C::config_end,
"@brief Commits the configuration settings\n"
"\n"
"Some configuration options are queued for performance reasons and become active only after 'commit_config' has been called. "
"After a sequence of \\set_config calls, this method should be called to activate the "
"settings made by these calls.\n"
"\n"
"This method has been introduced in version 0.25.\n"
) +
// TODO: basically this method belongs to PluginRoot (aka MainWindow).
// There is separate declaration for PluginRoot which we have to synchronize
// with this method.
method<C, bool, const std::string &> ("write_config", &C::write_config,
"@brief Writes configuration to a file\n"
"@args file_name\n"
"@return A value indicating whether the operation was successful\n"
"\n"
"If the configuration file cannot be written, \n"
"is returned but no exception is thrown.\n"
) +
// TODO: basically this method belongs to PluginRoot (aka MainWindow).
// There is separate declaration for PluginRoot which we have to synchronize
// with this method.
method<C, bool, const std::string &> ("read_config", &C::read_config,
"@brief Reads the configuration from a file\n"
"@args file_name\n"
"@return A value indicating whether the operation was successful\n"
"\n"
"This method siletly does nothing, if the config file does not\n"
"exist. If it does and an error occured, the error message is printed\n"
"on stderr. In both cases, false is returned.\n"
) +
method<C, lay::MainWindow *> ("main_window", &C::main_window,
"@brief Returns a reference to the main window\n"
"\n"
"@return A object reference to the main window object."
) +
method<C> ("execute|#exec", &C::exec,
"@brief Executes the application's main loop\n"
"\n"
"This method must be called in order to execute the application in the main "
"script if a script is provided."
) +
method<C> ("process_events", (void (C::*)()) &C::process_events,
"@brief Processes pending events\n"
"\n"
"This method processes pending events and dispatches them internally. Calling this "
"method periodically during a long operation keeps the application 'alive'"
) +
method<C, const std::string &> ("application_data_path", &C::appdata_path,
"@brief Returns the application's data path (where the configuration file is stored for example)\n"
"\n"
"This method has been added in version 0.22."
) +
method<C, const std::string &> ("inst_path", &C::inst_path,
"@brief Returns the application's installation path (where the executable is located)\n"
"\n"
"This method has been added in version 0.18. Version 0.22 offers the method \\klayout_path which "
"delivers all components of the search path."
) +
method<C, const std::vector<std::string> &> ("klayout_path", &C::klayout_path,
"@brief Returns the KLayout path (search path for KLayout components)\n"
"\n"
"The result is an array containing the components of the path.\n"
"\n"
"This method has been added in version 0.22."
) +
method<C, int> ("exit", &C::exit,
"@args result\n"
"@brief Ends the application with the given exit status\n"
"\n"
"This method should be called instead of simply shutting down the process. It performs some "
"important cleanup without which the process might crash. If the result code is 0 (success), "
"the configuration file will be updated unless that has been disabled by the -nc command line switch."
"\n"
"This method has been added in version 0.22."
) +
method<C, std::string> ("version", &C::version,
"@brief Returns the application's version string\n"
) +
method_ext<C, std::string> ("arch", &arch<C>,
"@brief Returns the architecture string\n"
"This method has been introduced in version 0.25."
) +
method<C *> ("instance", &C::instance,
"@brief Return the singleton instance of the application\n"
"\n"
"There is exactly one instance of the application. This instance can be obtained with this "
"method."
)
;
}
"@brief The application object\n"
"\n"
"The application object is the main port from which to access all the internals "
"of the application, in particular the main window."
static std::string application_doc ()
{
return
"@brief The application object\n"
"\n"
"The application object is the main port from which to access all the internals "
"of the application, in particular the main window."
;
}
);
/**
* @brief Creates the right application object declaration depending on the mode
*
* This declaration factory will register a GuiApplication declaration (derived from QApplication)
* if in GUI mode and a NonGuiApplication declaration (derived from QCoreApplication).
*/
void
LAY_PUBLIC make_application_decl (bool non_gui_mode)
{
static std::auto_ptr<Class<lay::GuiApplication> > gui_app_decl;
static std::auto_ptr<Class<lay::NonGuiApplication> > non_gui_app_decl;
if (non_gui_mode) {
non_gui_app_decl.reset (
new Class<lay::NonGuiApplication> (QT_EXTERNAL_BASE (QCoreApplication) "Application",
application_methods<lay::NonGuiApplication> (),
application_doc ()
)
);
} else {
gui_app_decl.reset (
new Class<lay::GuiApplication> (QT_EXTERNAL_BASE (QApplication) "Application",
application_methods<lay::GuiApplication> (),
application_doc ()
)
);
}
}
}

View File

@ -75,6 +75,11 @@
# include <dlfcn.h>
#endif
namespace gsi
{
void make_application_decl (bool non_gui_mode);
}
namespace lay
{
@ -165,7 +170,7 @@ static void ui_exception_handler_def (QWidget *parent)
// --------------------------------------------------------------------------------
static Application *ms_instance = 0;
static ApplicationBase *ms_instance = 0;
static PluginDescriptor load_plugin (const std::string &pp)
{
@ -210,8 +215,11 @@ static PluginDescriptor load_plugin (const std::string &pp)
return desc;
}
Application::Application (int &argc, char **argv, bool non_ui_mode)
: QApplication (argc, argv, !non_ui_mode),
// --------------------------------------------------------------------------------
// ApplicationBase implementation
ApplicationBase::ApplicationBase ()
: gsi::ObjectBase (),
m_lyp_map_all_cvs (true),
m_lyp_add_default (false),
m_write_config_file (true),
@ -224,8 +232,6 @@ Application::Application (int &argc, char **argv, bool non_ui_mode)
m_vo_mode (false),
m_editable (false),
m_enable_undo (true),
mp_qapp (0),
mp_qapp_gui (0),
mp_ruby_interpreter (0),
mp_python_interpreter (0),
mp_mw (0),
@ -234,20 +240,27 @@ Application::Application (int &argc, char **argv, bool non_ui_mode)
mp_plugin_root (0),
mp_recorder (0)
{
// nothing yet - see init
}
void
ApplicationBase::init_app (int &argc, char **argv, bool non_ui_mode)
{
m_no_gui = non_ui_mode;
gsi::make_application_decl (non_ui_mode);
// TODO: offer a strict mode for exception handling where this takes place:
// lay::Application::instance ()->exit (1);
// lay::ApplicationBase::instance ()->exit (1);
if (! non_ui_mode) {
tl::set_ui_exception_handlers (ui_exception_handler_tl, ui_exception_handler_std, ui_exception_handler_def);
}
mp_qapp = this;
mp_qapp_gui = (non_ui_mode ? 0 : this);
mp_dm_scheduler.reset (new tl::DeferredMethodScheduler ());
// install a special style proxy to overcome the issue of black-on-black tree expanders
if (mp_qapp_gui) {
mp_qapp_gui->setStyle (new lay::BackgroundAwareTreeStyle (0));
if (qapp_gui ()) {
qapp_gui ()->setStyle (new lay::BackgroundAwareTreeStyle (0));
}
// initialize the system codecs (Hint: this must be done after the QApplication is initialized because
@ -288,7 +301,7 @@ Application::Application (int &argc, char **argv, bool non_ui_mode)
// get the KLayout path
m_klayout_path = lay::get_klayout_path ();
if (mp_qapp_gui) {
if (qapp_gui ()) {
// create the configuration files paths and collect the initialization config files
// (the ones used for reset) into m_initial_config_files.
@ -390,7 +403,7 @@ Application::Application (int &argc, char **argv, bool non_ui_mode)
m_native_plugins.push_back (load_plugin (m));
modules.insert (mn);
} catch (tl::Exception &ex) {
tl::error << tl::to_string (tr ("Unable to load plugin %1: %2").arg (tl::to_qstring (m)).arg (tl::to_qstring (ex.msg ())));
tl::error << tl::to_string (QObject::tr ("Unable to load plugin %1: %2").arg (tl::to_qstring (m)).arg (tl::to_qstring (ex.msg ())));
}
}
}
@ -787,17 +800,17 @@ Application::Application (int &argc, char **argv, bool non_ui_mode)
db::set_default_editable_mode (m_editable);
db::enable_transactions (m_enable_undo);
if (mp_qapp_gui) {
mp_qapp_gui->setWindowIcon (QIcon (QString::fromUtf8 (":/logo.png")));
if (qapp_gui ()) {
qapp_gui ()->setWindowIcon (QIcon (QString::fromUtf8 (":/logo.png")));
#if QT_VERSION >= 0x040500
mp_qapp_gui->setAttribute (Qt::AA_DontShowIconsInMenus, false);
qapp_gui ()->setAttribute (Qt::AA_DontShowIconsInMenus, false);
#endif
}
if (mp_qapp_gui && ! gtf_record.empty ()) {
if (qapp_gui () && ! gtf_record.empty ()) {
// since the recorder tracks QAction connections etc., it must be instantiated before every other
// object performing a gtf::action_connect for example
mp_recorder = new gtf::Recorder (mp_qapp_gui, gtf_record);
mp_recorder = new gtf::Recorder (qapp_gui (), gtf_record);
mp_recorder->save_incremental (gtf_save_incremental);
}
@ -821,9 +834,9 @@ Application::Application (int &argc, char **argv, bool non_ui_mode)
// suffixes through the MacroInterpreter interface.
lym::MacroCollection::root ().rescan ();
if (mp_qapp_gui) {
mp_mw = new lay::MainWindow (mp_qapp_gui, "main_window");
QObject::connect (mp_mw, SIGNAL (closed ()), mp_qapp_gui, SLOT (quit ()));
if (qapp_gui ()) {
mp_mw = new lay::MainWindow (qapp_gui (), "main_window");
QObject::connect (mp_mw, SIGNAL (closed ()), qapp_gui (), SLOT (quit ()));
mp_plugin_root = mp_mw;
} else {
mp_pr = new lay::ProgressReporter ();
@ -863,7 +876,7 @@ Application::Application (int &argc, char **argv, bool non_ui_mode)
}
}
Application::~Application ()
ApplicationBase::~ApplicationBase ()
{
tl::set_ui_exception_handlers (0, 0, 0);
@ -875,7 +888,7 @@ Application::~Application ()
}
std::vector<std::string>
Application::scan_global_modules ()
ApplicationBase::scan_global_modules ()
{
// NOTE:
// this is deprecated functionality - for backward compatibility, global "*.rbm" and "*.pym" modules
@ -914,7 +927,7 @@ Application::scan_global_modules ()
if (rbm_file.exists () && rbm_file.isReadable ()) {
std::string m = tl::to_string (rbm_file.absoluteFilePath ());
if (modules.find (m) == modules.end ()) {
tl::warn << tl::to_string (tr ("Global modules are deprecated. Turn '%1' into an autorun macro instead and put it into 'macros' or 'pymacros'.").arg (tl::to_qstring (m)));
tl::warn << tl::to_string (QObject::tr ("Global modules are deprecated. Turn '%1' into an autorun macro instead and put it into 'macros' or 'pymacros'.").arg (tl::to_qstring (m)));
global_modules.push_back (m);
modules.insert (m);
}
@ -926,22 +939,8 @@ Application::scan_global_modules ()
return global_modules;
}
bool
Application::notify (QObject *receiver, QEvent *e)
{
// Note: due to a bug in some Qt versions (i.e. 4.8.3) throwing exceptions across
// signals may not be safe. Hence the local BEGIN_PROTECTED .. END_PROTECTED approach
// is still preferred over the global solution through "notify"
bool ret = true;
BEGIN_PROTECTED
ret = QApplication::notify (receiver, e);
END_PROTECTED
return ret;
}
void
Application::exit (int result)
ApplicationBase::exit (int result)
{
if (! result) {
finish ();
@ -951,7 +950,7 @@ Application::exit (int result)
}
void
Application::finish ()
ApplicationBase::finish ()
{
// save the recorded test events
if (mp_mw && mp_recorder && mp_recorder->recording ()) {
@ -978,7 +977,7 @@ Application::finish ()
}
void
Application::shutdown ()
ApplicationBase::shutdown ()
{
// uninitialize the plugins
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
@ -996,7 +995,10 @@ Application::shutdown ()
}
// delete all other top level widgets for safety - we don't want Ruby clean them up for us
QWidgetList tl_widgets = topLevelWidgets ();
QWidgetList tl_widgets;
if (qapp_gui ()) {
tl_widgets = qapp_gui ()->topLevelWidgets ();
}
for (QWidgetList::iterator w = tl_widgets.begin (); w != tl_widgets.end (); ++w) {
delete *w;
}
@ -1026,25 +1028,23 @@ Application::shutdown ()
mp_python_interpreter = 0;
}
mp_qapp = 0;
mp_qapp_gui = 0;
ms_instance = 0;
}
Application *
Application::instance ()
ApplicationBase *
ApplicationBase::instance ()
{
return ms_instance;
}
std::string
Application::version () const
ApplicationBase::version () const
{
return std::string (lay::Version::name ()) + " " + lay::Version::version ();
}
std::string
Application::usage ()
ApplicationBase::usage ()
{
std::string r;
r = std::string (lay::Version::exe_name ()) + " [<options>] [<file>] ..\n";
@ -1090,7 +1090,7 @@ Application::usage ()
}
int
Application::run ()
ApplicationBase::run ()
{
gtf::Player player (0);
@ -1267,7 +1267,7 @@ Application::run ()
}
void
Application::autorun ()
ApplicationBase::autorun ()
{
// call "autorun" on all plugins that wish so
for (std::vector <lay::PluginDescriptor>::const_iterator p = m_native_plugins.begin (); p != m_native_plugins.end (); ++p) {
@ -1281,7 +1281,7 @@ Application::autorun ()
}
void
Application::set_editable (bool e)
ApplicationBase::set_editable (bool e)
{
if (m_editable != e) {
m_editable = e;
@ -1310,51 +1310,8 @@ dump_children (QObject *obj, int level = 0)
}
}
int
Application::exec ()
{
if (m_no_gui) {
return 0;
} else {
// if requested, dump the widgets
if (tl::verbosity () >= 40) {
QWidgetList tl_widgets = QApplication::topLevelWidgets ();
tl::info << tl::to_string (QObject::tr ("Widget tree:"));
for (QWidgetList::const_iterator tl = tl_widgets.begin (); tl != tl_widgets.end (); ++tl) {
if (! (*tl)->objectName ().isEmpty ()) {
dump_children (*tl);
}
}
tl::info << "";
tl::info << tl::to_string (QObject::tr ("Actions list:"));
for (QWidgetList::const_iterator tl = tl_widgets.begin (); tl != tl_widgets.end (); ++tl) {
if (! (*tl)->objectName ().isEmpty ()) {
QList<QAction *> actions = (*tl)->findChildren<QAction *> ();
if (! actions.isEmpty ()) {
tl::info << tl::to_string ((*tl)->objectName ()) << ":";
for (QList<QAction *>::const_iterator a = actions.begin (); a != actions.end (); ++a) {
if (! (*a)->objectName ().isEmpty ()) {
tl::info << " " << tl::to_string ((*a)->objectName ());
}
}
}
}
}
tl::info << "";
}
return mp_qapp_gui->exec ();
}
}
void
Application::process_events (QEventLoop::ProcessEventsFlags flags, bool silent)
ApplicationBase::process_events (QEventLoop::ProcessEventsFlags flags, bool silent)
{
if (mp_mw) {
@ -1382,13 +1339,13 @@ Application::process_events (QEventLoop::ProcessEventsFlags flags, bool silent)
}
bool
Application::write_config (const std::string &config_file)
ApplicationBase::write_config (const std::string &config_file)
{
return mp_plugin_root ? mp_plugin_root->write_config (config_file) : 0;
}
void
Application::reset_config ()
ApplicationBase::reset_config ()
{
clear_config ();
for (std::vector <std::string>::const_iterator c = m_initial_config_files.begin (); c != m_initial_config_files.end (); ++c) {
@ -1399,7 +1356,7 @@ Application::reset_config ()
}
void
Application::clear_config ()
ApplicationBase::clear_config ()
{
if (mp_plugin_root) {
mp_plugin_root->clear_config ();
@ -1407,13 +1364,13 @@ Application::clear_config ()
}
bool
Application::read_config (const std::string &config_file)
ApplicationBase::read_config (const std::string &config_file)
{
return mp_plugin_root ? mp_plugin_root->read_config (config_file) : true;
}
void
Application::set_config (const std::string &name, const std::string &value)
ApplicationBase::set_config (const std::string &name, const std::string &value)
{
if (mp_plugin_root) {
mp_plugin_root->config_set (name, value);
@ -1421,7 +1378,7 @@ Application::set_config (const std::string &name, const std::string &value)
}
void
Application::config_end ()
ApplicationBase::config_end ()
{
if (mp_plugin_root) {
mp_plugin_root->config_end ();
@ -1429,7 +1386,7 @@ Application::config_end ()
}
std::string
Application::get_config (const std::string &name) const
ApplicationBase::get_config (const std::string &name) const
{
if (mp_plugin_root) {
return mp_plugin_root->config_get (name);
@ -1439,7 +1396,7 @@ Application::get_config (const std::string &name) const
}
std::vector<std::string>
Application::get_config_names () const
ApplicationBase::get_config_names () const
{
std::vector<std::string> names;
if (mp_plugin_root) {
@ -1449,12 +1406,88 @@ Application::get_config_names () const
}
bool
Application::special_app_flag (const std::string &name)
ApplicationBase::special_app_flag (const std::string &name)
{
// TODO: some more elaborate scheme?
const char *env = getenv (("KLAYOUT_" + name).c_str ());
return (env && *env);
}
// --------------------------------------------------------------------------------
// GuiApplication implementation
GuiApplication::GuiApplication (int &argc, char **argv)
: QApplication (argc, argv), ApplicationBase ()
{
init_app (argc, argv, false);
}
bool
GuiApplication::notify (QObject *receiver, QEvent *e)
{
// Note: due to a bug in some Qt versions (i.e. 4.8.3) throwing exceptions across
// signals may not be safe. Hence the local BEGIN_PROTECTED .. END_PROTECTED approach
// is still preferred over the global solution through "notify"
bool ret = true;
BEGIN_PROTECTED
ret = QApplication::notify (receiver, e);
END_PROTECTED
return ret;
}
int
GuiApplication::exec ()
{
// if requested, dump the widgets
if (tl::verbosity () >= 40) {
QWidgetList tl_widgets = QApplication::topLevelWidgets ();
tl::info << tl::to_string (QObject::tr ("Widget tree:"));
for (QWidgetList::const_iterator tl = tl_widgets.begin (); tl != tl_widgets.end (); ++tl) {
if (! (*tl)->objectName ().isEmpty ()) {
dump_children (*tl);
}
}
tl::info << "";
tl::info << tl::to_string (QObject::tr ("Actions list:"));
for (QWidgetList::const_iterator tl = tl_widgets.begin (); tl != tl_widgets.end (); ++tl) {
if (! (*tl)->objectName ().isEmpty ()) {
QList<QAction *> actions = (*tl)->findChildren<QAction *> ();
if (! actions.isEmpty ()) {
tl::info << tl::to_string ((*tl)->objectName ()) << ":";
for (QList<QAction *>::const_iterator a = actions.begin (); a != actions.end (); ++a) {
if (! (*a)->objectName ().isEmpty ()) {
tl::info << " " << tl::to_string ((*a)->objectName ());
}
}
}
}
}
tl::info << "";
}
return QApplication::exec ();
}
// --------------------------------------------------------------------------------
// NonGuiApplication implementation
NonGuiApplication::NonGuiApplication (int &argc, char **argv)
: QCoreApplication (argc, argv), ApplicationBase ()
{
init_app (argc, argv, true);
}
int
NonGuiApplication::exec ()
{
// A non-GUI application does nothing on exec
return 0;
}
}

View File

@ -82,33 +82,33 @@ struct PluginDescriptor
};
/**
* @brief The basic application object
* @brief The application base class
*
* This object encapsulates command line parsing, creation of the main window
* widget and the basic execution loop.
* This is the basic functionality for the application class.
* Two specializations exist: one for the GUI-less version (derived from QCoreApplication)
* and one for the GUI version (derived from QApplication).
*/
class LAY_PUBLIC Application
: public QApplication, public gsi::ObjectBase
class LAY_PUBLIC ApplicationBase
: public gsi::ObjectBase
{
public:
/**
* @brief The application constructor
* @brief The application constructor
*
* @param argc The number of external command-line arguments passed.
* @param argv The external command-line arguments.
* @param non_ui_mode True, if the UI shall not be enabled
*/
Application (int &argc, char **argv, bool non_ui_mode);
ApplicationBase ();
/**
* @brief Destructor
*/
~Application ();
virtual ~ApplicationBase ();
/**
* @brief The singleton instance
*/
static Application *instance ();
static ApplicationBase *instance ();
/**
* @brief Exit the application
@ -118,17 +118,12 @@ public:
void exit (int result);
/**
* @brief Reimplementation of notify from QApplication
*/
bool notify (QObject *receiver, QEvent *e);
/**
* @brief Return the program's version
* @brief Return the program's version
*/
std::string version () const;
/**
* @brief Return the program's usage string
* @brief Return the program's usage string
*/
std::string usage ();
@ -152,13 +147,15 @@ public:
*
* This method issues all the lower level methods required in order to perform the
* applications main code.
* Depending on the arguments and UI capabilities, this method will
* either execute the command line macros for open the main window.
*/
int run ();
/**
* @brief Execute the GUI main loop
* @brief Executes the UI loop if GUI is enabled
*/
int exec ();
virtual int exec () = 0;
/**
* @brief Process pending events
@ -221,9 +218,9 @@ public:
/**
* @brief Gets a value indicating whether the give special application flag is set
*
*
* Special application flags are ways to introduce debug or flags for special
* use cases. Such flags have a name and currently are controlled externally by
* use cases. Such flags have a name and currently are controlled externally by
* an environment variable called "KLAYOUT_x" where x is the name. If that
* variable is set and the value is non-empty, the flag is regarded set.
*/
@ -232,7 +229,7 @@ public:
/**
* @brief Return a reference to the Ruby interpreter
*/
gsi::Interpreter &ruby_interpreter ()
gsi::Interpreter &ruby_interpreter ()
{
return *mp_ruby_interpreter;
}
@ -240,7 +237,7 @@ public:
/**
* @brief Return a reference to the Ruby interpreter
*/
gsi::Interpreter &python_interpreter ()
gsi::Interpreter &python_interpreter ()
{
return *mp_python_interpreter;
}
@ -287,7 +284,7 @@ public:
/**
* @brief Reset config to global configuration
*/
void reset_config ();
void reset_config ();
/**
* @brief Synchronize macro collections with technology-specific macros
@ -328,6 +325,20 @@ public:
return m_native_plugins;
}
/**
* @brief Gets the QCoreApplication object
*/
virtual QCoreApplication *qapp () { return 0; }
/**
* @brief Gets the QApplication object
* This method will return non-null only if a GUI-enabled application is present.
*/
virtual QApplication *qapp_gui () { return 0; }
protected:
void init_app (int &argc, char **argv, bool non_ui_mode);
private:
void shutdown ();
void finish ();
@ -366,8 +377,6 @@ private:
bool m_vo_mode;
bool m_editable;
bool m_enable_undo;
QCoreApplication *mp_qapp;
QApplication *mp_qapp_gui;
std::auto_ptr<tl::DeferredMethodScheduler> mp_dm_scheduler;
// HINT: the ruby interpreter must be destroyed before MainWindow
// in order to maintain a valid MainWindow reference for ruby scripts and Ruby's GC all the time.
@ -381,13 +390,93 @@ private:
std::vector<PluginDescriptor> m_native_plugins;
};
/**
* @brief The GUI-enabled application class
*/
class LAY_PUBLIC GuiApplication
: public QApplication, public ApplicationBase
{
public:
GuiApplication (int &argc, char **argv);
QApplication *qapp_gui () { return this; }
QCoreApplication *qapp () { return this; }
/**
* @brief Reimplementation of notify from QApplication
*/
bool notify (QObject *receiver, QEvent *e);
/**
* @brief Gets the application instance, cast to this class
*/
static GuiApplication *instance ()
{
return dynamic_cast<GuiApplication *> (ApplicationBase::instance ());
}
/**
* @brief Specialization of exec
*/
int exec ();
/**
* @brief Hides QCoreApplication::exit
*/
void exit (int result)
{
ApplicationBase::exit (result);
}
};
/**
* @brief The non-GUI-enabled application class
*/
class LAY_PUBLIC NonGuiApplication
: public QCoreApplication, public ApplicationBase
{
public:
NonGuiApplication (int &argc, char **argv);
QApplication *qapp_gui () { return 0; }
QCoreApplication *qapp () { return this; }
/**
* @brief Gets the application instance, cast to this class
*/
static NonGuiApplication *instance ()
{
return dynamic_cast<NonGuiApplication *> (ApplicationBase::instance ());
}
/**
* @brief Specialization of exec
*/
int exec ();
/**
* @brief Hides QCoreApplication::exit
*/
void exit (int result)
{
ApplicationBase::exit (result);
}
};
} // namespace lay
namespace tl {
template <> struct type_traits<lay::Application> : public type_traits<void> {
template <> struct type_traits<lay::GuiApplication> : public type_traits<void> {
typedef tl::false_tag has_copy_constructor;
typedef tl::false_tag has_default_constructor;
};
template <> struct type_traits<lay::NonGuiApplication> : public type_traits<void> {
typedef tl::false_tag has_copy_constructor;
typedef tl::false_tag has_default_constructor;
};
}
#endif

View File

@ -119,7 +119,7 @@ FontController::sync_dirs ()
m_file_watcher->clear ();
m_file_watcher->enable (false);
std::vector<std::string> paths = lay::Application::instance ()->klayout_path ();
std::vector<std::string> paths = lay::ApplicationBase::instance ()->klayout_path ();
// add the salt grains as potential sources for library definitions

View File

@ -270,12 +270,12 @@ HelpSource::initialize_index ()
bool ok = false;
const QString help_index_cache_file = QString::fromUtf8 ("help-index.xml");
std::string per_user_cache_file = tl::to_string (QDir (tl::to_qstring (lay::Application::instance ()->appdata_path ())).absoluteFilePath (help_index_cache_file));
std::string per_user_cache_file = tl::to_string (QDir (tl::to_qstring (lay::ApplicationBase::instance ()->appdata_path ())).absoluteFilePath (help_index_cache_file));
// Try to obtain the help index from the installation or application path
std::vector<std::string> cache_files;
cache_files.push_back (tl::to_string (QDir (tl::to_qstring (lay::Application::instance ()->inst_path ())).absoluteFilePath (help_index_cache_file)));
cache_files.push_back (tl::to_string (QDir (tl::to_qstring (lay::ApplicationBase::instance ()->inst_path ())).absoluteFilePath (help_index_cache_file)));
cache_files.push_back (per_user_cache_file);
for (std::vector<std::string>::const_iterator c = cache_files.begin (); ! ok && c != cache_files.end (); ++c) {
@ -283,7 +283,7 @@ HelpSource::initialize_index ()
try {
tl::XMLFileSource in (*c);
help_index_structure.parse (in, *this);
if (m_klayout_version == lay::Application::instance ()->version ()) {
if (m_klayout_version == lay::ApplicationBase::instance ()->version ()) {
ok = true;
}
} catch (tl::Exception &ex) {
@ -353,7 +353,7 @@ HelpSource::create_index_file (const std::string &path)
std::string
HelpSource::klayout_version () const
{
return lay::Application::instance ()->version ();
return lay::ApplicationBase::instance ()->version ();
}
void
@ -513,7 +513,7 @@ HelpSource::get_image (const std::string &u)
std::string
HelpSource::get_css (const std::string &u)
{
std::ifstream t (tl::to_string (QDir (tl::to_qstring (lay::Application::instance()->inst_path ())).absoluteFilePath (QString::fromUtf8 ("help_format.css"))).c_str ());
std::ifstream t (tl::to_string (QDir (tl::to_qstring (lay::ApplicationBase::instance()->inst_path ())).absoluteFilePath (QString::fromUtf8 ("help_format.css"))).c_str ());
if (t.good ()) {
std::string c;
while (t.good ()) {

View File

@ -129,7 +129,7 @@ LibraryController::sync_files ()
// build a list of paths vs. technology
std::vector<std::pair<std::string, std::string> > paths;
std::vector<std::string> klayout_path = lay::Application::instance ()->klayout_path ();
std::vector<std::string> klayout_path = lay::ApplicationBase::instance ()->klayout_path ();
for (std::vector<std::string>::const_iterator p = klayout_path.begin (); p != klayout_path.end (); ++p) {
paths.push_back (std::make_pair (*p, std::string ()));
}

View File

@ -292,7 +292,7 @@ MacroController::drop_url (const std::string &path_or_url)
QMessageBox::No) == QMessageBox::Yes) {
// Use the application data folder
QDir folder (tl::to_qstring (lay::Application::instance ()->appdata_path ()));
QDir folder (tl::to_qstring (lay::ApplicationBase::instance ()->appdata_path ()));
std::string cat = "macros";
if (! macro->category ().empty ()) {
@ -300,7 +300,7 @@ MacroController::drop_url (const std::string &path_or_url)
}
if (! folder.cd (tl::to_qstring (cat))) {
throw tl::Exception (tl::to_string (QObject::tr ("Folder '%s' does not exists in installation path '%s' - cannot install")).c_str (), cat, lay::Application::instance ()->appdata_path ());
throw tl::Exception (tl::to_string (QObject::tr ("Folder '%s' does not exists in installation path '%s' - cannot install")).c_str (), cat, lay::ApplicationBase::instance ()->appdata_path ());
}
QFileInfo target (folder, file_name);

View File

@ -527,7 +527,7 @@ MacroEditorDialog::MacroEditorDialog (QWidget * /*parent*/, lym::MacroCollection
}
// scan macro templates
for (std::vector<std::string>::const_iterator p = lay::Application::instance ()->klayout_path ().begin (); p != lay::Application::instance ()->klayout_path ().end (); ++p) {
for (std::vector<std::string>::const_iterator p = lay::ApplicationBase::instance ()->klayout_path ().begin (); p != lay::ApplicationBase::instance ()->klayout_path ().end (); ++p) {
QDir dir (QDir (tl::to_qstring (*p)).filePath (tl::to_qstring ("macro-templates")));
@ -760,13 +760,13 @@ MacroEditorDialog::showEvent (QShowEvent *)
m_history_index = -1;
input_field->clearEditText ();
lay::Application::instance ()->ruby_interpreter ().push_console (this);
lay::ApplicationBase::instance ()->ruby_interpreter ().push_console (this);
if (m_debugging_on) {
lay::Application::instance ()->ruby_interpreter ().push_exec_handler (this);
lay::ApplicationBase::instance ()->ruby_interpreter ().push_exec_handler (this);
}
lay::Application::instance ()->python_interpreter ().push_console (this);
lay::ApplicationBase::instance ()->python_interpreter ().push_console (this);
if (m_debugging_on) {
lay::Application::instance ()->python_interpreter ().push_exec_handler (this);
lay::ApplicationBase::instance ()->python_interpreter ().push_exec_handler (this);
}
std::string ci;
@ -795,9 +795,9 @@ MacroEditorDialog::showEvent (QShowEvent *)
ex.test (";");
if (ip == "ruby") {
m_watch_expressions.push_back (std::make_pair (&lay::Application::instance ()->ruby_interpreter (), expr));
m_watch_expressions.push_back (std::make_pair (&lay::ApplicationBase::instance ()->ruby_interpreter (), expr));
} else if (ip == "python") {
m_watch_expressions.push_back (std::make_pair (&lay::Application::instance ()->python_interpreter (), expr));
m_watch_expressions.push_back (std::make_pair (&lay::ApplicationBase::instance ()->python_interpreter (), expr));
}
}
@ -900,9 +900,9 @@ MacroEditorDialog::closeEvent (QCloseEvent *)
if (! om.empty ()) {
om += ";";
}
if (i->first == &lay::Application::instance ()->ruby_interpreter ()) {
if (i->first == &lay::ApplicationBase::instance ()->ruby_interpreter ()) {
we += "ruby";
} else if (i->first == &lay::Application::instance ()->python_interpreter ()) {
} else if (i->first == &lay::ApplicationBase::instance ()->python_interpreter ()) {
we += "python";
}
we += ":";
@ -932,10 +932,10 @@ MacroEditorDialog::closeEvent (QCloseEvent *)
m_continue = false;
m_window_closed = true;
lay::Application::instance ()->ruby_interpreter ().remove_console (this);
lay::Application::instance ()->ruby_interpreter ().remove_exec_handler (this);
lay::Application::instance ()->python_interpreter ().remove_console (this);
lay::Application::instance ()->python_interpreter ().remove_exec_handler (this);
lay::ApplicationBase::instance ()->ruby_interpreter ().remove_console (this);
lay::ApplicationBase::instance ()->ruby_interpreter ().remove_exec_handler (this);
lay::ApplicationBase::instance ()->python_interpreter ().remove_console (this);
lay::ApplicationBase::instance ()->python_interpreter ().remove_exec_handler (this);
}
void
@ -951,11 +951,11 @@ MacroEditorDialog::set_debugging_on (bool on)
if (isVisible ()) {
if (on) {
lay::Application::instance ()->ruby_interpreter ().push_exec_handler (this);
lay::Application::instance ()->python_interpreter ().push_exec_handler (this);
lay::ApplicationBase::instance ()->ruby_interpreter ().push_exec_handler (this);
lay::ApplicationBase::instance ()->python_interpreter ().push_exec_handler (this);
} else {
lay::Application::instance ()->ruby_interpreter ().remove_exec_handler (this);
lay::Application::instance ()->python_interpreter ().remove_exec_handler (this);
lay::ApplicationBase::instance ()->ruby_interpreter ().remove_exec_handler (this);
lay::ApplicationBase::instance ()->python_interpreter ().remove_exec_handler (this);
}
}
@ -965,12 +965,12 @@ MacroEditorDialog::set_debugging_on (bool on)
void
MacroEditorDialog::process_events (QEventLoop::ProcessEventsFlags flags)
{
if (lay::Application::instance ()) {
if (lay::ApplicationBase::instance ()) {
// disable execution of deferred methods to avoid undesired execution of
// code while we are inside a Ruby callback through the silent mode
bool last_processing = m_in_processing;
m_in_processing = true;
lay::Application::instance ()->process_events (flags, true /*silent*/);
lay::ApplicationBase::instance ()->process_events (flags, true /*silent*/);
m_in_processing = last_processing;
}
}
@ -1132,9 +1132,9 @@ MacroEditorDialog::execute (const QString &cmd)
gsi::Interpreter *interpreter = 0;
if (rubyLangSel->isChecked ()) {
interpreter = &lay::Application::instance ()->ruby_interpreter ();
interpreter = &lay::ApplicationBase::instance ()->ruby_interpreter ();
} else if (pythonLangSel->isChecked ()) {
interpreter = &lay::Application::instance ()->python_interpreter ();
interpreter = &lay::ApplicationBase::instance ()->python_interpreter ();
}
if (interpreter) {
@ -3036,7 +3036,7 @@ MacroEditorDialog::do_update_ui_to_run_mode ()
// Force language type to match the current execution context
if (m_in_breakpoint && mp_current_interpreter) {
if (mp_current_interpreter == &lay::Application::instance ()->python_interpreter ()) {
if (mp_current_interpreter == &lay::ApplicationBase::instance ()->python_interpreter ()) {
pythonLangSel->setChecked (true);
rubyLangSel->setChecked (false);
} else {

View File

@ -1058,7 +1058,7 @@ MainWindow::init_menu ()
}
// if in "viewer-only mode", hide all entries in the "hide_vo" group
if ((lay::Application::instance () && lay::Application::instance ()->is_vo_mode ())) {
if ((lay::ApplicationBase::instance () && lay::ApplicationBase::instance ()->is_vo_mode ())) {
std::vector<std::string> hide_vo_grp = mp_menu->group ("hide_vo");
for (std::vector<std::string>::const_iterator g = hide_vo_grp.begin (); g != hide_vo_grp.end (); ++g) {
mp_menu->action (*g).set_visible (false);
@ -1067,7 +1067,7 @@ MainWindow::init_menu ()
// if not in editable mode, hide all entries from "edit_mode" group
// TODO: later do this on each change of the view - each view might get it's own editable mode
bool view_mode = (lay::Application::instance () && !lay::Application::instance ()->is_editable ());
bool view_mode = (lay::ApplicationBase::instance () && !lay::ApplicationBase::instance ()->is_editable ());
std::vector<std::string> edit_mode_grp = mp_menu->group ("edit_mode");
for (std::vector<std::string>::const_iterator g = edit_mode_grp.begin (); g != edit_mode_grp.end (); ++g) {
@ -1293,7 +1293,7 @@ MainWindow::about_to_exec ()
}
// TODO: later, each view may get it's own editable flag
if (lay::Application::instance () && !lay::Application::instance ()->is_editable ()) {
if (lay::ApplicationBase::instance () && !lay::ApplicationBase::instance ()->is_editable ()) {
TipDialog td (this,
tl::to_string (QObject::tr ("KLayout has been started in viewer mode. In this mode, editor functions are not available.\n\nTo enable these functions, start KLayout in editor mode by using the \"-e\" command line switch or select it as the default mode in the setup dialog. Choose \"Setup\" in the \"File\" menu and check \"Use editing mode by default\" on the \"Editing Mode\" page in the \"Application\" section.")),
"editor-mode");
@ -1329,7 +1329,7 @@ MainWindow::about_to_exec ()
edt::combine_mode_type cm = edt::CM_Add;
config_get (edt::cfg_edit_combine_mode, cm, edt::CMConverter ());
if (lay::Application::instance ()->is_editable () && cm != edt::CM_Add) {
if (lay::ApplicationBase::instance ()->is_editable () && cm != edt::CM_Add) {
lay::TipDialog td (QApplication::activeWindow (),
tl::to_string (QObject::tr ("The background combination mode of the shape editor is set to some other mode than 'Add'.\n"
"This can be confusing, because a shape may not be drawn as expected.\n\nTo switch back to normal mode, choose 'Add' for the background combination mode in the toolbar.")),
@ -3735,7 +3735,7 @@ MainWindow::clone_current_view ()
}
// create a new view
view = new lay::LayoutView (current_view (), &m_manager, lay::Application::instance ()->is_editable (), this, mp_view_stack);
view = new lay::LayoutView (current_view (), &m_manager, lay::ApplicationBase::instance ()->is_editable (), this, mp_view_stack);
connect (view, SIGNAL (title_changed ()), this, SLOT (view_title_changed ()));
connect (view, SIGNAL (dirty_changed ()), this, SLOT (view_title_changed ()));
connect (view, SIGNAL (edits_enabled_changed ()), this, SLOT (edits_enabled_changed ()));
@ -4344,7 +4344,7 @@ int
MainWindow::do_create_view ()
{
// create a new view
lay::LayoutView *view = new lay::LayoutView (&m_manager, lay::Application::instance ()->is_editable (), this, mp_view_stack);
lay::LayoutView *view = new lay::LayoutView (&m_manager, lay::ApplicationBase::instance ()->is_editable (), this, mp_view_stack);
connect (view, SIGNAL (title_changed ()), this, SLOT (view_title_changed ()));
connect (view, SIGNAL (dirty_changed ()), this, SLOT (view_title_changed ()));
@ -4538,9 +4538,9 @@ MainWindow::update_window_title ()
if (current_view ()->is_dirty ()) {
sep += "[+] ";
}
setWindowTitle (tl::to_qstring (lay::Application::instance ()->version () + sep + current_view ()->title ()));
setWindowTitle (tl::to_qstring (lay::ApplicationBase::instance ()->version () + sep + current_view ()->title ()));
} else {
setWindowTitle (tl::to_qstring (lay::Application::instance ()->version ()));
setWindowTitle (tl::to_qstring (lay::ApplicationBase::instance ()->version ()));
}
}
@ -5681,11 +5681,11 @@ HelpAboutDialog::HelpAboutDialog (QWidget *parent)
mp_ui->setupUi (this);
std::vector<std::string> build_options;
if (lay::Application::instance ()->ruby_interpreter ().available ()) {
build_options.push_back (tl::to_string (tr ("Ruby interpreter ")) + lay::Application::instance ()->ruby_interpreter ().version ());
if (lay::ApplicationBase::instance ()->ruby_interpreter ().available ()) {
build_options.push_back (tl::to_string (tr ("Ruby interpreter ")) + lay::ApplicationBase::instance ()->ruby_interpreter ().version ());
}
if (lay::Application::instance ()->python_interpreter ().available ()) {
build_options.push_back (tl::to_string (tr ("Python interpreter ")) + lay::Application::instance ()->python_interpreter ().version ());
if (lay::ApplicationBase::instance ()->python_interpreter ().available ()) {
build_options.push_back (tl::to_string (tr ("Python interpreter ")) + lay::ApplicationBase::instance ()->python_interpreter ().version ());
}
#if defined(HAVE_QTBINDINGS)
build_options.push_back (tl::to_string (tr ("Qt bindings for scripts")));
@ -5720,12 +5720,12 @@ HelpAboutDialog::HelpAboutDialog (QWidget *parent)
s += "</ul>";
}
if (! lay::Application::instance ()->native_plugins ().empty ()) {
if (! lay::ApplicationBase::instance ()->native_plugins ().empty ()) {
s += "<p>";
s += "<h4>";
s += escape_xml (tl::to_string (QObject::tr ("Binary extensions:")));
s += "</h4><ul>";
for (std::vector<lay::PluginDescriptor>::const_iterator pd = lay::Application::instance ()->native_plugins ().begin (); pd != lay::Application::instance ()->native_plugins ().end (); ++pd) {
for (std::vector<lay::PluginDescriptor>::const_iterator pd = lay::ApplicationBase::instance ()->native_plugins ().begin (); pd != lay::ApplicationBase::instance ()->native_plugins ().end (); ++pd) {
s += "<li>";
if (! pd->description.empty ()) {
s += escape_xml (pd->description);

View File

@ -272,7 +272,7 @@ SettingsForm::reset_clicked ()
BEGIN_PROTECTED
lay::Application::instance ()->reset_config ();
lay::ApplicationBase::instance ()->reset_config ();
setup ();
END_PROTECTED

View File

@ -292,12 +292,12 @@ void signal_handler (int signo, siginfo_t *si, void *)
std::auto_ptr<CrashMessage> msg;
bool has_gui = lay::Application::instance () && lay::Application::instance ()->has_gui ();
bool has_gui = lay::ApplicationBase::instance () && lay::ApplicationBase::instance ()->has_gui ();
if (has_gui) {
msg.reset (new CrashMessage (0, false, tl::to_qstring (text) + QObject::tr ("\nCollecting backtrace ..")));
msg->show ();
lay::Application::instance ()->setOverrideCursor (Qt::WaitCursor);
lay::ApplicationBase::instance ()->qapp_gui ()->setOverrideCursor (Qt::WaitCursor);
}
text += std::string ("\nBacktrace:\n");
@ -326,7 +326,7 @@ void signal_handler (int signo, siginfo_t *si, void *)
for (size_t i = 0; i < nptrs; ++i) {
if (has_gui) {
lay::Application::instance ()->processEvents ();
lay::ApplicationBase::instance ()->qapp_gui ()->processEvents ();
if (msg->is_cancel_pressed ()) {
text += "...\n";
break;
@ -402,7 +402,7 @@ void signal_handler (int signo, siginfo_t *si, void *)
if (has_gui) {
lay::Application::instance ()->setOverrideCursor (QCursor ());
lay::ApplicationBase::instance ()->qapp_gui ()->setOverrideCursor (QCursor ());
// YES! I! KNOW!
// In a signal handler you shall not do fancy stuff (in particular not

View File

@ -68,7 +68,7 @@ main (int argc, char **argv)
}
static int
run_tests (const std::vector<tl::TestBase *> &selected_tests, bool editable, bool non_editable, bool slow, lay::Application &app, bool gsi_coverage, const std::vector<std::string> &class_names_vector)
run_tests (const std::vector<tl::TestBase *> &selected_tests, bool editable, bool non_editable, bool slow, lay::ApplicationBase &app, bool gsi_coverage, const std::vector<std::string> &class_names_vector)
{
std::set<std::string> class_names;
class_names.insert (class_names_vector.begin (), class_names_vector.end ());
@ -374,7 +374,7 @@ main_cont (int &argc, char **argv)
static char av3[] = "-rx"; // No mplicit macros
char *av[] = { av0, av1, av2, av3, 0 };
int ac = sizeof (av) / sizeof (av[0]) - 1;
lay::Application app (ac, av, false);
lay::GuiApplication app (ac, av);
app.ruby_interpreter ().push_console (&console);
app.python_interpreter ().push_console (&console);