File indexing completed on 2025-03-16 10:52:56
0001 /* 0002 ** A program to convert the XML rendered by Words into LATEX. 0003 ** 0004 ** SPDX-FileCopyrightText: 2000 Robert JACOLIN 0005 ** 0006 ** This library is free software; you can redistribute it and/or 0007 ** modify it under the terms of the GNU Library General Public 0008 ** License as published by the Free Software Foundation; either 0009 ** version 2 of the License, or (at your option) any later version. 0010 ** 0011 ** This library is distributed in the hope that it will be useful, 0012 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 ** Library General Public License for more details. 0015 ** 0016 ** To receive a copy of the GNU Library General Public License, write to the 0017 ** Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 ** 0020 */ 0021 0022 #include "table.h" 0023 0024 #include <QBitArray> 0025 #include <QTextStream> 0026 0027 #include "LatexDebug.h" 0028 #include "cell.h" 0029 #include "column.h" 0030 #include "row.h" 0031 0032 /*******************************************/ 0033 /* Constructor */ 0034 /*******************************************/ 0035 Table::Table() 0036 { 0037 _maxCol = 0; 0038 _maxRow = 0; 0039 } 0040 0041 /*******************************************/ 0042 /* Destructor */ 0043 /*******************************************/ 0044 Table::~Table() 0045 { 0046 } 0047 0048 void Table::setMaxColumn(int col) 0049 { 0050 if (_maxCol < col) _maxCol = col; 0051 } 0052 0053 void Table::setMaxRow(int row) 0054 { 0055 if (_maxRow < row) _maxRow = row; 0056 } 0057 0058 void Table::analyze(const QDomNode node) 0059 { 0060 debugLatex << "New table"; 0061 if (getAttr(node, "columnnumber") == "1") 0062 setColumnNumber(); 0063 if (getAttr(node, "borders") == "1") 0064 setBorders(); 0065 if (getAttr(node, "hide") == "1") 0066 setHide(); 0067 if (getAttr(node, "hidezero") == "1") 0068 setHideZero(); 0069 if (getAttr(node, "firstletterupper") == "1") 0070 setFirstletterupper(); 0071 if (getAttr(node, "grid") == "1") 0072 setGrid(); 0073 if (getAttr(node, "printgrid") == "1") 0074 setPrintGrid(); 0075 if (getAttr(node, "printCommentIndicator") == "1") 0076 setPrintCommentIndicator(); 0077 if (getAttr(node, "printFormulaIndicator") == "1") 0078 setPrintFormulaIndicator(); 0079 if (getAttr(node, "showFormula") == "1") 0080 setShowFormula(); 0081 if (getAttr(node, "showFormulaIndicator") == "1") 0082 setShowFormulaIndicator(); 0083 if (getAttr(node, "lcmode") == "1") 0084 setLCMode(); 0085 setName(getAttr(node, "name")); 0086 0087 analyzePaper(getChild(node, "paper")); 0088 0089 int max = getNbChild(node); 0090 for (int index = 0; index < max; index++) { 0091 QString name = getChildName(node, index); 0092 if (name == "cell") { 0093 debugLatex << "----- cell -----"; 0094 Cell* cell = new Cell(); 0095 cell->analyze(getChild(node, index)); 0096 _cells.append(cell); 0097 setMaxColumn(cell->getCol()); 0098 setMaxRow(cell->getRow()); 0099 } else if (name == "column") { 0100 debugLatex << "----- column -----"; 0101 Column* column = new Column(); 0102 column->analyze(getChild(node, index)); 0103 _columns.append(column); 0104 } else if (name == "row") { 0105 debugLatex << "----- row -----"; 0106 Row* row = new Row(); 0107 row->analyze(getChild(node, index)); 0108 _rows.append(row); 0109 } else 0110 debugLatex << "name :" << name; 0111 } 0112 } 0113 0114 void Table::analyzePaper(const QDomNode node) 0115 { 0116 setFormat(getAttr(node, "format")); 0117 setOrientation(getAttr(node, "orientation")); 0118 0119 /* borders */ 0120 QDomNode border = getChild(node, "borders"); 0121 Q_UNUSED(border); 0122 setBorderRight(getAttr(node, "right").toLong()); 0123 setBorderLeft(getAttr(node, "left").toLong()); 0124 setBorderBottom(getAttr(node, "bottom").toLong()); 0125 setBorderTop(getAttr(node, "top").toLong()); 0126 } 0127 0128 Cell* Table::searchCell(int col, int row) 0129 { 0130 debugLatex << "search in list of" << _cells.count() << " cells"; 0131 foreach(Cell* cell, _cells) { 0132 debugLatex << "cell:" << cell->getRow() << "-" << cell->getCol(); 0133 if (cell->getCol() == col && cell->getRow() == row) 0134 return cell; 0135 } 0136 return nullptr; 0137 } 0138 0139 Column* Table::searchColumn(int col) 0140 { 0141 foreach(Column* column, _columns) { 0142 if (column->getCol() == col) 0143 return column; 0144 } 0145 return nullptr; 0146 } 0147 0148 Row* Table::searchRow(int rowNumber) 0149 { 0150 0151 foreach(Row* row, _rows) { 0152 if (row->getRow() == rowNumber) 0153 return row; 0154 } 0155 return nullptr; 0156 } 0157 0158 /*******************************************/ 0159 /* generate */ 0160 /*******************************************/ 0161 void Table::generate(QTextStream& out) 0162 { 0163 debugLatex << "GENERATION OF A TABLE" << getMaxRow() << " -" << getMaxColumn() 0164 << endl; 0165 out << endl << "%% " << getName() << endl; 0166 if (getOrientation() == "Portrait") { 0167 out << "\\begin{sidewaystable}" << endl << endl; 0168 indent(); 0169 writeIndent(out); 0170 } 0171 0172 out << "\\begin{tabular}"; 0173 generateTableHeader(out); 0174 out << endl; 0175 indent(); 0176 int rowNumber = 1; 0177 while (rowNumber <= getMaxRow()) { 0178 generateTopLineBorder(out, rowNumber); 0179 Row* row = searchRow(rowNumber); 0180 if (row != nullptr) 0181 row->generate(out); 0182 0183 for (int col = 1; col <= getMaxColumn(); col++) { 0184 writeIndent(out); 0185 generateCell(out, rowNumber, col); 0186 0187 if (col < getMaxColumn()) 0188 out << " & " << endl; 0189 } 0190 out << "\\\\" << endl; 0191 rowNumber++; 0192 } 0193 generateBottomLineBorder(out, rowNumber - 1); 0194 unindent(); 0195 writeIndent(out); 0196 out << "\\end{tabular}" << endl << endl; 0197 unindent(); 0198 0199 if (getOrientation() == "Portrait") { 0200 out << "\\end{sidewaystable}" << endl; 0201 unindent(); 0202 } 0203 /*Element* elt = 0; 0204 debugLatex <<"GENERATION OF A TABLE" << count(); 0205 out << endl << "\\begin{tabular}"; 0206 generateTableHeader(out); 0207 out << endl; 0208 indent(); 0209 0210 int row= 0; 0211 while(row <= getMaxRow()) 0212 { 0213 generateTopLineBorder(out, row); 0214 for(int col= 0; col <= getMaxCol(); col++) 0215 { 0216 writeIndent(out); 0217 */ 0218 /* Search the cell in the list */ 0219 /* elt = searchCell(row, col); 0220 0221 out << "\\multicolumn{1}{"; 0222 if(elt->hasLeftBorder()) 0223 out << "|"; 0224 out << "m{" << getCellSize(col) << "pt}"; 0225 0226 if(elt->hasRightBorder()) 0227 out << "|"; 0228 out << "}{" << endl; 0229 0230 generateCell(out, row, col); 0231 out << "}" << endl; 0232 if(col < getMaxCol()) 0233 out << "&" << endl; 0234 } 0235 out << "\\\\" << endl; 0236 writeIndent(out); 0237 row = row + 1; 0238 } 0239 generateBottomLineBorder(out, row - 1); 0240 out << "\\end{tabular}" << endl << endl; 0241 unindent();*/ 0242 debugLatex << "END OF GENERATION OF A TABLE"; 0243 } 0244 0245 /*******************************************/ 0246 /* generateTopLineBorder */ 0247 /*******************************************/ 0248 void Table::generateTopLineBorder(QTextStream& out, int row) 0249 { 0250 0251 Cell* cell = 0; 0252 QBitArray border(getMaxColumn()); 0253 bool fullLine = true; 0254 for (int index = 1; index <= getMaxColumn(); index++) { 0255 /* Search the cell in the list */ 0256 debugLatex << "search" << row << "," << index; 0257 cell = searchCell(index, row); 0258 0259 if (cell == nullptr) { 0260 cell = new Cell(row, index); 0261 _cells.append(cell); 0262 } 0263 0264 /* If the element has a border display it here */ 0265 border[ index - 1 ] = cell->hasTopBorder(); 0266 if (! cell->hasTopBorder()) 0267 fullLine = false; 0268 } 0269 0270 if (fullLine) { 0271 /* All column have a top border */ 0272 writeIndent(out); 0273 out << "\\hline" << endl; 0274 } else { 0275 int index = 0; 0276 while (index < getMaxColumn()) { 0277 if (border[index]) { 0278 int begin = index; 0279 int end; 0280 index++; 0281 while (index < getMaxColumn() && border[index]) { 0282 index++; 0283 } 0284 end = index - 1; 0285 out << "\\cline{" << begin << "-" << end << "} " << endl; 0286 } 0287 index++; 0288 } 0289 } 0290 0291 /*Row * row; 0292 row = searchRow(row); 0293 if(row != nullptr) 0294 row->generate(out);*/ 0295 } 0296 0297 /*******************************************/ 0298 /* generateBottomLineBorder */ 0299 /*******************************************/ 0300 void Table::generateBottomLineBorder(QTextStream& out, int row) 0301 { 0302 Cell* cell = 0; 0303 QBitArray border(getMaxColumn()); 0304 bool fullLine = true; 0305 0306 for (int index = 1; index <= getMaxColumn(); index++) { 0307 /* Search the cell in the list */ 0308 cell = searchCell(index, row); 0309 0310 if (cell == nullptr) { 0311 cell = new Cell(row, index); 0312 _cells.append(cell); 0313 } 0314 0315 /* If the element has a border display it here */ 0316 border[ index - 1 ] = cell->hasBottomBorder(); 0317 if (! cell->hasBottomBorder()) 0318 fullLine = false; 0319 } 0320 0321 if (fullLine) { 0322 /* All column have a bottom border */ 0323 writeIndent(out); 0324 out << "\\hline" << endl; 0325 } else { 0326 int index = 0; 0327 while (index < getMaxColumn()) { 0328 if (border[index]) { 0329 int begin = index; 0330 int end; 0331 ++index; 0332 while (index < getMaxColumn() && border[index]) { 0333 ++index; 0334 } 0335 end = index - 1; 0336 out << "\\cline{" << begin << "-" << end << "} " << endl; 0337 } 0338 ++index; 0339 } 0340 } 0341 } 0342 0343 /*******************************************/ 0344 /* generateCell */ 0345 /*******************************************/ 0346 void Table::generateCell(QTextStream& out, int row, int col) 0347 { 0348 debugLatex << "GENERATE CELL :" << row << "," << col; 0349 0350 /* Search the cell in the list */ 0351 Cell *cell = searchCell(col, row); 0352 if (cell != nullptr) { 0353 debugLatex << "generate cell with text:" << cell->getText(); 0354 cell->generate(out, this); 0355 } 0356 0357 debugLatex << "END OF A CELL"; 0358 } 0359 0360 /*******************************************/ 0361 /* generateTableHeader */ 0362 /*******************************************/ 0363 void Table::generateTableHeader(QTextStream& out) 0364 { 0365 Column* column = 0; 0366 0367 out << "{"; 0368 0369 for (int col = 1; col <= getMaxColumn(); col++) { 0370 column = searchColumn(col); 0371 if (column != nullptr) 0372 column->generate(out); 0373 else { 0374 out << "m{20pt}"; 0375 } 0376 } 0377 out << "}"; 0378 0379 } 0380