KWidgetsAddons

kpagewidgetmodel.cpp
1/*
2 This file is part of the KDE Libraries
3 SPDX-FileCopyrightText: 2006 Tobias Koenig <tokoe@kde.org>
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
18class KPageWidgetItemPrivate
19{
20public:
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 }
83}
84
86{
87 return d->enabled;
88}
89
91{
92 return d->headerVisible;
93}
94
96{
97 d->headerVisible = visible;
98
100}
101
103{
104 return d->widget;
105}
106
108{
109 d->name = name;
110
111 Q_EMIT changed();
112}
113
114QString KPageWidgetItem::name() const
115{
116 return d->name;
117}
118
120{
121 d->header = header;
122
123 Q_EMIT changed();
124}
125
126QString KPageWidgetItem::header() const
127{
128 return d->header;
129}
130
132{
133 d->icon = icon;
134
135 Q_EMIT changed();
136}
137
138QIcon KPageWidgetItem::icon() const
139{
140 return d->icon;
141}
142
144{
145 d->checkable = checkable;
146
147 Q_EMIT changed();
148}
149
151{
152 return d->checkable;
153}
154
156{
157 d->checked = checked;
158
159 Q_EMIT toggled(checked);
160 Q_EMIT changed();
161}
162
164{
165 return d->checked;
166}
167
168PageItem::PageItem(KPageWidgetItem *pageWidgetItem, PageItem *parent)
169 : mPageWidgetItem(pageWidgetItem)
170 , mParentItem(parent)
171{
172}
173
174PageItem::~PageItem()
175{
176 delete mPageWidgetItem;
177 mPageWidgetItem = nullptr;
178
179 qDeleteAll(mChildItems);
180}
181
182void PageItem::appendChild(PageItem *item)
183{
184 mChildItems.append(item);
185}
186
187void PageItem::insertChild(int row, PageItem *item)
188{
189 mChildItems.insert(row, item);
190}
191
192void PageItem::removeChild(int row)
193{
194 mChildItems.removeAt(row);
195}
196
197PageItem *PageItem::child(int row)
198{
199 return mChildItems.value(row);
200}
201
202int PageItem::childCount() const
203{
204 return mChildItems.count();
205}
206
207int PageItem::columnCount() const
208{
209 return 1;
210}
211
212PageItem *PageItem::parent()
213{
214 return mParentItem;
215}
216
217int PageItem::row() const
218{
219 if (mParentItem) {
220 return mParentItem->mChildItems.indexOf(const_cast<PageItem *>(this));
221 }
222
223 return 0;
224}
225
226KPageWidgetItem *PageItem::pageWidgetItem() const
227{
228 return mPageWidgetItem;
229}
230
231PageItem *PageItem::findChild(const KPageWidgetItem *item)
232{
233 if (mPageWidgetItem == item) {
234 return this;
235 }
236
237 for (int i = 0; i < mChildItems.count(); ++i) {
238 PageItem *pageItem = mChildItems[i]->findChild(item);
239 if (pageItem) {
240 return pageItem;
241 }
242 }
243
244 return nullptr;
245}
246
247void PageItem::dump(int indent)
248{
249 const QString indentation(indent, QLatin1Char(' '));
250
251 const QString name = (mPageWidgetItem ? mPageWidgetItem->name() : QStringLiteral("root"));
252 qCDebug(KWidgetsAddonsLog, "%s (%p)", qPrintable(QString(indentation + name)), (void *)this);
253 for (int i = 0; i < mChildItems.count(); ++i) {
254 mChildItems[i]->dump(indent + 2);
255 }
256}
257
259 : KPageModel(*new KPageWidgetModelPrivate, parent)
260{
261}
262
266
268{
269 return 1;
270}
271
272QVariant KPageWidgetModel::data(const QModelIndex &index, int role) const
273{
274 if (!index.isValid()) {
275 return QVariant();
276 }
277
278 PageItem *item = static_cast<PageItem *>(index.internalPointer());
279
280 if (role == Qt::DisplayRole) {
281 return QVariant(item->pageWidgetItem()->name());
282 } else if (role == Qt::DecorationRole) {
283 return QVariant(item->pageWidgetItem()->icon());
284 } else if (role == HeaderRole) {
285 return QVariant(item->pageWidgetItem()->header());
286 } else if (role == HeaderVisibleRole) {
287 return item->pageWidgetItem()->isHeaderVisible();
288 } else if (role == WidgetRole) {
289 return QVariant::fromValue(item->pageWidgetItem()->widget());
290 } else if (role == Qt::CheckStateRole) {
291 if (item->pageWidgetItem()->isCheckable()) {
292 return (item->pageWidgetItem()->isChecked() ? Qt::Checked : Qt::Unchecked);
293 } else {
294 return QVariant();
295 }
296 } else {
297 return QVariant();
298 }
299}
300
301bool KPageWidgetModel::setData(const QModelIndex &index, const QVariant &value, int role)
302{
303 if (!index.isValid()) {
304 return false;
305 }
306
307 if (role != Qt::CheckStateRole) {
308 return false;
309 }
310
311 PageItem *item = static_cast<PageItem *>(index.internalPointer());
312 if (!item) {
313 return false;
314 }
315
316 if (!item->pageWidgetItem()->isCheckable()) {
317 return false;
318 }
319
320 if (value.toInt() == Qt::Checked) {
321 item->pageWidgetItem()->setChecked(true);
322 } else {
323 item->pageWidgetItem()->setChecked(false);
324 }
325
326 return true;
327}
328
329Qt::ItemFlags KPageWidgetModel::flags(const QModelIndex &index) const
330{
331 if (!index.isValid()) {
332 return Qt::NoItemFlags;
333 }
334
336
337 PageItem *item = static_cast<PageItem *>(index.internalPointer());
338 if (item->pageWidgetItem()->isCheckable()) {
340 }
341 if (item->pageWidgetItem()->isEnabled()) {
342 flags |= Qt::ItemIsEnabled;
343 }
344
345 return flags;
346}
347
348QModelIndex KPageWidgetModel::index(int row, int column, const QModelIndex &parent) const
349{
350 Q_D(const KPageWidgetModel);
351
352 PageItem *parentItem;
353
354 if (parent.isValid()) {
355 parentItem = static_cast<PageItem *>(parent.internalPointer());
356 } else {
357 parentItem = d->rootItem;
358 }
359
360 PageItem *childItem = parentItem->child(row);
361 if (childItem) {
362 return createIndex(row, column, childItem);
363 } else {
364 return QModelIndex();
365 }
366}
367
369{
370 Q_D(const KPageWidgetModel);
371
372 if (!index.isValid()) {
373 return QModelIndex();
374 }
375
376 PageItem *item = static_cast<PageItem *>(index.internalPointer());
377 PageItem *parentItem = item->parent();
378
379 if (parentItem == d->rootItem) {
380 return QModelIndex();
381 } else {
382 return createIndex(parentItem->row(), 0, parentItem);
383 }
384}
385
386int KPageWidgetModel::rowCount(const QModelIndex &parent) const
387{
388 Q_D(const KPageWidgetModel);
389
390 PageItem *parentItem;
391
392 if (!parent.isValid()) {
393 parentItem = d->rootItem;
394 } else {
395 parentItem = static_cast<PageItem *>(parent.internalPointer());
396 }
397
398 return parentItem->childCount();
399}
400
402{
403 KPageWidgetItem *item = new KPageWidgetItem(widget, name);
404
405 addPage(item);
406
407 return item;
408}
409
411{
413
415 connect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged()));
416 connect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool)));
417
418 // The row to be inserted
419 int row = d->rootItem->childCount();
420
421 beginInsertRows(QModelIndex(), row, row);
422
423 PageItem *pageItem = new PageItem(item, d->rootItem);
424 d->rootItem->appendChild(pageItem);
425
427
429}
430
432{
433 KPageWidgetItem *item = new KPageWidgetItem(widget, name);
434
435 insertPage(before, item);
436
437 return item;
438}
439
441{
443
444 PageItem *beforePageItem = d->rootItem->findChild(before);
445 if (!beforePageItem) {
446 qCDebug(KWidgetsAddonsLog, "Invalid KPageWidgetItem passed!");
447 return;
448 }
449
451
452 connect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged()));
453 connect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool)));
454
455 PageItem *parent = beforePageItem->parent();
456 // The row to be inserted
457 int row = beforePageItem->row();
458
459 QModelIndex index;
460 if (parent != d->rootItem) {
461 index = createIndex(parent->row(), 0, parent);
462 }
463
464 beginInsertRows(index, row, row);
465
467 parent->insertChild(row, newPageItem);
468
470
472}
473
475{
476 KPageWidgetItem *item = new KPageWidgetItem(widget, name);
477
479
480 return item;
481}
482
484{
486
487 PageItem *parentPageItem = d->rootItem->findChild(parent);
488 if (!parentPageItem) {
489 qCDebug(KWidgetsAddonsLog, "Invalid KPageWidgetItem passed!");
490 return;
491 }
492
494
495 connect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged()));
496 connect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool)));
497
498 // The row to be inserted
499 int row = parentPageItem->childCount();
500
501 QModelIndex index;
502 if (parentPageItem != d->rootItem) {
503 index = createIndex(parentPageItem->row(), 0, parentPageItem);
504 }
505
506 beginInsertRows(index, row, row);
507
509 parentPageItem->appendChild(newPageItem);
510
512
514}
515
517{
518 if (!item) {
519 return;
520 }
521
523
524 PageItem *pageItem = d->rootItem->findChild(item);
525 if (!pageItem) {
526 qCDebug(KWidgetsAddonsLog, "Invalid KPageWidgetItem passed!");
527 return;
528 }
529
531
532 disconnect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged()));
533 disconnect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool)));
534
535 PageItem *parentPageItem = pageItem->parent();
536 int row = parentPageItem->row();
537
538 QModelIndex index;
539 if (parentPageItem != d->rootItem) {
540 index = createIndex(row, 0, parentPageItem);
541 }
542
543 beginRemoveRows(index, pageItem->row(), pageItem->row());
544
545 parentPageItem->removeChild(pageItem->row());
546 delete pageItem;
547
549
551}
552
554{
555 if (!index.isValid()) {
556 return nullptr;
557 }
558
559 PageItem *item = static_cast<PageItem *>(index.internalPointer());
560 if (!item) {
561 return nullptr;
562 }
563
564 return item->pageWidgetItem();
565}
566
567QModelIndex KPageWidgetModel::index(const KPageWidgetItem *item) const
568{
569 Q_D(const KPageWidgetModel);
570
571 if (!item) {
572 return QModelIndex();
573 }
574
575 const PageItem *pageItem = d->rootItem->findChild(item);
576 if (!pageItem) {
577 return QModelIndex();
578 }
579
580 return createIndex(pageItem->row(), 0, (void *)pageItem);
581}
582
583#include "moc_kpagewidgetmodel.cpp"
A base class for a model used by KPageView.
Definition kpagemodel.h:47
@ WidgetRole
A pointer to the page widget.
Definition kpagemodel.h:70
@ HeaderVisibleRole
when true, show the page header, if false don't
Definition kpagemodel.h:75
@ HeaderRole
A string to be rendered as page header.
Definition kpagemodel.h:59
KPageWidgetItem is used by KPageWidget and represents a page.
void setHeaderVisible(bool visible)
Set whether the page should show the header title.
void setName(const QString &name)
Sets the name of the item as shown in the navigation view of the page widget.
bool isEnabled() const
Returns whether the page widget item is enabled.
void setChecked(bool checked)
Sets whether the page widget item is checked.
void changed()
This signal is emitted whenever the icon or header is changed.
bool isCheckable() const
Returns whether the page widget item is checkable.
void toggled(bool checked)
This signal is emitted whenever the user checks or unchecks the item of setChecked() is called.
bool isChecked() const
Returns whether the page widget item is checked.
void setIcon(const QIcon &icon)
Sets the icon of the page widget item.
QWidget * widget() const
Returns the widget of the page widget item.
void setEnabled(bool)
Sets whether the page widget item is enabled.
KPageWidgetItem(QWidget *widget)
Creates a new page widget item.
void setCheckable(bool checkable)
Sets whether the page widget item is checkable in the view.
bool isHeaderVisible() const
Returns whether the page will show the header title.
void setHeader(const QString &header)
Sets the header of the page widget item.
~KPageWidgetItem() override
Destroys the page widget item.
bool enabled
This property holds whether the item is enabled.
This page model is used by KPageWidget to provide a hierarchical layout of pages.
KPageWidgetItem * insertPage(KPageWidgetItem *before, QWidget *widget, const QString &name)
Inserts a new page in the model.
KPageWidgetItem * addPage(QWidget *widget, const QString &name)
Adds a new top level page to the model.
void removePage(KPageWidgetItem *item)
Removes the page associated with the given KPageWidgetItem.
int columnCount(const QModelIndex &parent=QModelIndex()) const override
These methods are reimplemented from QAbstractItemModel.
KPageWidgetModel(QObject *parent=nullptr)
Creates a new page widget model.
KPageWidgetItem * item(const QModelIndex &index) const
Returns the KPageWidgetItem for a given index or a null pointer if the index is invalid.
void toggled(KPageWidgetItem *page, bool checked)
This signal is emitted whenever a checkable page changes its state.
KPageWidgetItem * addSubPage(KPageWidgetItem *parent, QWidget *widget, const QString &name)
Inserts a new sub page in the model.
~KPageWidgetModel() override
Destroys the page widget model.
QString name(StandardShortcut id)
void beginInsertRows(const QModelIndex &parent, int first, int last)
void beginRemoveRows(const QModelIndex &parent, int first, int last)
QModelIndex createIndex(int row, int column, const void *ptr) const const
void layoutAboutToBeChanged(const QList< QPersistentModelIndex > &parents, QAbstractItemModel::LayoutChangeHint hint)
void layoutChanged(const QList< QPersistentModelIndex > &parents, QAbstractItemModel::LayoutChangeHint hint)
void * internalPointer() const const
bool isValid() const const
int row() const const
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
T findChild(const QString &name, Qt::FindChildOptions options) const const
QObject * parent() const const
T qobject_cast(QObject *object)
DisplayRole
typedef ItemFlags
QVariant fromValue(T &&value)
int toInt(bool *ok) const const
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:14:43 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.