KWidgetsAddons

kpagewidgetmodel.cpp
1 /*
2  This file is part of the KDE Libraries
3  SPDX-FileCopyrightText: 2006 Tobias Koenig <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #include "kpagewidgetmodel.h"
9 #include "kpagewidgetmodel_p.h"
10 
11 #include "loggingcategory.h"
12 
13 #include <QPointer>
14 #include <QWidget>
15 
16 #include <QIcon>
17 
18 class KPageWidgetItemPrivate
19 {
20 public:
21  KPageWidgetItemPrivate()
22  : checkable(false)
23  , checked(false)
24  , enabled(true)
25  , headerVisible(true)
26  {
27  }
28 
29  ~KPageWidgetItemPrivate()
30  {
31  delete widget;
32  widget = nullptr;
33  }
34 
35  QString name;
36  QString header;
37  QIcon icon;
38  QPointer<QWidget> widget;
39  bool checkable : 1;
40  bool checked : 1;
41  bool enabled : 1;
42  bool headerVisible : 1;
43 };
44 
46  : QObject(nullptr)
47  , d(new KPageWidgetItemPrivate)
48 {
49  d->widget = widget;
50 
51  // Hide the widget, otherwise when the widget has this KPageView as
52  // parent the widget is shown outside the QStackedWidget if the page
53  // was not selected ( and reparented ) yet.
54  if (d->widget) {
55  d->widget->hide();
56  }
57 }
58 
60  : QObject(nullptr)
61  , d(new KPageWidgetItemPrivate)
62 {
63  d->widget = widget;
64  d->name = name;
65 
66  // Hide the widget, otherwise when the widget has this KPageView as
67  // parent the widget is shown outside the QStackedWidget if the page
68  // was not selected ( and reparented ) yet.
69  if (d->widget) {
70  d->widget->hide();
71  }
72 }
73 
75 
77 {
78  d->enabled = enabled;
79  if (d->widget) {
80  d->widget->setEnabled(enabled);
81  }
82  Q_EMIT changed();
83 }
84 
86 {
87  return d->enabled;
88 }
89 
91 {
92  return d->headerVisible;
93 }
94 
96 {
97  d->headerVisible = visible;
98 
99  Q_EMIT changed();
100 }
101 
103 {
104  return d->widget;
105 }
106 
108 {
109  d->name = name;
110 
111  Q_EMIT changed();
112 }
113 
115 {
116  return d->name;
117 }
118 
120 {
121  const bool autoHeaderInvisibilityTriggered = header.isEmpty() & !header.isNull();
122  if (autoHeaderInvisibilityTriggered) {
123  qCWarning(KWidgetsAddonsLog)
124  << "KPageWidgetItem::setHeader() called with empty non-null string, which is deprecated. Use KPageWidgetItem::setHeaderVisible(false) instead.";
125  }
126 
127  d->header = header;
128 
129  Q_EMIT changed();
130 }
131 
133 {
134  return d->header;
135 }
136 
138 {
139  d->icon = icon;
140 
141  Q_EMIT changed();
142 }
143 
145 {
146  return d->icon;
147 }
148 
149 void KPageWidgetItem::setCheckable(bool checkable)
150 {
151  d->checkable = checkable;
152 
153  Q_EMIT changed();
154 }
155 
157 {
158  return d->checkable;
159 }
160 
161 void KPageWidgetItem::setChecked(bool checked)
162 {
163  d->checked = checked;
164 
165  Q_EMIT toggled(checked);
166  Q_EMIT changed();
167 }
168 
170 {
171  return d->checked;
172 }
173 
174 PageItem::PageItem(KPageWidgetItem *pageWidgetItem, PageItem *parent)
175  : mPageWidgetItem(pageWidgetItem)
176  , mParentItem(parent)
177 {
178 }
179 
180 PageItem::~PageItem()
181 {
182  delete mPageWidgetItem;
183  mPageWidgetItem = nullptr;
184 
185  qDeleteAll(mChildItems);
186 }
187 
188 void PageItem::appendChild(PageItem *item)
189 {
190  mChildItems.append(item);
191 }
192 
193 void PageItem::insertChild(int row, PageItem *item)
194 {
195  mChildItems.insert(row, item);
196 }
197 
198 void PageItem::removeChild(int row)
199 {
200  mChildItems.removeAt(row);
201 }
202 
203 PageItem *PageItem::child(int row)
204 {
205  return mChildItems.value(row);
206 }
207 
208 int PageItem::childCount() const
209 {
210  return mChildItems.count();
211 }
212 
213 int PageItem::columnCount() const
214 {
215  return 1;
216 }
217 
218 PageItem *PageItem::parent()
219 {
220  return mParentItem;
221 }
222 
223 int PageItem::row() const
224 {
225  if (mParentItem) {
226  return mParentItem->mChildItems.indexOf(const_cast<PageItem *>(this));
227  }
228 
229  return 0;
230 }
231 
232 KPageWidgetItem *PageItem::pageWidgetItem() const
233 {
234  return mPageWidgetItem;
235 }
236 
237 PageItem *PageItem::findChild(const KPageWidgetItem *item)
238 {
239  if (mPageWidgetItem == item) {
240  return this;
241  }
242 
243  for (int i = 0; i < mChildItems.count(); ++i) {
244  PageItem *pageItem = mChildItems[i]->findChild(item);
245  if (pageItem) {
246  return pageItem;
247  }
248  }
249 
250  return nullptr;
251 }
252 
253 void PageItem::dump(int indent)
254 {
255  const QString indentation(indent, QLatin1Char(' '));
256 
257  const QString name = (mPageWidgetItem ? mPageWidgetItem->name() : QStringLiteral("root"));
258  qCDebug(KWidgetsAddonsLog, "%s (%p)", qPrintable(QString(indentation + name)), (void *)this);
259  for (int i = 0; i < mChildItems.count(); ++i) {
260  mChildItems[i]->dump(indent + 2);
261  }
262 }
263 
265  : KPageModel(*new KPageWidgetModelPrivate, parent)
266 {
267 }
268 
270 {
271 }
272 
274 {
275  return 1;
276 }
277 
278 QVariant KPageWidgetModel::data(const QModelIndex &index, int role) const
279 {
280  if (!index.isValid()) {
281  return QVariant();
282  }
283 
284  PageItem *item = static_cast<PageItem *>(index.internalPointer());
285 
286  if (role == Qt::DisplayRole) {
287  return QVariant(item->pageWidgetItem()->name());
288  } else if (role == Qt::DecorationRole) {
289  return QVariant(item->pageWidgetItem()->icon());
290  } else if (role == HeaderRole) {
291  return QVariant(item->pageWidgetItem()->header());
292  } else if (role == HeaderVisibleRole) {
293  return item->pageWidgetItem()->isHeaderVisible();
294  } else if (role == WidgetRole) {
295  return QVariant::fromValue(item->pageWidgetItem()->widget());
296  } else if (role == Qt::CheckStateRole) {
297  if (item->pageWidgetItem()->isCheckable()) {
298  return (item->pageWidgetItem()->isChecked() ? Qt::Checked : Qt::Unchecked);
299  } else {
300  return QVariant();
301  }
302  } else {
303  return QVariant();
304  }
305 }
306 
307 bool KPageWidgetModel::setData(const QModelIndex &index, const QVariant &value, int role)
308 {
309  if (!index.isValid()) {
310  return false;
311  }
312 
313  if (role != Qt::CheckStateRole) {
314  return false;
315  }
316 
317  PageItem *item = static_cast<PageItem *>(index.internalPointer());
318  if (!item) {
319  return false;
320  }
321 
322  if (!item->pageWidgetItem()->isCheckable()) {
323  return false;
324  }
325 
326  if (value.toInt() == Qt::Checked) {
327  item->pageWidgetItem()->setChecked(true);
328  } else {
329  item->pageWidgetItem()->setChecked(false);
330  }
331 
332  return true;
333 }
334 
335 Qt::ItemFlags KPageWidgetModel::flags(const QModelIndex &index) const
336 {
337  if (!index.isValid()) {
338  return Qt::NoItemFlags;
339  }
340 
342 
343  PageItem *item = static_cast<PageItem *>(index.internalPointer());
344  if (item->pageWidgetItem()->isCheckable()) {
345  flags |= Qt::ItemIsUserCheckable;
346  }
347  if (item->pageWidgetItem()->isEnabled()) {
348  flags |= Qt::ItemIsEnabled;
349  }
350 
351  return flags;
352 }
353 
354 QModelIndex KPageWidgetModel::index(int row, int column, const QModelIndex &parent) const
355 {
356  Q_D(const KPageWidgetModel);
357 
358  PageItem *parentItem;
359 
360  if (parent.isValid()) {
361  parentItem = static_cast<PageItem *>(parent.internalPointer());
362  } else {
363  parentItem = d->rootItem;
364  }
365 
366  PageItem *childItem = parentItem->child(row);
367  if (childItem) {
368  return createIndex(row, column, childItem);
369  } else {
370  return QModelIndex();
371  }
372 }
373 
375 {
376  Q_D(const KPageWidgetModel);
377 
378  if (!index.isValid()) {
379  return QModelIndex();
380  }
381 
382  PageItem *item = static_cast<PageItem *>(index.internalPointer());
383  PageItem *parentItem = item->parent();
384 
385  if (parentItem == d->rootItem) {
386  return QModelIndex();
387  } else {
388  return createIndex(parentItem->row(), 0, parentItem);
389  }
390 }
391 
392 int KPageWidgetModel::rowCount(const QModelIndex &parent) const
393 {
394  Q_D(const KPageWidgetModel);
395 
396  PageItem *parentItem;
397 
398  if (!parent.isValid()) {
399  parentItem = d->rootItem;
400  } else {
401  parentItem = static_cast<PageItem *>(parent.internalPointer());
402  }
403 
404  return parentItem->childCount();
405 }
406 
408 {
409  KPageWidgetItem *item = new KPageWidgetItem(widget, name);
410 
411  addPage(item);
412 
413  return item;
414 }
415 
417 {
419 
421  connect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged()));
422  connect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool)));
423 
424  // The row to be inserted
425  int row = d->rootItem->childCount();
426 
427  beginInsertRows(QModelIndex(), row, row);
428 
429  PageItem *pageItem = new PageItem(item, d->rootItem);
430  d->rootItem->appendChild(pageItem);
431 
432  endInsertRows();
433 
435 }
436 
438 {
439  KPageWidgetItem *item = new KPageWidgetItem(widget, name);
440 
441  insertPage(before, item);
442 
443  return item;
444 }
445 
447 {
449 
450  PageItem *beforePageItem = d->rootItem->findChild(before);
451  if (!beforePageItem) {
452  qCDebug(KWidgetsAddonsLog, "Invalid KPageWidgetItem passed!");
453  return;
454  }
455 
457 
458  connect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged()));
459  connect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool)));
460 
461  PageItem *parent = beforePageItem->parent();
462  // The row to be inserted
463  int row = beforePageItem->row();
464 
465  QModelIndex index;
466  if (parent != d->rootItem) {
467  index = createIndex(parent->row(), 0, parent);
468  }
469 
470  beginInsertRows(index, row, row);
471 
472  PageItem *newPageItem = new PageItem(item, parent);
473  parent->insertChild(row, newPageItem);
474 
475  endInsertRows();
476 
478 }
479 
481 {
482  KPageWidgetItem *item = new KPageWidgetItem(widget, name);
483 
484  addSubPage(parent, item);
485 
486  return item;
487 }
488 
490 {
492 
493  PageItem *parentPageItem = d->rootItem->findChild(parent);
494  if (!parentPageItem) {
495  qCDebug(KWidgetsAddonsLog, "Invalid KPageWidgetItem passed!");
496  return;
497  }
498 
500 
501  connect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged()));
502  connect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool)));
503 
504  // The row to be inserted
505  int row = parentPageItem->childCount();
506 
507  QModelIndex index;
508  if (parentPageItem != d->rootItem) {
509  index = createIndex(parentPageItem->row(), 0, parentPageItem);
510  }
511 
512  beginInsertRows(index, row, row);
513 
514  PageItem *newPageItem = new PageItem(item, parentPageItem);
515  parentPageItem->appendChild(newPageItem);
516 
517  endInsertRows();
518 
520 }
521 
523 {
524  if (!item) {
525  return;
526  }
527 
529 
530  PageItem *pageItem = d->rootItem->findChild(item);
531  if (!pageItem) {
532  qCDebug(KWidgetsAddonsLog, "Invalid KPageWidgetItem passed!");
533  return;
534  }
535 
537 
538  disconnect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged()));
539  disconnect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool)));
540 
541  PageItem *parentPageItem = pageItem->parent();
542  int row = parentPageItem->row();
543 
544  QModelIndex index;
545  if (parentPageItem != d->rootItem) {
546  index = createIndex(row, 0, parentPageItem);
547  }
548 
549  beginRemoveRows(index, pageItem->row(), pageItem->row());
550 
551  parentPageItem->removeChild(pageItem->row());
552  delete pageItem;
553 
554  endRemoveRows();
555 
557 }
558 
560 {
561  if (!index.isValid()) {
562  return nullptr;
563  }
564 
565  PageItem *item = static_cast<PageItem *>(index.internalPointer());
566  if (!item) {
567  return nullptr;
568  }
569 
570  return item->pageWidgetItem();
571 }
572 
573 QModelIndex KPageWidgetModel::index(const KPageWidgetItem *item) const
574 {
575  Q_D(const KPageWidgetModel);
576 
577  if (!item) {
578  return QModelIndex();
579  }
580 
581  const PageItem *pageItem = d->rootItem->findChild(item);
582  if (!pageItem) {
583  return QModelIndex();
584  }
585 
586  return createIndex(pageItem->row(), 0, (void *)pageItem);
587 }
588 
589 #include "moc_kpagewidgetmodel.cpp"
QString header() const
Returns the header of the page widget item.
void changed()
This signal is emitted whenever the icon or header is changed.
~KPageWidgetItem() override
Destroys the page widget item.
void layoutChanged(const QList< QPersistentModelIndex > &parents, QAbstractItemModel::LayoutChangeHint hint)
bool isHeaderVisible() const
Returns whether the page will show the header title.
void setChecked(bool checked)
Sets whether the page widget item is checked.
QString name() const
Returns the name of the page widget item.
KPageWidgetItem(QWidget *widget)
Creates a new page widget item.
~KPageWidgetModel() override
Destroys the page widget model.
void setHeaderVisible(bool visible)
Set whether the page should show the header title.
int columnCount(const QModelIndex &parent=QModelIndex()) const override
These methods are reimplemented from QAbstractItemModel.
A base class for a model used by KPageView.
Definition: kpagemodel.h:46
const QLatin1String name
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
void setEnabled(bool)
Sets whether the page widget item is enabled.
This page model is used by KPageWidget to provide a hierarchical layout of pages. ...
bool isNull() const const
void toggled(bool checked)
This signal is emitted whenever the user checks or unchecks the item of setChecked() is called...
void layoutAboutToBeChanged(const QList< QPersistentModelIndex > &parents, QAbstractItemModel::LayoutChangeHint hint)
bool isValid() const const
int toInt(bool *ok) const const
QIcon icon() const
Returns the icon of the page widget item.
KPageWidgetModel(QObject *parent=nullptr)
Creates a new page widget model.
when true, show the page header, if false don&#39;t
Definition: kpagemodel.h:75
bool enabled
This property holds whether the item is enabled.
bool isEnabled() const
Returns whether the page widget item is enabled.
DisplayRole
bool isEmpty() const const
void beginRemoveRows(const QModelIndex &parent, int first, int last)
int row() const const
void setIcon(const QIcon &icon)
Sets the icon of the page widget item.
KPageWidgetItem * addSubPage(KPageWidgetItem *parent, QWidget *widget, const QString &name)
Inserts a new sub page in the model.
void * internalPointer() const const
bool isChecked() const
Returns whether the page widget item is checked.
A string to be rendered as page header.
Definition: kpagemodel.h:59
void removePage(KPageWidgetItem *item)
Removes the page associated with the given KPageWidgetItem.
QModelIndex parent() const const
QModelIndex createIndex(int row, int column, void *ptr) const const
QWidget * widget() const
Returns the widget of the page widget item.
QVariant fromValue(const T &value)
KPageWidgetItem * item(const QModelIndex &index) const
Returns the KPageWidgetItem for a given index or a null pointer if the index is invalid.
A pointer to the page widget.
Definition: kpagemodel.h:70
void beginInsertRows(const QModelIndex &parent, int first, int last)
bool isCheckable() const
Returns whether the page widget item is checkable.
KPageWidgetItem is used by KPageWidget and represents a page.
Q_D(Todo)
void toggled(KPageWidgetItem *page, bool checked)
This signal is emitted whenever a checkable page changes its state.
void setHeader(const QString &header)
Sets the header of the page widget item.
void setName(const QString &name)
Sets the name of the item as shown in the navigation view of the page widget.
KPageWidgetItem * addPage(QWidget *widget, const QString &name)
Adds a new top level page to the model.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
void setCheckable(bool checkable)
Sets whether the page widget item is checkable in the view.
Q_EMITQ_EMIT
KPageWidgetItem * insertPage(KPageWidgetItem *before, QWidget *widget, const QString &name)
Inserts a new page in the model.
typedef ItemFlags
T findChild(const QString &name, Qt::FindChildOptions options) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Mon Jan 17 2022 22:40:44 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.