[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-04-21 15:48:40
Message-ID: 20100421154840.E5E02AC8A3 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1117238 by mkruisselbrink:

don't save builtin named ranges (that aren't really named ranges in the first place) \
as named ranges, but save autofilter ranges as autofilter ranges.


 M  +32 -3     import/excelimport.cc  
 M  +17 -4     sidewinder/excel.cpp  
 M  +4 -0      sidewinder/excel.h  
 M  +35 -0     sidewinder/formulas.cpp  
 M  +6 -2      sidewinder/formulas.h  
 M  +15 -6     sidewinder/globalssubstreamhandler.cpp  
 M  +23 -0     sidewinder/records.xml  
 M  +15 -4     sidewinder/workbook.cpp  
 M  +11 -7     sidewinder/workbook.h  


--- trunk/koffice/filters/kspread/excel/import/excelimport.cc #1117237:1117238
@@ -566,12 +566,12 @@
         processSheetForBody(store, sheet, xmlWriter);
     }
 
-    std::map<UString, UString> &namedAreas = workbook->namedAreas();
+    std::map<std::pair<unsigned, UString>, UString> &namedAreas = \
workbook->namedAreas();  if(namedAreas.size() > 0) {
         xmlWriter->startElement("table:named-expressions");
-        for(std::map<UString, UString>::iterator it = namedAreas.begin(); it != \
namedAreas.end(); it++) { +        for(std::map<std::pair<unsigned, UString>, \
UString>::iterator it = namedAreas.begin(); it != namedAreas.end(); it++) {  \
                xmlWriter->startElement("table:named-range");
-            xmlWriter->addAttribute("table:name", string((*it).first) ); // e.g. "My \
Named Range" +            xmlWriter->addAttribute("table:name", \
string((*it).first.second) ); // e.g. "My Named Range"  QString range = \
string((*it).second);  if(range.startsWith('[') && range.endsWith(']'))
                 range = range.mid(1, range.length() - 2);
@@ -581,6 +581,35 @@
         xmlWriter->endElement();
     }
 
+    bool openedDBRanges = false;
+    int rangeId = 1;
+    for (unsigned i = 0; i < workbook->sheetCount(); i++) {
+        QList<QRect> filters = workbook->filterRanges(i);
+        QString sheetName = string(workbook->sheet(i)->name());
+        if (filters.size()) {
+            if (!openedDBRanges) xmlWriter->startElement("table:database-ranges");
+            openedDBRanges = true;
+
+            foreach (const QRect& filter, filters) {
+                QString sRange(sheetName);
+                sRange.append(".");
+                sRange.append(columnName(filter.left()));
+                sRange.append(QString::number(filter.top()+1));
+                sRange.append(":");
+                sRange.append(sheetName);
+                sRange.append(".");
+                sRange.append(columnName(filter.right()));
+                sRange.append(QString::number(workbook->sheet(i)->maxRow()));
+                xmlWriter->startElement("table:database-range");
+                xmlWriter->addAttribute("table:name", \
QString("database-%1").arg(rangeId++)); +                \
xmlWriter->addAttribute("table:display-filter-buttons", "true"); +                \
xmlWriter->addAttribute("table:target-range-address", sRange); +                \
xmlWriter->endElement(); // table:database-range +            }
+        }
+    }
+    if (openedDBRanges) xmlWriter->endElement(); // table:database-ranges
+
     xmlWriter->endElement();  // office:spreadsheet
 }
 
--- trunk/koffice/filters/kspread/excel/sidewinder/excel.cpp #1117237:1117238
@@ -965,6 +965,8 @@
 public:
     unsigned optionFlags;
     UString definedName;
+    int sheetIndex; // 0 for global
+    bool builtin;
 };
 
 
@@ -990,6 +992,16 @@
     return d->definedName;
 }
 
+unsigned NameRecord::sheetIndex() const
+{
+    return d->sheetIndex;
+}
+
+bool NameRecord::isBuiltin() const
+{
+    return d->builtin;
+}
+
 void NameRecord::setData(unsigned size, const unsigned char* data, const unsigned \
int*)  {
     if (size < 14) {
@@ -1003,7 +1015,7 @@
     //const bool fOB = d->optionFlags & 0x04;
     //const bool fProc = d->optionFlags & 0x08;
     //const bool fCalcExp = d->optionFlags & 0x10;
-    const bool fBuiltin = d->optionFlags & 0x20;
+    d->builtin = d->optionFlags & 0x20;
     // 6 bits fGrp
     //const bool reserved1 = d->optionFlags & 0x1800;
     //const bool fPublished = d->optionFlags & 0x3000;
@@ -1013,7 +1025,7 @@
     const unsigned len = readU8(data + 3); // cch
     const unsigned cce = readU16(data + 4); // len of rgce
     // 2 bytes reserved
-    const unsigned iTab = readU16(data + 8); // if !=0 then its a local name
+    d->sheetIndex = readU16(data + 8); // if !=0 then its a local name
     // 4 bytes reserved
 
     if (version() == Excel95) {
@@ -1023,7 +1035,7 @@
         d->definedName = UString(buffer);
         delete[] buffer;
     } else  if (version() == Excel97) {
-        if( fBuiltin ) { // field is for a build-in name
+        if( d->builtin ) { // field is for a build-in name
             const unsigned opts = readU8(data + 14);
             const bool fHighByte = opts & 0x01;
             const unsigned id = fHighByte ? readU16(data + 15) : readU8(data + 15) + \
0x0*256; @@ -1041,6 +1053,7 @@
                 case 0x0A: d->definedName = "Auto_Activate"; break;
                 case 0x0B: d->definedName = "Auto_Deactivate"; break;
                 case 0x0C: d->definedName = "Sheet_Title"; break;
+                case 0x0D: d->definedName = "_FilterDatabase"; break;
                 default: break;
             }
         } else { // must satisfy same restrictions then name field on \
XLNameUnicodeString @@ -1090,7 +1103,7 @@
         m_formula = t;
     }
 
-    std::cout << "NameRecord name=" << d->definedName << " iTab=" << iTab << " \
fBuiltin=" << fBuiltin << " formula=" << m_formula.id() << " (" << \
m_formula.idAsString() << ")" << std::endl; +    std::cout << "NameRecord name=" << \
d->definedName << " iTab=" << d->sheetIndex << " fBuiltin=" << d->builtin << " \
formula=" << m_formula.id() << " (" << m_formula.idAsString() << ")" << std::endl;  }
 
 void NameRecord::dump(std::ostream& /*out*/) const
--- trunk/koffice/filters/kspread/excel/sidewinder/excel.h #1117237:1117238
@@ -620,6 +620,10 @@
 
     void setDefinedName(const UString& name);
 
+    unsigned sheetIndex() const;
+
+    bool isBuiltin() const;
+
     virtual void setData(unsigned size, const unsigned char* data, const unsigned \
int* continuePositions);  
     virtual const char* name() const {
--- trunk/koffice/filters/kspread/excel/sidewinder/formulas.cpp #1117237:1117238
@@ -974,6 +974,41 @@
     return result;
 }
 
+std::pair<unsigned, QRect> FormulaToken::filterArea3d() const
+{
+    if (version() != Excel97) {
+        return std::make_pair(0, QRect());
+    }
+
+    unsigned sheetRef = readU16(&d->data[0]);
+
+    // FIXME check data size !
+    unsigned char buf[2];
+    int row1Ref, row2Ref, col1Ref, col2Ref;
+
+    buf[0] = d->data[2];
+    buf[1] = d->data[3];
+    row1Ref = readU16(buf);
+
+    buf[0] = d->data[4];
+    buf[1] = d->data[5];
+    row2Ref = readU16(buf);
+
+    buf[0] = d->data[6];
+    buf[1] = d->data[7];
+    col1Ref = readU16(buf);
+
+    buf[0] = d->data[8];
+    buf[1] = d->data[9];
+    col2Ref = readU16(buf);
+
+    col1Ref &= 0x3fff;
+    col2Ref &= 0x3fff;
+
+    QRect range(col1Ref, row1Ref, col2Ref - col1Ref + 1, row2Ref - row1Ref + 1);
+    return std::make_pair(sheetRef, range);
+}
+
 UString FormulaToken::areaMap(unsigned row, unsigned col)
 {
     unsigned char buf[4];
--- trunk/koffice/filters/kspread/excel/sidewinder/formulas.h #1117237:1117238
@@ -26,6 +26,8 @@
 
 #include <vector>
 
+#include <QtCore/QRect>
+
 namespace Swinder
 {
 
@@ -129,6 +131,8 @@
     UString area(unsigned row, unsigned col, bool relative = false) const;
     // only when id is Area3d
     UString area3d(const std::vector<UString>& externSheets, unsigned row, unsigned \
col) const; +    // only when id is Area3d, assumes all references to be absolute
+    std::pair<unsigned, QRect> filterArea3d() const;
     // only when id is MemArea
     UString areaMap(unsigned row, unsigned col);
 
@@ -144,7 +148,7 @@
     std::pair<unsigned, unsigned> baseFormulaRecord() const;
 
     void operator=(const FormulaToken& token);
-    
+
 private:
     class Private;
     Private *d;
@@ -167,7 +171,7 @@
     FormulaTokens decodeFormula(unsigned size, unsigned pos, const unsigned char* \
data, unsigned version);  
     UString decodeFormula(unsigned row, unsigned col, bool isShared, const \
                FormulaTokens& tokens);
-    UString dataTableFormula(unsigned row, unsigned col, const DataTableRecord* \
record);     +    UString dataTableFormula(unsigned row, unsigned col, const \
DataTableRecord* record);  
     virtual const std::vector<UString>& externSheets() const { return \
                m_externSheets; }
     virtual UString nameFromIndex(unsigned /*index*/) const { return UString(); }
--- trunk/koffice/filters/kspread/excel/sidewinder/globalssubstreamhandler.cpp \
#1117237:1117238 @@ -679,12 +679,21 @@
     d->nameTable.push_back(record->definedName());
 
     if(record->m_formula.id() != FormulaToken::Unused) {
-        FormulaTokens tokens;
-        tokens.push_back(record->m_formula);
-        UString f = decodeFormula(0, 0, false, tokens);
-        if(!f.isEmpty()) {
-            UString n = record->definedName();
-            d->workbook->setNamedArea(n, f);
+        if (record->isBuiltin()) {
+            if (record->definedName() == "_FilterDatabase") {
+                if (record->m_formula.id() == FormulaToken::Area3d) {
+                    std::pair<unsigned, QRect> area = \
record->m_formula.filterArea3d(); +                    \
d->workbook->addFilterRange(area.first, area.second); +                }
+            }
+        } else {
+            FormulaTokens tokens;
+            tokens.push_back(record->m_formula);
+            UString f = decodeFormula(0, 0, false, tokens);
+            if(!f.isEmpty()) {
+                UString n = record->definedName();
+                d->workbook->setNamedArea(record->sheetIndex(), n, f);
+            }
         }
     }
 }
--- trunk/koffice/filters/kspread/excel/sidewinder/records.xml #1117237:1117238
@@ -957,5 +957,28 @@
 <record name="CompressPictures" id="0x089b">
 </record>
 
+<record name="AutoFilter" id="0x009e">
+  <field name="entry"           type="unsigned" size="16" />
+  <field name="join"            type="unsigned" size="2">
+    <enum name="JoinAnd" value="0" />
+    <enum name="JoinOr"  value="1" />
+  </field>
+  <field name="simple1"         type="bool"     size="1" />
+  <field name="simple2"         type="bool"     size="1" />
+  <field name="topN"            type="bool"     size="1" />
+  <field name="topDirection"    type="unsigned" size="1">
+    <enum name="TopNBottom" value="0" />
+    <enum name="TopNTop"    value="1" />
+  </field>
+  <field name="topPercentage"   type="bool"     size="1" />
+  <field name="topNCount"       type="unsigned" size="9" />
+</record>
 
+<record name="AutoFilter12" id="0x087e">
+</record>
+
+<record name="AutoFilterInfo" id="0x009d">
+  <field name="entries"     type="unsigned" size="16" />
+</record>
+
 </records>
--- trunk/koffice/filters/kspread/excel/sidewinder/workbook.cpp #1117237:1117238
@@ -33,7 +33,8 @@
     Store* store;
     std::vector<Sheet*> sheets;
     QHash<PropertyType, QVariant> properties;
-    std::map<UString, UString> namedAreas;
+    std::map<std::pair<unsigned, UString>, UString> namedAreas;
+    std::map<unsigned, QList<QRect> > filterRanges;
     int activeTab;
     bool passwordProtected;
     unsigned long passwd;
@@ -109,16 +110,26 @@
     d->properties[ type ] = value;
 }
 
-std::map<UString, UString>& Workbook::namedAreas()
+std::map<std::pair<unsigned, UString>, UString>& Workbook::namedAreas()
 {
     return d->namedAreas;
 }
 
-void Workbook::setNamedArea(UString name, UString formula)
+void Workbook::setNamedArea(unsigned sheet, UString name, UString formula)
 {
-    d->namedAreas[name] = formula;
+    d->namedAreas[std::make_pair(sheet, name)] = formula;
 }
 
+QList<QRect> Workbook::filterRanges(unsigned sheet) const
+{
+    return d->filterRanges[sheet];
+}
+
+void Workbook::addFilterRange(unsigned sheet, const QRect& range)
+{
+    d->filterRanges[sheet].push_back(range);
+}
+
 int Workbook::activeTab() const
 {
     return d->activeTab;
--- trunk/koffice/filters/kspread/excel/sidewinder/workbook.h #1117237:1117238
@@ -25,6 +25,7 @@
 
 #include <QtCore/QObject>
 #include <QtCore/QVariant>
+#include <QtCore/QRect>
 #include <string>
 #include <map>
 
@@ -36,7 +37,7 @@
 public:
     explicit Store() {}
     virtual ~Store() {}
-    
+
     virtual bool open(const std::string& filename) = 0;
     virtual bool write(const char *data, int size) = 0;
     virtual bool close() = 0;
@@ -51,7 +52,7 @@
 
     /**
      * Constructs a new workbook.
-     * 
+     *
      * @a store An optional implementation of the Store class
      * that is used to write content like images to.
      */
@@ -66,7 +67,7 @@
      * Returns the used KoStore or NULL if not KoStore was set.
     /*/
     Store* store() const;
-    
+
     /**
      * Clears the workbook, i.e. makes it as if it is just constructed.
      */
@@ -114,9 +115,12 @@
     QVariant property(PropertyType type, const QVariant &defaultValue = QVariant()) \
const;  void setProperty(PropertyType type, const QVariant &value);
 
-    std::map<UString, UString>& namedAreas();
-    void setNamedArea(UString name, UString formula);
-    
+    std::map<std::pair<unsigned, UString>, UString>& namedAreas();
+    void setNamedArea(unsigned sheet, UString name, UString formula);
+
+    QList<QRect> filterRanges(unsigned sheet) const;
+    void addFilterRange(unsigned sheet, const QRect& range);
+
     int activeTab() const;
     void setActiveTab(int tab);
 
@@ -127,7 +131,7 @@
     void setPassword(unsigned long hash);
 
     void emitProgress(int value);
-    
+
 signals:
     void sigProgress(int value);
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic