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