00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <ctype.h>
00022
00023 #include <qregexp.h>
00024
00025 #include <kdebug.h>
00026
00027 #include "formula.h"
00028 #include "kspread_doc.h"
00029 #include "kspread_locale.h"
00030 #include "kspread_map.h"
00031 #include "kspread_sheet.h"
00032 #include "kspread_style.h"
00033 #include "kspread_util.h"
00034
00035 using namespace KSpread;
00036
00037
00038 bool KSpread::formatIsDate (FormatType fmt)
00039 {
00040 return ((fmt == ShortDate_format) || (fmt == TextDate_format) ||
00041 (((int) fmt >= 200) && ((int) fmt < 300)));
00042 }
00043
00044 bool KSpread::formatIsTime (FormatType fmt)
00045 {
00046 return (((int) fmt >= 50) && ((int) fmt < 70));
00047 }
00048
00049 bool KSpread::formatIsFraction (FormatType fmt)
00050 {
00051 return (((int) fmt >= 70) && ((int) fmt < 80));
00052 }
00053
00054
00055
00056
00057 int KSpread::util_decodeColumnLabelText( const QString &_col )
00058 {
00059 int col = 0;
00060 int offset='a'-'A';
00061 int counterColumn = 0;
00062 for ( uint i=0; i < _col.length(); i++ )
00063 {
00064 counterColumn = (int) pow(26.0 , static_cast<int>(_col.length() - i - 1));
00065 if( _col[i] >= 'A' && _col[i] <= 'Z' )
00066 col += counterColumn * ( _col[i].latin1() - 'A' + 1);
00067 else if( _col[i] >= 'a' && _col[i] <= 'z' )
00068 col += counterColumn * ( _col[i].latin1() - 'A' - offset + 1 );
00069 else
00070 kdDebug(36001) << "util_decodeColumnLabelText: Wrong characters in label text for col:'" << _col << "'" << endl;
00071 }
00072 return col;
00073 }
00074
00075
00076 QString KSpread::util_rangeColumnName( const QRect &_area)
00077 {
00078 return QString("%1:%2")
00079 .arg( Cell::columnName( _area.left()))
00080 .arg( Cell::columnName(_area.right()));
00081 }
00082
00083
00084 QString KSpread::util_rangeRowName( const QRect &_area)
00085 {
00086 return QString("%1:%2")
00087 .arg( _area.top())
00088 .arg(_area.bottom());
00089 }
00090
00091 QString KSpread::util_rangeName(const QRect &_area)
00092 {
00093 return Cell::name( _area.left(), _area.top() ) + ":" +
00094 Cell::name( _area.right(), _area.bottom() );
00095 }
00096
00097 QString KSpread::util_rangeName(Sheet * _sheet, const QRect &_area)
00098 {
00099 return _sheet->sheetName() + "!" + util_rangeName(_area);
00100 }
00101
00102 QDomElement KSpread::util_createElement( const QString & tagName, const QFont & font, QDomDocument & doc )
00103 {
00104 QDomElement e( doc.createElement( tagName ) );
00105
00106 e.setAttribute( "family", font.family() );
00107 e.setAttribute( "size", font.pointSize() );
00108 e.setAttribute( "weight", font.weight() );
00109 if ( font.bold() )
00110 e.setAttribute( "bold", "yes" );
00111 if ( font.italic() )
00112 e.setAttribute( "italic", "yes" );
00113 if ( font.underline() )
00114 e.setAttribute( "underline", "yes" );
00115 if ( font.strikeOut() )
00116 e.setAttribute( "strikeout", "yes" );
00117
00118
00119 return e;
00120 }
00121
00122 QDomElement KSpread::util_createElement( const QString & tagname, const QPen & pen, QDomDocument & doc )
00123 {
00124 QDomElement e( doc.createElement( tagname ) );
00125 e.setAttribute( "color", pen.color().name() );
00126 e.setAttribute( "style", (int)pen.style() );
00127 e.setAttribute( "width", (int)pen.width() );
00128 return e;
00129 }
00130
00131 QFont KSpread::util_toFont( QDomElement & element )
00132 {
00133 QFont f;
00134 f.setFamily( element.attribute( "family" ) );
00135
00136 bool ok;
00137 f.setPointSize( element.attribute("size").toInt( &ok ) );
00138 if ( !ok )
00139 return QFont();
00140
00141 f.setWeight( element.attribute("weight").toInt( &ok ) );
00142 if ( !ok )
00143 return QFont();
00144
00145 if ( element.hasAttribute( "italic" ) && element.attribute("italic") == "yes" )
00146 f.setItalic( true );
00147
00148 if ( element.hasAttribute( "bold" ) && element.attribute("bold") == "yes" )
00149 f.setBold( true );
00150
00151 if ( element.hasAttribute( "underline" ) && element.attribute("underline") == "yes" )
00152 f.setUnderline( true );
00153
00154 if ( element.hasAttribute( "strikeout" ) && element.attribute("strikeout") == "yes" )
00155 f.setStrikeOut( true );
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 return f;
00167 }
00168
00169 QPen KSpread::util_toPen( QDomElement & element )
00170 {
00171 bool ok;
00172 QPen p;
00173
00174 p.setStyle( (Qt::PenStyle)element.attribute("style").toInt( &ok ) );
00175 if ( !ok )
00176 return QPen();
00177
00178 p.setWidth( element.attribute("width").toInt( &ok ) );
00179 if ( !ok )
00180 return QPen();
00181
00182 p.setColor( QColor( element.attribute("color") ) );
00183
00184 return p;
00185 }
00186
00187 Point::Point(const QString & _str)
00188 {
00189 _sheet = 0;
00190 init(_str);
00191 }
00192
00193 void Point::setPos(QPoint pos)
00194 {
00195 _pos=pos;
00196 }
00197 QPoint Point::pos() const
00198 {
00199 return _pos;
00200 }
00201 void Point::setSheet(Sheet* sheet)
00202 {
00203 _sheet=sheet;
00204 }
00205 KSpread::Sheet* Point::sheet() const
00206 {
00207 return _sheet;
00208 }
00209 void Point::setSheetName(QString name)
00210 {
00211 _sheetName=name;
00212 }
00213 QString Point::sheetName() const
00214 {
00215 return _sheetName;
00216 }
00217 void Point::setColumnFixed(bool colFixed)
00218 {
00219 _columnFixed=colFixed;
00220 }
00221 bool Point::columnFixed() const
00222 {
00223 return _columnFixed;
00224 }
00225 void Point::setRowFixed(bool rowFixed)
00226 {
00227 _rowFixed=rowFixed;
00228 }
00229 bool Point::rowFixed() const
00230 {
00231 return _rowFixed;
00232 }
00233
00234
00235 void Point::init(const QString & _str)
00236 {
00237 _columnFixed=false;
00238 _rowFixed=false;
00239
00240
00241 _pos.setX(-1);
00242
00243 uint len = _str.length();
00244 if ( !len )
00245 {
00246 kdDebug(36001) << "Point::init: len = 0" << endl;
00247 return;
00248 }
00249
00250 QString str( _str );
00251 int n = _str.find( '!' );
00252 if ( n != -1 )
00253 {
00254 _sheetName = _str.left( n );
00255 str = _str.right( len - n - 1 );
00256 len = str.length();
00257 }
00258
00259 uint p = 0;
00260
00261
00262 if ( str[0] == '$' )
00263 {
00264 _columnFixed = true;
00265 p++;
00266 }
00267 else
00268 _columnFixed = false;
00269
00270
00271 if ( p == len )
00272 {
00273 kdDebug(36001) << "Point::init: no point after '$' (str: '" << str.mid( p ) << "'" << endl;
00274 return;
00275 }
00276 if ( str[p] < 'A' || str[p] > 'Z' )
00277 {
00278 if ( str[p] < 'a' || str[p] > 'z' )
00279 {
00280 kdDebug(36001) << "Point::init: wrong first character in point (str: '" << str.mid( p ) << "'" << endl;
00281 return;
00282 }
00283 }
00284
00285 int x = -1;
00286
00287 int result = str.find( QRegExp("[^A-Za-z]+"), p );
00288
00289
00290 if ( result != -1 )
00291 x = util_decodeColumnLabelText( str.mid( p, result - p ) );
00292 else
00293 {
00294 kdDebug(36001) << "Point::init: no number in string (str: '" << str.mid( p, result ) << "'" << endl;
00295 return;
00296 }
00297 p = result;
00298
00299
00300 if ( x > KS_colMax )
00301 {
00302 kdDebug(36001) << "Point::init: column value too high (col: " << x << ")" << endl;
00303 return;
00304 }
00305
00306
00307 if (p == len)
00308 {
00309 kdDebug(36001) << "Point::init: p==len after cols" << endl;
00310 return;
00311 }
00312
00313 if (str[p] == '$')
00314 {
00315 _rowFixed = true;
00316 p++;
00317
00318 if ( p == len )
00319 {
00320 kdDebug(36001) << "Point::init: p==len after $ of row" << endl;
00321 return;
00322 }
00323 }
00324 else
00325 _rowFixed = false;
00326
00327 uint p2 = p;
00328 while ( p < len )
00329 {
00330 if ( !isdigit( QChar(str[p++]) ) )
00331 {
00332 kdDebug(36001) << "Point::init: no number" << endl;
00333 return;
00334 }
00335 }
00336
00337 bool ok;
00338 int y = str.mid( p2, p-p2 ).toInt( &ok );
00339 if ( !ok )
00340 {
00341 kdDebug(36001) << "Point::init: Invalid number (str: '" << str.mid( p2, p-p2 ) << "'" << endl;
00342 return;
00343 }
00344 if ( y > KS_rowMax )
00345 {
00346 kdDebug(36001) << "Point::init: row value too high (row: " << y << ")" << endl;
00347 return;
00348 }
00349 if ( y <= 0 )
00350 {
00351 kdDebug(36001) << "Point::init: y <= 0" << endl;
00352 return;
00353 }
00354 _pos = QPoint( x, y );
00355 }
00356
00357 bool util_isPointValid( QPoint point )
00358 {
00359 if ( point.x() >= 1
00360 && point.y() >= 1
00361 && point.x() <= KS_colMax
00362 && point.y() <= KS_rowMax
00363 )
00364 return true;
00365 else
00366 return false;
00367 }
00368
00369 bool util_isRectValid( QRect rect )
00370 {
00371 if ( util_isPointValid( rect.topLeft() )
00372 && util_isPointValid( rect.bottomRight() )
00373 )
00374 return true;
00375 else
00376 return false;
00377 }
00378
00379 Point::Point( const QString & str, Map * map,
00380 Sheet * sheet )
00381 {
00382
00383 uint p = 0;
00384 int p2 = str.find( '!' );
00385 if ( p2 != -1 )
00386 {
00387 _sheetName = str.left( p2++ );
00388 while ( true )
00389 {
00390 _sheet = map->findSheet( _sheetName );
00391 if ( !sheet && _sheetName[0] == ' ' )
00392 {
00393 _sheetName = _sheetName.right( _sheetName.length() - 1 );
00394 continue;
00395 }
00396 break;
00397 }
00398 p = p2;
00399
00400
00401 if ( _sheetName.isEmpty() )
00402 {
00403 kdDebug(36001) << "Point: tableName is unknown" << endl;
00404 _sheetName = "unknown";
00405 }
00406 }
00407 else
00408 {
00409 if ( sheet != 0 )
00410 {
00411 _sheet = sheet;
00412 _sheetName = sheet->sheetName();
00413 }
00414 else
00415 _sheet = 0;
00416 }
00417
00418 init( str.mid( p ) );
00419 }
00420
00421 Cell *Point::cell() const
00422 {
00423 return _sheet->cellAt(_pos);
00424 }
00425
00426 bool Point::operator== (const Point &cell) const
00427 {
00428
00429 return (_pos == cell.pos());
00430 }
00431
00432 bool Point::operator< (const Point &cell) const
00433 {
00434
00435 return (pos().y() < cell.pos().y()) ? true :
00436 ((pos().y() == cell.pos().y()) && (pos().x() < cell.pos().x()));
00437 }
00438
00439 bool Range::operator ==(const Range& otherRange) const
00440 {
00441 if ( _range == otherRange._range
00442 && _leftFixed == otherRange._leftFixed
00443 && _rightFixed == otherRange._rightFixed
00444 && _bottomFixed == otherRange._bottomFixed
00445 && _topFixed == otherRange._topFixed
00446 && _sheet == otherRange._sheet )
00447 return true;
00448 else
00449 return false;
00450 }
00451
00452 Range::Range()
00453 {
00454 _sheet = 0;
00455 _range.setLeft( -1 );
00456
00457 _leftFixed=false;
00458 _rightFixed=false;
00459 _topFixed=false;
00460 _bottomFixed=false;
00461 }
00462 Range::Range(const QString & _str)
00463 {
00464 _range.setLeft(-1);
00465 _sheet = 0;
00466
00467 int p = _str.find(':');
00468
00469
00470
00471 Point ul;
00472 Point lr; ;
00473
00474 if ( p != -1)
00475 {
00476 ul = Point(_str.left(p));
00477 lr = Point(_str.mid(p + 1));
00478 }
00479 else
00480 {
00481 ul = Point(_str);
00482 lr = ul;
00483 }
00484
00485 _range = QRect(ul.pos(), lr.pos());
00486 _sheetName = ul.sheetName();
00487
00488 _leftFixed = ul.columnFixed();
00489 _rightFixed = lr.columnFixed();
00490 _topFixed = ul.rowFixed();
00491 _bottomFixed = lr.rowFixed();
00492 }
00493
00494 Range::Range( const Range& r )
00495 {
00496 _sheet = r.sheet();
00497 _sheetName = r.sheetName();
00498 _range = r.range();
00499 _namedArea = r.namedArea();
00500
00501 _leftFixed=r._leftFixed;
00502 _rightFixed=r._rightFixed;
00503 _topFixed=r._topFixed;
00504 _bottomFixed=r._bottomFixed;
00505 }
00506
00507 Range::Range( const Point& ul, const Point& lr )
00508 {
00509 _range = QRect( ul.pos(), lr.pos() );
00510 if ( ul.sheetName() != lr.sheetName() )
00511 {
00512 _range.setLeft( -1 );
00513 return;
00514 }
00515 _sheetName = ul.sheetName();
00516 _sheet = ul.sheet();
00517 _leftFixed = ul.columnFixed();
00518 _rightFixed = lr.columnFixed();
00519 _topFixed = ul.rowFixed();
00520 _bottomFixed = lr.rowFixed();
00521 }
00522
00523 Range::Range(const QString & str, Map * map,
00524 Sheet * sheet)
00525 {
00526 _range.setLeft(-1);
00527 _sheet = 0;
00528
00529
00530 bool gotNamed = false;
00531 QString tmp = str.lower();
00532 QValueList < Reference >::Iterator it;
00533 QValueList < Reference > area = map->doc()->listArea();
00534 for (it = area.begin(); it != area.end(); ++it) {
00535 if ((*it).ref_name.lower() == tmp) {
00536
00537 _range = (*it).rect;
00538 _sheet = map->findSheet((*it).sheet_name);
00539 gotNamed = true;
00540 _namedArea = tmp;
00541 break;
00542 }
00543 }
00544 if (gotNamed) {
00545
00546 _leftFixed = false;
00547 _rightFixed = false;
00548 _topFixed = false;
00549 _bottomFixed = false;
00550 return;
00551 }
00552
00553 _range.setLeft(-1);
00554 _sheet = 0;
00555
00556 int p = 0;
00557 int p2 = str.find('!');
00558 if (p2 != -1)
00559 {
00560 _sheetName = str.left(p2++);
00561 while ( true )
00562 {
00563 _sheet = map->findSheet(_sheetName);
00564
00565 if ( !_sheet && _sheetName[0] == ' ' )
00566 {
00567 _sheetName = _sheetName.right( _sheetName.length() - 1 );
00568 continue;
00569 }
00570 break;
00571 }
00572 p = p2;
00573 } else
00574 _sheet = sheet;
00575
00576
00577 int p3 = str.find(':', p);
00578 if (p3 == -1)
00579 return;
00580
00581 Point ul(str.mid(p, p3 - p));
00582 Point lr(str.mid(p3 + 1));
00583 _range = QRect(ul.pos(), lr.pos());
00584
00585 _leftFixed = ul.columnFixed();
00586 _rightFixed = lr.columnFixed();
00587 _topFixed = ul.rowFixed();
00588 _bottomFixed = lr.rowFixed();
00589 }
00590
00591 QString Range::toString() const
00592 {
00593 QString result;
00594
00595 if (_sheet)
00596 {
00597 result=util_rangeName(_sheet,_range);
00598 }
00599 else
00600 {
00601 result=util_rangeName(_range);
00602 }
00603
00604
00605
00606 int pos=result.find("!")+1;
00607 Q_ASSERT(pos != -1);
00608
00609 if (_leftFixed)
00610 {
00611 result.insert(pos,'$');
00612 pos++;
00613 }
00614 if (_topFixed)
00615 {
00616 result.insert(pos+Cell::columnName(_range.left()).length(),'$');
00617 }
00618
00619 pos=result.find(":")+1;
00620 Q_ASSERT(pos != -1);
00621
00622 if (_rightFixed)
00623 {
00624 result.insert(pos,'$');
00625 pos++;
00626 }
00627 if (_bottomFixed)
00628 {
00629 result.insert(pos+Cell::columnName(_range.right()).length(),'$');
00630 }
00631
00632
00633 return result;
00634 }
00635
00636 void Range::getStartPoint(Point* pt)
00637 {
00638 if (!isValid()) return;
00639
00640 pt->setRow(startRow());
00641 pt->setColumn(startCol());
00642 pt->setColumnFixed(_leftFixed);
00643 pt->setRowFixed(_topFixed);
00644 pt->setSheet(_sheet);
00645 pt->setSheetName(_sheetName);
00646 }
00647
00648 void Range::getEndPoint(Point* pt)
00649 {
00650 if (!isValid()) return;
00651
00652 pt->setRow(endRow());
00653 pt->setColumn(endCol());
00654 pt->setColumnFixed(_rightFixed);
00655 pt->setRowFixed(_bottomFixed);
00656 pt->setSheet(_sheet);
00657 pt->setSheetName(_sheetName);
00658 }
00659
00660 bool Range::contains (const Point &cell) const
00661 {
00662 return _range.contains (cell.pos());
00663 }
00664
00665 bool Range::intersects (const Range &r) const
00666 {
00667 return _range.intersects (r.range());
00668 }
00669
00670 bool Range::isValid() const
00671 {
00672 return ( _range.left() >= 0 ) &&
00673 ( _range.right() >= 0 ) &&
00674 ( _sheet != 0 || _sheetName.isEmpty() ) &&
00675 ( _range.isValid() ) ;
00676 }
00677
00678 QRect Range::range() const
00679 {
00680 return _range;
00681 }
00682
00683 void Range::setLeftFixed(bool fixed)
00684 {
00685 _leftFixed=fixed;
00686 }
00687 bool Range::leftFixed() const
00688 {
00689 return _leftFixed;
00690 }
00691 void Range::setRightFixed(bool fixed)
00692 {
00693 _rightFixed=fixed;
00694 }
00695 bool Range::rightFixed() const
00696 {
00697 return _rightFixed;
00698 }
00699 void Range::setTopFixed(bool fixed)
00700 {
00701 _topFixed=fixed;
00702 }
00703 bool Range::topFixed() const
00704 {
00705 return _topFixed;
00706 }
00707 void Range::setBottomFixed(bool fixed)
00708 {
00709 _bottomFixed=fixed;
00710 }
00711 bool Range::bottomFixed() const
00712 {
00713 return _bottomFixed;
00714 }
00715 void Range::setSheet(Sheet* sheet)
00716 {
00717 _sheet=sheet;
00718 }
00719 KSpread::Sheet* Range::sheet() const
00720 {
00721 return _sheet;
00722 }
00723 void Range::setSheetName(QString sheetName)
00724 {
00725 _sheetName=sheetName;
00726 }
00727 QString Range::sheetName() const
00728 {
00729 return _sheetName;
00730 }
00731 QString Range::namedArea() const
00732 {
00733 return _namedArea;
00734 }
00735
00736
00737 bool KSpread::util_isAllSelected(const QRect &selection)
00738 {
00739 return ( selection.top() == 1 && selection.bottom() == KS_rowMax
00740 && selection.left() == 1 && selection.right() == KS_colMax);
00741 }
00742
00743 bool KSpread::util_isColumnSelected(const QRect &selection)
00744 {
00745 return ( (selection.top() == 1) && (selection.bottom() == KS_rowMax) );
00746 }
00747
00748 bool KSpread::util_isRowSelected(const QRect &selection)
00749 {
00750 return ( (selection.left() == 1) && (selection.right() == KS_colMax) );
00751 }
00752
00753 bool KSpread::util_isRowOrColumnSelected(const QRect &selection)
00754 {
00755 return ( (selection.left() == 1) && (selection.right() == KS_colMax)
00756 || (selection.top() == 1) && (selection.bottom() == KS_rowMax) );
00757 }
00758
00759
00760 bool KSpread::util_validateSheetName(const QString &name)
00761 {
00762 if (name[0] == ' ')
00763 {
00764 return false;
00765 }
00766 for (unsigned int i = 0; i < name.length(); i++)
00767 {
00768 if ( !(name[i].isLetterOrNumber() ||
00769 name[i] == ' ' || name[i] == '.' ||
00770 name[i] == '_'))
00771 {
00772 return false;
00773 }
00774 }
00775 return true;
00776 }
00777
00778
00779 RangeIterator::RangeIterator(QRect _range, Sheet* _sheet)
00780 {
00781 range = _range;
00782 sheet = _sheet;
00783 current = QPoint(0,0);
00784 }
00785
00786 RangeIterator::~RangeIterator()
00787 {
00788 }
00789
00790 Cell* RangeIterator::first()
00791 {
00792 current.setY(range.top());
00793
00794
00795
00796 current.setX(range.left() - 1);
00797 return next();
00798 }
00799
00800 Cell* RangeIterator::next()
00801 {
00802 if (current.x() == 0 && current.y() == 0)
00803 {
00804 return first();
00805 }
00806
00807 Cell* cell = NULL;
00808 bool done = false;
00809
00810 while (cell == NULL && !done)
00811 {
00812 cell = sheet->getNextCellRight(current.x(), current.y());
00813 if (cell != NULL && cell->column() > range.right())
00814 {
00815 cell = NULL;
00816 }
00817
00818 if (cell == NULL)
00819 {
00820 current.setX(range.left() - 1);
00821 current.setY(current.y() + 1);
00822 done = (current.y() > range.bottom());
00823 }
00824 }
00825 return cell;
00826 }
00827
00828
00829 int KSpread::util_penCompare( QPen const & pen1, QPen const & pen2 )
00830 {
00831 if ( pen1.style() == Qt::NoPen && pen2.style() == Qt::NoPen )
00832 return 0;
00833
00834 if ( pen1.style() == Qt::NoPen )
00835 return -1;
00836
00837 if ( pen2.style() == Qt::NoPen )
00838 return 1;
00839
00840 if ( pen1.width() < pen2.width() )
00841 return -1;
00842
00843 if ( pen1.width() > pen2.width() )
00844 return 1;
00845
00846 if ( pen1.style() < pen2.style() )
00847 return -1;
00848
00849 if ( pen1.style() > pen2.style() )
00850 return 1;
00851
00852 if ( pen1.color().name() < pen2.color().name() )
00853 return -1;
00854
00855 if ( pen1.color().name() > pen2.color().name() )
00856 return 1;
00857
00858 return 0;
00859 }
00860
00861
00862 QString KSpread::convertRefToBase( const QString & sheet, const QRect & rect )
00863 {
00864 QPoint bottomRight( rect.bottomRight() );
00865
00866 QString s( "$" );
00867 s += sheet;
00868 s += ".$";
00869 s += Cell::columnName( bottomRight.x() );
00870 s += '$';
00871 s += QString::number( bottomRight.y() );
00872
00873 return s;
00874 }
00875
00876 QString KSpread::convertRefToRange( const QString & sheet, const QRect & rect )
00877 {
00878 QPoint topLeft( rect.topLeft() );
00879 QPoint bottomRight( rect.bottomRight() );
00880
00881 if ( topLeft == bottomRight )
00882 return convertRefToBase( sheet, rect );
00883
00884 QString s( "$" );
00885 s += sheet;
00886 s += ".$";
00887 s += Cell::columnName( topLeft.x() );
00888 s += '$';
00889 s += QString::number( topLeft.y() );
00890 s += ":.$";
00891 s += Cell::columnName( bottomRight.x() );
00892 s += '$';
00893 s += QString::number( bottomRight.y() );
00894
00895 return s;
00896 }
00897
00898
00899 void KSpread::insertBracket( QString & s )
00900 {
00901 QChar c;
00902 int i = (int) s.length() - 1;
00903
00904 while ( i >= 0 )
00905 {
00906 c = s[i];
00907 if ( c == ' ' )
00908 s[i] = '_';
00909 if ( !(c.isLetterOrNumber() || c == ' ' || c == '.'
00910 || c == '_') )
00911 {
00912 s.insert( i + 1, '[' );
00913 return;
00914 }
00915 --i;
00916 }
00917 }
00918
00919
00920
00921 QString KSpread::convertRangeToRef( const QString & sheetName, const QRect & _area )
00922 {
00923 return sheetName + "." + Cell::name( _area.left(), _area.top() ) + ":" + sheetName + "."+ Cell::name( _area.right(), _area.bottom() );
00924 }
00925
00926 QString KSpread::convertOasisPenToString( const QPen & pen )
00927 {
00928 kdDebug()<<"convertOasisPenToString( const QPen & pen ) :"<<pen<<endl;
00929 QString s = QString( "%1pt " ).arg( pen.width() );
00930 switch( pen.style() )
00931 {
00932 case Qt::NoPen:
00933 return "none";
00934 case Qt::SolidLine:
00935 s+="solid";
00936 break;
00937 case Qt::DashLine:
00938 s+="dashed";
00939 break;
00940 case Qt::DotLine:
00941 s+="dotted";
00942 break;
00943 case Qt::DashDotLine:
00944 s+="dot-dash";
00945 break;
00946 case Qt::DashDotDotLine:
00947 s+="dot-dot-dash";
00948 break;
00949 default: break;
00950 }
00951 kdDebug()<<" convertOasisPenToString :"<<s<<endl;
00952 if ( pen.color().isValid() )
00953 {
00954 s+=' ';
00955 s+=Style::colorName(pen.color());
00956 }
00957 return s;
00958 }
00959
00960 QPen KSpread::convertOasisStringToPen( const QString &border )
00961 {
00962 QPen pen;
00963
00964 if (border.isEmpty() || border=="none" || border=="hidden")
00965 {
00966 pen.setStyle( Qt::NoPen );
00967 return pen;
00968 }
00969
00970
00971 QString _width = border.section(' ', 0, 0);
00972 QCString _style = border.section(' ', 1, 1).latin1();
00973 QString _color = border.section(' ', 2, 2);
00974
00975 pen.setWidth( ( int )( KoUnit::parseValue( _width, 1.0 ) ) );
00976
00977 if ( _style =="none" )
00978 pen.setStyle( Qt::NoPen );
00979 else if ( _style =="solid" )
00980 pen.setStyle( Qt::SolidLine );
00981 else if ( _style =="dashed" )
00982 pen.setStyle( Qt::DashLine );
00983 else if ( _style =="dotted" )
00984 pen.setStyle( Qt::DotLine );
00985 else if ( _style =="dot-dash" )
00986 pen.setStyle( Qt::DashDotLine );
00987 else if ( _style =="dot-dot-dash" )
00988 pen.setStyle( Qt::DashDotDotLine );
00989 else
00990 kdDebug()<<" style undefined : "<<_style<<endl;
00991
00992 if ( _color.isEmpty() )
00993 pen.setColor( QColor() );
00994 else
00995 pen.setColor( QColor( _color ) );
00996
00997 return pen;
00998 }
00999
01000
01001 bool KSpread::localReferenceAnchor( const QString &_ref )
01002 {
01003 bool isLocalRef = (_ref.find("http://") != 0 &&
01004 _ref.find("mailto:") != 0 &&
01005 _ref.find("ftp://") != 0 &&
01006 _ref.find("file:") != 0 );
01007 return isLocalRef;
01008 }
01009
01010
01011 QString KSpread::Oasis::decodeFormula(const QString& expr, const KLocale* locale)
01012 {
01013
01014 enum { Start, InNumber, InString, InIdentifier, InReference, InSheetName } state;
01015
01016
01017 QString decimal = locale ? locale->decimalSymbol() : ".";
01018
01019
01020 state = Start;
01021 unsigned int i = 0;
01022 const QString ex = expr;
01023 QString result;
01024
01025 if (ex[0] == '=')
01026 {
01027 result="=";
01028 ++i;
01029 }
01030
01031
01032 while( i < ex.length() )
01033 {
01034 QChar ch = ex[i];
01035
01036 switch( state )
01037 {
01038 case Start:
01039 {
01040
01041 if( ch.isDigit() )
01042 {
01043 state = InNumber;
01044 }
01045
01046
01047 else if ( ch == '"' )
01048 {
01049 state = InString;
01050 result.append( ex[i++] );
01051 }
01052
01053
01054
01055 else if( isIdentifier( ch ) )
01056 {
01057 state = InIdentifier;
01058 }
01059
01060
01061 else if ( ch.unicode() == '[' )
01062 {
01063 ++i;
01064 state = InReference;
01065 }
01066
01067
01068 else if ( ch == '.' )
01069 {
01070 state = InNumber;
01071 }
01072
01073
01074 else
01075 {
01076 int op;
01077 QString s;
01078
01079
01080 s.append( ch ).append( ex[i+1] );
01081 op = matchOperator( s );
01082
01083
01084 if( op == Token::InvalidOp )
01085 {
01086 s = QString( ch );
01087 op = matchOperator( s );
01088 }
01089
01090
01091 if ( op == Token::Equal )
01092 {
01093 result.append( "==" );
01094 }
01095 else
01096 {
01097 result.append( s );
01098 }
01099 if( op != Token::InvalidOp )
01100 {
01101 int len = s.length();
01102 i += len;
01103 }
01104 else
01105 {
01106 ++i;
01107 state = Start;
01108 }
01109 }
01110 break;
01111 }
01112 case InReference:
01113 {
01114
01115 if( isIdentifier( ch ) || ch.isDigit() || ch == ':' )
01116 result.append( ex[i] );
01117 else if ( ch == '.' && ex[i-1] != '[' && ex[i-1] != ':' )
01118 result.append( '!' );
01119 else if( ch == ']' )
01120 state = Start;
01121 else if ( ch.unicode() == 39 )
01122 {
01123 result.append( ex[i] );
01124 state = InSheetName;
01125 }
01126 ++i;
01127 break;
01128 }
01129 case InSheetName:
01130 {
01131 if ( ch.unicode() == 39 )
01132 state = InReference;
01133 result.append( ex[i] );
01134 ++i;
01135 break;
01136 }
01137 case InNumber:
01138 {
01139
01140 if( ch.isDigit() )
01141 result.append( ex[i++] );
01142
01143 else if ( ch == '.' )
01144 {
01145 result.append( decimal );
01146 ++i;
01147 }
01148
01149 else if( ch.upper() == 'E' )
01150 {
01151 result.append( 'E' );
01152 ++i;
01153 }
01154
01155 else
01156 state = Start;
01157 break;
01158 }
01159 case InString:
01160 {
01161
01162 if( ch != '"' )
01163 {
01164 result.append( ex[i++] );
01165 }
01166
01167 else
01168 {
01169 result.append( ch );
01170 ++i;
01171 state = Start;
01172 }
01173 break;
01174 }
01175 case InIdentifier:
01176 {
01177
01178 if( isIdentifier( ch ) || ch.isDigit() )
01179 result.append( ex[i++] );
01180
01181 else
01182 state = Start;
01183 break;
01184 }
01185 default:
01186 break;
01187 }
01188 }
01189 return result;
01190 }
01191
01192
01193
01194
01195
01196
01197
01198
01199