From 1107e5bacc5587409742dd4b333432b1a20c64b9 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Fri, 23 Sep 2022 22:00:33 +0200 Subject: [PATCH 1/6] Added doc and icon to dependencies. --- src/klayout.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/klayout.pro b/src/klayout.pro index 897d5b516..8c29c0b11 100644 --- a/src/klayout.pro +++ b/src/klayout.pro @@ -112,7 +112,7 @@ equals(HAVE_RUBY, "1") { plugins.depends += lay - klayout_main.depends += plugins $$MAIN_DEPENDS + klayout_main.depends += doc icons plugins $$MAIN_DEPENDS } else { From c8889504e6605501f3dd4c8296a773d782754716 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 22 Sep 2022 21:13:23 +0200 Subject: [PATCH 2/6] Enabling high-DPI scaling in QApplication --- src/klayout_main/klayout_main/klayout.cc | 1 + src/lay/lay/layApplication.cc | 20 ++++++++++++++------ src/lay/lay/layApplication.h | 7 +++++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/klayout_main/klayout_main/klayout.cc b/src/klayout_main/klayout_main/klayout.cc index 40cca527b..49ca8aa86 100644 --- a/src/klayout_main/klayout_main/klayout.cc +++ b/src/klayout_main/klayout_main/klayout.cc @@ -302,6 +302,7 @@ klayout_main_cont (int &argc, char **argv) if (non_ui_mode) { app.reset (new lay::NonGuiApplication (argc, argv)); } else { + lay::GuiApplication::initialize (); app.reset (new lay::GuiApplication (argc, argv)); lay::enable_signal_handler_gui (true); } diff --git a/src/lay/lay/layApplication.cc b/src/lay/lay/layApplication.cc index fe517860e..5aee10b73 100644 --- a/src/lay/lay/layApplication.cc +++ b/src/lay/lay/layApplication.cc @@ -1434,12 +1434,6 @@ GuiApplication::GuiApplication (int &argc, char **argv) setStyle (new lay::BackgroundAwareTreeStyle (0)); setWindowIcon (QIcon (QString::fromUtf8 (":/logo.png"))); -#if QT_VERSION >= 0x040500 - setAttribute (Qt::AA_DontShowIconsInMenus, false); -#endif -#if QT_VERSION >= 0x050000 - setAttribute (Qt::AA_UseHighDpiPixmaps, true); -#endif } GuiApplication::~GuiApplication () @@ -1453,6 +1447,20 @@ GuiApplication::~GuiApplication () shutdown (); } +void +GuiApplication::initialize () +{ +#if QT_VERSION >= 0x040500 + QCoreApplication::setAttribute (Qt::AA_DontShowIconsInMenus, false); +#endif +#if QT_VERSION >= 0x050000 + QCoreApplication::setAttribute (Qt::AA_UseHighDpiPixmaps, true); +#endif +#if QT_VERSION >= 0x050600 + QCoreApplication::setAttribute (Qt::AA_EnableHighDpiScaling, true); +#endif +} + bool GuiApplication::notify (QObject *receiver, QEvent *e) { diff --git a/src/lay/lay/layApplication.h b/src/lay/lay/layApplication.h index e5794cefd..6b42e1318 100644 --- a/src/lay/lay/layApplication.h +++ b/src/lay/lay/layApplication.h @@ -390,6 +390,13 @@ public: QApplication *qapp_gui () { return this; } + /** + * @brief Does some pre-initialization + * + * Must be called before the GuiApplication object is created + */ + static void initialize (); + /** * @brief Reimplementation of notify from QApplication */ From ab9fe57ec3363554c435163db7771ab00029e7a7 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Fri, 23 Sep 2022 23:31:23 +0200 Subject: [PATCH 3/6] Modified the original solution somewhat 1. Provide a menu icon in SVG (24x24px and 16x16px for later use elsewhere) 2. Proposing a solution based on QTabBar again - Rationale: the QTabWidget is intended as container for widgets but in our case it is not (the ViewStack will handle this). I am worried about the implications, specifically as there are widgets added during insertTab which are also added to the view stack container. Apart from that the visual effect is somewhat ugly. - The menu button is not part of the EnhancedTabBar as it does not provide a corner widget. But it is available as "visually detached" sub-widget and the main window can build a HBoxLayout for it. 3. Correspondingly renaming EnhancedTabWidget to EnhancedTabBar 4. I ported the "close all" and "close all except" feature from the macro editor's tabs to the view tab bar as I think this fits nicely into this enhancement. --- src/icons/icons.qrc | 4 + src/icons/images/menu_16px.png | Bin 0 -> 189 bytes src/icons/images/menu_16px@2x.png | Bin 0 -> 244 bytes src/icons/images/menu_24px.png | Bin 0 -> 203 bytes src/icons/images/menu_24px@2x.png | Bin 0 -> 228 bytes src/icons/svg/menu_16px.svg | 166 ++++++++++++++++ src/icons/svg/menu_24px.svg | 187 ++++++++++++++++++ src/lay/lay/lay.pro | 4 +- ...ancedTabWidget.cc => layEnhancedTabBar.cc} | 44 ++--- ...nhancedTabWidget.h => layEnhancedTabBar.h} | 12 +- src/lay/lay/layMainWindow.cc | 99 +++++++--- src/lay/lay/layMainWindow.h | 7 +- 12 files changed, 470 insertions(+), 53 deletions(-) create mode 100644 src/icons/images/menu_16px.png create mode 100644 src/icons/images/menu_16px@2x.png create mode 100644 src/icons/images/menu_24px.png create mode 100644 src/icons/images/menu_24px@2x.png create mode 100644 src/icons/svg/menu_16px.svg create mode 100644 src/icons/svg/menu_24px.svg rename src/lay/lay/{layEnhancedTabWidget.cc => layEnhancedTabBar.cc} (65%) rename src/lay/lay/{layEnhancedTabWidget.h => layEnhancedTabBar.h} (87%) diff --git a/src/icons/icons.qrc b/src/icons/icons.qrc index 1ff153d1a..e082993eb 100644 --- a/src/icons/icons.qrc +++ b/src/icons/icons.qrc @@ -125,6 +125,10 @@ images/m45_24px@2x.png images/m90_24px.png images/m90_24px@2x.png + images/menu_16px.png + images/menu_16px@2x.png + images/menu_24px.png + images/menu_24px@2x.png images/move_24px.png images/move_24px@2x.png images/move_simple_16px.png diff --git a/src/icons/images/menu_16px.png b/src/icons/images/menu_16px.png new file mode 100644 index 0000000000000000000000000000000000000000..3030686933d43cd46b6a8a2b3a30be99bb0db47a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F5he4R}c>anMprB-l zYeY$Kep*R+Vo@qXd3m{BW?pu2a$-TMUVc&f>~}U&Kt*1jE{-7!!<&nWYW`buU4W)Cc)I$ztaD0e0szZMLID5( literal 0 HcmV?d00001 diff --git a/src/icons/images/menu_16px@2x.png b/src/icons/images/menu_16px@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d8aee7d8572c7ffd045382bdb53cbb01419d001e GIT binary patch literal 244 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?4;b`WOlfBG>MC@5Lt z8c`CQpH@mmtT}V`<;yxP*J0&i(^Pc>)RVLroh*}%=HLDPfLZn^gYhxk`T6VG+BPS~#;7I1ax#Bin!ohJ&#ce|y@F*jW7 zs(rboanMprB-l zYeY$Kep*R+Vo@qXd3m{BW?pu2a$-TMUVc&f>~}U&Kt&OrE{-7{oyiFjtjxR;7g_)P z|F3`izySsKWtHU;l9KTcLO=fhU(e3Q*7pBN!iqSN11`(FJK1hDc{DXPI=1_KUMIk_ uNRizwSkTd6Ru@Op#Sj;Po@I*!85rg+hz?vL@)77F1_n=8KbLh*2~7aO9Ye+d literal 0 HcmV?d00001 diff --git a/src/icons/images/menu_24px@2x.png b/src/icons/images/menu_24px@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6c1b124f699e080d687da8408032278e34dfd83d GIT binary patch literal 228 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC&H|6fVg?3TAX~PbvH$7ERG^?_ ziEBhjaDG}zd16s2LwR|*US?i)adKios$PCk`s{Z$Qb0w8o-U3d8I5nRUF2*q;Awd{ zZ^!ms9fwmV?r2EJ=~ewuf8Kqz1NU{H%2rLGqVKkqeb#C(Yq-{4ysVO&{CUsgckU|N zQ}`$KvZi(aW9;5{lK + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/svg/menu_24px.svg b/src/icons/svg/menu_24px.svg new file mode 100644 index 000000000..46224677c --- /dev/null +++ b/src/icons/svg/menu_24px.svg @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/lay/lay/lay.pro b/src/lay/lay/lay.pro index f9065ad92..3500502b8 100644 --- a/src/lay/lay/lay.pro +++ b/src/lay/lay/lay.pro @@ -11,7 +11,7 @@ HEADERS = \ layClipDialog.h \ layControlWidgetStack.h \ layCrashMessage.h \ - layEnhancedTabWidget.h \ + layEnhancedTabBar.h \ layFillDialog.h \ layGSIHelpProvider.h \ layHelpAboutDialog.h \ @@ -122,7 +122,7 @@ SOURCES = \ layClipDialog.cc \ layControlWidgetStack.cc \ layCrashMessage.cc \ - layEnhancedTabWidget.cc \ + layEnhancedTabBar.cc \ layFillDialog.cc \ layGSIHelpProvider.cc \ layHelpAboutDialog.cc \ diff --git a/src/lay/lay/layEnhancedTabWidget.cc b/src/lay/lay/layEnhancedTabBar.cc similarity index 65% rename from src/lay/lay/layEnhancedTabWidget.cc rename to src/lay/lay/layEnhancedTabBar.cc index 83804d442..79d048b10 100644 --- a/src/lay/lay/layEnhancedTabWidget.cc +++ b/src/lay/lay/layEnhancedTabBar.cc @@ -21,7 +21,7 @@ */ -#include "layEnhancedTabWidget.h" +#include "layEnhancedTabBar.h" #include #include @@ -35,50 +35,52 @@ namespace lay // --------------------------------------------------------------------------------------------- // EnhancedTabWidget implementation -EnhancedTabWidget::EnhancedTabWidget (QWidget *parent) - : QTabWidget (parent) +EnhancedTabBar::EnhancedTabBar (QWidget *parent) + : QTabBar (parent) { mp_list_tool_button = new QToolButton (this); mp_list_tool_button->setAutoRaise (true); - ///\TODO: Replace placeholder with real icon. - mp_list_tool_button->setIcon (QIcon (QString::fromUtf8 (":/find_16px.png"))); - mp_list_tool_button->setIconSize (QSize (20, 20)); + mp_list_tool_button->hide (); + mp_list_tool_button->setIcon (QIcon (QString::fromUtf8 (":/menu_24px.png"))); + mp_list_tool_button->setIconSize (QSize (24, 24)); mp_list_tool_button->setMenu (new QMenu (this)); mp_list_tool_button->setPopupMode (QToolButton::InstantPopup); mp_list_tool_button->setToolButtonStyle (Qt::ToolButtonIconOnly); - mp_list_tool_button->setToolTip ( tr ("List of all opened views")); - setCornerWidget (mp_list_tool_button, Qt::TopRightCorner); + mp_list_tool_button->setToolTip (tr ("List of all opened views")); connect (mp_list_tool_button->menu (), &QMenu::aboutToShow, - this, &EnhancedTabWidget::list_tool_button_menu_about_to_show); + this, &EnhancedTabBar::list_tool_button_menu_about_to_show); mp_list_action_group = new QActionGroup (this); mp_list_action_group->setExclusive (true); connect (mp_list_action_group, &QActionGroup::triggered, - this, &EnhancedTabWidget::list_action_group_triggered); + this, &EnhancedTabBar::list_action_group_triggered); } -EnhancedTabWidget::~EnhancedTabWidget () = default; - -void EnhancedTabWidget::tabInserted (int index) +EnhancedTabBar::~EnhancedTabBar () { - QTabWidget::tabInserted (index); + // .. nothing yet .. +} + +void EnhancedTabBar::tabInserted (int index) +{ + QTabBar::tabInserted (index); update_list_button_visibility (); } -void EnhancedTabWidget::tabRemoved (int index) +void EnhancedTabBar::tabRemoved (int index) { - QTabWidget::tabRemoved (index); + QTabBar::tabRemoved (index); update_list_button_visibility (); } -void EnhancedTabWidget::list_action_group_triggered (QAction *action) +void EnhancedTabBar::list_action_group_triggered (QAction *action) { setCurrentIndex (action->data ().toInt ()); } -void EnhancedTabWidget::list_tool_button_menu_about_to_show () +void EnhancedTabBar::list_tool_button_menu_about_to_show () { mp_list_tool_button->menu ()->clear (); if (count () > 1) { @@ -92,11 +94,9 @@ void EnhancedTabWidget::list_tool_button_menu_about_to_show () } } -void EnhancedTabWidget::update_list_button_visibility() +void EnhancedTabBar::update_list_button_visibility() { - if (cornerWidget (Qt::TopRightCorner) != nullptr) { - cornerWidget (Qt::TopRightCorner)->setVisible (count () > 1); - } + mp_list_tool_button->setVisible (count () > 1); } } diff --git a/src/lay/lay/layEnhancedTabWidget.h b/src/lay/lay/layEnhancedTabBar.h similarity index 87% rename from src/lay/lay/layEnhancedTabWidget.h rename to src/lay/lay/layEnhancedTabBar.h index a88c34b85..3adcb2248 100644 --- a/src/lay/lay/layEnhancedTabWidget.h +++ b/src/lay/lay/layEnhancedTabBar.h @@ -24,7 +24,7 @@ #ifndef HDR_layEnhancedTabWidget #define HDR_layEnhancedTabWidget -#include +#include class QActionGroup; class QToolButton; @@ -32,14 +32,16 @@ class QToolButton; namespace lay { -class EnhancedTabWidget - : public QTabWidget +class EnhancedTabBar + : public QTabBar { Q_OBJECT public: - EnhancedTabWidget (QWidget *parent); - ~EnhancedTabWidget () override; + EnhancedTabBar (QWidget *parent); + ~EnhancedTabBar () override; + + QToolButton *menu_button () { return mp_list_tool_button; } protected: void tabInserted (int index) override; diff --git a/src/lay/lay/layMainWindow.cc b/src/lay/lay/layMainWindow.cc index be44fecd3..472421e91 100644 --- a/src/lay/lay/layMainWindow.cc +++ b/src/lay/lay/layMainWindow.cc @@ -70,7 +70,7 @@ #include "layDialogs.h" #include "laybasicConfig.h" #include "layConfig.h" -#include "layEnhancedTabWidget.h" +#include "layEnhancedTabBar.h" #include "layMainWindow.h" #include "layHelpDialog.h" #include "layNavigator.h" @@ -228,14 +228,30 @@ MainWindow::MainWindow (QApplication *app, const char *name, bool undo_enabled) vbl->setContentsMargins (0, 0, 0, 0); vbl->setSpacing (0); - mp_tab_widget = new EnhancedTabWidget (mp_main_frame); - vbl->addWidget (mp_tab_widget); - connect (mp_tab_widget, SIGNAL (currentChanged (int)), this, SLOT (view_selected (int))); + QHBoxLayout *vbh_tab = new QHBoxLayout (mp_main_frame); + vbh_tab->setSpacing (6); + vbl->addLayout (vbh_tab); + + EnhancedTabBar *enh_tab_widget = new EnhancedTabBar (mp_main_frame); + mp_tab_bar = enh_tab_widget; + vbh_tab->addWidget (enh_tab_widget); + vbh_tab->addWidget (enh_tab_widget->menu_button ()); + + connect (mp_tab_bar, SIGNAL (currentChanged (int)), this, SLOT (view_selected (int))); #if QT_VERSION >= 0x040500 - mp_tab_widget->setTabsClosable(true); - connect (mp_tab_widget, SIGNAL (tabCloseRequested (int)), this, SLOT (tab_close_requested (int))); + mp_tab_bar->setTabsClosable (true); + connect (mp_tab_bar, SIGNAL (tabCloseRequested (int)), this, SLOT (tab_close_requested (int))); #endif + mp_tab_bar->setContextMenuPolicy (Qt::ActionsContextMenu); + + QAction *action = new QAction (tr ("Close All"), this); + connect (action, SIGNAL (triggered ()), this, SLOT (close_all_views ())); + mp_tab_bar->addAction (action); + action = new QAction (tr ("Close All Except Current"), this); + connect (action, SIGNAL (triggered ()), this, SLOT (close_all_except_current_view ())); + mp_tab_bar->addAction (action); + mp_hp_dock_widget = new QDockWidget (QObject::tr ("Cells"), this); mp_hp_dock_widget->setObjectName (QString::fromUtf8 ("hp_dock_widget")); mp_hp_stack = new ControlWidgetStack (mp_hp_dock_widget, "hp_stack"); @@ -683,8 +699,8 @@ MainWindow::close_all () // Clear the tab bar bool f = m_disable_tab_selected; m_disable_tab_selected = true; - while (mp_tab_widget->count () > 0) { - mp_tab_widget->removeTab (mp_tab_widget->count () - 1); + while (mp_tab_bar->count () > 0) { + mp_tab_bar->removeTab (mp_tab_bar->count () - 1); } m_disable_tab_selected = f; @@ -2315,7 +2331,7 @@ MainWindow::view_selected (int index) // Hint: setting the focus to the tab bar avoids problem with dangling keyboard focus. // Sometimes, the focus was set to the hierarchy level spin buttons which caught Copy&Paste // events in effect. - mp_tab_widget->setFocus (); + mp_tab_bar->setFocus (); if (! m_disable_tab_selected) { select_view (index); @@ -2336,7 +2352,7 @@ MainWindow::select_view (int index) tl_assert (index >= 0 && index < int (views ())); - mp_tab_widget->setCurrentIndex (index); + mp_tab_bar->setCurrentIndex (index); bool box_set = (m_synchronized_views && current_view () != 0); db::DBox box; @@ -2565,7 +2581,7 @@ MainWindow::clone_current_view () bool f = m_disable_tab_selected; m_disable_tab_selected = true; - int index = mp_tab_widget->insertTab (-1, mp_views.back (), tl::to_qstring (view->title ())); + int index = mp_tab_bar->insertTab (-1, tl::to_qstring (view->title ())); m_disable_tab_selected = f; view_created_event (index); @@ -2580,10 +2596,22 @@ MainWindow::cm_close_all () interactive_close_view (-1, false); } +void +MainWindow::cm_close_all_except_current () +{ + int current_index = index_of (lay::LayoutView::current ()); + if (current_index >= 0) { + interactive_close_view (-current_index - 2, false); + } +} + void MainWindow::cm_close () { - interactive_close_view (index_of (lay::LayoutView::current ()), false); + int current_index = index_of (lay::LayoutView::current ()); + if (current_index >= 0) { + interactive_close_view (current_index, false); + } } void @@ -2597,7 +2625,11 @@ MainWindow::interactive_close_view (int index, bool all_cellviews) { if (index < 0) { - // close all views + // close all views or all except one: + // -1: close all + // -2: close except view #0 + // -3: close except view #1 + // ... bool can_close = true; @@ -2605,8 +2637,14 @@ MainWindow::interactive_close_view (int index, bool all_cellviews) std::string dirty_files; std::set seen_names; + int except = -2 - index; + for (index = 0; index < int (views ()); ++index) { + if (index == except) { + continue; + } + for (unsigned int i = 0; i < view (index)->cellviews (); ++i) { const lay::CellView &cv = view (index)->cellview (i); @@ -2653,8 +2691,11 @@ MainWindow::interactive_close_view (int index, bool all_cellviews) if (can_close) { BEGIN_PROTECTED - while (views () > 0) { - close_view (0); + for (index = int (views ()); index > 0; ) { + --index; + if (index != except) { + close_view (index); + } } END_PROTECTED } @@ -2788,6 +2829,18 @@ MainWindow::close_current_view () close_view (index_of (lay::LayoutView::current ())); } +void +MainWindow::close_all_views () +{ + cm_close_all (); +} + +void +MainWindow::close_all_except_current_view () +{ + cm_close_all_except_current (); +} + void MainWindow::close_view (int index) { @@ -2806,7 +2859,7 @@ MainWindow::close_view (int index) box = view (index)->viewport ().box (); } - mp_tab_widget->removeTab (index); + mp_tab_bar->removeTab (index); mp_view_stack->remove_widget (index); mp_lp_stack->remove_widget (index); mp_layer_toolbox_stack->remove_widget (index); @@ -3382,7 +3435,7 @@ MainWindow::create_view () bool f = m_disable_tab_selected; m_disable_tab_selected = true; - int index = mp_tab_widget->insertTab (-1, mp_views.back (), tl::to_qstring (current_view ()->title ())); + int index = mp_tab_bar->insertTab (-1, tl::to_qstring (current_view ()->title ())); m_disable_tab_selected = f; view_created_event (index); @@ -3445,7 +3498,7 @@ MainWindow::create_or_load_layout (const std::string *filename, const db::LoadLa bool f = m_disable_tab_selected; m_disable_tab_selected = true; - int index = mp_tab_widget->insertTab (-1, mp_views.back (), QString ()); + int index = mp_tab_bar->insertTab (-1, QString ()); update_tab_title (index); m_disable_tab_selected = f; view_created_event (index); @@ -3485,8 +3538,8 @@ MainWindow::update_tab_title (int i) title += v->title (); } - if (tl::to_string (mp_tab_widget->tabText (i)) != title) { - mp_tab_widget->setTabText (i, tl::to_qstring (title)); + if (tl::to_string (mp_tab_bar->tabText (i)) != title) { + mp_tab_bar->setTabText (i, tl::to_qstring (title)); } if (v) { @@ -3501,8 +3554,8 @@ MainWindow::update_tab_title (int i) files += tl::to_string (tr ("(not saved)")); } } - if (tl::to_string (mp_tab_widget->tabToolTip (i)) != files) { - mp_tab_widget->setTabToolTip (i, tl::to_qstring (files)); + if (tl::to_string (mp_tab_bar->tabToolTip (i)) != files) { + mp_tab_bar->setTabToolTip (i, tl::to_qstring (files)); } } } @@ -3892,6 +3945,8 @@ MainWindow::menu_activated (const std::string &symbol) cm_clone (); } else if (symbol == "cm_close_all") { cm_close_all (); + } else if (symbol == "cm_close_all_except_current") { + cm_close_all_except_current (); } else if (symbol == "cm_close") { cm_close (); } else if (symbol == "cm_packages") { diff --git a/src/lay/lay/layMainWindow.h b/src/lay/lay/layMainWindow.h index 086ced6fb..da7895f73 100644 --- a/src/lay/lay/layMainWindow.h +++ b/src/lay/lay/layMainWindow.h @@ -51,7 +51,7 @@ #include "tlDeferredExecution.h" #include "gsi.h" -class QTabWidget; +class QTabBar; class QToolBar; class QLabel; class QAction; @@ -632,6 +632,8 @@ public slots: void exit (); void close_current_view (); void close_view (int index); + void close_all_views (); + void close_all_except_current_view (); void tab_close_requested (int); void open_recent (size_t n); void open_recent_session (size_t n); @@ -682,7 +684,7 @@ private: TextProgressDelegate m_text_progress; // Main menu - QTabWidget *mp_tab_widget; + QTabBar *mp_tab_bar; QToolBar *mp_tool_bar; QDockWidget *mp_navigator_dock_widget; lay::Navigator *mp_navigator; @@ -788,6 +790,7 @@ private: void cm_new_layout (); void cm_clone (); void cm_close_all (); + void cm_close_all_except_current (); void cm_close (); void cm_packages (); void cm_technologies (); From 35aaf63051436b7dba4ba51728a89ec646739e19 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 24 Sep 2022 19:53:31 +0200 Subject: [PATCH 4/6] As suggested by Eugene: close left/close right added to macro editor's tab tab ... layout views will follow --- src/lay/lay/layMacroEditorDialog.cc | 33 +++++++++++++++++++++++++++-- src/lay/lay/layMacroEditorDialog.h | 3 +++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/lay/lay/layMacroEditorDialog.cc b/src/lay/lay/layMacroEditorDialog.cc index a09fef3d6..1a4934eb4 100644 --- a/src/lay/lay/layMacroEditorDialog.cc +++ b/src/lay/lay/layMacroEditorDialog.cc @@ -400,6 +400,12 @@ MacroEditorDialog::MacroEditorDialog (lay::Dispatcher *pr, lym::MacroCollection action = new QAction (tr ("Close All Except Current"), this); connect (action, SIGNAL (triggered ()), this, SLOT (close_all_but_current ())); tabWidget->addAction (action); + action = new QAction (tr ("Close All Left"), this); + connect (action, SIGNAL (triggered ()), this, SLOT (close_all_left ())); + tabWidget->addAction (action); + action = new QAction (tr ("Close All Right"), this); + connect (action, SIGNAL (triggered ()), this, SLOT (close_all_right ())); + tabWidget->addAction (action); dbgOn->setEnabled (true); runButton->setEnabled (true); @@ -2264,6 +2270,24 @@ END_PROTECTED void MacroEditorDialog::close_all_but_current () +{ + close_many (0); +} + +void +MacroEditorDialog::close_all_left () +{ + close_many (-1); +} + +void +MacroEditorDialog::close_all_right () +{ + close_many (1); +} + +void +MacroEditorDialog::close_many (int r2c) { if (m_in_exec) { return; @@ -2279,9 +2303,14 @@ BEGIN_PROTECTED return; } + std::set removed; + for (int i = tabWidget->count (); i > 0; ) { --i; - if (i != ci) { + if ((r2c == 0 && i != ci) || + (r2c < 0 && i < ci) || + (r2c > 0 && i > ci)) { + removed.insert (tabWidget->widget (i)); tabWidget->removeTab (i); } } @@ -2289,7 +2318,7 @@ BEGIN_PROTECTED std::map new_widgets; for (std::map ::iterator p = m_tab_widgets.begin (); p != m_tab_widgets.end (); ++p) { - if (cw && p->second == cw) { + if (removed.find (p->second) == removed.end ()) { new_widgets.insert (*p); } else { if (p->second) { diff --git a/src/lay/lay/layMacroEditorDialog.h b/src/lay/lay/layMacroEditorDialog.h index e3c14c68d..eec5e0f24 100644 --- a/src/lay/lay/layMacroEditorDialog.h +++ b/src/lay/lay/layMacroEditorDialog.h @@ -214,6 +214,8 @@ private slots: void tab_close_requested (int); void close_all (); void close_all_but_current (); + void close_all_left (); + void close_all_right (); void replace_mode_button_clicked (); void replace_next_button_clicked (); void replace_all_button_clicked (); @@ -264,6 +266,7 @@ private: void move_subfolder (lym::MacroCollection *source, lym::MacroCollection *target); lay::MacroEditorPage *create_page (lym::Macro *macro); void open_macro (lym::Macro *macro); + void close_many (int which_relative_to_current); void ensure_writeable_collection_selected (); void update_console_text (); void start_exec (gsi::Interpreter *interpreter); From 42de46caf203e075e898a3870ab62a63c3447f4b Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 24 Sep 2022 20:48:02 +0200 Subject: [PATCH 5/6] Added close left/right and clone to view tab's context menu too --- src/lay/lay/layMacroEditorDialog.cc | 1 - src/lay/lay/layMainWindow.cc | 105 ++++++++++++++++++++-------- src/lay/lay/layMainWindow.h | 7 +- 3 files changed, 81 insertions(+), 32 deletions(-) diff --git a/src/lay/lay/layMacroEditorDialog.cc b/src/lay/lay/layMacroEditorDialog.cc index 1a4934eb4..1d8694110 100644 --- a/src/lay/lay/layMacroEditorDialog.cc +++ b/src/lay/lay/layMacroEditorDialog.cc @@ -2295,7 +2295,6 @@ MacroEditorDialog::close_many (int r2c) BEGIN_PROTECTED - QWidget *cw = tabWidget->currentWidget (); int ci = tabWidget->currentIndex (); if (ci < 0) { diff --git a/src/lay/lay/layMainWindow.cc b/src/lay/lay/layMainWindow.cc index 472421e91..202882ffc 100644 --- a/src/lay/lay/layMainWindow.cc +++ b/src/lay/lay/layMainWindow.cc @@ -251,6 +251,18 @@ MainWindow::MainWindow (QApplication *app, const char *name, bool undo_enabled) action = new QAction (tr ("Close All Except Current"), this); connect (action, SIGNAL (triggered ()), this, SLOT (close_all_except_current_view ())); mp_tab_bar->addAction (action); + action = new QAction (tr ("Close All Left"), this); + connect (action, SIGNAL (triggered ()), this, SLOT (close_all_views_left ())); + mp_tab_bar->addAction (action); + action = new QAction (tr ("Close All Right"), this); + connect (action, SIGNAL (triggered ()), this, SLOT (close_all_views_right ())); + mp_tab_bar->addAction (action); + action = new QAction (this); + action->setSeparator (true); + mp_tab_bar->addAction (action); + action = new QAction (tr ("Clone Panel"), this); + connect (action, SIGNAL (triggered ()), this, SLOT (clone ())); + mp_tab_bar->addAction (action); mp_hp_dock_widget = new QDockWidget (QObject::tr ("Cells"), this); mp_hp_dock_widget->setObjectName (QString::fromUtf8 ("hp_dock_widget")); @@ -2593,7 +2605,7 @@ MainWindow::clone_current_view () void MainWindow::cm_close_all () { - interactive_close_view (-1, false); + interactive_close_view (0, views (), false, false); } void @@ -2601,7 +2613,25 @@ MainWindow::cm_close_all_except_current () { int current_index = index_of (lay::LayoutView::current ()); if (current_index >= 0) { - interactive_close_view (-current_index - 2, false); + interactive_close_view (current_index, current_index + 1, true, false); + } +} + +void +MainWindow::cm_close_all_left () +{ + int current_index = index_of (lay::LayoutView::current ()); + if (current_index >= 0) { + interactive_close_view (0, current_index, false, false); + } +} + +void +MainWindow::cm_close_all_right () +{ + int current_index = index_of (lay::LayoutView::current ()); + if (current_index >= 0) { + interactive_close_view (current_index + 1, views (), false, false); } } @@ -2610,26 +2640,21 @@ MainWindow::cm_close () { int current_index = index_of (lay::LayoutView::current ()); if (current_index >= 0) { - interactive_close_view (current_index, false); + interactive_close_view (current_index, current_index + 1, false, false); } } void MainWindow::tab_close_requested (int index) { - interactive_close_view (index, true); + interactive_close_view (index, index + 1, false, true); } void -MainWindow::interactive_close_view (int index, bool all_cellviews) +MainWindow::interactive_close_view (int from, int to, bool invert_range, bool all_cellviews) { - if (index < 0) { - - // close all views or all except one: - // -1: close all - // -2: close except view #0 - // -3: close except view #1 - // ... + // closes views in range [from, to[ (invert_range=false) or outside this range (invert_range=true) + if (invert_range || from + 1 != to) { bool can_close = true; @@ -2637,11 +2662,9 @@ MainWindow::interactive_close_view (int index, bool all_cellviews) std::string dirty_files; std::set seen_names; - int except = -2 - index; + for (int index = 0; index < int (views ()); ++index) { - for (index = 0; index < int (views ()); ++index) { - - if (index == except) { + if ((index >= from && index < to) == invert_range) { continue; } @@ -2691,31 +2714,31 @@ MainWindow::interactive_close_view (int index, bool all_cellviews) if (can_close) { BEGIN_PROTECTED - for (index = int (views ()); index > 0; ) { + for (int index = int (views ()); index > 0; ) { --index; - if (index != except) { + if ((index >= from && index < to) != invert_range) { close_view (index); } } END_PROTECTED } - } else if (view (index)) { + } else if (view (from)) { std::vector selected; - if (view (index)->cellviews () > 1) { + if (view (from)->cellviews () > 1) { if (all_cellviews) { - for (int i = 0; i < int (view (index)->cellviews ()); ++i) { + for (int i = 0; i < int (view (from)->cellviews ()); ++i) { selected.push_back (i); } } else { - SelectCellViewForm form (0, view (index), tl::to_string (QObject::tr ("Select Layouts To Close"))); - form.set_selection (view (index)->active_cellview_index ()); + SelectCellViewForm form (0, view (from), tl::to_string (QObject::tr ("Select Layouts To Close"))); + form.set_selection (view (from)->active_cellview_index ()); if (form.exec () != QDialog::Accepted) { return; @@ -2728,7 +2751,7 @@ MainWindow::interactive_close_view (int index, bool all_cellviews) } - } else if (view (index)->cellviews () > 0) { + } else if (view (from)->cellviews () > 0) { selected.push_back (0); } @@ -2739,7 +2762,7 @@ MainWindow::interactive_close_view (int index, bool all_cellviews) for (std::vector ::const_iterator i = selected.begin (); i != selected.end (); ++i) { - const lay::CellView &cv = view (index)->cellview (*i); + const lay::CellView &cv = view (from)->cellview (*i); if (cv->layout ().is_editable () && cv->is_dirty ()) { @@ -2756,7 +2779,7 @@ MainWindow::interactive_close_view (int index, bool all_cellviews) } for (std::vector ::const_iterator ii = selected.begin (); ii != selected.end (); ++ii) { - if (view (index)->cellview (*ii)->name () == name) { + if (view (from)->cellview (*ii)->name () == name) { --count; } } @@ -2799,14 +2822,14 @@ MainWindow::interactive_close_view (int index, bool all_cellviews) BEGIN_PROTECTED // Actually erase the selected cellviews - if (view (index)->cellviews () == selected.size ()) { + if (view (from)->cellviews () == selected.size ()) { // all cellviews selected - simply close - close_view (index); + close_view (from); } else { std::sort (selected.begin (), selected.end ()); int offset = 0; for (std::vector ::const_iterator i = selected.begin (); i != selected.end (); ++i) { - view (index)->erase_cellview ((unsigned int)(*i - offset)); + view (from)->erase_cellview ((unsigned int)(*i - offset)); ++offset; } } @@ -2816,13 +2839,19 @@ MainWindow::interactive_close_view (int index, bool all_cellviews) } } else { - close_view (index); + close_view (from); } } } +void +MainWindow::clone () +{ + clone_current_view (); +} + void MainWindow::close_current_view () { @@ -2841,6 +2870,18 @@ MainWindow::close_all_except_current_view () cm_close_all_except_current (); } +void +MainWindow::close_all_views_left () +{ + cm_close_all_left (); +} + +void +MainWindow::close_all_views_right () +{ + cm_close_all_right (); +} + void MainWindow::close_view (int index) { @@ -3945,6 +3986,10 @@ MainWindow::menu_activated (const std::string &symbol) cm_clone (); } else if (symbol == "cm_close_all") { cm_close_all (); + } else if (symbol == "cm_close_all_left") { + cm_close_all_left (); + } else if (symbol == "cm_close_all_right") { + cm_close_all_right (); } else if (symbol == "cm_close_all_except_current") { cm_close_all_except_current (); } else if (symbol == "cm_close") { diff --git a/src/lay/lay/layMainWindow.h b/src/lay/lay/layMainWindow.h index da7895f73..01c44ff89 100644 --- a/src/lay/lay/layMainWindow.h +++ b/src/lay/lay/layMainWindow.h @@ -634,6 +634,9 @@ public slots: void close_view (int index); void close_all_views (); void close_all_except_current_view (); + void close_all_views_left (); + void close_all_views_right (); + void clone (); void tab_close_requested (int); void open_recent (size_t n); void open_recent_session (size_t n); @@ -791,6 +794,8 @@ private: void cm_clone (); void cm_close_all (); void cm_close_all_except_current (); + void cm_close_all_left (); + void cm_close_all_right (); void cm_close (); void cm_packages (); void cm_technologies (); @@ -805,7 +810,7 @@ private: int dirty_files (std::string &dirty_files); void load_layer_props_from_file (const std::string &fn); - void interactive_close_view (int index, bool all_cellviews); + void interactive_close_view (int from, int to, bool invert_range, bool all_cellviews); void call_on_current_view (void (lay::LayoutView::*func) (), const std::string &op_desc); void current_view_changed (); void update_window_title (); From 95686ea63036db98635fd7061f17f6dad23afee2 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 5 Oct 2022 22:27:13 +0200 Subject: [PATCH 6/6] Modified 'close all except/left/right' to be effective on the tab the mouse points at. --- src/lay/lay/layMacroEditorDialog.cc | 20 ++++++--- src/lay/lay/layMacroEditorDialog.h | 3 +- src/lay/lay/layMainWindow.cc | 66 ++++++++++++----------------- src/lay/lay/layMainWindow.h | 7 ++- 4 files changed, 45 insertions(+), 51 deletions(-) diff --git a/src/lay/lay/layMacroEditorDialog.cc b/src/lay/lay/layMacroEditorDialog.cc index 1d8694110..8b50c5cd9 100644 --- a/src/lay/lay/layMacroEditorDialog.cc +++ b/src/lay/lay/layMacroEditorDialog.cc @@ -397,8 +397,8 @@ MacroEditorDialog::MacroEditorDialog (lay::Dispatcher *pr, lym::MacroCollection QAction *action = new QAction (tr ("Close All"), this); connect (action, SIGNAL (triggered ()), this, SLOT (close_all ())); tabWidget->addAction (action); - action = new QAction (tr ("Close All Except Current"), this); - connect (action, SIGNAL (triggered ()), this, SLOT (close_all_but_current ())); + action = new QAction (tr ("Close All Except This"), this); + connect (action, SIGNAL (triggered ()), this, SLOT (close_all_but_this ())); tabWidget->addAction (action); action = new QAction (tr ("Close All Left"), this); connect (action, SIGNAL (triggered ()), this, SLOT (close_all_left ())); @@ -474,6 +474,8 @@ MacroEditorDialog::MacroEditorDialog (lay::Dispatcher *pr, lym::MacroCollection connect (replaceAllButton, SIGNAL (clicked ()), this, SLOT (replace_all_button_clicked ())); connect (allVariables, SIGNAL (clicked (bool)), variableList, SLOT (set_show_all (bool))); + tabWidget->installEventFilter (this); + splitter->setCollapsible (1, false); replaceFrame->hide (); @@ -1541,7 +1543,13 @@ MacroEditorDialog::eventFilter (QObject *obj, QEvent *event) } - } + } else if (obj == tabWidget->tabBar () && dynamic_cast (event) != 0) { + + // just spy on the events, don't eat them + QMouseEvent *mouse_event = dynamic_cast (event); + m_mouse_pos = mouse_event->pos (); + + } return false; } @@ -2269,7 +2277,7 @@ END_PROTECTED } void -MacroEditorDialog::close_all_but_current () +MacroEditorDialog::close_all_but_this () { close_many (0); } @@ -2295,10 +2303,8 @@ MacroEditorDialog::close_many (int r2c) BEGIN_PROTECTED - int ci = tabWidget->currentIndex (); - + int ci = tabWidget->tabBar ()->tabAt (m_mouse_pos); if (ci < 0) { - close_all (); return; } diff --git a/src/lay/lay/layMacroEditorDialog.h b/src/lay/lay/layMacroEditorDialog.h index eec5e0f24..bfb45f24d 100644 --- a/src/lay/lay/layMacroEditorDialog.h +++ b/src/lay/lay/layMacroEditorDialog.h @@ -213,7 +213,7 @@ private slots: void search_finished (); void tab_close_requested (int); void close_all (); - void close_all_but_current (); + void close_all_but_this (); void close_all_left (); void close_all_right (); void replace_mode_button_clicked (); @@ -306,6 +306,7 @@ private: lay::Dispatcher *mp_plugin_root; lym::MacroCollection *mp_root; bool m_first_show; + QPoint m_mouse_pos; bool m_debugging_on; lym::Macro *mp_run_macro; std::vector m_macro_templates; diff --git a/src/lay/lay/layMainWindow.cc b/src/lay/lay/layMainWindow.cc index 202882ffc..470809b20 100644 --- a/src/lay/lay/layMainWindow.cc +++ b/src/lay/lay/layMainWindow.cc @@ -234,6 +234,7 @@ MainWindow::MainWindow (QApplication *app, const char *name, bool undo_enabled) EnhancedTabBar *enh_tab_widget = new EnhancedTabBar (mp_main_frame); mp_tab_bar = enh_tab_widget; + mp_tab_bar->installEventFilter (this); vbh_tab->addWidget (enh_tab_widget); vbh_tab->addWidget (enh_tab_widget->menu_button ()); @@ -248,8 +249,8 @@ MainWindow::MainWindow (QApplication *app, const char *name, bool undo_enabled) QAction *action = new QAction (tr ("Close All"), this); connect (action, SIGNAL (triggered ()), this, SLOT (close_all_views ())); mp_tab_bar->addAction (action); - action = new QAction (tr ("Close All Except Current"), this); - connect (action, SIGNAL (triggered ()), this, SLOT (close_all_except_current_view ())); + action = new QAction (tr ("Close All Except This"), this); + connect (action, SIGNAL (triggered ()), this, SLOT (close_all_except_this ())); mp_tab_bar->addAction (action); action = new QAction (tr ("Close All Left"), this); connect (action, SIGNAL (triggered ()), this, SLOT (close_all_views_left ())); @@ -2608,33 +2609,6 @@ MainWindow::cm_close_all () interactive_close_view (0, views (), false, false); } -void -MainWindow::cm_close_all_except_current () -{ - int current_index = index_of (lay::LayoutView::current ()); - if (current_index >= 0) { - interactive_close_view (current_index, current_index + 1, true, false); - } -} - -void -MainWindow::cm_close_all_left () -{ - int current_index = index_of (lay::LayoutView::current ()); - if (current_index >= 0) { - interactive_close_view (0, current_index, false, false); - } -} - -void -MainWindow::cm_close_all_right () -{ - int current_index = index_of (lay::LayoutView::current ()); - if (current_index >= 0) { - interactive_close_view (current_index + 1, views (), false, false); - } -} - void MainWindow::cm_close () { @@ -2865,21 +2839,30 @@ MainWindow::close_all_views () } void -MainWindow::close_all_except_current_view () +MainWindow::close_all_except_this () { - cm_close_all_except_current (); + int index = mp_tab_bar->tabAt (m_mouse_pos); + if (index >= 0) { + interactive_close_view (index, index + 1, true, false); + } } void MainWindow::close_all_views_left () { - cm_close_all_left (); + int index = mp_tab_bar->tabAt (m_mouse_pos); + if (index >= 0) { + interactive_close_view (0, index, false, false); + } } void MainWindow::close_all_views_right () { - cm_close_all_right (); + int index = mp_tab_bar->tabAt (m_mouse_pos); + if (index >= 0) { + interactive_close_view (index + 1, views (), false, false); + } } void @@ -3986,12 +3969,6 @@ MainWindow::menu_activated (const std::string &symbol) cm_clone (); } else if (symbol == "cm_close_all") { cm_close_all (); - } else if (symbol == "cm_close_all_left") { - cm_close_all_left (); - } else if (symbol == "cm_close_all_right") { - cm_close_all_right (); - } else if (symbol == "cm_close_all_except_current") { - cm_close_all_except_current (); } else if (symbol == "cm_close") { cm_close (); } else if (symbol == "cm_packages") { @@ -4058,6 +4035,17 @@ MainWindow::dragEnterEvent(QDragEnterEvent *event) } } +bool +MainWindow::eventFilter (QObject *watched, QEvent *event) +{ + // spy on the mouse events of the tab bar so we can tell which tab the menu was issued on + if (watched == mp_tab_bar && dynamic_cast (event) != 0) { + m_mouse_pos = dynamic_cast (event)->pos (); + } + + return QMainWindow::eventFilter (watched, event); +} + void MainWindow::dropEvent(QDropEvent *event) { diff --git a/src/lay/lay/layMainWindow.h b/src/lay/lay/layMainWindow.h index 01c44ff89..48c787f24 100644 --- a/src/lay/lay/layMainWindow.h +++ b/src/lay/lay/layMainWindow.h @@ -633,7 +633,7 @@ public slots: void close_current_view (); void close_view (int index); void close_all_views (); - void close_all_except_current_view (); + void close_all_except_this (); void close_all_views_left (); void close_all_views_right (); void clone (); @@ -680,6 +680,7 @@ protected: void update_content (); void do_update_menu (); void do_update_mru_menus (); + bool eventFilter (QObject *watched, QEvent *event); private: lay::Dispatcher m_dispatcher; @@ -688,6 +689,7 @@ private: // Main menu QTabBar *mp_tab_bar; + QPoint m_mouse_pos; QToolBar *mp_tool_bar; QDockWidget *mp_navigator_dock_widget; lay::Navigator *mp_navigator; @@ -793,9 +795,6 @@ private: void cm_new_layout (); void cm_clone (); void cm_close_all (); - void cm_close_all_except_current (); - void cm_close_all_left (); - void cm_close_all_right (); void cm_close (); void cm_packages (); void cm_technologies ();