filters

opencalcstyleexport.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2003 Norbert Andres <nandres@web.de>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include <opencalcstyleexport.h>
00021 
00022 #include <KoGlobal.h>
00023 
00024 #include <kspread_cell.h>
00025 #include <kspread_doc.h>
00026 #include <kspread_format.h>
00027 #include <kspread_sheet.h>
00028 #include <kspread_style.h>
00029 #include <kspread_style_manager.h>
00030 
00031 #include <qdom.h>
00032 
00033 using namespace KSpread;
00034 
00035 OpenCalcStyles::OpenCalcStyles()
00036 {
00037   m_cellStyles.setAutoDelete( true );
00038   m_columnStyles.setAutoDelete( true );
00039   m_numberStyles.setAutoDelete( true );
00040   m_rowStyles.setAutoDelete( true );
00041   m_sheetStyles.setAutoDelete( true );
00042 
00043   m_fontList.setAutoDelete( true );
00044 }
00045 
00046 OpenCalcStyles::~OpenCalcStyles()
00047 {
00048 }
00049 
00050 void OpenCalcStyles::writeStyles( QDomDocument & doc, QDomElement & autoStyles )
00051 {
00052   addColumnStyles( doc, autoStyles );
00053   addRowStyles( doc, autoStyles );
00054   addSheetStyles( doc, autoStyles );
00055   addNumberStyles( doc, autoStyles );
00056   addCellStyles( doc, autoStyles );
00057 }
00058 
00059 void OpenCalcStyles::writeFontDecl( QDomDocument & doc, QDomElement & fontDecls )
00060 {
00061   QFont * f = m_fontList.first();
00062   while ( f )
00063   {
00064     QDomElement fontDecl = doc.createElement( "style:font-decl" );
00065 
00066     fontDecl.setAttribute( "style:name", f->family() );
00067     fontDecl.setAttribute( "fo:font-family", f->family() );
00068     fontDecl.setAttribute( "style:font-pitch", ( f->fixedPitch() ? "fixed" : "variable" ) );
00069 
00070     // missing:
00071     // style:font-charset="x-symbol" style:font-family-generic="swiss"
00072     // style:font-style-name= "Bold/Standard/Regular"
00073 
00074     fontDecls.appendChild( fontDecl );
00075 
00076     f = m_fontList.next();
00077   }
00078 }
00079 
00080 void OpenCalcStyles::addFont( QFont const & font, bool def )
00081 {
00082   if ( def )
00083     m_defaultFont = font;
00084 
00085   QFont * f = m_fontList.first();
00086   while ( f )
00087   {
00088     if ( f->family() == font.family() )
00089       return;
00090 
00091     f = m_fontList.next();
00092   }
00093 
00094   f = new QFont( font );
00095   m_fontList.append( f );
00096 }
00097 
00098 QString OpenCalcStyles::cellStyle( CellStyle const & cs )
00099 {
00100   CellStyle * t = m_cellStyles.first();
00101   while ( t )
00102   {
00103     if ( CellStyle::isEqual( t, cs ) )
00104       return t->name;
00105 
00106     t = m_cellStyles.next();
00107   }
00108 
00109   t = new CellStyle();
00110   t->copyData( cs );
00111 
00112   m_cellStyles.append( t );
00113 
00114   t->name = QString( "ce%1" ).arg( m_cellStyles.count() );
00115 
00116   return t->name;
00117 }
00118 
00119 QString OpenCalcStyles::columnStyle( ColumnStyle const & cs )
00120 {
00121   ColumnStyle * t = m_columnStyles.first();
00122   while ( t )
00123   {
00124     if ( ColumnStyle::isEqual( t, cs ) )
00125       return t->name;
00126 
00127     t = m_columnStyles.next();
00128   }
00129 
00130   t = new ColumnStyle();
00131   t->copyData( cs );
00132 
00133   m_columnStyles.append( t );
00134 
00135   t->name = QString( "co%1" ).arg( m_columnStyles.count() );
00136 
00137   return t->name;
00138 }
00139 
00140 QString OpenCalcStyles::numberStyle( NumberStyle const & )
00141 {
00142   return "";
00143 }
00144 
00145 QString OpenCalcStyles::rowStyle( RowStyle const & rs )
00146 {
00147   RowStyle * t = m_rowStyles.first();
00148   while ( t )
00149   {
00150     if ( RowStyle::isEqual( t, rs ) )
00151       return t->name;
00152 
00153     t = m_rowStyles.next();
00154   }
00155 
00156   t = new RowStyle();
00157   t->copyData( rs );
00158 
00159   m_rowStyles.append( t );
00160 
00161   t->name = QString( "ro%1" ).arg( m_rowStyles.count() );
00162 
00163   return t->name;
00164 }
00165 
00166 QString OpenCalcStyles::sheetStyle( SheetStyle const & ts )
00167 {
00168   SheetStyle * t = m_sheetStyles.first();
00169   while ( t )
00170   {
00171     if ( SheetStyle::isEqual( t, ts ) )
00172       return t->name;
00173 
00174     t = m_sheetStyles.next();
00175   }
00176 
00177   t = new SheetStyle();
00178   t->copyData( ts );
00179 
00180   m_sheetStyles.append( t );
00181 
00182   t->name = QString( "ta%1" ).arg( m_sheetStyles.count() );
00183 
00184   return t->name;
00185 }
00186 
00187 QString convertPenToString( QPen const & pen )
00188 {
00189   QString s( QString( "%1cm solid " ).arg( pen.width() * 0.035 ) );
00190   s += pen.color().name();
00191 
00192   return s;
00193 }
00194 
00195 void OpenCalcStyles::addCellStyles( QDomDocument & doc, QDomElement & autoStyles )
00196 {
00197     CellStyle * t = m_cellStyles.first();
00198     while ( t )
00199     {
00200         QDomElement ts = doc.createElement( "style:style" );
00201         ts.setAttribute( "style:name", t->name );
00202         ts.setAttribute( "style:family", "table-cell" );
00203         ts.setAttribute( "style:parent-style-name", "Default" );
00204         if ( t->numberStyle.length() > 0 )
00205             ts.setAttribute( "style:data-style-name", t->numberStyle );
00206 
00207         QDomElement prop = doc.createElement( "style:properties" );
00208 
00209         if ( t->font.family() != m_defaultFont.family() )
00210             prop.setAttribute( "style:font-name", t->font.family() );
00211 
00212         if ( t->font.bold() != m_defaultFont.bold() )
00213             prop.setAttribute( "fo:font-weight", ( t->font.bold() ? "bold" : "light" ) );
00214 
00215         prop.setAttribute( "fo:font-size", QString( "%1pt" ).arg( t->font.pointSize() ) );
00216 
00217         if ( t->font.underline() != m_defaultFont.underline() )
00218         {
00219             prop.setAttribute( "style:text-underline", ( t->font.underline() ? "single" : "none" ) );
00220             if ( t->font.underline() )
00221                 prop.setAttribute( "style:text-underline-color", "font-color" );
00222         }
00223 
00224         if ( t->font.italic() != m_defaultFont.italic() )
00225             prop.setAttribute( "fo:font-style", ( t->font.italic() ? "italic" : "none" ) );
00226 
00227         if ( t->font.strikeOut() != m_defaultFont.strikeOut() )
00228             prop.setAttribute( "style:text-crossing-out", ( t->font.strikeOut() ? "single-line" : "none" ) );
00229 
00230         if ( t->color.name() != "#000000" )
00231             prop.setAttribute( "fo:color", t->color.name() );
00232 
00233         if ( t->bgColor.name() != "#ffffff" )
00234             prop.setAttribute( "fo:background-color", t->bgColor.name() );
00235 
00236         if ( t->alignX != Format::Undefined )
00237         {
00238             QString value;
00239             if ( t->alignX == Format::Center )
00240                 value = "center";
00241             else if ( t->alignX == Format::Right )
00242                 value = "end";
00243             else if ( t->alignX == Format::Left )
00244                 value = "start";
00245             prop.setAttribute( "fo:text-align", value );
00246         }
00247 
00248         if ( t->alignY != Format::Bottom ) // default in OpenCalc
00249             prop.setAttribute( "fo:vertical-align", ( t->alignY == Format::Middle ? "middle" : "top" ) );
00250 
00251         if ( t->indent > 0.0 )
00252         {
00253             prop.setAttribute( "fo:margin-left", QString( "%1pt" ).arg( t->indent ) );
00254             if ( t->alignX == Format::Undefined )
00255                 prop.setAttribute( "fo:text-align", "start" );
00256         }
00257 
00258         if ( t->wrap )
00259             prop.setAttribute( "fo:wrap-option", "wrap" );
00260 
00261         if ( t->vertical )
00262         {
00263             prop.setAttribute( "fo:direction", "ttb" );
00264             prop.setAttribute( "style:rotation-angle", "0" );
00265         }
00266 
00267         if ( t->angle != 0 )
00268             prop.setAttribute( "style:rotation-angle", QString::number( t->angle ) );
00269 
00270         if ( !t->print )
00271             prop.setAttribute( "style:print-content", "false" );
00272 
00273         if ( t->hideAll )
00274             prop.setAttribute( "style:cell-protect", "hidden-and-protected" );
00275         else
00276             if ( t->notProtected && !t->hideFormula )
00277                 prop.setAttribute( "style:cell-protect", "none" );
00278             else
00279                 if ( t->notProtected && t->hideFormula )
00280                     prop.setAttribute( "style:cell-protect", "formula-hidden" );
00281                 else if ( t->hideFormula )
00282                     prop.setAttribute( "style:cell-protect", "protected formula-hidden" );
00283                 else if ( !t->notProtected )
00284                     prop.setAttribute( "style:cell-protect", "protected" );
00285 
00286 
00287         if ( ( t->left == t->right ) && ( t->left == t->top ) && ( t->left == t->bottom ) )
00288         {
00289             if ( ( t->left.width() != 0 ) && ( t->left.style() != Qt::NoPen ) )
00290                 prop.setAttribute( "fo:border", convertPenToString( t->left ) );
00291         }
00292         else
00293         {
00294             if ( ( t->left.width() != 0 ) && ( t->left.style() != Qt::NoPen ) )
00295                 prop.setAttribute( "fo:border-left", convertPenToString( t->left ) );
00296 
00297             if ( ( t->right.width() != 0 ) && ( t->right.style() != Qt::NoPen ) )
00298                 prop.setAttribute( "fo:border-right", convertPenToString( t->right ) );
00299 
00300             if ( ( t->top.width() != 0 ) && ( t->top.style() != Qt::NoPen ) )
00301                 prop.setAttribute( "fo:border-top", convertPenToString( t->top ) );
00302 
00303             if ( ( t->bottom.width() != 0 ) && ( t->bottom.style() != Qt::NoPen ) )
00304                 prop.setAttribute( "fo:border-bottom", convertPenToString( t->bottom ) );
00305         }
00306 
00307         ts.appendChild( prop );
00308         autoStyles.appendChild( ts );
00309 
00310         t = m_cellStyles.next();
00311     }
00312 }
00313 
00314 void OpenCalcStyles::addColumnStyles( QDomDocument & doc, QDomElement & autoStyles )
00315 {
00316   ColumnStyle * t = m_columnStyles.first();
00317   while ( t )
00318   {
00319     QDomElement ts = doc.createElement( "style:style" );
00320     ts.setAttribute( "style:name", t->name );
00321     ts.setAttribute( "style:family", "table-column" );
00322 
00323     QDomElement prop = doc.createElement( "style:properties" );
00324     if ( t->breakB != ::Style::none )
00325       prop.setAttribute( "fo:break-before", ( t->breakB == ::Style::automatic ? "auto" : "page" ) );
00326     prop.setAttribute( "style:column-width", QString( "%1cm" ).arg( t->size ) );
00327 
00328     ts.appendChild( prop );
00329     autoStyles.appendChild( ts );
00330 
00331     t = m_columnStyles.next();
00332   }
00333 }
00334 
00335 void OpenCalcStyles::addNumberStyles( QDomDocument & /*doc*/, QDomElement & /*autoStyles*/ )
00336 {
00337 }
00338 
00339 void OpenCalcStyles::addRowStyles( QDomDocument & doc, QDomElement & autoStyles )
00340 {
00341   RowStyle * t = m_rowStyles.first();
00342   while ( t )
00343   {
00344     QDomElement ts = doc.createElement( "style:style" );
00345     ts.setAttribute( "style:name", t->name );
00346     ts.setAttribute( "style:family", "table-row" );
00347 
00348     QDomElement prop = doc.createElement( "style:properties" );
00349     prop.setAttribute( "style:row-height", QString( "%1cm" ).arg( t->size ) );
00350     if ( t->breakB != ::Style::none )
00351       prop.setAttribute( "fo:break-before", ( t->breakB == ::Style::automatic ? "auto" : "page" ) );
00352 
00353     ts.appendChild( prop );
00354     autoStyles.appendChild( ts );
00355 
00356     t = m_rowStyles.next();
00357   }
00358 }
00359 
00360 void OpenCalcStyles::addSheetStyles( QDomDocument & doc, QDomElement & autoStyles )
00361 {
00362   SheetStyle * t = m_sheetStyles.first();
00363   while ( t )
00364   {
00365     QDomElement ts = doc.createElement( "style:style" );
00366     ts.setAttribute( "style:name", t->name );
00367     ts.setAttribute( "style:family", "table" );
00368     ts.setAttribute( "style:master-page-name", "Default" );
00369 
00370     QDomElement prop = doc.createElement( "style:properties" );
00371     prop.setAttribute( "table:display", ( t->visible ? "true" : "false" ) );
00372 
00373     ts.appendChild( prop );
00374     autoStyles.appendChild( ts );
00375 
00376     t = m_sheetStyles.next();
00377   }
00378 }
00379 
00380 bool SheetStyle::isEqual( SheetStyle const * const t1, SheetStyle const & t2 )
00381 {
00382   if ( t1->visible == t2.visible )
00383     return true;
00384 
00385   return false;
00386 }
00387 
00388 CellStyle::CellStyle()
00389   : color( Qt::black ),
00390     bgColor( Qt::white ),
00391     indent( -1.0 ),
00392     wrap( false ),
00393     vertical( false ),
00394     angle( 0 ),
00395     print( true ),
00396     left ( Qt::black, 0, Qt::NoPen ),
00397     right( Qt::black, 0, Qt::NoPen ),
00398     top  ( Qt::black, 0, Qt::NoPen ),
00399     bottom( Qt::black, 0, Qt::NoPen ),
00400     hideAll( false ),
00401     hideFormula( false ),
00402     notProtected ( false ),
00403     alignX( Format::Undefined ),
00404     alignY( Format::Middle )
00405 {
00406 }
00407 
00408 void CellStyle::copyData( CellStyle const & ts )
00409 {
00410   font          = ts.font;
00411   numberStyle   = ts.numberStyle;
00412   color         = ts.color;
00413   bgColor       = ts.bgColor;
00414   indent        = ts.indent;
00415   wrap          = ts.wrap;
00416   vertical      = ts.vertical;
00417   angle         = ts.angle;
00418   print         = ts.print;
00419   left          = ts.left;
00420   right         = ts.right;
00421   top           = ts.top;
00422   bottom        = ts.bottom;
00423   hideAll       = ts.hideAll;
00424   hideFormula   = ts.hideFormula;
00425   notProtected  = ts.notProtected;
00426   alignX        = ts.alignX;
00427   alignY        = ts.alignY;
00428 }
00429 
00430 bool CellStyle::isEqual( CellStyle const * const t1, CellStyle const & t2 )
00431 {
00432   if ( ( t1->font == t2.font ) && ( t1->numberStyle == t2.numberStyle )
00433        && ( t1->color == t2.color ) && ( t1->bgColor == t2.bgColor )
00434        && ( t1->alignX == t2.alignX ) && ( t1->alignY == t2.alignY )
00435        && ( t1->indent == t2.indent ) && ( t1->wrap == t2.wrap )
00436        && ( t1->vertical == t2.vertical ) && ( t1->angle == t2.angle )
00437        && ( t1->print == t2.print ) && ( t1->left == t2.left )
00438        && ( t1->right == t2.right ) && ( t1->top == t2.top )
00439        && ( t1->bottom == t2.bottom ) && ( t1->hideAll == t2.hideAll )
00440        && ( t1->hideFormula == t2.hideFormula ) && ( t1->notProtected == t2.notProtected )
00441       )
00442     return true;
00443 
00444   return false;
00445 }
00446 
00447 // all except the number style
00448 void CellStyle::loadData( CellStyle & cs, Cell const * const cell )
00449 {
00450   int col = cell->column();
00451   int row = cell->row();
00452 
00453   Format * f = new Format( 0, cell->sheet()->doc()->styleManager()->defaultStyle() );
00454 
00455   QFont font = cell->format()->textFont( col, row );
00456   if ( font != f->font() )
00457     cs.font = font;
00458 
00459   QColor color = cell->format()->textColor( col, row );
00460   if ( color != f->textColor( col, row ) )
00461     cs.color   = color;
00462 
00463   QColor bgColor = cell->bgColor( col, row );
00464   if ( bgColor != f->bgColor( col, row ) )
00465     cs.bgColor = bgColor;
00466 
00467   if ( cell->format()->hasProperty( Format::PAlign ) || !cell->format()->hasNoFallBackProperties( Format::PAlign ) )
00468     cs.alignX = cell->format()->align( col, row );
00469 
00470   if ( cell->format()->hasProperty( Format::PAlignY ) || !cell->format()->hasNoFallBackProperties( Format::PAlignY ) )
00471     cs.alignY = cell->format()->alignY( col, row );
00472 
00473   if ( cell->format()->hasProperty( Format::PIndent ) || !cell->format()->hasNoFallBackProperties( Format::PIndent ) )
00474     cs.indent = cell->format()->getIndent( col, row );
00475 
00476   if ( cell->format()->hasProperty( Format::PAngle ) || !cell->format()->hasNoFallBackProperties( Format::PAngle ) )
00477     cs.angle  = -cell->format()->getAngle( col, row );
00478 
00479   if ( cell->format()->hasProperty( Format::PMultiRow ) || !cell->format()->hasNoFallBackProperties( Format::PMultiRow ) )
00480     cs.wrap   = cell->format()->multiRow( col, row );
00481 
00482   if ( cell->format()->hasProperty( Format::PVerticalText )
00483        || !cell->format()->hasNoFallBackProperties( Format::PVerticalText ) )
00484     cs.vertical = cell->format()->verticalText( col, row );
00485 
00486   if ( cell->format()->hasProperty( Format::PDontPrintText )
00487        || !cell->format()->hasNoFallBackProperties( Format::PDontPrintText ) )
00488     cs.print = !cell->format()->getDontprintText( col, row );
00489 
00490   if ( cell->format()->hasProperty( Format::PLeftBorder ) || !cell->format()->hasNoFallBackProperties( Format::PLeftBorder ) )
00491     cs.left  = cell->leftBorderPen( col, row );
00492 
00493   if ( cell->format()->hasProperty( Format::PRightBorder ) || !cell->format()->hasNoFallBackProperties( Format::PRightBorder ) )
00494     cs.right = cell->rightBorderPen( col, row );
00495 
00496   if ( cell->format()->hasProperty( Format::PTopBorder ) || !cell->format()->hasNoFallBackProperties( Format::PTopBorder ) )
00497     cs.top  = cell->topBorderPen( col, row );
00498 
00499   if ( cell->format()->hasProperty( Format::PBottomBorder ) || !cell->format()->hasNoFallBackProperties( Format::PBottomBorder ) )
00500     cs.bottom  = cell->bottomBorderPen( col, row );
00501 
00502   if ( cell->format()->hasProperty( Format::PNotProtected ) || !cell->format()->hasNoFallBackProperties( Format::PNotProtected ) )
00503     cs.notProtected = cell->format()->notProtected( col, row );
00504 
00505   if ( cell->format()->hasProperty( Format::PHideAll ) || !cell->format()->hasNoFallBackProperties( Format::PHideAll ) )
00506     cs.hideAll = cell->format()->isHideAll( col, row );
00507 
00508   if ( cell->format()->hasProperty( Format::PHideFormula ) || !cell->format()->hasNoFallBackProperties( Format::PHideFormula ) )
00509     cs.hideFormula = cell->format()->isHideFormula( col, row );
00510 }
00511 
00512 bool NumberStyle::isEqual( NumberStyle const * const t1, NumberStyle const & t2 )
00513 {
00514   if ( ( t1->type == t2.type ) && ( t1->pattern == t2.pattern ) )
00515     return true;
00516 
00517   return false;
00518 }
00519 
00520 void ColumnStyle::copyData( ColumnStyle const & cs )
00521 {
00522   breakB = cs.breakB;
00523   size   = cs.size;
00524 }
00525 
00526 bool ColumnStyle::isEqual( ColumnStyle const * const c1, ColumnStyle const & c2 )
00527 {
00528   if ( ( c1->breakB == c2.breakB ) && ( c1->size == c2.size ) )
00529     return true;
00530 
00531   return false;
00532 }
00533 
00534 void RowStyle::copyData( RowStyle const & cs )
00535 {
00536   breakB = cs.breakB;
00537   size   = cs.size;
00538 }
00539 
00540 bool RowStyle::isEqual( RowStyle const * const c1, RowStyle const & c2 )
00541 {
00542   if ( ( c1->breakB == c2.breakB ) && ( c1->size == c2.size ) )
00543     return true;
00544 
00545   return false;
00546 }
KDE Home | KDE Accessibility Home | Description of Access Keys