00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "qgridlayout.h"
00025
00026
00027 #include "qapplication.h"
00028 #include "qwidget.h"
00029 #include "qlist.h"
00030 #include "qsizepolicy.h"
00031 #include "qvector.h"
00032
00033 #include "qlayoutengine_p.h"
00034 #include "qlayout_p.h"
00035
00036
00037
00038
00039
00040
00041
00042 class QGridBox
00043 {
00044 public:
00045 QGridBox(QLayoutItem *lit) { item_ = lit; }
00046
00047 QGridBox(QWidget *wid) { item_ = new QWidgetItem(wid); }
00048 ~QGridBox() { delete item_; }
00049
00050 QSize sizeHint() const { return item_->sizeHint(); }
00051 QSize minimumSize() const { return item_->minimumSize(); }
00052 QSize maximumSize() const { return item_->maximumSize(); }
00053 Qt::Orientations expandingDirections() const { return item_->expandingDirections(); }
00054 bool isEmpty() const { return item_->isEmpty(); }
00055
00056 bool hasHeightForWidth() const { return item_->hasHeightForWidth(); }
00057 int heightForWidth(int w) const { return item_->heightForWidth(w); }
00058
00059 void setAlignment(Qt::Alignment a) { item_->setAlignment(a); }
00060 void setGeometry(const QRect &r) { item_->setGeometry(r); }
00061 Qt::Alignment alignment() const { return item_->alignment(); }
00062 QLayoutItem *item() { return item_; }
00063 QLayoutItem *takeItem() { QLayoutItem *i = item_; item_ = 0; return i; }
00064
00065 int hStretch() { return item_->widget() ?
00066 item_->widget()->sizePolicy().horizontalStretch() : 0; }
00067 int vStretch() { return item_->widget() ?
00068 item_->widget()->sizePolicy().verticalStretch() : 0; }
00069
00070 private:
00071 friend class QGridLayoutPrivate;
00072
00073 QLayoutItem *item_;
00074 int row, col;
00075 int torow, tocol;
00076 };
00077
00078 class QGridLayoutPrivate : public QLayoutPrivate
00079 {
00080 Q_DECLARE_PUBLIC(QGridLayout)
00081 public:
00082 QGridLayoutPrivate();
00083
00084 void add(QGridBox*, int row, int col);
00085 void add(QGridBox*, int row1, int row2, int col1, int col2);
00086 QSize sizeHint(int) const;
00087 QSize minimumSize(int) const;
00088 QSize maximumSize(int) const;
00089
00090 Qt::Orientations expandingDirections(int spacing) const;
00091
00092 void distribute(QRect, int);
00093 inline int numRows() const { return rr; }
00094 inline int numCols() const { return cc; }
00095 inline void expand(int rows, int cols)
00096 { setSize(qMax(rows, rr), qMax(cols, cc)); }
00097 inline void setRowStretch(int r, int s)
00098 { expand(r + 1, 0); rStretch[r] = s; setDirty(); }
00099 inline void setColStretch(int c, int s)
00100 { expand(0, c + 1); cStretch[c] = s; setDirty(); }
00101 inline int rowStretch(int r) const { return rStretch[r]; }
00102 inline int colStretch(int c) const { return cStretch[c]; }
00103 inline void setRowSpacing(int r, int s)
00104 { expand(r + 1, 0); rSpacing[r] = s; setDirty(); }
00105 inline void setColSpacing(int c, int s)
00106 { expand(0, c + 1); cSpacing[c] = s; setDirty(); }
00107 inline int rowSpacing(int r) const { return rSpacing[r]; }
00108 inline int colSpacing(int c) const { return cSpacing[c]; }
00109
00110 inline void setReversed(bool r, bool c) { hReversed = c; vReversed = r; }
00111 inline bool horReversed() const { return hReversed; }
00112 inline bool verReversed() const { return vReversed; }
00113 inline void setDirty() { needRecalc = true; hfw_width = -1; }
00114 inline bool isDirty() const { return needRecalc; }
00115 bool hasHeightForWidth(int space);
00116 int heightForWidth(int, int, int);
00117 int minimumHeightForWidth(int, int, int);
00118
00119 inline void getNextPos(int &row, int &col) { row = nextR; col = nextC; }
00120 inline int count() const { return things.count(); }
00121 QRect cellRect(int row, int col) const;
00122
00123 inline QLayoutItem *itemAt(int index) const {
00124 if (index < things.count())
00125 return things.at(index)->item();
00126 else
00127 return 0;
00128 }
00129 inline QLayoutItem *takeAt(int index) {
00130 QLayoutItem *item = 0;
00131 if (index < things.count()) {
00132 QGridBox *b = things.takeAt(index);
00133 if (b) {
00134 item = b->takeItem();
00135 delete b;
00136 }
00137 }
00138 return item;
00139 }
00140
00141 void getItemPosition(int index, int *row, int *column, int *rowSpan, int *columnSpan) {
00142 if (index < things.count()) {
00143 QGridBox *b = things.at(index);
00144 int toRow = b->torow < 0 ? rr-1 : b->torow;
00145 int toCol = b->tocol < 0 ? cc-1 : b->tocol;
00146 *row = b->row;
00147 *column = b->col;
00148 *rowSpan = toRow - *row + 1;
00149 *columnSpan = toCol - *column +1;
00150 }
00151 }
00152 void deleteAll();
00153
00154 private:
00155 void setNextPosAfter(int r, int c);
00156 void recalcHFW(int w, int s);
00157 void addHfwData(QGridBox *box, int width);
00158 void init();
00159 QSize findSize(int QLayoutStruct::*, int) const;
00160 void addData(QGridBox *b, bool r = true, bool c = true);
00161 void setSize(int rows, int cols);
00162 void setupLayoutData(int space);
00163 void setupHfwLayoutData(int space);
00164
00165 int rr;
00166 int cc;
00167 QVector<QLayoutStruct> rowData;
00168 QVector<QLayoutStruct> colData;
00169 QVector<QLayoutStruct> *hfwData;
00170 QVector<int> rStretch;
00171 QVector<int> cStretch;
00172 QVector<int> rSpacing;
00173 QVector<int> cSpacing;
00174 QList<QGridBox *> things;
00175
00176 int hfw_width;
00177 int hfw_height;
00178 int hfw_minheight;
00179 int nextR;
00180 int nextC;
00181
00182 uint hReversed : 1;
00183 uint vReversed : 1;
00184 uint needRecalc : 1;
00185 uint has_hfw : 1;
00186 uint addVertical : 1;
00187 };
00188
00189 QGridLayoutPrivate::QGridLayoutPrivate()
00190 {
00191 addVertical = false;
00192 setDirty();
00193 rr = cc = 0;
00194 nextR = nextC = 0;
00195 hfwData = 0;
00196 hReversed = false;
00197 vReversed = false;
00198 }
00199
00200 #if 0
00201 QGridLayoutPrivate::QGridLayoutPrivate(int nRows, int nCols)
00202 : rowData(0), colData(0)
00203 {
00204 init();
00205 if (nRows < 0) {
00206 nRows = 1;
00207 addVertical = false;
00208 }
00209 if (nCols < 0) {
00210 nCols = 1;
00211 addVertical = true;
00212 }
00213 setSize(nRows, nCols);
00214 }
00215 #endif
00216
00217 void QGridLayoutPrivate::deleteAll()
00218 {
00219 while (!things.isEmpty())
00220 delete things.takeFirst();
00221 delete hfwData;
00222 }
00223
00224 bool QGridLayoutPrivate::hasHeightForWidth(int spacing)
00225 {
00226 setupLayoutData(spacing);
00227 return has_hfw;
00228 }
00229
00230
00231
00232
00233
00234 void QGridLayoutPrivate::recalcHFW(int w, int spacing)
00235 {
00236
00237
00238
00239
00240 if (!hfwData)
00241 hfwData = new QVector<QLayoutStruct>(rr);
00242 setupHfwLayoutData(spacing);
00243 QVector<QLayoutStruct> &rData = *hfwData;
00244
00245 int h = 0;
00246 int mh = 0;
00247 int n = 0;
00248 for (int r = 0; r < rr; r++) {
00249 h += rData[r].sizeHint;
00250 mh += rData[r].minimumSize;
00251 if (!rData[r].empty)
00252 n++;
00253 }
00254 if (n) {
00255 h += (n - 1) * spacing;
00256 mh += (n - 1) * spacing;
00257 }
00258
00259 hfw_width = w;
00260 hfw_height = qMin(QLAYOUTSIZE_MAX, h);
00261 hfw_minheight = qMin(QLAYOUTSIZE_MAX, mh);
00262 }
00263
00264 int QGridLayoutPrivate::heightForWidth(int w, int margin, int spacing)
00265 {
00266 setupLayoutData(spacing);
00267 if (!has_hfw)
00268 return -1;
00269 if (w + 2*margin != hfw_width) {
00270 qGeomCalc(colData, 0, cc, 0, w - 2*margin, spacing);
00271 recalcHFW(w - 2*margin, spacing);
00272 }
00273 return hfw_height + 2*margin;
00274 }
00275
00276 int QGridLayoutPrivate::minimumHeightForWidth(int w, int margin, int spacing)
00277 {
00278 (void) heightForWidth(w, margin, spacing);
00279 return has_hfw ? (hfw_minheight + 2*margin) : -1;
00280 }
00281
00282 QSize QGridLayoutPrivate::findSize(int QLayoutStruct::*size, int spacer) const
00283 {
00284 QGridLayoutPrivate *that = const_cast<QGridLayoutPrivate*>(this);
00285 that->setupLayoutData(spacer);
00286
00287 int w = 0;
00288 int h = 0;
00289 int n = 0;
00290
00291 for (int r = 0; r < rr; r++) {
00292 h = h + rowData[r].*size;
00293 if (!rowData[r].empty)
00294 n++;
00295 }
00296 if (n)
00297 h += (n - 1) * spacer;
00298
00299 n = 0;
00300 for (int c = 0; c < cc; c++) {
00301 w = w + colData[c].*size;
00302 if (!colData[c].empty)
00303 n++;
00304 }
00305 if (n)
00306 w += (n - 1) * spacer;
00307
00308 w = qMin(QLAYOUTSIZE_MAX, w);
00309 h = qMin(QLAYOUTSIZE_MAX, h);
00310
00311 return QSize(w, h);
00312 }
00313
00314 Qt::Orientations QGridLayoutPrivate::expandingDirections(int spacing) const
00315 {
00316 QGridLayoutPrivate *that = const_cast<QGridLayoutPrivate*>(this);
00317 that->setupLayoutData(spacing);
00318 Qt::Orientations ret;
00319
00320 for (int r = 0; r < rr; r++) {
00321 if (rowData[r].expansive) {
00322 ret |= Qt::Vertical;
00323 break;
00324 }
00325 }
00326 for (int c = 0; c < cc; c++) {
00327 if (colData[c].expansive) {
00328 ret |= Qt::Horizontal;
00329 break;
00330 }
00331 }
00332 return ret;
00333 }
00334
00335 QSize QGridLayoutPrivate::sizeHint(int spacer) const
00336 {
00337 return findSize(&QLayoutStruct::sizeHint, spacer);
00338 }
00339
00340 QSize QGridLayoutPrivate::maximumSize(int spacer) const
00341 {
00342 return findSize(&QLayoutStruct::maximumSize, spacer);
00343 }
00344
00345 QSize QGridLayoutPrivate::minimumSize(int spacer) const
00346 {
00347 return findSize(&QLayoutStruct::minimumSize, spacer);
00348 }
00349
00350 void QGridLayoutPrivate::setSize(int r, int c)
00351 {
00352 if ((int)rowData.size() < r) {
00353 int newR = qMax(r, rr * 2);
00354 rowData.resize(newR);
00355 rStretch.resize(newR);
00356 rSpacing.resize(newR);
00357 for (int i = rr; i < newR; i++) {
00358 rowData[i].init();
00359 rowData[i].maximumSize = 0;
00360 rowData[i].pos = 0;
00361 rowData[i].size = 0;
00362 rStretch[i] = 0;
00363 rSpacing[i] = 0;
00364 }
00365 }
00366 if ((int)colData.size() < c) {
00367 int newC = qMax(c, cc * 2);
00368 colData.resize(newC);
00369 cStretch.resize(newC);
00370 cSpacing.resize(newC);
00371 for (int i = cc; i < newC; i++) {
00372 colData[i].init();
00373 colData[i].maximumSize = 0;
00374 colData[i].pos = 0;
00375 colData[i].size = 0;
00376 cStretch[i] = 0;
00377 cSpacing[i] = 0;
00378 }
00379 }
00380
00381 if (hfwData && (int)hfwData->size() < r) {
00382 delete hfwData;
00383 hfwData = 0;
00384 hfw_width = -1;
00385 }
00386 rr = r;
00387 cc = c;
00388 }
00389
00390 void QGridLayoutPrivate::setNextPosAfter(int row, int col)
00391 {
00392 if (addVertical) {
00393 if (col > nextC || col == nextC && row >= nextR) {
00394 nextR = row + 1;
00395 nextC = col;
00396 if (nextR >= rr) {
00397 nextR = 0;
00398 nextC++;
00399 }
00400 }
00401 } else {
00402 if (row > nextR || row == nextR && col >= nextC) {
00403 nextR = row;
00404 nextC = col + 1;
00405 if (nextC >= cc) {
00406 nextC = 0;
00407 nextR++;
00408 }
00409 }
00410 }
00411 }
00412
00413 void QGridLayoutPrivate::add(QGridBox *box, int row, int col)
00414 {
00415 expand(row+1, col+1);
00416 box->row = box->torow = row;
00417 box->col = box->tocol = col;
00418 things.append(box);
00419 setDirty();
00420 setNextPosAfter(row, col);
00421 }
00422
00423 void QGridLayoutPrivate::add(QGridBox *box, int row1, int row2, int col1,
00424 int col2 )
00425 {
00426 if (row2 >= 0 && row2 < row1)
00427 qWarning("QGridLayout: Multi-cell fromRow greater than toRow");
00428 if (col2 >= 0 && col2 < col1)
00429 qWarning("QGridLayout: Multi-cell fromCol greater than toCol");
00430 if (row1 == row2 && col1 == col2) {
00431 add(box, row1, col1);
00432 return;
00433 }
00434 expand(row2+1, col2+1);
00435 box->row = row1;
00436 box->col = col1;
00437
00438 box->torow = row2;
00439 box->tocol = col2;
00440
00441 things.append(box);
00442 setDirty();
00443 if (col2 < 0)
00444 col2 = cc - 1;
00445
00446 setNextPosAfter(row2, col2);
00447 }
00448
00449 void QGridLayoutPrivate::addData(QGridBox *box, bool r, bool c)
00450 {
00451 QSize hint = box->sizeHint();
00452 QSize minS = box->minimumSize();
00453 QSize maxS = box->maximumSize();
00454 const QWidget *widget = box->item()->widget();
00455
00456 if (box->isEmpty() && widget)
00457 return;
00458
00459 if (c) {
00460 if (!cStretch[box->col])
00461 colData[box->col].stretch = qMax(colData[box->col].stretch,
00462 box->hStretch());
00463 colData[box->col].sizeHint = qMax(hint.width(),
00464 colData[box->col].sizeHint);
00465 colData[box->col].minimumSize = qMax(minS.width(),
00466 colData[box->col].minimumSize);
00467
00468 qMaxExpCalc(colData[box->col].maximumSize, colData[box->col].expansive, colData[box->col].empty,
00469 maxS.width(), box->expandingDirections() & Qt::Horizontal, box->isEmpty());
00470 }
00471 if (r) {
00472 if (!rStretch[box->row])
00473 rowData[box->row].stretch = qMax(rowData[box->row].stretch,
00474 box->vStretch());
00475 rowData[box->row].sizeHint = qMax(hint.height(),
00476 rowData[box->row].sizeHint);
00477 rowData[box->row].minimumSize = qMax(minS.height(),
00478 rowData[box->row].minimumSize);
00479
00480 qMaxExpCalc(rowData[box->row].maximumSize, rowData[box->row].expansive, rowData[box->row].empty,
00481 maxS.height(), box->expandingDirections() & Qt::Vertical, box->isEmpty());
00482 }
00483 }
00484
00485 static void distributeMultiBox(QVector<QLayoutStruct> &chain, int spacing, int start, int end,
00486 int minSize, int sizeHint, QVector<int> &stretchArray, int stretch)
00487 {
00488 int i;
00489 int w = 0;
00490 int wh = 0;
00491 int max = 0;
00492 for (i = start; i <= end; i++) {
00493 w += chain[i].minimumSize;
00494 wh += chain[i].sizeHint;
00495 if (chain[i].empty)
00496 chain[i].maximumSize = QWIDGETSIZE_MAX;
00497 max += chain[i].maximumSize;
00498 chain[i].empty = false;
00499 if (stretchArray[i] == 0)
00500 chain[i].stretch = qMax(chain[i].stretch,stretch);
00501 }
00502 w += spacing * (end - start);
00503 wh += spacing * (end - start);
00504 max += spacing * (end - start);
00505
00506 if (max < minSize) {
00507
00508
00509
00510
00511
00512
00513
00514 qGeomCalc(chain, start, end - start + 1, 0, minSize, spacing);
00515 int pos = 0;
00516 for (i = start; i <= end; i++) {
00517 int nextPos = (i == end) ? minSize - 1 : chain[i + 1].pos;
00518 int realSize = nextPos - pos;
00519 if (i != end)
00520 realSize -= spacing;
00521 if (chain[i].minimumSize < realSize)
00522 chain[i].minimumSize = realSize;
00523 if (chain[i].maximumSize < chain[i].minimumSize)
00524 chain[i].maximumSize = chain[i].minimumSize;
00525 pos = nextPos;
00526 }
00527 } else if (w < minSize) {
00528 qGeomCalc(chain, start, end - start + 1, 0, minSize, spacing);
00529 for (i = start; i <= end; i++) {
00530 if (chain[i].minimumSize < chain[i].size)
00531 chain[i].minimumSize = chain[i].size;
00532 }
00533 }
00534
00535 if (wh < sizeHint) {
00536 qGeomCalc(chain, start, end - start + 1, 0, sizeHint, spacing);
00537 for (i = start; i <= end; i++) {
00538 if (chain[i].sizeHint < chain[i].size)
00539 chain[i].sizeHint = chain[i].size;
00540 }
00541 }
00542 }
00543
00544
00545
00546 void QGridLayoutPrivate::setupLayoutData(int spacing)
00547 {
00548 #ifndef QT_LAYOUT_DISABLE_CACHING
00549 if (!needRecalc)
00550 return;
00551 #endif
00552 has_hfw = false;
00553 int i;
00554
00555 for (i = 0; i < rr; i++) {
00556 rowData[i].init(rStretch[i], rSpacing[i]);
00557 rowData[i].maximumSize = rStretch[i] ? QLAYOUTSIZE_MAX : rSpacing[i];
00558 }
00559 for (i = 0; i < cc; i++) {
00560 colData[i].init(cStretch[i], cSpacing[i]);
00561 colData[i].maximumSize = cStretch[i] ? QLAYOUTSIZE_MAX : cSpacing[i];
00562 }
00563 for (int pass = 0; pass < 2; ++pass) {
00564 for (i = 0; i < things.size(); ++i) {
00565 QGridBox *box = things.at(i);
00566 int r1 = box->row;
00567 int c1 = box->col;
00568 int r2 = box->torow;
00569 int c2 = box->tocol;
00570 if (r2 < 0)
00571 r2 = rr - 1;
00572 if (c2 < 0)
00573 c2 = cc - 1;
00574
00575 QSize hint = box->sizeHint();
00576 QSize min = box->minimumSize();
00577 if (box->hasHeightForWidth())
00578 has_hfw = true;
00579
00580 if (r1 == r2) {
00581 if (pass == 0)
00582 addData(box, true, false);
00583 } else {
00584 if (pass == 1)
00585 distributeMultiBox(rowData, spacing, r1, r2, min.height(), hint.height(),
00586 rStretch, box->vStretch());
00587 }
00588 if (c1 == c2) {
00589 if (pass == 0)
00590 addData(box, false, true);
00591 } else {
00592 if (pass == 1)
00593 distributeMultiBox(colData, spacing, c1, c2, min.width(), hint.width(),
00594 cStretch, box->hStretch());
00595 }
00596 }
00597 }
00598
00599 for (i = 0; i < rr; i++)
00600 rowData[i].expansive = rowData[i].expansive || rowData[i].stretch > 0;
00601 for (i = 0; i < cc; i++)
00602 colData[i].expansive = colData[i].expansive || colData[i].stretch > 0;
00603
00604 needRecalc = false;
00605 }
00606
00607 void QGridLayoutPrivate::addHfwData(QGridBox *box, int width)
00608 {
00609 QVector<QLayoutStruct> &rData = *hfwData;
00610 if (box->hasHeightForWidth()) {
00611 int hint = box->heightForWidth(width);
00612 rData[box->row].sizeHint = qMax(hint, rData[box->row].sizeHint);
00613 rData[box->row].minimumSize = qMax(hint, rData[box->row].minimumSize);
00614 } else {
00615 QSize hint = box->sizeHint();
00616 QSize minS = box->minimumSize();
00617 rData[box->row].sizeHint = qMax(hint.height(), rData[box->row].sizeHint);
00618 rData[box->row].minimumSize = qMax(minS.height(), rData[box->row].minimumSize);
00619 }
00620 }
00621
00622
00623
00624
00625
00626
00627 void QGridLayoutPrivate::setupHfwLayoutData(int spacing)
00628 {
00629 QVector<QLayoutStruct> &rData = *hfwData;
00630 for (int i = 0; i < rr; i++) {
00631 rData[i] = rowData[i];
00632 rData[i].minimumSize = rData[i].sizeHint = rSpacing[i];
00633 }
00634
00635 for (int pass = 0; pass < 2; ++pass) {
00636 for (int i = 0; i < things.size(); ++i) {
00637 QGridBox *box = things.at(i);
00638 int r1 = box->row;
00639 int c1 = box->col;
00640 int r2 = box->torow;
00641 int c2 = box->tocol;
00642 if (r2 < 0)
00643 r2 = rr-1;
00644 if (c2 < 0)
00645 c2 = cc-1;
00646 int w = colData[c2].pos + colData[c2].size - colData[c1].pos;
00647
00648 if (r1 == r2) {
00649 if (pass == 0)
00650 addHfwData(box, w);
00651 } else {
00652 if (pass == 1) {
00653 QSize hint = box->sizeHint();
00654 QSize min = box->minimumSize();
00655 if (box->hasHeightForWidth()) {
00656 int hfwh = box->heightForWidth(w);
00657 if (hfwh > hint.height())
00658 hint.setHeight(hfwh);
00659 if (hfwh > min.height())
00660 min.setHeight(hfwh);
00661 }
00662 distributeMultiBox(rData, spacing, r1, r2,
00663 min.height(), hint.height(),
00664 rStretch, box->vStretch());
00665 }
00666 }
00667 }
00668 }
00669 for (int i = 0; i < rr; i++)
00670 rData[i].expansive = rData[i].expansive || rData[i].stretch > 0;
00671 }
00672
00673 void QGridLayoutPrivate::distribute(QRect r, int spacing)
00674 {
00675 Q_Q(QGridLayout);
00676 bool visualHReversed = hReversed;
00677 QWidget *parent = q->parentWidget();
00678 if (parent && parent->isRightToLeft())
00679 visualHReversed = !visualHReversed;
00680
00681 setupLayoutData(spacing);
00682
00683 qGeomCalc(colData, 0, cc, r.x(), r.width(), spacing);
00684 QVector<QLayoutStruct> *rDataPtr;
00685 if (has_hfw) {
00686 recalcHFW(r.width(), spacing);
00687 qGeomCalc(*hfwData, 0, rr, r.y(), r.height(), spacing);
00688 rDataPtr = hfwData;
00689 } else {
00690 qGeomCalc(rowData, 0, rr, r.y(), r.height(), spacing);
00691 rDataPtr = &rowData;
00692 }
00693 QVector<QLayoutStruct> &rData = *rDataPtr;
00694 int i;
00695
00696 bool reverse = ((r.bottom() > rect.bottom()) || (r.bottom() == rect.bottom()
00697 && ((r.right() > rect.right()) != visualHReversed)));
00698 int n = things.size();
00699 for (i = 0; i < n; ++i) {
00700 QGridBox *box = things.at(reverse ? n-i-1 : i);
00701 int r2 = box->torow;
00702 int c2 = box->tocol;
00703 if (r2 < 0)
00704 r2 = rr-1;
00705 if (c2 < 0)
00706 c2 = cc-1;
00707
00708 int x = colData[box->col].pos;
00709 int y = rData[box->row].pos;
00710 int x2p = colData[c2].pos + colData[c2].size;
00711 int y2p = rData[r2].pos + rData[r2].size;
00712 int w = x2p - x;
00713 int h = y2p - y;
00714
00715 if (visualHReversed)
00716 x = r.left() + r.right() - x - w + 1;
00717 if (vReversed)
00718 y = r.top() + r.bottom() - y - h + 1;
00719 box->setGeometry(QRect(x, y, w, h));
00720 }
00721 }
00722
00723 QRect QGridLayoutPrivate::cellRect(int row, int col) const
00724 {
00725 if (row < 0 || row >= rr || col < 0 || col >= cc)
00726 return QRect();
00727
00728 const QVector<QLayoutStruct> *rDataPtr;
00729 if (has_hfw && hfwData)
00730 rDataPtr = hfwData;
00731 else
00732 rDataPtr = &rowData;
00733 return QRect(colData[col].pos, (*rDataPtr)[row].pos, colData[col].size, (*rDataPtr)[row].size);
00734 }
00735
00817 QGridLayout::QGridLayout(QWidget *parent)
00818 : QLayout(*new QGridLayoutPrivate, 0, parent)
00819 {
00820 Q_D(QGridLayout);
00821 d->expand(1, 1);
00822 }
00823
00831 QGridLayout::QGridLayout()
00832 : QLayout(*new QGridLayoutPrivate, 0, 0)
00833 {
00834 Q_D(QGridLayout);
00835 d->expand(1, 1);
00836 }
00837
00838
00839 #ifdef QT3_SUPPORT
00840
00850 QGridLayout::QGridLayout(QWidget *parent, int nRows, int nCols, int margin,
00851 int space, const char *name)
00852 : QLayout(*new QGridLayoutPrivate, 0, parent)
00853 {
00854 Q_D(QGridLayout);
00855 d->expand(nRows, nCols);
00856 setMargin(margin);
00857 setSpacing(space<0 ? margin : space);
00858 setObjectName(QString::fromAscii(name));
00859 }
00860
00872 QGridLayout::QGridLayout(QLayout *parentLayout, int nRows, int nCols,
00873 int spacing, const char *name)
00874 : QLayout(*new QGridLayoutPrivate, parentLayout, 0)
00875 {
00876 Q_D(QGridLayout);
00877 d->expand(nRows, nCols);
00878 setSpacing(spacing);
00879 setObjectName(QString::fromAscii(name));
00880 }
00881
00893 QGridLayout::QGridLayout(int nRows, int nCols,
00894 int spacing, const char *name)
00895 : QLayout(*new QGridLayoutPrivate, 0, 0)
00896 {
00897 Q_D(QGridLayout);
00898 d->expand(nRows, nCols);
00899 setSpacing(spacing);
00900 setObjectName(QString::fromAscii(name));
00901 }
00902 #endif
00903
00904
00914 void QGridLayout::setDefaultPositioning(int n, Qt::Orientation orient)
00915 {
00916 Q_D(QGridLayout);
00917 if (orient == Qt::Horizontal) {
00918 d->expand(1, n);
00919 d->addVertical = false;
00920 } else {
00921 d->expand(n,1);
00922 d->addVertical = true;
00923 }
00924 }
00925
00926
00933 QGridLayout::~QGridLayout()
00934 {
00935 Q_D(QGridLayout);
00936 d->deleteAll();
00937 }
00938
00942 int QGridLayout::rowCount() const
00943 {
00944 Q_D(const QGridLayout);
00945 return d->numRows();
00946 }
00947
00951 int QGridLayout::columnCount() const
00952 {
00953 Q_D(const QGridLayout);
00954 return d->numCols();
00955 }
00956
00960 QSize QGridLayout::sizeHint() const
00961 {
00962 Q_D(const QGridLayout);
00963 int m = margin();
00964 return d->sizeHint(spacing()) + QSize(2 * m, 2 * m);
00965 }
00966
00970 QSize QGridLayout::minimumSize() const
00971 {
00972 Q_D(const QGridLayout);
00973 int m = margin();
00974 return d->minimumSize(spacing()) + QSize(2 * m, 2 * m);
00975 }
00976
00980 QSize QGridLayout::maximumSize() const
00981 {
00982 Q_D(const QGridLayout);
00983 int m = margin();
00984 QSize s = d->maximumSize(spacing()) +
00985 QSize(2 * m, 2 * m);
00986 s = s.boundedTo(QSize(QLAYOUTSIZE_MAX, QLAYOUTSIZE_MAX));
00987 if (alignment() & Qt::AlignHorizontal_Mask)
00988 s.setWidth(QLAYOUTSIZE_MAX);
00989 if (alignment() & Qt::AlignVertical_Mask)
00990 s.setHeight(QLAYOUTSIZE_MAX);
00991 return s;
00992 }
00993
00997 bool QGridLayout::hasHeightForWidth() const
00998 {
00999 return ((QGridLayout*)this)->d_func()->hasHeightForWidth(spacing());
01000 }
01001
01005 int QGridLayout::heightForWidth(int w) const
01006 {
01007 QGridLayout *that = (QGridLayout*)this;
01008 return that->d_func()->heightForWidth(w, margin(), spacing());
01009 }
01010
01014 int QGridLayout::minimumHeightForWidth(int w) const
01015 {
01016 QGridLayout *that = (QGridLayout*)this;
01017 return that->d_func()->minimumHeightForWidth(w, margin(), spacing());
01018 }
01019
01020 #ifdef QT3_SUPPORT
01021
01034 bool QGridLayout::findWidget(QWidget* w, int *row, int *column)
01035 {
01036 Q_D(QGridLayout);
01037 int index = indexOf(w);
01038 if (index < 0)
01039 return false;
01040 int dummy1, dummy2;
01041 d->getItemPosition(index, row, column, &dummy1, &dummy2);
01042 return true;
01043 }
01044 #endif
01045
01048 int QGridLayout::count() const
01049 {
01050 Q_D(const QGridLayout);
01051 return d->count();
01052 }
01053
01054
01058 QLayoutItem *QGridLayout::itemAt(int index) const
01059 {
01060 Q_D(const QGridLayout);
01061 return d->itemAt(index);
01062 }
01063
01064
01068 QLayoutItem *QGridLayout::takeAt(int index)
01069 {
01070 Q_D(QGridLayout);
01071 return d->takeAt(index);
01072 }
01073
01081 void QGridLayout::getItemPosition(int index, int *row, int *column, int *rowSpan, int *columnSpan)
01082 {
01083 Q_D(QGridLayout);
01084 d->getItemPosition(index, row, column, rowSpan, columnSpan);
01085 }
01086
01087
01091 void QGridLayout::setGeometry(const QRect &rect)
01092 {
01093 Q_D(QGridLayout);
01094 if (d->isDirty() || rect != geometry()) {
01095 QRect cr = alignment() ? alignmentRect(rect) : rect;
01096 int m = margin();
01097 QRect s(cr.x() + m, cr.y() + m,
01098 cr.width() - 2 * m, cr.height() - 2 * m);
01099 d->distribute(s, spacing());
01100 QLayout::setGeometry(rect);
01101 }
01102 }
01103
01113 QRect QGridLayout::cellRect(int row, int column) const
01114 {
01115 Q_D(const QGridLayout);
01116 return d->cellRect(row, column);
01117 }
01118 #ifdef QT3_SUPPORT
01119
01126 void QGridLayout::expand(int nRows, int nCols)
01127 {
01128 Q_D(QGridLayout);
01129 d->expand(nRows, nCols);
01130 }
01131 #endif
01132
01136 void QGridLayout::addItem(QLayoutItem *item)
01137 {
01138 Q_D(QGridLayout);
01139 int r, c;
01140 d->getNextPos(r, c);
01141 addItem(item, r, c);
01142 }
01143
01154 void QGridLayout::addItem(QLayoutItem *item, int row, int column, int rowSpan, int columnSpan, Qt::Alignment alignment)
01155 {
01156 Q_D(QGridLayout);
01157 QGridBox *b = new QGridBox(item);
01158 b->setAlignment(alignment);
01159 d->add(b, row, (rowSpan < 0) ? -1 : row + rowSpan - 1, column, (columnSpan < 0) ? -1 : column + columnSpan - 1);
01160 invalidate();
01161 }
01162
01163
01164
01165
01166
01167 static bool checkWidget(QLayout *l, QWidget *w)
01168 {
01169 if (!w) {
01170 qWarning("QLayout: Cannot add null widget to %s/%s", l->metaObject()->className(),
01171 l->objectName().toLocal8Bit().data());
01172 return false;
01173 }
01174 return true;
01175 }
01176
01185 void QGridLayout::addWidget(QWidget *widget, int row, int column, Qt::Alignment alignment)
01186 {
01187 if (!checkWidget(this, widget))
01188 return;
01189 if (row < 0 || column < 0) {
01190 qWarning("QGridLayout: Cannot add %s/%s to %s/%s at row %d column %d",
01191 widget->metaObject()->className(), widget->objectName().toLocal8Bit().data(),
01192 metaObject()->className(), objectName().toLocal8Bit().data(), row, column);
01193 return;
01194 }
01195 addChildWidget(widget);
01196 QWidgetItem *b = new QWidgetItem(widget);
01197 addItem(b, row, column, 1, 1, alignment);
01198 }
01199
01212 void QGridLayout::addWidget(QWidget *widget, int fromRow, int fromColumn,
01213 int rowSpan, int columnSpan, Qt::Alignment alignment)
01214 {
01215 Q_D(QGridLayout);
01216 if (!checkWidget(this, widget))
01217 return;
01218 int toRow = (rowSpan < 0) ? -1 : fromRow + rowSpan - 1;
01219 int toColumn = (columnSpan < 0) ? -1 : fromColumn + columnSpan - 1;
01220 addChildWidget(widget);
01221 QGridBox *b = new QGridBox(widget);
01222 b->setAlignment(alignment);
01223 d->add(b, fromRow, toRow, fromColumn, toColumn);
01224 invalidate();
01225 }
01226
01248 void QGridLayout::addLayout(QLayout *layout, int row, int column, Qt::Alignment alignment)
01249 {
01250 Q_D(QGridLayout);
01251 addChildLayout(layout);
01252 QGridBox *b = new QGridBox(layout);
01253 b->setAlignment(alignment);
01254 d->add(b, row, column);
01255 }
01256
01266 void QGridLayout::addLayout(QLayout *layout, int row, int column,
01267 int rowSpan, int columnSpan, Qt::Alignment alignment)
01268 {
01269 Q_D(QGridLayout);
01270 addChildLayout(layout);
01271 QGridBox *b = new QGridBox(layout);
01272 b->setAlignment(alignment);
01273 d->add(b, row, (rowSpan < 0) ? -1 : row + rowSpan - 1, column, (columnSpan < 0) ? -1 : column + columnSpan - 1);
01274 }
01275
01289 void QGridLayout::setRowStretch(int row, int stretch)
01290 {
01291 Q_D(QGridLayout);
01292 d->setRowStretch(row, stretch);
01293 invalidate();
01294 }
01295
01301 int QGridLayout::rowStretch(int row) const
01302 {
01303 Q_D(const QGridLayout);
01304 return d->rowStretch(row);
01305 }
01306
01312 int QGridLayout::columnStretch(int column) const
01313 {
01314 Q_D(const QGridLayout);
01315 return d->colStretch(column);
01316 }
01317
01335 void QGridLayout::setColumnStretch(int column, int stretch)
01336 {
01337 Q_D(QGridLayout);
01338 d->setColStretch(column, stretch);
01339 invalidate();
01340 }
01341
01342
01343
01349 void QGridLayout::setRowMinimumHeight(int row, int minSize)
01350 {
01351 Q_D(QGridLayout);
01352 d->setRowSpacing(row, minSize);
01353 invalidate();
01354 }
01355
01361 int QGridLayout::rowMinimumHeight(int row) const
01362 {
01363 Q_D(const QGridLayout);
01364 return d->rowSpacing(row);
01365 }
01366
01372 void QGridLayout::setColumnMinimumWidth(int column, int minSize)
01373 {
01374 Q_D(QGridLayout);
01375 d->setColSpacing(column, minSize);
01376 invalidate();
01377 }
01378
01384 int QGridLayout::columnMinimumWidth(int column) const
01385 {
01386 Q_D(const QGridLayout);
01387 return d->colSpacing(column);
01388 }
01389
01393 Qt::Orientations QGridLayout::expandingDirections() const
01394 {
01395 Q_D(const QGridLayout);
01396 return d->expandingDirections(spacing());
01397 }
01398
01402 void QGridLayout::setOriginCorner(Qt::Corner corner)
01403 {
01404 Q_D(QGridLayout);
01405 d->setReversed(corner == Qt::BottomLeftCorner || corner == Qt::BottomRightCorner,
01406 corner == Qt::TopRightCorner || corner == Qt::BottomRightCorner);
01407 }
01408
01413 Qt::Corner QGridLayout::originCorner() const
01414 {
01415 Q_D(const QGridLayout);
01416 if (d->horReversed()) {
01417 return d->verReversed() ? Qt::BottomRightCorner : Qt::TopRightCorner;
01418 } else {
01419 return d->verReversed() ? Qt::BottomLeftCorner : Qt::TopLeftCorner;
01420 }
01421 }
01422
01426 void QGridLayout::invalidate()
01427 {
01428 Q_D(QGridLayout);
01429 d->setDirty();
01430 QLayout::invalidate();
01431 }
01432