From 9b7a237a798986ae5a3f17f9ce9e718ec0d1f782 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 1 May 2022 10:30:26 +0200 Subject: [PATCH] WIP --- src/lay/lay/layClipDialog.cc | 2 +- src/lay/lay/layClipDialog.h | 2 +- src/lay/lay/layFillDialog.cc | 14 +- src/lay/lay/layFillDialog.h | 4 +- src/lay/lay/layMainWindow.cc | 4 +- src/lay/lay/laySearchReplacePlugin.cc | 4 +- src/laybasic/laybasic/layCellSelectionForm.cc | 2 +- src/laybasic/laybasic/layCellSelectionForm.h | 4 +- src/laybasic/laybasic/layCellTreeModel.cc | 6 +- src/laybasic/laybasic/layCellTreeModel.h | 10 +- src/laybasic/laybasic/layLayoutView.cc | 102 +------- src/laybasic/laybasic/layLayoutView.h | 82 +----- src/laybasic/laybasic/layLayoutViewBase.cc | 244 ++++++++++++++++-- src/laybasic/laybasic/layLayoutViewBase.h | 171 +++++++++++- .../lay_plugin/layBooleanOperationsPlugin.cc | 4 +- .../tools/diff/lay_plugin/layDiffPlugin.cc | 5 +- .../lay_plugin/layNetTracerDialog.cc | 3 +- .../lay_plugin/layNetTracerDialog.h | 7 + .../lay_plugin/layNetTracerPlugin.cc | 5 +- .../tools/view_25d/lay_plugin/layD25View.cc | 4 +- .../tools/view_25d/lay_plugin/layD25View.h | 2 +- .../view_25d/lay_plugin/layD25ViewWidget.cc | 2 +- .../view_25d/lay_plugin/layD25ViewWidget.h | 6 +- .../tools/xor/lay_plugin/layXORPlugin.cc | 7 +- .../tools/xor/lay_plugin/layXORToolDialog.cc | 2 +- .../tools/xor/lay_plugin/layXORToolDialog.h | 2 +- 26 files changed, 466 insertions(+), 234 deletions(-) diff --git a/src/lay/lay/layClipDialog.cc b/src/lay/lay/layClipDialog.cc index f644a8ce5..2c28187e0 100644 --- a/src/lay/lay/layClipDialog.cc +++ b/src/lay/lay/layClipDialog.cc @@ -66,7 +66,7 @@ static tl::RegisteredClass config_decl (new ClipDialogPl // ------------------------------------------------------------ -ClipDialog::ClipDialog (lay::Dispatcher *root, lay::LayoutView *vw) +ClipDialog::ClipDialog (lay::Dispatcher *root, LayoutViewBase *vw) : lay::Browser (root, vw), Ui::ClipDialog () { diff --git a/src/lay/lay/layClipDialog.h b/src/lay/lay/layClipDialog.h index bab730bf9..e84ad2435 100644 --- a/src/lay/lay/layClipDialog.h +++ b/src/lay/lay/layClipDialog.h @@ -40,7 +40,7 @@ class ClipDialog Q_OBJECT public: - ClipDialog (lay::Dispatcher *root, lay::LayoutView *view); + ClipDialog (lay::Dispatcher *root, lay::LayoutViewBase *view); ~ClipDialog (); public slots: diff --git a/src/lay/lay/layFillDialog.cc b/src/lay/lay/layFillDialog.cc index 5969b677a..ec0e30fed 100644 --- a/src/lay/lay/layFillDialog.cc +++ b/src/lay/lay/layFillDialog.cc @@ -73,8 +73,8 @@ static tl::RegisteredClass config_decl (new FillDialogPl // ------------------------------------------------------------ -FillDialog::FillDialog (lay::Dispatcher *main, lay::LayoutView *view) - : QDialog (view), +FillDialog::FillDialog (lay::Dispatcher *main, LayoutViewBase *view) + : QDialog (view->widget ()), lay::Plugin (main), Ui::FillDialog (), mp_view (view) @@ -315,8 +315,14 @@ FillDialog::get_fill_parameters () } else if (layer_spec_cbx->currentIndex () == 2) { - // selected layers - std::vector s = mp_view->selected_layers (); + // get selected layers + std::vector s; + + lay::LayoutView *lv = dynamic_cast (mp_view); + if (lv) { + s = lv->selected_layers (); // @@@ should be part of LayoutViewBase too + } + for (std::vector::const_iterator l = s.begin (); l != s.end (); ++l) { if (! (*l)->has_children () && cv->layout ().is_valid_layer ((*l)->layer_index ())) { fp.exclude_layers.push_back (cv->layout ().get_properties ((*l)->layer_index ())); diff --git a/src/lay/lay/layFillDialog.h b/src/lay/lay/layFillDialog.h index 52deb5826..faa06851a 100644 --- a/src/lay/lay/layFillDialog.h +++ b/src/lay/lay/layFillDialog.h @@ -76,7 +76,7 @@ class LAY_PUBLIC FillDialog Q_OBJECT public: - FillDialog (lay::Dispatcher *root, lay::LayoutView *view); + FillDialog (lay::Dispatcher *root, lay::LayoutViewBase *view); ~FillDialog (); public slots: @@ -95,7 +95,7 @@ private: void generate_fill (const FillParameters &fp); FillParameters get_fill_parameters (); - lay::LayoutView *mp_view; + lay::LayoutViewBase *mp_view; }; } diff --git a/src/lay/lay/layMainWindow.cc b/src/lay/lay/layMainWindow.cc index e1690b121..d632ce26a 100644 --- a/src/lay/lay/layMainWindow.cc +++ b/src/lay/lay/layMainWindow.cc @@ -159,7 +159,7 @@ MainWindow::MainWindow (QApplication *app, const char *name, bool undo_enabled) : QMainWindow (0), tl::Object (), lay::DispatcherDelegate (), - m_dispatcher (this, this), + m_dispatcher (this), m_text_progress (this, 10 /*verbosity threshold*/), m_mode (std::numeric_limits::max ()), mp_setup_form (0), @@ -179,6 +179,8 @@ MainWindow::MainWindow (QApplication *app, const char *name, bool undo_enabled) mp_app (app), m_manager (undo_enabled) { + m_dispatcher.set_menu_parent_widget (this); + // ensures the deferred method scheduler is present tl::DeferredMethodScheduler::instance (); diff --git a/src/lay/lay/laySearchReplacePlugin.cc b/src/lay/lay/laySearchReplacePlugin.cc index 6c4be161b..cca26248a 100644 --- a/src/lay/lay/laySearchReplacePlugin.cc +++ b/src/lay/lay/laySearchReplacePlugin.cc @@ -65,7 +65,9 @@ public: virtual lay::Plugin *create_plugin (db::Manager *, lay::Dispatcher *root, lay::LayoutViewBase *view) const { - return new SearchReplaceDialog (root, view); + lay::LayoutView *lv = dynamic_cast (view); + tl_assert (lv != 0); + return new SearchReplaceDialog (root, lv); } }; diff --git a/src/laybasic/laybasic/layCellSelectionForm.cc b/src/laybasic/laybasic/layCellSelectionForm.cc index 0bd3ff519..be93b86ea 100644 --- a/src/laybasic/laybasic/layCellSelectionForm.cc +++ b/src/laybasic/laybasic/layCellSelectionForm.cc @@ -49,7 +49,7 @@ static const std::string cfg_cell_selection_search_use_expressions ("cell-select // ------------------------------------------------------------ -CellSelectionForm::CellSelectionForm (QWidget *parent, LayoutView *view, const char *name, bool simple_mode) +CellSelectionForm::CellSelectionForm (QWidget *parent, LayoutViewBase *view, const char *name, bool simple_mode) : QDialog (parent), Ui::CellSelectionForm (), mp_view (view), m_current_cv (-1), diff --git a/src/laybasic/laybasic/layCellSelectionForm.h b/src/laybasic/laybasic/layCellSelectionForm.h index adc0a5cc7..f1447eee7 100644 --- a/src/laybasic/laybasic/layCellSelectionForm.h +++ b/src/laybasic/laybasic/layCellSelectionForm.h @@ -49,7 +49,7 @@ class LAYBASIC_PUBLIC CellSelectionForm Q_OBJECT public: - CellSelectionForm (QWidget *parent, LayoutView *view, const char *name, bool simple_mode = false); + CellSelectionForm (QWidget *parent, LayoutViewBase *view, const char *name, bool simple_mode = false); /** * @brief Obtain the selected cellview's index (with changes) @@ -76,7 +76,7 @@ public slots: void find_prev_clicked(); private: - lay::LayoutView *mp_view; + lay::LayoutViewBase *mp_view; std::vector m_cellviews; int m_current_cv; bool m_name_cb_enabled; diff --git a/src/laybasic/laybasic/layCellTreeModel.cc b/src/laybasic/laybasic/layCellTreeModel.cc index d8e4ca573..d15ddf2fd 100644 --- a/src/laybasic/laybasic/layCellTreeModel.cc +++ b/src/laybasic/laybasic/layCellTreeModel.cc @@ -303,7 +303,7 @@ CellTreeItem::by_area_equal_than (const CellTreeItem *b) const // valid ("under construction"). In this case, the model will return defaults or void // objects. -CellTreeModel::CellTreeModel (QWidget *parent, lay::LayoutView *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting) +CellTreeModel::CellTreeModel (QWidget *parent, lay::LayoutViewBase *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting) : QAbstractItemModel (parent), m_flags (flags), m_sorting (sorting), @@ -379,7 +379,7 @@ CellTreeModel::~CellTreeModel () } void -CellTreeModel::configure (lay::LayoutView *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting) +CellTreeModel::configure (lay::LayoutViewBase *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting) { db::Layout *layout = & view->cellview (cv_index)->layout (); do_configure (layout, 0, view, cv_index, flags, base, sorting); @@ -398,7 +398,7 @@ CellTreeModel::configure (db::Library *library, unsigned int flags, const db::Ce } void -CellTreeModel::do_configure (db::Layout *layout, db::Library *library, lay::LayoutView *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting) +CellTreeModel::do_configure (db::Layout *layout, db::Library *library, lay::LayoutViewBase *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting) { bool flat = ((flags & Flat) != 0) && ((flags & TopCells) == 0); diff --git a/src/laybasic/laybasic/layCellTreeModel.h b/src/laybasic/laybasic/layCellTreeModel.h index 2e8569e55..b0c6af312 100644 --- a/src/laybasic/laybasic/layCellTreeModel.h +++ b/src/laybasic/laybasic/layCellTreeModel.h @@ -45,7 +45,7 @@ namespace db namespace lay { -class LayoutView; +class LayoutViewBase; class CellTreeItem; /** @@ -85,7 +85,7 @@ public: * If flags "Children" or "Parents" are given, "base" must be set to the cell of which * the children or parents should be derived. */ - CellTreeModel (QWidget *parent, lay::LayoutView *view, int cv_index, unsigned int flags = 0, const db::Cell *base = 0, Sorting sorting = ByName); + CellTreeModel (QWidget *parent, lay::LayoutViewBase *view, int cv_index, unsigned int flags = 0, const db::Cell *base = 0, Sorting sorting = ByName); /** * @brief Constructor @@ -120,7 +120,7 @@ public: /** * @brief Reconfigures the model with a LayoutView */ - void configure (lay::LayoutView *view, int cv_index, unsigned int flags = 0, const db::Cell *base = 0, Sorting sorting = ByName); + void configure (LayoutViewBase *view, int cv_index, unsigned int flags = 0, const db::Cell *base = 0, Sorting sorting = ByName); /** * @brief Reconfigures the model with a pure Layout @@ -257,7 +257,7 @@ private: unsigned int m_flags; Sorting m_sorting; QWidget *mp_parent; - lay::LayoutView *mp_view; + lay::LayoutViewBase *mp_view; db::Layout *mp_layout; db::Library *mp_library; int m_cv_index; @@ -271,7 +271,7 @@ private: void build_top_level (); void clear_top_level (); bool search_children (const tl::GlobPattern &pattern, CellTreeItem *item); - void do_configure (db::Layout *layout, db::Library *library, lay::LayoutView *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting); + void do_configure (db::Layout *layout, db::Library *library, LayoutViewBase *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting); }; /** diff --git a/src/laybasic/laybasic/layLayoutView.cc b/src/laybasic/laybasic/layLayoutView.cc index 47e531863..95408cdad 100644 --- a/src/laybasic/laybasic/layLayoutView.cc +++ b/src/laybasic/laybasic/layLayoutView.cc @@ -321,6 +321,12 @@ LayoutView::~LayoutView () mp_bookmarks_view = 0; } +void +LayoutView::do_change_active_cellview () +{ + dm_setup_editor_option_pages (); +} + lay::EditorOptionsPages *LayoutView::editor_options_pages () { if (! mp_editor_options_frame) { @@ -614,21 +620,6 @@ LayoutView::set_or_request_current_layer (unsigned int cv_index, const db::Layer return false; } -bool -LayoutView::set_current_layer (unsigned int cv_index, const db::LayerProperties &lp) -{ - // rename the ones that got shifted. - lay::LayerPropertiesConstIterator l = begin_layers (); - while (! l.at_end ()) { - if (l->source (true).cv_index () == int (cv_index) && l->source (true).layer_props ().log_equal (lp)) { - set_current_layer (l); - return true; - } - ++l; - } - return false; -} - void LayoutView::set_current_layer (const lay::LayerPropertiesConstIterator &l) { @@ -637,13 +628,7 @@ LayoutView::set_current_layer (const lay::LayerPropertiesConstIterator &l) } } -void -LayoutView::do_set_current_layer (const lay::LayerPropertiesConstIterator &l) -{ - set_current_layer (l); -} - -lay::LayerPropertiesConstIterator +lay::LayerPropertiesConstIterator LayoutView::current_layer () const { if (mp_control_panel) { @@ -838,67 +823,6 @@ LayoutView::do_set_phase (int phase) } } -void -LayoutView::enable_active_cellview_changed_event (bool enable, bool silent) -{ - if (m_active_cellview_changed_event_enabled == enable) { - return; - } - - m_active_cellview_changed_event_enabled = enable; - if (enable) { - - if (!silent && ! m_active_cellview_changed_events.empty ()) { - - // deliver stored events - - // we need to cancel pending drawing or dragging operations to reflect the new cellview (different target, may have different technology etc.) - cancel_esc (); - - // we need to setup the editor option pages because the technology may have changed - dm_setup_editor_option_pages (); - - active_cellview_changed_event (); - for (std::set::const_iterator i = m_active_cellview_changed_events.begin (); i != m_active_cellview_changed_events.end (); ++i) { - active_cellview_changed_with_index_event (*i); - } - - // Because the title reflects the active one, emit a title changed event - if (title_string ().empty ()) { - emit title_changed (); - } - - } - - } - - m_active_cellview_changed_events.clear (); -} - -void -LayoutView::active_cellview_changed (int index) -{ - if (m_active_cellview_changed_event_enabled) { - - // we need to cancel pending drawing or dragging operations to reflect the new cellview (different target, may have different technology etc.) - cancel_esc (); - - // we need to setup the editor option pages because the technology may have changed - dm_setup_editor_option_pages (); - - active_cellview_changed_event (); - active_cellview_changed_with_index_event (index); - - // Because the title reflects the active one, emit a title changed event - if (title_string ().empty ()) { - emit title_changed (); - } - - } else { - m_active_cellview_changed_events.insert (index); - } -} - void LayoutView::active_library_changed (int /*index*/) { @@ -989,18 +913,6 @@ LayoutView::cut () } } -const lay::CellView & -LayoutView::active_cellview () const -{ - return cellview ((unsigned int) active_cellview_index ()); -} - -lay::CellViewRef -LayoutView::active_cellview_ref () -{ - return cellview_ref ((unsigned int) active_cellview_index ()); -} - int LayoutView::active_cellview_index () const { diff --git a/src/laybasic/laybasic/layLayoutView.h b/src/laybasic/laybasic/layLayoutView.h index 69af08d9d..7b06b183d 100644 --- a/src/laybasic/laybasic/layLayoutView.h +++ b/src/laybasic/laybasic/layLayoutView.h @@ -140,21 +140,6 @@ public: */ virtual bool has_selection (); - /** - * @brief Gets the window title of the view - */ - std::string title () const; - - /** - * @brief Sets the window title to an explicit string - */ - void set_title (const std::string &t); - - /** - * @brief Resets the explicit title and enable the automatic naming - */ - void reset_title (); - /** * @brief Display a status message */ @@ -179,7 +164,7 @@ public: * Switches the mode on application level. Use this method to initiate * a mode switch from the view. */ - void switch_mode (int m); + virtual void switch_mode (int m); /** * @brief Updates the menu for the given view @@ -210,7 +195,10 @@ public: * * Returns false if the layer is not a valid one. */ - bool set_current_layer (unsigned int cv_index, const db::LayerProperties &properties); + bool set_current_layer (unsigned int cv_index, const db::LayerProperties &properties) + { + return LayoutViewBase::set_current_layer (cv_index, properties); + } /** * @brief Sets the currently active layer @@ -218,7 +206,7 @@ public: * The active layer is the one that is active in the layer * browser panel. This method will also select this layer. */ - void set_current_layer (const lay::LayerPropertiesConstIterator &l); + virtual void set_current_layer (const lay::LayerPropertiesConstIterator &l); /** * @brief Retrieve the index of the currently active layer @@ -227,7 +215,7 @@ public: * browser panel. * This method returns a null iterator, if no layer is active. */ - lay::LayerPropertiesConstIterator current_layer () const; + virtual lay::LayerPropertiesConstIterator current_layer () const; /** * @brief Return the layers that are selected in the layer browser @@ -246,16 +234,6 @@ public: */ int active_cellview_index () const; - /** - * @brief Get the index of the active cellview (shown in hierarchy browser) - */ - const lay::CellView &active_cellview () const; - - /** - * @brief Gets a cellview reference to the active cellview - */ - lay::CellViewRef active_cellview_ref (); - /** * @brief Select a certain cellview for the active one */ @@ -277,18 +255,6 @@ public: */ void current_cell_path (int cv_index, cell_path_type &path) const; - /** - * @brief Cell path of the current cell - * - * This method version is provided for automation purposes mainly. - */ - cell_path_type get_current_cell_path (int cv_index) const - { - cell_path_type r; - current_cell_path (cv_index, r); - return r; - } - /** * @brief Cell path of the current cell in the active cellview * @@ -307,16 +273,6 @@ public: */ virtual void set_current_cell_path (int cv_index, const cell_path_type &path); - /** - * @brief Set the path to the current cell is the current cellview - * - * This is a convenience function setting the path for the active cellview. - */ - void set_current_cell_path (const cell_path_type &path) - { - set_current_cell_path (active_cellview_index (), path); - } - /** * @brief Remove unused layers */ @@ -496,19 +452,6 @@ public: */ tl::Event hide_event; - /** - * @brief An event triggered if the active cellview changes - * This event is triggered after the active cellview changed. - */ - tl::Event active_cellview_changed_event; - - /** - * @brief An event triggered if the active cellview changes - * This event is triggered after the active cellview changed. The integer parameter is the index of the - * new cellview. - */ - tl::event active_cellview_changed_with_index_event; - public slots: /** * @brief Store the current state on the "previous states" stack @@ -705,7 +648,11 @@ public slots: void deactivate_all_browsers (); private slots: - void active_cellview_changed (int index); + void active_cellview_changed (int index) + { + LayoutViewBase::active_cellview_changed (index); + } + void active_library_changed (int index); void side_panel_destroyed (); @@ -768,8 +715,6 @@ private: QSpinBox *mp_min_hier_spbx; QSpinBox *mp_max_hier_spbx; BookmarkList m_bookmarks; - bool m_active_cellview_changed_event_enabled; - std::set m_active_cellview_changed_events; bool m_always_show_source; bool m_always_show_ld; bool m_always_show_layout_index; @@ -796,13 +741,12 @@ protected: virtual void do_paste (); virtual void begin_layer_updates (); virtual void ensure_layer_selected (); - virtual void do_set_current_layer (const lay::LayerPropertiesConstIterator &l); virtual void update_content_for_cv (int cv_index); virtual void do_set_no_stipples (bool no_stipples); virtual void do_set_phase (int phase); virtual bool set_hier_levels_basic (std::pair l); + virtual void do_change_active_cellview (); virtual bool is_activated () const; - virtual void enable_active_cellview_changed_event (bool enable, bool silent = false); // overrides Editables method to display a message void signal_selection_changed (); diff --git a/src/laybasic/laybasic/layLayoutViewBase.cc b/src/laybasic/laybasic/layLayoutViewBase.cc index 84ecfad9e..488402a1d 100644 --- a/src/laybasic/laybasic/layLayoutViewBase.cc +++ b/src/laybasic/laybasic/layLayoutViewBase.cc @@ -304,6 +304,9 @@ LayoutViewBase::init (db::Manager *mgr) { manager (mgr); + m_active_cellview_index = -1; + m_active_cellview_changed_event_enabled = true; + m_annotation_shapes.manager (mgr); m_visibility_changed = false; @@ -625,6 +628,58 @@ LayoutViewBase::is_dirty () const return m_dirty; } +std::string +LayoutViewBase::title () const +{ + if (! m_title.empty ()) { + return m_title; + } else if (cellviews () == 0) { + return tl::to_string (QObject::tr ("")); + } else { + + int cv_index = active_cellview_index (); + if (cv_index < 0 || cv_index >= int (cellviews ())) { + cv_index = 0; + } + + const lay::CellView &cv0 = cellview (cv_index); + + std::string t; + + t += cv0->name (); + if (cv0->layout ().is_valid_cell_index (cv0.cell_index ())) { + t += " ["; + t += cv0->layout ().cell_name (cv0.cell_index ()); + t += "]"; + } + + if (cellviews () > 1) { + t += " ..."; + } + + return t; + + } +} + +void +LayoutViewBase::set_title (const std::string &t) +{ + if (m_title != t) { + m_title = t; + emit_title_changed (); + } +} + +void +LayoutViewBase::reset_title () +{ + if (! m_title.empty ()) { + m_title = ""; + emit_title_changed (); + } +} + bool LayoutViewBase::configure (const std::string &name, const std::string &value) { @@ -1355,6 +1410,35 @@ LayoutViewBase::rename_properties (unsigned int index, const std::string &new_na layer_list_changed_event (4); } +bool +LayoutViewBase::set_current_layer (unsigned int cv_index, const db::LayerProperties &lp) +{ + // rename the ones that got shifted. + lay::LayerPropertiesConstIterator l = begin_layers (); + while (! l.at_end ()) { + if (l->source (true).cv_index () == int (cv_index) && l->source (true).layer_props ().log_equal (lp)) { + set_current_layer (l); + return true; + } + ++l; + } + return false; +} + +void +LayoutViewBase::set_current_layer (const lay::LayerPropertiesConstIterator &l) +{ + // @@@ No checking happens + m_current_layer = l; +} + +lay::LayerPropertiesConstIterator +LayoutViewBase::current_layer () const +{ + // @@@ No checking happens + return m_current_layer; +} + void LayoutViewBase::merge_dither_pattern (lay::LayerPropertiesList &props) { @@ -1975,6 +2059,10 @@ LayoutViewBase::erase_cellview (unsigned int index) m_hidden_cells.erase (m_hidden_cells.begin () + index); } + if (m_current_cell_per_cellview.size () > index) { + m_current_cell_per_cellview.erase (m_current_cell_per_cellview.begin () + index); + } + for (unsigned int lindex = 0; lindex < layer_lists (); ++lindex) { // remove all references to the cellview @@ -2030,6 +2118,9 @@ LayoutViewBase::clear_cellviews () set_properties (lay::LayerPropertiesList ()); m_cellviews.clear (); + m_hidden_cells.clear (); + m_current_cell_per_cellview.clear (); + // clear the history, store path and zoom box m_display_states.clear (); m_display_state_ptr = 0; @@ -2312,7 +2403,7 @@ LayoutViewBase::add_new_layers (const std::vector &layer_ids, int set_properties (new_props); if (was_empty) { - do_set_current_layer (new_props.begin_const_recursive ()); + set_current_layer (new_props.begin_const_recursive ()); } } @@ -2601,6 +2692,11 @@ LayoutViewBase::reload_layout (unsigned int cv_index) } } + // clear the current cell (NOTE: this is for providing a cell target for some UI functions only) + if (m_current_cell_per_cellview.size () > cv_index) { + m_current_cell_per_cellview [cv_index] = cell_path_type (); + } + // Determine which layers to create as new layers. New layer need to be created // if these have not been present in the original layout and there are no layer views // referring to them. @@ -4116,13 +4212,133 @@ LayoutViewBase::cellview_changed (unsigned int index) } } +const lay::CellView & +LayoutViewBase::active_cellview () const +{ + return cellview ((unsigned int) active_cellview_index ()); +} + +lay::CellViewRef +LayoutViewBase::active_cellview_ref () +{ + return cellview_ref ((unsigned int) active_cellview_index ()); +} + +int +LayoutViewBase::active_cellview_index () const +{ + return m_active_cellview_index; +} + void -LayoutViewBase::set_current_cell_path (int /*cv_index*/, const cell_path_type & /*path*/) +LayoutViewBase::set_active_cellview_index (int index) +{ + if (index >= 0 && index < int (cellviews ())) { + if (m_active_cellview_index != index) { + m_active_cellview_index = index; + active_cellview_changed (index); + } + } else { + m_active_cellview_index = -1; + } +} + +void +LayoutViewBase::selected_cells_paths (int /*cv_index*/, std::vector & /*paths*/) const +{ + // TODO: not implemented yet as there is no setter so far. + // (but it is implemented in the UI version where it is bound to the hierarchy control panel) +} + +void +LayoutViewBase::current_cell_path (int cv_index, cell_path_type &path) const +{ + if (cv_index >= 0 && cv_index < int (m_current_cell_per_cellview.size ())) { + path = m_current_cell_per_cellview [cv_index]; + } else { + path = cell_path_type (); + } +} + +void +LayoutViewBase::set_current_cell_path (int cv_index, const cell_path_type &path) +{ + if (cv_index >= 0) { + while (cv_index <= int (m_current_cell_per_cellview.size ())) { + m_current_cell_per_cellview.push_back (cell_path_type ()); + } + m_current_cell_per_cellview [cv_index] = path; + } +} + +void +LayoutViewBase::do_change_active_cellview () { // .. nothing yet .. } -void +void +LayoutViewBase::enable_active_cellview_changed_event (bool enable, bool silent) +{ + if (m_active_cellview_changed_event_enabled == enable) { + return; + } + + m_active_cellview_changed_event_enabled = enable; + if (enable) { + + if (!silent && ! m_active_cellview_changed_events.empty ()) { + + // deliver stored events + + // we need to cancel pending drawing or dragging operations to reflect the new cellview (different target, may have different technology etc.) + cancel_esc (); + + // we need to setup the editor option pages because the technology may have changed + do_change_active_cellview (); + + active_cellview_changed_event (); + for (std::set::const_iterator i = m_active_cellview_changed_events.begin (); i != m_active_cellview_changed_events.end (); ++i) { + active_cellview_changed_with_index_event (*i); + } + + // Because the title reflects the active one, emit a title changed event + if (title_string ().empty ()) { + emit_title_changed (); + } + + } + + } + + m_active_cellview_changed_events.clear (); +} + +void +LayoutViewBase::active_cellview_changed (int index) +{ + if (m_active_cellview_changed_event_enabled) { + + // we need to cancel pending drawing or dragging operations to reflect the new cellview (different target, may have different technology etc.) + cancel_esc (); + + // we need to setup the editor option pages because the technology may have changed + do_change_active_cellview (); + + active_cellview_changed_event (); + active_cellview_changed_with_index_event (index); + + // Because the title reflects the active one, emit a title changed event + if (title_string ().empty ()) { + emit_title_changed (); + } + + } else { + m_active_cellview_changed_events.insert (index); + } +} + +void LayoutViewBase::select_cell_dispatch (const cell_path_type &path, int cellview_index) { bool set_max_hier = (m_full_hier_new_cell || has_max_hier ()); @@ -4781,12 +4997,6 @@ LayoutViewBase::ensure_layer_selected () // .. nothing yet .. } -void -LayoutViewBase::do_set_current_layer (const lay::LayerPropertiesConstIterator & /*l*/) -{ - // .. nothing yet .. -} - void LayoutViewBase::do_set_no_stipples (bool /*no_stipples*/) { @@ -4812,21 +5022,9 @@ LayoutViewBase::is_activated () const } void -LayoutViewBase::switch_mode (int /*m*/) +LayoutViewBase::switch_mode (int m) { - // .. nothing yet .. -} - -void -LayoutViewBase::set_active_cellview_index (int /*index*/) -{ - // .. nothing yet .. -} - -void -LayoutViewBase::enable_active_cellview_changed_event (bool /*enable*/, bool /*silent*/) -{ - // .. nothing yet .. + mode (m); } void diff --git a/src/laybasic/laybasic/layLayoutViewBase.h b/src/laybasic/laybasic/layLayoutViewBase.h index 781b534d2..50346e6a7 100644 --- a/src/laybasic/laybasic/layLayoutViewBase.h +++ b/src/laybasic/laybasic/layLayoutViewBase.h @@ -195,6 +195,22 @@ public: */ ~LayoutViewBase (); + /** + * @brief Gets the current mode + */ + int mode () const + { + return m_mode; + } + + /** + * @brief Switches the application's mode + * + * Switches the mode on application level. Use this method to initiate + * a mode switch from the view. + */ + virtual void switch_mode (int m); + /** * @brief Determine if there is something to copy * @@ -508,6 +524,33 @@ public: insert_layer_list (index, LayerPropertiesList ()); } + /** + * @brief Sets the currently active layer by layer properties and cell view index + * + * This method will look up that layer in the layer view tree and select that layer. + * This method will also select this layer. + * + * Returns false if the layer is not a valid one. + */ + bool set_current_layer (unsigned int cv_index, const db::LayerProperties &properties); + + /** + * @brief Sets the currently active layer + * + * The active layer is the one that is active in the layer + * browser panel. This method will also select this layer. + */ + virtual void set_current_layer (const lay::LayerPropertiesConstIterator &l); + + /** + * @brief Retrieve the index of the currently active layer + * + * The active layer is the one that is active in the layer + * browser panel. + * This method returns a null iterator, if no layer is active. + */ + virtual lay::LayerPropertiesConstIterator current_layer () const; + /** * @brief Set the custom dither pattern */ @@ -1837,7 +1880,96 @@ public: */ db::InstElement ascend (int cellview_index); - /** + /** + * @brief Get the index of the active cellview (shown in hierarchy browser) + */ + const lay::CellView &active_cellview () const; + + /** + * @brief Gets a cellview reference to the active cellview + */ + lay::CellViewRef active_cellview_ref (); + + /** + * @brief Get the index of the active cellview (shown in hierarchy browser) + */ + virtual int active_cellview_index () const; + + /** + * @brief Select a certain cellview for the active one + */ + virtual void set_active_cellview_index (int index); + + /** + * @brief An event triggered if the active cellview changes + * This event is triggered after the active cellview changed. + */ + tl::Event active_cellview_changed_event; + + /** + * @brief An event triggered if the active cellview changes + * This event is triggered after the active cellview changed. The integer parameter is the index of the + * new cellview. + */ + tl::event active_cellview_changed_with_index_event; + + /** + * @brief Cell paths of the selected cells + * + * The current cell is the one highlighted in the browser with the focus rectangle. The + * current path is returned for the cellview given by cv_index. + */ + virtual void selected_cells_paths (int cv_index, std::vector &paths) const; + + /** + * @brief Cell path of the current cell + * + * The current cell is the one highlighted in the browser with the focus rectangle. The + * current path is returned for the cellview given by cv_index. + */ + virtual void current_cell_path (int cv_index, cell_path_type &path) const; + + /** + * @brief Cell path of the current cell + * + * This method version is provided for automation purposes mainly. + */ + cell_path_type get_current_cell_path (int cv_index) const + { + cell_path_type r; + current_cell_path (cv_index, r); + return r; + } + + /** + * @brief Cell path of the current cell in the active cellview + * + * This is a convenience function returning the path for the active cellview. + */ + void current_cell_path (cell_path_type &path) const + { + current_cell_path (active_cellview_index (), path); + } + + /** + * @brief Set the path to the current cell + * + * The current cell is the one highlighted in the browser with the focus rectangle. The + * cell given by the path is highlighted and scrolled into view. + */ + virtual void set_current_cell_path (int cv_index, const cell_path_type &path); + + /** + * @brief Set the path to the current cell is the current cellview + * + * This is a convenience function setting the path for the active cellview. + */ + void set_current_cell_path (const cell_path_type &path) + { + set_current_cell_path (active_cellview_index (), path); + } + + /** * @brief Select a cell by path for a certain cell view and fit cell */ void select_cell_fit (const cell_path_type &path, int cellview_index); @@ -2186,6 +2318,21 @@ public: return mp_canvas->global_trans (); } + /** + * @brief Gets the window title of the view + */ + std::string title () const; + + /** + * @brief Sets the window title to an explicit string + */ + void set_title (const std::string &t); + + /** + * @brief Resets the explicit title and enable the automatic naming + */ + void reset_title (); + /** * @brief Removes the previous state from the stack */ @@ -2461,6 +2608,14 @@ private: lay::Plugin *mp_active_plugin; + int m_active_cellview_index; + bool m_active_cellview_changed_event_enabled; + std::set m_active_cellview_changed_events; + + lay::LayerPropertiesConstIterator m_current_layer; + + std::vector m_current_cell_per_cellview; + bool m_visibility_changed; tl::Clock m_clock, m_last_checked; @@ -2500,11 +2655,6 @@ protected: return m_options; } - int mode () const - { - return m_mode; - } - lay::Plugin *active_plugin () const { return mp_active_plugin; @@ -2525,18 +2675,17 @@ protected: virtual lay::Color default_background_color (); virtual void do_set_background_color (lay::Color color, lay::Color contrast); virtual void do_paste (); - virtual void switch_mode (int m); virtual void begin_layer_updates (); virtual void ensure_layer_selected (); - virtual void do_set_current_layer (const lay::LayerPropertiesConstIterator &l); virtual void do_set_no_stipples (bool no_stipples); virtual void do_set_phase (int phase); virtual bool is_activated () const; + virtual void do_change_active_cellview (); virtual void update_content_for_cv (int cv_index); - virtual void set_active_cellview_index (int index); - virtual void enable_active_cellview_changed_event (bool enable, bool silent = false); virtual bool set_hier_levels_basic (std::pair l); - virtual void set_current_cell_path (int cv_index, const cell_path_type &path); + + void enable_active_cellview_changed_event (bool enable, bool silent = false); + void active_cellview_changed (int index); virtual void emit_edits_enabled_changed () { } virtual void emit_title_changed () { } diff --git a/src/plugins/tools/bool/lay_plugin/layBooleanOperationsPlugin.cc b/src/plugins/tools/bool/lay_plugin/layBooleanOperationsPlugin.cc index 7202d66e1..892c78351 100644 --- a/src/plugins/tools/bool/lay_plugin/layBooleanOperationsPlugin.cc +++ b/src/plugins/tools/bool/lay_plugin/layBooleanOperationsPlugin.cc @@ -496,7 +496,9 @@ public: lay::Plugin *create_plugin (db::Manager *, lay::Dispatcher *root, lay::LayoutViewBase *view) const { - return new BooleanOperationsPlugin (root, view); + lay::LayoutView *lv = dynamic_cast (view); + tl_assert (lv != 0); + return new BooleanOperationsPlugin (root, lv); } }; diff --git a/src/plugins/tools/diff/lay_plugin/layDiffPlugin.cc b/src/plugins/tools/diff/lay_plugin/layDiffPlugin.cc index 7f207a1d2..b44dfa780 100644 --- a/src/plugins/tools/diff/lay_plugin/layDiffPlugin.cc +++ b/src/plugins/tools/diff/lay_plugin/layDiffPlugin.cc @@ -24,6 +24,7 @@ #include "layDispatcher.h" #include "layPlugin.h" +#include "layLayoutView.h" namespace lay { @@ -104,7 +105,9 @@ public: lay::Plugin *create_plugin (db::Manager *, lay::Dispatcher *root, lay::LayoutViewBase *view) const { - return new DiffPlugin (root, view); + lay::LayoutView *lv = dynamic_cast (view); + tl_assert (lv != 0); + return new DiffPlugin (root, lv); } }; diff --git a/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.cc b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.cc index 132d46a4a..7bda1dbb2 100644 --- a/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.cc +++ b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.cc @@ -68,7 +68,8 @@ NetTracerDialog::NetTracerDialog (lay::Dispatcher *root, lay::LayoutView *view) m_marker_intensity (0), m_auto_color_enabled (false), m_auto_color_index (0), - m_mouse_state (0) + m_mouse_state (0), + mp_view (view) { mp_export_file_dialog = new lay::FileDialog (this, tl::to_string (QObject::tr ("Export Net")), tl::to_string (QObject::tr ("KLayout net files (*.lyn);;All files (*)"))); diff --git a/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.h b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.h index 4bff2255f..8e072dbf1 100644 --- a/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.h +++ b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.h @@ -108,6 +108,8 @@ private: lay::FileDialog *mp_export_file_dialog; std::string m_export_file_name; + lay::LayoutView *mp_view; + void commit (); size_t get_trace_depth (); void update_highlights (); @@ -121,6 +123,11 @@ private: db::NetTracerNet *do_trace (const db::DBox &start_search_box, const db::DBox &stop_search_box, bool trace_path); bool get_net_tracer_setup (const lay::CellView &cv, db::NetTracerData &data); void trace_all_nets (db::LayoutToNetlist *l2ndb, const lay::CellView &cv, bool flat); + + lay::LayoutView *view () + { + return mp_view; + } }; } diff --git a/src/plugins/tools/net_tracer/lay_plugin/layNetTracerPlugin.cc b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerPlugin.cc index 4382851b4..409e0a71e 100644 --- a/src/plugins/tools/net_tracer/lay_plugin/layNetTracerPlugin.cc +++ b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerPlugin.cc @@ -28,6 +28,7 @@ #include "layConverters.h" #include "layCellView.h" +#include "layLayoutView.h" #include "gsiDecl.h" @@ -77,7 +78,9 @@ public: virtual lay::Plugin *create_plugin (db::Manager * /*manager*/, lay::Dispatcher *root, lay::LayoutViewBase *view) const { - return new NetTracerDialog (root, view); + lay::LayoutView *lv = dynamic_cast (view); + tl_assert (lv != 0); + return new NetTracerDialog (root, lv); } }; diff --git a/src/plugins/tools/view_25d/lay_plugin/layD25View.cc b/src/plugins/tools/view_25d/lay_plugin/layD25View.cc index 019dedecd..a00675974 100644 --- a/src/plugins/tools/view_25d/lay_plugin/layD25View.cc +++ b/src/plugins/tools/view_25d/lay_plugin/layD25View.cc @@ -38,7 +38,7 @@ namespace lay const double initial_elevation = 15.0; -D25View::D25View (lay::Dispatcher *root, lay::LayoutView *view) +D25View::D25View (lay::Dispatcher *root, LayoutViewBase *view) : lay::Browser (root, view, "d25_view"), dm_rerun_macro (this, &D25View::rerun_macro), dm_fit (this, &D25View::fit) @@ -94,7 +94,7 @@ D25View::D25View (lay::Dispatcher *root, lay::LayoutView *view) mp_ui->material_list->addAction (mp_ui->hide_selected_action); mp_ui->material_list->setContextMenuPolicy (Qt::ActionsContextMenu); - connect (mp_ui->material_list, SIGNAL (itemChanged (QListWidgetItem *)), this, SLOT (material_item_changed (QListWidgetItem *))); + connect (mp_ui->material_list, SIGNAL (itemChanged(QListWidgetItem *)), this, SLOT (material_item_changed(QListWidgetItem *))); } D25View::~D25View () diff --git a/src/plugins/tools/view_25d/lay_plugin/layD25View.h b/src/plugins/tools/view_25d/lay_plugin/layD25View.h index 724c14e25..6cc5cb269 100644 --- a/src/plugins/tools/view_25d/lay_plugin/layD25View.h +++ b/src/plugins/tools/view_25d/lay_plugin/layD25View.h @@ -57,7 +57,7 @@ class D25View Q_OBJECT public: - D25View (lay::Dispatcher *root, lay::LayoutView *view); + D25View (lay::Dispatcher *root, lay::LayoutViewBase *view); ~D25View (); virtual void menu_activated (const std::string &symbol); diff --git a/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc b/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc index 9fa1f77d6..7be0f8c24 100644 --- a/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc +++ b/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc @@ -711,7 +711,7 @@ D25ViewWidget::finish () } void -D25ViewWidget::attach_view (LayoutView *view) +D25ViewWidget::attach_view (LayoutViewBase *view) { mp_view = view; } diff --git a/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.h b/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.h index af5dd0a54..180a9cb89 100644 --- a/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.h +++ b/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.h @@ -57,7 +57,7 @@ namespace tl namespace lay { -class LayoutView; +class LayoutViewBase; class LayerPropertiesNode; class D25ViewWidget; @@ -106,7 +106,7 @@ public: void mouseReleaseEvent (QMouseEvent *event); void mouseMoveEvent (QMouseEvent *event); - void attach_view(lay::LayoutView *view); + void attach_view(lay::LayoutViewBase *view); QVector3D hit_point_with_scene(const QVector3D &line_dir); void refresh (); @@ -187,7 +187,7 @@ private: double m_scale_factor; double m_vscale_factor; QVector3D m_displacement; - lay::LayoutView *mp_view; + lay::LayoutViewBase *mp_view; db::DBox m_bbox; double m_zmin, m_zmax; bool m_zset; diff --git a/src/plugins/tools/xor/lay_plugin/layXORPlugin.cc b/src/plugins/tools/xor/lay_plugin/layXORPlugin.cc index 094f67beb..14864a9d9 100644 --- a/src/plugins/tools/xor/lay_plugin/layXORPlugin.cc +++ b/src/plugins/tools/xor/lay_plugin/layXORPlugin.cc @@ -26,6 +26,7 @@ #include "layDispatcher.h" #include "layPlugin.h" +#include "layLayoutView.h" namespace lay { @@ -34,7 +35,7 @@ class XORPlugin : public lay::Plugin { public: - XORPlugin (Plugin *parent, lay::LayoutViewBase *view) + XORPlugin (Plugin *parent, lay::LayoutView *view) : lay::Plugin (parent), mp_view (view) { mp_dialog = new lay::XORToolDialog (0); @@ -112,7 +113,9 @@ public: lay::Plugin *create_plugin (db::Manager *, lay::Dispatcher *root, lay::LayoutViewBase *view) const { - return new XORPlugin (root, view); + lay::LayoutView *lv = dynamic_cast (view); + tl_assert (lv != 0); + return new XORPlugin (root, lv); } }; diff --git a/src/plugins/tools/xor/lay_plugin/layXORToolDialog.cc b/src/plugins/tools/xor/lay_plugin/layXORToolDialog.cc index f5141f114..ff8c7888b 100644 --- a/src/plugins/tools/xor/lay_plugin/layXORToolDialog.cc +++ b/src/plugins/tools/xor/lay_plugin/layXORToolDialog.cc @@ -186,7 +186,7 @@ XORToolDialog::~XORToolDialog () } int -XORToolDialog::exec_dialog (lay::LayoutViewBase *view) +XORToolDialog::exec_dialog (lay::LayoutView *view) { mp_view = view; diff --git a/src/plugins/tools/xor/lay_plugin/layXORToolDialog.h b/src/plugins/tools/xor/lay_plugin/layXORToolDialog.h index a5b0d52be..adeb9fb1b 100644 --- a/src/plugins/tools/xor/lay_plugin/layXORToolDialog.h +++ b/src/plugins/tools/xor/lay_plugin/layXORToolDialog.h @@ -61,7 +61,7 @@ public: XORToolDialog (QWidget *parent); ~XORToolDialog (); - int exec_dialog (lay::LayoutViewBase *view); + int exec_dialog (lay::LayoutView *view); protected: void accept ();