You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
547 lines
17 KiB
547 lines
17 KiB
/* This file is part of the KDE project
|
|
Copyright (C) 2003 Norbert Andres <nandres@web.de>
|
|
|
|
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 <opencalcstyleexport.h>
|
|
|
|
#include <KoGlobal.h>
|
|
|
|
#include <kspread_cell.h>
|
|
#include <kspread_doc.h>
|
|
#include <kspread_format.h>
|
|
#include <kspread_sheet.h>
|
|
#include <kspread_style.h>
|
|
#include <kspread_style_manager.h>
|
|
|
|
#include <tqdom.h>
|
|
|
|
using namespace KSpread;
|
|
|
|
OpenCalcStyles::OpenCalcStyles()
|
|
{
|
|
m_cellStyles.setAutoDelete( true );
|
|
m_columnStyles.setAutoDelete( true );
|
|
m_numberStyles.setAutoDelete( true );
|
|
m_rowStyles.setAutoDelete( true );
|
|
m_sheetStyles.setAutoDelete( true );
|
|
|
|
m_fontList.setAutoDelete( true );
|
|
}
|
|
|
|
OpenCalcStyles::~OpenCalcStyles()
|
|
{
|
|
}
|
|
|
|
void OpenCalcStyles::writeStyles( TQDomDocument & doc, TQDomElement & autoStyles )
|
|
{
|
|
addColumnStyles( doc, autoStyles );
|
|
addRowStyles( doc, autoStyles );
|
|
addSheetStyles( doc, autoStyles );
|
|
addNumberStyles( doc, autoStyles );
|
|
addCellStyles( doc, autoStyles );
|
|
}
|
|
|
|
void OpenCalcStyles::writeFontDecl( TQDomDocument & doc, TQDomElement & fontDecls )
|
|
{
|
|
TQFont * f = m_fontList.first();
|
|
while ( f )
|
|
{
|
|
TQDomElement fontDecl = doc.createElement( "style:font-decl" );
|
|
|
|
fontDecl.setAttribute( "style:name", f->family() );
|
|
fontDecl.setAttribute( "fo:font-family", f->family() );
|
|
fontDecl.setAttribute( "style:font-pitch", ( f->fixedPitch() ? "fixed" : "variable" ) );
|
|
|
|
// missing:
|
|
// style:font-charset="x-symbol" style:font-family-generic="swiss"
|
|
// style:font-style-name= "Bold/Standard/Regular"
|
|
|
|
fontDecls.appendChild( fontDecl );
|
|
|
|
f = m_fontList.next();
|
|
}
|
|
}
|
|
|
|
void OpenCalcStyles::addFont( TQFont const & font, bool def )
|
|
{
|
|
if ( def )
|
|
m_defaultFont = font;
|
|
|
|
TQFont * f = m_fontList.first();
|
|
while ( f )
|
|
{
|
|
if ( f->family() == font.family() )
|
|
return;
|
|
|
|
f = m_fontList.next();
|
|
}
|
|
|
|
f = new TQFont( font );
|
|
m_fontList.append( f );
|
|
}
|
|
|
|
TQString OpenCalcStyles::cellStyle( CellStyle const & cs )
|
|
{
|
|
CellStyle * t = m_cellStyles.first();
|
|
while ( t )
|
|
{
|
|
if ( CellStyle::isEqual( t, cs ) )
|
|
return t->name;
|
|
|
|
t = m_cellStyles.next();
|
|
}
|
|
|
|
t = new CellStyle();
|
|
t->copyData( cs );
|
|
|
|
m_cellStyles.append( t );
|
|
|
|
t->name = TQString( "ce%1" ).tqarg( m_cellStyles.count() );
|
|
|
|
return t->name;
|
|
}
|
|
|
|
TQString OpenCalcStyles::columnStyle( ColumnStyle const & cs )
|
|
{
|
|
ColumnStyle * t = m_columnStyles.first();
|
|
while ( t )
|
|
{
|
|
if ( ColumnStyle::isEqual( t, cs ) )
|
|
return t->name;
|
|
|
|
t = m_columnStyles.next();
|
|
}
|
|
|
|
t = new ColumnStyle();
|
|
t->copyData( cs );
|
|
|
|
m_columnStyles.append( t );
|
|
|
|
t->name = TQString( "co%1" ).tqarg( m_columnStyles.count() );
|
|
|
|
return t->name;
|
|
}
|
|
|
|
TQString OpenCalcStyles::numberStyle( NumberStyle const & )
|
|
{
|
|
return "";
|
|
}
|
|
|
|
TQString OpenCalcStyles::rowStyle( RowStyle const & rs )
|
|
{
|
|
RowStyle * t = m_rowStyles.first();
|
|
while ( t )
|
|
{
|
|
if ( RowStyle::isEqual( t, rs ) )
|
|
return t->name;
|
|
|
|
t = m_rowStyles.next();
|
|
}
|
|
|
|
t = new RowStyle();
|
|
t->copyData( rs );
|
|
|
|
m_rowStyles.append( t );
|
|
|
|
t->name = TQString( "ro%1" ).tqarg( m_rowStyles.count() );
|
|
|
|
return t->name;
|
|
}
|
|
|
|
TQString OpenCalcStyles::sheetStyle( SheetStyle const & ts )
|
|
{
|
|
SheetStyle * t = m_sheetStyles.first();
|
|
while ( t )
|
|
{
|
|
if ( SheetStyle::isEqual( t, ts ) )
|
|
return t->name;
|
|
|
|
t = m_sheetStyles.next();
|
|
}
|
|
|
|
t = new SheetStyle();
|
|
t->copyData( ts );
|
|
|
|
m_sheetStyles.append( t );
|
|
|
|
t->name = TQString( "ta%1" ).tqarg( m_sheetStyles.count() );
|
|
|
|
return t->name;
|
|
}
|
|
|
|
TQString convertPenToString( TQPen const & pen )
|
|
{
|
|
TQString s( TQString( "%1cm solid " ).tqarg( pen.width() * 0.035 ) );
|
|
s += pen.color().name();
|
|
|
|
return s;
|
|
}
|
|
|
|
void OpenCalcStyles::addCellStyles( TQDomDocument & doc, TQDomElement & autoStyles )
|
|
{
|
|
CellStyle * t = m_cellStyles.first();
|
|
while ( t )
|
|
{
|
|
TQDomElement ts = doc.createElement( "style:style" );
|
|
ts.setAttribute( "style:name", t->name );
|
|
ts.setAttribute( "style:family", "table-cell" );
|
|
ts.setAttribute( "style:tqparent-style-name", "Default" );
|
|
if ( t->numberStyle.length() > 0 )
|
|
ts.setAttribute( "style:data-style-name", t->numberStyle );
|
|
|
|
TQDomElement prop = doc.createElement( "style:properties" );
|
|
|
|
if ( t->font.family() != m_defaultFont.family() )
|
|
prop.setAttribute( "style:font-name", t->font.family() );
|
|
|
|
if ( t->font.bold() != m_defaultFont.bold() )
|
|
prop.setAttribute( "fo:font-weight", ( t->font.bold() ? "bold" : "light" ) );
|
|
|
|
prop.setAttribute( "fo:font-size", TQString( "%1pt" ).tqarg( t->font.pointSize() ) );
|
|
|
|
if ( t->font.underline() != m_defaultFont.underline() )
|
|
{
|
|
prop.setAttribute( "style:text-underline", ( t->font.underline() ? "single" : "none" ) );
|
|
if ( t->font.underline() )
|
|
prop.setAttribute( "style:text-underline-color", "font-color" );
|
|
}
|
|
|
|
if ( t->font.italic() != m_defaultFont.italic() )
|
|
prop.setAttribute( "fo:font-style", ( t->font.italic() ? "italic" : "none" ) );
|
|
|
|
if ( t->font.strikeOut() != m_defaultFont.strikeOut() )
|
|
prop.setAttribute( "style:text-crossing-out", ( t->font.strikeOut() ? "single-line" : "none" ) );
|
|
|
|
if ( t->color.name() != "#000000" )
|
|
prop.setAttribute( "fo:color", t->color.name() );
|
|
|
|
if ( t->bgColor.name() != "#ffffff" )
|
|
prop.setAttribute( "fo:background-color", t->bgColor.name() );
|
|
|
|
if ( t->alignX != Format::Undefined )
|
|
{
|
|
TQString value;
|
|
if ( t->alignX == Format::Center )
|
|
value = "center";
|
|
else if ( t->alignX == Format::Right )
|
|
value = "end";
|
|
else if ( t->alignX == Format::Left )
|
|
value = "start";
|
|
prop.setAttribute( "fo:text-align", value );
|
|
}
|
|
|
|
if ( t->alignY != Format::Bottom ) // default in OpenCalc
|
|
prop.setAttribute( "fo:vertical-align", ( t->alignY == Format::Middle ? "middle" : "top" ) );
|
|
|
|
if ( t->indent > 0.0 )
|
|
{
|
|
prop.setAttribute( "fo:margin-left", TQString( "%1pt" ).tqarg( t->indent ) );
|
|
if ( t->alignX == Format::Undefined )
|
|
prop.setAttribute( "fo:text-align", "start" );
|
|
}
|
|
|
|
if ( t->wrap )
|
|
prop.setAttribute( "fo:wrap-option", "wrap" );
|
|
|
|
if ( t->vertical )
|
|
{
|
|
prop.setAttribute( "fo:direction", "ttb" );
|
|
prop.setAttribute( "style:rotation-angle", "0" );
|
|
}
|
|
|
|
if ( t->angle != 0 )
|
|
prop.setAttribute( "style:rotation-angle", TQString::number( t->angle ) );
|
|
|
|
if ( !t->print )
|
|
prop.setAttribute( "style:print-content", "false" );
|
|
|
|
if ( t->hideAll )
|
|
prop.setAttribute( "style:cell-protect", "hidden-and-protected" );
|
|
else
|
|
if ( t->notProtected && !t->hideFormula )
|
|
prop.setAttribute( "style:cell-protect", "none" );
|
|
else
|
|
if ( t->notProtected && t->hideFormula )
|
|
prop.setAttribute( "style:cell-protect", "formula-hidden" );
|
|
else if ( t->hideFormula )
|
|
prop.setAttribute( "style:cell-protect", "protected formula-hidden" );
|
|
else if ( !t->notProtected )
|
|
prop.setAttribute( "style:cell-protect", "protected" );
|
|
|
|
|
|
if ( ( t->left == t->right ) && ( t->left == t->top ) && ( t->left == t->bottom ) )
|
|
{
|
|
if ( ( t->left.width() != 0 ) && ( t->left.style() != TQt::NoPen ) )
|
|
prop.setAttribute( "fo:border", convertPenToString( t->left ) );
|
|
}
|
|
else
|
|
{
|
|
if ( ( t->left.width() != 0 ) && ( t->left.style() != TQt::NoPen ) )
|
|
prop.setAttribute( "fo:border-left", convertPenToString( t->left ) );
|
|
|
|
if ( ( t->right.width() != 0 ) && ( t->right.style() != TQt::NoPen ) )
|
|
prop.setAttribute( "fo:border-right", convertPenToString( t->right ) );
|
|
|
|
if ( ( t->top.width() != 0 ) && ( t->top.style() != TQt::NoPen ) )
|
|
prop.setAttribute( "fo:border-top", convertPenToString( t->top ) );
|
|
|
|
if ( ( t->bottom.width() != 0 ) && ( t->bottom.style() != TQt::NoPen ) )
|
|
prop.setAttribute( "fo:border-bottom", convertPenToString( t->bottom ) );
|
|
}
|
|
|
|
ts.appendChild( prop );
|
|
autoStyles.appendChild( ts );
|
|
|
|
t = m_cellStyles.next();
|
|
}
|
|
}
|
|
|
|
void OpenCalcStyles::addColumnStyles( TQDomDocument & doc, TQDomElement & autoStyles )
|
|
{
|
|
ColumnStyle * t = m_columnStyles.first();
|
|
while ( t )
|
|
{
|
|
TQDomElement ts = doc.createElement( "style:style" );
|
|
ts.setAttribute( "style:name", t->name );
|
|
ts.setAttribute( "style:family", "table-column" );
|
|
|
|
TQDomElement prop = doc.createElement( "style:properties" );
|
|
if ( t->breakB != ::Style::none )
|
|
prop.setAttribute( "fo:break-before", ( t->breakB == ::Style::automatic ? "auto" : "page" ) );
|
|
prop.setAttribute( "style:column-width", TQString( "%1cm" ).tqarg( t->size ) );
|
|
|
|
ts.appendChild( prop );
|
|
autoStyles.appendChild( ts );
|
|
|
|
t = m_columnStyles.next();
|
|
}
|
|
}
|
|
|
|
void OpenCalcStyles::addNumberStyles( TQDomDocument & /*doc*/, TQDomElement & /*autoStyles*/ )
|
|
{
|
|
}
|
|
|
|
void OpenCalcStyles::addRowStyles( TQDomDocument & doc, TQDomElement & autoStyles )
|
|
{
|
|
RowStyle * t = m_rowStyles.first();
|
|
while ( t )
|
|
{
|
|
TQDomElement ts = doc.createElement( "style:style" );
|
|
ts.setAttribute( "style:name", t->name );
|
|
ts.setAttribute( "style:family", "table-row" );
|
|
|
|
TQDomElement prop = doc.createElement( "style:properties" );
|
|
prop.setAttribute( "style:row-height", TQString( "%1cm" ).tqarg( t->size ) );
|
|
if ( t->breakB != ::Style::none )
|
|
prop.setAttribute( "fo:break-before", ( t->breakB == ::Style::automatic ? "auto" : "page" ) );
|
|
|
|
ts.appendChild( prop );
|
|
autoStyles.appendChild( ts );
|
|
|
|
t = m_rowStyles.next();
|
|
}
|
|
}
|
|
|
|
void OpenCalcStyles::addSheetStyles( TQDomDocument & doc, TQDomElement & autoStyles )
|
|
{
|
|
SheetStyle * t = m_sheetStyles.first();
|
|
while ( t )
|
|
{
|
|
TQDomElement ts = doc.createElement( "style:style" );
|
|
ts.setAttribute( "style:name", t->name );
|
|
ts.setAttribute( "style:family", "table" );
|
|
ts.setAttribute( "style:master-page-name", "Default" );
|
|
|
|
TQDomElement prop = doc.createElement( "style:properties" );
|
|
prop.setAttribute( "table:display", ( t->visible ? "true" : "false" ) );
|
|
|
|
ts.appendChild( prop );
|
|
autoStyles.appendChild( ts );
|
|
|
|
t = m_sheetStyles.next();
|
|
}
|
|
}
|
|
|
|
bool SheetStyle::isEqual( SheetStyle const * const t1, SheetStyle const & t2 )
|
|
{
|
|
if ( t1->visible == t2.visible )
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
CellStyle::CellStyle()
|
|
: color( TQt::black ),
|
|
bgColor( TQt::white ),
|
|
indent( -1.0 ),
|
|
wrap( false ),
|
|
vertical( false ),
|
|
angle( 0 ),
|
|
print( true ),
|
|
left ( TQt::black, 0, TQt::NoPen ),
|
|
right( TQt::black, 0, TQt::NoPen ),
|
|
top ( TQt::black, 0, TQt::NoPen ),
|
|
bottom( TQt::black, 0, TQt::NoPen ),
|
|
hideAll( false ),
|
|
hideFormula( false ),
|
|
notProtected ( false ),
|
|
alignX( Format::Undefined ),
|
|
alignY( Format::Middle )
|
|
{
|
|
}
|
|
|
|
void CellStyle::copyData( CellStyle const & ts )
|
|
{
|
|
font = ts.font;
|
|
numberStyle = ts.numberStyle;
|
|
color = ts.color;
|
|
bgColor = ts.bgColor;
|
|
indent = ts.indent;
|
|
wrap = ts.wrap;
|
|
vertical = ts.vertical;
|
|
angle = ts.angle;
|
|
print = ts.print;
|
|
left = ts.left;
|
|
right = ts.right;
|
|
top = ts.top;
|
|
bottom = ts.bottom;
|
|
hideAll = ts.hideAll;
|
|
hideFormula = ts.hideFormula;
|
|
notProtected = ts.notProtected;
|
|
alignX = ts.alignX;
|
|
alignY = ts.alignY;
|
|
}
|
|
|
|
bool CellStyle::isEqual( CellStyle const * const t1, CellStyle const & t2 )
|
|
{
|
|
if ( ( t1->font == t2.font ) && ( t1->numberStyle == t2.numberStyle )
|
|
&& ( t1->color == t2.color ) && ( t1->bgColor == t2.bgColor )
|
|
&& ( t1->alignX == t2.alignX ) && ( t1->alignY == t2.alignY )
|
|
&& ( t1->indent == t2.indent ) && ( t1->wrap == t2.wrap )
|
|
&& ( t1->vertical == t2.vertical ) && ( t1->angle == t2.angle )
|
|
&& ( t1->print == t2.print ) && ( t1->left == t2.left )
|
|
&& ( t1->right == t2.right ) && ( t1->top == t2.top )
|
|
&& ( t1->bottom == t2.bottom ) && ( t1->hideAll == t2.hideAll )
|
|
&& ( t1->hideFormula == t2.hideFormula ) && ( t1->notProtected == t2.notProtected )
|
|
)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
// all except the number style
|
|
void CellStyle::loadData( CellStyle & cs, Cell const * const cell )
|
|
{
|
|
int col = cell->column();
|
|
int row = cell->row();
|
|
|
|
Format * f = new Format( 0, cell->sheet()->doc()->styleManager()->defaultStyle() );
|
|
|
|
TQFont font = cell->format()->textFont( col, row );
|
|
if ( font != f->font() )
|
|
cs.font = font;
|
|
|
|
TQColor color = cell->format()->textColor( col, row );
|
|
if ( color != f->textColor( col, row ) )
|
|
cs.color = color;
|
|
|
|
TQColor bgColor = cell->bgColor( col, row );
|
|
if ( bgColor != f->bgColor( col, row ) )
|
|
cs.bgColor = bgColor;
|
|
|
|
if ( cell->format()->hasProperty( Format::PAlign ) || !cell->format()->hasNoFallBackProperties( Format::PAlign ) )
|
|
cs.alignX = cell->format()->align( col, row );
|
|
|
|
if ( cell->format()->hasProperty( Format::PAlignY ) || !cell->format()->hasNoFallBackProperties( Format::PAlignY ) )
|
|
cs.alignY = cell->format()->alignY( col, row );
|
|
|
|
if ( cell->format()->hasProperty( Format::PIndent ) || !cell->format()->hasNoFallBackProperties( Format::PIndent ) )
|
|
cs.indent = cell->format()->getIndent( col, row );
|
|
|
|
if ( cell->format()->hasProperty( Format::PAngle ) || !cell->format()->hasNoFallBackProperties( Format::PAngle ) )
|
|
cs.angle = -cell->format()->getAngle( col, row );
|
|
|
|
if ( cell->format()->hasProperty( Format::PMultiRow ) || !cell->format()->hasNoFallBackProperties( Format::PMultiRow ) )
|
|
cs.wrap = cell->format()->multiRow( col, row );
|
|
|
|
if ( cell->format()->hasProperty( Format::PVerticalText )
|
|
|| !cell->format()->hasNoFallBackProperties( Format::PVerticalText ) )
|
|
cs.vertical = cell->format()->verticalText( col, row );
|
|
|
|
if ( cell->format()->hasProperty( Format::PDontPrintText )
|
|
|| !cell->format()->hasNoFallBackProperties( Format::PDontPrintText ) )
|
|
cs.print = !cell->format()->getDontprintText( col, row );
|
|
|
|
if ( cell->format()->hasProperty( Format::PLeftBorder ) || !cell->format()->hasNoFallBackProperties( Format::PLeftBorder ) )
|
|
cs.left = cell->leftBorderPen( col, row );
|
|
|
|
if ( cell->format()->hasProperty( Format::PRightBorder ) || !cell->format()->hasNoFallBackProperties( Format::PRightBorder ) )
|
|
cs.right = cell->rightBorderPen( col, row );
|
|
|
|
if ( cell->format()->hasProperty( Format::PTopBorder ) || !cell->format()->hasNoFallBackProperties( Format::PTopBorder ) )
|
|
cs.top = cell->topBorderPen( col, row );
|
|
|
|
if ( cell->format()->hasProperty( Format::PBottomBorder ) || !cell->format()->hasNoFallBackProperties( Format::PBottomBorder ) )
|
|
cs.bottom = cell->bottomBorderPen( col, row );
|
|
|
|
if ( cell->format()->hasProperty( Format::PNotProtected ) || !cell->format()->hasNoFallBackProperties( Format::PNotProtected ) )
|
|
cs.notProtected = cell->format()->notProtected( col, row );
|
|
|
|
if ( cell->format()->hasProperty( Format::PHideAll ) || !cell->format()->hasNoFallBackProperties( Format::PHideAll ) )
|
|
cs.hideAll = cell->format()->isHideAll( col, row );
|
|
|
|
if ( cell->format()->hasProperty( Format::PHideFormula ) || !cell->format()->hasNoFallBackProperties( Format::PHideFormula ) )
|
|
cs.hideFormula = cell->format()->isHideFormula( col, row );
|
|
}
|
|
|
|
bool NumberStyle::isEqual( NumberStyle const * const t1, NumberStyle const & t2 )
|
|
{
|
|
if ( ( t1->type == t2.type ) && ( t1->pattern == t2.pattern ) )
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
void ColumnStyle::copyData( ColumnStyle const & cs )
|
|
{
|
|
breakB = cs.breakB;
|
|
size = cs.size;
|
|
}
|
|
|
|
bool ColumnStyle::isEqual( ColumnStyle const * const c1, ColumnStyle const & c2 )
|
|
{
|
|
if ( ( c1->breakB == c2.breakB ) && ( c1->size == c2.size ) )
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
void RowStyle::copyData( RowStyle const & cs )
|
|
{
|
|
breakB = cs.breakB;
|
|
size = cs.size;
|
|
}
|
|
|
|
bool RowStyle::isEqual( RowStyle const * const c1, RowStyle const & c2 )
|
|
{
|
|
if ( ( c1->breakB == c2.breakB ) && ( c1->size == c2.size ) )
|
|
return true;
|
|
|
|
return false;
|
|
}
|