kspread

region.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2005-2006 Stefan Nikolaus <stefan.nikolaus@kdemail.net>
00003 
00004    This program is free software; you can redistribute it and/or modify
00005    it under the terms of the GNU General Public License as published by
00006    the Free Software Foundation; either version 2 of the License, or
00007    (at your option) any later version.
00008 
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012    GNU General Public License for more details.
00013 
00014    You should have received a copy of the GNU General Public License
00015    along with this program; if not, write to the Free Software
00016    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
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   class Region
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       // range
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 // lr.isValid()
00098       {
00099         Point* point = createPoint(sRegion.right(delimiterPos + 1));
00100         point->setSheet(sheet);
00101         d->cells.append(point);
00102       }
00103     }
00104     else
00105     {
00106       // single cell
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 //   kdDebug() << k_funcinfo << endl;
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   // TODO Stefan: Improve!
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   // TODO Stefan: Improve!
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     // top range
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     // left range
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     // right range
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     // bottom range
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 //   bool adjacentPoint = false;
00408 //   QRect neighbour;
00409 
00410   // we don't have to check for occurences?
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 /*    else
00432     {
00433       neighbour = element->rect().normalize();
00434       neighbour.setTopLeft(neighbour.topLeft() - QPoint(1,1));
00435       neighbour.setBottomRight(neighbour.bottomRight() + QPoint(1,1));
00436       if (neighbour.contains(point))
00437       {
00438         adjacentPoint = true; // TODO Stefan: Implement!
00439         break;
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     // remove the '!'
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   class Element
00745 ****************************************************************************/
00746 
00747 Region::Element::Element()
00748     : m_sheet(0)
00749 {
00750 }
00751 
00752 Region::Element::~Element()
00753 {
00754 }
00755 
00756 
00757 /***************************************************************************
00758   class Point
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;//Region::filterSheetName(sCell);
00780 
00781     uint p = 0;
00782 
00783     // Fixed ?
00784     if (string[0] == '$')
00785     {
00786         p++;
00787     }
00788 
00789     // Malformed ?
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     //default is error
00805     int x = -1;
00806     //search for the first character != text
00807     int result = string.find( QRegExp("[^A-Za-z]+"), p );
00808 
00809     //get the colomn number for the character between actual position and the first non text charakter
00810     if ( result != -1 )
00811     {
00812         x = util_decodeColumnLabelText( string.mid( p, result - p ) ); // x is defined now
00813     }
00814     else  // If there isn't any, then this is not a point -> return
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     //limit is KS_colMax
00822     if ( x > KS_colMax )
00823     {
00824       kdDebug(36001) << "Region::Point::init: column value too high (col: " << x << ")" << endl;
00825         return;
00826     }
00827 
00828     // Malformed ?
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   // Malformed ?
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   class Range
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     //Region::filterSheetName(sRange);
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 } // namespace KSpread
KDE Home | KDE Accessibility Home | Description of Access Keys