From kde-commits Tue Jan 31 23:13:57 2006 From: Robert Knight Date: Tue, 31 Jan 2006 23:13:57 +0000 To: kde-commits Subject: koffice/kspread Message-Id: <1138749237.956931.12767.nullmailer () svn ! kde ! org> X-MARC-Message: https://marc.info/?l=kde-commits&m=113874925221280 SVN commit 504407 by knight: Fix crash when entering invalid cell or range references into formula editor. M +27 -7 kspread_editors.cc M +22 -0 kspread_util.cc M +7 -1 kspread_util.h M +3 -2 region.h M +21 -0 selection.cc --- trunk/koffice/kspread/kspread_editors.cc #504406:504407 @@ -36,6 +36,7 @@ #include #include #include +#include #include //#include @@ -116,6 +117,8 @@ QFont editorFont = textEdit()->currentFont(); QFont font; + uint oldRangeCount = d->rangeCount; + d->rangeCount = 0; QValueList colors = d->canvas->choice()->colors(); for (uint i = 0; i < d->tokens.count(); ++i) @@ -166,6 +169,10 @@ break; } } + + if (oldRangeCount != d->rangeCount) + d->rangeChanged = true; + return 0; } @@ -656,7 +663,6 @@ bool lastWasASemicolon = false; d->currentToken = 0; uint rangeCount = d->highlighter->rangeCount(); - int rangeCountDiff = rangeCount - d->rangeCount; d->rangeCount = rangeCount; Token token; @@ -726,7 +732,7 @@ // triggered by keyboard action? if (!d->updatingChoice) { - if (rangeCountDiff != 0 || d->highlighter->rangeChanged()) + if (d->highlighter->rangeChanged()) { d->highlighter->resetRangeChanged(); @@ -738,17 +744,31 @@ d->canvas->choice()->clear(); Region tmpRegion; Region::ConstIterator it; + + //A list of regions which have already been highlighted on the spreadsheet. + //This is so that we don't end up highlighting the same region twice in two different + //colours. + QValueList alreadyUsedRegions; + for (uint i = 0; i < tokens.count(); ++i) { Token token = tokens[i]; Token::Type type = token.type(); if (type == Token::Cell || type == Token::Range) { - it = Region(d->canvas->view(), token.text()).constBegin(); - if (d->canvas->choice()->isEmpty()) - d->canvas->choice()->initialize((*it)->rect(), (*it)->sheet()); - else - d->canvas->choice()->extend((*it)->rect(), (*it)->sheet()); + Region region(d->canvas->view(), token.text()); + it = region.constBegin(); + + //if (!alreadyUsedRegions.contains(region)) + { + + if (d->canvas->choice()->isEmpty()) + d->canvas->choice()->initialize((*it)->rect(), (*it)->sheet()); + else + d->canvas->choice()->extend((*it)->rect(), (*it)->sheet()); + + alreadyUsedRegions.append(region); + } } } --- trunk/koffice/kspread/kspread_util.cc #504406:504407 @@ -350,6 +350,28 @@ _pos = QPoint( x, y ); } +bool util_isPointValid( QPoint point ) +{ + if ( point.x() >= 0 + && point.y() >= 0 + && point.x() <= KS_colMax + && point.y() <= KS_rowMax + ) + return true; + else + return false; +} + +bool util_isRectValid( QRect rect ) +{ + if ( util_isPointValid( rect.topLeft() ) + && util_isPointValid( rect.bottomRight() ) + ) + return true; + else + return false; +} + Point::Point( const QString & str, Map * map, Sheet * sheet ) { --- trunk/koffice/kspread/kspread_util.h #504406:504407 @@ -36,6 +36,9 @@ class KLocale; +bool util_isPointValid(QPoint point); +bool util_isRectValid(QRect rect); + namespace KSpread { class Cell; @@ -61,7 +64,7 @@ _rowFixed = c._rowFixed; } - bool isValid() const { return ( _pos.x() >= 0 && ( _sheet != 0 || _sheetName.isEmpty() ) ); } + bool isValid() const { return ( util_isPointValid(pos()) && ( _sheet != 0 || _sheetName.isEmpty() ) ); } bool isSheetKnown() const { return ( ! _sheetName.isEmpty() && _sheet != 0 ); } Cell* cell() const; @@ -104,6 +107,7 @@ */ void setRowFixed(bool rowFixed); bool rowFixed() const; + private: Sheet* _sheet; @@ -298,6 +302,8 @@ bool util_isRowSelected(const QRect &selection); bool util_isRowOrColumnSelected( const QRect &selection ); + + bool util_validateSheetName(const QString &name); QDomElement util_createElement( const QString & tagName, const QFont & font, QDomDocument & doc ); --- trunk/koffice/kspread/region.h #504406:504407 @@ -29,6 +29,7 @@ #include #include "kspread_global.h" +#include "kspread_util.h" namespace KSpread { @@ -358,7 +359,7 @@ virtual ~Point(); virtual Type type() const { return Element::Point; } - virtual bool isValid() const { return !m_point.isNull(); } + virtual bool isValid() const { return (!m_point.isNull() && util_isPointValid(pos())); } virtual bool isColumn() const { return false; } virtual bool isRow() const { return false; } @@ -398,7 +399,7 @@ virtual ~Range(); virtual Type type() const { return Element::Range; } - virtual bool isValid() const { return !m_range.isNull(); } + virtual bool isValid() const { return !m_range.isNull() && util_isRectValid(rect()); } virtual bool isColumn() const { return (m_range.normalize().top() == 1 && m_range.normalize().bottom() == KS_rowMax); } virtual bool isRow() const { return (m_range.normalize().left() == 1 && m_range.normalize().right() == KS_colMax); } --- trunk/koffice/kspread/selection.cc #504406:504407 @@ -28,6 +28,7 @@ #include "kspread_editors.h" #include "kspread_sheet.h" #include "kspread_view.h" +#include "kspread_util.h" #include "selection.h" @@ -111,6 +112,9 @@ void Selection::initialize(const QPoint& point, Sheet* sheet) { + if (!util_isPointValid(point)) + return; + if (!sheet) { if (d->sheet) @@ -173,6 +177,9 @@ void Selection::initialize(const QRect& range, Sheet* sheet) { + if (!util_isRectValid(range) || ( range == QRect(0,0,1,1) )) + return; + if (!sheet) { if (d->sheet) @@ -215,6 +222,8 @@ // if the range was inserted clearSubRegion(); } + + Element* element = *(cells().begin() += d->activeSubRegionStart); // we end up with one element in the subregion d->activeSubRegionLength = 1; @@ -242,6 +251,9 @@ void Selection::initialize(const Region& region, Sheet* sheet) { + if (!region.isValid()) + return; + if (!sheet) { if (d->sheet) @@ -417,6 +429,9 @@ void Selection::extend(const QPoint& point, Sheet* sheet) { + if (!util_isPointValid(point)) + return; + if (!sheet) { if (d->sheet) @@ -463,6 +478,9 @@ void Selection::extend(const QRect& range, Sheet* sheet) { + if (!util_isRectValid(range)) + return; + if (!sheet) { if (d->sheet) @@ -525,6 +543,9 @@ 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)