Refactor: D-Pointer used for public classes
This commit is contained in:
@@ -15,7 +15,10 @@ HEADERS += $$PWD/xlsxdocprops_p.h \
|
|||||||
$$PWD/xlsxstyles_p.h \
|
$$PWD/xlsxstyles_p.h \
|
||||||
$$PWD/xlsxworksheet.h \
|
$$PWD/xlsxworksheet.h \
|
||||||
$$PWD/zipwriter_p.h \
|
$$PWD/zipwriter_p.h \
|
||||||
$$PWD/xlsxpackage_p.h
|
$$PWD/xlsxpackage_p.h \
|
||||||
|
$$PWD/xlsxworkbook_p.h \
|
||||||
|
$$PWD/xlsxworksheet_p.h \
|
||||||
|
$$PWD/xlsxformat_p.h
|
||||||
|
|
||||||
SOURCES += $$PWD/xlsxdocprops.cpp \
|
SOURCES += $$PWD/xlsxdocprops.cpp \
|
||||||
$$PWD/xlsxrelationships.cpp \
|
$$PWD/xlsxrelationships.cpp \
|
||||||
|
|||||||
+374
-229
@@ -23,316 +23,353 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include "xlsxformat.h"
|
#include "xlsxformat.h"
|
||||||
|
#include "xlsxformat_p.h"
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
namespace QXlsx {
|
namespace QXlsx {
|
||||||
|
|
||||||
QList<Format *> Format::s_xfFormats;
|
QList<Format *> FormatPrivate::s_xfFormats;
|
||||||
QList<Format *> Format::s_dxfFormats;
|
QList<Format *> FormatPrivate::s_dxfFormats;
|
||||||
|
|
||||||
Format::Format()
|
FormatPrivate::FormatPrivate(Format *p) :
|
||||||
|
q_ptr(p)
|
||||||
{
|
{
|
||||||
m_number.formatIndex = 0;
|
dirty = true;
|
||||||
|
|
||||||
m_font.bold = false;
|
is_dxf_fomat = false;
|
||||||
m_font.color = QColor(Qt::black);
|
xf_index = -1;
|
||||||
m_font.italic = false;
|
dxf_index = -1;
|
||||||
m_font.name = "Calibri";
|
|
||||||
m_font.scirpt = FontScriptNormal;
|
|
||||||
m_font.size = 11;
|
|
||||||
m_font.strikeOut = false;
|
|
||||||
m_font.underline = FontUnderlineNone;
|
|
||||||
m_font.shadow = false;
|
|
||||||
m_font.outline = false;
|
|
||||||
m_font.family = 2;
|
|
||||||
m_font.scheme = "minor";
|
|
||||||
m_font.charset = 0;
|
|
||||||
m_font.condense = 0;
|
|
||||||
m_font.extend = 0;
|
|
||||||
m_font._dirty = true;
|
|
||||||
m_font._redundant = false;
|
|
||||||
m_font._index = -1;
|
|
||||||
|
|
||||||
m_alignment.alignH = AlignHGeneral;
|
theme = 0;
|
||||||
m_alignment.alignV = AlignBottom;
|
color_indexed = 0;
|
||||||
m_alignment.wrap = false;
|
}
|
||||||
m_alignment.rotation = 0;
|
|
||||||
m_alignment.indent = 0;
|
|
||||||
m_alignment.shinkToFit = false;
|
|
||||||
|
|
||||||
m_border.left = BorderNone;
|
Format::Format() :
|
||||||
m_border.right = BorderNone;
|
d_ptr(new FormatPrivate(this))
|
||||||
m_border.top = BorderNone;
|
{
|
||||||
m_border.bottom = BorderNone;
|
|
||||||
m_border.diagonal = BorderNone;
|
|
||||||
m_border.diagonalType = DiagonalBorderNone;
|
|
||||||
m_border.leftColor = QColor();
|
|
||||||
m_border.rightColor = QColor();
|
|
||||||
m_border.topColor = QColor();
|
|
||||||
m_border.bottomColor = QColor();
|
|
||||||
m_border.diagonalColor = QColor();
|
|
||||||
m_border._dirty = true;
|
|
||||||
m_border._redundant = false;
|
|
||||||
m_border._index = -1;
|
|
||||||
|
|
||||||
m_fill.pattern = PatternNone;
|
}
|
||||||
m_fill.bgColor = QColor();
|
|
||||||
m_fill.fgColor = QColor();
|
|
||||||
m_fill._dirty = true;
|
|
||||||
m_fill._redundant = false;
|
|
||||||
m_fill._index = -1;
|
|
||||||
|
|
||||||
m_protection.locked = false;
|
Format::~Format()
|
||||||
m_protection.hidden = false;
|
{
|
||||||
|
delete d_ptr;
|
||||||
m_dirty = true;
|
|
||||||
|
|
||||||
m_is_dxf_fomat = false;
|
|
||||||
m_xf_index = -1;
|
|
||||||
m_dxf_index = -1;
|
|
||||||
|
|
||||||
m_theme = 0;
|
|
||||||
m_color_indexed = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Format::numberFormat() const
|
int Format::numberFormat() const
|
||||||
{
|
{
|
||||||
return m_number.formatIndex;
|
Q_D(const Format);
|
||||||
|
return d->numberData.formatIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setNumberFormat(int format)
|
void Format::setNumberFormat(int format)
|
||||||
{
|
{
|
||||||
m_dirty = true;
|
Q_D(Format);
|
||||||
m_number.formatIndex = format;
|
d->dirty = true;
|
||||||
|
d->numberData.formatIndex = format;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Format::fontSize() const
|
int Format::fontSize() const
|
||||||
{
|
{
|
||||||
return m_font.size;
|
Q_D(const Format);
|
||||||
|
return d->fontData.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setFontSize(int size)
|
void Format::setFontSize(int size)
|
||||||
{
|
{
|
||||||
m_font.size = size;
|
Q_D(Format);
|
||||||
m_font._dirty = true;
|
d->fontData.size = size;
|
||||||
|
d->fontData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Format::fontItalic() const
|
bool Format::fontItalic() const
|
||||||
{
|
{
|
||||||
return m_font.italic;
|
Q_D(const Format);
|
||||||
|
return d->fontData.italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setFontItalic(bool italic)
|
void Format::setFontItalic(bool italic)
|
||||||
{
|
{
|
||||||
m_font.italic = italic;
|
Q_D(Format);
|
||||||
m_font._dirty = true;
|
d->fontData.italic = italic;
|
||||||
|
d->fontData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Format::fontStrikeOut() const
|
bool Format::fontStrikeOut() const
|
||||||
{
|
{
|
||||||
return m_font.strikeOut;
|
Q_D(const Format);
|
||||||
|
return d->fontData.strikeOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setFontStrikeOut(bool strikeOut)
|
void Format::setFontStrikeOut(bool strikeOut)
|
||||||
{
|
{
|
||||||
m_font.strikeOut = strikeOut;
|
Q_D(Format);
|
||||||
m_font._dirty = true;
|
d->fontData.strikeOut = strikeOut;
|
||||||
|
d->fontData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor Format::fontColor() const
|
QColor Format::fontColor() const
|
||||||
{
|
{
|
||||||
return m_font.color;
|
Q_D(const Format);
|
||||||
|
return d->fontData.color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setFontColor(const QColor &color)
|
void Format::setFontColor(const QColor &color)
|
||||||
{
|
{
|
||||||
m_font.color = color;
|
Q_D(Format);
|
||||||
m_font._dirty = true;
|
d->fontData.color = color;
|
||||||
|
d->fontData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Format::fontBold() const
|
bool Format::fontBold() const
|
||||||
{
|
{
|
||||||
return m_font.bold;
|
Q_D(const Format);
|
||||||
|
return d->fontData.bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setFontBold(bool bold)
|
void Format::setFontBold(bool bold)
|
||||||
{
|
{
|
||||||
m_font.bold = bold;
|
Q_D(Format);
|
||||||
m_font._dirty = true;
|
d->fontData.bold = bold;
|
||||||
|
d->fontData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Format::FontScript Format::fontScript() const
|
Format::FontScript Format::fontScript() const
|
||||||
{
|
{
|
||||||
return m_font.scirpt;
|
Q_D(const Format);
|
||||||
|
return d->fontData.scirpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setFontScript(FontScript script)
|
void Format::setFontScript(FontScript script)
|
||||||
{
|
{
|
||||||
m_font.scirpt = script;
|
Q_D(Format);
|
||||||
m_font._dirty = true;
|
d->fontData.scirpt = script;
|
||||||
|
d->fontData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Format::FontUnderline Format::fontUnderline() const
|
Format::FontUnderline Format::fontUnderline() const
|
||||||
{
|
{
|
||||||
return m_font.underline;
|
Q_D(const Format);
|
||||||
|
return d->fontData.underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setFontUnderline(FontUnderline underline)
|
void Format::setFontUnderline(FontUnderline underline)
|
||||||
{
|
{
|
||||||
m_font.underline = underline;
|
Q_D(Format);
|
||||||
m_font._dirty = true;
|
d->fontData.underline = underline;
|
||||||
|
d->fontData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Format::fontOutline() const
|
bool Format::fontOutline() const
|
||||||
{
|
{
|
||||||
return m_font.outline;
|
Q_D(const Format);
|
||||||
|
return d->fontData.outline;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setFontOutline(bool outline)
|
void Format::setFontOutline(bool outline)
|
||||||
{
|
{
|
||||||
m_font.outline = outline;
|
Q_D(Format);
|
||||||
m_font._dirty = true;
|
d->fontData.outline = outline;
|
||||||
|
d->fontData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Format::fontName() const
|
QString Format::fontName() const
|
||||||
{
|
{
|
||||||
return m_font.name;
|
Q_D(const Format);
|
||||||
|
return d->fontData.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setFontName(const QString &name)
|
void Format::setFontName(const QString &name)
|
||||||
{
|
{
|
||||||
m_font.name = name;
|
Q_D(Format);
|
||||||
m_font._dirty = true;
|
d->fontData.name = name;
|
||||||
|
d->fontData._dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Format::hasFont() const
|
||||||
|
{
|
||||||
|
Q_D(const Format);
|
||||||
|
return !d->fontData._redundant;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Format::setFontRedundant(bool redundant)
|
||||||
|
{
|
||||||
|
Q_D(Format);
|
||||||
|
d->fontData._redundant = redundant;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Format::fontIndex() const
|
||||||
|
{
|
||||||
|
Q_D(const Format);
|
||||||
|
return d->fontData._index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Format::setFontIndex(int index)
|
||||||
|
{
|
||||||
|
Q_D(Format);
|
||||||
|
d->fontData._index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Format::fontFamily() const
|
||||||
|
{
|
||||||
|
Q_D(const Format);
|
||||||
|
return d->fontData.family;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Format::fontShadow() const
|
||||||
|
{
|
||||||
|
Q_D(const Format);
|
||||||
|
return d->fontData.shadow;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Format::fontScheme() const
|
||||||
|
{
|
||||||
|
Q_D(const Format);
|
||||||
|
return d->fontData.scheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Internal
|
/* Internal
|
||||||
*/
|
*/
|
||||||
QByteArray Format::fontKey() const
|
QByteArray Format::fontKey() const
|
||||||
{
|
{
|
||||||
if (m_font._dirty) {
|
Q_D(const Format);
|
||||||
|
if (d->fontData._dirty) {
|
||||||
QByteArray key;
|
QByteArray key;
|
||||||
QDataStream stream(&key, QIODevice::WriteOnly);
|
QDataStream stream(&key, QIODevice::WriteOnly);
|
||||||
stream<<m_font.bold<<m_font.charset<<m_font.color<<m_font.condense
|
stream<<d->fontData.bold<<d->fontData.charset<<d->fontData.color<<d->fontData.condense
|
||||||
<<m_font.extend<<m_font.family<<m_font.italic<<m_font.name
|
<<d->fontData.extend<<d->fontData.family<<d->fontData.italic<<d->fontData.name
|
||||||
<<m_font.outline<<m_font.scheme<<m_font.scirpt<<m_font.shadow
|
<<d->fontData.outline<<d->fontData.scheme<<d->fontData.scirpt<<d->fontData.shadow
|
||||||
<<m_font.size<<m_font.strikeOut<<m_font.underline;
|
<<d->fontData.size<<d->fontData.strikeOut<<d->fontData.underline;
|
||||||
|
|
||||||
const_cast<Format*>(this)->m_font._key = key;
|
const_cast<FormatPrivate*>(d)->fontData._key = key;
|
||||||
const_cast<Format*>(this)->m_font._dirty = false;
|
const_cast<FormatPrivate*>(d)->fontData._dirty = false;
|
||||||
const_cast<Format*>(this)->m_dirty = true; //Make sure formatKey() will be re-generated.
|
const_cast<FormatPrivate*>(d)->dirty = true; //Make sure formatKey() will be re-generated.
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_font._key;
|
return d->fontData._key;
|
||||||
}
|
}
|
||||||
|
|
||||||
Format::HorizontalAlignment Format::horizontalAlignment() const
|
Format::HorizontalAlignment Format::horizontalAlignment() const
|
||||||
{
|
{
|
||||||
return m_alignment.alignH;
|
Q_D(const Format);
|
||||||
|
return d->alignmentData.alignH;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setHorizontalAlignment(HorizontalAlignment align)
|
void Format::setHorizontalAlignment(HorizontalAlignment align)
|
||||||
{
|
{
|
||||||
if (m_alignment.indent &&(align != AlignHGeneral && align != AlignLeft &&
|
Q_D(Format);
|
||||||
|
if (d->alignmentData.indent &&(align != AlignHGeneral && align != AlignLeft &&
|
||||||
align != AlignRight && align != AlignHDistributed)) {
|
align != AlignRight && align != AlignHDistributed)) {
|
||||||
m_alignment.indent = 0;
|
d->alignmentData.indent = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_alignment.shinkToFit && (align == AlignHFill || align == AlignHJustify
|
if (d->alignmentData.shinkToFit && (align == AlignHFill || align == AlignHJustify
|
||||||
|| align == AlignHDistributed)) {
|
|| align == AlignHDistributed)) {
|
||||||
m_alignment.shinkToFit = false;
|
d->alignmentData.shinkToFit = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_alignment.alignH = align;
|
d->alignmentData.alignH = align;
|
||||||
m_dirty = true;
|
d->dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Format::VerticalAlignment Format::verticalAlignment() const
|
Format::VerticalAlignment Format::verticalAlignment() const
|
||||||
{
|
{
|
||||||
return m_alignment.alignV;
|
Q_D(const Format);
|
||||||
|
return d->alignmentData.alignV;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setVerticalAlignment(VerticalAlignment align)
|
void Format::setVerticalAlignment(VerticalAlignment align)
|
||||||
{
|
{
|
||||||
m_alignment.alignV = align;
|
Q_D(Format);
|
||||||
m_dirty = true;
|
d->alignmentData.alignV = align;
|
||||||
|
d->dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Format::textWrap() const
|
bool Format::textWrap() const
|
||||||
{
|
{
|
||||||
return m_alignment.wrap;
|
Q_D(const Format);
|
||||||
|
return d->alignmentData.wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setTextWarp(bool wrap)
|
void Format::setTextWarp(bool wrap)
|
||||||
{
|
{
|
||||||
if (wrap && m_alignment.shinkToFit)
|
Q_D(Format);
|
||||||
m_alignment.shinkToFit = false;
|
if (wrap && d->alignmentData.shinkToFit)
|
||||||
|
d->alignmentData.shinkToFit = false;
|
||||||
|
|
||||||
m_alignment.wrap = wrap;
|
d->alignmentData.wrap = wrap;
|
||||||
m_dirty = true;
|
d->dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Format::rotation() const
|
int Format::rotation() const
|
||||||
{
|
{
|
||||||
return m_alignment.rotation;
|
Q_D(const Format);
|
||||||
|
return d->alignmentData.rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setRotation(int rotation)
|
void Format::setRotation(int rotation)
|
||||||
{
|
{
|
||||||
m_alignment.rotation = rotation;
|
Q_D(Format);
|
||||||
m_dirty = true;
|
d->alignmentData.rotation = rotation;
|
||||||
|
d->dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Format::indent() const
|
int Format::indent() const
|
||||||
{
|
{
|
||||||
return m_alignment.indent;
|
Q_D(const Format);
|
||||||
|
return d->alignmentData.indent;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setIndent(int indent)
|
void Format::setIndent(int indent)
|
||||||
{
|
{
|
||||||
if (indent && (m_alignment.alignH != AlignHGeneral
|
Q_D(Format);
|
||||||
&& m_alignment.alignH != AlignLeft
|
if (indent && (d->alignmentData.alignH != AlignHGeneral
|
||||||
&& m_alignment.alignH != AlignRight
|
&& d->alignmentData.alignH != AlignLeft
|
||||||
&& m_alignment.alignH != AlignHJustify)) {
|
&& d->alignmentData.alignH != AlignRight
|
||||||
m_alignment.alignH = AlignLeft;
|
&& d->alignmentData.alignH != AlignHJustify)) {
|
||||||
|
d->alignmentData.alignH = AlignLeft;
|
||||||
}
|
}
|
||||||
m_alignment.indent = indent;
|
d->alignmentData.indent = indent;
|
||||||
m_dirty = true;
|
d->dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Format::shrinkToFit() const
|
bool Format::shrinkToFit() const
|
||||||
{
|
{
|
||||||
return m_alignment.shinkToFit;
|
Q_D(const Format);
|
||||||
|
return d->alignmentData.shinkToFit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setShrinkToFit(bool shink)
|
void Format::setShrinkToFit(bool shink)
|
||||||
{
|
{
|
||||||
if (shink && m_alignment.wrap)
|
Q_D(Format);
|
||||||
m_alignment.wrap = false;
|
if (shink && d->alignmentData.wrap)
|
||||||
if (shink && (m_alignment.alignH == AlignHFill
|
d->alignmentData.wrap = false;
|
||||||
|| m_alignment.alignH == AlignHJustify
|
if (shink && (d->alignmentData.alignH == AlignHFill
|
||||||
|| m_alignment.alignH == AlignHDistributed)) {
|
|| d->alignmentData.alignH == AlignHJustify
|
||||||
m_alignment.alignH = AlignLeft;
|
|| d->alignmentData.alignH == AlignHDistributed)) {
|
||||||
|
d->alignmentData.alignH = AlignLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_alignment.shinkToFit = shink;
|
d->alignmentData.shinkToFit = shink;
|
||||||
m_dirty = true;
|
d->dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Format::alignmentChanged() const
|
bool Format::alignmentChanged() const
|
||||||
{
|
{
|
||||||
return m_alignment.alignH != AlignHGeneral
|
Q_D(const Format);
|
||||||
|| m_alignment.alignV != AlignBottom
|
return d->alignmentData.alignH != AlignHGeneral
|
||||||
|| m_alignment.indent != 0
|
|| d->alignmentData.alignV != AlignBottom
|
||||||
|| m_alignment.wrap
|
|| d->alignmentData.indent != 0
|
||||||
|| m_alignment.rotation != 0
|
|| d->alignmentData.wrap
|
||||||
|| m_alignment.shinkToFit;
|
|| d->alignmentData.rotation != 0
|
||||||
|
|| d->alignmentData.shinkToFit;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Format::horizontalAlignmentString() const
|
QString Format::horizontalAlignmentString() const
|
||||||
{
|
{
|
||||||
|
Q_D(const Format);
|
||||||
QString alignH;
|
QString alignH;
|
||||||
switch (m_alignment.alignH) {
|
switch (d->alignmentData.alignH) {
|
||||||
case Format::AlignLeft:
|
case Format::AlignLeft:
|
||||||
alignH = "left";
|
alignH = "left";
|
||||||
break;
|
break;
|
||||||
@@ -362,8 +399,9 @@ QString Format::horizontalAlignmentString() const
|
|||||||
|
|
||||||
QString Format::verticalAlignmentString() const
|
QString Format::verticalAlignmentString() const
|
||||||
{
|
{
|
||||||
|
Q_D(const Format);
|
||||||
QString align;
|
QString align;
|
||||||
switch (m_alignment.alignV) {
|
switch (d->alignmentData.alignV) {
|
||||||
case AlignTop:
|
case AlignTop:
|
||||||
align = "top";
|
align = "top";
|
||||||
break;
|
break;
|
||||||
@@ -400,236 +438,318 @@ void Format::setBorderColor(const QColor &color)
|
|||||||
|
|
||||||
Format::BorderStyle Format::leftBorderStyle() const
|
Format::BorderStyle Format::leftBorderStyle() const
|
||||||
{
|
{
|
||||||
return m_border.left;
|
Q_D(const Format);
|
||||||
|
return d->borderData.left;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setLeftBorderStyle(BorderStyle style)
|
void Format::setLeftBorderStyle(BorderStyle style)
|
||||||
{
|
{
|
||||||
m_border.left = style;
|
Q_D(Format);
|
||||||
m_border._dirty = true;
|
d->borderData.left = style;
|
||||||
|
d->borderData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor Format::leftBorderColor() const
|
QColor Format::leftBorderColor() const
|
||||||
{
|
{
|
||||||
return m_border.leftColor;
|
Q_D(const Format);
|
||||||
|
return d->borderData.leftColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setLeftBorderColor(const QColor &color)
|
void Format::setLeftBorderColor(const QColor &color)
|
||||||
{
|
{
|
||||||
m_border.leftColor = color;
|
Q_D(Format);
|
||||||
m_border._dirty = true;
|
d->borderData.leftColor = color;
|
||||||
|
d->borderData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Format::BorderStyle Format::rightBorderStyle() const
|
Format::BorderStyle Format::rightBorderStyle() const
|
||||||
{
|
{
|
||||||
return m_border.right;
|
Q_D(const Format);
|
||||||
|
return d->borderData.right;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setRightBorderStyle(BorderStyle style)
|
void Format::setRightBorderStyle(BorderStyle style)
|
||||||
{
|
{
|
||||||
m_border.right = style;
|
Q_D(Format);
|
||||||
m_border._dirty = true;
|
d->borderData.right = style;
|
||||||
|
d->borderData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor Format::rightBorderColor() const
|
QColor Format::rightBorderColor() const
|
||||||
{
|
{
|
||||||
return m_border.rightColor;
|
Q_D(const Format);
|
||||||
|
return d->borderData.rightColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setRightBorderColor(const QColor &color)
|
void Format::setRightBorderColor(const QColor &color)
|
||||||
{
|
{
|
||||||
m_border.rightColor = color;
|
Q_D(Format);
|
||||||
m_border._dirty = true;
|
d->borderData.rightColor = color;
|
||||||
|
d->borderData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Format::BorderStyle Format::topBorderStyle() const
|
Format::BorderStyle Format::topBorderStyle() const
|
||||||
{
|
{
|
||||||
return m_border.top;
|
Q_D(const Format);
|
||||||
|
return d->borderData.top;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setTopBorderStyle(BorderStyle style)
|
void Format::setTopBorderStyle(BorderStyle style)
|
||||||
{
|
{
|
||||||
m_border.top = style;
|
Q_D(Format);
|
||||||
m_border._dirty = true;
|
d->borderData.top = style;
|
||||||
|
d->borderData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor Format::topBorderColor() const
|
QColor Format::topBorderColor() const
|
||||||
{
|
{
|
||||||
return m_border.topColor;
|
Q_D(const Format);
|
||||||
|
return d->borderData.topColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setTopBorderColor(const QColor &color)
|
void Format::setTopBorderColor(const QColor &color)
|
||||||
{
|
{
|
||||||
m_border.topColor = color;
|
Q_D(Format);
|
||||||
m_border._dirty = true;
|
d->borderData.topColor = color;
|
||||||
|
d->borderData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Format::BorderStyle Format::bottomBorderStyle() const
|
Format::BorderStyle Format::bottomBorderStyle() const
|
||||||
{
|
{
|
||||||
return m_border.bottom;
|
Q_D(const Format);
|
||||||
|
return d->borderData.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setBottomBorderStyle(BorderStyle style)
|
void Format::setBottomBorderStyle(BorderStyle style)
|
||||||
{
|
{
|
||||||
m_border.bottom = style;
|
Q_D(Format);
|
||||||
m_border._dirty = true;
|
d->borderData.bottom = style;
|
||||||
|
d->borderData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor Format::bottomBorderColor() const
|
QColor Format::bottomBorderColor() const
|
||||||
{
|
{
|
||||||
return m_border.bottomColor;
|
Q_D(const Format);
|
||||||
|
return d->borderData.bottomColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setBottomBorderColor(const QColor &color)
|
void Format::setBottomBorderColor(const QColor &color)
|
||||||
{
|
{
|
||||||
m_border.bottomColor = color;
|
Q_D(Format);
|
||||||
m_border._dirty = true;
|
d->borderData.bottomColor = color;
|
||||||
|
d->borderData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Format::BorderStyle Format::diagonalBorderStyle() const
|
Format::BorderStyle Format::diagonalBorderStyle() const
|
||||||
{
|
{
|
||||||
return m_border.diagonal;
|
Q_D(const Format);
|
||||||
|
return d->borderData.diagonal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setDiagonalBorderStyle(BorderStyle style)
|
void Format::setDiagonalBorderStyle(BorderStyle style)
|
||||||
{
|
{
|
||||||
m_border.diagonal = style;
|
Q_D(Format);
|
||||||
m_border._dirty = true;
|
d->borderData.diagonal = style;
|
||||||
|
d->borderData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Format::DiagonalBorderType Format::diagonalBorderType() const
|
Format::DiagonalBorderType Format::diagonalBorderType() const
|
||||||
{
|
{
|
||||||
return m_border.diagonalType;
|
Q_D(const Format);
|
||||||
|
return d->borderData.diagonalType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setDiagonalBorderType(DiagonalBorderType style)
|
void Format::setDiagonalBorderType(DiagonalBorderType style)
|
||||||
{
|
{
|
||||||
m_border.diagonalType = style;
|
Q_D(Format);
|
||||||
m_border._dirty = true;
|
d->borderData.diagonalType = style;
|
||||||
|
d->borderData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor Format::diagonalBorderColor() const
|
QColor Format::diagonalBorderColor() const
|
||||||
{
|
{
|
||||||
return m_border.diagonalColor;
|
Q_D(const Format);
|
||||||
|
return d->borderData.diagonalColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setDiagonalBorderColor(const QColor &color)
|
void Format::setDiagonalBorderColor(const QColor &color)
|
||||||
{
|
{
|
||||||
m_border.diagonalColor = color;
|
Q_D(Format);
|
||||||
m_border._dirty = true;
|
d->borderData.diagonalColor = color;
|
||||||
|
d->borderData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Format::hasBorders() const
|
||||||
|
{
|
||||||
|
Q_D(const Format);
|
||||||
|
return !d->borderData._redundant;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Format::setBorderRedundant(bool redundant)
|
||||||
|
{
|
||||||
|
Q_D(Format);
|
||||||
|
d->borderData._redundant = redundant;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Format::borderIndex() const
|
||||||
|
{
|
||||||
|
Q_D(const Format);
|
||||||
|
return d->borderData._index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Format::setBorderIndex(int index)
|
||||||
|
{
|
||||||
|
Q_D(Format);
|
||||||
|
d->borderData._index = index;
|
||||||
|
}
|
||||||
|
|
||||||
/* Internal
|
/* Internal
|
||||||
*/
|
*/
|
||||||
QByteArray Format::borderKey() const
|
QByteArray Format::borderKey() const
|
||||||
{
|
{
|
||||||
if (m_border._dirty) {
|
Q_D(const Format);
|
||||||
|
if (d->borderData._dirty) {
|
||||||
QByteArray key;
|
QByteArray key;
|
||||||
QDataStream stream(&key, QIODevice::WriteOnly);
|
QDataStream stream(&key, QIODevice::WriteOnly);
|
||||||
stream<<m_border.bottom<<m_border.bottomColor
|
stream<<d->borderData.bottom<<d->borderData.bottomColor
|
||||||
<<m_border.diagonal<<m_border.diagonalColor<<m_border.diagonalType
|
<<d->borderData.diagonal<<d->borderData.diagonalColor<<d->borderData.diagonalType
|
||||||
<<m_border.left<<m_border.leftColor
|
<<d->borderData.left<<d->borderData.leftColor
|
||||||
<<m_border.right<<m_border.rightColor
|
<<d->borderData.right<<d->borderData.rightColor
|
||||||
<<m_border.top<<m_border.topColor;
|
<<d->borderData.top<<d->borderData.topColor;
|
||||||
const_cast<Format*>(this)->m_border._key = key;
|
const_cast<FormatPrivate*>(d)->borderData._key = key;
|
||||||
const_cast<Format*>(this)->m_border._dirty = false;
|
const_cast<FormatPrivate*>(d)->borderData._dirty = false;
|
||||||
const_cast<Format*>(this)->m_dirty = true; //Make sure formatKey() will be re-generated.
|
const_cast<FormatPrivate*>(d)->dirty = true; //Make sure formatKey() will be re-generated.
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_border._key;
|
return d->borderData._key;
|
||||||
}
|
}
|
||||||
|
|
||||||
Format::FillPattern Format::fillPattern() const
|
Format::FillPattern Format::fillPattern() const
|
||||||
{
|
{
|
||||||
return m_fill.pattern;
|
Q_D(const Format);
|
||||||
|
return d->fillData.pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setFillPattern(FillPattern pattern)
|
void Format::setFillPattern(FillPattern pattern)
|
||||||
{
|
{
|
||||||
m_fill.pattern = pattern;
|
Q_D(Format);
|
||||||
m_fill._dirty = true;
|
d->fillData.pattern = pattern;
|
||||||
|
d->fillData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor Format::patternForegroundColor() const
|
QColor Format::patternForegroundColor() const
|
||||||
{
|
{
|
||||||
return m_fill.fgColor;
|
Q_D(const Format);
|
||||||
|
return d->fillData.fgColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setPatternForegroundColor(const QColor &color)
|
void Format::setPatternForegroundColor(const QColor &color)
|
||||||
{
|
{
|
||||||
if (color.isValid() && m_fill.pattern == PatternNone)
|
Q_D(Format);
|
||||||
m_fill.pattern = PatternSolid;
|
if (color.isValid() && d->fillData.pattern == PatternNone)
|
||||||
m_fill.fgColor = color;
|
d->fillData.pattern = PatternSolid;
|
||||||
m_fill._dirty = true;
|
d->fillData.fgColor = color;
|
||||||
|
d->fillData._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor Format::patternBackgroundColor() const
|
QColor Format::patternBackgroundColor() const
|
||||||
{
|
{
|
||||||
return m_fill.bgColor;
|
Q_D(const Format);
|
||||||
|
return d->fillData.bgColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setPatternBackgroundColor(const QColor &color)
|
void Format::setPatternBackgroundColor(const QColor &color)
|
||||||
{
|
{
|
||||||
if (color.isValid() && m_fill.pattern == PatternNone)
|
Q_D(Format);
|
||||||
m_fill.pattern = PatternSolid;
|
if (color.isValid() && d->fillData.pattern == PatternNone)
|
||||||
m_fill.bgColor = color;
|
d->fillData.pattern = PatternSolid;
|
||||||
m_fill._dirty = true;
|
d->fillData.bgColor = color;
|
||||||
|
d->fillData._dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Format::hasFill() const
|
||||||
|
{
|
||||||
|
Q_D(const Format);
|
||||||
|
return !d->fillData._redundant;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Format::setFillRedundant(bool redundant)
|
||||||
|
{
|
||||||
|
Q_D(Format);
|
||||||
|
d->fillData._redundant = redundant;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Format::fillIndex() const
|
||||||
|
{
|
||||||
|
Q_D(const Format);
|
||||||
|
return d->fillData._index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Format::setFillIndex(int index)
|
||||||
|
{
|
||||||
|
Q_D(Format);
|
||||||
|
d->fillData._index = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Internal
|
/* Internal
|
||||||
*/
|
*/
|
||||||
QByteArray Format::fillKey() const
|
QByteArray Format::fillKey() const
|
||||||
{
|
{
|
||||||
if (m_fill._dirty) {
|
Q_D(const Format);
|
||||||
|
if (d->fillData._dirty) {
|
||||||
QByteArray key;
|
QByteArray key;
|
||||||
QDataStream stream(&key, QIODevice::WriteOnly);
|
QDataStream stream(&key, QIODevice::WriteOnly);
|
||||||
stream<<m_fill.bgColor<<m_fill.fgColor<<m_fill.pattern;
|
stream<<d->fillData.bgColor<<d->fillData.fgColor<<d->fillData.pattern;
|
||||||
const_cast<Format*>(this)->m_fill._key = key;
|
const_cast<FormatPrivate*>(d)->fillData._key = key;
|
||||||
const_cast<Format*>(this)->m_fill._dirty = false;
|
const_cast<FormatPrivate*>(d)->fillData._dirty = false;
|
||||||
const_cast<Format*>(this)->m_dirty = true; //Make sure formatKey() will be re-generated.
|
const_cast<FormatPrivate*>(d)->dirty = true; //Make sure formatKey() will be re-generated.
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_fill._key;
|
return d->fillData._key;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Format::hidden() const
|
bool Format::hidden() const
|
||||||
{
|
{
|
||||||
return m_protection.hidden;
|
Q_D(const Format);
|
||||||
|
return d->protectionData.hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setHidden(bool hidden)
|
void Format::setHidden(bool hidden)
|
||||||
{
|
{
|
||||||
m_protection.hidden = hidden;
|
Q_D(Format);
|
||||||
m_dirty = true;
|
d->protectionData.hidden = hidden;
|
||||||
|
d->dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Format::locked() const
|
bool Format::locked() const
|
||||||
{
|
{
|
||||||
return m_protection.locked;
|
Q_D(const Format);
|
||||||
|
return d->protectionData.locked;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::setLocked(bool locked)
|
void Format::setLocked(bool locked)
|
||||||
{
|
{
|
||||||
m_protection.locked = locked;
|
Q_D(Format);
|
||||||
m_dirty = true;
|
d->protectionData.locked = locked;
|
||||||
|
d->dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray Format::formatKey() const
|
QByteArray Format::formatKey() const
|
||||||
{
|
{
|
||||||
if (m_dirty || m_font._dirty || m_border._dirty || m_fill._dirty) {
|
Q_D(const Format);
|
||||||
|
if (d->dirty || d->fontData._dirty || d->borderData._dirty || d->fillData._dirty) {
|
||||||
QByteArray key;
|
QByteArray key;
|
||||||
QDataStream stream(&key, QIODevice::WriteOnly);
|
QDataStream stream(&key, QIODevice::WriteOnly);
|
||||||
stream<<fontKey()<<borderKey()<<fillKey()
|
stream<<fontKey()<<borderKey()<<fillKey()
|
||||||
<<m_number.formatIndex
|
<<d->numberData.formatIndex
|
||||||
<<m_alignment.alignH<<m_alignment.alignV<<m_alignment.indent
|
<<d->alignmentData.alignH<<d->alignmentData.alignV<<d->alignmentData.indent
|
||||||
<<m_alignment.rotation<<m_alignment.shinkToFit<<m_alignment.wrap
|
<<d->alignmentData.rotation<<d->alignmentData.shinkToFit<<d->alignmentData.wrap
|
||||||
<<m_protection.hidden<<m_protection.locked;
|
<<d->protectionData.hidden<<d->protectionData.locked;
|
||||||
const_cast<Format*>(this)->m_formatKey = key;
|
const_cast<FormatPrivate*>(d)->formatKey = key;
|
||||||
const_cast<Format*>(this)->m_dirty = false;
|
const_cast<FormatPrivate*>(d)->dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_formatKey;
|
return d->formatKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Format::operator ==(const Format &format) const
|
bool Format::operator ==(const Format &format) const
|
||||||
@@ -650,35 +770,60 @@ bool Format::operator !=(const Format &format) const
|
|||||||
*/
|
*/
|
||||||
int Format::xfIndex(bool generateIfNotValid)
|
int Format::xfIndex(bool generateIfNotValid)
|
||||||
{
|
{
|
||||||
if (m_xf_index == -1 && generateIfNotValid) { //Generate a valid xf_index for this format
|
Q_D(Format);
|
||||||
|
if (d->xf_index == -1 && generateIfNotValid) { //Generate a valid xf_index for this format
|
||||||
int index = -1;
|
int index = -1;
|
||||||
for (int i=0; i<s_xfFormats.size(); ++i) {
|
for (int i=0; i<d->s_xfFormats.size(); ++i) {
|
||||||
if (*s_xfFormats[i] == *this) {
|
if (*d->s_xfFormats[i] == *this) {
|
||||||
index = i;
|
index = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
m_xf_index = index;
|
d->xf_index = index;
|
||||||
} else {
|
} else {
|
||||||
m_xf_index = s_xfFormats.size();
|
d->xf_index = d->s_xfFormats.size();
|
||||||
s_xfFormats.append(this);
|
d->s_xfFormats.append(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return m_xf_index;
|
return d->xf_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Format::clearExtraInfos()
|
void Format::clearExtraInfos()
|
||||||
{
|
{
|
||||||
m_xf_index = -1;
|
Q_D(Format);
|
||||||
m_dxf_index = -1;
|
d->xf_index = -1;
|
||||||
s_xfFormats.clear();
|
d->dxf_index = -1;
|
||||||
s_dxfFormats.clear();
|
d->s_xfFormats.clear();
|
||||||
|
d->s_dxfFormats.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Format::isDxfFormat() const
|
bool Format::isDxfFormat() const
|
||||||
{
|
{
|
||||||
return m_is_dxf_fomat;
|
Q_D(const Format);
|
||||||
|
return d->is_dxf_fomat;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Format::theme() const
|
||||||
|
{
|
||||||
|
Q_D(const Format);
|
||||||
|
return d->theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Format::colorIndexed() const
|
||||||
|
{
|
||||||
|
Q_D(const Format);
|
||||||
|
return d->color_indexed;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<Format *> Format::xfFormats()
|
||||||
|
{
|
||||||
|
return FormatPrivate::s_xfFormats;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<Format *> Format::dxfFormats()
|
||||||
|
{
|
||||||
|
return FormatPrivate::s_dxfFormats;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace QXlsx
|
} // namespace QXlsx
|
||||||
|
|||||||
+26
-103
@@ -34,9 +34,12 @@ namespace QXlsx {
|
|||||||
|
|
||||||
class Styles;
|
class Styles;
|
||||||
class Worksheet;
|
class Worksheet;
|
||||||
|
class WorksheetPrivate;
|
||||||
|
|
||||||
|
class FormatPrivate;
|
||||||
class Format
|
class Format
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PRIVATE(Format)
|
||||||
public:
|
public:
|
||||||
enum FontScript
|
enum FontScript
|
||||||
{
|
{
|
||||||
@@ -123,6 +126,8 @@ public:
|
|||||||
PatternGray0625
|
PatternGray0625
|
||||||
};
|
};
|
||||||
|
|
||||||
|
~Format();
|
||||||
|
|
||||||
int numberFormat() const;
|
int numberFormat() const;
|
||||||
void setNumberFormat(int format);
|
void setNumberFormat(int format);
|
||||||
|
|
||||||
@@ -201,129 +206,47 @@ public:
|
|||||||
private:
|
private:
|
||||||
friend class Styles;
|
friend class Styles;
|
||||||
friend class Worksheet;
|
friend class Worksheet;
|
||||||
|
friend class WorksheetPrivate;
|
||||||
Format();
|
Format();
|
||||||
|
|
||||||
struct NumberData
|
bool hasFont() const;
|
||||||
{
|
void setFontRedundant(bool redundant);
|
||||||
int formatIndex;
|
int fontIndex() const;
|
||||||
} m_number;
|
void setFontIndex(int index);
|
||||||
|
|
||||||
struct FontData
|
|
||||||
{
|
|
||||||
int size;
|
|
||||||
bool italic;
|
|
||||||
bool strikeOut;
|
|
||||||
QColor color;
|
|
||||||
bool bold;
|
|
||||||
FontScript scirpt;
|
|
||||||
FontUnderline underline;
|
|
||||||
bool outline;
|
|
||||||
bool shadow;
|
|
||||||
QString name;
|
|
||||||
int family;
|
|
||||||
int charset;
|
|
||||||
QString scheme;
|
|
||||||
int condense;
|
|
||||||
int extend;
|
|
||||||
|
|
||||||
//helper member
|
|
||||||
bool _dirty; //key re-generated is need.
|
|
||||||
QByteArray _key;
|
|
||||||
bool _redundant; //same font already used by some other Formats
|
|
||||||
int _index; //index in the Font list
|
|
||||||
} m_font;
|
|
||||||
bool hasFont() const {return !m_font._redundant;}
|
|
||||||
void setFontRedundant(bool redundant) {m_font._redundant = redundant;}
|
|
||||||
int fontIndex() const {return m_font._index;}
|
|
||||||
void setFontIndex(int index) {m_font._index = index;}
|
|
||||||
QByteArray fontKey() const;
|
QByteArray fontKey() const;
|
||||||
int fontFamily() const{return m_font.family;}
|
int fontFamily() const;
|
||||||
bool fontShadow() const {return m_font.shadow;}
|
bool fontShadow() const;
|
||||||
QString fontScheme() const {return m_font.scheme;}
|
QString fontScheme() const;
|
||||||
|
|
||||||
struct AlignmentData
|
|
||||||
{
|
|
||||||
HorizontalAlignment alignH;
|
|
||||||
VerticalAlignment alignV;
|
|
||||||
bool wrap;
|
|
||||||
int rotation;
|
|
||||||
int indent;
|
|
||||||
bool shinkToFit;
|
|
||||||
} m_alignment;
|
|
||||||
|
|
||||||
bool alignmentChanged() const;
|
bool alignmentChanged() const;
|
||||||
QString horizontalAlignmentString() const;
|
QString horizontalAlignmentString() const;
|
||||||
QString verticalAlignmentString() const;
|
QString verticalAlignmentString() const;
|
||||||
|
|
||||||
struct BorderData
|
|
||||||
{
|
|
||||||
BorderStyle left;
|
|
||||||
BorderStyle right;
|
|
||||||
BorderStyle top;
|
|
||||||
BorderStyle bottom;
|
|
||||||
BorderStyle diagonal;
|
|
||||||
QColor leftColor;
|
|
||||||
QColor rightColor;
|
|
||||||
QColor topColor;
|
|
||||||
QColor bottomColor;
|
|
||||||
QColor diagonalColor;
|
|
||||||
DiagonalBorderType diagonalType;
|
|
||||||
|
|
||||||
//helper member
|
|
||||||
bool _dirty; //key re-generated is need.
|
|
||||||
QByteArray _key;
|
|
||||||
bool _redundant; //same border already used by some other Formats
|
|
||||||
int _index; //index in the border list
|
|
||||||
} m_border;
|
|
||||||
|
|
||||||
QByteArray borderKey() const;
|
QByteArray borderKey() const;
|
||||||
bool hasBorders() const {return !m_border._redundant;}
|
bool hasBorders() const;
|
||||||
void setBorderRedundant(bool redundant) {m_border._redundant = redundant;}
|
void setBorderRedundant(bool redundant);
|
||||||
int borderIndex() const {return m_border._index;}
|
int borderIndex() const;
|
||||||
void setBorderIndex(int index) {m_border._index = index;}
|
void setBorderIndex(int index);
|
||||||
|
|
||||||
struct FillData {
|
|
||||||
FillPattern pattern;
|
|
||||||
QColor bgColor;
|
|
||||||
QColor fgColor;
|
|
||||||
|
|
||||||
//helper member
|
|
||||||
bool _dirty; //key re-generated is need.
|
|
||||||
QByteArray _key;
|
|
||||||
bool _redundant; //same border already used by some other Formats
|
|
||||||
int _index; //index in the border list
|
|
||||||
} m_fill;
|
|
||||||
|
|
||||||
QByteArray fillKey() const;
|
QByteArray fillKey() const;
|
||||||
bool hasFill() const {return !m_fill._redundant;}
|
bool hasFill() const;
|
||||||
void setFillRedundant(bool redundant) {m_fill._redundant = redundant;}
|
void setFillRedundant(bool redundant);
|
||||||
int fillIndex() const {return m_fill._index;}
|
int fillIndex() const;
|
||||||
void setFillIndex(int index) {m_fill._index = index;}
|
void setFillIndex(int index);
|
||||||
|
|
||||||
struct ProtectionData {
|
|
||||||
bool locked;
|
|
||||||
bool hidden;
|
|
||||||
} m_protection;
|
|
||||||
|
|
||||||
bool m_dirty; //The key re-generation is need.
|
|
||||||
QByteArray m_formatKey;
|
|
||||||
QByteArray formatKey() const;
|
QByteArray formatKey() const;
|
||||||
|
|
||||||
static QList<Format *> s_xfFormats;
|
static QList<Format *> xfFormats();
|
||||||
int m_xf_index;
|
static QList<Format *> dxfFormats();
|
||||||
int xfIndex(bool generateIfNotValid=true); //Generate index when first called.
|
int xfIndex(bool generateIfNotValid=true); //Generate index when first called.
|
||||||
void clearExtraInfos();
|
void clearExtraInfos();
|
||||||
|
|
||||||
bool m_is_dxf_fomat;
|
|
||||||
int m_dxf_index;
|
|
||||||
static QList<Format *> s_dxfFormats;
|
|
||||||
bool isDxfFormat() const;
|
bool isDxfFormat() const;
|
||||||
|
|
||||||
int m_theme;
|
int theme() const;
|
||||||
int m_color_indexed;
|
int colorIndexed() const;
|
||||||
int theme() const {return m_theme;}
|
|
||||||
int colorIndexed() const {return m_color_indexed;}
|
|
||||||
|
|
||||||
|
FormatPrivate * const d_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QXlsx
|
} // namespace QXlsx
|
||||||
|
|||||||
@@ -0,0 +1,172 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
|
||||||
|
** All right reserved.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
** a copy of this software and associated documentation files (the
|
||||||
|
** "Software"), to deal in the Software without restriction, including
|
||||||
|
** without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
** permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
** the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be
|
||||||
|
** included in all copies or substantial portions of the Software.
|
||||||
|
**
|
||||||
|
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef XLSXFORMAT_P_H
|
||||||
|
#define XLSXFORMAT_P_H
|
||||||
|
#include "xlsxformat.h"
|
||||||
|
|
||||||
|
namespace QXlsx {
|
||||||
|
|
||||||
|
struct NumberData
|
||||||
|
{
|
||||||
|
NumberData() : formatIndex(0) {}
|
||||||
|
|
||||||
|
int formatIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FontData
|
||||||
|
{
|
||||||
|
FontData() :
|
||||||
|
size(11), italic(false), strikeOut(false), color(QColor()), bold(false)
|
||||||
|
, scirpt(Format::FontScriptNormal), underline(Format::FontUnderlineNone)
|
||||||
|
, outline(false), shadow(false), name("Calibri"), family(2), charset(0)
|
||||||
|
, scheme("minor"), condense(0), extend(0)
|
||||||
|
, _dirty(true), _redundant(false), _index(-1)
|
||||||
|
|
||||||
|
{}
|
||||||
|
|
||||||
|
int size;
|
||||||
|
bool italic;
|
||||||
|
bool strikeOut;
|
||||||
|
QColor color;
|
||||||
|
bool bold;
|
||||||
|
Format::FontScript scirpt;
|
||||||
|
Format::FontUnderline underline;
|
||||||
|
bool outline;
|
||||||
|
bool shadow;
|
||||||
|
QString name;
|
||||||
|
int family;
|
||||||
|
int charset;
|
||||||
|
QString scheme;
|
||||||
|
int condense;
|
||||||
|
int extend;
|
||||||
|
|
||||||
|
//helper member
|
||||||
|
bool _dirty; //key re-generated is need.
|
||||||
|
QByteArray _key;
|
||||||
|
bool _redundant; //same font already used by some other Formats
|
||||||
|
int _index; //index in the Font list
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AlignmentData
|
||||||
|
{
|
||||||
|
AlignmentData() :
|
||||||
|
alignH(Format::AlignHGeneral), alignV(Format::AlignBottom)
|
||||||
|
, wrap(false), rotation(0), indent(0), shinkToFit(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Format::HorizontalAlignment alignH;
|
||||||
|
Format::VerticalAlignment alignV;
|
||||||
|
bool wrap;
|
||||||
|
int rotation;
|
||||||
|
int indent;
|
||||||
|
bool shinkToFit;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BorderData
|
||||||
|
{
|
||||||
|
BorderData() :
|
||||||
|
left(Format::BorderNone), right(Format::BorderNone), top(Format::BorderNone)
|
||||||
|
,bottom(Format::BorderNone), diagonal(Format::BorderNone)
|
||||||
|
,diagonalType(Format::DiagonalBorderNone)
|
||||||
|
,_dirty(true), _redundant(false), _index(-1)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Format::BorderStyle left;
|
||||||
|
Format::BorderStyle right;
|
||||||
|
Format::BorderStyle top;
|
||||||
|
Format::BorderStyle bottom;
|
||||||
|
Format::BorderStyle diagonal;
|
||||||
|
QColor leftColor;
|
||||||
|
QColor rightColor;
|
||||||
|
QColor topColor;
|
||||||
|
QColor bottomColor;
|
||||||
|
QColor diagonalColor;
|
||||||
|
Format::DiagonalBorderType diagonalType;
|
||||||
|
|
||||||
|
//helper member
|
||||||
|
bool _dirty; //key re-generated is need.
|
||||||
|
QByteArray _key;
|
||||||
|
bool _redundant; //same border already used by some other Formats
|
||||||
|
int _index; //index in the border list
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FillData {
|
||||||
|
FillData() :
|
||||||
|
pattern(Format::PatternNone)
|
||||||
|
,_dirty(true), _redundant(false), _index(-1)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Format::FillPattern pattern;
|
||||||
|
QColor bgColor;
|
||||||
|
QColor fgColor;
|
||||||
|
|
||||||
|
//helper member
|
||||||
|
bool _dirty; //key re-generated is need.
|
||||||
|
QByteArray _key;
|
||||||
|
bool _redundant; //same border already used by some other Formats
|
||||||
|
int _index; //index in the border list
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ProtectionData {
|
||||||
|
ProtectionData() :
|
||||||
|
locked(false), hidden(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool locked;
|
||||||
|
bool hidden;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FormatPrivate
|
||||||
|
{
|
||||||
|
Q_DECLARE_PUBLIC(Format)
|
||||||
|
public:
|
||||||
|
FormatPrivate(Format *p);
|
||||||
|
|
||||||
|
NumberData numberData;
|
||||||
|
FontData fontData;
|
||||||
|
AlignmentData alignmentData;
|
||||||
|
BorderData borderData;
|
||||||
|
FillData fillData;
|
||||||
|
ProtectionData protectionData;
|
||||||
|
|
||||||
|
bool dirty; //The key re-generation is need.
|
||||||
|
QByteArray formatKey;
|
||||||
|
|
||||||
|
static QList<Format *> s_xfFormats;
|
||||||
|
int xf_index;
|
||||||
|
|
||||||
|
static QList<Format *> s_dxfFormats;
|
||||||
|
bool is_dxf_fomat;
|
||||||
|
int dxf_index;
|
||||||
|
|
||||||
|
int theme;
|
||||||
|
int color_indexed;
|
||||||
|
|
||||||
|
Format *q_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // XLSXFORMAT_P_H
|
||||||
+2
-2
@@ -60,8 +60,8 @@ Format *Styles::addFormat()
|
|||||||
*/
|
*/
|
||||||
void Styles::prepareStyles()
|
void Styles::prepareStyles()
|
||||||
{
|
{
|
||||||
m_xf_formats = Format::s_xfFormats;
|
m_xf_formats = Format::xfFormats();
|
||||||
m_dxf_formats = Format::s_dxfFormats;
|
m_dxf_formats = Format::dxfFormats();
|
||||||
|
|
||||||
if (m_xf_formats.isEmpty())
|
if (m_xf_formats.isEmpty())
|
||||||
m_xf_formats.append(this->addFormat());
|
m_xf_formats.append(this->addFormat());
|
||||||
|
|||||||
+59
-39
@@ -23,6 +23,7 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include "xlsxworkbook.h"
|
#include "xlsxworkbook.h"
|
||||||
|
#include "xlsxworkbook_p.h"
|
||||||
#include "xlsxsharedstrings_p.h"
|
#include "xlsxsharedstrings_p.h"
|
||||||
#include "xlsxworksheet.h"
|
#include "xlsxworksheet.h"
|
||||||
#include "xlsxstyles_p.h"
|
#include "xlsxstyles_p.h"
|
||||||
@@ -32,44 +33,52 @@
|
|||||||
|
|
||||||
namespace QXlsx {
|
namespace QXlsx {
|
||||||
|
|
||||||
Workbook::Workbook(QObject *parent) :
|
WorkbookPrivate::WorkbookPrivate(Workbook *q) :
|
||||||
QObject(parent)
|
q_ptr(q)
|
||||||
{
|
{
|
||||||
m_sharedStrings = new SharedStrings(this);
|
sharedStrings = new SharedStrings(q);
|
||||||
m_styles = new Styles(this);
|
styles = new Styles(q);
|
||||||
|
|
||||||
|
x_window = 240;
|
||||||
|
y_window = 15;
|
||||||
|
window_width = 16095;
|
||||||
|
window_height = 9660;
|
||||||
|
|
||||||
m_x_window = 240;
|
strings_to_numbers_enabled = false;
|
||||||
m_y_window = 15;
|
date1904 = false;
|
||||||
m_window_width = 16095;
|
activesheet = 0;
|
||||||
m_window_height = 9660;
|
firstsheet = 0;
|
||||||
|
table_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Workbook::Workbook(QObject *parent) :
|
||||||
|
QObject(parent), d_ptr(new WorkbookPrivate(this))
|
||||||
|
{
|
||||||
|
|
||||||
m_strings_to_numbers_enabled = false;
|
|
||||||
m_date1904 = false;
|
|
||||||
m_activesheet = 0;
|
|
||||||
m_firstsheet = 0;
|
|
||||||
m_table_count = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Workbook::~Workbook()
|
Workbook::~Workbook()
|
||||||
{
|
{
|
||||||
|
delete d_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Workbook::save(const QString &name)
|
void Workbook::save(const QString &name)
|
||||||
{
|
{
|
||||||
|
Q_D(Workbook);
|
||||||
|
|
||||||
//Add a default worksheet if non have been added.
|
//Add a default worksheet if non have been added.
|
||||||
if (m_worksheets.size() == 0)
|
if (d->worksheets.size() == 0)
|
||||||
addWorksheet();
|
addWorksheet();
|
||||||
|
|
||||||
//Ensure that at least one worksheet has been selected.
|
//Ensure that at least one worksheet has been selected.
|
||||||
if (m_activesheet == 0) {
|
if (d->activesheet == 0) {
|
||||||
m_worksheets[0]->setHidden(false);
|
d->worksheets[0]->setHidden(false);
|
||||||
m_worksheets[0]->setSelected(true);
|
d->worksheets[0]->setSelected(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Set the active sheet
|
//Set the active sheet
|
||||||
foreach (Worksheet *sheet, m_worksheets) {
|
foreach (Worksheet *sheet, d->worksheets) {
|
||||||
if (sheet->index() == m_activesheet)
|
if (sheet->index() == d->activesheet)
|
||||||
sheet->setActived(true);
|
sheet->setActived(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +89,8 @@ void Workbook::save(const QString &name)
|
|||||||
|
|
||||||
bool Workbook::isDate1904() const
|
bool Workbook::isDate1904() const
|
||||||
{
|
{
|
||||||
return m_date1904;
|
Q_D(const Workbook);
|
||||||
|
return d->date1904;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -92,7 +102,8 @@ bool Workbook::isDate1904() const
|
|||||||
*/
|
*/
|
||||||
void Workbook::setDate1904(bool date1904)
|
void Workbook::setDate1904(bool date1904)
|
||||||
{
|
{
|
||||||
m_date1904 = date1904;
|
Q_D(Workbook);
|
||||||
|
d->date1904 = date1904;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -104,12 +115,14 @@ void Workbook::setDate1904(bool date1904)
|
|||||||
*/
|
*/
|
||||||
void Workbook::setStringsToNumbersEnabled(bool enable)
|
void Workbook::setStringsToNumbersEnabled(bool enable)
|
||||||
{
|
{
|
||||||
m_strings_to_numbers_enabled = enable;
|
Q_D(Workbook);
|
||||||
|
d->strings_to_numbers_enabled = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Workbook::isStringsToNumbersEnabled() const
|
bool Workbook::isStringsToNumbersEnabled() const
|
||||||
{
|
{
|
||||||
return m_strings_to_numbers_enabled;
|
Q_D(const Workbook);
|
||||||
|
return d->strings_to_numbers_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Workbook::defineName(const QString &name, const QString &formula)
|
void Workbook::defineName(const QString &name, const QString &formula)
|
||||||
@@ -119,38 +132,45 @@ void Workbook::defineName(const QString &name, const QString &formula)
|
|||||||
|
|
||||||
Worksheet *Workbook::addWorksheet(const QString &name)
|
Worksheet *Workbook::addWorksheet(const QString &name)
|
||||||
{
|
{
|
||||||
|
Q_D(Workbook);
|
||||||
|
|
||||||
QString worksheetName = name;
|
QString worksheetName = name;
|
||||||
int index = m_worksheets.size()+1;
|
int index = d->worksheets.size()+1;
|
||||||
if (name.isEmpty())
|
if (name.isEmpty())
|
||||||
worksheetName = QString("Sheet%1").arg(index);
|
worksheetName = QString("Sheet%1").arg(index);
|
||||||
|
|
||||||
Worksheet *sheet = new Worksheet(worksheetName, index, this);
|
Worksheet *sheet = new Worksheet(worksheetName, index, this);
|
||||||
m_worksheets.append(sheet);
|
d->worksheets.append(sheet);
|
||||||
return sheet;
|
return sheet;
|
||||||
}
|
}
|
||||||
|
|
||||||
Format *Workbook::addFormat()
|
Format *Workbook::addFormat()
|
||||||
{
|
{
|
||||||
return m_styles->addFormat();
|
Q_D(Workbook);
|
||||||
|
return d->styles->addFormat();
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Worksheet *> Workbook::worksheets() const
|
QList<Worksheet *> Workbook::worksheets() const
|
||||||
{
|
{
|
||||||
return m_worksheets;
|
Q_D(const Workbook);
|
||||||
|
return d->worksheets;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedStrings *Workbook::sharedStrings()
|
SharedStrings *Workbook::sharedStrings()
|
||||||
{
|
{
|
||||||
return m_sharedStrings;
|
Q_D(Workbook);
|
||||||
|
return d->sharedStrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
Styles *Workbook::styles()
|
Styles *Workbook::styles()
|
||||||
{
|
{
|
||||||
return m_styles;
|
Q_D(Workbook);
|
||||||
|
return d->styles;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Workbook::saveToXmlFile(QIODevice *device)
|
void Workbook::saveToXmlFile(QIODevice *device)
|
||||||
{
|
{
|
||||||
|
Q_D(Workbook);
|
||||||
XmlStreamWriter writer(device);
|
XmlStreamWriter writer(device);
|
||||||
|
|
||||||
writer.writeStartDocument("1.0", true);
|
writer.writeStartDocument("1.0", true);
|
||||||
@@ -166,26 +186,26 @@ void Workbook::saveToXmlFile(QIODevice *device)
|
|||||||
// writer.writeAttribute("codeName", "{37E998C4-C9E5-D4B9-71C8-EB1FF731991C}");
|
// writer.writeAttribute("codeName", "{37E998C4-C9E5-D4B9-71C8-EB1FF731991C}");
|
||||||
|
|
||||||
writer.writeEmptyElement("workbookPr");
|
writer.writeEmptyElement("workbookPr");
|
||||||
if (m_date1904)
|
if (d->date1904)
|
||||||
writer.writeAttribute("date1904", "1");
|
writer.writeAttribute("date1904", "1");
|
||||||
writer.writeAttribute("defaultThemeVersion", "124226");
|
writer.writeAttribute("defaultThemeVersion", "124226");
|
||||||
|
|
||||||
writer.writeStartElement("bookViews");
|
writer.writeStartElement("bookViews");
|
||||||
writer.writeEmptyElement("workbookView");
|
writer.writeEmptyElement("workbookView");
|
||||||
writer.writeAttribute("xWindow", QString::number(m_x_window));
|
writer.writeAttribute("xWindow", QString::number(d->x_window));
|
||||||
writer.writeAttribute("yWindow", QString::number(m_y_window));
|
writer.writeAttribute("yWindow", QString::number(d->y_window));
|
||||||
writer.writeAttribute("windowWidth", QString::number(m_window_width));
|
writer.writeAttribute("windowWidth", QString::number(d->window_width));
|
||||||
writer.writeAttribute("windowHeight", QString::number(m_window_height));
|
writer.writeAttribute("windowHeight", QString::number(d->window_height));
|
||||||
//Store the firstSheet when it isn't the default
|
//Store the firstSheet when it isn't the default
|
||||||
if (m_firstsheet > 0)
|
if (d->firstsheet > 0)
|
||||||
writer.writeAttribute("firstSheet", QString::number(m_firstsheet + 1));
|
writer.writeAttribute("firstSheet", QString::number(d->firstsheet + 1));
|
||||||
//Store the activeTab when it isn't the first sheet
|
//Store the activeTab when it isn't the first sheet
|
||||||
if (m_activesheet > 0)
|
if (d->activesheet > 0)
|
||||||
writer.writeAttribute("activeTab", QString::number(m_activesheet));
|
writer.writeAttribute("activeTab", QString::number(d->activesheet));
|
||||||
writer.writeEndElement();//bookviews
|
writer.writeEndElement();//bookviews
|
||||||
|
|
||||||
writer.writeStartElement("sheets");
|
writer.writeStartElement("sheets");
|
||||||
foreach (Worksheet *sheet, m_worksheets) {
|
foreach (Worksheet *sheet, d->worksheets) {
|
||||||
writer.writeEmptyElement("sheet");
|
writer.writeEmptyElement("sheet");
|
||||||
writer.writeAttribute("name", sheet->name());
|
writer.writeAttribute("name", sheet->name());
|
||||||
writer.writeAttribute("sheetId", QString::number(sheet->index()));
|
writer.writeAttribute("sheetId", QString::number(sheet->index()));
|
||||||
|
|||||||
+4
-15
@@ -37,13 +37,16 @@ class SharedStrings;
|
|||||||
class Styles;
|
class Styles;
|
||||||
class Package;
|
class Package;
|
||||||
|
|
||||||
|
class WorkbookPrivate;
|
||||||
class Workbook : public QObject
|
class Workbook : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_DECLARE_PRIVATE(Workbook)
|
||||||
public:
|
public:
|
||||||
Workbook(QObject *parent=0);
|
Workbook(QObject *parent=0);
|
||||||
~Workbook();
|
~Workbook();
|
||||||
|
|
||||||
|
QList<Worksheet *> worksheets() const;
|
||||||
Worksheet *addWorksheet(const QString &name = QString());
|
Worksheet *addWorksheet(const QString &name = QString());
|
||||||
Format *addFormat();
|
Format *addFormat();
|
||||||
// void addChart();
|
// void addChart();
|
||||||
@@ -59,25 +62,11 @@ private:
|
|||||||
friend class Package;
|
friend class Package;
|
||||||
friend class Worksheet;
|
friend class Worksheet;
|
||||||
|
|
||||||
QList<Worksheet *> worksheets() const;
|
|
||||||
SharedStrings *sharedStrings();
|
SharedStrings *sharedStrings();
|
||||||
Styles *styles();
|
Styles *styles();
|
||||||
void saveToXmlFile(QIODevice *device);
|
void saveToXmlFile(QIODevice *device);
|
||||||
|
|
||||||
SharedStrings *m_sharedStrings;
|
WorkbookPrivate * const d_ptr;
|
||||||
QList<Worksheet *> m_worksheets;
|
|
||||||
Styles *m_styles;
|
|
||||||
bool m_strings_to_numbers_enabled;
|
|
||||||
bool m_date1904;
|
|
||||||
|
|
||||||
int m_x_window;
|
|
||||||
int m_y_window;
|
|
||||||
int m_window_width;
|
|
||||||
int m_window_height;
|
|
||||||
|
|
||||||
int m_activesheet;
|
|
||||||
int m_firstsheet;
|
|
||||||
int m_table_count;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} //QXlsx
|
} //QXlsx
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
|
||||||
|
** All right reserved.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
** a copy of this software and associated documentation files (the
|
||||||
|
** "Software"), to deal in the Software without restriction, including
|
||||||
|
** without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
** permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
** the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be
|
||||||
|
** included in all copies or substantial portions of the Software.
|
||||||
|
**
|
||||||
|
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef XLSXWORKBOOK_P_H
|
||||||
|
#define XLSXWORKBOOK_P_H
|
||||||
|
#include "xlsxworkbook.h"
|
||||||
|
|
||||||
|
namespace QXlsx {
|
||||||
|
|
||||||
|
class WorkbookPrivate
|
||||||
|
{
|
||||||
|
Q_DECLARE_PUBLIC(Workbook)
|
||||||
|
public:
|
||||||
|
WorkbookPrivate(Workbook *q);
|
||||||
|
|
||||||
|
Workbook *q_ptr;
|
||||||
|
|
||||||
|
SharedStrings *sharedStrings;
|
||||||
|
QList<Worksheet *> worksheets;
|
||||||
|
Styles *styles;
|
||||||
|
|
||||||
|
bool strings_to_numbers_enabled;
|
||||||
|
bool date1904;
|
||||||
|
|
||||||
|
int x_window;
|
||||||
|
int y_window;
|
||||||
|
int window_width;
|
||||||
|
int window_height;
|
||||||
|
|
||||||
|
int activesheet;
|
||||||
|
int firstsheet;
|
||||||
|
int table_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // XLSXWORKBOOK_P_H
|
||||||
+241
-253
@@ -23,6 +23,7 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include "xlsxworksheet.h"
|
#include "xlsxworksheet.h"
|
||||||
|
#include "xlsxworksheet_p.h"
|
||||||
#include "xlsxworkbook.h"
|
#include "xlsxworkbook.h"
|
||||||
#include "xlsxformat.h"
|
#include "xlsxformat.h"
|
||||||
#include "xlsxutility_p.h"
|
#include "xlsxutility_p.h"
|
||||||
@@ -39,55 +40,157 @@
|
|||||||
|
|
||||||
namespace QXlsx {
|
namespace QXlsx {
|
||||||
|
|
||||||
struct XlsxCellData
|
WorksheetPrivate::WorksheetPrivate(Worksheet *p) :
|
||||||
|
q_ptr(p)
|
||||||
{
|
{
|
||||||
enum CellDataType {
|
xls_rowmax = 1048576;
|
||||||
Blank,
|
xls_colmax = 16384;
|
||||||
String,
|
xls_strmax = 32767;
|
||||||
Number,
|
dim_rowmin = INT32_MAX;
|
||||||
Formula,
|
dim_rowmax = INT32_MIN;
|
||||||
ArrayFormula,
|
dim_colmin = INT32_MAX;
|
||||||
Boolean,
|
dim_colmax = INT32_MIN;
|
||||||
DateTime
|
|
||||||
};
|
|
||||||
XlsxCellData(const QVariant &data=QVariant(), CellDataType type=Blank, Format *format=0) :
|
|
||||||
value(data), dataType(type), format(format)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
previous_row = 0;
|
||||||
|
|
||||||
|
outline_row_level = 0;
|
||||||
|
outline_col_level = 0;
|
||||||
|
|
||||||
|
default_row_height = 15;
|
||||||
|
default_row_zeroed = false;
|
||||||
|
|
||||||
|
hidden = false;
|
||||||
|
selected = false;
|
||||||
|
actived = false;
|
||||||
|
right_to_left = false;
|
||||||
|
show_zeros = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
WorksheetPrivate::~WorksheetPrivate()
|
||||||
|
{
|
||||||
|
typedef QMap<int, XlsxCellData *> RowMap;
|
||||||
|
foreach (RowMap row, cellTable) {
|
||||||
|
foreach (XlsxCellData *item, row)
|
||||||
|
delete item;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant value;
|
foreach (XlsxRowInfo *row, rowsInfo)
|
||||||
QString formula;
|
delete row;
|
||||||
CellDataType dataType;
|
|
||||||
Format *format;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct XlsxRowInfo
|
foreach (XlsxColumnInfo *col, colsInfo)
|
||||||
|
delete col;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Calculate the "spans" attribute of the <row> tag. This is an
|
||||||
|
XLSX optimisation and isn't strictly required. However, it
|
||||||
|
makes comparing files easier. The span is the same for each
|
||||||
|
block of 16 rows.
|
||||||
|
*/
|
||||||
|
void WorksheetPrivate::calculateSpans()
|
||||||
{
|
{
|
||||||
XlsxRowInfo(double height, Format *format, bool hidden) :
|
row_spans.clear();
|
||||||
height(height), format(format), hidden(hidden)
|
int span_min = INT32_MAX;
|
||||||
{
|
int span_max = INT32_MIN;
|
||||||
|
|
||||||
|
for (int row_num = dim_rowmin; row_num <= dim_rowmax; row_num++) {
|
||||||
|
if (cellTable.contains(row_num)) {
|
||||||
|
for (int col_num = dim_colmin; col_num <= dim_colmax; col_num++) {
|
||||||
|
if (cellTable[row_num].contains(col_num)) {
|
||||||
|
if (span_max == INT32_MIN) {
|
||||||
|
span_min = col_num;
|
||||||
|
span_max = col_num;
|
||||||
|
} else {
|
||||||
|
if (col_num < span_min)
|
||||||
|
span_min = col_num;
|
||||||
|
if (col_num > span_max)
|
||||||
|
span_max = col_num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (comments.contains(row_num)) {
|
||||||
|
for (int col_num = dim_colmin; col_num <= dim_colmax; col_num++) {
|
||||||
|
if (comments[row_num].contains(col_num)) {
|
||||||
|
if (span_max == INT32_MIN) {
|
||||||
|
span_min = col_num;
|
||||||
|
span_max = col_num;
|
||||||
|
} else {
|
||||||
|
if (col_num < span_min)
|
||||||
|
span_min = col_num;
|
||||||
|
if (col_num > span_max)
|
||||||
|
span_max = col_num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((row_num + 1)%16 == 0 || row_num == dim_rowmax) {
|
||||||
|
int span_index = row_num / 16;
|
||||||
|
if (span_max != INT32_MIN) {
|
||||||
|
span_min += 1;
|
||||||
|
span_max += 1;
|
||||||
|
row_spans[span_index] = QString("%1:%2").arg(span_min).arg(span_max);
|
||||||
|
span_max = INT32_MIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString WorksheetPrivate::generateDimensionString()
|
||||||
|
{
|
||||||
|
if (dim_rowmax == INT32_MIN && dim_colmax == INT32_MIN) {
|
||||||
|
//If the max dimensions are equal to INT32_MIN, then no dimension have been set
|
||||||
|
//and we use the default "A1"
|
||||||
|
return "A1";
|
||||||
}
|
}
|
||||||
|
|
||||||
double height;
|
if (dim_rowmax == INT32_MIN) {
|
||||||
Format *format;
|
//row dimensions aren't set but the column dimensions are set
|
||||||
bool hidden;
|
if (dim_colmin == dim_colmax) {
|
||||||
};
|
//The dimensions are a single cell and not a range
|
||||||
|
return xl_rowcol_to_cell(0, dim_colmin);
|
||||||
struct XlsxColumnInfo
|
} else {
|
||||||
{
|
const QString cell_1 = xl_rowcol_to_cell(0, dim_colmin);
|
||||||
XlsxColumnInfo(int column_min, int column_max, double width, Format *format, bool hidden) :
|
const QString cell_2 = xl_rowcol_to_cell(0, dim_colmax);
|
||||||
column_min(column_min), column_max(column_max), width(width), format(format), hidden(hidden)
|
return cell_1 + ":" + cell_2;
|
||||||
{
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
int column_min;
|
|
||||||
int column_max;
|
if (dim_rowmin == dim_rowmax && dim_colmin == dim_colmax) {
|
||||||
double width;
|
//Single cell
|
||||||
Format *format;
|
return xl_rowcol_to_cell(dim_rowmin, dim_rowmin);
|
||||||
bool hidden;
|
}
|
||||||
};
|
|
||||||
|
QString cell_1 = xl_rowcol_to_cell(dim_rowmin, dim_colmin);
|
||||||
|
QString cell_2 = xl_rowcol_to_cell(dim_rowmax, dim_colmax);
|
||||||
|
return cell_1 + ":" + cell_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check that row and col are valid and store the max and min
|
||||||
|
values for use in other methods/elements. The ignore_row /
|
||||||
|
ignore_col flags is used to indicate that we wish to perform
|
||||||
|
the dimension check without storing the value. The ignore
|
||||||
|
flags are use by setRow() and dataValidate.
|
||||||
|
*/
|
||||||
|
int WorksheetPrivate::checkDimensions(int row, int col, bool ignore_row, bool ignore_col)
|
||||||
|
{
|
||||||
|
if (row >= xls_rowmax || col >= xls_colmax)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!ignore_row) {
|
||||||
|
if (row < dim_rowmin) dim_rowmin = row;
|
||||||
|
if (row > dim_rowmax) dim_rowmax = row;
|
||||||
|
}
|
||||||
|
if (!ignore_col) {
|
||||||
|
if (col < dim_colmin) dim_colmin = col;
|
||||||
|
if (col > dim_colmax) dim_colmax = col;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Worksheet::Worksheet
|
* \brief Worksheet::Worksheet
|
||||||
@@ -96,44 +199,16 @@ struct XlsxColumnInfo
|
|||||||
* \param parent
|
* \param parent
|
||||||
*/
|
*/
|
||||||
Worksheet::Worksheet(const QString &name, int index, Workbook *parent) :
|
Worksheet::Worksheet(const QString &name, int index, Workbook *parent) :
|
||||||
QObject(parent), m_workbook(parent), m_name(name), m_index(index)
|
QObject(parent), d_ptr(new WorksheetPrivate(this))
|
||||||
{
|
{
|
||||||
m_xls_rowmax = 1048576;
|
d_ptr->name = name;
|
||||||
m_xls_colmax = 16384;
|
d_ptr->index = index;
|
||||||
m_xls_strmax = 32767;
|
d_ptr->workbook = parent;
|
||||||
m_dim_rowmin = INT32_MAX;
|
|
||||||
m_dim_rowmax = INT32_MIN;
|
|
||||||
m_dim_colmin = INT32_MAX;
|
|
||||||
m_dim_colmax = INT32_MIN;
|
|
||||||
|
|
||||||
m_previous_row = 0;
|
|
||||||
|
|
||||||
m_outline_row_level = 0;
|
|
||||||
m_outline_col_level = 0;
|
|
||||||
|
|
||||||
m_default_row_height = 15;
|
|
||||||
m_default_row_zeroed = false;
|
|
||||||
|
|
||||||
m_hidden = false;
|
|
||||||
m_selected = false;
|
|
||||||
m_actived = false;
|
|
||||||
m_right_to_left = false;
|
|
||||||
m_show_zeros = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Worksheet::~Worksheet()
|
Worksheet::~Worksheet()
|
||||||
{
|
{
|
||||||
typedef QMap<int, XlsxCellData *> RowMap;
|
delete d_ptr;
|
||||||
foreach (RowMap row, m_cellTable) {
|
|
||||||
foreach (XlsxCellData *item, row)
|
|
||||||
delete item;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (XlsxRowInfo *row, m_rowsInfo)
|
|
||||||
delete row;
|
|
||||||
|
|
||||||
foreach (XlsxColumnInfo *col, m_colsInfo)
|
|
||||||
delete col;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Worksheet::isChartsheet() const
|
bool Worksheet::isChartsheet() const
|
||||||
@@ -143,59 +218,73 @@ bool Worksheet::isChartsheet() const
|
|||||||
|
|
||||||
QString Worksheet::name() const
|
QString Worksheet::name() const
|
||||||
{
|
{
|
||||||
return m_name;
|
Q_D(const Worksheet);
|
||||||
|
return d->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Worksheet::index() const
|
int Worksheet::index() const
|
||||||
{
|
{
|
||||||
return m_index;
|
Q_D(const Worksheet);
|
||||||
|
return d->index;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Worksheet::isHidden() const
|
bool Worksheet::isHidden() const
|
||||||
{
|
{
|
||||||
return m_hidden;
|
Q_D(const Worksheet);
|
||||||
|
return d->hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Worksheet::isSelected() const
|
bool Worksheet::isSelected() const
|
||||||
{
|
{
|
||||||
return m_selected;
|
Q_D(const Worksheet);
|
||||||
|
return d->selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Worksheet::isActived() const
|
bool Worksheet::isActived() const
|
||||||
{
|
{
|
||||||
return m_actived;
|
Q_D(const Worksheet);
|
||||||
|
return d->actived;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Worksheet::setHidden(bool hidden)
|
void Worksheet::setHidden(bool hidden)
|
||||||
{
|
{
|
||||||
m_hidden = hidden;
|
Q_D(Worksheet);
|
||||||
|
d->hidden = hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Worksheet::setSelected(bool select)
|
void Worksheet::setSelected(bool select)
|
||||||
{
|
{
|
||||||
m_selected = select;
|
Q_D(Worksheet);
|
||||||
|
d->selected = select;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Worksheet::setActived(bool act)
|
void Worksheet::setActived(bool act)
|
||||||
{
|
{
|
||||||
m_actived = act;
|
Q_D(Worksheet);
|
||||||
|
d->actived = act;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Worksheet::setRightToLeft(bool enable)
|
void Worksheet::setRightToLeft(bool enable)
|
||||||
{
|
{
|
||||||
m_right_to_left = enable;
|
Q_D(Worksheet);
|
||||||
|
d->right_to_left = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Worksheet::setZeroValuesHidden(bool enable)
|
void Worksheet::setZeroValuesHidden(bool enable)
|
||||||
{
|
{
|
||||||
m_show_zeros = !enable;
|
Q_D(Worksheet);
|
||||||
|
d->show_zeros = !enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Worksheet::write(int row, int column, const QVariant &value, Format *format)
|
int Worksheet::write(int row, int column, const QVariant &value, Format *format)
|
||||||
{
|
{
|
||||||
|
Q_D(Worksheet);
|
||||||
bool ok;
|
bool ok;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
if (d->checkDimensions(row, column))
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (value.isNull()) { //blank
|
if (value.isNull()) { //blank
|
||||||
ret = writeBlank(row, column, format);
|
ret = writeBlank(row, column, format);
|
||||||
} else if (value.type() == QMetaType::Bool) { //Bool
|
} else if (value.type() == QMetaType::Bool) { //Bool
|
||||||
@@ -203,7 +292,7 @@ int Worksheet::write(int row, int column, const QVariant &value, Format *format)
|
|||||||
} else if (value.toDateTime().isValid()) { //DateTime
|
} else if (value.toDateTime().isValid()) { //DateTime
|
||||||
ret = writeDateTime(row, column, value.toDateTime(), format);
|
ret = writeDateTime(row, column, value.toDateTime(), format);
|
||||||
} else if (value.toDouble(&ok), ok) { //Number
|
} else if (value.toDouble(&ok), ok) { //Number
|
||||||
if (!m_workbook->isStringsToNumbersEnabled() && value.type() == QMetaType::QString) {
|
if (!d->workbook->isStringsToNumbersEnabled() && value.type() == QMetaType::QString) {
|
||||||
//Don't convert string to number if the flag not enabled.
|
//Don't convert string to number if the flag not enabled.
|
||||||
ret = writeString(row, column, value.toString(), format);
|
ret = writeString(row, column, value.toString(), format);
|
||||||
} else {
|
} else {
|
||||||
@@ -240,37 +329,40 @@ int Worksheet::write(const QString row_column, const QVariant &value, Format *fo
|
|||||||
|
|
||||||
int Worksheet::writeString(int row, int column, const QString &value, Format *format)
|
int Worksheet::writeString(int row, int column, const QString &value, Format *format)
|
||||||
{
|
{
|
||||||
|
Q_D(Worksheet);
|
||||||
int error = 0;
|
int error = 0;
|
||||||
QString content = value;
|
QString content = value;
|
||||||
if (checkDimensions(row, column))
|
if (d->checkDimensions(row, column))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (value.size() > m_xls_strmax) {
|
if (value.size() > d->xls_strmax) {
|
||||||
content = value.left(m_xls_strmax);
|
content = value.left(d->xls_strmax);
|
||||||
error = -2;
|
error = -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedStrings *sharedStrings = m_workbook->sharedStrings();
|
SharedStrings *sharedStrings = d->workbook->sharedStrings();
|
||||||
int index = sharedStrings->addSharedString(content);
|
int index = sharedStrings->addSharedString(content);
|
||||||
|
|
||||||
m_cellTable[row][column] = new XlsxCellData(index, XlsxCellData::String, format);
|
d->cellTable[row][column] = new XlsxCellData(index, XlsxCellData::String, format);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Worksheet::writeNumber(int row, int column, double value, Format *format)
|
int Worksheet::writeNumber(int row, int column, double value, Format *format)
|
||||||
{
|
{
|
||||||
if (checkDimensions(row, column))
|
Q_D(Worksheet);
|
||||||
|
if (d->checkDimensions(row, column))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
m_cellTable[row][column] = new XlsxCellData(value, XlsxCellData::Number, format);
|
d->cellTable[row][column] = new XlsxCellData(value, XlsxCellData::Number, format);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Worksheet::writeFormula(int row, int column, const QString &content, Format *format, double result)
|
int Worksheet::writeFormula(int row, int column, const QString &content, Format *format, double result)
|
||||||
{
|
{
|
||||||
|
Q_D(Worksheet);
|
||||||
int error = 0;
|
int error = 0;
|
||||||
QString formula = content;
|
QString formula = content;
|
||||||
if (checkDimensions(row, column))
|
if (d->checkDimensions(row, column))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
//Remove the formula '=' sign if exists
|
//Remove the formula '=' sign if exists
|
||||||
@@ -279,64 +371,44 @@ int Worksheet::writeFormula(int row, int column, const QString &content, Format
|
|||||||
|
|
||||||
XlsxCellData *data = new XlsxCellData(result, XlsxCellData::Formula, format);
|
XlsxCellData *data = new XlsxCellData(result, XlsxCellData::Formula, format);
|
||||||
data->formula = formula;
|
data->formula = formula;
|
||||||
m_cellTable[row][column] = data;
|
d->cellTable[row][column] = data;
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Worksheet::writeBlank(int row, int column, Format *format)
|
int Worksheet::writeBlank(int row, int column, Format *format)
|
||||||
{
|
{
|
||||||
if (checkDimensions(row, column))
|
Q_D(Worksheet);
|
||||||
|
if (d->checkDimensions(row, column))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
m_cellTable[row][column] = new XlsxCellData(QVariant(), XlsxCellData::Blank, format);
|
d->cellTable[row][column] = new XlsxCellData(QVariant(), XlsxCellData::Blank, format);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Worksheet::writeBool(int row, int column, bool value, Format *format)
|
int Worksheet::writeBool(int row, int column, bool value, Format *format)
|
||||||
{
|
{
|
||||||
if (checkDimensions(row, column))
|
Q_D(Worksheet);
|
||||||
|
if (d->checkDimensions(row, column))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
m_cellTable[row][column] = new XlsxCellData(value, XlsxCellData::Boolean, format);
|
d->cellTable[row][column] = new XlsxCellData(value, XlsxCellData::Boolean, format);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Worksheet::writeDateTime(int row, int column, const QDateTime &dt, Format *format)
|
int Worksheet::writeDateTime(int row, int column, const QDateTime &dt, Format *format)
|
||||||
{
|
{
|
||||||
if (checkDimensions(row, column))
|
Q_D(Worksheet);
|
||||||
|
if (d->checkDimensions(row, column))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
m_cellTable[row][column] = new XlsxCellData(dt, XlsxCellData::DateTime, format);
|
d->cellTable[row][column] = new XlsxCellData(dt, XlsxCellData::DateTime, format);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Check that row and col are valid and store the max and min
|
|
||||||
values for use in other methods/elements. The ignore_row /
|
|
||||||
ignore_col flags is used to indicate that we wish to perform
|
|
||||||
the dimension check without storing the value. The ignore
|
|
||||||
flags are use by setRow() and dataValidate.
|
|
||||||
*/
|
|
||||||
int Worksheet::checkDimensions(int row, int col, bool ignore_row, bool ignore_col)
|
|
||||||
{
|
|
||||||
if (row >= m_xls_rowmax || col >= m_xls_colmax)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (!ignore_row) {
|
|
||||||
if (row < m_dim_rowmin) m_dim_rowmin = row;
|
|
||||||
if (row > m_dim_rowmax) m_dim_rowmax = row;
|
|
||||||
}
|
|
||||||
if (!ignore_col) {
|
|
||||||
if (col < m_dim_colmin) m_dim_colmin = col;
|
|
||||||
if (col > m_dim_colmax) m_dim_colmax = col;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Worksheet::saveToXmlFile(QIODevice *device)
|
void Worksheet::saveToXmlFile(QIODevice *device)
|
||||||
{
|
{
|
||||||
|
Q_D(Worksheet);
|
||||||
XmlStreamWriter writer(device);
|
XmlStreamWriter writer(device);
|
||||||
|
|
||||||
writer.writeStartDocument("1.0", true);
|
writer.writeStartDocument("1.0", true);
|
||||||
@@ -350,38 +422,38 @@ void Worksheet::saveToXmlFile(QIODevice *device)
|
|||||||
// writer.writeAttribute("mc:Ignorable", "x14ac");
|
// writer.writeAttribute("mc:Ignorable", "x14ac");
|
||||||
|
|
||||||
writer.writeStartElement("dimension");
|
writer.writeStartElement("dimension");
|
||||||
writer.writeAttribute("ref", generateDimensionString());
|
writer.writeAttribute("ref", d->generateDimensionString());
|
||||||
writer.writeEndElement();//dimension
|
writer.writeEndElement();//dimension
|
||||||
|
|
||||||
writer.writeStartElement("sheetViews");
|
writer.writeStartElement("sheetViews");
|
||||||
writer.writeStartElement("sheetView");
|
writer.writeStartElement("sheetView");
|
||||||
if (!m_show_zeros)
|
if (!d->show_zeros)
|
||||||
writer.writeAttribute("showZeros", "0");
|
writer.writeAttribute("showZeros", "0");
|
||||||
if (m_right_to_left)
|
if (d->right_to_left)
|
||||||
writer.writeAttribute("rightToLeft", "1");
|
writer.writeAttribute("rightToLeft", "1");
|
||||||
if (m_selected)
|
if (d->selected)
|
||||||
writer.writeAttribute("tabSelected", "1");
|
writer.writeAttribute("tabSelected", "1");
|
||||||
writer.writeAttribute("workbookViewId", "0");
|
writer.writeAttribute("workbookViewId", "0");
|
||||||
writer.writeEndElement();//sheetView
|
writer.writeEndElement();//sheetView
|
||||||
writer.writeEndElement();//sheetViews
|
writer.writeEndElement();//sheetViews
|
||||||
|
|
||||||
writer.writeStartElement("sheetFormatPr");
|
writer.writeStartElement("sheetFormatPr");
|
||||||
writer.writeAttribute("defaultRowHeight", QString::number(m_default_row_height));
|
writer.writeAttribute("defaultRowHeight", QString::number(d->default_row_height));
|
||||||
if (m_default_row_height != 15)
|
if (d->default_row_height != 15)
|
||||||
writer.writeAttribute("customHeight", "1");
|
writer.writeAttribute("customHeight", "1");
|
||||||
if (m_default_row_zeroed)
|
if (d->default_row_zeroed)
|
||||||
writer.writeAttribute("zeroHeight", "1");
|
writer.writeAttribute("zeroHeight", "1");
|
||||||
if (m_outline_row_level)
|
if (d->outline_row_level)
|
||||||
writer.writeAttribute("outlineLevelRow", QString::number(m_outline_row_level));
|
writer.writeAttribute("outlineLevelRow", QString::number(d->outline_row_level));
|
||||||
if (m_outline_col_level)
|
if (d->outline_col_level)
|
||||||
writer.writeAttribute("outlineLevelCol", QString::number(m_outline_col_level));
|
writer.writeAttribute("outlineLevelCol", QString::number(d->outline_col_level));
|
||||||
//for Excel 2010
|
//for Excel 2010
|
||||||
// writer.writeAttribute("x14ac:dyDescent", "0.25");
|
// writer.writeAttribute("x14ac:dyDescent", "0.25");
|
||||||
writer.writeEndElement();//sheetFormatPr
|
writer.writeEndElement();//sheetFormatPr
|
||||||
|
|
||||||
if (!m_colsInfo.isEmpty()) {
|
if (!d->colsInfo.isEmpty()) {
|
||||||
writer.writeStartElement("cols");
|
writer.writeStartElement("cols");
|
||||||
foreach (XlsxColumnInfo *col_info, m_colsInfo) {
|
foreach (XlsxColumnInfo *col_info, d->colsInfo) {
|
||||||
writer.writeStartElement("col");
|
writer.writeStartElement("col");
|
||||||
writer.writeAttribute("min", QString::number(col_info->column_min));
|
writer.writeAttribute("min", QString::number(col_info->column_min));
|
||||||
writer.writeAttribute("max", QString::number(col_info->column_max));
|
writer.writeAttribute("max", QString::number(col_info->column_max));
|
||||||
@@ -398,10 +470,10 @@ void Worksheet::saveToXmlFile(QIODevice *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
writer.writeStartElement("sheetData");
|
writer.writeStartElement("sheetData");
|
||||||
if (m_dim_rowmax == INT32_MIN) {
|
if (d->dim_rowmax == INT32_MIN) {
|
||||||
//If the max dimensions are equal to INT32_MIN, then there is no data to write
|
//If the max dimensions are equal to INT32_MIN, then there is no data to write
|
||||||
} else {
|
} else {
|
||||||
writeSheetData(writer);
|
d->writeSheetData(writer);
|
||||||
}
|
}
|
||||||
writer.writeEndElement();//sheetData
|
writer.writeEndElement();//sheetData
|
||||||
|
|
||||||
@@ -409,59 +481,29 @@ void Worksheet::saveToXmlFile(QIODevice *device)
|
|||||||
writer.writeEndDocument();
|
writer.writeEndDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Worksheet::generateDimensionString()
|
void WorksheetPrivate::writeSheetData(XmlStreamWriter &writer)
|
||||||
{
|
|
||||||
if (m_dim_rowmax == INT32_MIN && m_dim_colmax == INT32_MIN) {
|
|
||||||
//If the max dimensions are equal to INT32_MIN, then no dimension have been set
|
|
||||||
//and we use the default "A1"
|
|
||||||
return "A1";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_dim_rowmax == INT32_MIN) {
|
|
||||||
//row dimensions aren't set but the column dimensions are set
|
|
||||||
if (m_dim_colmin == m_dim_colmax) {
|
|
||||||
//The dimensions are a single cell and not a range
|
|
||||||
return xl_rowcol_to_cell(0, m_dim_colmin);
|
|
||||||
} else {
|
|
||||||
const QString cell_1 = xl_rowcol_to_cell(0, m_dim_colmin);
|
|
||||||
const QString cell_2 = xl_rowcol_to_cell(0, m_dim_colmax);
|
|
||||||
return cell_1 + ":" + cell_2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_dim_rowmin == m_dim_rowmax && m_dim_colmin == m_dim_colmax) {
|
|
||||||
//Single cell
|
|
||||||
return xl_rowcol_to_cell(m_dim_rowmin, m_dim_rowmin);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString cell_1 = xl_rowcol_to_cell(m_dim_rowmin, m_dim_colmin);
|
|
||||||
QString cell_2 = xl_rowcol_to_cell(m_dim_rowmax, m_dim_colmax);
|
|
||||||
return cell_1 + ":" + cell_2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Worksheet::writeSheetData(XmlStreamWriter &writer)
|
|
||||||
{
|
{
|
||||||
calculateSpans();
|
calculateSpans();
|
||||||
for (int row_num = m_dim_rowmin; row_num <= m_dim_rowmax; row_num++) {
|
for (int row_num = dim_rowmin; row_num <= dim_rowmax; row_num++) {
|
||||||
if (!(m_cellTable.contains(row_num) || m_comments.contains(row_num) || m_rowsInfo.contains(row_num))) {
|
if (!(cellTable.contains(row_num) || comments.contains(row_num) || rowsInfo.contains(row_num))) {
|
||||||
//Only process rows with cell data / comments / formatting
|
//Only process rows with cell data / comments / formatting
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int span_index = row_num / 16;
|
int span_index = row_num / 16;
|
||||||
QString span;
|
QString span;
|
||||||
if (m_row_spans.contains(span_index))
|
if (row_spans.contains(span_index))
|
||||||
span = m_row_spans[span_index];
|
span = row_spans[span_index];
|
||||||
|
|
||||||
if (m_cellTable.contains(row_num)) {
|
if (cellTable.contains(row_num)) {
|
||||||
writer.writeStartElement("row");
|
writer.writeStartElement("row");
|
||||||
writer.writeAttribute("r", QString::number(row_num + 1));
|
writer.writeAttribute("r", QString::number(row_num + 1));
|
||||||
|
|
||||||
if (!span.isEmpty())
|
if (!span.isEmpty())
|
||||||
writer.writeAttribute("spans", span);
|
writer.writeAttribute("spans", span);
|
||||||
|
|
||||||
if (m_rowsInfo.contains(row_num)) {
|
if (rowsInfo.contains(row_num)) {
|
||||||
XlsxRowInfo *rowInfo = m_rowsInfo[row_num];
|
XlsxRowInfo *rowInfo = rowsInfo[row_num];
|
||||||
if (rowInfo->format) {
|
if (rowInfo->format) {
|
||||||
writer.writeAttribute("s", QString::number(rowInfo->format->xfIndex()));
|
writer.writeAttribute("s", QString::number(rowInfo->format->xfIndex()));
|
||||||
writer.writeAttribute("customFormat", "1");
|
writer.writeAttribute("customFormat", "1");
|
||||||
@@ -474,13 +516,13 @@ void Worksheet::writeSheetData(XmlStreamWriter &writer)
|
|||||||
writer.writeAttribute("hidden", "1");
|
writer.writeAttribute("hidden", "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int col_num = m_dim_colmin; col_num <= m_dim_colmax; col_num++) {
|
for (int col_num = dim_colmin; col_num <= dim_colmax; col_num++) {
|
||||||
if (m_cellTable[row_num].contains(col_num)) {
|
if (cellTable[row_num].contains(col_num)) {
|
||||||
writeCellData(writer, row_num, col_num, m_cellTable[row_num][col_num]);
|
writeCellData(writer, row_num, col_num, cellTable[row_num][col_num]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writer.writeEndElement(); //row
|
writer.writeEndElement(); //row
|
||||||
} else if (m_comments.contains(row_num)){
|
} else if (comments.contains(row_num)){
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@@ -488,7 +530,7 @@ void Worksheet::writeSheetData(XmlStreamWriter &writer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Worksheet::writeCellData(XmlStreamWriter &writer, int row, int col, XlsxCellData *cell)
|
void WorksheetPrivate::writeCellData(XmlStreamWriter &writer, int row, int col, XlsxCellData *cell)
|
||||||
{
|
{
|
||||||
//This is the innermost loop so efficiency is important.
|
//This is the innermost loop so efficiency is important.
|
||||||
QString cell_range = xl_rowcol_to_cell_fast(row, col);
|
QString cell_range = xl_rowcol_to_cell_fast(row, col);
|
||||||
@@ -499,10 +541,10 @@ void Worksheet::writeCellData(XmlStreamWriter &writer, int row, int col, XlsxCel
|
|||||||
//Style used by the cell, row or col
|
//Style used by the cell, row or col
|
||||||
if (cell->format)
|
if (cell->format)
|
||||||
writer.writeAttribute("s", QString::number(cell->format->xfIndex()));
|
writer.writeAttribute("s", QString::number(cell->format->xfIndex()));
|
||||||
else if (m_rowsInfo.contains(row) && m_rowsInfo[row]->format)
|
else if (rowsInfo.contains(row) && rowsInfo[row]->format)
|
||||||
writer.writeAttribute("s", QString::number(m_rowsInfo[row]->format->xfIndex()));
|
writer.writeAttribute("s", QString::number(rowsInfo[row]->format->xfIndex()));
|
||||||
else if (m_colsInfoHelper.contains(col) && m_colsInfoHelper[col]->format)
|
else if (colsInfoHelper.contains(col) && colsInfoHelper[col]->format)
|
||||||
writer.writeAttribute("s", QString::number(m_colsInfoHelper[col]->format->xfIndex()));
|
writer.writeAttribute("s", QString::number(colsInfoHelper[col]->format->xfIndex()));
|
||||||
|
|
||||||
if (cell->dataType == XlsxCellData::String) {
|
if (cell->dataType == XlsxCellData::String) {
|
||||||
//cell->data: Index of the string in sharedStringTable
|
//cell->data: Index of the string in sharedStringTable
|
||||||
@@ -527,91 +569,36 @@ void Worksheet::writeCellData(XmlStreamWriter &writer, int row, int col, XlsxCel
|
|||||||
//Ok, empty here.
|
//Ok, empty here.
|
||||||
} else if (cell->dataType == XlsxCellData::DateTime) {
|
} else if (cell->dataType == XlsxCellData::DateTime) {
|
||||||
QDateTime epoch(QDate(1899, 12, 31));
|
QDateTime epoch(QDate(1899, 12, 31));
|
||||||
if (m_workbook->isDate1904())
|
if (workbook->isDate1904())
|
||||||
epoch = QDateTime(QDate(1904, 1, 1));
|
epoch = QDateTime(QDate(1904, 1, 1));
|
||||||
qint64 delta = epoch.msecsTo(cell->value.toDateTime());
|
qint64 delta = epoch.msecsTo(cell->value.toDateTime());
|
||||||
double excel_time = delta / (1000*60*60*24);
|
double excel_time = delta / (1000*60*60*24);
|
||||||
//Account for Excel erroneously treating 1900 as a leap year.
|
//Account for Excel erroneously treating 1900 as a leap year.
|
||||||
if (!m_workbook->isDate1904() && excel_time > 59)
|
if (!workbook->isDate1904() && excel_time > 59)
|
||||||
excel_time += 1;
|
excel_time += 1;
|
||||||
writer.writeTextElement("v", QString::number(excel_time, 'g', 15));
|
writer.writeTextElement("v", QString::number(excel_time, 'g', 15));
|
||||||
}
|
}
|
||||||
writer.writeEndElement(); //c
|
writer.writeEndElement(); //c
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Calculate the "spans" attribute of the <row> tag. This is an
|
|
||||||
XLSX optimisation and isn't strictly required. However, it
|
|
||||||
makes comparing files easier. The span is the same for each
|
|
||||||
block of 16 rows.
|
|
||||||
*/
|
|
||||||
void Worksheet::calculateSpans()
|
|
||||||
{
|
|
||||||
m_row_spans.clear();
|
|
||||||
int span_min = INT32_MAX;
|
|
||||||
int span_max = INT32_MIN;
|
|
||||||
|
|
||||||
for (int row_num = m_dim_rowmin; row_num <= m_dim_rowmax; row_num++) {
|
|
||||||
if (m_cellTable.contains(row_num)) {
|
|
||||||
for (int col_num = m_dim_colmin; col_num <= m_dim_colmax; col_num++) {
|
|
||||||
if (m_cellTable[row_num].contains(col_num)) {
|
|
||||||
if (span_max == INT32_MIN) {
|
|
||||||
span_min = col_num;
|
|
||||||
span_max = col_num;
|
|
||||||
} else {
|
|
||||||
if (col_num < span_min)
|
|
||||||
span_min = col_num;
|
|
||||||
if (col_num > span_max)
|
|
||||||
span_max = col_num;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (m_comments.contains(row_num)) {
|
|
||||||
for (int col_num = m_dim_colmin; col_num <= m_dim_colmax; col_num++) {
|
|
||||||
if (m_comments[row_num].contains(col_num)) {
|
|
||||||
if (span_max == INT32_MIN) {
|
|
||||||
span_min = col_num;
|
|
||||||
span_max = col_num;
|
|
||||||
} else {
|
|
||||||
if (col_num < span_min)
|
|
||||||
span_min = col_num;
|
|
||||||
if (col_num > span_max)
|
|
||||||
span_max = col_num;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((row_num + 1)%16 == 0 || row_num == m_dim_rowmax) {
|
|
||||||
int span_index = row_num / 16;
|
|
||||||
if (span_max != INT32_MIN) {
|
|
||||||
span_min += 1;
|
|
||||||
span_max += 1;
|
|
||||||
m_row_spans[span_index] = QString("%1:%2").arg(span_min).arg(span_max);
|
|
||||||
span_max = INT32_MIN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Sets row height and format. Row height measured in point size. If format
|
Sets row height and format. Row height measured in point size. If format
|
||||||
equals 0 then format is ignored.
|
equals 0 then format is ignored.
|
||||||
*/
|
*/
|
||||||
bool Worksheet::setRow(int row, double height, Format *format, bool hidden)
|
bool Worksheet::setRow(int row, double height, Format *format, bool hidden)
|
||||||
{
|
{
|
||||||
int min_col = m_dim_colmax == INT32_MIN ? 0 : m_dim_colmin;
|
Q_D(Worksheet);
|
||||||
|
int min_col = d->dim_colmax == INT32_MIN ? 0 : d->dim_colmin;
|
||||||
|
|
||||||
if (checkDimensions(row, min_col))
|
if (d->checkDimensions(row, min_col))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (m_rowsInfo.contains(row)) {
|
if (d->rowsInfo.contains(row)) {
|
||||||
m_rowsInfo[row]->height = height;
|
d->rowsInfo[row]->height = height;
|
||||||
m_rowsInfo[row]->format = format;
|
d->rowsInfo[row]->format = format;
|
||||||
m_rowsInfo[row]->hidden = hidden;
|
d->rowsInfo[row]->hidden = hidden;
|
||||||
} else {
|
} else {
|
||||||
m_rowsInfo[row] = new XlsxRowInfo(height, format, hidden);
|
d->rowsInfo[row] = new XlsxRowInfo(height, format, hidden);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -624,19 +611,20 @@ bool Worksheet::setRow(int row, double height, Format *format, bool hidden)
|
|||||||
*/
|
*/
|
||||||
bool Worksheet::setColumn(int colFirst, int colLast, double width, Format *format, bool hidden)
|
bool Worksheet::setColumn(int colFirst, int colLast, double width, Format *format, bool hidden)
|
||||||
{
|
{
|
||||||
|
Q_D(Worksheet);
|
||||||
bool ignore_row = true;
|
bool ignore_row = true;
|
||||||
bool ignore_col = (format || (width && hidden)) ? false : true;
|
bool ignore_col = (format || (width && hidden)) ? false : true;
|
||||||
|
|
||||||
if (checkDimensions(0, colLast, ignore_row, ignore_col))
|
if (d->checkDimensions(0, colLast, ignore_row, ignore_col))
|
||||||
return false;
|
return false;
|
||||||
if (checkDimensions(0, colFirst, ignore_row, ignore_col))
|
if (d->checkDimensions(0, colFirst, ignore_row, ignore_col))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
XlsxColumnInfo *info = new XlsxColumnInfo(colFirst, colLast, width, format, hidden);
|
XlsxColumnInfo *info = new XlsxColumnInfo(colFirst, colLast, width, format, hidden);
|
||||||
m_colsInfo.append(info);
|
d->colsInfo.append(info);
|
||||||
|
|
||||||
for (int col=colFirst; col<=colLast; ++col)
|
for (int col=colFirst; col<=colLast; ++col)
|
||||||
m_colsInfoHelper[col] = info;
|
d->colsInfoHelper[col] = info;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-41
@@ -38,13 +38,11 @@ class Workbook;
|
|||||||
class XmlStreamWriter;
|
class XmlStreamWriter;
|
||||||
class Format;
|
class Format;
|
||||||
|
|
||||||
struct XlsxCellData;
|
class WorksheetPrivate;
|
||||||
struct XlsxRowInfo;
|
|
||||||
struct XlsxColumnInfo;
|
|
||||||
|
|
||||||
class Worksheet : public QObject
|
class Worksheet : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_DECLARE_PRIVATE(Worksheet)
|
||||||
public:
|
public:
|
||||||
int write(const QString row_column, const QVariant &value, Format *format=0);
|
int write(const QString row_column, const QVariant &value, Format *format=0);
|
||||||
int write(int row, int column, const QVariant &value, Format *format=0);
|
int write(int row, int column, const QVariant &value, Format *format=0);
|
||||||
@@ -77,44 +75,8 @@ private:
|
|||||||
void setSelected(bool select);
|
void setSelected(bool select);
|
||||||
void setActived(bool act);
|
void setActived(bool act);
|
||||||
void saveToXmlFile(QIODevice *device);
|
void saveToXmlFile(QIODevice *device);
|
||||||
int checkDimensions(int row, int col, bool ignore_row=false, bool ignore_col=false);
|
|
||||||
QString generateDimensionString();
|
|
||||||
void writeSheetData(XmlStreamWriter &writer);
|
|
||||||
void writeCellData(XmlStreamWriter &writer, int row, int col, XlsxCellData *cell);
|
|
||||||
void calculateSpans();
|
|
||||||
|
|
||||||
Workbook *m_workbook;
|
WorksheetPrivate * const d_ptr;
|
||||||
QMap<int, QMap<int, XlsxCellData *> > m_cellTable;
|
|
||||||
QMap<int, QMap<int, QString> > m_comments;
|
|
||||||
QMap<int, XlsxRowInfo *> m_rowsInfo;
|
|
||||||
QList<XlsxColumnInfo *> m_colsInfo;
|
|
||||||
QMap<int, XlsxColumnInfo *> m_colsInfoHelper;//Not owns the XlsxColumnInfo
|
|
||||||
|
|
||||||
|
|
||||||
int m_xls_rowmax;
|
|
||||||
int m_xls_colmax;
|
|
||||||
int m_xls_strmax;
|
|
||||||
int m_dim_rowmin;
|
|
||||||
int m_dim_rowmax;
|
|
||||||
int m_dim_colmin;
|
|
||||||
int m_dim_colmax;
|
|
||||||
int m_previous_row;
|
|
||||||
|
|
||||||
QMap<int, QString> m_row_spans;
|
|
||||||
|
|
||||||
int m_outline_row_level;
|
|
||||||
int m_outline_col_level;
|
|
||||||
|
|
||||||
int m_default_row_height;
|
|
||||||
bool m_default_row_zeroed;
|
|
||||||
|
|
||||||
QString m_name;
|
|
||||||
int m_index;
|
|
||||||
bool m_hidden;
|
|
||||||
bool m_selected;
|
|
||||||
bool m_actived;
|
|
||||||
bool m_right_to_left;
|
|
||||||
bool m_show_zeros;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} //QXlsx
|
} //QXlsx
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
|
||||||
|
** All right reserved.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
** a copy of this software and associated documentation files (the
|
||||||
|
** "Software"), to deal in the Software without restriction, including
|
||||||
|
** without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
** permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
** the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be
|
||||||
|
** included in all copies or substantial portions of the Software.
|
||||||
|
**
|
||||||
|
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef XLSXWORKSHEET_P_H
|
||||||
|
#define XLSXWORKSHEET_P_H
|
||||||
|
#include "xlsxworksheet.h"
|
||||||
|
|
||||||
|
namespace QXlsx {
|
||||||
|
|
||||||
|
struct XlsxCellData
|
||||||
|
{
|
||||||
|
enum CellDataType {
|
||||||
|
Blank,
|
||||||
|
String,
|
||||||
|
Number,
|
||||||
|
Formula,
|
||||||
|
ArrayFormula,
|
||||||
|
Boolean,
|
||||||
|
DateTime
|
||||||
|
};
|
||||||
|
XlsxCellData(const QVariant &data=QVariant(), CellDataType type=Blank, Format *format=0) :
|
||||||
|
value(data), dataType(type), format(format)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant value;
|
||||||
|
QString formula;
|
||||||
|
CellDataType dataType;
|
||||||
|
Format *format;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct XlsxRowInfo
|
||||||
|
{
|
||||||
|
XlsxRowInfo(double height, Format *format, bool hidden) :
|
||||||
|
height(height), format(format), hidden(hidden)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
double height;
|
||||||
|
Format *format;
|
||||||
|
bool hidden;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct XlsxColumnInfo
|
||||||
|
{
|
||||||
|
XlsxColumnInfo(int column_min, int column_max, double width, Format *format, bool hidden) :
|
||||||
|
column_min(column_min), column_max(column_max), width(width), format(format), hidden(hidden)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
int column_min;
|
||||||
|
int column_max;
|
||||||
|
double width;
|
||||||
|
Format *format;
|
||||||
|
bool hidden;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WorksheetPrivate
|
||||||
|
{
|
||||||
|
Q_DECLARE_PUBLIC(Worksheet)
|
||||||
|
public:
|
||||||
|
WorksheetPrivate(Worksheet *p);
|
||||||
|
~WorksheetPrivate();
|
||||||
|
int checkDimensions(int row, int col, bool ignore_row=false, bool ignore_col=false);
|
||||||
|
QString generateDimensionString();
|
||||||
|
void calculateSpans();
|
||||||
|
void writeSheetData(XmlStreamWriter &writer);
|
||||||
|
void writeCellData(XmlStreamWriter &writer, int row, int col, XlsxCellData *cell);
|
||||||
|
|
||||||
|
Workbook *workbook;
|
||||||
|
QMap<int, QMap<int, XlsxCellData *> > cellTable;
|
||||||
|
QMap<int, QMap<int, QString> > comments;
|
||||||
|
QMap<int, XlsxRowInfo *> rowsInfo;
|
||||||
|
QList<XlsxColumnInfo *> colsInfo;
|
||||||
|
QMap<int, XlsxColumnInfo *> colsInfoHelper;//Not owns the XlsxColumnInfo
|
||||||
|
|
||||||
|
int xls_rowmax;
|
||||||
|
int xls_colmax;
|
||||||
|
int xls_strmax;
|
||||||
|
int dim_rowmin;
|
||||||
|
int dim_rowmax;
|
||||||
|
int dim_colmin;
|
||||||
|
int dim_colmax;
|
||||||
|
int previous_row;
|
||||||
|
|
||||||
|
QMap<int, QString> row_spans;
|
||||||
|
|
||||||
|
int outline_row_level;
|
||||||
|
int outline_col_level;
|
||||||
|
|
||||||
|
int default_row_height;
|
||||||
|
bool default_row_zeroed;
|
||||||
|
|
||||||
|
QString name;
|
||||||
|
int index;
|
||||||
|
bool hidden;
|
||||||
|
bool selected;
|
||||||
|
bool actived;
|
||||||
|
bool right_to_left;
|
||||||
|
bool show_zeros;
|
||||||
|
|
||||||
|
Worksheet *q_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif // XLSXWORKSHEET_P_H
|
||||||
Reference in New Issue
Block a user