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