[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