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 000000000..303068693 Binary files /dev/null and b/src/icons/images/menu_16px.png differ diff --git a/src/icons/images/menu_16px@2x.png b/src/icons/images/menu_16px@2x.png new file mode 100644 index 000000000..d8aee7d85 Binary files /dev/null and b/src/icons/images/menu_16px@2x.png differ diff --git a/src/icons/images/menu_24px.png b/src/icons/images/menu_24px.png new file mode 100644 index 000000000..f6657dce0 Binary files /dev/null and b/src/icons/images/menu_24px.png differ diff --git a/src/icons/images/menu_24px@2x.png b/src/icons/images/menu_24px@2x.png new file mode 100644 index 000000000..6c1b124f6 Binary files /dev/null and b/src/icons/images/menu_24px@2x.png differ diff --git a/src/icons/svg/menu_16px.svg b/src/icons/svg/menu_16px.svg new file mode 100644 index 000000000..30ec850ea --- /dev/null +++ b/src/icons/svg/menu_16px.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 ();