QMdiArea: replace uses of QList<QRect> with QVector

A QList<QRect> is horribly inefficient, and this is private API, so we're free to
change it.

Change-Id: I26c2be51393f883d160b86ed1414f801f211df39
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2013-10-05 00:51:26 +02:00 committed by The Qt Project
parent d432d17f83
commit 0abc35b5f7
2 changed files with 28 additions and 26 deletions

View File

@ -169,7 +169,7 @@
#include <QResizeEvent> #include <QResizeEvent>
#include <QScrollBar> #include <QScrollBar>
#include <QtAlgorithms> #include <QtAlgorithms>
#include <QMutableListIterator> #include <QMutableVectorIterator>
#include <QPainter> #include <QPainter>
#include <QFontMetrics> #include <QFontMetrics>
#include <QStyleOption> #include <QStyleOption>
@ -413,7 +413,7 @@ void IconTiler::rearrange(QList<QWidget *> &widgets, const QRect &domain) const
\internal \internal
Calculates the accumulated overlap (intersection area) between 'source' and 'rects'. Calculates the accumulated overlap (intersection area) between 'source' and 'rects'.
*/ */
int MinOverlapPlacer::accumulatedOverlap(const QRect &source, const QList<QRect> &rects) int MinOverlapPlacer::accumulatedOverlap(const QRect &source, const QVector<QRect> &rects)
{ {
int accOverlap = 0; int accOverlap = 0;
foreach (const QRect &rect, rects) { foreach (const QRect &rect, rects) {
@ -429,7 +429,7 @@ int MinOverlapPlacer::accumulatedOverlap(const QRect &source, const QList<QRect>
Finds among 'source' the rectangle with the minimum accumulated overlap with the Finds among 'source' the rectangle with the minimum accumulated overlap with the
rectangles in 'rects'. rectangles in 'rects'.
*/ */
QRect MinOverlapPlacer::findMinOverlapRect(const QList<QRect> &source, const QList<QRect> &rects) QRect MinOverlapPlacer::findMinOverlapRect(const QVector<QRect> &source, const QVector<QRect> &rects)
{ {
int minAccOverlap = -1; int minAccOverlap = -1;
QRect minAccOverlapRect; QRect minAccOverlapRect;
@ -447,8 +447,8 @@ QRect MinOverlapPlacer::findMinOverlapRect(const QList<QRect> &source, const QLi
\internal \internal
Gets candidates for the final placement. Gets candidates for the final placement.
*/ */
void MinOverlapPlacer::getCandidatePlacements(const QSize &size, const QList<QRect> &rects, void MinOverlapPlacer::getCandidatePlacements(const QSize &size, const QVector<QRect> &rects,
const QRect &domain,QList<QRect> &candidates) const QRect &domain,QVector<QRect> &candidates)
{ {
QSet<int> xset; QSet<int> xset;
QSet<int> yset; QSet<int> yset;
@ -476,10 +476,10 @@ void MinOverlapPlacer::getCandidatePlacements(const QSize &size, const QList<QRe
Finds all rectangles in 'source' not completely inside 'domain'. The result is stored Finds all rectangles in 'source' not completely inside 'domain'. The result is stored
in 'result' and also removed from 'source'. in 'result' and also removed from 'source'.
*/ */
void MinOverlapPlacer::findNonInsiders(const QRect &domain, QList<QRect> &source, void MinOverlapPlacer::findNonInsiders(const QRect &domain, QVector<QRect> &source,
QList<QRect> &result) QVector<QRect> &result)
{ {
QMutableListIterator<QRect> it(source); QMutableVectorIterator<QRect> it(source);
while (it.hasNext()) { while (it.hasNext()) {
const QRect srcRect = it.next(); const QRect srcRect = it.next();
if (!domain.contains(srcRect)) { if (!domain.contains(srcRect)) {
@ -494,8 +494,8 @@ void MinOverlapPlacer::findNonInsiders(const QRect &domain, QList<QRect> &source
Finds all rectangles in 'source' that overlaps 'domain' by the maximum overlap area Finds all rectangles in 'source' that overlaps 'domain' by the maximum overlap area
between 'domain' and any rectangle in 'source'. The result is stored in 'result'. between 'domain' and any rectangle in 'source'. The result is stored in 'result'.
*/ */
void MinOverlapPlacer::findMaxOverlappers(const QRect &domain, const QList<QRect> &source, void MinOverlapPlacer::findMaxOverlappers(const QRect &domain, const QVector<QRect> &source,
QList<QRect> &result) QVector<QRect> &result)
{ {
int maxOverlap = -1; int maxOverlap = -1;
foreach (const QRect &srcRect, source) { foreach (const QRect &srcRect, source) {
@ -517,16 +517,16 @@ void MinOverlapPlacer::findMaxOverlappers(const QRect &domain, const QList<QRect
placement that overlaps the rectangles in 'rects' as little as possible while at the placement that overlaps the rectangles in 'rects' as little as possible while at the
same time being as much as possible inside 'domain'. same time being as much as possible inside 'domain'.
*/ */
QPoint MinOverlapPlacer::findBestPlacement(const QRect &domain, const QList<QRect> &rects, QPoint MinOverlapPlacer::findBestPlacement(const QRect &domain, const QVector<QRect> &rects,
QList<QRect> &source) QVector<QRect> &source)
{ {
QList<QRect> nonInsiders; QVector<QRect> nonInsiders;
findNonInsiders(domain, source, nonInsiders); findNonInsiders(domain, source, nonInsiders);
if (!source.empty()) if (!source.empty())
return findMinOverlapRect(source, rects).topLeft(); return findMinOverlapRect(source, rects).topLeft();
QList<QRect> maxOverlappers; QVector<QRect> maxOverlappers;
findMaxOverlappers(domain, nonInsiders, maxOverlappers); findMaxOverlappers(domain, nonInsiders, maxOverlappers);
return findMinOverlapRect(maxOverlappers, rects).topLeft(); return findMinOverlapRect(maxOverlappers, rects).topLeft();
} }
@ -538,7 +538,7 @@ QPoint MinOverlapPlacer::findBestPlacement(const QRect &domain, const QList<QRec
overlaps 'rects' as little as possible and 'domain' as much as possible. overlaps 'rects' as little as possible and 'domain' as much as possible.
Returns the position of the resulting rectangle. Returns the position of the resulting rectangle.
*/ */
QPoint MinOverlapPlacer::place(const QSize &size, const QList<QRect> &rects, QPoint MinOverlapPlacer::place(const QSize &size, const QVector<QRect> &rects,
const QRect &domain) const const QRect &domain) const
{ {
if (size.isEmpty() || !domain.isValid()) if (size.isEmpty() || !domain.isValid())
@ -548,7 +548,7 @@ QPoint MinOverlapPlacer::place(const QSize &size, const QList<QRect> &rects,
return QPoint(); return QPoint();
} }
QList<QRect> candidates; QVector<QRect> candidates;
getCandidatePlacements(size, rects, domain, candidates); getCandidatePlacements(size, rects, domain, candidates);
return findBestPlacement(domain, rects, candidates); return findBestPlacement(domain, rects, candidates);
} }
@ -882,7 +882,8 @@ void QMdiAreaPrivate::place(Placer *placer, QMdiSubWindow *child)
return; return;
} }
QList<QRect> rects; QVector<QRect> rects;
rects.reserve(childWindows.size());
QRect parentRect = q->rect(); QRect parentRect = q->rect();
foreach (QMdiSubWindow *window, childWindows) { foreach (QMdiSubWindow *window, childWindows) {
if (!sanityCheck(window, "QMdiArea::place") || window == child || !window->isVisibleTo(q) if (!sanityCheck(window, "QMdiArea::place") || window == child || !window->isVisibleTo(q)

View File

@ -59,6 +59,7 @@
#ifndef QT_NO_MDIAREA #ifndef QT_NO_MDIAREA
#include <QList> #include <QList>
#include <QVector>
#include <QRect> #include <QRect>
#include <QPoint> #include <QPoint>
#include <QtWidgets/qapplication.h> #include <QtWidgets/qapplication.h>
@ -116,24 +117,24 @@ public:
// Places the rectangle defined by 'size' relative to 'rects' and 'domain'. // Places the rectangle defined by 'size' relative to 'rects' and 'domain'.
// Returns the position of the resulting rectangle. // Returns the position of the resulting rectangle.
virtual QPoint place( virtual QPoint place(
const QSize &size, const QList<QRect> &rects, const QRect &domain) const = 0; const QSize &size, const QVector<QRect> &rects, const QRect &domain) const = 0;
virtual ~Placer() {} virtual ~Placer() {}
}; };
class MinOverlapPlacer : public Placer class MinOverlapPlacer : public Placer
{ {
QPoint place(const QSize &size, const QList<QRect> &rects, const QRect &domain) const; QPoint place(const QSize &size, const QVector<QRect> &rects, const QRect &domain) const;
static int accumulatedOverlap(const QRect &source, const QList<QRect> &rects); static int accumulatedOverlap(const QRect &source, const QVector<QRect> &rects);
static QRect findMinOverlapRect(const QList<QRect> &source, const QList<QRect> &rects); static QRect findMinOverlapRect(const QVector<QRect> &source, const QVector<QRect> &rects);
static void getCandidatePlacements( static void getCandidatePlacements(
const QSize &size, const QList<QRect> &rects, const QRect &domain, const QSize &size, const QVector<QRect> &rects, const QRect &domain,
QList<QRect> &candidates); QVector<QRect> &candidates);
static QPoint findBestPlacement( static QPoint findBestPlacement(
const QRect &domain, const QList<QRect> &rects, QList<QRect> &source); const QRect &domain, const QVector<QRect> &rects, QVector<QRect> &source);
static void findNonInsiders( static void findNonInsiders(
const QRect &domain, QList<QRect> &source, QList<QRect> &result); const QRect &domain, QVector<QRect> &source, QVector<QRect> &result);
static void findMaxOverlappers( static void findMaxOverlappers(
const QRect &domain, const QList<QRect> &source, QList<QRect> &result); const QRect &domain, const QVector<QRect> &source, QVector<QRect> &result);
}; };
} // namespace QMdi } // namespace QMdi