/* This file is part of the KDE project Copyright (C) 2003 Norbert Andres 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 #include #include #include #include #include #include #include #include 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" ).arg( 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" ).arg( 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" ).arg( 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" ).arg( m_sheetStyles.count() ); return t->name; } TQString convertPenToString( TQPen const & pen ) { TQString s( TQString( "%1cm solid " ).arg( 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:parent-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" ).arg( 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" ).arg( 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" ).arg( 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" ).arg( 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; }