diff --git a/src/ant/ant/antPlugin.cc b/src/ant/ant/antPlugin.cc index 443cebec1..1bd0d327e 100644 --- a/src/ant/ant/antPlugin.cc +++ b/src/ant/ant/antPlugin.cc @@ -169,7 +169,7 @@ PluginDeclaration::config_finalize () } void -PluginDeclaration::initialized (lay::PluginRoot *) +PluginDeclaration::initialized (lay::PluginRoot *root) { // Check if we already have templates (initial setup) bool any_templates = false; @@ -198,8 +198,8 @@ PluginDeclaration::initialized (lay::PluginRoot *) m_templates.push_back (ant::Template (tl::to_string (QObject::tr ("Box")), "W=$(abs(X))", "H=$(abs(Y))", "", ant::Object::STY_line, ant::Object::OL_box, true, lay::AC_Global, std::string ())); - lay::PluginRoot::instance ()->config_set (cfg_ruler_templates, ant::TemplatesConverter ().to_string (m_templates)); - lay::PluginRoot::instance ()->config_end (); + root->config_set (cfg_ruler_templates, ant::TemplatesConverter ().to_string (m_templates)); + root->config_end (); } } diff --git a/src/lay/lay/layApplication.cc b/src/lay/lay/layApplication.cc index 2c5a6bc02..76da61364 100644 --- a/src/lay/lay/layApplication.cc +++ b/src/lay/lay/layApplication.cc @@ -1114,7 +1114,7 @@ ApplicationBase::run () // Give the plugins a change to do some last-minute initialisation and checks for (tl::Registrar::iterator cls = tl::Registrar::begin (); cls != tl::Registrar::end (); ++cls) { lay::PluginDeclaration *pd = const_cast (&*cls); - pd->initialized (mw); + pd->initialized (plugin_root ()); } if (! m_no_gui && m_gtf_replay.empty () && m_gtf_record.empty ()) { @@ -1280,6 +1280,7 @@ ApplicationBase::special_app_flag (const std::string &name) GuiApplication::GuiApplication (int &argc, char **argv) : QApplication (argc, argv), ApplicationBase (false), mp_mw (0), + mp_plugin_root (0), mp_recorder (0) { // install a special style proxy to overcome the issue of black-on-black tree expanders @@ -1300,6 +1301,9 @@ GuiApplication::~GuiApplication () } shutdown (); + + delete mp_plugin_root; + mp_plugin_root = 0; } bool @@ -1455,15 +1459,18 @@ GuiApplication::start_recording () lay::PluginRoot * GuiApplication::plugin_root () const { - return mp_mw; + return mp_plugin_root; } void GuiApplication::setup () { - tl_assert (mp_mw == 0); + tl_assert (mp_mw == 0 && mp_plugin_root == 0); + + mp_plugin_root = new lay::PluginRootToMainWindow (); + mp_mw = new lay::MainWindow (this, mp_plugin_root, "main_window"); + mp_plugin_root->attach_to (mp_mw); - mp_mw = new lay::MainWindow (this, "main_window"); QObject::connect (mp_mw, SIGNAL (closed ()), this, SLOT (quit ())); // create a password dialog for use with the HTTP streams diff --git a/src/lay/lay/layApplication.h b/src/lay/lay/layApplication.h index 1aa7633ba..c49e3b7b5 100644 --- a/src/lay/lay/layApplication.h +++ b/src/lay/lay/layApplication.h @@ -57,6 +57,7 @@ namespace lay { class MainWindow; +class PluginRootToMainWindow; class PluginRoot; class ProgressReporter; class ProgressBar; @@ -443,6 +444,7 @@ protected: private: MainWindow *mp_mw; + PluginRootToMainWindow *mp_plugin_root; gtf::Recorder *mp_recorder; }; diff --git a/src/lay/lay/layMacroController.cc b/src/lay/lay/layMacroController.cc index 7bc3d8ca6..4ea5776cc 100644 --- a/src/lay/lay/layMacroController.cc +++ b/src/lay/lay/layMacroController.cc @@ -164,9 +164,9 @@ MacroController::initialized (lay::PluginRoot *root) connect (&m_temp_macros, SIGNAL (menu_needs_update ()), this, SLOT (macro_collection_changed ())); connect (&m_temp_macros, SIGNAL (macro_collection_changed (lym::MacroCollection *)), this, SLOT (macro_collection_changed ())); - mp_mw = dynamic_cast (root); + mp_mw = lay::MainWindow::instance (); if (mp_mw) { - mp_macro_editor = new lay::MacroEditorDialog (mp_mw, &lym::MacroCollection::root ()); + mp_macro_editor = new lay::MacroEditorDialog (root, &lym::MacroCollection::root ()); mp_macro_editor->setModal (false); } diff --git a/src/lay/lay/layMacroEditorDialog.cc b/src/lay/lay/layMacroEditorDialog.cc index eed7c5496..926400848 100644 --- a/src/lay/lay/layMacroEditorDialog.cc +++ b/src/lay/lay/layMacroEditorDialog.cc @@ -227,10 +227,10 @@ public: static lay::MacroEditorDialog *s_macro_editor_instance = 0; -MacroEditorDialog::MacroEditorDialog (lay::MainWindow *mw, lym::MacroCollection *root) +MacroEditorDialog::MacroEditorDialog (lay::PluginRoot *pr, lym::MacroCollection *root) : QDialog (0 /*show as individual top widget*/, Qt::Window), - lay::Plugin (mw, true), - mp_plugin_root (mw), + lay::Plugin (pr, true), + mp_plugin_root (pr), mp_root (root), m_first_show (true), m_in_processing (false), m_debugging_on (true), mp_run_macro (0), diff --git a/src/lay/lay/layMacroEditorDialog.h b/src/lay/lay/layMacroEditorDialog.h index bb492c71e..e1fea9391 100644 --- a/src/lay/lay/layMacroEditorDialog.h +++ b/src/lay/lay/layMacroEditorDialog.h @@ -98,7 +98,7 @@ public: /** * @brief Constructor */ - MacroEditorDialog (lay::MainWindow *parent, lym::MacroCollection *root); + MacroEditorDialog (lay::PluginRoot *pr, lym::MacroCollection *root); /** * @brief Destructor diff --git a/src/lay/lay/layMainWindow.cc b/src/lay/lay/layMainWindow.cc index 94d3941c3..37e55e9d5 100644 --- a/src/lay/lay/layMainWindow.cc +++ b/src/lay/lay/layMainWindow.cc @@ -443,8 +443,9 @@ MainWindow::instance () // ----------------------------------- -MainWindow::MainWindow (QApplication *app, const char *name) +MainWindow::MainWindow (QApplication *app, lay::Plugin *plugin_parent, const char *name) : QMainWindow (0), + lay::Plugin (plugin_parent), m_text_progress (this, 10 /*verbosity threshold*/), m_mode (std::numeric_limits::max ()), mp_setup_form (0), @@ -473,7 +474,7 @@ MainWindow::MainWindow (QApplication *app, const char *name) } mw_instance = this; - mp_setup_form = new SettingsForm (0, this, "setup_form"), + mp_setup_form = new SettingsForm (0, plugin_root (), "setup_form"), db::LibraryManager::instance ().changed_event.add (this, &MainWindow::libraries_changed); @@ -1082,13 +1083,13 @@ void MainWindow::dock_widget_visibility_changed (bool /*visible*/) { if (sender () == mp_lp_dock_widget) { - config_set (cfg_show_layer_panel, tl::to_string (!mp_lp_dock_widget->isHidden ())); + plugin_root ()->config_set (cfg_show_layer_panel, tl::to_string (!mp_lp_dock_widget->isHidden ())); } else if (sender () == mp_hp_dock_widget) { - config_set (cfg_show_hierarchy_panel, tl::to_string (!mp_hp_dock_widget->isHidden ())); + plugin_root ()->config_set (cfg_show_hierarchy_panel, tl::to_string (!mp_hp_dock_widget->isHidden ())); } else if (sender () == mp_navigator_dock_widget) { - config_set (cfg_show_navigator, tl::to_string (!mp_navigator_dock_widget->isHidden ())); + plugin_root ()->config_set (cfg_show_navigator, tl::to_string (!mp_navigator_dock_widget->isHidden ())); } else if (sender () == mp_layer_toolbox_dock_widget) { - config_set (cfg_show_layer_toolbox, tl::to_string (!mp_layer_toolbox_dock_widget->isHidden ())); + plugin_root ()->config_set (cfg_show_layer_toolbox, tl::to_string (!mp_layer_toolbox_dock_widget->isHidden ())); } } @@ -1283,7 +1284,7 @@ MainWindow::about_to_exec () lay::TipDialog::button_type button = lay::TipDialog::null_button; if (td.exec_dialog (button)) { if (button == lay::TipDialog::yes_button) { - config_set (cfg_full_hier_new_cell, true); + plugin_root ()->config_set (cfg_full_hier_new_cell, true); } // Don't bother the user with more dialogs. return; @@ -1734,17 +1735,6 @@ MainWindow::configure (const std::string &name, const std::string &value) apply_hidden (hidden); return true; - } else if (name == cfg_background_color) { - - if (mp_navigator) { - QColor color; - ColorConverter ().from_string (value, color); - mp_navigator->background_color (color); - } - - // do not take - let others receive the background color events as well - return false; - } else if (name == cfg_initial_technology) { m_initial_technology = value; @@ -1818,10 +1808,10 @@ MainWindow::libraries_changed () void MainWindow::read_dock_widget_state () { - config_set (cfg_show_layer_panel, tl::to_string (!mp_lp_dock_widget->isHidden ())); - config_set (cfg_show_hierarchy_panel, tl::to_string (!mp_hp_dock_widget->isHidden ())); - config_set (cfg_show_navigator, tl::to_string (!mp_navigator_dock_widget->isHidden ())); - config_set (cfg_show_layer_toolbox, tl::to_string (!mp_layer_toolbox_dock_widget->isHidden ())); + plugin_root ()->config_set (cfg_show_layer_panel, tl::to_string (!mp_lp_dock_widget->isHidden ())); + plugin_root ()->config_set (cfg_show_hierarchy_panel, tl::to_string (!mp_hp_dock_widget->isHidden ())); + plugin_root ()->config_set (cfg_show_navigator, tl::to_string (!mp_navigator_dock_widget->isHidden ())); + plugin_root ()->config_set (cfg_show_layer_toolbox, tl::to_string (!mp_layer_toolbox_dock_widget->isHidden ())); } void @@ -1934,7 +1924,7 @@ MainWindow::can_close () for (tl::Registrar::iterator cls = tl::Registrar::begin (); cls != tl::Registrar::end (); ++cls) { lay::PluginDeclaration *pd = const_cast (&*cls); - if (! pd->can_exit (this)) { + if (! pd->can_exit (plugin_root ())) { return false; } } @@ -1979,8 +1969,8 @@ MainWindow::save_state_to_config () { // save the dock widget state with all views closed (that state can be // used for staring klayout without any layout) - config_set (cfg_window_geometry, (const char *) saveGeometry ().toBase64 ().data ()); - config_set (cfg_window_state, (const char *) saveState ().toBase64 ().data ()); + plugin_root ()->config_set (cfg_window_geometry, (const char *) saveGeometry ().toBase64 ().data ()); + plugin_root ()->config_set (cfg_window_state, (const char *) saveState ().toBase64 ().data ()); } void @@ -2304,9 +2294,7 @@ MainWindow::intrinsic_mode_triggered () int mode = action->data ().toInt (); - if (lay::PluginRoot::instance ()) { - lay::PluginRoot::instance ()->select_mode (mode); - } + plugin_root ()->select_mode (mode); action->setChecked (true); @@ -3405,13 +3393,13 @@ MainWindow::cm_pull_in () void MainWindow::cm_reader_options () { - mp_layout_load_options->edit_global_options (this, db::Technologies::instance ()); + mp_layout_load_options->edit_global_options (plugin_root (), db::Technologies::instance ()); } void MainWindow::cm_writer_options () { - mp_layout_save_options->edit_global_options (this, db::Technologies::instance ()); + mp_layout_save_options->edit_global_options (plugin_root (), db::Technologies::instance ()); } void @@ -3680,7 +3668,7 @@ MainWindow::clone_current_view () } // create a new view - view = new lay::LayoutView (current_view (), &m_manager, lay::ApplicationBase::instance ()->is_editable (), this, mp_view_stack); + view = new lay::LayoutView (current_view (), &m_manager, lay::ApplicationBase::instance ()->is_editable (), plugin_root (), 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 ())); @@ -4116,7 +4104,7 @@ MainWindow::add_mru (const std::string &fn_rel, const std::string &tech) } } - config_set (cfg_mru, config_str); + plugin_root ()->config_set (cfg_mru, config_str); } void @@ -4169,7 +4157,7 @@ MainWindow::open_recent () return; } - if (mp_layout_load_options->show_always () && !mp_layout_load_options->edit_global_options (this, db::Technologies::instance ())) { + if (mp_layout_load_options->show_always () && !mp_layout_load_options->edit_global_options (plugin_root (), db::Technologies::instance ())) { return; } @@ -4218,7 +4206,7 @@ MainWindow::open (int mode) return; } - if (mp_layout_load_options->show_always () && !mp_layout_load_options->edit_global_options (this, db::Technologies::instance ())) { + if (mp_layout_load_options->show_always () && !mp_layout_load_options->edit_global_options (plugin_root (), db::Technologies::instance ())) { return; } @@ -4289,7 +4277,7 @@ int MainWindow::do_create_view () { // create a new view - lay::LayoutView *view = new lay::LayoutView (&m_manager, lay::ApplicationBase::instance ()->is_editable (), this, mp_view_stack); + lay::LayoutView *view = new lay::LayoutView (&m_manager, lay::ApplicationBase::instance ()->is_editable (), plugin_root (), mp_view_stack); connect (view, SIGNAL (title_changed ()), this, SLOT (view_title_changed ())); connect (view, SIGNAL (dirty_changed ()), this, SLOT (view_title_changed ())); @@ -4866,8 +4854,7 @@ MainWindow::show_assistant_topic (const std::string &s, bool modal) void MainWindow::cm_show_all_tips () { - config_set (cfg_tip_window_hidden, ""); - config_finalize (); + plugin_root ()->config_set (cfg_tip_window_hidden, ""); } void @@ -4899,7 +4886,7 @@ MainWindow::action_for_slot (const char *slot) lay::Action * MainWindow::create_config_action (const std::string &title, const std::string &cname, const std::string &cvalue) { - lay::ConfigureAction *ca = new lay::ConfigureAction(this, title, cname, cvalue); + lay::ConfigureAction *ca = new lay::ConfigureAction(plugin_root (), title, cname, cvalue); m_ca_collection.push_back (ca); return ca; } @@ -4907,7 +4894,7 @@ MainWindow::create_config_action (const std::string &title, const std::string &c lay::Action * MainWindow::create_config_action (const std::string &cname, const std::string &cvalue) { - lay::ConfigureAction *ca = new lay::ConfigureAction(this, std::string (), cname, cvalue); + lay::ConfigureAction *ca = new lay::ConfigureAction(plugin_root (), std::string (), cname, cvalue); m_ca_collection.push_back (ca); return ca; } @@ -5605,11 +5592,8 @@ MainWindow::plugin_registered (lay::PluginDeclaration *cls) // recreate all plugins for (std::vector ::iterator vp = mp_views.begin (); vp != mp_views.end (); ++vp) { - (*vp)->create_plugins (this); + (*vp)->create_plugins (plugin_root ()); } - - // re-establish the configuration - config_setup (); } void @@ -5619,13 +5603,55 @@ MainWindow::plugin_removed (lay::PluginDeclaration *cls) // recreate all plugins except the one that got removed for (std::vector ::iterator vp = mp_views.begin (); vp != mp_views.end (); ++vp) { - (*vp)->create_plugins (this, cls); + (*vp)->create_plugins (plugin_root (), cls); + } +} + +// ------------------------------------------------------------ +// Implementation of the PluginRootToMainWindow bride + +PluginRootToMainWindow::PluginRootToMainWindow () + : mp_main_window (0) +{ + // .. nothing yet .. +} + +void +PluginRootToMainWindow::attach_to (lay::MainWindow *main_window) +{ + mp_main_window = main_window; +} + +void +PluginRootToMainWindow::plugin_registered (lay::PluginDeclaration *cls) +{ + if (mp_main_window.get ()) { + mp_main_window->plugin_registered (cls); } // re-establish the configuration config_setup (); } +void +PluginRootToMainWindow::plugin_removed (lay::PluginDeclaration *cls) +{ + if (mp_main_window.get ()) { + mp_main_window->plugin_removed (cls); + } + + // re-establish the configuration + config_setup (); +} + +void +PluginRootToMainWindow::select_mode (int mode) +{ + if (mp_main_window.get ()) { + mp_main_window->select_mode (mode); + } +} + // ------------------------------------------------------------ // Implementation of the "help about" dialog diff --git a/src/lay/lay/layMainWindow.h b/src/lay/lay/layMainWindow.h index 834d5d00c..55a50d340 100644 --- a/src/lay/lay/layMainWindow.h +++ b/src/lay/lay/layMainWindow.h @@ -120,8 +120,8 @@ private: class LAY_PUBLIC MainWindow : public QMainWindow, - public lay::AbstractMenuProvider, - public lay::PluginRoot + public lay::Plugin, + public lay::AbstractMenuProvider { Q_OBJECT public: @@ -134,7 +134,7 @@ public: /** * @brief Constructor */ - MainWindow (QApplication *app = 0, const char *name = "main_window"); + MainWindow (QApplication *app = 0, lay::Plugin *parent_plugin = 0, const char *name = "main_window"); /** * @brief Destructor @@ -551,7 +551,7 @@ public: void show_macro_editor (const std::string &cat = std::string (), bool add = false); /** - * @brief Reimplementation of the plugin interface: handle a generic menu request + * @brief Handles a generic menu request */ void menu_activated (const std::string &symbol); @@ -870,6 +870,8 @@ protected: void do_update_file_menu (); private: + friend class PluginRootToMainWindow; + TextProgressDelegate m_text_progress; // Main menu @@ -973,14 +975,33 @@ private: void update_dock_widget_state (); void read_dock_widget_state (); - virtual void plugin_registered (lay::PluginDeclaration *cls); - virtual void plugin_removed (lay::PluginDeclaration *cls); + void plugin_registered (lay::PluginDeclaration *cls); + void plugin_removed (lay::PluginDeclaration *cls); void libraries_changed (); void apply_key_bindings (); void apply_hidden (const std::vector > &hidden); }; +class LAY_PUBLIC PluginRootToMainWindow + : public lay::PluginRoot +{ +public: + PluginRootToMainWindow (); + + void attach_to (lay::MainWindow *main_window); + + virtual void plugin_registered (lay::PluginDeclaration *cls); + virtual void plugin_removed (lay::PluginDeclaration *cls); + virtual void select_mode (int mode); + +private: + PluginRootToMainWindow (const PluginRootToMainWindow &); + PluginRootToMainWindow &operator= (const PluginRootToMainWindow &); + + tl::weak_ptr mp_main_window; +}; + } namespace tl { diff --git a/src/lay/lay/layNavigator.cc b/src/lay/lay/layNavigator.cc index 1dd2fd521..1b4ec8119 100644 --- a/src/lay/lay/layNavigator.cc +++ b/src/lay/lay/layNavigator.cc @@ -58,7 +58,7 @@ public: mp_box (0), m_color (0) { - // .. nothing yet .. + // .. nothing yet .. } ~NavigatorService () @@ -70,6 +70,25 @@ public: drag_cancel (); } + void background_color_changed () + { + QColor c = mp_view->background_color (); + + // replace by "real" background color if required + if (! c.isValid ()) { + c = mp_view->palette ().color (QPalette::Normal, QPalette::Base); + } + + QColor contrast; + if (c.green () > 128) { + contrast = QColor (0, 0, 0); + } else { + contrast = QColor (255, 255, 255); + } + + set_colors (c, contrast); + } + bool mouse_release_event (const db::DPoint & /*p*/, unsigned int /*buttons*/, bool /*prio*/) { if (mp_box) { @@ -349,10 +368,10 @@ public: tl::Object::detach_from_all_events (); mp_source_view = source_view; + mp_source_view->viewport_changed_event.add (this, &NavigatorService::update_marker); - if (mp_source_view) { - mp_source_view->viewport_changed_event.add (this, &NavigatorService::update_marker); - } + mp_view->background_color_changed_event.add (this, &NavigatorService::background_color_changed); + background_color_changed (); update_marker (); @@ -447,11 +466,8 @@ Navigator::Navigator (MainWindow *main_window) mp_menu_bar->setFrameShape (QFrame::NoFrame); mp_menu_bar->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Preferred); - mp_view = new LayoutView (0, false, mp_main_window, this, "navigator", LayoutView::LV_Naked + LayoutView::LV_NoZoom + LayoutView::LV_NoServices + LayoutView::LV_NoGrid); - mp_view->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding); - mp_view->setMinimumWidth (100); - mp_view->setMinimumHeight (100); - mp_view->hide (); + mp_view = 0; + mp_service = 0; mp_placeholder_label = new QLabel (this); mp_placeholder_label->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -461,9 +477,8 @@ Navigator::Navigator (MainWindow *main_window) QVBoxLayout *layout = new QVBoxLayout (this); layout->addWidget (mp_menu_bar); - layout->addWidget (mp_view); layout->addWidget (mp_placeholder_label); - layout->setStretchFactor (mp_view, 1); + layout->setStretchFactor (mp_placeholder_label, 1); layout->setMargin (0); layout->setSpacing (0); setLayout (layout); @@ -473,9 +488,6 @@ Navigator::Navigator (MainWindow *main_window) do_update_menu (); connect (mp_main_window->menu (), SIGNAL (changed ()), this, SLOT (menu_changed ())); - - mp_service = new NavigatorService (mp_view); - mp_view->view_object_widget ()->activate (mp_service); } Navigator::~Navigator () @@ -586,8 +598,8 @@ Navigator::showEvent (QShowEvent *) void Navigator::closeEvent (QCloseEvent *) { - mp_main_window->config_set (cfg_show_navigator, "false"); - mp_main_window->config_finalize (); + lay::PluginRoot::instance ()->config_set (cfg_show_navigator, "false"); + lay::PluginRoot::instance ()->config_end (); } void @@ -637,6 +649,14 @@ Navigator::view_closed (int index) } } +void +Navigator::resizeEvent (QResizeEvent *) +{ + if (mp_view) { + mp_view->setGeometry (mp_placeholder_label->geometry ()); + } +} + void Navigator::attach_view (LayoutView *view) { @@ -649,8 +669,24 @@ Navigator::attach_view (LayoutView *view) mp_source_view = view; + delete mp_service; + mp_service = 0; + + LayoutView *old_view = mp_view; + mp_view = 0; + if (mp_source_view) { + mp_view = new LayoutView (0, false, mp_source_view, this, "navigator", LayoutView::LV_Naked + LayoutView::LV_NoZoom + LayoutView::LV_NoServices + LayoutView::LV_NoGrid); + mp_view->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding); + mp_view->setMinimumWidth (100); + mp_view->setMinimumHeight (100); + mp_view->setGeometry (mp_placeholder_label->geometry ()); + mp_view->show (); + + mp_service = new NavigatorService (mp_view); + mp_view->view_object_widget ()->activate (mp_service); + mp_source_view->cellviews_changed_event.add (this, &Navigator::content_changed); mp_source_view->cellview_changed_event.add (this, &Navigator::content_changed_with_int); mp_source_view->geom_changed_event.add (this, &Navigator::content_changed); @@ -662,60 +698,36 @@ Navigator::attach_view (LayoutView *view) image_plugin->images_changed_event.add (this, &Navigator::content_changed); } - mp_view->show (); - mp_placeholder_label->hide (); + // update the list of frozen flags per view + std::set all_views; - } else { - mp_view->hide (); - mp_placeholder_label->show (); - } - - // update the list of frozen flags per view - std::set all_views; - - for (std::map ::const_iterator f = m_frozen_list.begin (); f != m_frozen_list.end (); ++f) { - all_views.insert (f->first); - } - - for (unsigned int i = 0; i < mp_main_window->views (); ++i) { - lay::LayoutView *view = mp_main_window->view (i); - if (m_frozen_list.find (view) != m_frozen_list.end ()) { - all_views.erase (view); + for (std::map ::const_iterator f = m_frozen_list.begin (); f != m_frozen_list.end (); ++f) { + all_views.insert (f->first); } + + for (unsigned int i = 0; i < mp_main_window->views (); ++i) { + lay::LayoutView *view = mp_main_window->view (i); + if (m_frozen_list.find (view) != m_frozen_list.end ()) { + all_views.erase (view); + } + } + + for (std::set ::const_iterator v = all_views.begin (); v != all_views.end (); ++v) { + all_views.erase (*v); + } + + Action freeze_action = mp_main_window->menu ()->action (freeze_action_path); + freeze_action.set_checked (m_frozen_list.find (mp_source_view) != m_frozen_list.end ()); + + // Hint: this must happen before update () + mp_service->attach_view (mp_source_view); + + update (); + } - for (std::set ::const_iterator v = all_views.begin (); v != all_views.end (); ++v) { - all_views.erase (*v); - } + delete old_view; - Action freeze_action = mp_main_window->menu ()->action (freeze_action_path); - freeze_action.set_checked (m_frozen_list.find (mp_source_view) != m_frozen_list.end ()); - - // Hint: this must happen before update () - mp_service->attach_view (mp_source_view); - - update (); - - } -} - -void -Navigator::background_color (QColor c) -{ - // replace by "real" background color if required - if (! c.isValid ()) { - c = palette ().color (QPalette::Normal, QPalette::Base); - } - - QColor contrast; - if (c.green () > 128) { - contrast = QColor (0, 0, 0); - } else { - contrast = QColor (255, 255, 255); - } - - if (mp_service) { - mp_service->set_colors (c, contrast); } } @@ -738,16 +750,13 @@ Navigator::update_layers () void Navigator::update () { - if (! mp_source_view || m_frozen_list.find (mp_source_view) == m_frozen_list.end ()) { - - if (! mp_source_view) { - mp_view->clear_cellviews (); - mp_view->clear_layers (); - } else { - mp_view->select_cellviews (mp_source_view->cellview_list ()); - mp_view->set_properties (mp_source_view->get_properties ()); - } + if (! mp_view || ! mp_source_view) { + return; + } + if (m_frozen_list.find (mp_source_view) == m_frozen_list.end ()) { + mp_view->select_cellviews (mp_source_view->cellview_list ()); + mp_view->set_properties (mp_source_view->get_properties ()); } else { mp_view->select_cellviews (mp_source_view->cellview_list ()); mp_view->set_properties (m_frozen_list [mp_source_view].layer_properties); @@ -759,7 +768,7 @@ Navigator::update () img_target->clear_images (); if (m_show_images) { - img::Service *img_source = (mp_source_view ? mp_source_view->get_plugin () : 0); + img::Service *img_source = (mp_source_view->get_plugin ()); if (img_source) { for (img::ImageIterator i = img_source->begin_images (); ! i.at_end (); ++i) { img_target->insert_image (*i); diff --git a/src/lay/lay/layNavigator.h b/src/lay/lay/layNavigator.h index c79e55923..5582eea8b 100644 --- a/src/lay/lay/layNavigator.h +++ b/src/lay/lay/layNavigator.h @@ -83,13 +83,13 @@ public: void freeze_clicked (); void all_hier_levels (bool f); void show_images (bool f); - void background_color (QColor c); static void init_menu (AbstractMenu &menu); protected: virtual void closeEvent (QCloseEvent *event); virtual void showEvent (QShowEvent *event); + virtual void resizeEvent (QResizeEvent *event); private slots: void menu_changed (); @@ -121,6 +121,7 @@ private: void layers_changed (int); void viewport_changed (); void hier_levels_changed (); + void update_background_color (); void content_changed_with_int (int) { diff --git a/src/lay/lay/laySaltController.cc b/src/lay/lay/laySaltController.cc index 7e3030bd6..4f6b78815 100644 --- a/src/lay/lay/laySaltController.cc +++ b/src/lay/lay/laySaltController.cc @@ -36,14 +36,21 @@ namespace lay static const std::string cfg_salt_manager_window_state ("salt-manager-window-state"); SaltController::SaltController () - : mp_salt_dialog (0), mp_mw (0), m_file_watcher (0), + : mp_salt_dialog (0), mp_mw (0), mp_plugin_root (0), m_file_watcher (0), dm_sync_file_watcher (this, &SaltController::sync_file_watcher), dm_sync_files (this, &SaltController::sync_files) { } void -SaltController::initialized (lay::PluginRoot *root) +SaltController::initialize (lay::PluginRoot *root) +{ + mp_mw = lay::MainWindow::instance (); + mp_plugin_root = root; +} + +void +SaltController::initialized (lay::PluginRoot * /*root*/) { if (! m_file_watcher) { m_file_watcher = new tl::FileSystemWatcher (this); @@ -51,8 +58,6 @@ SaltController::initialized (lay::PluginRoot *root) connect (m_file_watcher, SIGNAL (fileRemoved (const QString &)), this, SLOT (file_watcher_triggered ())); } - mp_mw = dynamic_cast (root); - connect (&m_salt, SIGNAL (collections_changed ()), this, SIGNAL (salt_changed ())); } @@ -128,11 +133,9 @@ SaltController::show_editor () if (mp_salt_dialog) { - if (mp_mw) { - std::string s = mp_mw->config_get (cfg_salt_manager_window_state); - if (! s.empty ()) { - lay::restore_dialog_state (mp_salt_dialog, s); - } + std::string s = mp_plugin_root->config_get (cfg_salt_manager_window_state); + if (! s.empty ()) { + lay::restore_dialog_state (mp_salt_dialog, s); } // while running the dialog, don't watch file events - that would interfere with @@ -141,9 +144,7 @@ SaltController::show_editor () mp_salt_dialog->exec (); m_file_watcher->enable (true); - if (mp_mw) { - mp_mw->config_set (cfg_salt_manager_window_state, lay::save_dialog_state (mp_salt_dialog)); - } + mp_plugin_root->config_set (cfg_salt_manager_window_state, lay::save_dialog_state (mp_salt_dialog)); sync_file_watcher (); diff --git a/src/lay/lay/laySaltController.h b/src/lay/lay/laySaltController.h index f6ff315d0..ce8ee0e9b 100644 --- a/src/lay/lay/laySaltController.h +++ b/src/lay/lay/laySaltController.h @@ -66,6 +66,11 @@ public: */ SaltController (); + /** + * @brief Reimplementation of the PluginDeclaration interface + */ + virtual void initialize (lay::PluginRoot *root); + /** * @brief Reimplementation of the PluginDeclaration interface */ @@ -186,6 +191,7 @@ signals: private: lay::SaltManagerDialog *mp_salt_dialog; lay::MainWindow *mp_mw; + lay::PluginRoot * mp_plugin_root; std::string m_salt_mine_url; lay::Salt m_salt; tl::FileSystemWatcher *m_file_watcher; diff --git a/src/lay/lay/laySettingsForm.cc b/src/lay/lay/laySettingsForm.cc index 8d595f807..5e9649cd0 100644 --- a/src/lay/lay/laySettingsForm.cc +++ b/src/lay/lay/laySettingsForm.cc @@ -40,9 +40,9 @@ namespace lay // ------------------------------------------------------------- -SettingsForm::SettingsForm (QWidget *parent, lay::MainWindow *mw, const char *name) +SettingsForm::SettingsForm (QWidget *parent, lay::PluginRoot *plugin_root, const char *name) : QDialog (parent), Ui::SettingsForm (), - mp_main_window (mw), m_finalize_recursion (false) + mp_plugin_root (plugin_root), m_finalize_recursion (false) { setObjectName (QString::fromUtf8 (name)); @@ -237,7 +237,7 @@ SettingsForm::setup () // setup the custom config pages for (std::vector ::iterator cp = m_config_pages.begin (); cp != m_config_pages.end (); ++cp) { - (*cp)->setup (mp_main_window); + (*cp)->setup (mp_plugin_root); } } @@ -246,14 +246,14 @@ SettingsForm::commit () { // commit the custom config pages for (std::vector ::iterator cp = m_config_pages.begin (); cp != m_config_pages.end (); ++cp) { - (*cp)->commit (mp_main_window); + (*cp)->commit (mp_plugin_root); } m_finalize_recursion = true; try { // config_end will make the main window call setup on the settings form. // the recursion sentinel takes care of that. - mp_main_window->config_end (); + mp_plugin_root->config_end (); m_finalize_recursion = false; } catch (...) { m_finalize_recursion = false; diff --git a/src/lay/lay/laySettingsForm.h b/src/lay/lay/laySettingsForm.h index 92ab4497d..1295b03cb 100644 --- a/src/lay/lay/laySettingsForm.h +++ b/src/lay/lay/laySettingsForm.h @@ -37,7 +37,7 @@ namespace lay { -class MainWindow; +class PluginRoot; class ConfigPage; class SettingsForm @@ -46,7 +46,7 @@ class SettingsForm Q_OBJECT public: - SettingsForm (QWidget *parent, lay::MainWindow *lv, const char *name); + SettingsForm (QWidget *parent, lay::PluginRoot *plugin_root, const char *name); void setup (); void commit (); @@ -58,7 +58,7 @@ public slots: void item_changed (QTreeWidgetItem *, QTreeWidgetItem *); private: - lay::MainWindow *mp_main_window; + lay::PluginRoot *mp_plugin_root; std::vector m_config_pages; bool m_finalize_recursion; }; diff --git a/src/lay/lay/layTechnologyController.cc b/src/lay/lay/layTechnologyController.cc index ec056fcde..8696e4f45 100644 --- a/src/lay/lay/layTechnologyController.cc +++ b/src/lay/lay/layTechnologyController.cc @@ -50,7 +50,7 @@ std::string tech_string_from_name (const std::string &tn) } TechnologyController::TechnologyController () - : PluginDeclaration (), mp_editor (0), mp_mw (0), mp_active_technology (0) + : PluginDeclaration (), mp_editor (0), mp_mw (0), mp_plugin_root (0), mp_active_technology (0) { m_configure_enabled = true; m_current_technology_updated = false; @@ -72,7 +72,8 @@ TechnologyController::instance () void TechnologyController::initialize (lay::PluginRoot *root) { - mp_mw = dynamic_cast (root); + mp_plugin_root = root; + mp_mw = lay::MainWindow::instance (); if (mp_mw) { mp_editor = new lay::TechSetupDialog (mp_mw); mp_editor->setModal (false); @@ -192,7 +193,7 @@ TechnologyController::update_active_technology () #if 0 // Hint with this implementation, the current technology follows the current layout. // Although that's a nice way to display the current technology, it's pretty confusing - lay::PluginRoot *pr = mp_mw; + lay::PluginRoot *pr = mp_plugin_root; if (pr) { pr->config_set (cfg_initial_technology, active_tech); } @@ -203,7 +204,7 @@ void TechnologyController::technologies_changed () { // update the configuration to reflect the persisted technologies - lay::PluginRoot *pr = mp_mw; + lay::PluginRoot *pr = mp_plugin_root; if (pr) { m_configure_enabled = false; try { @@ -474,9 +475,7 @@ TechnologyController::show_editor () } - if (mp_mw) { - mp_mw->config_set (cfg_tech_editor_window_state, lay::save_dialog_state (mp_editor)); - } + mp_plugin_root->config_set (cfg_tech_editor_window_state, lay::save_dialog_state (mp_editor)); } const std::string & diff --git a/src/lay/lay/layTechnologyController.h b/src/lay/lay/layTechnologyController.h index 0ad49e21e..dc347204b 100644 --- a/src/lay/lay/layTechnologyController.h +++ b/src/lay/lay/layTechnologyController.h @@ -132,6 +132,7 @@ private: bool m_technologies_configured; lay::TechSetupDialog *mp_editor; lay::MainWindow *mp_mw; + lay::PluginRoot *mp_plugin_root; std::vector m_paths; std::vector m_temp_tech; db::Technology *mp_active_technology; diff --git a/src/laybasic/laybasic/gsiDeclLayPlugin.cc b/src/laybasic/laybasic/gsiDeclLayPlugin.cc index 131897874..b83cc3603 100644 --- a/src/laybasic/laybasic/gsiDeclLayPlugin.cc +++ b/src/laybasic/laybasic/gsiDeclLayPlugin.cc @@ -849,18 +849,28 @@ Class decl_ButtonState ("lay", "ButtonState", ); static std::vector -get_config_names (lay::PluginRoot *view) +get_config_names (lay::PluginRoot *root) { std::vector names; - view->get_config_names (names); + root->get_config_names (names); return names; } -lay::PluginRoot *config_root_instance () +static lay::PluginRoot *config_root_instance () { return lay::PluginRoot::instance (); } +static tl::Variant get_config (lay::PluginRoot *root, const std::string &name) +{ + std::string value; + if (root->config_get (name, value)) { + return tl::Variant (value); + } else { + return tl::Variant (); + } +} + /** * @brief Exposes the PluginRoot interface * @@ -868,7 +878,7 @@ lay::PluginRoot *config_root_instance () * identify the plugin root node for configuration. The Plugin nature of this interface * is somewhat artificial and may be removed later. * - * TODO: this is a duplicate of the respective methods in LayoutView and MainWindow. + * TODO: this is a duplicate of the respective methods in LayoutView and Application. * This is intentional since we don't want to spend the only derivation path on this. * Once there is a mixin concept, provide a path through that concept. */ @@ -898,13 +908,13 @@ Class decl_PluginRoot ("lay", "PluginRoot", "exist. If it does and an error occured, the error message is printed\n" "on stderr. In both cases, false is returned.\n" ) + - method ("get_config", (bool (lay::PluginRoot::*) (const std::string &, std::string &) const) &lay::PluginRoot::config_get, - "@brief Get the value of a local configuration parameter\n" + method_ext ("get_config", &get_config, + "@brief Gets the value of a local 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" + "@return The value of the parameter or nil if there is no such parameter\n" ) + method ("set_config", (void (lay::PluginRoot::*) (const std::string &, const std::string &)) &lay::PluginRoot::config_set, "@brief Set a local configuration parameter with the given name to the given value\n" @@ -936,11 +946,16 @@ Class decl_PluginRoot ("lay", "PluginRoot", ), "@brief Root of the configuration space in the plugin context\n" "\n" - "This class provides access to the root configuration space. This object provides access to the configuration space in the context " - "of plugin programming.\n" - "Plugins are organized in a configuration tree. Configuration settings are propagated down to the individual plugins. " - "If there is a main window, the configuration root is identical with this object, so configuration settings " - "applied in the configuration root are available to all views.\n" + "This class provides access to the root configuration space in the context " + "of plugin programming. You can use this class to obtain configuration parameters " + "from the configuration tree during plugin initialization. However, the " + "preferred way of plugin configuration is through \\Plugin#configure.\n" + "\n" + "Currently, the application object provides an identical entry point for configuration modification. " + "For example, \"Application::instance.set_config\" is identical to \"PluginRoot::instance.set_config\". " + "Hence there is little motivation for the PluginRoot class currently and " + "this interface may be modified or removed in the future." + "\n" "\n" "This class has been introduced in version 0.25.\n" ); diff --git a/src/laybasic/laybasic/layLayoutView.cc b/src/laybasic/laybasic/layLayoutView.cc index 02d98642f..52d3deb34 100644 --- a/src/laybasic/laybasic/layLayoutView.cc +++ b/src/laybasic/laybasic/layLayoutView.cc @@ -247,9 +247,9 @@ const int timer_interval = 500; static LayoutView *ms_current = 0; -LayoutView::LayoutView (db::Manager *manager, bool editable, lay::PluginRoot *root, QWidget *parent, const char *name, unsigned int options) +LayoutView::LayoutView (db::Manager *manager, bool editable, lay::Plugin *plugin_parent, QWidget *parent, const char *name, unsigned int options) : QFrame (parent), - lay::Plugin (root), + lay::Plugin (plugin_parent), m_editable (editable), m_options (options), m_annotation_shapes (manager), @@ -259,7 +259,7 @@ LayoutView::LayoutView (db::Manager *manager, bool editable, lay::PluginRoot *ro tl::DeferredMethodScheduler::instance (); setObjectName (QString::fromUtf8 (name)); - init (manager, root, parent); + init (manager, plugin_root_maybe_null (), parent); } LayoutView::LayoutView (lay::LayoutView *source, db::Manager *manager, bool editable, lay::PluginRoot *root, QWidget *parent, const char *name, unsigned int options) @@ -537,7 +537,9 @@ LayoutView::init (db::Manager *mgr, lay::PluginRoot *root, QWidget * /*parent*/) connect (mp_timer, SIGNAL (timeout ()), this, SLOT (timer ())); mp_timer->start (timer_interval); - create_plugins (root); + if (root) { + create_plugins (root); + } m_new_layer_props.layer = 1; m_new_layer_props.datatype = 0; @@ -4468,6 +4470,8 @@ LayoutView::background_color (QColor c) mp_canvas->set_colors (c, contrast, mp_canvas->active_color ()); update_content (); + + background_color_changed_event (); } void diff --git a/src/laybasic/laybasic/layLayoutView.h b/src/laybasic/laybasic/layLayoutView.h index a9e3ff5aa..4d3e8b383 100644 --- a/src/laybasic/laybasic/layLayoutView.h +++ b/src/laybasic/laybasic/layLayoutView.h @@ -182,7 +182,7 @@ public: /** * @brief Constructor */ - LayoutView (db::Manager *mgr, bool editable, lay::PluginRoot *root, QWidget *parent = 0, const char *name = "view", unsigned int options = (unsigned int) LV_Normal); + LayoutView (db::Manager *mgr, bool editable, lay::Plugin *plugin_parent, QWidget *parent = 0, const char *name = "view", unsigned int options = (unsigned int) LV_Normal); /** * @brief Constructor (clone from another view) @@ -651,6 +651,11 @@ public: */ tl::Event viewport_changed_event; + /** + * @brief This event is triggered if the background color changed + */ + tl::Event background_color_changed_event; + /** * @brief An event signalling that the layer list has changed. * diff --git a/src/laybasic/laybasic/layPlugin.cc b/src/laybasic/laybasic/layPlugin.cc index 7271bccef..bb700cdb9 100644 --- a/src/laybasic/laybasic/layPlugin.cc +++ b/src/laybasic/laybasic/layPlugin.cc @@ -305,7 +305,7 @@ Plugin::config_set (const std::string &name, const std::string &value) } } - do_config_set (name, value); + do_config_set (name, value, false); // schedule a configuration finalization call (once for all config_set calls) dm_finalize_config (); @@ -363,6 +363,25 @@ Plugin::get_config_names (std::vector &names) const } } +PluginRoot * +Plugin::plugin_root () +{ + PluginRoot *pr = plugin_root_maybe_null (); + tl_assert (pr != 0); + return pr; +} + +PluginRoot * +Plugin::plugin_root_maybe_null () +{ + Plugin *p = this; + while (p->mp_parent) { + p = p->mp_parent; + } + + return dynamic_cast (p); +} + void Plugin::do_config_setup (Plugin *target) { @@ -371,7 +390,7 @@ Plugin::do_config_setup (Plugin *target) } // local configurations override the parent's configuration, i.e. are applied after the parents settings for (std::map::const_iterator p = m_repository.begin (); p != m_repository.end (); ++p) { - target->do_config_set (p->first, p->second); + target->do_config_set (p->first, p->second, false); } } @@ -385,8 +404,14 @@ Plugin::do_config_end () } bool -Plugin::do_config_set (const std::string &name, const std::string &value) +Plugin::do_config_set (const std::string &name, const std::string &value, bool for_child) { + if (for_child) { + // this is the case when we impose a configuration from the parent: in this case we + // have to remove it from the repository of local parameters. + m_repository.erase (name); + } + try { if (configure (name, value)) { // taken by us - don't propagate to the children @@ -398,7 +423,7 @@ Plugin::do_config_set (const std::string &name, const std::string &value) // propagate to all children (not only the first that takes it!) for (tl::weak_collection::iterator c = m_children.begin (); c != m_children.end (); ++c) { - c->do_config_set (name, value); + c->do_config_set (name, value, true); } return false; diff --git a/src/laybasic/laybasic/layPlugin.h b/src/laybasic/laybasic/layPlugin.h index c0c20bac5..49b79a91f 100644 --- a/src/laybasic/laybasic/layPlugin.h +++ b/src/laybasic/laybasic/layPlugin.h @@ -532,7 +532,8 @@ public: * * In order to make configuration changes effective, this method * must be called. It calls config_finalize recursively on the - * children. + * children. In GUI-enabled applications this step is optional + * and is performed automatically through a timer. */ void config_end (); @@ -632,6 +633,19 @@ public: */ void get_config_names (std::vector &names) const; + /** + * @brief Gets the plugin root (the parent plugin not having another parent) + * The returned pointer is guaranteed to be non-zero. + */ + PluginRoot *plugin_root (); + + /** + * @brief Gets the plugin root (the parent plugin not having another parent) + * This version may return null, if the plugin is instantiated without a + * root. + */ + PluginRoot *plugin_root_maybe_null (); + /** * @brief Menu command handler * @@ -761,7 +775,7 @@ private: /** * @brief Do the actual set or pass to the children if not taken */ - bool do_config_set (const std::string &name, const std::string &value); + bool do_config_set (const std::string &name, const std::string &value, bool for_child); /** * @brief Recursively call config_finalize