mirror of https://github.com/KLayout/klayout.git
Further refactoring - more functionality for GUI/non-GUI application classes.
This commit is contained in:
parent
bbb1514184
commit
9906565013
|
|
@ -225,6 +225,8 @@ ApplicationBase::ApplicationBase ()
|
||||||
m_write_config_file (true),
|
m_write_config_file (true),
|
||||||
m_gtf_replay_rate (0),
|
m_gtf_replay_rate (0),
|
||||||
m_gtf_replay_stop (-1),
|
m_gtf_replay_stop (-1),
|
||||||
|
m_gtf_record (),
|
||||||
|
m_gtf_save_incremental (false),
|
||||||
m_no_macros (false),
|
m_no_macros (false),
|
||||||
m_same_view (false),
|
m_same_view (false),
|
||||||
m_sync_mode (false),
|
m_sync_mode (false),
|
||||||
|
|
@ -233,12 +235,7 @@ ApplicationBase::ApplicationBase ()
|
||||||
m_editable (false),
|
m_editable (false),
|
||||||
m_enable_undo (true),
|
m_enable_undo (true),
|
||||||
mp_ruby_interpreter (0),
|
mp_ruby_interpreter (0),
|
||||||
mp_python_interpreter (0),
|
mp_python_interpreter (0)
|
||||||
mp_mw (0),
|
|
||||||
mp_pr (0),
|
|
||||||
mp_pb (0),
|
|
||||||
mp_plugin_root (0),
|
|
||||||
mp_recorder (0)
|
|
||||||
{
|
{
|
||||||
// nothing yet - see init
|
// nothing yet - see init
|
||||||
}
|
}
|
||||||
|
|
@ -256,8 +253,6 @@ ApplicationBase::init_app (int &argc, char **argv, bool non_ui_mode)
|
||||||
tl::set_ui_exception_handlers (ui_exception_handler_tl, ui_exception_handler_std, ui_exception_handler_def);
|
tl::set_ui_exception_handlers (ui_exception_handler_tl, ui_exception_handler_std, ui_exception_handler_def);
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_dm_scheduler.reset (new tl::DeferredMethodScheduler ());
|
|
||||||
|
|
||||||
// initialize the system codecs (Hint: this must be done after the QApplication is initialized because
|
// initialize the system codecs (Hint: this must be done after the QApplication is initialized because
|
||||||
// it will call setlocale)
|
// it will call setlocale)
|
||||||
tl::initialize_codecs ();
|
tl::initialize_codecs ();
|
||||||
|
|
@ -284,9 +279,6 @@ ApplicationBase::init_app (int &argc, char **argv, bool non_ui_mode)
|
||||||
tl_assert (ms_instance == 0);
|
tl_assert (ms_instance == 0);
|
||||||
ms_instance = this;
|
ms_instance = this;
|
||||||
|
|
||||||
std::string gtf_record;
|
|
||||||
bool gtf_save_incremental = false;
|
|
||||||
|
|
||||||
// get and create the klayout appdata folder if required
|
// get and create the klayout appdata folder if required
|
||||||
m_appdata_path = lay::get_appdata_path ();
|
m_appdata_path = lay::get_appdata_path ();
|
||||||
|
|
||||||
|
|
@ -491,11 +483,11 @@ ApplicationBase::init_app (int &argc, char **argv, bool non_ui_mode)
|
||||||
|
|
||||||
} else if (a == "-gr" && (i + 1) < argc) {
|
} else if (a == "-gr" && (i + 1) < argc) {
|
||||||
|
|
||||||
gtf_record = args [++i];
|
m_gtf_record = args [++i];
|
||||||
|
|
||||||
} else if (a == "-gi") {
|
} else if (a == "-gi") {
|
||||||
|
|
||||||
gtf_save_incremental = true;
|
m_gtf_save_incremental = true;
|
||||||
|
|
||||||
} else if (a == "-gp" && (i + 1) < argc) {
|
} else if (a == "-gp" && (i + 1) < argc) {
|
||||||
|
|
||||||
|
|
@ -795,11 +787,10 @@ ApplicationBase::init_app (int &argc, char **argv, bool non_ui_mode)
|
||||||
db::set_default_editable_mode (m_editable);
|
db::set_default_editable_mode (m_editable);
|
||||||
db::enable_transactions (m_enable_undo);
|
db::enable_transactions (m_enable_undo);
|
||||||
|
|
||||||
if (qapp_gui () && ! gtf_record.empty ()) {
|
if (! m_gtf_record.empty ()) {
|
||||||
// since the recorder tracks QAction connections etc., it must be instantiated before every other
|
// since the recorder tracks QAction connections etc., it must be instantiated before every other
|
||||||
// object performing a gtf::action_connect for example
|
// object performing a gtf::action_connect for example
|
||||||
mp_recorder = new gtf::Recorder (qapp_gui (), gtf_record);
|
prepare_recording (m_gtf_record, m_gtf_save_incremental);
|
||||||
mp_recorder->save_incremental (gtf_save_incremental);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tl::Eval::set_global_var ("appdata_path", tl::Variant (m_appdata_path));
|
tl::Eval::set_global_var ("appdata_path", tl::Variant (m_appdata_path));
|
||||||
|
|
@ -822,16 +813,8 @@ ApplicationBase::init_app (int &argc, char **argv, bool non_ui_mode)
|
||||||
// suffixes through the MacroInterpreter interface.
|
// suffixes through the MacroInterpreter interface.
|
||||||
lym::MacroCollection::root ().rescan ();
|
lym::MacroCollection::root ().rescan ();
|
||||||
|
|
||||||
if (qapp_gui ()) {
|
// creates the main window or plugin root as required
|
||||||
mp_mw = new lay::MainWindow (qapp_gui (), "main_window");
|
setup ();
|
||||||
QObject::connect (mp_mw, SIGNAL (closed ()), qapp_gui (), SLOT (quit ()));
|
|
||||||
mp_plugin_root = mp_mw;
|
|
||||||
} else {
|
|
||||||
mp_pr = new lay::ProgressReporter ();
|
|
||||||
mp_pb = new TextProgress (10 /*verbosity level*/);
|
|
||||||
mp_pr->set_progress_bar (mp_pb);
|
|
||||||
mp_plugin_root = new lay::PluginRoot ();
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize the plugins for the first time
|
// initialize the plugins for the first time
|
||||||
if (tl::verbosity () >= 20) {
|
if (tl::verbosity () >= 20) {
|
||||||
|
|
@ -842,11 +825,11 @@ ApplicationBase::init_app (int &argc, char **argv, bool non_ui_mode)
|
||||||
if (tl::verbosity () >= 20) {
|
if (tl::verbosity () >= 20) {
|
||||||
tl::info << " " << cls.current_name () << " [" << cls.current_position () << "]";
|
tl::info << " " << cls.current_name () << " [" << cls.current_position () << "]";
|
||||||
}
|
}
|
||||||
pd->initialize (mp_plugin_root);
|
pd->initialize (plugin_root ());
|
||||||
}
|
}
|
||||||
|
|
||||||
// establish the configuration
|
// establish the configuration
|
||||||
mp_plugin_root->config_setup ();
|
plugin_root ()->config_setup ();
|
||||||
|
|
||||||
// Some info output
|
// Some info output
|
||||||
if (tl::verbosity () >= 20) {
|
if (tl::verbosity () >= 20) {
|
||||||
|
|
@ -868,11 +851,8 @@ ApplicationBase::~ApplicationBase ()
|
||||||
{
|
{
|
||||||
tl::set_ui_exception_handlers (0, 0, 0);
|
tl::set_ui_exception_handlers (0, 0, 0);
|
||||||
|
|
||||||
if (! ms_instance) {
|
// check whether shutdown was called
|
||||||
return;
|
tl_assert (ms_instance == 0);
|
||||||
}
|
|
||||||
|
|
||||||
shutdown ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string>
|
std::vector<std::string>
|
||||||
|
|
@ -933,26 +913,28 @@ ApplicationBase::exit (int result)
|
||||||
if (! result) {
|
if (! result) {
|
||||||
finish ();
|
finish ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// uninitialize the plugins
|
||||||
|
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
|
||||||
|
lay::PluginDeclaration *pd = const_cast<lay::PluginDeclaration *> (&*cls);
|
||||||
|
pd->uninitialize (plugin_root ());
|
||||||
|
}
|
||||||
|
|
||||||
shutdown ();
|
shutdown ();
|
||||||
|
|
||||||
::exit (result);
|
::exit (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ApplicationBase::finish ()
|
ApplicationBase::finish ()
|
||||||
{
|
{
|
||||||
// save the recorded test events
|
if (plugin_root () && m_write_config_file) {
|
||||||
if (mp_mw && mp_recorder && mp_recorder->recording ()) {
|
|
||||||
mp_recorder->stop ();
|
|
||||||
mp_recorder->save ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mp_plugin_root && m_write_config_file) {
|
|
||||||
|
|
||||||
if (! m_config_file_to_write.empty ()) {
|
if (! m_config_file_to_write.empty ()) {
|
||||||
if (tl::verbosity () >= 20) {
|
if (tl::verbosity () >= 20) {
|
||||||
tl::info << tl::to_string (QObject::tr ("Updating configuration file ")) << m_config_file_to_write;
|
tl::info << tl::to_string (QObject::tr ("Updating configuration file ")) << m_config_file_to_write;
|
||||||
}
|
}
|
||||||
mp_plugin_root->write_config (m_config_file_to_write);
|
plugin_root ()->write_config (m_config_file_to_write);
|
||||||
}
|
}
|
||||||
if (! m_config_file_to_delete.empty () && m_config_file_to_delete != m_config_file_to_write) {
|
if (! m_config_file_to_delete.empty () && m_config_file_to_delete != m_config_file_to_write) {
|
||||||
if (tl::verbosity () >= 20) {
|
if (tl::verbosity () >= 20) {
|
||||||
|
|
@ -964,48 +946,21 @@ ApplicationBase::finish ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ApplicationBase::prepare_recording (const std::string & /*gtf_record*/, bool /*gtf_record_incremental*/)
|
||||||
|
{
|
||||||
|
// the base class does nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ApplicationBase::start_recording ()
|
||||||
|
{
|
||||||
|
// the base class does nothing
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ApplicationBase::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) {
|
|
||||||
lay::PluginDeclaration *pd = const_cast<lay::PluginDeclaration *> (&*cls);
|
|
||||||
pd->uninitialize (mp_plugin_root);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mp_mw) {
|
|
||||||
delete mp_mw;
|
|
||||||
mp_mw = 0;
|
|
||||||
mp_plugin_root = 0;
|
|
||||||
} else if (mp_plugin_root) {
|
|
||||||
delete mp_plugin_root;
|
|
||||||
mp_plugin_root = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete all other top level widgets for safety - we don't want Ruby clean them up for us
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mp_pr) {
|
|
||||||
delete mp_pr;
|
|
||||||
mp_pr = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mp_pb) {
|
|
||||||
delete mp_pb;
|
|
||||||
mp_pb = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mp_recorder) {
|
|
||||||
delete mp_recorder;
|
|
||||||
mp_recorder = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mp_ruby_interpreter) {
|
if (mp_ruby_interpreter) {
|
||||||
delete mp_ruby_interpreter;
|
delete mp_ruby_interpreter;
|
||||||
mp_ruby_interpreter = 0;
|
mp_ruby_interpreter = 0;
|
||||||
|
|
@ -1080,25 +1035,24 @@ ApplicationBase::usage ()
|
||||||
int
|
int
|
||||||
ApplicationBase::run ()
|
ApplicationBase::run ()
|
||||||
{
|
{
|
||||||
|
lay::MainWindow *mw = main_window ();
|
||||||
gtf::Player player (0);
|
gtf::Player player (0);
|
||||||
|
|
||||||
if (mp_mw) {
|
if (mw) {
|
||||||
|
|
||||||
mp_mw->set_synchronous (m_sync_mode);
|
(mw)->set_synchronous (m_sync_mode);
|
||||||
|
|
||||||
if (! m_no_gui) {
|
if (! m_no_gui) {
|
||||||
mp_mw->setWindowTitle (tl::to_qstring (version ()));
|
(mw)->setWindowTitle (tl::to_qstring (version ()));
|
||||||
mp_mw->resize (800, 600);
|
(mw)->resize (800, 600);
|
||||||
mp_mw->show ();
|
(mw)->show ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! m_gtf_replay.empty ()) {
|
if (! m_gtf_replay.empty ()) {
|
||||||
player.load (m_gtf_replay);
|
player.load (m_gtf_replay);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp_recorder) {
|
start_recording ();
|
||||||
mp_recorder->start ();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1108,7 +1062,7 @@ ApplicationBase::run ()
|
||||||
|
|
||||||
for (std::vector <std::string>::const_iterator c = m_config_files.begin (); c != m_config_files.end (); ++c) {
|
for (std::vector <std::string>::const_iterator c = m_config_files.begin (); c != m_config_files.end (); ++c) {
|
||||||
BEGIN_PROTECTED_CLEANUP
|
BEGIN_PROTECTED_CLEANUP
|
||||||
mp_plugin_root->read_config (*c);
|
plugin_root ()->read_config (*c);
|
||||||
// if the last config was read successfully no reset will happen:
|
// if the last config was read successfully no reset will happen:
|
||||||
config_failed = false;
|
config_failed = false;
|
||||||
END_PROTECTED_CLEANUP {
|
END_PROTECTED_CLEANUP {
|
||||||
|
|
@ -1153,7 +1107,7 @@ ApplicationBase::run ()
|
||||||
// Run plugin and macro specific initializations
|
// Run plugin and macro specific initializations
|
||||||
autorun ();
|
autorun ();
|
||||||
|
|
||||||
if (mp_mw) {
|
if (mw) {
|
||||||
|
|
||||||
for (std::vector <std::pair<file_type, std::pair<std::string, std::string> > >::const_iterator f = m_files.begin (); f != m_files.end (); ++f) {
|
for (std::vector <std::pair<file_type, std::pair<std::string, std::string> > >::const_iterator f = m_files.begin (); f != m_files.end (); ++f) {
|
||||||
|
|
||||||
|
|
@ -1162,29 +1116,29 @@ ApplicationBase::run ()
|
||||||
std::string filename = f->second.first;
|
std::string filename = f->second.first;
|
||||||
|
|
||||||
if (f->first != layout_file_with_tech) {
|
if (f->first != layout_file_with_tech) {
|
||||||
mp_mw->add_mru (f->second.first);
|
mw->add_mru (f->second.first);
|
||||||
mp_mw->load_layout (f->second.first, m_same_view ? 2 /*same view*/ : 1 /*new view*/);
|
mw->load_layout (f->second.first, m_same_view ? 2 /*same view*/ : 1 /*new view*/);
|
||||||
} else {
|
} else {
|
||||||
mp_mw->add_mru (f->second.first, f->second.second);
|
mw->add_mru (f->second.first, f->second.second);
|
||||||
mp_mw->load_layout (f->second.first, f->second.second, m_same_view ? 2 /*same view*/ : 1 /*new view*/);
|
mw->load_layout (f->second.first, f->second.second, m_same_view ? 2 /*same view*/ : 1 /*new view*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make the first one loaded the active one.
|
// Make the first one loaded the active one.
|
||||||
if (mp_mw->current_view ()) {
|
if (mw->current_view ()) {
|
||||||
mp_mw->current_view ()->set_active_cellview_index (0);
|
mw->current_view ()->set_active_cellview_index (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (mp_mw->current_view () == 0) {
|
if (mw->current_view () == 0) {
|
||||||
mp_mw->create_view ();
|
mw->create_view ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp_mw->current_view () != 0) {
|
if (mw->current_view () != 0) {
|
||||||
std::auto_ptr <rdb::Database> db (new rdb::Database ());
|
std::auto_ptr <rdb::Database> db (new rdb::Database ());
|
||||||
db->load (f->second.first);
|
db->load (f->second.first);
|
||||||
int rdb_index = mp_mw->current_view ()->add_rdb (db.release ());
|
int rdb_index = mw->current_view ()->add_rdb (db.release ());
|
||||||
mp_mw->current_view ()->open_rdb_browser (rdb_index, mp_mw->current_view ()->active_cellview_index ());
|
mw->current_view ()->open_rdb_browser (rdb_index, mw->current_view ()->active_cellview_index ());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1192,23 +1146,23 @@ ApplicationBase::run ()
|
||||||
|
|
||||||
if (! m_layer_props_file.empty ()) {
|
if (! m_layer_props_file.empty ()) {
|
||||||
|
|
||||||
if (m_lyp_map_all_cvs && mp_mw->is_single_cv_layer_properties_file (m_layer_props_file)) {
|
if (m_lyp_map_all_cvs && mw->is_single_cv_layer_properties_file (m_layer_props_file)) {
|
||||||
mp_mw->load_layer_properties (m_layer_props_file, -1, true /*all views*/, m_lyp_add_default);
|
mw->load_layer_properties (m_layer_props_file, -1, true /*all views*/, m_lyp_add_default);
|
||||||
} else {
|
} else {
|
||||||
mp_mw->load_layer_properties (m_layer_props_file, true /*all views*/, m_lyp_add_default);
|
mw->load_layer_properties (m_layer_props_file, true /*all views*/, m_lyp_add_default);
|
||||||
}
|
}
|
||||||
|
|
||||||
tl::log << "Layer properties loaded '" << m_layer_props_file << "'";
|
tl::log << "Layer properties loaded '" << m_layer_props_file << "'";
|
||||||
|
|
||||||
// because the layer may carry transformations, we need to refit the cellviews.
|
// because the layer may carry transformations, we need to refit the cellviews.
|
||||||
for (unsigned int v = 0; v != mp_mw->views (); ++v) {
|
for (unsigned int v = 0; v != mw->views (); ++v) {
|
||||||
mp_mw->view (v)->zoom_fit ();
|
mw->view (v)->zoom_fit ();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! m_session_file.empty ()) {
|
if (! m_session_file.empty ()) {
|
||||||
mp_mw->restore_session (m_session_file);
|
mw->restore_session (m_session_file);
|
||||||
tl::log << "Session restored '" << m_session_file << "'";
|
tl::log << "Session restored '" << m_session_file << "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1219,20 +1173,20 @@ ApplicationBase::run ()
|
||||||
// Give the plugins a change to do some last-minute initialisation and checks
|
// Give the plugins a change to do some last-minute initialisation and checks
|
||||||
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
|
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
|
||||||
lay::PluginDeclaration *pd = const_cast<lay::PluginDeclaration *> (&*cls);
|
lay::PluginDeclaration *pd = const_cast<lay::PluginDeclaration *> (&*cls);
|
||||||
pd->initialized (mp_mw);
|
pd->initialized (mw);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! m_no_gui && m_gtf_replay.empty () && ! mp_recorder) {
|
if (! m_no_gui && m_gtf_replay.empty () && m_gtf_record.empty ()) {
|
||||||
// Show initial tip window if required
|
// Show initial tip window if required
|
||||||
mp_mw->about_to_exec ();
|
mw->about_to_exec ();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (mp_plugin_root) {
|
} else if (plugin_root ()) {
|
||||||
|
|
||||||
// Give the plugins a change to do some last-minute initialisation and checks
|
// Give the plugins a change to do some last-minute initialisation and checks
|
||||||
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
|
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
|
||||||
lay::PluginDeclaration *pd = const_cast<lay::PluginDeclaration *> (&*cls);
|
lay::PluginDeclaration *pd = const_cast<lay::PluginDeclaration *> (&*cls);
|
||||||
pd->initialized (mp_plugin_root);
|
pd->initialized (plugin_root ());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1299,37 +1253,15 @@ dump_children (QObject *obj, int level = 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ApplicationBase::process_events (QEventLoop::ProcessEventsFlags flags, bool silent)
|
ApplicationBase::process_events (QEventLoop::ProcessEventsFlags /*flags*/, bool /*silent*/)
|
||||||
{
|
{
|
||||||
if (mp_mw) {
|
// The base class implementation does nothing ..
|
||||||
|
|
||||||
if (silent) {
|
|
||||||
mp_dm_scheduler->enable (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if QT_VERSION < 0x050000
|
|
||||||
QApplication::syncX ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mp_mw->enter_busy_mode (true);
|
|
||||||
try {
|
|
||||||
QApplication::processEvents (flags);
|
|
||||||
} catch (...) {
|
|
||||||
// ignore exceptions
|
|
||||||
}
|
|
||||||
mp_mw->enter_busy_mode (false);
|
|
||||||
|
|
||||||
if (silent) {
|
|
||||||
mp_dm_scheduler->enable (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ApplicationBase::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;
|
return plugin_root () ? plugin_root ()->write_config (config_file) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1346,38 +1278,38 @@ ApplicationBase::reset_config ()
|
||||||
void
|
void
|
||||||
ApplicationBase::clear_config ()
|
ApplicationBase::clear_config ()
|
||||||
{
|
{
|
||||||
if (mp_plugin_root) {
|
if (plugin_root ()) {
|
||||||
mp_plugin_root->clear_config ();
|
plugin_root ()->clear_config ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ApplicationBase::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;
|
return plugin_root () ? plugin_root ()->read_config (config_file) : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ApplicationBase::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) {
|
if (plugin_root ()) {
|
||||||
mp_plugin_root->config_set (name, value);
|
plugin_root ()->config_set (name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ApplicationBase::config_end ()
|
ApplicationBase::config_end ()
|
||||||
{
|
{
|
||||||
if (mp_plugin_root) {
|
if (plugin_root ()) {
|
||||||
mp_plugin_root->config_end ();
|
plugin_root ()->config_end ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
ApplicationBase::get_config (const std::string &name) const
|
ApplicationBase::get_config (const std::string &name) const
|
||||||
{
|
{
|
||||||
if (mp_plugin_root) {
|
if (plugin_root ()) {
|
||||||
return mp_plugin_root->config_get (name);
|
return plugin_root ()->config_get (name);
|
||||||
} else {
|
} else {
|
||||||
return std::string ();
|
return std::string ();
|
||||||
}
|
}
|
||||||
|
|
@ -1387,8 +1319,8 @@ std::vector<std::string>
|
||||||
ApplicationBase::get_config_names () const
|
ApplicationBase::get_config_names () const
|
||||||
{
|
{
|
||||||
std::vector<std::string> names;
|
std::vector<std::string> names;
|
||||||
if (mp_plugin_root) {
|
if (plugin_root ()) {
|
||||||
mp_plugin_root->get_config_names (names);
|
plugin_root ()->get_config_names (names);
|
||||||
}
|
}
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
@ -1405,7 +1337,9 @@ ApplicationBase::special_app_flag (const std::string &name)
|
||||||
// GuiApplication implementation
|
// GuiApplication implementation
|
||||||
|
|
||||||
GuiApplication::GuiApplication (int &argc, char **argv)
|
GuiApplication::GuiApplication (int &argc, char **argv)
|
||||||
: QApplication (argc, argv), ApplicationBase ()
|
: QApplication (argc, argv), ApplicationBase (),
|
||||||
|
mp_mw (0),
|
||||||
|
mp_recorder (0)
|
||||||
{
|
{
|
||||||
// install a special style proxy to overcome the issue of black-on-black tree expanders
|
// install a special style proxy to overcome the issue of black-on-black tree expanders
|
||||||
setStyle (new lay::BackgroundAwareTreeStyle (0));
|
setStyle (new lay::BackgroundAwareTreeStyle (0));
|
||||||
|
|
@ -1415,9 +1349,24 @@ GuiApplication::GuiApplication (int &argc, char **argv)
|
||||||
setAttribute (Qt::AA_DontShowIconsInMenus, false);
|
setAttribute (Qt::AA_DontShowIconsInMenus, false);
|
||||||
#endif
|
#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 ());
|
||||||
|
|
||||||
init_app (argc, argv, false);
|
init_app (argc, argv, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GuiApplication::~GuiApplication ()
|
||||||
|
{
|
||||||
|
// uninitialize the plugins
|
||||||
|
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
|
||||||
|
lay::PluginDeclaration *pd = const_cast<lay::PluginDeclaration *> (&*cls);
|
||||||
|
pd->uninitialize (plugin_root ());
|
||||||
|
}
|
||||||
|
|
||||||
|
shutdown ();
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GuiApplication::notify (QObject *receiver, QEvent *e)
|
GuiApplication::notify (QObject *receiver, QEvent *e)
|
||||||
{
|
{
|
||||||
|
|
@ -1469,15 +1418,125 @@ GuiApplication::exec ()
|
||||||
return QApplication::exec ();
|
return QApplication::exec ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GuiApplication::shutdown ()
|
||||||
|
{
|
||||||
|
if (mp_mw) {
|
||||||
|
delete mp_mw;
|
||||||
|
mp_mw = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete all other top level widgets for safety - we don't want Ruby clean them up for us
|
||||||
|
QWidgetList tl_widgets = topLevelWidgets ();
|
||||||
|
for (QWidgetList::iterator w = tl_widgets.begin (); w != tl_widgets.end (); ++w) {
|
||||||
|
delete *w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mp_recorder) {
|
||||||
|
delete mp_recorder;
|
||||||
|
mp_recorder = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplicationBase::shutdown ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GuiApplication::finish ()
|
||||||
|
{
|
||||||
|
// save the recorded test events
|
||||||
|
if (mp_recorder && mp_recorder->recording ()) {
|
||||||
|
mp_recorder->stop ();
|
||||||
|
mp_recorder->save ();
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplicationBase::finish ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GuiApplication::prepare_recording (const std::string >f_record, bool gtf_save_incremental)
|
||||||
|
{
|
||||||
|
tl_assert (mp_recorder == 0);
|
||||||
|
|
||||||
|
// 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 (this, gtf_record);
|
||||||
|
mp_recorder->save_incremental (gtf_save_incremental);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GuiApplication::start_recording ()
|
||||||
|
{
|
||||||
|
if (mp_recorder) {
|
||||||
|
mp_recorder->start ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lay::PluginRoot *
|
||||||
|
GuiApplication::plugin_root () const
|
||||||
|
{
|
||||||
|
return mp_mw;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GuiApplication::setup ()
|
||||||
|
{
|
||||||
|
tl_assert (mp_mw == 0);
|
||||||
|
|
||||||
|
mp_mw = new lay::MainWindow (this, "main_window");
|
||||||
|
QObject::connect (mp_mw, SIGNAL (closed ()), this, SLOT (quit ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GuiApplication::process_events (QEventLoop::ProcessEventsFlags flags, bool silent)
|
||||||
|
{
|
||||||
|
if (mp_mw) {
|
||||||
|
|
||||||
|
if (silent) {
|
||||||
|
mp_dm_scheduler->enable (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if QT_VERSION < 0x050000
|
||||||
|
QApplication::syncX ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mp_mw->enter_busy_mode (true);
|
||||||
|
try {
|
||||||
|
QApplication::processEvents (flags);
|
||||||
|
} catch (...) {
|
||||||
|
// ignore exceptions
|
||||||
|
}
|
||||||
|
mp_mw->enter_busy_mode (false);
|
||||||
|
|
||||||
|
if (silent) {
|
||||||
|
mp_dm_scheduler->enable (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------
|
||||||
// NonGuiApplication implementation
|
// NonGuiApplication implementation
|
||||||
|
|
||||||
NonGuiApplication::NonGuiApplication (int &argc, char **argv)
|
NonGuiApplication::NonGuiApplication (int &argc, char **argv)
|
||||||
: QCoreApplication (argc, argv), ApplicationBase ()
|
: QCoreApplication (argc, argv), ApplicationBase (),
|
||||||
|
mp_pr (0),
|
||||||
|
mp_pb (0),
|
||||||
|
mp_plugin_root (0)
|
||||||
{
|
{
|
||||||
init_app (argc, argv, true);
|
init_app (argc, argv, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NonGuiApplication::~NonGuiApplication ()
|
||||||
|
{
|
||||||
|
// uninitialize the plugins
|
||||||
|
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
|
||||||
|
lay::PluginDeclaration *pd = const_cast<lay::PluginDeclaration *> (&*cls);
|
||||||
|
pd->uninitialize (plugin_root ());
|
||||||
|
}
|
||||||
|
|
||||||
|
shutdown ();
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
NonGuiApplication::exec ()
|
NonGuiApplication::exec ()
|
||||||
{
|
{
|
||||||
|
|
@ -1485,5 +1544,35 @@ NonGuiApplication::exec ()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NonGuiApplication::shutdown ()
|
||||||
|
{
|
||||||
|
if (mp_plugin_root) {
|
||||||
|
delete mp_plugin_root;
|
||||||
|
mp_plugin_root = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mp_pr) {
|
||||||
|
delete mp_pr;
|
||||||
|
mp_pr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mp_pb) {
|
||||||
|
delete mp_pb;
|
||||||
|
mp_pb = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplicationBase::shutdown ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NonGuiApplication::setup ()
|
||||||
|
{
|
||||||
|
mp_pr = new lay::ProgressReporter ();
|
||||||
|
mp_pb = new TextProgress (10 /*verbosity level*/);
|
||||||
|
mp_pr->set_progress_bar (mp_pb);
|
||||||
|
mp_plugin_root = new lay::PluginRoot ();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -128,14 +128,12 @@ public:
|
||||||
std::string usage ();
|
std::string usage ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the main window's reference
|
* @brief Returns the main window's reference
|
||||||
*
|
*
|
||||||
* If the application has not been initialized properly, this pointer is 0.
|
* If the application has not been initialized properly or does not support GUI,
|
||||||
|
* this pointer is 0.
|
||||||
*/
|
*/
|
||||||
MainWindow *main_window () const
|
virtual MainWindow *main_window () const = 0;
|
||||||
{
|
|
||||||
return mp_mw;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Runs plugin and macro specific initializations
|
* @brief Runs plugin and macro specific initializations
|
||||||
|
|
@ -164,7 +162,7 @@ public:
|
||||||
* handling for the "close application window" case and a "silent" mode. In that mode, processing
|
* handling for the "close application window" case and a "silent" mode. In that mode, processing
|
||||||
* of deferred methods is disabled.
|
* of deferred methods is disabled.
|
||||||
*/
|
*/
|
||||||
void process_events (QEventLoop::ProcessEventsFlags flags, bool silent = false);
|
virtual void process_events (QEventLoop::ProcessEventsFlags flags, bool silent = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A shortcut for the default process_events
|
* @brief A shortcut for the default process_events
|
||||||
|
|
@ -325,11 +323,6 @@ public:
|
||||||
return m_native_plugins;
|
return m_native_plugins;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Gets the QCoreApplication object
|
|
||||||
*/
|
|
||||||
virtual QCoreApplication *qapp () { return 0; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the QApplication object
|
* @brief Gets the QApplication object
|
||||||
* This method will return non-null only if a GUI-enabled application is present.
|
* This method will return non-null only if a GUI-enabled application is present.
|
||||||
|
|
@ -338,10 +331,14 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void init_app (int &argc, char **argv, bool non_ui_mode);
|
void init_app (int &argc, char **argv, bool non_ui_mode);
|
||||||
|
virtual void setup () = 0;
|
||||||
|
virtual void shutdown ();
|
||||||
|
virtual void prepare_recording (const std::string >f_record, bool gtf_record_incremental);
|
||||||
|
virtual void start_recording ();
|
||||||
|
virtual lay::PluginRoot *plugin_root () const = 0;
|
||||||
|
virtual void finish ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void shutdown ();
|
|
||||||
void finish ();
|
|
||||||
std::vector<std::string> scan_global_modules ();
|
std::vector<std::string> scan_global_modules ();
|
||||||
|
|
||||||
enum file_type {
|
enum file_type {
|
||||||
|
|
@ -366,10 +363,11 @@ private:
|
||||||
std::vector<std::string> m_klayout_path;
|
std::vector<std::string> m_klayout_path;
|
||||||
std::string m_inst_path;
|
std::string m_inst_path;
|
||||||
std::string m_appdata_path;
|
std::string m_appdata_path;
|
||||||
std::vector< std::pair<std::string, std::string> > m_macro_categories;
|
|
||||||
bool m_write_config_file;
|
bool m_write_config_file;
|
||||||
std::vector< std::pair<std::string, std::string> > m_variables;
|
std::vector< std::pair<std::string, std::string> > m_variables;
|
||||||
int m_gtf_replay_rate, m_gtf_replay_stop;
|
int m_gtf_replay_rate, m_gtf_replay_stop;
|
||||||
|
std::string m_gtf_record;
|
||||||
|
bool m_gtf_save_incremental;
|
||||||
bool m_no_macros;
|
bool m_no_macros;
|
||||||
bool m_same_view;
|
bool m_same_view;
|
||||||
bool m_sync_mode;
|
bool m_sync_mode;
|
||||||
|
|
@ -377,16 +375,10 @@ private:
|
||||||
bool m_vo_mode;
|
bool m_vo_mode;
|
||||||
bool m_editable;
|
bool m_editable;
|
||||||
bool m_enable_undo;
|
bool m_enable_undo;
|
||||||
std::auto_ptr<tl::DeferredMethodScheduler> mp_dm_scheduler;
|
|
||||||
// HINT: the ruby interpreter must be destroyed before MainWindow
|
// 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.
|
// in order to maintain a valid MainWindow reference for ruby scripts and Ruby's GC all the time.
|
||||||
gsi::Interpreter *mp_ruby_interpreter;
|
gsi::Interpreter *mp_ruby_interpreter;
|
||||||
gsi::Interpreter *mp_python_interpreter;
|
gsi::Interpreter *mp_python_interpreter;
|
||||||
MainWindow *mp_mw;
|
|
||||||
lay::ProgressReporter *mp_pr;
|
|
||||||
lay::ProgressBar *mp_pb;
|
|
||||||
lay::PluginRoot *mp_plugin_root;
|
|
||||||
gtf::Recorder *mp_recorder;
|
|
||||||
std::vector<PluginDescriptor> m_native_plugins;
|
std::vector<PluginDescriptor> m_native_plugins;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -398,9 +390,9 @@ class LAY_PUBLIC GuiApplication
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GuiApplication (int &argc, char **argv);
|
GuiApplication (int &argc, char **argv);
|
||||||
|
~GuiApplication ();
|
||||||
|
|
||||||
QApplication *qapp_gui () { return this; }
|
QApplication *qapp_gui () { return this; }
|
||||||
QCoreApplication *qapp () { return this; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reimplementation of notify from QApplication
|
* @brief Reimplementation of notify from QApplication
|
||||||
|
|
@ -427,6 +419,33 @@ public:
|
||||||
{
|
{
|
||||||
ApplicationBase::exit (result);
|
ApplicationBase::exit (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the main window's reference
|
||||||
|
*/
|
||||||
|
virtual MainWindow *main_window () const
|
||||||
|
{
|
||||||
|
return mp_mw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reimplementation of ApplicationBase interface
|
||||||
|
*/
|
||||||
|
virtual void process_events (QEventLoop::ProcessEventsFlags flags, bool silent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void setup ();
|
||||||
|
virtual void shutdown ();
|
||||||
|
virtual void finish ();
|
||||||
|
virtual void prepare_recording (const std::string >f_record, bool gtf_save_incremental);
|
||||||
|
virtual void start_recording ();
|
||||||
|
|
||||||
|
virtual lay::PluginRoot *plugin_root () const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
MainWindow *mp_mw;
|
||||||
|
gtf::Recorder *mp_recorder;
|
||||||
|
std::auto_ptr<tl::DeferredMethodScheduler> mp_dm_scheduler;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -437,9 +456,7 @@ class LAY_PUBLIC NonGuiApplication
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NonGuiApplication (int &argc, char **argv);
|
NonGuiApplication (int &argc, char **argv);
|
||||||
|
~NonGuiApplication ();
|
||||||
QApplication *qapp_gui () { return 0; }
|
|
||||||
QCoreApplication *qapp () { return this; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the application instance, cast to this class
|
* @brief Gets the application instance, cast to this class
|
||||||
|
|
@ -461,6 +478,29 @@ public:
|
||||||
{
|
{
|
||||||
ApplicationBase::exit (result);
|
ApplicationBase::exit (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the main window's reference
|
||||||
|
* This incarnation returns 0 since no GUI is supported.
|
||||||
|
*/
|
||||||
|
virtual MainWindow *main_window () const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void setup ();
|
||||||
|
virtual void shutdown ();
|
||||||
|
|
||||||
|
virtual lay::PluginRoot *plugin_root () const
|
||||||
|
{
|
||||||
|
return mp_plugin_root;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
lay::ProgressReporter *mp_pr;
|
||||||
|
lay::ProgressBar *mp_pb;
|
||||||
|
lay::PluginRoot *mp_plugin_root;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace lay
|
} // namespace lay
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue