3537e662d833b615d264111588a37f2ec6d2d787
[profile/ivi/qtdeclarative.git] / src / qtquick1 / graphicsitems / qdeclarativepositioners.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "QtQuick1/private/qdeclarativepositioners_p.h"
43 #include "QtQuick1/private/qdeclarativepositioners_p_p.h"
44
45 #include <QtDeclarative/qdeclarative.h>
46 #include <QtQuick1/private/qdeclarativestate_p.h>
47 #include <QtQuick1/private/qdeclarativestategroup_p.h>
48 #include <QtQuick1/private/qdeclarativestateoperations_p.h>
49 #include <QtDeclarative/qdeclarativeinfo.h>
50 #include <QtCore/qmath.h>
51
52 #include <QDebug>
53 #include <QCoreApplication>
54
55 QT_BEGIN_NAMESPACE
56
57
58
59 static const QDeclarativeItemPrivate::ChangeTypes watchedChanges
60     = QDeclarativeItemPrivate::Geometry
61     | QDeclarativeItemPrivate::SiblingOrder
62     | QDeclarativeItemPrivate::Visibility
63     | QDeclarativeItemPrivate::Opacity
64     | QDeclarativeItemPrivate::Destroyed;
65
66 void QDeclarative1BasePositionerPrivate::watchChanges(QGraphicsObject *other)
67 {
68     if (QGraphicsItemPrivate::get(other)->isDeclarativeItem) {
69         QDeclarativeItemPrivate *otherPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(other));
70         otherPrivate->addItemChangeListener(this, watchedChanges);
71     } else {
72         Q_Q(QDeclarative1BasePositioner);
73         QObject::connect(other, SIGNAL(widthChanged()), q, SLOT(graphicsWidgetGeometryChanged()));
74         QObject::connect(other, SIGNAL(heightChanged()), q, SLOT(graphicsWidgetGeometryChanged()));
75         QObject::connect(other, SIGNAL(opacityChanged()), q, SLOT(graphicsWidgetGeometryChanged()));
76         QObject::connect(other, SIGNAL(visibleChanged()), q, SLOT(graphicsWidgetGeometryChanged()));
77     }
78 }
79
80 void QDeclarative1BasePositionerPrivate::unwatchChanges(QGraphicsObject* other)
81 {
82     if (QGraphicsItemPrivate::get(other)->isDeclarativeItem) {
83         QDeclarativeItemPrivate *otherPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(other));
84         otherPrivate->removeItemChangeListener(this, watchedChanges);
85     } else {
86         Q_Q(QDeclarative1BasePositioner);
87         QObject::disconnect(other, SIGNAL(widthChanged()), q, SLOT(graphicsWidgetGeometryChanged()));
88         QObject::disconnect(other, SIGNAL(heightChanged()), q, SLOT(graphicsWidgetGeometryChanged()));
89         QObject::disconnect(other, SIGNAL(opacityChanged()), q, SLOT(graphicsWidgetGeometryChanged()));
90         QObject::disconnect(other, SIGNAL(visibleChanged()), q, SLOT(graphicsWidgetGeometryChanged()));
91     }
92 }
93
94 void QDeclarative1BasePositioner::graphicsWidgetGeometryChanged()
95 {
96     prePositioning();
97 }
98
99 /*!
100     \internal
101     \class QDeclarative1BasePositioner
102     \brief The QDeclarative1BasePositioner class provides a base for QDeclarative1Graphics layouts.
103
104     To create a QDeclarative1Graphics Positioner, simply subclass QDeclarative1BasePositioner and implement
105     doLayout(), which is automatically called when the layout might need
106     updating. In doLayout() use the setX and setY functions from QDeclarative1BasePositioner, and the
107     base class will apply the positions along with the appropriate transitions. The items to
108     position are provided in order as the protected member positionedItems.
109
110     You also need to set a PositionerType, to declare whether you are positioning the x, y or both
111     for the child items. Depending on the chosen type, only x or y changes will be applied.
112
113     Note that the subclass is responsible for adding the spacing in between items.
114 */
115 QDeclarative1BasePositioner::QDeclarative1BasePositioner(PositionerType at, QDeclarativeItem *parent)
116     : QDeclarative1ImplicitSizeItem(*(new QDeclarative1BasePositionerPrivate), parent)
117 {
118     Q_D(QDeclarative1BasePositioner);
119     d->init(at);
120 }
121
122 QDeclarative1BasePositioner::QDeclarative1BasePositioner(QDeclarative1BasePositionerPrivate &dd, PositionerType at, QDeclarativeItem *parent)
123     : QDeclarative1ImplicitSizeItem(dd, parent)
124 {
125     Q_D(QDeclarative1BasePositioner);
126     d->init(at);
127 }
128
129 QDeclarative1BasePositioner::~QDeclarative1BasePositioner()
130 {
131     Q_D(QDeclarative1BasePositioner);
132     for (int i = 0; i < positionedItems.count(); ++i)
133         d->unwatchChanges(positionedItems.at(i).item);
134     positionedItems.clear();
135 }
136
137 int QDeclarative1BasePositioner::spacing() const
138 {
139     Q_D(const QDeclarative1BasePositioner);
140     return d->spacing;
141 }
142
143 void QDeclarative1BasePositioner::setSpacing(int s)
144 {
145     Q_D(QDeclarative1BasePositioner);
146     if (s==d->spacing)
147         return;
148     d->spacing = s;
149     prePositioning();
150     emit spacingChanged();
151 }
152
153 QDeclarative1Transition *QDeclarative1BasePositioner::move() const
154 {
155     Q_D(const QDeclarative1BasePositioner);
156     return d->moveTransition;
157 }
158
159 void QDeclarative1BasePositioner::setMove(QDeclarative1Transition *mt)
160 {
161     Q_D(QDeclarative1BasePositioner);
162     if (mt == d->moveTransition)
163         return;
164     d->moveTransition = mt;
165     emit moveChanged();
166 }
167
168 QDeclarative1Transition *QDeclarative1BasePositioner::add() const
169 {
170     Q_D(const QDeclarative1BasePositioner);
171     return d->addTransition;
172 }
173
174 void QDeclarative1BasePositioner::setAdd(QDeclarative1Transition *add)
175 {
176     Q_D(QDeclarative1BasePositioner);
177     if (add == d->addTransition)
178         return;
179
180     d->addTransition = add;
181     emit addChanged();
182 }
183
184 void QDeclarative1BasePositioner::componentComplete()
185 {
186     Q_D(QDeclarative1BasePositioner);
187     QDeclarativeItem::componentComplete();
188     positionedItems.reserve(d->QGraphicsItemPrivate::children.count());
189     prePositioning();
190     reportConflictingAnchors();
191 }
192
193 QVariant QDeclarative1BasePositioner::itemChange(GraphicsItemChange change,
194                                        const QVariant &value)
195 {
196     Q_D(QDeclarative1BasePositioner);
197     if (change == ItemChildAddedChange){
198         QGraphicsItem* item = value.value<QGraphicsItem*>();
199         QGraphicsObject* child = 0;
200         if(item)
201             child = item->toGraphicsObject();
202         if (child)
203             prePositioning();
204     } else if (change == ItemChildRemovedChange) {
205         QGraphicsItem* item = value.value<QGraphicsItem*>();
206         QGraphicsObject* child = 0;
207         if(item)
208             child = item->toGraphicsObject();
209         if (child) {
210             QDeclarative1BasePositioner::PositionedItem posItem(child);
211             int idx = positionedItems.find(posItem);
212             if (idx >= 0) {
213                 d->unwatchChanges(child);
214                 positionedItems.remove(idx);
215             }
216             prePositioning();
217         }
218     }
219     return QDeclarativeItem::itemChange(change, value);
220 }
221
222 void QDeclarative1BasePositioner::prePositioning()
223 {
224     Q_D(QDeclarative1BasePositioner);
225     if (!isComponentComplete())
226         return;
227
228     if (d->doingPositioning)
229         return;
230
231     d->queuedPositioning = false;
232     d->doingPositioning = true;
233     //Need to order children by creation order modified by stacking order
234     QList<QGraphicsItem *> children = d->QGraphicsItemPrivate::children;
235     qSort(children.begin(), children.end(), d->insertionOrder);
236
237     QPODVector<PositionedItem,8> oldItems;
238     positionedItems.copyAndClear(oldItems);
239     for (int ii = 0; ii < children.count(); ++ii) {
240         QGraphicsObject *child = children.at(ii)->toGraphicsObject();
241         if (!child)
242             continue;
243         QGraphicsItemPrivate *childPrivate = static_cast<QGraphicsItemPrivate*>(QGraphicsItemPrivate::get(child));
244         PositionedItem *item = 0;
245         PositionedItem posItem(child);
246         int wIdx = oldItems.find(posItem);
247         if (wIdx < 0) {
248             d->watchChanges(child);
249             positionedItems.append(posItem);
250             item = &positionedItems[positionedItems.count()-1];
251             item->isNew = true;
252             if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden || !childPrivate->width() || !childPrivate->height())
253                 item->isVisible = false;
254         } else {
255             item = &oldItems[wIdx];
256             // Items are only omitted from positioning if they are explicitly hidden
257             // i.e. their positioning is not affected if an ancestor is hidden.
258             if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden || !childPrivate->width() || !childPrivate->height()) {
259                 item->isVisible = false;
260             } else if (!item->isVisible) {
261                 item->isVisible = true;
262                 item->isNew = true;
263             } else {
264                 item->isNew = false;
265             }
266             positionedItems.append(*item);
267         }
268     }
269     QSizeF contentSize;
270     doPositioning(&contentSize);
271     if(d->addTransition || d->moveTransition)
272         finishApplyTransitions();
273     d->doingPositioning = false;
274     //Set implicit size to the size of its children
275     setImplicitHeight(contentSize.height());
276     setImplicitWidth(contentSize.width());
277 }
278
279 void QDeclarative1BasePositioner::positionX(int x, const PositionedItem &target)
280 {
281     Q_D(QDeclarative1BasePositioner);
282     if(d->type == Horizontal || d->type == Both){
283         if (target.isNew) {
284             if (!d->addTransition)
285                 target.item->setX(x);
286             else
287                 d->addActions << QDeclarative1Action(target.item, QLatin1String("x"), QVariant(x));
288         } else if (x != target.item->x()) {
289             if (!d->moveTransition)
290                 target.item->setX(x);
291             else
292                 d->moveActions << QDeclarative1Action(target.item, QLatin1String("x"), QVariant(x));
293         }
294     }
295 }
296
297 void QDeclarative1BasePositioner::positionY(int y, const PositionedItem &target)
298 {
299     Q_D(QDeclarative1BasePositioner);
300     if(d->type == Vertical || d->type == Both){
301         if (target.isNew) {
302             if (!d->addTransition)
303                 target.item->setY(y);
304             else
305                 d->addActions << QDeclarative1Action(target.item, QLatin1String("y"), QVariant(y));
306         } else if (y != target.item->y()) {
307             if (!d->moveTransition)
308                 target.item->setY(y);
309             else
310                 d->moveActions << QDeclarative1Action(target.item, QLatin1String("y"), QVariant(y));
311         }
312     }
313 }
314
315 void QDeclarative1BasePositioner::finishApplyTransitions()
316 {
317     Q_D(QDeclarative1BasePositioner);
318     // Note that if a transition is not set the transition manager will
319     // apply the changes directly, in the case add/move aren't set
320     d->addTransitionManager.transition(d->addActions, d->addTransition);
321     d->moveTransitionManager.transition(d->moveActions, d->moveTransition);
322     d->addActions.clear();
323     d->moveActions.clear();
324 }
325
326 /*!
327   \qmlclass Column QDeclarative1Column
328     \inqmlmodule QtQuick 1
329   \ingroup qml-positioning-elements
330   \since QtQuick 1.0
331   \brief The Column item arranges its children vertically.
332   \inherits Item
333
334   The Column item positions its child items so that they are vertically
335   aligned and not overlapping.
336
337   Spacing between items can be added using the \l spacing property.
338   Transitions can be used for cases where items managed by a Column are
339   added or moved. These are stored in the \l add and \l move properties
340   respectively.
341
342   See \l{Using QML Positioner and Repeater Items} for more details about this item and other
343   related items.
344
345   \section1 Example Usage
346
347   The following example positions differently shaped rectangles using a Column
348   item.
349
350   \image verticalpositioner_example.png
351
352   \snippet doc/src/snippets/qtquick1/column/vertical-positioner.qml document
353
354   \section1 Using Transitions
355
356   Transitions can be used to animate items that are added to, moved within,
357   or removed from a Column item. The \l add and \l move properties can be set to
358   the transitions that will be applied when items are added to, removed from,
359   or re-positioned within a Column item.
360
361   The use of transitions with positioners is described in more detail in the
362   \l{Using QML Positioner and Repeater Items#Using Transitions}{Using QML
363   Positioner and Repeater Items} document.
364
365   \image verticalpositioner_transition.gif
366
367   \qml
368   Column {
369       spacing: 2
370       add: Transition {
371           // Define an animation for adding a new item...
372       }
373       move: Transition {
374           // Define an animation for moving items within the column...
375       }
376       // ...
377   }
378   \endqml
379
380   \section1 Limitations
381
382   Note that the positioner assumes that the x and y positions of its children
383   will not change. If you manually change the x or y properties in script, bind
384   the x or y properties, use anchors on a child of a positioner, or have the
385   height of a child depend on the position of a child, then the
386   positioner may exhibit strange behavior. If you need to perform any of these
387   actions, consider positioning the items without the use of a Column.
388
389   Items with a width or height of 0 will not be positioned.
390
391   \sa Row, Grid, Flow, {declarative/positioners}{Positioners example}
392 */
393 /*!
394     \qmlproperty Transition QtQuick1::Column::add
395
396     This property holds the transition to be applied when adding an
397     item to the positioner. The transition will only be applied to the
398     added item(s).  Positioner transitions will only affect the
399     position (x, y) of items.
400
401     For a positioner, adding an item can mean that either the object
402     has been created or reparented, and thus is now a child or the
403     positioner, or that the object has had its opacity increased from
404     zero, and thus is now visible.
405
406     \sa move
407 */
408 /*!
409     \qmlproperty Transition QtQuick1::Column::move
410
411     This property holds the transition to apply when moving an item
412     within the positioner.  Positioner transitions will only affect
413     the position (x, y) of items.
414
415     This transition can be performed when other items are added or removed
416     from the positioner, or when items resize themselves.
417
418     \image positioner-move.gif
419
420     \qml
421     Column {
422         move: Transition {
423             NumberAnimation {
424                 properties: "y"
425                 duration: 1000
426             }
427         }
428     }
429     \endqml
430
431     \sa add, {declarative/positioners}{Positioners example}
432 */
433 /*!
434   \qmlproperty int QtQuick1::Column::spacing
435
436   The spacing is the amount in pixels left empty between adjacent
437   items. The default spacing is 0.
438
439   \sa Grid::spacing
440 */
441 QDeclarative1Column::QDeclarative1Column(QDeclarativeItem *parent)
442 : QDeclarative1BasePositioner(Vertical, parent)
443 {
444 }
445
446 void QDeclarative1Column::doPositioning(QSizeF *contentSize)
447 {
448     int voffset = 0;
449
450     for (int ii = 0; ii < positionedItems.count(); ++ii) {
451         const PositionedItem &child = positionedItems.at(ii);
452         if (!child.item || !child.isVisible)
453             continue;
454
455         if(child.item->y() != voffset)
456             positionY(voffset, child);
457
458         contentSize->setWidth(qMax(contentSize->width(), QGraphicsItemPrivate::get(child.item)->width()));
459
460         voffset += QGraphicsItemPrivate::get(child.item)->height();
461         voffset += spacing();
462     }
463
464     contentSize->setHeight(voffset - spacing());
465 }
466
467 void QDeclarative1Column::reportConflictingAnchors()
468 {
469     QDeclarative1BasePositionerPrivate *d = static_cast<QDeclarative1BasePositionerPrivate*>(QDeclarative1BasePositionerPrivate::get(this));
470     for (int ii = 0; ii < positionedItems.count(); ++ii) {
471         const PositionedItem &child = positionedItems.at(ii);
472         if (child.item && QGraphicsItemPrivate::get(child.item)->isDeclarativeItem) {
473             QDeclarative1Anchors *anchors = QDeclarativeItemPrivate::get(static_cast<QDeclarativeItem *>(child.item))->_anchors;
474             if (anchors) {
475                 QDeclarative1Anchors::Anchors usedAnchors = anchors->usedAnchors();
476                 if (usedAnchors & QDeclarative1Anchors::TopAnchor ||
477                     usedAnchors & QDeclarative1Anchors::BottomAnchor ||
478                     usedAnchors & QDeclarative1Anchors::VCenterAnchor ||
479                     anchors->fill() || anchors->centerIn()) {
480                     d->anchorConflict = true;
481                     break;
482                 }
483             }
484         }
485     }
486     if (d->anchorConflict) {
487         qmlInfo(this) << "Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column";
488     }
489 }
490
491 /*!
492   \qmlclass Row QDeclarative1Row
493     \inqmlmodule QtQuick 1
494   \ingroup qml-positioning-elements
495   \since QtQuick 1.0
496   \brief The Row item arranges its children horizontally.
497   \inherits Item
498
499   The Row item positions its child items so that they are horizontally
500   aligned and not overlapping. 
501
502   Use \l spacing to set the spacing between items in a Row, and use the
503   \l add and \l move properties to set the transitions that should be applied
504   when items are added to, removed from, or re-positioned within the Row.
505
506   See \l{Using QML Positioner and Repeater Items} for more details about this item and other
507   related items.
508
509   \section1 Example Usage
510
511   The following example lays out differently shaped rectangles using a Row.
512
513   \image horizontalpositioner_example.png
514
515   \snippet doc/src/snippets/qtquick1/row/row.qml document
516
517   \section1 Using Transitions
518
519   Transitions can be used to animate items that are added to, moved within,
520   or removed from a Grid item. The \l add and \l move properties can be set to
521   the transitions that will be applied when items are added to, removed from,
522   or re-positioned within a Row item.
523
524   \section1 Limitations
525
526   Note that the positioner assumes that the x and y positions of its children
527   will not change. If you manually change the x or y properties in script, bind
528   the x or y properties, use anchors on a child of a positioner, or have the
529   width of a child depend on the position of a child, then the
530   positioner may exhibit strange behaviour. If you need to perform any of these
531   actions, consider positioning the items without the use of a Row.
532
533   Items with a width or height of 0 will not be positioned.
534
535   \sa Column, Grid, Flow, {declarative/positioners}{Positioners example}
536 */
537 /*!
538     \qmlproperty Transition QtQuick1::Row::add
539
540     This property holds the transition to be applied when adding an
541     item to the positioner. The transition will only be applied to the
542     added item(s).  Positioner transitions will only affect the
543     position (x, y) of items.
544
545     For a positioner, adding an item can mean that either the object
546     has been created or reparented, and thus is now a child or the
547     positioner, or that the object has had its opacity increased from
548     zero, and thus is now visible.
549
550     \sa move
551 */
552 /*!
553     \qmlproperty Transition QtQuick1::Row::move
554
555     This property holds the transition to be applied when moving an
556     item within the positioner. Positioner transitions will only affect
557     the position (x, y) of items.
558
559     This transition can be performed when other items are added or removed
560     from the positioner, or when items resize themselves.
561
562     \qml
563     Row {
564         id: positioner
565         move: Transition {
566             NumberAnimation {
567                 properties: "x"
568                 duration: 1000
569             }
570         }
571     }
572     \endqml
573
574     \sa add, {declarative/positioners}{Positioners example}
575 */
576 /*!
577   \qmlproperty int QtQuick1::Row::spacing
578
579   The spacing is the amount in pixels left empty between adjacent
580   items. The default spacing is 0.
581
582   \sa Grid::spacing
583 */
584 QDeclarative1Row::QDeclarative1Row(QDeclarativeItem *parent)
585 : QDeclarative1BasePositioner(Horizontal, parent)
586 {
587 }
588
589 /*!
590     \qmlproperty enumeration QtQuick1::Row::layoutDirection
591     \since Quick 1.1
592
593     This property holds the layoutDirection of the row.
594
595     Possible values:
596
597     \list
598     \o Qt.LeftToRight (default) - Items are laid out from left to right. If the width of the row is explicitly set,
599     the left anchor remains to the left of the row.
600     \o Qt.RightToLeft - Items are laid out from right to left. If the width of the row is explicitly set,
601     the right anchor remains to the right of the row.
602     \endlist
603
604     \sa Grid::layoutDirection, Flow::layoutDirection, {declarative/righttoleft/layoutdirection}{Layout directions example}
605 */
606 Qt::LayoutDirection QDeclarative1Row::layoutDirection() const
607 {
608     return QDeclarative1BasePositionerPrivate::getLayoutDirection(this);
609 }
610
611 void QDeclarative1Row::setLayoutDirection(Qt::LayoutDirection layoutDirection)
612 {
613     QDeclarative1BasePositionerPrivate *d = static_cast<QDeclarative1BasePositionerPrivate* >(QDeclarative1BasePositionerPrivate::get(this));
614     if (d->layoutDirection != layoutDirection) {
615         d->layoutDirection = layoutDirection;
616         // For RTL layout the positioning changes when the width changes.
617         if (d->layoutDirection == Qt::RightToLeft)
618             d->addItemChangeListener(d, QDeclarativeItemPrivate::Geometry);
619         else
620             d->removeItemChangeListener(d, QDeclarativeItemPrivate::Geometry);
621         prePositioning();
622         emit layoutDirectionChanged();
623         emit effectiveLayoutDirectionChanged();
624     }
625 }
626
627 /*!
628     \qmlproperty enumeration QtQuick1::Row::effectiveLayoutDirection
629     This property holds the effective layout direction of the row positioner.
630
631     When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} for locale layouts,
632     the visual layout direction of the row positioner will be mirrored. However, the
633     property \l {Row::layoutDirection}{layoutDirection} will remain unchanged.
634
635     \sa Row::layoutDirection, {LayoutMirroring}{LayoutMirroring}
636 */
637
638 Qt::LayoutDirection QDeclarative1Row::effectiveLayoutDirection() const
639 {
640     return QDeclarative1BasePositionerPrivate::getEffectiveLayoutDirection(this);
641 }
642
643 void QDeclarative1Row::doPositioning(QSizeF *contentSize)
644 {
645     QDeclarative1BasePositionerPrivate *d = static_cast<QDeclarative1BasePositionerPrivate*>(QDeclarative1BasePositionerPrivate::get(this));
646     int hoffset = 0;
647
648     QList<int> hoffsets;
649     for (int ii = 0; ii < positionedItems.count(); ++ii) {
650         const PositionedItem &child = positionedItems.at(ii);
651         if (!child.item || !child.isVisible)
652             continue;
653
654         if(d->isLeftToRight()){
655             if(child.item->x() != hoffset)
656                 positionX(hoffset, child);
657         }else{
658             hoffsets << hoffset;
659         }
660
661         contentSize->setHeight(qMax(contentSize->height(), QGraphicsItemPrivate::get(child.item)->height()));
662
663         hoffset += QGraphicsItemPrivate::get(child.item)->width();
664         hoffset += spacing();
665     }
666
667     contentSize->setWidth(hoffset - spacing());
668
669     if(d->isLeftToRight())
670         return;
671
672     //Right to Left layout
673     int end = 0;
674     if(!widthValid())
675         end = contentSize->width();
676     else
677         end = width();
678
679     int acc = 0;
680     for (int ii = 0; ii < positionedItems.count(); ++ii) {
681         const PositionedItem &child = positionedItems.at(ii);
682         if (!child.item || !child.isVisible)
683             continue;
684         hoffset = end - hoffsets[acc++] - QGraphicsItemPrivate::get(child.item)->width();
685         if(child.item->x() != hoffset)
686             positionX(hoffset, child);
687     }
688 }
689
690 void QDeclarative1Row::reportConflictingAnchors()
691 {
692     QDeclarative1BasePositionerPrivate *d = static_cast<QDeclarative1BasePositionerPrivate*>(QDeclarative1BasePositionerPrivate::get(this));
693     for (int ii = 0; ii < positionedItems.count(); ++ii) {
694         const PositionedItem &child = positionedItems.at(ii);
695         if (child.item && QGraphicsItemPrivate::get(child.item)->isDeclarativeItem) {
696             QDeclarative1Anchors *anchors = QDeclarativeItemPrivate::get(static_cast<QDeclarativeItem *>(child.item))->_anchors;
697             if (anchors) {
698                 QDeclarative1Anchors::Anchors usedAnchors = anchors->usedAnchors();
699                 if (usedAnchors & QDeclarative1Anchors::LeftAnchor ||
700                     usedAnchors & QDeclarative1Anchors::RightAnchor ||
701                     usedAnchors & QDeclarative1Anchors::HCenterAnchor ||
702                     anchors->fill() || anchors->centerIn()) {
703                     d->anchorConflict = true;
704                     break;
705                 }
706             }
707         }
708     }
709     if (d->anchorConflict)
710         qmlInfo(this) << "Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row";
711 }
712
713 /*!
714   \qmlclass Grid QDeclarative1Grid
715     \inqmlmodule QtQuick 1
716   \ingroup qml-positioning-elements
717   \since QtQuick 1.0
718   \brief The Grid item positions its children in a grid.
719   \inherits Item
720
721   The Grid item positions its child items so that they are
722   aligned in a grid and are not overlapping. 
723
724   The grid positioner calculates a grid of rectangular cells of sufficient
725   size to hold all items, placing the items in the cells, from left to right
726   and top to bottom. Each item is positioned in the top-left corner of its
727   cell with position (0, 0).
728
729   A Grid defaults to four columns, and as many rows as are necessary to
730   fit all child items. The number of rows and columns can be constrained
731   by setting the \l rows and \l columns properties.
732
733   Spacing can be added between child items by setting the \l spacing
734   property. The amount of spacing applied will be the same in the
735   horizontal and vertical directions.
736
737   See \l{Using QML Positioner and Repeater Items} for more details about this item and other
738   related items.
739
740   \section1 Example Usage
741
742   The following example demonstrates this.
743
744   \image gridLayout_example.png
745
746   \snippet doc/src/snippets/qtquick1/grid/grid.qml document
747
748   \section1 Using Transitions
749
750   Transitions can be used to animate items that are added to, moved within,
751   or removed from a Grid item. The \l add and \l move properties can be set to
752   the transitions that will be applied when items are added to, removed from,
753   or re-positioned within a Grid item.
754
755   \section1 Limitations
756
757   Note that the positioner assumes that the x and y positions of its children
758   will not change. If you manually change the x or y properties in script, bind
759   the x or y properties, use anchors on a child of a positioner, or have the
760   width or height of a child depend on the position of a child, then the
761   positioner may exhibit strange behaviour. If you need to perform any of these
762   actions, consider positioning the items without the use of a Grid.
763
764   Items with a width or height of 0 will not be positioned.
765
766   \sa Flow, Row, Column, {declarative/positioners}{Positioners example}
767 */
768 /*!
769     \qmlproperty Transition QtQuick1::Grid::add
770
771     This property holds the transition to be applied when adding an
772     item to the positioner. The transition will only be applied to the
773     added item(s).  Positioner transitions will only affect the
774     position (x, y) of items.
775
776     For a positioner, adding an item can mean that either the object
777     has been created or reparented, and thus is now a child or the
778     positioner, or that the object has had its opacity increased from
779     zero, and thus is now visible.
780
781     \sa move
782 */
783 /*!
784     \qmlproperty Transition QtQuick1::Grid::move
785
786     This property holds the transition to be applied when moving an
787     item within the positioner. Positioner transitions will only affect
788     the position (x, y) of items.
789
790     This transition can be performed when other items are added or removed
791     from the positioner, or when items resize themselves.
792
793     \qml
794     Grid {
795         move: Transition {
796             NumberAnimation {
797                 properties: "x,y"
798                 duration: 1000
799             }
800         }
801     }
802     \endqml
803
804     \sa add, {declarative/positioners}{Positioners example}
805 */
806 /*!
807   \qmlproperty int QtQuick1::Grid::spacing
808
809   The spacing is the amount in pixels left empty between adjacent
810   items. The default spacing is 0.
811
812   The below example places a Grid containing a red, a blue and a
813   green rectangle on a gray background. The area the grid positioner
814   occupies is colored white. The positioner on the left has the
815   no spacing (the default), and the positioner on the right has
816   a spacing of 6.
817
818   \inlineimage qml-grid-no-spacing.png
819   \inlineimage qml-grid-spacing.png
820
821   \sa rows, columns
822 */
823 QDeclarative1Grid::QDeclarative1Grid(QDeclarativeItem *parent) :
824     QDeclarative1BasePositioner(Both, parent), m_rows(-1), m_columns(-1), m_flow(LeftToRight)
825 {
826 }
827
828 /*!
829     \qmlproperty int QtQuick1::Grid::columns
830
831     This property holds the number of columns in the grid. The default
832     number of columns is 4.
833
834     If the grid does not have enough items to fill the specified
835     number of columns, some columns will be of zero width.
836 */
837
838 /*!
839     \qmlproperty int QtQuick1::Grid::rows
840     This property holds the number of rows in the grid.
841
842     If the grid does not have enough items to fill the specified
843     number of rows, some rows will be of zero width.
844 */
845
846 void QDeclarative1Grid::setColumns(const int columns)
847 {
848     if (columns == m_columns)
849         return;
850     m_columns = columns;
851     prePositioning();
852     emit columnsChanged();
853 }
854
855 void QDeclarative1Grid::setRows(const int rows)
856 {
857     if (rows == m_rows)
858         return;
859     m_rows = rows;
860     prePositioning();
861     emit rowsChanged();
862 }
863
864 /*!
865     \qmlproperty enumeration QtQuick1::Grid::flow
866     This property holds the flow of the layout.
867
868     Possible values are:
869
870     \list
871     \o Grid.LeftToRight (default) - Items are positioned next to
872        each other in the \l layoutDirection, then wrapped to the next line.
873     \o Grid.TopToBottom - Items are positioned next to each
874        other from top to bottom, then wrapped to the next column.
875     \endlist
876 */
877 QDeclarative1Grid::Flow QDeclarative1Grid::flow() const
878 {
879     return m_flow;
880 }
881
882 void QDeclarative1Grid::setFlow(Flow flow)
883 {
884     if (m_flow != flow) {
885         m_flow = flow;
886         prePositioning();
887         emit flowChanged();
888     }
889 }
890
891 /*!
892     \qmlproperty enumeration QtQuick1::Grid::layoutDirection
893     \since Quick 1.1
894
895     This property holds the layout direction of the layout.
896
897     Possible values are:
898
899     \list
900     \o Qt.LeftToRight (default) - Items are positioned from the top to bottom,
901     and left to right. The flow direction is dependent on the
902     \l Grid::flow property.
903     \o Qt.RightToLeft - Items are positioned from the top to bottom,
904     and right to left. The flow direction is dependent on the
905     \l Grid::flow property.
906     \endlist
907
908     \sa Flow::layoutDirection, Row::layoutDirection, {declarative/righttoleft/layoutdirection}{Layout directions example}
909 */
910 Qt::LayoutDirection QDeclarative1Grid::layoutDirection() const
911 {
912     return QDeclarative1BasePositionerPrivate::getLayoutDirection(this);
913 }
914
915 void QDeclarative1Grid::setLayoutDirection(Qt::LayoutDirection layoutDirection)
916 {
917     QDeclarative1BasePositionerPrivate *d = static_cast<QDeclarative1BasePositionerPrivate*>(QDeclarative1BasePositionerPrivate::get(this));
918     if (d->layoutDirection != layoutDirection) {
919         d->layoutDirection = layoutDirection;
920         // For RTL layout the positioning changes when the width changes.
921         if (d->layoutDirection == Qt::RightToLeft)
922             d->addItemChangeListener(d, QDeclarativeItemPrivate::Geometry);
923         else
924             d->removeItemChangeListener(d, QDeclarativeItemPrivate::Geometry);
925         prePositioning();
926         emit layoutDirectionChanged();
927         emit effectiveLayoutDirectionChanged();
928     }
929 }
930
931 /*!
932     \qmlproperty enumeration QtQuick1::Grid::effectiveLayoutDirection
933     This property holds the effective layout direction of the grid positioner.
934
935     When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} for locale layouts,
936     the visual layout direction of the grid positioner will be mirrored. However, the
937     property \l {Grid::layoutDirection}{layoutDirection} will remain unchanged.
938
939     \sa Grid::layoutDirection, {LayoutMirroring}{LayoutMirroring}
940 */
941
942 Qt::LayoutDirection QDeclarative1Grid::effectiveLayoutDirection() const
943 {
944     return QDeclarative1BasePositionerPrivate::getEffectiveLayoutDirection(this);
945 }
946
947 void QDeclarative1Grid::doPositioning(QSizeF *contentSize)
948 {
949     QDeclarative1BasePositionerPrivate *d = static_cast<QDeclarative1BasePositionerPrivate*>(QDeclarative1BasePositionerPrivate::get(this));
950     int c = m_columns;
951     int r = m_rows;
952     //Is allocating the extra QPODVector too much overhead?
953     QPODVector<PositionedItem, 8> visibleItems;//we aren't concerned with invisible items
954     visibleItems.reserve(positionedItems.count());
955     for(int i=0; i<positionedItems.count(); i++)
956         if(positionedItems[i].item && positionedItems[i].isVisible)
957             visibleItems.append(positionedItems[i]);
958
959     int numVisible = visibleItems.count();
960     if (m_columns <= 0 && m_rows <= 0){
961         c = 4;
962         r = (numVisible+3)/4;
963     } else if (m_rows <= 0){
964         r = (numVisible+(m_columns-1))/m_columns;
965     } else if (m_columns <= 0){
966         c = (numVisible+(m_rows-1))/m_rows;
967     }
968
969     if(r==0 || c==0)
970         return; //Nothing to do
971
972     QList<int> maxColWidth;
973     QList<int> maxRowHeight;
974     int childIndex =0;
975     if (m_flow == LeftToRight) {
976         for (int i=0; i < r; i++){
977             for (int j=0; j < c; j++){
978                 if (j==0)
979                     maxRowHeight << 0;
980                 if (i==0)
981                     maxColWidth << 0;
982
983                 if (childIndex == visibleItems.count())
984                     break;
985
986                 const PositionedItem &child = visibleItems.at(childIndex++);
987                 QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child.item);
988                 if (childPrivate->width() > maxColWidth[j])
989                     maxColWidth[j] = childPrivate->width();
990                 if (childPrivate->height() > maxRowHeight[i])
991                     maxRowHeight[i] = childPrivate->height();
992             }
993         }
994     } else {
995         for (int j=0; j < c; j++){
996             for (int i=0; i < r; i++){
997                 if (j==0)
998                     maxRowHeight << 0;
999                 if (i==0)
1000                     maxColWidth << 0;
1001
1002                 if (childIndex == visibleItems.count())
1003                     break;
1004
1005                 const PositionedItem &child = visibleItems.at(childIndex++);
1006                 QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child.item);
1007                 if (childPrivate->width() > maxColWidth[j])
1008                     maxColWidth[j] = childPrivate->width();
1009                 if (childPrivate->height() > maxRowHeight[i])
1010                     maxRowHeight[i] = childPrivate->height();
1011             }
1012         }
1013     }
1014
1015     int widthSum = 0;
1016     for(int j=0; j < maxColWidth.size(); j++){
1017         if(j)
1018             widthSum += spacing();
1019         widthSum += maxColWidth[j];
1020     }
1021
1022     int heightSum = 0;
1023     for(int i=0; i < maxRowHeight.size(); i++){
1024         if(i)
1025             heightSum += spacing();
1026         heightSum += maxRowHeight[i];
1027     }
1028
1029     contentSize->setHeight(heightSum);
1030     contentSize->setWidth(widthSum);
1031
1032     int end = 0;
1033     if(widthValid())
1034         end = width();
1035     else
1036         end = widthSum;
1037
1038     int xoffset=0;
1039     if(!d->isLeftToRight())
1040         xoffset=end;
1041     int yoffset=0;
1042     int curRow =0;
1043     int curCol =0;
1044     for (int i = 0; i < visibleItems.count(); ++i) {
1045         const PositionedItem &child = visibleItems.at(i);
1046         int childXOffset = xoffset;
1047         if(!d->isLeftToRight())
1048             childXOffset -= QGraphicsItemPrivate::get(child.item)->width();
1049         if((child.item->x()!=childXOffset)||(child.item->y()!=yoffset)){
1050             positionX(childXOffset, child);
1051             positionY(yoffset, child);
1052         }
1053
1054         if (m_flow == LeftToRight) {
1055             if(d->isLeftToRight())
1056                 xoffset+=maxColWidth[curCol]+spacing();
1057             else
1058                 xoffset-=maxColWidth[curCol]+spacing();
1059             curCol++;
1060             curCol%=c;
1061             if (!curCol){
1062                 yoffset+=maxRowHeight[curRow]+spacing();
1063                 if(d->isLeftToRight())
1064                     xoffset=0;
1065                 else
1066                     xoffset=end;
1067                 curRow++;
1068                 if (curRow>=r)
1069                     break;
1070             }
1071         } else {
1072             yoffset+=maxRowHeight[curRow]+spacing();
1073             curRow++;
1074             curRow%=r;
1075             if (!curRow){
1076                 if(d->isLeftToRight())
1077                     xoffset+=maxColWidth[curCol]+spacing();
1078                 else
1079                     xoffset-=maxColWidth[curCol]+spacing();
1080                 yoffset=0;
1081                 curCol++;
1082                 if (curCol>=c)
1083                     break;
1084             }
1085         }
1086     }
1087 }
1088
1089 void QDeclarative1Grid::reportConflictingAnchors()
1090 {
1091     QDeclarative1BasePositionerPrivate *d = static_cast<QDeclarative1BasePositionerPrivate*>(QDeclarative1BasePositionerPrivate::get(this));
1092     for (int ii = 0; ii < positionedItems.count(); ++ii) {
1093         const PositionedItem &child = positionedItems.at(ii);
1094         if (child.item && QGraphicsItemPrivate::get(child.item)->isDeclarativeItem) {
1095             QDeclarative1Anchors *anchors = QDeclarativeItemPrivate::get(static_cast<QDeclarativeItem *>(child.item))->_anchors;
1096             if (anchors && (anchors->usedAnchors() || anchors->fill() || anchors->centerIn())) {
1097                 d->anchorConflict = true;
1098                 break;
1099             }
1100         }
1101     }
1102     if (d->anchorConflict)
1103         qmlInfo(this) << "Cannot specify anchors for items inside Grid";
1104 }
1105
1106 /*!
1107   \qmlclass Flow QDeclarative1Flow
1108     \inqmlmodule QtQuick 1
1109   \ingroup qml-positioning-elements
1110   \since QtQuick 1.0
1111   \brief The Flow item arranges its children side by side, wrapping as necessary.
1112   \inherits Item
1113
1114   The Flow item positions its child items like words on a page, wrapping them
1115   to create rows or columns of items that do not overlap.
1116
1117   Spacing between items can be added using the \l spacing property.
1118   Transitions can be used for cases where items managed by a Column are
1119   added or moved. These are stored in the \l add and \l move properties
1120   respectively.
1121
1122   See \l{Using QML Positioner and Repeater Items} for more details about this item and other
1123   related items.
1124
1125   \section1 Example Usage
1126
1127   The following example positions \l Text items within a parent item using
1128   a Flow item.
1129
1130   \image qml-flow-snippet.png
1131
1132   \snippet doc/src/snippets/qtquick1/flow.qml flow item
1133
1134   \section1 Using Transitions
1135
1136   Transitions can be used to animate items that are added to, moved within,
1137   or removed from a Flow item. The \l add and \l move properties can be set to
1138   the transitions that will be applied when items are added to, removed from,
1139   or re-positioned within a Flow item.
1140
1141   The use of transitions with positioners is described in more detail in the
1142   \l{Using QML Positioner and Repeater Items#Using Transitions}{Using QML
1143   Positioner and Repeater Items} document.
1144
1145   \section1 Limitations
1146
1147   Note that the positioner assumes that the x and y positions of its children
1148   will not change. If you manually change the x or y properties in script, bind
1149   the x or y properties, use anchors on a child of a positioner, or have the
1150   width or height of a child depend on the position of a child, then the
1151   positioner may exhibit strange behaviour.  If you need to perform any of these
1152   actions, consider positioning the items without the use of a Flow.
1153
1154   Items with a width or height of 0 will not be positioned.
1155
1156   \sa Column, Row, Grid, {declarative/positioners}{Positioners example}
1157 */
1158 /*!
1159     \qmlproperty Transition QtQuick1::Flow::add
1160
1161     This property holds the transition to be applied when adding an
1162     item to the positioner. The transition will only be applied to the
1163     added item(s).  Positioner transitions will only affect the
1164     position (x, y) of items.
1165
1166     For a positioner, adding an item can mean that either the object
1167     has been created or reparented, and thus is now a child or the
1168     positioner, or that the object has had its opacity increased from
1169     zero, and thus is now visible.
1170
1171     \sa move
1172 */
1173 /*!
1174     \qmlproperty Transition QtQuick1::Flow::move
1175
1176     This property holds the transition to be applied when moving an
1177     item within the positioner. Positioner transitions will only affect
1178     the position (x, y) of items.
1179
1180     This transition can be performed when other items are added or removed
1181     from the positioner, or when items resize themselves.
1182
1183     \qml
1184     Flow {
1185         id: positioner
1186         move: Transition {
1187             NumberAnimation {
1188                 properties: "x,y"
1189                 ease: "easeOutBounce"
1190             }
1191         }
1192     }
1193     \endqml
1194
1195     \sa add, {declarative/positioners}{Positioners example}
1196 */
1197 /*!
1198   \qmlproperty int QtQuick1::Flow::spacing
1199
1200   spacing is the amount in pixels left empty between each adjacent
1201   item, and defaults to 0.
1202
1203   \sa Grid::spacing
1204 */
1205
1206 class QDeclarative1FlowPrivate : public QDeclarative1BasePositionerPrivate
1207 {
1208     Q_DECLARE_PUBLIC(QDeclarative1Flow)
1209
1210 public:
1211     QDeclarative1FlowPrivate()
1212         : QDeclarative1BasePositionerPrivate(), flow(QDeclarative1Flow::LeftToRight)
1213     {}
1214
1215     QDeclarative1Flow::Flow flow;
1216 };
1217
1218 QDeclarative1Flow::QDeclarative1Flow(QDeclarativeItem *parent)
1219 : QDeclarative1BasePositioner(*(new QDeclarative1FlowPrivate), Both, parent)
1220 {
1221     Q_D(QDeclarative1Flow);
1222     // Flow layout requires relayout if its own size changes too.
1223     d->addItemChangeListener(d, QDeclarativeItemPrivate::Geometry);
1224 }
1225
1226 /*!
1227     \qmlproperty enumeration QtQuick1::Flow::flow
1228     This property holds the flow of the layout.
1229
1230     Possible values are:
1231
1232     \list
1233     \o Flow.LeftToRight (default) - Items are positioned next to
1234     to each other according to the \l layoutDirection until the width of the Flow
1235     is exceeded, then wrapped to the next line.
1236     \o Flow.TopToBottom - Items are positioned next to each
1237     other from top to bottom until the height of the Flow is exceeded,
1238     then wrapped to the next column.
1239     \endlist
1240 */
1241 QDeclarative1Flow::Flow QDeclarative1Flow::flow() const
1242 {
1243     Q_D(const QDeclarative1Flow);
1244     return d->flow;
1245 }
1246
1247 void QDeclarative1Flow::setFlow(Flow flow)
1248 {
1249     Q_D(QDeclarative1Flow);
1250     if (d->flow != flow) {
1251         d->flow = flow;
1252         prePositioning();
1253         emit flowChanged();
1254     }
1255 }
1256
1257 /*!
1258     \qmlproperty enumeration QtQuick1::Flow::layoutDirection
1259     \since Quick 1.1
1260
1261     This property holds the layout direction of the layout.
1262
1263     Possible values are:
1264
1265     \list
1266     \o Qt.LeftToRight (default) - Items are positioned from the top to bottom,
1267     and left to right. The flow direction is dependent on the
1268     \l Flow::flow property.
1269     \o Qt.RightToLeft - Items are positioned from the top to bottom,
1270     and right to left. The flow direction is dependent on the
1271     \l Flow::flow property.
1272     \endlist
1273
1274     \sa Grid::layoutDirection, Row::layoutDirection, {declarative/righttoleft/layoutdirection}{Layout directions example}
1275 */
1276
1277 Qt::LayoutDirection QDeclarative1Flow::layoutDirection() const
1278 {
1279     Q_D(const QDeclarative1Flow);
1280     return d->layoutDirection;
1281 }
1282
1283 void QDeclarative1Flow::setLayoutDirection(Qt::LayoutDirection layoutDirection)
1284 {
1285     Q_D(QDeclarative1Flow);
1286     if (d->layoutDirection != layoutDirection) {
1287         d->layoutDirection = layoutDirection;
1288         prePositioning();
1289         emit layoutDirectionChanged();
1290         emit effectiveLayoutDirectionChanged();
1291     }
1292 }
1293
1294 /*!
1295     \qmlproperty enumeration QtQuick1::Flow::effectiveLayoutDirection
1296     This property holds the effective layout direction of the flow positioner.
1297
1298     When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} for locale layouts,
1299     the visual layout direction of the grid positioner will be mirrored. However, the
1300     property \l {Flow::layoutDirection}{layoutDirection} will remain unchanged.
1301
1302     \sa Flow::layoutDirection, {LayoutMirroring}{LayoutMirroring}
1303 */
1304
1305 Qt::LayoutDirection QDeclarative1Flow::effectiveLayoutDirection() const
1306 {
1307     return QDeclarative1BasePositionerPrivate::getEffectiveLayoutDirection(this);
1308 }
1309
1310 void QDeclarative1Flow::doPositioning(QSizeF *contentSize)
1311 {
1312     Q_D(QDeclarative1Flow);
1313
1314     int hoffset = 0;
1315     int voffset = 0;
1316     int linemax = 0;
1317     QList<int> hoffsets;
1318
1319     for (int i = 0; i < positionedItems.count(); ++i) {
1320         const PositionedItem &child = positionedItems.at(i);
1321         if (!child.item || !child.isVisible)
1322             continue;
1323
1324         QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child.item);
1325         if (d->flow == LeftToRight)  {
1326             if (widthValid() && hoffset && hoffset + childPrivate->width() > width()) {
1327                 hoffset = 0;
1328                 voffset += linemax + spacing();
1329                 linemax = 0;
1330             }
1331         } else {
1332             if (heightValid() && voffset && voffset + childPrivate->height() > height()) {
1333                 voffset = 0;
1334                 hoffset += linemax + spacing();
1335                 linemax = 0;
1336             }
1337         }
1338
1339         if(d->isLeftToRight()){
1340             if(child.item->x() != hoffset)
1341                 positionX(hoffset, child);
1342         }else{
1343             hoffsets << hoffset;
1344         }
1345         if(child.item->y() != voffset)
1346             positionY(voffset, child);
1347
1348         contentSize->setWidth(qMax(contentSize->width(), hoffset + childPrivate->width()));
1349         contentSize->setHeight(qMax(contentSize->height(), voffset + childPrivate->height()));
1350
1351         if (d->flow == LeftToRight)  {
1352             hoffset += childPrivate->width();
1353             hoffset += spacing();
1354             linemax = qMax(linemax, qCeil(childPrivate->height()));
1355         } else {
1356             voffset += childPrivate->height();
1357             voffset += spacing();
1358             linemax = qMax(linemax, qCeil(childPrivate->width()));
1359         }
1360     }
1361
1362     if(d->isLeftToRight())
1363         return;
1364
1365     int end;
1366     if(widthValid())
1367         end = width();
1368     else
1369         end = contentSize->width();
1370     int acc = 0;
1371     for (int i = 0; i < positionedItems.count(); ++i) {
1372         const PositionedItem &child = positionedItems.at(i);
1373         if (!child.item || !child.isVisible)
1374             continue;
1375         hoffset = end - hoffsets[acc++] - QGraphicsItemPrivate::get(child.item)->width();
1376         if(child.item->x() != hoffset)
1377             positionX(hoffset, child);
1378     }
1379 }
1380
1381 void QDeclarative1Flow::reportConflictingAnchors()
1382 {
1383     Q_D(QDeclarative1Flow);
1384     for (int ii = 0; ii < positionedItems.count(); ++ii) {
1385         const PositionedItem &child = positionedItems.at(ii);
1386         if (child.item && QGraphicsItemPrivate::get(child.item)->isDeclarativeItem) {
1387             QDeclarative1Anchors *anchors = QDeclarativeItemPrivate::get(static_cast<QDeclarativeItem *>(child.item))->_anchors;
1388             if (anchors && (anchors->usedAnchors() || anchors->fill() || anchors->centerIn())) {
1389                 d->anchorConflict = true;
1390                 break;
1391             }
1392         }
1393     }
1394     if (d->anchorConflict)
1395         qmlInfo(this) << "Cannot specify anchors for items inside Flow";
1396 }
1397
1398
1399
1400 QT_END_NAMESPACE