Extract all QtQuick 1 elements into a separate library/plugin.
[profile/ivi/qtdeclarative.git] / src / qtquick1 / graphicsitems / qdeclarativepositioners.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
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   \ingroup qml-positioning-elements
329   \since 4.7
330   \brief The Column item arranges its children vertically.
331   \inherits Item
332
333   The Column item positions its child items so that they are vertically
334   aligned and not overlapping.
335
336   Spacing between items can be added using the \l spacing property.
337   Transitions can be used for cases where items managed by a Column are
338   added or moved. These are stored in the \l add and \l move properties
339   respectively.
340
341   See \l{Using QML Positioner and Repeater Items} for more details about this item and other
342   related items.
343
344   \section1 Example Usage
345
346   The following example positions differently shaped rectangles using a Column
347   item.
348
349   \image verticalpositioner_example.png
350
351   \snippet doc/src/snippets/declarative/column/vertical-positioner.qml document
352
353   \section1 Using Transitions
354
355   Transitions can be used to animate items that are added to, moved within,
356   or removed from a Column item. The \l add and \l move properties can be set to
357   the transitions that will be applied when items are added to, removed from,
358   or re-positioned within a Column item.
359
360   The use of transitions with positioners is described in more detail in the
361   \l{Using QML Positioner and Repeater Items#Using Transitions}{Using QML
362   Positioner and Repeater Items} document.
363
364   \image verticalpositioner_transition.gif
365
366   \qml
367   Column {
368       spacing: 2
369       add: Transition {
370           // Define an animation for adding a new item...
371       }
372       move: Transition {
373           // Define an animation for moving items within the column...
374       }
375       // ...
376   }
377   \endqml
378
379   \section1 Limitations
380
381   Note that the positioner assumes that the x and y positions of its children
382   will not change. If you manually change the x or y properties in script, bind
383   the x or y properties, use anchors on a child of a positioner, or have the
384   height of a child depend on the position of a child, then the
385   positioner may exhibit strange behavior. If you need to perform any of these
386   actions, consider positioning the items without the use of a Column.
387
388   Items with a width or height of 0 will not be positioned.
389
390   \sa Row, Grid, Flow, {declarative/positioners}{Positioners example}
391 */
392 /*!
393     \qmlproperty Transition Column::add
394
395     This property holds the transition to be applied when adding an
396     item to the positioner. The transition will only be applied to the
397     added item(s).  Positioner transitions will only affect the
398     position (x, y) of items.
399
400     For a positioner, adding an item can mean that either the object
401     has been created or reparented, and thus is now a child or the
402     positioner, or that the object has had its opacity increased from
403     zero, and thus is now visible.
404
405     \sa move
406 */
407 /*!
408     \qmlproperty Transition Column::move
409
410     This property holds the transition to apply when moving an item
411     within the positioner.  Positioner transitions will only affect
412     the position (x, y) of items.
413
414     This transition can be performed when other items are added or removed
415     from the positioner, or when items resize themselves.
416
417     \image positioner-move.gif
418
419     \qml
420     Column {
421         move: Transition {
422             NumberAnimation {
423                 properties: "y"
424                 duration: 1000
425             }
426         }
427     }
428     \endqml
429
430     \sa add, {declarative/positioners}{Positioners example}
431 */
432 /*!
433   \qmlproperty int Column::spacing
434
435   The spacing is the amount in pixels left empty between adjacent
436   items. The default spacing is 0.
437
438   \sa Grid::spacing
439 */
440 QDeclarative1Column::QDeclarative1Column(QDeclarativeItem *parent)
441 : QDeclarative1BasePositioner(Vertical, parent)
442 {
443 }
444
445 void QDeclarative1Column::doPositioning(QSizeF *contentSize)
446 {
447     int voffset = 0;
448
449     for (int ii = 0; ii < positionedItems.count(); ++ii) {
450         const PositionedItem &child = positionedItems.at(ii);
451         if (!child.item || !child.isVisible)
452             continue;
453
454         if(child.item->y() != voffset)
455             positionY(voffset, child);
456
457         contentSize->setWidth(qMax(contentSize->width(), QGraphicsItemPrivate::get(child.item)->width()));
458
459         voffset += QGraphicsItemPrivate::get(child.item)->height();
460         voffset += spacing();
461     }
462
463     contentSize->setHeight(voffset - spacing());
464 }
465
466 void QDeclarative1Column::reportConflictingAnchors()
467 {
468     QDeclarative1BasePositionerPrivate *d = static_cast<QDeclarative1BasePositionerPrivate*>(QDeclarative1BasePositionerPrivate::get(this));
469     for (int ii = 0; ii < positionedItems.count(); ++ii) {
470         const PositionedItem &child = positionedItems.at(ii);
471         if (child.item && QGraphicsItemPrivate::get(child.item)->isDeclarativeItem) {
472             QDeclarative1Anchors *anchors = QDeclarativeItemPrivate::get(static_cast<QDeclarativeItem *>(child.item))->_anchors;
473             if (anchors) {
474                 QDeclarative1Anchors::Anchors usedAnchors = anchors->usedAnchors();
475                 if (usedAnchors & QDeclarative1Anchors::TopAnchor ||
476                     usedAnchors & QDeclarative1Anchors::BottomAnchor ||
477                     usedAnchors & QDeclarative1Anchors::VCenterAnchor ||
478                     anchors->fill() || anchors->centerIn()) {
479                     d->anchorConflict = true;
480                     break;
481                 }
482             }
483         }
484     }
485     if (d->anchorConflict) {
486         qmlInfo(this) << "Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column";
487     }
488 }
489
490 /*!
491   \qmlclass Row QDeclarative1Row
492   \ingroup qml-positioning-elements
493   \since 4.7
494   \brief The Row item arranges its children horizontally.
495   \inherits Item
496
497   The Row item positions its child items so that they are horizontally
498   aligned and not overlapping. 
499
500   Use \l spacing to set the spacing between items in a Row, and use the
501   \l add and \l move properties to set the transitions that should be applied
502   when items are added to, removed from, or re-positioned within the Row.
503
504   See \l{Using QML Positioner and Repeater Items} for more details about this item and other
505   related items.
506
507   \section1 Example Usage
508
509   The following example lays out differently shaped rectangles using a Row.
510
511   \image horizontalpositioner_example.png
512
513   \snippet doc/src/snippets/declarative/row/row.qml document
514
515   \section1 Using Transitions
516
517   Transitions can be used to animate items that are added to, moved within,
518   or removed from a Grid item. The \l add and \l move properties can be set to
519   the transitions that will be applied when items are added to, removed from,
520   or re-positioned within a Row item.
521
522   \section1 Limitations
523
524   Note that the positioner assumes that the x and y positions of its children
525   will not change. If you manually change the x or y properties in script, bind
526   the x or y properties, use anchors on a child of a positioner, or have the
527   width of a child depend on the position of a child, then the
528   positioner may exhibit strange behaviour. If you need to perform any of these
529   actions, consider positioning the items without the use of a Row.
530
531   Items with a width or height of 0 will not be positioned.
532
533   \sa Column, Grid, Flow, {declarative/positioners}{Positioners example}
534 */
535 /*!
536     \qmlproperty Transition Row::add
537
538     This property holds the transition to be applied when adding an
539     item to the positioner. The transition will only be applied to the
540     added item(s).  Positioner transitions will only affect the
541     position (x, y) of items.
542
543     For a positioner, adding an item can mean that either the object
544     has been created or reparented, and thus is now a child or the
545     positioner, or that the object has had its opacity increased from
546     zero, and thus is now visible.
547
548     \sa move
549 */
550 /*!
551     \qmlproperty Transition Row::move
552
553     This property holds the transition to be applied when moving an
554     item within the positioner. Positioner transitions will only affect
555     the position (x, y) of items.
556
557     This transition can be performed when other items are added or removed
558     from the positioner, or when items resize themselves.
559
560     \qml
561     Row {
562         id: positioner
563         move: Transition {
564             NumberAnimation {
565                 properties: "x"
566                 duration: 1000
567             }
568         }
569     }
570     \endqml
571
572     \sa add, {declarative/positioners}{Positioners example}
573 */
574 /*!
575   \qmlproperty int Row::spacing
576
577   The spacing is the amount in pixels left empty between adjacent
578   items. The default spacing is 0.
579
580   \sa Grid::spacing
581 */
582 QDeclarative1Row::QDeclarative1Row(QDeclarativeItem *parent)
583 : QDeclarative1BasePositioner(Horizontal, parent)
584 {
585 }
586
587 /*!
588     \qmlproperty enumeration Row::layoutDirection
589     \since Quick 1.1
590
591     This property holds the layoutDirection of the row.
592
593     Possible values:
594
595     \list
596     \o Qt.LeftToRight (default) - Items are laid out from left to right. If the width of the row is explicitly set,
597     the left anchor remains to the left of the row.
598     \o Qt.RightToLeft - Items are laid out from right to left. If the width of the row is explicitly set,
599     the right anchor remains to the right of the row.
600     \endlist
601
602     \sa Grid::layoutDirection, Flow::layoutDirection, {declarative/righttoleft/layoutdirection}{Layout directions example}
603 */
604 Qt::LayoutDirection QDeclarative1Row::layoutDirection() const
605 {
606     return QDeclarative1BasePositionerPrivate::getLayoutDirection(this);
607 }
608
609 void QDeclarative1Row::setLayoutDirection(Qt::LayoutDirection layoutDirection)
610 {
611     QDeclarative1BasePositionerPrivate *d = static_cast<QDeclarative1BasePositionerPrivate* >(QDeclarative1BasePositionerPrivate::get(this));
612     if (d->layoutDirection != layoutDirection) {
613         d->layoutDirection = layoutDirection;
614         // For RTL layout the positioning changes when the width changes.
615         if (d->layoutDirection == Qt::RightToLeft)
616             d->addItemChangeListener(d, QDeclarativeItemPrivate::Geometry);
617         else
618             d->removeItemChangeListener(d, QDeclarativeItemPrivate::Geometry);
619         prePositioning();
620         emit layoutDirectionChanged();
621         emit effectiveLayoutDirectionChanged();
622     }
623 }
624
625 /*!
626     \qmlproperty enumeration Row::effectiveLayoutDirection
627     This property holds the effective layout direction of the row positioner.
628
629     When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} for locale layouts,
630     the visual layout direction of the row positioner will be mirrored. However, the
631     property \l {Row::layoutDirection}{layoutDirection} will remain unchanged.
632
633     \sa Row::layoutDirection, {LayoutMirroring}{LayoutMirroring}
634 */
635
636 Qt::LayoutDirection QDeclarative1Row::effectiveLayoutDirection() const
637 {
638     return QDeclarative1BasePositionerPrivate::getEffectiveLayoutDirection(this);
639 }
640
641 void QDeclarative1Row::doPositioning(QSizeF *contentSize)
642 {
643     QDeclarative1BasePositionerPrivate *d = static_cast<QDeclarative1BasePositionerPrivate*>(QDeclarative1BasePositionerPrivate::get(this));
644     int hoffset = 0;
645
646     QList<int> hoffsets;
647     for (int ii = 0; ii < positionedItems.count(); ++ii) {
648         const PositionedItem &child = positionedItems.at(ii);
649         if (!child.item || !child.isVisible)
650             continue;
651
652         if(d->isLeftToRight()){
653             if(child.item->x() != hoffset)
654                 positionX(hoffset, child);
655         }else{
656             hoffsets << hoffset;
657         }
658
659         contentSize->setHeight(qMax(contentSize->height(), QGraphicsItemPrivate::get(child.item)->height()));
660
661         hoffset += QGraphicsItemPrivate::get(child.item)->width();
662         hoffset += spacing();
663     }
664
665     contentSize->setWidth(hoffset - spacing());
666
667     if(d->isLeftToRight())
668         return;
669
670     //Right to Left layout
671     int end = 0;
672     if(!widthValid())
673         end = contentSize->width();
674     else
675         end = width();
676
677     int acc = 0;
678     for (int ii = 0; ii < positionedItems.count(); ++ii) {
679         const PositionedItem &child = positionedItems.at(ii);
680         if (!child.item || !child.isVisible)
681             continue;
682         hoffset = end - hoffsets[acc++] - QGraphicsItemPrivate::get(child.item)->width();
683         if(child.item->x() != hoffset)
684             positionX(hoffset, child);
685     }
686 }
687
688 void QDeclarative1Row::reportConflictingAnchors()
689 {
690     QDeclarative1BasePositionerPrivate *d = static_cast<QDeclarative1BasePositionerPrivate*>(QDeclarative1BasePositionerPrivate::get(this));
691     for (int ii = 0; ii < positionedItems.count(); ++ii) {
692         const PositionedItem &child = positionedItems.at(ii);
693         if (child.item && QGraphicsItemPrivate::get(child.item)->isDeclarativeItem) {
694             QDeclarative1Anchors *anchors = QDeclarativeItemPrivate::get(static_cast<QDeclarativeItem *>(child.item))->_anchors;
695             if (anchors) {
696                 QDeclarative1Anchors::Anchors usedAnchors = anchors->usedAnchors();
697                 if (usedAnchors & QDeclarative1Anchors::LeftAnchor ||
698                     usedAnchors & QDeclarative1Anchors::RightAnchor ||
699                     usedAnchors & QDeclarative1Anchors::HCenterAnchor ||
700                     anchors->fill() || anchors->centerIn()) {
701                     d->anchorConflict = true;
702                     break;
703                 }
704             }
705         }
706     }
707     if (d->anchorConflict)
708         qmlInfo(this) << "Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row";
709 }
710
711 /*!
712   \qmlclass Grid QDeclarative1Grid
713   \ingroup qml-positioning-elements
714   \since 4.7
715   \brief The Grid item positions its children in a grid.
716   \inherits Item
717
718   The Grid item positions its child items so that they are
719   aligned in a grid and are not overlapping. 
720
721   The grid positioner calculates a grid of rectangular cells of sufficient
722   size to hold all items, placing the items in the cells, from left to right
723   and top to bottom. Each item is positioned in the top-left corner of its
724   cell with position (0, 0).
725
726   A Grid defaults to four columns, and as many rows as are necessary to
727   fit all child items. The number of rows and columns can be constrained
728   by setting the \l rows and \l columns properties.
729
730   Spacing can be added between child items by setting the \l spacing
731   property. The amount of spacing applied will be the same in the
732   horizontal and vertical directions.
733
734   See \l{Using QML Positioner and Repeater Items} for more details about this item and other
735   related items.
736
737   \section1 Example Usage
738
739   The following example demonstrates this.
740
741   \image gridLayout_example.png
742
743   \snippet doc/src/snippets/declarative/grid/grid.qml document
744
745   \section1 Using Transitions
746
747   Transitions can be used to animate items that are added to, moved within,
748   or removed from a Grid item. The \l add and \l move properties can be set to
749   the transitions that will be applied when items are added to, removed from,
750   or re-positioned within a Grid item.
751
752   \section1 Limitations
753
754   Note that the positioner assumes that the x and y positions of its children
755   will not change. If you manually change the x or y properties in script, bind
756   the x or y properties, use anchors on a child of a positioner, or have the
757   width or height of a child depend on the position of a child, then the
758   positioner may exhibit strange behaviour. If you need to perform any of these
759   actions, consider positioning the items without the use of a Grid.
760
761   Items with a width or height of 0 will not be positioned.
762
763   \sa Flow, Row, Column, {declarative/positioners}{Positioners example}
764 */
765 /*!
766     \qmlproperty Transition Grid::add
767
768     This property holds the transition to be applied when adding an
769     item to the positioner. The transition will only be applied to the
770     added item(s).  Positioner transitions will only affect the
771     position (x, y) of items.
772
773     For a positioner, adding an item can mean that either the object
774     has been created or reparented, and thus is now a child or the
775     positioner, or that the object has had its opacity increased from
776     zero, and thus is now visible.
777
778     \sa move
779 */
780 /*!
781     \qmlproperty Transition Grid::move
782
783     This property holds the transition to be applied when moving an
784     item within the positioner. Positioner transitions will only affect
785     the position (x, y) of items.
786
787     This transition can be performed when other items are added or removed
788     from the positioner, or when items resize themselves.
789
790     \qml
791     Grid {
792         move: Transition {
793             NumberAnimation {
794                 properties: "x,y"
795                 duration: 1000
796             }
797         }
798     }
799     \endqml
800
801     \sa add, {declarative/positioners}{Positioners example}
802 */
803 /*!
804   \qmlproperty int Grid::spacing
805
806   The spacing is the amount in pixels left empty between adjacent
807   items. The default spacing is 0.
808
809   The below example places a Grid containing a red, a blue and a
810   green rectangle on a gray background. The area the grid positioner
811   occupies is colored white. The positioner on the left has the
812   no spacing (the default), and the positioner on the right has
813   a spacing of 6.
814
815   \inlineimage qml-grid-no-spacing.png
816   \inlineimage qml-grid-spacing.png
817
818   \sa rows, columns
819 */
820 QDeclarative1Grid::QDeclarative1Grid(QDeclarativeItem *parent) :
821     QDeclarative1BasePositioner(Both, parent), m_rows(-1), m_columns(-1), m_flow(LeftToRight)
822 {
823 }
824
825 /*!
826     \qmlproperty int Grid::columns
827
828     This property holds the number of columns in the grid. The default
829     number of columns is 4.
830
831     If the grid does not have enough items to fill the specified
832     number of columns, some columns will be of zero width.
833 */
834
835 /*!
836     \qmlproperty int Grid::rows
837     This property holds the number of rows in the grid.
838
839     If the grid does not have enough items to fill the specified
840     number of rows, some rows will be of zero width.
841 */
842
843 void QDeclarative1Grid::setColumns(const int columns)
844 {
845     if (columns == m_columns)
846         return;
847     m_columns = columns;
848     prePositioning();
849     emit columnsChanged();
850 }
851
852 void QDeclarative1Grid::setRows(const int rows)
853 {
854     if (rows == m_rows)
855         return;
856     m_rows = rows;
857     prePositioning();
858     emit rowsChanged();
859 }
860
861 /*!
862     \qmlproperty enumeration Grid::flow
863     This property holds the flow of the layout.
864
865     Possible values are:
866
867     \list
868     \o Grid.LeftToRight (default) - Items are positioned next to
869        each other in the \l layoutDirection, then wrapped to the next line.
870     \o Grid.TopToBottom - Items are positioned next to each
871        other from top to bottom, then wrapped to the next column.
872     \endlist
873 */
874 QDeclarative1Grid::Flow QDeclarative1Grid::flow() const
875 {
876     return m_flow;
877 }
878
879 void QDeclarative1Grid::setFlow(Flow flow)
880 {
881     if (m_flow != flow) {
882         m_flow = flow;
883         prePositioning();
884         emit flowChanged();
885     }
886 }
887
888 /*!
889     \qmlproperty enumeration Grid::layoutDirection
890     \since Quick 1.1
891
892     This property holds the layout direction of the layout.
893
894     Possible values are:
895
896     \list
897     \o Qt.LeftToRight (default) - Items are positioned from the top to bottom,
898     and left to right. The flow direction is dependent on the
899     \l Grid::flow property.
900     \o Qt.RightToLeft - Items are positioned from the top to bottom,
901     and right to left. The flow direction is dependent on the
902     \l Grid::flow property.
903     \endlist
904
905     \sa Flow::layoutDirection, Row::layoutDirection, {declarative/righttoleft/layoutdirection}{Layout directions example}
906 */
907 Qt::LayoutDirection QDeclarative1Grid::layoutDirection() const
908 {
909     return QDeclarative1BasePositionerPrivate::getLayoutDirection(this);
910 }
911
912 void QDeclarative1Grid::setLayoutDirection(Qt::LayoutDirection layoutDirection)
913 {
914     QDeclarative1BasePositionerPrivate *d = static_cast<QDeclarative1BasePositionerPrivate*>(QDeclarative1BasePositionerPrivate::get(this));
915     if (d->layoutDirection != layoutDirection) {
916         d->layoutDirection = layoutDirection;
917         // For RTL layout the positioning changes when the width changes.
918         if (d->layoutDirection == Qt::RightToLeft)
919             d->addItemChangeListener(d, QDeclarativeItemPrivate::Geometry);
920         else
921             d->removeItemChangeListener(d, QDeclarativeItemPrivate::Geometry);
922         prePositioning();
923         emit layoutDirectionChanged();
924         emit effectiveLayoutDirectionChanged();
925     }
926 }
927
928 /*!
929     \qmlproperty enumeration Grid::effectiveLayoutDirection
930     This property holds the effective layout direction of the grid positioner.
931
932     When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} for locale layouts,
933     the visual layout direction of the grid positioner will be mirrored. However, the
934     property \l {Grid::layoutDirection}{layoutDirection} will remain unchanged.
935
936     \sa Grid::layoutDirection, {LayoutMirroring}{LayoutMirroring}
937 */
938
939 Qt::LayoutDirection QDeclarative1Grid::effectiveLayoutDirection() const
940 {
941     return QDeclarative1BasePositionerPrivate::getEffectiveLayoutDirection(this);
942 }
943
944 void QDeclarative1Grid::doPositioning(QSizeF *contentSize)
945 {
946     QDeclarative1BasePositionerPrivate *d = static_cast<QDeclarative1BasePositionerPrivate*>(QDeclarative1BasePositionerPrivate::get(this));
947     int c = m_columns;
948     int r = m_rows;
949     //Is allocating the extra QPODVector too much overhead?
950     QPODVector<PositionedItem, 8> visibleItems;//we aren't concerned with invisible items
951     visibleItems.reserve(positionedItems.count());
952     for(int i=0; i<positionedItems.count(); i++)
953         if(positionedItems[i].item && positionedItems[i].isVisible)
954             visibleItems.append(positionedItems[i]);
955
956     int numVisible = visibleItems.count();
957     if (m_columns <= 0 && m_rows <= 0){
958         c = 4;
959         r = (numVisible+3)/4;
960     } else if (m_rows <= 0){
961         r = (numVisible+(m_columns-1))/m_columns;
962     } else if (m_columns <= 0){
963         c = (numVisible+(m_rows-1))/m_rows;
964     }
965
966     if(r==0 || c==0)
967         return; //Nothing to do
968
969     QList<int> maxColWidth;
970     QList<int> maxRowHeight;
971     int childIndex =0;
972     if (m_flow == LeftToRight) {
973         for (int i=0; i < r; i++){
974             for (int j=0; j < c; j++){
975                 if (j==0)
976                     maxRowHeight << 0;
977                 if (i==0)
978                     maxColWidth << 0;
979
980                 if (childIndex == visibleItems.count())
981                     break;
982
983                 const PositionedItem &child = visibleItems.at(childIndex++);
984                 QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child.item);
985                 if (childPrivate->width() > maxColWidth[j])
986                     maxColWidth[j] = childPrivate->width();
987                 if (childPrivate->height() > maxRowHeight[i])
988                     maxRowHeight[i] = childPrivate->height();
989             }
990         }
991     } else {
992         for (int j=0; j < c; j++){
993             for (int i=0; i < r; i++){
994                 if (j==0)
995                     maxRowHeight << 0;
996                 if (i==0)
997                     maxColWidth << 0;
998
999                 if (childIndex == visibleItems.count())
1000                     break;
1001
1002                 const PositionedItem &child = visibleItems.at(childIndex++);
1003                 QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child.item);
1004                 if (childPrivate->width() > maxColWidth[j])
1005                     maxColWidth[j] = childPrivate->width();
1006                 if (childPrivate->height() > maxRowHeight[i])
1007                     maxRowHeight[i] = childPrivate->height();
1008             }
1009         }
1010     }
1011
1012     int widthSum = 0;
1013     for(int j=0; j < maxColWidth.size(); j++){
1014         if(j)
1015             widthSum += spacing();
1016         widthSum += maxColWidth[j];
1017     }
1018
1019     int heightSum = 0;
1020     for(int i=0; i < maxRowHeight.size(); i++){
1021         if(i)
1022             heightSum += spacing();
1023         heightSum += maxRowHeight[i];
1024     }
1025
1026     contentSize->setHeight(heightSum);
1027     contentSize->setWidth(widthSum);
1028
1029     int end = 0;
1030     if(widthValid())
1031         end = width();
1032     else
1033         end = widthSum;
1034
1035     int xoffset=0;
1036     if(!d->isLeftToRight())
1037         xoffset=end;
1038     int yoffset=0;
1039     int curRow =0;
1040     int curCol =0;
1041     for (int i = 0; i < visibleItems.count(); ++i) {
1042         const PositionedItem &child = visibleItems.at(i);
1043         int childXOffset = xoffset;
1044         if(!d->isLeftToRight())
1045             childXOffset -= QGraphicsItemPrivate::get(child.item)->width();
1046         if((child.item->x()!=childXOffset)||(child.item->y()!=yoffset)){
1047             positionX(childXOffset, child);
1048             positionY(yoffset, child);
1049         }
1050
1051         if (m_flow == LeftToRight) {
1052             if(d->isLeftToRight())
1053                 xoffset+=maxColWidth[curCol]+spacing();
1054             else
1055                 xoffset-=maxColWidth[curCol]+spacing();
1056             curCol++;
1057             curCol%=c;
1058             if (!curCol){
1059                 yoffset+=maxRowHeight[curRow]+spacing();
1060                 if(d->isLeftToRight())
1061                     xoffset=0;
1062                 else
1063                     xoffset=end;
1064                 curRow++;
1065                 if (curRow>=r)
1066                     break;
1067             }
1068         } else {
1069             yoffset+=maxRowHeight[curRow]+spacing();
1070             curRow++;
1071             curRow%=r;
1072             if (!curRow){
1073                 if(d->isLeftToRight())
1074                     xoffset+=maxColWidth[curCol]+spacing();
1075                 else
1076                     xoffset-=maxColWidth[curCol]+spacing();
1077                 yoffset=0;
1078                 curCol++;
1079                 if (curCol>=c)
1080                     break;
1081             }
1082         }
1083     }
1084 }
1085
1086 void QDeclarative1Grid::reportConflictingAnchors()
1087 {
1088     QDeclarative1BasePositionerPrivate *d = static_cast<QDeclarative1BasePositionerPrivate*>(QDeclarative1BasePositionerPrivate::get(this));
1089     for (int ii = 0; ii < positionedItems.count(); ++ii) {
1090         const PositionedItem &child = positionedItems.at(ii);
1091         if (child.item && QGraphicsItemPrivate::get(child.item)->isDeclarativeItem) {
1092             QDeclarative1Anchors *anchors = QDeclarativeItemPrivate::get(static_cast<QDeclarativeItem *>(child.item))->_anchors;
1093             if (anchors && (anchors->usedAnchors() || anchors->fill() || anchors->centerIn())) {
1094                 d->anchorConflict = true;
1095                 break;
1096             }
1097         }
1098     }
1099     if (d->anchorConflict)
1100         qmlInfo(this) << "Cannot specify anchors for items inside Grid";
1101 }
1102
1103 /*!
1104   \qmlclass Flow QDeclarative1Flow
1105   \ingroup qml-positioning-elements
1106   \since 4.7
1107   \brief The Flow item arranges its children side by side, wrapping as necessary.
1108   \inherits Item
1109
1110   The Flow item positions its child items like words on a page, wrapping them
1111   to create rows or columns of items that do not overlap.
1112
1113   Spacing between items can be added using the \l spacing property.
1114   Transitions can be used for cases where items managed by a Column are
1115   added or moved. These are stored in the \l add and \l move properties
1116   respectively.
1117
1118   See \l{Using QML Positioner and Repeater Items} for more details about this item and other
1119   related items.
1120
1121   \section1 Example Usage
1122
1123   The following example positions \l Text items within a parent item using
1124   a Flow item.
1125
1126   \image qml-flow-snippet.png
1127
1128   \snippet doc/src/snippets/declarative/flow.qml flow item
1129
1130   \section1 Using Transitions
1131
1132   Transitions can be used to animate items that are added to, moved within,
1133   or removed from a Flow item. The \l add and \l move properties can be set to
1134   the transitions that will be applied when items are added to, removed from,
1135   or re-positioned within a Flow item.
1136
1137   The use of transitions with positioners is described in more detail in the
1138   \l{Using QML Positioner and Repeater Items#Using Transitions}{Using QML
1139   Positioner and Repeater Items} document.
1140
1141   \section1 Limitations
1142
1143   Note that the positioner assumes that the x and y positions of its children
1144   will not change. If you manually change the x or y properties in script, bind
1145   the x or y properties, use anchors on a child of a positioner, or have the
1146   width or height of a child depend on the position of a child, then the
1147   positioner may exhibit strange behaviour.  If you need to perform any of these
1148   actions, consider positioning the items without the use of a Flow.
1149
1150   Items with a width or height of 0 will not be positioned.
1151
1152   \sa Column, Row, Grid, {declarative/positioners}{Positioners example}
1153 */
1154 /*!
1155     \qmlproperty Transition Flow::add
1156
1157     This property holds the transition to be applied when adding an
1158     item to the positioner. The transition will only be applied to the
1159     added item(s).  Positioner transitions will only affect the
1160     position (x, y) of items.
1161
1162     For a positioner, adding an item can mean that either the object
1163     has been created or reparented, and thus is now a child or the
1164     positioner, or that the object has had its opacity increased from
1165     zero, and thus is now visible.
1166
1167     \sa move
1168 */
1169 /*!
1170     \qmlproperty Transition Flow::move
1171
1172     This property holds the transition to be applied when moving an
1173     item within the positioner. Positioner transitions will only affect
1174     the position (x, y) of items.
1175
1176     This transition can be performed when other items are added or removed
1177     from the positioner, or when items resize themselves.
1178
1179     \qml
1180     Flow {
1181         id: positioner
1182         move: Transition {
1183             NumberAnimation {
1184                 properties: "x,y"
1185                 ease: "easeOutBounce"
1186             }
1187         }
1188     }
1189     \endqml
1190
1191     \sa add, {declarative/positioners}{Positioners example}
1192 */
1193 /*!
1194   \qmlproperty int Flow::spacing
1195
1196   spacing is the amount in pixels left empty between each adjacent
1197   item, and defaults to 0.
1198
1199   \sa Grid::spacing
1200 */
1201
1202 class QDeclarative1FlowPrivate : public QDeclarative1BasePositionerPrivate
1203 {
1204     Q_DECLARE_PUBLIC(QDeclarative1Flow)
1205
1206 public:
1207     QDeclarative1FlowPrivate()
1208         : QDeclarative1BasePositionerPrivate(), flow(QDeclarative1Flow::LeftToRight)
1209     {}
1210
1211     QDeclarative1Flow::Flow flow;
1212 };
1213
1214 QDeclarative1Flow::QDeclarative1Flow(QDeclarativeItem *parent)
1215 : QDeclarative1BasePositioner(*(new QDeclarative1FlowPrivate), Both, parent)
1216 {
1217     Q_D(QDeclarative1Flow);
1218     // Flow layout requires relayout if its own size changes too.
1219     d->addItemChangeListener(d, QDeclarativeItemPrivate::Geometry);
1220 }
1221
1222 /*!
1223     \qmlproperty enumeration Flow::flow
1224     This property holds the flow of the layout.
1225
1226     Possible values are:
1227
1228     \list
1229     \o Flow.LeftToRight (default) - Items are positioned next to
1230     to each other according to the \l layoutDirection until the width of the Flow
1231     is exceeded, then wrapped to the next line.
1232     \o Flow.TopToBottom - Items are positioned next to each
1233     other from top to bottom until the height of the Flow is exceeded,
1234     then wrapped to the next column.
1235     \endlist
1236 */
1237 QDeclarative1Flow::Flow QDeclarative1Flow::flow() const
1238 {
1239     Q_D(const QDeclarative1Flow);
1240     return d->flow;
1241 }
1242
1243 void QDeclarative1Flow::setFlow(Flow flow)
1244 {
1245     Q_D(QDeclarative1Flow);
1246     if (d->flow != flow) {
1247         d->flow = flow;
1248         prePositioning();
1249         emit flowChanged();
1250     }
1251 }
1252
1253 /*!
1254     \qmlproperty enumeration Flow::layoutDirection
1255     \since Quick 1.1
1256
1257     This property holds the layout direction of the layout.
1258
1259     Possible values are:
1260
1261     \list
1262     \o Qt.LeftToRight (default) - Items are positioned from the top to bottom,
1263     and left to right. The flow direction is dependent on the
1264     \l Flow::flow property.
1265     \o Qt.RightToLeft - Items are positioned from the top to bottom,
1266     and right to left. The flow direction is dependent on the
1267     \l Flow::flow property.
1268     \endlist
1269
1270     \sa Grid::layoutDirection, Row::layoutDirection, {declarative/righttoleft/layoutdirection}{Layout directions example}
1271 */
1272
1273 Qt::LayoutDirection QDeclarative1Flow::layoutDirection() const
1274 {
1275     Q_D(const QDeclarative1Flow);
1276     return d->layoutDirection;
1277 }
1278
1279 void QDeclarative1Flow::setLayoutDirection(Qt::LayoutDirection layoutDirection)
1280 {
1281     Q_D(QDeclarative1Flow);
1282     if (d->layoutDirection != layoutDirection) {
1283         d->layoutDirection = layoutDirection;
1284         prePositioning();
1285         emit layoutDirectionChanged();
1286         emit effectiveLayoutDirectionChanged();
1287     }
1288 }
1289
1290 /*!
1291     \qmlproperty enumeration Flow::effectiveLayoutDirection
1292     This property holds the effective layout direction of the flow positioner.
1293
1294     When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} for locale layouts,
1295     the visual layout direction of the grid positioner will be mirrored. However, the
1296     property \l {Flow::layoutDirection}{layoutDirection} will remain unchanged.
1297
1298     \sa Flow::layoutDirection, {LayoutMirroring}{LayoutMirroring}
1299 */
1300
1301 Qt::LayoutDirection QDeclarative1Flow::effectiveLayoutDirection() const
1302 {
1303     return QDeclarative1BasePositionerPrivate::getEffectiveLayoutDirection(this);
1304 }
1305
1306 void QDeclarative1Flow::doPositioning(QSizeF *contentSize)
1307 {
1308     Q_D(QDeclarative1Flow);
1309
1310     int hoffset = 0;
1311     int voffset = 0;
1312     int linemax = 0;
1313     QList<int> hoffsets;
1314
1315     for (int i = 0; i < positionedItems.count(); ++i) {
1316         const PositionedItem &child = positionedItems.at(i);
1317         if (!child.item || !child.isVisible)
1318             continue;
1319
1320         QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child.item);
1321         if (d->flow == LeftToRight)  {
1322             if (widthValid() && hoffset && hoffset + childPrivate->width() > width()) {
1323                 hoffset = 0;
1324                 voffset += linemax + spacing();
1325                 linemax = 0;
1326             }
1327         } else {
1328             if (heightValid() && voffset && voffset + childPrivate->height() > height()) {
1329                 voffset = 0;
1330                 hoffset += linemax + spacing();
1331                 linemax = 0;
1332             }
1333         }
1334
1335         if(d->isLeftToRight()){
1336             if(child.item->x() != hoffset)
1337                 positionX(hoffset, child);
1338         }else{
1339             hoffsets << hoffset;
1340         }
1341         if(child.item->y() != voffset)
1342             positionY(voffset, child);
1343
1344         contentSize->setWidth(qMax(contentSize->width(), hoffset + childPrivate->width()));
1345         contentSize->setHeight(qMax(contentSize->height(), voffset + childPrivate->height()));
1346
1347         if (d->flow == LeftToRight)  {
1348             hoffset += childPrivate->width();
1349             hoffset += spacing();
1350             linemax = qMax(linemax, qCeil(childPrivate->height()));
1351         } else {
1352             voffset += childPrivate->height();
1353             voffset += spacing();
1354             linemax = qMax(linemax, qCeil(childPrivate->width()));
1355         }
1356     }
1357
1358     if(d->isLeftToRight())
1359         return;
1360
1361     int end;
1362     if(widthValid())
1363         end = width();
1364     else
1365         end = contentSize->width();
1366     int acc = 0;
1367     for (int i = 0; i < positionedItems.count(); ++i) {
1368         const PositionedItem &child = positionedItems.at(i);
1369         if (!child.item || !child.isVisible)
1370             continue;
1371         hoffset = end - hoffsets[acc++] - QGraphicsItemPrivate::get(child.item)->width();
1372         if(child.item->x() != hoffset)
1373             positionX(hoffset, child);
1374     }
1375 }
1376
1377 void QDeclarative1Flow::reportConflictingAnchors()
1378 {
1379     Q_D(QDeclarative1Flow);
1380     for (int ii = 0; ii < positionedItems.count(); ++ii) {
1381         const PositionedItem &child = positionedItems.at(ii);
1382         if (child.item && QGraphicsItemPrivate::get(child.item)->isDeclarativeItem) {
1383             QDeclarative1Anchors *anchors = QDeclarativeItemPrivate::get(static_cast<QDeclarativeItem *>(child.item))->_anchors;
1384             if (anchors && (anchors->usedAnchors() || anchors->fill() || anchors->centerIn())) {
1385                 d->anchorConflict = true;
1386                 break;
1387             }
1388         }
1389     }
1390     if (d->anchorConflict)
1391         qmlInfo(this) << "Cannot specify anchors for items inside Flow";
1392 }
1393
1394
1395
1396 QT_END_NAMESPACE