00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qregexp.h>
00022
00023 #include <kdebug.h>
00024
00025 #include "kspread_canvas.h"
00026 #include "kspread_cell.h"
00027 #include "kspread_doc.h"
00028 #include "kspread_editors.h"
00029 #include "kspread_sheet.h"
00030 #include "kspread_view.h"
00031 #include "kspread_util.h"
00032
00033 #include "selection.h"
00034
00035
00036
00037
00038 using namespace KSpread;
00039
00040
00041
00042
00043
00044 class Selection::Private
00045 {
00046 public:
00047 Private(View *v)
00048 {
00049 view = v;
00050 sheet = 0;
00051 anchor = QPoint(1,1);
00052 cursor = QPoint(1,1);
00053 marker = QPoint(1,1);
00054
00055 colors.push_back(Qt::red);
00056 colors.push_back(Qt::blue);
00057 colors.push_back(Qt::magenta);
00058 colors.push_back(Qt::darkRed);
00059 colors.push_back(Qt::darkGreen);
00060 colors.push_back(Qt::darkMagenta);
00061 colors.push_back(Qt::darkCyan);
00062 colors.push_back(Qt::darkYellow);
00063
00064 multipleSelection = false;
00065
00066 activeElement = Iterator();
00067 activeSubRegionStart = 0;
00068 activeSubRegionLength = 0;
00069 }
00070
00071 View* view;
00072 Sheet* sheet;
00073 QPoint anchor;
00074 QPoint cursor;
00075 QPoint marker;
00076 QValueList<QColor> colors;
00077
00078 bool multipleSelection : 1;
00079
00080 Selection::Iterator activeElement;
00081 uint activeSubRegionStart;
00082 uint activeSubRegionLength;
00083 };
00084
00085
00086
00087
00088 namespace KSpread {
00089
00090 Selection::Selection(View *view)
00091 : QObject(view), Region(1,1)
00092 {
00093 d = new Private(view);
00094 d->activeSubRegionStart = 0;
00095 d->activeSubRegionLength = 1;
00096 }
00097
00098 Selection::Selection(const Selection& selection)
00099 : QObject(selection.d->view), Region()
00100 {
00101
00102 d = new Private(selection.d->view);
00103 d->sheet = selection.d->sheet;
00104 d->activeSubRegionStart = 0;
00105 d->activeSubRegionLength = cells().count();
00106 }
00107
00108 Selection::~Selection()
00109 {
00110 delete d;
00111 }
00112
00113 void Selection::initialize(const QPoint& point, Sheet* sheet)
00114 {
00115 if (!util_isPointValid(point))
00116 return;
00117
00118 if (!d->view->activeSheet())
00119 return;
00120
00121 if (!sheet)
00122 {
00123 if (d->sheet)
00124 {
00125 sheet = d->sheet;
00126 }
00127 else
00128 {
00129 sheet = d->view->activeSheet();
00130 }
00131 }
00132
00133 Region changedRegion(*this);
00134 changedRegion.add(extendToMergedAreas(QRect(d->anchor,d->marker)));
00135
00136 QPoint topLeft(point);
00137 Cell* cell = d->view->activeSheet()->cellAt(point);
00138 if (cell->isObscured() && cell->isPartOfMerged())
00139 {
00140 cell = cell->obscuringCells().first();
00141 topLeft = QPoint(cell->column(), cell->row());
00142 }
00143
00144 d->anchor = topLeft;
00145 d->cursor = point;
00146 d->marker = topLeft;
00147
00148 fixSubRegionDimension();
00149 Iterator it = cells().begin() += d->activeSubRegionStart + d->activeSubRegionLength;
00150 if (it != insert(it, topLeft, sheet))
00151 {
00152
00153 clearSubRegion();
00154 }
00155 Element* element = *(cells().begin() += d->activeSubRegionStart);
00156
00157 d->activeSubRegionLength = 1;
00158 if (element && element->type() == Element::Point)
00159 {
00160 Point* point = static_cast<Point*>(element);
00161 point->setColor(d->colors[cells().size() % d->colors.size()]);
00162 }
00163 else if (element && element->type() == Element::Range)
00164 {
00165 Range* range = static_cast<Range*>(element);
00166 range->setColor(d->colors[cells().size() % d->colors.size()]);
00167 }
00168
00169 d->activeElement = cells().begin();
00170
00171 if (changedRegion == *this)
00172 {
00173 emit changed(Region(topLeft, sheet));
00174 return;
00175 }
00176 changedRegion.add(topLeft, sheet);
00177
00178 emit changed(changedRegion);
00179 }
00180
00181 void Selection::initialize(const QRect& range, Sheet* sheet)
00182 {
00183 if (!util_isRectValid(range) || ( range == QRect(0,0,1,1) ))
00184 return;
00185
00186 if (!sheet)
00187 {
00188 if (d->sheet)
00189 {
00190 sheet = d->sheet;
00191 }
00192 else
00193 {
00194 sheet = d->view->activeSheet();
00195 }
00196 }
00197
00198 Region changedRegion(*this);
00199 changedRegion.add(extendToMergedAreas(QRect(d->anchor,d->marker)));
00200
00201 QPoint topLeft(range.topLeft());
00202 Cell* cell = d->view->activeSheet()->cellAt(topLeft);
00203 if (cell->isObscured() && cell->isPartOfMerged())
00204 {
00205 cell = cell->obscuringCells().first();
00206 topLeft = QPoint(cell->column(), cell->row());
00207 }
00208
00209 QPoint bottomRight(range.bottomRight());
00210 cell = d->view->activeSheet()->cellAt(bottomRight);
00211 if (cell->isObscured() && cell->isPartOfMerged())
00212 {
00213 cell = cell->obscuringCells().first();
00214 bottomRight = QPoint(cell->column(), cell->row());
00215 }
00216
00217 d->anchor = topLeft;
00218 d->cursor = bottomRight;
00219 d->marker = bottomRight;
00220
00221 fixSubRegionDimension();
00222 Iterator it = cells().begin() += d->activeSubRegionStart + d->activeSubRegionLength;
00223 if (it != insert(it, QRect(topLeft, bottomRight), sheet))
00224 {
00225
00226 clearSubRegion();
00227 }
00228
00229 Element* element = *(cells().begin() += d->activeSubRegionStart);
00230
00231 d->activeSubRegionLength = 1;
00232 if (element && element->type() == Element::Point)
00233 {
00234 Point* point = static_cast<Point*>(element);
00235 point->setColor(d->colors[cells().size() % d->colors.size()]);
00236 }
00237 else if (element && element->type() == Element::Range)
00238 {
00239 Range* range = static_cast<Range*>(element);
00240 range->setColor(d->colors[cells().size() % d->colors.size()]);
00241 }
00242
00243 d->activeElement = cells().begin();
00244
00245 if (changedRegion == *this)
00246 {
00247 return;
00248 }
00249 changedRegion.add(QRect(topLeft, bottomRight), sheet);
00250
00251 emit changed(changedRegion);
00252 }
00253
00254 void Selection::initialize(const Region& region, Sheet* sheet)
00255 {
00256 if (!region.isValid())
00257 return;
00258
00259 if (!sheet)
00260 {
00261 if (d->sheet)
00262 {
00263 sheet = d->sheet;
00264 }
00265 else
00266 {
00267 sheet = d->view->activeSheet();
00268 }
00269 }
00270
00271 Region changedRegion(*this);
00272 changedRegion.add(extendToMergedAreas(QRect(d->anchor,d->marker)));
00273
00274
00275
00276 clear();
00277 Element* element = add(region);
00278 if (element && element->type() == Element::Point)
00279 {
00280 Point* point = static_cast<Point*>(element);
00281 point->setColor(d->colors[cells().size() % d->colors.size()]);
00282 }
00283 else if (element && element->type() == Element::Range)
00284 {
00285 Range* range = static_cast<Range*>(element);
00286 range->setColor(d->colors[cells().size() % d->colors.size()]);
00287 }
00288
00289 QPoint topLeft(cells().last()->rect().normalize().topLeft());
00290 Cell* cell = d->view->activeSheet()->cellAt(topLeft);
00291 if (cell->isObscured() && cell->isPartOfMerged())
00292 {
00293 cell = cell->obscuringCells().first();
00294 topLeft = QPoint(cell->column(), cell->row());
00295 }
00296
00297 QPoint bottomRight(cells().last()->rect().normalize().bottomRight());
00298 cell = d->view->activeSheet()->cellAt(bottomRight);
00299 if (cell->isObscured() && cell->isPartOfMerged())
00300 {
00301 cell = cell->obscuringCells().first();
00302 bottomRight = QPoint(cell->column(), cell->row());
00303 }
00304
00305 d->anchor = topLeft;
00306 d->cursor = topLeft;
00307 d->marker = bottomRight;
00308
00309 d->activeElement = --cells().end();
00310
00311 if (changedRegion == *this)
00312 {
00313 return;
00314 }
00315
00316 emit changed(changedRegion);
00317 }
00318
00319 void Selection::update()
00320 {
00321 emit changed(*this);
00322 }
00323
00324 void Selection::update(const QPoint& point)
00325 {
00326 uint count = cells().count();
00327
00328 if (cells().isEmpty())
00329 {
00330 add(point);
00331 d->activeSubRegionLength += cells().count() - count;
00332 return;
00333 }
00334 if (d->activeElement == cells().end())
00335 {
00336
00337 d->activeElement--;
00338 }
00339
00340 Sheet* sheet = (*d->activeElement)->sheet();
00341 if (sheet != d->view->activeSheet())
00342 {
00343 extend(point);
00344 d->activeSubRegionLength += cells().count() - count;
00345 return;
00346 }
00347
00348 QPoint topLeft(point);
00349 Cell* cell = d->view->activeSheet()->cellAt(point);
00350 if (cell->isObscured() && cell->isPartOfMerged())
00351 {
00352 cell = cell->obscuringCells().first();
00353 topLeft = QPoint(cell->column(), cell->row());
00354 }
00355
00356 if (topLeft == d->marker)
00357 {
00358 return;
00359 }
00360
00361 QRect area1 = (*d->activeElement)->rect().normalize();
00362 QRect newRange = extendToMergedAreas(QRect(d->anchor, topLeft));
00363
00364 Element* oldElement = *d->activeElement;
00365
00366 Iterator it = cells().remove(d->activeElement);
00367 delete oldElement;
00368
00369 d->activeElement = insert(it, newRange, sheet, d->multipleSelection);
00370 d->activeSubRegionLength += cells().count() - count;
00371
00372
00373
00374
00375
00376 if (d->activeElement == cells().end())
00377 {
00378 d->activeElement--;
00379 }
00380
00381 QRect area2 = (*d->activeElement)->rect().normalize();
00382 Region changedRegion;
00383
00384 bool newLeft = area1.left() != area2.left();
00385 bool newTop = area1.top() != area2.top();
00386 bool newRight = area1.right() != area2.right();
00387 bool newBottom = area1.bottom() != area2.bottom();
00388
00389
00390 int farLeft = QMIN(area1.left(), area2.left());
00391 int innerLeft = QMAX(area1.left(), area2.left());
00392
00393 int farTop = QMIN(area1.top(), area2.top());
00394 int innerTop = QMAX(area1.top(), area2.top());
00395
00396 int farRight = QMAX(area1.right(), area2.right());
00397 int innerRight = QMIN(area1.right(), area2.right());
00398
00399 int farBottom = QMAX(area1.bottom(), area2.bottom());
00400 int innerBottom = QMIN(area1.bottom(), area2.bottom());
00401
00402 if (newLeft)
00403 {
00404 changedRegion.add(QRect(QPoint(farLeft, innerTop),
00405 QPoint(innerLeft-1, innerBottom)));
00406 if (newTop)
00407 {
00408 changedRegion.add(QRect(QPoint(farLeft, farTop),
00409 QPoint(innerLeft-1, innerTop-1)));
00410 }
00411 if (newBottom)
00412 {
00413 changedRegion.add(QRect(QPoint(farLeft, innerBottom+1),
00414 QPoint(innerLeft-1, farBottom)));
00415 }
00416 }
00417
00418 if (newTop)
00419 {
00420 changedRegion.add(QRect(QPoint(innerLeft, farTop),
00421 QPoint(innerRight, innerTop-1)));
00422 }
00423
00424 if (newRight)
00425 {
00426 changedRegion.add(QRect(QPoint(innerRight+1, innerTop),
00427 QPoint(farRight, innerBottom)));
00428 if (newTop)
00429 {
00430 changedRegion.add(QRect(QPoint(innerRight+1, farTop),
00431 QPoint(farRight, innerTop-1)));
00432 }
00433 if (newBottom)
00434 {
00435 changedRegion.add(QRect(QPoint(innerRight+1, innerBottom+1),
00436 QPoint(farRight, farBottom)));
00437 }
00438 }
00439
00440 if (newBottom)
00441 {
00442 changedRegion.add(QRect(QPoint(innerLeft, innerBottom+1),
00443 QPoint(innerRight, farBottom)));
00444 }
00445
00446 d->marker = topLeft;
00447 d->cursor = point;
00448
00449 emit changed(changedRegion);
00450 }
00451
00452 void Selection::extend(const QPoint& point, Sheet* sheet)
00453 {
00454 if (!util_isPointValid(point))
00455 return;
00456
00457 if (isEmpty())
00458 {
00459 initialize(point, sheet);
00460 return;
00461 }
00462 if (d->activeElement == cells().end())
00463 {
00464
00465 d->activeElement--;
00466 }
00467
00468 if (!sheet)
00469 {
00470 if (d->sheet)
00471 {
00472 sheet = d->sheet;
00473 }
00474 else
00475 {
00476 sheet = d->view->activeSheet();
00477 }
00478 }
00479
00480 Region changedRegion = Region(extendToMergedAreas(QRect(d->marker,d->marker)));
00481
00482 QPoint topLeft(point);
00483 Cell* cell = d->view->activeSheet()->cellAt(point);
00484 if (cell->isObscured() && cell->isPartOfMerged())
00485 {
00486 cell = cell->obscuringCells().first();
00487 topLeft = QPoint(cell->column(), cell->row());
00488 }
00489
00490 uint count = cells().count();
00491 if (d->multipleSelection)
00492 {
00493 d->activeElement = insert(++d->activeElement, point, sheet, false);
00494 }
00495 else
00496 {
00497 eor(topLeft, sheet);
00498 d->activeElement = --cells().end();
00499 }
00500 d->anchor = (*d->activeElement)->rect().topLeft();
00501 d->cursor = (*d->activeElement)->rect().bottomRight();
00502 d->marker = d->cursor;
00503
00504 d->activeSubRegionLength += cells().count() - count;
00505
00506 changedRegion.add(topLeft, sheet);
00507 changedRegion.add(*this);
00508
00509 emit changed(changedRegion);
00510 }
00511
00512 void Selection::extend(const QRect& range, Sheet* sheet)
00513 {
00514
00515 if (!util_isRectValid(range) || (range == QRect(0,0,1,1)))
00516 return;
00517
00518 if (isEmpty())
00519 {
00520 initialize(range, sheet);
00521 return;
00522 }
00523 if (d->activeElement == cells().end())
00524 {
00525
00526 d->activeElement--;
00527 }
00528
00529 if (!sheet)
00530 {
00531 if (d->sheet)
00532 {
00533 sheet = d->sheet;
00534 }
00535 else
00536 {
00537 sheet = d->view->activeSheet();
00538 }
00539 }
00540
00541 QPoint topLeft(range.topLeft());
00542 Cell* cell = d->view->activeSheet()->cellAt(topLeft);
00543 if (cell->isObscured() && cell->isPartOfMerged())
00544 {
00545 cell = cell->obscuringCells().first();
00546 topLeft = QPoint(cell->column(), cell->row());
00547 }
00548
00549 QPoint bottomRight(range.bottomRight());
00550 cell = d->view->activeSheet()->cellAt(bottomRight);
00551 if (cell->isObscured() && cell->isPartOfMerged())
00552 {
00553 cell = cell->obscuringCells().first();
00554 bottomRight = QPoint(cell->column(), cell->row());
00555 }
00556
00557 d->anchor = topLeft;
00558 d->cursor = topLeft;
00559 d->marker = bottomRight;
00560
00561 uint count = cells().count();
00562 Element* element;
00563 if (d->multipleSelection)
00564 {
00565 d->activeElement = insert(++d->activeElement, extendToMergedAreas(QRect(topLeft, bottomRight)).normalize(), sheet, false);
00566 element = *d->activeElement;
00567 }
00568 else
00569 {
00570 element = add(extendToMergedAreas(QRect(topLeft, bottomRight)).normalize(), sheet);
00571 d->activeElement = --cells().end();
00572 }
00573 if (element && element->type() == Element::Point)
00574 {
00575 Point* point = static_cast<Point*>(element);
00576 point->setColor(d->colors[cells().size() % d->colors.size()]);
00577 }
00578 else if (element && element->type() == Element::Range)
00579 {
00580 Range* range = static_cast<Range*>(element);
00581 range->setColor(d->colors[cells().size() % d->colors.size()]);
00582 }
00583
00584 d->activeSubRegionLength += cells().count() - count;
00585
00586 emit changed(*this);
00587 }
00588
00589 void Selection::extend(const Region& region)
00590 {
00591 if (!region.isValid())
00592 return;
00593
00594 uint count = cells().count();
00595 ConstIterator end(region.constEnd());
00596 for (ConstIterator it = region.constBegin(); it != end; ++it)
00597 {
00598 Element *element = *it;
00599 if (element && element->type() == Element::Point)
00600 {
00601 Point* point = static_cast<Point*>(element);
00602 extend(point->pos(), element->sheet());
00603 }
00604 else
00605 {
00606 extend(element->rect(), element->sheet());
00607 }
00608 }
00609
00610 d->activeSubRegionLength += cells().count() - count;
00611
00612 emit changed(*this);
00613 }
00614
00615 Selection::Element* Selection::eor(const QPoint& point, Sheet* sheet)
00616 {
00617 if (isSingular())
00618 {
00619 return Region::add(point, sheet);
00620 }
00621 return Region::eor(point, sheet);
00622 }
00623
00624 const QPoint& Selection::anchor() const
00625 {
00626 return d->anchor;
00627 }
00628
00629 const QPoint& Selection::cursor() const
00630 {
00631 return d->cursor;
00632 }
00633
00634 const QPoint& Selection::marker() const
00635 {
00636 return d->marker;
00637 }
00638
00639 bool Selection::isSingular() const
00640 {
00641 return Region::isSingular();
00642 }
00643
00644 QRect Selection::selectionHandleArea() const
00645 {
00646 int column, row;
00647
00648
00649 if (isColumnOrRowSelected())
00650 {
00651 column = d->marker.x();
00652 row = d->marker.y();
00653 }
00654 else
00655 {
00656 column = lastRange().right();
00657 row = lastRange().bottom();
00658 }
00659 const Cell* cell = d->view->activeSheet()->cellAt(column, row);
00660
00661 double xpos = d->view->activeSheet()->dblColumnPos( column );
00662 double ypos = d->view->activeSheet()->dblRowPos( row );
00663 double width = cell->dblWidth( column );
00664 double height = cell->dblHeight( row );
00665
00666 QPoint rightBottom( d->view->doc()->zoomItX( xpos + width ),
00667 d->view->doc()->zoomItY( ypos + height ) );
00668
00669 QRect handle( ( rightBottom.x() - 2 ),
00670 ( rightBottom.y() - 2 ),
00671 ( 5 ),
00672 ( 5 ) );
00673 return handle;
00674 }
00675
00676 QString Selection::name(Sheet* sheet) const
00677 {
00678 return Region::name(sheet ? sheet : d->sheet);
00679 }
00680
00681 void Selection::setSheet(Sheet* sheet)
00682 {
00683 d->sheet = sheet;
00684 }
00685
00686 Sheet* Selection::sheet() const
00687 {
00688 return d->sheet;
00689 }
00690
00691 void Selection::setActiveElement(const QPoint& point)
00692 {
00693 uint counter = 0;
00694 Iterator end = cells().end();
00695 for (Iterator it = cells().begin(); it != end; ++it)
00696 {
00697 QRect range = (*it)->rect();
00698 if (range.topLeft() == point || range.bottomRight() == point)
00699 {
00700 d->anchor = range.topLeft();
00701 d->cursor = range.bottomRight();
00702 d->marker = range.bottomRight();
00703 d->activeElement = it;
00704 d->activeSubRegionStart = counter;
00705 d->activeSubRegionLength = 1;
00706 if (d->view->canvasWidget()->editor())
00707 {
00708 d->view->canvasWidget()->editor()->setCursorToRange(counter);
00709 }
00710 }
00711 counter++;
00712 }
00713 }
00714
00715 void Selection::setActiveElement(uint pos)
00716 {
00717 if (pos >= cells().count())
00718 {
00719 kdDebug() << "Selection::setActiveElement: position exceeds list" << endl;
00720 d->activeElement = cells().begin();
00721 return;
00722 }
00723
00724 Iterator it = cells().begin() += pos;
00725 QRect range = (*it)->rect();
00726 d->anchor = range.topLeft();
00727 d->cursor = range.bottomRight();
00728 d->marker = range.bottomRight();
00729 d->activeElement = it;
00730 }
00731
00732 Region::Element* Selection::activeElement() const
00733 {
00734 return (d->activeElement == cells().end()) ? 0 : *d->activeElement;
00735 }
00736
00737 void Selection::clear()
00738 {
00739 d->activeSubRegionStart = 0;
00740 d->activeSubRegionLength = 0;
00741 Region::clear();
00742 d->activeElement = cells().begin();
00743 }
00744
00745 void Selection::clearSubRegion()
00746 {
00747 if (isEmpty())
00748 {
00749 return;
00750 }
00751
00752
00753
00754
00755 Iterator it = cells().begin();
00756 Iterator end = it += d->activeSubRegionStart;
00757 end += d->activeSubRegionLength;
00758 while (it != end)
00759 {
00760
00761 delete *it;
00762 it = cells().remove(it);
00763 }
00764 d->activeSubRegionLength = 0;
00765 d->activeElement = it;
00766
00767 }
00768
00769 void Selection::fixSubRegionDimension()
00770 {
00771 if (d->activeSubRegionStart > cells().count())
00772 {
00773 kdDebug() << "Selection::fixSubRegionDimension: start position exceeds list" << endl;
00774 d->activeSubRegionStart = 0;
00775 d->activeSubRegionLength = cells().count();
00776 return;
00777 }
00778 if (d->activeSubRegionStart + d->activeSubRegionLength > cells().count())
00779 {
00780 kdDebug() << "Selection::fixSubRegionDimension: length exceeds list" << endl;
00781 d->activeSubRegionLength = cells().count() - d->activeSubRegionStart;
00782 return;
00783 }
00784 }
00785
00786 void Selection::setActiveSubRegion(uint start, uint length)
00787 {
00788
00789 d->activeSubRegionStart = start;
00790 d->activeSubRegionLength = length;
00791 fixSubRegionDimension();
00792 d->activeElement = cells().begin() += d->activeSubRegionStart;
00793 }
00794
00795 QString Selection::activeSubRegionName() const
00796 {
00797
00798
00799
00800
00801 QStringList names;
00802 Iterator it = cells().begin();
00803 it += d->activeSubRegionStart;
00804 Iterator end = it;
00805 end += d->activeSubRegionLength;
00806 while (it != end)
00807 {
00808 names += (*it++)->name(d->sheet);
00809 }
00810
00811 return names.isEmpty() ? "" : names.join(";");
00812 }
00813
00814 void Selection::setMultipleSelection(bool state)
00815 {
00816 d->multipleSelection = state;
00817 }
00818
00819 const QValueList<QColor>& Selection::colors() const
00820 {
00821 return d->colors;
00822 }
00823
00824 QRect Selection::lastRange(bool extend) const
00825 {
00826 QRect selection = QRect(d->anchor, d->marker).normalize();
00827 return extend ? extendToMergedAreas(selection) : selection;
00828 }
00829
00830 QRect Selection::selection(bool extend) const
00831 {
00832 QRect selection = QRect(d->anchor, d->marker).normalize();
00833 return extend ? extendToMergedAreas(selection) : selection;
00834 }
00835
00836 QRect Selection::extendToMergedAreas(QRect area) const
00837 {
00838 if (!d->view->activeSheet())
00839 return area;
00840
00841 area = area.normalize();
00842 const Cell *cell = d->view->activeSheet()->cellAt(area.left(), area.top());
00843
00844 if( Region::Range(area).isColumn() || Region::Range(area).isRow() )
00845 {
00846 return area;
00847 }
00848 else if ( !(cell->isObscured() && cell->isPartOfMerged()) &&
00849 (cell->mergedXCells() + 1) >= area.width() &&
00850 (cell->mergedYCells() + 1) >= area.height())
00851 {
00852
00853
00854
00855
00856
00857 area.setWidth(cell->mergedXCells() + 1);
00858 area.setHeight(cell->mergedYCells() + 1);
00859 }
00860 else
00861 {
00862 int top=area.top();
00863 int left=area.left();
00864 int bottom=area.bottom();
00865 int right=area.right();
00866 for ( int x = area.left(); x <= area.right(); x++ )
00867 for ( int y = area.top(); y <= area.bottom(); y++ )
00868 {
00869 cell = d->view->activeSheet()->cellAt( x, y );
00870 if( cell->doesMergeCells())
00871 {
00872 right=QMAX(right,cell->mergedXCells()+x);
00873 bottom=QMAX(bottom,cell->mergedYCells()+y);
00874 }
00875 else if ( cell->isObscured() && cell->isPartOfMerged() )
00876 {
00877 cell = cell->obscuringCells().first();
00878 left=QMIN(left,cell->column());
00879 top=QMIN(top,cell->row());
00880 bottom=QMAX(bottom,cell->row() + cell->mergedYCells());
00881 right=QMAX(right,cell->column() + cell->mergedXCells());
00882 }
00883 }
00884
00885 area.setCoords(left,top,right,bottom);
00886 }
00887 return area;
00888 }
00889
00890 Selection::Region::Point* Selection::createPoint(const QPoint& point) const
00891 {
00892 return new Point(point);
00893 }
00894
00895 Selection::Region::Point* Selection::createPoint(const QString& string) const
00896 {
00897 return new Point(string);
00898 }
00899
00900 Selection::Region::Point* Selection::createPoint(const Point& point) const
00901 {
00902 return new Point(point);
00903 }
00904
00905 Selection::Region::Range* Selection::createRange(const QRect& rect) const
00906 {
00907 return new Range(rect);
00908 }
00909
00910 Selection::Region::Range* Selection::createRange(const QString& string) const
00911 {
00912 return new Range(string);
00913 }
00914
00915 Selection::Region::Range* Selection::createRange(const Range& range) const
00916 {
00917 return new Range(range);
00918 }
00919
00920
00921
00922
00923
00924 Selection::Point::Point(const QPoint& point)
00925 : Region::Point(point),
00926 m_color(Qt::black),
00927 m_columnFixed(false),
00928 m_rowFixed(false)
00929 {
00930 }
00931
00932 Selection::Point::Point(const QString& string)
00933 : Region::Point(string),
00934 m_color(Qt::black),
00935 m_columnFixed(false),
00936 m_rowFixed(false)
00937 {
00938 if (!isValid())
00939 {
00940 return;
00941 }
00942
00943 uint p = 0;
00944
00945 if (string[p++] == '$')
00946 {
00947 m_columnFixed = true;
00948 }
00949
00950
00951 int result = string.find( QRegExp("[^A-Za-z]+"), p );
00952 if (string[result] == '$')
00953 {
00954 m_rowFixed = true;
00955 }
00956 }
00957
00958
00959
00960
00961
00962 Selection::Range::Range(const QRect& range)
00963 : Region::Range(range),
00964 m_color(Qt::black),
00965 m_leftFixed(false),
00966 m_rightFixed(false),
00967 m_topFixed(false),
00968 m_bottomFixed(false)
00969 {
00970 }
00971
00972 Selection::Range::Range(const QString& string)
00973 : Region::Range(string),
00974 m_color(Qt::black),
00975 m_leftFixed(false),
00976 m_rightFixed(false),
00977 m_topFixed(false),
00978 m_bottomFixed(false)
00979 {
00980 if (!isValid())
00981 {
00982 return;
00983 }
00984
00985 int delimiterPos = string.find(':');
00986 if (delimiterPos == -1)
00987 {
00988 return;
00989 }
00990
00991 Selection::Point ul(string.left(delimiterPos));
00992 Selection::Point lr(string.mid(delimiterPos + 1));
00993
00994 if (!ul.isValid() || !lr.isValid())
00995 {
00996 return;
00997 }
00998 m_leftFixed = ul.columnFixed();
00999 m_rightFixed = lr.columnFixed();
01000 m_topFixed = ul.rowFixed();
01001 m_bottomFixed = lr.rowFixed();
01002 }
01003
01004 }
01005 #include "selection.moc"