Qt 4.8
qstackedlayout.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qstackedlayout.h"
43 #include "qlayout_p.h"
44 
45 #include <qlist.h>
46 #include <qwidget.h>
47 #include "private/qlayoutengine_p.h"
48 
50 
52 {
54 public:
57  int index;
59 };
60 
154  : QLayout(*new QStackedLayoutPrivate, 0, 0)
155 {
156 }
157 
165  : QLayout(*new QStackedLayoutPrivate, 0, parent)
166 {
167 }
168 
174  : QLayout(*new QStackedLayoutPrivate, parentLayout, 0)
175 {
176 }
177 
183 {
185  qDeleteAll(d->list);
186 }
187 
198 {
200  return insertWidget(d->list.count(), widget);
201 }
202 
218 {
220  addChildWidget(widget);
221  index = qMin(index, d->list.count());
222  if (index < 0)
223  index = d->list.count();
224  QWidgetItem *wi = QLayoutPrivate::createWidgetItem(this, widget);
225  d->list.insert(index, wi);
226  invalidate();
227  if (d->index < 0) {
228  setCurrentIndex(index);
229  } else {
230  if (index <= d->index)
231  ++d->index;
232  if (d->stackingMode == StackOne)
233  widget->hide();
234  widget->lower();
235  }
236  return index;
237 }
238 
243 {
244  Q_D(const QStackedLayout);
245  return d->list.value(index);
246 }
247 
248 // Code that enables proper handling of the case that takeAt() is
249 // called somewhere inside QObject destructor (can't call hide()
250 // on the object then)
251 
253 {
254 public:
255  inline bool wasDeleted() const { return d_ptr->wasDeleted; }
256 };
257 
258 static bool qt_wasDeleted(const QWidget *w) { return static_cast<const QtFriendlyLayoutWidget*>(w)->wasDeleted(); }
259 
260 
265 {
267  if (index <0 || index >= d->list.size())
268  return 0;
269  QLayoutItem *item = d->list.takeAt(index);
270  if (index == d->index) {
271  d->index = -1;
272  if ( d->list.count() > 0 ) {
273  int newIndex = (index == d->list.count()) ? index-1 : index;
274  setCurrentIndex(newIndex);
275  } else {
276  emit currentChanged(-1);
277  }
278  } else if (index < d->index) {
279  --d->index;
280  }
281  emit widgetRemoved(index);
282  if (item->widget() && !qt_wasDeleted(item->widget()))
283  item->widget()->hide();
284  return item;
285 }
286 
299 {
301  QWidget *prev = currentWidget();
302  QWidget *next = widget(index);
303  if (!next || next == prev)
304  return;
305 
306  bool reenableUpdates = false;
308 
309  if (parent && parent->updatesEnabled()) {
310  reenableUpdates = true;
311  parent->setUpdatesEnabled(false);
312  }
313 
314  QPointer<QWidget> fw = parent ? parent->window()->focusWidget() : 0;
315  const bool focusWasOnOldPage = fw && (prev && prev->isAncestorOf(fw));
316 
317  if (prev) {
318  prev->clearFocus();
319  if (d->stackingMode == StackOne)
320  prev->hide();
321  }
322 
323  d->index = index;
324  next->raise();
325  next->show();
326 
327  // try to move focus onto the incoming widget if focus
328  // was somewhere on the outgoing widget.
329 
330  if (parent) {
331  if (focusWasOnOldPage) {
332  // look for the best focus widget we can find
333  if (QWidget *nfw = next->focusWidget())
334  nfw->setFocus();
335  else {
336  // second best: first child widget in the focus chain
337  if (QWidget *i = fw) {
338  while ((i = i->nextInFocusChain()) != fw) {
339  if (((i->focusPolicy() & Qt::TabFocus) == Qt::TabFocus)
340  && !i->focusProxy() && i->isVisibleTo(next) && i->isEnabled()
341  && next->isAncestorOf(i)) {
342  i->setFocus();
343  break;
344  }
345  }
346  // third best: incoming widget
347  if (i == fw )
348  next->setFocus();
349  }
350  }
351  }
352  }
353  if (reenableUpdates)
354  parent->setUpdatesEnabled(true);
355  emit currentChanged(index);
356 }
357 
359 {
360  Q_D(const QStackedLayout);
361  return d->index;
362 }
363 
364 
374 {
375  int index = indexOf(widget);
376  if (index == -1) {
377  qWarning("QStackedLayout::setCurrentWidget: Widget %p not contained in stack", widget);
378  return;
379  }
380  setCurrentIndex(index);
381 }
382 
383 
391 {
392  Q_D(const QStackedLayout);
393  return d->index >= 0 ? d->list.at(d->index)->widget() : 0;
394 }
395 
403 {
404  Q_D(const QStackedLayout);
405  if (index < 0 || index >= d->list.size())
406  return 0;
407  return d->list.at(index)->widget();
408 }
409 
420 {
421  Q_D(const QStackedLayout);
422  return d->list.size();
423 }
424 
425 
430 {
431  QWidget *widget = item->widget();
432  if (widget) {
433  addWidget(widget);
434  delete item;
435  } else {
436  qWarning("QStackedLayout::addItem: Only widgets can be added");
437  }
438 }
439 
444 {
445  Q_D(const QStackedLayout);
446  QSize s(0, 0);
447  int n = d->list.count();
448 
449  for (int i = 0; i < n; ++i)
450  if (QWidget *widget = d->list.at(i)->widget()) {
451  QSize ws(widget->sizeHint());
453  ws.setWidth(0);
455  ws.setHeight(0);
456  s = s.expandedTo(ws);
457  }
458  return s;
459 }
460 
465 {
466  Q_D(const QStackedLayout);
467  QSize s(0, 0);
468  int n = d->list.count();
469 
470  for (int i = 0; i < n; ++i)
471  if (QWidget *widget = d->list.at(i)->widget())
473  return s;
474 }
475 
480 {
482  switch (d->stackingMode) {
483  case StackOne:
484  if (QWidget *widget = currentWidget())
485  widget->setGeometry(rect);
486  break;
487  case StackAll:
488  if (const int n = d->list.count())
489  for (int i = 0; i < n; ++i)
490  if (QWidget *widget = d->list.at(i)->widget())
491  widget->setGeometry(rect);
492  break;
493  }
494 }
495 
529 {
530  Q_D(const QStackedLayout);
531  return d->stackingMode;
532 }
533 
535 {
537  if (d->stackingMode == stackingMode)
538  return;
539  d->stackingMode = stackingMode;
540 
541  const int n = d->list.count();
542  if (n == 0)
543  return;
544 
545  switch (d->stackingMode) {
546  case StackOne:
547  if (const int idx = currentIndex())
548  for (int i = 0; i < n; ++i)
549  if (QWidget *widget = d->list.at(i)->widget())
550  widget->setVisible(i == idx);
551  break;
552  case StackAll: { // Turn overlay on: Make sure all widgets are the same size
553  QRect geometry;
554  if (const QWidget *widget = currentWidget())
555  geometry = widget->geometry();
556  for (int i = 0; i < n; ++i)
557  if (QWidget *widget = d->list.at(i)->widget()) {
558  if (!geometry.isNull())
559  widget->setGeometry(geometry);
560  widget->setVisible(true);
561  }
562  }
563  break;
564  }
565 }
566 
double d
Definition: qnumeric_p.h:62
void setCurrentWidget(QWidget *w)
Sets the current widget to be the specified widget.
QWidget * focusWidget() const
Returns the last child of this widget that setFocus had been called on.
Definition: qwidget.cpp:6863
bool isNull() const
Returns true if the rectangle is a null rectangle, otherwise returns false.
Definition: qrect.h:231
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
Q_GUI_EXPORT QSize qSmartMinSize(const QSize &sizeHint, const QSize &minSizeHint, const QSize &minSize, const QSize &maxSize, const QSizePolicy &sizePolicy)
Q_CORE_EXPORT QTextStream & ws(QTextStream &s)
static bool qt_wasDeleted(const QWidget *w)
void setCurrentIndex(int index)
Policy horizontalPolicy() const
Definition: qsizepolicy.h:118
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
QSize expandedTo(const QSize &) const
Returns a size holding the maximum width and height of this size and the given otherSize.
Definition: qsize.h:187
uint wasDeleted
Definition: qobject.h:98
~QStackedLayout()
Destroys this QStackedLayout.
void widgetRemoved(int index)
This signal is emitted whenever a widget is removed from the layout.
void setGeometry(int x, int y, int w, int h)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qwidget.h:1017
void invalidate()
Reimplemented Function
Definition: qlayout.cpp:673
void setUpdatesEnabled(bool enable)
Definition: qwidget.cpp:7670
#define Q_D(Class)
Definition: qglobal.h:2482
void currentChanged(int index)
This signal is emitted whenever the current widget in the layout changes.
void setStackingMode(StackingMode stackingMode)
The QStackedLayout class provides a stack of widgets where only one widget is visible at a time...
QWidget * parentWidget() const
Returns the parent widget of this layout, or 0 if this layout is not installed on any widget...
Definition: qlayout.cpp:616
void clearFocus()
Takes keyboard input focus from the widget.
Definition: qwidget.cpp:6757
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
The QLayoutItem class provides an abstract item that a QLayout manipulates.
Definition: qlayoutitem.h:64
void lower()
Lowers the widget to the bottom of the parent widget&#39;s stack.
Definition: qwidget.cpp:11939
int currentIndex() const
bool updatesEnabled
whether updates are enabled
Definition: qwidget.h:190
int count() const
the number of widgets contained in the layout
void raise()
Raises this widget to the top of the parent widget&#39;s stack.
Definition: qwidget.cpp:11901
virtual int indexOf(QWidget *) const
Searches for widget widget in this layout (not including child layouts).
Definition: qlayout.cpp:1378
The QLayout class is the base class of geometry managers.
Definition: qlayout.h:90
QSize sizeHint() const
Reimplemented Function
#define emit
Definition: qobjectdefs.h:76
int addWidget(QWidget *w)
Adds the given widget to the end of this layout and returns the index position of the widget...
Q_CORE_EXPORT void qWarning(const char *,...)
StackingMode stackingMode() const
void show()
Shows the widget and its child widgets.
The QWidgetItem class is a layout item that represents a widget.
Definition: qlayoutitem.h:122
virtual void setVisible(bool visible)
Definition: qwidget.cpp:7991
void hide()
Hides the widget.
Definition: qwidget.h:501
static QWidgetItem * createWidgetItem(const QLayout *layout, QWidget *widget)
Definition: qlayout.cpp:190
void setFocus()
Gives the keyboard input focus to this widget (or its focus proxy) if this widget or one of its paren...
Definition: qwidget.h:432
QSize minimumSize() const
Reimplemented Function
#define Q_DECLARE_PUBLIC(Class)
Definition: qglobal.h:2477
QStackedLayout::StackingMode stackingMode
void addChildWidget(QWidget *w)
This function is called from addWidget() functions in subclasses to add w as a managed widget of a la...
Definition: qlayout.cpp:1045
QSizePolicy sizePolicy
the default layout behavior of the widget
Definition: qwidget.h:171
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
int insertWidget(int index, QWidget *w)
Inserts the given widget at the given index in this QStackedLayout.
Policy verticalPolicy() const
Definition: qsizepolicy.h:119
bool isAncestorOf(const QWidget *child) const
Returns true if this widget is a parent, (or grandparent and so on to any level), of the given child...
Definition: qwidget.cpp:8573
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
StackingMode
This enum specifies how the layout handles its child widgets regarding their visibility.
QLayoutItem * takeAt(int)
Reimplemented Function
quint16 index
QWidget * window() const
Returns the window for this widget, i.e.
Definition: qwidget.cpp:4492
QScopedPointer< QObjectData > d_ptr
Definition: qobject.h:320
void setGeometry(const QRect &rect)
Reimplemented Function
virtual QWidget * widget()
If this item is a QWidget, it is returned as a QWidget; otherwise 0 is returned.
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
QSize sizeHint
the recommended size for the widget
Definition: qwidget.h:195
void addItem(QLayoutItem *item)
Reimplemented Function
QRect geometry() const
Reimplemented Function
Definition: qlayout.cpp:664
QLayoutItem * itemAt(int) const
Reimplemented Function
QRect geometry
the geometry of the widget relative to its parent and excluding the window frame
Definition: qwidget.h:158
Q_OUTOFLINE_TEMPLATE void qDeleteAll(ForwardIterator begin, ForwardIterator end)
Definition: qalgorithms.h:319
QWidget * currentWidget() const
Returns the current widget, or 0 if there are no widgets in this layout.
QList< QLayoutItem * > list
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
QStackedLayout()
Constructs a QStackedLayout with no parent.