[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