• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

KDEUI

  • sources
  • kde-4.12
  • kdelibs
  • kdeui
  • paged
kpageview.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the KDE Libraries
3 
4  Copyright (C) 2006 Tobias Koenig (tokoe@kde.org)
5  Copyright (C) 2007 Rafael Fernández López (ereslibre@kde.org)
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Library General Public
9  License as published by the Free Software Foundation; either
10  version 2 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Library General Public License for more details.
16 
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21 */
22 
23 #include "kpageview.h"
24 #include "kpageview_p.h"
25 
26 #include "kpagemodel.h"
27 
28 #include <kdialog.h>
29 #include <kiconloader.h>
30 #include <ktitlewidget.h>
31 
32 #include <QAbstractItemView>
33 #include <QGridLayout>
34 #include <QLabel>
35 #include <QSize>
36 #include <QStackedWidget>
37 #include <QTimer>
38 
39 void KPageViewPrivate::_k_rebuildGui()
40 {
41  // clean up old view
42  Q_Q(KPageView);
43 
44  QModelIndex currentLastIndex;
45  if ( view && view->selectionModel() ) {
46  QObject::disconnect(view->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
47  q, SLOT(_k_pageSelected(QItemSelection,QItemSelection)));
48  currentLastIndex = view->selectionModel()->currentIndex();
49  }
50 
51  delete view;
52  view = q->createView();
53 
54  Q_ASSERT( view );
55 
56  view->setSelectionBehavior( QAbstractItemView::SelectItems );
57  view->setSelectionMode( QAbstractItemView::SingleSelection );
58 
59  if ( model ) {
60  view->setModel( model );
61  }
62 
63  // setup new view
64  if ( view->selectionModel() ) {
65  QObject::connect(view->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), q, SLOT(_k_pageSelected(QItemSelection,QItemSelection)));
66 
67  if ( currentLastIndex.isValid() )
68  view->selectionModel()->setCurrentIndex( currentLastIndex, QItemSelectionModel::Select );
69  else if ( model )
70  view->selectionModel()->setCurrentIndex( model->index( 0, 0 ), QItemSelectionModel::Select );
71  }
72 
73  if (faceType == KPageView::Tabbed) {
74  stack->setVisible(false);
75  layout->removeWidget( stack );
76  } else {
77  layout->addWidget( stack, 2, 1 );
78  stack->setVisible(true);
79  }
80 
81  titleWidget->setVisible(q->showPageHeader());
82 
83  Qt::Alignment alignment = q->viewPosition();
84  if ( alignment & Qt::AlignTop )
85  layout->addWidget( view, 2, 1 );
86  else if ( alignment & Qt::AlignRight )
87  layout->addWidget( view, 1, 2, 2, 1 );
88  else if ( alignment & Qt::AlignBottom )
89  layout->addWidget( view, 4, 1 );
90  else if ( alignment & Qt::AlignLeft )
91  layout->addWidget( view, 1, 0, 2, 1 );
92 }
93 
94 void KPageViewPrivate::updateSelection()
95 {
100  if ( !model )
101  return;
102 
103  if ( !view || !view->selectionModel() )
104  return;
105 
106  const QModelIndex index = view->selectionModel()->currentIndex();
107  if ( !index.isValid() )
108  view->selectionModel()->setCurrentIndex( model->index( 0, 0 ), QItemSelectionModel::Select );
109 }
110 
111 void KPageViewPrivate::cleanupPages()
112 {
117  const QList<QWidget*> widgets = collectPages();
118 
119  for ( int i = 0; i < stack->count(); ++i ) {
120  QWidget *page = stack->widget( i );
121 
122  bool found = false;
123  for ( int j = 0; j < widgets.count(); ++j ) {
124  if ( widgets[ j ] == page )
125  found = true;
126  }
127 
128  if ( !found )
129  stack->removeWidget( page );
130  }
131 }
132 
133 QList<QWidget *> KPageViewPrivate::collectPages(const QModelIndex &parentIndex)
134 {
139  QList<QWidget*> retval;
140 
141  int rows = model->rowCount( parentIndex );
142  for ( int j = 0; j < rows; ++j ) {
143  const QModelIndex index = model->index( j, 0, parentIndex );
144  retval.append( qvariant_cast<QWidget*>( model->data( index, KPageModel::WidgetRole ) ) );
145 
146  if ( model->rowCount( index ) > 0 ) {
147  retval += collectPages( index );
148  }
149  }
150 
151  return retval;
152 }
153 
154 KPageView::FaceType KPageViewPrivate::detectAutoFace() const
155 {
156  if ( !model )
157  return KPageView::Plain;
158 
162  bool hasSubPages = false;
163  const int count = model->rowCount();
164  for ( int i = 0; i < count; ++i ) {
165  if ( model->rowCount( model->index( i, 0 ) ) > 0 ) {
166  hasSubPages = true;
167  break;
168  }
169  }
170 
171  if ( hasSubPages )
172  return KPageView::Tree;
173 
174  if ( model->rowCount() > 1 )
175  return KPageView::List;
176 
177  return KPageView::Plain;
178 }
179 
180 void KPageViewPrivate::_k_modelChanged()
181 {
182  if ( !model )
183  return;
184 
189  if (faceType == KPageView::Auto) {
190  _k_rebuildGui();
191  // If you discover some crashes use the line below instead...
192  //QTimer::singleShot(0, q, SLOT(_k_rebuildGui()));
193  }
194 
198  QSize size = stack->size();
199  const QList<QWidget*> widgets = collectPages();
200  for ( int i = 0; i < widgets.count(); ++i ) {
201  const QWidget *widget = widgets[ i ];
202  if ( widget )
203  size = size.expandedTo( widget->minimumSizeHint() );
204  }
205  stack->setMinimumSize( size );
206 
207  updateSelection();
208 }
209 
210 void KPageViewPrivate::_k_pageSelected(const QItemSelection &index, const QItemSelection &previous)
211 {
212  if ( !model )
213  return;
214 
215  // Return if the current Index is not valid
216  if ( index.indexes().size() != 1 ) {
217  return;
218  }
219  QModelIndex currentIndex = index.indexes().first();
220 
221  QModelIndex previousIndex;
222  // The previous index can be invalid
223  if ( previous.indexes().size() == 1 ) {
224  previousIndex = previous.indexes().first();
225  }
226 
227  if (faceType != KPageView::Tabbed) {
228  QWidget *widget = qvariant_cast<QWidget*>( model->data( currentIndex, KPageModel::WidgetRole ) );
229 
230  if ( widget ) {
231  if ( stack->indexOf( widget ) == -1 ) { // not included yet
232  stack->addWidget( widget );
233  }
234 
235  stack->setCurrentWidget( widget );
236  } else {
237  stack->setCurrentWidget( defaultWidget );
238  }
239 
240  updateTitleWidget(currentIndex);
241  }
242 
243  Q_Q(KPageView);
244  emit q->currentPageChanged(currentIndex, previousIndex);
245 }
246 
247 void KPageViewPrivate::updateTitleWidget(const QModelIndex& index)
248 {
249  Q_Q(KPageView);
250 
251  QString header = model->data( index, KPageModel::HeaderRole ).toString();
252  if ( header.isNull() ) { //TODO KDE5 remove that ugly logic, see also doxy-comments in KPageWidgetItem::setHeader()
253  header = model->data( index, Qt::DisplayRole ).toString();
254  }
255 
256  const QIcon icon = model->data( index, Qt::DecorationRole ).value<QIcon>();
257  titleWidget->setPixmap( icon.pixmap( 22, 22 ) );
258  titleWidget->setText( header );
259 
260  titleWidget->setVisible(q->showPageHeader());
261 }
262 
263 void KPageViewPrivate::_k_dataChanged(const QModelIndex &, const QModelIndex &)
264 {
269  if ( !view )
270  return;
271 
272  QModelIndex index = view->selectionModel()->currentIndex();
273  if ( !index.isValid() )
274  return;
275 
276  updateTitleWidget( index );
277 }
278 
279 KPageViewPrivate::KPageViewPrivate(KPageView *_parent)
280  : q_ptr(_parent), model(0), faceType(KPageView::Auto),
281  layout(0), stack(0), titleWidget(0), view(0)
282 {
283 }
284 
285 void KPageViewPrivate::init()
286 {
287  Q_Q(KPageView);
288  layout = new QGridLayout(q);
289  stack = new KPageStackedWidget(q);
290  titleWidget = new KTitleWidget(q);
291  QPixmap emptyPixmap(22, 22);
292  emptyPixmap.fill(Qt::transparent);
293  titleWidget->setPixmap(emptyPixmap);
294  layout->addWidget(titleWidget, 1, 1);
295  layout->addWidget(stack, 2, 1);
296 
297  defaultWidget = new QWidget(q);
298  stack->addWidget(defaultWidget);
299 
300  // stack should use most space
301  layout->setColumnStretch(1, 1);
302  layout->setRowStretch(2, 1);
303 }
304 
308 KPageView::KPageView( QWidget *parent )
309  : QWidget(parent), d_ptr(new KPageViewPrivate(this))
310 {
311  d_ptr->init();
312 }
313 
314 KPageView::KPageView(KPageViewPrivate &dd, QWidget *parent)
315  : QWidget(parent), d_ptr(&dd)
316 {
317  d_ptr->init();
318 }
319 
320 KPageView::~KPageView()
321 {
322  delete d_ptr;
323 }
324 
325 void KPageView::setModel(QAbstractItemModel *model)
326 {
327  Q_D(KPageView);
328  // clean up old model
329  if ( d->model ) {
330  disconnect(d->model, SIGNAL(layoutChanged()), this, SLOT(_k_modelChanged()));
331  disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
332  this, SLOT(_k_dataChanged(QModelIndex,QModelIndex)));
333  }
334 
335  d->model = model;
336 
337  if ( d->model ) {
338  connect(d->model, SIGNAL(layoutChanged()), this, SLOT(_k_modelChanged()));
339  connect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
340  this, SLOT(_k_dataChanged(QModelIndex,QModelIndex)));
341 
342  // set new model in navigation view
343  if ( d->view )
344  d->view->setModel( model );
345  }
346 
347  d->_k_rebuildGui();
348 }
349 
350 QAbstractItemModel* KPageView::model() const
351 {
352  return d_func()->model;
353 }
354 
355 void KPageView::setFaceType( FaceType faceType )
356 {
357  Q_D(KPageView);
358  d->faceType = faceType;
359 
360  d->_k_rebuildGui();
361 }
362 
363 KPageView::FaceType KPageView::faceType() const
364 {
365  return d_func()->faceType;
366 }
367 
368 void KPageView::setCurrentPage( const QModelIndex &index )
369 {
370  Q_D(KPageView);
371  if ( !d->view || !d->view->selectionModel() )
372  return;
373 
374  d->view->selectionModel()->setCurrentIndex( index, QItemSelectionModel::SelectCurrent );
375 }
376 
377 QModelIndex KPageView::currentPage() const
378 {
379  Q_D(const KPageView);
380  if ( !d->view || !d->view->selectionModel() )
381  return QModelIndex();
382 
383  return d->view->selectionModel()->currentIndex();
384 }
385 
386 void KPageView::setItemDelegate( QAbstractItemDelegate *delegate )
387 {
388  Q_D(KPageView);
389  if ( d->view )
390  d->view->setItemDelegate( delegate );
391 }
392 
393 QAbstractItemDelegate* KPageView::itemDelegate() const
394 {
395  Q_D(const KPageView);
396  if ( d->view )
397  return d->view->itemDelegate();
398  else
399  return 0;
400 }
401 
402 void KPageView::setDefaultWidget( QWidget *widget )
403 {
404  Q_D(KPageView);
405 
406  Q_ASSERT(widget);
407 
408  bool isCurrent = (d->stack->currentIndex() == d->stack->indexOf( d->defaultWidget ));
409 
410  // remove old default widget
411  d->stack->removeWidget( d->defaultWidget );
412  delete d->defaultWidget;
413 
414  // add new default widget
415  d->defaultWidget = widget;
416  d->stack->addWidget(d->defaultWidget);
417 
418  if (isCurrent)
419  d->stack->setCurrentWidget(d->defaultWidget);
420 }
421 
422 QAbstractItemView* KPageView::createView()
423 {
424  Q_D(KPageView);
425  if ( d->faceType == Auto ) {
426  const FaceType faceType = d->detectAutoFace();
427 
428  if ( faceType == Plain )
429  return new KDEPrivate::KPagePlainView( this );
430  else if ( faceType == List )
431  return new KDEPrivate::KPageListView( this );
432  else if ( faceType == Tree )
433  return new KDEPrivate::KPageTreeView( this );
434  else // should never happen
435  return 0;
436  } else if ( d->faceType == Plain )
437  return new KDEPrivate::KPagePlainView( this );
438  else if ( d->faceType == List )
439  return new KDEPrivate::KPageListView( this );
440  else if ( d->faceType == Tree )
441  return new KDEPrivate::KPageTreeView( this );
442  else if ( d->faceType == Tabbed )
443  return new KDEPrivate::KPageTabbedView( this );
444  else
445  return 0;
446 }
447 
448 bool KPageView::showPageHeader() const
449 {
450  Q_D(const KPageView);
451  FaceType faceType = d->faceType;
452 
453  if ( faceType == Auto )
454  faceType = d->detectAutoFace();
455 
456  if ( faceType == Tabbed ) {
457  return false;
458  } else {
459  return !d->titleWidget->text().isEmpty();
460  }
461 }
462 
463 Qt::Alignment KPageView::viewPosition() const
464 {
465  Q_D(const KPageView);
466  FaceType faceType = d->faceType;
467 
468  if ( faceType == Auto )
469  faceType = d->detectAutoFace();
470 
471  if ( faceType == Plain || faceType == Tabbed )
472  return Qt::AlignTop;
473  else
474  return Qt::AlignLeft;
475 }
476 
477 #include "kpageview.moc"
kdialog.h
header
const char header[]
ktitlewidget.h
KPageView::Tree
Definition: kpageview.h:90
KPageView::KPageView
KPageView(QWidget *parent=0)
Creates a page view with given parent.
Definition: kpageview.cpp:308
QWidget
KPageView::~KPageView
virtual ~KPageView()
Destroys the page view.
Definition: kpageview.cpp:320
KPageView::FaceType
FaceType
This enum is used to decide which type of navigation view shall be used in the page view...
Definition: kpageview.h:85
kpageview.h
kiconloader.h
QString
KPageView::createView
virtual QAbstractItemView * createView()
Returns the navigation view, depending on the current face type.
Definition: kpageview.cpp:422
KPageView::setFaceType
void setFaceType(FaceType faceType)
Sets the face type of the page view.
Definition: kpageview.cpp:355
KPageView::List
Definition: kpageview.h:89
KPageView
A base class which can handle multiple pages.
Definition: kpageview.h:60
KPageView::setModel
void setModel(QAbstractItemModel *model)
Sets the model of the page view.
Definition: kpageview.cpp:325
KPageView::currentPage
QModelIndex currentPage() const
Returns the index for the current page or an invalid index if no current page exists.
Definition: kpageview.cpp:377
KPageModel::HeaderRole
A string to be rendered as page header.
Definition: kpagemodel.h:69
KPageView::Plain
Definition: kpageview.h:88
KPageView::model
QAbstractItemModel * model() const
Returns the model of the page view.
Definition: kpageview.cpp:350
KPageView::faceType
FaceType faceType() const
Returns the face type of the page view.
QAbstractItemModel
KPageView::Tabbed
Definition: kpageview.h:91
kpagemodel.h
KPageModel::WidgetRole
A pointer to the page widget.
Definition: kpagemodel.h:80
KPageView::setItemDelegate
void setItemDelegate(QAbstractItemDelegate *delegate)
Sets the item.
Definition: kpageview.cpp:386
KPageView::showPageHeader
virtual bool showPageHeader() const
Returns whether the page header should be visible.
Definition: kpageview.cpp:448
KPageView::itemDelegate
QAbstractItemDelegate * itemDelegate() const
Returns the item delegate of the page view.
Definition: kpageview.cpp:393
KPageView::setCurrentPage
void setCurrentPage(const QModelIndex &index)
Sets the page with.
Definition: kpageview.cpp:368
KTitleWidget
Standard title widget with a white background and round border.
Definition: ktitlewidget.h:61
QSize
KPageView::d_ptr
KPageViewPrivate *const d_ptr
Definition: kpageview.h:190
KPageView::viewPosition
virtual Qt::Alignment viewPosition() const
Returns the position where the navigation view should be located according to the page stack...
Definition: kpageview.cpp:463
KPageView::Auto
Definition: kpageview.h:87
QList< QWidget * >
KPageView::setDefaultWidget
void setDefaultWidget(QWidget *widget)
Sets the widget which will be shown when a page is selected that has no own widget set...
Definition: kpageview.cpp:402
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:49:15 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal