File indexing completed on 2025-01-19 13:27:32
0001 /* This file is part of the KDE project 0002 Copyright (C) 2003 Norbert Andres <nandres@web.de> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 * Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include <opencalcstyleexport.h> 0021 0022 #include <sheets/Cell.h> 0023 #include <sheets/part/Doc.h> 0024 #include <sheets/Map.h> 0025 #include <sheets/Sheet.h> 0026 #include <sheets/Style.h> 0027 #include <sheets/StyleManager.h> 0028 0029 #include <QDomDocument> 0030 0031 using namespace Calligra::Sheets; 0032 0033 OpenCalcStyles::OpenCalcStyles() 0034 { 0035 } 0036 0037 OpenCalcStyles::~OpenCalcStyles() 0038 { 0039 while (!m_cellStyles.isEmpty()) delete m_cellStyles.takeFirst(); 0040 while (!m_columnStyles.isEmpty()) delete m_columnStyles.takeFirst(); 0041 while (!m_numberStyles.isEmpty()) delete m_numberStyles.takeFirst(); 0042 while (!m_rowStyles.isEmpty()) delete m_rowStyles.takeFirst(); 0043 while (!m_sheetStyles.isEmpty()) delete m_sheetStyles.takeFirst(); 0044 while (!m_fontList.isEmpty()) delete m_fontList.takeFirst(); 0045 } 0046 0047 void OpenCalcStyles::writeStyles(QDomDocument & doc, QDomElement & autoStyles) 0048 { 0049 addColumnStyles(doc, autoStyles); 0050 addRowStyles(doc, autoStyles); 0051 addSheetStyles(doc, autoStyles); 0052 addNumberStyles(doc, autoStyles); 0053 addCellStyles(doc, autoStyles); 0054 } 0055 0056 void OpenCalcStyles::writeFontDecl(QDomDocument & doc, QDomElement & fontDecls) 0057 { 0058 foreach(QFont * f, m_fontList) { 0059 QDomElement fontDecl = doc.createElement("style:font-decl"); 0060 0061 fontDecl.setAttribute("style:name", f->family()); 0062 fontDecl.setAttribute("fo:font-family", f->family()); 0063 fontDecl.setAttribute("style:font-pitch", (f->fixedPitch() ? "fixed" : "variable")); 0064 0065 // missing: 0066 // style:font-charset="x-symbol" style:font-family-generic="swiss" 0067 // style:font-style-name= "Bold/Standard/Regular" 0068 0069 fontDecls.appendChild(fontDecl); 0070 } 0071 } 0072 0073 void OpenCalcStyles::addFont(QFont const & font, bool def) 0074 { 0075 if (def) 0076 m_defaultFont = font; 0077 0078 foreach(QFont * f, m_fontList) { 0079 if (f->family() == font.family()) 0080 return; 0081 0082 } 0083 0084 QFont * f = new QFont(font); 0085 m_fontList.append(f); 0086 } 0087 0088 QString OpenCalcStyles::cellStyle(CellStyle const & cs) 0089 { 0090 CellStyle * t = 0; 0091 foreach(t, m_cellStyles) { 0092 if (CellStyle::isEqual(t, cs)) 0093 return t->name; 0094 } 0095 0096 t = new CellStyle(); 0097 t->copyData(cs); 0098 0099 m_cellStyles.append(t); 0100 0101 t->name = QString("ce%1").arg(m_cellStyles.count()); 0102 0103 return t->name; 0104 } 0105 0106 QString OpenCalcStyles::columnStyle(ColumnStyle const & cs) 0107 { 0108 ColumnStyle * t = 0; 0109 foreach(t, m_columnStyles) { 0110 if (ColumnStyle::isEqual(t, cs)) 0111 return t->name; 0112 } 0113 0114 t = new ColumnStyle(); 0115 t->copyData(cs); 0116 0117 m_columnStyles.append(t); 0118 0119 t->name = QString("co%1").arg(m_columnStyles.count()); 0120 0121 return t->name; 0122 } 0123 0124 QString OpenCalcStyles::numberStyle(NumberStyle const &) 0125 { 0126 return ""; 0127 } 0128 0129 QString OpenCalcStyles::rowStyle(RowStyle const & rs) 0130 { 0131 RowStyle * t = 0; 0132 foreach(t, m_rowStyles) { 0133 if (RowStyle::isEqual(t, rs)) 0134 return t->name; 0135 } 0136 0137 t = new RowStyle(); 0138 t->copyData(rs); 0139 0140 m_rowStyles.append(t); 0141 0142 t->name = QString("ro%1").arg(m_rowStyles.count()); 0143 0144 return t->name; 0145 } 0146 0147 QString OpenCalcStyles::sheetStyle(SheetStyle const & ts) 0148 { 0149 SheetStyle * t = 0; 0150 foreach(t, m_sheetStyles) { 0151 if (SheetStyle::isEqual(t, ts)) 0152 return t->name; 0153 } 0154 0155 t = new SheetStyle(); 0156 t->copyData(ts); 0157 0158 m_sheetStyles.append(t); 0159 0160 t->name = QString("ta%1").arg(m_sheetStyles.count()); 0161 0162 return t->name; 0163 } 0164 0165 QString convertPenToString(QPen const & pen) 0166 { 0167 QString s(QString("%1cm solid ").arg(pen.width() * 0.035)); 0168 s += pen.color().name(); 0169 0170 return s; 0171 } 0172 0173 void OpenCalcStyles::addCellStyles(QDomDocument & doc, QDomElement & autoStyles) 0174 { 0175 0176 CellStyle * t = 0; 0177 foreach(t, m_cellStyles) { 0178 QDomElement ts = doc.createElement("style:style"); 0179 ts.setAttribute("style:name", t->name); 0180 ts.setAttribute("style:family", "table-cell"); 0181 ts.setAttribute("style:parent-style-name", "Default"); 0182 if (t->numberStyle.length() > 0) 0183 ts.setAttribute("style:data-style-name", t->numberStyle); 0184 0185 QDomElement prop = doc.createElement("style:properties"); 0186 0187 if (t->font.family() != m_defaultFont.family()) 0188 prop.setAttribute("style:font-name", t->font.family()); 0189 0190 if (t->font.bold() != m_defaultFont.bold()) 0191 prop.setAttribute("fo:font-weight", (t->font.bold() ? "bold" : "light")); 0192 0193 prop.setAttribute("fo:font-size", QString("%1pt").arg(t->font.pointSize())); 0194 0195 if (t->font.underline() != m_defaultFont.underline()) { 0196 prop.setAttribute("style:text-underline", (t->font.underline() ? "single" : "none")); 0197 if (t->font.underline()) 0198 prop.setAttribute("style:text-underline-color", "font-color"); 0199 } 0200 0201 if (t->font.italic() != m_defaultFont.italic()) 0202 prop.setAttribute("fo:font-style", (t->font.italic() ? "italic" : "none")); 0203 0204 if (t->font.strikeOut() != m_defaultFont.strikeOut()) 0205 prop.setAttribute("style:text-crossing-out", (t->font.strikeOut() ? "single-line" : "none")); 0206 0207 if (t->color.name() != "#000000") 0208 prop.setAttribute("fo:color", t->color.name()); 0209 0210 if (t->bgColor.name() != "#ffffff") 0211 prop.setAttribute("fo:background-color", t->bgColor.name()); 0212 0213 if (t->alignX != Calligra::Sheets::Style::HAlignUndefined) { 0214 QString value; 0215 if (t->alignX == Calligra::Sheets::Style::Center) 0216 value = "center"; 0217 else if (t->alignX == Calligra::Sheets::Style::Right) 0218 value = "end"; 0219 else if (t->alignX == Calligra::Sheets::Style::Left) 0220 value = "start"; 0221 prop.setAttribute("fo:text-align", value); 0222 } 0223 0224 if (t->alignY != Calligra::Sheets::Style::Bottom) // default in OpenCalc 0225 prop.setAttribute("fo:vertical-align", (t->alignY == Calligra::Sheets::Style::Middle ? "middle" : "top")); 0226 0227 if (t->indent > 0.0) { 0228 prop.setAttribute("fo:margin-left", QString("%1pt").arg(t->indent)); 0229 if (t->alignX == Calligra::Sheets::Style::HAlignUndefined) 0230 prop.setAttribute("fo:text-align", "start"); 0231 } 0232 0233 if (t->wrap) 0234 prop.setAttribute("fo:wrap-option", "wrap"); 0235 0236 if (t->vertical) { 0237 prop.setAttribute("fo:direction", "ttb"); 0238 prop.setAttribute("style:rotation-angle", "0"); 0239 } 0240 0241 if (t->angle != 0) 0242 prop.setAttribute("style:rotation-angle", QString::number(t->angle)); 0243 0244 if (!t->print) 0245 prop.setAttribute("style:print-content", "false"); 0246 0247 if (t->hideAll) 0248 prop.setAttribute("style:cell-protect", "hidden-and-protected"); 0249 else if (t->notProtected && !t->hideFormula) 0250 prop.setAttribute("style:cell-protect", "none"); 0251 else if (t->notProtected && t->hideFormula) 0252 prop.setAttribute("style:cell-protect", "formula-hidden"); 0253 else if (t->hideFormula) 0254 prop.setAttribute("style:cell-protect", "protected formula-hidden"); 0255 else if (!t->notProtected) 0256 prop.setAttribute("style:cell-protect", "protected"); 0257 0258 0259 if ((t->left == t->right) && (t->left == t->top) && (t->left == t->bottom)) { 0260 if ((t->left.width() != 0) && (t->left.style() != Qt::NoPen)) 0261 prop.setAttribute("fo:border", convertPenToString(t->left)); 0262 } else { 0263 if ((t->left.width() != 0) && (t->left.style() != Qt::NoPen)) 0264 prop.setAttribute("fo:border-left", convertPenToString(t->left)); 0265 0266 if ((t->right.width() != 0) && (t->right.style() != Qt::NoPen)) 0267 prop.setAttribute("fo:border-right", convertPenToString(t->right)); 0268 0269 if ((t->top.width() != 0) && (t->top.style() != Qt::NoPen)) 0270 prop.setAttribute("fo:border-top", convertPenToString(t->top)); 0271 0272 if ((t->bottom.width() != 0) && (t->bottom.style() != Qt::NoPen)) 0273 prop.setAttribute("fo:border-bottom", convertPenToString(t->bottom)); 0274 } 0275 0276 ts.appendChild(prop); 0277 autoStyles.appendChild(ts); 0278 } 0279 } 0280 0281 void OpenCalcStyles::addColumnStyles(QDomDocument & doc, QDomElement & autoStyles) 0282 { 0283 ColumnStyle * t = 0; 0284 foreach(t, m_columnStyles) { 0285 QDomElement ts = doc.createElement("style:style"); 0286 ts.setAttribute("style:name", t->name); 0287 ts.setAttribute("style:family", "table-column"); 0288 0289 QDomElement prop = doc.createElement("style:properties"); 0290 if (t->breakB != ::Style::none) 0291 prop.setAttribute("fo:break-before", (t->breakB == ::Style::automatic ? "auto" : "page")); 0292 prop.setAttribute("style:column-width", QString("%1cm").arg(t->size)); 0293 0294 ts.appendChild(prop); 0295 autoStyles.appendChild(ts); 0296 } 0297 } 0298 0299 void OpenCalcStyles::addNumberStyles(QDomDocument & /*doc*/, QDomElement & /*autoStyles*/) 0300 { 0301 } 0302 0303 void OpenCalcStyles::addRowStyles(QDomDocument & doc, QDomElement & autoStyles) 0304 { 0305 RowStyle * t = 0; 0306 foreach(t, m_rowStyles) { 0307 QDomElement ts = doc.createElement("style:style"); 0308 ts.setAttribute("style:name", t->name); 0309 ts.setAttribute("style:family", "table-row"); 0310 0311 QDomElement prop = doc.createElement("style:properties"); 0312 prop.setAttribute("style:row-height", QString("%1cm").arg(t->size)); 0313 if (t->breakB != ::Style::none) 0314 prop.setAttribute("fo:break-before", (t->breakB == ::Style::automatic ? "auto" : "page")); 0315 0316 ts.appendChild(prop); 0317 autoStyles.appendChild(ts); 0318 0319 } 0320 } 0321 0322 void OpenCalcStyles::addSheetStyles(QDomDocument & doc, QDomElement & autoStyles) 0323 { 0324 SheetStyle * t = 0; 0325 foreach(t, m_sheetStyles) { 0326 QDomElement ts = doc.createElement("style:style"); 0327 ts.setAttribute("style:name", t->name); 0328 ts.setAttribute("style:family", "table"); 0329 ts.setAttribute("style:master-page-name", "Default"); 0330 0331 QDomElement prop = doc.createElement("style:properties"); 0332 prop.setAttribute("table:display", (t->visible ? "true" : "false")); 0333 0334 ts.appendChild(prop); 0335 autoStyles.appendChild(ts); 0336 } 0337 } 0338 0339 bool SheetStyle::isEqual(SheetStyle const * const t1, SheetStyle const & t2) 0340 { 0341 if (t1->visible == t2.visible) 0342 return true; 0343 0344 return false; 0345 } 0346 0347 CellStyle::CellStyle() 0348 : color(Qt::black), 0349 bgColor(Qt::white), 0350 indent(-1.0), 0351 wrap(false), 0352 vertical(false), 0353 angle(0), 0354 print(true), 0355 left(Qt::black, 0, Qt::NoPen), 0356 right(Qt::black, 0, Qt::NoPen), 0357 top(Qt::black, 0, Qt::NoPen), 0358 bottom(Qt::black, 0, Qt::NoPen), 0359 hideAll(false), 0360 hideFormula(false), 0361 notProtected(false), 0362 alignX(Calligra::Sheets::Style::HAlignUndefined), 0363 alignY(Calligra::Sheets::Style::Middle) 0364 { 0365 } 0366 0367 void CellStyle::copyData(CellStyle const & ts) 0368 { 0369 font = ts.font; 0370 numberStyle = ts.numberStyle; 0371 color = ts.color; 0372 bgColor = ts.bgColor; 0373 indent = ts.indent; 0374 wrap = ts.wrap; 0375 vertical = ts.vertical; 0376 angle = ts.angle; 0377 print = ts.print; 0378 left = ts.left; 0379 right = ts.right; 0380 top = ts.top; 0381 bottom = ts.bottom; 0382 hideAll = ts.hideAll; 0383 hideFormula = ts.hideFormula; 0384 notProtected = ts.notProtected; 0385 alignX = ts.alignX; 0386 alignY = ts.alignY; 0387 } 0388 0389 bool CellStyle::isEqual(CellStyle const * const t1, CellStyle const & t2) 0390 { 0391 if ((t1->font == t2.font) && (t1->numberStyle == t2.numberStyle) 0392 && (t1->color == t2.color) && (t1->bgColor == t2.bgColor) 0393 && (t1->alignX == t2.alignX) && (t1->alignY == t2.alignY) 0394 && (t1->indent == t2.indent) && (t1->wrap == t2.wrap) 0395 && (t1->vertical == t2.vertical) && (t1->angle == t2.angle) 0396 && (t1->print == t2.print) && (t1->left == t2.left) 0397 && (t1->right == t2.right) && (t1->top == t2.top) 0398 && (t1->bottom == t2.bottom) && (t1->hideAll == t2.hideAll) 0399 && (t1->hideFormula == t2.hideFormula) && (t1->notProtected == t2.notProtected) 0400 ) 0401 return true; 0402 0403 return false; 0404 } 0405 0406 // all except the number style 0407 void CellStyle::loadData(CellStyle & cs, const Cell& cell) 0408 { 0409 const Calligra::Sheets::Style style = cell.style(); 0410 const Calligra::Sheets::Style* defaultStyle = cell.sheet()->map()->styleManager()->defaultStyle(); 0411 0412 QFont font = style.font(); 0413 if (font != defaultStyle->font()) 0414 cs.font = font; 0415 0416 QColor color = style.fontColor(); 0417 if (color != defaultStyle->fontColor()) 0418 cs.color = color; 0419 0420 QColor bgColor = style.backgroundColor(); 0421 if (bgColor != defaultStyle->backgroundColor()) 0422 cs.bgColor = bgColor; 0423 0424 if (style.hasAttribute(Calligra::Sheets::Style::HorizontalAlignment)) 0425 cs.alignX = style.halign(); 0426 0427 if (style.hasAttribute(Calligra::Sheets::Style::VerticalAlignment)) 0428 cs.alignY = style.valign(); 0429 0430 if (style.hasAttribute(Calligra::Sheets::Style::Indentation)) 0431 cs.indent = style.indentation(); 0432 0433 if (style.hasAttribute(Calligra::Sheets::Style::Angle)) 0434 cs.angle = -style.angle(); 0435 0436 if (style.hasAttribute(Calligra::Sheets::Style::MultiRow)) 0437 cs.wrap = style.wrapText(); 0438 0439 if (style.hasAttribute(Calligra::Sheets::Style::VerticalText)) 0440 cs.vertical = style.verticalText(); 0441 0442 if (style.hasAttribute(Calligra::Sheets::Style::DontPrintText)) 0443 cs.print = style.printText(); 0444 0445 if (style.hasAttribute(Calligra::Sheets::Style::LeftPen)) 0446 cs.left = style.leftBorderPen(); 0447 0448 if (style.hasAttribute(Calligra::Sheets::Style::RightPen)) 0449 cs.right = style.rightBorderPen(); 0450 0451 if (style.hasAttribute(Calligra::Sheets::Style::TopPen)) 0452 cs.top = style.topBorderPen(); 0453 0454 if (style.hasAttribute(Calligra::Sheets::Style::BottomPen)) 0455 cs.bottom = style.bottomBorderPen(); 0456 0457 if (style.hasAttribute(Calligra::Sheets::Style::NotProtected)) 0458 cs.notProtected = style.notProtected(); 0459 0460 if (style.hasAttribute(Calligra::Sheets::Style::HideAll)) 0461 cs.hideAll = style.hideAll(); 0462 0463 if (style.hasAttribute(Calligra::Sheets::Style::HideFormula)) 0464 cs.hideFormula = style.hideFormula(); 0465 } 0466 0467 bool NumberStyle::isEqual(NumberStyle const * const t1, NumberStyle const & t2) 0468 { 0469 if ((t1->type == t2.type) && (t1->pattern == t2.pattern)) 0470 return true; 0471 0472 return false; 0473 } 0474 0475 void ColumnStyle::copyData(ColumnStyle const & cs) 0476 { 0477 breakB = cs.breakB; 0478 size = cs.size; 0479 } 0480 0481 bool ColumnStyle::isEqual(ColumnStyle const * const c1, ColumnStyle const & c2) 0482 { 0483 if ((c1->breakB == c2.breakB) && (c1->size == c2.size)) 0484 return true; 0485 0486 return false; 0487 } 0488 0489 void RowStyle::copyData(RowStyle const & cs) 0490 { 0491 breakB = cs.breakB; 0492 size = cs.size; 0493 } 0494 0495 bool RowStyle::isEqual(RowStyle const * const c1, RowStyle const & c2) 0496 { 0497 if ((c1->breakB == c2.breakB) && (c1->size == c2.size)) 0498 return true; 0499 0500 return false; 0501 }