28#include "kspread_doc.h"
29#include "kspread_locale.h"
30#include "kspread_map.h"
31#include "kspread_sheet.h"
32#include "kspread_style.h"
33#include "kspread_util.h"
38bool KSpread::formatIsDate (FormatType fmt)
40 return ((fmt == ShortDate_format) || (fmt == TextDate_format) ||
41 (((
int) fmt >= 200) && ((
int) fmt < 300)));
44bool KSpread::formatIsTime (FormatType fmt)
46 return (((
int) fmt >= 50) && ((
int) fmt < 70));
49bool KSpread::formatIsFraction (FormatType fmt)
51 return (((
int) fmt >= 70) && ((
int) fmt < 80));
61 int counterColumn = 0;
62 for ( uint i=0; i < _col.length(); i++ )
64 counterColumn = (int) pow(26.0 ,
static_cast<int>(_col.length() - i - 1));
65 if( (
int)(_col[i]) >=
'A' && (
int)(_col[i]) <=
'Z' )
66 col += counterColumn * ( _col[i].latin1() -
'A' + 1);
67 else if( (
int)(_col[i]) >=
'a' && (
int)(_col[i]) <=
'z' )
68 col += counterColumn * ( _col[i].latin1() -
'A' - offset + 1 );
70 kdDebug(36001) <<
"util_decodeColumnLabelText: Wrong characters in label text for col:'" << _col <<
"'" << endl;
76TQString KSpread::util_rangeColumnName(
const TQRect &_area)
78 return TQString(
"%1:%2")
84TQString KSpread::util_rangeRowName(
const TQRect &_area)
86 return TQString(
"%1:%2")
91TQString KSpread::util_rangeName(
const TQRect &_area)
93 return Cell::name( _area.left(), _area.top() ) +
":" +
97TQString KSpread::util_rangeName(Sheet * _sheet,
const TQRect &_area)
99 return _sheet->sheetName() +
"!" + util_rangeName(_area);
102TQDomElement KSpread::util_createElement(
const TQString & tagName,
const TQFont & font, TQDomDocument & doc )
104 TQDomElement e( doc.createElement( tagName ) );
106 e.setAttribute(
"family", font.family() );
107 e.setAttribute(
"size", font.pointSize() );
108 e.setAttribute(
"weight", font.weight() );
110 e.setAttribute(
"bold",
"yes" );
112 e.setAttribute(
"italic",
"yes" );
113 if ( font.underline() )
114 e.setAttribute(
"underline",
"yes" );
115 if ( font.strikeOut() )
116 e.setAttribute(
"strikeout",
"yes" );
122TQDomElement KSpread::util_createElement(
const TQString & tagname,
const TQPen & pen, TQDomDocument & doc )
124 TQDomElement e( doc.createElement( tagname ) );
125 e.setAttribute(
"color", pen.color().name() );
126 e.setAttribute(
"style", (
int)pen.style() );
127 e.setAttribute(
"width", (
int)pen.width() );
131TQFont KSpread::util_toFont( TQDomElement & element )
134 f.setFamily( element.attribute(
"family" ) );
137 f.setPointSize( element.attribute(
"size").toInt( &ok ) );
141 f.setWeight( element.attribute(
"weight").toInt( &ok ) );
145 if ( element.hasAttribute(
"italic" ) && element.attribute(
"italic") ==
"yes" )
148 if ( element.hasAttribute(
"bold" ) && element.attribute(
"bold") ==
"yes" )
151 if ( element.hasAttribute(
"underline" ) && element.attribute(
"underline") ==
"yes" )
152 f.setUnderline(
true );
154 if ( element.hasAttribute(
"strikeout" ) && element.attribute(
"strikeout") ==
"yes" )
155 f.setStrikeOut(
true );
169TQPen KSpread::util_toPen( TQDomElement & element )
174 p.setStyle( (TQt::PenStyle)element.attribute(
"style").toInt( &ok ) );
178 p.setWidth( element.attribute(
"width").toInt( &ok ) );
182 p.setColor( TQColor( element.attribute(
"color") ) );
187Point::Point(
const TQString & _str)
197TQPoint Point::pos()
const
205KSpread::Sheet* Point::sheet()
const
213TQString Point::sheetName()
const
219 _columnFixed=colFixed;
221bool Point::columnFixed()
const
229bool Point::rowFixed()
const
235void Point::init(
const TQString & _str)
243 uint len = _str.length();
246 kdDebug(36001) <<
"Point::init: len = 0" << endl;
250 TQString str( _str );
251 int n = _str.find(
'!' );
254 _sheetName = _str.left( n );
255 str = _str.right( len - n - 1 );
268 _columnFixed =
false;
273 kdDebug(36001) <<
"Point::init: no point after '$' (str: '" << str.mid( p ) <<
"'" << endl;
276 if ( str[p] <
'A' || str[p] >
'Z' )
278 if ( str[p] <
'a' || str[p] >
'z' )
280 kdDebug(36001) <<
"Point::init: wrong first character in point (str: '" << str.mid( p ) <<
"'" << endl;
287 int result = str.find( TQRegExp(
"[^A-Za-z]+"), p );
294 kdDebug(36001) <<
"Point::init: no number in string (str: '" << str.mid( p, result ) <<
"'" << endl;
302 kdDebug(36001) <<
"Point::init: column value too high (col: " << x <<
")" << endl;
309 kdDebug(36001) <<
"Point::init: p==len after cols" << endl;
320 kdDebug(36001) <<
"Point::init: p==len after $ of row" << endl;
330 if ( !isdigit( TQChar(str[p++]) ) )
332 kdDebug(36001) <<
"Point::init: no number" << endl;
338 int y = str.mid( p2, p-p2 ).toInt( &ok );
341 kdDebug(36001) <<
"Point::init: Invalid number (str: '" << str.mid( p2, p-p2 ) <<
"'" << endl;
346 kdDebug(36001) <<
"Point::init: row value too high (row: " << y <<
")" << endl;
351 kdDebug(36001) <<
"Point::init: y <= 0" << endl;
354 _pos = TQPoint( x, y );
357bool util_isPointValid( TQPoint point )
361 && point.x() <= KS_colMax
362 && point.y() <= KS_rowMax
369bool util_isRectValid( TQRect rect )
371 if ( util_isPointValid( rect.topLeft() )
372 && util_isPointValid( rect.bottomRight() )
379Point::Point(
const TQString & str,
Map * map,
384 int p2 = str.find(
'!' );
387 _sheetName = str.left( p2++ );
391 if ( !sheet && _sheetName[0] ==
' ' )
393 _sheetName = _sheetName.right( _sheetName.length() - 1 );
401 if ( _sheetName.isEmpty() )
403 kdDebug(36001) <<
"Point: tableName is unknown" << endl;
404 _sheetName =
"unknown";
412 _sheetName = sheet->sheetName();
418 init( str.mid( p ) );
421Cell *Point::cell()
const
423 return _sheet->cellAt(_pos);
426bool Point::operator== (
const Point &cell)
const
429 return (_pos == cell.pos());
432bool Point::operator< (
const Point &cell)
const
435 return (pos().y() < cell.pos().y()) ? true :
436 ((pos().y() == cell.pos().y()) && (pos().x() < cell.pos().x()));
441 if ( _range == otherRange._range
442 && _leftFixed == otherRange._leftFixed
443 && _rightFixed == otherRange._rightFixed
444 && _bottomFixed == otherRange._bottomFixed
445 && _topFixed == otherRange._topFixed
446 && _sheet == otherRange._sheet )
455 _range.setLeft( -1 );
462Range::Range(
const TQString & _str)
467 int p = _str.find(
':');
476 ul =
Point(_str.left(p));
477 lr =
Point(_str.mid(p + 1));
485 _range = TQRect(ul.pos(), lr.pos());
486 _sheetName = ul.sheetName();
488 _leftFixed = ul.columnFixed();
489 _rightFixed = lr.columnFixed();
490 _topFixed = ul.rowFixed();
491 _bottomFixed = lr.rowFixed();
494 Range::Range(
const Range& r )
497 _sheetName = r.sheetName();
501 _leftFixed=r._leftFixed;
502 _rightFixed=r._rightFixed;
503 _topFixed=r._topFixed;
504 _bottomFixed=r._bottomFixed;
507 Range::Range(
const Point& ul,
const Point& lr )
509 _range = TQRect( ul.pos(), lr.pos() );
510 if ( ul.sheetName() != lr.sheetName() )
512 _range.setLeft( -1 );
515 _sheetName = ul.sheetName();
517 _leftFixed = ul.columnFixed();
518 _rightFixed = lr.columnFixed();
519 _topFixed = ul.rowFixed();
520 _bottomFixed = lr.rowFixed();
523Range::Range(
const TQString & str,
Map * map,
530 bool gotNamed =
false;
531 TQString tmp = str.lower();
532 TQValueList < Reference >::Iterator it;
533 TQValueList < Reference > area = map->doc()->listArea();
534 for (it = area.begin(); it != area.end(); ++it) {
535 if ((*it).ref_name.lower() == tmp) {
538 _sheet = map->
findSheet((*it).sheet_name);
549 _bottomFixed =
false;
557 int p2 = str.find(
'!');
560 _sheetName = str.left(p2++);
565 if ( !_sheet && _sheetName[0] ==
' ' )
567 _sheetName = _sheetName.right( _sheetName.length() - 1 );
577 int p3 = str.find(
':', p);
581 Point ul(str.mid(p, p3 - p));
582 Point lr(str.mid(p3 + 1));
583 _range = TQRect(ul.pos(), lr.pos());
585 _leftFixed = ul.columnFixed();
586 _rightFixed = lr.columnFixed();
587 _topFixed = ul.rowFixed();
588 _bottomFixed = lr.rowFixed();
597 result=util_rangeName(_sheet,_range);
601 result=util_rangeName(_range);
606 int pos=result.find(
"!")+1;
611 result.insert(pos,
'$');
619 pos=result.find(
":")+1;
624 result.insert(pos,
'$');
640 pt->setRow(startRow());
641 pt->setColumn(startCol());
652 pt->setRow(endRow());
653 pt->setColumn(endCol());
662 return _range.contains (cell.pos());
667 return _range.intersects (r.
range());
672 return ( _range.left() >= 0 ) &&
673 ( _range.right() >= 0 ) &&
674 ( _sheet != 0 || _sheetName.isEmpty() ) &&
675 ( _range.isValid() ) ;
687bool Range::leftFixed()
const
695bool Range::rightFixed()
const
703bool Range::topFixed()
const
711bool Range::bottomFixed()
const
719KSpread::Sheet* Range::sheet()
const
725 _sheetName=sheetName;
727TQString Range::sheetName()
const
737bool KSpread::util_isAllSelected(
const TQRect &selection)
739 return ( selection.top() == 1 && selection.bottom() == KS_rowMax
740 && selection.left() == 1 && selection.right() == KS_colMax);
743bool KSpread::util_isColumnSelected(
const TQRect &selection)
745 return ( (selection.top() == 1) && (selection.bottom() == KS_rowMax) );
748bool KSpread::util_isRowSelected(
const TQRect &selection)
750 return ( (selection.left() == 1) && (selection.right() == KS_colMax) );
753bool KSpread::util_isRowOrColumnSelected(
const TQRect &selection)
755 return ( (selection.left() == 1) && (selection.right() == KS_colMax)
756 || (selection.top() == 1) && (selection.bottom() == KS_rowMax) );
760bool KSpread::util_validateSheetName(
const TQString &name)
766 for (
unsigned int i = 0; i < name.length(); i++)
768 if ( !(name[i].isLetterOrNumber() ||
769 name[i] ==
' ' || name[i] ==
'.' ||
783 current = TQPoint(0,0);
786RangeIterator::~RangeIterator()
792 current.setY(range.top());
796 current.setX(range.left() - 1);
802 if (current.x() == 0 && current.y() == 0)
810 while (cell == NULL && !done)
812 cell = sheet->getNextCellRight(current.x(), current.y());
813 if (cell != NULL && cell->column() > range.right())
820 current.setX(range.left() - 1);
821 current.setY(current.y() + 1);
822 done = (current.y() > range.bottom());
829int KSpread::util_penCompare( TQPen
const & pen1, TQPen
const & pen2 )
831 if ( pen1.style() == TQt::NoPen && pen2.style() == TQt::NoPen )
834 if ( pen1.style() == TQt::NoPen )
837 if ( pen2.style() == TQt::NoPen )
840 if ( pen1.width() < pen2.width() )
843 if ( pen1.width() > pen2.width() )
846 if ( pen1.style() < pen2.style() )
849 if ( pen1.style() > pen2.style() )
852 if ( pen1.color().name() < pen2.color().name() )
855 if ( pen1.color().name() > pen2.color().name() )
862TQString KSpread::convertRefToBase(
const TQString & sheet,
const TQRect & rect )
864 TQPoint bottomRight( rect.bottomRight() );
871 s += TQString::number( bottomRight.y() );
876TQString KSpread::convertRefToRange(
const TQString & sheet,
const TQRect & rect )
878 TQPoint topLeft( rect.topLeft() );
879 TQPoint bottomRight( rect.bottomRight() );
881 if ( topLeft == bottomRight )
882 return convertRefToBase( sheet, rect );
889 s += TQString::number( topLeft.y() );
893 s += TQString::number( bottomRight.y() );
899void KSpread::insertBracket( TQString & s )
902 int i = (int) s.length() - 1;
909 if ( !(c.isLetterOrNumber() || c ==
' ' || c ==
'.'
912 s.insert( i + 1,
'[' );
921TQString KSpread::convertRangeToRef(
const TQString & sheetName,
const TQRect & _area )
923 return sheetName +
"." +
Cell::name( _area.left(), _area.top() ) +
":" + sheetName +
"."+
Cell::name( _area.right(), _area.bottom() );
926TQString KSpread::convertOasisPenToString(
const TQPen & pen )
936 TQString s = TQString(
"%1pt " ).arg( (pen.width() == 0) ? 1 : pen.width() );
937 switch( pen.style() )
950 case TQt::DashDotLine:
953 case TQt::DashDotDotLine:
958 kdDebug()<<
" convertOasisPenToString :"<<s<<endl;
959 if ( pen.color().isValid() )
967TQPen KSpread::convertOasisStringToPen(
const TQString &border )
971 if (border.isEmpty() || border==
"none" || border==
"hidden")
973 pen.setStyle( TQt::NoPen );
978 TQString _width = border.section(
' ', 0, 0);
979 TQCString _style = border.section(
' ', 1, 1).latin1();
980 TQString _color = border.section(
' ', 2, 2);
982 pen.setWidth( (
int )( KoUnit::parseValue( _width, 1.0 ) ) );
984 if ( _style ==
"none" )
985 pen.setStyle( TQt::NoPen );
986 else if ( _style ==
"solid" )
987 pen.setStyle( TQt::SolidLine );
988 else if ( _style ==
"dashed" )
989 pen.setStyle( TQt::DashLine );
990 else if ( _style ==
"dotted" )
991 pen.setStyle( TQt::DotLine );
992 else if ( _style ==
"dot-dash" )
993 pen.setStyle( TQt::DashDotLine );
994 else if ( _style ==
"dot-dot-dash" )
995 pen.setStyle( TQt::DashDotDotLine );
997 kdDebug()<<
" style undefined : "<<_style<<endl;
999 if ( _color.isEmpty() )
1000 pen.setColor( TQColor() );
1002 pen.setColor( TQColor( _color ) );
1008bool KSpread::localReferenceAnchor(
const TQString &_ref )
1010 bool isLocalRef = (_ref.find(
"http://") != 0 &&
1011 _ref.find(
"mailto:") != 0 &&
1012 _ref.find(
"ftp://") != 0 &&
1013 _ref.find(
"file:") != 0 );
1018TQString KSpread::Oasis::decodeFormula(
const TQString& expr,
const TDELocale* locale)
1021 enum { Start, InNumber, InString, InIdentifier, InReference, InSheetName } state;
1024 TQString decimal = locale ? locale->decimalSymbol() :
".";
1029 const TQString ex = expr;
1039 while( i < ex.length() )
1054 else if ( ch ==
'"' )
1057 result.append( ex[i++] );
1064 state = InIdentifier;
1068 else if ( ch.unicode() ==
'[' )
1071 state = InReference;
1073 if ( ex[i] ==
'$' ) ++i;
1077 else if ( ch ==
'.' )
1079 if ( ex[i+1].isDigit() )
1082 state = InReference;
1092 s.append( ch ).append( ex[i+1] );
1105 result.append(
"==" );
1113 int len = s.length();
1128 result.append( ex[i] );
1129 else if ( ch ==
'.' && i > 0 && ex[i-1] !=
'[' && ex[i-1] !=
':' )
1130 result.append(
'!' );
1131 else if( ch ==
']' )
1133 else if ( ch ==
'\'' )
1135 result.append( ex[i] );
1136 state = InSheetName;
1138 if ( ex[i] ==
'$' ) ++i;
1140 else if ( ch !=
'.' )
1151 state = InReference;
1152 result.append( ex[i] );
1160 result.append( ex[i++] );
1162 else if ( ch ==
'.' )
1164 result.append( decimal );
1168 else if( ch.upper() ==
'E' )
1170 result.append(
'E' );
1183 result.append( ex[i++] );
1188 result.append( ch );
1198 result.append( ex[i++] );
For every cell in the spread sheet there is a Cell object.
TQString name() const
Returns the name of the cell.
TQString columnName() const
Returns the column name of the cell.
A map is a simple container for all sheets.
Sheet * findSheet(const TQString &_name)
searches for a sheet named _name
Represents the position of a single cell in a workbook.
void setSheet(Sheet *sheet)
Sets the sheet which this point lies on.
void setColumnFixed(bool colFixed)
Sets whether or not the column (x coordinate) of this point is fixed (ie.
void setPos(TQPoint pos)
Sets the position of this point (in rows and columns).
void setSheetName(TQString name)
Sets the name of the sheet which this point lies on.
void setRowFixed(bool rowFixed)
Sets whether or not the row (y coordinate) of this point is fixed (ie.
RangeIterator(TQRect _range, Sheet *_sheet)
Contstruct the iterator with the rectangular cell area and which sheet the area is on.
Represents a region within a workbook.
void setRightFixed(bool fixed)
Sets whether or not the right column is fixed.
bool isValid() const
Returns true if this Range represents a valid region of a spreadsheet.
void setSheet(Sheet *sheet)
Sets the Sheet object associated with this range.
bool operator==(const Range &range) const
Returns true if the other range occupies the same area on the same sheet as this range.
void setBottomFixed(bool fixed)
Sets whether or not the bottom row is fixed.
bool intersects(const Range &r) const
Returns true if this range intersects Range r (ie.
void getStartPoint(Point *pt)
Fills a Point with info (row,column,sheet) about the first point in the range.
void setSheetName(TQString sheetName)
Sets the name of the sheet associated with this range.
void setLeftFixed(bool fixed)
Sets whether or not the left column is fixed .
bool contains(const Point &cell) const
Returns true if this range includes the specified cell.
TQString namedArea() const
Returns the named area represented by this range or an empty string otherwise.
void setTopFixed(bool fixed)
Sets whether or not the top row is fixed.
void getEndPoint(Point *pt)
Fills a Point with info (row,column,sheet) about the last point the range.
TQString toString() const
Returns a string representation of this range as it would appear in a formula.
TQRect range() const
Returns the area on the spreadsheet occupied by this range.
static TQString colorName(const TQColor &color)
Returns the name of a colour.
@ InvalidOp
invalid operator
KSPREAD_EXPORT int util_decodeColumnLabelText(const TQString &_col)
Call this function to decode the text of a column label to an integer i.e.
bool isIdentifier(TQChar ch)
helper function: return true for valid identifier character
Token::Op matchOperator(const TQString &text)
helper function: return operator of given token text e.g.