KDDockWidgets API Documentation  1.5
TabWidgetQuick.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 
12 #include "TabWidgetQuick_p.h"
13 #include "Config.h"
14 #include "FrameworkWidgetFactory.h"
15 
16 #include "../Frame_p.h"
17 
18 #include <QDebug>
19 #include <QScopedValueRollback>
20 
21 using namespace KDDockWidgets;
22 
23 TabWidgetQuick::TabWidgetQuick(Frame *parent)
24  : QWidgetAdapter(parent)
25  , TabWidget(this, parent)
26  , m_dockWidgetModel(new DockWidgetModel(this))
27  , m_tabBar(Config::self().frameworkWidgetFactory()->createTabBar(this))
28 {
29  connect(m_dockWidgetModel, &DockWidgetModel::countChanged, this,
30  [this] {
31  if (m_currentDockWidget && indexOfDockWidget(m_currentDockWidget) == -1) {
32  // The current dock widget was removed, set the first one as current
33  if (numDockWidgets() > 0)
34  setCurrentDockWidget(0);
35  }
36 
37  Q_EMIT countChanged(); });
38 }
39 
40 TabBar *TabWidgetQuick::tabBar() const
41 {
42  return m_tabBar;
43 }
44 
45 int TabWidgetQuick::numDockWidgets() const
46 {
47  return m_dockWidgetModel->count();
48 }
49 
50 void TabWidgetQuick::removeDockWidget(DockWidgetBase *dw)
51 {
52  m_dockWidgetModel->remove(dw);
53 }
54 
55 int TabWidgetQuick::indexOfDockWidget(const DockWidgetBase *dw) const
56 {
57  return m_dockWidgetModel->indexOf(dw);
58 }
59 
60 bool TabWidgetQuick::isPositionDraggable(QPoint p) const
61 {
62  Q_UNUSED(p);
63  return true;
64 }
65 
66 void TabWidgetQuick::setCurrentDockWidget(int index)
67 {
68  DockWidgetBase *dw = dockwidgetAt(index);
69 
70  if (m_currentDockWidget != dw) {
71  m_currentDockWidget = dw;
72  Q_EMIT currentDockWidgetChanged(dw);
73  Q_EMIT currentTabChanged(index);
74  }
75 }
76 
77 QObject *TabWidgetQuick::tabBarObj() const
78 {
79  return m_tabBar->asWidget();
80 }
81 
82 bool TabWidgetQuick::insertDockWidget(int index, DockWidgetBase *dw, const QIcon &, const QString &title)
83 {
84  Q_UNUSED(title); // todo
85  return m_dockWidgetModel->insert(dw, index);
86 }
87 
88 void TabWidgetQuick::setTabBarAutoHide(bool)
89 {
90  qWarning() << Q_FUNC_INFO << "Not implemented";
91 }
92 
93 void TabWidgetQuick::renameTab(int index, const QString &)
94 {
95  Q_UNUSED(index);
96  qWarning() << Q_FUNC_INFO << "Not implemented";
97 }
98 
99 void TabWidgetQuick::changeTabIcon(int index, const QIcon &)
100 {
101  Q_UNUSED(index);
102  qWarning() << Q_FUNC_INFO << "Not implemented";
103 }
104 
105 DockWidgetBase *TabWidgetQuick::dockwidgetAt(int index) const
106 {
107  return m_dockWidgetModel->dockWidgetAt(index);
108 }
109 
110 int TabWidgetQuick::currentIndex() const
111 {
112  if (!m_currentDockWidget)
113  return -1;
114 
115  const int index = indexOfDockWidget(m_currentDockWidget);
116 
117  if (index == -1)
118  qWarning() << Q_FUNC_INFO << "Unexpected null index for" << m_currentDockWidget << this
119  << "; count=" << m_dockWidgetModel->count();
120 
121  return index;
122 }
123 
124 DockWidgetModel *TabWidgetQuick::dockWidgetModel() const
125 {
126  return m_dockWidgetModel;
127 }
128 
129 DockWidgetModel::DockWidgetModel(QObject *parent)
130  : QAbstractListModel(parent)
131 {
132 }
133 
134 int DockWidgetModel::count() const
135 {
136  return m_dockWidgets.size();
137 }
138 
139 int DockWidgetModel::rowCount(const QModelIndex &parent) const
140 {
141  return parent.isValid() ? 0 : m_dockWidgets.size();
142 }
143 
144 QVariant DockWidgetModel::data(const QModelIndex &index, int role) const
145 {
146  const int row = index.row();
147  if (row < 0 || row >= m_dockWidgets.size())
148  return {};
149 
150  DockWidgetBase *dw = m_dockWidgets.at(row);
151 
152  switch (role) {
153  case Role_Title:
154  return dw->title();
155  }
156 
157  return {};
158 }
159 
160 DockWidgetBase *DockWidgetModel::dockWidgetAt(int index) const
161 {
162  if (index < 0 || index >= m_dockWidgets.size()) {
163  // Can happen. Benign.
164  return nullptr;
165  }
166 
167  return m_dockWidgets[index];
168 }
169 
170 bool DockWidgetModel::contains(DockWidgetBase *dw) const
171 {
172  return m_dockWidgets.contains(dw);
173 }
174 
175 QHash<int, QByteArray> DockWidgetModel::roleNames() const
176 {
177  return { { Role_Title, "title" } };
178 }
179 
180 void DockWidgetModel::emitDataChangedFor(DockWidgetBase *dw)
181 {
182  const int row = indexOf(dw);
183  if (row == -1) {
184  qWarning() << Q_FUNC_INFO << "Couldn't find" << dw;
185  } else {
186  QModelIndex index = this->index(row, 0);
187  Q_EMIT dataChanged(index, index);
188  }
189 }
190 
191 void DockWidgetModel::remove(DockWidgetBase *dw)
192 {
193  QScopedValueRollback<bool> guard(m_removeGuard, true);
194  const int row = indexOf(dw);
195  if (row == -1) {
196  if (!m_removeGuard) {
197  // can happen if there's reentrancy. Some user code reacting
198  // to the signals and call remove for whatever reason.
199  qWarning() << Q_FUNC_INFO << "Nothing to remove"
200  << static_cast<void *>(dw); // Print address only, as it might be deleted already
201  }
202  } else {
203  const auto connections = m_connections.take(dw);
204  for (const QMetaObject::Connection &conn : connections)
205  disconnect(conn);
206 
207  beginRemoveRows(QModelIndex(), row, row);
208  m_dockWidgets.removeOne(dw);
209  endRemoveRows();
210 
211  Q_EMIT countChanged();
212  }
213 }
214 
215 int DockWidgetModel::indexOf(const DockWidgetBase *dw)
216 {
217  return m_dockWidgets.indexOf(const_cast<DockWidgetBase *>(dw));
218 }
219 
220 bool DockWidgetModel::insert(DockWidgetBase *dw, int index)
221 {
222  if (m_dockWidgets.contains(dw)) {
223  qWarning() << Q_FUNC_INFO << "Shouldn't happen";
224  return false;
225  }
226 
227  QMetaObject::Connection conn = connect(dw, &DockWidgetBase::titleChanged, this, [dw, this] {
228  emitDataChangedFor(dw);
229  });
230 
231  QMetaObject::Connection conn2 = connect(dw, &QObject::destroyed, this, [dw, this] {
232  remove(dw);
233  });
234 
235  m_connections[dw] = { conn, conn2 };
236 
237  beginInsertRows(QModelIndex(), index, index);
238  m_dockWidgets.insert(index, dw);
239  endInsertRows();
240 
241  Q_EMIT countChanged();
242  return true;
243 }
QMetaObject::Connection
QAbstractListModel
KDDockWidgets::DockWidgetBase::title
QString title
Definition: DockWidgetBase.h:66
QObject::destroyed
void destroyed(QObject *obj)
QObject
QString
KDDockWidgets::Config
Singleton to allow to choose certain behaviours of the framework.
Definition: Config.h:55
QIcon
QModelIndex::isValid
bool isValid() const const
QModelIndex::row
int row() const const
Config.h
Application-wide config to tune certain behaviours of the framework.
KDDockWidgets::DockWidgetBase
The DockWidget base-class. DockWidget and DockWidgetBase are only split in two so we can share some c...
Definition: DockWidgetBase.h:61
KDDockWidgets
Definition: Config.cpp:36
QScopedValueRollback
QModelIndex
QVariant
QHash
QPoint
FrameworkWidgetFactory.h
A factory class for allowing the user to customize some internal widgets.

© 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