File indexing completed on 2024-05-12 16:33:30

0001 /* This file is part of the KDE project
0002 
0003    Copyright 2008 Johannes Simon <johannes.simon@gmail.com>
0004    Copyright 2009 Inge Wallin    <inge@lysator.liu.se>
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    You should have received a copy of the GNU Library General Public License
0017    along with this library; see the file COPYING.LIB.  If not, write to
0018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019    Boston, MA 02110-1301, USA.
0020 */
0021 
0022 
0023 // Own
0024 #include "ChartTableModel.h"
0025 
0026 // C
0027 #include <cmath>
0028 
0029 // Qt
0030 #include <QDomNode>
0031 #include <QDomDocument>
0032 
0033 // Calligra
0034 #include <KoXmlReader.h>
0035 #include <KoXmlWriter.h>
0036 #include <KoGenStyles.h>
0037 #include <KoXmlNS.h>
0038 #include <KoOdfLoadingContext.h>
0039 #include <KoShapeLoadingContext.h>
0040 
0041 // KoChart
0042 #include "CellRegion.h"
0043 #include "OdfLoadingHelper.h"
0044 #include "ChartDebug.h"
0045 
0046 
0047 namespace KoChart {
0048 
0049 ChartTableModel::ChartTableModel(QObject *parent /* = 0 */)
0050     : QStandardItemModel(parent)
0051 {
0052 }
0053 
0054 ChartTableModel::~ChartTableModel()
0055 {
0056 }
0057 
0058 QVariant ChartTableModel::headerData(int section, Qt::Orientation orientation, int role) const
0059 {
0060     if (orientation == Qt::Horizontal) {
0061         if (role == Qt::DisplayRole) {
0062             return CellRegion::columnName(section+1);
0063         }
0064     }
0065     return QStandardItemModel::headerData(section, orientation, role);
0066 }
0067 
0068 QHash<QString, QVector<QRect> > ChartTableModel::cellRegion() const
0069 {
0070     // FIXME: Unimplemented?
0071     return QHash<QString, QVector<QRect> >();
0072 }
0073 
0074 bool ChartTableModel::setCellRegion(const QString& /*regionName*/)
0075 {
0076 #if 0 // FIXME: What does this code do?
0077     int result = 0;
0078 
0079     const int size = regionName.size();
0080     for (int i = 0; i < size; i++) {
0081         result += (CellRegion::rangeCharToInt(regionName[i].toLatin1())
0082                    * std::pow(10.0, (size - i - 1)));
0083     }
0084 
0085     return result;
0086 #endif
0087     return true;
0088 }
0089 
0090 bool ChartTableModel::isCellRegionValid(const QString& regionName) const
0091 {
0092     Q_UNUSED(regionName);
0093 
0094     return true;
0095 }
0096 
0097 bool ChartTableModel::loadOdf(const KoXmlElement &tableElement,
0098                               KoShapeLoadingContext &context)
0099 {
0100     Q_UNUSED(context);
0101 
0102     debugChartOdf<<"Load table";
0103     setRowCount(0);
0104     setColumnCount(0);
0105 
0106     //QDomDocument doc;
0107     //KoXml::asQDomElement(doc, tableElement);
0108     //QTextStream stream(stdout);
0109     //stream << doc.documentElement();
0110 
0111     int row = 0;
0112     KoXmlElement  n;
0113     forEachElement (n, tableElement) {
0114         if (n.namespaceURI() != KoXmlNS::table)
0115             continue;
0116 
0117         if (n.localName() == "table-columns" || n.localName() == "table-header-columns") {
0118             int column = 0;
0119             KoXmlElement  _n;
0120             forEachElement (_n, n) {
0121                 if (_n.namespaceURI() != KoXmlNS::table || _n.localName() != "table-column")
0122                     continue;
0123                 column += qMax(1, _n.attributeNS(KoXmlNS::table, "number-columns-repeated").toInt());
0124                 if (column > columnCount())
0125                     setColumnCount(column);
0126             }
0127         }
0128         else if (n.localName() == "table-rows" || n.localName() == "table-header-rows") {
0129             if (n.localName() == "table-header-rows") {
0130                 if (row >= 1) {
0131                     // There can only be one header-row and only at the very beginning.
0132                     // So, ignore all following header-rows to be sure our internal
0133                     // table doesn't start at the wrong offset or something like that.
0134                     continue;
0135                 }
0136             }
0137 
0138             KoXmlElement  _n;
0139             forEachElement (_n, n) {
0140                 if (_n.namespaceURI() != KoXmlNS::table || _n.localName() != "table-row")
0141                     continue;
0142 
0143                 // Add a row to the internal representation.
0144                 setRowCount(row + 1);
0145 
0146                 // Loop through all cells in a table row.
0147                 int  column = 0;
0148                 KoXmlElement  __n;
0149                 forEachElement (__n, _n) {
0150                     if (__n.namespaceURI() != KoXmlNS::table || __n.localName() != "table-cell")
0151                         continue;
0152 
0153                     // We have a cell so be sure our column-counter is increased right now so
0154                     // any 'continue' coming now will leave with the correct value for the next
0155                     // cell we deal with.
0156                     ++column;
0157 
0158                     // If this row is wider than any previous one, then add another column.
0159                     if (column > columnCount())
0160                         setColumnCount(column);
0161 
0162                     const QString valueType = __n.attributeNS(KoXmlNS::office, "value-type");
0163                     QString valueString = __n.attributeNS(KoXmlNS::office, "value");
0164                     const KoXmlElement valueElement = __n.namedItemNS(KoXmlNS::text, "p").toElement();
0165                     if ((valueElement.isNull() || !valueElement.isElement()) && valueString.isEmpty())
0166                         continue;
0167 
0168                     // Read the actual value in the cell.
0169                     QVariant value;
0170                     if (valueString.isEmpty())
0171                         valueString = valueElement.text().trimmed();
0172                     if (valueType == "float")
0173                         value = valueString.toDouble();
0174                     else if (valueType == "boolean")
0175                         value = (bool)valueString.toInt();
0176                     else // if (valueType == "string")
0177                         value = valueString;
0178 
0179                     setData(index(row, column - 1), value);
0180                 } // foreach table:table-cell
0181                 ++row;
0182 
0183             } // foreach table:table-row
0184         }
0185     }
0186     debugChartOdf<<"Loaded table:"<<rowCount()<<','<<columnCount();
0187     return true;
0188 }
0189 
0190 bool ChartTableModel::saveOdf(KoXmlWriter &bodyWriter, KoGenStyles &mainStyles ) const
0191 {
0192     Q_UNUSED(bodyWriter);
0193     Q_UNUSED(mainStyles);
0194     // The save logic is in ChartShape::saveOdf
0195     return true;
0196 }
0197 
0198 }