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 QList<QAction *> actions;
44};
45
47 : QObject(nullptr)
48 , d(new KPageWidgetItemPrivate)
49{
50 d->widget = widget;
51
52 // Hide the widget, otherwise when the widget has this KPageView as
53 // parent the widget is shown outside the QStackedWidget if the page
54 // was not selected ( and reparented ) yet.
55 if (d->widget) {
56 d->widget->hide();
57 }
58}
59
61 : QObject(nullptr)
62 , d(new KPageWidgetItemPrivate)
63{
64 d->widget = widget;
65 d->name = name;
66
67 // Hide the widget, otherwise when the widget has this KPageView as
68 // parent the widget is shown outside the QStackedWidget if the page
69 // was not selected ( and reparented ) yet.
70 if (d->widget) {
71 d->widget->hide();
72 }
73}
74
76
78{
79 d->enabled = enabled;
80 if (d->widget) {
81 d->widget->setEnabled(enabled);
82 }
84}
85
87{
88 return d->enabled;
89}
90
92{
93 return d->headerVisible;
94}
95
97{
98 d->headerVisible = visible;
99
100 Q_EMIT changed();
101}
102
104{
105 return d->widget;
106}
107
109{
110 d->name = name;
111
112 Q_EMIT changed();
113}
114
115QString KPageWidgetItem::name() const
116{
117 return d->name;
118}
119
121{
122 d->header = header;
123
124 Q_EMIT changed();
125}
126
127QString KPageWidgetItem::header() const
128{
129 return d->header;
130}
131
133{
134 d->icon = icon;
135
136 Q_EMIT changed();
137}
138
139QIcon KPageWidgetItem::icon() const
140{
141 return d->icon;
142}
143
145{
146 d->checkable = checkable;
147
148 Q_EMIT changed();
149}
150
152{
153 return d->checkable;
154}
155
157{
158 d->checked = checked;
159
160 Q_EMIT toggled(checked);
161 Q_EMIT changed();
162}
163
165{
166 return d->checked;
167}
168
170{
171 return d->actions;
172}
173
175{
176 if (d->actions == actions) {
177 return;
178 }
179 d->actions = actions;
181}
182
183PageItem::PageItem(KPageWidgetItem *pageWidgetItem, PageItem *parent)
184 : mPageWidgetItem(pageWidgetItem)
185 , mParentItem(parent)
186{
187}
188
189PageItem::~PageItem()
190{
191 delete mPageWidgetItem;
192 mPageWidgetItem = nullptr;
193
194 qDeleteAll(mChildItems);
195}
196
197void PageItem::appendChild(PageItem *item)
198{
199 mChildItems.append(item);
200}
201
202void PageItem::insertChild(int row, PageItem *item)
203{
204 mChildItems.insert(row, item);
205}
206
207void PageItem::removeChild(int row)
208{
209 mChildItems.removeAt(row);
210}
211
212PageItem *PageItem::child(int row)
213{
214 return mChildItems.value(row);
215}
216
217int PageItem::childCount() const
218{
219 return mChildItems.count();
220}
221
222int PageItem::columnCount() const
223{
224 return 1;
225}
226
227PageItem *PageItem::parent()
228{
229 return mParentItem;
230}
231
232int PageItem::row() const
233{
234 if (mParentItem) {
235 return mParentItem->mChildItems.indexOf(const_cast<PageItem *>(this));
236 }
237
238 return 0;
239}
240
241KPageWidgetItem *PageItem::pageWidgetItem() const
242{
243 return mPageWidgetItem;
244}
245
246PageItem *PageItem::findChild(const KPageWidgetItem *item)
247{
248 if (mPageWidgetItem == item) {
249 return this;
250 }
251
252 for (int i = 0; i < mChildItems.count(); ++i) {
253 PageItem *pageItem = mChildItems[i]->findChild(item);
254 if (pageItem) {
255 return pageItem;
256 }
257 }
258
259 return nullptr;
260}
261
262void PageItem::dump(int indent)
263{
264 const QString indentation(indent, QLatin1Char(' '));
265
266 const QString name = (mPageWidgetItem ? mPageWidgetItem->name() : QStringLiteral("root"));
267 qCDebug(KWidgetsAddonsLog, "%s (%p)", qPrintable(QString(indentation + name)), (void *)this);
268 for (int i = 0; i < mChildItems.count(); ++i) {
269 mChildItems[i]->dump(indent + 2);
270 }
271}
272
274 : KPageModel(*new KPageWidgetModelPrivate, parent)
275{
276}
277
281
283{
284 return 1;
285}
286
287QVariant KPageWidgetModel::data(const QModelIndex &index, int role) const
288{
289 if (!index.isValid()) {
290 return QVariant();
291 }
292
293 PageItem *item = static_cast<PageItem *>(index.internalPointer());
294
295 if (role == Qt::DisplayRole) {
296 return QVariant(item->pageWidgetItem()->name());
297 } else if (role == Qt::DecorationRole) {
298 return QVariant(item->pageWidgetItem()->icon());
299 } else if (role == HeaderRole) {
300 return QVariant(item->pageWidgetItem()->header());
301 } else if (role == HeaderVisibleRole) {
302 return item->pageWidgetItem()->isHeaderVisible();
303 } else if (role == WidgetRole) {
304 return QVariant::fromValue(item->pageWidgetItem()->widget());
305 } else if (role == ActionsRole) {
306 return QVariant::fromValue(item->pageWidgetItem()->actions());
307 } else if (role == Qt::CheckStateRole) {
308 if (item->pageWidgetItem()->isCheckable()) {
309 return (item->pageWidgetItem()->isChecked() ? Qt::Checked : Qt::Unchecked);
310 } else {
311 return QVariant();
312 }
313 } else {
314 return QVariant();
315 }
316}
317
318bool KPageWidgetModel::setData(const QModelIndex &index, const QVariant &value, int role)
319{
320 if (!index.isValid()) {
321 return false;
322 }
323
324 if (role != Qt::CheckStateRole) {
325 return false;
326 }
327
328 PageItem *item = static_cast<PageItem *>(index.internalPointer());
329 if (!item) {
330 return false;
331 }
332
333 if (!item->pageWidgetItem()->isCheckable()) {
334 return false;
335 }
336
337 if (value.toInt() == Qt::Checked) {
338 item->pageWidgetItem()->setChecked(true);
339 } else {
340 item->pageWidgetItem()->setChecked(false);
341 }
342
343 return true;
344}
345
346Qt::ItemFlags KPageWidgetModel::flags(const QModelIndex &index) const
347{
348 if (!index.isValid()) {
349 return Qt::NoItemFlags;
350 }
351
353
354 PageItem *item = static_cast<PageItem *>(index.internalPointer());
355 if (item->pageWidgetItem()->isCheckable()) {
357 }
358 if (item->pageWidgetItem()->isEnabled()) {
359 flags |= Qt::ItemIsEnabled;
360 }
361
362 return flags;
363}
364
365QModelIndex KPageWidgetModel::index(int row, int column, const QModelIndex &parent) const
366{
367 Q_D(const KPageWidgetModel);
368
369 PageItem *parentItem;
370
371 if (parent.isValid()) {
372 parentItem = static_cast<PageItem *>(parent.internalPointer());
373 } else {
374 parentItem = d->rootItem;
375 }
376
377 PageItem *childItem = parentItem->child(row);
378 if (childItem) {
379 return createIndex(row, column, childItem);
380 } else {
381 return QModelIndex();
382 }
383}
384
386{
387 Q_D(const KPageWidgetModel);
388
389 if (!index.isValid()) {
390 return QModelIndex();
391 }
392
393 PageItem *item = static_cast<PageItem *>(index.internalPointer());
394 PageItem *parentItem = item->parent();
395
396 if (parentItem == d->rootItem) {
397 return QModelIndex();
398 } else {
399 return createIndex(parentItem->row(), 0, parentItem);
400 }
401}
402
403int KPageWidgetModel::rowCount(const QModelIndex &parent) const
404{
405 Q_D(const KPageWidgetModel);
406
407 PageItem *parentItem;
408
409 if (!parent.isValid()) {
410 parentItem = d->rootItem;
411 } else {
412 parentItem = static_cast<PageItem *>(parent.internalPointer());
413 }
414
415 return parentItem->childCount();
416}
417
419{
420 KPageWidgetItem *item = new KPageWidgetItem(widget, name);
421
422 addPage(item);
423
424 return item;
425}
426
428{
430
432 connect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged()));
433 connect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool)));
434
435 // The row to be inserted
436 int row = d->rootItem->childCount();
437
438 beginInsertRows(QModelIndex(), row, row);
439
440 PageItem *pageItem = new PageItem(item, d->rootItem);
441 d->rootItem->appendChild(pageItem);
442
444
446}
447
449{
450 KPageWidgetItem *item = new KPageWidgetItem(widget, name);
451
452 insertPage(before, item);
453
454 return item;
455}
456
458{
460
461 PageItem *beforePageItem = d->rootItem->findChild(before);
462 if (!beforePageItem) {
463 qCDebug(KWidgetsAddonsLog, "Invalid KPageWidgetItem passed!");
464 return;
465 }
466
468
469 connect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged()));
470 connect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool)));
471
472 PageItem *parent = beforePageItem->parent();
473 // The row to be inserted
474 int row = beforePageItem->row();
475
476 QModelIndex index;
477 if (parent != d->rootItem) {
478 index = createIndex(parent->row(), 0, parent);
479 }
480
481 beginInsertRows(index, row, row);
482
483 PageItem *newPageItem = new PageItem(item, parent);
484 parent->insertChild(row, newPageItem);
485
487
489}
490
492{
493 KPageWidgetItem *item = new KPageWidgetItem(widget, name);
494
496
497 return item;
498}
499
501{
503
504 PageItem *parentPageItem = d->rootItem->findChild(parent);
505 if (!parentPageItem) {
506 qCDebug(KWidgetsAddonsLog, "Invalid KPageWidgetItem passed!");
507 return;
508 }
509
511
512 connect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged()));
513 connect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool)));
514
515 // The row to be inserted
516 int row = parentPageItem->childCount();
517
518 QModelIndex index;
519 if (parentPageItem != d->rootItem) {
520 index = createIndex(parentPageItem->row(), 0, parentPageItem);
521 }
522
523 beginInsertRows(index, row, row);
524
525 PageItem *newPageItem = new PageItem(item, parentPageItem);
526 parentPageItem->appendChild(newPageItem);
527
529
531}
532
534{
535 if (!item) {
536 return;
537 }
538
540
541 PageItem *pageItem = d->rootItem->findChild(item);
542 if (!pageItem) {
543 qCDebug(KWidgetsAddonsLog, "Invalid KPageWidgetItem passed!");
544 return;
545 }
546
548
549 disconnect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged()));
550 disconnect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool)));
551
552 PageItem *parentPageItem = pageItem->parent();
553 int row = parentPageItem->row();
554
555 QModelIndex index;
556 if (parentPageItem != d->rootItem) {
557 index = createIndex(row, 0, parentPageItem);
558 }
559
560 beginRemoveRows(index, pageItem->row(), pageItem->row());
561
562 parentPageItem->removeChild(pageItem->row());
563 delete pageItem;
564
566
568}
569
571{
572 if (!index.isValid()) {
573 return nullptr;
574 }
575
576 PageItem *item = static_cast<PageItem *>(index.internalPointer());
577 if (!item) {
578 return nullptr;
579 }
580
581 return item->pageWidgetItem();
582}
583
584QModelIndex KPageWidgetModel::index(const KPageWidgetItem *item) const
585{
586 Q_D(const KPageWidgetModel);
587
588 if (!item) {
589 return QModelIndex();
590 }
591
592 const PageItem *pageItem = d->rootItem->findChild(item);
593 if (!pageItem) {
594 return QModelIndex();
595 }
596
597 return createIndex(pageItem->row(), 0, (void *)pageItem);
598}
599
600#include "moc_kpagewidgetmodel.cpp"
A base class for a model used by KPageView.
Definition kpagemodel.h:47
@ ActionsRole
The list of actions associated to the page.
Definition kpagemodel.h:80
@ 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 actionsChanged()
This signal is emitted whenever the actions associated to the page are changed.
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 setActions(QList< QAction * > actions)
Set the actions associated to the page.
void setEnabled(bool)
Sets whether the page widget item is enabled.
KPageWidgetItem(QWidget *widget)
Creates a new page widget item.
QList< QAction * > actions
This property holds the actions associated to the page.
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(StandardAction 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)
QObject * parent() const const
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 Fri Oct 11 2024 12:19:04 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.