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