From 8a21d9718ecb93106a8b0ef69ca29219eb93a34a Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 8 Sep 2019 01:11:19 +0200 Subject: [PATCH 1/4] First implementation --- src/lay/lay/layConfig.h | 1 + src/lay/lay/layMainConfigPages.cc | 1 + src/lay/lay/layMainWindow.cc | 35 ++++++ src/lay/lay/layMainWindow.h | 6 +- src/laybasic/laybasic/layBookmarkList.cc | 29 +++++ src/laybasic/laybasic/layBookmarkList.h | 7 ++ src/laybasic/laybasic/layBookmarksView.cc | 146 ++++++++++++++++++++++ src/laybasic/laybasic/layBookmarksView.h | 67 ++++++++++ src/laybasic/laybasic/layLayoutView.cc | 34 ++++- src/laybasic/laybasic/layLayoutView.h | 27 ++-- src/laybasic/laybasic/laybasic.pro | 6 +- 11 files changed, 345 insertions(+), 14 deletions(-) create mode 100644 src/laybasic/laybasic/layBookmarksView.cc create mode 100644 src/laybasic/laybasic/layBookmarksView.h diff --git a/src/lay/lay/layConfig.h b/src/lay/lay/layConfig.h index 2181893aa..59d7bed80 100644 --- a/src/lay/lay/layConfig.h +++ b/src/lay/lay/layConfig.h @@ -50,6 +50,7 @@ static const std::string cfg_navigator_show_images ("navigator-show-images"); static const std::string cfg_show_layer_toolbox ("show-layer-toolbox"); static const std::string cfg_show_hierarchy_panel ("show-hierarchy-panel"); static const std::string cfg_show_libraries_view ("show-libraries-view"); +static const std::string cfg_show_bookmarks_view ("show-bookmarks-view"); static const std::string cfg_show_layer_panel ("show-layer-panel"); static const std::string cfg_window_state ("window-state"); static const std::string cfg_layout_file_watcher_enabled ("layout-file-watcher-enabled"); diff --git a/src/lay/lay/layMainConfigPages.cc b/src/lay/lay/layMainConfigPages.cc index ceb7aabc0..d9e916450 100644 --- a/src/lay/lay/layMainConfigPages.cc +++ b/src/lay/lay/layMainConfigPages.cc @@ -69,6 +69,7 @@ public: options.push_back (std::pair (cfg_show_layer_toolbox, "true")); options.push_back (std::pair (cfg_show_hierarchy_panel, "true")); options.push_back (std::pair (cfg_show_libraries_view, "true")); + options.push_back (std::pair (cfg_show_bookmarks_view, "false")); options.push_back (std::pair (cfg_show_layer_panel, "true")); options.push_back (std::pair (cfg_layout_file_watcher_enabled, "true")); options.push_back (std::pair (cfg_window_state, "")); diff --git a/src/lay/lay/layMainWindow.cc b/src/lay/lay/layMainWindow.cc index 99695696c..33fcf8237 100644 --- a/src/lay/lay/layMainWindow.cc +++ b/src/lay/lay/layMainWindow.cc @@ -513,6 +513,13 @@ MainWindow::MainWindow (QApplication *app, lay::Plugin *plugin_parent, const cha connect (mp_libs_dock_widget, SIGNAL (visibilityChanged (bool)), this, SLOT (dock_widget_visibility_changed (bool))); m_libs_visible = true; + mp_bm_dock_widget = new QDockWidget (QObject::tr ("Bookmarks"), this); + mp_bm_dock_widget->setObjectName (QString::fromUtf8 ("bookmarks_dock_widget")); + mp_bm_stack = new ControlWidgetStack (mp_bm_dock_widget, "bookmarks_stack"); + mp_bm_dock_widget->setWidget (mp_bm_stack); + connect (mp_bm_dock_widget, SIGNAL (visibilityChanged (bool)), this, SLOT (dock_widget_visibility_changed (bool))); + m_bm_visible = true; + mp_view_stack = new ViewWidgetStack (mp_main_frame); mp_view_stack->setObjectName (QString::fromUtf8 ("view_stack")); vbl->addWidget (mp_view_stack); @@ -545,6 +552,7 @@ MainWindow::MainWindow (QApplication *app, lay::Plugin *plugin_parent, const cha addDockWidget(Qt::LeftDockWidgetArea, mp_navigator_dock_widget); addDockWidget(Qt::LeftDockWidgetArea, mp_hp_dock_widget); addDockWidget(Qt::LeftDockWidgetArea, mp_libs_dock_widget); + addDockWidget(Qt::RightDockWidgetArea, mp_bm_dock_widget); addDockWidget(Qt::RightDockWidgetArea, mp_lp_dock_widget); addDockWidget(Qt::RightDockWidgetArea, mp_layer_toolbox_dock_widget); @@ -865,6 +873,7 @@ MainWindow::init_menu () MenuLayoutEntry ("show_layer_toolbox", tl::to_string (QObject::tr ("Layer Toolbox")), std::make_pair (cfg_show_layer_toolbox, "?")), MenuLayoutEntry ("show_hierarchy_panel", tl::to_string (QObject::tr ("Cells")), std::make_pair (cfg_show_hierarchy_panel, "?")), MenuLayoutEntry ("show_libraries_view", tl::to_string (QObject::tr ("Libraries")), std::make_pair (cfg_show_libraries_view, "?")), + MenuLayoutEntry ("show_bookmarks_view", tl::to_string (QObject::tr ("Bookmarks")), std::make_pair (cfg_show_bookmarks_view, "?")), MenuLayoutEntry ("reset_window_state", tl::to_string (QObject::tr ("Restore Window")), SLOT (cm_reset_window_state ())), MenuLayoutEntry::separator ("selection_group"), MenuLayoutEntry ("transient_selection", tl::to_string (QObject::tr ("Highlight Object Under Mouse")), std::make_pair (cfg_sel_transient_mode, "?")), @@ -1092,6 +1101,8 @@ MainWindow::dock_widget_visibility_changed (bool /*visible*/) plugin_root ()->config_set (cfg_show_hierarchy_panel, tl::to_string (!mp_hp_dock_widget->isHidden ())); } else if (sender () == mp_libs_dock_widget) { plugin_root ()->config_set (cfg_show_libraries_view, tl::to_string (!mp_libs_dock_widget->isHidden ())); + } else if (sender () == mp_bm_dock_widget) { + plugin_root ()->config_set (cfg_show_bookmarks_view, tl::to_string (!mp_bm_dock_widget->isHidden ())); } else if (sender () == mp_navigator_dock_widget) { plugin_root ()->config_set (cfg_show_navigator, tl::to_string (!mp_navigator_dock_widget->isHidden ())); } else if (sender () == mp_layer_toolbox_dock_widget) { @@ -1257,6 +1268,7 @@ MainWindow::close_all () mp_lp_stack->removeWidget (mp_views.size ()); mp_hp_stack->removeWidget (mp_views.size ()); mp_libs_stack->removeWidget (mp_views.size ()); + mp_bm_stack->removeWidget (mp_views.size ()); mp_view_stack->removeWidget (mp_views.size ()); delete view; @@ -1716,6 +1728,17 @@ MainWindow::configure (const std::string &name, const std::string &value) return true; + } else if (name == cfg_show_bookmarks_view) { + + tl::from_string (value, m_bm_visible); + if (m_bm_visible) { + mp_bm_dock_widget->show (); + } else { + mp_bm_dock_widget->hide (); + } + + return true; + } else if (name == cfg_show_layer_panel) { tl::from_string (value, m_lp_visible); @@ -1829,6 +1852,7 @@ MainWindow::read_dock_widget_state () 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_libraries_view, tl::to_string (!mp_libs_dock_widget->isHidden ())); + plugin_root ()->config_set (cfg_show_bookmarks_view, tl::to_string (!mp_bm_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 ())); } @@ -1848,6 +1872,12 @@ MainWindow::update_dock_widget_state () mp_libs_dock_widget->hide (); } + if (m_bm_visible) { + mp_bm_dock_widget->show (); + } else { + mp_bm_dock_widget->hide (); + } + if (m_lp_visible) { mp_lp_dock_widget->show (); } else { @@ -3347,6 +3377,7 @@ MainWindow::select_view (int index) mp_hp_stack->raiseWidget (index); mp_lp_stack->raiseWidget (index); mp_libs_stack->raiseWidget (index); + mp_bm_stack->raiseWidget (index); mp_setup_form->setup (); } @@ -3766,6 +3797,7 @@ MainWindow::clone_current_view () mp_lp_stack->addWidget (view->layer_control_frame ()); mp_hp_stack->addWidget (view->hierarchy_control_frame ()); mp_libs_stack->addWidget (view->libraries_frame ()); + mp_bm_stack->addWidget (view->bookmarks_frame ()); bool f = m_disable_tab_selected; m_disable_tab_selected = true; @@ -4013,6 +4045,7 @@ MainWindow::close_view (int index) mp_lp_stack->removeWidget (index); mp_hp_stack->removeWidget (index); mp_libs_stack->removeWidget (index); + mp_bm_stack->removeWidget (index); view_closed_event (int (index)); @@ -4392,6 +4425,7 @@ MainWindow::create_view () mp_lp_stack->addWidget (mp_views.back ()->layer_control_frame ()); mp_hp_stack->addWidget (mp_views.back ()->hierarchy_control_frame ()); mp_libs_stack->addWidget (mp_views.back ()->libraries_frame ()); + mp_bm_stack->addWidget (mp_views.back ()->bookmarks_frame ()); bool f = m_disable_tab_selected; m_disable_tab_selected = true; @@ -4454,6 +4488,7 @@ MainWindow::create_or_load_layout (const std::string *filename, const db::LoadLa mp_lp_stack->addWidget (mp_views.back ()->layer_control_frame ()); mp_hp_stack->addWidget (mp_views.back ()->hierarchy_control_frame ()); mp_libs_stack->addWidget (mp_views.back ()->libraries_frame ()); + mp_bm_stack->addWidget (mp_views.back ()->bookmarks_frame ()); bool f = m_disable_tab_selected; m_disable_tab_selected = true; diff --git a/src/lay/lay/layMainWindow.h b/src/lay/lay/layMainWindow.h index dc79128c4..d2269534f 100644 --- a/src/lay/lay/layMainWindow.h +++ b/src/lay/lay/layMainWindow.h @@ -875,9 +875,9 @@ private: QToolBar *mp_tool_bar; QDockWidget *mp_navigator_dock_widget; lay::Navigator *mp_navigator; - QDockWidget *mp_hp_dock_widget, *mp_lp_dock_widget, *mp_libs_dock_widget; - ControlWidgetStack *mp_hp_stack, *mp_lp_stack, *mp_libs_stack; - bool m_hp_visible, m_lp_visible, m_libs_visible, m_navigator_visible, m_layer_toolbox_visible; + QDockWidget *mp_hp_dock_widget, *mp_lp_dock_widget, *mp_libs_dock_widget, *mp_bm_dock_widget; + ControlWidgetStack *mp_hp_stack, *mp_lp_stack, *mp_libs_stack, *mp_bm_stack; + bool m_hp_visible, m_lp_visible, m_libs_visible, m_bm_visible, m_navigator_visible, m_layer_toolbox_visible; QDockWidget *mp_layer_toolbox_dock_widget; lay::LayerToolbox *mp_layer_toolbox; ViewWidgetStack *mp_view_stack; diff --git a/src/laybasic/laybasic/layBookmarkList.cc b/src/laybasic/laybasic/layBookmarkList.cc index a5e21817d..764dc28fc 100644 --- a/src/laybasic/laybasic/layBookmarkList.cc +++ b/src/laybasic/laybasic/layBookmarkList.cc @@ -25,6 +25,8 @@ #include "tlXMLParser.h" #include +#include +#include namespace lay { @@ -86,6 +88,33 @@ BookmarkList::save (const std::string &fn) const tl::log << "Saved bookmarks to " << fn; } +std::string +BookmarkList::propose_new_bookmark_name () const +{ + int n = 0; + + for (const_iterator b = begin (); b != end (); ++b) { + + const std::string &name = b->name (); + if (! name.empty ()) { + + const char *cp = name.c_str () + name.size (); + while (cp != name.c_str ()) { + if (! isdigit (cp [-1])) { + break; + } + --cp; + } + + int nn = atoi (cp); + n = std::max (nn, n); + + } + + } + + return "B" + tl::to_string (n + 1); +} } diff --git a/src/laybasic/laybasic/layBookmarkList.h b/src/laybasic/laybasic/layBookmarkList.h index 6d9051642..682abfb45 100644 --- a/src/laybasic/laybasic/layBookmarkList.h +++ b/src/laybasic/laybasic/layBookmarkList.h @@ -27,6 +27,7 @@ #include "laybasicCommon.h" #include "layDisplayState.h" +#include "tlObject.h" #include #include @@ -89,6 +90,7 @@ public: * @brief The list of bookmarks */ class LAYBASIC_PUBLIC BookmarkList + : public tl::Object { public: typedef std::vector bookmark_list_type; @@ -182,6 +184,11 @@ public: return m_list [index]; } + /** + * @brief Propose a new bookmark name + */ + std::string propose_new_bookmark_name () const; + /** * @brief Save the list */ diff --git a/src/laybasic/laybasic/layBookmarksView.cc b/src/laybasic/laybasic/layBookmarksView.cc new file mode 100644 index 000000000..2314fc659 --- /dev/null +++ b/src/laybasic/laybasic/layBookmarksView.cc @@ -0,0 +1,146 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2019 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#include "layBookmarksView.h" +#include "layLayoutView.h" + +#include + +namespace lay +{ + +// -------------------------------------------------------------------------------------------- + +class BookmarkListModel + : public QAbstractItemModel +{ +public: + BookmarkListModel (const lay::BookmarkList *bookmarks) + : mp_bookmarks (bookmarks) + { + // .. nothing yet .. + } + + int rowCount (const QModelIndex &index) const + { + return index.isValid () ? 0 : int (mp_bookmarks->size ()); + } + + int columnCount (const QModelIndex &) const + { + return 1; + } + + QVariant data (const QModelIndex &index, int role) const + { + if (role == Qt::DisplayRole && index.row () >= 0 && index.row () < int (mp_bookmarks->size ())) { + return tl::to_qstring (mp_bookmarks->name (size_t (index.row ()))); + } + + return QVariant (); + } + + QModelIndex index (int row, int column, const QModelIndex &parent) const + { + if (parent.isValid ()) { + return QModelIndex (); + } else { + return createIndex (row, column, 0); + } + } + + QModelIndex parent(const QModelIndex &) const + { + return QModelIndex (); + } + + void refresh () + { + dataChanged (createIndex (0, 0, 0), createIndex (rowCount (QModelIndex ()), 1, 0)); + } + +private: + const lay::BookmarkList *mp_bookmarks; +}; + +// -------------------------------------------------------------------------------------------- + +BookmarksView::BookmarksView (LayoutView *view, QWidget *parent, const char *name) + : QFrame (parent) +{ + setObjectName (QString::fromUtf8 (name)); + + mp_view = view; + + QVBoxLayout *layout = new QVBoxLayout (); + layout->setMargin (0); + setLayout (layout); + + mp_bookmarks = new QListView (this); + layout->addWidget (mp_bookmarks); + + mp_bookmarks->setModel (new BookmarkListModel (&view->bookmarks ())); + + connect (mp_bookmarks, SIGNAL (doubleClicked (const QModelIndex &)), this, SLOT (bookmark_triggered (const QModelIndex &))); +} + +BookmarksView::~BookmarksView () +{ + // .. nothing yet .. +} + +void +BookmarksView::set_background_color (QColor c) +{ + QPalette pl (mp_bookmarks->palette ()); + pl.setColor (QPalette::Base, c); + mp_bookmarks->setPalette (pl); +} + +void +BookmarksView::set_text_color (QColor c) +{ + QPalette pl (mp_bookmarks->palette ()); + pl.setColor (QPalette::Text, c); + mp_bookmarks->setPalette (pl); +} + +void +BookmarksView::refresh () +{ + BookmarkListModel *model = dynamic_cast (mp_bookmarks->model ()); + if (model) { + model->refresh (); + } +} + +void +BookmarksView::bookmark_triggered (const QModelIndex &index) +{ + if (index.row () >= 0 && index.row () < int (mp_view->bookmarks ().size ())) { + mp_view->goto_view (mp_view->bookmarks ().state (index.row ())); + } +} + +} + diff --git a/src/laybasic/laybasic/layBookmarksView.h b/src/laybasic/laybasic/layBookmarksView.h new file mode 100644 index 000000000..db3e72010 --- /dev/null +++ b/src/laybasic/laybasic/layBookmarksView.h @@ -0,0 +1,67 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2019 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#ifndef HDR_layBookmarksView +#define HDR_layBookmarksView + +#include "laybasicCommon.h" + +#include "layBookmarkList.h" + +#include +#include + +namespace lay +{ + +class LayoutView; + +/** + * @brief A widget to display a bookmark list + */ +class LAYBASIC_PUBLIC BookmarksView + : public QFrame +{ +Q_OBJECT + +public: + BookmarksView (LayoutView *view, QWidget *parent, const char *name); + ~BookmarksView (); + + void set_background_color (QColor c); + void set_text_color (QColor c); + + void refresh (); + +public slots: + void bookmark_triggered (const QModelIndex &index); + +public: + LayoutView *mp_view; + QListView *mp_bookmarks; +}; + +} // namespace lay + +#endif + diff --git a/src/laybasic/laybasic/layLayoutView.cc b/src/laybasic/laybasic/layLayoutView.cc index 31e7709a8..ec54c3702 100644 --- a/src/laybasic/laybasic/layLayoutView.cc +++ b/src/laybasic/laybasic/layLayoutView.cc @@ -68,6 +68,7 @@ #include "layParsedLayerSource.h" #include "layBookmarkManagementForm.h" #include "layNetlistBrowserDialog.h" +#include "layBookmarksView.h" #include "dbLayout.h" #include "dbLayoutUtils.h" #include "dbRecursiveShapeIterator.h" @@ -359,7 +360,9 @@ LayoutView::init (db::Manager *mgr, lay::PluginRoot *root, QWidget * /*parent*/) mp_hierarchy_panel = 0; mp_hierarchy_frame = 0; mp_libraries_view = 0; + mp_bookmarks_view = 0; mp_libraries_frame = 0; + mp_bookmarks_frame = 0; mp_min_hier_spbx = 0; mp_max_hier_spbx = 0; m_from_level = 0; @@ -506,6 +509,20 @@ LayoutView::init (db::Manager *mgr, lay::PluginRoot *root, QWidget * /*parent*/) } + if ((m_options & LV_NoBookmarksView) == 0 && (m_options & LV_Naked) == 0) { + + QFrame *bookmarks_frame = new QFrame (0); + bookmarks_frame->setObjectName (QString::fromUtf8 ("bookmarks_frame")); + mp_bookmarks_frame = bookmarks_frame; + QVBoxLayout *left_frame_ly = new QVBoxLayout (bookmarks_frame); + left_frame_ly->setMargin (0); + left_frame_ly->setSpacing (0); + + mp_bookmarks_view = new lay::BookmarksView (this, bookmarks_frame, "bookmarks"); + left_frame_ly->addWidget (mp_bookmarks_view, 1 /*stretch*/); + + } + if ((m_options & LV_NoLibrariesView) == 0 && (m_options & LV_Naked) == 0) { QFrame *libraries_frame = new QFrame (0); @@ -654,6 +671,12 @@ LayoutView::~LayoutView () } mp_libraries_frame = 0; mp_libraries_view = 0; + + if (mp_bookmarks_frame) { + delete mp_bookmarks_frame; + } + mp_bookmarks_frame = 0; + mp_bookmarks_view = 0; } void LayoutView::hideEvent (QHideEvent *) @@ -3771,10 +3794,12 @@ LayoutView::cancel () void LayoutView::bookmark_current_view () { + QString proposed_name = tl::to_qstring (m_bookmarks.propose_new_bookmark_name ()); + while (true) { bool ok = false; QString text = QInputDialog::getText (this, QObject::tr ("Enter Bookmark Name"), QObject::tr ("Bookmark name"), - QLineEdit::Normal, QString::null, &ok); + QLineEdit::Normal, proposed_name, &ok); if (! ok) { break; } else if (text.isEmpty ()) { @@ -3799,6 +3824,7 @@ void LayoutView::bookmarks (const BookmarkList &b) { m_bookmarks = b; + mp_bookmarks_view->refresh (); emit menu_needs_update (); } @@ -3807,6 +3833,7 @@ LayoutView::bookmark_view (const std::string &name) { DisplayState state (box (), get_min_hier_levels (), get_max_hier_levels (), m_cellviews); m_bookmarks.add (name, state); + mp_bookmarks_view->refresh (); emit menu_needs_update (); } @@ -4526,6 +4553,11 @@ LayoutView::background_color (QColor c) mp_libraries_view->set_text_color (contrast); } + if (mp_bookmarks_view) { + mp_bookmarks_view->set_background_color (c); + mp_bookmarks_view->set_text_color (contrast); + } + if (mp_selection_service) { mp_selection_service->set_colors (c, contrast); } diff --git a/src/laybasic/laybasic/layLayoutView.h b/src/laybasic/laybasic/layLayoutView.h index 6d9da0bde..5e92104d4 100644 --- a/src/laybasic/laybasic/layLayoutView.h +++ b/src/laybasic/laybasic/layLayoutView.h @@ -71,6 +71,7 @@ class AbstractMenu; class LayerControlPanel; class HierarchyControlPanel; class LibrariesView; +class BookmarksView; class MouseTracker; class ZoomService; class SelectionService; @@ -170,13 +171,14 @@ public: LV_NoLayers = 1, LV_NoHierarchyPanel = 2, LV_NoLibrariesView = 4, - LV_Naked = 8, - LV_NoZoom = 16, - LV_NoGrid = 32, - LV_NoMove = 64, - LV_NoTracker = 128, - LV_NoSelection = 256, - LV_NoPlugins = 512, + LV_NoBookmarksView = 8, + LV_Naked = 16, + LV_NoZoom = 32, + LV_NoGrid = 64, + LV_NoMove = 128, + LV_NoTracker = 256, + LV_NoSelection = 512, + LV_NoPlugins = 1024, LV_NoServices = LV_NoMove + LV_NoTracker + LV_NoSelection + LV_NoPlugins }; @@ -246,6 +248,14 @@ public: return mp_libraries_frame; } + /** + * @brief Gets the container with the bookmarks view + */ + QWidget *bookmarks_frame () + { + return mp_bookmarks_frame; + } + /** * @brief Pastes from clipboard * @@ -2748,7 +2758,8 @@ private: lay::LayerControlPanel *mp_control_panel; lay::HierarchyControlPanel *mp_hierarchy_panel; lay::LibrariesView *mp_libraries_view; - QWidget *mp_control_frame, *mp_hierarchy_frame, *mp_libraries_frame; + lay::BookmarksView *mp_bookmarks_view; + QWidget *mp_control_frame, *mp_hierarchy_frame, *mp_libraries_frame, *mp_bookmarks_frame; QSpinBox *mp_min_hier_spbx; QSpinBox *mp_max_hier_spbx; std::list m_cellviews; diff --git a/src/laybasic/laybasic/laybasic.pro b/src/laybasic/laybasic/laybasic.pro index 443343ce1..d74ab99fa 100644 --- a/src/laybasic/laybasic/laybasic.pro +++ b/src/laybasic/laybasic/laybasic.pro @@ -176,7 +176,8 @@ SOURCES = \ layIndexedNetlistModel.cc \ layNetlistCrossReferenceModel.cc \ layNetlistBrowserTreeModel.cc \ - layLibrariesView.cc + layLibrariesView.cc \ + layBookmarksView.cc HEADERS = \ gtf.h \ @@ -273,7 +274,8 @@ HEADERS = \ layIndexedNetlistModel.h \ layNetlistCrossReferenceModel.h \ layNetlistBrowserTreeModel.h \ - layLibrariesView.h + layLibrariesView.h \ + layBookmarksView.h INCLUDEPATH += $$TL_INC $$GSI_INC $$DB_INC $$RDB_INC $$LYM_INC DEPENDPATH += $$TL_INC $$GSI_INC $$DB_INC $$RDB_INC $$LYM_INC From d2d22eafb5cc68d0f69e0b429609cecd80ee1554 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 8 Sep 2019 01:22:34 +0200 Subject: [PATCH 2/4] Implementation of #343 (dockable bookmark window) Here is the proposal: - There is a new panel similar to the layer list showing the bookmarks. It can be shown using View/Bookmarks. Initially this panel is hidden. - Double-clicking on an item in this bookmark list will navigate to the bookmark. - Context menu entries of this panel are: manage, load and save bookmarks (like in main menu) In addition, "bookmark this view" now proposes a bookmark name make of "B" and a unique number. --- src/laybasic/laybasic/layBookmarksView.cc | 34 +++++++++++++++++++++++ src/laybasic/laybasic/layBookmarksView.h | 6 +++- src/laybasic/laybasic/layLayoutView.cc | 1 + 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/laybasic/laybasic/layBookmarksView.cc b/src/laybasic/laybasic/layBookmarksView.cc index 2314fc659..6fc80c82d 100644 --- a/src/laybasic/laybasic/layBookmarksView.cc +++ b/src/laybasic/laybasic/layBookmarksView.cc @@ -23,6 +23,8 @@ #include "layBookmarksView.h" #include "layLayoutView.h" +#include "layAbstractMenu.h" +#include "layAbstractMenuProvider.h" #include @@ -100,7 +102,9 @@ BookmarksView::BookmarksView (LayoutView *view, QWidget *parent, const char *nam layout->addWidget (mp_bookmarks); mp_bookmarks->setModel (new BookmarkListModel (&view->bookmarks ())); + mp_bookmarks->setContextMenuPolicy (Qt::CustomContextMenu); + connect (mp_bookmarks, SIGNAL (customContextMenuRequested (const QPoint &)), this, SLOT (context_menu (const QPoint &))); connect (mp_bookmarks, SIGNAL (doubleClicked (const QModelIndex &)), this, SLOT (bookmark_triggered (const QModelIndex &))); } @@ -109,6 +113,24 @@ BookmarksView::~BookmarksView () // .. nothing yet .. } +void +BookmarksView::init_menu (lay::AbstractMenu &menu) +{ + MenuLayoutEntry context_menu [] = { + MenuLayoutEntry ("manage_bookmarks", tl::to_string (QObject::tr ("Manage Bookmarks")), SLOT (cm_manage_bookmarks ())), + MenuLayoutEntry ("load_bookmarks", tl::to_string (QObject::tr ("Load Bookmarks")), SLOT (cm_load_bookmarks ())), + MenuLayoutEntry ("save_bookmarks", tl::to_string (QObject::tr ("Save Bookmarks")), SLOT (cm_save_bookmarks ())), + MenuLayoutEntry::last () + }; + + MenuLayoutEntry main_menu [] = { + MenuLayoutEntry ("@bookmarks_context_menu", "", context_menu), + MenuLayoutEntry::last () + }; + + menu.init (main_menu); +} + void BookmarksView::set_background_color (QColor c) { @@ -134,6 +156,18 @@ BookmarksView::refresh () } } +void +BookmarksView::context_menu (const QPoint &p) +{ + tl_assert (lay::AbstractMenuProvider::instance () != 0); + + QListView *bm_list = dynamic_cast (sender ()); + if (bm_list) { + QMenu *ctx_menu = lay::AbstractMenuProvider::instance ()->menu ()->detached_menu ("bookmarks_context_menu"); + ctx_menu->exec (bm_list->mapToGlobal (p)); + } +} + void BookmarksView::bookmark_triggered (const QModelIndex &index) { diff --git a/src/laybasic/laybasic/layBookmarksView.h b/src/laybasic/laybasic/layBookmarksView.h index db3e72010..4731c2c77 100644 --- a/src/laybasic/laybasic/layBookmarksView.h +++ b/src/laybasic/laybasic/layBookmarksView.h @@ -35,6 +35,7 @@ namespace lay { class LayoutView; +class AbstractMenu; /** * @brief A widget to display a bookmark list @@ -53,10 +54,13 @@ public: void refresh (); + static void init_menu (lay::AbstractMenu &menu); + public slots: void bookmark_triggered (const QModelIndex &index); + void context_menu (const QPoint &p); -public: +private: LayoutView *mp_view; QListView *mp_bookmarks; }; diff --git a/src/laybasic/laybasic/layLayoutView.cc b/src/laybasic/laybasic/layLayoutView.cc index ec54c3702..3619a8973 100644 --- a/src/laybasic/laybasic/layLayoutView.cc +++ b/src/laybasic/laybasic/layLayoutView.cc @@ -840,6 +840,7 @@ LayoutView::init_menu (lay::AbstractMenu &menu) lay::LayerControlPanel::init_menu (menu); lay::HierarchyControlPanel::init_menu (menu); lay::LibrariesView::init_menu (menu); + lay::BookmarksView::init_menu (menu); } void From d9d3b3cafee7d01748e355009d34369b538c1de2 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 8 Sep 2019 02:23:38 +0200 Subject: [PATCH 3/4] Some enhancements to #343 fix - "follow selection": allows navigating between the bookmarks with the cursor keys - "manage bookmarks" now starts with the selected bookmarks also selected. --- .../laybasic/layBookmarkManagementForm.cc | 14 ++++++-- .../laybasic/layBookmarkManagementForm.h | 5 ++- src/laybasic/laybasic/layBookmarksView.cc | 33 ++++++++++++++++++- src/laybasic/laybasic/layBookmarksView.h | 7 ++++ src/laybasic/laybasic/layLayoutView.cc | 16 ++++++++- src/laybasic/laybasic/laybasicConfig.h | 2 ++ 6 files changed, 72 insertions(+), 5 deletions(-) diff --git a/src/laybasic/laybasic/layBookmarkManagementForm.cc b/src/laybasic/laybasic/layBookmarkManagementForm.cc index c1dace6e2..c7506ad5d 100644 --- a/src/laybasic/laybasic/layBookmarkManagementForm.cc +++ b/src/laybasic/laybasic/layBookmarkManagementForm.cc @@ -53,7 +53,7 @@ private: // ------------------------------------------------------------ -BookmarkManagementForm::BookmarkManagementForm (QWidget *parent, const char *name, const lay::BookmarkList &bookmarks) +BookmarkManagementForm::BookmarkManagementForm (QWidget *parent, const char *name, const lay::BookmarkList &bookmarks, const std::set &selected) : QDialog (parent), Ui::BookmarkManagementForm (), m_bookmarks (bookmarks) { @@ -61,8 +61,18 @@ BookmarkManagementForm::BookmarkManagementForm (QWidget *parent, const char *nam Ui::BookmarkManagementForm::setupUi (this); + QListWidgetItem *first_item = 0; + for (size_t i = 0; i < m_bookmarks.size (); ++i) { - new BookmarkListLVI (bookmark_list, m_bookmarks.name (i), m_bookmarks.state (i)); + QListWidgetItem *item = new BookmarkListLVI (bookmark_list, m_bookmarks.name (i), m_bookmarks.state (i)); + item->setSelected (selected.find (i) != selected.end ()); + if (! first_item && item->isSelected ()) { + first_item = item; + } + } + + if (first_item) { + bookmark_list->scrollToItem (first_item); } connect (delete_button, SIGNAL (clicked ()), this, SLOT (delete_pressed ())); diff --git a/src/laybasic/laybasic/layBookmarkManagementForm.h b/src/laybasic/laybasic/layBookmarkManagementForm.h index 093697a82..b1428a108 100644 --- a/src/laybasic/laybasic/layBookmarkManagementForm.h +++ b/src/laybasic/laybasic/layBookmarkManagementForm.h @@ -26,8 +26,11 @@ #include // required during the dependency pass #include "ui_BookmarkManagementForm.h" + #include "layLayoutView.h" +#include + namespace lay { @@ -37,7 +40,7 @@ class BookmarkManagementForm Q_OBJECT public: - BookmarkManagementForm (QWidget *parent, const char *name, const lay::BookmarkList &bookmarks); + BookmarkManagementForm (QWidget *parent, const char *name, const lay::BookmarkList &bookmarks, const std::set &selected); /** * @brief Obtain the bookmark list diff --git a/src/laybasic/laybasic/layBookmarksView.cc b/src/laybasic/laybasic/layBookmarksView.cc index 6fc80c82d..25a91b3be 100644 --- a/src/laybasic/laybasic/layBookmarksView.cc +++ b/src/laybasic/laybasic/layBookmarksView.cc @@ -26,6 +26,8 @@ #include "layAbstractMenu.h" #include "layAbstractMenuProvider.h" +#include "laybasicConfig.h" + #include namespace lay @@ -88,7 +90,7 @@ private: // -------------------------------------------------------------------------------------------- BookmarksView::BookmarksView (LayoutView *view, QWidget *parent, const char *name) - : QFrame (parent) + : QFrame (parent), m_follow_selection (false) { setObjectName (QString::fromUtf8 (name)); @@ -102,10 +104,12 @@ BookmarksView::BookmarksView (LayoutView *view, QWidget *parent, const char *nam layout->addWidget (mp_bookmarks); mp_bookmarks->setModel (new BookmarkListModel (&view->bookmarks ())); + mp_bookmarks->setSelectionMode (QAbstractItemView::ExtendedSelection); mp_bookmarks->setContextMenuPolicy (Qt::CustomContextMenu); connect (mp_bookmarks, SIGNAL (customContextMenuRequested (const QPoint &)), this, SLOT (context_menu (const QPoint &))); connect (mp_bookmarks, SIGNAL (doubleClicked (const QModelIndex &)), this, SLOT (bookmark_triggered (const QModelIndex &))); + connect (mp_bookmarks->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (current_bookmark_changed (const QModelIndex &))); } BookmarksView::~BookmarksView () @@ -113,10 +117,29 @@ BookmarksView::~BookmarksView () // .. nothing yet .. } +std::set +BookmarksView::selected_bookmarks () +{ + QModelIndexList sel = mp_bookmarks->selectionModel ()->selectedIndexes (); + std::set res; + for (QModelIndexList::const_iterator i = sel.begin (); i != sel.end (); ++i) { + res.insert (int (i->row ())); + } + return res; +} + +void +BookmarksView::follow_selection (bool f) +{ + m_follow_selection = f; +} + void BookmarksView::init_menu (lay::AbstractMenu &menu) { MenuLayoutEntry context_menu [] = { + MenuLayoutEntry ("follow_selection", tl::to_string (QObject::tr ("Follow Selection")), std::make_pair (cfg_bookmarks_follow_selection, "?")), + MenuLayoutEntry::separator ("ops_group"), MenuLayoutEntry ("manage_bookmarks", tl::to_string (QObject::tr ("Manage Bookmarks")), SLOT (cm_manage_bookmarks ())), MenuLayoutEntry ("load_bookmarks", tl::to_string (QObject::tr ("Load Bookmarks")), SLOT (cm_load_bookmarks ())), MenuLayoutEntry ("save_bookmarks", tl::to_string (QObject::tr ("Save Bookmarks")), SLOT (cm_save_bookmarks ())), @@ -168,6 +191,14 @@ BookmarksView::context_menu (const QPoint &p) } } +void +BookmarksView::current_bookmark_changed (const QModelIndex &index) +{ + if (m_follow_selection) { + bookmark_triggered (index); + } +} + void BookmarksView::bookmark_triggered (const QModelIndex &index) { diff --git a/src/laybasic/laybasic/layBookmarksView.h b/src/laybasic/laybasic/layBookmarksView.h index 4731c2c77..0c2ae3d09 100644 --- a/src/laybasic/laybasic/layBookmarksView.h +++ b/src/laybasic/laybasic/layBookmarksView.h @@ -31,6 +31,8 @@ #include #include +#include + namespace lay { @@ -51,6 +53,9 @@ public: void set_background_color (QColor c); void set_text_color (QColor c); + void follow_selection (bool f); + + std::set selected_bookmarks (); void refresh (); @@ -58,11 +63,13 @@ public: public slots: void bookmark_triggered (const QModelIndex &index); + void current_bookmark_changed (const QModelIndex &index); void context_menu (const QPoint &p); private: LayoutView *mp_view; QListView *mp_bookmarks; + bool m_follow_selection; }; } // namespace lay diff --git a/src/laybasic/laybasic/layLayoutView.cc b/src/laybasic/laybasic/layLayoutView.cc index 3619a8973..d669f4da0 100644 --- a/src/laybasic/laybasic/layLayoutView.cc +++ b/src/laybasic/laybasic/layLayoutView.cc @@ -1011,6 +1011,15 @@ LayoutView::configure (const std::string &name, const std::string &value) } return true; + } else if (name == cfg_bookmarks_follow_selection) { + + bool f; + tl::from_string (value, f); + if (mp_bookmarks_view) { + mp_bookmarks_view->follow_selection (f); + } + return true; + } else if (name == cfg_current_lib_view) { if (mp_libraries_view) { @@ -3815,7 +3824,12 @@ LayoutView::bookmark_current_view () void LayoutView::manage_bookmarks () { - BookmarkManagementForm dialog (this, "bookmark_form", bookmarks ()); + std::set selected_bm; + if (mp_bookmarks_frame->isVisible ()) { + selected_bm = mp_bookmarks_view->selected_bookmarks (); + } + + BookmarkManagementForm dialog (this, "bookmark_form", bookmarks (), selected_bm); if (dialog.exec ()) { bookmarks (dialog.bookmarks ()); } diff --git a/src/laybasic/laybasic/laybasicConfig.h b/src/laybasic/laybasic/laybasicConfig.h index 16c420ab3..933052717 100644 --- a/src/laybasic/laybasic/laybasicConfig.h +++ b/src/laybasic/laybasic/laybasicConfig.h @@ -130,6 +130,8 @@ static const std::string cfg_cell_list_sorting ("cell-list-sorting"); static const std::string cfg_split_lib_views ("split-lib-views"); static const std::string cfg_current_lib_view ("current-lib-view"); +static const std::string cfg_bookmarks_follow_selection ("bookmarks-follow-selection"); + static const std::string cfg_pan_distance ("pan-distance"); static const std::string cfg_paste_display_mode ("paste-display-mode"); From a7b3f1dfcd48890aa38dba3f698197f06ae94792 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 8 Sep 2019 20:01:22 +0200 Subject: [PATCH 4/4] Added documentation for dockable bookmarks feature --- src/lay/lay/doc/manual/bookmarks.xml | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/lay/lay/doc/manual/bookmarks.xml b/src/lay/lay/doc/manual/bookmarks.xml index 7428fa2d5..7c5d5833c 100644 --- a/src/lay/lay/doc/manual/bookmarks.xml +++ b/src/lay/lay/doc/manual/bookmarks.xml @@ -17,4 +17,33 @@ Bookmarks" and "Save Bookmarks" functions from the "Bookmarks" menu.

+

+ The bookmark list is available as a dockable tool window as well: + check the "View/Bookmark List" option to enable this dock window. + The bookmark list by default is shown at the bottom right side of + the layout view. +

+ +

Dockable Bookmark List

+ +

+ To navigate to a bookmark from the dockable bookmark list, double-click + the entry. + From the context menu (right mouse click) you can select these functions: +

+ +
    +
  • Follow Selection: if this option is checked, the selected + bookmark will immediately change the view accordingly. With this + option, you can browse the bookmark list with the arrow keys + while the view updates automatically. +
  • +
  • Manage bookmarks: opens the bookmark management dialog (same + as from the "Bookmarks" menu). +
  • +
  • Load bookmarks and Save bookmarks: loads or saves the + bookmarks to a file (same function as from the "Bookmarks" menu). +
  • +
+