source: trunk/src/gui/graphicsview/qgraphicsgridlayout.cpp@ 624

Last change on this file since 624 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 18.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*!
43 \class QGraphicsGridLayout
44 \brief The QGraphicsGridLayout class provides a grid layout for managing
45 widgets in Graphics View.
46 \since 4.4
47
48 \ingroup graphicsview-api
49
50 The most common way to use QGraphicsGridLayout is to construct an object
51 on the heap with no parent, add widgets and layouts by calling addItem(),
52 and finally assign the layout to a widget by calling
53 QGraphicsWidget::setLayout(). QGraphicsGridLayout automatically computes
54 the dimensions of the grid as you add items.
55
56 \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsgridlayout.cpp 0
57
58 The layout takes ownership of the items. In some cases when the layout
59 item also inherits from QGraphicsItem (such as QGraphicsWidget) there will be a
60 ambiguity in ownership because the layout item belongs to two ownership hierarchies.
61 See the documentation of QGraphicsLayoutItem::setOwnedByLayout() how to handle
62 this.
63 You can access each item in the layout by calling count() and itemAt(). Calling
64 removeAt() will remove an item from the layout, without
65 destroying it.
66
67 \sa QGraphicsLinearLayout, QGraphicsWidget
68*/
69
70#include "qglobal.h"
71
72#ifndef QT_NO_GRAPHICSVIEW
73
74#include "qapplication.h"
75#include "qwidget.h"
76#include "qgraphicslayout_p.h"
77#include "qgraphicslayoutitem.h"
78#include "qgraphicsgridlayout.h"
79#include "qgraphicswidget.h"
80#include "qgridlayoutengine_p.h"
81#include <QtCore/qdebug.h>
82
83QT_BEGIN_NAMESPACE
84
85class QGraphicsGridLayoutPrivate : public QGraphicsLayoutPrivate
86{
87public:
88 QGraphicsGridLayoutPrivate() { }
89 QLayoutStyleInfo styleInfo() const;
90
91 QGridLayoutEngine engine;
92#ifdef QT_DEBUG
93 void dump(int indent) const;
94#endif
95};
96
97QLayoutStyleInfo QGraphicsGridLayoutPrivate::styleInfo() const
98{
99 static QWidget *wid = 0;
100 if (!wid)
101 wid = new QWidget;
102 QGraphicsItem *item = parentItem();
103 QStyle *style = (item && item->isWidget()) ? static_cast<QGraphicsWidget*>(item)->style() : QApplication::style();
104 return QLayoutStyleInfo(style, wid);
105}
106
107/*!
108 Constructs a QGraphicsGridLayout instance. \a parent is passed to
109 QGraphicsLayout's constructor.
110*/
111QGraphicsGridLayout::QGraphicsGridLayout(QGraphicsLayoutItem *parent)
112 : QGraphicsLayout(*new QGraphicsGridLayoutPrivate(), parent)
113{
114}
115
116/*!
117 Destroys the QGraphicsGridLayout object.
118*/
119QGraphicsGridLayout::~QGraphicsGridLayout()
120{
121 for (int i = count() - 1; i >= 0; --i) {
122 QGraphicsLayoutItem *item = itemAt(i);
123 // The following lines can be removed, but this removes the item
124 // from the layout more efficiently than the implementation of
125 // ~QGraphicsLayoutItem.
126 removeAt(i);
127 if (item) {
128 item->setParentLayoutItem(0);
129 if (item->ownedByLayout())
130 delete item;
131 }
132 }
133}
134
135/*!
136 Adds \a item to the grid on \a row and \a column. You can specify a
137 \a rowSpan and \a columnSpan and an optional \a alignment.
138*/
139void QGraphicsGridLayout::addItem(QGraphicsLayoutItem *item, int row, int column,
140 int rowSpan, int columnSpan, Qt::Alignment alignment)
141{
142 Q_D(QGraphicsGridLayout);
143 if (row < 0 || column < 0) {
144 qWarning("QGraphicsGridLayout::addItem: invalid row/column: %d",
145 row < 0 ? row : column);
146 return;
147 }
148 if (columnSpan < 1 || rowSpan < 1) {
149 qWarning("QGraphicsGridLayout::addItem: invalid row span/column span: %d",
150 rowSpan < 1 ? rowSpan : columnSpan);
151 return;
152 }
153 if (!item) {
154 qWarning("QGraphicsGridLayout::addItem: cannot add null item");
155 return;
156 }
157 if (item == this) {
158 qWarning("QGraphicsGridLayout::addItem: cannot insert itself");
159 return;
160 }
161
162 d->addChildLayoutItem(item);
163
164 new QGridLayoutItem(&d->engine, item, row, column, rowSpan, columnSpan, alignment);
165 invalidate();
166}
167
168/*!
169 \fn QGraphicsGridLayout::addItem(QGraphicsLayoutItem *item, int row, int column, Qt::Alignment alignment = 0)
170
171 Adds \a item to the grid on \a row and \a column. You can specify
172 an optional \a alignment for \a item.
173*/
174
175/*!
176 Sets the default horizontal spacing for the grid layout to \a spacing.
177*/
178void QGraphicsGridLayout::setHorizontalSpacing(qreal spacing)
179{
180 Q_D(QGraphicsGridLayout);
181 d->engine.setSpacing(spacing, Qt::Horizontal);
182 invalidate();
183}
184
185/*!
186 Returns the default horizontal spacing for the grid layout.
187*/
188qreal QGraphicsGridLayout::horizontalSpacing() const
189{
190 Q_D(const QGraphicsGridLayout);
191 return d->engine.spacing(d->styleInfo(), Qt::Horizontal);
192}
193
194/*!
195 Sets the default vertical spacing for the grid layout to \a spacing.
196*/
197void QGraphicsGridLayout::setVerticalSpacing(qreal spacing)
198{
199 Q_D(QGraphicsGridLayout);
200 d->engine.setSpacing(spacing, Qt::Vertical);
201 invalidate();
202}
203
204/*!
205 Returns the default vertical spacing for the grid layout.
206*/
207qreal QGraphicsGridLayout::verticalSpacing() const
208{
209 Q_D(const QGraphicsGridLayout);
210 return d->engine.spacing(d->styleInfo(), Qt::Vertical);
211}
212
213/*!
214 Sets the grid layout's default spacing, both vertical and
215 horizontal, to \a spacing.
216
217 \sa rowSpacing(), columnSpacing()
218*/
219void QGraphicsGridLayout::setSpacing(qreal spacing)
220{
221 Q_D(QGraphicsGridLayout);
222 d->engine.setSpacing(spacing, Qt::Horizontal | Qt::Vertical);
223 invalidate();
224}
225
226/*!
227 Sets the spacing for \a row to \a spacing.
228*/
229void QGraphicsGridLayout::setRowSpacing(int row, qreal spacing)
230{
231 Q_D(QGraphicsGridLayout);
232 d->engine.setRowSpacing(row, spacing, Qt::Vertical);
233 invalidate();
234}
235
236/*!
237 Returns the row spacing for \a row.
238*/
239qreal QGraphicsGridLayout::rowSpacing(int row) const
240{
241 Q_D(const QGraphicsGridLayout);
242 return d->engine.rowSpacing(row, Qt::Vertical);
243}
244
245/*!
246 Sets the spacing for \a column to \a spacing.
247*/
248void QGraphicsGridLayout::setColumnSpacing(int column, qreal spacing)
249{
250 Q_D(QGraphicsGridLayout);
251 d->engine.setRowSpacing(column, spacing, Qt::Horizontal);
252 invalidate();
253}
254
255/*!
256 Returns the column spacing for \a column.
257*/
258qreal QGraphicsGridLayout::columnSpacing(int column) const
259{
260 Q_D(const QGraphicsGridLayout);
261 return d->engine.rowSpacing(column, Qt::Horizontal);
262}
263
264/*!
265 Sets the stretch factor for \a row to \a stretch.
266*/
267void QGraphicsGridLayout::setRowStretchFactor(int row, int stretch)
268{
269 Q_D(QGraphicsGridLayout);
270 d->engine.setRowStretchFactor(row, stretch, Qt::Vertical);
271 invalidate();
272}
273
274/*!
275 Returns the stretch factor for \a row.
276*/
277int QGraphicsGridLayout::rowStretchFactor(int row) const
278{
279 Q_D(const QGraphicsGridLayout);
280 return d->engine.rowStretchFactor(row, Qt::Vertical);
281}
282
283/*!
284 Sets the stretch factor for \a column to \a stretch.
285*/
286void QGraphicsGridLayout::setColumnStretchFactor(int column, int stretch)
287{
288 Q_D(QGraphicsGridLayout);
289 d->engine.setRowStretchFactor(column, stretch, Qt::Horizontal);
290 invalidate();
291}
292
293/*!
294 Returns the stretch factor for \a column.
295*/
296int QGraphicsGridLayout::columnStretchFactor(int column) const
297{
298 Q_D(const QGraphicsGridLayout);
299 return d->engine.rowStretchFactor(column, Qt::Horizontal);
300}
301
302/*!
303 Sets the minimum height for row, \a row, to \a height.
304*/
305void QGraphicsGridLayout::setRowMinimumHeight(int row, qreal height)
306{
307 Q_D(QGraphicsGridLayout);
308 d->engine.setRowSizeHint(Qt::MinimumSize, row, height, Qt::Vertical);
309 invalidate();
310}
311
312/*!
313 Returns the minimum height for row, \a row.
314*/
315qreal QGraphicsGridLayout::rowMinimumHeight(int row) const
316{
317 Q_D(const QGraphicsGridLayout);
318 return d->engine.rowSizeHint(Qt::MinimumSize, row, Qt::Vertical);
319}
320
321/*!
322 Sets the preferred height for row, \a row, to \a height.
323*/
324void QGraphicsGridLayout::setRowPreferredHeight(int row, qreal height)
325{
326 Q_D(QGraphicsGridLayout);
327 d->engine.setRowSizeHint(Qt::PreferredSize, row, height, Qt::Vertical);
328 invalidate();
329}
330
331/*!
332 Returns the preferred height for row, \a row.
333*/
334qreal QGraphicsGridLayout::rowPreferredHeight(int row) const
335{
336 Q_D(const QGraphicsGridLayout);
337 return d->engine.rowSizeHint(Qt::PreferredSize, row, Qt::Vertical);
338}
339
340/*!
341 Sets the maximum height for row, \a row, to \a height.
342*/
343void QGraphicsGridLayout::setRowMaximumHeight(int row, qreal height)
344{
345 Q_D(QGraphicsGridLayout);
346 d->engine.setRowSizeHint(Qt::MaximumSize, row, height, Qt::Vertical);
347 invalidate();
348}
349
350/*!
351 Returns the maximum height for row, \a row.
352*/
353qreal QGraphicsGridLayout::rowMaximumHeight(int row) const
354{
355 Q_D(const QGraphicsGridLayout);
356 return d->engine.rowSizeHint(Qt::MaximumSize, row, Qt::Vertical);
357}
358
359/*!
360 Sets the fixed height for row, \a row, to \a height.
361*/
362void QGraphicsGridLayout::setRowFixedHeight(int row, qreal height)
363{
364 Q_D(QGraphicsGridLayout);
365 d->engine.setRowSizeHint(Qt::MinimumSize, row, height, Qt::Vertical);
366 d->engine.setRowSizeHint(Qt::MaximumSize, row, height, Qt::Vertical);
367 invalidate();
368}
369
370/*!
371 Sets the minimum width for \a column to \a width.
372*/
373void QGraphicsGridLayout::setColumnMinimumWidth(int column, qreal width)
374{
375 Q_D(QGraphicsGridLayout);
376 d->engine.setRowSizeHint(Qt::MinimumSize, column, width, Qt::Horizontal);
377 invalidate();
378}
379
380/*!
381 Returns the minimum width for \a column.
382*/
383qreal QGraphicsGridLayout::columnMinimumWidth(int column) const
384{
385 Q_D(const QGraphicsGridLayout);
386 return d->engine.rowSizeHint(Qt::MinimumSize, column, Qt::Horizontal);
387}
388
389/*!
390 Sets the preferred width for \a column to \a width.
391*/
392void QGraphicsGridLayout::setColumnPreferredWidth(int column, qreal width)
393{
394 Q_D(QGraphicsGridLayout);
395 d->engine.setRowSizeHint(Qt::PreferredSize, column, width, Qt::Horizontal);
396 invalidate();
397}
398
399/*!
400 Returns the preferred width for \a column.
401*/
402qreal QGraphicsGridLayout::columnPreferredWidth(int column) const
403{
404 Q_D(const QGraphicsGridLayout);
405 return d->engine.rowSizeHint(Qt::PreferredSize, column, Qt::Horizontal);
406}
407
408/*!
409 Sets the maximum width of \a column to \a width.
410*/
411void QGraphicsGridLayout::setColumnMaximumWidth(int column, qreal width)
412{
413 Q_D(QGraphicsGridLayout);
414 d->engine.setRowSizeHint(Qt::MaximumSize, column, width, Qt::Horizontal);
415 invalidate();
416}
417
418/*!
419 Returns the maximum width for \a column.
420*/
421qreal QGraphicsGridLayout::columnMaximumWidth(int column) const
422{
423 Q_D(const QGraphicsGridLayout);
424 return d->engine.rowSizeHint(Qt::MaximumSize, column, Qt::Horizontal);
425}
426
427/*!
428 Sets the fixed width of \a column to \a width.
429*/
430void QGraphicsGridLayout::setColumnFixedWidth(int column, qreal width)
431{
432 Q_D(QGraphicsGridLayout);
433 d->engine.setRowSizeHint(Qt::MinimumSize, column, width, Qt::Horizontal);
434 d->engine.setRowSizeHint(Qt::MaximumSize, column, width, Qt::Horizontal);
435 invalidate();
436}
437
438/*!
439 Sets the alignment of \a row to \a alignment.
440*/
441void QGraphicsGridLayout::setRowAlignment(int row, Qt::Alignment alignment)
442{
443 Q_D(QGraphicsGridLayout);
444 d->engine.setRowAlignment(row, alignment, Qt::Vertical);
445 invalidate();
446}
447
448/*!
449 Returns the alignment of \a row.
450*/
451Qt::Alignment QGraphicsGridLayout::rowAlignment(int row) const
452{
453 Q_D(const QGraphicsGridLayout);
454 return d->engine.rowAlignment(row, Qt::Vertical);
455}
456
457/*!
458 Sets the alignment for \a column to \a alignment.
459*/
460void QGraphicsGridLayout::setColumnAlignment(int column, Qt::Alignment alignment)
461{
462 Q_D(QGraphicsGridLayout);
463 d->engine.setRowAlignment(column, alignment, Qt::Horizontal);
464 invalidate();
465}
466
467/*!
468 Returns the alignment for \a column.
469*/
470Qt::Alignment QGraphicsGridLayout::columnAlignment(int column) const
471{
472 Q_D(const QGraphicsGridLayout);
473 return d->engine.rowAlignment(column, Qt::Horizontal);
474}
475
476/*!
477 Sets the alignment for \a item to \a alignment.
478*/
479void QGraphicsGridLayout::setAlignment(QGraphicsLayoutItem *item, Qt::Alignment alignment)
480{
481 Q_D(QGraphicsGridLayout);
482 d->engine.setAlignment(item, alignment);
483 invalidate();
484}
485
486/*!
487 Returns the alignment for \a item.
488*/
489Qt::Alignment QGraphicsGridLayout::alignment(QGraphicsLayoutItem *item) const
490{
491 Q_D(const QGraphicsGridLayout);
492 return d->engine.alignment(item);
493}
494
495/*!
496 Returns the number of rows in the grid layout. This is always one more
497 than the index of the last row that is occupied by a layout item (empty
498 rows are counted except for those at the end).
499*/
500int QGraphicsGridLayout::rowCount() const
501{
502 Q_D(const QGraphicsGridLayout);
503 return d->engine.effectiveLastRow(Qt::Vertical) + 1;
504}
505
506/*!
507 Returns the number of columns in the grid layout. This is always one more
508 than the index of the last column that is occupied by a layout item (empty
509 columns are counted except for those at the end).
510*/
511int QGraphicsGridLayout::columnCount() const
512{
513 Q_D(const QGraphicsGridLayout);
514 return d->engine.effectiveLastRow(Qt::Horizontal) + 1;
515}
516
517/*!
518 Returns a pointer to the layout item at (\a row, \a column).
519*/
520QGraphicsLayoutItem *QGraphicsGridLayout::itemAt(int row, int column) const
521{
522 Q_D(const QGraphicsGridLayout);
523 if (row < 0 || row >= rowCount() || column < 0 || column >= columnCount()) {
524 qWarning("QGraphicsGridLayout::itemAt: invalid row, column %d, %d", row, column);
525 return 0;
526 }
527 if (QGridLayoutItem *item = d->engine.itemAt(row, column))
528 return item->layoutItem();
529 return 0;
530}
531
532/*!
533 Returns the number of layout items in this grid layout.
534*/
535int QGraphicsGridLayout::count() const
536{
537 Q_D(const QGraphicsGridLayout);
538 return d->engine.itemCount();
539}
540
541/*!
542 Returns the layout item at \a index, or 0 if there is no layout item at
543 this index.
544*/
545QGraphicsLayoutItem *QGraphicsGridLayout::itemAt(int index) const
546{
547 Q_D(const QGraphicsGridLayout);
548 if (index < 0 || index >= d->engine.itemCount()) {
549 qWarning("QGraphicsGridLayout::itemAt: invalid index %d", index);
550 return 0;
551 }
552 QGraphicsLayoutItem *item = 0;
553 if (QGridLayoutItem *gridItem = d->engine.itemAt(index))
554 item = gridItem->layoutItem();
555 return item;
556}
557
558/*!
559 Removes the layout item at \a index without destroying it. Ownership of
560 the item is transferred to the caller.
561
562 \sa addItem()
563*/
564void QGraphicsGridLayout::removeAt(int index)
565{
566 Q_D(QGraphicsGridLayout);
567 if (index < 0 || index >= d->engine.itemCount()) {
568 qWarning("QGraphicsGridLayout::removeAt: invalid index %d", index);
569 return;
570 }
571 if (QGridLayoutItem *gridItem = d->engine.itemAt(index)) {
572 if (QGraphicsLayoutItem *layoutItem = gridItem->layoutItem())
573 layoutItem->setParentLayoutItem(0);
574 d->engine.removeItem(gridItem);
575 delete gridItem;
576 invalidate();
577 }
578}
579
580/*!
581 \reimp
582*/
583void QGraphicsGridLayout::invalidate()
584{
585 Q_D(QGraphicsGridLayout);
586 d->engine.invalidate();
587 QGraphicsLayout::invalidate();
588}
589
590#ifdef QT_DEBUG
591void QGraphicsGridLayoutPrivate::dump(int indent) const
592{
593 if (qt_graphicsLayoutDebug()) {
594 engine.dump(indent + 1);
595 }
596}
597#endif
598
599/*!
600 Sets the bounding geometry of the grid layout to \a rect.
601*/
602void QGraphicsGridLayout::setGeometry(const QRectF &rect)
603{
604 Q_D(QGraphicsGridLayout);
605 QGraphicsLayout::setGeometry(rect);
606 QRectF effectiveRect = geometry();
607 qreal left, top, right, bottom;
608 getContentsMargins(&left, &top, &right, &bottom);
609 Qt::LayoutDirection visualDir = d->visualDirection();
610 d->engine.setVisualDirection(visualDir);
611 if (visualDir == Qt::RightToLeft)
612 qSwap(left, right);
613 effectiveRect.adjust(+left, +top, -right, -bottom);
614 d->engine.setGeometries(d->styleInfo(), effectiveRect);
615#ifdef QT_DEBUG
616 if (qt_graphicsLayoutDebug()) {
617 static int counter = 0;
618 qDebug("==== BEGIN DUMP OF QGraphicsGridLayout (%d)====", counter++);
619 d->dump(1);
620 qDebug("==== END DUMP OF QGraphicsGridLayout ====");
621 }
622#endif
623}
624
625/*!
626 \reimp
627*/
628QSizeF QGraphicsGridLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
629{
630 Q_D(const QGraphicsGridLayout);
631 qreal left, top, right, bottom;
632 getContentsMargins(&left, &top, &right, &bottom);
633 return d->engine.sizeHint(d->styleInfo(), which , constraint) + QSizeF(left + right, top + bottom);
634}
635
636
637#if 0
638// ### kill? (implement and kill?)
639QRect QGraphicsGridLayout::cellRect(int row, int column, int rowSpan, int columnSpan) const
640{
641 Q_D(const QGraphicsGridLayout);
642 return QRect();
643// return d->engine.cellRect(parentLayoutable(), contentsGeometry(), row, column, rowSpan, columnSpan);
644}
645
646QSizePolicy::ControlTypes QGraphicsGridLayout::controlTypes(LayoutSide side) const
647{
648 Q_D(const QGraphicsGridLayout);
649 return d->engine.controlTypes(side);
650}
651#endif
652
653QT_END_NAMESPACE
654
655#endif //QT_NO_GRAPHICSVIEW
Note: See TracBrowser for help on using the repository browser.