Mercurial > octave
view libgui/src/tab-bar.cc @ 31646:c6d54dd31a7e stable
maint: Use macros to begin/end C++ namespaces.
* BaseControl.cc, BaseControl.h, ButtonControl.cc, ButtonControl.h,
ButtonGroup.cc, ButtonGroup.h, Canvas.cc, Canvas.h,
CheckBoxControl.cc, CheckBoxControl.h, Container.cc, Container.h,
ContextMenu.cc, ContextMenu.h, EditControl.cc, EditControl.h,
Figure.cc, Figure.h, FigureWindow.cc, FigureWindow.h, GLCanvas.cc,
GLCanvas.h, GenericEventNotify.h, KeyMap.cc, KeyMap.h,
ListBoxControl.cc, ListBoxControl.h, Logger.cc, Logger.h, Menu.cc,
Menu.h, MenuContainer.h, Object.cc, Object.h, ObjectProxy.cc,
ObjectProxy.h, Panel.cc, Panel.h, PopupMenuControl.cc,
PopupMenuControl.h, PushButtonControl.cc, PushButtonControl.h,
PushTool.cc, PushTool.h, QtHandlesUtils.cc, QtHandlesUtils.h,
RadioButtonControl.cc, RadioButtonControl.h, SliderControl.cc,
SliderControl.h, Table.cc, Table.h, TextControl.cc, TextControl.h,
TextEdit.cc, TextEdit.h, ToggleButtonControl.cc,
ToggleButtonControl.h, ToggleTool.cc, ToggleTool.h, ToolBar.cc,
ToolBar.h, ToolBarButton.cc, ToolBarButton.h, annotation-dialog.cc,
annotation-dialog.h, gl-select.cc, gl-select.h, qopengl-functions.h,
qt-graphics-toolkit.cc, qt-graphics-toolkit.h, QTerminal.h,
color-picker.cc, color-picker.h, command-widget.cc, command-widget.h,
community-news.cc, community-news.h, dialog.cc, dialog.h,
documentation-bookmarks.cc, documentation-bookmarks.h,
documentation-dock-widget.cc, documentation-dock-widget.h,
documentation.cc, documentation.h, dw-main-window.cc,
dw-main-window.h, external-editor-interface.cc,
external-editor-interface.h, files-dock-widget.cc,
files-dock-widget.h, find-files-dialog.cc, find-files-dialog.h,
find-files-model.cc, find-files-model.h, graphics-init.cc,
graphics-init.h, gui-settings.cc, gui-settings.h, gui-utils.cc,
gui-utils.h, history-dock-widget.cc, history-dock-widget.h,
interpreter-qobject.cc, interpreter-qobject.h, led-indicator.cc,
led-indicator.h, file-editor-interface.h, file-editor-tab.cc,
file-editor-tab.h, file-editor.cc, file-editor.h, find-dialog.cc,
find-dialog.h, marker.cc, marker.h, octave-qscintilla.cc,
octave-qscintilla.h, octave-txt-lexer.cc, octave-txt-lexer.h,
main-window.cc, main-window.h, news-reader.cc, news-reader.h,
octave-dock-widget.cc, octave-dock-widget.h, octave-qobject.cc,
octave-qobject.h, qt-application.cc, qt-application.h,
qt-interpreter-events.cc, qt-interpreter-events.h, qt-utils.h,
release-notes.cc, release-notes.h, resource-manager.cc,
resource-manager.h, set-path-dialog.cc, set-path-dialog.h,
set-path-model.cc, set-path-model.h, settings-dialog.cc,
settings-dialog.h, shortcut-manager.cc, shortcut-manager.h,
tab-bar.cc, tab-bar.h, terminal-dock-widget.cc,
terminal-dock-widget.h, variable-editor-model.cc,
variable-editor-model.h, variable-editor.cc, variable-editor.h,
welcome-wizard.cc, welcome-wizard.h, workspace-model.cc,
workspace-model.h, workspace-view.cc, workspace-view.h:
Use new macros to begin/end C++ namespaces.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 06 Dec 2022 14:37:51 -0500 |
parents | 796f54d4ddbf |
children | 29d734430e5f |
line wrap: on
line source
//////////////////////////////////////////////////////////////////////// // // Copyright (C) 2018-2022 The Octave Project Developers // // See the file COPYRIGHT.md in the top-level directory of this // distribution or <https://octave.org/copyright/>. // // This file is part of Octave. // // Octave 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 3 of the License, or // (at your option) any later version. // // Octave 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 Octave; see the file COPYING. If not, see // <https://www.gnu.org/licenses/>. // //////////////////////////////////////////////////////////////////////// // This file implements a tab bar derived from QTabBar with a contextmenu // and possibility to close a tab via double-left or middle mouse click. #if defined (HAVE_CONFIG_H) # include "config.h" #endif #include "tab-bar.h" OCTAVE_BEGIN_NAMESPACE(octave) // // Reimplemented QTabbar // tab_bar::tab_bar (QWidget *p) : QTabBar (p), m_context_menu (new QMenu (this)) { } void tab_bar::set_rotated (int rotated) { m_rotated = rotated; } // slots for tab navigation void tab_bar::switch_left_tab (void) { switch_tab (-1); } void tab_bar::switch_right_tab (void) { switch_tab (1); } void tab_bar::move_tab_left (void) { switch_tab (-1, true); } void tab_bar::move_tab_right (void) { switch_tab (1, true); } void tab_bar::switch_tab (int direction, bool movetab) { int tabs = count (); if (tabs < 2) return; int old_pos = currentIndex (); int new_pos = currentIndex () + direction; if (new_pos < 0 || new_pos >= tabs) new_pos = new_pos - direction*tabs; if (movetab) { moveTab (old_pos, new_pos); setCurrentIndex (old_pos); setCurrentIndex (new_pos); } else setCurrentIndex (new_pos); } void tab_bar::sort_tabs_alph (void) { QString current_title = tabText (currentIndex ()); int tab_with_focus = 0; // Get all tab title and sort QStringList tab_texts; for (int i = 0; i < count (); i++) tab_texts.append (tabText (i)); tab_texts.sort (); // Move tab into the order of the generated string list for (int title = 0; title < tab_texts.count (); title++) { // Target tab is same as place of title in QStringList. // Find index of next title in string list, leaving out the // tabs (or titles) that were already moved. for (int tab = title; tab < count (); tab++) { if (tabText (tab) == tab_texts.at (title)) { // Index of next tile found, so move tab into next position moveTab (tab, title); if (tab_texts.at (title) == current_title) tab_with_focus = title; break; } } } setCurrentIndex (tab_with_focus); } // The following two functions are reimplemented for allowing rotated // tabs and are based on this answer on stack overflow: // https://stackoverflow.com/a/50579369 // Reimplemented size hint allowing rotated tabs QSize tab_bar::tabSizeHint (int idx) const { QSize s = QTabBar::tabSizeHint (idx); if (m_rotated) s.transpose(); return s; } // Reimplemented paint event allowing rotated tabs void tab_bar::paintEvent(QPaintEvent *e) { // Just process the original event if not rotated if (! m_rotated) return QTabBar::paintEvent (e); // Process the event for rotated tabs QStylePainter painter (this); QStyleOptionTab opt; for (int idx = 0; idx < count(); idx++) { initStyleOption (&opt, idx); painter.drawControl (QStyle::CE_TabBarTabShape, opt); painter.save (); QSize s = opt.rect.size(); s.transpose(); QRect rect (QPoint (), s); rect.moveCenter (opt.rect.center ()); opt.rect = rect; QPoint p = tabRect (idx).center (); painter.translate (p); painter.rotate (-m_rotated*90); painter.translate (-p); painter.drawControl (QStyle::CE_TabBarTabLabel, opt); painter.restore (); } } // Reimplement mouse event for filtering out the desired mouse clicks void tab_bar::mousePressEvent (QMouseEvent *me) { QPoint click_pos; int clicked_idx = -1; // detect the tab where the click occurred for (int i = 0; i < count (); i++) { click_pos = mapToGlobal (me->pos ()); if (tabRect (i).contains (mapFromGlobal (click_pos))) { clicked_idx = i; break; } } // If a tab was clicked if (clicked_idx >= 0) { int current_idx = currentIndex (); int current_count = count (); // detect the mouse click if ((me->type () == QEvent::MouseButtonDblClick && me->button() == Qt::LeftButton) || (me->type () != QEvent::MouseButtonDblClick && me->button() == Qt::MiddleButton)) { // Middle click or double click -> close the tab // Make the clicked tab the current one and close it setCurrentIndex (clicked_idx); emit close_current_tab_signal (true); // Was the closed tab before or after the previously current tab? // According to the result, use previous index or reduce it by one if (current_idx - clicked_idx > 0) setCurrentIndex (current_idx - 1); else if (current_idx - clicked_idx < 0) setCurrentIndex (current_idx); } else if (me->type () != QEvent::MouseButtonDblClick && me->button() == Qt::RightButton) { // Right click, show context menu setCurrentIndex (clicked_idx); // Fill context menu with actions for selecting current tabs m_ctx_actions = m_context_menu->actions (); // Copy of basic actions QMenu ctx_menu; // The menu actually used connect (&ctx_menu, &QMenu::triggered, this, &tab_bar::ctx_menu_activated); for (int i = count () - 1; i >= 0; i--) { // Prepend an action for each tab QAction *a = new QAction (tabIcon (i), tabText (i), &ctx_menu); m_ctx_actions.prepend (a); } // Add all actions to our menu ctx_menu.insertActions (nullptr, m_ctx_actions); if (! ctx_menu.exec (click_pos)) { // No action selected, back to previous tab setCurrentIndex (current_idx); } else if (count () < current_count) { // A tab was closed: // Was the possibly only closed tab before or after the // previously current tab? According to the result, use previous // index or reduce it by one. Also prevent using a too large // index if other or all files were closed. int new_idx = count () - 1; if (new_idx > 0) { if (current_idx - clicked_idx > 0) new_idx = current_idx - 1; else if (current_idx - clicked_idx < 0) new_idx = current_idx; } if (new_idx >= 0) setCurrentIndex (new_idx); } } else { // regular handling of the mouse event QTabBar::mousePressEvent (me); } } else { // regular handling of the mouse event QTabBar::mousePressEvent (me); } } // Slot if a menu entry in the context menu is activated void tab_bar::ctx_menu_activated (QAction *a) { // If the index of the activated action is in the range of // the current tabs, set the related current tab. The basic actions // are handled by the editor int i = m_ctx_actions.indexOf (a); if ((i > -1) && (i < count ())) setCurrentIndex (i); } OCTAVE_END_NAMESPACE(octave)