diff options
Diffstat (limited to 'kspread/selection.cpp')
-rw-r--r-- | kspread/selection.cpp | 1009 |
1 files changed, 1009 insertions, 0 deletions
diff --git a/kspread/selection.cpp b/kspread/selection.cpp new file mode 100644 index 00000000..f05a6db5 --- /dev/null +++ b/kspread/selection.cpp @@ -0,0 +1,1009 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + Copyright (C) 2005-2006 Stefan Nikolaus <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include <tqregexp.h> + +#include <kdebug.h> + +#include "kspread_canvas.h" +#include "kspread_cell.h" +#include "kspread_doc.h" +#include "kspread_editors.h" +#include "kspread_sheet.h" +#include "kspread_view.h" +#include "kspread_util.h" + +#include "selection.h" + +// TODO Stefan: Substract points in selections +// TODO Stefan: KPart signal (kspread_events.h) + +using namespace KSpread; + +/*************************************************************************** + class Selection::Private +****************************************************************************/ + +class Selection::Private +{ +public: + Private(View *v) + { + view = v; + sheet = 0; + anchor = TQPoint(1,1); + cursor = TQPoint(1,1); + marker = TQPoint(1,1); + + colors.push_back(TQt::red); + colors.push_back(TQt::blue); + colors.push_back(TQt::magenta); + colors.push_back(TQt::darkRed); + colors.push_back(TQt::darkGreen); + colors.push_back(TQt::darkMagenta); + colors.push_back(TQt::darkCyan); + colors.push_back(TQt::darkYellow); + + multipleSelection = false; + + activeElement = Iterator(); + activeSubRegionStart = 0; + activeSubRegionLength = 0; + } + + View* view; + Sheet* sheet; + TQPoint anchor; + TQPoint cursor; + TQPoint marker; + TQValueList<TQColor> colors; + + bool multipleSelection : 1; + + Selection::Iterator activeElement; + uint activeSubRegionStart; + uint activeSubRegionLength; +}; + +/*************************************************************************** + class Selection +****************************************************************************/ +namespace KSpread { + +Selection::Selection(View *view) + : TQObject(view), Region(1,1) +{ + d = new Private(view); + d->activeSubRegionStart = 0; + d->activeSubRegionLength = 1; +} + +Selection::Selection(const Selection& selection) + : TQObject(selection.d->view), Region() +{ +/* kdDebug() << k_funcinfo << endl;*/ + d = new Private(selection.d->view); + d->sheet = selection.d->sheet; + d->activeSubRegionStart = 0; + d->activeSubRegionLength = cells().count(); +} + +Selection::~Selection() +{ + delete d; +} + +void Selection::initialize(const TQPoint& point, Sheet* sheet) +{ + if (!util_isPointValid(point)) + return; + + if (!d->view->activeSheet()) + return; + + if (!sheet) + { + if (d->sheet) + { + sheet = d->sheet; + } + else + { + sheet = d->view->activeSheet(); + } + } + + Region changedRegion(*this); + changedRegion.add(extendToMergedAreas(TQRect(d->anchor,d->marker))); + + TQPoint topLeft(point); + Cell* cell = d->view->activeSheet()->cellAt(point); + if (cell->isObscured() && cell->isPartOfMerged()) + { + cell = cell->obscuringCells().first(); + topLeft = TQPoint(cell->column(), cell->row()); + } + + d->anchor = topLeft; + d->cursor = point; + d->marker = topLeft; + + fixSubRegionDimension(); // TODO remove this sanity check + Iterator it = cells().begin() += d->activeSubRegionStart + d->activeSubRegionLength; + if (it != insert(it, topLeft, sheet/*, true*/)) + { + // if the point was inserted + clearSubRegion(); + } + Element* element = *(cells().begin() += d->activeSubRegionStart); + // we end up with one element in the subregion + d->activeSubRegionLength = 1; + if (element && element->type() == Element::Point) + { + Point* point = static_cast<Point*>(element); + point->setColor(d->colors[cells().size() % d->colors.size()]); + } + else if (element && element->type() == Element::Range) + { + Range* range = static_cast<Range*>(element); + range->setColor(d->colors[cells().size() % d->colors.size()]); + } + + d->activeElement = cells().begin(); + + if (changedRegion == *this) + { + emit changed(Region(topLeft, sheet)); + return; + } + changedRegion.add(topLeft, sheet); + + emit changed(changedRegion); +} + +void Selection::initialize(const TQRect& range, Sheet* sheet) +{ + if (!util_isRectValid(range) || ( range == TQRect(0,0,1,1) )) + return; + + if (!sheet) + { + if (d->sheet) + { + sheet = d->sheet; + } + else + { + sheet = d->view->activeSheet(); + } + } + + Region changedRegion(*this); + changedRegion.add(extendToMergedAreas(TQRect(d->anchor,d->marker))); + + TQPoint topLeft(range.topLeft()); + Cell* cell = d->view->activeSheet()->cellAt(topLeft); + if (cell->isObscured() && cell->isPartOfMerged()) + { + cell = cell->obscuringCells().first(); + topLeft = TQPoint(cell->column(), cell->row()); + } + + TQPoint bottomRight(range.bottomRight()); + cell = d->view->activeSheet()->cellAt(bottomRight); + if (cell->isObscured() && cell->isPartOfMerged()) + { + cell = cell->obscuringCells().first(); + bottomRight = TQPoint(cell->column(), cell->row()); + } + + d->anchor = topLeft; + d->cursor = bottomRight; + d->marker = bottomRight; + + fixSubRegionDimension(); // TODO remove this sanity check + Iterator it = cells().begin() += d->activeSubRegionStart + d->activeSubRegionLength; + if (it != insert(it, TQRect(topLeft, bottomRight), sheet/*, true*/)) + { + // if the range was inserted + clearSubRegion(); + } + + Element* element = *(cells().begin() += d->activeSubRegionStart); + // we end up with one element in the subregion + d->activeSubRegionLength = 1; + if (element && element->type() == Element::Point) + { + Point* point = static_cast<Point*>(element); + point->setColor(d->colors[cells().size() % d->colors.size()]); + } + else if (element && element->type() == Element::Range) + { + Range* range = static_cast<Range*>(element); + range->setColor(d->colors[cells().size() % d->colors.size()]); + } + + d->activeElement = cells().begin(); + + if (changedRegion == *this) + { + return; + } + changedRegion.add(TQRect(topLeft, bottomRight), sheet); + + emit changed(changedRegion); +} + +void Selection::initialize(const Region& region, Sheet* sheet) +{ + if (!region.isValid()) + return; + + if (!sheet) + { + if (d->sheet) + { + sheet = d->sheet; + } + else + { + sheet = d->view->activeSheet(); + } + } + + Region changedRegion(*this); + changedRegion.add(extendToMergedAreas(TQRect(d->anchor,d->marker))); + + // TODO Stefan: handle subregion insertion + // TODO Stefan: handle obscured cells correctly + clear(); + Element* element = add(region); + if (element && element->type() == Element::Point) + { + Point* point = static_cast<Point*>(element); + point->setColor(d->colors[cells().size() % d->colors.size()]); + } + else if (element && element->type() == Element::Range) + { + Range* range = static_cast<Range*>(element); + range->setColor(d->colors[cells().size() % d->colors.size()]); + } + + TQPoint topLeft(cells().last()->rect().normalize().topLeft()); + Cell* cell = d->view->activeSheet()->cellAt(topLeft); + if (cell->isObscured() && cell->isPartOfMerged()) + { + cell = cell->obscuringCells().first(); + topLeft = TQPoint(cell->column(), cell->row()); + } + + TQPoint bottomRight(cells().last()->rect().normalize().bottomRight()); + cell = d->view->activeSheet()->cellAt(bottomRight); + if (cell->isObscured() && cell->isPartOfMerged()) + { + cell = cell->obscuringCells().first(); + bottomRight = TQPoint(cell->column(), cell->row()); + } + + d->anchor = topLeft; + d->cursor = topLeft; + d->marker = bottomRight; + + d->activeElement = --cells().end(); + d->activeSubRegionStart = 0; + d->activeSubRegionLength = cells().count(); + + if (changedRegion == *this) + { + return; + } + changedRegion.add( region ); + + emit changed(changedRegion); +} + +void Selection::update() +{ + emit changed(*this); +} + +void Selection::update(const TQPoint& point) +{ + uint count = cells().count(); + + if (cells().isEmpty()) + { + add(point); + d->activeSubRegionLength += cells().count() - count; + return; + } + if (d->activeElement == cells().end()) + { + // we're not empty, so this will not become again end() + d->activeElement--; + } + + Sheet* sheet = (*d->activeElement)->sheet(); + if (sheet != d->view->activeSheet()) + { + extend(point); + d->activeSubRegionLength += cells().count() - count; + return; + } + + TQPoint topLeft(point); + Cell* cell = d->view->activeSheet()->cellAt(point); + if (cell->isObscured() && cell->isPartOfMerged()) + { + cell = cell->obscuringCells().first(); + topLeft = TQPoint(cell->column(), cell->row()); + } + + if (topLeft == d->marker) + { + return; + } + + TQRect area1 = (*d->activeElement)->rect().normalize(); + TQRect newRange = extendToMergedAreas(TQRect(d->anchor, topLeft)); + + Element* oldElement = *d->activeElement; + // returns iterator to the next element or end + Iterator it = cells().remove(d->activeElement); + delete oldElement; + // returns iterator to the new element (before 'it') or 'it' + d->activeElement = insert(it, newRange, sheet, d->multipleSelection); + d->activeSubRegionLength += cells().count() - count; + + // The call to insert() above can just return the iterator which has been + // passed in. This may be cells.end(), if the old active element was the + // iterator to the list's end (!= last element). So attempts to dereference + // it will fail. + if (d->activeElement == cells().end()) + { + d->activeElement--; + } + + TQRect area2 = (*d->activeElement)->rect().normalize(); + Region changedRegion; + + bool newLeft = area1.left() != area2.left(); + bool newTop = area1.top() != area2.top(); + bool newRight = area1.right() != area2.right(); + bool newBottom = area1.bottom() != area2.bottom(); + + /* first, calculate some numbers that we'll use a few times */ + int farLeft = TQMIN(area1.left(), area2.left()); + int innerLeft = TQMAX(area1.left(), area2.left()); + + int farTop = TQMIN(area1.top(), area2.top()); + int innerTop = TQMAX(area1.top(), area2.top()); + + int farRight = TQMAX(area1.right(), area2.right()); + int innerRight = TQMIN(area1.right(), area2.right()); + + int farBottom = TQMAX(area1.bottom(), area2.bottom()); + int innerBottom = TQMIN(area1.bottom(), area2.bottom()); + + if (newLeft) + { + changedRegion.add(TQRect(TQPoint(farLeft, innerTop), + TQPoint(innerLeft-1, innerBottom))); + if (newTop) + { + changedRegion.add(TQRect(TQPoint(farLeft, farTop), + TQPoint(innerLeft-1, innerTop-1))); + } + if (newBottom) + { + changedRegion.add(TQRect(TQPoint(farLeft, innerBottom+1), + TQPoint(innerLeft-1, farBottom))); + } + } + + if (newTop) + { + changedRegion.add(TQRect(TQPoint(innerLeft, farTop), + TQPoint(innerRight, innerTop-1))); + } + + if (newRight) + { + changedRegion.add(TQRect(TQPoint(innerRight+1, innerTop), + TQPoint(farRight, innerBottom))); + if (newTop) + { + changedRegion.add(TQRect(TQPoint(innerRight+1, farTop), + TQPoint(farRight, innerTop-1))); + } + if (newBottom) + { + changedRegion.add(TQRect(TQPoint(innerRight+1, innerBottom+1), + TQPoint(farRight, farBottom))); + } + } + + if (newBottom) + { + changedRegion.add(TQRect(TQPoint(innerLeft, innerBottom+1), + TQPoint(innerRight, farBottom))); + } + + d->marker = topLeft; + d->cursor = point; + + emit changed(changedRegion); +} + +void Selection::extend(const TQPoint& point, Sheet* sheet) +{ + if (!util_isPointValid(point)) + return; + + if (isEmpty()) + { + initialize(point, sheet); + return; + } + if (d->activeElement == cells().end()) + { + // we're not empty, so this will not become again end() + d->activeElement--; + } + + if (!sheet) + { + if (d->sheet) + { + sheet = d->sheet; + } + else + { + sheet = d->view->activeSheet(); + } + } + + Region changedRegion = Region(extendToMergedAreas(TQRect(d->marker,d->marker))); + + TQPoint topLeft(point); + Cell* cell = d->view->activeSheet()->cellAt(point); + if (cell->isObscured() && cell->isPartOfMerged()) + { + cell = cell->obscuringCells().first(); + topLeft = TQPoint(cell->column(), cell->row()); + } + + uint count = cells().count(); + if (d->multipleSelection) + { + d->activeElement = insert(++d->activeElement, point, sheet, false); + } + else + { + eor(topLeft, sheet); + d->activeElement = --cells().end(); + } + d->anchor = (*d->activeElement)->rect().topLeft(); + d->cursor = (*d->activeElement)->rect().bottomRight(); + d->marker = d->cursor; + + d->activeSubRegionLength += cells().count() - count; + + changedRegion.add(topLeft, sheet); + changedRegion.add(*this); + + emit changed(changedRegion); +} + +void Selection::extend(const TQRect& range, Sheet* sheet) +{ + //See comment in Selection::initialize(const TQRect& range, Sheet* sheet) + if (!util_isRectValid(range) || (range == TQRect(0,0,1,1))) + return; + + if (isEmpty()) + { + initialize(range, sheet); + return; + } + if (d->activeElement == cells().end()) + { + // we're not empty, so this will not become again end() + d->activeElement--; + } + + if (!sheet) + { + if (d->sheet) + { + sheet = d->sheet; + } + else + { + sheet = d->view->activeSheet(); + } + } + + TQPoint topLeft(range.topLeft()); + Cell* cell = d->view->activeSheet()->cellAt(topLeft); + if (cell->isObscured() && cell->isPartOfMerged()) + { + cell = cell->obscuringCells().first(); + topLeft = TQPoint(cell->column(), cell->row()); + } + + TQPoint bottomRight(range.bottomRight()); + cell = d->view->activeSheet()->cellAt(bottomRight); + if (cell->isObscured() && cell->isPartOfMerged()) + { + cell = cell->obscuringCells().first(); + bottomRight = TQPoint(cell->column(), cell->row()); + } + + d->anchor = topLeft; + d->cursor = topLeft; + d->marker = bottomRight; + + uint count = cells().count(); + Element* element; + if (d->multipleSelection) + { + d->activeElement = insert(++d->activeElement, extendToMergedAreas(TQRect(topLeft, bottomRight)).normalize(), sheet, false); + element = (d->activeElement == cells().end()) ? 0 : *d->activeElement; + } + else + { + element = add(extendToMergedAreas(TQRect(topLeft, bottomRight)).normalize(), sheet); + d->activeElement = --cells().end(); + } + if (element && element->type() == Element::Point) + { + Point* point = static_cast<Point*>(element); + point->setColor(d->colors[cells().size() % d->colors.size()]); + } + else if (element && element->type() == Element::Range) + { + Range* range = static_cast<Range*>(element); + range->setColor(d->colors[cells().size() % d->colors.size()]); + } + + d->activeSubRegionLength += cells().count() - count; + + emit changed(*this); +} + +void Selection::extend(const Region& region) +{ + if (!region.isValid()) + return; + + uint count = cells().count(); + ConstIterator end(region.constEnd()); + for (ConstIterator it = region.constBegin(); it != end; ++it) + { + Element *element = *it; + if (!element) continue; + if (element->type() == Element::Point) + { + Point* point = static_cast<Point*>(element); + extend(point->pos(), element->sheet()); + } + else + { + extend(element->rect(), element->sheet()); + } + } + + d->activeSubRegionLength += cells().count() - count; + + emit changed(*this); +} + +Selection::Element* Selection::eor(const TQPoint& point, Sheet* sheet) +{ + if (isSingular()) + { + return Region::add(point, sheet); + } + return Region::eor(point, sheet); +} + +const TQPoint& Selection::anchor() const +{ + return d->anchor; +} + +const TQPoint& Selection::cursor() const +{ + return d->cursor; +} + +const TQPoint& Selection::marker() const +{ + return d->marker; +} + +bool Selection::isSingular() const +{ + return Region::isSingular(); +} + +TQRect Selection::selectionHandleArea() const +{ + int column, row; + + // complete rows/columns are selected, use the marker. + if (isColumnOrRowSelected()) + { + column = d->marker.x(); + row = d->marker.y(); + } + else + { + column = lastRange().right(); + row = lastRange().bottom(); + } + const Cell* cell = d->view->activeSheet()->cellAt(column, row); + + double xpos = d->view->activeSheet()->dblColumnPos( column ); + double ypos = d->view->activeSheet()->dblRowPos( row ); + double width = cell->dblWidth( column ); + double height = cell->dblHeight( row ); + + TQPoint rightBottom( d->view->doc()->zoomItX( xpos + width ), + d->view->doc()->zoomItY( ypos + height ) ); + + TQRect handle( ( rightBottom.x() - 2 ), + ( rightBottom.y() - 2 ), + ( 5 ), + ( 5 ) ); + return handle; +} + +TQString Selection::name(Sheet* sheet) const +{ + return Region::name(sheet ? sheet : d->sheet); +} + +void Selection::setSheet(Sheet* sheet) +{ + d->sheet = sheet; +} + +Sheet* Selection::sheet() const +{ + return d->sheet; +} + +void Selection::setActiveElement(const TQPoint& point) +{ + uint counter = 0; + Iterator end = cells().end(); + for (Iterator it = cells().begin(); it != end; ++it) + { + TQRect range = (*it)->rect(); + if (range.topLeft() == point || range.bottomRight() == point) + { + d->anchor = range.topLeft(); + d->cursor = range.bottomRight(); + d->marker = range.bottomRight(); + d->activeElement = it; + d->activeSubRegionStart = counter; + d->activeSubRegionLength = 1; + if (d->view->canvasWidget()->editor()) + { + d->view->canvasWidget()->editor()->setCursorToRange(counter); + } + } + counter++; + } +} + +void Selection::setActiveElement(uint pos) +{ + if (pos >= cells().count()) + { + kdDebug() << "Selection::setActiveElement: position exceeds list" << endl; + d->activeElement = cells().begin(); + return; + } + + Iterator it = cells().begin() += pos; + TQRect range = (*it)->rect(); + d->anchor = range.topLeft(); + d->cursor = range.bottomRight(); + d->marker = range.bottomRight(); + d->activeElement = it; +} + +Region::Element* Selection::activeElement() const +{ + return (d->activeElement == cells().end()) ? 0 : *d->activeElement; +} + +void Selection::clear() +{ + d->activeSubRegionStart = 0; + d->activeSubRegionLength = 0; + Region::clear(); + d->activeElement = cells().begin(); +} + +void Selection::clearSubRegion() +{ + if (isEmpty()) + { + return; + } +// kdDebug() << *this << endl; +// kdDebug() << d->activeSubRegionStart << endl; +// kdDebug() << d->activeSubRegionLength << endl; + + Iterator it = cells().begin(); + Iterator end = it += d->activeSubRegionStart; + end += d->activeSubRegionLength; + while (it != end) + { +/* kdDebug() << (*it)->name() << endl;*/ + delete *it; + it = cells().remove(it); + } + d->activeSubRegionLength = 0; + d->activeElement = it; +/* kdDebug() << "ENDE" << endl;*/ +} + +void Selection::fixSubRegionDimension() +{ + if (d->activeSubRegionStart > cells().count()) + { + kdDebug() << "Selection::fixSubRegionDimension: start position exceeds list" << endl; + d->activeSubRegionStart = 0; + d->activeSubRegionLength = cells().count(); + return; + } + if (d->activeSubRegionStart + d->activeSubRegionLength > cells().count()) + { + kdDebug() << "Selection::fixSubRegionDimension: length exceeds list" << endl; + d->activeSubRegionLength = cells().count() - d->activeSubRegionStart; + return; + } +} + +void Selection::setActiveSubRegion(uint start, uint length) +{ +// kdDebug() << k_funcinfo << endl; + d->activeSubRegionStart = start; + d->activeSubRegionLength = length; + fixSubRegionDimension(); + d->activeElement = cells().begin() += d->activeSubRegionStart; +} + +TQString Selection::activeSubRegionName() const +{ +// kdDebug() << k_funcinfo << endl; +// kdDebug() << *this << endl; +// kdDebug() << "start = " << d->activeSubRegionStart << ", len = " << d->activeSubRegionLength << endl; + + TQStringList names; + Iterator it = cells().begin(); + it += d->activeSubRegionStart; + Iterator end = it; + end += d->activeSubRegionLength; + while (it != end) + { + names += (*it++)->name(d->sheet); + } +/* kdDebug() << "ENDE" << endl;*/ + return names.isEmpty() ? "" : names.join(";"); +} + +void Selection::setMultipleSelection(bool state) +{ + d->multipleSelection = state; +} + +const TQValueList<TQColor>& Selection::colors() const +{ + return d->colors; +} + +TQRect Selection::lastRange(bool extend) const +{ + TQRect selection = TQRect(d->anchor, d->marker).normalize(); + return extend ? extendToMergedAreas(selection) : selection; +} + +TQRect Selection::selection(bool extend) const +{ + TQRect selection = TQRect(d->anchor, d->marker).normalize(); + return extend ? extendToMergedAreas(selection) : selection; +} + +TQRect Selection::extendToMergedAreas(TQRect area) const +{ + if (!d->view->activeSheet()) + return area; + + area = area.normalize(); // TODO Stefan: avoid this + const Cell *cell = d->view->activeSheet()->cellAt(area.left(), area.top()); + + if( Region::Range(area).isColumn() || Region::Range(area).isRow() ) + { + return area; + } + else if ( !(cell->isObscured() && cell->isPartOfMerged()) && + (cell->mergedXCells() + 1) >= area.width() && + (cell->mergedYCells() + 1) >= area.height()) + { + /* if just a single cell is selected, we need to merge even when + the obscuring isn't forced. But only if this is the cell that + is doing the obscuring -- we still want to be able to click on a cell + that is being obscured. + */ + area.setWidth(cell->mergedXCells() + 1); + area.setHeight(cell->mergedYCells() + 1); + } + else + { + int top=area.top(); + int left=area.left(); + int bottom=area.bottom(); + int right=area.right(); + for ( int x = area.left(); x <= area.right(); x++ ) + for ( int y = area.top(); y <= area.bottom(); y++ ) + { + cell = d->view->activeSheet()->cellAt( x, y ); + if( cell->doesMergeCells()) + { + right=TQMAX(right,cell->mergedXCells()+x); + bottom=TQMAX(bottom,cell->mergedYCells()+y); + } + else if ( cell->isObscured() && cell->isPartOfMerged() ) + { + cell = cell->obscuringCells().first(); + left=TQMIN(left,cell->column()); + top=TQMIN(top,cell->row()); + bottom=TQMAX(bottom,cell->row() + cell->mergedYCells()); + right=TQMAX(right,cell->column() + cell->mergedXCells()); + } + } + + area.setCoords(left,top,right,bottom); + } + return area; +} + +Selection::Region::Point* Selection::createPoint(const TQPoint& point) const +{ + return new Point(point); +} + +Selection::Region::Point* Selection::createPoint(const TQString& string) const +{ + return new Point(string); +} + +Selection::Region::Point* Selection::createPoint(const Point& point) const +{ + return new Point(point); +} + +Selection::Region::Range* Selection::createRange(const TQRect& rect) const +{ + return new Range(rect); +} + +Selection::Region::Range* Selection::createRange(const TQString& string) const +{ + return new Range(string); +} + +Selection::Region::Range* Selection::createRange(const Range& range) const +{ + return new Range(range); +} + +/*************************************************************************** + class Point +****************************************************************************/ + +Selection::Point::Point(const TQPoint& point) + : Region::Point(point), + m_color(TQt::black), + m_columnFixed(false), + m_rowFixed(false) +{ +} + +Selection::Point::Point(const TQString& string) + : Region::Point(string), + m_color(TQt::black), + m_columnFixed(false), + m_rowFixed(false) +{ + if (!isValid()) + { + return; + } + + uint p = 0; + // Fixed? + if (string[p++] == '$') + { + m_columnFixed = true; + } + + //search for the first character != text + int result = string.find( TQRegExp("[^A-Za-z]+"), p ); + if (string[result] == '$') + { + m_rowFixed = true; + } +} + +/*************************************************************************** + class Range +****************************************************************************/ + +Selection::Range::Range(const TQRect& range) + : Region::Range(range), + m_color(TQt::black), + m_leftFixed(false), + m_rightFixed(false), + m_topFixed(false), + m_bottomFixed(false) +{ +} + +Selection::Range::Range(const TQString& string) + : Region::Range(string), + m_color(TQt::black), + m_leftFixed(false), + m_rightFixed(false), + m_topFixed(false), + m_bottomFixed(false) +{ + if (!isValid()) + { + return; + } + + int delimiterPos = string.find(':'); + if (delimiterPos == -1) + { + return; + } + + Selection::Point ul(string.left(delimiterPos)); + Selection::Point lr(string.mid(delimiterPos + 1)); + + if (!ul.isValid() || !lr.isValid()) + { + return; + } + m_leftFixed = ul.columnFixed(); + m_rightFixed = lr.columnFixed(); + m_topFixed = ul.rowFixed(); + m_bottomFixed = lr.rowFixed(); +} + +} // namespace KSpread +#include "selection.moc" |