00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00071
00072
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 )
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 & , QDomElement & )
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
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 }