~ubuntu-branches/ubuntu/precise/koffice/precise

« back to all changes in this revision

Viewing changes to filters/kspread/xlsx/XlsxXmlChartReader.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2010-09-21 15:36:35 UTC
  • mfrom: (1.4.1 upstream) (60.2.11 maverick)
  • Revision ID: james.westby@ubuntu.com-20100921153635-6tejqkiro2u21ydi
Tags: 1:2.2.2-0ubuntu3
Add kubuntu_03_fix-crash-on-closing-sqlite-connection-2.2.2.diff and
kubuntu_04_support-large-memo-values-for-msaccess-2.2.2.diff as
recommended by upstream http://kexi-
project.org/wiki/wikiview/index.php@Kexi2.2_Patches.html#sqlite_stab
ility

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of Office 2007 Filters for KOffice
 
3
 *
 
4
 * Copyright (C) 2010 Sebastian Sauer <sebsauer@kdab.com>
 
5
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 
6
 *
 
7
 * Contact: Suresh Chande suresh.chande@nokia.com
 
8
 *
 
9
 * This library is free software; you can redistribute it and/or
 
10
 * modify it under the terms of the GNU Lesser General Public License
 
11
 * version 2.1 as published by the Free Software Foundation.
 
12
 *
 
13
 * This library is distributed in the hope that it will be useful, but
 
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
16
 * Lesser General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU Lesser General Public
 
19
 * License along with this library; if not, write to the Free Software
 
20
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 
21
 * 02110-1301 USA
 
22
 *
 
23
 */
 
24
 
 
25
#include "XlsxXmlChartReader.h"
 
26
#include "XlsxXmlDrawingReader.h"
 
27
#include "XlsxXmlWorksheetReader.h"
 
28
#include "XlsxImport.h"
 
29
 
 
30
#include "Charting.h"
 
31
#include "ChartExport.h"
 
32
 
 
33
#define MSOOXML_CURRENT_NS "c"
 
34
#define MSOOXML_CURRENT_CLASS XlsxXmlChartReader
 
35
#define BIND_READ_CLASS MSOOXML_CURRENT_CLASS
 
36
 
 
37
#include <MsooXmlReader_p.h>
 
38
#include <MsooXmlUtils.h>
 
39
 
 
40
#include <QFontMetricsF>
 
41
 
 
42
// calculates the column width in pixels
 
43
int columnWidth(unsigned long col, unsigned long dx = 0, qreal defaultColumnWidth = 8.43) {
 
44
    QFont font("Arial", 10);
 
45
    QFontMetricsF fm(font);
 
46
    const qreal characterWidth = fm.width("h");
 
47
    defaultColumnWidth *= characterWidth;
 
48
    return (defaultColumnWidth * col) + (dx / 1024.0 * defaultColumnWidth);
 
49
}
 
50
 
 
51
// calculates the row height in pixels
 
52
int rowHeight(unsigned long row, unsigned long dy = 0, qreal defaultRowHeight = 12.75)
 
53
{
 
54
    return defaultRowHeight * row + dy;
 
55
}
 
56
 
 
57
// Returns A for 1, B for 2, C for 3, etc.
 
58
QString columnName(uint column)
 
59
{
 
60
    QString s;
 
61
    unsigned digits = 1;
 
62
    unsigned offset = 0;
 
63
    for (unsigned limit = 26; column >= limit + offset; limit *= 26, digits++)
 
64
        offset += limit;
 
65
    for (unsigned col = column - offset; digits; --digits, col /= 26)
 
66
        s.prepend(QChar('A' + (col % 26)));
 
67
    return s;
 
68
}
 
69
 
 
70
XlsxXmlChartReaderContext::XlsxXmlChartReaderContext(XlsxXmlDrawingReaderContext* _drawingReaderContext)
 
71
    : MSOOXML::MsooXmlReaderContext()
 
72
    , drawingReaderContext(_drawingReaderContext)
 
73
    , m_chart(0)
 
74
    , m_chartExport(0)
 
75
{
 
76
}
 
77
 
 
78
XlsxXmlChartReaderContext::~XlsxXmlChartReaderContext()
 
79
{
 
80
    delete m_chart;
 
81
}
 
82
 
 
83
XlsxXmlChartReader::XlsxXmlChartReader(KoOdfWriters *writers)
 
84
    : MSOOXML::MsooXmlCommonReader(writers)
 
85
    , m_context(0)
 
86
    , m_currentSeries(0)
 
87
{
 
88
}
 
89
 
 
90
XlsxXmlChartReader::~XlsxXmlChartReader()
 
91
{
 
92
}
 
93
 
 
94
KoFilter::ConversionStatus XlsxXmlChartReader::read(MSOOXML::MsooXmlReaderContext* context)
 
95
{
 
96
    m_context = dynamic_cast<XlsxXmlChartReaderContext*>(context);
 
97
    Q_ASSERT(m_context);
 
98
    Q_ASSERT(m_context->drawingReaderContext);
 
99
    Q_ASSERT(m_context->drawingReaderContext->worksheetReaderContext);
 
100
 
 
101
    readNext();
 
102
    if (!isStartDocument()) {
 
103
        return KoFilter::WrongFormat;
 
104
    }
 
105
 
 
106
    readNext();
 
107
    if (!expectEl("c:chartSpace")) {
 
108
        return KoFilter::WrongFormat;
 
109
    }
 
110
 
 
111
    delete m_context->m_chart;
 
112
    m_context->m_chart = new Charting::Chart;
 
113
 
 
114
    delete m_context->m_chartExport;
 
115
    m_context->m_chartExport = new ChartExport(m_context->m_chart);
 
116
 
 
117
    while (!atEnd()) {
 
118
        QXmlStreamReader::TokenType tokenType = readNext();
 
119
        if(tokenType == QXmlStreamReader::Invalid || tokenType == QXmlStreamReader::EndDocument) break;
 
120
        if (isStartElement()) {
 
121
            TRY_READ_IF(plotArea)
 
122
            ELSE_TRY_READ_IF(legend)
 
123
        }
 
124
    }
 
125
 
 
126
    // static is fine here cause we only need to take care that that number is unique in the
 
127
    // exported ODS file and do not take if the number is continuous or whatever.
 
128
    static int chartNumber = 0;
 
129
 
 
130
    m_context->m_chartExport->m_href = QString("Chart%1").arg(++chartNumber);
 
131
    QMap<XlsxXmlDrawingReaderContext::AnchorType, XlsxXmlDrawingReaderContext::Position> positions = m_context->drawingReaderContext->m_positions;
 
132
    const QString sheetName = m_context->drawingReaderContext->worksheetReaderContext->worksheetName;
 
133
    if(! sheetName.isEmpty()) {
 
134
        m_context->m_chartExport->m_endCellAddress += sheetName + '.';
 
135
    }
 
136
 
 
137
    if(positions.contains(XlsxXmlDrawingReaderContext::FromAnchor)) {
 
138
        XlsxXmlDrawingReaderContext::Position f = positions[XlsxXmlDrawingReaderContext::FromAnchor];
 
139
        m_context->m_chartExport->m_endCellAddress += columnName(f.m_col) + QString::number(f.m_row);
 
140
        m_context->m_chartExport->m_x = columnWidth(f.m_col-1, 0 /*f.m_colOff*/);
 
141
        m_context->m_chartExport->m_y = rowHeight(f.m_row-1, 0 /*f.m_rowOff*/);
 
142
        if(positions.contains(XlsxXmlDrawingReaderContext::ToAnchor)) {
 
143
            XlsxXmlDrawingReaderContext::Position t = positions[XlsxXmlDrawingReaderContext::ToAnchor];
 
144
            m_context->m_chartExport->m_width = columnWidth( t.m_col - f.m_col - 1, 0 /*t.m_colOff*/);
 
145
            m_context->m_chartExport->m_height = rowHeight( t.m_row - f.m_row - 1, 0 /*t.m_rowOff*/);
 
146
        }
 
147
    }
 
148
 
 
149
 
 
150
    if (!m_context->m_chart->m_cellRangeAddress.isNull() ) {
 
151
        m_context->m_chartExport->m_cellRangeAddress.clear();
 
152
        if (!sheetName.isEmpty()) m_context->m_chartExport->m_cellRangeAddress += sheetName + '.';
 
153
        m_context->m_chartExport->m_cellRangeAddress += columnName(m_context->m_chart->m_cellRangeAddress.left()) + QString::number(m_context->m_chart->m_cellRangeAddress.top()) + ":" +
 
154
                                                        columnName(m_context->m_chart->m_cellRangeAddress.right()) + QString::number(m_context->m_chart->m_cellRangeAddress.bottom());
 
155
    }
 
156
 
 
157
    m_context->m_chartExport->m_notifyOnUpdateOfRanges = m_currentSeries->m_valuesCellRangeAddress; //m_cellRangeAddress
 
158
    
 
159
    // the index will by written by the XlsxXmlWorksheetReader
 
160
    //m_context->m_chartExport->saveIndex(body);
 
161
 
 
162
    // write the embedded object file
 
163
    KoStore* storeout = m_context->drawingReaderContext->worksheetReaderContext->import->outputStore();
 
164
    m_context->m_chartExport->saveContent(storeout, manifest);
 
165
 
 
166
    m_context = 0;
 
167
    return KoFilter::OK;
 
168
}
 
169
 
 
170
#undef CURRENT_EL
 
171
#define CURRENT_EL plotArea
 
172
KoFilter::ConversionStatus XlsxXmlChartReader::read_plotArea()
 
173
{
 
174
    READ_PROLOGUE
 
175
    while (!atEnd()) {
 
176
        readNext();
 
177
        if (isStartElement()) {
 
178
            TRY_READ_IF(ser)
 
179
            ELSE_TRY_READ_IF(pieChart)
 
180
            ELSE_TRY_READ_IF(firstSliceAng)
 
181
        }
 
182
        BREAK_IF_END_OF(CURRENT_EL);
 
183
    }
 
184
    READ_EPILOGUE
 
185
}
 
186
 
 
187
#undef CURRENT_EL
 
188
#define CURRENT_EL ser
 
189
KoFilter::ConversionStatus XlsxXmlChartReader::read_ser()
 
190
{
 
191
    READ_PROLOGUE
 
192
    
 
193
    m_currentSeries = new Charting::Series;
 
194
    m_context->m_chart->m_series << m_currentSeries;
 
195
    //m_currentSeries->m_dataTypeX = record->dataTypeX();
 
196
    //m_currentSeries->m_countXValues = record->countXValues();
 
197
    //m_currentSeries->m_countYValues = record->countYValues();
 
198
    //m_currentSeries->m_countBubbleSizeValues = record->countBubbleSizeValues();
 
199
 
 
200
    while (!atEnd()) {
 
201
        readNext();
 
202
        if (isStartElement()) {
 
203
            TRY_READ_IF(val)
 
204
            //ELSE_TRY_READ_IF(idx)
 
205
            //ELSE_TRY_READ_IF(order)
 
206
        }
 
207
        BREAK_IF_END_OF(CURRENT_EL);
 
208
    }
 
209
 
 
210
    READ_EPILOGUE
 
211
}
 
212
 
 
213
#undef CURRENT_EL
 
214
#define CURRENT_EL val
 
215
KoFilter::ConversionStatus XlsxXmlChartReader::read_val()
 
216
{
 
217
    READ_PROLOGUE
 
218
    while (!atEnd()) {
 
219
        readNext();
 
220
        if (isStartElement()) {
 
221
            TRY_READ_IF(numCache)
 
222
            if (qualifiedName() == QLatin1String(QUALIFIED_NAME(f))) {
 
223
                m_currentSeries->m_valuesCellRangeAddress = readElementText();
 
224
            }
 
225
        }
 
226
        BREAK_IF_END_OF(CURRENT_EL);
 
227
    }
 
228
    READ_EPILOGUE
 
229
}
 
230
 
 
231
#undef CURRENT_EL
 
232
#define CURRENT_EL numCache
 
233
KoFilter::ConversionStatus XlsxXmlChartReader::read_numCache()
 
234
{
 
235
    READ_PROLOGUE
 
236
    while (!atEnd()) {
 
237
        readNext();
 
238
        if (isStartElement()) {
 
239
            if (qualifiedName() == QLatin1String(QUALIFIED_NAME(ptCount))) {
 
240
                const QXmlStreamAttributes attrs(attributes());
 
241
                TRY_READ_ATTR_WITHOUT_NS(val)
 
242
                m_currentSeries->m_countYValues = val.toInt();
 
243
            }
 
244
            //else if (qualifiedName() == QLatin1String(QUALIFIED_NAME(pt)))
 
245
            //else if (qualifiedName() == QLatin1String(QUALIFIED_NAME(formatCode)))
 
246
        }
 
247
        BREAK_IF_END_OF(CURRENT_EL);
 
248
    }
 
249
    READ_EPILOGUE
 
250
}
 
251
 
 
252
#undef CURRENT_EL
 
253
#define CURRENT_EL legend
 
254
KoFilter::ConversionStatus XlsxXmlChartReader::read_legend()
 
255
{
 
256
    //TODO
 
257
    return KoFilter::OK;
 
258
}
 
259
 
 
260
#undef CURRENT_EL
 
261
#define CURRENT_EL pieChart
 
262
KoFilter::ConversionStatus XlsxXmlChartReader::read_pieChart()
 
263
{
 
264
    if(!m_context->m_chart->m_impl) {
 
265
        m_context->m_chart->m_impl = new Charting::PieImpl();
 
266
    }
 
267
    return KoFilter::OK;
 
268
}
 
269
 
 
270
KoFilter::ConversionStatus XlsxXmlChartReader::read_firstSliceAng()
 
271
{
 
272
    if(Charting::PieImpl* pie = dynamic_cast<Charting::PieImpl*>(m_context->m_chart->m_impl)) {
 
273
        const QXmlStreamAttributes attrs(attributes());
 
274
        TRY_READ_ATTR(val)
 
275
        pie->m_anStart = val.toInt(); // default value is zero
 
276
    }
 
277
    return KoFilter::OK;
 
278
}