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     QString sRegion = *it;
00073     if (!sheet)
00074     {
00075       sheet = filterSheetName(sRegion);
00076     }
00077 
00078     int delimiterPos = sRegion.find(':');
00079     if (delimiterPos > -1)
00080     {
00081       // range
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       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 //   kdDebug() << k_funcinfo << endl;
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   // TODO Stefan: Improve!
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   // TODO Stefan: Improve!
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     // top range
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     // left range
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     // right range
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     // bottom range
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 //   bool adjacentPoint = false;
00405 //   QRect neighbour;
00406 
00407   // we don't have to check for occurences?
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 /*    else
00429     {
00430       neighbour = element->rect().normalize();
00431       neighbour.setTopLeft(neighbour.topLeft() - QPoint(1,1));
00432       neighbour.setBottomRight(neighbour.bottomRight() + QPoint(1,1));
00433       if (neighbour.contains(point))
00434       {
00435         adjacentPoint = true; // TODO Stefan: Implement!
00436         break;
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     // remove the '!'
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   class Element
00742 ****************************************************************************/
00743 
00744 Region::Element::Element()
00745     : m_sheet(0)
00746 {
00747 }
00748 
00749 Region::Element::~Element()
00750 {
00751 }
00752 
00753 
00754 /***************************************************************************
00755   class Point
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;//Region::filterSheetName(sCell);
00777 
00778     uint p = 0;
00779 
00780     // Fixed ?
00781     if (string[0] == '$')
00782     {
00783         p++;
00784     }
00785 
00786     // Malformed ?
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     //default is error
00802     int x = -1;
00803     //search for the first character != text
00804     int result = string.find( QRegExp("[^A-Za-z]+"), p );
00805 
00806     //get the colomn number for the character between actual position and the first non text charakter
00807     if ( result != -1 )
00808     {
00809         x = util_decodeColumnLabelText( string.mid( p, result - p ) ); // x is defined now
00810     }
00811     else  // If there isn't any, then this is not a point -> return
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     //limit is KS_colMax
00819     if ( x > KS_colMax )
00820     {
00821       kdDebug(36001) << "Region::Point::init: column value too high (col: " << x << ")" << endl;
00822         return;
00823     }
00824 
00825     // Malformed ?
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   // Malformed ?
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   class Range
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     //Region::filterSheetName(sRange);
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 } // namespace KSpread
KDE Home | KDE Accessibility Home | Description of Access Keys