File indexing completed on 2025-02-16 13:49:57

0001 /*
0002 ** A program to convert the XML rendered by Words into LATEX.
0003 **
0004 ** Copyright (C) 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     setBorderRight(getAttr(node, "right").toLong());
0122     setBorderLeft(getAttr(node, "left").toLong());
0123     setBorderBottom(getAttr(node, "bottom").toLong());
0124     setBorderTop(getAttr(node, "top").toLong());
0125 }
0126 
0127 Cell* Table::searchCell(int col, int row)
0128 {
0129     debugLatex << "search in list of" << _cells.count() << " cells";
0130     foreach(Cell* cell, _cells) {
0131         debugLatex << "cell:" << cell->getRow() << "-" << cell->getCol();
0132         if (cell->getCol() == col && cell->getRow() == row)
0133             return cell;
0134     }
0135     return nullptr;
0136 }
0137 
0138 Column* Table::searchColumn(int col)
0139 {
0140     foreach(Column* column, _columns) {
0141         if (column->getCol() == col)
0142             return column;
0143     }
0144     return nullptr;
0145 }
0146 
0147 Row* Table::searchRow(int rowNumber)
0148 {
0149 
0150     foreach(Row* row, _rows) {
0151         if (row->getRow() == rowNumber)
0152             return row;
0153     }
0154     return nullptr;
0155 }
0156 
0157 /*******************************************/
0158 /* generate                                */
0159 /*******************************************/
0160 void Table::generate(QTextStream& out)
0161 {
0162     debugLatex << "GENERATION OF A TABLE" << getMaxRow() << " -" << getMaxColumn()
0163     << endl;
0164     out << endl << "%% " << getName() << endl;
0165     if (getOrientation() == "Portrait") {
0166         out << "\\begin{sidewaystable}" << endl << endl;
0167         indent();
0168         writeIndent(out);
0169     }
0170 
0171     out << "\\begin{tabular}";
0172     generateTableHeader(out);
0173     out << endl;
0174     indent();
0175     int rowNumber = 1;
0176     while (rowNumber <= getMaxRow()) {
0177         generateTopLineBorder(out, rowNumber);
0178         Row* row = searchRow(rowNumber);
0179         if (row != nullptr)
0180             row->generate(out);
0181 
0182         for (int col = 1; col <= getMaxColumn(); col++) {
0183             writeIndent(out);
0184             generateCell(out, rowNumber, col);
0185 
0186             if (col < getMaxColumn())
0187                 out << " & " << endl;
0188         }
0189         out << "\\\\" << endl;
0190         rowNumber++;
0191     }
0192     generateBottomLineBorder(out, rowNumber - 1);
0193     unindent();
0194     writeIndent(out);
0195     out << "\\end{tabular}" << endl << endl;
0196     unindent();
0197 
0198     if (getOrientation() == "Portrait") {
0199         out << "\\end{sidewaystable}" << endl;
0200         unindent();
0201     }
0202     /*Element* elt = 0;
0203     debugLatex <<"GENERATION OF A TABLE" << count();
0204     out << endl << "\\begin{tabular}";
0205     generateTableHeader(out);
0206     out << endl;
0207     indent();
0208 
0209     int row= 0;
0210     while(row <= getMaxRow())
0211     {
0212      generateTopLineBorder(out, row);
0213      for(int col= 0; col <= getMaxCol(); col++)
0214      {
0215       writeIndent(out);
0216     */
0217     /* Search the cell in the list */
0218     /* elt = searchCell(row, col);
0219 
0220      out << "\\multicolumn{1}{";
0221      if(elt->hasLeftBorder())
0222       out << "|";
0223      out << "m{" << getCellSize(col) << "pt}";
0224 
0225      if(elt->hasRightBorder())
0226       out << "|";
0227      out << "}{" << endl;
0228 
0229      generateCell(out, row, col);
0230      out << "}" << endl;
0231      if(col < getMaxCol())
0232       out << "&" << endl;
0233     }
0234     out << "\\\\" << endl;
0235     writeIndent(out);
0236     row = row + 1;
0237     }
0238     generateBottomLineBorder(out, row - 1);
0239     out << "\\end{tabular}" << endl << endl;
0240     unindent();*/
0241     debugLatex << "END OF GENERATION OF A TABLE";
0242 }
0243 
0244 /*******************************************/
0245 /* generateTopLineBorder                   */
0246 /*******************************************/
0247 void Table::generateTopLineBorder(QTextStream& out, int row)
0248 {
0249 
0250     Cell* cell = 0;
0251     QBitArray border(getMaxColumn());
0252     bool fullLine = true;
0253     for (int index = 1; index <= getMaxColumn(); index++) {
0254         /* Search the cell in the list */
0255         debugLatex << "search" << row << "," << index;
0256         cell = searchCell(index, row);
0257 
0258         if (cell == nullptr) {
0259             cell = new Cell(row, index);
0260             _cells.append(cell);
0261         }
0262 
0263         /* If the element has a border display it here */
0264         border[ index - 1 ] = cell->hasTopBorder();
0265         if (! cell->hasTopBorder())
0266             fullLine = false;
0267     }
0268 
0269     if (fullLine) {
0270         /* All column have a top border */
0271         writeIndent(out);
0272         out << "\\hline" << endl;
0273     } else {
0274         int index = 0;
0275         while (index < getMaxColumn()) {
0276             if (border[index]) {
0277                 int begin = index;
0278                 int end;
0279                 index++;
0280                 while (index < getMaxColumn() && border[index]) {
0281                     index++;
0282                 }
0283                 end = index - 1;
0284                 out << "\\cline{" << begin << "-" << end << "} " << endl;
0285             }
0286             index++;
0287         }
0288     }
0289 
0290     /*Row * row;
0291     row = searchRow(row);
0292     if(row != nullptr)
0293      row->generate(out);*/
0294 }
0295 
0296 /*******************************************/
0297 /* generateBottomLineBorder                */
0298 /*******************************************/
0299 void Table::generateBottomLineBorder(QTextStream& out, int row)
0300 {
0301     Cell* cell = 0;
0302     QBitArray border(getMaxColumn());
0303     bool fullLine = true;
0304 
0305     for (int index = 1; index <= getMaxColumn(); index++) {
0306         /* Search the cell in the list */
0307         cell = searchCell(index, row);
0308 
0309         if (cell == nullptr) {
0310             cell = new Cell(row, index);
0311             _cells.append(cell);
0312         }
0313 
0314         /* If the element has a border display it here */
0315         border[ index - 1 ] = cell->hasBottomBorder();
0316         if (! cell->hasBottomBorder())
0317             fullLine = false;
0318     }
0319 
0320     if (fullLine) {
0321         /* All column have a bottom border */
0322         writeIndent(out);
0323         out << "\\hline" << endl;
0324     } else {
0325         int index = 0;
0326         while (index < getMaxColumn()) {
0327             if (border[index]) {
0328                 int begin = index;
0329                 int end;
0330                 ++index;
0331                 while (index < getMaxColumn() && border[index]) {
0332                     ++index;
0333                 }
0334                 end = index - 1;
0335                 out << "\\cline{" << begin << "-" << end << "} " << endl;
0336             }
0337             ++index;
0338         }
0339     }
0340 }
0341 
0342 /*******************************************/
0343 /* generateCell                            */
0344 /*******************************************/
0345 void Table::generateCell(QTextStream& out, int row, int col)
0346 {
0347     debugLatex << "GENERATE CELL :" << row << "," << col;
0348 
0349     /* Search the cell in the list */
0350     Cell *cell = searchCell(col, row);
0351     if (cell != nullptr) {
0352         debugLatex << "generate cell with text:" << cell->getText();
0353         cell->generate(out, this);
0354     }
0355 
0356     debugLatex << "END OF A CELL";
0357 }
0358 
0359 /*******************************************/
0360 /* generateTableHeader                     */
0361 /*******************************************/
0362 void Table::generateTableHeader(QTextStream& out)
0363 {
0364     Column* column = 0;
0365 
0366     out << "{";
0367 
0368     for (int col = 1; col <= getMaxColumn(); col++) {
0369         column = searchColumn(col);
0370         if (column != nullptr)
0371             column->generate(out);
0372         else {
0373             out << "m{20pt}";
0374         }
0375     }
0376     out << "}";
0377 
0378 }
0379