KDDockWidgets API Documentation  1.5
TabWidgetWidget.cpp
Go to the documentation of this file.
1 /*
2  This file is part of KDDockWidgets.
3 
4  SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
5  Author: SĂ©rgio Martins <sergio.martins@kdab.com>
6 
7  SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
8 
9  Contact KDAB at <info@kdab.com> for commercial licensing options.
10 */
11 
19 #include "TabWidgetWidget_p.h"
20 #include "Config.h"
21 #include "FrameworkWidgetFactory.h"
22 #include "../Frame_p.h"
23 #include "../TitleBar_p.h"
24 #include "../DockRegistry_p.h"
25 
26 #include <QMouseEvent>
27 #include <QTabBar>
28 #include <QHBoxLayout>
29 #include <QAbstractButton>
30 #include <QMenu>
31 
32 using namespace KDDockWidgets;
33 
34 TabWidgetWidget::TabWidgetWidget(Frame *parent)
35  : QTabWidget(parent)
36  , TabWidget(this, parent)
37  , m_tabBar(Config::self().frameworkWidgetFactory()->createTabBar(this))
38 {
39  setTabBar(static_cast<QTabBar *>(m_tabBar->asWidget()));
40  setTabsClosable(Config::self().flags() & Config::Flag_TabsHaveCloseButton);
41 
42  setContextMenuPolicy(Qt::CustomContextMenu);
43  connect(this, &QTabWidget::customContextMenuRequested, this, &TabWidgetWidget::showContextMenu);
44 
45  // In case tabs closable is set by the factory, a tabClosedRequested() is emitted when the user presses [x]
46  connect(this, &QTabWidget::tabCloseRequested, this, [this](int index) {
47  if (DockWidgetBase *dw = dockwidgetAt(index)) {
48  if (dw->options() & DockWidgetBase::Option_NotClosable) {
49  qWarning() << "QTabWidget::tabCloseRequested: Refusing to close dock widget with Option_NotClosable option. name=" << dw->uniqueName();
50  } else {
51  dw->close();
52  }
53  } else {
54  qWarning() << "QTabWidget::tabCloseRequested Couldn't find dock widget for index" << index << "; count=" << count();
55  }
56  });
57 
58  connect(this, &QTabWidget::currentChanged, this, [this](int index) {
59  onCurrentTabChanged(index);
60  Q_EMIT currentTabChanged(index);
61  Q_EMIT currentDockWidgetChanged(currentDockWidget());
62  });
63 
64  if (!QTabWidget::tabBar()->isVisible())
65  setFocusProxy(nullptr);
66 
67  setupTabBarButtons();
68 }
69 
70 TabBar *TabWidgetWidget::tabBar() const
71 {
72  return m_tabBar;
73 }
74 
75 int TabWidgetWidget::numDockWidgets() const
76 {
77  return count();
78 }
79 
80 void TabWidgetWidget::removeDockWidget(DockWidgetBase *dw)
81 {
82  removeTab(indexOf(dw));
83 }
84 
85 int TabWidgetWidget::indexOfDockWidget(const DockWidgetBase *dw) const
86 {
87  return indexOf(const_cast<DockWidgetBase *>(dw));
88 }
89 
90 void TabWidgetWidget::mouseDoubleClickEvent(QMouseEvent *ev)
91 {
92  if (onMouseDoubleClick(ev->pos())) {
93  ev->accept();
94  } else {
95  ev->ignore();
96  }
97 }
98 
99 void TabWidgetWidget::mousePressEvent(QMouseEvent *ev)
100 {
102 
103  if ((Config::self().flags() & Config::Flag_TitleBarIsFocusable) && !frame()->isFocused()) {
104  // User clicked on the tab widget itself
105  frame()->FocusScope::focus(Qt::MouseFocusReason);
106  }
107 }
108 
109 void TabWidgetWidget::tabInserted(int)
110 {
111  onTabInserted();
112 }
113 
114 void TabWidgetWidget::tabRemoved(int)
115 {
116  onTabRemoved();
117 }
118 
119 bool TabWidgetWidget::isPositionDraggable(QPoint p) const
120 {
121  if (tabPosition() != QTabWidget::North) {
122  qWarning() << Q_FUNC_INFO << "Not implemented yet. Only North is supported";
123  return false;
124  }
125 
126  return p.y() >= 0 && p.y() <= QTabWidget::tabBar()->height();
127 }
128 
129 void TabWidgetWidget::setCurrentDockWidget(int index)
130 {
131  setCurrentIndex(index);
132 }
133 
134 bool TabWidgetWidget::insertDockWidget(int index, DockWidgetBase *dw,
135  const QIcon &icon, const QString &title)
136 {
137  insertTab(index, dw, icon, title);
138  return true;
139 }
140 
141 void TabWidgetWidget::setTabBarAutoHide(bool b)
142 {
144 }
145 
146 void TabWidgetWidget::renameTab(int index, const QString &text)
147 {
148  setTabText(index, text);
149 }
150 
151 void TabWidgetWidget::changeTabIcon(int index, const QIcon &icon)
152 {
153  setTabIcon(index, icon);
154 }
155 
156 DockWidgetBase *TabWidgetWidget::dockwidgetAt(int index) const
157 {
158  return qobject_cast<DockWidgetBase *>(widget(index));
159 }
160 
161 int TabWidgetWidget::currentIndex() const
162 {
163  return QTabWidget::currentIndex();
164 }
165 
166 void TabWidgetWidget::setupTabBarButtons()
167 {
168  if (!(Config::self().flags() & Config::Flag_ShowButtonsOnTabBarIfTitleBarHidden))
169  return;
170 
171  auto factory = Config::self().frameworkWidgetFactory();
172  m_closeButton = factory->createTitleBarButton(this, TitleBarButtonType::Close);
173  m_floatButton = factory->createTitleBarButton(this, TitleBarButtonType::Float);
174 
175  auto cornerWidget = new QWidget(this);
176  cornerWidget->setObjectName(QStringLiteral("Corner Widget"));
177 
178  setCornerWidget(cornerWidget, Qt::TopRightCorner);
179 
180  m_cornerWidgetLayout = new QHBoxLayout(cornerWidget);
181 
182  m_cornerWidgetLayout->addWidget(m_floatButton);
183  m_cornerWidgetLayout->addWidget(m_closeButton);
184 
185  connect(m_floatButton, &QAbstractButton::clicked, this, [this] {
186  TitleBar *tb = frame()->titleBar();
187  tb->onFloatClicked();
188  });
189 
190  connect(m_closeButton, &QAbstractButton::clicked, this, [this] {
191  TitleBar *tb = frame()->titleBar();
192  tb->onCloseClicked();
193  });
194 
195  updateMargins();
196  connect(DockRegistry::self(), &DockRegistry::windowChangedScreen, this, [this](QWindow *w) {
197  if (w == window()->windowHandle())
198  updateMargins();
199  });
200 }
201 
202 void TabWidgetWidget::updateMargins()
203 {
204  const qreal factor = logicalDpiFactor(this);
205  m_cornerWidgetLayout->setContentsMargins(QMargins(0, 0, 2, 0) * factor);
206  m_cornerWidgetLayout->setSpacing(int(2 * factor));
207 }
208 
209 void TabWidgetWidget::showContextMenu(QPoint pos)
210 {
211  if (!(Config::self().flags() & Config::Flag_AllowSwitchingTabsViaMenu))
212  return;
213 
214  QTabBar *tabBar = QTabWidget::tabBar();
215  // We don't want context menu if there is only one tab
216  if (tabBar->count() <= 1)
217  return;
218 
219  // Click on a tab => No menu
220  if (tabBar->tabAt(pos) >= 0)
221  return;
222 
223  // Right click is allowed only on the tabs area
224  QRect tabAreaRect = tabBar->rect();
225  tabAreaRect.setWidth(this->width());
226  if (!tabAreaRect.contains(pos))
227  return;
228 
229  QMenu menu(this);
230  for (int i = 0; i < tabBar->count(); ++i) {
231  QAction *action = menu.addAction(tabText(i), this, [this, i] {
232  setCurrentIndex(i);
233  });
234  if (i == currentIndex())
235  action->setDisabled(true);
236  }
237  menu.exec(mapToGlobal(pos));
238 }
QTabWidget
QMouseEvent::pos
QPoint pos() const const
QTabBar::count
count
QRect::setWidth
void setWidth(int width)
QRect
QWidget::customContextMenuRequested
void customContextMenuRequested(const QPoint &pos)
QWidget::rect
rect
QTabBar
QTabWidget::setTabBarAutoHide
void setTabBarAutoHide(bool enabled)
QWindow
QAbstractButton::clicked
void clicked(bool checked)
QWidget
QMenu
Qt::CustomContextMenu
CustomContextMenu
QPoint::y
int y() const const
Qt::TopRightCorner
TopRightCorner
QTabBar::tabAt
int tabAt(const QPoint &position) const const
QRect::contains
bool contains(const QRect &rectangle, bool proper) const const
QMouseEvent
QTabWidget::North
North
QWidget::isVisible
bool isVisible() const const
Qt::MouseFocusReason
MouseFocusReason
QString
QTabWidget::currentChanged
void currentChanged(int index)
KDDockWidgets::Config
Singleton to allow to choose certain behaviours of the framework.
Definition: Config.h:55
QAction::setDisabled
void setDisabled(bool b)
QIcon
QMargins
Config.h
Application-wide config to tune certain behaviours of the framework.
QTabWidget::tabBar
QTabBar * tabBar() const const
QWidget::height
height
QHBoxLayout
QEvent::ignore
void ignore()
KDDockWidgets::DockWidgetBase
The DockWidget base-class. DockWidget and DockWidgetBase are only split in two so we can share some c...
Definition: DockWidgetBase.h:61
QTabWidget::currentIndex
currentIndex
QAction
KDDockWidgets
Definition: Config.cpp:36
QPoint
QEvent::accept
void accept()
FrameworkWidgetFactory.h
A factory class for allowing the user to customize some internal widgets.
QTabWidget::tabCloseRequested
void tabCloseRequested(int index)
QWidget::mousePressEvent
virtual void mousePressEvent(QMouseEvent *event)

© 2019-2022 Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
KDDockWidgets
Advanced Dock Widget Framework for Qt
https://www.kdab.com/development-resources/qt-tools/kddockwidgets/
Generated on Mon Mar 7 2022 02:01:21 for KDDockWidgets API Documentation by doxygen 1.8.20