/* This file is part of the KDE project
Copyright 1998 , 1999 Torben Weis < weis @ kde . org >
Copyright 1999 - 2006 The KSpread Team
www . koffice . org / kspread
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 <assert.h>
# include <ctype.h>
# include <float.h>
# include <math.h>
# include <pwd.h>
# include <stdlib.h>
# include <unistd.h>
# include <tqapplication.h>
# include <tqcheckbox.h>
# include <tqclipboard.h>
# include <tqlabel.h>
# include <tqlayout.h>
# include <tqlineedit.h>
# include <tqpicture.h>
# include <tqregexp.h>
# include <tqvbox.h>
# include <tqmap.h>
# include <kdebug.h>
# include <kmdcodec.h>
# include <kfind.h>
# include <kfinddialog.h>
# include <tdemessagebox.h>
# include <kreplace.h>
# include <kreplacedialog.h>
# include <kprinter.h>
# include <kurl.h>
# include <koChart.h>
# include <KoDom.h>
# include <KoDocumentInfo.h>
# include <KoOasisLoadingContext.h>
# include <KoOasisSettings.h>
# include <KoOasisStyles.h>
# include <KoQueryTrader.h>
# include <KoStyleStack.h>
# include <KoUnit.h>
# include <KoXmlNS.h>
# include <KoXmlWriter.h>
# include "commands.h"
# include "dependencies.h"
# include "selection.h"
# include "ksploadinginfo.h"
# include "ksprsavinginfo.h"
# include "kspread_canvas.h"
# include "kspread_cluster.h"
# include "kspread_condition.h"
# include "kspread_doc.h"
# include "kspread_global.h"
# include "kspread_locale.h"
# include "kspread_map.h"
# include "kspread_object.h"
# include "kspread_sheetprint.h"
# include "kspread_style.h"
# include "kspread_style_manager.h"
# include "kspread_undo.h"
# include "kspread_util.h"
# include "kspread_view.h"
# include "manipulator.h"
# include "manipulator_data.h"
# include "KSpreadTableIface.h"
# include "kspread_sheet.h"
# include "kspread_sheet.moc"
# define NO_MODIFICATION_POSSIBLE \
do { \
KMessageBox : : error ( 0 , i18n ( " You cannot change a protected sheet " ) ) ; return ; \
} while ( 0 )
namespace KSpread {
/*****************************************************************************
*
* CellBinding
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
CellBinding : : CellBinding ( Sheet * _sheet , const TQRect & _area )
{
m_rctDataArea = _area ;
m_pSheet = _sheet ;
m_pSheet - > addCellBinding ( this ) ;
m_bIgnoreChanges = false ;
}
CellBinding : : ~ CellBinding ( )
{
m_pSheet - > removeCellBinding ( this ) ;
}
void CellBinding : : cellChanged ( Cell * _cell )
{
if ( m_bIgnoreChanges )
return ;
emit changed ( _cell ) ;
}
bool CellBinding : : contains ( int _x , int _y )
{
return m_rctDataArea . contains ( TQPoint ( _x , _y ) ) ;
}
/*****************************************************************************
*
* ChartBinding
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
ChartBinding : : ChartBinding ( Sheet * _sheet , const TQRect & _area , EmbeddedChart * _child )
: CellBinding ( _sheet , _area )
{
m_child = _child ;
}
ChartBinding : : ~ ChartBinding ( )
{
}
void ChartBinding : : cellChanged ( Cell * /*changedCell*/ )
{
if ( m_bIgnoreChanges )
return ;
//Ensure display gets updated by marking all cells underneath the chart as
//dirty
const TQRect chartGeometry = m_child - > geometry ( ) . toTQRect ( ) ;
double tmp ;
int left = sheet ( ) - > leftColumn ( chartGeometry . left ( ) , tmp ) ;
int top = sheet ( ) - > topRow ( chartGeometry . top ( ) , tmp ) ;
int right = sheet ( ) - > rightColumn ( chartGeometry . right ( ) ) ;
int bottom = sheet ( ) - > bottomRow ( chartGeometry . bottom ( ) ) ;
sheet ( ) - > setRegionPaintDirty ( TQRect ( left , top , right - left , bottom - top ) ) ;
//kdDebug(36001) << m_rctDataArea << endl;
// Get the chart and resize its data if necessary.
//
// FIXME: Only do this if he data actually changed size.
KoChart : : Part * chart = m_child - > chart ( ) ;
chart - > resizeData ( m_rctDataArea . height ( ) , m_rctDataArea . width ( ) ) ;
// Reset all the data, i.e. retransfer them to the chart.
// This is definitely not the most efficient way to do this.
//
// FIXME: Find a way to do it with just the data that changed.
Cell * cell ;
for ( int row = 0 ; row < m_rctDataArea . height ( ) ; row + + ) {
for ( int col = 0 ; col < m_rctDataArea . width ( ) ; col + + ) {
cell = m_pSheet - > cellAt ( m_rctDataArea . left ( ) + col ,
m_rctDataArea . top ( ) + row ) ;
if ( cell & & cell - > value ( ) . isNumber ( ) )
chart - > setCellData ( row , col , cell - > value ( ) . asFloat ( ) ) ;
else if ( cell )
chart - > setCellData ( row , col , cell - > value ( ) . asString ( ) ) ;
else
chart - > setCellData ( row , col , KoChart : : Value ( ) ) ;
}
}
chart - > analyzeHeaders ( ) ;
// ######### Kalle may be interested in that, too
#if 0
Chart : : Range range ;
range . top = m_rctDataArea . top ( ) ;
range . left = m_rctDataArea . left ( ) ;
range . right = m_rctDataArea . right ( ) ;
range . bottom = m_rctDataArea . bottom ( ) ;
range . sheet = m_pSheet - > name ( ) ; */
//m_child->chart()->setData( matrix );
// Force a redraw of the chart on all views
/** TODO - replace the call below with something that will repaint this chart */
# endif
// sheet()->emit_polygonInvalidated( m_child->framePointArray() );
}
/******************************************************************/
/* Class: TextDrag */
/******************************************************************/
TextDrag : : TextDrag ( TQWidget * dragSource , const char * name )
: TQTextDrag ( dragSource , name )
{
}
TextDrag : : ~ TextDrag ( )
{
}
TQByteArray TextDrag : : encodedData ( const char * mime ) const
{
if ( strcmp ( selectionMimeType ( ) , mime ) = = 0 )
return m_kspread ;
else
return TQTextDrag : : encodedData ( mime ) ;
}
bool TextDrag : : canDecode ( TQMimeSource * e )
{
if ( e - > provides ( selectionMimeType ( ) ) )
return true ;
return TQTextDrag : : canDecode ( e ) ;
}
const char * TextDrag : : format ( int i ) const
{
if ( i < 4 ) // HACK, but how to do otherwise ??
return TQTextDrag : : format ( i ) ;
else if ( i = = 4 )
return selectionMimeType ( ) ;
else return 0 ;
}
const char * TextDrag : : selectionMimeType ( )
{
return " application/x-kspread-snippet " ;
}
/*****************************************************************************
*
* Sheet
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
class Sheet : : Private
{
public :
Map * workbook ;
DCOPObject * dcop ;
TQString name ;
int id ;
Sheet : : LayoutDirection layoutDirection ;
// true if sheet is hidden
bool hide ;
// password of protected sheet
TQCString password ;
bool showGrid ;
bool showFormula ;
bool showFormulaIndicator ;
bool showCommentIndicator ;
bool autoCalc ;
bool lcMode ;
bool showColumnNumber ;
bool hideZero ;
bool firstLetterUpper ;
// clusters to hold objects
Cluster cells ;
RowCluster rows ;
ColumnCluster columns ;
// default objects
Cell * defaultCell ;
Format * defaultFormat ;
RowFormat * defaultRowFormat ;
ColumnFormat * defaultColumnFormat ;
// hold the print object
SheetPrint * print ;
// cells that need painting
Region paintDirtyList ;
// to get font metrics
TQPainter * painter ;
TQWidget * widget ;
// List of all cell bindings. For example charts use bindings to get
// informed about changing cell contents.
TQPtrList < CellBinding > cellBindings ;
// Indicates whether the sheet should paint the page breaks.
// Doing so costs some time, so by default it should be turned off.
bool showPageBorders ;
// List of all embedded objects. FIXME unused ??
// TQPtrList<Child> m_lstChildren;
// The highest row and column ever accessed by the user.
int maxRow ;
int maxColumn ;
// Max range of canvas in x and ye direction.
// Depends on KS_colMax/KS_rowMax and the width/height of all columns/rows
double sizeMaxX ;
double sizeMaxY ;
bool scrollBarUpdates ;
TQPen emptyPen ;
TQBrush emptyBrush ;
TQColor emptyColor ;
int scrollPosX ;
int scrollPosY ;
KSpread : : DependencyManager * dependencies ;
} ;
int Sheet : : s_id = 0L ;
TQIntDict < Sheet > * Sheet : : s_mapSheets ;
Sheet * Sheet : : find ( int _id )
{
if ( ! s_mapSheets )
return 0L ;
return ( * s_mapSheets ) [ _id ] ;
}
Sheet : : Sheet ( Map * map ,
const TQString & sheetName , const char * _name )
: TQObject ( map , _name )
{
if ( s_mapSheets = = 0L )
s_mapSheets = new TQIntDict < Sheet > ;
d = new Private ;
d - > workbook = map ;
d - > id = s_id + + ;
s_mapSheets - > insert ( d - > id , this ) ;
d - > layoutDirection = LeftToRight ;
d - > defaultFormat = new Format ( this , d - > workbook - > doc ( ) - > styleManager ( ) - > defaultStyle ( ) ) ;
d - > emptyPen . setStyle ( TQt : : NoPen ) ;
d - > dcop = 0 ;
d - > name = sheetName ;
dcopObject ( ) ;
d - > cellBindings . setAutoDelete ( false ) ;
// m_lstChildren.setAutoDelete( true );
d - > cells . setAutoDelete ( true ) ;
d - > rows . setAutoDelete ( true ) ;
d - > columns . setAutoDelete ( true ) ;
d - > defaultCell = new Cell ( this , d - > workbook - > doc ( ) - > styleManager ( ) - > defaultStyle ( ) , 0 , 0 ) ;
d - > defaultRowFormat = new RowFormat ( this , 0 ) ;
d - > defaultRowFormat - > setDefault ( ) ;
d - > defaultColumnFormat = new ColumnFormat ( this , 0 ) ;
d - > defaultColumnFormat - > setDefault ( ) ;
d - > widget = new TQWidget ( ) ;
d - > painter = new TQPainter ;
d - > painter - > begin ( d - > widget ) ;
d - > maxColumn = 256 ;
d - > maxRow = 256 ;
d - > sizeMaxX = KS_colMax * d - > defaultColumnFormat - > dblWidth ( ) ; // default is max cols * default width
d - > sizeMaxY = KS_rowMax * d - > defaultRowFormat - > dblHeight ( ) ; // default is max rows * default height
d - > scrollBarUpdates = true ;
setHidden ( false ) ;
d - > showGrid = true ;
d - > showFormula = false ;
d - > showFormulaIndicator = true ;
d - > showCommentIndicator = true ;
d - > showPageBorders = false ;
d - > lcMode = false ;
d - > showColumnNumber = false ;
d - > hideZero = false ;
d - > firstLetterUpper = false ;
d - > autoCalc = true ;
// Get a unique name so that we can offer scripting
if ( ! _name )
{
TQCString s ;
s . sprintf ( " Sheet%i " , s_id ) ;
TQObject : : setName ( s . data ( ) ) ;
}
d - > print = new SheetPrint ( this ) ;
// initialize dependencies
d - > dependencies = new KSpread : : DependencyManager ( this ) ;
// connect to named area slots
TQObject : : connect ( doc ( ) , TQT_SIGNAL ( sig_addAreaName ( const TQString & ) ) ,
this , TQT_SLOT ( slotAreaModified ( const TQString & ) ) ) ;
TQObject : : connect ( doc ( ) , TQT_SIGNAL ( sig_removeAreaName ( const TQString & ) ) ,
this , TQT_SLOT ( slotAreaModified ( const TQString & ) ) ) ;
}
TQString Sheet : : sheetName ( ) const
{
return d - > name ;
}
Map * Sheet : : workbook ( ) const
{
return d - > workbook ;
}
Doc * Sheet : : doc ( ) const
{
return d - > workbook - > doc ( ) ;
}
int Sheet : : id ( ) const
{
return d - > id ;
}
Sheet : : LayoutDirection Sheet : : layoutDirection ( ) const
{
return d - > layoutDirection ;
}
void Sheet : : setLayoutDirection ( LayoutDirection dir )
{
d - > layoutDirection = dir ;
}
bool Sheet : : isRightToLeft ( ) const
{
return d - > layoutDirection = = RightToLeft ;
}
bool Sheet : : isHidden ( ) const
{
return d - > hide ;
}
void Sheet : : setHidden ( bool hidden )
{
d - > hide = hidden ;
}
bool Sheet : : getShowGrid ( ) const
{
return d - > showGrid ;
}
void Sheet : : setShowGrid ( bool _showGrid )
{
d - > showGrid = _showGrid ;
}
bool Sheet : : getShowFormula ( ) const
{
return d - > showFormula ;
}
void Sheet : : setShowFormula ( bool _showFormula )
{
d - > showFormula = _showFormula ;
}
bool Sheet : : getShowFormulaIndicator ( ) const
{
return d - > showFormulaIndicator ;
}
void Sheet : : setShowFormulaIndicator ( bool _showFormulaIndicator )
{
d - > showFormulaIndicator = _showFormulaIndicator ;
}
bool Sheet : : getShowCommentIndicator ( ) const
{
return d - > showCommentIndicator ;
}
void Sheet : : setShowCommentIndicator ( bool _indic )
{
d - > showCommentIndicator = _indic ;
}
bool Sheet : : getLcMode ( ) const
{
return d - > lcMode ;
}
void Sheet : : setLcMode ( bool _lcMode )
{
d - > lcMode = _lcMode ;
}
bool Sheet : : getAutoCalc ( ) const
{
return d - > autoCalc ;
}
void Sheet : : setAutoCalc ( bool _AutoCalc )
{
//Avoid possible recalculation of dependancies if the auto calc setting hasn't changed
if ( d - > autoCalc = = _AutoCalc )
return ;
//If enabling automatic calculation, make sure that the dependencies are up-to-date
if ( _AutoCalc = = true )
{
updateAllDependencies ( ) ;
recalc ( ) ;
}
d - > autoCalc = _AutoCalc ;
}
bool Sheet : : getShowColumnNumber ( ) const
{
return d - > showColumnNumber ;
}
void Sheet : : setShowColumnNumber ( bool _showColumnNumber )
{
d - > showColumnNumber = _showColumnNumber ;
}
bool Sheet : : getHideZero ( ) const
{
return d - > hideZero ;
}
void Sheet : : setHideZero ( bool _hideZero )
{
d - > hideZero = _hideZero ;
}
bool Sheet : : getFirstLetterUpper ( ) const
{
return d - > firstLetterUpper ;
}
void Sheet : : setFirstLetterUpper ( bool _firstUpper )
{
d - > firstLetterUpper = _firstUpper ;
}
bool Sheet : : isShowPageBorders ( ) const
{
return d - > showPageBorders ;
}
bool Sheet : : isEmpty ( unsigned long int x , unsigned long int y ) const
{
const Cell * c = cellAt ( x , y ) ;
if ( ! c | | c - > isEmpty ( ) )
return true ;
return false ;
}
Cell * Sheet : : defaultCell ( ) const
{
return d - > defaultCell ;
}
Format * Sheet : : defaultFormat ( )
{
return d - > defaultFormat ;
}
const Format * Sheet : : defaultFormat ( ) const
{
return d - > defaultFormat ;
}
const ColumnFormat * Sheet : : columnFormat ( int _column ) const
{
const ColumnFormat * p = d - > columns . lookup ( _column ) ;
if ( p ! = 0L )
return p ;
return d - > defaultColumnFormat ;
}
ColumnFormat * Sheet : : columnFormat ( int _column )
{
ColumnFormat * p = d - > columns . lookup ( _column ) ;
if ( p ! = 0L )
return p ;
return d - > defaultColumnFormat ;
}
const RowFormat * Sheet : : rowFormat ( int _row ) const
{
const RowFormat * p = d - > rows . lookup ( _row ) ;
if ( p ! = 0L )
return p ;
return d - > defaultRowFormat ;
}
RowFormat * Sheet : : rowFormat ( int _row )
{
RowFormat * p = d - > rows . lookup ( _row ) ;
if ( p ! = 0L )
return p ;
return d - > defaultRowFormat ;
}
Value Sheet : : value ( int col , int row ) const
{
Cell * cell = d - > cells . lookup ( col , row ) ;
if ( cell )
return cell - > value ( ) ;
Value empty ;
return empty ;
}
Value Sheet : : valueRange ( int col1 , int row1 ,
int col2 , int row2 ) const
{
return d - > cells . valueRange ( col1 , row1 , col2 , row2 ) ;
}
void Sheet : : password ( TQCString & passwd ) const
{
passwd = d - > password ;
}
bool Sheet : : isProtected ( ) const
{
return ! d - > password . isNull ( ) ;
}
void Sheet : : setProtected ( TQCString const & passwd )
{
d - > password = passwd ;
}
bool Sheet : : checkPassword ( TQCString const & passwd ) const
{
return ( passwd = = d - > password ) ;
}
SheetPrint * Sheet : : print ( ) const
{
return d - > print ;
}
TQPainter & Sheet : : painter ( )
{
return * d - > painter ;
}
TQWidget * Sheet : : widget ( ) const
{
return d - > widget ;
}
CellBinding * Sheet : : firstCellBinding ( )
{
return d - > cellBindings . first ( ) ;
}
CellBinding * Sheet : : nextCellBinding ( )
{
return d - > cellBindings . next ( ) ;
}
void Sheet : : setDefaultHeight ( double height )
{
if ( isProtected ( ) )
NO_MODIFICATION_POSSIBLE ;
d - > defaultRowFormat - > setDblHeight ( height ) ;
}
void Sheet : : setDefaultWidth ( double width )
{
if ( isProtected ( ) )
NO_MODIFICATION_POSSIBLE ;
d - > defaultColumnFormat - > setDblWidth ( width ) ;
}
double Sheet : : sizeMaxX ( ) const
{
return d - > sizeMaxX ;
}
double Sheet : : sizeMaxY ( ) const
{
return d - > sizeMaxY ;
}
int Sheet : : maxColumn ( ) const
{
return d - > maxColumn ;
}
int Sheet : : maxRow ( ) const
{
return d - > maxRow ;
}
const TQPen & Sheet : : emptyPen ( ) const
{
return d - > emptyPen ;
}
const TQBrush & Sheet : : emptyBrush ( ) const
{
return d - > emptyBrush ;
}
const TQColor & Sheet : : emptyColor ( ) const
{
return d - > emptyColor ;
}
KSpread : : DependencyManager * Sheet : : dependencies ( )
{
return d - > dependencies ;
}
int Sheet : : numSelected ( ) const
{
int num = 0 ;
TQPtrListIterator < EmbeddedObject > it ( d - > workbook - > doc ( ) - > embeddedObjects ( ) ) ;
for ( ; it . current ( ) ; + + it )
{
if ( it . current ( ) - > sheet ( ) = = this & & it . current ( ) - > isSelected ( ) )
num + + ;
}
return num ;
}
int Sheet : : leftColumn ( double _xpos , double & _left ,
const Canvas * _canvas ) const
{
if ( _canvas )
{
_xpos + = _canvas - > xOffset ( ) ;
_left = - _canvas - > xOffset ( ) ;
}
else
_left = 0.0 ;
int col = 1 ;
double x = columnFormat ( col ) - > dblWidth ( _canvas ) ;
while ( x < _xpos )
{
// Should never happen
if ( col > = KS_colMax )
{
kdDebug ( 36001 ) < < " Sheet:leftColumn: invalid column (col: " < < col + 1 < < " ) " < < endl ;
return KS_colMax + 1 ; //Return out of range value, so other code can react on this
}
_left + = columnFormat ( col ) - > dblWidth ( _canvas ) ;
col + + ;
x + = columnFormat ( col ) - > dblWidth ( _canvas ) ;
}
return col ;
}
int Sheet : : rightColumn ( double _xpos , const Canvas * _canvas ) const
{
if ( _canvas )
_xpos + = _canvas - > xOffset ( ) ;
int col = 1 ;
double x = 0.0 ;
while ( x < _xpos )
{
// Should never happen
if ( col > KS_colMax )
{
kdDebug ( 36001 ) < < " Sheet:rightColumn: invalid column (col: " < < col < < " ) " < < endl ;
return KS_colMax + 1 ; //Return out of range value, so other code can react on this
}
x + = columnFormat ( col ) - > dblWidth ( _canvas ) ;
col + + ;
}
return col - 1 ;
}
TQRect Sheet : : visibleRect ( Canvas const * const _canvas ) const
{
int top = 0 ;
int left = 0 ;
double x = 0 ;
double y = 0 ;
double width = 0 ;
double height = 0 ;
if ( _canvas )
{
y + = _canvas - > yOffset ( ) * _canvas - > zoom ( ) ;
x + = _canvas - > xOffset ( ) * _canvas - > zoom ( ) ;
width = _canvas - > width ( ) ;
height = _canvas - > height ( ) ;
}
double yn = rowFormat ( top ) - > dblHeight ( _canvas ) ;
while ( yn < y )
{
if ( top > = KS_rowMax ) // Should never happen
break ;
+ + top ;
yn + = rowFormat ( top ) - > dblHeight ( _canvas ) ;
}
int bottom = top + 1 ;
y + = height ;
while ( yn < y )
{
if ( bottom > KS_rowMax ) // Should never happen
break ;
+ + bottom ;
yn + = rowFormat ( bottom ) - > dblHeight ( _canvas ) ;
}
double xn = columnFormat ( left ) - > dblWidth ( _canvas ) ;
while ( xn < x )
{
if ( left > = KS_colMax ) // Should never happen
break ;
+ + left ;
xn + = columnFormat ( left ) - > dblWidth ( _canvas ) ;
}
x + = width ;
int right = left + 1 ;
while ( xn < x )
{
if ( right > KS_colMax ) // Should never happen
break ;
+ + right ;
xn + = columnFormat ( right ) - > dblWidth ( _canvas ) ;
}
x + = width ;
return TQRect ( left , top , right - left + 1 , bottom - top + 1 ) ;
}
int Sheet : : topRow ( double _ypos , double & _top ,
const Canvas * _canvas ) const
{
if ( _canvas )
{
_ypos + = _canvas - > yOffset ( ) ;
_top = - _canvas - > yOffset ( ) ;
}
else
_top = 0.0 ;
int row = 1 ;
double y = rowFormat ( row ) - > dblHeight ( _canvas ) ;
while ( y < _ypos )
{
// Should never happen
if ( row > = KS_rowMax )
{
kdDebug ( 36001 ) < < " Sheet:topRow: invalid row (row: " < < row + 1 < < " ) " < < endl ;
return KS_rowMax + 1 ; //Return out of range value, so other code can react on this
}
_top + = rowFormat ( row ) - > dblHeight ( _canvas ) ;
row + + ;
y + = rowFormat ( row ) - > dblHeight ( _canvas ) ;
}
return row ;
}
int Sheet : : bottomRow ( double _ypos , const Canvas * _canvas ) const
{
if ( _canvas )
_ypos + = _canvas - > yOffset ( ) ;
int row = 1 ;
double y = 0.0 ;
while ( y < _ypos )
{
// Should never happen
if ( row > KS_rowMax )
{
kdDebug ( 36001 ) < < " Sheet:bottomRow: invalid row (row: " < < row < < " ) " < < endl ;
return KS_rowMax + 1 ; //Return out of range value, so other code can react on this
}
y + = rowFormat ( row ) - > dblHeight ( _canvas ) ;
row + + ;
}
return row - 1 ;
}
double Sheet : : dblColumnPos ( int _col , const Canvas * _canvas ) const
{
double x = 0.0 ;
if ( _canvas )
x - = _canvas - > xOffset ( ) ;
for ( int col = 1 ; col < _col ; col + + )
{
// Should never happen
if ( col > KS_colMax )
{
kdDebug ( 36001 ) < < " Sheet:columnPos: invalid column (col: " < < col < < " ) " < < endl ;
return x ;
}
x + = columnFormat ( col ) - > dblWidth ( _canvas ) ;
}
return x ;
}
int Sheet : : columnPos ( int _col , const Canvas * _canvas ) const
{
return ( int ) dblColumnPos ( _col , _canvas ) ;
}
double Sheet : : dblRowPos ( int _row , const Canvas * _canvas ) const
{
double y = 0.0 ;
if ( _canvas )
y - = _canvas - > yOffset ( ) ;
for ( int row = 1 ; row < _row ; row + + )
{
// Should never happen
if ( row > KS_rowMax )
{
kdDebug ( 36001 ) < < " Sheet:rowPos: invalid row (row: " < < row < < " ) " < < endl ;
return y ;
}
y + = rowFormat ( row ) - > dblHeight ( _canvas ) ;
}
return y ;
}
int Sheet : : rowPos ( int _row , const Canvas * _canvas ) const
{
return ( int ) dblRowPos ( _row , _canvas ) ;
}
void Sheet : : adjustSizeMaxX ( double _x )
{
d - > sizeMaxX + = _x ;
}
void Sheet : : adjustSizeMaxY ( double _y )
{
d - > sizeMaxY + = _y ;
}
Cell * Sheet : : visibleCellAt ( int _column , int _row , bool _scrollbar_update )
{
Cell * cell = cellAt ( _column , _row , _scrollbar_update ) ;
if ( cell - > obscuringCells ( ) . isEmpty ( ) )
return cell ;
else
return cell - > obscuringCells ( ) . last ( ) ;
}
Cell * Sheet : : firstCell ( ) const
{
return d - > cells . firstCell ( ) ;
}
RowFormat * Sheet : : firstRow ( ) const
{
return d - > rows . first ( ) ;
}
ColumnFormat * Sheet : : firstCol ( ) const
{
return d - > columns . first ( ) ;
}
Cell * Sheet : : cellAt ( int _column , int _row ) const
{
Cell * p = d - > cells . lookup ( _column , _row ) ;
if ( p ! = 0L )
return p ;
return d - > defaultCell ;
}
Cell * Sheet : : cellAt ( int _column , int _row , bool _scrollbar_update )
{
if ( _scrollbar_update & & d - > scrollBarUpdates )
{
checkRangeHBorder ( _column ) ;
checkRangeVBorder ( _row ) ;
}
Cell * p = d - > cells . lookup ( _column , _row ) ;
if ( p ! = 0L )
return p ;
return d - > defaultCell ;
}
ColumnFormat * Sheet : : nonDefaultColumnFormat ( int _column , bool force_creation )
{
ColumnFormat * p = d - > columns . lookup ( _column ) ;
if ( p ! = 0L | | ! force_creation )
return p ;
p = new ColumnFormat ( this , _column ) ;
// TODO: copy the default ColumnFormat here!!
p - > setDblWidth ( d - > defaultColumnFormat - > dblWidth ( ) ) ;
d - > columns . insertElement ( p , _column ) ;
return p ;
}
RowFormat * Sheet : : nonDefaultRowFormat ( int _row , bool force_creation )
{
RowFormat * p = d - > rows . lookup ( _row ) ;
if ( p ! = 0L | | ! force_creation )
return p ;
p = new RowFormat ( this , _row ) ;
// TODO: copy the default RowLFormat here!!
p - > setDblHeight ( d - > defaultRowFormat - > dblHeight ( ) ) ;
d - > rows . insertElement ( p , _row ) ;
return p ;
}
Cell * Sheet : : nonDefaultCell ( int _column , int _row ,
bool _scrollbar_update , Style * _style )
{
// NOTE Stefan: _scrollbar_update defaults to false and this function
// is never called with it being true. So, this here is
// actually never processed. I'll leave this in here for the
// case I'm mistaken, but will remove it for 2.0.
if ( _scrollbar_update & & d - > scrollBarUpdates )
{
checkRangeHBorder ( _column ) ;
checkRangeVBorder ( _row ) ;
}
Cell * p = d - > cells . lookup ( _column , _row ) ;
if ( p ! = 0L )
return p ;
Cell * cell = 0 ;
if ( _style )
cell = new Cell ( this , _style , _column , _row ) ;
else
cell = new Cell ( this , _column , _row ) ;
insertCell ( cell ) ;
return cell ;
}
void Sheet : : setText ( int _row , int _column , const TQString & _text , bool asString )
{
ProtectedCheck prot ;
prot . setSheet ( this ) ;
prot . add ( TQPoint ( _column , _row ) ) ;
if ( prot . check ( ) )
NO_MODIFICATION_POSSIBLE ;
DataManipulator * dm = new DataManipulator ( ) ;
dm - > setSheet ( this ) ;
dm - > setValue ( _text ) ;
dm - > setParsing ( ! asString ) ;
dm - > add ( TQPoint ( _column , _row ) ) ;
dm - > execute ( ) ;
/* PRE-MANIPULATOR CODE looked like this:
TODO remove this after the new code works
if ( ! doc ( ) - > undoLocked ( ) )
{
UndoSetText * undo = new UndoSetText ( doc ( ) , this , cell - > text ( ) , _column , _row , cell - > formatType ( ) ) ;
doc ( ) - > addCommand ( undo ) ;
}
// The cell will force a display refresh itself, so we dont have to care here.
cell - > setCellText ( _text , asString ) ;
*/
//refresh anchor
if ( _text . at ( 0 ) = = ' ! ' )
emit sig_updateView ( this , Region ( _column , _row , _column , _row ) ) ;
}
void Sheet : : setArrayFormula ( Selection * selectionInfo , const TQString & _text )
{
// check protection
ProtectedCheck prot ;
prot . setSheet ( this ) ;
prot . add ( * selectionInfo ) ;
if ( prot . check ( ) )
NO_MODIFICATION_POSSIBLE ;
// create and call the manipulator
ArrayFormulaManipulator * afm = new ArrayFormulaManipulator ;
afm - > setSheet ( this ) ;
afm - > setText ( _text ) ;
afm - > add ( * selectionInfo ) ;
afm - > execute ( ) ;
/* PRE-MANIPULATOR CODE LOOKED LIKE THIS
TODO remove this when the above code works
// add undo
if ( ! doc ( ) - > undoLocked ( ) )
{
UndoChangeAreaTextCell * undo =
new UndoChangeAreaTextCell ( doc ( ) , this ,
TQRect ( _column , _row , cols , rows ) ) ;
doc ( ) - > addCommand ( undo ) ;
}
// fill in the cells ... top-left one gets the formula, the rest gets =INDEX
// TODO: also fill in information about cells being a part of a range
Cell * cell = nonDefaultCell ( _column , _row ) ;
cell - > setCellText ( _text , false ) ;
TQString cellRef = cell - > name ( ) ;
for ( int row = 0 ; row < rows ; + + row )
for ( int col = 0 ; col < cols ; col + + )
if ( col | | row )
{
Cell * cell = nonDefaultCell ( _column + col , _row + row ) ;
cell - > setCellText ( " =INDEX( " + cellRef + " ; " + TQString : : number ( row + 1 )
+ " ; " + TQString : : number ( col + 1 ) + " ) " , false ) ;
}
*/
}
void Sheet : : setLayoutDirtyFlag ( )
{
Cell * c = d - > cells . firstCell ( ) ;
for ( ; c ; c = c - > nextCell ( ) )
c - > setLayoutDirtyFlag ( ) ;
}
void Sheet : : setCalcDirtyFlag ( )
{
Cell * c = d - > cells . firstCell ( ) ;
for ( ; c ; c = c - > nextCell ( ) )
{
if ( ! ( c - > isObscured ( ) & & c - > isPartOfMerged ( ) ) )
c - > setCalcDirtyFlag ( ) ;
}
}
void Sheet : : updateAllDependencies ( )
{
for ( Cell * cell = d - > cells . firstCell ( ) ; cell ; cell = cell - > nextCell ( ) )
{
Point cellLocation ;
cellLocation . setSheet ( cell - > sheet ( ) ) ;
cellLocation . setRow ( cell - > row ( ) ) ;
cellLocation . setColumn ( cell - > column ( ) ) ;
d - > dependencies - > cellChanged ( cellLocation ) ;
}
}
void Sheet : : recalc ( )
{
recalc ( false ) ;
}
void Sheet : : recalc ( bool force )
{
ElapsedTime et ( " Recalculating " + d - > name , ElapsedTime : : PrintOnlyTime ) ;
// emitBeginOperation(true);
// setRegionPaintDirty(TQRect(TQPoint(1,1), TQPoint(KS_colMax, KS_rowMax)));
setCalcDirtyFlag ( ) ;
//If automatic calculation is disabled, don't recalculate unless the force flag has been
//set.
if ( ! getAutoCalc ( ) & & ! force )
return ;
//If automatic calculation is disabled, the dependencies won't be up to date, so they need
//to be recalculated.
//FIXME: Tomas, is there a more efficient way to do this?
if ( ! getAutoCalc ( ) )
updateAllDependencies ( ) ;
// (Tomas): actually recalc each cell
// this is FAR from being perfect, dependencies will cause some to be
// recalculated a LOT, but it's still better than otherwise, where
// we get no recalc if the result stored in a file differs from the
// current one - then we only obtain the correct result AFTER we scroll
// to the cell ... recalc should actually ... recalc :)
Cell * c ;
int count = 0 ;
c = d - > cells . firstCell ( ) ;
for ( ; c ; c = c - > nextCell ( ) )
+ + count ;
int cur = 0 ;
int percent = - 1 ;
c = d - > cells . firstCell ( ) ;
for ( ; c ; c = c - > nextCell ( ) )
{
c - > calc ( false ) ;
cur + + ;
// some debug output to get some idea how damn slow this is ...
if ( cur * 100 / count ! = percent ) {
percent = cur * 100 / count ;
// kdDebug() << "Recalc: " << percent << "%" << endl;
}
}
// emitEndOperation();
emit sig_updateView ( this ) ;
}
void Sheet : : valueChanged ( Cell * cell )
{
//TODO: call cell updating, when cell damaging implemented
//prepare the Point structure
Point c ;
c . setRow ( cell - > row ( ) ) ;
c . setColumn ( cell - > column ( ) ) ;
c . setSheet ( this ) ;
//update dependencies
if ( getAutoCalc ( ) )
d - > dependencies - > cellChanged ( c ) ;
//REMOVED - modification change - this was causing modified flag to be set inappropriately.
//nobody else seems to be setting the modified flag, so we do it here
// doc()->setModified (true);
}
/*
Methods working on selections :
TYPE A :
{ columns selected :
for all rows with properties X , X ' :
if default - cell create new cell
}
post undo object ( always a UndoCellLayout ; difference in title only )
{ rows selected :
if condition Y clear properties X , X ' of cells ;
set properties X , X ' of rowformats
emit complete update ;
}
{ columns selected :
if condition Y clear properties X , X ' of cells ;
set properties X , X ' of columnformats ;
for all rows with properties X , X ' :
create cells if necessary and set properties X , X '
emit complete update ;
}
{ cells selected :
for all cells with condition Y :
create if necessary and set properties X , X ' and do Z ;
emit update on selected region ;
}
USED in :
setSelectionFont
setSelectionSize
setSelectionAngle
setSelectionTextColor
setSelectionBgColor
setSelectionPercent
borderAll
borderRemove ( exceptions : # # # creates cells ( why ? ) , # # # changes default cell if cell - regions selected ? )
setSelectionAlign
setSelectionAlignY
setSelectionMoneyFormat
increaseIndent
decreaseIndent
TYPE B :
post undo object
{ rows selected :
if condition Y do X with cells ;
emit update on selection ;
}
{ columns selected :
if condition Y do X with cells ;
emit update on selection ;
}
{ cells selected :
if condition Y do X with cells ; create cell if non - default ;
emit update on selection ;
}
USED in :
setSelectionUpperLower ( exceptions : no undo ; no create - if - default ; # # # modifies default - cell ? )
setSelectionFirstLetterUpper ( exceptions : no undo ; no create - if - default ; # # # modifies default - cell ? )
setSelectionVerticalText
setSelectionComment
setSelectionRemoveComment ( exeception : no create - if - default and work only on non - default - cells for cell regions )
setSelectionBorderColor ( exeception : no create - if - default and work only on non - default - cells for cell regions )
setSelectionMultiRow
setSelectionPrecision
clearTextSelection ( exception : all only if ! areaIsEmpty ( ) )
clearValiditySelection ( exception : all only if ! areaIsEmpty ( ) )
clearConditionalSelection ( exception : all only if ! areaIsEmpty ( ) )
setConditional ( exception : conditional after create - if - default for cell regions )
setValidity ( exception : conditional after create - if - default for cell regions )
OTHERS :
borderBottom
borderRight
borderLeft
borderTop
borderOutline
= > these work only on some cells ( at the border ) ; undo only if cells affected ; rest is similar to type A
- - > better not use CellWorker / workOnCells ( )
defaultSelection
= > similar to TYPE B , but works on columns / rows if complete columns / rows selected
- - > use emit_signal = false and return value of workOnCells to finish
getWordSpelling
= > returns text , no signal emitted , no cell - create , similar to TYPE B
- - > use emit_signal = false , create_if_default = false and type B
setWordSpelling
= > no signal emitted , no cell - create , similar to type B
- - > use emit_signal = false , create_if_default = false and type B
*/
class UndoAction * Sheet : : CellWorkerTypeA : : createUndoAction ( Doc * doc , Sheet * sheet , const KSpread : : Region & region )
{
TQString title = getUndoTitle ( ) ;
return new UndoCellFormat ( doc , sheet , region , title ) ;
}
/*
Sheet : : SelectionType Sheet : : workOnCells ( const TQPoint & _marker , CellWorker & worker )
{
// see what is selected; if nothing, take marker position
bool selected = ( m_rctSelection . left ( ) ! = 0 ) ;
TQRect r ( m_rctSelection ) ;
if ( ! selected )
r . setCoords ( _marker . x ( ) , _marker . y ( ) , _marker . x ( ) , _marker . y ( ) ) ;
// create cells in rows if complete columns selected
Cell * cell ;
if ( ! worker . type_B & & selected & & isColumnSelected ( ) )
{
for ( RowFormat * rw = d - > rows . first ( ) ; rw ; rw = rw - > next ( ) )
{
if ( ! rw - > isDefault ( ) & & worker . testCondition ( rw ) )
{
for ( int i = m_rctSelection . left ( ) ; i < = m_rctSelection . right ( ) ; i + + )
{
cell = cellAt ( i , rw - > row ( ) ) ;
if ( cell = = d - > defaultCell )
// '&& worker.create_if_default' unnecessary as never used in type A
{
cell = new Cell ( this , i , rw - > row ( ) ) ;
insertCell ( cell ) ;
}
}
}
}
}
// create an undo action
if ( ! doc ( ) - > undoLocked ( ) )
{
UndoAction * undo = worker . createUndoAction ( doc ( ) , this , r ) ;
// test if the worker has an undo action
if ( undo ! = 0L )
doc ( ) - > addCommand ( undo ) ;
}
// complete rows selected ?
if ( selected & & isRowSelected ( ) )
{
int row ;
for ( Cell * cell = d - > cells . firstCell ( ) ; cell ; cell = cell - > nextCell ( ) )
{
row = cell - > row ( ) ;
if ( m_rctSelection . top ( ) < = row & & m_rctSelection . bottom ( ) > = row
& & worker . testCondition ( cell ) )
if ( worker . type_B )
worker . doWork ( cell , false , cell - > column ( ) , row ) ;
else
worker . prepareCell ( cell ) ;
}
if ( worker . type_B ) {
// for type B there's nothing left to do
if ( worker . emit_signal )
emit sig_updateView ( this , r ) ;
} else {
// for type A now work on row formats
for ( int i = m_rctSelection . top ( ) ; i < = m_rctSelection . bottom ( ) ; i + + )
{
RowFormat * rw = nonDefaultRowFormat ( i ) ;
worker . doWork ( rw ) ;
}
if ( worker . emit_signal )
emit sig_updateView ( this ) ;
}
return CompleteRows ;
}
// complete columns selected ?
else if ( selected & & isColumnSelected ( ) )
{
int col ;
for ( Cell * cell = d - > cells . firstCell ( ) ; cell ; cell = cell - > nextCell ( ) )
{
col = cell - > column ( ) ;
if ( m_rctSelection . left ( ) < = col & & m_rctSelection . right ( ) > = col
& & worker . testCondition ( cell ) )
if ( worker . type_B )
worker . doWork ( cell , false , col , cell - > row ( ) ) ;
else
worker . prepareCell ( cell ) ;
}
if ( worker . type_B ) {
if ( worker . emit_signal )
emit sig_updateView ( this , r ) ;
} else {
// for type A now work on column formats
for ( int i = m_rctSelection . left ( ) ; i < = m_rctSelection . right ( ) ; i + + )
{
ColumnFormat * cl = nonDefaultColumnFormat ( i ) ;
worker . doWork ( cl ) ;
}
Cell * cell ;
for ( RowFormat * rw = d - > rows . first ( ) ; rw ; rw = rw - > next ( ) )
{
if ( ! rw - > isDefault ( ) & & worker . testCondition ( rw ) )
{
for ( int i = m_rctSelection . left ( ) ; i < = m_rctSelection . right ( ) ; i + + )
{
cell = cellAt ( i , rw - > row ( ) ) ;
// ### this if should be not necessary; cells are created
// before the undo object is created, aren't they?
if ( cell = = d - > defaultCell )
{
cell = new Cell ( this , i , rw - > row ( ) ) ;
insertCell ( cell ) ;
}
worker . doWork ( cell , false , i , rw - > row ( ) ) ;
}
}
}
if ( worker . emit_signal )
emit sig_updateView ( this ) ;
}
return CompleteColumns ;
}
// cell region selected
else
{
Cell * cell ;
for ( int x = r . left ( ) ; x < = r . right ( ) ; x + + )
for ( int y = r . top ( ) ; y < = r . bottom ( ) ; y + + )
{
cell = cellAt ( x , y ) ;
if ( worker . testCondition ( cell ) )
{
if ( worker . create_if_default & & cell = = d - > defaultCell )
{
cell = new Cell ( this , x , y ) ;
insertCell ( cell ) ;
}
if ( cell ! = d - > defaultCell )
worker . doWork ( cell , true , x , y ) ;
}
}
if ( worker . emit_signal )
emit sig_updateView ( this , r ) ;
return CellRegion ;
}
}
*/
Sheet : : SelectionType Sheet : : workOnCells ( Selection * selectionInfo , CellWorker & worker )
{
Sheet : : SelectionType result ;
doc ( ) - > emitBeginOperation ( ) ;
// see what is selected; if nothing, take marker position
bool selected = ! ( selectionInfo - > isSingular ( ) ) ;
// create an undo action
if ( ! doc ( ) - > undoLocked ( ) )
{
UndoAction * undo = worker . createUndoAction ( doc ( ) , this , * selectionInfo ) ;
// test if the worker has an undo action
if ( undo ! = 0 )
{
doc ( ) - > addCommand ( undo ) ;
}
}
Region : : ConstIterator endOfList ( selectionInfo - > constEnd ( ) ) ;
for ( Region : : ConstIterator it = selectionInfo - > constBegin ( ) ; it ! = endOfList ; + + it )
{
// see what is selected; if nothing, take marker position
TQRect range = ( * it ) - > rect ( ) . normalize ( ) ;
int top = range . top ( ) ;
int left = range . left ( ) ;
int bottom = range . bottom ( ) ;
int right = range . right ( ) ;
// create cells in rows if complete columns selected
Cell * cell ;
Style * s = doc ( ) - > styleManager ( ) - > defaultStyle ( ) ;
if ( ! worker . type_B & & selected & & util_isColumnSelected ( range ) )
{
for ( RowFormat * rw = d - > rows . first ( ) ; rw ; rw = rw - > next ( ) )
{
if ( worker . testCondition ( rw ) )
{
for ( int col = left ; col < = right ; + + col )
{
cell = nonDefaultCell ( col , rw - > row ( ) , false , s ) ;
}
}
}
}
// complete rows selected ?
if ( selected & & util_isRowSelected ( range ) )
{
for ( int row = top ; row < = bottom ; + + row )
{
cell = getFirstCellRow ( row ) ;
while ( cell )
{
if ( worker . testCondition ( cell ) )
{
if ( worker . type_B )
worker . doWork ( cell , false , cell - > column ( ) , row ) ;
else
worker . prepareCell ( cell ) ;
}
cell = getNextCellRight ( cell - > column ( ) , row ) ;
}
}
if ( worker . type_B )
{
// for type B there's nothing left to do
;
}
else
{
// for type A now work on row formats
for ( int i = top ; i < = bottom ; + + i )
{
RowFormat * rw = nonDefaultRowFormat ( i ) ;
worker . doWork ( rw ) ;
}
for ( int row = top ; row < = bottom ; + + row )
{
cell = getFirstCellRow ( row ) ;
while ( cell )
{
if ( worker . testCondition ( cell ) )
{
worker . doWork ( cell , false , cell - > column ( ) , row ) ;
}
cell = getNextCellRight ( cell - > column ( ) , row ) ;
}
}
}
result = CompleteRows ;
}
// complete columns selected ?
else if ( selected & & util_isColumnSelected ( range ) )
{
for ( int col = range . left ( ) ; col < = right ; + + col )
{
cell = getFirstCellColumn ( col ) ;
while ( cell )
{
if ( worker . testCondition ( cell ) )
{
if ( worker . type_B )
worker . doWork ( cell , false , col , cell - > row ( ) ) ;
else
worker . prepareCell ( cell ) ;
}
cell = getNextCellDown ( col , cell - > row ( ) ) ;
}
}
if ( worker . type_B )
{
;
}
else
{
// for type A now work on column formats
for ( int i = left ; i < = right ; + + i )
{
ColumnFormat * cl = nonDefaultColumnFormat ( i ) ;
worker . doWork ( cl ) ;
}
for ( RowFormat * rw = d - > rows . first ( ) ; rw ; rw = rw - > next ( ) )
{
if ( worker . testCondition ( rw ) )
{
for ( int i = left ; i < = right ; + + i )
{
cell = nonDefaultCell ( i , rw - > row ( ) , false , s ) ;
worker . doWork ( cell , false , i , rw - > row ( ) ) ;
}
}
}
}
result = CompleteColumns ;
}
// cell region selected
else
{
for ( int x = left ; x < = right ; + + x )
{
enableScrollBarUpdates ( false ) ;
for ( int y = top ; y < = bottom ; + + y )
{
cell = cellAt ( x , y ) ;
if ( worker . testCondition ( cell ) )
{
if ( cell = = d - > defaultCell & & worker . create_if_default )
{
cell = new Cell ( this , s , x , y ) ;
insertCell ( cell ) ;
}
if ( cell ! = d - > defaultCell )
{
// kdDebug() << "not default" << endl;
worker . doWork ( cell , true , x , y ) ;
}
}
}
enableScrollBarUpdates ( true ) ;
checkRangeVBorder ( bottom ) ;
}
checkRangeHBorder ( right ) ;
result = CellRegion ;
}
} // for Region::Elements
// emitEndOperation();
emit sig_updateView ( this ) ;
if ( worker . emit_signal )
{
emit sig_updateView ( this , * selectionInfo ) ;
}
return result ;
}
void Sheet : : setSelectionFont ( Selection * selectionInfo ,
const char * _font , int _size ,
signed char _bold , signed char _italic ,
signed char _underline , signed char _strike )
{
FontManipulator * manipulator = new FontManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setProperty ( Format : : PFont ) ;
manipulator - > setFontFamily ( _font ) ;
manipulator - > setFontSize ( _size ) ;
manipulator - > setFontBold ( _bold ) ;
manipulator - > setFontItalic ( _italic ) ;
manipulator - > setFontStrike ( _strike ) ;
manipulator - > setFontUnderline ( _underline ) ;
manipulator - > add ( * selectionInfo ) ;
manipulator - > execute ( ) ;
}
void Sheet : : setSelectionSize ( Selection * selectionInfo ,
int _size )
{
// TODO Stefan: Increase/Decrease font size still used?
int size ;
Cell * c ;
TQPoint marker ( selectionInfo - > marker ( ) ) ;
c = cellAt ( marker ) ;
size = c - > format ( ) - > textFontSize ( marker . x ( ) , marker . y ( ) ) ;
FontManipulator * manipulator = new FontManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setProperty ( Format : : PFont ) ;
manipulator - > setFontSize ( _size + size ) ;
manipulator - > add ( * selectionInfo ) ;
manipulator - > execute ( ) ;
}
struct SetSelectionUpperLowerWorker : public Sheet : : CellWorker {
int _type ;
Sheet * _s ;
SetSelectionUpperLowerWorker ( int type , Sheet * s )
: Sheet : : CellWorker ( false ) , _type ( type ) , _s ( s ) { }
class UndoAction * createUndoAction ( Doc * doc , Sheet * sheet , const KSpread : : Region & region )
{
return new UndoChangeAreaTextCell ( doc , sheet , region ) ;
}
bool testCondition ( Cell * c ) {
return ( ! c - > value ( ) . isNumber ( ) & & ! c - > value ( ) . isBoolean ( ) & & ! c - > isFormula ( ) & & ! c - > isDefault ( )
& & ! c - > text ( ) . isEmpty ( ) & & c - > text ( ) [ 0 ] ! = ' * ' & & c - > text ( ) [ 0 ] ! = ' ! '
& & ! c - > isPartOfMerged ( ) ) ;
}
void doWork ( Cell * cell , bool , int , int )
{
cell - > setDisplayDirtyFlag ( ) ;
if ( _type = = - 1 )
cell - > setCellText ( ( cell - > text ( ) . lower ( ) ) ) ;
else if ( _type = = 1 )
cell - > setCellText ( ( cell - > text ( ) . upper ( ) ) ) ;
cell - > clearDisplayDirtyFlag ( ) ;
}
} ;
void Sheet : : setSelectionUpperLower ( Selection * selectionInfo ,
int _type )
{
SetSelectionUpperLowerWorker w ( _type , this ) ;
workOnCells ( selectionInfo , w ) ;
}
struct SetSelectionFirstLetterUpperWorker : public Sheet : : CellWorker
{
Changes * _c ;
Sheet * _s ;
SetSelectionFirstLetterUpperWorker ( Sheet * s )
: Sheet : : CellWorker ( false ) , _s ( s ) { }
class UndoAction * createUndoAction ( Doc * doc , Sheet * sheet , const KSpread : : Region & region ) {
return new UndoChangeAreaTextCell ( doc , sheet , region ) ;
}
bool testCondition ( Cell * c ) {
return ( ! c - > value ( ) . isNumber ( ) & & ! c - > value ( ) . isBoolean ( ) & & ! c - > isFormula ( ) & & ! c - > isDefault ( )
& & ! c - > text ( ) . isEmpty ( ) & & c - > text ( ) [ 0 ] ! = ' * ' & & c - > text ( ) [ 0 ] ! = ' ! '
& & ! c - > isPartOfMerged ( ) ) ;
}
void doWork ( Cell * cell , bool , int , int )
{
cell - > setDisplayDirtyFlag ( ) ;
TQString tmp = cell - > text ( ) ;
int len = tmp . length ( ) ;
cell - > setCellText ( ( tmp . at ( 0 ) . upper ( ) + tmp . right ( len - 1 ) ) ) ;
cell - > clearDisplayDirtyFlag ( ) ;
}
} ;
void Sheet : : setSelectionfirstLetterUpper ( Selection * selectionInfo )
{
SetSelectionFirstLetterUpperWorker w ( this ) ;
workOnCells ( selectionInfo , w ) ;
}
struct SetSelectionVerticalTextWorker : public Sheet : : CellWorker {
bool _b ;
SetSelectionVerticalTextWorker ( bool b ) : Sheet : : CellWorker ( ) , _b ( b ) { }
class UndoAction * createUndoAction ( Doc * doc , Sheet * sheet , const KSpread : : Region & region ) {
TQString title = i18n ( " Vertical Text " ) ;
return new UndoCellFormat ( doc , sheet , region , title ) ;
}
bool testCondition ( Cell * cell ) {
return ( ! cell - > isPartOfMerged ( ) ) ;
}
void doWork ( Cell * cell , bool , int , int ) {
cell - > setDisplayDirtyFlag ( ) ;
cell - > format ( ) - > setVerticalText ( _b ) ;
cell - > format ( ) - > setMultiRow ( false ) ;
cell - > format ( ) - > setAngle ( 0 ) ;
cell - > clearDisplayDirtyFlag ( ) ;
}
} ;
void Sheet : : setSelectionVerticalText ( Selection * selectionInfo ,
bool _b )
{
SetSelectionVerticalTextWorker w ( _b ) ;
workOnCells ( selectionInfo , w ) ;
}
struct SetSelectionCommentWorker : public Sheet : : CellWorker {
TQString _comment ;
SetSelectionCommentWorker ( TQString comment ) : Sheet : : CellWorker ( ) , _comment ( comment ) { }
class UndoAction * createUndoAction ( Doc * doc , Sheet * sheet , const KSpread : : Region & region ) {
TQString title = i18n ( " Add Comment " ) ;
return new UndoCellFormat ( doc , sheet , region , title ) ;
}
bool testCondition ( Cell * cell ) {
return ( ! cell - > isPartOfMerged ( ) ) ;
}
void doWork ( Cell * cell , bool , int , int ) {
cell - > setDisplayDirtyFlag ( ) ;
cell - > format ( ) - > setComment ( _comment ) ;
cell - > clearDisplayDirtyFlag ( ) ;
}
} ;
void Sheet : : setSelectionComment ( Selection * selectionInfo ,
const TQString & _comment )
{
SetSelectionCommentWorker w ( _comment ) ;
workOnCells ( selectionInfo , w ) ;
}
void Sheet : : setSelectionAngle ( Selection * selectionInfo ,
int _value )
{
AngleManipulator * manipulator = new AngleManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setProperty ( Format : : PAngle ) ;
manipulator - > setAngle ( _value ) ;
manipulator - > add ( * selectionInfo ) ;
manipulator - > execute ( ) ;
}
struct SetSelectionRemoveCommentWorker : public Sheet : : CellWorker {
SetSelectionRemoveCommentWorker ( ) : Sheet : : CellWorker ( false ) { }
class UndoAction * createUndoAction ( Doc * doc , Sheet * sheet , const KSpread : : Region & region ) {
TQString title = i18n ( " Remove Comment " ) ;
return new UndoCellFormat ( doc , sheet , region , title ) ;
}
bool testCondition ( Cell * cell ) {
return ( ! cell - > isPartOfMerged ( ) ) ;
}
void doWork ( Cell * cell , bool , int , int ) {
cell - > setDisplayDirtyFlag ( ) ;
cell - > format ( ) - > setComment ( " " ) ;
cell - > clearDisplayDirtyFlag ( ) ;
}
} ;
void Sheet : : setSelectionRemoveComment ( Selection * selectionInfo )
{
if ( areaIsEmpty ( * selectionInfo , Comment ) )
return ;
SetSelectionRemoveCommentWorker w ;
workOnCells ( selectionInfo , w ) ;
}
void Sheet : : setSelectionTextColor ( Selection * selectionInfo ,
const TQColor & tb_Color )
{
FontColorManipulator * manipulator = new FontColorManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setProperty ( Format : : PTextPen ) ;
manipulator - > setTextColor ( tb_Color ) ;
manipulator - > add ( * selectionInfo ) ;
manipulator - > execute ( ) ;
}
void Sheet : : setSelectionbgColor ( Selection * selectionInfo ,
const TQColor & bg_Color )
{
BackgroundColorManipulator * manipulator = new BackgroundColorManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setProperty ( Format : : PBackgroundColor ) ;
manipulator - > setBackgroundColor ( bg_Color ) ;
manipulator - > add ( * selectionInfo ) ;
manipulator - > execute ( ) ;
}
struct SetSelectionBorderColorWorker : public Sheet : : CellWorker {
const TQColor & bd_Color ;
SetSelectionBorderColorWorker ( const TQColor & _bd_Color ) : Sheet : : CellWorker ( false ) , bd_Color ( _bd_Color ) { }
class UndoAction * createUndoAction ( Doc * doc , Sheet * sheet , const KSpread : : Region & region ) {
TQString title = i18n ( " Change Border Color " ) ;
return new UndoCellFormat ( doc , sheet , region , title ) ;
}
bool testCondition ( Cell * cell ) {
return ( ! cell - > isPartOfMerged ( ) ) ;
}
void doWork ( Cell * cell , bool , int , int ) {
cell - > setDisplayDirtyFlag ( ) ;
int it_Row = cell - > row ( ) ;
int it_Col = cell - > column ( ) ;
if ( cell - > format ( ) - > topBorderStyle ( it_Row , it_Col ) ! = TQt : : NoPen )
cell - > format ( ) - > setTopBorderColor ( bd_Color ) ;
if ( cell - > format ( ) - > leftBorderStyle ( it_Row , it_Col ) ! = TQt : : NoPen )
cell - > format ( ) - > setLeftBorderColor ( bd_Color ) ;
if ( cell - > format ( ) - > fallDiagonalStyle ( it_Row , it_Col ) ! = TQt : : NoPen )
cell - > format ( ) - > setFallDiagonalColor ( bd_Color ) ;
if ( cell - > format ( ) - > goUpDiagonalStyle ( it_Row , it_Col ) ! = TQt : : NoPen )
cell - > format ( ) - > setGoUpDiagonalColor ( bd_Color ) ;
if ( cell - > format ( ) - > bottomBorderStyle ( it_Row , it_Col ) ! = TQt : : NoPen )
cell - > format ( ) - > setBottomBorderColor ( bd_Color ) ;
if ( cell - > format ( ) - > rightBorderStyle ( it_Row , it_Col ) ! = TQt : : NoPen )
cell - > format ( ) - > setRightBorderColor ( bd_Color ) ;
cell - > clearDisplayDirtyFlag ( ) ;
}
} ;
void Sheet : : setSelectionBorderColor ( Selection * selectionInfo ,
const TQColor & bd_Color )
{
SetSelectionBorderColorWorker w ( bd_Color ) ;
workOnCells ( selectionInfo , w ) ;
}
void Sheet : : setSeries ( const TQPoint & _marker , double start , double end , double step , Series mode , Series type )
{
doc ( ) - > emitBeginOperation ( ) ;
TQString cellText ;
int x , y ; /* just some loop counters */
/* the actual number of columns or rows that the series will span.
i . e . this will count 3 cells for a single cell that spans three rows
*/
int numberOfCells ;
if ( end > start )
numberOfCells = ( int ) ( ( end - start ) / step + 1 ) ; /*initialize for linear*/
else if ( end < start )
numberOfCells = ( int ) ( ( start - end ) / step + 1 ) ; /*initialize for linear*/
else //equal ! => one cell fix infini loop
numberOfCells = 1 ;
if ( type = = Geometric )
{
/* basically, A(n) = start ^ n
* so when does end = start ^ n ? ?
* when n = ln ( end ) / ln ( start )
*/
numberOfCells = ( int ) ( ( log ( ( double ) end ) / log ( ( double ) start ) ) +
DBL_EPSILON ) + 1 ;
}
Cell * cell = NULL ;
/* markers for the top-left corner of the undo region. It'll probably
* be the top left corner of where the series is , but if something in front
* is obscuring the cell , then it needs to be part of the undo region */
TQRect undoRegion ;
undoRegion . setLeft ( _marker . x ( ) ) ;
undoRegion . setTop ( _marker . y ( ) ) ;
/* this whole block is used to find the correct size for the undo region.
We ' re checking for two different things ( in these examples ,
mode = = column ) :
1. cells are vertically merged . This means that one value in the
series will span multiple cells .
2. a cell in the column is merged to a cell to its left . In this case
the cell value will be stored in the left most cell so we need to
extend the undo range to include that column .
*/
if ( mode = = Column )
{
for ( y = _marker . y ( ) ; y < = ( _marker . y ( ) + numberOfCells - 1 ) & & y < = KS_rowMax ; y + + )
{
cell = cellAt ( _marker . x ( ) , y ) ;
if ( cell - > isPartOfMerged ( ) )
{
/* case 2. */
cell = cell - > obscuringCells ( ) . first ( ) ;
undoRegion . setLeft ( TQMIN ( undoRegion . left ( ) , cell - > column ( ) ) ) ;
}
/* case 1. Add the extra space to numberOfCells and then skip
over the region . Note that because of the above if block ' cell '
points to the correct cell in the case where both case 1 and 2
are true
*/
numberOfCells + = cell - > extraYCells ( ) ;
y + = cell - > extraYCells ( ) ;
}
undoRegion . setRight ( _marker . x ( ) ) ;
undoRegion . setBottom ( y - 1 ) ;
checkRangeVBorder ( undoRegion . bottom ( ) ) ;
}
else if ( mode = = Row )
{
for ( x = _marker . x ( ) ; x < = ( _marker . x ( ) + numberOfCells - 1 ) & & x < = KS_colMax ; x + + )
{
/* see the code above for a column series for a description of
what is going on here . */
cell = cellAt ( x , _marker . y ( ) , false ) ;
if ( cell - > isPartOfMerged ( ) )
{
cell = cell - > obscuringCells ( ) . first ( ) ;
undoRegion . setTop ( TQMIN ( undoRegion . top ( ) , cell - > row ( ) ) ) ;
}
numberOfCells + = cell - > extraXCells ( ) ;
x + = cell - > extraXCells ( ) ;
}
undoRegion . setBottom ( _marker . y ( ) ) ;
undoRegion . setRight ( x - 1 ) ;
checkRangeHBorder ( undoRegion . right ( ) ) ;
}
kdDebug ( ) < < " Saving undo information " < < endl ;
if ( ! doc ( ) - > undoLocked ( ) )
{
UndoChangeAreaTextCell * undo = new
UndoChangeAreaTextCell ( doc ( ) , this , undoRegion ) ;
doc ( ) - > addCommand ( undo ) ;
}
kdDebug ( ) < < " Saving undo information done " < < endl ;
setRegionPaintDirty ( undoRegion ) ;
x = _marker . x ( ) ;
y = _marker . y ( ) ;
/* now we're going to actually loop through and set the values */
double incr ;
Style * s = doc ( ) - > styleManager ( ) - > defaultStyle ( ) ;
if ( step > = 0 & & start < end )
{
for ( incr = start ; incr < = end ; )
{
cell = nonDefaultCell ( x , y , false , s ) ;
if ( cell - > isPartOfMerged ( ) )
{
cell = cell - > obscuringCells ( ) . first ( ) ;
}
// cell->setCellText(cellText.setNum( incr ));
cell - > setNumber ( incr ) ;
if ( mode = = Column )
{
+ + y ;
if ( cell - > doesMergeCells ( ) )
{
y + = cell - > extraYCells ( ) ;
}
if ( y > KS_rowMax )
{
break ;
}
}
else if ( mode = = Row )
{
+ + x ;
if ( cell - > doesMergeCells ( ) )
{
x + = cell - > extraXCells ( ) ;
}
if ( x > KS_colMax )
{
break ;
}
}
else
{
kdDebug ( 36001 ) < < " Error in Series::mode " < < endl ;
return ;
}
if ( type = = Linear )
incr = incr + step ;
else if ( type = = Geometric )
incr = incr * step ;
else
{
kdDebug ( 36001 ) < < " Error in Series::type " < < endl ;
return ;
}
}
}
else
if ( step > = 0 & & start > end )
{
for ( incr = start ; incr > = end ; )
{
cell = nonDefaultCell ( x , y , false , s ) ;
if ( cell - > isPartOfMerged ( ) )
{
cell = cell - > obscuringCells ( ) . first ( ) ;
}
// cell->setCellText(cellText.setNum( incr ));
cell - > setNumber ( incr ) ;
if ( mode = = Column )
{
+ + y ;
if ( cell - > doesMergeCells ( ) )
{
y + = cell - > extraYCells ( ) ;
}
if ( y > KS_rowMax )
{
break ;
}
}
else if ( mode = = Row )
{
+ + x ;
if ( cell - > doesMergeCells ( ) )
{
x + = cell - > extraXCells ( ) ;
}
if ( x > KS_colMax )
{
break ;
}
}
else
{
kdDebug ( 36001 ) < < " Error in Series::mode " < < endl ;
return ;
}
if ( type = = Linear )
incr = incr + step ;
else if ( type = = Geometric )
incr = incr * step ;
else
{
kdDebug ( 36001 ) < < " Error in Series::type " < < endl ;
return ;
}
}
}
else
{
for ( incr = start ; incr < = end ; )
{
cell = nonDefaultCell ( x , y , false , s ) ;
if ( cell - > isPartOfMerged ( ) )
{
cell = cell - > obscuringCells ( ) . first ( ) ;
}
//cell->setCellText(cellText.setNum( incr ));
cell - > setNumber ( incr ) ;
if ( mode = = Column )
{
+ + y ;
if ( cell - > doesMergeCells ( ) )
{
y + = cell - > extraYCells ( ) ;
}
if ( y > KS_rowMax )
{
break ;
}
}
else if ( mode = = Row )
{
+ + x ;
if ( cell - > doesMergeCells ( ) )
{
x + = cell - > extraXCells ( ) ;
}
if ( x > KS_colMax )
{
break ;
}
}
else
{
kdDebug ( 36001 ) < < " Error in Series::mode " < < endl ;
return ;
}
if ( type = = Linear )
incr = incr + step ;
else if ( type = = Geometric )
{
incr = incr * step ;
//a step = 1 into geometric serie is not good
//we don't increase value => infini loop
if ( step = = 1 )
return ;
}
else
{
kdDebug ( 36001 ) < < " Error in Series::type " < < endl ;
return ;
}
}
}
// doc()->emitEndOperation();
emit sig_updateView ( this ) ;
}
struct SetSelectionPercentWorker : public Sheet : : CellWorkerTypeA
{
bool b ;
SetSelectionPercentWorker ( bool _b ) : b ( _b ) { }
TQString getUndoTitle ( ) { return i18n ( " Format Percent " ) ; }
bool testCondition ( RowFormat * ) {
//TODO: no idea what to put here, now that factor's gone :(
return ( true ) ;
}
void doWork ( RowFormat * rw ) {
//rw->setPrecision( 0 );
rw - > setFormatType ( b ? Percentage_format : Generic_format ) ;
}
void doWork ( ColumnFormat * cl ) {
cl - > setFormatType ( b ? Percentage_format : Generic_format ) ;
}
void prepareCell ( Cell * cell ) {
cell - > format ( ) - > clearProperty ( Format : : PFormatType ) ;
cell - > format ( ) - > clearNoFallBackProperties ( Format : : PFormatType ) ;
}
bool testCondition ( Cell * cell ) {
return ( ! cell - > isPartOfMerged ( ) ) ;
}
void doWork ( Cell * cell , bool cellRegion , int , int ) {
if ( cellRegion )
cell - > setDisplayDirtyFlag ( ) ;
cell - > format ( ) - > setFormatType ( b ? Percentage_format : Generic_format ) ;
if ( cellRegion )
cell - > clearDisplayDirtyFlag ( ) ;
}
} ;
void Sheet : : setSelectionPercent ( Selection * selectionInfo , bool b )
{
SetSelectionPercentWorker w ( b ) ;
workOnCells ( selectionInfo , w ) ;
}
void Sheet : : slotAreaModified ( const TQString & name )
{
d - > dependencies - > areaModified ( name ) ;
}
void Sheet : : refreshRemoveAreaName ( const TQString & _areaName )
{
Cell * c = d - > cells . firstCell ( ) ;
TQString tmp = " ' " + _areaName + " ' " ;
for ( ; c ; c = c - > nextCell ( ) )
{
if ( c - > isFormula ( ) )
{
if ( c - > text ( ) . find ( tmp ) ! = - 1 )
{
if ( ! c - > makeFormula ( ) )
kdError ( 36001 ) < < " ERROR: Syntax ERROR " < < endl ;
}
}
}
}
void Sheet : : refreshChangeAreaName ( const TQString & _areaName )
{
Cell * c = d - > cells . firstCell ( ) ;
TQString tmp = " ' " + _areaName + " ' " ;
for ( ; c ; c = c - > nextCell ( ) )
{
if ( c - > isFormula ( ) )
{
if ( c - > text ( ) . find ( tmp ) ! = - 1 )
{
if ( ! c - > makeFormula ( ) )
kdError ( 36001 ) < < " ERROR: Syntax ERROR " < < endl ;
else
{
/* setting a cell calc dirty also sets it paint dirty */
c - > setCalcDirtyFlag ( ) ;
}
}
}
}
}
void Sheet : : changeCellTabName ( TQString const & old_name , TQString const & new_name )
{
Cell * c = d - > cells . firstCell ( ) ;
for ( ; c ; c = c - > nextCell ( ) )
{
if ( c - > isFormula ( ) )
{
if ( c - > text ( ) . find ( old_name ) ! = - 1 )
{
int nb = c - > text ( ) . contains ( old_name + " ! " ) ;
TQString tmp = old_name + " ! " ;
int len = tmp . length ( ) ;
tmp = c - > text ( ) ;
for ( int i = 0 ; i < nb ; i + + )
{
int pos = tmp . find ( old_name + " ! " ) ;
tmp . replace ( pos , len , new_name + " ! " ) ;
}
c - > setCellText ( tmp ) ;
}
}
}
}
bool Sheet : : shiftRow ( const TQRect & rect , bool makeUndo )
{
UndoInsertCellRow * undo = 0 ;
if ( ! doc ( ) - > undoLocked ( ) & & makeUndo )
{
undo = new UndoInsertCellRow ( doc ( ) , this , rect ) ;
doc ( ) - > addCommand ( undo ) ;
}
bool res = true ;
bool result ;
for ( int i = rect . top ( ) ; i < = rect . bottom ( ) ; i + + )
{
for ( int j = 0 ; j < = ( rect . right ( ) - rect . left ( ) ) ; j + + )
{
result = d - > cells . shiftRow ( TQPoint ( rect . left ( ) , i ) ) ;
if ( ! result )
res = false ;
}
}
TQPtrListIterator < Sheet > it ( workbook ( ) - > sheetList ( ) ) ;
for ( ; it . current ( ) ; + + it )
{
for ( int i = rect . top ( ) ; i < = rect . bottom ( ) ; i + + )
it . current ( ) - > changeNameCellRef ( TQPoint ( rect . left ( ) , i ) , false ,
Sheet : : ColumnInsert , name ( ) ,
( rect . right ( ) - rect . left ( ) + 1 ) ,
undo ) ;
}
refreshChart ( TQPoint ( rect . left ( ) , rect . top ( ) ) , false , Sheet : : ColumnInsert ) ;
refreshMergedCell ( ) ;
recalc ( ) ;
emit sig_updateView ( this ) ;
return res ;
}
bool Sheet : : shiftColumn ( const TQRect & rect , bool makeUndo )
{
UndoInsertCellCol * undo = 0 ;
if ( ! doc ( ) - > undoLocked ( ) & & makeUndo )
{
undo = new UndoInsertCellCol ( doc ( ) , this , rect ) ;
doc ( ) - > addCommand ( undo ) ;
}
bool res = true ;
bool result ;
for ( int i = rect . left ( ) ; i < = rect . right ( ) ; i + + )
{
for ( int j = 0 ; j < = ( rect . bottom ( ) - rect . top ( ) ) ; j + + )
{
result = d - > cells . shiftColumn ( TQPoint ( i , rect . top ( ) ) ) ;
if ( ! result )
res = false ;
}
}
TQPtrListIterator < Sheet > it ( workbook ( ) - > sheetList ( ) ) ;
for ( ; it . current ( ) ; + + it )
{
for ( int i = rect . left ( ) ; i < = rect . right ( ) ; i + + )
it . current ( ) - > changeNameCellRef ( TQPoint ( i , rect . top ( ) ) , false ,
Sheet : : RowInsert , name ( ) ,
( rect . bottom ( ) - rect . top ( ) + 1 ) ,
undo ) ;
}
refreshChart ( /*marker*/ TQPoint ( rect . left ( ) , rect . top ( ) ) , false , Sheet : : RowInsert ) ;
refreshMergedCell ( ) ;
recalc ( ) ;
emit sig_updateView ( this ) ;
return res ;
}
void Sheet : : unshiftColumn ( const TQRect & rect , bool makeUndo )
{
UndoRemoveCellCol * undo = 0 ;
if ( ! doc ( ) - > undoLocked ( ) & & makeUndo )
{
undo = new UndoRemoveCellCol ( doc ( ) , this , rect ) ;
doc ( ) - > addCommand ( undo ) ;
}
for ( int i = rect . top ( ) ; i < = rect . bottom ( ) ; i + + )
for ( int j = rect . left ( ) ; j < = rect . right ( ) ; j + + )
d - > cells . remove ( j , i ) ;
for ( int i = rect . left ( ) ; i < = rect . right ( ) ; i + + )
for ( int j = 0 ; j < = ( rect . bottom ( ) - rect . top ( ) ) ; j + + )
d - > cells . unshiftColumn ( TQPoint ( i , rect . top ( ) ) ) ;
TQPtrListIterator < Sheet > it ( workbook ( ) - > sheetList ( ) ) ;
for ( ; it . current ( ) ; + + it )
for ( int i = rect . left ( ) ; i < = rect . right ( ) ; i + + )
it . current ( ) - > changeNameCellRef ( TQPoint ( i , rect . top ( ) ) , false ,
Sheet : : RowRemove , name ( ) ,
( rect . bottom ( ) - rect . top ( ) + 1 ) ,
undo ) ;
refreshChart ( TQPoint ( rect . left ( ) , rect . top ( ) ) , false , Sheet : : RowRemove ) ;
refreshMergedCell ( ) ;
recalc ( ) ;
emit sig_updateView ( this ) ;
}
void Sheet : : unshiftRow ( const TQRect & rect , bool makeUndo )
{
UndoRemoveCellRow * undo = 0 ;
if ( ! doc ( ) - > undoLocked ( ) & & makeUndo )
{
undo = new UndoRemoveCellRow ( doc ( ) , this , rect ) ;
doc ( ) - > addCommand ( undo ) ;
}
for ( int i = rect . top ( ) ; i < = rect . bottom ( ) ; i + + )
for ( int j = rect . left ( ) ; j < = rect . right ( ) ; j + + )
d - > cells . remove ( j , i ) ;
for ( int i = rect . top ( ) ; i < = rect . bottom ( ) ; i + + )
for ( int j = 0 ; j < = ( rect . right ( ) - rect . left ( ) ) ; j + + )
d - > cells . unshiftRow ( TQPoint ( rect . left ( ) , i ) ) ;
TQPtrListIterator < Sheet > it ( workbook ( ) - > sheetList ( ) ) ;
for ( ; it . current ( ) ; + + it )
for ( int i = rect . top ( ) ; i < = rect . bottom ( ) ; i + + )
it . current ( ) - > changeNameCellRef ( TQPoint ( rect . left ( ) , i ) , false ,
Sheet : : ColumnRemove , name ( ) ,
( rect . right ( ) - rect . left ( ) + 1 ) ,
undo ) ;
refreshChart ( TQPoint ( rect . left ( ) , rect . top ( ) ) , false , Sheet : : ColumnRemove ) ;
refreshMergedCell ( ) ;
recalc ( ) ;
emit sig_updateView ( this ) ;
}
bool Sheet : : insertColumn ( int col , int nbCol , bool makeUndo )
{
UndoInsertColumn * undo = 0 ;
if ( ! doc ( ) - > undoLocked ( ) & & makeUndo )
{
undo = new UndoInsertColumn ( doc ( ) , this , col , nbCol ) ;
doc ( ) - > addCommand ( undo ) ;
}
bool res = true ;
bool result ;
for ( int i = 0 ; i < = nbCol ; i + + )
{
// Recalculate range max (minus size of last column)
d - > sizeMaxX - = columnFormat ( KS_colMax ) - > dblWidth ( ) ;
result = d - > cells . insertColumn ( col ) ;
d - > columns . insertColumn ( col ) ;
if ( ! result )
res = false ;
//Recalculate range max (plus size of new column)
d - > sizeMaxX + = columnFormat ( col + i ) - > dblWidth ( ) ;
}
TQPtrListIterator < Sheet > it ( workbook ( ) - > sheetList ( ) ) ;
for ( ; it . current ( ) ; + + it )
it . current ( ) - > changeNameCellRef ( TQPoint ( col , 1 ) , true ,
Sheet : : ColumnInsert , name ( ) ,
nbCol + 1 , undo ) ;
//update print settings
d - > print - > insertColumn ( col , nbCol ) ;
refreshChart ( TQPoint ( col , 1 ) , true , Sheet : : ColumnInsert ) ;
refreshMergedCell ( ) ;
recalc ( ) ;
emit sig_updateHBorder ( this ) ;
emit sig_updateView ( this ) ;
return res ;
}
bool Sheet : : insertRow ( int row , int nbRow , bool makeUndo )
{
UndoInsertRow * undo = 0 ;
if ( ! doc ( ) - > undoLocked ( ) & & makeUndo )
{
undo = new UndoInsertRow ( doc ( ) , this , row , nbRow ) ;
doc ( ) - > addCommand ( undo ) ;
}
bool res = true ;
bool result ;
for ( int i = 0 ; i < = nbRow ; i + + )
{
// Recalculate range max (minus size of last row)
d - > sizeMaxY - = rowFormat ( KS_rowMax ) - > dblHeight ( ) ;
result = d - > cells . insertRow ( row ) ;
d - > rows . insertRow ( row ) ;
if ( ! result )
res = false ;
//Recalculate range max (plus size of new row)
d - > sizeMaxY + = rowFormat ( row ) - > dblHeight ( ) ;
}
TQPtrListIterator < Sheet > it ( workbook ( ) - > sheetList ( ) ) ;
for ( ; it . current ( ) ; + + it )
it . current ( ) - > changeNameCellRef ( TQPoint ( 1 , row ) , true ,
Sheet : : RowInsert , name ( ) ,
nbRow + 1 , undo ) ;
//update print settings
d - > print - > insertRow ( row , nbRow ) ;
refreshChart ( TQPoint ( 1 , row ) , true , Sheet : : RowInsert ) ;
refreshMergedCell ( ) ;
recalc ( ) ;
emit sig_updateVBorder ( this ) ;
emit sig_updateView ( this ) ;
return res ;
}
void Sheet : : removeColumn ( int col , int nbCol , bool makeUndo )
{
UndoRemoveColumn * undo = 0 ;
if ( ! doc ( ) - > undoLocked ( ) & & makeUndo )
{
undo = new UndoRemoveColumn ( doc ( ) , this , col , nbCol ) ;
doc ( ) - > addCommand ( undo ) ;
}
for ( int i = 0 ; i < = nbCol ; + + i )
{
// Recalculate range max (minus size of removed column)
d - > sizeMaxX - = columnFormat ( col ) - > dblWidth ( ) ;
d - > cells . removeColumn ( col ) ;
d - > columns . removeColumn ( col ) ;
//Recalculate range max (plus size of new column)
d - > sizeMaxX + = columnFormat ( KS_colMax ) - > dblWidth ( ) ;
}
TQPtrListIterator < Sheet > it ( workbook ( ) - > sheetList ( ) ) ;
for ( ; it . current ( ) ; + + it )
it . current ( ) - > changeNameCellRef ( TQPoint ( col , 1 ) , true ,
Sheet : : ColumnRemove , name ( ) ,
nbCol + 1 , undo ) ;
//update print settings
d - > print - > removeColumn ( col , nbCol ) ;
refreshChart ( TQPoint ( col , 1 ) , true , Sheet : : ColumnRemove ) ;
refreshMergedCell ( ) ;
recalc ( ) ;
emit sig_updateHBorder ( this ) ;
emit sig_updateView ( this ) ;
}
void Sheet : : removeRow ( int row , int nbRow , bool makeUndo )
{
UndoRemoveRow * undo = 0 ;
if ( ! doc ( ) - > undoLocked ( ) & & makeUndo )
{
undo = new UndoRemoveRow ( doc ( ) , this , row , nbRow ) ;
doc ( ) - > addCommand ( undo ) ;
}
for ( int i = 0 ; i < = nbRow ; i + + )
{
// Recalculate range max (minus size of removed row)
d - > sizeMaxY - = rowFormat ( row ) - > dblHeight ( ) ;
d - > cells . removeRow ( row ) ;
d - > rows . removeRow ( row ) ;
//Recalculate range max (plus size of new row)
d - > sizeMaxY + = rowFormat ( KS_rowMax ) - > dblHeight ( ) ;
}
TQPtrListIterator < Sheet > it ( workbook ( ) - > sheetList ( ) ) ;
for ( ; it . current ( ) ; + + it )
it . current ( ) - > changeNameCellRef ( TQPoint ( 1 , row ) , true ,
Sheet : : RowRemove , name ( ) ,
nbRow + 1 , undo ) ;
//update print settings
d - > print - > removeRow ( row , nbRow ) ;
refreshChart ( TQPoint ( 1 , row ) , true , Sheet : : RowRemove ) ;
refreshMergedCell ( ) ;
recalc ( ) ;
emit sig_updateVBorder ( this ) ;
emit sig_updateView ( this ) ;
}
void Sheet : : hideRow ( const Region & region )
{
HideShowManipulator * manipulator = new HideShowManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setManipulateRows ( true ) ;
manipulator - > add ( region ) ;
manipulator - > execute ( ) ;
}
void Sheet : : emitHideRow ( )
{
emit sig_updateVBorder ( this ) ;
emit sig_updateView ( this ) ;
}
void Sheet : : showRow ( const Region & region )
{
HideShowManipulator * manipulator = new HideShowManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setManipulateRows ( true ) ;
manipulator - > setReverse ( true ) ;
manipulator - > add ( region ) ;
manipulator - > execute ( ) ;
}
void Sheet : : hideColumn ( const Region & region )
{
HideShowManipulator * manipulator = new HideShowManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setManipulateColumns ( true ) ;
manipulator - > add ( region ) ;
manipulator - > execute ( ) ;
}
void Sheet : : emitHideColumn ( )
{
emit sig_updateHBorder ( this ) ;
emit sig_updateView ( this ) ;
}
void Sheet : : showColumn ( const Region & region )
{
HideShowManipulator * manipulator = new HideShowManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setManipulateColumns ( true ) ;
manipulator - > setReverse ( true ) ;
manipulator - > add ( region ) ;
manipulator - > execute ( ) ;
}
void Sheet : : refreshChart ( const TQPoint & pos , bool fullRowOrColumn , ChangeRef ref )
{
Cell * c = d - > cells . firstCell ( ) ;
for ( ; c ; c = c - > nextCell ( ) )
{
if ( ( ref = = ColumnInsert | | ref = = ColumnRemove ) & & fullRowOrColumn
& & c - > column ( ) > = ( pos . x ( ) - 1 ) )
{
if ( c - > updateChart ( ) )
return ;
}
else if ( ( ref = = ColumnInsert | | ref = = ColumnRemove ) & & ! fullRowOrColumn
& & c - > column ( ) > = ( pos . x ( ) - 1 ) & & c - > row ( ) = = pos . y ( ) )
{
if ( c - > updateChart ( ) )
return ;
}
else if ( ( ref = = RowInsert | | ref = = RowRemove ) & & fullRowOrColumn
& & c - > row ( ) > = ( pos . y ( ) - 1 ) )
{
if ( c - > updateChart ( ) )
return ;
}
else if ( ( ref = = RowInsert | | ref = = RowRemove ) & & ! fullRowOrColumn
& & c - > column ( ) = = pos . x ( ) & & c - > row ( ) > = ( pos . y ( ) - 1 ) )
{
if ( c - > updateChart ( ) )
return ;
}
}
//refresh chart when there is a chart and you remove
//all cells
if ( c = = 0L )
{
CellBinding * bind ;
for ( bind = firstCellBinding ( ) ; bind ! = 0L ; bind = nextCellBinding ( ) )
{
bind - > cellChanged ( 0 ) ;
}
// CellBinding * bind = firstCellBinding();
// if ( bind != 0L )
// bind->cellChanged( 0 );
}
}
void Sheet : : refreshMergedCell ( )
{
Cell * c = d - > cells . firstCell ( ) ;
for ( ; c ; c = c - > nextCell ( ) )
{
if ( c - > doesMergeCells ( ) )
c - > mergeCells ( c - > column ( ) , c - > row ( ) , c - > extraXCells ( ) , c - > extraYCells ( ) ) ;
}
}
void Sheet : : changeNameCellRef ( const TQPoint & pos , bool fullRowOrColumn ,
ChangeRef ref , TQString tabname , int nbCol ,
UndoInsertRemoveAction * undo )
{
bool correctDefaultSheetName = ( tabname = = name ( ) ) ; // for cells without sheet ref (eg "A1")
Cell * c = d - > cells . firstCell ( ) ;
for ( ; c ; c = c - > nextCell ( ) )
{
if ( c - > isFormula ( ) )
{
TQString origText = c - > text ( ) ;
unsigned int i = 0 ;
bool error = false ;
TQString newText ;
bool correctSheetName = correctDefaultSheetName ;
//bool previousCorrectSheetName = false;
TQChar origCh ;
for ( ; i < origText . length ( ) ; + + i )
{
origCh = origText [ i ] ;
if ( origCh ! = ' : ' & & origCh ! = ' $ ' & & ! origCh . isLetter ( ) )
{
newText + = origCh ;
// Reset the "correct table indicator"
correctSheetName = correctDefaultSheetName ;
}
else // Letter or dollar : maybe start of cell name/range
// (or even ':', like in a range - note that correctSheet is kept in this case)
{
// Collect everything that forms a name (cell name or sheet name)
TQString str ;
bool sheetNameFound = false ; //Sheet names need spaces
for ( ; ( i < origText . length ( ) ) & & // until the end
( ( origText [ i ] . isLetter ( ) | | origText [ i ] . isDigit ( ) | | origText [ i ] = = ' $ ' ) | | // all text and numbers are welcome
( sheetNameFound & & origText [ i ] . isSpace ( ) ) ) //in case of a sheet name, we include spaces too
; + + i )
{
str + = origText [ i ] ;
if ( origText [ i ] = = ' ! ' )
sheetNameFound = true ;
}
// Was it a sheet name ?
if ( origText [ i ] = = ' ! ' )
{
newText + = str + ' ! ' ; // Copy it (and the '!')
// Look for the sheet name right before that '!'
correctSheetName = ( newText . right ( tabname . length ( ) + 1 ) = = tabname + " ! " ) ;
}
else // It must be a cell identifier
{
// Parse it
Point point ( str ) ;
if ( point . isValid ( ) )
{
int col = point . pos ( ) . x ( ) ;
int row = point . pos ( ) . y ( ) ;
TQString newPoint ;
// Update column
if ( point . columnFixed ( ) )
newPoint = ' $ ' ;
if ( ref = = ColumnInsert
& & correctSheetName
& & col + nbCol < = KS_colMax
& & col > = pos . x ( ) // Column after the new one : +1
& & ( fullRowOrColumn | | row = = pos . y ( ) ) ) // All rows or just one
{
newPoint + = Cell : : columnName ( col + nbCol ) ;
}
else if ( ref = = ColumnRemove
& & correctSheetName
& & col > pos . x ( ) // Column after the deleted one : -1
& & ( fullRowOrColumn | | row = = pos . y ( ) ) ) // All rows or just one
{
newPoint + = Cell : : columnName ( col - nbCol ) ;
}
else
newPoint + = Cell : : columnName ( col ) ;
// Update row
if ( point . rowFixed ( ) )
newPoint + = ' $ ' ;
if ( ref = = RowInsert
& & correctSheetName
& & row + nbCol < = KS_rowMax
& & row > = pos . y ( ) // Row after the new one : +1
& & ( fullRowOrColumn | | col = = pos . x ( ) ) ) // All columns or just one
{
newPoint + = TQString : : number ( row + nbCol ) ;
}
else if ( ref = = RowRemove
& & correctSheetName
& & row > pos . y ( ) // Row after the deleted one : -1
& & ( fullRowOrColumn | | col = = pos . x ( ) ) ) // All columns or just one
{
newPoint + = TQString : : number ( row - nbCol ) ;
}
else
newPoint + = TQString : : number ( row ) ;
if ( correctSheetName & &
( ( ref = = ColumnRemove
& & col = = pos . x ( ) // Column is the deleted one : error
& & ( fullRowOrColumn | | row = = pos . y ( ) ) ) | |
( ref = = RowRemove
& & row = = pos . y ( ) // Row is the deleted one : error
& & ( fullRowOrColumn | | col = = pos . x ( ) ) ) | |
( ref = = ColumnInsert
& & col + nbCol > KS_colMax
& & col > = pos . x ( ) // Column after the new one : +1
& & ( fullRowOrColumn | | row = = pos . y ( ) ) ) | |
( ref = = RowInsert
& & row + nbCol > KS_rowMax
& & row > = pos . y ( ) // Row after the new one : +1
& & ( fullRowOrColumn | | col = = pos . x ( ) ) ) ) )
{
newPoint = " # " + i18n ( " Dependency " ) + " ! " ;
error = true ;
}
newText + = newPoint ;
}
else // Not a cell ref
{
kdDebug ( 36001 ) < < " Copying (unchanged) : ' " < < str < < " ' " < < endl ;
newText + = str ;
}
// Copy the char that got us to stop
if ( i < origText . length ( ) ) {
newText + = origText [ i ] ;
if ( origText [ i ] ! = ' : ' )
correctSheetName = correctDefaultSheetName ;
}
}
}
}
if ( error & & undo ! = 0 ) //Save the original formula, as we cannot calculate the undo of broken formulas
{
TQString formulaText = c - > text ( ) ;
int origCol = c - > column ( ) ;
int origRow = c - > row ( ) ;
if ( ref = = ColumnInsert & & origCol > = pos . x ( ) )
origCol - = nbCol ;
if ( ref = = RowInsert & & origRow > = pos . y ( ) )
origRow - = nbCol ;
if ( ref = = ColumnRemove & & origCol > = pos . x ( ) )
origCol + = nbCol ;
if ( ref = = RowRemove & & origRow > = pos . y ( ) )
origRow + = nbCol ;
undo - > saveFormulaReference ( this , origCol , origRow , formulaText ) ;
}
c - > setCellText ( newText ) ;
}
}
}
#if 0
void Sheet : : replace ( const TQString & _find , const TQString & _replace , long options ,
Canvas * canvas )
{
Selection * selectionInfo = canvas - > view ( ) - > selectionInfo ( ) ;
// Identify the region of interest.
TQRect region ( selectionInfo - > selection ( ) ) ;
TQPoint marker ( selectionInfo - > marker ( ) ) ;
if ( options & KReplaceDialog : : SelectedText )
{
// Complete rows selected ?
if ( util_isRowSelected ( region ) )
{
}
// Complete columns selected ?
else if ( util_isColumnSelected ( region ) )
{
}
}
else
{
// All cells.
region . setCoords ( 1 , 1 , d - > maxRow , d - > maxColumn ) ;
}
// Create the class that handles all the actual replace stuff, and connect it to its
// local slots.
KReplace dialog ( _find , _replace , options ) ;
TQObject : : connect (
& dialog , TQT_SIGNAL ( highlight ( const TQString & , int , int , const TQRect & ) ) ,
canvas , TQT_SLOT ( highlight ( const TQString & , int , int , const TQRect & ) ) ) ;
TQObject : : connect (
& dialog , TQT_SIGNAL ( replace ( const TQString & , int , int , int , const TQRect & ) ) ,
canvas , TQT_SLOT ( replace ( const TQString & , int , int , int , const TQRect & ) ) ) ;
// Now do the replacing...
if ( ! doc ( ) - > undoLocked ( ) )
{
UndoChangeAreaTextCell * undo = new UndoChangeAreaTextCell ( doc ( ) , this , region ) ;
doc ( ) - > addCommand ( undo ) ;
}
TQRect cellRegion ( 0 , 0 , 0 , 0 ) ;
bool bck = options & KFindDialog : : FindBackwards ;
int colStart = ! bck ? region . left ( ) : region . right ( ) ;
int colEnd = ! bck ? region . right ( ) : region . left ( ) ;
int rowStart = ! bck ? region . top ( ) : region . bottom ( ) ;
int rowEnd = ! bck ? region . bottom ( ) : region . top ( ) ;
if ( options & KFindDialog : : FromCursor ) {
colStart = marker . x ( ) ;
rowStart = marker . y ( ) ;
}
Cell * cell ;
for ( int row = rowStart ; ! bck ? row < rowEnd : row > rowEnd ; ! bck ? + + row : - - row )
{
for ( int col = colStart ; ! bck ? col < colEnd : col > colEnd ; ! bck ? + + col : - - col )
{
cell = cellAt ( col , row ) ;
if ( ! cell - > isDefault ( ) & & ! cell - > isObscured ( ) & & ! cell - > isFormula ( ) )
{
TQString text = cell - > text ( ) ;
cellRegion . setTop ( row ) ;
cellRegion . setLeft ( col ) ;
if ( ! dialog . replace ( text , cellRegion ) )
return ;
}
}
}
}
# endif
void Sheet : : borderBottom ( Selection * selectionInfo , const TQColor & _color )
{
BorderManipulator * manipulator = new BorderManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setBottomBorderPen ( TQPen ( _color , 1 , TQt : : SolidLine ) ) ;
manipulator - > add ( * selectionInfo ) ;
manipulator - > execute ( ) ;
}
void Sheet : : borderRight ( Selection * selectionInfo , const TQColor & _color )
{
BorderManipulator * manipulator = new BorderManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setRightBorderPen ( TQPen ( _color , 1 , TQt : : SolidLine ) ) ;
manipulator - > add ( * selectionInfo ) ;
manipulator - > execute ( ) ;
}
void Sheet : : borderLeft ( Selection * selectionInfo , const TQColor & _color )
{
BorderManipulator * manipulator = new BorderManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setLeftBorderPen ( TQPen ( _color , 1 , TQt : : SolidLine ) ) ;
manipulator - > add ( * selectionInfo ) ;
manipulator - > execute ( ) ;
}
void Sheet : : borderTop ( Selection * selectionInfo , const TQColor & _color )
{
BorderManipulator * manipulator = new BorderManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setTopBorderPen ( TQPen ( _color , 1 , TQt : : SolidLine ) ) ;
manipulator - > add ( * selectionInfo ) ;
manipulator - > execute ( ) ;
}
void Sheet : : borderOutline ( Selection * selectionInfo , const TQColor & _color )
{
BorderManipulator * manipulator = new BorderManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setTopBorderPen ( TQPen ( _color , 1 , TQt : : SolidLine ) ) ;
manipulator - > setBottomBorderPen ( TQPen ( _color , 1 , TQt : : SolidLine ) ) ;
manipulator - > setLeftBorderPen ( TQPen ( _color , 1 , TQt : : SolidLine ) ) ;
manipulator - > setRightBorderPen ( TQPen ( _color , 1 , TQt : : SolidLine ) ) ;
manipulator - > add ( * selectionInfo ) ;
manipulator - > execute ( ) ;
}
void Sheet : : borderAll ( Selection * selectionInfo ,
const TQColor & _color )
{
BorderManipulator * manipulator = new BorderManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setTopBorderPen ( TQPen ( _color , 1 , TQt : : SolidLine ) ) ;
manipulator - > setBottomBorderPen ( TQPen ( _color , 1 , TQt : : SolidLine ) ) ;
manipulator - > setLeftBorderPen ( TQPen ( _color , 1 , TQt : : SolidLine ) ) ;
manipulator - > setRightBorderPen ( TQPen ( _color , 1 , TQt : : SolidLine ) ) ;
manipulator - > setHorizontalPen ( TQPen ( _color , 1 , TQt : : SolidLine ) ) ;
manipulator - > setVerticalPen ( TQPen ( _color , 1 , TQt : : SolidLine ) ) ;
manipulator - > add ( * selectionInfo ) ;
manipulator - > execute ( ) ;
}
void Sheet : : borderRemove ( Selection * selectionInfo )
{
BorderManipulator * manipulator = new BorderManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setTopBorderPen ( TQPen ( TQt : : NoPen ) ) ;
manipulator - > setBottomBorderPen ( TQPen ( TQt : : NoPen ) ) ;
manipulator - > setLeftBorderPen ( TQPen ( TQt : : NoPen ) ) ;
manipulator - > setRightBorderPen ( TQPen ( TQt : : NoPen ) ) ;
manipulator - > setHorizontalPen ( TQPen ( TQt : : NoPen ) ) ;
manipulator - > setVerticalPen ( TQPen ( TQt : : NoPen ) ) ;
manipulator - > add ( * selectionInfo ) ;
manipulator - > execute ( ) ;
}
void Sheet : : sortByRow ( const TQRect & area , int ref_row , SortingOrder mode )
{
Point point ;
point . setSheet ( this ) ;
point . setSheetName ( d - > name ) ;
point . setPos ( area . topLeft ( ) ) ;
point . setColumnFixed ( false ) ;
point . setRowFixed ( false ) ;
sortByRow ( area , ref_row , 0 , 0 , mode , mode , mode , 0 , false , false , point , true ) ;
}
void Sheet : : sortByColumn ( const TQRect & area , int ref_column , SortingOrder mode )
{
Point point ;
point . setSheet ( this ) ;
point . setSheetName ( d - > name ) ;
point . setPos ( area . topLeft ( ) ) ;
point . setColumnFixed ( false ) ;
point . setRowFixed ( false ) ;
sortByColumn ( area , ref_column , 0 , 0 , mode , mode , mode , 0 , false , false ,
point , true ) ;
}
void Sheet : : checkCellContent ( Cell * cell1 , Cell * cell2 , int & ret )
{
if ( cell1 - > isEmpty ( ) )
{
ret = 1 ;
return ;
}
else if ( cell1 - > isObscured ( ) & & cell1 - > isPartOfMerged ( ) )
{
ret = 1 ;
return ;
}
else if ( cell2 - > isEmpty ( ) )
{
ret = 2 ;
return ;
}
ret = 0 ;
}
void Sheet : : sortByRow ( const TQRect & area , int key1 , int key2 , int key3 ,
SortingOrder order1 , SortingOrder order2 ,
SortingOrder order3 ,
TQStringList const * firstKey , bool copyFormat ,
bool headerRow , Point const & outputPoint , bool respectCase )
{
TQRect r ( area ) ;
Map : : respectCase = respectCase ;
Q_ASSERT ( order1 = = Increase | | order1 = = Decrease ) ;
// It may not happen that entire columns are selected.
Q_ASSERT ( util_isColumnSelected ( r ) = = false ) ;
// Are entire rows selected ?
if ( util_isRowSelected ( r ) )
{
r . setLeft ( KS_colMax ) ;
r . setRight ( 0 ) ;
// Determine a correct left and right.
// Iterate over all cells to find out which cells are
// located in the selected rows.
for ( int row = r . top ( ) ; row < = r . bottom ( ) ; + + row )
{
Cell * c = getFirstCellRow ( row ) ;
int col ;
while ( c )
{
col = c - > column ( ) ;
if ( ! c - > isEmpty ( ) )
{
if ( col > r . right ( ) )
r . rRight ( ) = col ;
if ( col < r . left ( ) )
r . rLeft ( ) = col ;
}
c = getNextCellRight ( col , row ) ;
}
}
// Any cells to sort here ?
if ( r . right ( ) < r . left ( ) )
{
Map : : respectCase = true ;
return ;
}
}
TQRect target ( outputPoint . pos ( ) . x ( ) , outputPoint . pos ( ) . y ( ) , r . width ( ) , r . height ( ) ) ;
doc ( ) - > emitBeginOperation ( ) ;
if ( ! doc ( ) - > undoLocked ( ) )
{
UndoSort * undo = new UndoSort ( doc ( ) , this , target ) ;
doc ( ) - > addCommand ( undo ) ;
}
if ( target . topLeft ( ) ! = r . topLeft ( ) )
{
int targetLeft = target . left ( ) ;
int targetTop = target . top ( ) ;
int sourceTop = r . top ( ) ;
int sourceLeft = r . left ( ) ;
key1 = key1 - sourceTop + targetTop ;
key2 = key2 - sourceTop + targetTop ;
key3 = key3 - sourceTop + targetTop ;
for ( int x = 0 ; x < r . width ( ) ; + + x )
{
for ( int y = 0 ; y < r . height ( ) ; + + y )
{
// from - to
copyCells ( sourceLeft + x , sourceTop + y ,
targetLeft + x , targetTop + y , copyFormat ) ;
}
}
}
// Sorting algorithm: David's :). Well, I guess it's called minmax or so.
// For each column, we look for all cells right hand of it and we find the one to swap with it.
// Much faster than the awful bubbleSort...
Cell * cell ;
Cell * cell1 ;
Cell * cell2 ;
Cell * bestCell ;
int status = 0 ;
for ( int d = target . left ( ) ; d < = target . right ( ) ; + + d )
{
cell1 = cellAt ( d , key1 ) ;
if ( cell1 - > isObscured ( ) & & cell1 - > isPartOfMerged ( ) )
{
Cell * obscuring = cell1 - > obscuringCells ( ) . first ( ) ;
cell = cellAt ( obscuring - > column ( ) , key1 ) ;
cell1 = cellAt ( obscuring - > column ( ) + cell - > extraXCells ( ) + 1 ,
obscuring - > column ( ) ) ;
d = obscuring - > column ( ) + cell - > extraXCells ( ) + 1 ;
}
// Look for which column we want to swap with the one number d
bestCell = cell1 ;
int bestX = d ;
for ( int x = d + 1 ; x < = target . right ( ) ; x + + )
{
cell2 = cellAt ( x , key1 ) ;
checkCellContent ( cell2 , bestCell , status ) ;
if ( status = = 1 )
continue ;
else if ( status = = 2 )
{
// empty cells are always shifted to the end
bestCell = cell2 ;
bestX = x ;
continue ;
}
if ( firstKey )
{
int i1 = firstKey - > findIndex ( cell2 - > text ( ) ) ;
int i2 = firstKey - > findIndex ( bestCell - > text ( ) ) ;
if ( i1 ! = - 1 & & i2 ! = - 1 )
{
if ( ( order1 = = Increase & & i1 < i2 )
| | ( order1 = = Decrease & & i1 > i2 ) )
{
bestCell = cell2 ;
bestX = x ;
continue ;
}
if ( i1 = = i2 )
{
// check 2nd key
if ( key2 < = 0 )
continue ;
Cell * cell22 = cellAt ( x , key2 ) ;
Cell * bestCell2 = cellAt ( bestX , key2 ) ;
if ( cell22 - > isEmpty ( ) )
{
/* No need to swap */
continue ;
}
else if ( cell22 - > isObscured ( ) & & cell22 - > isPartOfMerged ( ) )
{
/* No need to swap */
continue ;
}
else if ( bestCell2 - > isEmpty ( ) )
{
// empty cells are always shifted to the end
bestCell = cell2 ;
bestX = x ;
continue ;
}
if ( ( order2 = = Increase & & * cell22 < * bestCell2 )
| | ( order2 = = Decrease & & * cell22 > * bestCell2 ) )
{
bestCell = cell2 ;
bestX = x ;
continue ;
}
else if ( ( order2 = = Increase & & * cell22 > * bestCell2 )
| | ( order2 = = Decrease & & * cell22 < * bestCell2 ) )
{
// already in right order
continue ;
}
else
{
// they are equal, check 3rd key
if ( key3 < = 0 )
continue ;
Cell * cell23 = cellAt ( x , key3 ) ;
Cell * bestCell3 = cellAt ( bestX , key3 ) ;
if ( cell23 - > isEmpty ( ) )
{
/* No need to swap */
continue ;
}
else if ( cell23 - > isObscured ( ) & & cell23 - > isPartOfMerged ( ) )
{
/* No need to swap */
continue ;
}
else if ( bestCell3 - > isEmpty ( ) )
{
// empty cells are always shifted to the end
bestCell = cell2 ;
bestX = x ;
continue ;
}
if ( ( order3 = = Increase & & * cell23 < * bestCell3 )
| | ( order3 = = Decrease & & * cell23 > * bestCell3 ) )
{
// they are really equal or in the right order
// no swap necessary
continue ;
}
else
{
bestCell = cell2 ;
bestX = x ;
continue ;
}
}
}
continue ;
}
else if ( i1 ! = - 1 & & i2 = = - 1 )
{
// if not in the key list, the cell is shifted to the end - always
bestCell = cell2 ;
bestX = x ;
continue ;
}
else if ( i2 ! = - 1 & & i1 = = - 1 )
{
// only text of cell2 is in the list so it is smaller than bestCell
/* No need to swap */
continue ;
}
// if i1 and i2 are equals -1 go on:
} // end if (firstKey)
// Here we use the operators < and > for cells, which do it all.
if ( ( order1 = = Increase & & * cell2 < * bestCell )
| | ( order1 = = Decrease & & * cell2 > * bestCell ) )
{
bestCell = cell2 ;
bestX = x ;
continue ;
}
else if ( ( order1 = = Increase & & * cell2 > * bestCell )
| | ( order1 = = Decrease & & * cell2 < * bestCell ) )
{
// no change necessary
continue ;
}
else
{
// *cell2 equals *bestCell
// check 2nd key
if ( key2 < = 0 )
continue ;
Cell * cell22 = cellAt ( d , key2 ) ;
Cell * bestCell2 = cellAt ( x , key2 ) ;
checkCellContent ( cell2 , bestCell , status ) ;
if ( status = = 1 )
continue ;
else if ( status = = 2 )
{
// empty cells are always shifted to the end
bestCell = cell2 ;
bestX = x ;
continue ;
}
if ( ( order2 = = Increase & & * cell22 > * bestCell2 )
| | ( order2 = = Decrease & & * cell22 < * bestCell2 ) )
{
bestCell = cell2 ;
bestX = x ;
continue ;
}
else
if ( ( order2 = = Increase & & * cell22 > * bestCell2 )
| | ( order2 = = Decrease & & * cell22 < * bestCell2 ) )
{
// already in right order
continue ;
}
else
{
// they are equal, check 3rd key
if ( key3 = = 0 )
continue ;
Cell * cell23 = cellAt ( d , key3 ) ;
Cell * bestCell3 = cellAt ( x , key3 ) ;
checkCellContent ( cell2 , bestCell , status ) ;
if ( status = = 1 )
continue ;
else if ( status = = 2 )
{
// empty cells are always shifted to the end
bestCell = cell2 ;
bestX = x ;
continue ;
}
if ( ( order3 = = Increase & & * cell23 > * bestCell3 )
| | ( order3 = = Decrease & & * cell23 < * bestCell3 ) )
{
bestCell = cell2 ;
bestX = x ;
continue ;
}
else
{
// they are really equal
// no swap necessary
continue ;
}
}
}
}
// Swap columns cell1 and bestCell (i.e. d and bestX)
if ( d ! = bestX )
{
int top = target . top ( ) ;
if ( headerRow )
+ + top ;
for ( int y = target . bottom ( ) ; y > = top ; - - y )
{
if ( y ! = key1 & & y ! = key2 & & y ! = key3 )
swapCells ( d , y , bestX , y , copyFormat ) ;
}
if ( key3 > 0 )
swapCells ( d , key3 , bestX , key3 , copyFormat ) ;
if ( key2 > 0 )
swapCells ( d , key2 , bestX , key2 , copyFormat ) ;
swapCells ( d , key1 , bestX , key1 , copyFormat ) ;
}
} // for (d = ...; ...; ++d)
Map : : respectCase = true ;
// doc()->emitEndOperation();
emit sig_updateView ( this ) ;
}
void Sheet : : sortByColumn ( const TQRect & area , int key1 , int key2 , int key3 ,
SortingOrder order1 , SortingOrder order2 ,
SortingOrder order3 ,
TQStringList const * firstKey , bool copyFormat ,
bool headerRow ,
Point const & outputPoint , bool respectCase )
{
TQRect r ( area ) ;
Map : : respectCase = respectCase ;
Q_ASSERT ( order1 = = Increase | | order1 = = Decrease ) ;
// It may not happen that entire rows are selected.
Q_ASSERT ( util_isRowSelected ( r ) = = false ) ;
// Are entire columns selected ?
if ( util_isColumnSelected ( r ) )
{
r . setTop ( KS_rowMax ) ;
r . setBottom ( 0 ) ;
// Determine a correct top and bottom.
// Iterate over all cells to find out which cells are
// located in the selected columns.
for ( int col = r . left ( ) ; col < = r . right ( ) ; + + col )
{
Cell * c = getFirstCellColumn ( col ) ;
int row ;
while ( c )
{
row = c - > row ( ) ;
if ( ! c - > isEmpty ( ) )
{
if ( row > r . bottom ( ) )
r . rBottom ( ) = row ;
if ( row < r . top ( ) )
r . rTop ( ) = row ;
}
c = getNextCellDown ( col , row ) ;
}
}
// Any cells to sort here ?
if ( r . bottom ( ) < r . top ( ) )
{
Map : : respectCase = true ;
return ;
}
}
TQRect target ( outputPoint . pos ( ) . x ( ) , outputPoint . pos ( ) . y ( ) , r . width ( ) , r . height ( ) ) ;
if ( ! doc ( ) - > undoLocked ( ) )
{
UndoSort * undo = new UndoSort ( doc ( ) , this , target ) ;
doc ( ) - > addCommand ( undo ) ;
}
doc ( ) - > emitBeginOperation ( ) ;
if ( target . topLeft ( ) ! = r . topLeft ( ) )
{
int targetLeft = target . left ( ) ;
int targetTop = target . top ( ) ;
int sourceTop = r . top ( ) ;
int sourceLeft = r . left ( ) ;
key1 = key1 - sourceLeft + targetLeft ;
key2 = key2 - sourceLeft + targetLeft ;
key3 = key3 - sourceLeft + targetLeft ;
for ( int x = 0 ; x < r . width ( ) ; + + x )
{
for ( int y = 0 ; y < r . height ( ) ; + + y )
{
// from - to
copyCells ( sourceLeft + x , sourceTop + y ,
targetLeft + x , targetTop + y , copyFormat ) ;
}
}
}
// Sorting algorithm: David's :). Well, I guess it's called minmax or so.
// For each row, we look for all rows under it and we find the one to swap with it.
// Much faster than the awful bubbleSort...
// Torben: Asymptotically it is alltogether O(n^2) :-)
Cell * cell ;
Cell * cell1 ;
Cell * cell2 ;
Cell * bestCell ;
int status = 0 ;
int d = target . top ( ) ;
if ( headerRow )
+ + d ;
for ( ; d < = target . bottom ( ) ; + + d )
{
// Look for which row we want to swap with the one number d
cell1 = cellAt ( key1 , d ) ;
if ( cell1 - > isObscured ( ) & & cell1 - > isPartOfMerged ( ) )
{
Cell * obscuring = cell1 - > obscuringCells ( ) . first ( ) ;
cell = cellAt ( key1 , obscuring - > row ( ) ) ;
cell1 = cellAt ( key1 , obscuring - > row ( ) + cell - > extraYCells ( ) + 1 ) ;
d = obscuring - > row ( ) + cell - > extraYCells ( ) + 1 ;
}
bestCell = cell1 ;
int bestY = d ;
for ( int y = d + 1 ; y < = target . bottom ( ) ; + + y )
{
cell2 = cellAt ( key1 , y ) ;
if ( cell2 - > isEmpty ( ) )
{
/* No need to swap */
continue ;
}
else if ( cell2 - > isObscured ( ) & & cell2 - > isPartOfMerged ( ) )
{
/* No need to swap */
continue ;
}
else if ( bestCell - > isEmpty ( ) )
{
// empty cells are always shifted to the end
bestCell = cell2 ;
bestY = y ;
continue ;
}
if ( firstKey )
{
int i1 = firstKey - > findIndex ( cell2 - > text ( ) ) ;
int i2 = firstKey - > findIndex ( bestCell - > text ( ) ) ;
if ( i1 ! = - 1 & & i2 ! = - 1 )
{
if ( ( order1 = = Increase & & i1 < i2 )
| | ( order1 = = Decrease & & i1 > i2 ) )
{
bestCell = cell2 ;
bestY = y ;
continue ;
}
if ( i1 = = i2 )
{
// check 2nd key
if ( key2 < = 0 )
continue ;
Cell * cell22 = cellAt ( key2 , d ) ;
Cell * bestCell2 = cellAt ( key2 , y ) ;
if ( cell22 - > isEmpty ( ) )
{
/* No need to swap */
continue ;
}
else if ( cell22 - > isObscured ( ) & & cell22 - > isPartOfMerged ( ) )
{
/* No need to swap */
continue ;
}
else if ( bestCell2 - > isEmpty ( ) )
{
// empty cells are always shifted to the end
bestCell = cell2 ;
bestY = y ;
continue ;
}
if ( ( order2 = = Increase & & * cell22 > * bestCell2 )
| | ( order2 = = Decrease & & * cell22 < * bestCell2 ) )
{
bestCell = cell2 ;
bestY = y ;
continue ;
}
else if ( ( order2 = = Increase & & * cell22 < * bestCell2 )
| | ( order2 = = Decrease & & * cell22 > * bestCell2 ) )
{
// already in right order
continue ;
}
else
{
// they are equal, check 3rd key
if ( key3 < = 0 )
continue ;
Cell * cell23 = cellAt ( key3 , d ) ;
Cell * bestCell3 = cellAt ( key3 , y ) ;
checkCellContent ( cell2 , bestCell , status ) ;
if ( status = = 1 )
continue ;
else if ( status = = 2 )
{
// empty cells are always shifted to the end
bestCell = cell2 ;
bestY = y ;
continue ;
}
if ( ( order3 = = Increase & & * cell23 < * bestCell3 )
| | ( order3 = = Decrease & & * cell23 > * bestCell3 ) )
{
bestCell = cell2 ;
bestY = y ;
continue ;
}
else
{
// they are really equal or in the correct order
// no swap necessary
continue ;
}
}
}
continue ;
}
else if ( i1 ! = - 1 & & i2 = = - 1 )
{
// if not in the key list, the cell is shifted to the end - always
bestCell = cell2 ;
bestY = y ;
continue ;
}
else if ( i2 ! = - 1 & & i1 = = - 1 )
{
// only text of cell2 is in the list so it is smaller than bestCell
/* No need to swap */
continue ;
}
// if i1 and i2 are equals -1 go on:
} // if (firstKey)
// Here we use the operators < and > for cells, which do it all.
if ( ( order1 = = Increase & & * cell2 < * bestCell )
| | ( order1 = = Decrease & & * cell2 > * bestCell ) )
{
bestCell = cell2 ;
bestY = y ;
}
else if ( ( order1 = = Increase & & * cell2 > * bestCell )
| | ( order1 = = Decrease & & * cell2 < * bestCell ) )
{
// no change necessary
continue ;
}
else
{
// *cell2 equals *bestCell
// check 2nd key
if ( key2 = = 0 )
continue ;
Cell * cell22 = cellAt ( key2 , y ) ;
Cell * bestCell2 = cellAt ( key2 , bestY ) ;
if ( cell22 - > isEmpty ( ) )
{
/* No need to swap */
continue ;
}
else if ( cell22 - > isObscured ( ) & & cell22 - > isPartOfMerged ( ) )
{
/* No need to swap */
continue ;
}
else if ( bestCell2 - > isEmpty ( ) )
{
// empty cells are always shifted to the end
bestCell = cell2 ;
bestY = y ;
continue ;
}
if ( ( order2 = = Increase & & * cell22 < * bestCell2 )
| | ( order2 = = Decrease & & * cell22 > * bestCell2 ) )
{
bestCell = cell2 ;
bestY = y ;
continue ;
}
else if ( ( order2 = = Increase & & * cell22 > * bestCell2 )
| | ( order2 = = Decrease & & * cell22 < * bestCell2 ) )
{
continue ;
}
else
{
// they are equal, check 3rd key
if ( key3 = = 0 )
continue ;
Cell * cell23 = cellAt ( key3 , y ) ;
Cell * bestCell3 = cellAt ( key3 , bestY ) ;
if ( cell23 - > isEmpty ( ) )
{
/* No need to swap */
continue ;
}
else if ( cell23 - > isObscured ( ) & & cell23 - > isPartOfMerged ( ) )
{
/* No need to swap */
continue ;
}
else if ( bestCell3 - > isEmpty ( ) )
{
// empty cells are always shifted to the end
bestCell = cell2 ;
bestY = y ;
continue ;
}
if ( ( order3 = = Increase & & * cell23 < * bestCell3 )
| | ( order3 = = Decrease & & * cell23 > * bestCell3 ) )
{
bestCell = cell2 ;
bestY = y ;
continue ;
}
else
{
// they are really equal or already in the correct order
// no swap necessary
continue ;
}
}
}
}
// Swap rows cell1 and bestCell (i.e. d and bestY)
if ( d ! = bestY )
{
for ( int x = target . left ( ) ; x < = target . right ( ) ; + + x )
{
if ( x ! = key1 & & x ! = key2 & & x ! = key3 )
swapCells ( x , d , x , bestY , copyFormat ) ;
}
if ( key3 > 0 )
swapCells ( key3 , d , key3 , bestY , copyFormat ) ;
if ( key2 > 0 )
swapCells ( key2 , d , key2 , bestY , copyFormat ) ;
swapCells ( key1 , d , key1 , bestY , copyFormat ) ;
}
} // for (d = ...; ...; ++d)
// doc()->emitEndOperation();
Map : : respectCase = true ;
emit sig_updateView ( this ) ;
}
// from - to - copyFormat
void Sheet : : copyCells ( int x1 , int y1 , int x2 , int y2 , bool cpFormat )
{
Cell * sourceCell = cellAt ( x1 , y1 ) ;
Cell * targetCell = cellAt ( x2 , y2 ) ;
if ( sourceCell - > isDefault ( ) & & targetCell - > isDefault ( ) )
{
// if the source and target is default there is nothing to copy
return ;
}
targetCell = nonDefaultCell ( x2 , y2 ) ;
// TODO: check if this enough
targetCell - > copyContent ( sourceCell ) ;
/*
if ( ! sourceCell - > isFormula ( ) )
{
targetCell - > copyContent ( sourceCell ) ;
}
else
{
targetCell - > setCellText ( targetCell - > decodeFormula ( sourceCell - > encodeFormula ( ) ) ) ;
targetCell - > setCalcDirtyFlag ( ) ;
targetCell - > calc ( false ) ;
}
*/
if ( cpFormat )
{
targetCell - > copyFormat ( sourceCell ) ;
/*
targetCell - > setAlign ( sourceCell - > format ( ) - > align ( x1 , y1 ) ) ;
targetCell - > setAlignY ( sourceCell - > format ( ) - > alignY ( x1 , y1 ) ) ;
targetCell - > setTextFont ( sourceCell - > format ( ) - > textFont ( x1 , y1 ) ) ;
targetCell - > setTextColor ( sourceCell - > textColor ( x1 , y1 ) ) ;
targetCell - > setBgColor ( sourceCell - > bgColor ( x1 , y1 ) ) ;
targetCell - > setLeftBorderPen ( sourceCell - > leftBorderPen ( x1 , y1 ) ) ;
targetCell - > setTopBorderPen ( sourceCell - > topBorderPen ( x1 , y1 ) ) ;
targetCell - > setBottomBorderPen ( sourceCell - > bottomBorderPen ( x1 , y1 ) ) ;
targetCell - > setRightBorderPen ( sourceCell - > rightBorderPen ( x1 , y1 ) ) ;
targetCell - > setFallDiagonalPen ( sourceCell - > fallDiagonalPen ( x1 , y1 ) ) ;
targetCell - > setGoUpDiagonalPen ( sourceCell - > goUpDiagonalPen ( x1 , y1 ) ) ;
targetCell - > setBackGroundBrush ( sourceCell - > backGroundBrush ( x1 , y1 ) ) ;
targetCell - > setPrecision ( sourceCell - > precision ( x1 , y1 ) ) ;
targetCell - > format ( ) - > setPrefix ( sourceCell - > prefix ( x1 , y1 ) ) ;
targetCell - > format ( ) - > setPostfix ( sourceCell - > postfix ( x1 , y1 ) ) ;
targetCell - > setFloatFormat ( sourceCell - > floatFormat ( x1 , y1 ) ) ;
targetCell - > setFloatColor ( sourceCell - > floatColor ( x1 , y1 ) ) ;
targetCell - > setMultiRow ( sourceCell - > multiRow ( x1 , y1 ) ) ;
targetCell - > setVerticalText ( sourceCell - > verticalText ( x1 , y1 ) ) ;
targetCell - > setStyle ( sourceCell - > style ( ) ) ;
targetCell - > setDontPrintText ( sourceCell - > getDontprintText ( x1 , y1 ) ) ;
targetCell - > setIndent ( sourceCell - > getIndent ( x1 , y1 ) ) ;
targetCell - > SetConditionList ( sourceCell - > GetConditionList ( ) ) ;
targetCell - > setComment ( sourceCell - > comment ( x1 , y1 ) ) ;
targetCell - > setAngle ( sourceCell - > getAngle ( x1 , y1 ) ) ;
targetCell - > setFormatType ( sourceCell - > getFormatType ( x1 , y1 ) ) ;
*/
}
}
void Sheet : : swapCells ( int x1 , int y1 , int x2 , int y2 , bool cpFormat )
{
Cell * ref1 = cellAt ( x1 , y1 ) ;
Cell * ref2 = cellAt ( x2 , y2 ) ;
if ( ref1 - > isDefault ( ) )
{
if ( ! ref2 - > isDefault ( ) )
{
ref1 = nonDefaultCell ( x1 , y1 ) ;
// TODO : make ref2 default instead of copying a default cell into it
}
else
return ; // nothing to do
}
else
if ( ref2 - > isDefault ( ) )
{
ref2 = nonDefaultCell ( x2 , y2 ) ;
// TODO : make ref1 default instead of copying a default cell into it
}
// Dummy cell used for swapping cells.
// In fact we copy only content and no layout
// information. Imagine sorting in a sheet. Swapping
// the format while sorting is not what you would expect
// as a user.
if ( ! ref1 - > isFormula ( ) & & ! ref2 - > isFormula ( ) )
{
Cell * tmp = new Cell ( this , - 1 , - 1 ) ;
tmp - > copyContent ( ref1 ) ;
ref1 - > copyContent ( ref2 ) ;
ref2 - > copyContent ( tmp ) ;
delete tmp ;
}
else
if ( ref1 - > isFormula ( ) & & ref2 - > isFormula ( ) )
{
TQString d = ref1 - > encodeFormula ( ) ;
ref1 - > setCellText ( ref1 - > decodeFormula ( ref2 - > encodeFormula ( ) ) ) ;
ref1 - > setCalcDirtyFlag ( ) ;
ref1 - > calc ( false ) ;
ref2 - > setCellText ( ref2 - > decodeFormula ( d ) ) ;
ref2 - > setCalcDirtyFlag ( ) ;
ref2 - > calc ( false ) ;
}
else
if ( ref1 - > isFormula ( ) & & ! ref2 - > isFormula ( ) )
{
TQString d = ref1 - > encodeFormula ( ) ;
ref1 - > setCellText ( ref2 - > text ( ) ) ;
ref2 - > setCellText ( ref2 - > decodeFormula ( d ) ) ;
ref2 - > setCalcDirtyFlag ( ) ;
ref2 - > calc ( false ) ;
}
else
if ( ! ref1 - > isFormula ( ) & & ref2 - > isFormula ( ) )
{
TQString d = ref2 - > encodeFormula ( ) ;
ref2 - > setCellText ( ref1 - > text ( ) ) ;
ref1 - > setCellText ( ref1 - > decodeFormula ( d ) ) ;
ref1 - > setCalcDirtyFlag ( ) ;
ref1 - > calc ( false ) ;
}
if ( cpFormat )
{
Format : : Align a = ref1 - > format ( ) - > align ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setAlign ( ref2 - > format ( ) - > align ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setAlign ( a ) ;
Format : : AlignY ay = ref1 - > format ( ) - > alignY ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setAlignY ( ref2 - > format ( ) - > alignY ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setAlignY ( ay ) ;
TQFont textFont = ref1 - > format ( ) - > textFont ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setTextFont ( ref2 - > format ( ) - > textFont ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setTextFont ( textFont ) ;
TQColor textColor = ref1 - > format ( ) - > textColor ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setTextColor ( ref2 - > format ( ) - > textColor ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setTextColor ( textColor ) ;
TQColor bgColor = ref1 - > bgColor ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setBgColor ( ref2 - > bgColor ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setBgColor ( bgColor ) ;
TQPen lbp = ref1 - > leftBorderPen ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > setLeftBorderPen ( ref2 - > leftBorderPen ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > setLeftBorderPen ( lbp ) ;
TQPen tbp = ref1 - > topBorderPen ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > setTopBorderPen ( ref2 - > topBorderPen ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > setTopBorderPen ( tbp ) ;
TQPen bbp = ref1 - > bottomBorderPen ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > setBottomBorderPen ( ref2 - > bottomBorderPen ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > setBottomBorderPen ( bbp ) ;
TQPen rbp = ref1 - > rightBorderPen ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > setRightBorderPen ( ref2 - > rightBorderPen ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > setRightBorderPen ( rbp ) ;
TQPen fdp = ref1 - > format ( ) - > fallDiagonalPen ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setFallDiagonalPen ( ref2 - > format ( ) - > fallDiagonalPen ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setFallDiagonalPen ( fdp ) ;
TQPen udp = ref1 - > format ( ) - > goUpDiagonalPen ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setGoUpDiagonalPen ( ref2 - > format ( ) - > goUpDiagonalPen ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setGoUpDiagonalPen ( udp ) ;
TQBrush bgBrush = ref1 - > backGroundBrush ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setBackGroundBrush ( ref2 - > backGroundBrush ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setBackGroundBrush ( bgBrush ) ;
int pre = ref1 - > format ( ) - > precision ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setPrecision ( ref2 - > format ( ) - > precision ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setPrecision ( pre ) ;
TQString prefix = ref1 - > format ( ) - > prefix ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setPrefix ( ref2 - > format ( ) - > prefix ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setPrefix ( prefix ) ;
TQString postfix = ref1 - > format ( ) - > postfix ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setPostfix ( ref2 - > format ( ) - > postfix ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setPostfix ( postfix ) ;
Format : : FloatFormat f = ref1 - > format ( ) - > floatFormat ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setFloatFormat ( ref2 - > format ( ) - > floatFormat ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setFloatFormat ( f ) ;
Format : : FloatColor c = ref1 - > format ( ) - > floatColor ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setFloatColor ( ref2 - > format ( ) - > floatColor ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setFloatColor ( c ) ;
bool multi = ref1 - > format ( ) - > multiRow ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setMultiRow ( ref2 - > format ( ) - > multiRow ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setMultiRow ( multi ) ;
bool vert = ref1 - > format ( ) - > verticalText ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setVerticalText ( ref2 - > format ( ) - > verticalText ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setVerticalText ( vert ) ;
bool print = ref1 - > format ( ) - > getDontprintText ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setDontPrintText ( ref2 - > format ( ) - > getDontprintText ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setDontPrintText ( print ) ;
double ind = ref1 - > format ( ) - > getIndent ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setIndent ( ref2 - > format ( ) - > getIndent ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setIndent ( ind ) ;
TQValueList < Conditional > conditionList = ref1 - > conditionList ( ) ;
ref1 - > setConditionList ( ref2 - > conditionList ( ) ) ;
ref2 - > setConditionList ( conditionList ) ;
TQString com = ref1 - > format ( ) - > comment ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setComment ( ref2 - > format ( ) - > comment ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setComment ( com ) ;
int angle = ref1 - > format ( ) - > getAngle ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setAngle ( ref2 - > format ( ) - > getAngle ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setAngle ( angle ) ;
FormatType form = ref1 - > format ( ) - > getFormatType ( ref1 - > column ( ) , ref1 - > row ( ) ) ;
ref1 - > format ( ) - > setFormatType ( ref2 - > format ( ) - > getFormatType ( ref2 - > column ( ) , ref2 - > row ( ) ) ) ;
ref2 - > format ( ) - > setFormatType ( form ) ;
}
}
void Sheet : : refreshPreference ( )
{
if ( getAutoCalc ( ) )
recalc ( ) ;
emit sig_updateHBorder ( this ) ;
emit sig_updateView ( this ) ;
}
bool Sheet : : areaIsEmpty ( const Region & region , TestType _type )
{
Region : : ConstIterator endOfList = region . constEnd ( ) ;
for ( Region : : ConstIterator it = region . constBegin ( ) ; it ! = endOfList ; + + it )
{
TQRect range = ( * it ) - > rect ( ) . normalize ( ) ;
// Complete rows selected ?
if ( ( * it ) - > isRow ( ) )
{
for ( int row = range . top ( ) ; row < = range . bottom ( ) ; + + row )
{
Cell * c = getFirstCellRow ( row ) ;
while ( c )
{
if ( ! c - > isPartOfMerged ( ) )
{
switch ( _type )
{
case Text :
if ( ! c - > text ( ) . isEmpty ( ) )
return false ;
break ;
case Validity :
if ( c - > getValidity ( 0 ) )
return false ;
break ;
case Comment :
if ( ! c - > format ( ) - > comment ( c - > column ( ) , row ) . isEmpty ( ) )
return false ;
break ;
case ConditionalCellAttribute :
if ( c - > conditionList ( ) . count ( ) > 0 )
return false ;
break ;
}
}
c = getNextCellRight ( c - > column ( ) , row ) ;
}
}
}
// Complete columns selected ?
else if ( ( * it ) - > isColumn ( ) )
{
for ( int col = range . left ( ) ; col < = range . right ( ) ; + + col )
{
Cell * c = getFirstCellColumn ( col ) ;
while ( c )
{
if ( ! c - > isPartOfMerged ( ) )
{
switch ( _type )
{
case Text :
if ( ! c - > text ( ) . isEmpty ( ) )
return false ;
break ;
case Validity :
if ( c - > getValidity ( 0 ) )
return false ;
break ;
case Comment :
if ( ! c - > format ( ) - > comment ( col , c - > row ( ) ) . isEmpty ( ) )
return false ;
break ;
case ConditionalCellAttribute :
if ( c - > conditionList ( ) . count ( ) > 0 )
return false ;
break ;
}
}
c = getNextCellDown ( col , c - > row ( ) ) ;
}
}
}
else
{
Cell * cell ;
int right = range . right ( ) ;
int bottom = range . bottom ( ) ;
for ( int x = range . left ( ) ; x < = right ; + + x )
for ( int y = range . top ( ) ; y < = bottom ; + + y )
{
cell = cellAt ( x , y ) ;
if ( ! cell - > isPartOfMerged ( ) )
{
switch ( _type )
{
case Text :
if ( ! cell - > text ( ) . isEmpty ( ) )
return false ;
break ;
case Validity :
if ( cell - > getValidity ( 0 ) )
return false ;
break ;
case Comment :
if ( ! cell - > format ( ) - > comment ( x , y ) . isEmpty ( ) )
return false ;
break ;
case ConditionalCellAttribute :
if ( cell - > conditionList ( ) . count ( ) > 0 )
return false ;
break ;
}
}
}
}
}
return true ;
}
struct SetSelectionMultiRowWorker : public Sheet : : CellWorker
{
bool enable ;
SetSelectionMultiRowWorker ( bool _enable )
: Sheet : : CellWorker ( ) , enable ( _enable ) { }
class UndoAction * createUndoAction ( Doc * doc , Sheet * sheet , const KSpread : : Region & region )
{
TQString title = i18n ( " Multirow " ) ;
return new UndoCellFormat ( doc , sheet , region , title ) ;
}
bool testCondition ( Cell * cell )
{
return ( ! cell - > isPartOfMerged ( ) ) ;
}
void doWork ( Cell * cell , bool , int , int )
{
cell - > setDisplayDirtyFlag ( ) ;
cell - > format ( ) - > setMultiRow ( enable ) ;
cell - > format ( ) - > setVerticalText ( false ) ;
cell - > format ( ) - > setAngle ( 0 ) ;
cell - > clearDisplayDirtyFlag ( ) ;
}
} ;
void Sheet : : setSelectionMultiRow ( Selection * selectionInfo ,
bool enable )
{
SetSelectionMultiRowWorker w ( enable ) ;
workOnCells ( selectionInfo , w ) ;
}
TQString Sheet : : guessColumnTitle ( TQRect & area , int col )
{
//Verify range
Range rg ;
rg . setRange ( area ) ;
rg . setSheet ( this ) ;
if ( ( ! rg . isValid ( ) ) | | ( col < area . left ( ) ) | | ( col > area . right ( ) ) )
return TQString ( ) ;
//The current guess logic is fairly simple - if the top row of the given area
//appears to contain headers (ie. there is text in each column) the text in the column at
//the top row of the area is returned.
/* for (int i=area.left();i<=area.right();i++)
{
Value cellValue = value ( i , area . top ( ) ) ;
if ( ! cellValue . isString ( ) )
return TQString ( ) ;
} */
Value cellValue = value ( col , area . top ( ) ) ;
return cellValue . asString ( ) ;
}
TQString Sheet : : guessRowTitle ( TQRect & area , int row )
{
//Verify range
Range rg ;
rg . setRange ( area ) ;
rg . setSheet ( this ) ;
if ( ( ! rg . isValid ( ) ) | | ( row < area . top ( ) ) | | ( row > area . bottom ( ) ) )
return TQString ( ) ;
//The current guess logic is fairly simple - if the leftmost column of the given area
//appears to contain headers (ie. there is text in each row) the text in the row at
//the leftmost column of the area is returned.
/*for (int i=area.top();i<=area.bottom();i++)
{
Value cellValue = value ( area . left ( ) , i ) ;
if ( ! cellValue . isString ( ) )
return TQString ( ) ;
} */
Value cellValue = value ( area . left ( ) , row ) ;
return cellValue . asString ( ) ;
}
void Sheet : : setSelectionAlign ( Selection * selectionInfo ,
Format : : Align _align )
{
HorAlignManipulator * manipulator = new HorAlignManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setProperty ( Format : : PAlign ) ;
manipulator - > setHorizontalAlignment ( _align ) ;
manipulator - > add ( * selectionInfo ) ;
manipulator - > execute ( ) ;
}
void Sheet : : setSelectionAlignY ( Selection * selectionInfo ,
Format : : AlignY _alignY )
{
VerAlignManipulator * manipulator = new VerAlignManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setProperty ( Format : : PAlignY ) ;
manipulator - > setVerticalAlignment ( _alignY ) ;
manipulator - > add ( * selectionInfo ) ;
manipulator - > execute ( ) ;
}
struct SetSelectionPrecisionWorker : public Sheet : : CellWorker {
int _delta ;
SetSelectionPrecisionWorker ( int delta ) : Sheet : : CellWorker ( ) , _delta ( delta ) { }
class UndoAction * createUndoAction ( Doc * doc , Sheet * sheet , const KSpread : : Region & region ) {
TQString title = i18n ( " Change Precision " ) ;
return new UndoCellFormat ( doc , sheet , region , title ) ;
}
bool testCondition ( Cell * cell ) {
return ( ! cell - > isPartOfMerged ( ) ) ;
}
void doWork ( Cell * cell , bool , int , int ) {
cell - > setDisplayDirtyFlag ( ) ;
if ( _delta = = 1 )
cell - > incPrecision ( ) ;
else
cell - > decPrecision ( ) ;
cell - > clearDisplayDirtyFlag ( ) ;
}
} ;
void Sheet : : setSelectionPrecision ( Selection * selectionInfo ,
int _delta )
{
SetSelectionPrecisionWorker w ( _delta ) ;
workOnCells ( selectionInfo , w ) ;
}
struct SetSelectionStyleWorker : public Sheet : : CellWorkerTypeA
{
Style * m_style ;
SetSelectionStyleWorker ( Style * style )
: m_style ( style )
{
}
TQString getUndoTitle ( )
{
return i18n ( " Apply Style " ) ;
}
void doWork ( RowFormat * rw )
{
rw - > setStyle ( m_style ) ;
}
void doWork ( ColumnFormat * cl )
{
cl - > setStyle ( m_style ) ;
}
bool testCondition ( Cell * cell )
{
return ( ! cell - > isPartOfMerged ( ) & & cell - > format ( ) - > style ( ) ! = m_style ) ;
}
void doWork ( Cell * cell , bool cellRegion , int , int )
{
if ( cellRegion )
cell - > setDisplayDirtyFlag ( ) ;
cell - > format ( ) - > setStyle ( m_style ) ;
if ( cellRegion )
cell - > clearDisplayDirtyFlag ( ) ;
}
} ;
void Sheet : : setSelectionStyle ( Selection * selectionInfo , Style * style )
{
SetSelectionStyleWorker w ( style ) ;
workOnCells ( selectionInfo , w ) ;
}
struct SetSelectionMoneyFormatWorker : public Sheet : : CellWorkerTypeA
{
bool b ;
Doc * m_pDoc ;
SetSelectionMoneyFormatWorker ( bool _b , Doc * _doc ) : b ( _b ) , m_pDoc ( _doc ) { }
TQString getUndoTitle ( ) { return i18n ( " Format Money " ) ; }
bool testCondition ( RowFormat * rw ) {
return ( rw - > hasProperty ( Format : : PFormatType )
| | rw - > hasProperty ( Format : : PPrecision ) ) ;
}
void doWork ( RowFormat * rw ) {
rw - > setFormatType ( b ? Money_format : Generic_format ) ;
rw - > setPrecision ( b ? m_pDoc - > locale ( ) - > fracDigits ( ) : 0 ) ;
}
void doWork ( ColumnFormat * cl ) {
cl - > setFormatType ( b ? Money_format : Generic_format ) ;
cl - > setPrecision ( b ? m_pDoc - > locale ( ) - > fracDigits ( ) : 0 ) ;
}
void prepareCell ( Cell * c ) {
c - > format ( ) - > clearProperty ( Format : : PPrecision ) ;
c - > format ( ) - > clearNoFallBackProperties ( Format : : PPrecision ) ;
c - > format ( ) - > clearProperty ( Format : : PFormatType ) ;
c - > format ( ) - > clearNoFallBackProperties ( Format : : PFormatType ) ;
}
bool testCondition ( Cell * cell ) {
return ( ! cell - > isPartOfMerged ( ) ) ;
}
void doWork ( Cell * cell , bool cellRegion , int , int ) {
if ( cellRegion )
cell - > setDisplayDirtyFlag ( ) ;
cell - > format ( ) - > setFormatType ( b ? Money_format : Generic_format ) ;
cell - > format ( ) - > setPrecision ( b ? m_pDoc - > locale ( ) - > fracDigits ( ) : 0 ) ;
if ( cellRegion )
cell - > clearDisplayDirtyFlag ( ) ;
}
} ;
void Sheet : : setSelectionMoneyFormat ( Selection * selectionInfo ,
bool b )
{
SetSelectionMoneyFormatWorker w ( b , doc ( ) ) ;
workOnCells ( selectionInfo , w ) ;
}
struct IncreaseIndentWorker : public Sheet : : CellWorkerTypeA {
double tmpIndent ;
double valIndent ;
IncreaseIndentWorker ( double _tmpIndent , double _valIndent )
: tmpIndent ( _tmpIndent ) , valIndent ( _valIndent ) { }
TQString getUndoTitle ( ) { return i18n ( " Increase Indent " ) ; }
bool testCondition ( RowFormat * rw ) {
return ( rw - > hasProperty ( Format : : PIndent ) ) ;
}
void doWork ( RowFormat * rw ) {
rw - > setIndent ( tmpIndent + valIndent ) ;
//rw->setAlign( Format::Left );
}
void doWork ( ColumnFormat * cl ) {
cl - > setIndent ( tmpIndent + valIndent ) ;
//cl->setAlign( Format::Left );
}
void prepareCell ( Cell * c ) {
c - > format ( ) - > clearProperty ( Format : : PIndent ) ;
c - > format ( ) - > clearNoFallBackProperties ( Format : : PIndent ) ;
//c->format()->clearProperty( Format::PAlign );
//c->format()->clearNoFallBackProperties( Format::PAlign );
}
bool testCondition ( Cell * cell ) {
return ( ! cell - > isPartOfMerged ( ) ) ;
}
void doWork ( Cell * cell , bool cellRegion , int x , int y ) {
if ( cellRegion ) {
if ( cell - > format ( ) - > align ( x , y ) ! = Format : : Left )
{
//cell->setAlign(Format::Left);
//cell->format()->setIndent( 0.0 );
}
cell - > setDisplayDirtyFlag ( ) ;
cell - > format ( ) - > setIndent ( /* ### ??? --> */ cell - > format ( ) - > getIndent ( x , y ) /* <-- */ + valIndent ) ;
cell - > clearDisplayDirtyFlag ( ) ;
} else {
cell - > format ( ) - > setIndent ( tmpIndent + valIndent ) ;
//cell->setAlign( Format::Left);
}
}
} ;
void Sheet : : increaseIndent ( Selection * selectionInfo )
{
TQPoint marker ( selectionInfo - > marker ( ) ) ;
double valIndent = doc ( ) - > getIndentValue ( ) ;
Cell * c = cellAt ( marker ) ;
double tmpIndent = c - > format ( ) - > getIndent ( marker . x ( ) , marker . y ( ) ) ;
IncreaseIndentWorker w ( tmpIndent , valIndent ) ;
workOnCells ( selectionInfo , w ) ;
}
struct DecreaseIndentWorker : public Sheet : : CellWorkerTypeA {
double tmpIndent , valIndent ;
DecreaseIndentWorker ( double _tmpIndent , double _valIndent ) : tmpIndent ( _tmpIndent ) , valIndent ( _valIndent ) { }
TQString getUndoTitle ( ) { return i18n ( " Decrease Indent " ) ; }
bool testCondition ( RowFormat * rw ) {
return ( rw - > hasProperty ( Format : : PIndent ) ) ;
}
void doWork ( RowFormat * rw ) {
rw - > setIndent ( TQMAX ( 0.0 , tmpIndent - valIndent ) ) ;
}
void doWork ( ColumnFormat * cl ) {
cl - > setIndent ( TQMAX ( 0.0 , tmpIndent - valIndent ) ) ;
}
void prepareCell ( Cell * c ) {
c - > format ( ) - > clearProperty ( Format : : PIndent ) ;
c - > format ( ) - > clearNoFallBackProperties ( Format : : PIndent ) ;
}
bool testCondition ( Cell * cell ) {
return ( ! cell - > isPartOfMerged ( ) ) ;
}
void doWork ( Cell * cell , bool cellRegion , int x , int y ) {
if ( cellRegion ) {
cell - > setDisplayDirtyFlag ( ) ;
cell - > format ( ) - > setIndent ( TQMAX ( 0.0 , cell - > format ( ) - > getIndent ( x , y ) - valIndent ) ) ;
cell - > clearDisplayDirtyFlag ( ) ;
} else {
cell - > format ( ) - > setIndent ( TQMAX ( 0.0 , tmpIndent - valIndent ) ) ;
}
}
} ;
void Sheet : : decreaseIndent ( Selection * selectionInfo )
{
double valIndent = doc ( ) - > getIndentValue ( ) ;
TQPoint marker ( selectionInfo - > marker ( ) ) ;
Cell * c = cellAt ( marker ) ;
double tmpIndent = c - > format ( ) - > getIndent ( marker . x ( ) , marker . y ( ) ) ;
DecreaseIndentWorker w ( tmpIndent , valIndent ) ;
workOnCells ( selectionInfo , w ) ;
}
int Sheet : : adjustColumnHelper ( Cell * c , int _col , int _row )
{
double long_max = 0.0 ;
c - > calculateTextParameters ( painter ( ) , _col , _row ) ;
if ( c - > textWidth ( ) > long_max )
{
double indent = 0.0 ;
int a = c - > format ( ) - > align ( c - > column ( ) , c - > row ( ) ) ;
if ( a = = Format : : Undefined )
{
if ( c - > value ( ) . isNumber ( ) | | c - > isDate ( ) | | c - > isTime ( ) )
a = Format : : Right ;
else
a = Format : : Left ;
}
if ( a = = Format : : Left )
indent = c - > format ( ) - > getIndent ( c - > column ( ) , c - > row ( ) ) ;
long_max = indent + c - > textWidth ( )
+ c - > format ( ) - > leftBorderWidth ( c - > column ( ) , c - > row ( ) )
+ c - > format ( ) - > rightBorderWidth ( c - > column ( ) , c - > row ( ) ) ;
}
return ( int ) long_max ;
}
void Sheet : : adjustArea ( const Region & region )
{
AdjustColumnRowManipulator * manipulator = new AdjustColumnRowManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setAdjustColumn ( true ) ;
manipulator - > setAdjustRow ( true ) ;
manipulator - > add ( region ) ;
manipulator - > execute ( ) ;
}
void Sheet : : adjustColumn ( const Region & region )
{
AdjustColumnRowManipulator * manipulator = new AdjustColumnRowManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setAdjustColumn ( true ) ;
manipulator - > add ( region ) ;
manipulator - > execute ( ) ;
}
void Sheet : : adjustRow ( const Region & region )
{
AdjustColumnRowManipulator * manipulator = new AdjustColumnRowManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setAdjustRow ( true ) ;
manipulator - > add ( region ) ;
manipulator - > execute ( ) ;
}
struct ClearTextSelectionWorker : public Sheet : : CellWorker {
Sheet * _s ;
ClearTextSelectionWorker ( Sheet * s )
: Sheet : : CellWorker ( ) , _s ( s ) { }
class UndoAction * createUndoAction ( Doc * doc , Sheet * sheet , const KSpread : : Region & region ) {
return new UndoChangeAreaTextCell ( doc , sheet , region ) ;
}
bool testCondition ( Cell * cell ) {
return ( ! cell - > isObscured ( ) ) ;
}
void doWork ( Cell * cell , bool , int , int )
{
cell - > setCellText ( " " ) ;
}
} ;
void Sheet : : clearTextSelection ( Selection * selectionInfo )
{
if ( areaIsEmpty ( * selectionInfo ) )
return ;
ClearTextSelectionWorker w ( this ) ;
workOnCells ( selectionInfo , w ) ;
}
struct ClearValiditySelectionWorker : public Sheet : : CellWorker {
ClearValiditySelectionWorker ( ) : Sheet : : CellWorker ( ) { }
class UndoAction * createUndoAction ( Doc * doc , Sheet * sheet , const KSpread : : Region & region ) {
return new UndoConditional ( doc , sheet , region ) ;
}
bool testCondition ( Cell * cell ) {
return ( ! cell - > isObscured ( ) ) ;
}
void doWork ( Cell * cell , bool , int , int ) {
cell - > removeValidity ( ) ;
}
} ;
void Sheet : : clearValiditySelection ( Selection * selectionInfo )
{
if ( areaIsEmpty ( * selectionInfo , Validity ) )
return ;
ClearValiditySelectionWorker w ;
workOnCells ( selectionInfo , w ) ;
}
struct ClearConditionalSelectionWorker : public Sheet : : CellWorker
{
ClearConditionalSelectionWorker ( ) : Sheet : : CellWorker ( ) { }
class UndoAction * createUndoAction ( Doc * doc ,
Sheet * sheet ,
const KSpread : : Region & region )
{
return new UndoConditional ( doc , sheet , region ) ;
}
bool testCondition ( Cell * cell )
{
return ( ! cell - > isObscured ( ) ) ;
}
void doWork ( Cell * cell , bool , int , int )
{
TQValueList < Conditional > emptyList ;
cell - > setConditionList ( emptyList ) ;
}
} ;
void Sheet : : clearConditionalSelection ( Selection * selectionInfo )
{
ClearConditionalSelectionWorker w ;
workOnCells ( selectionInfo , w ) ;
}
void Sheet : : fillSelection ( Selection * selectionInfo , int direction )
{
TQRect rct ( selectionInfo - > selection ( ) ) ;
int right = rct . right ( ) ;
int bottom = rct . bottom ( ) ;
int left = rct . left ( ) ;
int top = rct . top ( ) ;
int width = rct . width ( ) ;
int height = rct . height ( ) ;
TQDomDocument undoDoc = saveCellRegion ( rct ) ;
loadSelectionUndo ( undoDoc , rct , left - 1 , top - 1 , false , 0 ) ;
TQDomDocument doc ;
switch ( direction )
{
case Right :
doc = saveCellRegion ( TQRect ( left , top , 1 , height ) ) ;
break ;
case Up :
doc = saveCellRegion ( TQRect ( left , bottom , width , 1 ) ) ;
break ;
case Left :
doc = saveCellRegion ( TQRect ( right , top , 1 , height ) ) ;
break ;
case Down :
doc = saveCellRegion ( TQRect ( left , top , width , 1 ) ) ;
break ;
} ;
// Save to buffer
TQBuffer buffer ;
buffer . open ( IO_WriteOnly ) ;
TQTextStream str ( & buffer ) ;
str . setEncoding ( TQTextStream : : UnicodeUTF8 ) ;
str < < doc ;
buffer . close ( ) ;
int i ;
switch ( direction )
{
case Right :
for ( i = left + 1 ; i < = right ; + + i )
{
paste ( buffer . buffer ( ) , TQRect ( i , top , 1 , 1 ) , false ) ;
}
break ;
case Up :
for ( i = bottom + 1 ; i > = top ; - - i )
{
paste ( buffer . buffer ( ) , TQRect ( left , i , 1 , 1 ) , false ) ;
}
break ;
case Left :
for ( i = right - 1 ; i > = left ; - - i )
{
paste ( buffer . buffer ( ) , TQRect ( i , top , 1 , 1 ) , false ) ;
}
break ;
case Down :
for ( i = top + 1 ; i < = bottom ; + + i )
{
paste ( buffer . buffer ( ) , TQRect ( left , i , 1 , 1 ) , false ) ;
}
break ;
}
this - > doc ( ) - > setModified ( true ) ;
}
struct DefaultSelectionWorker : public Sheet : : CellWorker {
DefaultSelectionWorker ( ) : Sheet : : CellWorker ( true , false , true ) { }
class UndoAction * createUndoAction ( Doc * doc , Sheet * sheet , const KSpread : : Region & region ) {
TQString title = i18n ( " Default Parameters " ) ;
return new UndoCellFormat ( doc , sheet , region , title ) ;
}
bool testCondition ( Cell * ) {
return true ;
}
void doWork ( Cell * cell , bool , int , int ) {
cell - > defaultStyle ( ) ;
}
} ;
void Sheet : : defaultSelection ( Selection * selectionInfo )
{
TQRect selection ( selectionInfo - > selection ( ) ) ;
DefaultSelectionWorker w ;
SelectionType st = workOnCells ( selectionInfo , w ) ;
switch ( st ) {
case CompleteRows :
RowFormat * rw ;
for ( int i = selection . top ( ) ; i < = selection . bottom ( ) ; i + + ) {
rw = nonDefaultRowFormat ( i ) ;
rw - > defaultStyleFormat ( ) ;
}
emit sig_updateView ( this , * selectionInfo ) ;
return ;
case CompleteColumns :
ColumnFormat * cl ;
for ( int i = selection . left ( ) ; i < = selection . right ( ) ; i + + ) {
cl = nonDefaultColumnFormat ( i ) ;
cl - > defaultStyleFormat ( ) ;
}
emit sig_updateView ( this , * selectionInfo ) ;
return ;
case CellRegion :
emit sig_updateView ( this , * selectionInfo ) ;
return ;
}
}
struct SetConditionalWorker : public Sheet : : CellWorker
{
TQValueList < Conditional > conditionList ;
SetConditionalWorker ( TQValueList < Conditional > _tmp ) :
Sheet : : CellWorker ( ) , conditionList ( _tmp ) { }
class UndoAction * createUndoAction ( Doc * doc ,
Sheet * sheet , const KSpread : : Region & region )
{
return new UndoConditional ( doc , sheet , region ) ;
}
bool testCondition ( Cell * )
{
return true ;
}
void doWork ( Cell * cell , bool , int , int )
{
if ( ! cell - > isObscured ( ) ) // TODO: isPartOfMerged()???
{
cell - > setConditionList ( conditionList ) ;
cell - > setDisplayDirtyFlag ( ) ;
}
}
} ;
void Sheet : : setConditional ( Selection * selectionInfo ,
TQValueList < Conditional > const & newConditions )
{
if ( ! doc ( ) - > undoLocked ( ) )
{
UndoConditional * undo = new UndoConditional ( doc ( ) , this , * selectionInfo ) ;
doc ( ) - > addCommand ( undo ) ;
}
Region : : ConstIterator endOfList = selectionInfo - > constEnd ( ) ;
for ( Region : : ConstIterator it = selectionInfo - > constBegin ( ) ; it ! = endOfList ; + + it )
{
TQRect range = ( * it ) - > rect ( ) . normalize ( ) ;
int l = range . left ( ) ;
int r = range . right ( ) ;
int t = range . top ( ) ;
int b = range . bottom ( ) ;
Cell * cell ;
Style * s = doc ( ) - > styleManager ( ) - > defaultStyle ( ) ;
for ( int x = l ; x < = r ; + + x )
{
for ( int y = t ; y < = b ; + + y )
{
cell = nonDefaultCell ( x , y , false , s ) ;
cell - > setConditionList ( newConditions ) ;
cell - > setDisplayDirtyFlag ( ) ;
}
}
}
emit sig_updateView ( this , * selectionInfo ) ;
}
struct SetValidityWorker : public Sheet : : CellWorker {
Validity tmp ;
SetValidityWorker ( Validity _tmp ) : Sheet : : CellWorker ( ) , tmp ( _tmp ) { }
class UndoAction * createUndoAction ( Doc * doc , Sheet * sheet , const KSpread : : Region & region ) {
return new UndoConditional ( doc , sheet , region ) ;
}
bool testCondition ( Cell * ) {
return true ;
}
void doWork ( Cell * cell , bool , int , int ) {
if ( ! cell - > isObscured ( ) ) {
cell - > setDisplayDirtyFlag ( ) ;
if ( tmp . m_restriction = = Restriction : : None )
cell - > removeValidity ( ) ;
else
{
Validity * tmpValidity = cell - > getValidity ( ) ;
tmpValidity - > message = tmp . message ;
tmpValidity - > title = tmp . title ;
tmpValidity - > valMin = tmp . valMin ;
tmpValidity - > valMax = tmp . valMax ;
tmpValidity - > m_cond = tmp . m_cond ;
tmpValidity - > m_action = tmp . m_action ;
tmpValidity - > m_restriction = tmp . m_restriction ;
tmpValidity - > timeMin = tmp . timeMin ;
tmpValidity - > timeMax = tmp . timeMax ;
tmpValidity - > dateMin = tmp . dateMin ;
tmpValidity - > dateMax = tmp . dateMax ;
tmpValidity - > displayMessage = tmp . displayMessage ;
tmpValidity - > allowEmptyCell = tmp . allowEmptyCell ;
tmpValidity - > displayValidationInformation = tmp . displayValidationInformation ;
tmpValidity - > titleInfo = tmp . titleInfo ;
tmpValidity - > messageInfo = tmp . messageInfo ;
tmpValidity - > listValidity = tmp . listValidity ;
}
cell - > clearDisplayDirtyFlag ( ) ;
}
}
} ;
void Sheet : : setValidity ( Selection * selectionInfo ,
KSpread : : Validity tmp )
{
SetValidityWorker w ( tmp ) ;
workOnCells ( selectionInfo , w ) ;
}
struct GetWordSpellingWorker : public Sheet : : CellWorker {
TQString & listWord ;
GetWordSpellingWorker ( TQString & _listWord ) : Sheet : : CellWorker ( false , false , true ) , listWord ( _listWord ) { }
class UndoAction * createUndoAction ( Doc * , Sheet * , const KSpread : : Region & ) {
return 0 ;
}
bool testCondition ( Cell * ) {
return true ;
}
void doWork ( Cell * c , bool cellRegion , int , int ) {
if ( ! c - > isObscured ( ) | | cellRegion /* ### ??? */ ) {
if ( ! c - > isFormula ( ) & & ! c - > value ( ) . isNumber ( ) & & ! c - > value ( ) . asString ( ) . isEmpty ( ) & & ! c - > isTime ( )
& & ! c - > isDate ( )
& & ! c - > text ( ) . isEmpty ( ) )
{
listWord + = c - > text ( ) + ' \n ' ;
}
}
}
} ;
TQString Sheet : : getWordSpelling ( Selection * selectionInfo )
{
TQString listWord ;
GetWordSpellingWorker w ( listWord ) ;
workOnCells ( selectionInfo , w ) ;
return listWord ;
}
struct SetWordSpellingWorker : public Sheet : : CellWorker {
TQStringList & list ;
int pos ;
Sheet * sheet ;
SetWordSpellingWorker ( TQStringList & _list , Sheet * s )
: Sheet : : CellWorker ( false , false , true ) , list ( _list ) , pos ( 0 ) , sheet ( s ) { }
class UndoAction * createUndoAction ( Doc * doc , Sheet * sheet , const KSpread : : Region & region ) {
return new UndoChangeAreaTextCell ( doc , sheet , region ) ;
}
bool testCondition ( Cell * ) {
return true ;
}
void doWork ( Cell * c , bool cellRegion , int , int )
{
if ( ! c - > isObscured ( ) | | cellRegion /* ### ??? */ ) {
if ( ! c - > isFormula ( ) & & ! c - > value ( ) . isNumber ( ) & & ! c - > value ( ) . asString ( ) . isEmpty ( ) & & ! c - > isTime ( )
& & ! c - > isDate ( )
& & ! c - > text ( ) . isEmpty ( ) )
{
c - > setCellText ( list [ pos ] ) ;
pos + + ;
}
}
}
} ;
void Sheet : : setWordSpelling ( Selection * selectionInfo ,
const TQString _listWord )
{
TQStringList list = TQStringList : : split ( ' \n ' , _listWord ) ;
SetWordSpellingWorker w ( list , this ) ;
workOnCells ( selectionInfo , w ) ;
}
static TQString cellAsText ( Cell * cell , unsigned int max )
{
TQString result ;
if ( ! cell - > isDefault ( ) )
{
int l = max - cell - > strOutText ( ) . length ( ) ;
if ( cell - > defineAlignX ( ) = = Format : : Right )
{
for ( int i = 0 ; i < l ; + + i )
result + = " " ;
result + = cell - > strOutText ( ) ;
}
else if ( cell - > defineAlignX ( ) = = Format : : Left )
{
result + = " " ;
result + = cell - > strOutText ( ) ;
// start with "1" because we already set one space
for ( int i = 1 ; i < l ; + + i )
result + = " " ;
}
else // centered
{
int i ;
int s = ( int ) l / 2 ;
for ( i = 0 ; i < s ; + + i )
result + = " " ;
result + = cell - > strOutText ( ) ;
for ( i = s ; i < l ; + + i )
result + = " " ;
}
}
else
{
for ( unsigned int i = 0 ; i < max ; + + i )
result + = " " ;
}
return result ;
}
TQString Sheet : : copyAsText ( Selection * selectionInfo )
{
// Only one cell selected? => copy active cell
if ( selectionInfo - > isSingular ( ) )
{
Cell * cell = cellAt ( selectionInfo - > marker ( ) ) ;
if ( ! cell - > isDefault ( ) )
return cell - > strOutText ( ) ;
return " " ;
}
TQRect selection ( selectionInfo - > selection ( ) ) ;
// Find area
unsigned top = selection . bottom ( ) ;
unsigned bottom = selection . top ( ) ;
unsigned left = selection . right ( ) ;
unsigned right = selection . left ( ) ;
unsigned max = 1 ;
for ( Cell * c = d - > cells . firstCell ( ) ; c ; c = c - > nextCell ( ) )
{
if ( ! c - > isDefault ( ) )
{
TQPoint p ( c - > column ( ) , c - > row ( ) ) ;
if ( selection . contains ( p ) )
{
top = TQMIN ( top , ( unsigned ) c - > row ( ) ) ;
left = TQMIN ( left , ( unsigned ) c - > column ( ) ) ;
bottom = TQMAX ( bottom , ( unsigned ) c - > row ( ) ) ;
right = TQMAX ( right , ( unsigned ) c - > column ( ) ) ;
if ( c - > strOutText ( ) . length ( ) > max )
max = c - > strOutText ( ) . length ( ) ;
}
}
}
+ + max ;
TQString result ;
for ( unsigned y = top ; y < = bottom ; + + y )
{
for ( unsigned x = left ; x < = right ; + + x )
{
Cell * cell = cellAt ( x , y ) ;
result + = cellAsText ( cell , max ) ;
}
result + = " \n " ;
}
return result ;
}
void Sheet : : copySelection ( Selection * selectionInfo )
{
TQDomDocument doc = saveCellRegion ( * selectionInfo , true ) ;
// Save to buffer
TQBuffer buffer ;
buffer . open ( IO_WriteOnly ) ;
TQTextStream str ( & buffer ) ;
str . setEncoding ( TQTextStream : : UnicodeUTF8 ) ;
str < < doc ;
buffer . close ( ) ;
TextDrag * kd = new TextDrag ( 0L ) ;
kd - > setPlain ( copyAsText ( selectionInfo ) ) ;
kd - > setKSpread ( buffer . buffer ( ) ) ;
TQApplication : : clipboard ( ) - > setData ( kd ) ;
}
void Sheet : : cutSelection ( Selection * selectionInfo )
{
TQDomDocument doc = saveCellRegion ( * selectionInfo , true , true ) ;
// Save to buffer
TQBuffer buffer ;
buffer . open ( IO_WriteOnly ) ;
TQTextStream str ( & buffer ) ;
str . setEncoding ( TQTextStream : : UnicodeUTF8 ) ;
str < < doc ;
buffer . close ( ) ;
TextDrag * kd = new TextDrag ( 0L ) ;
kd - > setPlain ( copyAsText ( selectionInfo ) ) ;
kd - > setKSpread ( buffer . buffer ( ) ) ;
TQApplication : : clipboard ( ) - > setData ( kd ) ;
deleteSelection ( selectionInfo , true ) ;
}
void Sheet : : paste ( const TQRect & pasteArea , bool makeUndo ,
Paste : : Mode mode , Paste : : Operation operation ,
bool insert , int insertTo , bool pasteFC ,
TQClipboard : : Mode clipboardMode )
{
TQMimeSource * mime = TQApplication : : clipboard ( ) - > data ( clipboardMode ) ;
if ( ! mime )
return ;
TQByteArray b ;
if ( mime - > provides ( TextDrag : : selectionMimeType ( ) ) )
{
b = mime - > encodedData ( TextDrag : : selectionMimeType ( ) ) ;
}
else if ( mime - > provides ( " text/plain " ) )
{
// Note: TQClipboard::text() seems to do a better job than encodedData( "text/plain" )
// In particular it handles charsets (in the mimetype). Copied from KPresenter ;-)
TQString _text = TQApplication : : clipboard ( ) - > text ( clipboardMode ) ;
doc ( ) - > emitBeginOperation ( ) ;
pasteTextPlain ( _text , pasteArea ) ;
emit sig_updateView ( this ) ;
// doc()->emitEndOperation();
return ;
}
else
return ;
// Do the actual pasting.
doc ( ) - > emitBeginOperation ( ) ;
paste ( b , pasteArea , makeUndo , mode , operation , insert , insertTo , pasteFC ) ;
emit sig_updateView ( this ) ;
// doc()->emitEndOperation();
}
void Sheet : : pasteTextPlain ( TQString & _text , TQRect pasteArea )
{
// TQString tmp;
// tmp= TQString::fromLocal8Bit(_mime->encodedData( "text/plain" ));
if ( _text . isEmpty ( ) )
return ;
TQString tmp = _text ;
int i ;
int mx = pasteArea . left ( ) ;
int my = pasteArea . top ( ) ;
int rows = 1 ;
int len = tmp . length ( ) ;
//count the numbers of lines in text
for ( i = 0 ; i < len ; + + i )
{
if ( tmp [ i ] = = ' \n ' )
+ + rows ;
}
Cell * cell = nonDefaultCell ( mx , my ) ;
if ( rows = = 1 )
{
if ( ! doc ( ) - > undoLocked ( ) )
{
UndoSetText * undo = new UndoSetText ( doc ( ) , this , cell - > text ( ) , mx , my , cell - > formatType ( ) ) ;
doc ( ) - > addCommand ( undo ) ;
}
}
else
{
TQRect rect ( mx , my , mx , my + rows - 1 ) ;
UndoChangeAreaTextCell * undo = new UndoChangeAreaTextCell ( doc ( ) , this , rect ) ;
doc ( ) - > addCommand ( undo ) ;
}
i = 0 ;
TQString rowtext ;
while ( i < rows )
{
int p = 0 ;
p = tmp . find ( ' \n ' ) ;
if ( p < 0 )
p = tmp . length ( ) ;
rowtext = tmp . left ( p ) ;
if ( ! isProtected ( ) | | cell - > format ( ) - > notProtected ( mx , my + i ) )
{
cell - > setCellText ( rowtext ) ;
cell - > updateChart ( ) ;
}
// next cell
+ + i ;
cell = nonDefaultCell ( mx , my + i ) ;
if ( ! cell | | p = = ( int ) tmp . length ( ) )
break ;
// exclude the left part and '\n'
tmp = tmp . right ( tmp . length ( ) - p - 1 ) ;
}
if ( ! isLoading ( ) )
refreshMergedCell ( ) ;
emit sig_updateView ( this ) ;
emit sig_updateHBorder ( this ) ;
emit sig_updateVBorder ( this ) ;
}
void Sheet : : paste ( const TQByteArray & b , const TQRect & pasteArea , bool makeUndo ,
Paste : : Mode mode , Paste : : Operation operation ,
bool insert , int insertTo , bool pasteFC )
{
kdDebug ( 36001 ) < < " Parsing " < < b . size ( ) < < " bytes " < < endl ;
TQBuffer buffer ( b ) ;
buffer . open ( IO_ReadOnly ) ;
TQDomDocument doc ;
doc . setContent ( & buffer ) ;
buffer . close ( ) ;
// ##### TODO: Test for parsing errors
int mx = pasteArea . left ( ) ;
int my = pasteArea . top ( ) ;
loadSelection ( doc , pasteArea , mx - 1 , my - 1 , makeUndo ,
mode , operation , insert , insertTo , pasteFC ) ;
}
bool Sheet : : loadSelection ( const TQDomDocument & doc , const TQRect & pasteArea ,
int _xshift , int _yshift , bool makeUndo ,
Paste : : Mode mode , Paste : : Operation operation , bool insert ,
int insertTo , bool pasteFC )
{
//kdDebug(36001) << "loadSelection called. pasteArea=" << pasteArea << endl;
if ( ! isLoading ( ) & & makeUndo )
{
loadSelectionUndo ( doc , pasteArea , _xshift , _yshift , insert , insertTo ) ;
}
TQDomElement root = doc . documentElement ( ) ; // "spreadsheet-snippet"
int rowsInClpbrd = root . attribute ( " rows " ) . toInt ( ) ;
int columnsInClpbrd = root . attribute ( " columns " ) . toInt ( ) ;
// find size of rectangle that we want to paste to (either clipboard size or current selection)
const int pasteWidth = ( pasteArea . width ( ) > = columnsInClpbrd
& & util_isRowSelected ( pasteArea ) = = false
& & root . namedItem ( " rows " ) . toElement ( ) . isNull ( ) )
? pasteArea . width ( ) : columnsInClpbrd ;
const int pasteHeight = ( pasteArea . height ( ) > = rowsInClpbrd
& & util_isColumnSelected ( pasteArea ) = = false
& & root . namedItem ( " columns " ) . toElement ( ) . isNull ( ) )
? pasteArea . height ( ) : rowsInClpbrd ;
// kdDebug() << "loadSelection: paste area has size "
// << pasteHeight << " rows * "
// << pasteWidth << " columns " << endl;
// kdDebug() << "loadSelection: " << rowsInClpbrd << " rows and "
// << columnsInClpbrd << " columns in clipboard." << endl;
// kdDebug() << "xshift: " << _xshift << " _yshift: " << _yshift << endl;
TQDomElement e = root . firstChild ( ) . toElement ( ) ; // "columns", "rows" or "cell"
for ( ; ! e . isNull ( ) ; e = e . nextSibling ( ) . toElement ( ) )
{
// entire columns given
if ( e . tagName ( ) = = " columns " & & ! isProtected ( ) )
{
_yshift = 0 ;
// Clear the existing columns
int col = e . attribute ( " column " ) . toInt ( ) ;
int width = e . attribute ( " count " ) . toInt ( ) ;
if ( ! insert )
{
for ( int i = col ; i < col + width ; + + i )
{
d - > cells . clearColumn ( _xshift + i ) ;
d - > columns . removeElement ( _xshift + i ) ;
}
}
// Insert column formats
TQDomElement c = e . firstChild ( ) . toElement ( ) ;
for ( ; ! c . isNull ( ) ; c = c . nextSibling ( ) . toElement ( ) )
{
if ( c . tagName ( ) = = " column " )
{
ColumnFormat * cl = new ColumnFormat ( this , 0 ) ;
if ( cl - > load ( c , _xshift , mode , pasteFC ) )
insertColumnFormat ( cl ) ;
else
delete cl ;
}
}
}
// entire rows given
if ( e . tagName ( ) = = " rows " & & ! isProtected ( ) )
{
_xshift = 0 ;
// Clear the existing rows
int row = e . attribute ( " row " ) . toInt ( ) ;
int height = e . attribute ( " count " ) . toInt ( ) ;
if ( ! insert )
{
for ( int i = row ; i < row + height ; + + i )
{
d - > cells . clearRow ( _yshift + i ) ;
d - > rows . removeElement ( _yshift + i ) ;
}
}
// Insert row formats
TQDomElement c = e . firstChild ( ) . toElement ( ) ;
for ( ; ! c . isNull ( ) ; c = c . nextSibling ( ) . toElement ( ) )
{
if ( c . tagName ( ) = = " row " )
{
RowFormat * cl = new RowFormat ( this , 0 ) ;
if ( cl - > load ( c , _yshift , mode , pasteFC ) )
insertRowFormat ( cl ) ;
else
delete cl ;
}
}
}
Cell * refreshCell = 0 ;
Cell * cell ;
Cell * cellBackup = NULL ;
if ( e . tagName ( ) = = " cell " )
{
int row = e . attribute ( " row " ) . toInt ( ) + _yshift ;
int col = e . attribute ( " column " ) . toInt ( ) + _xshift ;
// tile the selection with the clipboard contents
for ( int roff = 0 ; row + roff - _yshift < = pasteHeight ; roff + = rowsInClpbrd )
{
for ( int coff = 0 ; col + coff - _xshift < = pasteWidth ; coff + = columnsInClpbrd )
{
// kdDebug() << "loadSelection: cell at " << (col+coff) << "," << (row+roff)
// << " with roff,coff= " << roff << "," << coff
// << ", _xshift: " << _xshift << ", _yshift: " << _yshift << endl;
cell = nonDefaultCell ( col + coff , row + roff ) ;
if ( isProtected ( ) & & ! cell - > format ( ) - > notProtected ( col + coff , row + roff ) )
{
continue ;
}
cellBackup = new Cell ( this , cell - > column ( ) , cell - > row ( ) ) ;
cellBackup - > copyAll ( cell ) ;
if ( ! cell - > load ( e , _xshift + coff , _yshift + roff , mode , operation , pasteFC ) )
{
cell - > copyAll ( cellBackup ) ;
}
else
{
if ( cell - > isFormula ( ) )
{
cell - > setCalcDirtyFlag ( ) ;
}
}
delete cellBackup ;
cell = cellAt ( col + coff , row + roff ) ;
if ( ! refreshCell & & cell - > updateChart ( false ) )
{
refreshCell = cell ;
}
}
}
}
//refresh chart after that you paste all cells
/* I don't think this is gonna work....doesn't this only update
one chart - - the one which had a dependant cell update first ? - John
I don ' t have time to check on this now . . . .
*/
if ( refreshCell )
refreshCell - > updateChart ( ) ;
}
this - > doc ( ) - > setModified ( true ) ;
if ( ! isLoading ( ) )
refreshMergedCell ( ) ;
emit sig_updateView ( this ) ;
emit sig_updateHBorder ( this ) ;
emit sig_updateVBorder ( this ) ;
return true ;
}
void Sheet : : loadSelectionUndo ( const TQDomDocument & d , const TQRect & loadArea ,
int _xshift , int _yshift ,
bool insert , int insertTo )
{
TQDomElement root = d . documentElement ( ) ; // "spreadsheet-snippet"
int rowsInClpbrd = root . attribute ( " rows " ) . toInt ( ) ;
int columnsInClpbrd = root . attribute ( " columns " ) . toInt ( ) ;
// find rect that we paste to
const int pasteWidth = ( loadArea . width ( ) > = columnsInClpbrd & &
util_isRowSelected ( loadArea ) = = false & &
root . namedItem ( " rows " ) . toElement ( ) . isNull ( ) )
? loadArea . width ( ) : columnsInClpbrd ;
const int pasteHeight = ( loadArea . height ( ) > = rowsInClpbrd & &
util_isColumnSelected ( loadArea ) = = false & &
root . namedItem ( " columns " ) . toElement ( ) . isNull ( ) )
? loadArea . height ( ) : rowsInClpbrd ;
uint numCols = 0 ;
uint numRows = 0 ;
Region region ;
for ( TQDomNode n = root . firstChild ( ) ; ! n . isNull ( ) ; n = n . nextSibling ( ) )
{
TQDomElement e = n . toElement ( ) ; // "columns", "rows" or "cell"
if ( e . tagName ( ) = = " columns " )
{
_yshift = 0 ;
int col = e . attribute ( " column " ) . toInt ( ) ;
int width = e . attribute ( " count " ) . toInt ( ) ;
for ( int coff = 0 ; col + coff < = pasteWidth ; coff + = columnsInClpbrd )
{
uint overlap = TQMAX ( 0 , ( col - 1 + coff + width ) - pasteWidth ) ;
uint effWidth = width - overlap ;
region . add ( TQRect ( _xshift + col + coff , 1 , effWidth , KS_rowMax ) ) ;
numCols + = effWidth ;
}
}
else if ( e . tagName ( ) = = " rows " )
{
_xshift = 0 ;
int row = e . attribute ( " row " ) . toInt ( ) ;
int height = e . attribute ( " count " ) . toInt ( ) ;
for ( int roff = 0 ; row + roff < = pasteHeight ; roff + = rowsInClpbrd )
{
uint overlap = TQMAX ( 0 , ( row - 1 + roff + height ) - pasteHeight ) ;
uint effHeight = height - overlap ;
region . add ( TQRect ( 1 , _yshift + row + roff , KS_colMax , effHeight ) ) ;
numRows + = effHeight ;
}
}
else if ( ! e . isNull ( ) )
{
// store the cols/rows for the insertion
int col = e . attribute ( " column " ) . toInt ( ) ;
int row = e . attribute ( " row " ) . toInt ( ) ;
for ( int coff = 0 ; col + coff < = pasteWidth ; coff + = columnsInClpbrd )
{
for ( int roff = 0 ; row + roff < = pasteHeight ; roff + = rowsInClpbrd )
{
region . add ( TQPoint ( _xshift + col + coff , _yshift + row + roff ) ) ;
}
}
}
}
if ( ! doc ( ) - > undoLocked ( ) )
{
UndoCellPaste * undo = new UndoCellPaste ( doc ( ) , this , _xshift , _yshift , region , insert , insertTo ) ;
doc ( ) - > addCommand ( undo ) ;
}
if ( insert )
{
TQRect rect = region . boundingRect ( ) ;
// shift cells to the right
if ( insertTo = = - 1 & & numCols = = 0 & & numRows = = 0 )
{
rect . setWidth ( rect . width ( ) ) ;
shiftRow ( rect , false ) ;
}
// shift cells to the bottom
else if ( insertTo = = 1 & & numCols = = 0 & & numRows = = 0 )
{
rect . setHeight ( rect . height ( ) ) ;
shiftColumn ( rect , false ) ;
}
// insert columns
else if ( insertTo = = 0 & & numCols = = 0 & & numRows > 0 )
{
insertRow ( rect . top ( ) , rect . height ( ) - 1 , false ) ;
}
// insert rows
else if ( insertTo = = 0 & & numCols > 0 & & numRows = = 0 )
{
insertColumn ( rect . left ( ) , rect . width ( ) - 1 , false ) ;
}
}
}
bool Sheet : : testAreaPasteInsert ( ) const
{
TQMimeSource * mime = TQApplication : : clipboard ( ) - > data ( TQClipboard : : Clipboard ) ;
if ( ! mime )
return false ;
TQByteArray b ;
if ( mime - > provides ( " application/x-kspread-snippet " ) )
b = mime - > encodedData ( " application/x-kspread-snippet " ) ;
else
return false ;
TQBuffer buffer ( b ) ;
buffer . open ( IO_ReadOnly ) ;
TQDomDocument d ;
d . setContent ( & buffer ) ;
buffer . close ( ) ;
TQDomElement e = d . documentElement ( ) ;
if ( ! e . namedItem ( " columns " ) . toElement ( ) . isNull ( ) )
return false ;
if ( ! e . namedItem ( " rows " ) . toElement ( ) . isNull ( ) )
return false ;
TQDomElement c = e . firstChild ( ) . toElement ( ) ;
for ( ; ! c . isNull ( ) ; c = c . nextSibling ( ) . toElement ( ) )
{
if ( c . tagName ( ) = = " cell " )
return true ;
}
return false ;
}
void Sheet : : deleteCells ( const Region & region )
{
// A list of all cells we want to delete.
TQPtrStack < Cell > cellStack ;
Region : : ConstIterator endOfList = region . constEnd ( ) ;
for ( Region : : ConstIterator it = region . constBegin ( ) ; it ! = endOfList ; + + it )
{
TQRect range = ( * it ) - > rect ( ) . normalize ( ) ;
int right = range . right ( ) ;
int left = range . left ( ) ;
int bottom = range . bottom ( ) ;
int col ;
for ( int row = range . top ( ) ; row < = bottom ; + + row )
{
Cell * c = getFirstCellRow ( row ) ;
while ( c )
{
col = c - > column ( ) ;
if ( col < left )
{
c = getNextCellRight ( left - 1 , row ) ;
continue ;
}
if ( col > right )
break ;
if ( ! c - > isDefault ( ) )
cellStack . push ( c ) ;
c = getNextCellRight ( col , row ) ;
}
}
}
d - > cells . setAutoDelete ( false ) ;
// Remove the cells from the sheet
while ( ! cellStack . isEmpty ( ) )
{
Cell * cell = cellStack . pop ( ) ;
d - > cells . remove ( cell - > column ( ) , cell - > row ( ) ) ;
cell - > setCalcDirtyFlag ( ) ;
setRegionPaintDirty ( cell - > cellRect ( ) ) ;
delete cell ;
}
d - > cells . setAutoDelete ( true ) ;
setLayoutDirtyFlag ( ) ;
// TODO: don't go through all cells here!
// Since obscured cells might have been deleted we
// have to reenforce it.
Cell * c = d - > cells . firstCell ( ) ;
for ( ; c ; c = c - > nextCell ( ) )
{
if ( c - > doesMergeCells ( ) & & ! c - > isDefault ( ) )
c - > mergeCells ( c - > column ( ) , c - > row ( ) ,
c - > extraXCells ( ) , c - > extraYCells ( ) ) ;
}
doc ( ) - > setModified ( true ) ;
}
void Sheet : : deleteSelection ( Selection * selectionInfo , bool undo )
{
if ( undo & & ! doc ( ) - > undoLocked ( ) )
{
UndoDelete * undo = new UndoDelete ( doc ( ) , this , * selectionInfo ) ;
doc ( ) - > addCommand ( undo ) ;
}
Region : : ConstIterator endOfList = selectionInfo - > constEnd ( ) ;
for ( Region : : ConstIterator it = selectionInfo - > constBegin ( ) ; it ! = endOfList ; + + it )
{
TQRect range = ( * it ) - > rect ( ) . normalize ( ) ;
// Entire rows selected ?
if ( util_isRowSelected ( range ) )
{
for ( int i = range . top ( ) ; i < = range . bottom ( ) ; + + i )
{
d - > cells . clearRow ( i ) ;
d - > rows . removeElement ( i ) ;
}
emit sig_updateVBorder ( this ) ;
}
// Entire columns selected ?
else if ( util_isColumnSelected ( range ) )
{
for ( int i = range . left ( ) ; i < = range . right ( ) ; + + i )
{
d - > cells . clearColumn ( i ) ;
d - > columns . removeElement ( i ) ;
}
emit sig_updateHBorder ( this ) ;
}
else
{
setRegionPaintDirty ( range ) ;
deleteCells ( range ) ;
}
}
refreshMergedCell ( ) ;
emit sig_updateView ( this ) ;
}
void Sheet : : updateView ( )
{
emit sig_updateView ( this ) ;
}
void Sheet : : updateView ( TQRect const & rect )
{
emit sig_updateView ( this , rect ) ;
}
void Sheet : : updateView ( Region * region )
{
emit sig_updateView ( this , * region ) ;
}
void Sheet : : refreshView ( const Region & region )
{
Region tmpRegion ;
Region : : ConstIterator endOfList = region . constEnd ( ) ;
for ( Region : : ConstIterator it = region . constBegin ( ) ; it ! = endOfList ; + + it )
{
TQRect range = ( * it ) - > rect ( ) . normalize ( ) ;
// TODO: don't go through all cells when refreshing!
TQRect tmp ( range ) ;
Cell * c = d - > cells . firstCell ( ) ;
for ( ; c ; c = c - > nextCell ( ) )
{
if ( ! c - > isDefault ( ) & &
c - > row ( ) > = range . top ( ) & & c - > row ( ) < = range . bottom ( ) & &
c - > column ( ) > = range . left ( ) & & c - > column ( ) < = range . right ( ) )
{
if ( c - > doesMergeCells ( ) )
{
int right = TQMAX ( tmp . right ( ) , c - > column ( ) + c - > extraXCells ( ) ) ;
int bottom = TQMAX ( tmp . bottom ( ) , c - > row ( ) + c - > extraYCells ( ) ) ;
tmp . setRight ( right ) ;
tmp . setBottom ( bottom ) ;
}
}
}
deleteCells ( range ) ;
tmpRegion . add ( tmp ) ;
}
emit sig_updateView ( this , tmpRegion ) ;
}
void Sheet : : mergeCells ( const Region & region , bool hor , bool ver )
{
// sanity check
if ( isProtected ( ) )
return ;
if ( workbook ( ) - > isProtected ( ) )
return ;
MergeManipulator * manipulator = new MergeManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setHorizontalMerge ( hor ) ;
manipulator - > setVerticalMerge ( ver ) ;
manipulator - > add ( region ) ;
manipulator - > execute ( ) ;
}
void Sheet : : dissociateCells ( const Region & region )
{
// sanity check
if ( isProtected ( ) )
return ;
if ( workbook ( ) - > isProtected ( ) )
return ;
Manipulator * manipulator = new MergeManipulator ( ) ;
manipulator - > setSheet ( this ) ;
manipulator - > setReverse ( true ) ;
manipulator - > add ( region ) ;
manipulator - > execute ( ) ;
}
bool Sheet : : testListChoose ( Selection * selectionInfo )
{
TQRect selection ( selectionInfo - > selection ( ) ) ;
TQPoint marker ( selectionInfo - > marker ( ) ) ;
Cell * cell = cellAt ( marker . x ( ) , marker . y ( ) ) ;
TQString tmp = cell - > text ( ) ;
Cell * c = firstCell ( ) ;
bool different = false ;
int col ;
for ( ; c ; c = c - > nextCell ( ) )
{
col = c - > column ( ) ;
if ( selection . left ( ) < = col & & selection . right ( ) > = col & &
! c - > isPartOfMerged ( ) & &
! ( col = = marker . x ( ) & & c - > row ( ) = = marker . y ( ) ) )
{
if ( ! c - > isFormula ( ) & & ! c - > value ( ) . isNumber ( ) & & ! c - > value ( ) . asString ( ) . isEmpty ( )
& & ! c - > isTime ( ) & & ! c - > isDate ( ) )
{
if ( c - > text ( ) ! = tmp )
different = true ;
}
}
}
return different ;
}
TQDomDocument Sheet : : saveCellRegion ( const Region & region , bool copy , bool era )
{
TQDomDocument dd ( " spreadsheet-snippet " ) ;
dd . appendChild ( dd . createProcessingInstruction ( " xml " , " version= \" 1.0 \" encoding= \" UTF-8 \" " ) ) ;
TQDomElement root = dd . createElement ( " spreadsheet-snippet " ) ;
dd . appendChild ( root ) ;
// find the upper left corner of the selection
TQRect boundingRect = region . boundingRect ( ) ;
int left = boundingRect . left ( ) ;
int top = boundingRect . top ( ) ;
// for tiling the clipboard content in the selection
root . setAttribute ( " rows " , boundingRect . height ( ) ) ;
root . setAttribute ( " columns " , boundingRect . width ( ) ) ;
Region : : ConstIterator endOfList = region . constEnd ( ) ;
for ( Region : : ConstIterator it = region . constBegin ( ) ; it ! = endOfList ; + + it )
{
TQRect range = ( * it ) - > rect ( ) . normalize ( ) ;
//
// Entire rows selected?
//
if ( ( * it ) - > isRow ( ) )
{
TQDomElement rows = dd . createElement ( " rows " ) ;
rows . setAttribute ( " count " , range . height ( ) ) ;
rows . setAttribute ( " row " , range . top ( ) - top + 1 ) ;
root . appendChild ( rows ) ;
// Save all cells.
for ( Cell * cell = d - > cells . firstCell ( ) ; cell ; cell = cell - > nextCell ( ) )
{
if ( ! cell - > isDefault ( ) & & ! cell - > isPartOfMerged ( ) )
{
TQPoint point ( cell - > column ( ) , cell - > row ( ) ) ;
if ( range . contains ( point ) )
{
root . appendChild ( cell - > save ( dd , 0 , top - 1 , copy , copy , era ) ) ;
}
}
}
// ##### Inefficient
// Save the row formats if there are any
RowFormat * format ;
for ( int row = range . top ( ) ; row < = range . bottom ( ) ; + + row )
{
format = rowFormat ( row ) ;
if ( format & & ! format - > isDefault ( ) )
{
TQDomElement e = format - > save ( dd , top - 1 , copy ) ;
if ( ! e . isNull ( ) )
{
rows . appendChild ( e ) ;
}
}
}
continue ;
}
//
// Entire columns selected?
//
if ( ( * it ) - > isColumn ( ) )
{
TQDomElement columns = dd . createElement ( " columns " ) ;
columns . setAttribute ( " count " , range . width ( ) ) ;
columns . setAttribute ( " column " , range . left ( ) - left + 1 ) ;
root . appendChild ( columns ) ;
// Save all cells.
for ( Cell * cell = d - > cells . firstCell ( ) ; cell ; cell = cell - > nextCell ( ) )
{
if ( ! cell - > isDefault ( ) & & ! cell - > isPartOfMerged ( ) )
{
TQPoint point ( cell - > column ( ) , cell - > row ( ) ) ;
if ( range . contains ( point ) )
{
root . appendChild ( cell - > save ( dd , left - 1 , 0 , copy , copy , era ) ) ;
}
}
}
// ##### Inefficient
// Save the column formats if there are any
ColumnFormat * format ;
for ( int col = range . left ( ) ; col < = range . right ( ) ; + + col )
{
format = columnFormat ( col ) ;
if ( format & & ! format - > isDefault ( ) )
{
TQDomElement e = format - > save ( dd , left - 1 , copy ) ;
if ( ! e . isNull ( ) )
{
columns . appendChild ( e ) ;
}
}
}
continue ;
}
// Save all cells.
//store all cell
//when they don't exist we created them
//because it's necessary when there is a format on a column/row
//but I remove cell which is inserted.
Cell * cell ;
bool insert ;
enableScrollBarUpdates ( false ) ;
for ( int col = range . left ( ) ; col < = range . right ( ) ; + + col )
{
for ( int row = range . top ( ) ; row < = range . bottom ( ) ; + + row )
{
insert = false ;
cell = cellAt ( col , row ) ;
if ( cell = = d - > defaultCell )
{
cell = new Cell ( this , col , row ) ;
insertCell ( cell ) ;
insert = true ;
}
root . appendChild ( cell - > save ( dd , left - 1 , top - 1 , true , copy , era ) ) ;
if ( insert )
{
d - > cells . remove ( col , row ) ;
}
}
}
enableScrollBarUpdates ( true ) ;
}
return dd ;
}
TQDomElement Sheet : : saveXML ( TQDomDocument & dd )
{
TQDomElement sheet = dd . createElement ( " table " ) ;
sheet . setAttribute ( " name " , d - > name ) ;
//Laurent: for oasis format I think that we must use style:direction...
sheet . setAttribute ( " layoutDirection " , ( d - > layoutDirection = = RightToLeft ) ? " rtl " : " ltr " ) ;
sheet . setAttribute ( " columnnumber " , ( int ) d - > showColumnNumber ) ;
sheet . setAttribute ( " borders " , ( int ) d - > showPageBorders ) ;
sheet . setAttribute ( " hide " , ( int ) d - > hide ) ;
sheet . setAttribute ( " hidezero " , ( int ) d - > hideZero ) ;
sheet . setAttribute ( " firstletterupper " , ( int ) d - > firstLetterUpper ) ;
sheet . setAttribute ( " grid " , ( int ) d - > showGrid ) ;
sheet . setAttribute ( " printGrid " , ( int ) d - > print - > printGrid ( ) ) ;
sheet . setAttribute ( " printCommentIndicator " , ( int ) d - > print - > printCommentIndicator ( ) ) ;
sheet . setAttribute ( " printFormulaIndicator " , ( int ) d - > print - > printFormulaIndicator ( ) ) ;
sheet . setAttribute ( " showFormula " , ( int ) d - > showFormula ) ;
sheet . setAttribute ( " showFormulaIndicator " , ( int ) d - > showFormulaIndicator ) ;
sheet . setAttribute ( " showCommentIndicator " , ( int ) d - > showCommentIndicator ) ;
sheet . setAttribute ( " lcmode " , ( int ) d - > lcMode ) ;
sheet . setAttribute ( " autoCalc " , ( int ) d - > autoCalc ) ;
sheet . setAttribute ( " borders1.2 " , 1 ) ;
if ( ! d - > password . isNull ( ) )
{
if ( d - > password . size ( ) > 0 )
{
TQCString str = KCodecs : : base64Encode ( d - > password ) ;
sheet . setAttribute ( " protected " , TQString ( str . data ( ) ) ) ;
}
else
sheet . setAttribute ( " protected " , " " ) ;
}
// paper parameters
TQDomElement paper = dd . createElement ( " paper " ) ;
paper . setAttribute ( " format " , d - > print - > paperFormatString ( ) ) ;
paper . setAttribute ( " orientation " , d - > print - > orientationString ( ) ) ;
sheet . appendChild ( paper ) ;
TQDomElement borders = dd . createElement ( " borders " ) ;
borders . setAttribute ( " left " , d - > print - > leftBorder ( ) ) ;
borders . setAttribute ( " top " , d - > print - > topBorder ( ) ) ;
borders . setAttribute ( " right " , d - > print - > rightBorder ( ) ) ;
borders . setAttribute ( " bottom " , d - > print - > bottomBorder ( ) ) ;
paper . appendChild ( borders ) ;
TQDomElement head = dd . createElement ( " head " ) ;
paper . appendChild ( head ) ;
if ( ! d - > print - > headLeft ( ) . isEmpty ( ) )
{
TQDomElement left = dd . createElement ( " left " ) ;
head . appendChild ( left ) ;
left . appendChild ( dd . createTextNode ( d - > print - > headLeft ( ) ) ) ;
}
if ( ! d - > print - > headMid ( ) . isEmpty ( ) )
{
TQDomElement center = dd . createElement ( " center " ) ;
head . appendChild ( center ) ;
center . appendChild ( dd . createTextNode ( d - > print - > headMid ( ) ) ) ;
}
if ( ! d - > print - > headRight ( ) . isEmpty ( ) )
{
TQDomElement right = dd . createElement ( " right " ) ;
head . appendChild ( right ) ;
right . appendChild ( dd . createTextNode ( d - > print - > headRight ( ) ) ) ;
}
TQDomElement foot = dd . createElement ( " foot " ) ;
paper . appendChild ( foot ) ;
if ( ! d - > print - > footLeft ( ) . isEmpty ( ) )
{
TQDomElement left = dd . createElement ( " left " ) ;
foot . appendChild ( left ) ;
left . appendChild ( dd . createTextNode ( d - > print - > footLeft ( ) ) ) ;
}
if ( ! d - > print - > footMid ( ) . isEmpty ( ) )
{
TQDomElement center = dd . createElement ( " center " ) ;
foot . appendChild ( center ) ;
center . appendChild ( dd . createTextNode ( d - > print - > footMid ( ) ) ) ;
}
if ( ! d - > print - > footRight ( ) . isEmpty ( ) )
{
TQDomElement right = dd . createElement ( " right " ) ;
foot . appendChild ( right ) ;
right . appendChild ( dd . createTextNode ( d - > print - > footRight ( ) ) ) ;
}
// print range
TQDomElement printrange = dd . createElement ( " printrange-rect " ) ;
TQRect _printRange = d - > print - > printRange ( ) ;
int left = _printRange . left ( ) ;
int right = _printRange . right ( ) ;
int top = _printRange . top ( ) ;
int bottom = _printRange . bottom ( ) ;
//If whole rows are selected, then we store zeros, as KS_colMax may change in future
if ( left = = 1 & & right = = KS_colMax )
{
left = 0 ;
right = 0 ;
}
//If whole columns are selected, then we store zeros, as KS_rowMax may change in future
if ( top = = 1 & & bottom = = KS_rowMax )
{
top = 0 ;
bottom = 0 ;
}
printrange . setAttribute ( " left-rect " , left ) ;
printrange . setAttribute ( " right-rect " , right ) ;
printrange . setAttribute ( " bottom-rect " , bottom ) ;
printrange . setAttribute ( " top-rect " , top ) ;
sheet . appendChild ( printrange ) ;
// Print repeat columns
TQDomElement printRepeatColumns = dd . createElement ( " printrepeatcolumns " ) ;
printRepeatColumns . setAttribute ( " left " , d - > print - > printRepeatColumns ( ) . first ) ;
printRepeatColumns . setAttribute ( " right " , d - > print - > printRepeatColumns ( ) . second ) ;
sheet . appendChild ( printRepeatColumns ) ;
// Print repeat rows
TQDomElement printRepeatRows = dd . createElement ( " printrepeatrows " ) ;
printRepeatRows . setAttribute ( " top " , d - > print - > printRepeatRows ( ) . first ) ;
printRepeatRows . setAttribute ( " bottom " , d - > print - > printRepeatRows ( ) . second ) ;
sheet . appendChild ( printRepeatRows ) ;
//Save print zoom
sheet . setAttribute ( " printZoom " , d - > print - > zoom ( ) ) ;
//Save page limits
sheet . setAttribute ( " printPageLimitX " , d - > print - > pageLimitX ( ) ) ;
sheet . setAttribute ( " printPageLimitY " , d - > print - > pageLimitY ( ) ) ;
// Save all cells.
Cell * c = d - > cells . firstCell ( ) ;
for ( ; c ; c = c - > nextCell ( ) )
{
if ( ! c - > isDefault ( ) )
{
TQDomElement e = c - > save ( dd ) ;
if ( ! e . isNull ( ) )
sheet . appendChild ( e ) ;
}
}
// Save all RowFormat objects.
RowFormat * rl = d - > rows . first ( ) ;
for ( ; rl ; rl = rl - > next ( ) )
{
if ( ! rl - > isDefault ( ) )
{
TQDomElement e = rl - > save ( dd ) ;
if ( e . isNull ( ) )
return TQDomElement ( ) ;
sheet . appendChild ( e ) ;
}
}
// Save all ColumnFormat objects.
ColumnFormat * cl = d - > columns . first ( ) ;
for ( ; cl ; cl = cl - > next ( ) )
{
if ( ! cl - > isDefault ( ) )
{
TQDomElement e = cl - > save ( dd ) ;
if ( e . isNull ( ) )
return TQDomElement ( ) ;
sheet . appendChild ( e ) ;
}
}
TQPtrListIterator < EmbeddedObject > chl = doc ( ) - > embeddedObjects ( ) ;
for ( ; chl . current ( ) ; + + chl )
{
if ( chl . current ( ) - > sheet ( ) = = this )
{
TQDomElement e = chl . current ( ) - > save ( dd ) ;
if ( e . isNull ( ) )
return TQDomElement ( ) ;
sheet . appendChild ( e ) ;
}
}
return sheet ;
}
bool Sheet : : isLoading ( )
{
return doc ( ) - > isLoading ( ) ;
}
TQPtrList < EmbeddedObject > Sheet : : getSelectedObjects ( )
{
TQPtrList < EmbeddedObject > objects ;
TQPtrListIterator < EmbeddedObject > it = doc ( ) - > embeddedObjects ( ) ;
for ( ; it . current ( ) ; + + it )
{
if ( it . current ( ) - > isSelected ( )
& & it . current ( ) - > sheet ( ) = = this )
{
objects . append ( it . current ( ) ) ;
}
}
return objects ;
}
KoRect Sheet : : getRealRect ( bool all )
{
KoRect rect ;
TQPtrListIterator < EmbeddedObject > it ( doc ( ) - > embeddedObjects ( ) ) ;
for ( ; it . current ( ) ; + + it )
{
if ( all | | ( it . current ( ) - > isSelected ( ) & & ! it . current ( ) - > isProtect ( ) ) )
rect | = it . current ( ) - > geometry ( ) ;
}
return rect ;
}
// move object for releasemouseevent
KCommand * Sheet : : moveObject ( View * _view , double diffx , double diffy )
{
bool createCommand = false ;
MoveObjectByCmd * moveByCmd = 0L ;
Canvas * canvas = _view - > canvasWidget ( ) ;
TQPtrList < EmbeddedObject > _objects ;
_objects . setAutoDelete ( false ) ;
TQPtrListIterator < EmbeddedObject > it ( doc ( ) - > embeddedObjects ( ) /*m_objectList*/ ) ;
for ( ; it . current ( ) ; + + it )
{
if ( it . current ( ) - > isSelected ( ) & & ! it . current ( ) - > isProtect ( ) )
{
_objects . append ( it . current ( ) ) ;
KoRect geometry = it . current ( ) - > geometry ( ) ;
geometry . moveBy ( - canvas - > xOffset ( ) , - canvas - > yOffset ( ) ) ;
TQRect br = doc ( ) - > zoomRect ( geometry /*it.current()->geometry()*/ ) ;
br . moveBy ( doc ( ) - > zoomItX ( diffx ) , doc ( ) - > zoomItY ( diffy ) ) ;
br . moveBy ( doc ( ) - > zoomItX ( - canvas - > xOffset ( ) ) , doc ( ) - > zoomItY ( - canvas - > yOffset ( ) ) ) ;
canvas - > repaint ( br ) ; // Previous position
canvas - > repaintObject ( it . current ( ) ) ; // New position
createCommand = true ;
}
}
if ( createCommand ) {
moveByCmd = new MoveObjectByCmd ( i18n ( " Move Objects " ) , KoPoint ( diffx , diffy ) ,
_objects , doc ( ) , this ) ;
// m_doc->updateSideBarItem( this );
}
return moveByCmd ;
}
KCommand * Sheet : : moveObject ( View * _view , const KoPoint & _move , bool key )
{
TQPtrList < EmbeddedObject > _objects ;
_objects . setAutoDelete ( false ) ;
MoveObjectByCmd * moveByCmd = 0L ;
Canvas * canvas = _view - > canvasWidget ( ) ;
TQPtrListIterator < EmbeddedObject > it ( doc ( ) - > embeddedObjects ( ) /*m_objectList*/ ) ;
for ( ; it . current ( ) ; + + it )
{
if ( it . current ( ) - > isSelected ( ) & & ! it . current ( ) - > isProtect ( ) ) {
KoRect geometry = it . current ( ) - > geometry ( ) ;
geometry . moveBy ( - canvas - > xOffset ( ) , - canvas - > yOffset ( ) ) ;
TQRect oldBoundingRect = doc ( ) - > zoomRect ( geometry ) ;
KoRect r = it . current ( ) - > geometry ( ) ;
r . moveBy ( _move . x ( ) , _move . y ( ) ) ;
it . current ( ) - > setGeometry ( r ) ;
_objects . append ( it . current ( ) ) ;
canvas - > repaint ( oldBoundingRect ) ;
canvas - > repaintObject ( it . current ( ) ) ;
}
}
if ( key & & ! _objects . isEmpty ( ) )
moveByCmd = new MoveObjectByCmd ( i18n ( " Move Objects " ) ,
KoPoint ( _move ) ,
_objects , doc ( ) , this ) ;
return moveByCmd ;
}
/*
* Check if object name already exists .
*/
bool Sheet : : objectNameExists ( EmbeddedObject * object , TQPtrList < EmbeddedObject > & list ) {
TQPtrListIterator < EmbeddedObject > it ( list ) ;
for ( it . toFirst ( ) ; it . current ( ) ; + + it ) {
// object name can exist in current object.
if ( it . current ( ) - > getObjectName ( ) = = object - > getObjectName ( ) & &
it . current ( ) ! = object ) {
return true ;
}
}
return false ;
}
void Sheet : : unifyObjectName ( EmbeddedObject * object ) {
if ( object - > getObjectName ( ) . isEmpty ( ) ) {
object - > setObjectName ( object - > getTypeString ( ) ) ;
}
TQString objectName ( object - > getObjectName ( ) ) ;
TQPtrList < EmbeddedObject > list ( doc ( ) - > embeddedObjects ( ) ) ;
int count = 1 ;
while ( objectNameExists ( object , list ) ) {
count + + ;
TQRegExp rx ( " \\ ( \\ d{1,3} \\ ) $ " ) ;
if ( rx . search ( objectName ) ! = - 1 ) {
objectName . remove ( rx ) ;
}
objectName + = TQString ( " (%1) " ) . arg ( count ) ;
object - > setObjectName ( objectName ) ;
}
}
void Sheet : : checkContentDirection ( TQString const & name )
{
/* set sheet's direction to RTL if sheet name is an RTL string */
if ( ( name . isRightToLeft ( ) ) )
setLayoutDirection ( RightToLeft ) ;
else
setLayoutDirection ( LeftToRight ) ;
emit sig_refreshView ( ) ;
}
bool Sheet : : loadSheetStyleFormat ( TQDomElement * style )
{
TQString hleft , hmiddle , hright ;
TQString fleft , fmiddle , fright ;
TQDomNode header = KoDom : : namedItemNS ( * style , KoXmlNS : : style , " header " ) ;
if ( ! header . isNull ( ) )
{
kdDebug ( ) < < " Header exists " < < endl ;
TQDomNode part = KoDom : : namedItemNS ( header , KoXmlNS : : style , " region-left " ) ;
if ( ! part . isNull ( ) )
{
hleft = getPart ( part ) ;
kdDebug ( ) < < " Header left: " < < hleft < < endl ;
}
else
kdDebug ( ) < < " Style:region:left doesn't exist! " < < endl ;
part = KoDom : : namedItemNS ( header , KoXmlNS : : style , " region-center " ) ;
if ( ! part . isNull ( ) )
{
hmiddle = getPart ( part ) ;
kdDebug ( ) < < " Header middle: " < < hmiddle < < endl ;
}
part = KoDom : : namedItemNS ( header , KoXmlNS : : style , " region-right " ) ;
if ( ! part . isNull ( ) )
{
hright = getPart ( part ) ;
kdDebug ( ) < < " Header right: " < < hright < < endl ;
}
}
//TODO implement it under kspread
TQDomNode headerleft = KoDom : : namedItemNS ( * style , KoXmlNS : : style , " header-left " ) ;
if ( ! headerleft . isNull ( ) )
{
TQDomElement e = headerleft . toElement ( ) ;
if ( e . hasAttributeNS ( KoXmlNS : : style , " display " ) )
kdDebug ( ) < < " header.hasAttribute( style:display ) : " < < e . hasAttributeNS ( KoXmlNS : : style , " display " ) < < endl ;
else
kdDebug ( ) < < " header left doesn't has attribute style:display \n " ;
}
//TODO implement it under kspread
TQDomNode footerleft = KoDom : : namedItemNS ( * style , KoXmlNS : : style , " footer-left " ) ;
if ( ! footerleft . isNull ( ) )
{
TQDomElement e = footerleft . toElement ( ) ;
if ( e . hasAttributeNS ( KoXmlNS : : style , " display " ) )
kdDebug ( ) < < " footer.hasAttribute( style:display ) : " < < e . hasAttributeNS ( KoXmlNS : : style , " display " ) < < endl ;
else
kdDebug ( ) < < " footer left doesn't has attribute style:display \n " ;
}
TQDomNode footer = KoDom : : namedItemNS ( * style , KoXmlNS : : style , " footer " ) ;
if ( ! footer . isNull ( ) )
{
TQDomNode part = KoDom : : namedItemNS ( footer , KoXmlNS : : style , " region-left " ) ;
if ( ! part . isNull ( ) )
{
fleft = getPart ( part ) ;
kdDebug ( ) < < " Footer left: " < < fleft < < endl ;
}
part = KoDom : : namedItemNS ( footer , KoXmlNS : : style , " region-center " ) ;
if ( ! part . isNull ( ) )
{
fmiddle = getPart ( part ) ;
kdDebug ( ) < < " Footer middle: " < < fmiddle < < endl ;
}
part = KoDom : : namedItemNS ( footer , KoXmlNS : : style , " region-right " ) ;
if ( ! part . isNull ( ) )
{
fright = getPart ( part ) ;
kdDebug ( ) < < " Footer right: " < < fright < < endl ;
}
}
print ( ) - > setHeadFootLine ( hleft , hmiddle , hright ,
fleft , fmiddle , fright ) ;
return true ;
}
void Sheet : : replaceMacro ( TQString & text , const TQString & old , const TQString & newS )
{
int n = text . find ( old ) ;
if ( n ! = - 1 )
text = text . replace ( n , old . length ( ) , newS ) ;
}
TQString Sheet : : getPart ( const TQDomNode & part )
{
TQString result ;
TQDomElement e = KoDom : : namedItemNS ( part , KoXmlNS : : text , " p " ) ;
while ( ! e . isNull ( ) )
{
TQString text = e . text ( ) ;
kdDebug ( ) < < " PART: " < < text < < endl ;
TQDomElement macro = KoDom : : namedItemNS ( e , KoXmlNS : : text , " time " ) ;
if ( ! macro . isNull ( ) )
replaceMacro ( text , macro . text ( ) , " <time> " ) ;
macro = KoDom : : namedItemNS ( e , KoXmlNS : : text , " date " ) ;
if ( ! macro . isNull ( ) )
replaceMacro ( text , macro . text ( ) , " <date> " ) ;
macro = KoDom : : namedItemNS ( e , KoXmlNS : : text , " page-number " ) ;
if ( ! macro . isNull ( ) )
replaceMacro ( text , macro . text ( ) , " <page> " ) ;
macro = KoDom : : namedItemNS ( e , KoXmlNS : : text , " page-count " ) ;
if ( ! macro . isNull ( ) )
replaceMacro ( text , macro . text ( ) , " <pages> " ) ;
macro = KoDom : : namedItemNS ( e , KoXmlNS : : text , " sheet-name " ) ;
if ( ! macro . isNull ( ) )
replaceMacro ( text , macro . text ( ) , " <sheet> " ) ;
macro = KoDom : : namedItemNS ( e , KoXmlNS : : text , " title " ) ;
if ( ! macro . isNull ( ) )
replaceMacro ( text , macro . text ( ) , " <name> " ) ;
macro = KoDom : : namedItemNS ( e , KoXmlNS : : text , " file-name " ) ;
if ( ! macro . isNull ( ) )
replaceMacro ( text , macro . text ( ) , " <file> " ) ;
//add support for multi line into kspread
if ( ! result . isEmpty ( ) )
result + = ' \n ' ;
result + = text ;
e = e . nextSibling ( ) . toElement ( ) ;
}
return result ;
}
bool Sheet : : loadOasis ( const TQDomElement & sheetElement , KoOasisLoadingContext & oasisContext , TQDict < Style > & styleMap )
{
d - > layoutDirection = LeftToRight ;
if ( sheetElement . hasAttributeNS ( KoXmlNS : : table , " style-name " ) )
{
TQString stylename = sheetElement . attributeNS ( KoXmlNS : : table , " style-name " , TQString ( ) ) ;
//kdDebug()<<" style of table :"<<stylename<<endl;
const TQDomElement * style = oasisContext . oasisStyles ( ) . findStyle ( stylename , " table " ) ;
Q_ASSERT ( style ) ;
//kdDebug()<<" style :"<<style<<endl;
if ( style )
{
TQDomElement properties ( KoDom : : namedItemNS ( * style , KoXmlNS : : style , " table-properties " ) ) ;
if ( ! properties . isNull ( ) )
{
if ( properties . hasAttributeNS ( KoXmlNS : : table , " display " ) )
{
bool visible = ( properties . attributeNS ( KoXmlNS : : table , " display " , TQString ( ) ) = = " true " ? true : false ) ;
d - > hide = ! visible ;
}
}
if ( style - > hasAttributeNS ( KoXmlNS : : style , " master-page-name " ) )
{
TQString masterPageStyleName = style - > attributeNS ( KoXmlNS : : style , " master-page-name " , TQString ( ) ) ;
//kdDebug()<<"style->attribute( style:master-page-name ) :"<<masterPageStyleName <<endl;
TQDomElement * masterStyle = oasisContext . oasisStyles ( ) . masterPages ( ) [ masterPageStyleName ] ;
//kdDebug()<<"oasisStyles.styles()[masterPageStyleName] :"<<masterStyle<<endl;
if ( masterStyle )
{
loadSheetStyleFormat ( masterStyle ) ;
if ( masterStyle - > hasAttributeNS ( KoXmlNS : : style , " page-layout-name " ) )
{
TQString masterPageLayoutStyleName = masterStyle - > attributeNS ( KoXmlNS : : style , " page-layout-name " , TQString ( ) ) ;
//kdDebug()<<"masterPageLayoutStyleName :"<<masterPageLayoutStyleName<<endl;
const TQDomElement * masterLayoutStyle = oasisContext . oasisStyles ( ) . findStyle ( masterPageLayoutStyleName ) ;
if ( masterLayoutStyle )
{
//kdDebug()<<"masterLayoutStyle :"<<masterLayoutStyle<<endl;
KoStyleStack styleStack ;
styleStack . setTypeProperties ( " page-layout " ) ;
styleStack . push ( * masterLayoutStyle ) ;
loadOasisMasterLayoutPage ( styleStack ) ;
}
}
}
}
}
}
//Maps from a column index to the name of the default cell style for that column
TQMap < int , TQString > defaultColumnCellStyles ;
int rowIndex = 1 ;
int indexCol = 1 ;
TQDomNode rowNode = sheetElement . firstChild ( ) ;
// Some spreadsheet programs may support more rows than
// KSpread so limit the number of repeated rows.
// FIXME POSSIBLE DATA LOSS!
while ( ! rowNode . isNull ( ) & & rowIndex < = KS_rowMax )
{
kdDebug ( ) < < " rowIndex : " < < rowIndex < < " indexCol : " < < indexCol < < endl ;
TQDomElement rowElement = rowNode . toElement ( ) ;
if ( ! rowElement . isNull ( ) )
{
kdDebug ( ) < < " Sheet::loadOasis rowElement.tagName() : " < < rowElement . localName ( ) < < endl ;
if ( rowElement . namespaceURI ( ) = = KoXmlNS : : table )
{
if ( rowElement . localName ( ) = = " table-column " & & indexCol < = KS_colMax )
{
kdDebug ( ) < < " table-column found : index column before " < < indexCol < < endl ;
loadColumnFormat ( rowElement , oasisContext . oasisStyles ( ) , indexCol , styleMap ) ;
kdDebug ( ) < < " table-column found : index column after " < < indexCol < < endl ;
}
else if ( rowElement . localName ( ) = = " table-header-rows " )
{
TQDomNode headerRowNode = rowElement . firstChild ( ) ;
while ( ! headerRowNode . isNull ( ) )
{
// NOTE Handle header rows as ordinary ones
// as long as they're not supported.
loadRowFormat ( headerRowNode . toElement ( ) , rowIndex ,
oasisContext , /*rowNode.isNull() ,*/ styleMap ) ;
headerRowNode = headerRowNode . nextSibling ( ) ;
}
}
else if ( rowElement . localName ( ) = = " table-row " )
{
kdDebug ( ) < < " table-row found :index row before " < < rowIndex < < endl ;
loadRowFormat ( rowElement , rowIndex , oasisContext , /*rowNode.isNull() ,*/ styleMap ) ;
kdDebug ( ) < < " table-row found :index row after " < < rowIndex < < endl ;
}
else if ( rowElement . localName ( ) = = " shapes " )
loadOasisObjects ( rowElement , oasisContext ) ;
}
}
rowNode = rowNode . nextSibling ( ) ;
}
if ( sheetElement . hasAttributeNS ( KoXmlNS : : table , " print-ranges " ) )
{
// e.g.: Sheet4.A1:Sheet4.E28
TQString range = sheetElement . attributeNS ( KoXmlNS : : table , " print-ranges " , TQString ( ) ) ;
range = Oasis : : decodeFormula ( range ) ;
Range p ( range ) ;
if ( sheetName ( ) = = p . sheetName ( ) )
d - > print - > setPrintRange ( p . range ( ) ) ;
}
if ( sheetElement . attributeNS ( KoXmlNS : : table , " protected " , TQString ( ) ) = = " true " )
{
TQCString passwd ( " " ) ;
if ( sheetElement . hasAttributeNS ( KoXmlNS : : table , " protection-key " ) )
{
TQString p = sheetElement . attributeNS ( KoXmlNS : : table , " protection-key " , TQString ( ) ) ;
TQCString str ( p . latin1 ( ) ) ;
kdDebug ( 30518 ) < < " Decoding password: " < < str < < endl ;
passwd = KCodecs : : base64Decode ( str ) ;
}
kdDebug ( 30518 ) < < " Password hash: ' " < < passwd < < " ' " < < endl ;
d - > password = passwd ;
}
return true ;
}
void Sheet : : loadOasisObjects ( const TQDomElement & parent , KoOasisLoadingContext & oasisContext )
{
TQDomElement e ;
TQDomNode n = parent . firstChild ( ) ;
while ( ! n . isNull ( ) )
{
e = n . toElement ( ) ;
if ( e . localName ( ) = = " frame " & & e . namespaceURI ( ) = = KoXmlNS : : draw )
{
EmbeddedObject * obj = 0 ;
TQDomNode object = KoDom : : namedItemNS ( e , KoXmlNS : : draw , " object " ) ;
if ( ! object . isNull ( ) )
{
if ( ! object . toElement ( ) . attributeNS ( KoXmlNS : : draw , " notify-on-update-of-ranges " , TQString ( ) ) . isNull ( ) )
obj = new EmbeddedChart ( doc ( ) , this ) ;
else
obj = new EmbeddedKOfficeObject ( doc ( ) , this ) ;
}
else
{
TQDomNode image = KoDom : : namedItemNS ( e , KoXmlNS : : draw , " image " ) ;
if ( ! image . isNull ( ) )
obj = new EmbeddedPictureObject ( this , doc ( ) - > pictureCollection ( ) ) ;
else
kdDebug ( ) < < " Object type wasn't loaded! " < < endl ;
}
if ( obj )
{
obj - > loadOasis ( e , oasisContext ) ;
insertObject ( obj ) ;
}
}
n = n . nextSibling ( ) ;
}
}
void Sheet : : loadOasisMasterLayoutPage ( KoStyleStack & styleStack )
{
// use A4 as default page size
float left = 20.0 ;
float right = 20.0 ;
float top = 20.0 ;
float bottom = 20.0 ;
float width = 210.0 ;
float height = 297.0 ;
TQString orientation = " Portrait " ;
TQString format ;
// Laurent : Why we stored layout information as Millimeter ?!!!!!
// kspread used point for all other attribute
// I don't understand :(
if ( styleStack . hasAttributeNS ( KoXmlNS : : fo , " page-width " ) )
{
width = KoUnit : : toMM ( KoUnit : : parseValue ( styleStack . attributeNS ( KoXmlNS : : fo , " page-width " ) ) ) ;
}
if ( styleStack . hasAttributeNS ( KoXmlNS : : fo , " page-height " ) )
{
height = KoUnit : : toMM ( KoUnit : : parseValue ( styleStack . attributeNS ( KoXmlNS : : fo , " page-height " ) ) ) ;
}
if ( styleStack . hasAttributeNS ( KoXmlNS : : fo , " margin-top " ) )
{
top = KoUnit : : toMM ( KoUnit : : parseValue ( styleStack . attributeNS ( KoXmlNS : : fo , " margin-top " ) ) ) ;
}
if ( styleStack . hasAttributeNS ( KoXmlNS : : fo , " margin-bottom " ) )
{
bottom = KoUnit : : toMM ( KoUnit : : parseValue ( styleStack . attributeNS ( KoXmlNS : : fo , " margin-bottom " ) ) ) ;
}
if ( styleStack . hasAttributeNS ( KoXmlNS : : fo , " margin-left " ) )
{
left = KoUnit : : toMM ( KoUnit : : parseValue ( styleStack . attributeNS ( KoXmlNS : : fo , " margin-left " ) ) ) ;
}
if ( styleStack . hasAttributeNS ( KoXmlNS : : fo , " margin-right " ) )
{
right = KoUnit : : toMM ( KoUnit : : parseValue ( styleStack . attributeNS ( KoXmlNS : : fo , " margin-right " ) ) ) ;
}
if ( styleStack . hasAttributeNS ( KoXmlNS : : style , " writing-mode " ) )
{
kdDebug ( ) < < " styleStack.hasAttribute( style:writing-mode ) : " < < styleStack . hasAttributeNS ( KoXmlNS : : style , " writing-mode " ) < < endl ;
d - > layoutDirection = ( styleStack . attributeNS ( KoXmlNS : : style , " writing-mode " ) = = " lr-tb " ) ? LeftToRight : RightToLeft ;
//TODO
//<value>lr-tb</value>
//<value>rl-tb</value>
//<value>tb-rl</value>
//<value>tb-lr</value>
//<value>lr</value>
//<value>rl</value>
//<value>tb</value>
//<value>page</value>
}
if ( styleStack . hasAttributeNS ( KoXmlNS : : style , " print-orientation " ) )
{
orientation = ( styleStack . attributeNS ( KoXmlNS : : style , " print-orientation " ) = = " landscape " ) ? " Landscape " : " Portrait " ;
}
if ( styleStack . hasAttributeNS ( KoXmlNS : : style , " num-format " ) )
{
//not implemented into kspread
//These attributes specify the numbering style to use.
//If a numbering style is not specified, the numbering style is inherited from
//the page style. See section 6.7.8 for information on these attributes
kdDebug ( ) < < " num-format : " < < styleStack . attributeNS ( KoXmlNS : : style , " num-format " ) < < endl ;
}
if ( styleStack . hasAttributeNS ( KoXmlNS : : fo , " background-color " ) )
{
//TODO
kdDebug ( ) < < " fo:background-color : " < < styleStack . attributeNS ( KoXmlNS : : fo , " background-color " ) < < endl ;
}
if ( styleStack . hasAttributeNS ( KoXmlNS : : style , " print " ) )
{
//todo parsing
TQString str = styleStack . attributeNS ( KoXmlNS : : style , " print " ) ;
kdDebug ( ) < < " style:print : " < < str < < endl ;
if ( str . contains ( " headers " ) )
{
//TODO implement it into kspread
}
if ( str . contains ( " grid " ) )
{
d - > print - > setPrintGrid ( true ) ;
}
if ( str . contains ( " annotations " ) )
{
//TODO it's not implemented
}
if ( str . contains ( " objects " ) )
{
//TODO it's not implemented
}
if ( str . contains ( " charts " ) )
{
//TODO it's not implemented
}
if ( str . contains ( " drawings " ) )
{
//TODO it's not implemented
}
if ( str . contains ( " formulas " ) )
{
d - > showFormula = true ;
}
if ( str . contains ( " zero-values " ) )
{
//TODO it's not implemented
}
}
if ( styleStack . hasAttributeNS ( KoXmlNS : : style , " table-centering " ) )
{
TQString str = styleStack . attributeNS ( KoXmlNS : : style , " table-centering " ) ;
//TODO not implemented into kspread
kdDebug ( ) < < " styleStack.attribute( style:table-centering ) : " < < str < < endl ;
#if 0
if ( str = = " horizontal " )
{
}
else if ( str = = " vertical " )
{
}
else if ( str = = " both " )
{
}
else if ( str = = " none " )
{
}
else
kdDebug ( ) < < " table-centering unknown : " < < str < < endl ;
# endif
}
format = TQString ( " %1x%2 " ) . arg ( width ) . arg ( height ) ;
kdDebug ( ) < < " format : " < < format < < endl ;
d - > print - > setPaperLayout ( left , top , right , bottom , format , orientation ) ;
kdDebug ( ) < < " left margin : " < < left < < " right : " < < right < < " top : " < < top < < " bottom : " < < bottom < < endl ;
//<style:properties fo:page-width="21.8cm" fo:page-height="28.801cm" fo:margin-top="2cm" fo:margin-bottom="2.799cm" fo:margin-left="1.3cm" fo:margin-right="1.3cm" style:writing-mode="lr-tb"/>
// TQString format = paper.attribute( "format" );
// TQString orientation = paper.attribute( "orientation" );
// d->print->setPaperLayout( left, top, right, bottom, format, orientation );
// }
}
bool Sheet : : loadColumnFormat ( const TQDomElement & column , const KoOasisStyles & oasisStyles , int & indexCol , const TQDict < Style > & styleMap )
{
kdDebug ( ) < < " bool Sheet::loadColumnFormat(const TQDomElement& column, const KoOasisStyles& oasisStyles, unsigned int & indexCol ) index Col : " < < indexCol < < endl ;
bool isNonDefaultColumn = false ;
int number = 1 ;
if ( column . hasAttributeNS ( KoXmlNS : : table , " number-columns-repeated " ) )
{
bool ok = true ;
int n = column . attributeNS ( KoXmlNS : : table , " number-columns-repeated " , TQString ( ) ) . toInt ( & ok ) ;
if ( ok )
// Some spreadsheet programs may support more rows than KSpread so
// limit the number of repeated rows.
// FIXME POSSIBLE DATA LOSS!
number = TQMIN ( n , KS_colMax - indexCol + 1 ) ;
kdDebug ( ) < < " Repeated: " < < number < < endl ;
}
Format layout ( this , doc ( ) - > styleManager ( ) - > defaultStyle ( ) ) ;
if ( column . hasAttributeNS ( KoXmlNS : : table , " default-cell-style-name " ) )
{
const TQString styleName = column . attributeNS ( KoXmlNS : : table , " default-cell-style-name " , TQString ( ) ) ;
if ( ! styleName . isEmpty ( ) )
{
Style * const style = styleMap [ styleName ] ;
if ( style )
{
layout . setStyle ( style ) ;
isNonDefaultColumn = true ;
}
}
}
bool collapsed = false ;
if ( column . hasAttributeNS ( KoXmlNS : : table , " visibility " ) )
{
const TQString visibility = column . attributeNS ( KoXmlNS : : table , " visibility " , TQString ( ) ) ;
if ( visibility = = " visible " )
collapsed = false ;
else if ( visibility = = " collapse " )
collapsed = true ;
else if ( visibility = = " filter " )
collapsed = false ; // FIXME Stefan: Set to true, if filters are supported.
isNonDefaultColumn = true ;
}
KoStyleStack styleStack ;
if ( column . hasAttributeNS ( KoXmlNS : : table , " style-name " ) )
{
TQString str = column . attributeNS ( KoXmlNS : : table , " style-name " , TQString ( ) ) ;
const TQDomElement * style = oasisStyles . findStyle ( str , " table-column " ) ;
if ( style )
{
styleStack . push ( * style ) ;
isNonDefaultColumn = true ;
}
}
styleStack . setTypeProperties ( " table-column " ) ; //style for column
double width = - 1.0 ;
if ( styleStack . hasAttributeNS ( KoXmlNS : : style , " column-width " ) )
{
width = KoUnit : : parseValue ( styleStack . attributeNS ( KoXmlNS : : style , " column-width " ) , - 1.0 ) ;
kdDebug ( ) < < " style:column-width : width : " < < width < < endl ;
isNonDefaultColumn = true ;
}
bool insertPageBreak = false ;
if ( styleStack . hasAttributeNS ( KoXmlNS : : fo , " break-before " ) )
{
TQString str = styleStack . attributeNS ( KoXmlNS : : fo , " break-before " ) ;
if ( str = = " page " )
{
insertPageBreak = true ;
}
else
kdDebug ( ) < < " str : " < < str < < endl ;
isNonDefaultColumn = true ;
}
for ( int i = 0 ; i < number ; + + i )
{
// kdDebug()<<" insert new column: pos :"<<indexCol<<" width :"<<width<<" hidden ? "<<collapsed<<endl;
ColumnFormat * columnFormat ;
if ( isNonDefaultColumn )
{
columnFormat = nonDefaultColumnFormat ( indexCol ) ;
if ( width ! = - 1.0 ) //safe
columnFormat - > setWidth ( ( int ) width ) ;
// if ( insertPageBreak )
// columnFormat->setPageBreak( true )
if ( collapsed )
columnFormat - > setHide ( true ) ;
}
else
{
columnFormat = this - > columnFormat ( indexCol ) ;
}
columnFormat - > copy ( layout ) ;
+ + indexCol ;
}
// kdDebug()<<" after index column !!!!!!!!!!!!!!!!!! :"<<indexCol<<endl;
return true ;
}
bool Sheet : : loadRowFormat ( const TQDomElement & row , int & rowIndex , KoOasisLoadingContext & oasisContext , TQDict < Style > & styleMap )
{
// kdDebug()<<"Sheet::loadRowFormat( const TQDomElement& row, int &rowIndex,const KoOasisStyles& oasisStyles, bool isLast )***********\n";
int backupRow = rowIndex ;
bool isNonDefaultRow = false ;
KoStyleStack styleStack ;
if ( row . hasAttributeNS ( KoXmlNS : : table , " style-name " ) )
{
TQString str = row . attributeNS ( KoXmlNS : : table , " style-name " , TQString ( ) ) ;
const TQDomElement * style = oasisContext . oasisStyles ( ) . findStyle ( str , " table-row " ) ;
if ( style )
{
styleStack . push ( * style ) ;
isNonDefaultRow = true ;
}
}
styleStack . setTypeProperties ( " table-row " ) ;
Format layout ( this , doc ( ) - > styleManager ( ) - > defaultStyle ( ) ) ;
if ( row . hasAttributeNS ( KoXmlNS : : table , " default-cell-style-name " ) )
{
const TQString styleName = row . attributeNS ( KoXmlNS : : table , " default-cell-style-name " , TQString ( ) ) ;
if ( ! styleName . isEmpty ( ) )
{
Style * const style = styleMap [ styleName ] ;
if ( style )
{
layout . setStyle ( style ) ;
isNonDefaultRow = true ;
}
}
}
double height = - 1.0 ;
if ( styleStack . hasAttributeNS ( KoXmlNS : : style , " row-height " ) )
{
height = KoUnit : : parseValue ( styleStack . attributeNS ( KoXmlNS : : style , " row-height " ) , - 1.0 ) ;
// kdDebug()<<" properties style:row-height : height :"<<height<<endl;
isNonDefaultRow = true ;
}
int number = 1 ;
if ( row . hasAttributeNS ( KoXmlNS : : table , " number-rows-repeated " ) )
{
bool ok = true ;
int n = row . attributeNS ( KoXmlNS : : table , " number-rows-repeated " , TQString ( ) ) . toInt ( & ok ) ;
if ( ok )
// Some spreadsheet programs may support more rows than KSpread so
// limit the number of repeated rows.
// FIXME POSSIBLE DATA LOSS!
number = TQMIN ( n , KS_rowMax - rowIndex + 1 ) ;
}
bool collapse = false ;
if ( row . hasAttributeNS ( KoXmlNS : : table , " visibility " ) )
{
const TQString visibility = row . attributeNS ( KoXmlNS : : table , " visibility " , TQString ( ) ) ;
if ( visibility = = " visible " )
collapse = false ;
else if ( visibility = = " collapse " )
collapse = true ;
else if ( visibility = = " filter " )
collapse = false ; // FIXME Stefan: Set to true, if filters are supported.
isNonDefaultRow = true ;
}
bool insertPageBreak = false ;
if ( styleStack . hasAttributeNS ( KoXmlNS : : fo , " break-before " ) )
{
TQString str = styleStack . attributeNS ( KoXmlNS : : fo , " break-before " ) ;
if ( str = = " page " )
{
insertPageBreak = true ;
}
// else
// kdDebug()<<" str :"<<str<<endl;
isNonDefaultRow = true ;
}
//number == number of row to be copy. But we must copy cell too.
for ( int i = 0 ; i < number ; + + i )
{
// kdDebug()<<" create non defaultrow format :"<<rowIndex<<" repeate : "<<number<<" height :"<<height<<endl;
RowFormat * rowFormat ;
if ( isNonDefaultRow )
{
rowFormat = nonDefaultRowFormat ( rowIndex ) ;
if ( height ! = - 1.0 )
rowFormat - > setHeight ( ( int ) height ) ;
if ( collapse )
rowFormat - > setHide ( true ) ;
}
else
{
rowFormat = this - > rowFormat ( rowIndex ) ;
}
rowFormat - > copy ( layout ) ;
+ + rowIndex ;
}
int columnIndex = 0 ;
TQDomNode cellNode = row . firstChild ( ) ;
int endRow = min ( backupRow + number , KS_rowMax ) ;
while ( ! cellNode . isNull ( ) )
{
TQDomElement cellElement = cellNode . toElement ( ) ;
if ( ! cellElement . isNull ( ) )
{
columnIndex + + ;
TQString localName = cellElement . localName ( ) ;
if ( ( ( localName = = " table-cell " ) | | ( localName = = " covered-table-cell " ) ) & & cellElement . namespaceURI ( ) = = KoXmlNS : : table )
{
//kdDebug() << "Loading cell #" << cellCount << endl;
Style * style = 0 ;
const bool cellHasStyle = cellElement . hasAttributeNS ( KoXmlNS : : table , " style-name " ) ;
if ( cellHasStyle )
{
style = styleMap [ cellElement . attributeNS ( KoXmlNS : : table , " style-name " , TQString ( ) ) ] ;
}
Cell * const cell = nonDefaultCell ( columnIndex , backupRow ) ; // FIXME Stefan: if empty, delete afterwards
cell - > loadOasis ( cellElement , oasisContext , style ) ;
int cols = 1 ;
// Copy this cell across & down, if it has repeated rows or columns, but only
// if the cell has some content or a style associated with it.
if ( ( number > 1 ) | | cellElement . hasAttributeNS ( KoXmlNS : : table , " number-columns-repeated " ) )
{
bool ok = false ;
int n = cellElement . attributeNS ( KoXmlNS : : table , " number-columns-repeated " , TQString ( ) ) . toInt ( & ok ) ;
if ( ok )
// Some spreadsheet programs may support more columns than
// KSpread so limit the number of repeated columns.
// FIXME POSSIBLE DATA LOSS!
cols = TQMIN ( n , KS_colMax - columnIndex + 1 ) ;
if ( ! cellHasStyle & & ( cell - > isEmpty ( ) & & cell - > format ( ) - > comment ( columnIndex , backupRow ) . isEmpty ( ) ) )
{
// just increment it
columnIndex + = cols - 1 ;
}
else
{
for ( int k = cols ; k ; - - k )
{
if ( k ! = cols )
columnIndex + + ;
for ( int newRow = backupRow ; newRow < endRow ; + + newRow )
{
Cell * target = nonDefaultCell ( columnIndex , newRow ) ;
if ( cell ! = target )
target - > copyAll ( cell ) ;
}
}
}
}
}
}
cellNode = cellNode . nextSibling ( ) ;
}
return true ;
}
void Sheet : : maxRowCols ( int & maxCols , int & maxRows )
{
const Cell * cell = firstCell ( ) ;
while ( cell )
{
if ( cell - > column ( ) > maxCols )
maxCols = cell - > column ( ) ;
if ( cell - > row ( ) > maxRows )
maxRows = cell - > row ( ) ;
cell = cell - > nextCell ( ) ;
}
const RowFormat * row = firstRow ( ) ;
while ( row )
{
if ( row - > row ( ) > maxRows )
maxRows = row - > row ( ) ;
row = row - > next ( ) ;
}
const ColumnFormat * col = firstCol ( ) ;
while ( col )
{
if ( col - > column ( ) > maxCols )
maxCols = col - > column ( ) ;
col = col - > next ( ) ;
}
}
bool Sheet : : compareRows ( int row1 , int row2 , int & maxCols ) const
{
if ( * rowFormat ( row1 ) ! = * rowFormat ( row2 ) )
{
// kdDebug() << "\t Formats of " << row1 << " and " << row2 << " are different" << endl;
return false ;
}
// FIXME Stefan: Make use of the cluster functionality.
for ( int col = 1 ; col < = maxCols ; + + col )
{
if ( * cellAt ( col , row1 ) ! = * cellAt ( col , row2 ) )
{
// kdDebug() << "\t Cell at column " << col << " in row " << row2 << " differs from the one in row " << row1 << endl;
return false ;
}
}
return true ;
}
void Sheet : : saveOasisHeaderFooter ( KoXmlWriter & xmlWriter ) const
{
TQString headerLeft = print ( ) - > headLeft ( ) ;
TQString headerCenter = print ( ) - > headMid ( ) ;
TQString headerRight = print ( ) - > headRight ( ) ;
TQString footerLeft = print ( ) - > footLeft ( ) ;
TQString footerCenter = print ( ) - > footMid ( ) ;
TQString footerRight = print ( ) - > footRight ( ) ;
xmlWriter . startElement ( " style:header " ) ;
if ( ( ! headerLeft . isEmpty ( ) )
| | ( ! headerCenter . isEmpty ( ) )
| | ( ! headerRight . isEmpty ( ) ) )
{
xmlWriter . startElement ( " style:region-left " ) ;
xmlWriter . startElement ( " text:p " ) ;
convertPart ( headerLeft , xmlWriter ) ;
xmlWriter . endElement ( ) ;
xmlWriter . endElement ( ) ;
xmlWriter . startElement ( " style:region-center " ) ;
xmlWriter . startElement ( " text:p " ) ;
convertPart ( headerCenter , xmlWriter ) ;
xmlWriter . endElement ( ) ;
xmlWriter . endElement ( ) ;
xmlWriter . startElement ( " style:region-right " ) ;
xmlWriter . startElement ( " text:p " ) ;
convertPart ( headerRight , xmlWriter ) ;
xmlWriter . endElement ( ) ;
xmlWriter . endElement ( ) ;
}
else
{
xmlWriter . startElement ( " text:p " ) ;
xmlWriter . startElement ( " text:sheet-name " ) ;
xmlWriter . addTextNode ( " ??? " ) ;
xmlWriter . endElement ( ) ;
xmlWriter . endElement ( ) ;
}
xmlWriter . endElement ( ) ;
xmlWriter . startElement ( " style:footer " ) ;
if ( ( ! footerLeft . isEmpty ( ) )
| | ( ! footerCenter . isEmpty ( ) )
| | ( ! footerRight . isEmpty ( ) ) )
{
xmlWriter . startElement ( " style:region-left " ) ;
xmlWriter . startElement ( " text:p " ) ;
convertPart ( footerLeft , xmlWriter ) ;
xmlWriter . endElement ( ) ;
xmlWriter . endElement ( ) ; //style:region-left
xmlWriter . startElement ( " style:region-center " ) ;
xmlWriter . startElement ( " text:p " ) ;
convertPart ( footerCenter , xmlWriter ) ;
xmlWriter . endElement ( ) ;
xmlWriter . endElement ( ) ;
xmlWriter . startElement ( " style:region-right " ) ;
xmlWriter . startElement ( " text:p " ) ;
convertPart ( footerRight , xmlWriter ) ;
xmlWriter . endElement ( ) ;
xmlWriter . endElement ( ) ;
}
else
{
xmlWriter . startElement ( " text:p " ) ;
xmlWriter . startElement ( " text:sheet-name " ) ;
xmlWriter . addTextNode ( " Page " ) ; // ???
xmlWriter . endElement ( ) ;
xmlWriter . startElement ( " text:page-number " ) ;
xmlWriter . addTextNode ( " 1 " ) ; // ???
xmlWriter . endElement ( ) ;
xmlWriter . endElement ( ) ;
}
xmlWriter . endElement ( ) ;
}
void Sheet : : addText ( const TQString & text , KoXmlWriter & writer ) const
{
if ( ! text . isEmpty ( ) )
writer . addTextNode ( text ) ;
}
void Sheet : : convertPart ( const TQString & part , KoXmlWriter & xmlWriter ) const
{
TQString text ;
TQString var ;
bool inVar = false ;
uint i = 0 ;
uint l = part . length ( ) ;
while ( i < l )
{
if ( inVar | | part [ i ] = = ' < ' )
{
inVar = true ;
var + = part [ i ] ;
if ( part [ i ] = = ' > ' )
{
inVar = false ;
if ( var = = " <page> " )
{
addText ( text , xmlWriter ) ;
xmlWriter . startElement ( " text:page-number " ) ;
xmlWriter . addTextNode ( " 1 " ) ;
xmlWriter . endElement ( ) ;
}
else if ( var = = " <pages> " )
{
addText ( text , xmlWriter ) ;
xmlWriter . startElement ( " text:page-count " ) ;
xmlWriter . addTextNode ( " 99 " ) ; //TODO I think that it can be different from 99
xmlWriter . endElement ( ) ;
}
else if ( var = = " <date> " )
{
addText ( text , xmlWriter ) ;
//text:p><text:date style:data-style-name="N2" text:date-value="2005-10-02">02/10/2005</text:date>, <text:time>10:20:12</text:time></text:p> "add style" => create new style
#if 0 //FIXME
TQDomElement t = dd . createElement ( " text:date " ) ;
t . setAttribute ( " text:date-value " , " 0-00-00 " ) ;
// todo: "style:data-style-name", "N2"
t . appendChild ( dd . createTextNode ( TQDate : : currentDate ( ) . toString ( ) ) ) ;
parent . appendChild ( t ) ;
# endif
}
else if ( var = = " <time> " )
{
addText ( text , xmlWriter ) ;
xmlWriter . startElement ( " text:time " ) ;
xmlWriter . addTextNode ( TQTime : : currentTime ( ) . toString ( ) ) ;
xmlWriter . endElement ( ) ;
}
else if ( var = = " <file> " ) // filepath + name
{
addText ( text , xmlWriter ) ;
xmlWriter . startElement ( " text:file-name " ) ;
xmlWriter . addAttribute ( " text:display " , " full " ) ;
xmlWriter . addTextNode ( " ??? " ) ;
xmlWriter . endElement ( ) ;
}
else if ( var = = " <name> " ) // filename
{
addText ( text , xmlWriter ) ;
xmlWriter . startElement ( " text:title " ) ;
xmlWriter . addTextNode ( " ??? " ) ;
xmlWriter . endElement ( ) ;
}
else if ( var = = " <author> " )
{
Doc * sdoc = d - > workbook - > doc ( ) ;
KoDocumentInfo * docInfo = sdoc - > documentInfo ( ) ;
KoDocumentInfoAuthor * authorPage = static_cast < KoDocumentInfoAuthor * > ( docInfo - > page ( " author " ) ) ;
text + = authorPage - > fullName ( ) ;
addText ( text , xmlWriter ) ;
}
else if ( var = = " <email> " )
{
Doc * sdoc = d - > workbook - > doc ( ) ;
KoDocumentInfo * docInfo = sdoc - > documentInfo ( ) ;
KoDocumentInfoAuthor * authorPage = static_cast < KoDocumentInfoAuthor * > ( docInfo - > page ( " author " ) ) ;
text + = authorPage - > email ( ) ;
addText ( text , xmlWriter ) ;
}
else if ( var = = " <org> " )
{
Doc * sdoc = d - > workbook - > doc ( ) ;
KoDocumentInfo * docInfo = sdoc - > documentInfo ( ) ;
KoDocumentInfoAuthor * authorPage = static_cast < KoDocumentInfoAuthor * > ( docInfo - > page ( " author " ) ) ;
text + = authorPage - > company ( ) ;
addText ( text , xmlWriter ) ;
}
else if ( var = = " <sheet> " )
{
addText ( text , xmlWriter ) ;
xmlWriter . startElement ( " text:sheet-name " ) ;
xmlWriter . addTextNode ( " ??? " ) ;
xmlWriter . endElement ( ) ;
}
else
{
// no known variable:
text + = var ;
addText ( text , xmlWriter ) ;
}
text = " " ;
var = " " ;
}
}
else
{
text + = part [ i ] ;
}
+ + i ;
}
if ( ! text . isEmpty ( ) | | ! var . isEmpty ( ) )
{
//we don't have var at the end =>store it
addText ( text + var , xmlWriter ) ;
}
kdDebug ( ) < < " text end : " < < text < < " var : " < < var < < endl ;
}
void Sheet : : loadOasisSettings ( const KoOasisSettings : : NamedMap & settings )
{
// Find the entry in the map that applies to this sheet (by name)
KoOasisSettings : : Items items = settings . entry ( d - > name ) ;
if ( items . isNull ( ) )
return ;
d - > hideZero = items . parseConfigItemBool ( " ShowZeroValues " ) ;
d - > showGrid = items . parseConfigItemBool ( " ShowGrid " ) ;
d - > firstLetterUpper = items . parseConfigItemBool ( " FirstLetterUpper " ) ;
int cursorX = items . parseConfigItemInt ( " CursorPositionX " ) ;
int cursorY = items . parseConfigItemInt ( " CursorPositionY " ) ;
doc ( ) - > loadingInfo ( ) - > setCursorPosition ( this , TQPoint ( cursorX , cursorY ) ) ;
double offsetX = items . parseConfigItemDouble ( " xOffset " ) ;
double offsetY = items . parseConfigItemDouble ( " yOffset " ) ;
doc ( ) - > loadingInfo ( ) - > setScrollingOffset ( this , KoPoint ( offsetX , offsetY ) ) ;
d - > showFormulaIndicator = items . parseConfigItemBool ( " ShowFormulaIndicator " ) ;
d - > showCommentIndicator = items . parseConfigItemBool ( " ShowCommentIndicator " ) ;
d - > showPageBorders = items . parseConfigItemBool ( " ShowPageBorders " ) ;
d - > lcMode = items . parseConfigItemBool ( " lcmode " ) ;
d - > autoCalc = items . parseConfigItemBool ( " autoCalc " ) ;
d - > showColumnNumber = items . parseConfigItemBool ( " ShowColumnNumber " ) ;
}
void Sheet : : saveOasisSettings ( KoXmlWriter & settingsWriter ) const
{
//not into each page into oo spec
settingsWriter . addConfigItem ( " ShowZeroValues " , d - > hideZero ) ;
settingsWriter . addConfigItem ( " ShowGrid " , d - > showGrid ) ;
//not define into oo spec
settingsWriter . addConfigItem ( " FirstLetterUpper " , d - > firstLetterUpper ) ;
settingsWriter . addConfigItem ( " ShowFormulaIndicator " , d - > showFormulaIndicator ) ;
settingsWriter . addConfigItem ( " ShowCommentIndicator " , d - > showCommentIndicator ) ;
settingsWriter . addConfigItem ( " ShowPageBorders " , d - > showPageBorders ) ;
settingsWriter . addConfigItem ( " lcmode " , d - > lcMode ) ;
settingsWriter . addConfigItem ( " autoCalc " , d - > autoCalc ) ;
settingsWriter . addConfigItem ( " ShowColumnNumber " , d - > showColumnNumber ) ;
}
bool Sheet : : saveOasis ( KoXmlWriter & xmlWriter , KoGenStyles & mainStyles , GenValidationStyles & valStyle , KoStore * store , KoXmlWriter * /*manifestWriter*/ , int & indexObj , int & partIndexObj )
{
int maxCols = 1 ;
int maxRows = 1 ;
xmlWriter . startElement ( " table:table " ) ;
xmlWriter . addAttribute ( " table:name " , d - > name ) ;
xmlWriter . addAttribute ( " table:style-name " , saveOasisSheetStyleName ( mainStyles ) ) ;
if ( ! d - > password . isEmpty ( ) )
{
xmlWriter . addAttribute ( " table:protected " , " true " ) ;
TQCString str = KCodecs : : base64Encode ( d - > password ) ;
xmlWriter . addAttribute ( " table:protection-key " , TQString ( str . data ( ) ) ) ; /* FIXME !!!!*/
}
TQRect _printRange = d - > print - > printRange ( ) ;
if ( _printRange ! = ( TQRect ( TQPoint ( 1 , 1 ) , TQPoint ( KS_colMax , KS_rowMax ) ) ) )
{
TQString range = convertRangeToRef ( d - > name , _printRange ) ;
kdDebug ( ) < < " range : " < < range < < endl ;
xmlWriter . addAttribute ( " table:print-ranges " , range ) ;
}
saveOasisObjects ( store , xmlWriter , mainStyles , indexObj , partIndexObj ) ;
maxRowCols ( maxCols , maxRows ) ;
saveOasisColRowCell ( xmlWriter , mainStyles , maxCols , maxRows , valStyle ) ;
xmlWriter . endElement ( ) ;
return true ;
}
void Sheet : : saveOasisPrintStyleLayout ( KoGenStyle & style ) const
{
TQString printParameter ;
if ( d - > print - > printGrid ( ) )
printParameter = " grid " ;
if ( d - > print - > printObjects ( ) )
printParameter + = " objects " ;
if ( d - > print - > printCharts ( ) )
printParameter + = " charts " ;
if ( d - > showFormula )
printParameter + = " formulas " ;
if ( ! printParameter . isEmpty ( ) )
{
printParameter + = " drawings zero-values " ; //default print style attributes in OO
style . addProperty ( " style:print " , printParameter ) ;
}
}
TQString Sheet : : saveOasisSheetStyleName ( KoGenStyles & mainStyles )
{
KoGenStyle pageStyle ( Doc : : STYLE_PAGE , " table " /*FIXME I don't know if name is sheet*/ ) ;
KoGenStyle pageMaster ( Doc : : STYLE_PAGEMASTER ) ;
pageMaster . addAttribute ( " style:page-layout-name " , d - > print - > saveOasisSheetStyleLayout ( mainStyles ) ) ;
TQBuffer buffer ;
buffer . open ( IO_WriteOnly ) ;
KoXmlWriter elementWriter ( & buffer ) ; // TODO pass indentation level
saveOasisHeaderFooter ( elementWriter ) ;
TQString elementContents = TQString : : fromUtf8 ( buffer . buffer ( ) , buffer . buffer ( ) . size ( ) ) ;
pageMaster . addChildElement ( " headerfooter " , elementContents ) ;
pageStyle . addAttribute ( " style:master-page-name " , mainStyles . lookup ( pageMaster , " Standard " ) ) ;
pageStyle . addProperty ( " table:display " , ! d - > hide ) ;
return mainStyles . lookup ( pageStyle , " ta " ) ;
}
void Sheet : : saveOasisColRowCell ( KoXmlWriter & xmlWriter , KoGenStyles & mainStyles ,
int maxCols , int maxRows , GenValidationStyles & valStyle )
{
kdDebug ( ) < < " Sheet::saveOasisColRowCell: " < < d - > name < < endl ;
kdDebug ( ) < < " \t Sheet dimension: " < < maxCols < < " x " < < maxRows < < endl ;
// saving the columns
//
int i = 1 ;
while ( i < = maxCols )
{
// kdDebug() << "Sheet::saveOasisColRowCell: first col loop:"
// << " i: " << i
// << " column: " << column->column() << endl;
ColumnFormat * column = columnFormat ( i ) ;
KoGenStyle currentColumnStyle ( Doc : : STYLE_COLUMN_AUTO , " table-column " ) ;
currentColumnStyle . addPropertyPt ( " style:column-width " , column - > dblWidth ( ) ) ;
currentColumnStyle . addProperty ( " fo:break-before " , " auto " ) ; /*FIXME auto or not ?*/
//style default layout for column
KoGenStyle currentDefaultCellStyle ; // the type is determined in saveOasisCellStyle
TQString currentDefaultCellStyleName = column - > saveOasisCellStyle ( currentDefaultCellStyle , mainStyles ) ;
bool hide = column - > isHide ( ) ;
bool refColumnIsDefault = column - > isDefault ( ) ;
int j = i ;
int repeated = 1 ;
while ( j < = maxCols )
{
// kdDebug() << "Sheet::saveOasisColRowCell: second col loop:"
// << " j: " << j
// << " column: " << nextColumn->column() << endl;
ColumnFormat * nextColumn = d - > columns . next ( j + + ) ;
// no next or not the adjacent column?
if ( ! nextColumn | | nextColumn - > column ( ) ! = j )
{
if ( refColumnIsDefault )
{
// if the origin column was a default column,
// we count the default columns
if ( ! nextColumn )
{
repeated = maxCols - i + 1 ;
}
else
{
repeated = nextColumn - > column ( ) - j + 1 ;
}
}
// otherwise we just stop here to process the adjacent
// column in the next iteration of the outer loop
break ;
}
#if 0
KoGenStyle nextColumnStyle ( Doc : : STYLE_COLUMN_AUTO , " table-column " ) ;
nextColumnStyle . addPropertyPt ( " style:column-width " , nextColumn - > dblWidth ( ) ) ; /*FIXME pt and not mm */
nextColumnStyle . addProperty ( " fo:break-before " , " auto " ) ; /*FIXME auto or not ?*/
KoGenStyle nextDefaultCellStyle ; // the type is determined in saveOasisCellStyle
TQString nextDefaultCellStyleName = nextColumn - > saveOasisCellStyle ( nextDefaultCellStyle , mainStyles ) ;
if ( hide ! = nextColumn - > isHide ( ) | |
nextDefaultCellStyleName ! = currentDefaultCellStyleName | |
! ( nextColumnStyle = = currentColumnStyle ) )
{
break ;
}
# endif
if ( * column ! = * nextColumn )
{
break ;
}
+ + repeated ;
}
xmlWriter . startElement ( " table:table-column " ) ;
if ( ! column - > isDefault ( ) )
{
xmlWriter . addAttribute ( " table:style-name " , mainStyles . lookup ( currentColumnStyle , " co " ) ) ;
if ( ! currentDefaultCellStyle . isDefaultStyle ( ) )
xmlWriter . addAttribute ( " table:default-cell-style-name " , currentDefaultCellStyleName ) ;
if ( hide )
xmlWriter . addAttribute ( " table:visibility " , " collapse " ) ;
}
if ( repeated > 1 )
xmlWriter . addAttribute ( " table:number-columns-repeated " , repeated ) ;
xmlWriter . endElement ( ) ;
kdDebug ( ) < < " Sheet::saveOasisColRowCell: column " < < i < < " "
< < " repeated " < < repeated < < " time(s) " < < endl ;
i + = repeated ;
}
// saving the rows and the cells
// we have to loop through all rows of the used area
for ( i = 1 ; i < = maxRows ; + + i )
{
RowFormat * const row = rowFormat ( i ) ;
KoGenStyle currentRowStyle ( Doc : : STYLE_ROW_AUTO , " table-row " ) ;
currentRowStyle . addPropertyPt ( " style:row-height " , row - > dblHeight ( ) ) ;
currentRowStyle . addProperty ( " fo:break-before " , " auto " ) ; /*FIXME auto or not ?*/
// default cell style for row
KoGenStyle currentDefaultCellStyle ; // the type is determined in saveOasisCellStyle
TQString currentDefaultCellStyleName = row - > saveOasisCellStyle ( currentDefaultCellStyle , mainStyles ) ;
xmlWriter . startElement ( " table:table-row " ) ;
if ( ! row - > isDefault ( ) )
{
xmlWriter . addAttribute ( " table:style-name " , mainStyles . lookup ( currentRowStyle , " ro " ) ) ;
}
int repeated = 1 ;
// empty row?
if ( ! getFirstCellRow ( i ) )
{
// kDebug() << "Sheet::saveOasisColRowCell: first row loop:"
// << " i: " << i
// << " row: " << row->row() << endl;
//bool isHidden = row->isHide();
bool isDefault = row - > isDefault ( ) ;
int j = i + 1 ;
// search for
// next non-empty row
// or
// next row with different Format
while ( j < = maxRows & & ! getFirstCellRow ( j ) )
{
RowFormat * const nextRow = rowFormat ( j ) ;
// kDebug() << "Sheet::saveOasisColRowCell: second row loop:"
// << " j: " << j
// << " row: " << nextRow->row() << endl;
// if the reference row has the default row format
if ( isDefault )
{
// if the next is not default, stop here
if ( ! nextRow - > isDefault ( ) )
break ;
// otherwise, jump to the next
+ + j ;
continue ;
}
#if 0
// create the Oasis representation of the format for the comparison
KoGenStyle nextRowStyle ( Doc : : STYLE_ROW_AUTO , " table-row " ) ;
nextRowStyle . addPropertyPt ( " style:row-height " , nextRow - > dblHeight ( ) ) ;
nextRowStyle . addProperty ( " fo:break-before " , " auto " ) ; /*FIXME auto or not ?*/
// default cell style name for next row
KoGenStyle nextDefaultCellStyle ; // the type is determined in saveOasisCellStyle
TQString nextDefaultCellStyleName = nextRow - > saveOasisCellStyle ( nextDefaultCellStyle , mainStyles ) ;
// if the formats differ, stop here
if ( isHidden ! = nextRow - > isHide ( ) | |
nextDefaultCellStyleName ! = currentDefaultCellStyleName | |
! ( nextRowStyle = = currentRowStyle ) )
{
break ;
}
# endif
if ( * row ! = * nextRow )
{
break ;
}
// otherwise, process the next
+ + j ;
}
repeated = j - i ;
if ( repeated > 1 )
xmlWriter . addAttribute ( " table:number-rows-repeated " , repeated ) ;
if ( ! currentDefaultCellStyle . isDefaultStyle ( ) )
xmlWriter . addAttribute ( " table:default-cell-style-name " , currentDefaultCellStyleName ) ;
if ( row - > isHide ( ) ) // never true for the default row
xmlWriter . addAttribute ( " table:visibility " , " collapse " ) ;
// NOTE Stefan: Even if paragraph 8.1 states, that rows may be empty, the
// RelaxNG schema does not allow that.
xmlWriter . startElement ( " table:table-cell " ) ;
xmlWriter . endElement ( ) ;
kdDebug ( ) < < " Sheet::saveOasisColRowCell: empty row " < < i < < ' '
< < " repeated " < < repeated < < " time(s) " < < endl ;
// copy the index for the next row to process
i = j - 1 ; /*it's already incremented in the for loop*/
}
else // row is not empty
{
if ( ! currentDefaultCellStyle . isDefaultStyle ( ) )
xmlWriter . addAttribute ( " table:default-cell-style-name " , currentDefaultCellStyleName ) ;
if ( row - > isHide ( ) ) // never true for the default row
xmlWriter . addAttribute ( " table:visibility " , " collapse " ) ;
int j = i + 1 ;
while ( compareRows ( i , j , maxCols ) & & j < = maxRows )
{
j + + ;
repeated + + ;
}
if ( repeated > 1 )
{
kdDebug ( ) < < " Sheet::saveOasisColRowCell: NON-empty row " < < i < < ' '
< < " repeated " < < repeated < < " times " < < endl ;
xmlWriter . addAttribute ( " table:number-rows-repeated " , repeated ) ;
}
saveOasisCells ( xmlWriter , mainStyles , i , maxCols , valStyle ) ;
// copy the index for the next row to process
i = j - 1 ; /*it's already incremented in the for loop*/
}
xmlWriter . endElement ( ) ;
}
}
void Sheet : : saveOasisCells ( KoXmlWriter & xmlWriter , KoGenStyles & mainStyles , int row , int maxCols , GenValidationStyles & valStyle )
{
int i = 1 ;
Cell * cell = cellAt ( i , row ) ;
Cell * nextCell = getNextCellRight ( i , row ) ;
// while
// the current cell is not a default one
// or
// we have a further cell in this row
while ( ! cell - > isDefault ( ) | | nextCell )
{
kdDebug ( ) < < " Sheet::saveOasisCells: "
< < " i: " < < i
< < " column: " < < ( cell - > isDefault ( ) ? 0 : cell - > column ( ) ) < < endl ;
int repeated = 1 ;
cell - > saveOasis ( xmlWriter , mainStyles , row , i , repeated , valStyle ) ;
i + = repeated ;
// stop if we reached the end column
if ( i > maxCols )
break ;
cell = cellAt ( i , row ) ;
nextCell = getNextCellRight ( i , row ) ;
}
}
bool Sheet : : loadXML ( const TQDomElement & sheet )
{
bool ok = false ;
if ( ! doc ( ) - > loadingInfo ( ) | | ! doc ( ) - > loadingInfo ( ) - > loadTemplate ( ) )
{
d - > name = sheet . attribute ( " name " ) ;
if ( d - > name . isEmpty ( ) )
{
doc ( ) - > setErrorMessage ( i18n ( " Invalid document. Sheet name is empty. " ) ) ;
return false ;
}
}
bool detectDirection = true ;
d - > layoutDirection = LeftToRight ;
TQString layoutDir = sheet . attribute ( " layoutDirection " ) ;
if ( ! layoutDir . isEmpty ( ) )
{
if ( layoutDir = = " rtl " )
{
detectDirection = false ;
d - > layoutDirection = RightToLeft ;
}
else if ( layoutDir = = " ltr " )
{
detectDirection = false ;
d - > layoutDirection = LeftToRight ;
}
else
kdDebug ( ) < < " Direction not implemented : " < < layoutDir < < endl ;
}
if ( detectDirection )
checkContentDirection ( d - > name ) ;
/* older versions of KSpread allowed all sorts of characters that
the parser won ' t actually understand . Replace these with ' _ '
Also , the initial character cannot be a space .
*/
if ( d - > name [ 0 ] = = ' ' )
{
d - > name . remove ( 0 , 1 ) ;
}
for ( unsigned int i = 0 ; i < d - > name . length ( ) ; i + + )
{
if ( ! ( d - > name [ i ] . isLetterOrNumber ( ) | |
d - > name [ i ] = = ' ' | | d - > name [ i ] = = ' . ' | |
d - > name [ i ] = = ' _ ' ) )
{
d - > name [ i ] = ' _ ' ;
}
}
/* make sure there are no name collisions with the altered name */
TQString testName ;
TQString baseName ;
int nameSuffix = 0 ;
testName = d - > name ;
baseName = d - > name ;
/* so we don't panic over finding ourself in the follwing test*/
d - > name = " " ;
while ( workbook ( ) - > findSheet ( testName ) ! = NULL )
{
nameSuffix + + ;
testName = baseName + ' _ ' + TQString : : number ( nameSuffix ) ;
}
d - > name = testName ;
kdDebug ( 36001 ) < < " Sheet::loadXML: table name= " < < d - > name < < endl ;
setName ( d - > name . utf8 ( ) ) ;
( dynamic_cast < SheetIface * > ( dcopObject ( ) ) ) - > sheetNameHasChanged ( ) ;
if ( sheet . hasAttribute ( " grid " ) )
{
d - > showGrid = ( int ) sheet . attribute ( " grid " ) . toInt ( & ok ) ;
// we just ignore 'ok' - if it didn't work, go on
}
if ( sheet . hasAttribute ( " printGrid " ) )
{
d - > print - > setPrintGrid ( ( bool ) sheet . attribute ( " printGrid " ) . toInt ( & ok ) ) ;
// we just ignore 'ok' - if it didn't work, go on
}
if ( sheet . hasAttribute ( " printCommentIndicator " ) )
{
d - > print - > setPrintCommentIndicator ( ( bool ) sheet . attribute ( " printCommentIndicator " ) . toInt ( & ok ) ) ;
// we just ignore 'ok' - if it didn't work, go on
}
if ( sheet . hasAttribute ( " printFormulaIndicator " ) )
{
d - > print - > setPrintFormulaIndicator ( ( bool ) sheet . attribute ( " printFormulaIndicator " ) . toInt ( & ok ) ) ;
// we just ignore 'ok' - if it didn't work, go on
}
if ( sheet . hasAttribute ( " hide " ) )
{
d - > hide = ( bool ) sheet . attribute ( " hide " ) . toInt ( & ok ) ;
// we just ignore 'ok' - if it didn't work, go on
}
if ( sheet . hasAttribute ( " showFormula " ) )
{
d - > showFormula = ( bool ) sheet . attribute ( " showFormula " ) . toInt ( & ok ) ;
// we just ignore 'ok' - if it didn't work, go on
}
//Compatibility with KSpread 1.1.x
if ( sheet . hasAttribute ( " formular " ) )
{
d - > showFormula = ( bool ) sheet . attribute ( " formular " ) . toInt ( & ok ) ;
// we just ignore 'ok' - if it didn't work, go on
}
if ( sheet . hasAttribute ( " showFormulaIndicator " ) )
{
d - > showFormulaIndicator = ( bool ) sheet . attribute ( " showFormulaIndicator " ) . toInt ( & ok ) ;
// we just ignore 'ok' - if it didn't work, go on
}
if ( sheet . hasAttribute ( " showCommentIndicator " ) )
{
d - > showCommentIndicator = ( bool ) sheet . attribute ( " showCommentIndicator " ) . toInt ( & ok ) ;
// we just ignore 'ok' - if it didn't work, go on
}
if ( sheet . hasAttribute ( " borders " ) )
{
d - > showPageBorders = ( bool ) sheet . attribute ( " borders " ) . toInt ( & ok ) ;
// we just ignore 'ok' - if it didn't work, go on
}
if ( sheet . hasAttribute ( " lcmode " ) )
{
d - > lcMode = ( bool ) sheet . attribute ( " lcmode " ) . toInt ( & ok ) ;
// we just ignore 'ok' - if it didn't work, go on
}
if ( sheet . hasAttribute ( " autoCalc " ) )
{
d - > autoCalc = ( bool ) sheet . attribute ( " autoCalc " ) . toInt ( & ok ) ;
// we just ignore 'ok' - if it didn't work, go on
}
if ( sheet . hasAttribute ( " columnnumber " ) )
{
d - > showColumnNumber = ( bool ) sheet . attribute ( " columnnumber " ) . toInt ( & ok ) ;
// we just ignore 'ok' - if it didn't work, go on
}
if ( sheet . hasAttribute ( " hidezero " ) )
{
d - > hideZero = ( bool ) sheet . attribute ( " hidezero " ) . toInt ( & ok ) ;
// we just ignore 'ok' - if it didn't work, go on
}
if ( sheet . hasAttribute ( " firstletterupper " ) )
{
d - > firstLetterUpper = ( bool ) sheet . attribute ( " firstletterupper " ) . toInt ( & ok ) ;
// we just ignore 'ok' - if it didn't work, go on
}
// Load the paper layout
TQDomElement paper = sheet . namedItem ( " paper " ) . toElement ( ) ;
if ( ! paper . isNull ( ) )
{
TQString format = paper . attribute ( " format " ) ;
TQString orientation = paper . attribute ( " orientation " ) ;
// <borders>
TQDomElement borders = paper . namedItem ( " borders " ) . toElement ( ) ;
if ( ! borders . isNull ( ) )
{
float left = borders . attribute ( " left " ) . toFloat ( ) ;
float right = borders . attribute ( " right " ) . toFloat ( ) ;
float top = borders . attribute ( " top " ) . toFloat ( ) ;
float bottom = borders . attribute ( " bottom " ) . toFloat ( ) ;
d - > print - > setPaperLayout ( left , top , right , bottom , format , orientation ) ;
}
TQString hleft , hright , hcenter ;
TQString fleft , fright , fcenter ;
// <head>
TQDomElement head = paper . namedItem ( " head " ) . toElement ( ) ;
if ( ! head . isNull ( ) )
{
TQDomElement left = head . namedItem ( " left " ) . toElement ( ) ;
if ( ! left . isNull ( ) )
hleft = left . text ( ) ;
TQDomElement center = head . namedItem ( " center " ) . toElement ( ) ;
if ( ! center . isNull ( ) )
hcenter = center . text ( ) ;
TQDomElement right = head . namedItem ( " right " ) . toElement ( ) ;
if ( ! right . isNull ( ) )
hright = right . text ( ) ;
}
// <foot>
TQDomElement foot = paper . namedItem ( " foot " ) . toElement ( ) ;
if ( ! foot . isNull ( ) )
{
TQDomElement left = foot . namedItem ( " left " ) . toElement ( ) ;
if ( ! left . isNull ( ) )
fleft = left . text ( ) ;
TQDomElement center = foot . namedItem ( " center " ) . toElement ( ) ;
if ( ! center . isNull ( ) )
fcenter = center . text ( ) ;
TQDomElement right = foot . namedItem ( " right " ) . toElement ( ) ;
if ( ! right . isNull ( ) )
fright = right . text ( ) ;
}
d - > print - > setHeadFootLine ( hleft , hcenter , hright , fleft , fcenter , fright ) ;
}
// load print range
TQDomElement printrange = sheet . namedItem ( " printrange-rect " ) . toElement ( ) ;
if ( ! printrange . isNull ( ) )
{
int left = printrange . attribute ( " left-rect " ) . toInt ( ) ;
int right = printrange . attribute ( " right-rect " ) . toInt ( ) ;
int bottom = printrange . attribute ( " bottom-rect " ) . toInt ( ) ;
int top = printrange . attribute ( " top-rect " ) . toInt ( ) ;
if ( left = = 0 ) //whole row(s) selected
{
left = 1 ;
right = KS_colMax ;
}
if ( top = = 0 ) //whole column(s) selected
{
top = 1 ;
bottom = KS_rowMax ;
}
d - > print - > setPrintRange ( TQRect ( TQPoint ( left , top ) , TQPoint ( right , bottom ) ) ) ;
}
// load print zoom
if ( sheet . hasAttribute ( " printZoom " ) )
{
double zoom = sheet . attribute ( " printZoom " ) . toDouble ( & ok ) ;
if ( ok )
{
d - > print - > setZoom ( zoom ) ;
}
}
// load page limits
if ( sheet . hasAttribute ( " printPageLimitX " ) )
{
int pageLimit = sheet . attribute ( " printPageLimitX " ) . toInt ( & ok ) ;
if ( ok )
{
d - > print - > setPageLimitX ( pageLimit ) ;
}
}
// load page limits
if ( sheet . hasAttribute ( " printPageLimitY " ) )
{
int pageLimit = sheet . attribute ( " printPageLimitY " ) . toInt ( & ok ) ;
if ( ok )
{
d - > print - > setPageLimitY ( pageLimit ) ;
}
}
// Load the cells
TQDomNode n = sheet . firstChild ( ) ;
while ( ! n . isNull ( ) )
{
TQDomElement e = n . toElement ( ) ;
if ( ! e . isNull ( ) )
{
TQString tagName = e . tagName ( ) ;
if ( tagName = = " cell " )
{
Cell * cell = new Cell ( this , 0 , 0 ) ;
if ( cell - > load ( e , 0 , 0 ) )
insertCell ( cell ) ;
else
delete cell ; // Allow error handling: just skip invalid cells
}
else if ( tagName = = " row " )
{
RowFormat * rl = new RowFormat ( this , 0 ) ;
if ( rl - > load ( e ) )
insertRowFormat ( rl ) ;
else
delete rl ;
}
else if ( tagName = = " column " )
{
ColumnFormat * cl = new ColumnFormat ( this , 0 ) ;
if ( cl - > load ( e ) )
insertColumnFormat ( cl ) ;
else
delete cl ;
}
else if ( tagName = = " object " )
{
EmbeddedKOfficeObject * ch = new EmbeddedKOfficeObject ( doc ( ) , this ) ;
if ( ch - > load ( e ) )
insertObject ( ch ) ;
else
{
ch - > embeddedObject ( ) - > setDeleted ( true ) ;
delete ch ;
}
}
else if ( tagName = = " chart " )
{
EmbeddedChart * ch = new EmbeddedChart ( doc ( ) , this ) ;
if ( ch - > load ( e ) )
insertObject ( ch ) ;
else
{
ch - > embeddedObject ( ) - > setDeleted ( true ) ;
delete ch ;
}
}
}
n = n . nextSibling ( ) ;
}
// load print repeat columns
TQDomElement printrepeatcolumns = sheet . namedItem ( " printrepeatcolumns " ) . toElement ( ) ;
if ( ! printrepeatcolumns . isNull ( ) )
{
int left = printrepeatcolumns . attribute ( " left " ) . toInt ( ) ;
int right = printrepeatcolumns . attribute ( " right " ) . toInt ( ) ;
d - > print - > setPrintRepeatColumns ( qMakePair ( left , right ) ) ;
}
// load print repeat rows
TQDomElement printrepeatrows = sheet . namedItem ( " printrepeatrows " ) . toElement ( ) ;
if ( ! printrepeatrows . isNull ( ) )
{
int top = printrepeatrows . attribute ( " top " ) . toInt ( ) ;
int bottom = printrepeatrows . attribute ( " bottom " ) . toInt ( ) ;
d - > print - > setPrintRepeatRows ( qMakePair ( top , bottom ) ) ;
}
if ( ! sheet . hasAttribute ( " borders1.2 " ) )
{
convertObscuringBorders ( ) ;
}
if ( sheet . hasAttribute ( " protected " ) )
{
TQString passwd = sheet . attribute ( " protected " ) ;
if ( passwd . length ( ) > 0 )
{
TQCString str ( passwd . latin1 ( ) ) ;
d - > password = KCodecs : : base64Decode ( str ) ;
}
else
d - > password = TQCString ( " " ) ;
}
return true ;
}
bool Sheet : : loadChildren ( KoStore * _store )
{
TQPtrListIterator < EmbeddedObject > it ( doc ( ) - > embeddedObjects ( ) ) ;
for ( ; it . current ( ) ; + + it )
{
if ( it . current ( ) - > sheet ( ) = = this & & ( it . current ( ) - > getType ( ) = = OBJECT_KOFFICE_PART | | it . current ( ) - > getType ( ) = = OBJECT_CHART ) )
{
kdDebug ( ) < < " KSpreadSheet::loadChildren " < < endl ;
if ( ! dynamic_cast < EmbeddedKOfficeObject * > ( it . current ( ) ) - > embeddedObject ( ) - > loadDocument ( _store ) )
return false ;
}
}
return true ;
}
void Sheet : : setShowPageBorders ( bool b )
{
if ( b = = d - > showPageBorders )
return ;
d - > showPageBorders = b ;
emit sig_updateView ( this ) ;
}
void Sheet : : addCellBinding ( CellBinding * _bind )
{
d - > cellBindings . append ( _bind ) ;
doc ( ) - > setModified ( true ) ;
}
void Sheet : : removeCellBinding ( CellBinding * _bind )
{
d - > cellBindings . removeRef ( _bind ) ;
doc ( ) - > setModified ( true ) ;
}
Sheet * Sheet : : findSheet ( const TQString & _name )
{
if ( ! workbook ( ) )
return 0L ;
return workbook ( ) - > findSheet ( _name ) ;
}
// ###### Torben: Use this one instead of d->cells.insert()
void Sheet : : insertCell ( Cell * _cell )
{
d - > cells . insert ( _cell , _cell - > column ( ) , _cell - > row ( ) ) ;
// Adjust the scrollbar range, if the max. dimension has changed.
if ( d - > scrollBarUpdates )
{
checkRangeHBorder ( _cell - > column ( ) ) ;
checkRangeVBorder ( _cell - > row ( ) ) ;
}
}
void Sheet : : insertColumnFormat ( ColumnFormat * l )
{
d - > columns . insertElement ( l , l - > column ( ) ) ;
}
void Sheet : : insertRowFormat ( RowFormat * l )
{
d - > rows . insertElement ( l , l - > row ( ) ) ;
}
void Sheet : : update ( )
{
Cell * c = d - > cells . firstCell ( ) ;
for ( ; c ; c = c - > nextCell ( ) )
{
updateCell ( c , c - > column ( ) , c - > row ( ) ) ;
}
}
void Sheet : : updateCellArea ( const Region & cellArea )
{
if ( doc ( ) - > isLoading ( ) | | doc ( ) - > delayCalculation ( ) | | ( ! getAutoCalc ( ) ) )
return ;
setRegionPaintDirty ( cellArea ) ;
}
void Sheet : : updateCell ( Cell */ * cell */ , int _column , int _row )
{
TQRect cellArea ( TQPoint ( _column , _row ) , TQPoint ( _column , _row ) ) ;
updateCellArea ( cellArea ) ;
}
void Sheet : : emit_updateRow ( RowFormat * _format , int _row , bool repaint )
{
if ( doc ( ) - > isLoading ( ) )
return ;
Cell * c = d - > cells . firstCell ( ) ;
for ( ; c ; c = c - > nextCell ( ) )
if ( c - > row ( ) = = _row )
c - > setLayoutDirtyFlag ( true ) ;
if ( repaint )
{
//All the cells in this row, or below this row will need to be repainted
//So add that region of the sheet to the paint dirty list.
setRegionPaintDirty ( TQRect ( 0 , _row , KS_colMax , KS_rowMax ) ) ;
emit sig_updateVBorder ( this ) ;
emit sig_updateView ( this ) ;
}
emit sig_maxRow ( maxRow ( ) ) ;
_format - > clearDisplayDirtyFlag ( ) ;
}
void Sheet : : emit_updateColumn ( ColumnFormat * _format , int _column )
{
if ( doc ( ) - > isLoading ( ) )
return ;
Cell * c = d - > cells . firstCell ( ) ;
for ( ; c ; c = c - > nextCell ( ) )
if ( c - > column ( ) = = _column )
c - > setLayoutDirtyFlag ( true ) ;
//All the cells in this column or to the right of it will need to be repainted if the column
//has been resized or hidden, so add that region of the sheet to the paint dirty list.
setRegionPaintDirty ( TQRect ( _column , 0 , KS_colMax , KS_rowMax ) ) ;
emit sig_updateHBorder ( this ) ;
emit sig_updateView ( this ) ;
emit sig_maxColumn ( maxColumn ( ) ) ;
_format - > clearDisplayDirtyFlag ( ) ;
}
bool Sheet : : insertChart ( const KoRect & _rect , KoDocumentEntry & _e , const TQRect & _data )
{
kdDebug ( 36001 ) < < " Creating document " < < endl ;
KoDocument * dd = _e . createDoc ( ) ;
kdDebug ( 36001 ) < < " Created " < < endl ;
if ( ! dd )
// Error message is already displayed, so just return
return false ;
kdDebug ( 36001 ) < < " NOW FETCHING INTERFACE " < < endl ;
if ( ! dd - > initDoc ( KoDocument : : InitDocEmbedded ) )
return false ;
EmbeddedChart * ch = new EmbeddedChart ( doc ( ) , this , dd , _rect ) ;
ch - > setDataArea ( _data ) ;
ch - > update ( ) ;
ch - > chart ( ) - > setCanChangeValue ( false ) ;
KoChart : : WizardExtension * wiz = ch - > chart ( ) - > wizardExtension ( ) ;
Range dataRange ;
dataRange . setRange ( _data ) ;
dataRange . setSheet ( this ) ;
TQString rangeString = dataRange . toString ( ) ;
if ( wiz )
wiz - > show ( rangeString ) ;
insertObject ( ch ) ;
return true ;
}
bool Sheet : : insertChild ( const KoRect & _rect , KoDocumentEntry & _e )
{
KoDocument * d = _e . createDoc ( doc ( ) ) ;
if ( ! d )
{
kdDebug ( ) < < " Error inserting child! " < < endl ;
return false ;
}
if ( ! d - > initDoc ( KoDocument : : InitDocEmbedded ) )
return false ;
EmbeddedKOfficeObject * ch = new EmbeddedKOfficeObject ( doc ( ) , this , d , _rect ) ;
insertObject ( ch ) ;
return true ;
}
bool Sheet : : insertPicture ( const KoPoint & point , const KURL & url )
{
KoPicture picture = doc ( ) - > pictureCollection ( ) - > downloadPicture ( url , 0 ) ;
return insertPicture ( point , picture ) ;
}
bool Sheet : : insertPicture ( const KoPoint & point , KoPicture & picture )
{
if ( picture . isNull ( ) )
return false ;
KoPictureKey key = picture . getKey ( ) ;
KoRect destinationRect ;
destinationRect . setLeft ( point . x ( ) ) ;
destinationRect . setTop ( point . y ( ) ) ;
//Generate correct pixel size - this is a bit tricky.
//This ensures that when we load the image it appears
//the same size on screen on a 100%-zoom KSpread spreadsheet as it would in an
//image viewer or another spreadsheet program such as OpenOffice.
//
//KoUnit assumes 72DPI, whereas the user's display resolution will probably be
//different (eg. 96*96). So, we convert the actual size in pixels into inches
//using the screen display resolution and then use KoUnit to convert back into
//the appropriate pixel size KSpread.
KoSize destinationSize ;
double inchWidth = ( double ) picture . getOriginalSize ( ) . width ( ) / KoGlobal : : dpiX ( ) ;
double inchHeight = ( double ) picture . getOriginalSize ( ) . height ( ) / KoGlobal : : dpiY ( ) ;
destinationSize . setWidth ( KoUnit : : fromUserValue ( inchWidth , KoUnit : : U_INCH ) ) ;
destinationSize . setHeight ( KoUnit : : fromUserValue ( inchHeight , KoUnit : : U_INCH ) ) ;
destinationRect . setSize ( destinationSize ) ;
EmbeddedPictureObject * object = new EmbeddedPictureObject ( this , destinationRect , doc ( ) - > pictureCollection ( ) , key ) ;
// ch->setPicture(key);
insertObject ( object ) ;
return true ;
}
bool Sheet : : insertPicture ( const KoPoint & point , const TQPixmap & pixmap )
{
TQByteArray data ;
TQBuffer buffer ( data ) ;
buffer . open ( IO_ReadWrite ) ;
pixmap . save ( & buffer , " PNG " ) ;
//Reset the buffer so that KoPicture reads the whole file from the beginning
//(at the moment the read/write position is at the end)
buffer . reset ( ) ;
KoPicture picture ;
picture . load ( & buffer , " PNG " ) ;
doc ( ) - > pictureCollection ( ) - > insertPicture ( picture ) ;
return insertPicture ( point , picture ) ;
}
void Sheet : : insertObject ( EmbeddedObject * _obj )
{
doc ( ) - > insertObject ( _obj ) ;
emit sig_updateView ( _obj ) ;
}
void Sheet : : changeChildGeometry ( EmbeddedKOfficeObject * _child , const KoRect & _rect )
{
_child - > setGeometry ( _rect ) ;
emit sig_updateChildGeometry ( _child ) ;
}
bool Sheet : : saveChildren ( KoStore * _store , const TQString & _path )
{
int i = 0 ;
TQPtrListIterator < EmbeddedObject > it ( doc ( ) - > embeddedObjects ( ) ) ;
for ( ; it . current ( ) ; + + it )
{
if ( it . current ( ) - > sheet ( ) = = this & & ( it . current ( ) - > getType ( ) = = OBJECT_KOFFICE_PART | | it . current ( ) - > getType ( ) = = OBJECT_CHART ) )
{
TQString path = TQString ( " %1/%2 " ) . arg ( _path ) . arg ( i + + ) ;
if ( ! dynamic_cast < EmbeddedKOfficeObject * > ( it . current ( ) ) - > embeddedObject ( ) - > document ( ) - > saveToStore ( _store , path ) )
return false ;
}
}
return true ;
}
bool Sheet : : saveOasisObjects ( KoStore */ * store */ , KoXmlWriter & xmlWriter , KoGenStyles & mainStyles , int & indexObj , int & partIndexObj )
{
//int i = 0;
if ( doc ( ) - > embeddedObjects ( ) . isEmpty ( ) )
return true ;
bool objectFound = false ; // object on this sheet?
EmbeddedObject : : KSpreadOasisSaveContext sc ( xmlWriter , mainStyles , indexObj , partIndexObj ) ;
TQPtrListIterator < EmbeddedObject > it ( doc ( ) - > embeddedObjects ( ) ) ;
for ( ; it . current ( ) ; + + it )
{
if ( it . current ( ) - > sheet ( ) = = this & & ( doc ( ) - > savingWholeDocument ( ) | | it . current ( ) - > isSelected ( ) ) )
{
if ( ! objectFound )
{
xmlWriter . startElement ( " table:shapes " ) ;
objectFound = true ;
}
if ( ! it . current ( ) - > saveOasisObject ( sc ) )
{
xmlWriter . endElement ( ) ;
return false ;
}
+ + indexObj ;
}
}
if ( objectFound )
{
xmlWriter . endElement ( ) ;
}
return true ;
}
Sheet : : ~ Sheet ( )
{
//Disable automatic recalculation of dependancies on this sheet to prevent crashes
//in certain situations:
//
//For example, suppose a cell in SheetB depends upon a cell in SheetA. If the cell in SheetB is emptied
//after SheetA has already been deleted, the program would try to remove dependancies from the cell in SheetA
//causing a crash.
setAutoCalc ( false ) ;
s_mapSheets - > remove ( d - > id ) ;
//when you remove all sheet (close file)
//you must reinit s_id otherwise there is not
//the good name between map and sheet
if ( s_mapSheets - > count ( ) = = 0 )
s_id = 0L ;
Cell * c = d - > cells . firstCell ( ) ;
for ( ; c ; c = c - > nextCell ( ) )
c - > sheetDies ( ) ;
d - > cells . clear ( ) ; // cells destructor needs sheet to still exist
d - > painter - > end ( ) ;
delete d - > painter ;
delete d - > widget ;
delete d - > defaultFormat ;
delete d - > defaultCell ;
delete d - > defaultRowFormat ;
delete d - > defaultColumnFormat ;
delete d - > print ;
delete d - > dcop ;
delete d - > dependencies ;
delete d ;
//this is for debugging a crash
d = 0 ;
}
void Sheet : : checkRangeHBorder ( int _column )
{
if ( d - > scrollBarUpdates & & _column > d - > maxColumn )
{
d - > maxColumn = _column ;
emit sig_maxColumn ( _column ) ;
}
}
void Sheet : : checkRangeVBorder ( int _row )
{
if ( d - > scrollBarUpdates & & _row > d - > maxRow )
{
d - > maxRow = _row ;
emit sig_maxRow ( _row ) ;
}
}
void Sheet : : enableScrollBarUpdates ( bool _enable )
{
d - > scrollBarUpdates = _enable ;
}
DCOPObject * Sheet : : dcopObject ( )
{
if ( ! d - > dcop )
d - > dcop = new SheetIface ( this ) ;
return d - > dcop ;
}
void Sheet : : hideSheet ( bool _hide )
{
setHidden ( _hide ) ;
if ( _hide )
emit sig_SheetHidden ( this ) ;
else
emit sig_SheetShown ( this ) ;
}
void Sheet : : removeSheet ( )
{
emit sig_SheetRemoved ( this ) ;
}
bool Sheet : : setSheetName ( const TQString & name , bool init , bool /*makeUndo*/ )
{
if ( workbook ( ) - > findSheet ( name ) )
return false ;
if ( isProtected ( ) )
return false ;
if ( d - > name = = name )
return true ;
TQString old_name = d - > name ;
d - > name = name ;
if ( init )
return true ;
TQPtrListIterator < Sheet > it ( workbook ( ) - > sheetList ( ) ) ;
for ( ; it . current ( ) ; + + it )
it . current ( ) - > changeCellTabName ( old_name , name ) ;
doc ( ) - > changeAreaSheetName ( old_name , name ) ;
emit sig_nameChanged ( this , old_name ) ;
setName ( name . utf8 ( ) ) ;
( dynamic_cast < SheetIface * > ( dcopObject ( ) ) ) - > sheetNameHasChanged ( ) ;
return true ;
}
void Sheet : : updateLocale ( )
{
doc ( ) - > emitBeginOperation ( true ) ;
setRegionPaintDirty ( TQRect ( TQPoint ( 1 , 1 ) , TQPoint ( KS_colMax , KS_rowMax ) ) ) ;
Cell * c = d - > cells . firstCell ( ) ;
for ( ; c ; c = c - > nextCell ( ) )
{
TQString _text = c - > text ( ) ;
c - > setCellText ( _text ) ;
}
emit sig_updateView ( this ) ;
// doc()->emitEndOperation();
}
Cell * Sheet : : getFirstCellColumn ( int col ) const
{ return d - > cells . getFirstCellColumn ( col ) ; }
Cell * Sheet : : getLastCellColumn ( int col ) const
{ return d - > cells . getLastCellColumn ( col ) ; }
Cell * Sheet : : getFirstCellRow ( int row ) const
{ return d - > cells . getFirstCellRow ( row ) ; }
Cell * Sheet : : getLastCellRow ( int row ) const
{ return d - > cells . getLastCellRow ( row ) ; }
Cell * Sheet : : getNextCellUp ( int col , int row ) const
{ return d - > cells . getNextCellUp ( col , row ) ; }
Cell * Sheet : : getNextCellDown ( int col , int row ) const
{ return d - > cells . getNextCellDown ( col , row ) ; }
Cell * Sheet : : getNextCellLeft ( int col , int row ) const
{ return d - > cells . getNextCellLeft ( col , row ) ; }
Cell * Sheet : : getNextCellRight ( int col , int row ) const
{ return d - > cells . getNextCellRight ( col , row ) ; }
void Sheet : : convertObscuringBorders ( )
{
/* a word of explanation here:
beginning with KSpread 1.2 ( actually , cvs of Mar 28 , 2002 ) , border information
is stored differently . Previously , for a cell obscuring a region , the entire
region ' s border ' s data would be stored in the obscuring cell . This caused
some data loss in certain situations . After that date , each cell stores
its own border data , and prints it even if it is an obscured cell ( as long
as that border isn ' t across an obscuring border ) .
Anyway , this function is used when loading a file that was stored with the
old way of borders . All new files have the sheet attribute " borders1.2 " so
if that isn ' t in the file , all the border data will be converted here .
It ' s a bit of a hack but I can ' t think of a better way and it ' s not * that *
bad of a hack . : - )
*/
Cell * c = d - > cells . firstCell ( ) ;
TQPen topPen , bottomPen , leftPen , rightPen ;
for ( ; c ; c = c - > nextCell ( ) )
{
if ( c - > extraXCells ( ) > 0 | | c - > extraYCells ( ) > 0 )
{
topPen = c - > topBorderPen ( c - > column ( ) , c - > row ( ) ) ;
leftPen = c - > leftBorderPen ( c - > column ( ) , c - > row ( ) ) ;
rightPen = c - > rightBorderPen ( c - > column ( ) , c - > row ( ) ) ;
bottomPen = c - > bottomBorderPen ( c - > column ( ) , c - > row ( ) ) ;
c - > format ( ) - > setTopBorderStyle ( TQt : : NoPen ) ;
c - > format ( ) - > setLeftBorderStyle ( TQt : : NoPen ) ;
c - > format ( ) - > setRightBorderStyle ( TQt : : NoPen ) ;
c - > format ( ) - > setBottomBorderStyle ( TQt : : NoPen ) ;
for ( int x = c - > column ( ) ; x < c - > column ( ) + c - > extraXCells ( ) ; x + + )
{
nonDefaultCell ( x , c - > row ( ) ) - > setTopBorderPen ( topPen ) ;
nonDefaultCell ( x , c - > row ( ) + c - > extraYCells ( ) ) - >
setBottomBorderPen ( bottomPen ) ;
}
for ( int y = c - > row ( ) ; y < c - > row ( ) + c - > extraYCells ( ) ; y + + )
{
nonDefaultCell ( c - > column ( ) , y ) - > setLeftBorderPen ( leftPen ) ;
nonDefaultCell ( c - > column ( ) + c - > extraXCells ( ) , y ) - >
setRightBorderPen ( rightPen ) ;
}
}
}
}
/**********************
* Printout Functions *
* * * * * * * * * * * * * * * * * * * * * */
// TODO Stefan: these belong to View, even better Canvas
void Sheet : : setRegionPaintDirty ( Region const & region )
{
DilationManipulator manipulator ;
manipulator . setSheet ( this ) ;
manipulator . add ( region ) ;
manipulator . execute ( ) ;
// don't put it in the undo list! ;-)
d - > paintDirtyList . add ( manipulator ) ;
//kdDebug() << "setRegionPaintDirty "<< static_cast<Region*>(&manipulator)->name(this) << endl;
}
void Sheet : : setRegionPaintDirty ( TQRect const & range )
{
DilationManipulator manipulator ;
manipulator . setSheet ( this ) ;
manipulator . add ( range ) ;
manipulator . execute ( ) ;
// don't put it in the undo list! ;-)
d - > paintDirtyList . add ( manipulator ) ;
//kdDebug() << "setRegionPaintDirty "<< static_cast<Region*>(&manipulator)->name(this) << endl;
}
void Sheet : : clearPaintDirtyData ( )
{
d - > paintDirtyList . clear ( ) ;
}
bool Sheet : : cellIsPaintDirty ( TQPoint const & cell ) const
{
return d - > paintDirtyList . contains ( cell ) ;
}
# ifndef NDEBUG
void Sheet : : printDebug ( )
{
int iMaxColumn = maxColumn ( ) ;
int iMaxRow = maxRow ( ) ;
kdDebug ( 36001 ) < < " Cell | Content | DataT | Text " < < endl ;
Cell * cell ;
for ( int currentrow = 1 ; currentrow < iMaxRow ; + + currentrow )
{
for ( int currentcolumn = 1 ; currentcolumn < iMaxColumn ; currentcolumn + + )
{
cell = cellAt ( currentcolumn , currentrow ) ;
if ( ! cell - > isDefault ( ) & & ! cell - > isEmpty ( ) )
{
TQString cellDescr = Cell : : name ( currentcolumn , currentrow ) ;
cellDescr = cellDescr . rightJustify ( 4 , ' ' ) ;
//TQString cellDescr = "Cell ";
//cellDescr += TQString::number(currentrow).rightJustify(3,'0') + ',';
//cellDescr += TQString::number(currentcolumn).rightJustify(3,'0') + ' ';
cellDescr + = " | " ;
cellDescr + = cell - > value ( ) . type ( ) ;
cellDescr + = " | " ;
cellDescr + = cell - > text ( ) ;
if ( cell - > isFormula ( ) )
cellDescr + = TQString ( " [result: %1] " ) . arg ( cell - > value ( ) . asString ( ) ) ;
kdDebug ( 36001 ) < < cellDescr < < endl ;
}
}
}
}
# endif
} // namespace KSpread