summaryrefslogtreecommitdiffstats
path: root/kspread/region.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kspread/region.cpp')
-rw-r--r--kspread/region.cpp956
1 files changed, 956 insertions, 0 deletions
diff --git a/kspread/region.cpp b/kspread/region.cpp
new file mode 100644
index 00000000..92c408ef
--- /dev/null
+++ b/kspread/region.cpp
@@ -0,0 +1,956 @@
+/* This file is part of the KDE project
+ Copyright (C) 2005-2006 Stefan Nikolaus <[email protected]>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <tqregexp.h>
+#include <tqstringlist.h>
+
+#include <kdebug.h>
+
+#include "kspread_cell.h"
+#include "kspread_doc.h"
+#include "kspread_global.h"
+#include "kspread_map.h"
+#include "kspread_sheet.h"
+#include "kspread_util.h"
+#include "kspread_view.h"
+
+#include "region.h"
+
+namespace KSpread
+{
+
+class Region::Private
+{
+public:
+ Private()
+ {
+ view = 0;
+ }
+
+ View* view;
+ TQValueList<Element*> cells;
+};
+
+
+/***************************************************************************
+ class Region
+****************************************************************************/
+
+Region::Region()
+{
+ d = new Private();
+}
+
+Region::Region(View* view, const TQString& string, Sheet* sheet)
+{
+ d = new Private();
+ d->view = view;
+
+ if (string.isEmpty())
+ {
+ return;
+ }
+ TQStringList substrings = TQStringList::split(';', string);
+ TQStringList::ConstIterator end = substrings.constEnd();
+ for (TQStringList::ConstIterator it = substrings.constBegin(); it != end; ++it)
+ {
+ TQString sRegion = *it;
+ if (!sheet)
+ {
+ sheet = filterSheetName(sRegion);
+ }
+
+ int delimiterPos = sRegion.find(':');
+ if (delimiterPos > -1)
+ {
+ // range
+ Point ul(sRegion.left(delimiterPos));
+ Point lr(sRegion.mid(delimiterPos + 1));
+
+ if (ul.isValid() && lr.isValid())
+ {
+ Range* range = createRange(sRegion);
+ range->setSheet(sheet);
+ d->cells.append(range);
+ }
+ else if (ul.isValid())
+ {
+ Point* point = createPoint(sRegion.left(delimiterPos));
+ point->setSheet(sheet);
+ d->cells.append(point);
+ }
+ else // lr.isValid()
+ {
+ Point* point = createPoint(sRegion.right(delimiterPos + 1));
+ point->setSheet(sheet);
+ d->cells.append(point);
+ }
+ }
+ else
+ {
+ // single cell
+ Point* point = createPoint(sRegion);
+ point->setSheet(sheet);
+ d->cells.append(point);
+ }
+ }
+}
+
+Region::Region(const TQRect& rect, Sheet* sheet)
+{
+ d = new Private();
+
+ if (rect.isNull())
+ {
+ kdError(36001) << "Region::Region(const TQRect&): TQRect is empty!" << endl;
+ return;
+ }
+ add(rect, sheet);
+}
+
+Region::Region(const TQPoint& point, Sheet* sheet)
+{
+ d = new Private();
+
+ if (point.isNull())
+ {
+ kdError(36001) << "Region::Region(const TQPoint&): TQPoint is empty!" << endl;
+ return;
+ }
+ add(point, sheet);
+}
+
+Region::Region(const Region& list)
+{
+ d = new Private();
+ d->view = list.d->view;
+
+ ConstIterator end(list.d->cells.constEnd());
+ for (ConstIterator it = list.d->cells.constBegin(); it != end; ++it)
+ {
+ Element *element = *it;
+ if (element->type() == Element::Point)
+ {
+ Point* point = static_cast<Point*>(element);
+ d->cells.append(createPoint(*point));
+ }
+ else
+ {
+ Range* range = static_cast<Range*>(element);
+ d->cells.append(createRange(*range));
+ }
+ }
+}
+
+Region::Region(int x, int y, Sheet* sheet)
+{
+ d = new Private();
+
+ if (x<1 || y<1)
+ {
+ kdError(36001) << "Region::Region(int x, int y): Coordinates are invalid!" << endl;
+ return;
+ }
+ add(TQPoint(x,y), sheet);
+}
+
+Region::Region(int x, int y, int width, int height, Sheet* sheet)
+{
+ d = new Private();
+
+ if (x<1 || y<1 || width<1 || height<1)
+ {
+ kdError(36001) << "Region::Region(int x, int y, int width, int height): Dimensions are invalid!" << endl;
+ return;
+ }
+ add(TQRect(x,y,width,height), sheet);
+}
+
+
+Region::~Region()
+{
+ d->cells.clear();
+ delete d;
+}
+
+View* Region::view() const
+{
+ Q_ASSERT(d->view);
+ return d->view;
+}
+
+void Region::setView(View* view)
+{
+ d->view = view;
+}
+
+bool Region::isValid() const
+{
+ ConstIterator end = d->cells.constEnd();
+ for (ConstIterator it = d->cells.constBegin(); it != end; ++it)
+ {
+ if (!(*it)->isValid())
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool Region::isSingular() const
+{
+ if (d->cells.isEmpty() || d->cells.count() > 1 || (*d->cells.constBegin())->type() != Element::Point)
+ {
+ return false;
+ }
+ return true;
+}
+
+bool Region::isContiguous() const
+{
+ if (d->cells.count() != 1 || !isValid())
+ {
+ return false;
+ }
+ return true;
+}
+
+TQString Region::name(Sheet* originSheet) const
+{
+ TQStringList names;
+ ConstIterator endOfList(d->cells.constEnd());
+ for (ConstIterator it = d->cells.constBegin(); it != endOfList; ++it)
+ {
+ Element *element = *it;
+ names += element->name(originSheet);
+ }
+ return names.isEmpty() ? "" : names.join(";");
+}
+
+Region::Element* Region::add(const TQPoint& point, Sheet* sheet)
+{
+// kdDebug() << k_funcinfo << endl;
+ if (point.x() < 1 || point.y() < 1)
+ {
+ return 0;
+ }
+ Iterator it = insert(d->cells.end(), point, sheet, false);
+ return (it == d->cells.end()) ? 0 : *it;
+}
+
+Region::Element* Region::add(const TQRect& range, Sheet* sheet)
+{
+ if (range.normalize().width() == 0 || range.normalize().height() == 0)
+ {
+ return 0;
+ }
+ if (range.size() == TQSize(1,1))
+ {
+ return add(range.topLeft(), sheet);
+ }
+ Iterator it = insert(d->cells.end(), range, sheet, false);
+ return (it == d->cells.end()) ? 0 : *it;
+}
+
+Region::Element* Region::add(const Region& region)
+{
+ ConstIterator endOfList(region.d->cells.constEnd());
+ for (ConstIterator it = region.d->cells.constBegin(); it != endOfList; ++it)
+ {
+ add((*it)->rect(), (*it)->sheet());
+ }
+ return d->cells.isEmpty() ? 0 : d->cells.last();
+}
+
+void Region::sub(const TQPoint& point)
+{
+ // TODO Stefan: Improve!
+ Iterator endOfList(d->cells.end());
+ for (Iterator it = d->cells.begin(); it != endOfList; ++it)
+ {
+ Element *element = *it;
+ if (element->rect() == TQRect(point,point))
+ {
+ delete element;
+ d->cells.remove(element);
+ break;
+ }
+ }
+}
+
+void Region::sub(const TQRect& range)
+{
+ // TODO Stefan: Improve!
+ Iterator endOfList(d->cells.end());
+ for (Iterator it = d->cells.begin(); it != endOfList; ++it)
+ {
+ Element *element = *it;
+ if (element->rect().normalize() == range.normalize())
+ {
+ delete element;
+ d->cells.remove(element);
+ break;
+ }
+ }
+}
+
+void Region::sub(const Region& region)
+{
+ ConstIterator endOfList(region.constEnd());
+ for (ConstIterator it = region.constBegin(); it != endOfList; ++it)
+ {
+ Element *element = *it;
+ if (element->type() == Element::Point)
+ {
+ Point* point = static_cast<Point*>(element);
+ sub(point->pos());
+ }
+ else
+ {
+ sub(element->rect());
+ }
+ }
+}
+
+Region::Element* Region::eor(const TQPoint& point, Sheet* sheet)
+{
+ bool containsPoint = false;
+
+ Iterator it = cells().begin();
+ Iterator endOfList = cells().end();
+ while (it != endOfList)
+ {
+ if (!(*it)->contains(point))
+ {
+ ++it;
+ continue;
+ }
+ containsPoint = true;
+ int x = point.x();
+ int y = point.y();
+ TQRect fullRange = (*it)->rect().normalize();
+ delete *it;
+ it = cells().remove(it);
+
+ // top range
+ int left = fullRange.left();
+ int top = fullRange.top();
+ int width = fullRange.width();
+ int height = y - top;
+ if (height > 0)
+ {
+ insert(it, TQRect(left, top, width, height), sheet);
+ }
+ // left range
+ left = fullRange.left();
+ top = y;
+ width = TQMAX(0, x - left);
+ height = 1;
+ if (width > 0)
+ {
+ insert(it, TQRect(left, top, width, height), sheet);
+ }
+ // right range
+ left = TQMIN(x+1, fullRange.right());
+ top = y;
+ width = TQMAX(0, fullRange.right() - x);
+ height = 1;
+ if (width > 0)
+ {
+ insert(it, TQRect(left, top, width, height), sheet);
+ }
+ // bottom range
+ left = fullRange.left();
+ top = y+1;
+ width = fullRange.width();
+ height = TQMAX(0, fullRange.bottom() - y);
+ if (height > 0)
+ {
+ insert(it, TQRect(left, top, width, height), sheet);
+ }
+ return *it;
+ }
+
+ if (!containsPoint)
+ {
+ return add(point, sheet);
+ }
+ return 0;
+}
+
+Region::Iterator Region::insert(Region::Iterator pos, const TQPoint& point, Sheet* sheet, bool multi)
+{
+ if (point.x() < 1 || point.y() < 1)
+ {
+ return pos;
+ }
+
+ bool containsPoint = false;
+// bool adjacentPoint = false;
+// TQRect neighbour;
+
+ // we don't have to check for occurences?
+ if (multi)
+ {
+ Point* rpoint = createPoint(point);
+ rpoint->setSheet(sheet);
+ return d->cells.insert(pos, rpoint);
+ }
+
+ ConstIterator endOfList(d->cells.constEnd());
+ for (ConstIterator it = d->cells.constBegin(); it != endOfList; ++it)
+ {
+ Element *element = *it;
+ if (sheet && sheet != element->sheet())
+ {
+ continue;
+ }
+ if (element->contains(point))
+ {
+ containsPoint = true;
+ break;
+ }
+/* else
+ {
+ neighbour = element->rect().normalize();
+ neighbour.setTopLeft(neighbour.topLeft() - TQPoint(1,1));
+ neighbour.setBottomRight(neighbour.bottomRight() + TQPoint(1,1));
+ if (neighbour.contains(point))
+ {
+ adjacentPoint = true; // TODO Stefan: Implement!
+ break;
+ }
+ }*/
+ }
+ if ( !containsPoint )
+ {
+ Point* rpoint = createPoint(point);
+ rpoint->setSheet(sheet);
+ return d->cells.insert(pos, rpoint);
+ }
+ return pos;
+}
+
+Region::Iterator Region::insert(Region::Iterator pos, const TQRect& range, Sheet* sheet, bool multi)
+{
+ if (range.size() == TQSize(1,1))
+ {
+ return insert(pos, range.topLeft(), sheet);
+ }
+
+ if (multi)
+ {
+ Range* rrange = createRange(range);
+ rrange->setSheet(sheet);
+ return d->cells.insert(pos, rrange);
+ }
+
+ bool containsRange = false;
+
+ Iterator it( d->cells.begin() );
+ Iterator endOfList( d->cells.end() );
+ while ( it != endOfList )
+ {
+ if (sheet && sheet != (*it)->sheet())
+ {
+ ++it;
+ continue;
+ }
+ if ((*it)->contains(range))
+ {
+ containsRange = true;
+ }
+ else if (range.contains((*it)->rect()))
+ {
+ delete *it;
+ it = d->cells.remove(it);
+ continue;
+ }
+ ++it;
+ }
+ if ( !containsRange )
+ {
+ Range* rrange = createRange(range);
+ rrange->setSheet(sheet);
+ return d->cells.insert(pos, rrange);
+ }
+ return pos;
+}
+
+bool Region::isColumnAffected(uint col) const
+{
+ ConstIterator endOfList(d->cells.constEnd());
+ for (ConstIterator it = d->cells.constBegin(); it != endOfList; ++it)
+ {
+ Element *element = *it;
+ TQRect normalizedRegion = element->rect().normalize();
+ if ((int)col >= normalizedRegion.left() && (int)col <= normalizedRegion.right())
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Region::isRowAffected(uint row) const
+{
+ ConstIterator endOfList(d->cells.constEnd());
+ for (ConstIterator it = d->cells.constBegin(); it != endOfList; ++it)
+ {
+ Element *element = *it;
+ TQRect normalizedRegion = element->rect().normalize();
+ if ((int)row >= normalizedRegion.top() && (int)row <= normalizedRegion.bottom())
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Region::isColumnSelected(uint col) const
+{
+ ConstIterator endOfList(d->cells.constEnd());
+ for (ConstIterator it = d->cells.constBegin(); it != endOfList; ++it)
+ {
+ Element *element = *it;
+ TQRect region = element->rect().normalize();
+ if ((col == 0 || ((int)col >= region.left() && (int)col <= region.right())) &&
+ region.top() == 1 && region.bottom() == KS_rowMax)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Region::isRowSelected(uint row) const
+{
+ ConstIterator endOfList(d->cells.constEnd());
+ for (ConstIterator it = d->cells.constBegin(); it != endOfList; ++it)
+ {
+ Element *element = *it;
+ TQRect region = element->rect().normalize();
+ if ((row == 0 || ((int)row >= region.top() && (int)row <= region.bottom())) &&
+ region.left() == 1 && region.right() == KS_colMax)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Region::isColumnOrRowSelected() const
+{
+ ConstIterator endOfList(d->cells.constEnd());
+ for (ConstIterator it = d->cells.constBegin(); it != endOfList; ++it)
+ {
+ Element *element = *it;
+ TQRect region = element->rect().normalize();
+ if ((region.top() == 1 && region.bottom() == KS_rowMax) ||
+ (region.left() == 1 && region.right() == KS_colMax))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Region::contains(const TQPoint& point, Sheet* sheet) const
+{
+ if (d->cells.isEmpty())
+ {
+ return false;
+ }
+ ConstIterator endOfList(d->cells.constEnd());
+ for (ConstIterator it = d->cells.constBegin(); it != endOfList; ++it)
+ {
+ Element *element = *it;
+ if (element->contains(point))
+ {
+ if (sheet && element->sheet() != sheet)
+ {
+ return false;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Region::isEmpty() const
+{
+ return d->cells.isEmpty();
+}
+
+void Region::clear()
+{
+ Iterator end(d->cells.end());
+ for (Iterator it = d->cells.begin(); it != end; it = d->cells.remove(it))
+ {
+ delete *it;
+ }
+}
+
+TQRect Region::boundingRect() const
+{
+ int left = KS_colMax;
+ int right = 1;
+ int top = KS_rowMax;
+ int bottom = 1;
+ Region::ConstIterator endOfList = cells().constEnd();
+ for (Region::ConstIterator it = cells().constBegin(); it != endOfList; ++it)
+ {
+ TQRect range = (*it)->rect().normalize();
+ if (range.left() < left)
+ {
+ left = range.left();
+ }
+ if (range.right() > right)
+ {
+ right = range.right();
+ }
+ if (range.top() < top)
+ {
+ top = range.top();
+ }
+ if (range.bottom() > bottom)
+ {
+ bottom = range.bottom();
+ }
+ }
+ return TQRect(left, top, right-left+1, bottom-top+1);
+}
+
+Region::ConstIterator Region::constBegin() const
+{
+ return d->cells.constBegin();
+}
+
+Region::ConstIterator Region::constEnd() const
+{
+ return d->cells.constEnd();
+}
+
+TQValueList<Region::Element*>& Region::cells() const
+{
+ return d->cells;
+}
+
+bool Region::operator==(const Region& other) const
+{
+ ConstIterator endOfList(d->cells.constEnd());
+ ConstIterator endOfOtherList(other.d->cells.constEnd());
+ ConstIterator it = d->cells.constBegin();
+ ConstIterator it2 = other.d->cells.constBegin();
+ while (it != endOfList && it2 != endOfOtherList)
+ {
+ if ((*it++)->rect() != (*it2++)->rect())
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+void Region::operator=(const Region& other)
+{
+ d->view = other.d->view;
+ clear();
+ ConstIterator end(other.d->cells.constEnd());
+ for (ConstIterator it = other.d->cells.constBegin(); it != end; ++it)
+ {
+ Element *element = *it;
+ if (element->type() == Element::Point)
+ {
+ Point* point = static_cast<Point*>(element);
+ d->cells.append(createPoint(*point));
+ }
+ else
+ {
+ Range* range = static_cast<Range*>(element);
+ d->cells.append(createRange(*range));
+ }
+ }
+}
+
+Sheet* Region::filterSheetName(TQString& sRegion)
+{
+ Sheet* sheet = 0;
+ int delimiterPos = sRegion.find( '!' );
+ if (delimiterPos > -1)
+ {
+ TQString sheetName = sRegion.left(delimiterPos);
+ // remove the '!'
+ sRegion = sRegion.right(sRegion.length() - delimiterPos - 1);
+ sheet = d->view->doc()->map()->findSheet(sheetName);
+ if (!sheet)
+ {
+ kdDebug() << "Sheet " << sheetName << " not found. Using active sheet!" << endl;
+ sheet = d->view->activeSheet();
+ }
+ }
+ return sheet;
+}
+
+Region::Point* Region::createPoint(const TQPoint& point) const
+{
+ return new Point(point);
+}
+
+Region::Point* Region::createPoint(const TQString& string) const
+{
+ return new Point(string);
+}
+
+Region::Point* Region::createPoint(const Point& point) const
+{
+ return new Point(point);
+}
+
+Region::Range* Region::createRange(const TQRect& rect) const
+{
+ return new Range(rect);
+}
+
+Region::Range* Region::createRange(const TQString& string) const
+{
+ return new Range(string);
+}
+
+Region::Range* Region::createRange(const Range& range) const
+{
+ return new Range(range);
+}
+
+/***************************************************************************
+ class Element
+****************************************************************************/
+
+Region::Element::Element()
+ : m_sheet(0)
+{
+}
+
+Region::Element::~Element()
+{
+}
+
+
+/***************************************************************************
+ class Point
+****************************************************************************/
+
+Region::Point::Point(const TQPoint& point)
+ : Region::Element(),
+ m_point(point)
+{
+}
+
+Region::Point::Point(const TQString& sCell)
+ : Region::Element(),
+ m_point()
+{
+ uint length = sCell.length();
+
+ if (length == 0)
+ {
+ kdDebug(36001) << "Region::Point::init: length = 0" << endl;
+ return;
+ }
+
+ TQString string = sCell;//Region::filterSheetName(sCell);
+
+ uint p = 0;
+
+ // Fixed ?
+ if (string[0] == '$')
+ {
+ p++;
+ }
+
+ // Malformed ?
+ if (p == length)
+ {
+ kdDebug(36001) << "Region::Point::init: no point after '$' (string: '" << string.mid(p) << "'" << endl;
+ return;
+ }
+
+ if (string[p] < 'A' || string[p] > 'Z')
+ {
+ if (string[p] < 'a' || string[p] > 'z')
+ {
+ kdDebug(36001) << "Region::Point::init: wrong first character in point (string: '" << string.mid(p) << "'" << endl;
+ return;
+ }
+ }
+ //default is error
+ int x = -1;
+ //search for the first character != text
+ int result = string.find( TQRegExp("[^A-Za-z]+"), p );
+
+ //get the colomn number for the character between actual position and the first non text charakter
+ if ( result != -1 )
+ {
+ x = util_decodeColumnLabelText( string.mid( p, result - p ) ); // x is defined now
+ }
+ else // If there isn't any, then this is not a point -> return
+ {
+ kdDebug(36001) << "Region::Point::init: no number in string (string: '" << string.mid( p, result ) << "'" << endl;
+ return;
+ }
+ p = result;
+
+ //limit is KS_colMax
+ if ( x > KS_colMax )
+ {
+ kdDebug(36001) << "Region::Point::init: column value too high (col: " << x << ")" << endl;
+ return;
+ }
+
+ // Malformed ?
+ if (p == length)
+ {
+ kdDebug(36001) << "Region::Point::init: p==length after cols" << endl;
+ return;
+ }
+
+ if (string[p] == '$')
+ {
+ p++;
+ // Malformed ?
+ if ( p == length )
+ {
+ kdDebug(36001) << "Region::Point::init: p==length after $ of row" << endl;
+ return;
+ }
+ }
+
+ uint p2 = p;
+ while ( p < length )
+ {
+ if (!TQChar(string[p++]).isDigit())
+ {
+ kdDebug(36001) << "Region::Point::init: no number" << endl;
+ return;
+ }
+ }
+
+ bool ok;
+ int y = string.mid( p2, p-p2 ).toInt( &ok );
+ if ( !ok )
+ {
+ kdDebug(36001) << "Region::Point::init: Invalid number (string: '" << string.mid( p2, p-p2 ) << "'" << endl;
+ return;
+ }
+ if ( y > KS_rowMax )
+ {
+ kdDebug(36001) << "Region::Point::init: row value too high (row: " << y << ")" << endl;
+ return;
+ }
+ if ( y <= 0 )
+ {
+ kdDebug(36001) << "Region::Point::init: y <= 0" << endl;
+ return;
+ }
+
+ m_point = TQPoint(x, y);
+}
+
+Region::Point::~Point()
+{
+}
+
+TQString Region::Point::name(Sheet* originSheet) const
+{
+ TQString name = "";
+ if (m_sheet && m_sheet != originSheet)
+ {
+ name = m_sheet->sheetName() + "!";
+ }
+ return name + Cell::name(m_point.x(), m_point.y());
+}
+
+bool Region::Point::contains(const TQPoint& point) const
+{
+ return (m_point == point);
+}
+
+bool Region::Point::contains(const TQRect& range) const
+{
+ return (range.width() == 1) && (range.height() == 1) && (range.topLeft() == m_point);
+}
+
+
+/***************************************************************************
+ class Range
+****************************************************************************/
+
+Region::Range::Range(const TQRect& rect)
+ : Region::Element(),
+ m_range(rect)
+{
+}
+
+Region::Range::Range(const TQString& sRange)
+ : Region::Element(),
+ m_range()
+{
+ int delimiterPos = sRange.find(':');
+ if (delimiterPos == -1)
+ {
+ return;
+ }
+
+ //Region::filterSheetName(sRange);
+
+ Region::Point ul(sRange.left(delimiterPos));
+ Region::Point lr(sRange.mid(delimiterPos + 1));
+
+ if (!ul.isValid() || !lr.isValid())
+ {
+ return;
+ }
+ m_range = TQRect(ul.pos(), lr.pos());
+}
+
+Region::Range::~Range()
+{
+}
+
+TQString Region::Range::name(Sheet* originSheet) const
+{
+ TQString name = "";
+ if (m_sheet && m_sheet != originSheet)
+ {
+ name = m_sheet->sheetName() + "!";
+ }
+ return name + Cell::name(m_range.left(), m_range.top()) + ":" +
+ Cell::name(m_range.right(), m_range.bottom() );
+}
+
+bool Region::Range::contains(const TQPoint& point) const
+{
+ return m_range.normalize().contains(point);
+}
+
+bool Region::Range::contains(const TQRect& range) const
+{
+ return m_range.normalize().contains(range.normalize());
+}
+
+} // namespace KSpread