[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: koffice/filters/kspread/excel
From: Marijn Kruisselbrink <m.kruisselbrink () student ! tue ! nl>
Date: 2010-08-29 20:54:37
Message-ID: 20100829205437.25C03AC888 () svn ! kde ! org
[Download RAW message or body]
SVN commit 1169657 by mkruisselbrink:
add a proper SST record when writing a file
M +29 -6 export/ExcelExport.cpp
M +8 -0 export/ExcelExport.h
M +11 -0 sidewinder/XlsRecordOutputStream.cpp
M +1 -0 sidewinder/XlsRecordOutputStream.h
M +26 -0 sidewinder/excel.cpp
M +5 -0 sidewinder/excel.h
--- trunk/koffice/filters/kspread/excel/export/ExcelExport.cpp #1169656:1169657
@@ -35,6 +35,7 @@
#include <Map.h>
#include <Sheet.h>
#include <RowColumnFormat.h>
+#include <ValueStorage.h>
#include <kspread_limits.h>
#include <swinder.h>
@@ -175,13 +176,18 @@
o.writeRecord(CountryRecord(0));
- // TODO: proper SST
- o.startRecord(SSTRecord::id);
- o.writeUnsigned(32, 0);
- o.writeUnsigned(32, 0);
- o.endRecord();
+ QHash<QString, unsigned> stringTable;
+ {
+ SSTRecord sst(0);
+ ExtSSTRecord esst(0);
+ sst.setExtSSTRecord(&esst);
+ for (int i = 0; i < d->inputDoc->map()->count(); i++) {
+ buildStringTable(d->inputDoc->map()->sheet(i), sst, stringTable);
+ }
+ o.writeRecord(sst);
+ o.writeRecord(esst);
+ }
- o.writeRecord(ExtSSTRecord(0));
o.writeRecord(EOFRecord(0));
for (int i = 0; i < d->inputDoc->map()->count(); i++) {
@@ -212,6 +218,23 @@
return width / factor * 256;
}
+void ExcelExport::buildStringTable(KSpread::Sheet* sheet, Swinder::SSTRecord& sst, \
QHash<QString, unsigned>& stringTable) +{
+ unsigned useCount = 0;
+ const KSpread::ValueStorage* values = sheet->cellStorage()->valueStorage();
+ for (int i = 0; i < values->count(); i++) {
+ KSpread::Value v = values->data(i);
+ if (v.isString()) {
+ QString s = v.asString();
+ if (!stringTable.contains(s)) {
+ stringTable.insert(s, sst.addString(s));
+ }
+ useCount++;
+ }
+ }
+ sst.setUseCount(sst.useCount() + useCount);
+}
+
void ExcelExport::convertSheet(KSpread::Sheet* sheet)
{
XlsRecordOutputStream& o = *d->out;
--- trunk/koffice/filters/kspread/excel/export/ExcelExport.h #1169656:1169657
@@ -20,6 +20,9 @@
#ifndef EXCELEXPORT_H
#define EXCELEXPORT_H
+#include <QHash>
+#include <QString>
+
#include <KoFilter.h>
#include <KoStore.h>
@@ -27,6 +30,10 @@
class Sheet;
}
+namespace Swinder {
+ class SSTRecord;
+}
+
class ExcelExport : public KoFilter
{
@@ -40,6 +47,7 @@
virtual KoFilter::ConversionStatus convert(const QByteArray& from, const \
QByteArray& to);
void convertSheet(KSpread::Sheet* sheet);
+ void buildStringTable(KSpread::Sheet* sheet, Swinder::SSTRecord& sst, \
QHash<QString, unsigned>& stringTable); private:
class Private;
Private* d;
--- trunk/koffice/filters/kspread/excel/sidewinder/XlsRecordOutputStream.cpp \
#1169656:1169657 @@ -38,9 +38,20 @@
qint64 XlsRecordOutputStream::pos() const
{
+ if (m_currentRecord != NORECORD) {
+ return m_dataStream.device()->pos() + 4 + m_buffer->size();
+ } else {
return m_dataStream.device()->pos();
}
+}
+qint64 XlsRecordOutputStream::recordPos() const
+{
+ Q_ASSERT(m_currentRecord != NORECORD);
+ Q_ASSERT(m_curBitOffset == 0);
+ return m_buffer->size();
+}
+
void XlsRecordOutputStream::writeRecord(const Record& record)
{
startRecord(record.rtti());
--- trunk/koffice/filters/kspread/excel/sidewinder/XlsRecordOutputStream.h \
#1169656:1169657 @@ -57,6 +57,7 @@
void writeBlob(const QByteArray& value);
qint64 pos() const;
+ qint64 recordPos() const;
private:
QDataStream m_dataStream;
unsigned m_currentRecord;
--- trunk/koffice/filters/kspread/excel/sidewinder/excel.cpp #1169656:1169657
@@ -1151,6 +1151,7 @@
unsigned total;
std::vector<QString> strings;
std::vector<std::map<unsigned, unsigned> > formatRuns;
+ ExtSSTRecord* esst;
};
SSTRecord::SSTRecord(Workbook *book):
@@ -1158,6 +1159,7 @@
{
d = new SSTRecord::Private();
d->total = 0;
+ d->esst = 0;
}
SSTRecord::~SSTRecord()
@@ -1210,9 +1212,18 @@
void SSTRecord::writeData(XlsRecordOutputStream &out) const
{
+ unsigned dsst = qMax<unsigned>(8, (count() / 128)+1);
+ if (d->esst) {
+ d->esst->setDsst(dsst);
+ d->esst->setGroupCount((count() + dsst-1) / dsst);
+ }
out.writeUnsigned(32, d->total);
out.writeUnsigned(32,count());
for (unsigned i = 0; i < count(); i++) {
+ if (i % dsst == 0 && d->esst) {
+ d->esst->setIb(i/dsst, out.pos());
+ d->esst->setCbOffset(i/dsst, out.recordPos() + 4);
+ }
out.writeUnicodeStringWithFlagsAndLength(stringAt(i));
}
}
@@ -1222,6 +1233,21 @@
return d->strings.size();
}
+unsigned SSTRecord::useCount() const
+{
+ return d->total;
+}
+
+void SSTRecord::setUseCount(unsigned count)
+{
+ d->total = count;
+}
+
+void SSTRecord::setExtSSTRecord(ExtSSTRecord *esst)
+{
+ d->esst = esst;
+}
+
// why not just string() ? to avoid easy confusion with std::string
QString SSTRecord::stringAt(unsigned index) const
{
--- trunk/koffice/filters/kspread/excel/sidewinder/excel.h #1169656:1169657
@@ -720,6 +720,11 @@
*/
unsigned count() const;
+ unsigned useCount() const;
+ void setUseCount(unsigned count);
+
+ void setExtSSTRecord(ExtSSTRecord* esst);
+
/**
Returns the string at specified index.
Note that index must be less than count().
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic