// This file was automatically generated from records.xml
#include "records.h"
#include <vector>
#include <iomanip>
#include "XlsRecordOutputStream.h"

namespace Swinder {

// ========== BackupRecord ==========

const unsigned BackupRecord::id = 0x0040;

class BackupRecord::Private
{
public:
    bool backupEnabled;
};

BackupRecord::BackupRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setBackupEnabled(false);
}

BackupRecord::~BackupRecord()
{
    delete d;
}

BackupRecord::BackupRecord( const BackupRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

BackupRecord& BackupRecord::operator=( const BackupRecord& record )
{
    *d = *record.d;
    return *this;
}

bool BackupRecord::isBackupEnabled() const
{
    return d->backupEnabled;
}

void BackupRecord::setBackupEnabled(bool backupEnabled )
{
    d->backupEnabled = backupEnabled;
}

void BackupRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setBackupEnabled(readU16(data) != 0);
}

void BackupRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, isBackupEnabled());
}

void BackupRecord::dump( std::ostream& out ) const
{
    out << "Backup" << std::endl;
    out << "      BackupEnabled : " << isBackupEnabled() << std::endl;
}

static Record* createBackupRecord(Swinder::Workbook *book)
{
    return new BackupRecord(book);
}

// ========== BOFRecord ==========

const unsigned BOFRecord::id = 0x0809;

class BOFRecord::Private
{
public:
    unsigned build;
    bool fBeta;
    bool fBetaAny;
    bool fFontLimit;
    bool fGIJmp;
    bool fMacAny;
    bool fOOM;
    bool fRisc;
    bool fRiscAny;
    bool fWin;
    bool fWinAny;
    unsigned rawVersion;
    Type type;
    VerLastXLSaved verLastXLSaved;
    unsigned verLowestBiff;
    VerXLHigh verXLHigh;
    unsigned year;
};

BOFRecord::BOFRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setBuild(0x4DE4);
    setFBeta(false);
    setFBetaAny(false);
    setFFontLimit(false);
    setFGIJmp(false);
    setFMacAny(false);
    setFOOM(false);
    setFRisc(false);
    setFRiscAny(false);
    setFWin(true);
    setFWinAny(true);
    setRawVersion(0x0600);
    setType(Workbook);
    setVerLastXLSaved(LExcel97);
    setVerLowestBiff(6);
    setVerXLHigh(HExcel97);
    setYear(0x07CD);
}

BOFRecord::~BOFRecord()
{
    delete d;
}

BOFRecord::BOFRecord( const BOFRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

BOFRecord& BOFRecord::operator=( const BOFRecord& record )
{
    *d = *record.d;
    return *this;
}

QString BOFRecord::typeToString(Type type)
{
    switch (type) {
        case Workbook: return QString("Workbook");
        case VBModule: return QString("VBModule");
        case Worksheet: return QString("Worksheet");
        case Chart: return QString("Chart");
        case MacroSheet: return QString("MacroSheet");
        case Workspace: return QString("Workspace");
        default: return QString("Unknown: %1").arg(type);
    }
}

QString BOFRecord::verXLHighToString(VerXLHigh verXLHigh)
{
    switch (verXLHigh) {
        case HExcel97: return QString("HExcel97");
        case HExcel2000: return QString("HExcel2000");
        case HExcel2002: return QString("HExcel2002");
        case HExcel2003: return QString("HExcel2003");
        case HExcel2007: return QString("HExcel2007");
        case HExcel2010: return QString("HExcel2010");
        default: return QString("Unknown: %1").arg(verXLHigh);
    }
}

QString BOFRecord::verLastXLSavedToString(VerLastXLSaved verLastXLSaved)
{
    switch (verLastXLSaved) {
        case LExcel97: return QString("LExcel97");
        case LExcel2000: return QString("LExcel2000");
        case LExcel2002: return QString("LExcel2002");
        case LExcel2003: return QString("LExcel2003");
        case LExcel2007: return QString("LExcel2007");
        case LExcel2010: return QString("LExcel2010");
        default: return QString("Unknown: %1").arg(verLastXLSaved);
    }
}

unsigned BOFRecord::build() const
{
    return d->build;
}

void BOFRecord::setBuild(unsigned build )
{
    d->build = build;
}

bool BOFRecord::isFBeta() const
{
    return d->fBeta;
}

void BOFRecord::setFBeta(bool fBeta )
{
    d->fBeta = fBeta;
}

bool BOFRecord::isFBetaAny() const
{
    return d->fBetaAny;
}

void BOFRecord::setFBetaAny(bool fBetaAny )
{
    d->fBetaAny = fBetaAny;
}

bool BOFRecord::isFFontLimit() const
{
    return d->fFontLimit;
}

void BOFRecord::setFFontLimit(bool fFontLimit )
{
    d->fFontLimit = fFontLimit;
}

bool BOFRecord::isFGIJmp() const
{
    return d->fGIJmp;
}

void BOFRecord::setFGIJmp(bool fGIJmp )
{
    d->fGIJmp = fGIJmp;
}

bool BOFRecord::isFMacAny() const
{
    return d->fMacAny;
}

void BOFRecord::setFMacAny(bool fMacAny )
{
    d->fMacAny = fMacAny;
}

bool BOFRecord::isFOOM() const
{
    return d->fOOM;
}

void BOFRecord::setFOOM(bool fOOM )
{
    d->fOOM = fOOM;
}

bool BOFRecord::isFRisc() const
{
    return d->fRisc;
}

void BOFRecord::setFRisc(bool fRisc )
{
    d->fRisc = fRisc;
}

bool BOFRecord::isFRiscAny() const
{
    return d->fRiscAny;
}

void BOFRecord::setFRiscAny(bool fRiscAny )
{
    d->fRiscAny = fRiscAny;
}

bool BOFRecord::isFWin() const
{
    return d->fWin;
}

void BOFRecord::setFWin(bool fWin )
{
    d->fWin = fWin;
}

bool BOFRecord::isFWinAny() const
{
    return d->fWinAny;
}

void BOFRecord::setFWinAny(bool fWinAny )
{
    d->fWinAny = fWinAny;
}

unsigned BOFRecord::rawVersion() const
{
    return d->rawVersion;
}

void BOFRecord::setRawVersion(unsigned rawVersion )
{
    d->rawVersion = rawVersion;
}

BOFRecord::Type BOFRecord::type() const
{
    return d->type;
}

void BOFRecord::setType(Type type )
{
    d->type = type;
}

BOFRecord::VerLastXLSaved BOFRecord::verLastXLSaved() const
{
    return d->verLastXLSaved;
}

void BOFRecord::setVerLastXLSaved(VerLastXLSaved verLastXLSaved )
{
    d->verLastXLSaved = verLastXLSaved;
}

unsigned BOFRecord::verLowestBiff() const
{
    return d->verLowestBiff;
}

void BOFRecord::setVerLowestBiff(unsigned verLowestBiff )
{
    d->verLowestBiff = verLowestBiff;
}

BOFRecord::VerXLHigh BOFRecord::verXLHigh() const
{
    return d->verXLHigh;
}

void BOFRecord::setVerXLHigh(VerXLHigh verXLHigh )
{
    d->verXLHigh = verXLHigh;
}

unsigned BOFRecord::year() const
{
    return d->year;
}

void BOFRecord::setYear(unsigned year )
{
    d->year = year;
}

unsigned BOFRecord::version() const
{
    return rawVersion() == 0x0500 ? Excel95 : rawVersion() == 0x0600 ? Excel97 : UnknownExcel;
}

void BOFRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    if (size < 2) {
        setIsValid(false);
        return;
    }
    setRawVersion(readU16(data));
    setType(static_cast<Type>(readU16(data + 2)));
    curOffset = 4;
    if (recordSize() >= 8) {
        if (size < curOffset + 4) {
            setIsValid(false);
            return;
        }
        setBuild(readU16(data + curOffset));
        setYear(readU16(data + curOffset + 2));
        curOffset += 4;
        if (recordSize() >= 16) {
            if (size < curOffset + 8) {
                setIsValid(false);
                return;
            }
            setFWin(((readU8(data + curOffset)) & 0x1) != 0);
            setFRisc(((readU8(data + curOffset) >> 1) & 0x1) != 0);
            setFBeta(((readU8(data + curOffset) >> 2) & 0x1) != 0);
            setFWinAny(((readU8(data + curOffset) >> 3) & 0x1) != 0);
            setFMacAny(((readU8(data + curOffset) >> 4) & 0x1) != 0);
            setFBetaAny(((readU8(data + curOffset) >> 5) & 0x1) != 0);
            setFRiscAny(((readU8(data + curOffset + 1)) & 0x1) != 0);
            setFOOM(((readU8(data + curOffset + 1) >> 1) & 0x1) != 0);
            setFGIJmp(((readU8(data + curOffset + 1) >> 2) & 0x1) != 0);
            setFFontLimit(((readU8(data + curOffset + 1) >> 5) & 0x1) != 0);
            setVerXLHigh(static_cast<VerXLHigh>(((readU16(data + curOffset + 1) >> 6) & 0xf)));
            setVerLowestBiff(readU8(data + curOffset + 4));
            setVerLastXLSaved(static_cast<VerLastXLSaved>(((readU8(data + curOffset + 5)) & 0xf)));
            curOffset += 8;
        }
    }
}

void BOFRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, rawVersion());
    out.writeUnsigned(16, type());
    if (recordSize() >= 8) {
        out.writeUnsigned(16, build());
        out.writeUnsigned(16, year());
        if (recordSize() >= 16) {
            out.writeUnsigned(1, isFWin());
            out.writeUnsigned(1, isFRisc());
            out.writeUnsigned(1, isFBeta());
            out.writeUnsigned(1, isFWinAny());
            out.writeUnsigned(1, isFMacAny());
            out.writeUnsigned(1, isFBetaAny());
            out.writeUnsigned(2, 0);
            out.writeUnsigned(1, isFRiscAny());
            out.writeUnsigned(1, isFOOM());
            out.writeUnsigned(1, isFGIJmp());
            out.writeUnsigned(2, 0);
            out.writeUnsigned(1, isFFontLimit());
            out.writeUnsigned(4, verXLHigh());
            out.writeUnsigned(1, 0);
            out.writeUnsigned(13, 0);
            out.writeUnsigned(8, verLowestBiff());
            out.writeUnsigned(4, verLastXLSaved());
            out.writeUnsigned(20, 0);
        }
    }
}

void BOFRecord::dump( std::ostream& out ) const
{
    out << "BOF" << std::endl;
    out << "         RawVersion : " << rawVersion() << std::endl;
    out << "               Type : " << typeToString(type()) << std::endl;
    if (recordSize() >= 8) {
        out << "              Build : " << build() << std::endl;
        out << "               Year : " << year() << std::endl;
        if (recordSize() >= 16) {
            out << "               FWin : " << isFWin() << std::endl;
            out << "              FRisc : " << isFRisc() << std::endl;
            out << "              FBeta : " << isFBeta() << std::endl;
            out << "            FWinAny : " << isFWinAny() << std::endl;
            out << "            FMacAny : " << isFMacAny() << std::endl;
            out << "           FBetaAny : " << isFBetaAny() << std::endl;
            out << "           FRiscAny : " << isFRiscAny() << std::endl;
            out << "               FOOM : " << isFOOM() << std::endl;
            out << "             FGIJmp : " << isFGIJmp() << std::endl;
            out << "         FFontLimit : " << isFFontLimit() << std::endl;
            out << "          VerXLHigh : " << verXLHighToString(verXLHigh()) << std::endl;
            out << "      VerLowestBiff : " << verLowestBiff() << std::endl;
            out << "     VerLastXLSaved : " << verLastXLSavedToString(verLastXLSaved()) << std::endl;
        }
    }
}

static Record* createBOFRecord(Swinder::Workbook *book)
{
    return new BOFRecord(book);
}

// ========== EOFRecord ==========

const unsigned EOFRecord::id = 0x000A;

class EOFRecord::Private
{
public:
};

EOFRecord::EOFRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

EOFRecord::~EOFRecord()
{
    delete d;
}

EOFRecord::EOFRecord( const EOFRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

EOFRecord& EOFRecord::operator=( const EOFRecord& record )
{
    *d = *record.d;
    return *this;
}

void EOFRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void EOFRecord::writeData( XlsRecordOutputStream& ) const
{
}

void EOFRecord::dump( std::ostream& out ) const
{
    out << "EOF" << std::endl;
}

static Record* createEOFRecord(Swinder::Workbook *book)
{
    return new EOFRecord(book);
}

// ========== BlankRecord ==========

const unsigned BlankRecord::id = 0x0201;

class BlankRecord::Private
{
public:
    unsigned column;
    unsigned row;
    unsigned xfIndex;
};

BlankRecord::BlankRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setColumn(0);
    setRow(0);
    setXfIndex(0);
}

BlankRecord::~BlankRecord()
{
    delete d;
}

BlankRecord::BlankRecord( const BlankRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

BlankRecord& BlankRecord::operator=( const BlankRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned BlankRecord::column() const
{
    return d->column;
}

void BlankRecord::setColumn(unsigned column )
{
    d->column = column;
}

unsigned BlankRecord::row() const
{
    return d->row;
}

void BlankRecord::setRow(unsigned row )
{
    d->row = row;
}

unsigned BlankRecord::xfIndex() const
{
    return d->xfIndex;
}

void BlankRecord::setXfIndex(unsigned xfIndex )
{
    d->xfIndex = xfIndex;
}

void BlankRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 6) {
        setIsValid(false);
        return;
    }
    setRow(readU16(data));
    setColumn(readU16(data + 2));
    setXfIndex(readU16(data + 4));
}

void BlankRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, row());
    out.writeUnsigned(16, column());
    out.writeUnsigned(16, xfIndex());
}

void BlankRecord::dump( std::ostream& out ) const
{
    out << "Blank" << std::endl;
    out << "                Row : " << row() << std::endl;
    out << "             Column : " << column() << std::endl;
    out << "            XfIndex : " << xfIndex() << std::endl;
}

static Record* createBlankRecord(Swinder::Workbook *book)
{
    return new BlankRecord(book);
}

// ========== BoolErrRecord ==========

const unsigned BoolErrRecord::id = 0x0205;

class BoolErrRecord::Private
{
public:
    unsigned column;
    bool error;
    unsigned row;
    unsigned value;
    unsigned xfIndex;
};

BoolErrRecord::BoolErrRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setColumn(0);
    setError(false);
    setRow(0);
    setValue(0);
    setXfIndex(0);
}

BoolErrRecord::~BoolErrRecord()
{
    delete d;
}

BoolErrRecord::BoolErrRecord( const BoolErrRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

BoolErrRecord& BoolErrRecord::operator=( const BoolErrRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned BoolErrRecord::column() const
{
    return d->column;
}

void BoolErrRecord::setColumn(unsigned column )
{
    d->column = column;
}

bool BoolErrRecord::isError() const
{
    return d->error;
}

void BoolErrRecord::setError(bool error )
{
    d->error = error;
}

unsigned BoolErrRecord::row() const
{
    return d->row;
}

void BoolErrRecord::setRow(unsigned row )
{
    d->row = row;
}

unsigned BoolErrRecord::value() const
{
    return d->value;
}

void BoolErrRecord::setValue(unsigned value )
{
    d->value = value;
}

unsigned BoolErrRecord::xfIndex() const
{
    return d->xfIndex;
}

void BoolErrRecord::setXfIndex(unsigned xfIndex )
{
    d->xfIndex = xfIndex;
}

Value BoolErrRecord::asValue() const
{
    return isError() ? errorAsValue(value()) : Value(value() ? true : false);
}

void BoolErrRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 8) {
        setIsValid(false);
        return;
    }
    setRow(readU16(data));
    setColumn(readU16(data + 2));
    setXfIndex(readU16(data + 4));
    setValue(readU8(data + 6));
    setError(readU8(data + 7) != 0);
}

void BoolErrRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, row());
    out.writeUnsigned(16, column());
    out.writeUnsigned(16, xfIndex());
    out.writeUnsigned(8, value());
    out.writeUnsigned(8, isError());
}

void BoolErrRecord::dump( std::ostream& out ) const
{
    out << "BoolErr" << std::endl;
    out << "                Row : " << row() << std::endl;
    out << "             Column : " << column() << std::endl;
    out << "            XfIndex : " << xfIndex() << std::endl;
    out << "              Value : " << value() << std::endl;
    out << "              Error : " << isError() << std::endl;
}

static Record* createBoolErrRecord(Swinder::Workbook *book)
{
    return new BoolErrRecord(book);
}

// ========== StartBlockRecord ==========

const unsigned StartBlockRecord::id = 0x0852;

class StartBlockRecord::Private
{
public:
    unsigned frtHeaderOld;
    unsigned iObjectContext;
    unsigned iObjectInstance1;
    unsigned iObjectInstance2;
    unsigned iObjectKind;
};

StartBlockRecord::StartBlockRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFrtHeaderOld(0);
    setIObjectContext(0);
    setIObjectInstance1(0);
    setIObjectInstance2(0);
    setIObjectKind(0);
}

StartBlockRecord::~StartBlockRecord()
{
    delete d;
}

StartBlockRecord::StartBlockRecord( const StartBlockRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

StartBlockRecord& StartBlockRecord::operator=( const StartBlockRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned StartBlockRecord::frtHeaderOld() const
{
    return d->frtHeaderOld;
}

void StartBlockRecord::setFrtHeaderOld(unsigned frtHeaderOld )
{
    d->frtHeaderOld = frtHeaderOld;
}

unsigned StartBlockRecord::iObjectContext() const
{
    return d->iObjectContext;
}

void StartBlockRecord::setIObjectContext(unsigned iObjectContext )
{
    d->iObjectContext = iObjectContext;
}

unsigned StartBlockRecord::iObjectInstance1() const
{
    return d->iObjectInstance1;
}

void StartBlockRecord::setIObjectInstance1(unsigned iObjectInstance1 )
{
    d->iObjectInstance1 = iObjectInstance1;
}

unsigned StartBlockRecord::iObjectInstance2() const
{
    return d->iObjectInstance2;
}

void StartBlockRecord::setIObjectInstance2(unsigned iObjectInstance2 )
{
    d->iObjectInstance2 = iObjectInstance2;
}

unsigned StartBlockRecord::iObjectKind() const
{
    return d->iObjectKind;
}

void StartBlockRecord::setIObjectKind(unsigned iObjectKind )
{
    d->iObjectKind = iObjectKind;
}

void StartBlockRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 12) {
        setIsValid(false);
        return;
    }
    setFrtHeaderOld(readU32(data));
    setIObjectKind(readU16(data + 4));
    setIObjectContext(readU16(data + 6));
    setIObjectInstance1(readU16(data + 8));
    setIObjectInstance2(readU16(data + 10));
}

void StartBlockRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(32, frtHeaderOld());
    out.writeUnsigned(16, iObjectKind());
    out.writeUnsigned(16, iObjectContext());
    out.writeUnsigned(16, iObjectInstance1());
    out.writeUnsigned(16, iObjectInstance2());
}

void StartBlockRecord::dump( std::ostream& out ) const
{
    out << "StartBlock" << std::endl;
    out << "       FrtHeaderOld : " << frtHeaderOld() << std::endl;
    out << "        IObjectKind : " << iObjectKind() << std::endl;
    out << "     IObjectContext : " << iObjectContext() << std::endl;
    out << "   IObjectInstance1 : " << iObjectInstance1() << std::endl;
    out << "   IObjectInstance2 : " << iObjectInstance2() << std::endl;
}

static Record* createStartBlockRecord(Swinder::Workbook *book)
{
    return new StartBlockRecord(book);
}

// ========== EndBlockRecord ==========

const unsigned EndBlockRecord::id = 0x0853;

class EndBlockRecord::Private
{
public:
    unsigned frtHeaderOld;
    unsigned iObjectKind;
};

EndBlockRecord::EndBlockRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFrtHeaderOld(0);
    setIObjectKind(0);
}

EndBlockRecord::~EndBlockRecord()
{
    delete d;
}

EndBlockRecord::EndBlockRecord( const EndBlockRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

EndBlockRecord& EndBlockRecord::operator=( const EndBlockRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned EndBlockRecord::frtHeaderOld() const
{
    return d->frtHeaderOld;
}

void EndBlockRecord::setFrtHeaderOld(unsigned frtHeaderOld )
{
    d->frtHeaderOld = frtHeaderOld;
}

unsigned EndBlockRecord::iObjectKind() const
{
    return d->iObjectKind;
}

void EndBlockRecord::setIObjectKind(unsigned iObjectKind )
{
    d->iObjectKind = iObjectKind;
}

void EndBlockRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 6) {
        setIsValid(false);
        return;
    }
    setFrtHeaderOld(readU32(data));
    setIObjectKind(readU16(data + 4));
}

void EndBlockRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(32, frtHeaderOld());
    out.writeUnsigned(16, iObjectKind());
}

void EndBlockRecord::dump( std::ostream& out ) const
{
    out << "EndBlock" << std::endl;
    out << "       FrtHeaderOld : " << frtHeaderOld() << std::endl;
    out << "        IObjectKind : " << iObjectKind() << std::endl;
}

static Record* createEndBlockRecord(Swinder::Workbook *book)
{
    return new EndBlockRecord(book);
}

// ========== ShapePropsStreamRecord ==========

const unsigned ShapePropsStreamRecord::id = 0x08a4;

class ShapePropsStreamRecord::Private
{
public:
    unsigned dwChecksum;
    unsigned grbitFrt;
    QString rgb;
    unsigned rt;
    unsigned unused;
    unsigned wObjContext;
};

ShapePropsStreamRecord::ShapePropsStreamRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setDwChecksum(0);
    setGrbitFrt(0);
    setRt(0);
    setUnused(0);
    setWObjContext(0);
}

ShapePropsStreamRecord::~ShapePropsStreamRecord()
{
    delete d;
}

ShapePropsStreamRecord::ShapePropsStreamRecord( const ShapePropsStreamRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ShapePropsStreamRecord& ShapePropsStreamRecord::operator=( const ShapePropsStreamRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned ShapePropsStreamRecord::dwChecksum() const
{
    return d->dwChecksum;
}

void ShapePropsStreamRecord::setDwChecksum(unsigned dwChecksum )
{
    d->dwChecksum = dwChecksum;
}

unsigned ShapePropsStreamRecord::grbitFrt() const
{
    return d->grbitFrt;
}

void ShapePropsStreamRecord::setGrbitFrt(unsigned grbitFrt )
{
    d->grbitFrt = grbitFrt;
}

QString ShapePropsStreamRecord::rgb() const
{
    return d->rgb;
}

void ShapePropsStreamRecord::setRgb(QString rgb )
{
    d->rgb = rgb;
}

unsigned ShapePropsStreamRecord::rt() const
{
    return d->rt;
}

void ShapePropsStreamRecord::setRt(unsigned rt )
{
    d->rt = rt;
}

unsigned ShapePropsStreamRecord::unused() const
{
    return d->unused;
}

void ShapePropsStreamRecord::setUnused(unsigned unused )
{
    d->unused = unused;
}

unsigned ShapePropsStreamRecord::wObjContext() const
{
    return d->wObjContext;
}

void ShapePropsStreamRecord::setWObjContext(unsigned wObjContext )
{
    d->wObjContext = wObjContext;
}

void ShapePropsStreamRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    bool stringLengthError = false;
    unsigned stringSize;
    if (size < 24) {
        setIsValid(false);
        return;
    }
    setRt(readU16(data));
    setGrbitFrt(readU16(data + 2));
    setWObjContext(readU16(data + 12));
    setUnused(readU16(data + 14));
    setDwChecksum(readU32(data + 16));
    unsigned cb = readU32(data + 20);
    curOffset = 24;
    setRgb(readByteString(data + curOffset, cb, size - curOffset, &stringLengthError, &stringSize));
    if (stringLengthError) {
        setIsValid(false);
        return;
    }
    curOffset += stringSize;
}

void ShapePropsStreamRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, rt());
    out.writeUnsigned(16, grbitFrt());
    out.writeUnsigned(64, 0);
    out.writeUnsigned(16, wObjContext());
    out.writeUnsigned(16, unused());
    out.writeUnsigned(32, dwChecksum());
    out.writeUnsigned(32, rgb().length());
    out.writeByteString(rgb());
}

void ShapePropsStreamRecord::dump( std::ostream& out ) const
{
    out << "ShapePropsStream" << std::endl;
    out << "                 Rt : " << rt() << std::endl;
    out << "           GrbitFrt : " << grbitFrt() << std::endl;
    out << "        WObjContext : " << wObjContext() << std::endl;
    out << "             Unused : " << unused() << std::endl;
    out << "         DwChecksum : " << dwChecksum() << std::endl;
    out << "                Rgb : " << rgb() << std::endl;
}

static Record* createShapePropsStreamRecord(Swinder::Workbook *book)
{
    return new ShapePropsStreamRecord(book);
}

// ========== TextPropsStreamRecord ==========

const unsigned TextPropsStreamRecord::id = 0x08a5;

class TextPropsStreamRecord::Private
{
public:
    unsigned dwChecksum;
    unsigned grbitFrt;
    QString rgb;
    unsigned rt;
};

TextPropsStreamRecord::TextPropsStreamRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setDwChecksum(0);
    setGrbitFrt(0);
    setRt(0);
}

TextPropsStreamRecord::~TextPropsStreamRecord()
{
    delete d;
}

TextPropsStreamRecord::TextPropsStreamRecord( const TextPropsStreamRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

TextPropsStreamRecord& TextPropsStreamRecord::operator=( const TextPropsStreamRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned TextPropsStreamRecord::dwChecksum() const
{
    return d->dwChecksum;
}

void TextPropsStreamRecord::setDwChecksum(unsigned dwChecksum )
{
    d->dwChecksum = dwChecksum;
}

unsigned TextPropsStreamRecord::grbitFrt() const
{
    return d->grbitFrt;
}

void TextPropsStreamRecord::setGrbitFrt(unsigned grbitFrt )
{
    d->grbitFrt = grbitFrt;
}

QString TextPropsStreamRecord::rgb() const
{
    return d->rgb;
}

void TextPropsStreamRecord::setRgb(QString rgb )
{
    d->rgb = rgb;
}

unsigned TextPropsStreamRecord::rt() const
{
    return d->rt;
}

void TextPropsStreamRecord::setRt(unsigned rt )
{
    d->rt = rt;
}

void TextPropsStreamRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    bool stringLengthError = false;
    unsigned stringSize;
    if (size < 20) {
        setIsValid(false);
        return;
    }
    setRt(readU16(data));
    setGrbitFrt(readU16(data + 2));
    setDwChecksum(readU32(data + 12));
    unsigned cb = readU32(data + 16);
    curOffset = 20;
    setRgb(readByteString(data + curOffset, cb, size - curOffset, &stringLengthError, &stringSize));
    if (stringLengthError) {
        setIsValid(false);
        return;
    }
    curOffset += stringSize;
}

void TextPropsStreamRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, rt());
    out.writeUnsigned(16, grbitFrt());
    out.writeUnsigned(64, 0);
    out.writeUnsigned(32, dwChecksum());
    out.writeUnsigned(32, rgb().length());
    out.writeByteString(rgb());
}

void TextPropsStreamRecord::dump( std::ostream& out ) const
{
    out << "TextPropsStream" << std::endl;
    out << "                 Rt : " << rt() << std::endl;
    out << "           GrbitFrt : " << grbitFrt() << std::endl;
    out << "         DwChecksum : " << dwChecksum() << std::endl;
    out << "                Rgb : " << rgb() << std::endl;
}

static Record* createTextPropsStreamRecord(Swinder::Workbook *book)
{
    return new TextPropsStreamRecord(book);
}

// ========== ChartFrtInfoRecord ==========

const unsigned ChartFrtInfoRecord::id = 0x850;

class ChartFrtInfoRecord::Private
{
public:
};

ChartFrtInfoRecord::ChartFrtInfoRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

ChartFrtInfoRecord::~ChartFrtInfoRecord()
{
    delete d;
}

ChartFrtInfoRecord::ChartFrtInfoRecord( const ChartFrtInfoRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ChartFrtInfoRecord& ChartFrtInfoRecord::operator=( const ChartFrtInfoRecord& record )
{
    *d = *record.d;
    return *this;
}

void ChartFrtInfoRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void ChartFrtInfoRecord::writeData( XlsRecordOutputStream& ) const
{
}

void ChartFrtInfoRecord::dump( std::ostream& out ) const
{
    out << "ChartFrtInfo" << std::endl;
}

static Record* createChartFrtInfoRecord(Swinder::Workbook *book)
{
    return new ChartFrtInfoRecord(book);
}

// ========== DataLabelExtContentsRecord ==========

const unsigned DataLabelExtContentsRecord::id = 0x86B;

class DataLabelExtContentsRecord::Private
{
public:
    bool fBubSize;
    bool fCatName;
    bool fPercent;
    bool fSerName;
    bool fValue;
    unsigned grbitFrt;
    unsigned rt;
};

DataLabelExtContentsRecord::DataLabelExtContentsRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFBubSize(false);
    setFCatName(false);
    setFPercent(false);
    setFSerName(false);
    setFValue(false);
    setGrbitFrt(0);
    setRt(0);
}

DataLabelExtContentsRecord::~DataLabelExtContentsRecord()
{
    delete d;
}

DataLabelExtContentsRecord::DataLabelExtContentsRecord( const DataLabelExtContentsRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

DataLabelExtContentsRecord& DataLabelExtContentsRecord::operator=( const DataLabelExtContentsRecord& record )
{
    *d = *record.d;
    return *this;
}

bool DataLabelExtContentsRecord::isFBubSize() const
{
    return d->fBubSize;
}

void DataLabelExtContentsRecord::setFBubSize(bool fBubSize )
{
    d->fBubSize = fBubSize;
}

bool DataLabelExtContentsRecord::isFCatName() const
{
    return d->fCatName;
}

void DataLabelExtContentsRecord::setFCatName(bool fCatName )
{
    d->fCatName = fCatName;
}

bool DataLabelExtContentsRecord::isFPercent() const
{
    return d->fPercent;
}

void DataLabelExtContentsRecord::setFPercent(bool fPercent )
{
    d->fPercent = fPercent;
}

bool DataLabelExtContentsRecord::isFSerName() const
{
    return d->fSerName;
}

void DataLabelExtContentsRecord::setFSerName(bool fSerName )
{
    d->fSerName = fSerName;
}

bool DataLabelExtContentsRecord::isFValue() const
{
    return d->fValue;
}

void DataLabelExtContentsRecord::setFValue(bool fValue )
{
    d->fValue = fValue;
}

unsigned DataLabelExtContentsRecord::grbitFrt() const
{
    return d->grbitFrt;
}

void DataLabelExtContentsRecord::setGrbitFrt(unsigned grbitFrt )
{
    d->grbitFrt = grbitFrt;
}

unsigned DataLabelExtContentsRecord::rt() const
{
    return d->rt;
}

void DataLabelExtContentsRecord::setRt(unsigned rt )
{
    d->rt = rt;
}

void DataLabelExtContentsRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 14) {
        setIsValid(false);
        return;
    }
    setRt(readU16(data));
    setGrbitFrt(readU16(data + 2));
    setFSerName(((readU8(data + 12)) & 0x1) != 0);
    setFCatName(((readU8(data + 12) >> 1) & 0x1) != 0);
    setFValue(((readU8(data + 12) >> 2) & 0x1) != 0);
    setFPercent(((readU8(data + 12) >> 3) & 0x1) != 0);
    setFBubSize(((readU8(data + 12) >> 4) & 0x1) != 0);
}

void DataLabelExtContentsRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, rt());
    out.writeUnsigned(16, grbitFrt());
    out.writeUnsigned(64, 0);
    out.writeUnsigned(1, isFSerName());
    out.writeUnsigned(1, isFCatName());
    out.writeUnsigned(1, isFValue());
    out.writeUnsigned(1, isFPercent());
    out.writeUnsigned(1, isFBubSize());
    out.writeUnsigned(11, 0);
}

void DataLabelExtContentsRecord::dump( std::ostream& out ) const
{
    out << "DataLabelExtContents" << std::endl;
    out << "                 Rt : " << rt() << std::endl;
    out << "           GrbitFrt : " << grbitFrt() << std::endl;
    out << "           FSerName : " << isFSerName() << std::endl;
    out << "           FCatName : " << isFCatName() << std::endl;
    out << "             FValue : " << isFValue() << std::endl;
    out << "           FPercent : " << isFPercent() << std::endl;
    out << "           FBubSize : " << isFBubSize() << std::endl;
}

static Record* createDataLabelExtContentsRecord(Swinder::Workbook *book)
{
    return new DataLabelExtContentsRecord(book);
}

// ========== ChartLayout12ARecord ==========

const unsigned ChartLayout12ARecord::id = 0x08a7;

class ChartLayout12ARecord::Private
{
public:
    unsigned dwChecksum;
    double dx;
    double dy;
    bool fLayoutTargetInner;
    unsigned grbitFrt;
    unsigned rt;
    unsigned wHeightMode;
    unsigned wWidthMode;
    unsigned wXMode;
    unsigned wYMode;
    double x;
    int xBR;
    int xTL;
    double y;
    int yBR;
    int yTL;
};

ChartLayout12ARecord::ChartLayout12ARecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setDwChecksum(0);
    setFLayoutTargetInner(false);
    setGrbitFrt(0);
    setRt(0);
    setWHeightMode(0);
    setWWidthMode(0);
    setWXMode(0);
    setWYMode(0);
    setXBR(0);
    setXTL(0);
    setYBR(0);
    setYTL(0);
}

ChartLayout12ARecord::~ChartLayout12ARecord()
{
    delete d;
}

ChartLayout12ARecord::ChartLayout12ARecord( const ChartLayout12ARecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ChartLayout12ARecord& ChartLayout12ARecord::operator=( const ChartLayout12ARecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned ChartLayout12ARecord::dwChecksum() const
{
    return d->dwChecksum;
}

void ChartLayout12ARecord::setDwChecksum(unsigned dwChecksum )
{
    d->dwChecksum = dwChecksum;
}

double ChartLayout12ARecord::dx() const
{
    return d->dx;
}

void ChartLayout12ARecord::setDx(double dx )
{
    d->dx = dx;
}

double ChartLayout12ARecord::dy() const
{
    return d->dy;
}

void ChartLayout12ARecord::setDy(double dy )
{
    d->dy = dy;
}

bool ChartLayout12ARecord::isFLayoutTargetInner() const
{
    return d->fLayoutTargetInner;
}

void ChartLayout12ARecord::setFLayoutTargetInner(bool fLayoutTargetInner )
{
    d->fLayoutTargetInner = fLayoutTargetInner;
}

unsigned ChartLayout12ARecord::grbitFrt() const
{
    return d->grbitFrt;
}

void ChartLayout12ARecord::setGrbitFrt(unsigned grbitFrt )
{
    d->grbitFrt = grbitFrt;
}

unsigned ChartLayout12ARecord::rt() const
{
    return d->rt;
}

void ChartLayout12ARecord::setRt(unsigned rt )
{
    d->rt = rt;
}

unsigned ChartLayout12ARecord::wHeightMode() const
{
    return d->wHeightMode;
}

void ChartLayout12ARecord::setWHeightMode(unsigned wHeightMode )
{
    d->wHeightMode = wHeightMode;
}

unsigned ChartLayout12ARecord::wWidthMode() const
{
    return d->wWidthMode;
}

void ChartLayout12ARecord::setWWidthMode(unsigned wWidthMode )
{
    d->wWidthMode = wWidthMode;
}

unsigned ChartLayout12ARecord::wXMode() const
{
    return d->wXMode;
}

void ChartLayout12ARecord::setWXMode(unsigned wXMode )
{
    d->wXMode = wXMode;
}

unsigned ChartLayout12ARecord::wYMode() const
{
    return d->wYMode;
}

void ChartLayout12ARecord::setWYMode(unsigned wYMode )
{
    d->wYMode = wYMode;
}

double ChartLayout12ARecord::x() const
{
    return d->x;
}

void ChartLayout12ARecord::setX(double x )
{
    d->x = x;
}

int ChartLayout12ARecord::xBR() const
{
    return d->xBR;
}

void ChartLayout12ARecord::setXBR(int xBR )
{
    d->xBR = xBR;
}

int ChartLayout12ARecord::xTL() const
{
    return d->xTL;
}

void ChartLayout12ARecord::setXTL(int xTL )
{
    d->xTL = xTL;
}

double ChartLayout12ARecord::y() const
{
    return d->y;
}

void ChartLayout12ARecord::setY(double y )
{
    d->y = y;
}

int ChartLayout12ARecord::yBR() const
{
    return d->yBR;
}

void ChartLayout12ARecord::setYBR(int yBR )
{
    d->yBR = yBR;
}

int ChartLayout12ARecord::yTL() const
{
    return d->yTL;
}

void ChartLayout12ARecord::setYTL(int yTL )
{
    d->yTL = yTL;
}

void ChartLayout12ARecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 66) {
        setIsValid(false);
        return;
    }
    setRt(readU16(data));
    setGrbitFrt(readU16(data + 2));
    setDwChecksum(readU32(data + 12));
    setFLayoutTargetInner(((readU8(data + 16)) & 0x1) != 0);
    setXTL(readS16(data + 18));
    setYTL(readS16(data + 20));
    setXBR(readS16(data + 22));
    setYBR(readS16(data + 24));
    setWXMode(readU16(data + 26));
    setWYMode(readU16(data + 28));
    setWWidthMode(readU16(data + 30));
    setWHeightMode(readU16(data + 32));
    setX(readFloat64(data + 34));
    setY(readFloat64(data + 42));
    setDx(readFloat64(data + 50));
    setDy(readFloat64(data + 58));
}

void ChartLayout12ARecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, rt());
    out.writeUnsigned(16, grbitFrt());
    out.writeUnsigned(64, 0);
    out.writeUnsigned(32, dwChecksum());
    out.writeUnsigned(1, isFLayoutTargetInner());
    out.writeUnsigned(15, 0);
    out.writeSigned(16, xTL());
    out.writeSigned(16, yTL());
    out.writeSigned(16, xBR());
    out.writeSigned(16, yBR());
    out.writeUnsigned(16, wXMode());
    out.writeUnsigned(16, wYMode());
    out.writeUnsigned(16, wWidthMode());
    out.writeUnsigned(16, wHeightMode());
    out.writeFloat(64, x());
    out.writeFloat(64, y());
    out.writeFloat(64, dx());
    out.writeFloat(64, dy());
}

void ChartLayout12ARecord::dump( std::ostream& out ) const
{
    out << "ChartLayout12A" << std::endl;
    out << "                 Rt : " << rt() << std::endl;
    out << "           GrbitFrt : " << grbitFrt() << std::endl;
    out << "         DwChecksum : " << dwChecksum() << std::endl;
    out << " FLayoutTargetInner : " << isFLayoutTargetInner() << std::endl;
    out << "                XTL : " << xTL() << std::endl;
    out << "                YTL : " << yTL() << std::endl;
    out << "                XBR : " << xBR() << std::endl;
    out << "                YBR : " << yBR() << std::endl;
    out << "             WXMode : " << wXMode() << std::endl;
    out << "             WYMode : " << wYMode() << std::endl;
    out << "         WWidthMode : " << wWidthMode() << std::endl;
    out << "        WHeightMode : " << wHeightMode() << std::endl;
    out << "                  X : " << x() << std::endl;
    out << "                  Y : " << y() << std::endl;
    out << "                 Dx : " << dx() << std::endl;
    out << "                 Dy : " << dy() << std::endl;
}

static Record* createChartLayout12ARecord(Swinder::Workbook *book)
{
    return new ChartLayout12ARecord(book);
}

// ========== LeftMarginRecord ==========

const unsigned LeftMarginRecord::id = 0x0026;

class LeftMarginRecord::Private
{
public:
    double leftMargin;
};

LeftMarginRecord::LeftMarginRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

LeftMarginRecord::~LeftMarginRecord()
{
    delete d;
}

LeftMarginRecord::LeftMarginRecord( const LeftMarginRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

LeftMarginRecord& LeftMarginRecord::operator=( const LeftMarginRecord& record )
{
    *d = *record.d;
    return *this;
}

double LeftMarginRecord::leftMargin() const
{
    return d->leftMargin;
}

void LeftMarginRecord::setLeftMargin(double leftMargin )
{
    d->leftMargin = leftMargin;
}

void LeftMarginRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 8) {
        setIsValid(false);
        return;
    }
    setLeftMargin(readFloat64(data));
}

void LeftMarginRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeFloat(64, leftMargin());
}

void LeftMarginRecord::dump( std::ostream& out ) const
{
    out << "LeftMargin" << std::endl;
    out << "         LeftMargin : " << leftMargin() << std::endl;
}

static Record* createLeftMarginRecord(Swinder::Workbook *book)
{
    return new LeftMarginRecord(book);
}

// ========== RightMarginRecord ==========

const unsigned RightMarginRecord::id = 0x0027;

class RightMarginRecord::Private
{
public:
    double rightMargin;
};

RightMarginRecord::RightMarginRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

RightMarginRecord::~RightMarginRecord()
{
    delete d;
}

RightMarginRecord::RightMarginRecord( const RightMarginRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

RightMarginRecord& RightMarginRecord::operator=( const RightMarginRecord& record )
{
    *d = *record.d;
    return *this;
}

double RightMarginRecord::rightMargin() const
{
    return d->rightMargin;
}

void RightMarginRecord::setRightMargin(double rightMargin )
{
    d->rightMargin = rightMargin;
}

void RightMarginRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 8) {
        setIsValid(false);
        return;
    }
    setRightMargin(readFloat64(data));
}

void RightMarginRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeFloat(64, rightMargin());
}

void RightMarginRecord::dump( std::ostream& out ) const
{
    out << "RightMargin" << std::endl;
    out << "        RightMargin : " << rightMargin() << std::endl;
}

static Record* createRightMarginRecord(Swinder::Workbook *book)
{
    return new RightMarginRecord(book);
}

// ========== TopMarginRecord ==========

const unsigned TopMarginRecord::id = 0x0028;

class TopMarginRecord::Private
{
public:
    double topMargin;
};

TopMarginRecord::TopMarginRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

TopMarginRecord::~TopMarginRecord()
{
    delete d;
}

TopMarginRecord::TopMarginRecord( const TopMarginRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

TopMarginRecord& TopMarginRecord::operator=( const TopMarginRecord& record )
{
    *d = *record.d;
    return *this;
}

double TopMarginRecord::topMargin() const
{
    return d->topMargin;
}

void TopMarginRecord::setTopMargin(double topMargin )
{
    d->topMargin = topMargin;
}

void TopMarginRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 8) {
        setIsValid(false);
        return;
    }
    setTopMargin(readFloat64(data));
}

void TopMarginRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeFloat(64, topMargin());
}

void TopMarginRecord::dump( std::ostream& out ) const
{
    out << "TopMargin" << std::endl;
    out << "          TopMargin : " << topMargin() << std::endl;
}

static Record* createTopMarginRecord(Swinder::Workbook *book)
{
    return new TopMarginRecord(book);
}

// ========== BottomMarginRecord ==========

const unsigned BottomMarginRecord::id = 0x0029;

class BottomMarginRecord::Private
{
public:
    double bottomMargin;
};

BottomMarginRecord::BottomMarginRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

BottomMarginRecord::~BottomMarginRecord()
{
    delete d;
}

BottomMarginRecord::BottomMarginRecord( const BottomMarginRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

BottomMarginRecord& BottomMarginRecord::operator=( const BottomMarginRecord& record )
{
    *d = *record.d;
    return *this;
}

double BottomMarginRecord::bottomMargin() const
{
    return d->bottomMargin;
}

void BottomMarginRecord::setBottomMargin(double bottomMargin )
{
    d->bottomMargin = bottomMargin;
}

void BottomMarginRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 8) {
        setIsValid(false);
        return;
    }
    setBottomMargin(readFloat64(data));
}

void BottomMarginRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeFloat(64, bottomMargin());
}

void BottomMarginRecord::dump( std::ostream& out ) const
{
    out << "BottomMargin" << std::endl;
    out << "       BottomMargin : " << bottomMargin() << std::endl;
}

static Record* createBottomMarginRecord(Swinder::Workbook *book)
{
    return new BottomMarginRecord(book);
}

// ========== BoundSheetRecord ==========

const unsigned BoundSheetRecord::id = 0x0085;

class BoundSheetRecord::Private
{
public:
    unsigned bofPosition;
    QString sheetName;
    SheetState sheetState;
    SheetType sheetType;
};

BoundSheetRecord::BoundSheetRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setBofPosition(0);
    setSheetState(Visible);
    setSheetType(Worksheet);
}

BoundSheetRecord::~BoundSheetRecord()
{
    delete d;
}

BoundSheetRecord::BoundSheetRecord( const BoundSheetRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

BoundSheetRecord& BoundSheetRecord::operator=( const BoundSheetRecord& record )
{
    *d = *record.d;
    return *this;
}

QString BoundSheetRecord::sheetStateToString(SheetState sheetState)
{
    switch (sheetState) {
        case Visible: return QString("Visible");
        case Hidden: return QString("Hidden");
        case StrongHidden: return QString("StrongHidden");
        default: return QString("Unknown: %1").arg(sheetState);
    }
}

QString BoundSheetRecord::sheetTypeToString(SheetType sheetType)
{
    switch (sheetType) {
        case Worksheet: return QString("Worksheet");
        case Chart: return QString("Chart");
        case VBModule: return QString("VBModule");
        default: return QString("Unknown: %1").arg(sheetType);
    }
}

unsigned BoundSheetRecord::bofPosition() const
{
    return d->bofPosition;
}

void BoundSheetRecord::setBofPosition(unsigned bofPosition )
{
    d->bofPosition = bofPosition;
}

QString BoundSheetRecord::sheetName() const
{
    return d->sheetName;
}

void BoundSheetRecord::setSheetName(QString sheetName )
{
    d->sheetName = sheetName;
}

BoundSheetRecord::SheetState BoundSheetRecord::sheetState() const
{
    return d->sheetState;
}

void BoundSheetRecord::setSheetState(SheetState sheetState )
{
    d->sheetState = sheetState;
}

BoundSheetRecord::SheetType BoundSheetRecord::sheetType() const
{
    return d->sheetType;
}

void BoundSheetRecord::setSheetType(SheetType sheetType )
{
    d->sheetType = sheetType;
}

void BoundSheetRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    bool stringLengthError = false;
    unsigned stringSize;
    if (size < 7) {
        setIsValid(false);
        return;
    }
    setBofPosition(readU32(data));
    setSheetState(static_cast<SheetState>(readU8(data + 4)));
    setSheetType(static_cast<SheetType>(readU8(data + 5)));
    unsigned sheetNameLength = readU8(data + 6);
    curOffset = 7;
    if (version() < Excel97) {
        setSheetName(readByteString(data + curOffset, sheetNameLength, size - curOffset, &stringLengthError, &stringSize));
        if (stringLengthError) {
            setIsValid(false);
            return;
        }
        curOffset += stringSize;
    }
    if (version() >= Excel97) {
        setSheetName(readUnicodeString(data + curOffset, sheetNameLength, size - curOffset, &stringLengthError, &stringSize));
        if (stringLengthError) {
            setIsValid(false);
            return;
        }
        curOffset += stringSize;
    }
}

void BoundSheetRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(32, bofPosition());
    out.writeUnsigned(8, sheetState());
    out.writeUnsigned(8, sheetType());
    out.writeUnsigned(8, sheetName().length());
    if (version() < Excel97) {
        out.writeByteString(sheetName());
    }
    if (version() >= Excel97) {
        out.writeUnicodeStringWithFlags(sheetName());
    }
}

void BoundSheetRecord::dump( std::ostream& out ) const
{
    out << "BoundSheet" << std::endl;
    out << "        BofPosition : " << bofPosition() << std::endl;
    out << "         SheetState : " << sheetStateToString(sheetState()) << std::endl;
    out << "          SheetType : " << sheetTypeToString(sheetType()) << std::endl;
    if (version() < Excel97) {
        out << "          SheetName : " << sheetName() << std::endl;
    }
    if (version() >= Excel97) {
        out << "          SheetName : " << sheetName() << std::endl;
    }
}

static Record* createBoundSheetRecord(Swinder::Workbook *book)
{
    return new BoundSheetRecord(book);
}

// ========== CalcModeRecord ==========

const unsigned CalcModeRecord::id = 0x000D;

class CalcModeRecord::Private
{
public:
    CalcMode calcMode;
};

CalcModeRecord::CalcModeRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCalcMode(Automatic);
}

CalcModeRecord::~CalcModeRecord()
{
    delete d;
}

CalcModeRecord::CalcModeRecord( const CalcModeRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

CalcModeRecord& CalcModeRecord::operator=( const CalcModeRecord& record )
{
    *d = *record.d;
    return *this;
}

QString CalcModeRecord::calcModeToString(CalcMode calcMode)
{
    switch (calcMode) {
        case Manual: return QString("Manual");
        case Automatic: return QString("Automatic");
        case SemiAutomatic: return QString("SemiAutomatic");
        default: return QString("Unknown: %1").arg(calcMode);
    }
}

CalcModeRecord::CalcMode CalcModeRecord::calcMode() const
{
    return d->calcMode;
}

void CalcModeRecord::setCalcMode(CalcMode calcMode )
{
    d->calcMode = calcMode;
}

void CalcModeRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setCalcMode(static_cast<CalcMode>(readS16(data)));
}

void CalcModeRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, calcMode());
}

void CalcModeRecord::dump( std::ostream& out ) const
{
    out << "CalcMode" << std::endl;
    out << "           CalcMode : " << calcModeToString(calcMode()) << std::endl;
}

static Record* createCalcModeRecord(Swinder::Workbook *book)
{
    return new CalcModeRecord(book);
}

// ========== ColInfoRecord ==========

const unsigned ColInfoRecord::id = 0x007D;

class ColInfoRecord::Private
{
public:
    bool bestFit;
    unsigned firstColumn;
    bool hidden;
    unsigned lastColumn;
    bool nonDefaultWidth;
    bool notCollapsed;
    unsigned outlineLevel;
    bool showPhonetic;
    unsigned width;
    unsigned xfIndex;
};

ColInfoRecord::ColInfoRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setBestFit(false);
    setFirstColumn(0);
    setHidden(false);
    setLastColumn(0);
    setNonDefaultWidth(false);
    setNotCollapsed(false);
    setOutlineLevel(0);
    setShowPhonetic(false);
    setWidth(0);
    setXfIndex(0);
}

ColInfoRecord::~ColInfoRecord()
{
    delete d;
}

ColInfoRecord::ColInfoRecord( const ColInfoRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ColInfoRecord& ColInfoRecord::operator=( const ColInfoRecord& record )
{
    *d = *record.d;
    return *this;
}

bool ColInfoRecord::isBestFit() const
{
    return d->bestFit;
}

void ColInfoRecord::setBestFit(bool bestFit )
{
    d->bestFit = bestFit;
}

unsigned ColInfoRecord::firstColumn() const
{
    return d->firstColumn;
}

void ColInfoRecord::setFirstColumn(unsigned firstColumn )
{
    d->firstColumn = firstColumn;
}

bool ColInfoRecord::isHidden() const
{
    return d->hidden;
}

void ColInfoRecord::setHidden(bool hidden )
{
    d->hidden = hidden;
}

unsigned ColInfoRecord::lastColumn() const
{
    return d->lastColumn;
}

void ColInfoRecord::setLastColumn(unsigned lastColumn )
{
    d->lastColumn = lastColumn;
}

bool ColInfoRecord::isNonDefaultWidth() const
{
    return d->nonDefaultWidth;
}

void ColInfoRecord::setNonDefaultWidth(bool nonDefaultWidth )
{
    d->nonDefaultWidth = nonDefaultWidth;
}

bool ColInfoRecord::isNotCollapsed() const
{
    return d->notCollapsed;
}

void ColInfoRecord::setNotCollapsed(bool notCollapsed )
{
    d->notCollapsed = notCollapsed;
}

unsigned ColInfoRecord::outlineLevel() const
{
    return d->outlineLevel;
}

void ColInfoRecord::setOutlineLevel(unsigned outlineLevel )
{
    d->outlineLevel = outlineLevel;
}

bool ColInfoRecord::isShowPhonetic() const
{
    return d->showPhonetic;
}

void ColInfoRecord::setShowPhonetic(bool showPhonetic )
{
    d->showPhonetic = showPhonetic;
}

unsigned ColInfoRecord::width() const
{
    return d->width;
}

void ColInfoRecord::setWidth(unsigned width )
{
    d->width = width;
}

unsigned ColInfoRecord::xfIndex() const
{
    return d->xfIndex;
}

void ColInfoRecord::setXfIndex(unsigned xfIndex )
{
    d->xfIndex = xfIndex;
}

bool ColInfoRecord::isCollapsed() const
{
    return !isNotCollapsed();
}

void ColInfoRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 12) {
        setIsValid(false);
        return;
    }
    setFirstColumn(readU16(data));
    setLastColumn(readU16(data + 2));
    setWidth(readU16(data + 4));
    setXfIndex(readU16(data + 6));
    setHidden(((readU8(data + 8)) & 0x1) != 0);
    setNonDefaultWidth(((readU8(data + 8) >> 1) & 0x1) != 0);
    setBestFit(((readU8(data + 8) >> 2) & 0x1) != 0);
    setShowPhonetic(((readU8(data + 8) >> 3) & 0x1) != 0);
    setOutlineLevel(((readU8(data + 9)) & 0x7));
    setNotCollapsed(((readU8(data + 9) >> 4) & 0x1) != 0);
}

void ColInfoRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, firstColumn());
    out.writeUnsigned(16, lastColumn());
    out.writeUnsigned(16, width());
    out.writeUnsigned(16, xfIndex());
    out.writeUnsigned(1, isHidden());
    out.writeUnsigned(1, isNonDefaultWidth());
    out.writeUnsigned(1, isBestFit());
    out.writeUnsigned(1, isShowPhonetic());
    out.writeUnsigned(4, 0);
    out.writeUnsigned(3, outlineLevel());
    out.writeUnsigned(1, 0);
    out.writeUnsigned(1, isNotCollapsed());
    out.writeUnsigned(3, 0);
    out.writeUnsigned(16, 0);
}

void ColInfoRecord::dump( std::ostream& out ) const
{
    out << "ColInfo" << std::endl;
    out << "        FirstColumn : " << firstColumn() << std::endl;
    out << "         LastColumn : " << lastColumn() << std::endl;
    out << "              Width : " << width() << std::endl;
    out << "            XfIndex : " << xfIndex() << std::endl;
    out << "             Hidden : " << isHidden() << std::endl;
    out << "    NonDefaultWidth : " << isNonDefaultWidth() << std::endl;
    out << "            BestFit : " << isBestFit() << std::endl;
    out << "       ShowPhonetic : " << isShowPhonetic() << std::endl;
    out << "       OutlineLevel : " << outlineLevel() << std::endl;
    out << "       NotCollapsed : " << isNotCollapsed() << std::endl;
}

static Record* createColInfoRecord(Swinder::Workbook *book)
{
    return new ColInfoRecord(book);
}

// ========== DataTableRecord ==========

const unsigned DataTableRecord::id = 0x0236;

class DataTableRecord::Private
{
public:
    bool alwaysCalc;
    unsigned firstColumn;
    unsigned firstRow;
    unsigned inputColumn1;
    unsigned inputColumn2;
    unsigned inputRow1;
    unsigned inputRow2;
    unsigned lastColumn;
    unsigned lastRow;
    bool rowColTable;
    bool rowInput;
};

DataTableRecord::DataTableRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setAlwaysCalc(false);
    setFirstColumn(0);
    setFirstRow(0);
    setInputColumn1(0);
    setInputColumn2(0);
    setInputRow1(0);
    setInputRow2(0);
    setLastColumn(0);
    setLastRow(0);
    setRowColTable(false);
    setRowInput(false);
}

DataTableRecord::~DataTableRecord()
{
    delete d;
}

DataTableRecord::DataTableRecord( const DataTableRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

DataTableRecord& DataTableRecord::operator=( const DataTableRecord& record )
{
    *d = *record.d;
    return *this;
}

QString DataTableRecord::directionToString(Direction direction)
{
    switch (direction) {
        case InputRow: return QString("InputRow");
        case InputColumn: return QString("InputColumn");
        case Input2D: return QString("Input2D");
        default: return QString("Unknown: %1").arg(direction);
    }
}

bool DataTableRecord::isAlwaysCalc() const
{
    return d->alwaysCalc;
}

void DataTableRecord::setAlwaysCalc(bool alwaysCalc )
{
    d->alwaysCalc = alwaysCalc;
}

unsigned DataTableRecord::firstColumn() const
{
    return d->firstColumn;
}

void DataTableRecord::setFirstColumn(unsigned firstColumn )
{
    d->firstColumn = firstColumn;
}

unsigned DataTableRecord::firstRow() const
{
    return d->firstRow;
}

void DataTableRecord::setFirstRow(unsigned firstRow )
{
    d->firstRow = firstRow;
}

unsigned DataTableRecord::inputColumn1() const
{
    return d->inputColumn1;
}

void DataTableRecord::setInputColumn1(unsigned inputColumn1 )
{
    d->inputColumn1 = inputColumn1;
}

unsigned DataTableRecord::inputColumn2() const
{
    return d->inputColumn2;
}

void DataTableRecord::setInputColumn2(unsigned inputColumn2 )
{
    d->inputColumn2 = inputColumn2;
}

unsigned DataTableRecord::inputRow1() const
{
    return d->inputRow1;
}

void DataTableRecord::setInputRow1(unsigned inputRow1 )
{
    d->inputRow1 = inputRow1;
}

unsigned DataTableRecord::inputRow2() const
{
    return d->inputRow2;
}

void DataTableRecord::setInputRow2(unsigned inputRow2 )
{
    d->inputRow2 = inputRow2;
}

unsigned DataTableRecord::lastColumn() const
{
    return d->lastColumn;
}

void DataTableRecord::setLastColumn(unsigned lastColumn )
{
    d->lastColumn = lastColumn;
}

unsigned DataTableRecord::lastRow() const
{
    return d->lastRow;
}

void DataTableRecord::setLastRow(unsigned lastRow )
{
    d->lastRow = lastRow;
}

bool DataTableRecord::isRowColTable() const
{
    return d->rowColTable;
}

void DataTableRecord::setRowColTable(bool rowColTable )
{
    d->rowColTable = rowColTable;
}

bool DataTableRecord::isRowInput() const
{
    return d->rowInput;
}

void DataTableRecord::setRowInput(bool rowInput )
{
    d->rowInput = rowInput;
}

DataTableRecord::Direction DataTableRecord::direction() const
{
    return isRowColTable() ? Input2D : isRowInput() ? InputRow : InputColumn;
}

void DataTableRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 16) {
        setIsValid(false);
        return;
    }
    setFirstRow(readU16(data));
    setLastRow(readU16(data + 2));
    setFirstColumn(readU8(data + 4));
    setLastColumn(readU8(data + 5));
    setAlwaysCalc(((readU8(data + 6)) & 0x1) != 0);
    setRowInput(((readU8(data + 6) >> 2) & 0x1) != 0);
    setRowColTable(((readU8(data + 6) >> 3) & 0x1) != 0);
    setInputRow1(readU16(data + 8));
    setInputColumn1(readU16(data + 10));
    setInputRow2(readU16(data + 12));
    setInputColumn2(readU16(data + 14));
}

void DataTableRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, firstRow());
    out.writeUnsigned(16, lastRow());
    out.writeUnsigned(8, firstColumn());
    out.writeUnsigned(8, lastColumn());
    out.writeUnsigned(1, isAlwaysCalc());
    out.writeUnsigned(1, 0);
    out.writeUnsigned(1, isRowInput());
    out.writeUnsigned(1, isRowColTable());
    out.writeUnsigned(12, 0);
    out.writeUnsigned(16, inputRow1());
    out.writeUnsigned(16, inputColumn1());
    out.writeUnsigned(16, inputRow2());
    out.writeUnsigned(16, inputColumn2());
}

void DataTableRecord::dump( std::ostream& out ) const
{
    out << "DataTable" << std::endl;
    out << "           FirstRow : " << firstRow() << std::endl;
    out << "            LastRow : " << lastRow() << std::endl;
    out << "        FirstColumn : " << firstColumn() << std::endl;
    out << "         LastColumn : " << lastColumn() << std::endl;
    out << "         AlwaysCalc : " << isAlwaysCalc() << std::endl;
    out << "           RowInput : " << isRowInput() << std::endl;
    out << "        RowColTable : " << isRowColTable() << std::endl;
    out << "          InputRow1 : " << inputRow1() << std::endl;
    out << "       InputColumn1 : " << inputColumn1() << std::endl;
    out << "          InputRow2 : " << inputRow2() << std::endl;
    out << "       InputColumn2 : " << inputColumn2() << std::endl;
}

static Record* createDataTableRecord(Swinder::Workbook *book)
{
    return new DataTableRecord(book);
}

// ========== DateModeRecord ==========

const unsigned DateModeRecord::id = 0x0022;

class DateModeRecord::Private
{
public:
    bool base1904;
};

DateModeRecord::DateModeRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setBase1904(false);
}

DateModeRecord::~DateModeRecord()
{
    delete d;
}

DateModeRecord::DateModeRecord( const DateModeRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

DateModeRecord& DateModeRecord::operator=( const DateModeRecord& record )
{
    *d = *record.d;
    return *this;
}

bool DateModeRecord::isBase1904() const
{
    return d->base1904;
}

void DateModeRecord::setBase1904(bool base1904 )
{
    d->base1904 = base1904;
}

void DateModeRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setBase1904(readU16(data) != 0);
}

void DateModeRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, isBase1904());
}

void DateModeRecord::dump( std::ostream& out ) const
{
    out << "DateMode" << std::endl;
    out << "           Base1904 : " << isBase1904() << std::endl;
}

static Record* createDateModeRecord(Swinder::Workbook *book)
{
    return new DateModeRecord(book);
}

// ========== DimensionRecord ==========

const unsigned DimensionRecord::id = 0x0200;

class DimensionRecord::Private
{
public:
    unsigned firstColumn;
    unsigned firstRow;
    unsigned lastColumnPlus1;
    unsigned lastRowPlus1;
};

DimensionRecord::DimensionRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFirstColumn(0);
    setFirstRow(0);
    setLastColumnPlus1(0);
    setLastRowPlus1(0);
}

DimensionRecord::~DimensionRecord()
{
    delete d;
}

DimensionRecord::DimensionRecord( const DimensionRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

DimensionRecord& DimensionRecord::operator=( const DimensionRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned DimensionRecord::firstColumn() const
{
    return d->firstColumn;
}

void DimensionRecord::setFirstColumn(unsigned firstColumn )
{
    d->firstColumn = firstColumn;
}

unsigned DimensionRecord::firstRow() const
{
    return d->firstRow;
}

void DimensionRecord::setFirstRow(unsigned firstRow )
{
    d->firstRow = firstRow;
}

unsigned DimensionRecord::lastColumnPlus1() const
{
    return d->lastColumnPlus1;
}

void DimensionRecord::setLastColumnPlus1(unsigned lastColumnPlus1 )
{
    d->lastColumnPlus1 = lastColumnPlus1;
}

unsigned DimensionRecord::lastRowPlus1() const
{
    return d->lastRowPlus1;
}

void DimensionRecord::setLastRowPlus1(unsigned lastRowPlus1 )
{
    d->lastRowPlus1 = lastRowPlus1;
}

unsigned DimensionRecord::lastRow() const
{
    return lastRowPlus1() == 0 ? 0 : lastRowPlus1() - 1;
}

unsigned DimensionRecord::lastColumn() const
{
    return lastColumnPlus1() == 0 ? 0 : lastColumnPlus1() - 1;
}

void DimensionRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    curOffset = 0;
    if (version() < Excel97) {
        if (size < curOffset + 4) {
            setIsValid(false);
            return;
        }
        setFirstRow(readU16(data + curOffset));
        setLastRowPlus1(readU16(data + curOffset + 2));
        curOffset += 4;
    }
    if (version() >= Excel97) {
        if (size < curOffset + 8) {
            setIsValid(false);
            return;
        }
        setFirstRow(readU32(data + curOffset));
        setLastRowPlus1(readU32(data + curOffset + 4));
        curOffset += 8;
    }
    if (size < curOffset + 6) {
        setIsValid(false);
        return;
    }
    setFirstColumn(readU16(data + curOffset));
    setLastColumnPlus1(readU16(data + curOffset + 2));
}

void DimensionRecord::writeData( XlsRecordOutputStream& out ) const
{
    if (version() < Excel97) {
        out.writeUnsigned(16, firstRow());
        out.writeUnsigned(16, lastRowPlus1());
    }
    if (version() >= Excel97) {
        out.writeUnsigned(32, firstRow());
        out.writeUnsigned(32, lastRowPlus1());
    }
    out.writeUnsigned(16, firstColumn());
    out.writeUnsigned(16, lastColumnPlus1());
    out.writeUnsigned(16, 0);
}

void DimensionRecord::dump( std::ostream& out ) const
{
    out << "Dimension" << std::endl;
    if (version() < Excel97) {
        out << "           FirstRow : " << firstRow() << std::endl;
        out << "       LastRowPlus1 : " << lastRowPlus1() << std::endl;
    }
    if (version() >= Excel97) {
        out << "           FirstRow : " << firstRow() << std::endl;
        out << "       LastRowPlus1 : " << lastRowPlus1() << std::endl;
    }
    out << "        FirstColumn : " << firstColumn() << std::endl;
    out << "    LastColumnPlus1 : " << lastColumnPlus1() << std::endl;
}

static Record* createDimensionRecord(Swinder::Workbook *book)
{
    return new DimensionRecord(book);
}

// ========== ExternSheetRecord ==========

const unsigned ExternSheetRecord::id = 0x0017;

class ExternSheetRecord::Private
{
public:
    std::vector<unsigned> bookRef;
    std::vector<unsigned> firstSheetRef;
    std::vector<unsigned> lastSheetRef;
    unsigned refCount;
};

ExternSheetRecord::ExternSheetRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setRefCount(0);
}

ExternSheetRecord::~ExternSheetRecord()
{
    delete d;
}

ExternSheetRecord::ExternSheetRecord( const ExternSheetRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ExternSheetRecord& ExternSheetRecord::operator=( const ExternSheetRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned ExternSheetRecord::bookRef( unsigned index ) const
{
    return d->bookRef[index];
}

void ExternSheetRecord::setBookRef( unsigned index, unsigned bookRef )
{
    d->bookRef[index] = bookRef;
}

unsigned ExternSheetRecord::firstSheetRef( unsigned index ) const
{
    return d->firstSheetRef[index];
}

void ExternSheetRecord::setFirstSheetRef( unsigned index, unsigned firstSheetRef )
{
    d->firstSheetRef[index] = firstSheetRef;
}

unsigned ExternSheetRecord::lastSheetRef( unsigned index ) const
{
    return d->lastSheetRef[index];
}

void ExternSheetRecord::setLastSheetRef( unsigned index, unsigned lastSheetRef )
{
    d->lastSheetRef[index] = lastSheetRef;
}

unsigned ExternSheetRecord::refCount() const
{
    return d->refCount;
}

void ExternSheetRecord::setRefCount(unsigned refCount )
{
    d->refCount = refCount;
    d->bookRef.resize(refCount);
    d->firstSheetRef.resize(refCount);
    d->lastSheetRef.resize(refCount);
}

void ExternSheetRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    curOffset = 0;
    if (version() >= Excel97) {
        if (size < curOffset + 2) {
            setIsValid(false);
            return;
        }
        setRefCount(readU16(data + curOffset));
        curOffset += 2;
        for (unsigned i = 0, endi = refCount(); i < endi; ++i) {
            if (size < curOffset + 6) {
                setIsValid(false);
                return;
            }
            setBookRef(i, readU16(data + curOffset));
            setFirstSheetRef(i, readU16(data + curOffset + 2));
            setLastSheetRef(i, readU16(data + curOffset + 4));
            curOffset += 6;
        }
    }
}

void ExternSheetRecord::writeData( XlsRecordOutputStream& out ) const
{
    if (version() >= Excel97) {
        out.writeUnsigned(16, refCount());
        for (unsigned i = 0, endi = refCount(); i < endi; ++i) {
            out.writeUnsigned(16, bookRef(i));
            out.writeUnsigned(16, firstSheetRef(i));
            out.writeUnsigned(16, lastSheetRef(i));
        }
    }
}

void ExternSheetRecord::dump( std::ostream& out ) const
{
    out << "ExternSheet" << std::endl;
    if (version() >= Excel97) {
        out << "           RefCount : " << refCount() << std::endl;
        for (unsigned i = 0, endi = refCount(); i < endi; ++i) {
            out << "        BookRef " << std::setw(3) << i <<" : " << bookRef(i) << std::endl;
            out << "  FirstSheetRef " << std::setw(3) << i <<" : " << firstSheetRef(i) << std::endl;
            out << "   LastSheetRef " << std::setw(3) << i <<" : " << lastSheetRef(i) << std::endl;
        }
    }
}

static Record* createExternSheetRecord(Swinder::Workbook *book)
{
    return new ExternSheetRecord(book);
}

// ========== FontRecord ==========

const unsigned FontRecord::id = 0x0031;

class FontRecord::Private
{
public:
    unsigned characterSet;
    unsigned colorIndex;
    bool condensed;
    Escapement escapement;
    bool extended;
    FontFamily fontFamily;
    QString fontName;
    unsigned fontWeight;
    unsigned height;
    bool italic;
    bool outline;
    bool shadow;
    bool strikeout;
    Underline underline;
};

FontRecord::FontRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCharacterSet(0);
    setColorIndex(0x7FFF);
    setCondensed(false);
    setEscapement(Normal);
    setExtended(false);
    setFontFamily(Unknown);
    setFontWeight(400);
    setHeight(200);
    setItalic(false);
    setOutline(false);
    setShadow(false);
    setStrikeout(false);
    setUnderline(None);
}

FontRecord::~FontRecord()
{
    delete d;
}

FontRecord::FontRecord( const FontRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

FontRecord& FontRecord::operator=( const FontRecord& record )
{
    *d = *record.d;
    return *this;
}

QString FontRecord::escapementToString(Escapement escapement)
{
    switch (escapement) {
        case Normal: return QString("Normal");
        case Superscript: return QString("Superscript");
        case Subscript: return QString("Subscript");
        default: return QString("Unknown: %1").arg(escapement);
    }
}

QString FontRecord::underlineToString(Underline underline)
{
    switch (underline) {
        case None: return QString("None");
        case Single: return QString("Single");
        case Double: return QString("Double");
        case SingleAccounting: return QString("SingleAccounting");
        case DoubleAccounting: return QString("DoubleAccounting");
        default: return QString("Unknown: %1").arg(underline);
    }
}

QString FontRecord::fontFamilyToString(FontFamily fontFamily)
{
    switch (fontFamily) {
        case Unknown: return QString("Unknown");
        case Roman: return QString("Roman");
        case Swiss: return QString("Swiss");
        case Modern: return QString("Modern");
        case Script: return QString("Script");
        case Decorative: return QString("Decorative");
        default: return QString("Unknown: %1").arg(fontFamily);
    }
}

unsigned FontRecord::characterSet() const
{
    return d->characterSet;
}

void FontRecord::setCharacterSet(unsigned characterSet )
{
    d->characterSet = characterSet;
}

unsigned FontRecord::colorIndex() const
{
    return d->colorIndex;
}

void FontRecord::setColorIndex(unsigned colorIndex )
{
    d->colorIndex = colorIndex;
}

bool FontRecord::isCondensed() const
{
    return d->condensed;
}

void FontRecord::setCondensed(bool condensed )
{
    d->condensed = condensed;
}

FontRecord::Escapement FontRecord::escapement() const
{
    return d->escapement;
}

void FontRecord::setEscapement(Escapement escapement )
{
    d->escapement = escapement;
}

bool FontRecord::isExtended() const
{
    return d->extended;
}

void FontRecord::setExtended(bool extended )
{
    d->extended = extended;
}

FontRecord::FontFamily FontRecord::fontFamily() const
{
    return d->fontFamily;
}

void FontRecord::setFontFamily(FontFamily fontFamily )
{
    d->fontFamily = fontFamily;
}

QString FontRecord::fontName() const
{
    return d->fontName;
}

void FontRecord::setFontName(QString fontName )
{
    d->fontName = fontName;
}

unsigned FontRecord::fontWeight() const
{
    return d->fontWeight;
}

void FontRecord::setFontWeight(unsigned fontWeight )
{
    d->fontWeight = fontWeight;
}

unsigned FontRecord::height() const
{
    return d->height;
}

void FontRecord::setHeight(unsigned height )
{
    d->height = height;
}

bool FontRecord::isItalic() const
{
    return d->italic;
}

void FontRecord::setItalic(bool italic )
{
    d->italic = italic;
}

bool FontRecord::isOutline() const
{
    return d->outline;
}

void FontRecord::setOutline(bool outline )
{
    d->outline = outline;
}

bool FontRecord::isShadow() const
{
    return d->shadow;
}

void FontRecord::setShadow(bool shadow )
{
    d->shadow = shadow;
}

bool FontRecord::isStrikeout() const
{
    return d->strikeout;
}

void FontRecord::setStrikeout(bool strikeout )
{
    d->strikeout = strikeout;
}

FontRecord::Underline FontRecord::underline() const
{
    return d->underline;
}

void FontRecord::setUnderline(Underline underline )
{
    d->underline = underline;
}

void FontRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    bool stringLengthError = false;
    unsigned stringSize;
    if (size < 15) {
        setIsValid(false);
        return;
    }
    setHeight(readU16(data));
    setItalic(((readU8(data + 2) >> 1) & 0x1) != 0);
    setStrikeout(((readU8(data + 2) >> 3) & 0x1) != 0);
    setOutline(((readU8(data + 2) >> 4) & 0x1) != 0);
    setShadow(((readU8(data + 2) >> 5) & 0x1) != 0);
    setCondensed(((readU8(data + 2) >> 6) & 0x1) != 0);
    setExtended(((readU8(data + 2) >> 7) & 0x1) != 0);
    setColorIndex(readU16(data + 4));
    setFontWeight(readU16(data + 6));
    setEscapement(static_cast<Escapement>(readU16(data + 8)));
    setUnderline(static_cast<Underline>(readU8(data + 10)));
    setFontFamily(static_cast<FontFamily>(readU8(data + 11)));
    setCharacterSet(readU8(data + 12));
    unsigned fontNameLength = readU8(data + 14);
    curOffset = 15;
    if (version() < Excel97) {
        setFontName(readByteString(data + curOffset, fontNameLength, size - curOffset, &stringLengthError, &stringSize));
        if (stringLengthError) {
            setIsValid(false);
            return;
        }
        curOffset += stringSize;
    }
    if (version() >= Excel97) {
        setFontName(readUnicodeString(data + curOffset, fontNameLength, size - curOffset, &stringLengthError, &stringSize));
        if (stringLengthError) {
            setIsValid(false);
            return;
        }
        curOffset += stringSize;
    }
}

void FontRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, height());
    out.writeUnsigned(1, 0);
    out.writeUnsigned(1, isItalic());
    out.writeUnsigned(1, 0);
    out.writeUnsigned(1, isStrikeout());
    out.writeUnsigned(1, isOutline());
    out.writeUnsigned(1, isShadow());
    out.writeUnsigned(1, isCondensed());
    out.writeUnsigned(1, isExtended());
    out.writeUnsigned(8, 0);
    out.writeUnsigned(16, colorIndex());
    out.writeUnsigned(16, fontWeight());
    out.writeUnsigned(16, escapement());
    out.writeUnsigned(8, underline());
    out.writeUnsigned(8, fontFamily());
    out.writeUnsigned(8, characterSet());
    out.writeUnsigned(8, 0);
    out.writeUnsigned(8, fontName().length());
    if (version() < Excel97) {
        out.writeByteString(fontName());
    }
    if (version() >= Excel97) {
        out.writeUnicodeStringWithFlags(fontName());
    }
}

void FontRecord::dump( std::ostream& out ) const
{
    out << "Font" << std::endl;
    out << "             Height : " << height() << std::endl;
    out << "             Italic : " << isItalic() << std::endl;
    out << "          Strikeout : " << isStrikeout() << std::endl;
    out << "            Outline : " << isOutline() << std::endl;
    out << "             Shadow : " << isShadow() << std::endl;
    out << "          Condensed : " << isCondensed() << std::endl;
    out << "           Extended : " << isExtended() << std::endl;
    out << "         ColorIndex : " << colorIndex() << std::endl;
    out << "         FontWeight : " << fontWeight() << std::endl;
    out << "         Escapement : " << escapementToString(escapement()) << std::endl;
    out << "          Underline : " << underlineToString(underline()) << std::endl;
    out << "         FontFamily : " << fontFamilyToString(fontFamily()) << std::endl;
    out << "       CharacterSet : " << characterSet() << std::endl;
    if (version() < Excel97) {
        out << "           FontName : " << fontName() << std::endl;
    }
    if (version() >= Excel97) {
        out << "           FontName : " << fontName() << std::endl;
    }
}

static Record* createFontRecord(Swinder::Workbook *book)
{
    return new FontRecord(book);
}

// ========== HeaderRecord ==========

const unsigned HeaderRecord::id = 0x0014;

class HeaderRecord::Private
{
public:
    QString header;
};

HeaderRecord::HeaderRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

HeaderRecord::~HeaderRecord()
{
    delete d;
}

HeaderRecord::HeaderRecord( const HeaderRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

HeaderRecord& HeaderRecord::operator=( const HeaderRecord& record )
{
    *d = *record.d;
    return *this;
}

QString HeaderRecord::header() const
{
    return d->header;
}

void HeaderRecord::setHeader(QString header )
{
    d->header = header;
}

void HeaderRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    bool stringLengthError = false;
    unsigned stringSize;
    curOffset = 0;
    if (recordSize() > 0) {
        if (version() < Excel97) {
            if (size < curOffset + 1) {
                setIsValid(false);
                return;
            }
            unsigned headerLength = readU8(data + curOffset);
            curOffset += 1;
            setHeader(readByteString(data + curOffset, headerLength, size - curOffset, &stringLengthError, &stringSize));
            if (stringLengthError) {
                setIsValid(false);
                return;
            }
            curOffset += stringSize;
        }
        if (version() >= Excel97) {
            if (size < curOffset + 2) {
                setIsValid(false);
                return;
            }
            unsigned headerLength = readU16(data + curOffset);
            curOffset += 2;
            setHeader(readUnicodeString(data + curOffset, headerLength, size - curOffset, &stringLengthError, &stringSize));
            if (stringLengthError) {
                setIsValid(false);
                return;
            }
            curOffset += stringSize;
        }
    }
}

void HeaderRecord::writeData( XlsRecordOutputStream& out ) const
{
    if (recordSize() > 0) {
        if (version() < Excel97) {
            out.writeUnsigned(8, header().length());
            out.writeByteString(header());
        }
        if (version() >= Excel97) {
            out.writeUnsigned(16, header().length());
            out.writeUnicodeStringWithFlags(header());
        }
    }
}

void HeaderRecord::dump( std::ostream& out ) const
{
    out << "Header" << std::endl;
    if (recordSize() > 0) {
        if (version() < Excel97) {
            out << "             Header : " << header() << std::endl;
        }
        if (version() >= Excel97) {
            out << "             Header : " << header() << std::endl;
        }
    }
}

static Record* createHeaderRecord(Swinder::Workbook *book)
{
    return new HeaderRecord(book);
}

// ========== FooterRecord ==========

const unsigned FooterRecord::id = 0x0015;

class FooterRecord::Private
{
public:
    QString footer;
};

FooterRecord::FooterRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

FooterRecord::~FooterRecord()
{
    delete d;
}

FooterRecord::FooterRecord( const FooterRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

FooterRecord& FooterRecord::operator=( const FooterRecord& record )
{
    *d = *record.d;
    return *this;
}

QString FooterRecord::footer() const
{
    return d->footer;
}

void FooterRecord::setFooter(QString footer )
{
    d->footer = footer;
}

void FooterRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    bool stringLengthError = false;
    unsigned stringSize;
    curOffset = 0;
    if (recordSize() > 0) {
        if (version() < Excel97) {
            if (size < curOffset + 1) {
                setIsValid(false);
                return;
            }
            unsigned footerLength = readU8(data + curOffset);
            curOffset += 1;
            setFooter(readByteString(data + curOffset, footerLength, size - curOffset, &stringLengthError, &stringSize));
            if (stringLengthError) {
                setIsValid(false);
                return;
            }
            curOffset += stringSize;
        }
        if (version() >= Excel97) {
            if (size < curOffset + 2) {
                setIsValid(false);
                return;
            }
            unsigned footerLength = readU16(data + curOffset);
            curOffset += 2;
            setFooter(readUnicodeString(data + curOffset, footerLength, size - curOffset, &stringLengthError, &stringSize));
            if (stringLengthError) {
                setIsValid(false);
                return;
            }
            curOffset += stringSize;
        }
    }
}

void FooterRecord::writeData( XlsRecordOutputStream& out ) const
{
    if (recordSize() > 0) {
        if (version() < Excel97) {
            out.writeUnsigned(8, footer().length());
            out.writeByteString(footer());
        }
        if (version() >= Excel97) {
            out.writeUnsigned(16, footer().length());
            out.writeUnicodeStringWithFlags(footer());
        }
    }
}

void FooterRecord::dump( std::ostream& out ) const
{
    out << "Footer" << std::endl;
    if (recordSize() > 0) {
        if (version() < Excel97) {
            out << "             Footer : " << footer() << std::endl;
        }
        if (version() >= Excel97) {
            out << "             Footer : " << footer() << std::endl;
        }
    }
}

static Record* createFooterRecord(Swinder::Workbook *book)
{
    return new FooterRecord(book);
}

// ========== FormatRecord ==========

const unsigned FormatRecord::id = 0x041E;

class FormatRecord::Private
{
public:
    QString formatString;
    unsigned index;
};

FormatRecord::FormatRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setIndex(0);
}

FormatRecord::~FormatRecord()
{
    delete d;
}

FormatRecord::FormatRecord( const FormatRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

FormatRecord& FormatRecord::operator=( const FormatRecord& record )
{
    *d = *record.d;
    return *this;
}

QString FormatRecord::formatString() const
{
    return d->formatString;
}

void FormatRecord::setFormatString(QString formatString )
{
    d->formatString = formatString;
}

unsigned FormatRecord::index() const
{
    return d->index;
}

void FormatRecord::setIndex(unsigned index )
{
    d->index = index;
}

void FormatRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    bool stringLengthError = false;
    unsigned stringSize;
    if (size < 2) {
        setIsValid(false);
        return;
    }
    setIndex(readU16(data));
    curOffset = 2;
    if (version() < Excel97) {
        if (size < curOffset + 1) {
            setIsValid(false);
            return;
        }
        unsigned formatStringLength = readU8(data + curOffset);
        curOffset += 1;
        setFormatString(readByteString(data + curOffset, formatStringLength, size - curOffset, &stringLengthError, &stringSize));
        if (stringLengthError) {
            setIsValid(false);
            return;
        }
        curOffset += stringSize;
    }
    if (version() >= Excel97) {
        if (size < curOffset + 2) {
            setIsValid(false);
            return;
        }
        unsigned formatStringLength = readU16(data + curOffset);
        curOffset += 2;
        setFormatString(readUnicodeString(data + curOffset, formatStringLength, size - curOffset, &stringLengthError, &stringSize));
        if (stringLengthError) {
            setIsValid(false);
            return;
        }
        curOffset += stringSize;
    }
}

void FormatRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, index());
    if (version() < Excel97) {
        out.writeUnsigned(8, formatString().length());
        out.writeByteString(formatString());
    }
    if (version() >= Excel97) {
        out.writeUnsigned(16, formatString().length());
        out.writeUnicodeStringWithFlags(formatString());
    }
}

void FormatRecord::dump( std::ostream& out ) const
{
    out << "Format" << std::endl;
    out << "              Index : " << index() << std::endl;
    if (version() < Excel97) {
        out << "       FormatString : " << formatString() << std::endl;
    }
    if (version() >= Excel97) {
        out << "       FormatString : " << formatString() << std::endl;
    }
}

static Record* createFormatRecord(Swinder::Workbook *book)
{
    return new FormatRecord(book);
}

// ========== XFRecord ==========

const unsigned XFRecord::id = 0x00e0;

class XFRecord::Private
{
public:
    unsigned bottomBorderColor;
    BorderStyle bottomBorderStyle;
    unsigned diagonalBorderColor;
    BorderStyle diagonalBorderStyle;
    bool diagonalBottomLeftBorder;
    bool diagonalTopLeftBorder;
    bool dontUpdateAlcFromParent;
    bool dontUpdateBackgroundFromParent;
    bool dontUpdateBorderFromParent;
    bool dontUpdateFontFromParent;
    bool dontUpdateNumberFormatFromParent;
    bool dontUpdateProtectionFromParent;
    FillPattern fillPattern;
    unsigned fontIndex;
    unsigned formatIndex;
    bool formulaHidden;
    bool hasPrefixChars;
    bool hasXFExt;
    HorizontalAlignment horizontalAlignment;
    unsigned indentationLevel;
    bool isButton;
    bool isStyleXF;
    bool lastLineJustified;
    unsigned leftBorderColor;
    BorderStyle leftBorderStyle;
    bool locked;
    unsigned parentStyle;
    unsigned patternBackColor;
    unsigned patternForeColor;
    unsigned rawTextRotation1;
    unsigned rawTextRotation97;
    ReadingOrder readingOrder;
    unsigned rightBorderColor;
    BorderStyle rightBorderStyle;
    bool shrinkToFit;
    bool textWrap;
    unsigned topBorderColor;
    BorderStyle topBorderStyle;
    VerticalAlignment verticalAlignment;
};

XFRecord::XFRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setBottomBorderColor(0);
    setBottomBorderStyle(NoLine);
    setDiagonalBorderColor(0);
    setDiagonalBorderStyle(NoLine);
    setDiagonalBottomLeftBorder(false);
    setDiagonalTopLeftBorder(false);
    setDontUpdateAlcFromParent(false);
    setDontUpdateBackgroundFromParent(false);
    setDontUpdateBorderFromParent(false);
    setDontUpdateFontFromParent(false);
    setDontUpdateNumberFormatFromParent(false);
    setDontUpdateProtectionFromParent(false);
    setFillPattern(Null);
    setFontIndex(0);
    setFormatIndex(0);
    setFormulaHidden(false);
    setHasPrefixChars(false);
    setHasXFExt(false);
    setHorizontalAlignment(General);
    setIndentationLevel(0);
    setIsButton(false);
    setIsStyleXF(true);
    setLastLineJustified(false);
    setLeftBorderColor(0);
    setLeftBorderStyle(NoLine);
    setLocked(true);
    setParentStyle(0xFFF);
    setPatternBackColor(65);
    setPatternForeColor(64);
    setRawTextRotation1(0);
    setRawTextRotation97(0);
    setReadingOrder(Context);
    setRightBorderColor(0);
    setRightBorderStyle(NoLine);
    setShrinkToFit(false);
    setTextWrap(false);
    setTopBorderColor(0);
    setTopBorderStyle(NoLine);
    setVerticalAlignment(Bottom);
}

XFRecord::~XFRecord()
{
    delete d;
}

XFRecord::XFRecord( const XFRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

XFRecord& XFRecord::operator=( const XFRecord& record )
{
    *d = *record.d;
    return *this;
}

QString XFRecord::horizontalAlignmentToString(HorizontalAlignment horizontalAlignment)
{
    switch (horizontalAlignment) {
        case Unspecified: return QString("Unspecified");
        case General: return QString("General");
        case Left: return QString("Left");
        case Centered: return QString("Centered");
        case Right: return QString("Right");
        case Filled: return QString("Filled");
        case Justified: return QString("Justified");
        case CenteredSelection: return QString("CenteredSelection");
        case Distributed: return QString("Distributed");
        default: return QString("Unknown: %1").arg(horizontalAlignment);
    }
}

QString XFRecord::verticalAlignmentToString(VerticalAlignment verticalAlignment)
{
    switch (verticalAlignment) {
        case Top: return QString("Top");
        case VCentered: return QString("VCentered");
        case Bottom: return QString("Bottom");
        case VJustified: return QString("VJustified");
        case VDistributed: return QString("VDistributed");
        default: return QString("Unknown: %1").arg(verticalAlignment);
    }
}

QString XFRecord::readingOrderToString(ReadingOrder readingOrder)
{
    switch (readingOrder) {
        case Context: return QString("Context");
        case LeftToRight: return QString("LeftToRight");
        case RightToLeft: return QString("RightToLeft");
        default: return QString("Unknown: %1").arg(readingOrder);
    }
}

QString XFRecord::borderStyleToString(BorderStyle BorderStyle)
{
    switch (BorderStyle) {
        case NoLine: return QString("NoLine");
        case Thin: return QString("Thin");
        case Medium: return QString("Medium");
        case Dashed: return QString("Dashed");
        case Dotted: return QString("Dotted");
        case Thick: return QString("Thick");
        case Double: return QString("Double");
        case Hair: return QString("Hair");
        case MediumDashed: return QString("MediumDashed");
        case ThinDashDotted: return QString("ThinDashDotted");
        case MediumDashDotted: return QString("MediumDashDotted");
        case ThinDashDotDotted: return QString("ThinDashDotDotted");
        case MediumDashDotDotted: return QString("MediumDashDotDotted");
        case SlantedMediumDashDotted: return QString("SlantedMediumDashDotted");
        default: return QString("Unknown: %1").arg(BorderStyle);
    }
}

QString XFRecord::fillPatternToString(FillPattern FillPattern)
{
    switch (FillPattern) {
        case Null: return QString("Null");
        case Solid: return QString("Solid");
        case MediumGray: return QString("MediumGray");
        case DarkGray: return QString("DarkGray");
        case LightGray: return QString("LightGray");
        case Horizontal: return QString("Horizontal");
        case Vertical: return QString("Vertical");
        case DiagonalDown: return QString("DiagonalDown");
        case DiagonalUp: return QString("DiagonalUp");
        case DiagonalGrid: return QString("DiagonalGrid");
        case ThickDiagonalGrid: return QString("ThickDiagonalGrid");
        case ThinHorizontal: return QString("ThinHorizontal");
        case ThinVertical: return QString("ThinVertical");
        case ThinDiagonalDown: return QString("ThinDiagonalDown");
        case ThinDiagonalUp: return QString("ThinDiagonalUp");
        case ThinGrid: return QString("ThinGrid");
        case ThinDiagonalGrid: return QString("ThinDiagonalGrid");
        case Gray1250: return QString("Gray1250");
        case Gray0625: return QString("Gray0625");
        default: return QString("Unknown: %1").arg(FillPattern);
    }
}

unsigned XFRecord::bottomBorderColor() const
{
    return d->bottomBorderColor;
}

void XFRecord::setBottomBorderColor(unsigned bottomBorderColor )
{
    d->bottomBorderColor = bottomBorderColor;
}

XFRecord::BorderStyle XFRecord::bottomBorderStyle() const
{
    return d->bottomBorderStyle;
}

void XFRecord::setBottomBorderStyle(BorderStyle bottomBorderStyle )
{
    d->bottomBorderStyle = bottomBorderStyle;
}

unsigned XFRecord::diagonalBorderColor() const
{
    return d->diagonalBorderColor;
}

void XFRecord::setDiagonalBorderColor(unsigned diagonalBorderColor )
{
    d->diagonalBorderColor = diagonalBorderColor;
}

XFRecord::BorderStyle XFRecord::diagonalBorderStyle() const
{
    return d->diagonalBorderStyle;
}

void XFRecord::setDiagonalBorderStyle(BorderStyle diagonalBorderStyle )
{
    d->diagonalBorderStyle = diagonalBorderStyle;
}

bool XFRecord::isDiagonalBottomLeftBorder() const
{
    return d->diagonalBottomLeftBorder;
}

void XFRecord::setDiagonalBottomLeftBorder(bool diagonalBottomLeftBorder )
{
    d->diagonalBottomLeftBorder = diagonalBottomLeftBorder;
}

bool XFRecord::isDiagonalTopLeftBorder() const
{
    return d->diagonalTopLeftBorder;
}

void XFRecord::setDiagonalTopLeftBorder(bool diagonalTopLeftBorder )
{
    d->diagonalTopLeftBorder = diagonalTopLeftBorder;
}

bool XFRecord::isDontUpdateAlcFromParent() const
{
    return d->dontUpdateAlcFromParent;
}

void XFRecord::setDontUpdateAlcFromParent(bool dontUpdateAlcFromParent )
{
    d->dontUpdateAlcFromParent = dontUpdateAlcFromParent;
}

bool XFRecord::isDontUpdateBackgroundFromParent() const
{
    return d->dontUpdateBackgroundFromParent;
}

void XFRecord::setDontUpdateBackgroundFromParent(bool dontUpdateBackgroundFromParent )
{
    d->dontUpdateBackgroundFromParent = dontUpdateBackgroundFromParent;
}

bool XFRecord::isDontUpdateBorderFromParent() const
{
    return d->dontUpdateBorderFromParent;
}

void XFRecord::setDontUpdateBorderFromParent(bool dontUpdateBorderFromParent )
{
    d->dontUpdateBorderFromParent = dontUpdateBorderFromParent;
}

bool XFRecord::isDontUpdateFontFromParent() const
{
    return d->dontUpdateFontFromParent;
}

void XFRecord::setDontUpdateFontFromParent(bool dontUpdateFontFromParent )
{
    d->dontUpdateFontFromParent = dontUpdateFontFromParent;
}

bool XFRecord::isDontUpdateNumberFormatFromParent() const
{
    return d->dontUpdateNumberFormatFromParent;
}

void XFRecord::setDontUpdateNumberFormatFromParent(bool dontUpdateNumberFormatFromParent )
{
    d->dontUpdateNumberFormatFromParent = dontUpdateNumberFormatFromParent;
}

bool XFRecord::isDontUpdateProtectionFromParent() const
{
    return d->dontUpdateProtectionFromParent;
}

void XFRecord::setDontUpdateProtectionFromParent(bool dontUpdateProtectionFromParent )
{
    d->dontUpdateProtectionFromParent = dontUpdateProtectionFromParent;
}

XFRecord::FillPattern XFRecord::fillPattern() const
{
    return d->fillPattern;
}

void XFRecord::setFillPattern(FillPattern fillPattern )
{
    d->fillPattern = fillPattern;
}

unsigned XFRecord::fontIndex() const
{
    return d->fontIndex;
}

void XFRecord::setFontIndex(unsigned fontIndex )
{
    d->fontIndex = fontIndex;
}

unsigned XFRecord::formatIndex() const
{
    return d->formatIndex;
}

void XFRecord::setFormatIndex(unsigned formatIndex )
{
    d->formatIndex = formatIndex;
}

bool XFRecord::isFormulaHidden() const
{
    return d->formulaHidden;
}

void XFRecord::setFormulaHidden(bool formulaHidden )
{
    d->formulaHidden = formulaHidden;
}

bool XFRecord::hasPrefixChars() const
{
    return d->hasPrefixChars;
}

void XFRecord::setHasPrefixChars(bool hasPrefixChars )
{
    d->hasPrefixChars = hasPrefixChars;
}

bool XFRecord::hasXFExt() const
{
    return d->hasXFExt;
}

void XFRecord::setHasXFExt(bool hasXFExt )
{
    d->hasXFExt = hasXFExt;
}

XFRecord::HorizontalAlignment XFRecord::horizontalAlignment() const
{
    return d->horizontalAlignment;
}

void XFRecord::setHorizontalAlignment(HorizontalAlignment horizontalAlignment )
{
    d->horizontalAlignment = horizontalAlignment;
}

unsigned XFRecord::indentationLevel() const
{
    return d->indentationLevel;
}

void XFRecord::setIndentationLevel(unsigned indentationLevel )
{
    d->indentationLevel = indentationLevel;
}

bool XFRecord::isButton() const
{
    return d->isButton;
}

void XFRecord::setIsButton(bool isButton )
{
    d->isButton = isButton;
}

bool XFRecord::isStyleXF() const
{
    return d->isStyleXF;
}

void XFRecord::setIsStyleXF(bool isStyleXF )
{
    d->isStyleXF = isStyleXF;
}

bool XFRecord::isLastLineJustified() const
{
    return d->lastLineJustified;
}

void XFRecord::setLastLineJustified(bool lastLineJustified )
{
    d->lastLineJustified = lastLineJustified;
}

unsigned XFRecord::leftBorderColor() const
{
    return d->leftBorderColor;
}

void XFRecord::setLeftBorderColor(unsigned leftBorderColor )
{
    d->leftBorderColor = leftBorderColor;
}

XFRecord::BorderStyle XFRecord::leftBorderStyle() const
{
    return d->leftBorderStyle;
}

void XFRecord::setLeftBorderStyle(BorderStyle leftBorderStyle )
{
    d->leftBorderStyle = leftBorderStyle;
}

bool XFRecord::isLocked() const
{
    return d->locked;
}

void XFRecord::setLocked(bool locked )
{
    d->locked = locked;
}

unsigned XFRecord::parentStyle() const
{
    return d->parentStyle;
}

void XFRecord::setParentStyle(unsigned parentStyle )
{
    d->parentStyle = parentStyle;
}

unsigned XFRecord::patternBackColor() const
{
    return d->patternBackColor;
}

void XFRecord::setPatternBackColor(unsigned patternBackColor )
{
    d->patternBackColor = patternBackColor;
}

unsigned XFRecord::patternForeColor() const
{
    return d->patternForeColor;
}

void XFRecord::setPatternForeColor(unsigned patternForeColor )
{
    d->patternForeColor = patternForeColor;
}

unsigned XFRecord::rawTextRotation1() const
{
    return d->rawTextRotation1;
}

void XFRecord::setRawTextRotation1(unsigned rawTextRotation1 )
{
    d->rawTextRotation1 = rawTextRotation1;
}

unsigned XFRecord::rawTextRotation97() const
{
    return d->rawTextRotation97;
}

void XFRecord::setRawTextRotation97(unsigned rawTextRotation97 )
{
    d->rawTextRotation97 = rawTextRotation97;
}

XFRecord::ReadingOrder XFRecord::readingOrder() const
{
    return d->readingOrder;
}

void XFRecord::setReadingOrder(ReadingOrder readingOrder )
{
    d->readingOrder = readingOrder;
}

unsigned XFRecord::rightBorderColor() const
{
    return d->rightBorderColor;
}

void XFRecord::setRightBorderColor(unsigned rightBorderColor )
{
    d->rightBorderColor = rightBorderColor;
}

XFRecord::BorderStyle XFRecord::rightBorderStyle() const
{
    return d->rightBorderStyle;
}

void XFRecord::setRightBorderStyle(BorderStyle rightBorderStyle )
{
    d->rightBorderStyle = rightBorderStyle;
}

bool XFRecord::isShrinkToFit() const
{
    return d->shrinkToFit;
}

void XFRecord::setShrinkToFit(bool shrinkToFit )
{
    d->shrinkToFit = shrinkToFit;
}

bool XFRecord::isTextWrap() const
{
    return d->textWrap;
}

void XFRecord::setTextWrap(bool textWrap )
{
    d->textWrap = textWrap;
}

unsigned XFRecord::topBorderColor() const
{
    return d->topBorderColor;
}

void XFRecord::setTopBorderColor(unsigned topBorderColor )
{
    d->topBorderColor = topBorderColor;
}

XFRecord::BorderStyle XFRecord::topBorderStyle() const
{
    return d->topBorderStyle;
}

void XFRecord::setTopBorderStyle(BorderStyle topBorderStyle )
{
    d->topBorderStyle = topBorderStyle;
}

XFRecord::VerticalAlignment XFRecord::verticalAlignment() const
{
    return d->verticalAlignment;
}

void XFRecord::setVerticalAlignment(VerticalAlignment verticalAlignment )
{
    d->verticalAlignment = verticalAlignment;
}

int XFRecord::rotationAngle() const
{
    return version() < Excel97
        ? (rawTextRotation1() == 2 ? 90 : rawTextRotation1() == 3 ? 180 : 0)
        : (rawTextRotation97() == 255 ? 0 : rawTextRotation97());
}

bool XFRecord::stackedLetters() const
{
    return version() < Excel97
        ? rawTextRotation1() == 1 : rawTextRotation97() == 255;
}

void XFRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    setFontIndex(readU16(data));
    setFormatIndex(readU16(data + 2));
    setLocked(((readU8(data + 4)) & 0x1) != 0);
    setFormulaHidden(((readU8(data + 4) >> 1) & 0x1) != 0);
    setIsStyleXF(((readU8(data + 4) >> 2) & 0x1) != 0);
    setHasPrefixChars(((readU8(data + 4) >> 3) & 0x1) != 0);
    setParentStyle(((readU16(data + 4) >> 4) & 0xfff));
    setHorizontalAlignment(static_cast<HorizontalAlignment>(((readU8(data + 6)) & 0x7)));
    setTextWrap(((readU8(data + 6) >> 3) & 0x1) != 0);
    setVerticalAlignment(static_cast<VerticalAlignment>(((readU8(data + 6) >> 4) & 0x7)));
    setLastLineJustified(((readU8(data + 6) >> 7) & 0x1) != 0);
    curOffset = 7;
    if (version() < Excel97) {
        if (size < curOffset + 9) {
            setIsValid(false);
            return;
        }
        setRawTextRotation1(((readU8(data + curOffset)) & 0x3));
        setDontUpdateNumberFormatFromParent(((readU8(data + curOffset) >> 2) & 0x1) != 0);
        setDontUpdateFontFromParent(((readU8(data + curOffset) >> 3) & 0x1) != 0);
        setDontUpdateAlcFromParent(((readU8(data + curOffset) >> 4) & 0x1) != 0);
        setDontUpdateBorderFromParent(((readU8(data + curOffset) >> 5) & 0x1) != 0);
        setDontUpdateBackgroundFromParent(((readU8(data + curOffset) >> 6) & 0x1) != 0);
        setDontUpdateProtectionFromParent(((readU8(data + curOffset) >> 7) & 0x1) != 0);
        setPatternForeColor(((readU8(data + curOffset + 1)) & 0x7f));
        setPatternBackColor(((readU16(data + curOffset + 1) >> 7) & 0x7f));
        setFillPattern(static_cast<FillPattern>(((readU8(data + curOffset + 3)) & 0x3f)));
        setBottomBorderStyle(static_cast<BorderStyle>(((readU16(data + curOffset + 3) >> 6) & 0x7)));
        setBottomBorderColor(((readU8(data + curOffset + 4) >> 1) & 0x7f));
        setTopBorderStyle(static_cast<BorderStyle>(((readU8(data + curOffset + 5)) & 0x7)));
        setLeftBorderStyle(static_cast<BorderStyle>(((readU8(data + curOffset + 5) >> 3) & 0x7)));
        setRightBorderStyle(static_cast<BorderStyle>(((readU16(data + curOffset + 5) >> 6) & 0x7)));
        setTopBorderColor(((readU8(data + curOffset + 6) >> 1) & 0x7f));
        setLeftBorderColor(((readU8(data + curOffset + 7)) & 0x7f));
        setRightBorderColor(((readU16(data + curOffset + 7) >> 7) & 0x7f));
        curOffset += 9;
    }
    if (version() >= Excel97) {
        if (size < curOffset + 13) {
            setIsValid(false);
            return;
        }
        setRawTextRotation97(readU8(data + curOffset));
        setIndentationLevel(((readU8(data + curOffset + 1)) & 0xf));
        setShrinkToFit(((readU8(data + curOffset + 1) >> 4) & 0x1) != 0);
        setReadingOrder(static_cast<ReadingOrder>(((readU8(data + curOffset + 1) >> 6) & 0x3)));
        setDontUpdateNumberFormatFromParent(((readU8(data + curOffset + 2) >> 2) & 0x1) != 0);
        setDontUpdateFontFromParent(((readU8(data + curOffset + 2) >> 3) & 0x1) != 0);
        setDontUpdateAlcFromParent(((readU8(data + curOffset + 2) >> 4) & 0x1) != 0);
        setDontUpdateBorderFromParent(((readU8(data + curOffset + 2) >> 5) & 0x1) != 0);
        setDontUpdateBackgroundFromParent(((readU8(data + curOffset + 2) >> 6) & 0x1) != 0);
        setDontUpdateProtectionFromParent(((readU8(data + curOffset + 2) >> 7) & 0x1) != 0);
        setLeftBorderStyle(static_cast<BorderStyle>(((readU8(data + curOffset + 3)) & 0xf)));
        setRightBorderStyle(static_cast<BorderStyle>(((readU8(data + curOffset + 3) >> 4) & 0xf)));
        setTopBorderStyle(static_cast<BorderStyle>(((readU8(data + curOffset + 4)) & 0xf)));
        setBottomBorderStyle(static_cast<BorderStyle>(((readU8(data + curOffset + 4) >> 4) & 0xf)));
        setLeftBorderColor(((readU8(data + curOffset + 5)) & 0x7f));
        setRightBorderColor(((readU16(data + curOffset + 5) >> 7) & 0x7f));
        setDiagonalTopLeftBorder(((readU8(data + curOffset + 6) >> 6) & 0x1) != 0);
        setDiagonalBottomLeftBorder(((readU8(data + curOffset + 6) >> 7) & 0x1) != 0);
        setTopBorderColor(((readU8(data + curOffset + 7)) & 0x7f));
        setBottomBorderColor(((readU16(data + curOffset + 7) >> 7) & 0x7f));
        setDiagonalBorderColor(((readU16(data + curOffset + 8) >> 6) & 0x7f));
        setDiagonalBorderStyle(static_cast<BorderStyle>(((readU16(data + curOffset + 9) >> 5) & 0xf)));
        setHasXFExt(((readU8(data + curOffset + 10) >> 1) & 0x1) != 0);
        setFillPattern(static_cast<FillPattern>(((readU8(data + curOffset + 10) >> 2) & 0x3f)));
        setPatternForeColor(((readU8(data + curOffset + 11)) & 0x7f));
        setPatternBackColor(((readU16(data + curOffset + 11) >> 7) & 0x7f));
        setIsButton(((readU8(data + curOffset + 12) >> 6) & 0x1) != 0);
        curOffset += 13;
    }
}

void XFRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, fontIndex());
    out.writeUnsigned(16, formatIndex());
    out.writeUnsigned(1, isLocked());
    out.writeUnsigned(1, isFormulaHidden());
    out.writeUnsigned(1, isStyleXF());
    out.writeUnsigned(1, hasPrefixChars());
    out.writeUnsigned(12, parentStyle());
    out.writeUnsigned(3, horizontalAlignment());
    out.writeUnsigned(1, isTextWrap());
    out.writeUnsigned(3, verticalAlignment());
    out.writeUnsigned(1, isLastLineJustified());
    if (version() < Excel97) {
        out.writeUnsigned(2, rawTextRotation1());
        out.writeUnsigned(1, isDontUpdateNumberFormatFromParent());
        out.writeUnsigned(1, isDontUpdateFontFromParent());
        out.writeUnsigned(1, isDontUpdateAlcFromParent());
        out.writeUnsigned(1, isDontUpdateBorderFromParent());
        out.writeUnsigned(1, isDontUpdateBackgroundFromParent());
        out.writeUnsigned(1, isDontUpdateProtectionFromParent());
        out.writeUnsigned(7, patternForeColor());
        out.writeUnsigned(7, patternBackColor());
        out.writeUnsigned(2, 0);
        out.writeUnsigned(6, fillPattern());
        out.writeUnsigned(3, bottomBorderStyle());
        out.writeUnsigned(7, bottomBorderColor());
        out.writeUnsigned(3, topBorderStyle());
        out.writeUnsigned(3, leftBorderStyle());
        out.writeUnsigned(3, rightBorderStyle());
        out.writeUnsigned(7, topBorderColor());
        out.writeUnsigned(7, leftBorderColor());
        out.writeUnsigned(7, rightBorderColor());
        out.writeUnsigned(2, 0);
    }
    if (version() >= Excel97) {
        out.writeUnsigned(8, rawTextRotation97());
        out.writeUnsigned(4, indentationLevel());
        out.writeUnsigned(1, isShrinkToFit());
        out.writeUnsigned(1, 0);
        out.writeUnsigned(2, readingOrder());
        out.writeUnsigned(2, 0);
        out.writeUnsigned(1, isDontUpdateNumberFormatFromParent());
        out.writeUnsigned(1, isDontUpdateFontFromParent());
        out.writeUnsigned(1, isDontUpdateAlcFromParent());
        out.writeUnsigned(1, isDontUpdateBorderFromParent());
        out.writeUnsigned(1, isDontUpdateBackgroundFromParent());
        out.writeUnsigned(1, isDontUpdateProtectionFromParent());
        out.writeUnsigned(4, leftBorderStyle());
        out.writeUnsigned(4, rightBorderStyle());
        out.writeUnsigned(4, topBorderStyle());
        out.writeUnsigned(4, bottomBorderStyle());
        out.writeUnsigned(7, leftBorderColor());
        out.writeUnsigned(7, rightBorderColor());
        out.writeUnsigned(1, isDiagonalTopLeftBorder());
        out.writeUnsigned(1, isDiagonalBottomLeftBorder());
        out.writeUnsigned(7, topBorderColor());
        out.writeUnsigned(7, bottomBorderColor());
        out.writeUnsigned(7, diagonalBorderColor());
        out.writeUnsigned(4, diagonalBorderStyle());
        out.writeUnsigned(1, hasXFExt());
        out.writeUnsigned(6, fillPattern());
        out.writeUnsigned(7, patternForeColor());
        out.writeUnsigned(7, patternBackColor());
        out.writeUnsigned(1, isButton());
        out.writeUnsigned(1, 0);
    }
}

void XFRecord::dump( std::ostream& out ) const
{
    out << "XF" << std::endl;
    out << "          FontIndex : " << fontIndex() << std::endl;
    out << "        FormatIndex : " << formatIndex() << std::endl;
    out << "             Locked : " << isLocked() << std::endl;
    out << "      FormulaHidden : " << isFormulaHidden() << std::endl;
    out << "          IsStyleXF : " << isStyleXF() << std::endl;
    out << "     HasPrefixChars : " << hasPrefixChars() << std::endl;
    out << "        ParentStyle : " << parentStyle() << std::endl;
    out << "HorizontalAlignment : " << horizontalAlignmentToString(horizontalAlignment()) << std::endl;
    out << "           TextWrap : " << isTextWrap() << std::endl;
    out << "  VerticalAlignment : " << verticalAlignmentToString(verticalAlignment()) << std::endl;
    out << "  LastLineJustified : " << isLastLineJustified() << std::endl;
    if (version() < Excel97) {
        out << "   RawTextRotation1 : " << rawTextRotation1() << std::endl;
        out << "DontUpdateNumberFormatFromParent : " << isDontUpdateNumberFormatFromParent() << std::endl;
        out << "DontUpdateFontFromParent : " << isDontUpdateFontFromParent() << std::endl;
        out << "DontUpdateAlcFromParent : " << isDontUpdateAlcFromParent() << std::endl;
        out << "DontUpdateBorderFromParent : " << isDontUpdateBorderFromParent() << std::endl;
        out << "DontUpdateBackgroundFromParent : " << isDontUpdateBackgroundFromParent() << std::endl;
        out << "DontUpdateProtectionFromParent : " << isDontUpdateProtectionFromParent() << std::endl;
        out << "   PatternForeColor : " << patternForeColor() << std::endl;
        out << "   PatternBackColor : " << patternBackColor() << std::endl;
        out << "        FillPattern : " << fillPatternToString(fillPattern()) << std::endl;
        out << "  BottomBorderStyle : " << borderStyleToString(bottomBorderStyle()) << std::endl;
        out << "  BottomBorderColor : " << bottomBorderColor() << std::endl;
        out << "     TopBorderStyle : " << borderStyleToString(topBorderStyle()) << std::endl;
        out << "    LeftBorderStyle : " << borderStyleToString(leftBorderStyle()) << std::endl;
        out << "   RightBorderStyle : " << borderStyleToString(rightBorderStyle()) << std::endl;
        out << "     TopBorderColor : " << topBorderColor() << std::endl;
        out << "    LeftBorderColor : " << leftBorderColor() << std::endl;
        out << "   RightBorderColor : " << rightBorderColor() << std::endl;
    }
    if (version() >= Excel97) {
        out << "  RawTextRotation97 : " << rawTextRotation97() << std::endl;
        out << "   IndentationLevel : " << indentationLevel() << std::endl;
        out << "        ShrinkToFit : " << isShrinkToFit() << std::endl;
        out << "       ReadingOrder : " << readingOrderToString(readingOrder()) << std::endl;
        out << "DontUpdateNumberFormatFromParent : " << isDontUpdateNumberFormatFromParent() << std::endl;
        out << "DontUpdateFontFromParent : " << isDontUpdateFontFromParent() << std::endl;
        out << "DontUpdateAlcFromParent : " << isDontUpdateAlcFromParent() << std::endl;
        out << "DontUpdateBorderFromParent : " << isDontUpdateBorderFromParent() << std::endl;
        out << "DontUpdateBackgroundFromParent : " << isDontUpdateBackgroundFromParent() << std::endl;
        out << "DontUpdateProtectionFromParent : " << isDontUpdateProtectionFromParent() << std::endl;
        out << "    LeftBorderStyle : " << borderStyleToString(leftBorderStyle()) << std::endl;
        out << "   RightBorderStyle : " << borderStyleToString(rightBorderStyle()) << std::endl;
        out << "     TopBorderStyle : " << borderStyleToString(topBorderStyle()) << std::endl;
        out << "  BottomBorderStyle : " << borderStyleToString(bottomBorderStyle()) << std::endl;
        out << "    LeftBorderColor : " << leftBorderColor() << std::endl;
        out << "   RightBorderColor : " << rightBorderColor() << std::endl;
        out << "DiagonalTopLeftBorder : " << isDiagonalTopLeftBorder() << std::endl;
        out << "DiagonalBottomLeftBorder : " << isDiagonalBottomLeftBorder() << std::endl;
        out << "     TopBorderColor : " << topBorderColor() << std::endl;
        out << "  BottomBorderColor : " << bottomBorderColor() << std::endl;
        out << "DiagonalBorderColor : " << diagonalBorderColor() << std::endl;
        out << "DiagonalBorderStyle : " << borderStyleToString(diagonalBorderStyle()) << std::endl;
        out << "           HasXFExt : " << hasXFExt() << std::endl;
        out << "        FillPattern : " << fillPatternToString(fillPattern()) << std::endl;
        out << "   PatternForeColor : " << patternForeColor() << std::endl;
        out << "   PatternBackColor : " << patternBackColor() << std::endl;
        out << "           IsButton : " << isButton() << std::endl;
    }
}

static Record* createXFRecord(Swinder::Workbook *book)
{
    return new XFRecord(book);
}

// ========== LabelRecord ==========

const unsigned LabelRecord::id = 0x0204;

class LabelRecord::Private
{
public:
    unsigned column;
    QString label;
    unsigned row;
    unsigned xfIndex;
};

LabelRecord::LabelRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setColumn(0);
    setRow(0);
    setXfIndex(0);
}

LabelRecord::~LabelRecord()
{
    delete d;
}

LabelRecord::LabelRecord( const LabelRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

LabelRecord& LabelRecord::operator=( const LabelRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned LabelRecord::column() const
{
    return d->column;
}

void LabelRecord::setColumn(unsigned column )
{
    d->column = column;
}

QString LabelRecord::label() const
{
    return d->label;
}

void LabelRecord::setLabel(QString label )
{
    d->label = label;
}

unsigned LabelRecord::row() const
{
    return d->row;
}

void LabelRecord::setRow(unsigned row )
{
    d->row = row;
}

unsigned LabelRecord::xfIndex() const
{
    return d->xfIndex;
}

void LabelRecord::setXfIndex(unsigned xfIndex )
{
    d->xfIndex = xfIndex;
}

void LabelRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    bool stringLengthError = false;
    unsigned stringSize;
    if (size < 8) {
        setIsValid(false);
        return;
    }
    setRow(readU16(data));
    setColumn(readU16(data + 2));
    setXfIndex(readU16(data + 4));
    unsigned labelLength = readU16(data + 6);
    curOffset = 8;
    if (version() < Excel97) {
        setLabel(readByteString(data + curOffset, labelLength, size - curOffset, &stringLengthError, &stringSize));
        if (stringLengthError) {
            setIsValid(false);
            return;
        }
        curOffset += stringSize;
    }
    if (version() >= Excel97) {
        setLabel(readUnicodeString(data + curOffset, labelLength, size - curOffset, &stringLengthError, &stringSize));
        if (stringLengthError) {
            setIsValid(false);
            return;
        }
        curOffset += stringSize;
    }
}

void LabelRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, row());
    out.writeUnsigned(16, column());
    out.writeUnsigned(16, xfIndex());
    out.writeUnsigned(16, label().length());
    if (version() < Excel97) {
        out.writeByteString(label());
    }
    if (version() >= Excel97) {
        out.writeUnicodeStringWithFlags(label());
    }
}

void LabelRecord::dump( std::ostream& out ) const
{
    out << "Label" << std::endl;
    out << "                Row : " << row() << std::endl;
    out << "             Column : " << column() << std::endl;
    out << "            XfIndex : " << xfIndex() << std::endl;
    if (version() < Excel97) {
        out << "              Label : " << label() << std::endl;
    }
    if (version() >= Excel97) {
        out << "              Label : " << label() << std::endl;
    }
}

static Record* createLabelRecord(Swinder::Workbook *book)
{
    return new LabelRecord(book);
}

// ========== LabelSSTRecord ==========

const unsigned LabelSSTRecord::id = 0x00FD;

class LabelSSTRecord::Private
{
public:
    unsigned column;
    unsigned row;
    unsigned sstIndex;
    unsigned xfIndex;
};

LabelSSTRecord::LabelSSTRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setColumn(0);
    setRow(0);
    setSstIndex(0);
    setXfIndex(0);
}

LabelSSTRecord::~LabelSSTRecord()
{
    delete d;
}

LabelSSTRecord::LabelSSTRecord( const LabelSSTRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

LabelSSTRecord& LabelSSTRecord::operator=( const LabelSSTRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned LabelSSTRecord::column() const
{
    return d->column;
}

void LabelSSTRecord::setColumn(unsigned column )
{
    d->column = column;
}

unsigned LabelSSTRecord::row() const
{
    return d->row;
}

void LabelSSTRecord::setRow(unsigned row )
{
    d->row = row;
}

unsigned LabelSSTRecord::sstIndex() const
{
    return d->sstIndex;
}

void LabelSSTRecord::setSstIndex(unsigned sstIndex )
{
    d->sstIndex = sstIndex;
}

unsigned LabelSSTRecord::xfIndex() const
{
    return d->xfIndex;
}

void LabelSSTRecord::setXfIndex(unsigned xfIndex )
{
    d->xfIndex = xfIndex;
}

void LabelSSTRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 10) {
        setIsValid(false);
        return;
    }
    setRow(readU16(data));
    setColumn(readU16(data + 2));
    setXfIndex(readU16(data + 4));
    setSstIndex(readU32(data + 6));
}

void LabelSSTRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, row());
    out.writeUnsigned(16, column());
    out.writeUnsigned(16, xfIndex());
    out.writeUnsigned(32, sstIndex());
}

void LabelSSTRecord::dump( std::ostream& out ) const
{
    out << "LabelSST" << std::endl;
    out << "                Row : " << row() << std::endl;
    out << "             Column : " << column() << std::endl;
    out << "            XfIndex : " << xfIndex() << std::endl;
    out << "           SstIndex : " << sstIndex() << std::endl;
}

static Record* createLabelSSTRecord(Swinder::Workbook *book)
{
    return new LabelSSTRecord(book);
}

// ========== MergedCellsRecord ==========

const unsigned MergedCellsRecord::id = 0x00E5;

class MergedCellsRecord::Private
{
public:
    unsigned count;
    std::vector<unsigned> firstColumn;
    std::vector<unsigned> firstRow;
    std::vector<unsigned> lastColumn;
    std::vector<unsigned> lastRow;
};

MergedCellsRecord::MergedCellsRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCount(0);
}

MergedCellsRecord::~MergedCellsRecord()
{
    delete d;
}

MergedCellsRecord::MergedCellsRecord( const MergedCellsRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

MergedCellsRecord& MergedCellsRecord::operator=( const MergedCellsRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned MergedCellsRecord::count() const
{
    return d->count;
}

void MergedCellsRecord::setCount(unsigned count )
{
    d->count = count;
    d->firstRow.resize(count);
    d->lastRow.resize(count);
    d->firstColumn.resize(count);
    d->lastColumn.resize(count);
}

unsigned MergedCellsRecord::firstColumn( unsigned index ) const
{
    return d->firstColumn[index];
}

void MergedCellsRecord::setFirstColumn( unsigned index, unsigned firstColumn )
{
    d->firstColumn[index] = firstColumn;
}

unsigned MergedCellsRecord::firstRow( unsigned index ) const
{
    return d->firstRow[index];
}

void MergedCellsRecord::setFirstRow( unsigned index, unsigned firstRow )
{
    d->firstRow[index] = firstRow;
}

unsigned MergedCellsRecord::lastColumn( unsigned index ) const
{
    return d->lastColumn[index];
}

void MergedCellsRecord::setLastColumn( unsigned index, unsigned lastColumn )
{
    d->lastColumn[index] = lastColumn;
}

unsigned MergedCellsRecord::lastRow( unsigned index ) const
{
    return d->lastRow[index];
}

void MergedCellsRecord::setLastRow( unsigned index, unsigned lastRow )
{
    d->lastRow[index] = lastRow;
}

void MergedCellsRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    if (size < 2) {
        setIsValid(false);
        return;
    }
    setCount(readU16(data));
    curOffset = 2;
    for (unsigned i = 0, endi = count(); i < endi; ++i) {
        if (size < curOffset + 8) {
            setIsValid(false);
            return;
        }
        setFirstRow(i, readU16(data + curOffset));
        setLastRow(i, readU16(data + curOffset + 2));
        setFirstColumn(i, readU16(data + curOffset + 4));
        setLastColumn(i, readU16(data + curOffset + 6));
        curOffset += 8;
    }
}

void MergedCellsRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, count());
    for (unsigned i = 0, endi = count(); i < endi; ++i) {
        out.writeUnsigned(16, firstRow(i));
        out.writeUnsigned(16, lastRow(i));
        out.writeUnsigned(16, firstColumn(i));
        out.writeUnsigned(16, lastColumn(i));
    }
}

void MergedCellsRecord::dump( std::ostream& out ) const
{
    out << "MergedCells" << std::endl;
    out << "              Count : " << count() << std::endl;
    for (unsigned i = 0, endi = count(); i < endi; ++i) {
        out << "       FirstRow " << std::setw(3) << i <<" : " << firstRow(i) << std::endl;
        out << "        LastRow " << std::setw(3) << i <<" : " << lastRow(i) << std::endl;
        out << "    FirstColumn " << std::setw(3) << i <<" : " << firstColumn(i) << std::endl;
        out << "     LastColumn " << std::setw(3) << i <<" : " << lastColumn(i) << std::endl;
    }
}

static Record* createMergedCellsRecord(Swinder::Workbook *book)
{
    return new MergedCellsRecord(book);
}

// ========== MulBlankRecord ==========

const unsigned MulBlankRecord::id = 0x00BE;

class MulBlankRecord::Private
{
public:
    unsigned firstColumn;
    unsigned lastColumn;
    unsigned row;
    std::vector<unsigned> xfIndex;
};

MulBlankRecord::MulBlankRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFirstColumn(0);
    setLastColumn(0);
    setRow(0);
}

MulBlankRecord::~MulBlankRecord()
{
    delete d;
}

MulBlankRecord::MulBlankRecord( const MulBlankRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

MulBlankRecord& MulBlankRecord::operator=( const MulBlankRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned MulBlankRecord::firstColumn() const
{
    return d->firstColumn;
}

void MulBlankRecord::setFirstColumn(unsigned firstColumn )
{
    d->firstColumn = firstColumn;
}

unsigned MulBlankRecord::lastColumn() const
{
    return d->lastColumn;
}

void MulBlankRecord::setLastColumn(unsigned lastColumn )
{
    d->lastColumn = lastColumn;
}

unsigned MulBlankRecord::row() const
{
    return d->row;
}

void MulBlankRecord::setRow(unsigned row )
{
    d->row = row;
}

unsigned MulBlankRecord::xfIndex( unsigned index ) const
{
    return d->xfIndex[index];
}

void MulBlankRecord::setXfIndex( unsigned index, unsigned xfIndex )
{
    d->xfIndex[index] = xfIndex;
}

void MulBlankRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    if (size < 4) {
        setIsValid(false);
        return;
    }
    setRow(readU16(data));
    setFirstColumn(readU16(data + 2));
    curOffset = 4;
    d->xfIndex.resize((size-6)/2);
    for (unsigned i = 0, endi = (size-6)/2; i < endi; ++i) {
        if (size < curOffset + 2) {
            setIsValid(false);
            return;
        }
        setXfIndex(i, readU16(data + curOffset));
        curOffset += 2;
    }
    if (size < curOffset + 2) {
        setIsValid(false);
        return;
    }
    setLastColumn(readU16(data + curOffset));
}

void MulBlankRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, row());
    out.writeUnsigned(16, firstColumn());
    for (unsigned i = 0, endi = d->xfIndex.size(); i < endi; ++i) {
        out.writeUnsigned(16, xfIndex(i));
    }
    out.writeUnsigned(16, lastColumn());
}

void MulBlankRecord::dump( std::ostream& out ) const
{
    out << "MulBlank" << std::endl;
    out << "                Row : " << row() << std::endl;
    out << "        FirstColumn : " << firstColumn() << std::endl;
    for (unsigned i = 0, endi = d->xfIndex.size(); i < endi; ++i) {
        out << "        XfIndex " << std::setw(3) << i <<" : " << xfIndex(i) << std::endl;
    }
    out << "         LastColumn : " << lastColumn() << std::endl;
}

static Record* createMulBlankRecord(Swinder::Workbook *book)
{
    return new MulBlankRecord(book);
}

// ========== NumberRecord ==========

const unsigned NumberRecord::id = 0x0203;

class NumberRecord::Private
{
public:
    unsigned column;
    double number;
    unsigned row;
    unsigned xfIndex;
};

NumberRecord::NumberRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setColumn(0);
    setRow(0);
    setXfIndex(0);
}

NumberRecord::~NumberRecord()
{
    delete d;
}

NumberRecord::NumberRecord( const NumberRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

NumberRecord& NumberRecord::operator=( const NumberRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned NumberRecord::column() const
{
    return d->column;
}

void NumberRecord::setColumn(unsigned column )
{
    d->column = column;
}

double NumberRecord::number() const
{
    return d->number;
}

void NumberRecord::setNumber(double number )
{
    d->number = number;
}

unsigned NumberRecord::row() const
{
    return d->row;
}

void NumberRecord::setRow(unsigned row )
{
    d->row = row;
}

unsigned NumberRecord::xfIndex() const
{
    return d->xfIndex;
}

void NumberRecord::setXfIndex(unsigned xfIndex )
{
    d->xfIndex = xfIndex;
}

void NumberRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 14) {
        setIsValid(false);
        return;
    }
    setRow(readU16(data));
    setColumn(readU16(data + 2));
    setXfIndex(readU16(data + 4));
    setNumber(readFloat64(data + 6));
}

void NumberRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, row());
    out.writeUnsigned(16, column());
    out.writeUnsigned(16, xfIndex());
    out.writeFloat(64, number());
}

void NumberRecord::dump( std::ostream& out ) const
{
    out << "Number" << std::endl;
    out << "                Row : " << row() << std::endl;
    out << "             Column : " << column() << std::endl;
    out << "            XfIndex : " << xfIndex() << std::endl;
    out << "             Number : " << number() << std::endl;
}

static Record* createNumberRecord(Swinder::Workbook *book)
{
    return new NumberRecord(book);
}

// ========== PaletteRecord ==========

const unsigned PaletteRecord::id = 0x0092;

class PaletteRecord::Private
{
public:
    std::vector<unsigned> blue;
    unsigned count;
    std::vector<unsigned> green;
    std::vector<unsigned> red;
};

PaletteRecord::PaletteRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCount(0);
}

PaletteRecord::~PaletteRecord()
{
    delete d;
}

PaletteRecord::PaletteRecord( const PaletteRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

PaletteRecord& PaletteRecord::operator=( const PaletteRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned PaletteRecord::blue( unsigned index ) const
{
    return d->blue[index];
}

void PaletteRecord::setBlue( unsigned index, unsigned blue )
{
    d->blue[index] = blue;
}

unsigned PaletteRecord::count() const
{
    return d->count;
}

void PaletteRecord::setCount(unsigned count )
{
    d->count = count;
    d->red.resize(count);
    d->green.resize(count);
    d->blue.resize(count);
}

unsigned PaletteRecord::green( unsigned index ) const
{
    return d->green[index];
}

void PaletteRecord::setGreen( unsigned index, unsigned green )
{
    d->green[index] = green;
}

unsigned PaletteRecord::red( unsigned index ) const
{
    return d->red[index];
}

void PaletteRecord::setRed( unsigned index, unsigned red )
{
    d->red[index] = red;
}

void PaletteRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    if (size < 2) {
        setIsValid(false);
        return;
    }
    setCount(readU16(data));
    curOffset = 2;
    for (unsigned i = 0, endi = count(); i < endi; ++i) {
        if (size < curOffset + 4) {
            setIsValid(false);
            return;
        }
        setRed(i, readU8(data + curOffset));
        setGreen(i, readU8(data + curOffset + 1));
        setBlue(i, readU8(data + curOffset + 2));
        curOffset += 4;
    }
}

void PaletteRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, count());
    for (unsigned i = 0, endi = count(); i < endi; ++i) {
        out.writeUnsigned(8, red(i));
        out.writeUnsigned(8, green(i));
        out.writeUnsigned(8, blue(i));
        out.writeUnsigned(8, 0);
    }
}

void PaletteRecord::dump( std::ostream& out ) const
{
    out << "Palette" << std::endl;
    out << "              Count : " << count() << std::endl;
    for (unsigned i = 0, endi = count(); i < endi; ++i) {
        out << "            Red " << std::setw(3) << i <<" : " << red(i) << std::endl;
        out << "          Green " << std::setw(3) << i <<" : " << green(i) << std::endl;
        out << "           Blue " << std::setw(3) << i <<" : " << blue(i) << std::endl;
    }
}

static Record* createPaletteRecord(Swinder::Workbook *book)
{
    return new PaletteRecord(book);
}

// ========== RowRecord ==========

const unsigned RowRecord::id = 0x0208;

class RowRecord::Private
{
public:
    unsigned firstColumn;
    unsigned height;
    bool hidden;
    unsigned lastColumnPlus1;
    bool notCollapsed;
    unsigned outlineLevel;
    unsigned row;
    unsigned xfIndex;
};

RowRecord::RowRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFirstColumn(0);
    setHeight(0);
    setHidden(false);
    setLastColumnPlus1(0);
    setNotCollapsed(false);
    setOutlineLevel(0);
    setRow(0);
    setXfIndex(0);
}

RowRecord::~RowRecord()
{
    delete d;
}

RowRecord::RowRecord( const RowRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

RowRecord& RowRecord::operator=( const RowRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned RowRecord::firstColumn() const
{
    return d->firstColumn;
}

void RowRecord::setFirstColumn(unsigned firstColumn )
{
    d->firstColumn = firstColumn;
}

unsigned RowRecord::height() const
{
    return d->height;
}

void RowRecord::setHeight(unsigned height )
{
    d->height = height;
}

bool RowRecord::isHidden() const
{
    return d->hidden;
}

void RowRecord::setHidden(bool hidden )
{
    d->hidden = hidden;
}

unsigned RowRecord::lastColumnPlus1() const
{
    return d->lastColumnPlus1;
}

void RowRecord::setLastColumnPlus1(unsigned lastColumnPlus1 )
{
    d->lastColumnPlus1 = lastColumnPlus1;
}

bool RowRecord::isNotCollapsed() const
{
    return d->notCollapsed;
}

void RowRecord::setNotCollapsed(bool notCollapsed )
{
    d->notCollapsed = notCollapsed;
}

unsigned RowRecord::outlineLevel() const
{
    return d->outlineLevel;
}

void RowRecord::setOutlineLevel(unsigned outlineLevel )
{
    d->outlineLevel = outlineLevel;
}

unsigned RowRecord::row() const
{
    return d->row;
}

void RowRecord::setRow(unsigned row )
{
    d->row = row;
}

unsigned RowRecord::xfIndex() const
{
    return d->xfIndex;
}

void RowRecord::setXfIndex(unsigned xfIndex )
{
    d->xfIndex = xfIndex;
}

bool RowRecord::isCollapsed() const
{
    return !isNotCollapsed();
}

void RowRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 16) {
        setIsValid(false);
        return;
    }
    setRow(readU16(data));
    setFirstColumn(readU16(data + 2));
    setLastColumnPlus1(readU16(data + 4));
    setHeight(readU16(data + 6));
    setOutlineLevel(((readU8(data + 12)) & 0x7));
    setNotCollapsed(((readU8(data + 12) >> 4) & 0x1) != 0);
    setHidden(((readU8(data + 12) >> 5) & 0x1) != 0);
    setXfIndex(((readU16(data + 14)) & 0xfff));
}

void RowRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, row());
    out.writeUnsigned(16, firstColumn());
    out.writeUnsigned(16, lastColumnPlus1());
    out.writeUnsigned(16, height());
    out.writeUnsigned(16, 0);
    out.writeUnsigned(16, 0);
    out.writeUnsigned(3, outlineLevel());
    out.writeUnsigned(1, 0);
    out.writeUnsigned(1, isNotCollapsed());
    out.writeUnsigned(1, isHidden());
    out.writeUnsigned(2, 0);
    out.writeUnsigned(8, 1);
    out.writeUnsigned(12, xfIndex());
    out.writeUnsigned(4, 0);
}

void RowRecord::dump( std::ostream& out ) const
{
    out << "Row" << std::endl;
    out << "                Row : " << row() << std::endl;
    out << "        FirstColumn : " << firstColumn() << std::endl;
    out << "    LastColumnPlus1 : " << lastColumnPlus1() << std::endl;
    out << "             Height : " << height() << std::endl;
    out << "       OutlineLevel : " << outlineLevel() << std::endl;
    out << "       NotCollapsed : " << isNotCollapsed() << std::endl;
    out << "             Hidden : " << isHidden() << std::endl;
    out << "            XfIndex : " << xfIndex() << std::endl;
}

static Record* createRowRecord(Swinder::Workbook *book)
{
    return new RowRecord(book);
}

// ========== StringRecord ==========

const unsigned StringRecord::id = 0x0207;

class StringRecord::Private
{
public:
    QString ustring;
};

StringRecord::StringRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

StringRecord::~StringRecord()
{
    delete d;
}

StringRecord::StringRecord( const StringRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

StringRecord& StringRecord::operator=( const StringRecord& record )
{
    *d = *record.d;
    return *this;
}

QString StringRecord::ustring() const
{
    return d->ustring;
}

void StringRecord::setUstring(QString ustring )
{
    d->ustring = ustring;
}

Value StringRecord::value() const
{
    return Value(ustring());
}

void StringRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    bool stringLengthError = false;
    unsigned stringSize;
    if (size < 2) {
        setIsValid(false);
        return;
    }
    unsigned stringLength = readU16(data);
    curOffset = 2;
    if (version() < Excel97) {
        setUstring(readByteString(data + curOffset, stringLength, size - curOffset, &stringLengthError, &stringSize));
        if (stringLengthError) {
            setIsValid(false);
            return;
        }
        curOffset += stringSize;
    }
    if (version() >= Excel97) {
        setUstring(readUnicodeString(data + curOffset, stringLength, size - curOffset, &stringLengthError, &stringSize));
        if (stringLengthError) {
            setIsValid(false);
            return;
        }
        curOffset += stringSize;
    }
}

void StringRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, ustring().length());
    if (version() < Excel97) {
        out.writeByteString(ustring());
    }
    if (version() >= Excel97) {
        out.writeUnicodeStringWithFlags(ustring());
    }
}

void StringRecord::dump( std::ostream& out ) const
{
    out << "String" << std::endl;
    if (version() < Excel97) {
        out << "            Ustring : " << ustring() << std::endl;
    }
    if (version() >= Excel97) {
        out << "            Ustring : " << ustring() << std::endl;
    }
}

static Record* createStringRecord(Swinder::Workbook *book)
{
    return new StringRecord(book);
}

// ========== NoteRecord ==========

const unsigned NoteRecord::id = 0x1C;

class NoteRecord::Private
{
public:
    unsigned column;
    unsigned idObj;
    unsigned opts;
    unsigned row;
};

NoteRecord::NoteRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setColumn(0);
    setIdObj(0);
    setOpts(0);
    setRow(0);
}

NoteRecord::~NoteRecord()
{
    delete d;
}

NoteRecord::NoteRecord( const NoteRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

NoteRecord& NoteRecord::operator=( const NoteRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned NoteRecord::column() const
{
    return d->column;
}

void NoteRecord::setColumn(unsigned column )
{
    d->column = column;
}

unsigned NoteRecord::idObj() const
{
    return d->idObj;
}

void NoteRecord::setIdObj(unsigned idObj )
{
    d->idObj = idObj;
}

unsigned NoteRecord::opts() const
{
    return d->opts;
}

void NoteRecord::setOpts(unsigned opts )
{
    d->opts = opts;
}

unsigned NoteRecord::row() const
{
    return d->row;
}

void NoteRecord::setRow(unsigned row )
{
    d->row = row;
}

void NoteRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 8) {
        setIsValid(false);
        return;
    }
    setRow(readU16(data));
    setColumn(readU16(data + 2));
    setOpts(readU16(data + 4));
    setIdObj(readU16(data + 6));
}

void NoteRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, row());
    out.writeUnsigned(16, column());
    out.writeUnsigned(16, opts());
    out.writeUnsigned(16, idObj());
}

void NoteRecord::dump( std::ostream& out ) const
{
    out << "Note" << std::endl;
    out << "                Row : " << row() << std::endl;
    out << "             Column : " << column() << std::endl;
    out << "               Opts : " << opts() << std::endl;
    out << "              IdObj : " << idObj() << std::endl;
}

static Record* createNoteRecord(Swinder::Workbook *book)
{
    return new NoteRecord(book);
}

// ========== ProtectRecord ==========

const unsigned ProtectRecord::id = 0x0012;

class ProtectRecord::Private
{
public:
    bool locked;
};

ProtectRecord::ProtectRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setLocked(false);
}

ProtectRecord::~ProtectRecord()
{
    delete d;
}

ProtectRecord::ProtectRecord( const ProtectRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ProtectRecord& ProtectRecord::operator=( const ProtectRecord& record )
{
    *d = *record.d;
    return *this;
}

bool ProtectRecord::isLocked() const
{
    return d->locked;
}

void ProtectRecord::setLocked(bool locked )
{
    d->locked = locked;
}

void ProtectRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setLocked(readU16(data) != 0);
}

void ProtectRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, isLocked());
}

void ProtectRecord::dump( std::ostream& out ) const
{
    out << "Protect" << std::endl;
    out << "             Locked : " << isLocked() << std::endl;
}

static Record* createProtectRecord(Swinder::Workbook *book)
{
    return new ProtectRecord(book);
}

// ========== DefaultRowHeightRecord ==========

const unsigned DefaultRowHeightRecord::id = 0x225;

class DefaultRowHeightRecord::Private
{
public:
    bool dyZero;
    bool exAsc;
    bool exDsc;
    int miyRw;
    int miyRwHidden;
    bool unsynced;
};

DefaultRowHeightRecord::DefaultRowHeightRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setDyZero(false);
    setExAsc(false);
    setExDsc(false);
    setMiyRw(255);
    setMiyRwHidden(0);
    setUnsynced(false);
}

DefaultRowHeightRecord::~DefaultRowHeightRecord()
{
    delete d;
}

DefaultRowHeightRecord::DefaultRowHeightRecord( const DefaultRowHeightRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

DefaultRowHeightRecord& DefaultRowHeightRecord::operator=( const DefaultRowHeightRecord& record )
{
    *d = *record.d;
    return *this;
}

bool DefaultRowHeightRecord::isDyZero() const
{
    return d->dyZero;
}

void DefaultRowHeightRecord::setDyZero(bool dyZero )
{
    d->dyZero = dyZero;
}

bool DefaultRowHeightRecord::isExAsc() const
{
    return d->exAsc;
}

void DefaultRowHeightRecord::setExAsc(bool exAsc )
{
    d->exAsc = exAsc;
}

bool DefaultRowHeightRecord::isExDsc() const
{
    return d->exDsc;
}

void DefaultRowHeightRecord::setExDsc(bool exDsc )
{
    d->exDsc = exDsc;
}

int DefaultRowHeightRecord::miyRw() const
{
    return d->miyRw;
}

void DefaultRowHeightRecord::setMiyRw(int miyRw )
{
    d->miyRw = miyRw;
}

int DefaultRowHeightRecord::miyRwHidden() const
{
    return d->miyRwHidden;
}

void DefaultRowHeightRecord::setMiyRwHidden(int miyRwHidden )
{
    d->miyRwHidden = miyRwHidden;
}

bool DefaultRowHeightRecord::isUnsynced() const
{
    return d->unsynced;
}

void DefaultRowHeightRecord::setUnsynced(bool unsynced )
{
    d->unsynced = unsynced;
}

void DefaultRowHeightRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    if (size < 2) {
        setIsValid(false);
        return;
    }
    setUnsynced(((readU8(data)) & 0x1) != 0);
    setDyZero(((readU8(data) >> 1) & 0x1) != 0);
    setExAsc(((readU8(data) >> 2) & 0x1) != 0);
    setExDsc(((readU8(data) >> 3) & 0x1) != 0);
    curOffset = 2;
    if (!isDyZero()) {
        if (size < curOffset + 2) {
            setIsValid(false);
            return;
        }
        setMiyRw(readS16(data + curOffset));
        curOffset += 2;
    }
    if (isDyZero()) {
        if (size < curOffset + 2) {
            setIsValid(false);
            return;
        }
        setMiyRwHidden(readS16(data + curOffset));
        curOffset += 2;
    }
}

void DefaultRowHeightRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(1, isUnsynced());
    out.writeUnsigned(1, isDyZero());
    out.writeUnsigned(1, isExAsc());
    out.writeUnsigned(1, isExDsc());
    out.writeUnsigned(12, 0);
    if (!isDyZero()) {
        out.writeSigned(16, miyRw());
    }
    if (isDyZero()) {
        out.writeSigned(16, miyRwHidden());
    }
}

void DefaultRowHeightRecord::dump( std::ostream& out ) const
{
    out << "DefaultRowHeight" << std::endl;
    out << "           Unsynced : " << isUnsynced() << std::endl;
    out << "             DyZero : " << isDyZero() << std::endl;
    out << "              ExAsc : " << isExAsc() << std::endl;
    out << "              ExDsc : " << isExDsc() << std::endl;
    if (!isDyZero()) {
        out << "              MiyRw : " << miyRw() << std::endl;
    }
    if (isDyZero()) {
        out << "        MiyRwHidden : " << miyRwHidden() << std::endl;
    }
}

static Record* createDefaultRowHeightRecord(Swinder::Workbook *book)
{
    return new DefaultRowHeightRecord(book);
}

// ========== DefaultColWidthRecord ==========

const unsigned DefaultColWidthRecord::id = 0x55;

class DefaultColWidthRecord::Private
{
public:
    unsigned cchdefColWidth;
};

DefaultColWidthRecord::DefaultColWidthRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCchdefColWidth(8);
}

DefaultColWidthRecord::~DefaultColWidthRecord()
{
    delete d;
}

DefaultColWidthRecord::DefaultColWidthRecord( const DefaultColWidthRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

DefaultColWidthRecord& DefaultColWidthRecord::operator=( const DefaultColWidthRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned DefaultColWidthRecord::cchdefColWidth() const
{
    return d->cchdefColWidth;
}

void DefaultColWidthRecord::setCchdefColWidth(unsigned cchdefColWidth )
{
    d->cchdefColWidth = cchdefColWidth;
}

void DefaultColWidthRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setCchdefColWidth(readU16(data));
}

void DefaultColWidthRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, cchdefColWidth());
}

void DefaultColWidthRecord::dump( std::ostream& out ) const
{
    out << "DefaultColWidth" << std::endl;
    out << "     CchdefColWidth : " << cchdefColWidth() << std::endl;
}

static Record* createDefaultColWidthRecord(Swinder::Workbook *book)
{
    return new DefaultColWidthRecord(book);
}

// ========== HCenterRecord ==========

const unsigned HCenterRecord::id = 0x0083;

class HCenterRecord::Private
{
public:
    bool centered;
};

HCenterRecord::HCenterRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCentered(false);
}

HCenterRecord::~HCenterRecord()
{
    delete d;
}

HCenterRecord::HCenterRecord( const HCenterRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

HCenterRecord& HCenterRecord::operator=( const HCenterRecord& record )
{
    *d = *record.d;
    return *this;
}

bool HCenterRecord::isCentered() const
{
    return d->centered;
}

void HCenterRecord::setCentered(bool centered )
{
    d->centered = centered;
}

void HCenterRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setCentered(readU16(data) != 0);
}

void HCenterRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, isCentered());
}

void HCenterRecord::dump( std::ostream& out ) const
{
    out << "HCenter" << std::endl;
    out << "           Centered : " << isCentered() << std::endl;
}

static Record* createHCenterRecord(Swinder::Workbook *book)
{
    return new HCenterRecord(book);
}

// ========== VCenterRecord ==========

const unsigned VCenterRecord::id = 0x0084;

class VCenterRecord::Private
{
public:
    bool centered;
};

VCenterRecord::VCenterRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCentered(false);
}

VCenterRecord::~VCenterRecord()
{
    delete d;
}

VCenterRecord::VCenterRecord( const VCenterRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

VCenterRecord& VCenterRecord::operator=( const VCenterRecord& record )
{
    *d = *record.d;
    return *this;
}

bool VCenterRecord::isCentered() const
{
    return d->centered;
}

void VCenterRecord::setCentered(bool centered )
{
    d->centered = centered;
}

void VCenterRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setCentered(readU16(data) != 0);
}

void VCenterRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, isCentered());
}

void VCenterRecord::dump( std::ostream& out ) const
{
    out << "VCenter" << std::endl;
    out << "           Centered : " << isCentered() << std::endl;
}

static Record* createVCenterRecord(Swinder::Workbook *book)
{
    return new VCenterRecord(book);
}

// ========== SetupRecord ==========

const unsigned SetupRecord::id = 0x00a1;

class SetupRecord::Private
{
public:
    bool commentsAsEndNotes;
    bool custumStartPageNumber;
    bool draftQuality;
    ErrorPrintMode errorPrintMode;
    unsigned fitHeightToPageCount;
    unsigned fitWidthToPageCount;
    double footerMargin;
    bool greyscale;
    double headerMargin;
    bool leftToRight;
    bool noOrientationSet;
    bool noPaperSizeSet;
    unsigned numCopies;
    unsigned paperSize;
    bool portrait;
    bool printNotes;
    unsigned printResolution;
    unsigned scalePercentage;
    int startingPageNumber;
    unsigned verticalPrintResolution;
};

SetupRecord::SetupRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCommentsAsEndNotes(false);
    setCustumStartPageNumber(false);
    setDraftQuality(false);
    setErrorPrintMode(ErrorsAsDisplayed);
    setFitHeightToPageCount(1);
    setFitWidthToPageCount(1);
    setFooterMargin(0.5);
    setGreyscale(false);
    setHeaderMargin(0.5);
    setLeftToRight(false);
    setNoOrientationSet(false);
    setNoPaperSizeSet(false);
    setNumCopies(1);
    setPaperSize(1);
    setPortrait(true);
    setPrintNotes(false);
    setPrintResolution(200);
    setScalePercentage(100);
    setStartingPageNumber(1);
    setVerticalPrintResolution(200);
}

SetupRecord::~SetupRecord()
{
    delete d;
}

SetupRecord::SetupRecord( const SetupRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

SetupRecord& SetupRecord::operator=( const SetupRecord& record )
{
    *d = *record.d;
    return *this;
}

QString SetupRecord::errorPrintModeToString(ErrorPrintMode errorPrintMode)
{
    switch (errorPrintMode) {
        case ErrorsAsDisplayed: return QString("ErrorsAsDisplayed");
        case ErrorsAsBlank: return QString("ErrorsAsBlank");
        case ErrorsAsDashes: return QString("ErrorsAsDashes");
        case ErrorsAsNA: return QString("ErrorsAsNA");
        default: return QString("Unknown: %1").arg(errorPrintMode);
    }
}

bool SetupRecord::isCommentsAsEndNotes() const
{
    return d->commentsAsEndNotes;
}

void SetupRecord::setCommentsAsEndNotes(bool commentsAsEndNotes )
{
    d->commentsAsEndNotes = commentsAsEndNotes;
}

bool SetupRecord::isCustumStartPageNumber() const
{
    return d->custumStartPageNumber;
}

void SetupRecord::setCustumStartPageNumber(bool custumStartPageNumber )
{
    d->custumStartPageNumber = custumStartPageNumber;
}

bool SetupRecord::isDraftQuality() const
{
    return d->draftQuality;
}

void SetupRecord::setDraftQuality(bool draftQuality )
{
    d->draftQuality = draftQuality;
}

SetupRecord::ErrorPrintMode SetupRecord::errorPrintMode() const
{
    return d->errorPrintMode;
}

void SetupRecord::setErrorPrintMode(ErrorPrintMode errorPrintMode )
{
    d->errorPrintMode = errorPrintMode;
}

unsigned SetupRecord::fitHeightToPageCount() const
{
    return d->fitHeightToPageCount;
}

void SetupRecord::setFitHeightToPageCount(unsigned fitHeightToPageCount )
{
    d->fitHeightToPageCount = fitHeightToPageCount;
}

unsigned SetupRecord::fitWidthToPageCount() const
{
    return d->fitWidthToPageCount;
}

void SetupRecord::setFitWidthToPageCount(unsigned fitWidthToPageCount )
{
    d->fitWidthToPageCount = fitWidthToPageCount;
}

double SetupRecord::footerMargin() const
{
    return d->footerMargin;
}

void SetupRecord::setFooterMargin(double footerMargin )
{
    d->footerMargin = footerMargin;
}

bool SetupRecord::isGreyscale() const
{
    return d->greyscale;
}

void SetupRecord::setGreyscale(bool greyscale )
{
    d->greyscale = greyscale;
}

double SetupRecord::headerMargin() const
{
    return d->headerMargin;
}

void SetupRecord::setHeaderMargin(double headerMargin )
{
    d->headerMargin = headerMargin;
}

bool SetupRecord::isLeftToRight() const
{
    return d->leftToRight;
}

void SetupRecord::setLeftToRight(bool leftToRight )
{
    d->leftToRight = leftToRight;
}

bool SetupRecord::isNoOrientationSet() const
{
    return d->noOrientationSet;
}

void SetupRecord::setNoOrientationSet(bool noOrientationSet )
{
    d->noOrientationSet = noOrientationSet;
}

bool SetupRecord::isNoPaperSizeSet() const
{
    return d->noPaperSizeSet;
}

void SetupRecord::setNoPaperSizeSet(bool noPaperSizeSet )
{
    d->noPaperSizeSet = noPaperSizeSet;
}

unsigned SetupRecord::numCopies() const
{
    return d->numCopies;
}

void SetupRecord::setNumCopies(unsigned numCopies )
{
    d->numCopies = numCopies;
}

unsigned SetupRecord::paperSize() const
{
    return d->paperSize;
}

void SetupRecord::setPaperSize(unsigned paperSize )
{
    d->paperSize = paperSize;
}

bool SetupRecord::isPortrait() const
{
    return d->portrait;
}

void SetupRecord::setPortrait(bool portrait )
{
    d->portrait = portrait;
}

bool SetupRecord::isPrintNotes() const
{
    return d->printNotes;
}

void SetupRecord::setPrintNotes(bool printNotes )
{
    d->printNotes = printNotes;
}

unsigned SetupRecord::printResolution() const
{
    return d->printResolution;
}

void SetupRecord::setPrintResolution(unsigned printResolution )
{
    d->printResolution = printResolution;
}

unsigned SetupRecord::scalePercentage() const
{
    return d->scalePercentage;
}

void SetupRecord::setScalePercentage(unsigned scalePercentage )
{
    d->scalePercentage = scalePercentage;
}

int SetupRecord::startingPageNumber() const
{
    return d->startingPageNumber;
}

void SetupRecord::setStartingPageNumber(int startingPageNumber )
{
    d->startingPageNumber = startingPageNumber;
}

unsigned SetupRecord::verticalPrintResolution() const
{
    return d->verticalPrintResolution;
}

void SetupRecord::setVerticalPrintResolution(unsigned verticalPrintResolution )
{
    d->verticalPrintResolution = verticalPrintResolution;
}

void SetupRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 34) {
        setIsValid(false);
        return;
    }
    setPaperSize(readU16(data));
    setScalePercentage(readU16(data + 2));
    setStartingPageNumber(readS16(data + 4));
    setFitWidthToPageCount(readU16(data + 6));
    setFitHeightToPageCount(readU16(data + 8));
    setLeftToRight(((readU8(data + 10)) & 0x1) != 0);
    setPortrait(((readU8(data + 10) >> 1) & 0x1) != 0);
    setNoPaperSizeSet(((readU8(data + 10) >> 2) & 0x1) != 0);
    setGreyscale(((readU8(data + 10) >> 3) & 0x1) != 0);
    setDraftQuality(((readU8(data + 10) >> 4) & 0x1) != 0);
    setPrintNotes(((readU8(data + 10) >> 5) & 0x1) != 0);
    setNoOrientationSet(((readU8(data + 10) >> 6) & 0x1) != 0);
    setCustumStartPageNumber(((readU8(data + 10) >> 7) & 0x1) != 0);
    setCommentsAsEndNotes(((readU8(data + 11) >> 1) & 0x1) != 0);
    setErrorPrintMode(static_cast<ErrorPrintMode>(((readU8(data + 11) >> 2) & 0x3)));
    setPrintResolution(readU16(data + 12));
    setVerticalPrintResolution(readU16(data + 14));
    setHeaderMargin(readFloat64(data + 16));
    setFooterMargin(readFloat64(data + 24));
    setNumCopies(readU16(data + 32));
}

void SetupRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, paperSize());
    out.writeUnsigned(16, scalePercentage());
    out.writeSigned(16, startingPageNumber());
    out.writeUnsigned(16, fitWidthToPageCount());
    out.writeUnsigned(16, fitHeightToPageCount());
    out.writeUnsigned(1, isLeftToRight());
    out.writeUnsigned(1, isPortrait());
    out.writeUnsigned(1, isNoPaperSizeSet());
    out.writeUnsigned(1, isGreyscale());
    out.writeUnsigned(1, isDraftQuality());
    out.writeUnsigned(1, isPrintNotes());
    out.writeUnsigned(1, isNoOrientationSet());
    out.writeUnsigned(1, isCustumStartPageNumber());
    out.writeUnsigned(1, 0);
    out.writeUnsigned(1, isCommentsAsEndNotes());
    out.writeUnsigned(2, errorPrintMode());
    out.writeUnsigned(4, 0);
    out.writeUnsigned(16, printResolution());
    out.writeUnsigned(16, verticalPrintResolution());
    out.writeFloat(64, headerMargin());
    out.writeFloat(64, footerMargin());
    out.writeUnsigned(16, numCopies());
}

void SetupRecord::dump( std::ostream& out ) const
{
    out << "Setup" << std::endl;
    out << "          PaperSize : " << paperSize() << std::endl;
    out << "    ScalePercentage : " << scalePercentage() << std::endl;
    out << " StartingPageNumber : " << startingPageNumber() << std::endl;
    out << "FitWidthToPageCount : " << fitWidthToPageCount() << std::endl;
    out << "FitHeightToPageCount : " << fitHeightToPageCount() << std::endl;
    out << "        LeftToRight : " << isLeftToRight() << std::endl;
    out << "           Portrait : " << isPortrait() << std::endl;
    out << "     NoPaperSizeSet : " << isNoPaperSizeSet() << std::endl;
    out << "          Greyscale : " << isGreyscale() << std::endl;
    out << "       DraftQuality : " << isDraftQuality() << std::endl;
    out << "         PrintNotes : " << isPrintNotes() << std::endl;
    out << "   NoOrientationSet : " << isNoOrientationSet() << std::endl;
    out << "CustumStartPageNumber : " << isCustumStartPageNumber() << std::endl;
    out << " CommentsAsEndNotes : " << isCommentsAsEndNotes() << std::endl;
    out << "     ErrorPrintMode : " << errorPrintModeToString(errorPrintMode()) << std::endl;
    out << "    PrintResolution : " << printResolution() << std::endl;
    out << "VerticalPrintResolution : " << verticalPrintResolution() << std::endl;
    out << "       HeaderMargin : " << headerMargin() << std::endl;
    out << "       FooterMargin : " << footerMargin() << std::endl;
    out << "          NumCopies : " << numCopies() << std::endl;
}

static Record* createSetupRecord(Swinder::Workbook *book)
{
    return new SetupRecord(book);
}

// ========== CrtLineRecord ==========

const unsigned CrtLineRecord::id = 0x101c;

class CrtLineRecord::Private
{
public:
    unsigned identifier;
};

CrtLineRecord::CrtLineRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setIdentifier(0);
}

CrtLineRecord::~CrtLineRecord()
{
    delete d;
}

CrtLineRecord::CrtLineRecord( const CrtLineRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

CrtLineRecord& CrtLineRecord::operator=( const CrtLineRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned CrtLineRecord::identifier() const
{
    return d->identifier;
}

void CrtLineRecord::setIdentifier(unsigned identifier )
{
    d->identifier = identifier;
}

void CrtLineRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setIdentifier(readU16(data));
}

void CrtLineRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, identifier());
}

void CrtLineRecord::dump( std::ostream& out ) const
{
    out << "CrtLine" << std::endl;
    out << "         Identifier : " << identifier() << std::endl;
}

static Record* createCrtLineRecord(Swinder::Workbook *book)
{
    return new CrtLineRecord(book);
}

// ========== UnitsRecord ==========

const unsigned UnitsRecord::id = 0x1001;

class UnitsRecord::Private
{
public:
};

UnitsRecord::UnitsRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

UnitsRecord::~UnitsRecord()
{
    delete d;
}

UnitsRecord::UnitsRecord( const UnitsRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

UnitsRecord& UnitsRecord::operator=( const UnitsRecord& record )
{
    *d = *record.d;
    return *this;
}

void UnitsRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void UnitsRecord::writeData( XlsRecordOutputStream& ) const
{
}

void UnitsRecord::dump( std::ostream& out ) const
{
    out << "Units" << std::endl;
}

static Record* createUnitsRecord(Swinder::Workbook *book)
{
    return new UnitsRecord(book);
}

// ========== PrintSizeRecord ==========

const unsigned PrintSizeRecord::id = 0x0033;

class PrintSizeRecord::Private
{
public:
    PrintSize printSize;
};

PrintSizeRecord::PrintSizeRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setPrintSize(WorkbookDefaults);
}

PrintSizeRecord::~PrintSizeRecord()
{
    delete d;
}

PrintSizeRecord::PrintSizeRecord( const PrintSizeRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

PrintSizeRecord& PrintSizeRecord::operator=( const PrintSizeRecord& record )
{
    *d = *record.d;
    return *this;
}

QString PrintSizeRecord::printSizeToString(PrintSize printSize)
{
    switch (printSize) {
        case WorkbookDefaults: return QString("WorkbookDefaults");
        case FillPage: return QString("FillPage");
        case FillPageProportionally: return QString("FillPageProportionally");
        case SizeFromChartRecord: return QString("SizeFromChartRecord");
        default: return QString("Unknown: %1").arg(printSize);
    }
}

PrintSizeRecord::PrintSize PrintSizeRecord::printSize() const
{
    return d->printSize;
}

void PrintSizeRecord::setPrintSize(PrintSize printSize )
{
    d->printSize = printSize;
}

void PrintSizeRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setPrintSize(static_cast<PrintSize>(readU16(data)));
}

void PrintSizeRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, printSize());
}

void PrintSizeRecord::dump( std::ostream& out ) const
{
    out << "PrintSize" << std::endl;
    out << "          PrintSize : " << printSizeToString(printSize()) << std::endl;
}

static Record* createPrintSizeRecord(Swinder::Workbook *book)
{
    return new PrintSizeRecord(book);
}

// ========== ChartRecord ==========

const unsigned ChartRecord::id = 0x1002;

class ChartRecord::Private
{
public:
    double height;
    double width;
    double x;
    double y;
};

ChartRecord::ChartRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

ChartRecord::~ChartRecord()
{
    delete d;
}

ChartRecord::ChartRecord( const ChartRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ChartRecord& ChartRecord::operator=( const ChartRecord& record )
{
    *d = *record.d;
    return *this;
}

double ChartRecord::height() const
{
    return d->height;
}

void ChartRecord::setHeight(double height )
{
    d->height = height;
}

double ChartRecord::width() const
{
    return d->width;
}

void ChartRecord::setWidth(double width )
{
    d->width = width;
}

double ChartRecord::x() const
{
    return d->x;
}

void ChartRecord::setX(double x )
{
    d->x = x;
}

double ChartRecord::y() const
{
    return d->y;
}

void ChartRecord::setY(double y )
{
    d->y = y;
}

void ChartRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 16) {
        setIsValid(false);
        return;
    }
    setX(readFixed32(data));
    setY(readFixed32(data + 4));
    setWidth(readFixed32(data + 8));
    setHeight(readFixed32(data + 12));
}

void ChartRecord::writeData( XlsRecordOutputStream& out ) const
{
    // TODO x());
    // TODO y());
    // TODO width());
    // TODO height());
}

void ChartRecord::dump( std::ostream& out ) const
{
    out << "Chart" << std::endl;
    out << "                  X : " << x() << std::endl;
    out << "                  Y : " << y() << std::endl;
    out << "              Width : " << width() << std::endl;
    out << "             Height : " << height() << std::endl;
}

static Record* createChartRecord(Swinder::Workbook *book)
{
    return new ChartRecord(book);
}

// ========== SheetExtRecord ==========

const unsigned SheetExtRecord::id = 0x0862;

class SheetExtRecord::Private
{
public:
    unsigned cb;
    unsigned color;
    bool fCondFmtCalc;
    bool fNotPublished;
    unsigned icvPlain;
    unsigned icvPlain12;
};

SheetExtRecord::SheetExtRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCb(0);
    setColor(0);
    setFCondFmtCalc(false);
    setFNotPublished(false);
    setIcvPlain(0);
    setIcvPlain12(0);
}

SheetExtRecord::~SheetExtRecord()
{
    delete d;
}

SheetExtRecord::SheetExtRecord( const SheetExtRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

SheetExtRecord& SheetExtRecord::operator=( const SheetExtRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned SheetExtRecord::cb() const
{
    return d->cb;
}

void SheetExtRecord::setCb(unsigned cb )
{
    d->cb = cb;
}

unsigned SheetExtRecord::color() const
{
    return d->color;
}

void SheetExtRecord::setColor(unsigned color )
{
    d->color = color;
}

bool SheetExtRecord::isFCondFmtCalc() const
{
    return d->fCondFmtCalc;
}

void SheetExtRecord::setFCondFmtCalc(bool fCondFmtCalc )
{
    d->fCondFmtCalc = fCondFmtCalc;
}

bool SheetExtRecord::isFNotPublished() const
{
    return d->fNotPublished;
}

void SheetExtRecord::setFNotPublished(bool fNotPublished )
{
    d->fNotPublished = fNotPublished;
}

unsigned SheetExtRecord::icvPlain() const
{
    return d->icvPlain;
}

void SheetExtRecord::setIcvPlain(unsigned icvPlain )
{
    d->icvPlain = icvPlain;
}

unsigned SheetExtRecord::icvPlain12() const
{
    return d->icvPlain12;
}

void SheetExtRecord::setIcvPlain12(unsigned icvPlain12 )
{
    d->icvPlain12 = icvPlain12;
}

void SheetExtRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 14) {
        setIsValid(false);
        return;
    }
    setCb(readU32(data));
    setIcvPlain(((readU8(data + 4)) & 0x7f));
    setIcvPlain12(((readU8(data + 8)) & 0x7f));
    setFCondFmtCalc(((readU8(data + 8) >> 7) & 0x1) != 0);
    setFNotPublished(((readU8(data + 9)) & 0x1) != 0);
    setColor(readU16(data + 12));
}

void SheetExtRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(32, cb());
    out.writeUnsigned(7, icvPlain());
    out.writeUnsigned(25, 0);
    out.writeUnsigned(7, icvPlain12());
    out.writeUnsigned(1, isFCondFmtCalc());
    out.writeUnsigned(1, isFNotPublished());
    out.writeUnsigned(23, 0);
    out.writeUnsigned(16, color());
}

void SheetExtRecord::dump( std::ostream& out ) const
{
    out << "SheetExt" << std::endl;
    out << "                 Cb : " << cb() << std::endl;
    out << "           IcvPlain : " << icvPlain() << std::endl;
    out << "         IcvPlain12 : " << icvPlain12() << std::endl;
    out << "       FCondFmtCalc : " << isFCondFmtCalc() << std::endl;
    out << "      FNotPublished : " << isFNotPublished() << std::endl;
    out << "              Color : " << color() << std::endl;
}

static Record* createSheetExtRecord(Swinder::Workbook *book)
{
    return new SheetExtRecord(book);
}

// ========== BeginRecord ==========

const unsigned BeginRecord::id = 0x1033;

class BeginRecord::Private
{
public:
};

BeginRecord::BeginRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

BeginRecord::~BeginRecord()
{
    delete d;
}

BeginRecord::BeginRecord( const BeginRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

BeginRecord& BeginRecord::operator=( const BeginRecord& record )
{
    *d = *record.d;
    return *this;
}

void BeginRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void BeginRecord::writeData( XlsRecordOutputStream& ) const
{
}

void BeginRecord::dump( std::ostream& out ) const
{
    out << "Begin" << std::endl;
}

static Record* createBeginRecord(Swinder::Workbook *book)
{
    return new BeginRecord(book);
}

// ========== EndRecord ==========

const unsigned EndRecord::id = 0x1034;

class EndRecord::Private
{
public:
};

EndRecord::EndRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

EndRecord::~EndRecord()
{
    delete d;
}

EndRecord::EndRecord( const EndRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

EndRecord& EndRecord::operator=( const EndRecord& record )
{
    *d = *record.d;
    return *this;
}

void EndRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void EndRecord::writeData( XlsRecordOutputStream& ) const
{
}

void EndRecord::dump( std::ostream& out ) const
{
    out << "End" << std::endl;
}

static Record* createEndRecord(Swinder::Workbook *book)
{
    return new EndRecord(book);
}

// ========== DataFormatRecord ==========

const unsigned DataFormatRecord::id = 0x1006;

class DataFormatRecord::Private
{
public:
    unsigned iss;
    unsigned xi;
    unsigned yi;
};

DataFormatRecord::DataFormatRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setIss(0);
    setXi(0);
    setYi(0);
}

DataFormatRecord::~DataFormatRecord()
{
    delete d;
}

DataFormatRecord::DataFormatRecord( const DataFormatRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

DataFormatRecord& DataFormatRecord::operator=( const DataFormatRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned DataFormatRecord::iss() const
{
    return d->iss;
}

void DataFormatRecord::setIss(unsigned iss )
{
    d->iss = iss;
}

unsigned DataFormatRecord::xi() const
{
    return d->xi;
}

void DataFormatRecord::setXi(unsigned xi )
{
    d->xi = xi;
}

unsigned DataFormatRecord::yi() const
{
    return d->yi;
}

void DataFormatRecord::setYi(unsigned yi )
{
    d->yi = yi;
}

void DataFormatRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 6) {
        setIsValid(false);
        return;
    }
    setXi(readU16(data));
    setYi(readU16(data + 2));
    setIss(readU16(data + 4));
}

void DataFormatRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, xi());
    out.writeUnsigned(16, yi());
    out.writeUnsigned(16, iss());
}

void DataFormatRecord::dump( std::ostream& out ) const
{
    out << "DataFormat" << std::endl;
    out << "                 Xi : " << xi() << std::endl;
    out << "                 Yi : " << yi() << std::endl;
    out << "                Iss : " << iss() << std::endl;
}

static Record* createDataFormatRecord(Swinder::Workbook *book)
{
    return new DataFormatRecord(book);
}

// ========== LineFormatRecord ==========

const unsigned LineFormatRecord::id = 0x1007;

class LineFormatRecord::Private
{
public:
    unsigned blue;
    bool fAuto;
    bool fAutoCo;
    bool fAxisOn;
    unsigned green;
    unsigned icv;
    Lns lns;
    unsigned red;
    We we;
};

LineFormatRecord::LineFormatRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setBlue(0);
    setFAuto(false);
    setFAutoCo(false);
    setFAxisOn(false);
    setGreen(0);
    setIcv(0);
    setLns(Solid);
    setRed(0);
    setWe(Hairline);
}

LineFormatRecord::~LineFormatRecord()
{
    delete d;
}

LineFormatRecord::LineFormatRecord( const LineFormatRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

LineFormatRecord& LineFormatRecord::operator=( const LineFormatRecord& record )
{
    *d = *record.d;
    return *this;
}

QString LineFormatRecord::lnsToString(Lns lns)
{
    switch (lns) {
        case Solid: return QString("Solid");
        case Dash: return QString("Dash");
        case Dot: return QString("Dot");
        case DashDot: return QString("DashDot");
        case DashDotDot: return QString("DashDotDot");
        case None: return QString("None");
        case DarkGrayPattern: return QString("DarkGrayPattern");
        case MediumGrayPattern: return QString("MediumGrayPattern");
        case LightGrayPattern: return QString("LightGrayPattern");
        default: return QString("Unknown: %1").arg(lns);
    }
}

QString LineFormatRecord::weToString(We we)
{
    switch (we) {
        case Hairline: return QString("Hairline");
        case NarrowSingle: return QString("NarrowSingle");
        case MediumDouble: return QString("MediumDouble");
        case WideTriple: return QString("WideTriple");
        default: return QString("Unknown: %1").arg(we);
    }
}

unsigned LineFormatRecord::blue() const
{
    return d->blue;
}

void LineFormatRecord::setBlue(unsigned blue )
{
    d->blue = blue;
}

bool LineFormatRecord::isFAuto() const
{
    return d->fAuto;
}

void LineFormatRecord::setFAuto(bool fAuto )
{
    d->fAuto = fAuto;
}

bool LineFormatRecord::isFAutoCo() const
{
    return d->fAutoCo;
}

void LineFormatRecord::setFAutoCo(bool fAutoCo )
{
    d->fAutoCo = fAutoCo;
}

bool LineFormatRecord::isFAxisOn() const
{
    return d->fAxisOn;
}

void LineFormatRecord::setFAxisOn(bool fAxisOn )
{
    d->fAxisOn = fAxisOn;
}

unsigned LineFormatRecord::green() const
{
    return d->green;
}

void LineFormatRecord::setGreen(unsigned green )
{
    d->green = green;
}

unsigned LineFormatRecord::icv() const
{
    return d->icv;
}

void LineFormatRecord::setIcv(unsigned icv )
{
    d->icv = icv;
}

LineFormatRecord::Lns LineFormatRecord::lns() const
{
    return d->lns;
}

void LineFormatRecord::setLns(Lns lns )
{
    d->lns = lns;
}

unsigned LineFormatRecord::red() const
{
    return d->red;
}

void LineFormatRecord::setRed(unsigned red )
{
    d->red = red;
}

LineFormatRecord::We LineFormatRecord::we() const
{
    return d->we;
}

void LineFormatRecord::setWe(We we )
{
    d->we = we;
}

void LineFormatRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 12) {
        setIsValid(false);
        return;
    }
    setRed(readU8(data));
    setGreen(readU8(data + 1));
    setBlue(readU8(data + 2));
    setLns(static_cast<Lns>(readU16(data + 4)));
    setWe(static_cast<We>(readS16(data + 6)));
    setFAuto(((readU8(data + 8)) & 0x1) != 0);
    setFAxisOn(((readU8(data + 8) >> 2) & 0x1) != 0);
    setFAutoCo(((readU8(data + 8) >> 3) & 0x1) != 0);
    setIcv(readU16(data + 10));
}

void LineFormatRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(8, red());
    out.writeUnsigned(8, green());
    out.writeUnsigned(8, blue());
    out.writeUnsigned(8, 0);
    out.writeUnsigned(16, lns());
    out.writeUnsigned(16, we());
    out.writeUnsigned(1, isFAuto());
    out.writeUnsigned(1, 0);
    out.writeUnsigned(1, isFAxisOn());
    out.writeUnsigned(1, isFAutoCo());
    out.writeUnsigned(12, 0);
    out.writeUnsigned(16, icv());
}

void LineFormatRecord::dump( std::ostream& out ) const
{
    out << "LineFormat" << std::endl;
    out << "                Red : " << red() << std::endl;
    out << "              Green : " << green() << std::endl;
    out << "               Blue : " << blue() << std::endl;
    out << "                Lns : " << lnsToString(lns()) << std::endl;
    out << "                 We : " << weToString(we()) << std::endl;
    out << "              FAuto : " << isFAuto() << std::endl;
    out << "            FAxisOn : " << isFAxisOn() << std::endl;
    out << "            FAutoCo : " << isFAutoCo() << std::endl;
    out << "                Icv : " << icv() << std::endl;
}

static Record* createLineFormatRecord(Swinder::Workbook *book)
{
    return new LineFormatRecord(book);
}

// ========== MarkerFormatRecord ==========

const unsigned MarkerFormatRecord::id = 0x1009;

class MarkerFormatRecord::Private
{
public:
    unsigned blueBackground;
    unsigned blueForeground;
    unsigned fAuto;
    unsigned fNotShowBrd;
    unsigned fNotShowInt;
    unsigned greenBackground;
    unsigned greenForeground;
    unsigned icvBack;
    unsigned icvFore;
    unsigned imk;
    unsigned redBackground;
    unsigned redForeground;
};

MarkerFormatRecord::MarkerFormatRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setBlueBackground(0);
    setBlueForeground(0);
    setFAuto(0);
    setFNotShowBrd(0);
    setFNotShowInt(0);
    setGreenBackground(0);
    setGreenForeground(0);
    setIcvBack(0);
    setIcvFore(0);
    setImk(0);
    setRedBackground(0);
    setRedForeground(0);
}

MarkerFormatRecord::~MarkerFormatRecord()
{
    delete d;
}

MarkerFormatRecord::MarkerFormatRecord( const MarkerFormatRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

MarkerFormatRecord& MarkerFormatRecord::operator=( const MarkerFormatRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned MarkerFormatRecord::blueBackground() const
{
    return d->blueBackground;
}

void MarkerFormatRecord::setBlueBackground(unsigned blueBackground )
{
    d->blueBackground = blueBackground;
}

unsigned MarkerFormatRecord::blueForeground() const
{
    return d->blueForeground;
}

void MarkerFormatRecord::setBlueForeground(unsigned blueForeground )
{
    d->blueForeground = blueForeground;
}

unsigned MarkerFormatRecord::fAuto() const
{
    return d->fAuto;
}

void MarkerFormatRecord::setFAuto(unsigned fAuto )
{
    d->fAuto = fAuto;
}

unsigned MarkerFormatRecord::fNotShowBrd() const
{
    return d->fNotShowBrd;
}

void MarkerFormatRecord::setFNotShowBrd(unsigned fNotShowBrd )
{
    d->fNotShowBrd = fNotShowBrd;
}

unsigned MarkerFormatRecord::fNotShowInt() const
{
    return d->fNotShowInt;
}

void MarkerFormatRecord::setFNotShowInt(unsigned fNotShowInt )
{
    d->fNotShowInt = fNotShowInt;
}

unsigned MarkerFormatRecord::greenBackground() const
{
    return d->greenBackground;
}

void MarkerFormatRecord::setGreenBackground(unsigned greenBackground )
{
    d->greenBackground = greenBackground;
}

unsigned MarkerFormatRecord::greenForeground() const
{
    return d->greenForeground;
}

void MarkerFormatRecord::setGreenForeground(unsigned greenForeground )
{
    d->greenForeground = greenForeground;
}

unsigned MarkerFormatRecord::icvBack() const
{
    return d->icvBack;
}

void MarkerFormatRecord::setIcvBack(unsigned icvBack )
{
    d->icvBack = icvBack;
}

unsigned MarkerFormatRecord::icvFore() const
{
    return d->icvFore;
}

void MarkerFormatRecord::setIcvFore(unsigned icvFore )
{
    d->icvFore = icvFore;
}

unsigned MarkerFormatRecord::imk() const
{
    return d->imk;
}

void MarkerFormatRecord::setImk(unsigned imk )
{
    d->imk = imk;
}

unsigned MarkerFormatRecord::redBackground() const
{
    return d->redBackground;
}

void MarkerFormatRecord::setRedBackground(unsigned redBackground )
{
    d->redBackground = redBackground;
}

unsigned MarkerFormatRecord::redForeground() const
{
    return d->redForeground;
}

void MarkerFormatRecord::setRedForeground(unsigned redForeground )
{
    d->redForeground = redForeground;
}

void MarkerFormatRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 16) {
        setIsValid(false);
        return;
    }
    setRedForeground(readU8(data));
    setGreenForeground(readU8(data + 1));
    setBlueForeground(readU8(data + 2));
    setRedBackground(readU8(data + 4));
    setGreenBackground(readU8(data + 5));
    setBlueBackground(readU8(data + 6));
    setImk(readU16(data + 8));
    setFAuto(((readU8(data + 10)) & 0x1));
    setFNotShowInt(((readU8(data + 10) >> 4) & 0x1));
    setFNotShowBrd(((readU8(data + 10) >> 5) & 0x1));
    setIcvFore(readU16(data + 12));
    setIcvBack(readU16(data + 14));
}

void MarkerFormatRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(8, redForeground());
    out.writeUnsigned(8, greenForeground());
    out.writeUnsigned(8, blueForeground());
    out.writeUnsigned(8, 0);
    out.writeUnsigned(8, redBackground());
    out.writeUnsigned(8, greenBackground());
    out.writeUnsigned(8, blueBackground());
    out.writeUnsigned(8, 0);
    out.writeUnsigned(16, imk());
    out.writeUnsigned(1, fAuto());
    out.writeUnsigned(3, 0);
    out.writeUnsigned(1, fNotShowInt());
    out.writeUnsigned(1, fNotShowBrd());
    out.writeUnsigned(10, 0);
    out.writeUnsigned(16, icvFore());
    out.writeUnsigned(16, icvBack());
}

void MarkerFormatRecord::dump( std::ostream& out ) const
{
    out << "MarkerFormat" << std::endl;
    out << "      RedForeground : " << redForeground() << std::endl;
    out << "    GreenForeground : " << greenForeground() << std::endl;
    out << "     BlueForeground : " << blueForeground() << std::endl;
    out << "      RedBackground : " << redBackground() << std::endl;
    out << "    GreenBackground : " << greenBackground() << std::endl;
    out << "     BlueBackground : " << blueBackground() << std::endl;
    out << "                Imk : " << imk() << std::endl;
    out << "              FAuto : " << fAuto() << std::endl;
    out << "        FNotShowInt : " << fNotShowInt() << std::endl;
    out << "        FNotShowBrd : " << fNotShowBrd() << std::endl;
    out << "            IcvFore : " << icvFore() << std::endl;
    out << "            IcvBack : " << icvBack() << std::endl;
}

static Record* createMarkerFormatRecord(Swinder::Workbook *book)
{
    return new MarkerFormatRecord(book);
}

// ========== AreaFormatRecord ==========

const unsigned AreaFormatRecord::id = 0x100a;

class AreaFormatRecord::Private
{
public:
    unsigned blueBackground;
    unsigned blueForeground;
    bool fAuto;
    bool fInvertNeg;
    unsigned fls;
    unsigned greenBackground;
    unsigned greenForeground;
    unsigned icvBackground;
    unsigned icvForeground;
    unsigned redBackground;
    unsigned redForeground;
};

AreaFormatRecord::AreaFormatRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setBlueBackground(0);
    setBlueForeground(0);
    setFAuto(false);
    setFInvertNeg(false);
    setFls(0);
    setGreenBackground(0);
    setGreenForeground(0);
    setIcvBackground(0);
    setIcvForeground(0);
    setRedBackground(0);
    setRedForeground(0);
}

AreaFormatRecord::~AreaFormatRecord()
{
    delete d;
}

AreaFormatRecord::AreaFormatRecord( const AreaFormatRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

AreaFormatRecord& AreaFormatRecord::operator=( const AreaFormatRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned AreaFormatRecord::blueBackground() const
{
    return d->blueBackground;
}

void AreaFormatRecord::setBlueBackground(unsigned blueBackground )
{
    d->blueBackground = blueBackground;
}

unsigned AreaFormatRecord::blueForeground() const
{
    return d->blueForeground;
}

void AreaFormatRecord::setBlueForeground(unsigned blueForeground )
{
    d->blueForeground = blueForeground;
}

bool AreaFormatRecord::isFAuto() const
{
    return d->fAuto;
}

void AreaFormatRecord::setFAuto(bool fAuto )
{
    d->fAuto = fAuto;
}

bool AreaFormatRecord::isFInvertNeg() const
{
    return d->fInvertNeg;
}

void AreaFormatRecord::setFInvertNeg(bool fInvertNeg )
{
    d->fInvertNeg = fInvertNeg;
}

unsigned AreaFormatRecord::fls() const
{
    return d->fls;
}

void AreaFormatRecord::setFls(unsigned fls )
{
    d->fls = fls;
}

unsigned AreaFormatRecord::greenBackground() const
{
    return d->greenBackground;
}

void AreaFormatRecord::setGreenBackground(unsigned greenBackground )
{
    d->greenBackground = greenBackground;
}

unsigned AreaFormatRecord::greenForeground() const
{
    return d->greenForeground;
}

void AreaFormatRecord::setGreenForeground(unsigned greenForeground )
{
    d->greenForeground = greenForeground;
}

unsigned AreaFormatRecord::icvBackground() const
{
    return d->icvBackground;
}

void AreaFormatRecord::setIcvBackground(unsigned icvBackground )
{
    d->icvBackground = icvBackground;
}

unsigned AreaFormatRecord::icvForeground() const
{
    return d->icvForeground;
}

void AreaFormatRecord::setIcvForeground(unsigned icvForeground )
{
    d->icvForeground = icvForeground;
}

unsigned AreaFormatRecord::redBackground() const
{
    return d->redBackground;
}

void AreaFormatRecord::setRedBackground(unsigned redBackground )
{
    d->redBackground = redBackground;
}

unsigned AreaFormatRecord::redForeground() const
{
    return d->redForeground;
}

void AreaFormatRecord::setRedForeground(unsigned redForeground )
{
    d->redForeground = redForeground;
}

void AreaFormatRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 16) {
        setIsValid(false);
        return;
    }
    setRedForeground(readU8(data));
    setGreenForeground(readU8(data + 1));
    setBlueForeground(readU8(data + 2));
    setRedBackground(readU8(data + 4));
    setGreenBackground(readU8(data + 5));
    setBlueBackground(readU8(data + 6));
    setFls(readU16(data + 8));
    setFAuto(((readU8(data + 10)) & 0x1) != 0);
    setFInvertNeg(((readU8(data + 10) >> 1) & 0x1) != 0);
    setIcvForeground(readU16(data + 12));
    setIcvBackground(readU16(data + 14));
}

void AreaFormatRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(8, redForeground());
    out.writeUnsigned(8, greenForeground());
    out.writeUnsigned(8, blueForeground());
    out.writeUnsigned(8, 0);
    out.writeUnsigned(8, redBackground());
    out.writeUnsigned(8, greenBackground());
    out.writeUnsigned(8, blueBackground());
    out.writeUnsigned(8, 0);
    out.writeUnsigned(16, fls());
    out.writeUnsigned(1, isFAuto());
    out.writeUnsigned(1, isFInvertNeg());
    out.writeUnsigned(14, 0);
    out.writeUnsigned(16, icvForeground());
    out.writeUnsigned(16, icvBackground());
}

void AreaFormatRecord::dump( std::ostream& out ) const
{
    out << "AreaFormat" << std::endl;
    out << "      RedForeground : " << redForeground() << std::endl;
    out << "    GreenForeground : " << greenForeground() << std::endl;
    out << "     BlueForeground : " << blueForeground() << std::endl;
    out << "      RedBackground : " << redBackground() << std::endl;
    out << "    GreenBackground : " << greenBackground() << std::endl;
    out << "     BlueBackground : " << blueBackground() << std::endl;
    out << "                Fls : " << fls() << std::endl;
    out << "              FAuto : " << isFAuto() << std::endl;
    out << "         FInvertNeg : " << isFInvertNeg() << std::endl;
    out << "      IcvForeground : " << icvForeground() << std::endl;
    out << "      IcvBackground : " << icvBackground() << std::endl;
}

static Record* createAreaFormatRecord(Swinder::Workbook *book)
{
    return new AreaFormatRecord(book);
}

// ========== PieRecord ==========

const unsigned PieRecord::id = 0x1019;

class PieRecord::Private
{
public:
    unsigned anStart;
    bool fHasShadow;
    bool fShowLdrLines;
    unsigned pcDonut;
};

PieRecord::PieRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setAnStart(0);
    setFHasShadow(false);
    setFShowLdrLines(false);
    setPcDonut(0);
}

PieRecord::~PieRecord()
{
    delete d;
}

PieRecord::PieRecord( const PieRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

PieRecord& PieRecord::operator=( const PieRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned PieRecord::anStart() const
{
    return d->anStart;
}

void PieRecord::setAnStart(unsigned anStart )
{
    d->anStart = anStart;
}

bool PieRecord::isFHasShadow() const
{
    return d->fHasShadow;
}

void PieRecord::setFHasShadow(bool fHasShadow )
{
    d->fHasShadow = fHasShadow;
}

bool PieRecord::isFShowLdrLines() const
{
    return d->fShowLdrLines;
}

void PieRecord::setFShowLdrLines(bool fShowLdrLines )
{
    d->fShowLdrLines = fShowLdrLines;
}

unsigned PieRecord::pcDonut() const
{
    return d->pcDonut;
}

void PieRecord::setPcDonut(unsigned pcDonut )
{
    d->pcDonut = pcDonut;
}

void PieRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 6) {
        setIsValid(false);
        return;
    }
    setAnStart(readU16(data));
    setPcDonut(readU16(data + 2));
    setFHasShadow(((readU8(data + 4)) & 0x1) != 0);
    setFShowLdrLines(((readU8(data + 4) >> 1) & 0x1) != 0);
}

void PieRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, anStart());
    out.writeUnsigned(16, pcDonut());
    out.writeUnsigned(1, isFHasShadow());
    out.writeUnsigned(1, isFShowLdrLines());
    out.writeUnsigned(14, 0);
}

void PieRecord::dump( std::ostream& out ) const
{
    out << "Pie" << std::endl;
    out << "            AnStart : " << anStart() << std::endl;
    out << "            PcDonut : " << pcDonut() << std::endl;
    out << "         FHasShadow : " << isFHasShadow() << std::endl;
    out << "      FShowLdrLines : " << isFShowLdrLines() << std::endl;
}

static Record* createPieRecord(Swinder::Workbook *book)
{
    return new PieRecord(book);
}

// ========== PieFormatRecord ==========

const unsigned PieFormatRecord::id = 0x100b;

class PieFormatRecord::Private
{
public:
    int pcExplode;
};

PieFormatRecord::PieFormatRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setPcExplode(0);
}

PieFormatRecord::~PieFormatRecord()
{
    delete d;
}

PieFormatRecord::PieFormatRecord( const PieFormatRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

PieFormatRecord& PieFormatRecord::operator=( const PieFormatRecord& record )
{
    *d = *record.d;
    return *this;
}

int PieFormatRecord::pcExplode() const
{
    return d->pcExplode;
}

void PieFormatRecord::setPcExplode(int pcExplode )
{
    d->pcExplode = pcExplode;
}

void PieFormatRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setPcExplode(readS16(data));
}

void PieFormatRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeSigned(16, pcExplode());
}

void PieFormatRecord::dump( std::ostream& out ) const
{
    out << "PieFormat" << std::endl;
    out << "          PcExplode : " << pcExplode() << std::endl;
}

static Record* createPieFormatRecord(Swinder::Workbook *book)
{
    return new PieFormatRecord(book);
}

// ========== AttachedLabelRecord ==========

const unsigned AttachedLabelRecord::id = 0x100c;

class AttachedLabelRecord::Private
{
public:
    bool fShowBubbleSizes;
    bool fShowLabel;
    bool fShowLabelAndPerc;
    bool fShowPercent;
    bool fShowSeriesName;
    bool fShowValue;
    unsigned unused;
};

AttachedLabelRecord::AttachedLabelRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFShowBubbleSizes(false);
    setFShowLabel(false);
    setFShowLabelAndPerc(false);
    setFShowPercent(false);
    setFShowSeriesName(false);
    setFShowValue(false);
    setUnused(0);
}

AttachedLabelRecord::~AttachedLabelRecord()
{
    delete d;
}

AttachedLabelRecord::AttachedLabelRecord( const AttachedLabelRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

AttachedLabelRecord& AttachedLabelRecord::operator=( const AttachedLabelRecord& record )
{
    *d = *record.d;
    return *this;
}

bool AttachedLabelRecord::isFShowBubbleSizes() const
{
    return d->fShowBubbleSizes;
}

void AttachedLabelRecord::setFShowBubbleSizes(bool fShowBubbleSizes )
{
    d->fShowBubbleSizes = fShowBubbleSizes;
}

bool AttachedLabelRecord::isFShowLabel() const
{
    return d->fShowLabel;
}

void AttachedLabelRecord::setFShowLabel(bool fShowLabel )
{
    d->fShowLabel = fShowLabel;
}

bool AttachedLabelRecord::isFShowLabelAndPerc() const
{
    return d->fShowLabelAndPerc;
}

void AttachedLabelRecord::setFShowLabelAndPerc(bool fShowLabelAndPerc )
{
    d->fShowLabelAndPerc = fShowLabelAndPerc;
}

bool AttachedLabelRecord::isFShowPercent() const
{
    return d->fShowPercent;
}

void AttachedLabelRecord::setFShowPercent(bool fShowPercent )
{
    d->fShowPercent = fShowPercent;
}

bool AttachedLabelRecord::isFShowSeriesName() const
{
    return d->fShowSeriesName;
}

void AttachedLabelRecord::setFShowSeriesName(bool fShowSeriesName )
{
    d->fShowSeriesName = fShowSeriesName;
}

bool AttachedLabelRecord::isFShowValue() const
{
    return d->fShowValue;
}

void AttachedLabelRecord::setFShowValue(bool fShowValue )
{
    d->fShowValue = fShowValue;
}

unsigned AttachedLabelRecord::unused() const
{
    return d->unused;
}

void AttachedLabelRecord::setUnused(unsigned unused )
{
    d->unused = unused;
}

void AttachedLabelRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setFShowValue(((readU8(data)) & 0x1) != 0);
    setFShowPercent(((readU8(data) >> 1) & 0x1) != 0);
    setFShowLabelAndPerc(((readU8(data) >> 2) & 0x1) != 0);
    setUnused(((readU8(data) >> 3) & 0x1));
    setFShowLabel(((readU8(data) >> 4) & 0x1) != 0);
    setFShowBubbleSizes(((readU8(data) >> 5) & 0x1) != 0);
    setFShowSeriesName(((readU8(data) >> 6) & 0x1) != 0);
}

void AttachedLabelRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(1, isFShowValue());
    out.writeUnsigned(1, isFShowPercent());
    out.writeUnsigned(1, isFShowLabelAndPerc());
    out.writeUnsigned(1, unused());
    out.writeUnsigned(1, isFShowLabel());
    out.writeUnsigned(1, isFShowBubbleSizes());
    out.writeUnsigned(1, isFShowSeriesName());
    out.writeUnsigned(9, 0);
}

void AttachedLabelRecord::dump( std::ostream& out ) const
{
    out << "AttachedLabel" << std::endl;
    out << "         FShowValue : " << isFShowValue() << std::endl;
    out << "       FShowPercent : " << isFShowPercent() << std::endl;
    out << "  FShowLabelAndPerc : " << isFShowLabelAndPerc() << std::endl;
    out << "             Unused : " << unused() << std::endl;
    out << "         FShowLabel : " << isFShowLabel() << std::endl;
    out << "   FShowBubbleSizes : " << isFShowBubbleSizes() << std::endl;
    out << "    FShowSeriesName : " << isFShowSeriesName() << std::endl;
}

static Record* createAttachedLabelRecord(Swinder::Workbook *book)
{
    return new AttachedLabelRecord(book);
}

// ========== ChartFormatRecord ==========

const unsigned ChartFormatRecord::id = 0x1014;

class ChartFormatRecord::Private
{
public:
    bool fVaried;
    unsigned icrt;
};

ChartFormatRecord::ChartFormatRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFVaried(false);
    setIcrt(0);
}

ChartFormatRecord::~ChartFormatRecord()
{
    delete d;
}

ChartFormatRecord::ChartFormatRecord( const ChartFormatRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ChartFormatRecord& ChartFormatRecord::operator=( const ChartFormatRecord& record )
{
    *d = *record.d;
    return *this;
}

bool ChartFormatRecord::isFVaried() const
{
    return d->fVaried;
}

void ChartFormatRecord::setFVaried(bool fVaried )
{
    d->fVaried = fVaried;
}

unsigned ChartFormatRecord::icrt() const
{
    return d->icrt;
}

void ChartFormatRecord::setIcrt(unsigned icrt )
{
    d->icrt = icrt;
}

void ChartFormatRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 20) {
        setIsValid(false);
        return;
    }
    setFVaried(((readU8(data + 16)) & 0x1) != 0);
    setIcrt(readU16(data + 18));
}

void ChartFormatRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(32, 0);
    out.writeUnsigned(32, 0);
    out.writeUnsigned(32, 0);
    out.writeUnsigned(32, 0);
    out.writeUnsigned(1, isFVaried());
    out.writeUnsigned(15, 0);
    out.writeUnsigned(16, icrt());
}

void ChartFormatRecord::dump( std::ostream& out ) const
{
    out << "ChartFormat" << std::endl;
    out << "            FVaried : " << isFVaried() << std::endl;
    out << "               Icrt : " << icrt() << std::endl;
}

static Record* createChartFormatRecord(Swinder::Workbook *book)
{
    return new ChartFormatRecord(book);
}

// ========== LegendRecord ==========

const unsigned LegendRecord::id = 0x1015;

class LegendRecord::Private
{
public:
    unsigned dx;
    unsigned dy;
    bool fAutoPosX;
    bool fAutoPosY;
    bool fAutoPosition;
    bool fVert;
    bool fWasDataTable;
    unsigned unused;
    unsigned wSpace;
    unsigned x;
    unsigned y;
};

LegendRecord::LegendRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setDx(0);
    setDy(0);
    setFAutoPosX(false);
    setFAutoPosY(false);
    setFAutoPosition(false);
    setFVert(false);
    setFWasDataTable(false);
    setUnused(0);
    setWSpace(0);
    setX(0);
    setY(0);
}

LegendRecord::~LegendRecord()
{
    delete d;
}

LegendRecord::LegendRecord( const LegendRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

LegendRecord& LegendRecord::operator=( const LegendRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned LegendRecord::dx() const
{
    return d->dx;
}

void LegendRecord::setDx(unsigned dx )
{
    d->dx = dx;
}

unsigned LegendRecord::dy() const
{
    return d->dy;
}

void LegendRecord::setDy(unsigned dy )
{
    d->dy = dy;
}

bool LegendRecord::isFAutoPosX() const
{
    return d->fAutoPosX;
}

void LegendRecord::setFAutoPosX(bool fAutoPosX )
{
    d->fAutoPosX = fAutoPosX;
}

bool LegendRecord::isFAutoPosY() const
{
    return d->fAutoPosY;
}

void LegendRecord::setFAutoPosY(bool fAutoPosY )
{
    d->fAutoPosY = fAutoPosY;
}

bool LegendRecord::isFAutoPosition() const
{
    return d->fAutoPosition;
}

void LegendRecord::setFAutoPosition(bool fAutoPosition )
{
    d->fAutoPosition = fAutoPosition;
}

bool LegendRecord::isFVert() const
{
    return d->fVert;
}

void LegendRecord::setFVert(bool fVert )
{
    d->fVert = fVert;
}

bool LegendRecord::isFWasDataTable() const
{
    return d->fWasDataTable;
}

void LegendRecord::setFWasDataTable(bool fWasDataTable )
{
    d->fWasDataTable = fWasDataTable;
}

unsigned LegendRecord::unused() const
{
    return d->unused;
}

void LegendRecord::setUnused(unsigned unused )
{
    d->unused = unused;
}

unsigned LegendRecord::wSpace() const
{
    return d->wSpace;
}

void LegendRecord::setWSpace(unsigned wSpace )
{
    d->wSpace = wSpace;
}

unsigned LegendRecord::x() const
{
    return d->x;
}

void LegendRecord::setX(unsigned x )
{
    d->x = x;
}

unsigned LegendRecord::y() const
{
    return d->y;
}

void LegendRecord::setY(unsigned y )
{
    d->y = y;
}

void LegendRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 20) {
        setIsValid(false);
        return;
    }
    setX(readU32(data));
    setY(readU32(data + 4));
    setDx(readU32(data + 8));
    setDy(readU32(data + 12));
    setUnused(readU8(data + 16));
    setWSpace(readU8(data + 17));
    setFAutoPosition(((readU8(data + 18)) & 0x1) != 0);
    setFAutoPosX(((readU8(data + 18) >> 2) & 0x1) != 0);
    setFAutoPosY(((readU8(data + 18) >> 3) & 0x1) != 0);
    setFVert(((readU8(data + 18) >> 4) & 0x1) != 0);
    setFWasDataTable(((readU8(data + 18) >> 5) & 0x1) != 0);
}

void LegendRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(32, x());
    out.writeUnsigned(32, y());
    out.writeUnsigned(32, dx());
    out.writeUnsigned(32, dy());
    out.writeUnsigned(8, unused());
    out.writeUnsigned(8, wSpace());
    out.writeUnsigned(1, isFAutoPosition());
    out.writeUnsigned(1, 0);
    out.writeUnsigned(1, isFAutoPosX());
    out.writeUnsigned(1, isFAutoPosY());
    out.writeUnsigned(1, isFVert());
    out.writeUnsigned(1, isFWasDataTable());
    out.writeUnsigned(10, 0);
}

void LegendRecord::dump( std::ostream& out ) const
{
    out << "Legend" << std::endl;
    out << "                  X : " << x() << std::endl;
    out << "                  Y : " << y() << std::endl;
    out << "                 Dx : " << dx() << std::endl;
    out << "                 Dy : " << dy() << std::endl;
    out << "             Unused : " << unused() << std::endl;
    out << "             WSpace : " << wSpace() << std::endl;
    out << "      FAutoPosition : " << isFAutoPosition() << std::endl;
    out << "          FAutoPosX : " << isFAutoPosX() << std::endl;
    out << "          FAutoPosY : " << isFAutoPosY() << std::endl;
    out << "              FVert : " << isFVert() << std::endl;
    out << "      FWasDataTable : " << isFWasDataTable() << std::endl;
}

static Record* createLegendRecord(Swinder::Workbook *book)
{
    return new LegendRecord(book);
}

// ========== SeriesListRecord ==========

const unsigned SeriesListRecord::id = 0x1016;

class SeriesListRecord::Private
{
public:
    unsigned cser;
    std::vector<unsigned> rgiser;
};

SeriesListRecord::SeriesListRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCser(0);
}

SeriesListRecord::~SeriesListRecord()
{
    delete d;
}

SeriesListRecord::SeriesListRecord( const SeriesListRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

SeriesListRecord& SeriesListRecord::operator=( const SeriesListRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned SeriesListRecord::cser() const
{
    return d->cser;
}

void SeriesListRecord::setCser(unsigned cser )
{
    d->cser = cser;
    d->rgiser.resize(cser);
}

unsigned SeriesListRecord::rgiser( unsigned index ) const
{
    return d->rgiser[index];
}

void SeriesListRecord::setRgiser( unsigned index, unsigned rgiser )
{
    d->rgiser[index] = rgiser;
}

void SeriesListRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    if (size < 2) {
        setIsValid(false);
        return;
    }
    setCser(readU16(data));
    curOffset = 2;
    for (unsigned i = 0, endi = cser(); i < endi; ++i) {
        if (size < curOffset + 2) {
            setIsValid(false);
            return;
        }
        setRgiser(i, readU16(data + curOffset));
        curOffset += 2;
    }
}

void SeriesListRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, cser());
    for (unsigned i = 0, endi = cser(); i < endi; ++i) {
        out.writeUnsigned(16, rgiser(i));
    }
}

void SeriesListRecord::dump( std::ostream& out ) const
{
    out << "SeriesList" << std::endl;
    out << "               Cser : " << cser() << std::endl;
    for (unsigned i = 0, endi = cser(); i < endi; ++i) {
        out << "         Rgiser " << std::setw(3) << i <<" : " << rgiser(i) << std::endl;
    }
}

static Record* createSeriesListRecord(Swinder::Workbook *book)
{
    return new SeriesListRecord(book);
}

// ========== BarRecord ==========

const unsigned BarRecord::id = 0x1017;

class BarRecord::Private
{
public:
    bool f100;
    bool fHasShadow;
    bool fStacked;
    bool fTranspose;
    unsigned pcGap;
    int pcOverlap;
};

BarRecord::BarRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setF100(false);
    setFHasShadow(false);
    setFStacked(false);
    setFTranspose(false);
    setPcGap(0);
    setPcOverlap(0);
}

BarRecord::~BarRecord()
{
    delete d;
}

BarRecord::BarRecord( const BarRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

BarRecord& BarRecord::operator=( const BarRecord& record )
{
    *d = *record.d;
    return *this;
}

bool BarRecord::isF100() const
{
    return d->f100;
}

void BarRecord::setF100(bool f100 )
{
    d->f100 = f100;
}

bool BarRecord::isFHasShadow() const
{
    return d->fHasShadow;
}

void BarRecord::setFHasShadow(bool fHasShadow )
{
    d->fHasShadow = fHasShadow;
}

bool BarRecord::isFStacked() const
{
    return d->fStacked;
}

void BarRecord::setFStacked(bool fStacked )
{
    d->fStacked = fStacked;
}

bool BarRecord::isFTranspose() const
{
    return d->fTranspose;
}

void BarRecord::setFTranspose(bool fTranspose )
{
    d->fTranspose = fTranspose;
}

unsigned BarRecord::pcGap() const
{
    return d->pcGap;
}

void BarRecord::setPcGap(unsigned pcGap )
{
    d->pcGap = pcGap;
}

int BarRecord::pcOverlap() const
{
    return d->pcOverlap;
}

void BarRecord::setPcOverlap(int pcOverlap )
{
    d->pcOverlap = pcOverlap;
}

void BarRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 6) {
        setIsValid(false);
        return;
    }
    setPcOverlap(readS16(data));
    setPcGap(readU16(data + 2));
    setFTranspose(((readU8(data + 4)) & 0x1) != 0);
    setFStacked(((readU8(data + 4) >> 1) & 0x1) != 0);
    setF100(((readU8(data + 4) >> 2) & 0x1) != 0);
    setFHasShadow(((readU8(data + 4) >> 3) & 0x1) != 0);
}

void BarRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeSigned(16, pcOverlap());
    out.writeUnsigned(16, pcGap());
    out.writeUnsigned(1, isFTranspose());
    out.writeUnsigned(1, isFStacked());
    out.writeUnsigned(1, isF100());
    out.writeUnsigned(1, isFHasShadow());
    out.writeUnsigned(12, 0);
}

void BarRecord::dump( std::ostream& out ) const
{
    out << "Bar" << std::endl;
    out << "          PcOverlap : " << pcOverlap() << std::endl;
    out << "              PcGap : " << pcGap() << std::endl;
    out << "         FTranspose : " << isFTranspose() << std::endl;
    out << "           FStacked : " << isFStacked() << std::endl;
    out << "               F100 : " << isF100() << std::endl;
    out << "         FHasShadow : " << isFHasShadow() << std::endl;
}

static Record* createBarRecord(Swinder::Workbook *book)
{
    return new BarRecord(book);
}

// ========== LineRecord ==========

const unsigned LineRecord::id = 0x1018;

class LineRecord::Private
{
public:
    bool f100;
    bool fHasShadow;
    bool fStacked;
};

LineRecord::LineRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setF100(false);
    setFHasShadow(false);
    setFStacked(false);
}

LineRecord::~LineRecord()
{
    delete d;
}

LineRecord::LineRecord( const LineRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

LineRecord& LineRecord::operator=( const LineRecord& record )
{
    *d = *record.d;
    return *this;
}

bool LineRecord::isF100() const
{
    return d->f100;
}

void LineRecord::setF100(bool f100 )
{
    d->f100 = f100;
}

bool LineRecord::isFHasShadow() const
{
    return d->fHasShadow;
}

void LineRecord::setFHasShadow(bool fHasShadow )
{
    d->fHasShadow = fHasShadow;
}

bool LineRecord::isFStacked() const
{
    return d->fStacked;
}

void LineRecord::setFStacked(bool fStacked )
{
    d->fStacked = fStacked;
}

void LineRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setFStacked(((readU8(data)) & 0x1) != 0);
    setF100(((readU8(data) >> 1) & 0x1) != 0);
    setFHasShadow(((readU8(data) >> 2) & 0x1) != 0);
}

void LineRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(1, isFStacked());
    out.writeUnsigned(1, isF100());
    out.writeUnsigned(1, isFHasShadow());
    out.writeUnsigned(13, 0);
}

void LineRecord::dump( std::ostream& out ) const
{
    out << "Line" << std::endl;
    out << "           FStacked : " << isFStacked() << std::endl;
    out << "               F100 : " << isF100() << std::endl;
    out << "         FHasShadow : " << isFHasShadow() << std::endl;
}

static Record* createLineRecord(Swinder::Workbook *book)
{
    return new LineRecord(book);
}

// ========== AreaRecord ==========

const unsigned AreaRecord::id = 0x101a;

class AreaRecord::Private
{
public:
    bool f100;
    bool fHasShadow;
    bool fStacked;
};

AreaRecord::AreaRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setF100(false);
    setFHasShadow(false);
    setFStacked(false);
}

AreaRecord::~AreaRecord()
{
    delete d;
}

AreaRecord::AreaRecord( const AreaRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

AreaRecord& AreaRecord::operator=( const AreaRecord& record )
{
    *d = *record.d;
    return *this;
}

bool AreaRecord::isF100() const
{
    return d->f100;
}

void AreaRecord::setF100(bool f100 )
{
    d->f100 = f100;
}

bool AreaRecord::isFHasShadow() const
{
    return d->fHasShadow;
}

void AreaRecord::setFHasShadow(bool fHasShadow )
{
    d->fHasShadow = fHasShadow;
}

bool AreaRecord::isFStacked() const
{
    return d->fStacked;
}

void AreaRecord::setFStacked(bool fStacked )
{
    d->fStacked = fStacked;
}

void AreaRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setFStacked(((readU8(data)) & 0x1) != 0);
    setF100(((readU8(data) >> 1) & 0x1) != 0);
    setFHasShadow(((readU8(data) >> 2) & 0x1) != 0);
}

void AreaRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(1, isFStacked());
    out.writeUnsigned(1, isF100());
    out.writeUnsigned(1, isFHasShadow());
    out.writeUnsigned(13, 0);
}

void AreaRecord::dump( std::ostream& out ) const
{
    out << "Area" << std::endl;
    out << "           FStacked : " << isFStacked() << std::endl;
    out << "               F100 : " << isF100() << std::endl;
    out << "         FHasShadow : " << isFHasShadow() << std::endl;
}

static Record* createAreaRecord(Swinder::Workbook *book)
{
    return new AreaRecord(book);
}

// ========== ScatterRecord ==========

const unsigned ScatterRecord::id = 0x101b;

class ScatterRecord::Private
{
public:
    bool fBubbles;
    bool fHasShadow;
    bool fShowNegBubbles;
    unsigned pcBubbleSizeRatio;
    unsigned wBubbleSize;
};

ScatterRecord::ScatterRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFBubbles(false);
    setFHasShadow(false);
    setFShowNegBubbles(false);
    setPcBubbleSizeRatio(0);
    setWBubbleSize(0);
}

ScatterRecord::~ScatterRecord()
{
    delete d;
}

ScatterRecord::ScatterRecord( const ScatterRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ScatterRecord& ScatterRecord::operator=( const ScatterRecord& record )
{
    *d = *record.d;
    return *this;
}

bool ScatterRecord::isFBubbles() const
{
    return d->fBubbles;
}

void ScatterRecord::setFBubbles(bool fBubbles )
{
    d->fBubbles = fBubbles;
}

bool ScatterRecord::isFHasShadow() const
{
    return d->fHasShadow;
}

void ScatterRecord::setFHasShadow(bool fHasShadow )
{
    d->fHasShadow = fHasShadow;
}

bool ScatterRecord::isFShowNegBubbles() const
{
    return d->fShowNegBubbles;
}

void ScatterRecord::setFShowNegBubbles(bool fShowNegBubbles )
{
    d->fShowNegBubbles = fShowNegBubbles;
}

unsigned ScatterRecord::pcBubbleSizeRatio() const
{
    return d->pcBubbleSizeRatio;
}

void ScatterRecord::setPcBubbleSizeRatio(unsigned pcBubbleSizeRatio )
{
    d->pcBubbleSizeRatio = pcBubbleSizeRatio;
}

unsigned ScatterRecord::wBubbleSize() const
{
    return d->wBubbleSize;
}

void ScatterRecord::setWBubbleSize(unsigned wBubbleSize )
{
    d->wBubbleSize = wBubbleSize;
}

void ScatterRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 6) {
        setIsValid(false);
        return;
    }
    setPcBubbleSizeRatio(readU16(data));
    setWBubbleSize(readU16(data + 2));
    setFBubbles(((readU8(data + 4)) & 0x1) != 0);
    setFShowNegBubbles(((readU8(data + 4) >> 1) & 0x1) != 0);
    setFHasShadow(((readU8(data + 4) >> 2) & 0x1) != 0);
}

void ScatterRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, pcBubbleSizeRatio());
    out.writeUnsigned(16, wBubbleSize());
    out.writeUnsigned(1, isFBubbles());
    out.writeUnsigned(1, isFShowNegBubbles());
    out.writeUnsigned(1, isFHasShadow());
    out.writeUnsigned(13, 0);
}

void ScatterRecord::dump( std::ostream& out ) const
{
    out << "Scatter" << std::endl;
    out << "  PcBubbleSizeRatio : " << pcBubbleSizeRatio() << std::endl;
    out << "        WBubbleSize : " << wBubbleSize() << std::endl;
    out << "           FBubbles : " << isFBubbles() << std::endl;
    out << "    FShowNegBubbles : " << isFShowNegBubbles() << std::endl;
    out << "         FHasShadow : " << isFHasShadow() << std::endl;
}

static Record* createScatterRecord(Swinder::Workbook *book)
{
    return new ScatterRecord(book);
}

// ========== AxisRecord ==========

const unsigned AxisRecord::id = 0x101d;

class AxisRecord::Private
{
public:
    unsigned wType;
};

AxisRecord::AxisRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setWType(0);
}

AxisRecord::~AxisRecord()
{
    delete d;
}

AxisRecord::AxisRecord( const AxisRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

AxisRecord& AxisRecord::operator=( const AxisRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned AxisRecord::wType() const
{
    return d->wType;
}

void AxisRecord::setWType(unsigned wType )
{
    d->wType = wType;
}

void AxisRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setWType(readU16(data));
}

void AxisRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, wType());
}

void AxisRecord::dump( std::ostream& out ) const
{
    out << "Axis" << std::endl;
    out << "              WType : " << wType() << std::endl;
}

static Record* createAxisRecord(Swinder::Workbook *book)
{
    return new AxisRecord(book);
}

// ========== TickRecord ==========

const unsigned TickRecord::id = 0x101e;

class TickRecord::Private
{
public:
    unsigned blue;
    bool fAutoCo;
    bool fAutoMode;
    bool fAutoRot;
    unsigned green;
    unsigned iReadingOrder;
    unsigned icv;
    unsigned red;
    unsigned rot;
    unsigned tktMajor;
    unsigned tktMinor;
    unsigned tlt;
    unsigned trot;
    unsigned unused;
    unsigned wBkgMode;
};

TickRecord::TickRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setBlue(0);
    setFAutoCo(false);
    setFAutoMode(false);
    setFAutoRot(false);
    setGreen(0);
    setIReadingOrder(0);
    setIcv(0);
    setRed(0);
    setRot(0);
    setTktMajor(0);
    setTktMinor(0);
    setTlt(0);
    setTrot(0);
    setUnused(0);
    setWBkgMode(0);
}

TickRecord::~TickRecord()
{
    delete d;
}

TickRecord::TickRecord( const TickRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

TickRecord& TickRecord::operator=( const TickRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned TickRecord::blue() const
{
    return d->blue;
}

void TickRecord::setBlue(unsigned blue )
{
    d->blue = blue;
}

bool TickRecord::isFAutoCo() const
{
    return d->fAutoCo;
}

void TickRecord::setFAutoCo(bool fAutoCo )
{
    d->fAutoCo = fAutoCo;
}

bool TickRecord::isFAutoMode() const
{
    return d->fAutoMode;
}

void TickRecord::setFAutoMode(bool fAutoMode )
{
    d->fAutoMode = fAutoMode;
}

bool TickRecord::isFAutoRot() const
{
    return d->fAutoRot;
}

void TickRecord::setFAutoRot(bool fAutoRot )
{
    d->fAutoRot = fAutoRot;
}

unsigned TickRecord::green() const
{
    return d->green;
}

void TickRecord::setGreen(unsigned green )
{
    d->green = green;
}

unsigned TickRecord::iReadingOrder() const
{
    return d->iReadingOrder;
}

void TickRecord::setIReadingOrder(unsigned iReadingOrder )
{
    d->iReadingOrder = iReadingOrder;
}

unsigned TickRecord::icv() const
{
    return d->icv;
}

void TickRecord::setIcv(unsigned icv )
{
    d->icv = icv;
}

unsigned TickRecord::red() const
{
    return d->red;
}

void TickRecord::setRed(unsigned red )
{
    d->red = red;
}

unsigned TickRecord::rot() const
{
    return d->rot;
}

void TickRecord::setRot(unsigned rot )
{
    d->rot = rot;
}

unsigned TickRecord::tktMajor() const
{
    return d->tktMajor;
}

void TickRecord::setTktMajor(unsigned tktMajor )
{
    d->tktMajor = tktMajor;
}

unsigned TickRecord::tktMinor() const
{
    return d->tktMinor;
}

void TickRecord::setTktMinor(unsigned tktMinor )
{
    d->tktMinor = tktMinor;
}

unsigned TickRecord::tlt() const
{
    return d->tlt;
}

void TickRecord::setTlt(unsigned tlt )
{
    d->tlt = tlt;
}

unsigned TickRecord::trot() const
{
    return d->trot;
}

void TickRecord::setTrot(unsigned trot )
{
    d->trot = trot;
}

unsigned TickRecord::unused() const
{
    return d->unused;
}

void TickRecord::setUnused(unsigned unused )
{
    d->unused = unused;
}

unsigned TickRecord::wBkgMode() const
{
    return d->wBkgMode;
}

void TickRecord::setWBkgMode(unsigned wBkgMode )
{
    d->wBkgMode = wBkgMode;
}

void TickRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 30) {
        setIsValid(false);
        return;
    }
    setTktMajor(readU8(data));
    setTktMinor(readU8(data + 1));
    setTlt(readU8(data + 2));
    setWBkgMode(readU8(data + 3));
    setRed(readU8(data + 4));
    setGreen(readU8(data + 5));
    setBlue(readU8(data + 6));
    setFAutoCo(((readU8(data + 24)) & 0x1) != 0);
    setFAutoMode(((readU8(data + 24) >> 1) & 0x1) != 0);
    setRot(((readU8(data + 24) >> 2) & 0x7));
    setFAutoRot(((readU8(data + 24) >> 5) & 0x1) != 0);
    setUnused(readU8(data + 24));
    setIReadingOrder(((readU8(data + 25) >> 6) & 0x3));
    setIcv(readU16(data + 26));
    setTrot(readU16(data + 28));
}

void TickRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(8, tktMajor());
    out.writeUnsigned(8, tktMinor());
    out.writeUnsigned(8, tlt());
    out.writeUnsigned(8, wBkgMode());
    out.writeUnsigned(8, red());
    out.writeUnsigned(8, green());
    out.writeUnsigned(8, blue());
    out.writeUnsigned(8, 0);
    out.writeUnsigned(32, 0);
    out.writeUnsigned(32, 0);
    out.writeUnsigned(32, 0);
    out.writeUnsigned(32, 0);
    out.writeUnsigned(1, isFAutoCo());
    out.writeUnsigned(1, isFAutoMode());
    out.writeUnsigned(3, rot());
    out.writeUnsigned(1, isFAutoRot());
    out.writeUnsigned(8, unused());
    out.writeUnsigned(2, iReadingOrder());
    out.writeUnsigned(16, icv());
    out.writeUnsigned(16, trot());
}

void TickRecord::dump( std::ostream& out ) const
{
    out << "Tick" << std::endl;
    out << "           TktMajor : " << tktMajor() << std::endl;
    out << "           TktMinor : " << tktMinor() << std::endl;
    out << "                Tlt : " << tlt() << std::endl;
    out << "           WBkgMode : " << wBkgMode() << std::endl;
    out << "                Red : " << red() << std::endl;
    out << "              Green : " << green() << std::endl;
    out << "               Blue : " << blue() << std::endl;
    out << "            FAutoCo : " << isFAutoCo() << std::endl;
    out << "          FAutoMode : " << isFAutoMode() << std::endl;
    out << "                Rot : " << rot() << std::endl;
    out << "           FAutoRot : " << isFAutoRot() << std::endl;
    out << "             Unused : " << unused() << std::endl;
    out << "      IReadingOrder : " << iReadingOrder() << std::endl;
    out << "                Icv : " << icv() << std::endl;
    out << "               Trot : " << trot() << std::endl;
}

static Record* createTickRecord(Swinder::Workbook *book)
{
    return new TickRecord(book);
}

// ========== ValueRangeRecord ==========

const unsigned ValueRangeRecord::id = 0x101f;

class ValueRangeRecord::Private
{
public:
    bool fAutoCross;
    bool fAutoMajor;
    bool fAutoMax;
    bool fAutoMin;
    bool fAutoMinor;
    bool fLog;
    bool fMaxCross;
    bool fReversed;
    double numCross;
    double numMajor;
    double numMax;
    double numMin;
    double numMinor;
};

ValueRangeRecord::ValueRangeRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFAutoCross(false);
    setFAutoMajor(false);
    setFAutoMax(false);
    setFAutoMin(false);
    setFAutoMinor(false);
    setFLog(false);
    setFMaxCross(false);
    setFReversed(false);
}

ValueRangeRecord::~ValueRangeRecord()
{
    delete d;
}

ValueRangeRecord::ValueRangeRecord( const ValueRangeRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ValueRangeRecord& ValueRangeRecord::operator=( const ValueRangeRecord& record )
{
    *d = *record.d;
    return *this;
}

bool ValueRangeRecord::isFAutoCross() const
{
    return d->fAutoCross;
}

void ValueRangeRecord::setFAutoCross(bool fAutoCross )
{
    d->fAutoCross = fAutoCross;
}

bool ValueRangeRecord::isFAutoMajor() const
{
    return d->fAutoMajor;
}

void ValueRangeRecord::setFAutoMajor(bool fAutoMajor )
{
    d->fAutoMajor = fAutoMajor;
}

bool ValueRangeRecord::isFAutoMax() const
{
    return d->fAutoMax;
}

void ValueRangeRecord::setFAutoMax(bool fAutoMax )
{
    d->fAutoMax = fAutoMax;
}

bool ValueRangeRecord::isFAutoMin() const
{
    return d->fAutoMin;
}

void ValueRangeRecord::setFAutoMin(bool fAutoMin )
{
    d->fAutoMin = fAutoMin;
}

bool ValueRangeRecord::isFAutoMinor() const
{
    return d->fAutoMinor;
}

void ValueRangeRecord::setFAutoMinor(bool fAutoMinor )
{
    d->fAutoMinor = fAutoMinor;
}

bool ValueRangeRecord::isFLog() const
{
    return d->fLog;
}

void ValueRangeRecord::setFLog(bool fLog )
{
    d->fLog = fLog;
}

bool ValueRangeRecord::isFMaxCross() const
{
    return d->fMaxCross;
}

void ValueRangeRecord::setFMaxCross(bool fMaxCross )
{
    d->fMaxCross = fMaxCross;
}

bool ValueRangeRecord::isFReversed() const
{
    return d->fReversed;
}

void ValueRangeRecord::setFReversed(bool fReversed )
{
    d->fReversed = fReversed;
}

double ValueRangeRecord::numCross() const
{
    return d->numCross;
}

void ValueRangeRecord::setNumCross(double numCross )
{
    d->numCross = numCross;
}

double ValueRangeRecord::numMajor() const
{
    return d->numMajor;
}

void ValueRangeRecord::setNumMajor(double numMajor )
{
    d->numMajor = numMajor;
}

double ValueRangeRecord::numMax() const
{
    return d->numMax;
}

void ValueRangeRecord::setNumMax(double numMax )
{
    d->numMax = numMax;
}

double ValueRangeRecord::numMin() const
{
    return d->numMin;
}

void ValueRangeRecord::setNumMin(double numMin )
{
    d->numMin = numMin;
}

double ValueRangeRecord::numMinor() const
{
    return d->numMinor;
}

void ValueRangeRecord::setNumMinor(double numMinor )
{
    d->numMinor = numMinor;
}

void ValueRangeRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 41) {
        setIsValid(false);
        return;
    }
    setNumMin(readFloat64(data));
    setNumMax(readFloat64(data + 8));
    setNumMajor(readFloat64(data + 16));
    setNumMinor(readFloat64(data + 24));
    setNumCross(readFloat64(data + 32));
    setFAutoMin(((readU8(data + 40)) & 0x1) != 0);
    setFAutoMax(((readU8(data + 40) >> 1) & 0x1) != 0);
    setFAutoMajor(((readU8(data + 40) >> 2) & 0x1) != 0);
    setFAutoMinor(((readU8(data + 40) >> 3) & 0x1) != 0);
    setFAutoCross(((readU8(data + 40) >> 4) & 0x1) != 0);
    setFLog(((readU8(data + 40) >> 5) & 0x1) != 0);
    setFReversed(((readU8(data + 40) >> 6) & 0x1) != 0);
    setFMaxCross(((readU8(data + 40) >> 7) & 0x1) != 0);
}

void ValueRangeRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeFloat(64, numMin());
    out.writeFloat(64, numMax());
    out.writeFloat(64, numMajor());
    out.writeFloat(64, numMinor());
    out.writeFloat(64, numCross());
    out.writeUnsigned(1, isFAutoMin());
    out.writeUnsigned(1, isFAutoMax());
    out.writeUnsigned(1, isFAutoMajor());
    out.writeUnsigned(1, isFAutoMinor());
    out.writeUnsigned(1, isFAutoCross());
    out.writeUnsigned(1, isFLog());
    out.writeUnsigned(1, isFReversed());
    out.writeUnsigned(1, isFMaxCross());
}

void ValueRangeRecord::dump( std::ostream& out ) const
{
    out << "ValueRange" << std::endl;
    out << "             NumMin : " << numMin() << std::endl;
    out << "             NumMax : " << numMax() << std::endl;
    out << "           NumMajor : " << numMajor() << std::endl;
    out << "           NumMinor : " << numMinor() << std::endl;
    out << "           NumCross : " << numCross() << std::endl;
    out << "           FAutoMin : " << isFAutoMin() << std::endl;
    out << "           FAutoMax : " << isFAutoMax() << std::endl;
    out << "         FAutoMajor : " << isFAutoMajor() << std::endl;
    out << "         FAutoMinor : " << isFAutoMinor() << std::endl;
    out << "         FAutoCross : " << isFAutoCross() << std::endl;
    out << "               FLog : " << isFLog() << std::endl;
    out << "          FReversed : " << isFReversed() << std::endl;
    out << "          FMaxCross : " << isFMaxCross() << std::endl;
}

static Record* createValueRangeRecord(Swinder::Workbook *book)
{
    return new ValueRangeRecord(book);
}

// ========== CatSerRangeRecord ==========

const unsigned CatSerRangeRecord::id = 0x1020;

class CatSerRangeRecord::Private
{
public:
    unsigned catCross;
    unsigned catLabel;
    unsigned catMark;
    bool fBetween;
    bool fMaxCross;
    bool fReverse;
};

CatSerRangeRecord::CatSerRangeRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCatCross(0);
    setCatLabel(0);
    setCatMark(0);
    setFBetween(false);
    setFMaxCross(false);
    setFReverse(false);
}

CatSerRangeRecord::~CatSerRangeRecord()
{
    delete d;
}

CatSerRangeRecord::CatSerRangeRecord( const CatSerRangeRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

CatSerRangeRecord& CatSerRangeRecord::operator=( const CatSerRangeRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned CatSerRangeRecord::catCross() const
{
    return d->catCross;
}

void CatSerRangeRecord::setCatCross(unsigned catCross )
{
    d->catCross = catCross;
}

unsigned CatSerRangeRecord::catLabel() const
{
    return d->catLabel;
}

void CatSerRangeRecord::setCatLabel(unsigned catLabel )
{
    d->catLabel = catLabel;
}

unsigned CatSerRangeRecord::catMark() const
{
    return d->catMark;
}

void CatSerRangeRecord::setCatMark(unsigned catMark )
{
    d->catMark = catMark;
}

bool CatSerRangeRecord::isFBetween() const
{
    return d->fBetween;
}

void CatSerRangeRecord::setFBetween(bool fBetween )
{
    d->fBetween = fBetween;
}

bool CatSerRangeRecord::isFMaxCross() const
{
    return d->fMaxCross;
}

void CatSerRangeRecord::setFMaxCross(bool fMaxCross )
{
    d->fMaxCross = fMaxCross;
}

bool CatSerRangeRecord::isFReverse() const
{
    return d->fReverse;
}

void CatSerRangeRecord::setFReverse(bool fReverse )
{
    d->fReverse = fReverse;
}

void CatSerRangeRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 8) {
        setIsValid(false);
        return;
    }
    setCatCross(readU16(data));
    setCatLabel(readU16(data + 2));
    setCatMark(readU16(data + 4));
    setFBetween(((readU8(data + 6)) & 0x1) != 0);
    setFMaxCross(((readU8(data + 6) >> 1) & 0x1) != 0);
    setFReverse(((readU8(data + 6) >> 2) & 0x1) != 0);
}

void CatSerRangeRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, catCross());
    out.writeUnsigned(16, catLabel());
    out.writeUnsigned(16, catMark());
    out.writeUnsigned(1, isFBetween());
    out.writeUnsigned(1, isFMaxCross());
    out.writeUnsigned(1, isFReverse());
    out.writeUnsigned(13, 0);
}

void CatSerRangeRecord::dump( std::ostream& out ) const
{
    out << "CatSerRange" << std::endl;
    out << "           CatCross : " << catCross() << std::endl;
    out << "           CatLabel : " << catLabel() << std::endl;
    out << "            CatMark : " << catMark() << std::endl;
    out << "           FBetween : " << isFBetween() << std::endl;
    out << "          FMaxCross : " << isFMaxCross() << std::endl;
    out << "           FReverse : " << isFReverse() << std::endl;
}

static Record* createCatSerRangeRecord(Swinder::Workbook *book)
{
    return new CatSerRangeRecord(book);
}

// ========== CrtLayout12Record ==========

const unsigned CrtLayout12Record::id = 0x89D;

class CrtLayout12Record::Private
{
public:
};

CrtLayout12Record::CrtLayout12Record(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

CrtLayout12Record::~CrtLayout12Record()
{
    delete d;
}

CrtLayout12Record::CrtLayout12Record( const CrtLayout12Record& record )
    : Record(record), d(new Private)
{
    *this = record;
}

CrtLayout12Record& CrtLayout12Record::operator=( const CrtLayout12Record& record )
{
    *d = *record.d;
    return *this;
}

void CrtLayout12Record::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void CrtLayout12Record::writeData( XlsRecordOutputStream& ) const
{
}

void CrtLayout12Record::dump( std::ostream& out ) const
{
    out << "CrtLayout12" << std::endl;
}

static Record* createCrtLayout12Record(Swinder::Workbook *book)
{
    return new CrtLayout12Record(book);
}

// ========== CatLabRecord ==========

const unsigned CatLabRecord::id = 0x856;

class CatLabRecord::Private
{
public:
    unsigned at;
    unsigned cAutoCatLabelReal;
    unsigned grbitFrt;
    unsigned rt;
    unsigned wOffset;
};

CatLabRecord::CatLabRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setAt(0);
    setCAutoCatLabelReal(0);
    setGrbitFrt(0);
    setRt(0);
    setWOffset(0);
}

CatLabRecord::~CatLabRecord()
{
    delete d;
}

CatLabRecord::CatLabRecord( const CatLabRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

CatLabRecord& CatLabRecord::operator=( const CatLabRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned CatLabRecord::at() const
{
    return d->at;
}

void CatLabRecord::setAt(unsigned at )
{
    d->at = at;
}

unsigned CatLabRecord::cAutoCatLabelReal() const
{
    return d->cAutoCatLabelReal;
}

void CatLabRecord::setCAutoCatLabelReal(unsigned cAutoCatLabelReal )
{
    d->cAutoCatLabelReal = cAutoCatLabelReal;
}

unsigned CatLabRecord::grbitFrt() const
{
    return d->grbitFrt;
}

void CatLabRecord::setGrbitFrt(unsigned grbitFrt )
{
    d->grbitFrt = grbitFrt;
}

unsigned CatLabRecord::rt() const
{
    return d->rt;
}

void CatLabRecord::setRt(unsigned rt )
{
    d->rt = rt;
}

unsigned CatLabRecord::wOffset() const
{
    return d->wOffset;
}

void CatLabRecord::setWOffset(unsigned wOffset )
{
    d->wOffset = wOffset;
}

void CatLabRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 10) {
        setIsValid(false);
        return;
    }
    setRt(readU16(data));
    setGrbitFrt(readU16(data + 2));
    setWOffset(readU16(data + 4));
    setAt(readU16(data + 6));
    setCAutoCatLabelReal(((readU8(data + 8)) & 0x1));
}

void CatLabRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, rt());
    out.writeUnsigned(16, grbitFrt());
    out.writeUnsigned(16, wOffset());
    out.writeUnsigned(16, at());
    out.writeUnsigned(1, cAutoCatLabelReal());
    out.writeUnsigned(15, 0);
}

void CatLabRecord::dump( std::ostream& out ) const
{
    out << "CatLab" << std::endl;
    out << "                 Rt : " << rt() << std::endl;
    out << "           GrbitFrt : " << grbitFrt() << std::endl;
    out << "            WOffset : " << wOffset() << std::endl;
    out << "                 At : " << at() << std::endl;
    out << "  CAutoCatLabelReal : " << cAutoCatLabelReal() << std::endl;
}

static Record* createCatLabRecord(Swinder::Workbook *book)
{
    return new CatLabRecord(book);
}

// ========== AxisLineRecord ==========

const unsigned AxisLineRecord::id = 0x1021;

class AxisLineRecord::Private
{
public:
    Identifier identifier;
};

AxisLineRecord::AxisLineRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setIdentifier(AxisItself);
}

AxisLineRecord::~AxisLineRecord()
{
    delete d;
}

AxisLineRecord::AxisLineRecord( const AxisLineRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

AxisLineRecord& AxisLineRecord::operator=( const AxisLineRecord& record )
{
    *d = *record.d;
    return *this;
}

QString AxisLineRecord::identifierToString(Identifier identifier)
{
    switch (identifier) {
        case AxisItself: return QString("AxisItself");
        case MajorGridlinesAlongTheAxis: return QString("MajorGridlinesAlongTheAxis");
        case MinorGridlinesAlongTheAxis: return QString("MinorGridlinesAlongTheAxis");
        case WallsAndFloorsOf3DChart: return QString("WallsAndFloorsOf3DChart");
        default: return QString("Unknown: %1").arg(identifier);
    }
}

AxisLineRecord::Identifier AxisLineRecord::identifier() const
{
    return d->identifier;
}

void AxisLineRecord::setIdentifier(Identifier identifier )
{
    d->identifier = identifier;
}

void AxisLineRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setIdentifier(static_cast<Identifier>(readU16(data)));
}

void AxisLineRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, identifier());
}

void AxisLineRecord::dump( std::ostream& out ) const
{
    out << "AxisLine" << std::endl;
    out << "         Identifier : " << identifierToString(identifier()) << std::endl;
}

static Record* createAxisLineRecord(Swinder::Workbook *book)
{
    return new AxisLineRecord(book);
}

// ========== CrtLinkRecord ==========

const unsigned CrtLinkRecord::id = 0x1022;

class CrtLinkRecord::Private
{
public:
};

CrtLinkRecord::CrtLinkRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

CrtLinkRecord::~CrtLinkRecord()
{
    delete d;
}

CrtLinkRecord::CrtLinkRecord( const CrtLinkRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

CrtLinkRecord& CrtLinkRecord::operator=( const CrtLinkRecord& record )
{
    *d = *record.d;
    return *this;
}

void CrtLinkRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void CrtLinkRecord::writeData( XlsRecordOutputStream& ) const
{
}

void CrtLinkRecord::dump( std::ostream& out ) const
{
    out << "CrtLink" << std::endl;
}

static Record* createCrtLinkRecord(Swinder::Workbook *book)
{
    return new CrtLinkRecord(book);
}

// ========== DefaultTextRecord ==========

const unsigned DefaultTextRecord::id = 0x1024;

class DefaultTextRecord::Private
{
public:
    Identifier identifier;
};

DefaultTextRecord::DefaultTextRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setIdentifier(ShowPercent0_or_ShowValue0);
}

DefaultTextRecord::~DefaultTextRecord()
{
    delete d;
}

DefaultTextRecord::DefaultTextRecord( const DefaultTextRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

DefaultTextRecord& DefaultTextRecord::operator=( const DefaultTextRecord& record )
{
    *d = *record.d;
    return *this;
}

QString DefaultTextRecord::identifierToString(Identifier identifier)
{
    switch (identifier) {
        case ShowPercent0_or_ShowValue0: return QString("ShowPercent0_or_ShowValue0");
        case ShowPercent1_or_ShowValue1: return QString("ShowPercent1_or_ShowValue1");
        case Scalable0: return QString("Scalable0");
        case Scalable1: return QString("Scalable1");
        default: return QString("Unknown: %1").arg(identifier);
    }
}

DefaultTextRecord::Identifier DefaultTextRecord::identifier() const
{
    return d->identifier;
}

void DefaultTextRecord::setIdentifier(Identifier identifier )
{
    d->identifier = identifier;
}

void DefaultTextRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setIdentifier(static_cast<Identifier>(readU16(data)));
}

void DefaultTextRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, identifier());
}

void DefaultTextRecord::dump( std::ostream& out ) const
{
    out << "DefaultText" << std::endl;
    out << "         Identifier : " << identifierToString(identifier()) << std::endl;
}

static Record* createDefaultTextRecord(Swinder::Workbook *book)
{
    return new DefaultTextRecord(book);
}

// ========== TextRecord ==========

const unsigned TextRecord::id = 0x1025;

class TextRecord::Private
{
public:
    unsigned at;
    unsigned dx;
    unsigned dy;
    bool fAutoColor;
    bool fAutoMode;
    bool fAutoText;
    bool fDeleted;
    bool fGenerated;
    bool fShowBubbleSizes;
    bool fShowKey;
    bool fShowLabel;
    bool fShowLabelAndPerc;
    bool fShowPercent;
    bool fShowValue;
    unsigned icvText;
    unsigned rgbText;
    unsigned unused1;
    unsigned unused2;
    unsigned vat;
    unsigned wBkgMode;
    unsigned x;
    unsigned y;
};

TextRecord::TextRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setAt(0);
    setDx(0);
    setDy(0);
    setFAutoColor(false);
    setFAutoMode(false);
    setFAutoText(false);
    setFDeleted(false);
    setFGenerated(false);
    setFShowBubbleSizes(false);
    setFShowKey(false);
    setFShowLabel(false);
    setFShowLabelAndPerc(false);
    setFShowPercent(false);
    setFShowValue(false);
    setIcvText(0);
    setRgbText(0);
    setUnused1(0);
    setUnused2(0);
    setVat(0);
    setWBkgMode(0);
    setX(0);
    setY(0);
}

TextRecord::~TextRecord()
{
    delete d;
}

TextRecord::TextRecord( const TextRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

TextRecord& TextRecord::operator=( const TextRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned TextRecord::at() const
{
    return d->at;
}

void TextRecord::setAt(unsigned at )
{
    d->at = at;
}

unsigned TextRecord::dx() const
{
    return d->dx;
}

void TextRecord::setDx(unsigned dx )
{
    d->dx = dx;
}

unsigned TextRecord::dy() const
{
    return d->dy;
}

void TextRecord::setDy(unsigned dy )
{
    d->dy = dy;
}

bool TextRecord::isFAutoColor() const
{
    return d->fAutoColor;
}

void TextRecord::setFAutoColor(bool fAutoColor )
{
    d->fAutoColor = fAutoColor;
}

bool TextRecord::isFAutoMode() const
{
    return d->fAutoMode;
}

void TextRecord::setFAutoMode(bool fAutoMode )
{
    d->fAutoMode = fAutoMode;
}

bool TextRecord::isFAutoText() const
{
    return d->fAutoText;
}

void TextRecord::setFAutoText(bool fAutoText )
{
    d->fAutoText = fAutoText;
}

bool TextRecord::isFDeleted() const
{
    return d->fDeleted;
}

void TextRecord::setFDeleted(bool fDeleted )
{
    d->fDeleted = fDeleted;
}

bool TextRecord::isFGenerated() const
{
    return d->fGenerated;
}

void TextRecord::setFGenerated(bool fGenerated )
{
    d->fGenerated = fGenerated;
}

bool TextRecord::isFShowBubbleSizes() const
{
    return d->fShowBubbleSizes;
}

void TextRecord::setFShowBubbleSizes(bool fShowBubbleSizes )
{
    d->fShowBubbleSizes = fShowBubbleSizes;
}

bool TextRecord::isFShowKey() const
{
    return d->fShowKey;
}

void TextRecord::setFShowKey(bool fShowKey )
{
    d->fShowKey = fShowKey;
}

bool TextRecord::isFShowLabel() const
{
    return d->fShowLabel;
}

void TextRecord::setFShowLabel(bool fShowLabel )
{
    d->fShowLabel = fShowLabel;
}

bool TextRecord::isFShowLabelAndPerc() const
{
    return d->fShowLabelAndPerc;
}

void TextRecord::setFShowLabelAndPerc(bool fShowLabelAndPerc )
{
    d->fShowLabelAndPerc = fShowLabelAndPerc;
}

bool TextRecord::isFShowPercent() const
{
    return d->fShowPercent;
}

void TextRecord::setFShowPercent(bool fShowPercent )
{
    d->fShowPercent = fShowPercent;
}

bool TextRecord::isFShowValue() const
{
    return d->fShowValue;
}

void TextRecord::setFShowValue(bool fShowValue )
{
    d->fShowValue = fShowValue;
}

unsigned TextRecord::icvText() const
{
    return d->icvText;
}

void TextRecord::setIcvText(unsigned icvText )
{
    d->icvText = icvText;
}

unsigned TextRecord::rgbText() const
{
    return d->rgbText;
}

void TextRecord::setRgbText(unsigned rgbText )
{
    d->rgbText = rgbText;
}

unsigned TextRecord::unused1() const
{
    return d->unused1;
}

void TextRecord::setUnused1(unsigned unused1 )
{
    d->unused1 = unused1;
}

unsigned TextRecord::unused2() const
{
    return d->unused2;
}

void TextRecord::setUnused2(unsigned unused2 )
{
    d->unused2 = unused2;
}

unsigned TextRecord::vat() const
{
    return d->vat;
}

void TextRecord::setVat(unsigned vat )
{
    d->vat = vat;
}

unsigned TextRecord::wBkgMode() const
{
    return d->wBkgMode;
}

void TextRecord::setWBkgMode(unsigned wBkgMode )
{
    d->wBkgMode = wBkgMode;
}

unsigned TextRecord::x() const
{
    return d->x;
}

void TextRecord::setX(unsigned x )
{
    d->x = x;
}

unsigned TextRecord::y() const
{
    return d->y;
}

void TextRecord::setY(unsigned y )
{
    d->y = y;
}

void TextRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 28) {
        setIsValid(false);
        return;
    }
    setAt(readU8(data));
    setVat(readU8(data + 1));
    setWBkgMode(readU16(data + 2));
    setRgbText(readU32(data + 4));
    setX(readU32(data + 8));
    setY(readU32(data + 12));
    setDx(readU32(data + 16));
    setDy(readU32(data + 20));
    setFAutoColor(((readU8(data + 24)) & 0x1) != 0);
    setFShowKey(((readU8(data + 24) >> 1) & 0x1) != 0);
    setFShowValue(((readU8(data + 24) >> 2) & 0x1) != 0);
    setUnused1(((readU8(data + 24) >> 3) & 0x1));
    setFAutoText(((readU8(data + 24) >> 4) & 0x1) != 0);
    setFGenerated(((readU8(data + 24) >> 5) & 0x1) != 0);
    setFDeleted(((readU8(data + 24) >> 6) & 0x1) != 0);
    setFAutoMode(((readU8(data + 24) >> 7) & 0x1) != 0);
    setUnused2(((readU8(data + 25)) & 0x7));
    setFShowLabelAndPerc(((readU8(data + 25) >> 3) & 0x1) != 0);
    setFShowPercent(((readU8(data + 25) >> 4) & 0x1) != 0);
    setFShowBubbleSizes(((readU8(data + 25) >> 5) & 0x1) != 0);
    setFShowLabel(((readU8(data + 25) >> 6) & 0x1) != 0);
    setIcvText(readU16(data + 26));
}

void TextRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(8, at());
    out.writeUnsigned(8, vat());
    out.writeUnsigned(16, wBkgMode());
    out.writeUnsigned(32, rgbText());
    out.writeUnsigned(32, x());
    out.writeUnsigned(32, y());
    out.writeUnsigned(32, dx());
    out.writeUnsigned(32, dy());
    out.writeUnsigned(1, isFAutoColor());
    out.writeUnsigned(1, isFShowKey());
    out.writeUnsigned(1, isFShowValue());
    out.writeUnsigned(1, unused1());
    out.writeUnsigned(1, isFAutoText());
    out.writeUnsigned(1, isFGenerated());
    out.writeUnsigned(1, isFDeleted());
    out.writeUnsigned(1, isFAutoMode());
    out.writeUnsigned(3, unused2());
    out.writeUnsigned(1, isFShowLabelAndPerc());
    out.writeUnsigned(1, isFShowPercent());
    out.writeUnsigned(1, isFShowBubbleSizes());
    out.writeUnsigned(1, isFShowLabel());
    out.writeUnsigned(1, 0);
    out.writeUnsigned(16, icvText());
}

void TextRecord::dump( std::ostream& out ) const
{
    out << "Text" << std::endl;
    out << "                 At : " << at() << std::endl;
    out << "                Vat : " << vat() << std::endl;
    out << "           WBkgMode : " << wBkgMode() << std::endl;
    out << "            RgbText : " << rgbText() << std::endl;
    out << "                  X : " << x() << std::endl;
    out << "                  Y : " << y() << std::endl;
    out << "                 Dx : " << dx() << std::endl;
    out << "                 Dy : " << dy() << std::endl;
    out << "         FAutoColor : " << isFAutoColor() << std::endl;
    out << "           FShowKey : " << isFShowKey() << std::endl;
    out << "         FShowValue : " << isFShowValue() << std::endl;
    out << "            Unused1 : " << unused1() << std::endl;
    out << "          FAutoText : " << isFAutoText() << std::endl;
    out << "         FGenerated : " << isFGenerated() << std::endl;
    out << "           FDeleted : " << isFDeleted() << std::endl;
    out << "          FAutoMode : " << isFAutoMode() << std::endl;
    out << "            Unused2 : " << unused2() << std::endl;
    out << "  FShowLabelAndPerc : " << isFShowLabelAndPerc() << std::endl;
    out << "       FShowPercent : " << isFShowPercent() << std::endl;
    out << "   FShowBubbleSizes : " << isFShowBubbleSizes() << std::endl;
    out << "         FShowLabel : " << isFShowLabel() << std::endl;
    out << "            IcvText : " << icvText() << std::endl;
}

static Record* createTextRecord(Swinder::Workbook *book)
{
    return new TextRecord(book);
}

// ========== FontXRecord ==========

const unsigned FontXRecord::id = 0x1026;

class FontXRecord::Private
{
public:
};

FontXRecord::FontXRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

FontXRecord::~FontXRecord()
{
    delete d;
}

FontXRecord::FontXRecord( const FontXRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

FontXRecord& FontXRecord::operator=( const FontXRecord& record )
{
    *d = *record.d;
    return *this;
}

void FontXRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void FontXRecord::writeData( XlsRecordOutputStream& ) const
{
}

void FontXRecord::dump( std::ostream& out ) const
{
    out << "FontX" << std::endl;
}

static Record* createFontXRecord(Swinder::Workbook *book)
{
    return new FontXRecord(book);
}

// ========== ObjectLinkRecord ==========

const unsigned ObjectLinkRecord::id = 0x1027;

class ObjectLinkRecord::Private
{
public:
    WLinkObj wLinkObj;
    unsigned wLinkVar1;
    unsigned wLinkVar2;
};

ObjectLinkRecord::ObjectLinkRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setWLinkObj(EntireChart);
    setWLinkVar1(0);
    setWLinkVar2(0);
}

ObjectLinkRecord::~ObjectLinkRecord()
{
    delete d;
}

ObjectLinkRecord::ObjectLinkRecord( const ObjectLinkRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ObjectLinkRecord& ObjectLinkRecord::operator=( const ObjectLinkRecord& record )
{
    *d = *record.d;
    return *this;
}

QString ObjectLinkRecord::wLinkObjToString(WLinkObj wLinkObj)
{
    switch (wLinkObj) {
        case EntireChart: return QString("EntireChart");
        case ValueOrVerticalAxis: return QString("ValueOrVerticalAxis");
        case CategoryOrHorizontalAxis: return QString("CategoryOrHorizontalAxis");
        case SeriesOrDatapoints: return QString("SeriesOrDatapoints");
        case SeriesAxis: return QString("SeriesAxis");
        case DisplayUnitsLabelsOfAxis: return QString("DisplayUnitsLabelsOfAxis");
        default: return QString("Unknown: %1").arg(wLinkObj);
    }
}

ObjectLinkRecord::WLinkObj ObjectLinkRecord::wLinkObj() const
{
    return d->wLinkObj;
}

void ObjectLinkRecord::setWLinkObj(WLinkObj wLinkObj )
{
    d->wLinkObj = wLinkObj;
}

unsigned ObjectLinkRecord::wLinkVar1() const
{
    return d->wLinkVar1;
}

void ObjectLinkRecord::setWLinkVar1(unsigned wLinkVar1 )
{
    d->wLinkVar1 = wLinkVar1;
}

unsigned ObjectLinkRecord::wLinkVar2() const
{
    return d->wLinkVar2;
}

void ObjectLinkRecord::setWLinkVar2(unsigned wLinkVar2 )
{
    d->wLinkVar2 = wLinkVar2;
}

void ObjectLinkRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 6) {
        setIsValid(false);
        return;
    }
    setWLinkObj(static_cast<WLinkObj>(readU16(data)));
    setWLinkVar1(readU16(data + 2));
    setWLinkVar2(readU16(data + 4));
}

void ObjectLinkRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, wLinkObj());
    out.writeUnsigned(16, wLinkVar1());
    out.writeUnsigned(16, wLinkVar2());
}

void ObjectLinkRecord::dump( std::ostream& out ) const
{
    out << "ObjectLink" << std::endl;
    out << "           WLinkObj : " << wLinkObjToString(wLinkObj()) << std::endl;
    out << "          WLinkVar1 : " << wLinkVar1() << std::endl;
    out << "          WLinkVar2 : " << wLinkVar2() << std::endl;
}

static Record* createObjectLinkRecord(Swinder::Workbook *book)
{
    return new ObjectLinkRecord(book);
}

// ========== PlotAreaRecord ==========

const unsigned PlotAreaRecord::id = 0x1035;

class PlotAreaRecord::Private
{
public:
};

PlotAreaRecord::PlotAreaRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

PlotAreaRecord::~PlotAreaRecord()
{
    delete d;
}

PlotAreaRecord::PlotAreaRecord( const PlotAreaRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

PlotAreaRecord& PlotAreaRecord::operator=( const PlotAreaRecord& record )
{
    *d = *record.d;
    return *this;
}

void PlotAreaRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void PlotAreaRecord::writeData( XlsRecordOutputStream& ) const
{
}

void PlotAreaRecord::dump( std::ostream& out ) const
{
    out << "PlotArea" << std::endl;
}

static Record* createPlotAreaRecord(Swinder::Workbook *book)
{
    return new PlotAreaRecord(book);
}

// ========== MsoDrawingSelectionRecord ==========

const unsigned MsoDrawingSelectionRecord::id = 0x00ed;

class MsoDrawingSelectionRecord::Private
{
public:
};

MsoDrawingSelectionRecord::MsoDrawingSelectionRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

MsoDrawingSelectionRecord::~MsoDrawingSelectionRecord()
{
    delete d;
}

MsoDrawingSelectionRecord::MsoDrawingSelectionRecord( const MsoDrawingSelectionRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

MsoDrawingSelectionRecord& MsoDrawingSelectionRecord::operator=( const MsoDrawingSelectionRecord& record )
{
    *d = *record.d;
    return *this;
}

void MsoDrawingSelectionRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void MsoDrawingSelectionRecord::writeData( XlsRecordOutputStream& ) const
{
}

void MsoDrawingSelectionRecord::dump( std::ostream& out ) const
{
    out << "MsoDrawingSelection" << std::endl;
}

static Record* createMsoDrawingSelectionRecord(Swinder::Workbook *book)
{
    return new MsoDrawingSelectionRecord(book);
}

// ========== Chart3dRecord ==========

const unsigned Chart3dRecord::id = 0x103a;

class Chart3dRecord::Private
{
public:
    int anElev;
    int anRot;
    bool f3DScaling;
    bool fCluster;
    bool fNotPieChart;
    bool fPerspective;
    bool fWalls2D;
    int pcDepth;
    int pcDist;
    unsigned pcGap;
    unsigned pcHeight;
};

Chart3dRecord::Chart3dRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setAnElev(0);
    setAnRot(0);
    setF3DScaling(false);
    setFCluster(false);
    setFNotPieChart(false);
    setFPerspective(false);
    setFWalls2D(false);
    setPcDepth(0);
    setPcDist(0);
    setPcGap(0);
    setPcHeight(0);
}

Chart3dRecord::~Chart3dRecord()
{
    delete d;
}

Chart3dRecord::Chart3dRecord( const Chart3dRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

Chart3dRecord& Chart3dRecord::operator=( const Chart3dRecord& record )
{
    *d = *record.d;
    return *this;
}

int Chart3dRecord::anElev() const
{
    return d->anElev;
}

void Chart3dRecord::setAnElev(int anElev )
{
    d->anElev = anElev;
}

int Chart3dRecord::anRot() const
{
    return d->anRot;
}

void Chart3dRecord::setAnRot(int anRot )
{
    d->anRot = anRot;
}

bool Chart3dRecord::isF3DScaling() const
{
    return d->f3DScaling;
}

void Chart3dRecord::setF3DScaling(bool f3DScaling )
{
    d->f3DScaling = f3DScaling;
}

bool Chart3dRecord::isFCluster() const
{
    return d->fCluster;
}

void Chart3dRecord::setFCluster(bool fCluster )
{
    d->fCluster = fCluster;
}

bool Chart3dRecord::isFNotPieChart() const
{
    return d->fNotPieChart;
}

void Chart3dRecord::setFNotPieChart(bool fNotPieChart )
{
    d->fNotPieChart = fNotPieChart;
}

bool Chart3dRecord::isFPerspective() const
{
    return d->fPerspective;
}

void Chart3dRecord::setFPerspective(bool fPerspective )
{
    d->fPerspective = fPerspective;
}

bool Chart3dRecord::isFWalls2D() const
{
    return d->fWalls2D;
}

void Chart3dRecord::setFWalls2D(bool fWalls2D )
{
    d->fWalls2D = fWalls2D;
}

int Chart3dRecord::pcDepth() const
{
    return d->pcDepth;
}

void Chart3dRecord::setPcDepth(int pcDepth )
{
    d->pcDepth = pcDepth;
}

int Chart3dRecord::pcDist() const
{
    return d->pcDist;
}

void Chart3dRecord::setPcDist(int pcDist )
{
    d->pcDist = pcDist;
}

unsigned Chart3dRecord::pcGap() const
{
    return d->pcGap;
}

void Chart3dRecord::setPcGap(unsigned pcGap )
{
    d->pcGap = pcGap;
}

unsigned Chart3dRecord::pcHeight() const
{
    return d->pcHeight;
}

void Chart3dRecord::setPcHeight(unsigned pcHeight )
{
    d->pcHeight = pcHeight;
}

void Chart3dRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 14) {
        setIsValid(false);
        return;
    }
    setAnRot(readS16(data));
    setAnElev(readS16(data + 2));
    setPcDist(readS16(data + 4));
    setPcHeight(readU16(data + 6));
    setPcDepth(readS16(data + 8));
    setPcGap(readU16(data + 10));
    setFPerspective(((readU8(data + 12)) & 0x1) != 0);
    setFCluster(((readU8(data + 12) >> 1) & 0x1) != 0);
    setF3DScaling(((readU8(data + 12) >> 2) & 0x1) != 0);
    setFNotPieChart(((readU8(data + 12) >> 4) & 0x1) != 0);
    setFWalls2D(((readU8(data + 12) >> 5) & 0x1) != 0);
}

void Chart3dRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeSigned(16, anRot());
    out.writeSigned(16, anElev());
    out.writeSigned(16, pcDist());
    out.writeUnsigned(16, pcHeight());
    out.writeSigned(16, pcDepth());
    out.writeUnsigned(16, pcGap());
    out.writeUnsigned(1, isFPerspective());
    out.writeUnsigned(1, isFCluster());
    out.writeUnsigned(1, isF3DScaling());
    out.writeUnsigned(1, 0);
    out.writeUnsigned(1, isFNotPieChart());
    out.writeUnsigned(1, isFWalls2D());
    out.writeUnsigned(10, 0);
}

void Chart3dRecord::dump( std::ostream& out ) const
{
    out << "Chart3d" << std::endl;
    out << "              AnRot : " << anRot() << std::endl;
    out << "             AnElev : " << anElev() << std::endl;
    out << "             PcDist : " << pcDist() << std::endl;
    out << "           PcHeight : " << pcHeight() << std::endl;
    out << "            PcDepth : " << pcDepth() << std::endl;
    out << "              PcGap : " << pcGap() << std::endl;
    out << "       FPerspective : " << isFPerspective() << std::endl;
    out << "           FCluster : " << isFCluster() << std::endl;
    out << "         F3DScaling : " << isF3DScaling() << std::endl;
    out << "       FNotPieChart : " << isFNotPieChart() << std::endl;
    out << "           FWalls2D : " << isFWalls2D() << std::endl;
}

static Record* createChart3dRecord(Swinder::Workbook *book)
{
    return new Chart3dRecord(book);
}

// ========== PicFRecord ==========

const unsigned PicFRecord::id = 0x103c;

class PicFRecord::Private
{
public:
};

PicFRecord::PicFRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

PicFRecord::~PicFRecord()
{
    delete d;
}

PicFRecord::PicFRecord( const PicFRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

PicFRecord& PicFRecord::operator=( const PicFRecord& record )
{
    *d = *record.d;
    return *this;
}

void PicFRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void PicFRecord::writeData( XlsRecordOutputStream& ) const
{
}

void PicFRecord::dump( std::ostream& out ) const
{
    out << "PicF" << std::endl;
}

static Record* createPicFRecord(Swinder::Workbook *book)
{
    return new PicFRecord(book);
}

// ========== DropBarRecord ==========

const unsigned DropBarRecord::id = 0x103d;

class DropBarRecord::Private
{
public:
};

DropBarRecord::DropBarRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

DropBarRecord::~DropBarRecord()
{
    delete d;
}

DropBarRecord::DropBarRecord( const DropBarRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

DropBarRecord& DropBarRecord::operator=( const DropBarRecord& record )
{
    *d = *record.d;
    return *this;
}

void DropBarRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void DropBarRecord::writeData( XlsRecordOutputStream& ) const
{
}

void DropBarRecord::dump( std::ostream& out ) const
{
    out << "DropBar" << std::endl;
}

static Record* createDropBarRecord(Swinder::Workbook *book)
{
    return new DropBarRecord(book);
}

// ========== RadarRecord ==========

const unsigned RadarRecord::id = 0x103e;

class RadarRecord::Private
{
public:
    bool fHasShadow;
    bool fRdrAxLab;
};

RadarRecord::RadarRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFHasShadow(false);
    setFRdrAxLab(false);
}

RadarRecord::~RadarRecord()
{
    delete d;
}

RadarRecord::RadarRecord( const RadarRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

RadarRecord& RadarRecord::operator=( const RadarRecord& record )
{
    *d = *record.d;
    return *this;
}

bool RadarRecord::isFHasShadow() const
{
    return d->fHasShadow;
}

void RadarRecord::setFHasShadow(bool fHasShadow )
{
    d->fHasShadow = fHasShadow;
}

bool RadarRecord::isFRdrAxLab() const
{
    return d->fRdrAxLab;
}

void RadarRecord::setFRdrAxLab(bool fRdrAxLab )
{
    d->fRdrAxLab = fRdrAxLab;
}

void RadarRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setFRdrAxLab(((readU8(data)) & 0x1) != 0);
    setFHasShadow(((readU8(data) >> 1) & 0x1) != 0);
}

void RadarRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(1, isFRdrAxLab());
    out.writeUnsigned(1, isFHasShadow());
    out.writeUnsigned(14, 0);
}

void RadarRecord::dump( std::ostream& out ) const
{
    out << "Radar" << std::endl;
    out << "          FRdrAxLab : " << isFRdrAxLab() << std::endl;
    out << "         FHasShadow : " << isFHasShadow() << std::endl;
}

static Record* createRadarRecord(Swinder::Workbook *book)
{
    return new RadarRecord(book);
}

// ========== SurfRecord ==========

const unsigned SurfRecord::id = 0x103f;

class SurfRecord::Private
{
public:
    bool f3DPhongShade;
    bool fFillSurface;
};

SurfRecord::SurfRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setF3DPhongShade(false);
    setFFillSurface(false);
}

SurfRecord::~SurfRecord()
{
    delete d;
}

SurfRecord::SurfRecord( const SurfRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

SurfRecord& SurfRecord::operator=( const SurfRecord& record )
{
    *d = *record.d;
    return *this;
}

bool SurfRecord::isF3DPhongShade() const
{
    return d->f3DPhongShade;
}

void SurfRecord::setF3DPhongShade(bool f3DPhongShade )
{
    d->f3DPhongShade = f3DPhongShade;
}

bool SurfRecord::isFFillSurface() const
{
    return d->fFillSurface;
}

void SurfRecord::setFFillSurface(bool fFillSurface )
{
    d->fFillSurface = fFillSurface;
}

void SurfRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setFFillSurface(((readU8(data)) & 0x1) != 0);
    setF3DPhongShade(((readU8(data) >> 1) & 0x1) != 0);
}

void SurfRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(1, isFFillSurface());
    out.writeUnsigned(1, isF3DPhongShade());
    out.writeUnsigned(14, 0);
}

void SurfRecord::dump( std::ostream& out ) const
{
    out << "Surf" << std::endl;
    out << "       FFillSurface : " << isFFillSurface() << std::endl;
    out << "      F3DPhongShade : " << isF3DPhongShade() << std::endl;
}

static Record* createSurfRecord(Swinder::Workbook *book)
{
    return new SurfRecord(book);
}

// ========== RadarAreaRecord ==========

const unsigned RadarAreaRecord::id = 0x1040;

class RadarAreaRecord::Private
{
public:
    bool fHasShadow;
    bool fRdrAxLab;
};

RadarAreaRecord::RadarAreaRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFHasShadow(false);
    setFRdrAxLab(false);
}

RadarAreaRecord::~RadarAreaRecord()
{
    delete d;
}

RadarAreaRecord::RadarAreaRecord( const RadarAreaRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

RadarAreaRecord& RadarAreaRecord::operator=( const RadarAreaRecord& record )
{
    *d = *record.d;
    return *this;
}

bool RadarAreaRecord::isFHasShadow() const
{
    return d->fHasShadow;
}

void RadarAreaRecord::setFHasShadow(bool fHasShadow )
{
    d->fHasShadow = fHasShadow;
}

bool RadarAreaRecord::isFRdrAxLab() const
{
    return d->fRdrAxLab;
}

void RadarAreaRecord::setFRdrAxLab(bool fRdrAxLab )
{
    d->fRdrAxLab = fRdrAxLab;
}

void RadarAreaRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setFRdrAxLab(((readU8(data)) & 0x1) != 0);
    setFHasShadow(((readU8(data) >> 1) & 0x1) != 0);
}

void RadarAreaRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(1, isFRdrAxLab());
    out.writeUnsigned(1, isFHasShadow());
    out.writeUnsigned(14, 0);
}

void RadarAreaRecord::dump( std::ostream& out ) const
{
    out << "RadarArea" << std::endl;
    out << "          FRdrAxLab : " << isFRdrAxLab() << std::endl;
    out << "         FHasShadow : " << isFHasShadow() << std::endl;
}

static Record* createRadarAreaRecord(Swinder::Workbook *book)
{
    return new RadarAreaRecord(book);
}

// ========== AxisParentRecord ==========

const unsigned AxisParentRecord::id = 0x1041;

class AxisParentRecord::Private
{
public:
    unsigned iax;
};

AxisParentRecord::AxisParentRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setIax(0);
}

AxisParentRecord::~AxisParentRecord()
{
    delete d;
}

AxisParentRecord::AxisParentRecord( const AxisParentRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

AxisParentRecord& AxisParentRecord::operator=( const AxisParentRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned AxisParentRecord::iax() const
{
    return d->iax;
}

void AxisParentRecord::setIax(unsigned iax )
{
    d->iax = iax;
}

void AxisParentRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setIax(readU16(data));
}

void AxisParentRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, iax());
}

void AxisParentRecord::dump( std::ostream& out ) const
{
    out << "AxisParent" << std::endl;
    out << "                Iax : " << iax() << std::endl;
}

static Record* createAxisParentRecord(Swinder::Workbook *book)
{
    return new AxisParentRecord(book);
}

// ========== LegendExceptionRecord ==========

const unsigned LegendExceptionRecord::id = 0x1043;

class LegendExceptionRecord::Private
{
public:
};

LegendExceptionRecord::LegendExceptionRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

LegendExceptionRecord::~LegendExceptionRecord()
{
    delete d;
}

LegendExceptionRecord::LegendExceptionRecord( const LegendExceptionRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

LegendExceptionRecord& LegendExceptionRecord::operator=( const LegendExceptionRecord& record )
{
    *d = *record.d;
    return *this;
}

void LegendExceptionRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void LegendExceptionRecord::writeData( XlsRecordOutputStream& ) const
{
}

void LegendExceptionRecord::dump( std::ostream& out ) const
{
    out << "LegendException" << std::endl;
}

static Record* createLegendExceptionRecord(Swinder::Workbook *book)
{
    return new LegendExceptionRecord(book);
}

// ========== ShtPropsRecord ==========

const unsigned ShtPropsRecord::id = 0x1044;

class ShtPropsRecord::Private
{
public:
    bool fAlwaysAutoPlotArea;
    bool fManPlotArea;
    bool fManSerAlloc;
    bool fNotSizeWIth;
    bool fPlotVisOnly;
    unsigned mdBlank;
};

ShtPropsRecord::ShtPropsRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFAlwaysAutoPlotArea(false);
    setFManPlotArea(false);
    setFManSerAlloc(false);
    setFNotSizeWIth(false);
    setFPlotVisOnly(false);
    setMdBlank(0);
}

ShtPropsRecord::~ShtPropsRecord()
{
    delete d;
}

ShtPropsRecord::ShtPropsRecord( const ShtPropsRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ShtPropsRecord& ShtPropsRecord::operator=( const ShtPropsRecord& record )
{
    *d = *record.d;
    return *this;
}

bool ShtPropsRecord::isFAlwaysAutoPlotArea() const
{
    return d->fAlwaysAutoPlotArea;
}

void ShtPropsRecord::setFAlwaysAutoPlotArea(bool fAlwaysAutoPlotArea )
{
    d->fAlwaysAutoPlotArea = fAlwaysAutoPlotArea;
}

bool ShtPropsRecord::isFManPlotArea() const
{
    return d->fManPlotArea;
}

void ShtPropsRecord::setFManPlotArea(bool fManPlotArea )
{
    d->fManPlotArea = fManPlotArea;
}

bool ShtPropsRecord::isFManSerAlloc() const
{
    return d->fManSerAlloc;
}

void ShtPropsRecord::setFManSerAlloc(bool fManSerAlloc )
{
    d->fManSerAlloc = fManSerAlloc;
}

bool ShtPropsRecord::isFNotSizeWIth() const
{
    return d->fNotSizeWIth;
}

void ShtPropsRecord::setFNotSizeWIth(bool fNotSizeWIth )
{
    d->fNotSizeWIth = fNotSizeWIth;
}

bool ShtPropsRecord::isFPlotVisOnly() const
{
    return d->fPlotVisOnly;
}

void ShtPropsRecord::setFPlotVisOnly(bool fPlotVisOnly )
{
    d->fPlotVisOnly = fPlotVisOnly;
}

unsigned ShtPropsRecord::mdBlank() const
{
    return d->mdBlank;
}

void ShtPropsRecord::setMdBlank(unsigned mdBlank )
{
    d->mdBlank = mdBlank;
}

void ShtPropsRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 4) {
        setIsValid(false);
        return;
    }
    setFManSerAlloc(((readU8(data)) & 0x1) != 0);
    setFPlotVisOnly(((readU8(data) >> 1) & 0x1) != 0);
    setFNotSizeWIth(((readU8(data) >> 2) & 0x1) != 0);
    setFManPlotArea(((readU8(data) >> 3) & 0x1) != 0);
    setFAlwaysAutoPlotArea(((readU8(data) >> 4) & 0x1) != 0);
    setMdBlank(readU8(data + 2));
}

void ShtPropsRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(1, isFManSerAlloc());
    out.writeUnsigned(1, isFPlotVisOnly());
    out.writeUnsigned(1, isFNotSizeWIth());
    out.writeUnsigned(1, isFManPlotArea());
    out.writeUnsigned(1, isFAlwaysAutoPlotArea());
    out.writeUnsigned(11, 0);
    out.writeUnsigned(8, mdBlank());
    out.writeUnsigned(8, 0);
}

void ShtPropsRecord::dump( std::ostream& out ) const
{
    out << "ShtProps" << std::endl;
    out << "       FManSerAlloc : " << isFManSerAlloc() << std::endl;
    out << "       FPlotVisOnly : " << isFPlotVisOnly() << std::endl;
    out << "       FNotSizeWIth : " << isFNotSizeWIth() << std::endl;
    out << "       FManPlotArea : " << isFManPlotArea() << std::endl;
    out << "FAlwaysAutoPlotArea : " << isFAlwaysAutoPlotArea() << std::endl;
    out << "            MdBlank : " << mdBlank() << std::endl;
}

static Record* createShtPropsRecord(Swinder::Workbook *book)
{
    return new ShtPropsRecord(book);
}

// ========== SerToCrtRecord ==========

const unsigned SerToCrtRecord::id = 0x1045;

class SerToCrtRecord::Private
{
public:
    unsigned identifier;
};

SerToCrtRecord::SerToCrtRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setIdentifier(0);
}

SerToCrtRecord::~SerToCrtRecord()
{
    delete d;
}

SerToCrtRecord::SerToCrtRecord( const SerToCrtRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

SerToCrtRecord& SerToCrtRecord::operator=( const SerToCrtRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned SerToCrtRecord::identifier() const
{
    return d->identifier;
}

void SerToCrtRecord::setIdentifier(unsigned identifier )
{
    d->identifier = identifier;
}

void SerToCrtRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setIdentifier(readU16(data));
}

void SerToCrtRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, identifier());
}

void SerToCrtRecord::dump( std::ostream& out ) const
{
    out << "SerToCrt" << std::endl;
    out << "         Identifier : " << identifier() << std::endl;
}

static Record* createSerToCrtRecord(Swinder::Workbook *book)
{
    return new SerToCrtRecord(book);
}

// ========== AxesUsedRecord ==========

const unsigned AxesUsedRecord::id = 0x1046;

class AxesUsedRecord::Private
{
public:
    unsigned cAxes;
};

AxesUsedRecord::AxesUsedRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCAxes(0);
}

AxesUsedRecord::~AxesUsedRecord()
{
    delete d;
}

AxesUsedRecord::AxesUsedRecord( const AxesUsedRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

AxesUsedRecord& AxesUsedRecord::operator=( const AxesUsedRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned AxesUsedRecord::cAxes() const
{
    return d->cAxes;
}

void AxesUsedRecord::setCAxes(unsigned cAxes )
{
    d->cAxes = cAxes;
}

void AxesUsedRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setCAxes(readU16(data));
}

void AxesUsedRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, cAxes());
}

void AxesUsedRecord::dump( std::ostream& out ) const
{
    out << "AxesUsed" << std::endl;
    out << "              CAxes : " << cAxes() << std::endl;
}

static Record* createAxesUsedRecord(Swinder::Workbook *book)
{
    return new AxesUsedRecord(book);
}

// ========== SBaseRefRecord ==========

const unsigned SBaseRefRecord::id = 0x1048;

class SBaseRefRecord::Private
{
public:
};

SBaseRefRecord::SBaseRefRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

SBaseRefRecord::~SBaseRefRecord()
{
    delete d;
}

SBaseRefRecord::SBaseRefRecord( const SBaseRefRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

SBaseRefRecord& SBaseRefRecord::operator=( const SBaseRefRecord& record )
{
    *d = *record.d;
    return *this;
}

void SBaseRefRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void SBaseRefRecord::writeData( XlsRecordOutputStream& ) const
{
}

void SBaseRefRecord::dump( std::ostream& out ) const
{
    out << "SBaseRef" << std::endl;
}

static Record* createSBaseRefRecord(Swinder::Workbook *book)
{
    return new SBaseRefRecord(book);
}

// ========== SerParentRecord ==========

const unsigned SerParentRecord::id = 0x104a;

class SerParentRecord::Private
{
public:
};

SerParentRecord::SerParentRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

SerParentRecord::~SerParentRecord()
{
    delete d;
}

SerParentRecord::SerParentRecord( const SerParentRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

SerParentRecord& SerParentRecord::operator=( const SerParentRecord& record )
{
    *d = *record.d;
    return *this;
}

void SerParentRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void SerParentRecord::writeData( XlsRecordOutputStream& ) const
{
}

void SerParentRecord::dump( std::ostream& out ) const
{
    out << "SerParent" << std::endl;
}

static Record* createSerParentRecord(Swinder::Workbook *book)
{
    return new SerParentRecord(book);
}

// ========== SerAuxTrendRecord ==========

const unsigned SerAuxTrendRecord::id = 0x104b;

class SerAuxTrendRecord::Private
{
public:
};

SerAuxTrendRecord::SerAuxTrendRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

SerAuxTrendRecord::~SerAuxTrendRecord()
{
    delete d;
}

SerAuxTrendRecord::SerAuxTrendRecord( const SerAuxTrendRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

SerAuxTrendRecord& SerAuxTrendRecord::operator=( const SerAuxTrendRecord& record )
{
    *d = *record.d;
    return *this;
}

void SerAuxTrendRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void SerAuxTrendRecord::writeData( XlsRecordOutputStream& ) const
{
}

void SerAuxTrendRecord::dump( std::ostream& out ) const
{
    out << "SerAuxTrend" << std::endl;
}

static Record* createSerAuxTrendRecord(Swinder::Workbook *book)
{
    return new SerAuxTrendRecord(book);
}

// ========== IFmtRecord ==========

const unsigned IFmtRecord::id = 0x104e;

class IFmtRecord::Private
{
public:
    unsigned ifmt;
};

IFmtRecord::IFmtRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setIfmt(0);
}

IFmtRecord::~IFmtRecord()
{
    delete d;
}

IFmtRecord::IFmtRecord( const IFmtRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

IFmtRecord& IFmtRecord::operator=( const IFmtRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned IFmtRecord::ifmt() const
{
    return d->ifmt;
}

void IFmtRecord::setIfmt(unsigned ifmt )
{
    d->ifmt = ifmt;
}

void IFmtRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setIfmt(readU16(data));
}

void IFmtRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, ifmt());
}

void IFmtRecord::dump( std::ostream& out ) const
{
    out << "IFmt" << std::endl;
    out << "               Ifmt : " << ifmt() << std::endl;
}

static Record* createIFmtRecord(Swinder::Workbook *book)
{
    return new IFmtRecord(book);
}

// ========== PosRecord ==========

const unsigned PosRecord::id = 0x104f;

class PosRecord::Private
{
public:
    unsigned mdBotRt;
    unsigned mdTopLt;
    unsigned unused1;
    unsigned unused2;
    unsigned unused3;
    unsigned unused4;
    unsigned x1;
    unsigned x2;
    unsigned y1;
    unsigned y2;
};

PosRecord::PosRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setMdBotRt(0);
    setMdTopLt(0);
    setUnused1(0);
    setUnused2(0);
    setUnused3(0);
    setUnused4(0);
    setX1(0);
    setX2(0);
    setY1(0);
    setY2(0);
}

PosRecord::~PosRecord()
{
    delete d;
}

PosRecord::PosRecord( const PosRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

PosRecord& PosRecord::operator=( const PosRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned PosRecord::mdBotRt() const
{
    return d->mdBotRt;
}

void PosRecord::setMdBotRt(unsigned mdBotRt )
{
    d->mdBotRt = mdBotRt;
}

unsigned PosRecord::mdTopLt() const
{
    return d->mdTopLt;
}

void PosRecord::setMdTopLt(unsigned mdTopLt )
{
    d->mdTopLt = mdTopLt;
}

unsigned PosRecord::unused1() const
{
    return d->unused1;
}

void PosRecord::setUnused1(unsigned unused1 )
{
    d->unused1 = unused1;
}

unsigned PosRecord::unused2() const
{
    return d->unused2;
}

void PosRecord::setUnused2(unsigned unused2 )
{
    d->unused2 = unused2;
}

unsigned PosRecord::unused3() const
{
    return d->unused3;
}

void PosRecord::setUnused3(unsigned unused3 )
{
    d->unused3 = unused3;
}

unsigned PosRecord::unused4() const
{
    return d->unused4;
}

void PosRecord::setUnused4(unsigned unused4 )
{
    d->unused4 = unused4;
}

unsigned PosRecord::x1() const
{
    return d->x1;
}

void PosRecord::setX1(unsigned x1 )
{
    d->x1 = x1;
}

unsigned PosRecord::x2() const
{
    return d->x2;
}

void PosRecord::setX2(unsigned x2 )
{
    d->x2 = x2;
}

unsigned PosRecord::y1() const
{
    return d->y1;
}

void PosRecord::setY1(unsigned y1 )
{
    d->y1 = y1;
}

unsigned PosRecord::y2() const
{
    return d->y2;
}

void PosRecord::setY2(unsigned y2 )
{
    d->y2 = y2;
}

void PosRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 20) {
        setIsValid(false);
        return;
    }
    setMdTopLt(readU16(data));
    setMdBotRt(readU16(data + 2));
    setX1(readU16(data + 4));
    setUnused1(readU16(data + 6));
    setY1(readU16(data + 8));
    setUnused2(readU16(data + 10));
    setX2(readU16(data + 12));
    setUnused3(readU16(data + 14));
    setY2(readU16(data + 16));
    setUnused4(readU16(data + 18));
}

void PosRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, mdTopLt());
    out.writeUnsigned(16, mdBotRt());
    out.writeUnsigned(16, x1());
    out.writeUnsigned(16, unused1());
    out.writeUnsigned(16, y1());
    out.writeUnsigned(16, unused2());
    out.writeUnsigned(16, x2());
    out.writeUnsigned(16, unused3());
    out.writeUnsigned(16, y2());
    out.writeUnsigned(16, unused4());
}

void PosRecord::dump( std::ostream& out ) const
{
    out << "Pos" << std::endl;
    out << "            MdTopLt : " << mdTopLt() << std::endl;
    out << "            MdBotRt : " << mdBotRt() << std::endl;
    out << "                 X1 : " << x1() << std::endl;
    out << "            Unused1 : " << unused1() << std::endl;
    out << "                 Y1 : " << y1() << std::endl;
    out << "            Unused2 : " << unused2() << std::endl;
    out << "                 X2 : " << x2() << std::endl;
    out << "            Unused3 : " << unused3() << std::endl;
    out << "                 Y2 : " << y2() << std::endl;
    out << "            Unused4 : " << unused4() << std::endl;
}

static Record* createPosRecord(Swinder::Workbook *book)
{
    return new PosRecord(book);
}

// ========== AIRunsRecord ==========

const unsigned AIRunsRecord::id = 0x1050;

class AIRunsRecord::Private
{
public:
};

AIRunsRecord::AIRunsRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

AIRunsRecord::~AIRunsRecord()
{
    delete d;
}

AIRunsRecord::AIRunsRecord( const AIRunsRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

AIRunsRecord& AIRunsRecord::operator=( const AIRunsRecord& record )
{
    *d = *record.d;
    return *this;
}

void AIRunsRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void AIRunsRecord::writeData( XlsRecordOutputStream& ) const
{
}

void AIRunsRecord::dump( std::ostream& out ) const
{
    out << "AIRuns" << std::endl;
}

static Record* createAIRunsRecord(Swinder::Workbook *book)
{
    return new AIRunsRecord(book);
}

// ========== SerAuxErrBarRecord ==========

const unsigned SerAuxErrBarRecord::id = 0x105b;

class SerAuxErrBarRecord::Private
{
public:
};

SerAuxErrBarRecord::SerAuxErrBarRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

SerAuxErrBarRecord::~SerAuxErrBarRecord()
{
    delete d;
}

SerAuxErrBarRecord::SerAuxErrBarRecord( const SerAuxErrBarRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

SerAuxErrBarRecord& SerAuxErrBarRecord::operator=( const SerAuxErrBarRecord& record )
{
    *d = *record.d;
    return *this;
}

void SerAuxErrBarRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void SerAuxErrBarRecord::writeData( XlsRecordOutputStream& ) const
{
}

void SerAuxErrBarRecord::dump( std::ostream& out ) const
{
    out << "SerAuxErrBar" << std::endl;
}

static Record* createSerAuxErrBarRecord(Swinder::Workbook *book)
{
    return new SerAuxErrBarRecord(book);
}

// ========== ClrtClientRecord ==========

const unsigned ClrtClientRecord::id = 0x105c;

class ClrtClientRecord::Private
{
public:
};

ClrtClientRecord::ClrtClientRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

ClrtClientRecord::~ClrtClientRecord()
{
    delete d;
}

ClrtClientRecord::ClrtClientRecord( const ClrtClientRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ClrtClientRecord& ClrtClientRecord::operator=( const ClrtClientRecord& record )
{
    *d = *record.d;
    return *this;
}

void ClrtClientRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void ClrtClientRecord::writeData( XlsRecordOutputStream& ) const
{
}

void ClrtClientRecord::dump( std::ostream& out ) const
{
    out << "ClrtClient" << std::endl;
}

static Record* createClrtClientRecord(Swinder::Workbook *book)
{
    return new ClrtClientRecord(book);
}

// ========== SerFmtRecord ==========

const unsigned SerFmtRecord::id = 0x105d;

class SerFmtRecord::Private
{
public:
};

SerFmtRecord::SerFmtRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

SerFmtRecord::~SerFmtRecord()
{
    delete d;
}

SerFmtRecord::SerFmtRecord( const SerFmtRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

SerFmtRecord& SerFmtRecord::operator=( const SerFmtRecord& record )
{
    *d = *record.d;
    return *this;
}

void SerFmtRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void SerFmtRecord::writeData( XlsRecordOutputStream& ) const
{
}

void SerFmtRecord::dump( std::ostream& out ) const
{
    out << "SerFmt" << std::endl;
}

static Record* createSerFmtRecord(Swinder::Workbook *book)
{
    return new SerFmtRecord(book);
}

// ========== Chart3DBarShapeRecord ==========

const unsigned Chart3DBarShapeRecord::id = 0x105f;

class Chart3DBarShapeRecord::Private
{
public:
    unsigned riser;
    unsigned taper;
};

Chart3DBarShapeRecord::Chart3DBarShapeRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setRiser(0);
    setTaper(0);
}

Chart3DBarShapeRecord::~Chart3DBarShapeRecord()
{
    delete d;
}

Chart3DBarShapeRecord::Chart3DBarShapeRecord( const Chart3DBarShapeRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

Chart3DBarShapeRecord& Chart3DBarShapeRecord::operator=( const Chart3DBarShapeRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned Chart3DBarShapeRecord::riser() const
{
    return d->riser;
}

void Chart3DBarShapeRecord::setRiser(unsigned riser )
{
    d->riser = riser;
}

unsigned Chart3DBarShapeRecord::taper() const
{
    return d->taper;
}

void Chart3DBarShapeRecord::setTaper(unsigned taper )
{
    d->taper = taper;
}

void Chart3DBarShapeRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setRiser(readU8(data));
    setTaper(readU8(data + 1));
}

void Chart3DBarShapeRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(8, riser());
    out.writeUnsigned(8, taper());
}

void Chart3DBarShapeRecord::dump( std::ostream& out ) const
{
    out << "Chart3DBarShape" << std::endl;
    out << "              Riser : " << riser() << std::endl;
    out << "              Taper : " << taper() << std::endl;
}

static Record* createChart3DBarShapeRecord(Swinder::Workbook *book)
{
    return new Chart3DBarShapeRecord(book);
}

// ========== FbiRecord ==========

const unsigned FbiRecord::id = 0x1060;

class FbiRecord::Private
{
public:
};

FbiRecord::FbiRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

FbiRecord::~FbiRecord()
{
    delete d;
}

FbiRecord::FbiRecord( const FbiRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

FbiRecord& FbiRecord::operator=( const FbiRecord& record )
{
    *d = *record.d;
    return *this;
}

void FbiRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void FbiRecord::writeData( XlsRecordOutputStream& ) const
{
}

void FbiRecord::dump( std::ostream& out ) const
{
    out << "Fbi" << std::endl;
}

static Record* createFbiRecord(Swinder::Workbook *book)
{
    return new FbiRecord(book);
}

// ========== BopPopRecord ==========

const unsigned BopPopRecord::id = 0x1061;

class BopPopRecord::Private
{
public:
};

BopPopRecord::BopPopRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

BopPopRecord::~BopPopRecord()
{
    delete d;
}

BopPopRecord::BopPopRecord( const BopPopRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

BopPopRecord& BopPopRecord::operator=( const BopPopRecord& record )
{
    *d = *record.d;
    return *this;
}

void BopPopRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void BopPopRecord::writeData( XlsRecordOutputStream& ) const
{
}

void BopPopRecord::dump( std::ostream& out ) const
{
    out << "BopPop" << std::endl;
}

static Record* createBopPopRecord(Swinder::Workbook *book)
{
    return new BopPopRecord(book);
}

// ========== AxcExtRecord ==========

const unsigned AxcExtRecord::id = 0x1062;

class AxcExtRecord::Private
{
public:
    unsigned catCrossDate;
    unsigned catMajor;
    unsigned catMax;
    unsigned catMin;
    unsigned catMinor;
    unsigned duBase;
    unsigned duMajor;
    unsigned duMinor;
    bool fAutoBase;
    bool fAutoCross;
    bool fAutoDate;
    bool fAutoMajor;
    bool fAutoMax;
    bool fAutoMin;
    bool fAutoMinor;
    bool fDateAxis;
};

AxcExtRecord::AxcExtRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCatCrossDate(0);
    setCatMajor(0);
    setCatMax(0);
    setCatMin(0);
    setCatMinor(0);
    setDuBase(0);
    setDuMajor(0);
    setDuMinor(0);
    setFAutoBase(false);
    setFAutoCross(false);
    setFAutoDate(false);
    setFAutoMajor(false);
    setFAutoMax(false);
    setFAutoMin(false);
    setFAutoMinor(false);
    setFDateAxis(false);
}

AxcExtRecord::~AxcExtRecord()
{
    delete d;
}

AxcExtRecord::AxcExtRecord( const AxcExtRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

AxcExtRecord& AxcExtRecord::operator=( const AxcExtRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned AxcExtRecord::catCrossDate() const
{
    return d->catCrossDate;
}

void AxcExtRecord::setCatCrossDate(unsigned catCrossDate )
{
    d->catCrossDate = catCrossDate;
}

unsigned AxcExtRecord::catMajor() const
{
    return d->catMajor;
}

void AxcExtRecord::setCatMajor(unsigned catMajor )
{
    d->catMajor = catMajor;
}

unsigned AxcExtRecord::catMax() const
{
    return d->catMax;
}

void AxcExtRecord::setCatMax(unsigned catMax )
{
    d->catMax = catMax;
}

unsigned AxcExtRecord::catMin() const
{
    return d->catMin;
}

void AxcExtRecord::setCatMin(unsigned catMin )
{
    d->catMin = catMin;
}

unsigned AxcExtRecord::catMinor() const
{
    return d->catMinor;
}

void AxcExtRecord::setCatMinor(unsigned catMinor )
{
    d->catMinor = catMinor;
}

unsigned AxcExtRecord::duBase() const
{
    return d->duBase;
}

void AxcExtRecord::setDuBase(unsigned duBase )
{
    d->duBase = duBase;
}

unsigned AxcExtRecord::duMajor() const
{
    return d->duMajor;
}

void AxcExtRecord::setDuMajor(unsigned duMajor )
{
    d->duMajor = duMajor;
}

unsigned AxcExtRecord::duMinor() const
{
    return d->duMinor;
}

void AxcExtRecord::setDuMinor(unsigned duMinor )
{
    d->duMinor = duMinor;
}

bool AxcExtRecord::isFAutoBase() const
{
    return d->fAutoBase;
}

void AxcExtRecord::setFAutoBase(bool fAutoBase )
{
    d->fAutoBase = fAutoBase;
}

bool AxcExtRecord::isFAutoCross() const
{
    return d->fAutoCross;
}

void AxcExtRecord::setFAutoCross(bool fAutoCross )
{
    d->fAutoCross = fAutoCross;
}

bool AxcExtRecord::isFAutoDate() const
{
    return d->fAutoDate;
}

void AxcExtRecord::setFAutoDate(bool fAutoDate )
{
    d->fAutoDate = fAutoDate;
}

bool AxcExtRecord::isFAutoMajor() const
{
    return d->fAutoMajor;
}

void AxcExtRecord::setFAutoMajor(bool fAutoMajor )
{
    d->fAutoMajor = fAutoMajor;
}

bool AxcExtRecord::isFAutoMax() const
{
    return d->fAutoMax;
}

void AxcExtRecord::setFAutoMax(bool fAutoMax )
{
    d->fAutoMax = fAutoMax;
}

bool AxcExtRecord::isFAutoMin() const
{
    return d->fAutoMin;
}

void AxcExtRecord::setFAutoMin(bool fAutoMin )
{
    d->fAutoMin = fAutoMin;
}

bool AxcExtRecord::isFAutoMinor() const
{
    return d->fAutoMinor;
}

void AxcExtRecord::setFAutoMinor(bool fAutoMinor )
{
    d->fAutoMinor = fAutoMinor;
}

bool AxcExtRecord::isFDateAxis() const
{
    return d->fDateAxis;
}

void AxcExtRecord::setFDateAxis(bool fDateAxis )
{
    d->fDateAxis = fDateAxis;
}

void AxcExtRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 17) {
        setIsValid(false);
        return;
    }
    setCatMin(readU16(data));
    setCatMax(readU16(data + 2));
    setCatMajor(readU16(data + 4));
    setDuMajor(readU16(data + 6));
    setCatMinor(readU16(data + 8));
    setDuMinor(readU16(data + 10));
    setDuBase(readU16(data + 12));
    setCatCrossDate(readU16(data + 14));
    setFAutoMin(((readU8(data + 16)) & 0x1) != 0);
    setFAutoMax(((readU8(data + 16) >> 1) & 0x1) != 0);
    setFAutoMajor(((readU8(data + 16) >> 2) & 0x1) != 0);
    setFAutoMinor(((readU8(data + 16) >> 3) & 0x1) != 0);
    setFDateAxis(((readU8(data + 16) >> 4) & 0x1) != 0);
    setFAutoBase(((readU8(data + 16) >> 5) & 0x1) != 0);
    setFAutoCross(((readU8(data + 16) >> 6) & 0x1) != 0);
    setFAutoDate(((readU8(data + 16) >> 7) & 0x1) != 0);
}

void AxcExtRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, catMin());
    out.writeUnsigned(16, catMax());
    out.writeUnsigned(16, catMajor());
    out.writeUnsigned(16, duMajor());
    out.writeUnsigned(16, catMinor());
    out.writeUnsigned(16, duMinor());
    out.writeUnsigned(16, duBase());
    out.writeUnsigned(16, catCrossDate());
    out.writeUnsigned(1, isFAutoMin());
    out.writeUnsigned(1, isFAutoMax());
    out.writeUnsigned(1, isFAutoMajor());
    out.writeUnsigned(1, isFAutoMinor());
    out.writeUnsigned(1, isFDateAxis());
    out.writeUnsigned(1, isFAutoBase());
    out.writeUnsigned(1, isFAutoCross());
    out.writeUnsigned(1, isFAutoDate());
}

void AxcExtRecord::dump( std::ostream& out ) const
{
    out << "AxcExt" << std::endl;
    out << "             CatMin : " << catMin() << std::endl;
    out << "             CatMax : " << catMax() << std::endl;
    out << "           CatMajor : " << catMajor() << std::endl;
    out << "            DuMajor : " << duMajor() << std::endl;
    out << "           CatMinor : " << catMinor() << std::endl;
    out << "            DuMinor : " << duMinor() << std::endl;
    out << "             DuBase : " << duBase() << std::endl;
    out << "       CatCrossDate : " << catCrossDate() << std::endl;
    out << "           FAutoMin : " << isFAutoMin() << std::endl;
    out << "           FAutoMax : " << isFAutoMax() << std::endl;
    out << "         FAutoMajor : " << isFAutoMajor() << std::endl;
    out << "         FAutoMinor : " << isFAutoMinor() << std::endl;
    out << "          FDateAxis : " << isFDateAxis() << std::endl;
    out << "          FAutoBase : " << isFAutoBase() << std::endl;
    out << "         FAutoCross : " << isFAutoCross() << std::endl;
    out << "          FAutoDate : " << isFAutoDate() << std::endl;
}

static Record* createAxcExtRecord(Swinder::Workbook *book)
{
    return new AxcExtRecord(book);
}

// ========== DatRecord ==========

const unsigned DatRecord::id = 0x1063;

class DatRecord::Private
{
public:
};

DatRecord::DatRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

DatRecord::~DatRecord()
{
    delete d;
}

DatRecord::DatRecord( const DatRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

DatRecord& DatRecord::operator=( const DatRecord& record )
{
    *d = *record.d;
    return *this;
}

void DatRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void DatRecord::writeData( XlsRecordOutputStream& ) const
{
}

void DatRecord::dump( std::ostream& out ) const
{
    out << "Dat" << std::endl;
}

static Record* createDatRecord(Swinder::Workbook *book)
{
    return new DatRecord(book);
}

// ========== PlotGrowthRecord ==========

const unsigned PlotGrowthRecord::id = 0x1064;

class PlotGrowthRecord::Private
{
public:
};

PlotGrowthRecord::PlotGrowthRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

PlotGrowthRecord::~PlotGrowthRecord()
{
    delete d;
}

PlotGrowthRecord::PlotGrowthRecord( const PlotGrowthRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

PlotGrowthRecord& PlotGrowthRecord::operator=( const PlotGrowthRecord& record )
{
    *d = *record.d;
    return *this;
}

void PlotGrowthRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void PlotGrowthRecord::writeData( XlsRecordOutputStream& ) const
{
}

void PlotGrowthRecord::dump( std::ostream& out ) const
{
    out << "PlotGrowth" << std::endl;
}

static Record* createPlotGrowthRecord(Swinder::Workbook *book)
{
    return new PlotGrowthRecord(book);
}

// ========== SIIndexRecord ==========

const unsigned SIIndexRecord::id = 0x1065;

class SIIndexRecord::Private
{
public:
    unsigned numIndex;
};

SIIndexRecord::SIIndexRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setNumIndex(0);
}

SIIndexRecord::~SIIndexRecord()
{
    delete d;
}

SIIndexRecord::SIIndexRecord( const SIIndexRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

SIIndexRecord& SIIndexRecord::operator=( const SIIndexRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned SIIndexRecord::numIndex() const
{
    return d->numIndex;
}

void SIIndexRecord::setNumIndex(unsigned numIndex )
{
    d->numIndex = numIndex;
}

void SIIndexRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setNumIndex(readU16(data));
}

void SIIndexRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, numIndex());
}

void SIIndexRecord::dump( std::ostream& out ) const
{
    out << "SIIndex" << std::endl;
    out << "           NumIndex : " << numIndex() << std::endl;
}

static Record* createSIIndexRecord(Swinder::Workbook *book)
{
    return new SIIndexRecord(book);
}

// ========== GelFrameRecord ==========

const unsigned GelFrameRecord::id = 0x1066;

class GelFrameRecord::Private
{
public:
};

GelFrameRecord::GelFrameRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

GelFrameRecord::~GelFrameRecord()
{
    delete d;
}

GelFrameRecord::GelFrameRecord( const GelFrameRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

GelFrameRecord& GelFrameRecord::operator=( const GelFrameRecord& record )
{
    *d = *record.d;
    return *this;
}

void GelFrameRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void GelFrameRecord::writeData( XlsRecordOutputStream& ) const
{
}

void GelFrameRecord::dump( std::ostream& out ) const
{
    out << "GelFrame" << std::endl;
}

static Record* createGelFrameRecord(Swinder::Workbook *book)
{
    return new GelFrameRecord(book);
}

// ========== BobPopCustomRecord ==========

const unsigned BobPopCustomRecord::id = 0x1067;

class BobPopCustomRecord::Private
{
public:
};

BobPopCustomRecord::BobPopCustomRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

BobPopCustomRecord::~BobPopCustomRecord()
{
    delete d;
}

BobPopCustomRecord::BobPopCustomRecord( const BobPopCustomRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

BobPopCustomRecord& BobPopCustomRecord::operator=( const BobPopCustomRecord& record )
{
    *d = *record.d;
    return *this;
}

void BobPopCustomRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void BobPopCustomRecord::writeData( XlsRecordOutputStream& ) const
{
}

void BobPopCustomRecord::dump( std::ostream& out ) const
{
    out << "BobPopCustom" << std::endl;
}

static Record* createBobPopCustomRecord(Swinder::Workbook *book)
{
    return new BobPopCustomRecord(book);
}

// ========== Fbi2Record ==========

const unsigned Fbi2Record::id = 0x1068;

class Fbi2Record::Private
{
public:
};

Fbi2Record::Fbi2Record(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

Fbi2Record::~Fbi2Record()
{
    delete d;
}

Fbi2Record::Fbi2Record( const Fbi2Record& record )
    : Record(record), d(new Private)
{
    *this = record;
}

Fbi2Record& Fbi2Record::operator=( const Fbi2Record& record )
{
    *d = *record.d;
    return *this;
}

void Fbi2Record::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void Fbi2Record::writeData( XlsRecordOutputStream& ) const
{
}

void Fbi2Record::dump( std::ostream& out ) const
{
    out << "Fbi2" << std::endl;
}

static Record* createFbi2Record(Swinder::Workbook *book)
{
    return new Fbi2Record(book);
}

// ========== ZoomLevelRecord ==========

const unsigned ZoomLevelRecord::id = 0x00a0;

class ZoomLevelRecord::Private
{
public:
    int denominator;
    int numerator;
};

ZoomLevelRecord::ZoomLevelRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setDenominator(0);
    setNumerator(0);
}

ZoomLevelRecord::~ZoomLevelRecord()
{
    delete d;
}

ZoomLevelRecord::ZoomLevelRecord( const ZoomLevelRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ZoomLevelRecord& ZoomLevelRecord::operator=( const ZoomLevelRecord& record )
{
    *d = *record.d;
    return *this;
}

int ZoomLevelRecord::denominator() const
{
    return d->denominator;
}

void ZoomLevelRecord::setDenominator(int denominator )
{
    d->denominator = denominator;
}

int ZoomLevelRecord::numerator() const
{
    return d->numerator;
}

void ZoomLevelRecord::setNumerator(int numerator )
{
    d->numerator = numerator;
}

void ZoomLevelRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 4) {
        setIsValid(false);
        return;
    }
    setNumerator(readS16(data));
    setDenominator(readS16(data + 2));
}

void ZoomLevelRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeSigned(16, numerator());
    out.writeSigned(16, denominator());
}

void ZoomLevelRecord::dump( std::ostream& out ) const
{
    out << "ZoomLevel" << std::endl;
    out << "          Numerator : " << numerator() << std::endl;
    out << "        Denominator : " << denominator() << std::endl;
}

static Record* createZoomLevelRecord(Swinder::Workbook *book)
{
    return new ZoomLevelRecord(book);
}

// ========== FrameRecord ==========

const unsigned FrameRecord::id = 0x1032;

class FrameRecord::Private
{
public:
    bool autoPosition;
    bool autoSize;
    FrameType frameType;
};

FrameRecord::FrameRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setAutoPosition(false);
    setAutoSize(false);
    setFrameType(SimpleFrame);
}

FrameRecord::~FrameRecord()
{
    delete d;
}

FrameRecord::FrameRecord( const FrameRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

FrameRecord& FrameRecord::operator=( const FrameRecord& record )
{
    *d = *record.d;
    return *this;
}

QString FrameRecord::frameTypeToString(FrameType frameType)
{
    switch (frameType) {
        case SimpleFrame: return QString("SimpleFrame");
        case ShadowedFrame: return QString("ShadowedFrame");
        default: return QString("Unknown: %1").arg(frameType);
    }
}

bool FrameRecord::isAutoPosition() const
{
    return d->autoPosition;
}

void FrameRecord::setAutoPosition(bool autoPosition )
{
    d->autoPosition = autoPosition;
}

bool FrameRecord::isAutoSize() const
{
    return d->autoSize;
}

void FrameRecord::setAutoSize(bool autoSize )
{
    d->autoSize = autoSize;
}

FrameRecord::FrameType FrameRecord::frameType() const
{
    return d->frameType;
}

void FrameRecord::setFrameType(FrameType frameType )
{
    d->frameType = frameType;
}

void FrameRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 4) {
        setIsValid(false);
        return;
    }
    setFrameType(static_cast<FrameType>(readU16(data)));
    setAutoSize(((readU8(data + 2)) & 0x1) != 0);
    setAutoPosition(((readU8(data + 2) >> 1) & 0x1) != 0);
}

void FrameRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, frameType());
    out.writeUnsigned(1, isAutoSize());
    out.writeUnsigned(1, isAutoPosition());
    out.writeUnsigned(14, 0);
}

void FrameRecord::dump( std::ostream& out ) const
{
    out << "Frame" << std::endl;
    out << "          FrameType : " << frameTypeToString(frameType()) << std::endl;
    out << "           AutoSize : " << isAutoSize() << std::endl;
    out << "       AutoPosition : " << isAutoPosition() << std::endl;
}

static Record* createFrameRecord(Swinder::Workbook *book)
{
    return new FrameRecord(book);
}

// ========== SeriesRecord ==========

const unsigned SeriesRecord::id = 0x1003;

class SeriesRecord::Private
{
public:
    unsigned bubbleSizeDataType;
    unsigned countBubbleSizeValues;
    unsigned countXValues;
    unsigned countYValues;
    DataTypeX dataTypeX;
    unsigned dataTypeY;
};

SeriesRecord::SeriesRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setBubbleSizeDataType(0);
    setCountBubbleSizeValues(0);
    setCountXValues(0);
    setCountYValues(0);
    setDataTypeX(Numeric);
    setDataTypeY(0);
}

SeriesRecord::~SeriesRecord()
{
    delete d;
}

SeriesRecord::SeriesRecord( const SeriesRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

SeriesRecord& SeriesRecord::operator=( const SeriesRecord& record )
{
    *d = *record.d;
    return *this;
}

QString SeriesRecord::dataTypeXToString(DataTypeX dataTypeX)
{
    switch (dataTypeX) {
        case Numeric: return QString("Numeric");
        case Textual: return QString("Textual");
        default: return QString("Unknown: %1").arg(dataTypeX);
    }
}

unsigned SeriesRecord::bubbleSizeDataType() const
{
    return d->bubbleSizeDataType;
}

void SeriesRecord::setBubbleSizeDataType(unsigned bubbleSizeDataType )
{
    d->bubbleSizeDataType = bubbleSizeDataType;
}

unsigned SeriesRecord::countBubbleSizeValues() const
{
    return d->countBubbleSizeValues;
}

void SeriesRecord::setCountBubbleSizeValues(unsigned countBubbleSizeValues )
{
    d->countBubbleSizeValues = countBubbleSizeValues;
}

unsigned SeriesRecord::countXValues() const
{
    return d->countXValues;
}

void SeriesRecord::setCountXValues(unsigned countXValues )
{
    d->countXValues = countXValues;
}

unsigned SeriesRecord::countYValues() const
{
    return d->countYValues;
}

void SeriesRecord::setCountYValues(unsigned countYValues )
{
    d->countYValues = countYValues;
}

SeriesRecord::DataTypeX SeriesRecord::dataTypeX() const
{
    return d->dataTypeX;
}

void SeriesRecord::setDataTypeX(DataTypeX dataTypeX )
{
    d->dataTypeX = dataTypeX;
}

unsigned SeriesRecord::dataTypeY() const
{
    return d->dataTypeY;
}

void SeriesRecord::setDataTypeY(unsigned dataTypeY )
{
    d->dataTypeY = dataTypeY;
}

void SeriesRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 12) {
        setIsValid(false);
        return;
    }
    setDataTypeX(static_cast<DataTypeX>(readU16(data)));
    setDataTypeY(readU16(data + 2));
    setCountXValues(readU16(data + 4));
    setCountYValues(readU16(data + 6));
    setBubbleSizeDataType(readU16(data + 8));
    setCountBubbleSizeValues(readU16(data + 10));
}

void SeriesRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, dataTypeX());
    out.writeUnsigned(16, dataTypeY());
    out.writeUnsigned(16, countXValues());
    out.writeUnsigned(16, countYValues());
    out.writeUnsigned(16, bubbleSizeDataType());
    out.writeUnsigned(16, countBubbleSizeValues());
}

void SeriesRecord::dump( std::ostream& out ) const
{
    out << "Series" << std::endl;
    out << "          DataTypeX : " << dataTypeXToString(dataTypeX()) << std::endl;
    out << "          DataTypeY : " << dataTypeY() << std::endl;
    out << "       CountXValues : " << countXValues() << std::endl;
    out << "       CountYValues : " << countYValues() << std::endl;
    out << " BubbleSizeDataType : " << bubbleSizeDataType() << std::endl;
    out << "CountBubbleSizeValues : " << countBubbleSizeValues() << std::endl;
}

static Record* createSeriesRecord(Swinder::Workbook *book)
{
    return new SeriesRecord(book);
}

// ========== SeriesTextRecord ==========

const unsigned SeriesTextRecord::id = 0x100d;

class SeriesTextRecord::Private
{
public:
    QString text;
};

SeriesTextRecord::SeriesTextRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

SeriesTextRecord::~SeriesTextRecord()
{
    delete d;
}

SeriesTextRecord::SeriesTextRecord( const SeriesTextRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

SeriesTextRecord& SeriesTextRecord::operator=( const SeriesTextRecord& record )
{
    *d = *record.d;
    return *this;
}

QString SeriesTextRecord::text() const
{
    return d->text;
}

void SeriesTextRecord::setText(QString text )
{
    d->text = text;
}

void SeriesTextRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    bool stringLengthError = false;
    unsigned stringSize;
    if (size < 3) {
        setIsValid(false);
        return;
    }
    unsigned stringLength = readU8(data + 2);
    curOffset = 3;
    setText(readUnicodeString(data + curOffset, stringLength, size - curOffset, &stringLengthError, &stringSize));
    if (stringLengthError) {
        setIsValid(false);
        return;
    }
    curOffset += stringSize;
}

void SeriesTextRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, 0);
    out.writeUnsigned(8, text().length());
    out.writeUnicodeStringWithFlags(text());
}

void SeriesTextRecord::dump( std::ostream& out ) const
{
    out << "SeriesText" << std::endl;
    out << "               Text : " << text() << std::endl;
}

static Record* createSeriesTextRecord(Swinder::Workbook *book)
{
    return new SeriesTextRecord(book);
}

// ========== GridSetReservedRecord ==========

const unsigned GridSetReservedRecord::id = 0x0082;

class GridSetReservedRecord::Private
{
public:
    unsigned gridSetReserved;
};

GridSetReservedRecord::GridSetReservedRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setGridSetReserved(1);
}

GridSetReservedRecord::~GridSetReservedRecord()
{
    delete d;
}

GridSetReservedRecord::GridSetReservedRecord( const GridSetReservedRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

GridSetReservedRecord& GridSetReservedRecord::operator=( const GridSetReservedRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned GridSetReservedRecord::gridSetReserved() const
{
    return d->gridSetReserved;
}

void GridSetReservedRecord::setGridSetReserved(unsigned gridSetReserved )
{
    d->gridSetReserved = gridSetReserved;
}

void GridSetReservedRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setGridSetReserved(readU16(data));
}

void GridSetReservedRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, gridSetReserved());
}

void GridSetReservedRecord::dump( std::ostream& out ) const
{
    out << "GridSetReserved" << std::endl;
    out << "    GridSetReserved : " << gridSetReserved() << std::endl;
}

static Record* createGridSetReservedRecord(Swinder::Workbook *book)
{
    return new GridSetReservedRecord(book);
}

// ========== Excel9FileRecord ==========

const unsigned Excel9FileRecord::id = 0x01c0;

class Excel9FileRecord::Private
{
public:
};

Excel9FileRecord::Excel9FileRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

Excel9FileRecord::~Excel9FileRecord()
{
    delete d;
}

Excel9FileRecord::Excel9FileRecord( const Excel9FileRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

Excel9FileRecord& Excel9FileRecord::operator=( const Excel9FileRecord& record )
{
    *d = *record.d;
    return *this;
}

void Excel9FileRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void Excel9FileRecord::writeData( XlsRecordOutputStream& ) const
{
}

void Excel9FileRecord::dump( std::ostream& out ) const
{
    out << "Excel9File" << std::endl;
}

static Record* createExcel9FileRecord(Swinder::Workbook *book)
{
    return new Excel9FileRecord(book);
}

// ========== Compat12Record ==========

const unsigned Compat12Record::id = 0x088c;

class Compat12Record::Private
{
public:
};

Compat12Record::Compat12Record(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

Compat12Record::~Compat12Record()
{
    delete d;
}

Compat12Record::Compat12Record( const Compat12Record& record )
    : Record(record), d(new Private)
{
    *this = record;
}

Compat12Record& Compat12Record::operator=( const Compat12Record& record )
{
    *d = *record.d;
    return *this;
}

void Compat12Record::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void Compat12Record::writeData( XlsRecordOutputStream& ) const
{
}

void Compat12Record::dump( std::ostream& out ) const
{
    out << "Compat12" << std::endl;
}

static Record* createCompat12Record(Swinder::Workbook *book)
{
    return new Compat12Record(book);
}

// ========== Window1Record ==========

const unsigned Window1Record::id = 0x003D;

class Window1Record::Private
{
public:
    unsigned cTabSel;
    int dxWn;
    int dyWn;
    bool fBotAdornment;
    bool fDspHScroll;
    bool fDspVScroll;
    bool fHidden;
    bool fIconic;
    bool fNoAFDateGroup;
    bool fVeryHidden;
    unsigned itabCur;
    unsigned itabFirst;
    unsigned wTabRatio;
    int xWn;
    int yWn;
};

Window1Record::Window1Record(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCTabSel(1);
    setDxWn(24000);
    setDyWn(18000);
    setFBotAdornment(true);
    setFDspHScroll(true);
    setFDspVScroll(true);
    setFHidden(false);
    setFIconic(false);
    setFNoAFDateGroup(false);
    setFVeryHidden(false);
    setItabCur(0);
    setItabFirst(0);
    setWTabRatio(600);
    setXWn(0);
    setYWn(0);
}

Window1Record::~Window1Record()
{
    delete d;
}

Window1Record::Window1Record( const Window1Record& record )
    : Record(record), d(new Private)
{
    *this = record;
}

Window1Record& Window1Record::operator=( const Window1Record& record )
{
    *d = *record.d;
    return *this;
}

unsigned Window1Record::cTabSel() const
{
    return d->cTabSel;
}

void Window1Record::setCTabSel(unsigned cTabSel )
{
    d->cTabSel = cTabSel;
}

int Window1Record::dxWn() const
{
    return d->dxWn;
}

void Window1Record::setDxWn(int dxWn )
{
    d->dxWn = dxWn;
}

int Window1Record::dyWn() const
{
    return d->dyWn;
}

void Window1Record::setDyWn(int dyWn )
{
    d->dyWn = dyWn;
}

bool Window1Record::isFBotAdornment() const
{
    return d->fBotAdornment;
}

void Window1Record::setFBotAdornment(bool fBotAdornment )
{
    d->fBotAdornment = fBotAdornment;
}

bool Window1Record::isFDspHScroll() const
{
    return d->fDspHScroll;
}

void Window1Record::setFDspHScroll(bool fDspHScroll )
{
    d->fDspHScroll = fDspHScroll;
}

bool Window1Record::isFDspVScroll() const
{
    return d->fDspVScroll;
}

void Window1Record::setFDspVScroll(bool fDspVScroll )
{
    d->fDspVScroll = fDspVScroll;
}

bool Window1Record::isFHidden() const
{
    return d->fHidden;
}

void Window1Record::setFHidden(bool fHidden )
{
    d->fHidden = fHidden;
}

bool Window1Record::isFIconic() const
{
    return d->fIconic;
}

void Window1Record::setFIconic(bool fIconic )
{
    d->fIconic = fIconic;
}

bool Window1Record::isFNoAFDateGroup() const
{
    return d->fNoAFDateGroup;
}

void Window1Record::setFNoAFDateGroup(bool fNoAFDateGroup )
{
    d->fNoAFDateGroup = fNoAFDateGroup;
}

bool Window1Record::isFVeryHidden() const
{
    return d->fVeryHidden;
}

void Window1Record::setFVeryHidden(bool fVeryHidden )
{
    d->fVeryHidden = fVeryHidden;
}

unsigned Window1Record::itabCur() const
{
    return d->itabCur;
}

void Window1Record::setItabCur(unsigned itabCur )
{
    d->itabCur = itabCur;
}

unsigned Window1Record::itabFirst() const
{
    return d->itabFirst;
}

void Window1Record::setItabFirst(unsigned itabFirst )
{
    d->itabFirst = itabFirst;
}

unsigned Window1Record::wTabRatio() const
{
    return d->wTabRatio;
}

void Window1Record::setWTabRatio(unsigned wTabRatio )
{
    d->wTabRatio = wTabRatio;
}

int Window1Record::xWn() const
{
    return d->xWn;
}

void Window1Record::setXWn(int xWn )
{
    d->xWn = xWn;
}

int Window1Record::yWn() const
{
    return d->yWn;
}

void Window1Record::setYWn(int yWn )
{
    d->yWn = yWn;
}

void Window1Record::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 18) {
        setIsValid(false);
        return;
    }
    setXWn(readS16(data));
    setYWn(readS16(data + 2));
    setDxWn(readS16(data + 4));
    setDyWn(readS16(data + 6));
    setFHidden(((readU8(data + 8)) & 0x1) != 0);
    setFIconic(((readU8(data + 8) >> 1) & 0x1) != 0);
    setFVeryHidden(((readU8(data + 8) >> 2) & 0x1) != 0);
    setFDspHScroll(((readU8(data + 8) >> 3) & 0x1) != 0);
    setFDspVScroll(((readU8(data + 8) >> 4) & 0x1) != 0);
    setFBotAdornment(((readU8(data + 8) >> 5) & 0x1) != 0);
    setFNoAFDateGroup(((readU8(data + 8) >> 6) & 0x1) != 0);
    setItabCur(readU16(data + 10));
    setItabFirst(readU16(data + 12));
    setCTabSel(readU16(data + 14));
    setWTabRatio(readU16(data + 16));
}

void Window1Record::writeData( XlsRecordOutputStream& out ) const
{
    out.writeSigned(16, xWn());
    out.writeSigned(16, yWn());
    out.writeSigned(16, dxWn());
    out.writeSigned(16, dyWn());
    out.writeUnsigned(1, isFHidden());
    out.writeUnsigned(1, isFIconic());
    out.writeUnsigned(1, isFVeryHidden());
    out.writeUnsigned(1, isFDspHScroll());
    out.writeUnsigned(1, isFDspVScroll());
    out.writeUnsigned(1, isFBotAdornment());
    out.writeUnsigned(1, isFNoAFDateGroup());
    out.writeUnsigned(9, 0);
    out.writeUnsigned(16, itabCur());
    out.writeUnsigned(16, itabFirst());
    out.writeUnsigned(16, cTabSel());
    out.writeUnsigned(16, wTabRatio());
}

void Window1Record::dump( std::ostream& out ) const
{
    out << "Window1" << std::endl;
    out << "                XWn : " << xWn() << std::endl;
    out << "                YWn : " << yWn() << std::endl;
    out << "               DxWn : " << dxWn() << std::endl;
    out << "               DyWn : " << dyWn() << std::endl;
    out << "            FHidden : " << isFHidden() << std::endl;
    out << "            FIconic : " << isFIconic() << std::endl;
    out << "        FVeryHidden : " << isFVeryHidden() << std::endl;
    out << "        FDspHScroll : " << isFDspHScroll() << std::endl;
    out << "        FDspVScroll : " << isFDspVScroll() << std::endl;
    out << "      FBotAdornment : " << isFBotAdornment() << std::endl;
    out << "     FNoAFDateGroup : " << isFNoAFDateGroup() << std::endl;
    out << "            ItabCur : " << itabCur() << std::endl;
    out << "          ItabFirst : " << itabFirst() << std::endl;
    out << "            CTabSel : " << cTabSel() << std::endl;
    out << "          WTabRatio : " << wTabRatio() << std::endl;
}

static Record* createWindow1Record(Swinder::Workbook *book)
{
    return new Window1Record(book);
}

// ========== Window2Record ==========

const unsigned Window2Record::id = 0x023E;

class Window2Record::Private
{
public:
    unsigned colLeft;
    bool fDefaultHdr;
    bool fDspFmlaRt;
    bool fDspGridRt;
    bool fDspGuts;
    bool fDspRwColRt;
    bool fDspZerosRt;
    bool fFrozenNoSplit;
    bool fFrozenRt;
    bool fPaged;
    bool fRightToLeft;
    bool fSLV;
    bool fSelected;
    unsigned icvHdr;
    unsigned rwTop;
    unsigned wScaleNormal;
    unsigned wScaleSLV;
    bool hasSheetFields;
};

Window2Record::Window2Record(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setColLeft(0);
    setFDefaultHdr(true);
    setFDspFmlaRt(false);
    setFDspGridRt(true);
    setFDspGuts(true);
    setFDspRwColRt(true);
    setFDspZerosRt(true);
    setFFrozenNoSplit(false);
    setFFrozenRt(false);
    setFPaged(true);
    setFRightToLeft(false);
    setFSLV(false);
    setFSelected(true);
    setIcvHdr(64);
    setRwTop(0);
    setWScaleNormal(0);
    setWScaleSLV(0);
    d->hasSheetFields = false;
}

Window2Record::~Window2Record()
{
    delete d;
}

Window2Record::Window2Record( const Window2Record& record )
    : Record(record), d(new Private)
{
    *this = record;
}

Window2Record& Window2Record::operator=( const Window2Record& record )
{
    *d = *record.d;
    return *this;
}

unsigned Window2Record::colLeft() const
{
    return d->colLeft;
}

void Window2Record::setColLeft(unsigned colLeft )
{
    d->colLeft = colLeft;
}

bool Window2Record::isFDefaultHdr() const
{
    return d->fDefaultHdr;
}

void Window2Record::setFDefaultHdr(bool fDefaultHdr )
{
    d->fDefaultHdr = fDefaultHdr;
}

bool Window2Record::isFDspFmlaRt() const
{
    return d->fDspFmlaRt;
}

void Window2Record::setFDspFmlaRt(bool fDspFmlaRt )
{
    d->fDspFmlaRt = fDspFmlaRt;
}

bool Window2Record::isFDspGridRt() const
{
    return d->fDspGridRt;
}

void Window2Record::setFDspGridRt(bool fDspGridRt )
{
    d->fDspGridRt = fDspGridRt;
}

bool Window2Record::isFDspGuts() const
{
    return d->fDspGuts;
}

void Window2Record::setFDspGuts(bool fDspGuts )
{
    d->fDspGuts = fDspGuts;
}

bool Window2Record::isFDspRwColRt() const
{
    return d->fDspRwColRt;
}

void Window2Record::setFDspRwColRt(bool fDspRwColRt )
{
    d->fDspRwColRt = fDspRwColRt;
}

bool Window2Record::isFDspZerosRt() const
{
    return d->fDspZerosRt;
}

void Window2Record::setFDspZerosRt(bool fDspZerosRt )
{
    d->fDspZerosRt = fDspZerosRt;
}

bool Window2Record::isFFrozenNoSplit() const
{
    return d->fFrozenNoSplit;
}

void Window2Record::setFFrozenNoSplit(bool fFrozenNoSplit )
{
    d->fFrozenNoSplit = fFrozenNoSplit;
}

bool Window2Record::isFFrozenRt() const
{
    return d->fFrozenRt;
}

void Window2Record::setFFrozenRt(bool fFrozenRt )
{
    d->fFrozenRt = fFrozenRt;
}

bool Window2Record::isFPaged() const
{
    return d->fPaged;
}

void Window2Record::setFPaged(bool fPaged )
{
    d->fPaged = fPaged;
}

bool Window2Record::isFRightToLeft() const
{
    return d->fRightToLeft;
}

void Window2Record::setFRightToLeft(bool fRightToLeft )
{
    d->fRightToLeft = fRightToLeft;
}

bool Window2Record::isFSLV() const
{
    return d->fSLV;
}

void Window2Record::setFSLV(bool fSLV )
{
    d->fSLV = fSLV;
}

bool Window2Record::isFSelected() const
{
    return d->fSelected;
}

void Window2Record::setFSelected(bool fSelected )
{
    d->fSelected = fSelected;
}

unsigned Window2Record::icvHdr() const
{
    return d->icvHdr;
}

void Window2Record::setIcvHdr(unsigned icvHdr )
{
    d->icvHdr = icvHdr;
}

unsigned Window2Record::rwTop() const
{
    return d->rwTop;
}

void Window2Record::setRwTop(unsigned rwTop )
{
    d->rwTop = rwTop;
}

unsigned Window2Record::wScaleNormal() const
{
    return d->wScaleNormal;
}

void Window2Record::setWScaleNormal(unsigned wScaleNormal )
{
    d->wScaleNormal = wScaleNormal;
}

unsigned Window2Record::wScaleSLV() const
{
    return d->wScaleSLV;
}

void Window2Record::setWScaleSLV(unsigned wScaleSLV )
{
    d->wScaleSLV = wScaleSLV;
}

bool Window2Record::hasSheetFields() const
{
    return d->hasSheetFields;
}

void Window2Record::setHasSheetFields( bool value )
{
    d->hasSheetFields = value;
}

void Window2Record::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    if (size < 10) {
        setIsValid(false);
        return;
    }
    setFDspFmlaRt(((readU8(data)) & 0x1) != 0);
    setFDspGridRt(((readU8(data) >> 1) & 0x1) != 0);
    setFDspRwColRt(((readU8(data) >> 2) & 0x1) != 0);
    setFFrozenRt(((readU8(data) >> 3) & 0x1) != 0);
    setFDspZerosRt(((readU8(data) >> 4) & 0x1) != 0);
    setFDefaultHdr(((readU8(data) >> 5) & 0x1) != 0);
    setFRightToLeft(((readU8(data) >> 6) & 0x1) != 0);
    setFDspGuts(((readU8(data) >> 7) & 0x1) != 0);
    setFFrozenNoSplit(((readU8(data + 1)) & 0x1) != 0);
    setFSelected(((readU8(data + 1) >> 1) & 0x1) != 0);
    setFPaged(((readU8(data + 1) >> 2) & 0x1) != 0);
    setFSLV(((readU8(data + 1) >> 3) & 0x1) != 0);
    setRwTop(readU16(data + 2));
    setColLeft(readU16(data + 4));
    setIcvHdr(readU16(data + 6));
    curOffset = 10;
    d->hasSheetFields = true;
    unsigned savedOffsetSheetFields = curOffset;
    {
        if (size < curOffset + 8) {
            d->hasSheetFields = false;
            goto sheetFieldsFailed;
        }
        setWScaleSLV(readU16(data + curOffset));
        setWScaleNormal(readU16(data + curOffset + 2));
        curOffset += 8;
    }
sheetFieldsFailed:
    if (!d->hasSheetFields) {
        curOffset = savedOffsetSheetFields;
    }
}

void Window2Record::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(1, isFDspFmlaRt());
    out.writeUnsigned(1, isFDspGridRt());
    out.writeUnsigned(1, isFDspRwColRt());
    out.writeUnsigned(1, isFFrozenRt());
    out.writeUnsigned(1, isFDspZerosRt());
    out.writeUnsigned(1, isFDefaultHdr());
    out.writeUnsigned(1, isFRightToLeft());
    out.writeUnsigned(1, isFDspGuts());
    out.writeUnsigned(1, isFFrozenNoSplit());
    out.writeUnsigned(1, isFSelected());
    out.writeUnsigned(1, isFPaged());
    out.writeUnsigned(1, isFSLV());
    out.writeUnsigned(4, 0);
    out.writeUnsigned(16, rwTop());
    out.writeUnsigned(16, colLeft());
    out.writeUnsigned(16, icvHdr());
    out.writeUnsigned(16, 0);
    if (hasSheetFields()) {
        out.writeUnsigned(16, wScaleSLV());
        out.writeUnsigned(16, wScaleNormal());
        out.writeUnsigned(16, 0);
        out.writeUnsigned(16, 0);
    }
}

void Window2Record::dump( std::ostream& out ) const
{
    out << "Window2" << std::endl;
    out << "         FDspFmlaRt : " << isFDspFmlaRt() << std::endl;
    out << "         FDspGridRt : " << isFDspGridRt() << std::endl;
    out << "        FDspRwColRt : " << isFDspRwColRt() << std::endl;
    out << "          FFrozenRt : " << isFFrozenRt() << std::endl;
    out << "        FDspZerosRt : " << isFDspZerosRt() << std::endl;
    out << "        FDefaultHdr : " << isFDefaultHdr() << std::endl;
    out << "       FRightToLeft : " << isFRightToLeft() << std::endl;
    out << "           FDspGuts : " << isFDspGuts() << std::endl;
    out << "     FFrozenNoSplit : " << isFFrozenNoSplit() << std::endl;
    out << "          FSelected : " << isFSelected() << std::endl;
    out << "             FPaged : " << isFPaged() << std::endl;
    out << "               FSLV : " << isFSLV() << std::endl;
    out << "              RwTop : " << rwTop() << std::endl;
    out << "            ColLeft : " << colLeft() << std::endl;
    out << "             IcvHdr : " << icvHdr() << std::endl;
    if (hasSheetFields()) {
        out << "          WScaleSLV : " << wScaleSLV() << std::endl;
        out << "       WScaleNormal : " << wScaleNormal() << std::endl;
    }
}

static Record* createWindow2Record(Swinder::Workbook *book)
{
    return new Window2Record(book);
}

// ========== ObjProtectedRecord ==========

const unsigned ObjProtectedRecord::id = 0x0063;

class ObjProtectedRecord::Private
{
public:
    unsigned fLockObj;
};

ObjProtectedRecord::ObjProtectedRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFLockObj(0);
}

ObjProtectedRecord::~ObjProtectedRecord()
{
    delete d;
}

ObjProtectedRecord::ObjProtectedRecord( const ObjProtectedRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ObjProtectedRecord& ObjProtectedRecord::operator=( const ObjProtectedRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned ObjProtectedRecord::fLockObj() const
{
    return d->fLockObj;
}

void ObjProtectedRecord::setFLockObj(unsigned fLockObj )
{
    d->fLockObj = fLockObj;
}

void ObjProtectedRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setFLockObj(readU16(data));
}

void ObjProtectedRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, fLockObj());
}

void ObjProtectedRecord::dump( std::ostream& out ) const
{
    out << "ObjProtected" << std::endl;
    out << "           FLockObj : " << fLockObj() << std::endl;
}

static Record* createObjProtectedRecord(Swinder::Workbook *book)
{
    return new ObjProtectedRecord(book);
}

// ========== ScenarioProtectRecord ==========

const unsigned ScenarioProtectRecord::id = 0x00dd;

class ScenarioProtectRecord::Private
{
public:
    unsigned fScenProtect;
};

ScenarioProtectRecord::ScenarioProtectRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFScenProtect(0);
}

ScenarioProtectRecord::~ScenarioProtectRecord()
{
    delete d;
}

ScenarioProtectRecord::ScenarioProtectRecord( const ScenarioProtectRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ScenarioProtectRecord& ScenarioProtectRecord::operator=( const ScenarioProtectRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned ScenarioProtectRecord::fScenProtect() const
{
    return d->fScenProtect;
}

void ScenarioProtectRecord::setFScenProtect(unsigned fScenProtect )
{
    d->fScenProtect = fScenProtect;
}

void ScenarioProtectRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setFScenProtect(readU16(data));
}

void ScenarioProtectRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, fScenProtect());
}

void ScenarioProtectRecord::dump( std::ostream& out ) const
{
    out << "ScenarioProtect" << std::endl;
    out << "       FScenProtect : " << fScenProtect() << std::endl;
}

static Record* createScenarioProtectRecord(Swinder::Workbook *book)
{
    return new ScenarioProtectRecord(book);
}

// ========== WinProtectRecord ==========

const unsigned WinProtectRecord::id = 0x0019;

class WinProtectRecord::Private
{
public:
    unsigned fLockWin;
};

WinProtectRecord::WinProtectRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFLockWin(0);
}

WinProtectRecord::~WinProtectRecord()
{
    delete d;
}

WinProtectRecord::WinProtectRecord( const WinProtectRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

WinProtectRecord& WinProtectRecord::operator=( const WinProtectRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned WinProtectRecord::fLockWin() const
{
    return d->fLockWin;
}

void WinProtectRecord::setFLockWin(unsigned fLockWin )
{
    d->fLockWin = fLockWin;
}

void WinProtectRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setFLockWin(readU16(data));
}

void WinProtectRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, fLockWin());
}

void WinProtectRecord::dump( std::ostream& out ) const
{
    out << "WinProtect" << std::endl;
    out << "           FLockWin : " << fLockWin() << std::endl;
}

static Record* createWinProtectRecord(Swinder::Workbook *book)
{
    return new WinProtectRecord(book);
}

// ========== Prot4RevRecord ==========

const unsigned Prot4RevRecord::id = 0x01af;

class Prot4RevRecord::Private
{
public:
    unsigned fRevLock;
};

Prot4RevRecord::Prot4RevRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFRevLock(0);
}

Prot4RevRecord::~Prot4RevRecord()
{
    delete d;
}

Prot4RevRecord::Prot4RevRecord( const Prot4RevRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

Prot4RevRecord& Prot4RevRecord::operator=( const Prot4RevRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned Prot4RevRecord::fRevLock() const
{
    return d->fRevLock;
}

void Prot4RevRecord::setFRevLock(unsigned fRevLock )
{
    d->fRevLock = fRevLock;
}

void Prot4RevRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setFRevLock(readU16(data));
}

void Prot4RevRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, fRevLock());
}

void Prot4RevRecord::dump( std::ostream& out ) const
{
    out << "Prot4Rev" << std::endl;
    out << "           FRevLock : " << fRevLock() << std::endl;
}

static Record* createProt4RevRecord(Swinder::Workbook *book)
{
    return new Prot4RevRecord(book);
}

// ========== Prot4RevPassRecord ==========

const unsigned Prot4RevPassRecord::id = 0x01bc;

class Prot4RevPassRecord::Private
{
public:
    unsigned protPwdRev;
};

Prot4RevPassRecord::Prot4RevPassRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setProtPwdRev(0);
}

Prot4RevPassRecord::~Prot4RevPassRecord()
{
    delete d;
}

Prot4RevPassRecord::Prot4RevPassRecord( const Prot4RevPassRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

Prot4RevPassRecord& Prot4RevPassRecord::operator=( const Prot4RevPassRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned Prot4RevPassRecord::protPwdRev() const
{
    return d->protPwdRev;
}

void Prot4RevPassRecord::setProtPwdRev(unsigned protPwdRev )
{
    d->protPwdRev = protPwdRev;
}

void Prot4RevPassRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setProtPwdRev(readU16(data));
}

void Prot4RevPassRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, protPwdRev());
}

void Prot4RevPassRecord::dump( std::ostream& out ) const
{
    out << "Prot4RevPass" << std::endl;
    out << "         ProtPwdRev : " << protPwdRev() << std::endl;
}

static Record* createProt4RevPassRecord(Swinder::Workbook *book)
{
    return new Prot4RevPassRecord(book);
}

// ========== PasswordRecord ==========

const unsigned PasswordRecord::id = 0x0013;

class PasswordRecord::Private
{
public:
    unsigned wPassword;
};

PasswordRecord::PasswordRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setWPassword(0);
}

PasswordRecord::~PasswordRecord()
{
    delete d;
}

PasswordRecord::PasswordRecord( const PasswordRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

PasswordRecord& PasswordRecord::operator=( const PasswordRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned PasswordRecord::wPassword() const
{
    return d->wPassword;
}

void PasswordRecord::setWPassword(unsigned wPassword )
{
    d->wPassword = wPassword;
}

void PasswordRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setWPassword(readU16(data));
}

void PasswordRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, wPassword());
}

void PasswordRecord::dump( std::ostream& out ) const
{
    out << "Password" << std::endl;
    out << "          WPassword : " << wPassword() << std::endl;
}

static Record* createPasswordRecord(Swinder::Workbook *book)
{
    return new PasswordRecord(book);
}

// ========== InterfaceHdrRecord ==========

const unsigned InterfaceHdrRecord::id = 0x00e1;

class InterfaceHdrRecord::Private
{
public:
    unsigned codePage;
};

InterfaceHdrRecord::InterfaceHdrRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCodePage(0x04B0);
}

InterfaceHdrRecord::~InterfaceHdrRecord()
{
    delete d;
}

InterfaceHdrRecord::InterfaceHdrRecord( const InterfaceHdrRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

InterfaceHdrRecord& InterfaceHdrRecord::operator=( const InterfaceHdrRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned InterfaceHdrRecord::codePage() const
{
    return d->codePage;
}

void InterfaceHdrRecord::setCodePage(unsigned codePage )
{
    d->codePage = codePage;
}

void InterfaceHdrRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setCodePage(readU16(data));
}

void InterfaceHdrRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, codePage());
}

void InterfaceHdrRecord::dump( std::ostream& out ) const
{
    out << "InterfaceHdr" << std::endl;
    out << "           CodePage : " << codePage() << std::endl;
}

static Record* createInterfaceHdrRecord(Swinder::Workbook *book)
{
    return new InterfaceHdrRecord(book);
}

// ========== MmsReservedRecord ==========

const unsigned MmsReservedRecord::id = 0x00c1;

class MmsReservedRecord::Private
{
public:
};

MmsReservedRecord::MmsReservedRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

MmsReservedRecord::~MmsReservedRecord()
{
    delete d;
}

MmsReservedRecord::MmsReservedRecord( const MmsReservedRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

MmsReservedRecord& MmsReservedRecord::operator=( const MmsReservedRecord& record )
{
    *d = *record.d;
    return *this;
}

void MmsReservedRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
}

void MmsReservedRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, 0);
}

void MmsReservedRecord::dump( std::ostream& out ) const
{
    out << "MmsReserved" << std::endl;
}

static Record* createMmsReservedRecord(Swinder::Workbook *book)
{
    return new MmsReservedRecord(book);
}

// ========== InterfaceEndRecord ==========

const unsigned InterfaceEndRecord::id = 0x00e2;

class InterfaceEndRecord::Private
{
public:
};

InterfaceEndRecord::InterfaceEndRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

InterfaceEndRecord::~InterfaceEndRecord()
{
    delete d;
}

InterfaceEndRecord::InterfaceEndRecord( const InterfaceEndRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

InterfaceEndRecord& InterfaceEndRecord::operator=( const InterfaceEndRecord& record )
{
    *d = *record.d;
    return *this;
}

void InterfaceEndRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void InterfaceEndRecord::writeData( XlsRecordOutputStream& ) const
{
}

void InterfaceEndRecord::dump( std::ostream& out ) const
{
    out << "InterfaceEnd" << std::endl;
}

static Record* createInterfaceEndRecord(Swinder::Workbook *book)
{
    return new InterfaceEndRecord(book);
}

// ========== LastWriteAccessRecord ==========

const unsigned LastWriteAccessRecord::id = 0x005c;

class LastWriteAccessRecord::Private
{
public:
    QByteArray unusedBlob;
    QString userName;
};

LastWriteAccessRecord::LastWriteAccessRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

LastWriteAccessRecord::~LastWriteAccessRecord()
{
    delete d;
}

LastWriteAccessRecord::LastWriteAccessRecord( const LastWriteAccessRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

LastWriteAccessRecord& LastWriteAccessRecord::operator=( const LastWriteAccessRecord& record )
{
    *d = *record.d;
    return *this;
}

QByteArray LastWriteAccessRecord::unusedBlob() const
{
    return d->unusedBlob;
}

void LastWriteAccessRecord::setUnusedBlob(QByteArray unusedBlob )
{
    d->unusedBlob = unusedBlob;
}

QString LastWriteAccessRecord::userName() const
{
    return d->userName;
}

void LastWriteAccessRecord::setUserName(QString userName )
{
    d->userName = userName;
}

void LastWriteAccessRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    bool stringLengthError = false;
    unsigned stringSize;
    if (size < 2) {
        setIsValid(false);
        return;
    }
    unsigned userNameLength = readU16(data);
    curOffset = 2;
    setUserName(readUnicodeString(data + curOffset, userNameLength, size - curOffset, &stringLengthError, &stringSize));
    if (stringLengthError) {
        setIsValid(false);
        return;
    }
    curOffset += stringSize;
    setUnusedBlob(QByteArray(reinterpret_cast<const char*>(data + curOffset), 0));
}

void LastWriteAccessRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, userName().length());
    out.writeUnicodeStringWithFlags(userName());
    out.writeBlob(unusedBlob());
}

void LastWriteAccessRecord::dump( std::ostream& out ) const
{
    out << "LastWriteAccess" << std::endl;
    out << "           UserName : " << userName() << std::endl;
    out << "         UnusedBlob : " << unusedBlob() << std::endl;
}

static Record* createLastWriteAccessRecord(Swinder::Workbook *book)
{
    return new LastWriteAccessRecord(book);
}

// ========== CodePageRecord ==========

const unsigned CodePageRecord::id = 0x0042;

class CodePageRecord::Private
{
public:
    unsigned codePage;
};

CodePageRecord::CodePageRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCodePage(1200);
}

CodePageRecord::~CodePageRecord()
{
    delete d;
}

CodePageRecord::CodePageRecord( const CodePageRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

CodePageRecord& CodePageRecord::operator=( const CodePageRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned CodePageRecord::codePage() const
{
    return d->codePage;
}

void CodePageRecord::setCodePage(unsigned codePage )
{
    d->codePage = codePage;
}

void CodePageRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setCodePage(readU16(data));
}

void CodePageRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, codePage());
}

void CodePageRecord::dump( std::ostream& out ) const
{
    out << "CodePage" << std::endl;
    out << "           CodePage : " << codePage() << std::endl;
}

static Record* createCodePageRecord(Swinder::Workbook *book)
{
    return new CodePageRecord(book);
}

// ========== DSFReservedRecord ==========

const unsigned DSFReservedRecord::id = 0x0161;

class DSFReservedRecord::Private
{
public:
};

DSFReservedRecord::DSFReservedRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

DSFReservedRecord::~DSFReservedRecord()
{
    delete d;
}

DSFReservedRecord::DSFReservedRecord( const DSFReservedRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

DSFReservedRecord& DSFReservedRecord::operator=( const DSFReservedRecord& record )
{
    *d = *record.d;
    return *this;
}

void DSFReservedRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
}

void DSFReservedRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, 0);
}

void DSFReservedRecord::dump( std::ostream& out ) const
{
    out << "DSFReserved" << std::endl;
}

static Record* createDSFReservedRecord(Swinder::Workbook *book)
{
    return new DSFReservedRecord(book);
}

// ========== RRTabIdRecord ==========

const unsigned RRTabIdRecord::id = 0x013d;

class RRTabIdRecord::Private
{
public:
    std::vector<unsigned> sheetId;
};

RRTabIdRecord::RRTabIdRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

RRTabIdRecord::~RRTabIdRecord()
{
    delete d;
}

RRTabIdRecord::RRTabIdRecord( const RRTabIdRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

RRTabIdRecord& RRTabIdRecord::operator=( const RRTabIdRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned RRTabIdRecord::sheetId( unsigned index ) const
{
    return d->sheetId[index];
}

void RRTabIdRecord::setSheetId( unsigned index, unsigned sheetId )
{
    d->sheetId[index] = sheetId;
}

unsigned RRTabIdRecord::sheetCount() const
{
    return d->sheetId.size();
}

void RRTabIdRecord::setSheetCount( unsigned sheetCount )
{
    d->sheetId.resize(sheetCount);
}

void RRTabIdRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    curOffset = 0;
    d->sheetId.resize(recordSize()/2);
    for (unsigned i = 0, endi = recordSize()/2; i < endi; ++i) {
        if (size < curOffset + 2) {
            setIsValid(false);
            return;
        }
        setSheetId(i, readU16(data + curOffset));
        curOffset += 2;
    }
}

void RRTabIdRecord::writeData( XlsRecordOutputStream& out ) const
{
    for (unsigned i = 0, endi = d->sheetId.size(); i < endi; ++i) {
        out.writeUnsigned(16, sheetId(i));
    }
}

void RRTabIdRecord::dump( std::ostream& out ) const
{
    out << "RRTabId" << std::endl;
    for (unsigned i = 0, endi = d->sheetId.size(); i < endi; ++i) {
        out << "        SheetId " << std::setw(3) << i <<" : " << sheetId(i) << std::endl;
    }
}

static Record* createRRTabIdRecord(Swinder::Workbook *book)
{
    return new RRTabIdRecord(book);
}

// ========== HideObjRecord ==========

const unsigned HideObjRecord::id = 0x008d;

class HideObjRecord::Private
{
public:
    HideObj hideObj;
};

HideObjRecord::HideObjRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setHideObj(ShowAll);
}

HideObjRecord::~HideObjRecord()
{
    delete d;
}

HideObjRecord::HideObjRecord( const HideObjRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

HideObjRecord& HideObjRecord::operator=( const HideObjRecord& record )
{
    *d = *record.d;
    return *this;
}

QString HideObjRecord::hideObjToString(HideObj hideObj)
{
    switch (hideObj) {
        case ShowAll: return QString("ShowAll");
        case ShowPlaceholder: return QString("ShowPlaceholder");
        case HideAll: return QString("HideAll");
        default: return QString("Unknown: %1").arg(hideObj);
    }
}

HideObjRecord::HideObj HideObjRecord::hideObj() const
{
    return d->hideObj;
}

void HideObjRecord::setHideObj(HideObj hideObj )
{
    d->hideObj = hideObj;
}

void HideObjRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setHideObj(static_cast<HideObj>(readU16(data)));
}

void HideObjRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, hideObj());
}

void HideObjRecord::dump( std::ostream& out ) const
{
    out << "HideObj" << std::endl;
    out << "            HideObj : " << hideObjToString(hideObj()) << std::endl;
}

static Record* createHideObjRecord(Swinder::Workbook *book)
{
    return new HideObjRecord(book);
}

// ========== CalcPrecisionRecord ==========

const unsigned CalcPrecisionRecord::id = 0x000e;

class CalcPrecisionRecord::Private
{
public:
    bool fullPrec;
};

CalcPrecisionRecord::CalcPrecisionRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFullPrec(false);
}

CalcPrecisionRecord::~CalcPrecisionRecord()
{
    delete d;
}

CalcPrecisionRecord::CalcPrecisionRecord( const CalcPrecisionRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

CalcPrecisionRecord& CalcPrecisionRecord::operator=( const CalcPrecisionRecord& record )
{
    *d = *record.d;
    return *this;
}

bool CalcPrecisionRecord::isFullPrec() const
{
    return d->fullPrec;
}

void CalcPrecisionRecord::setFullPrec(bool fullPrec )
{
    d->fullPrec = fullPrec;
}

void CalcPrecisionRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setFullPrec(readU16(data) != 0);
}

void CalcPrecisionRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, isFullPrec());
}

void CalcPrecisionRecord::dump( std::ostream& out ) const
{
    out << "CalcPrecision" << std::endl;
    out << "           FullPrec : " << isFullPrec() << std::endl;
}

static Record* createCalcPrecisionRecord(Swinder::Workbook *book)
{
    return new CalcPrecisionRecord(book);
}

// ========== RefreshAllRecord ==========

const unsigned RefreshAllRecord::id = 0x01b7;

class RefreshAllRecord::Private
{
public:
    bool refreshAll;
};

RefreshAllRecord::RefreshAllRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setRefreshAll(false);
}

RefreshAllRecord::~RefreshAllRecord()
{
    delete d;
}

RefreshAllRecord::RefreshAllRecord( const RefreshAllRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

RefreshAllRecord& RefreshAllRecord::operator=( const RefreshAllRecord& record )
{
    *d = *record.d;
    return *this;
}

bool RefreshAllRecord::isRefreshAll() const
{
    return d->refreshAll;
}

void RefreshAllRecord::setRefreshAll(bool refreshAll )
{
    d->refreshAll = refreshAll;
}

void RefreshAllRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setRefreshAll(readU16(data) != 0);
}

void RefreshAllRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, isRefreshAll());
}

void RefreshAllRecord::dump( std::ostream& out ) const
{
    out << "RefreshAll" << std::endl;
    out << "         RefreshAll : " << isRefreshAll() << std::endl;
}

static Record* createRefreshAllRecord(Swinder::Workbook *book)
{
    return new RefreshAllRecord(book);
}

// ========== BookBoolRecord ==========

const unsigned BookBoolRecord::id = 0x00da;

class BookBoolRecord::Private
{
public:
    bool envelopeInitDone;
    bool envelopeVisible;
    bool hasEnvelope;
    bool hideBorderUnselLists;
    bool noSaveSup;
    UpdateLinks updateLinks;
};

BookBoolRecord::BookBoolRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setEnvelopeInitDone(false);
    setEnvelopeVisible(false);
    setHasEnvelope(false);
    setHideBorderUnselLists(false);
    setNoSaveSup(false);
    setUpdateLinks(PromptUser);
}

BookBoolRecord::~BookBoolRecord()
{
    delete d;
}

BookBoolRecord::BookBoolRecord( const BookBoolRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

BookBoolRecord& BookBoolRecord::operator=( const BookBoolRecord& record )
{
    *d = *record.d;
    return *this;
}

QString BookBoolRecord::updateLinksToString(UpdateLinks updateLinks)
{
    switch (updateLinks) {
        case PromptUser: return QString("PromptUser");
        case DontUpdate: return QString("DontUpdate");
        case SilentUpdate: return QString("SilentUpdate");
        default: return QString("Unknown: %1").arg(updateLinks);
    }
}

bool BookBoolRecord::isEnvelopeInitDone() const
{
    return d->envelopeInitDone;
}

void BookBoolRecord::setEnvelopeInitDone(bool envelopeInitDone )
{
    d->envelopeInitDone = envelopeInitDone;
}

bool BookBoolRecord::isEnvelopeVisible() const
{
    return d->envelopeVisible;
}

void BookBoolRecord::setEnvelopeVisible(bool envelopeVisible )
{
    d->envelopeVisible = envelopeVisible;
}

bool BookBoolRecord::hasEnvelope() const
{
    return d->hasEnvelope;
}

void BookBoolRecord::setHasEnvelope(bool hasEnvelope )
{
    d->hasEnvelope = hasEnvelope;
}

bool BookBoolRecord::isHideBorderUnselLists() const
{
    return d->hideBorderUnselLists;
}

void BookBoolRecord::setHideBorderUnselLists(bool hideBorderUnselLists )
{
    d->hideBorderUnselLists = hideBorderUnselLists;
}

bool BookBoolRecord::isNoSaveSup() const
{
    return d->noSaveSup;
}

void BookBoolRecord::setNoSaveSup(bool noSaveSup )
{
    d->noSaveSup = noSaveSup;
}

BookBoolRecord::UpdateLinks BookBoolRecord::updateLinks() const
{
    return d->updateLinks;
}

void BookBoolRecord::setUpdateLinks(UpdateLinks updateLinks )
{
    d->updateLinks = updateLinks;
}

void BookBoolRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setNoSaveSup(((readU8(data)) & 0x1) != 0);
    setHasEnvelope(((readU8(data) >> 2) & 0x1) != 0);
    setEnvelopeVisible(((readU8(data) >> 3) & 0x1) != 0);
    setEnvelopeInitDone(((readU8(data) >> 4) & 0x1) != 0);
    setUpdateLinks(static_cast<UpdateLinks>(((readU8(data) >> 5) & 0x3)));
    setHideBorderUnselLists(((readU8(data + 1)) & 0x1) != 0);
}

void BookBoolRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(1, isNoSaveSup());
    out.writeUnsigned(1, 0);
    out.writeUnsigned(1, hasEnvelope());
    out.writeUnsigned(1, isEnvelopeVisible());
    out.writeUnsigned(1, isEnvelopeInitDone());
    out.writeUnsigned(2, updateLinks());
    out.writeUnsigned(1, 0);
    out.writeUnsigned(1, isHideBorderUnselLists());
    out.writeUnsigned(7, 0);
}

void BookBoolRecord::dump( std::ostream& out ) const
{
    out << "BookBool" << std::endl;
    out << "          NoSaveSup : " << isNoSaveSup() << std::endl;
    out << "        HasEnvelope : " << hasEnvelope() << std::endl;
    out << "    EnvelopeVisible : " << isEnvelopeVisible() << std::endl;
    out << "   EnvelopeInitDone : " << isEnvelopeInitDone() << std::endl;
    out << "        UpdateLinks : " << updateLinksToString(updateLinks()) << std::endl;
    out << "HideBorderUnselLists : " << isHideBorderUnselLists() << std::endl;
}

static Record* createBookBoolRecord(Swinder::Workbook *book)
{
    return new BookBoolRecord(book);
}

// ========== StyleRecord ==========

const unsigned StyleRecord::id = 0x0293;

class StyleRecord::Private
{
public:
    bool builtIn;
    unsigned builtInOutlineLevel;
    unsigned builtInType;
    QString styleName;
    unsigned xfIndex;
};

StyleRecord::StyleRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setBuiltIn(true);
    setBuiltInOutlineLevel(0xFF);
    setBuiltInType(0);
    setXfIndex(0);
}

StyleRecord::~StyleRecord()
{
    delete d;
}

StyleRecord::StyleRecord( const StyleRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

StyleRecord& StyleRecord::operator=( const StyleRecord& record )
{
    *d = *record.d;
    return *this;
}

bool StyleRecord::isBuiltIn() const
{
    return d->builtIn;
}

void StyleRecord::setBuiltIn(bool builtIn )
{
    d->builtIn = builtIn;
}

unsigned StyleRecord::builtInOutlineLevel() const
{
    return d->builtInOutlineLevel;
}

void StyleRecord::setBuiltInOutlineLevel(unsigned builtInOutlineLevel )
{
    d->builtInOutlineLevel = builtInOutlineLevel;
}

unsigned StyleRecord::builtInType() const
{
    return d->builtInType;
}

void StyleRecord::setBuiltInType(unsigned builtInType )
{
    d->builtInType = builtInType;
}

QString StyleRecord::styleName() const
{
    return d->styleName;
}

void StyleRecord::setStyleName(QString styleName )
{
    d->styleName = styleName;
}

unsigned StyleRecord::xfIndex() const
{
    return d->xfIndex;
}

void StyleRecord::setXfIndex(unsigned xfIndex )
{
    d->xfIndex = xfIndex;
}

void StyleRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    bool stringLengthError = false;
    unsigned stringSize;
    if (size < 4) {
        setIsValid(false);
        return;
    }
    setXfIndex(((readU16(data)) & 0xfff));
    setBuiltIn(((readU8(data + 1) >> 7) & 0x1) != 0);
    setBuiltInType(readU8(data + 2));
    setBuiltInOutlineLevel(readU8(data + 3));
    curOffset = 4;
    if (!isBuiltIn()) {
        if (size < curOffset + 2) {
            setIsValid(false);
            return;
        }
        unsigned nameLength = readU16(data + curOffset);
        curOffset += 2;
        setStyleName(readUnicodeString(data + curOffset, nameLength, size - curOffset, &stringLengthError, &stringSize));
        if (stringLengthError) {
            setIsValid(false);
            return;
        }
        curOffset += stringSize;
    }
}

void StyleRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(12, xfIndex());
    out.writeUnsigned(3, 0);
    out.writeUnsigned(1, isBuiltIn());
    out.writeUnsigned(8, builtInType());
    out.writeUnsigned(8, builtInOutlineLevel());
    if (!isBuiltIn()) {
        out.writeUnsigned(16, styleName().length());
        out.writeUnicodeStringWithFlags(styleName());
    }
}

void StyleRecord::dump( std::ostream& out ) const
{
    out << "Style" << std::endl;
    out << "            XfIndex : " << xfIndex() << std::endl;
    out << "            BuiltIn : " << isBuiltIn() << std::endl;
    out << "        BuiltInType : " << builtInType() << std::endl;
    out << "BuiltInOutlineLevel : " << builtInOutlineLevel() << std::endl;
    if (!isBuiltIn()) {
        out << "          StyleName : " << styleName() << std::endl;
    }
}

static Record* createStyleRecord(Swinder::Workbook *book)
{
    return new StyleRecord(book);
}

// ========== UsesELFsRecord ==========

const unsigned UsesELFsRecord::id = 0x0160;

class UsesELFsRecord::Private
{
public:
    bool usesElfs;
};

UsesELFsRecord::UsesELFsRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setUsesElfs(false);
}

UsesELFsRecord::~UsesELFsRecord()
{
    delete d;
}

UsesELFsRecord::UsesELFsRecord( const UsesELFsRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

UsesELFsRecord& UsesELFsRecord::operator=( const UsesELFsRecord& record )
{
    *d = *record.d;
    return *this;
}

bool UsesELFsRecord::isUsesElfs() const
{
    return d->usesElfs;
}

void UsesELFsRecord::setUsesElfs(bool usesElfs )
{
    d->usesElfs = usesElfs;
}

void UsesELFsRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setUsesElfs(readU16(data) != 0);
}

void UsesELFsRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, isUsesElfs());
}

void UsesELFsRecord::dump( std::ostream& out ) const
{
    out << "UsesELFs" << std::endl;
    out << "           UsesElfs : " << isUsesElfs() << std::endl;
}

static Record* createUsesELFsRecord(Swinder::Workbook *book)
{
    return new UsesELFsRecord(book);
}

// ========== CountryRecord ==========

const unsigned CountryRecord::id = 0x008c;

class CountryRecord::Private
{
public:
    unsigned countryDef;
    unsigned countryWinIni;
};

CountryRecord::CountryRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCountryDef(1);
    setCountryWinIni(1);
}

CountryRecord::~CountryRecord()
{
    delete d;
}

CountryRecord::CountryRecord( const CountryRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

CountryRecord& CountryRecord::operator=( const CountryRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned CountryRecord::countryDef() const
{
    return d->countryDef;
}

void CountryRecord::setCountryDef(unsigned countryDef )
{
    d->countryDef = countryDef;
}

unsigned CountryRecord::countryWinIni() const
{
    return d->countryWinIni;
}

void CountryRecord::setCountryWinIni(unsigned countryWinIni )
{
    d->countryWinIni = countryWinIni;
}

void CountryRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 4) {
        setIsValid(false);
        return;
    }
    setCountryDef(readU16(data));
    setCountryWinIni(readU16(data + 2));
}

void CountryRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, countryDef());
    out.writeUnsigned(16, countryWinIni());
}

void CountryRecord::dump( std::ostream& out ) const
{
    out << "Country" << std::endl;
    out << "         CountryDef : " << countryDef() << std::endl;
    out << "      CountryWinIni : " << countryWinIni() << std::endl;
}

static Record* createCountryRecord(Swinder::Workbook *book)
{
    return new CountryRecord(book);
}

// ========== ExtSSTRecord ==========

const unsigned ExtSSTRecord::id = 0x00ff;

class ExtSSTRecord::Private
{
public:
    std::vector<unsigned> cbOffset;
    unsigned dsst;
    std::vector<unsigned> ib;
};

ExtSSTRecord::ExtSSTRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setDsst(8);
}

ExtSSTRecord::~ExtSSTRecord()
{
    delete d;
}

ExtSSTRecord::ExtSSTRecord( const ExtSSTRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ExtSSTRecord& ExtSSTRecord::operator=( const ExtSSTRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned ExtSSTRecord::cbOffset( unsigned index ) const
{
    return d->cbOffset[index];
}

void ExtSSTRecord::setCbOffset( unsigned index, unsigned cbOffset )
{
    d->cbOffset[index] = cbOffset;
}

unsigned ExtSSTRecord::dsst() const
{
    return d->dsst;
}

void ExtSSTRecord::setDsst(unsigned dsst )
{
    d->dsst = dsst;
}

unsigned ExtSSTRecord::ib( unsigned index ) const
{
    return d->ib[index];
}

void ExtSSTRecord::setIb( unsigned index, unsigned ib )
{
    d->ib[index] = ib;
}

unsigned ExtSSTRecord::groupCount() const
{
    return d->ib.size();
}

void ExtSSTRecord::setGroupCount( unsigned groupCount )
{
    d->ib.resize(groupCount);
    d->cbOffset.resize(groupCount);
}

void ExtSSTRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    if (size < 2) {
        setIsValid(false);
        return;
    }
    setDsst(readU16(data));
    curOffset = 2;
    d->ib.resize((recordSize() - 2) / 8);
    d->cbOffset.resize((recordSize() - 2) / 8);
    for (unsigned i = 0, endi = (recordSize() - 2) / 8; i < endi; ++i) {
        if (size < curOffset + 8) {
            setIsValid(false);
            return;
        }
        setIb(i, readU32(data + curOffset));
        setCbOffset(i, readU16(data + curOffset + 4));
        curOffset += 8;
    }
}

void ExtSSTRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, dsst());
    for (unsigned i = 0, endi = d->ib.size(); i < endi; ++i) {
        out.writeUnsigned(32, ib(i));
        out.writeUnsigned(16, cbOffset(i));
        out.writeUnsigned(16, 0);
    }
}

void ExtSSTRecord::dump( std::ostream& out ) const
{
    out << "ExtSST" << std::endl;
    out << "               Dsst : " << dsst() << std::endl;
    for (unsigned i = 0, endi = d->ib.size(); i < endi; ++i) {
        out << "             Ib " << std::setw(3) << i <<" : " << ib(i) << std::endl;
        out << "       CbOffset " << std::setw(3) << i <<" : " << cbOffset(i) << std::endl;
    }
}

static Record* createExtSSTRecord(Swinder::Workbook *book)
{
    return new ExtSSTRecord(book);
}

// ========== IndexRecord ==========

const unsigned IndexRecord::id = 0x020b;

class IndexRecord::Private
{
public:
    std::vector<unsigned> dbCellPosition;
    unsigned defColWidthPosition;
    unsigned rowMaxPlus1;
    unsigned rowMin;
};

IndexRecord::IndexRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setDefColWidthPosition(0);
    setRowMaxPlus1(0);
    setRowMin(0);
}

IndexRecord::~IndexRecord()
{
    delete d;
}

IndexRecord::IndexRecord( const IndexRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

IndexRecord& IndexRecord::operator=( const IndexRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned IndexRecord::dbCellPosition( unsigned index ) const
{
    return d->dbCellPosition[index];
}

void IndexRecord::setDbCellPosition( unsigned index, unsigned dbCellPosition )
{
    d->dbCellPosition[index] = dbCellPosition;
}

unsigned IndexRecord::defColWidthPosition() const
{
    return d->defColWidthPosition;
}

void IndexRecord::setDefColWidthPosition(unsigned defColWidthPosition )
{
    d->defColWidthPosition = defColWidthPosition;
}

unsigned IndexRecord::rowMaxPlus1() const
{
    return d->rowMaxPlus1;
}

void IndexRecord::setRowMaxPlus1(unsigned rowMaxPlus1 )
{
    d->rowMaxPlus1 = rowMaxPlus1;
}

unsigned IndexRecord::rowMin() const
{
    return d->rowMin;
}

void IndexRecord::setRowMin(unsigned rowMin )
{
    d->rowMin = rowMin;
}

unsigned IndexRecord::rowBlockCount() const
{
    return d->dbCellPosition.size();
}

void IndexRecord::setRowBlockCount( unsigned rowBlockCount )
{
    d->dbCellPosition.resize(rowBlockCount);
}

void IndexRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    if (size < 16) {
        setIsValid(false);
        return;
    }
    setRowMin(readU32(data + 4));
    setRowMaxPlus1(readU32(data + 8));
    setDefColWidthPosition(readU32(data + 12));
    curOffset = 16;
    d->dbCellPosition.resize((recordSize() - 16) / 4);
    for (unsigned i = 0, endi = (recordSize() - 16) / 4; i < endi; ++i) {
        if (size < curOffset + 4) {
            setIsValid(false);
            return;
        }
        setDbCellPosition(i, readU32(data + curOffset));
        curOffset += 4;
    }
}

void IndexRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(32, 0);
    out.writeUnsigned(32, rowMin());
    out.writeUnsigned(32, rowMaxPlus1());
    out.writeUnsigned(32, defColWidthPosition());
    for (unsigned i = 0, endi = d->dbCellPosition.size(); i < endi; ++i) {
        out.writeUnsigned(32, dbCellPosition(i));
    }
}

void IndexRecord::dump( std::ostream& out ) const
{
    out << "Index" << std::endl;
    out << "             RowMin : " << rowMin() << std::endl;
    out << "        RowMaxPlus1 : " << rowMaxPlus1() << std::endl;
    out << "DefColWidthPosition : " << defColWidthPosition() << std::endl;
    for (unsigned i = 0, endi = d->dbCellPosition.size(); i < endi; ++i) {
        out << " DbCellPosition " << std::setw(3) << i <<" : " << dbCellPosition(i) << std::endl;
    }
}

static Record* createIndexRecord(Swinder::Workbook *book)
{
    return new IndexRecord(book);
}

// ========== DBCellRecord ==========

const unsigned DBCellRecord::id = 0x00d7;

class DBCellRecord::Private
{
public:
    std::vector<unsigned> cellOffset;
    unsigned firstRowOffset;
};

DBCellRecord::DBCellRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setFirstRowOffset(0);
}

DBCellRecord::~DBCellRecord()
{
    delete d;
}

DBCellRecord::DBCellRecord( const DBCellRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

DBCellRecord& DBCellRecord::operator=( const DBCellRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned DBCellRecord::cellOffset( unsigned index ) const
{
    return d->cellOffset[index];
}

void DBCellRecord::setCellOffset( unsigned index, unsigned cellOffset )
{
    d->cellOffset[index] = cellOffset;
}

unsigned DBCellRecord::firstRowOffset() const
{
    return d->firstRowOffset;
}

void DBCellRecord::setFirstRowOffset(unsigned firstRowOffset )
{
    d->firstRowOffset = firstRowOffset;
}

unsigned DBCellRecord::rowCount() const
{
    return d->cellOffset.size();
}

void DBCellRecord::setRowCount( unsigned rowCount )
{
    d->cellOffset.resize(rowCount);
}

void DBCellRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    if (size < 4) {
        setIsValid(false);
        return;
    }
    setFirstRowOffset(readU32(data));
    curOffset = 4;
    d->cellOffset.resize((recordSize() - 4) / 2);
    for (unsigned i = 0, endi = (recordSize() - 4) / 2; i < endi; ++i) {
        if (size < curOffset + 2) {
            setIsValid(false);
            return;
        }
        setCellOffset(i, readU16(data + curOffset));
        curOffset += 2;
    }
}

void DBCellRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(32, firstRowOffset());
    for (unsigned i = 0, endi = d->cellOffset.size(); i < endi; ++i) {
        out.writeUnsigned(16, cellOffset(i));
    }
}

void DBCellRecord::dump( std::ostream& out ) const
{
    out << "DBCell" << std::endl;
    out << "     FirstRowOffset : " << firstRowOffset() << std::endl;
    for (unsigned i = 0, endi = d->cellOffset.size(); i < endi; ++i) {
        out << "     CellOffset " << std::setw(3) << i <<" : " << cellOffset(i) << std::endl;
    }
}

static Record* createDBCellRecord(Swinder::Workbook *book)
{
    return new DBCellRecord(book);
}

// ========== CalcCountRecord ==========

const unsigned CalcCountRecord::id = 0x000c;

class CalcCountRecord::Private
{
public:
    int iterCount;
};

CalcCountRecord::CalcCountRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setIterCount(100);
}

CalcCountRecord::~CalcCountRecord()
{
    delete d;
}

CalcCountRecord::CalcCountRecord( const CalcCountRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

CalcCountRecord& CalcCountRecord::operator=( const CalcCountRecord& record )
{
    *d = *record.d;
    return *this;
}

int CalcCountRecord::iterCount() const
{
    return d->iterCount;
}

void CalcCountRecord::setIterCount(int iterCount )
{
    d->iterCount = iterCount;
}

void CalcCountRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setIterCount(readS16(data));
}

void CalcCountRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeSigned(16, iterCount());
}

void CalcCountRecord::dump( std::ostream& out ) const
{
    out << "CalcCount" << std::endl;
    out << "          IterCount : " << iterCount() << std::endl;
}

static Record* createCalcCountRecord(Swinder::Workbook *book)
{
    return new CalcCountRecord(book);
}

// ========== CalcRefModeRecord ==========

const unsigned CalcRefModeRecord::id = 0x000f;

class CalcRefModeRecord::Private
{
public:
    bool refA1;
};

CalcRefModeRecord::CalcRefModeRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setRefA1(true);
}

CalcRefModeRecord::~CalcRefModeRecord()
{
    delete d;
}

CalcRefModeRecord::CalcRefModeRecord( const CalcRefModeRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

CalcRefModeRecord& CalcRefModeRecord::operator=( const CalcRefModeRecord& record )
{
    *d = *record.d;
    return *this;
}

bool CalcRefModeRecord::isRefA1() const
{
    return d->refA1;
}

void CalcRefModeRecord::setRefA1(bool refA1 )
{
    d->refA1 = refA1;
}

void CalcRefModeRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setRefA1(readU16(data) != 0);
}

void CalcRefModeRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, isRefA1());
}

void CalcRefModeRecord::dump( std::ostream& out ) const
{
    out << "CalcRefMode" << std::endl;
    out << "              RefA1 : " << isRefA1() << std::endl;
}

static Record* createCalcRefModeRecord(Swinder::Workbook *book)
{
    return new CalcRefModeRecord(book);
}

// ========== CalcIterRecord ==========

const unsigned CalcIterRecord::id = 0x0011;

class CalcIterRecord::Private
{
public:
    bool iterativeCalcs;
};

CalcIterRecord::CalcIterRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setIterativeCalcs(false);
}

CalcIterRecord::~CalcIterRecord()
{
    delete d;
}

CalcIterRecord::CalcIterRecord( const CalcIterRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

CalcIterRecord& CalcIterRecord::operator=( const CalcIterRecord& record )
{
    *d = *record.d;
    return *this;
}

bool CalcIterRecord::isIterativeCalcs() const
{
    return d->iterativeCalcs;
}

void CalcIterRecord::setIterativeCalcs(bool iterativeCalcs )
{
    d->iterativeCalcs = iterativeCalcs;
}

void CalcIterRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setIterativeCalcs(readU16(data) != 0);
}

void CalcIterRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, isIterativeCalcs());
}

void CalcIterRecord::dump( std::ostream& out ) const
{
    out << "CalcIter" << std::endl;
    out << "     IterativeCalcs : " << isIterativeCalcs() << std::endl;
}

static Record* createCalcIterRecord(Swinder::Workbook *book)
{
    return new CalcIterRecord(book);
}

// ========== CalcDeltaRecord ==========

const unsigned CalcDeltaRecord::id = 0x0010;

class CalcDeltaRecord::Private
{
public:
    double numDelta;
};

CalcDeltaRecord::CalcDeltaRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setNumDelta(0.001);
}

CalcDeltaRecord::~CalcDeltaRecord()
{
    delete d;
}

CalcDeltaRecord::CalcDeltaRecord( const CalcDeltaRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

CalcDeltaRecord& CalcDeltaRecord::operator=( const CalcDeltaRecord& record )
{
    *d = *record.d;
    return *this;
}

double CalcDeltaRecord::numDelta() const
{
    return d->numDelta;
}

void CalcDeltaRecord::setNumDelta(double numDelta )
{
    d->numDelta = numDelta;
}

void CalcDeltaRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 8) {
        setIsValid(false);
        return;
    }
    setNumDelta(readFloat64(data));
}

void CalcDeltaRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeFloat(64, numDelta());
}

void CalcDeltaRecord::dump( std::ostream& out ) const
{
    out << "CalcDelta" << std::endl;
    out << "           NumDelta : " << numDelta() << std::endl;
}

static Record* createCalcDeltaRecord(Swinder::Workbook *book)
{
    return new CalcDeltaRecord(book);
}

// ========== CalcSaveRecalcRecord ==========

const unsigned CalcSaveRecalcRecord::id = 0x005f;

class CalcSaveRecalcRecord::Private
{
public:
    bool recalcBeforeSave;
};

CalcSaveRecalcRecord::CalcSaveRecalcRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setRecalcBeforeSave(false);
}

CalcSaveRecalcRecord::~CalcSaveRecalcRecord()
{
    delete d;
}

CalcSaveRecalcRecord::CalcSaveRecalcRecord( const CalcSaveRecalcRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

CalcSaveRecalcRecord& CalcSaveRecalcRecord::operator=( const CalcSaveRecalcRecord& record )
{
    *d = *record.d;
    return *this;
}

bool CalcSaveRecalcRecord::isRecalcBeforeSave() const
{
    return d->recalcBeforeSave;
}

void CalcSaveRecalcRecord::setRecalcBeforeSave(bool recalcBeforeSave )
{
    d->recalcBeforeSave = recalcBeforeSave;
}

void CalcSaveRecalcRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setRecalcBeforeSave(readU16(data) != 0);
}

void CalcSaveRecalcRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, isRecalcBeforeSave());
}

void CalcSaveRecalcRecord::dump( std::ostream& out ) const
{
    out << "CalcSaveRecalc" << std::endl;
    out << "   RecalcBeforeSave : " << isRecalcBeforeSave() << std::endl;
}

static Record* createCalcSaveRecalcRecord(Swinder::Workbook *book)
{
    return new CalcSaveRecalcRecord(book);
}

// ========== PrintRowColRecord ==========

const unsigned PrintRowColRecord::id = 0x002a;

class PrintRowColRecord::Private
{
public:
    bool printRowColHeaders;
};

PrintRowColRecord::PrintRowColRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setPrintRowColHeaders(false);
}

PrintRowColRecord::~PrintRowColRecord()
{
    delete d;
}

PrintRowColRecord::PrintRowColRecord( const PrintRowColRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

PrintRowColRecord& PrintRowColRecord::operator=( const PrintRowColRecord& record )
{
    *d = *record.d;
    return *this;
}

bool PrintRowColRecord::isPrintRowColHeaders() const
{
    return d->printRowColHeaders;
}

void PrintRowColRecord::setPrintRowColHeaders(bool printRowColHeaders )
{
    d->printRowColHeaders = printRowColHeaders;
}

void PrintRowColRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setPrintRowColHeaders(readU16(data) != 0);
}

void PrintRowColRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, isPrintRowColHeaders());
}

void PrintRowColRecord::dump( std::ostream& out ) const
{
    out << "PrintRowCol" << std::endl;
    out << " PrintRowColHeaders : " << isPrintRowColHeaders() << std::endl;
}

static Record* createPrintRowColRecord(Swinder::Workbook *book)
{
    return new PrintRowColRecord(book);
}

// ========== PrintGridRecord ==========

const unsigned PrintGridRecord::id = 0x002b;

class PrintGridRecord::Private
{
public:
    bool printGrid;
};

PrintGridRecord::PrintGridRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setPrintGrid(false);
}

PrintGridRecord::~PrintGridRecord()
{
    delete d;
}

PrintGridRecord::PrintGridRecord( const PrintGridRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

PrintGridRecord& PrintGridRecord::operator=( const PrintGridRecord& record )
{
    *d = *record.d;
    return *this;
}

bool PrintGridRecord::isPrintGrid() const
{
    return d->printGrid;
}

void PrintGridRecord::setPrintGrid(bool printGrid )
{
    d->printGrid = printGrid;
}

void PrintGridRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setPrintGrid(((readU8(data)) & 0x1) != 0);
}

void PrintGridRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(1, isPrintGrid());
    out.writeUnsigned(15, 0);
}

void PrintGridRecord::dump( std::ostream& out ) const
{
    out << "PrintGrid" << std::endl;
    out << "          PrintGrid : " << isPrintGrid() << std::endl;
}

static Record* createPrintGridRecord(Swinder::Workbook *book)
{
    return new PrintGridRecord(book);
}

// ========== GutsRecord ==========

const unsigned GutsRecord::id = 0x0080;

class GutsRecord::Private
{
public:
    unsigned maxColumnOutlineLevel;
    unsigned maxRowOutlineLevel;
};

GutsRecord::GutsRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setMaxColumnOutlineLevel(0);
    setMaxRowOutlineLevel(0);
}

GutsRecord::~GutsRecord()
{
    delete d;
}

GutsRecord::GutsRecord( const GutsRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

GutsRecord& GutsRecord::operator=( const GutsRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned GutsRecord::maxColumnOutlineLevel() const
{
    return d->maxColumnOutlineLevel;
}

void GutsRecord::setMaxColumnOutlineLevel(unsigned maxColumnOutlineLevel )
{
    d->maxColumnOutlineLevel = maxColumnOutlineLevel;
}

unsigned GutsRecord::maxRowOutlineLevel() const
{
    return d->maxRowOutlineLevel;
}

void GutsRecord::setMaxRowOutlineLevel(unsigned maxRowOutlineLevel )
{
    d->maxRowOutlineLevel = maxRowOutlineLevel;
}

void GutsRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 8) {
        setIsValid(false);
        return;
    }
    setMaxRowOutlineLevel(readU16(data + 4));
    setMaxColumnOutlineLevel(readU16(data + 6));
}

void GutsRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, 0);
    out.writeUnsigned(16, 0);
    out.writeUnsigned(16, maxRowOutlineLevel());
    out.writeUnsigned(16, maxColumnOutlineLevel());
}

void GutsRecord::dump( std::ostream& out ) const
{
    out << "Guts" << std::endl;
    out << " MaxRowOutlineLevel : " << maxRowOutlineLevel() << std::endl;
    out << "MaxColumnOutlineLevel : " << maxColumnOutlineLevel() << std::endl;
}

static Record* createGutsRecord(Swinder::Workbook *book)
{
    return new GutsRecord(book);
}

// ========== WsBoolRecord ==========

const unsigned WsBoolRecord::id = 0x0081;

class WsBoolRecord::Private
{
public:
    bool altExprEval;
    bool altFormulaEntry;
    bool applyStylesInOutline;
    bool colSumsRight;
    bool dialogSheet;
    bool fitToPage;
    bool rowSumsBelow;
    bool showAutoBreaks;
    bool syncHorizScrolling;
    bool syncVertScrolling;
};

WsBoolRecord::WsBoolRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setAltExprEval(false);
    setAltFormulaEntry(false);
    setApplyStylesInOutline(false);
    setColSumsRight(true);
    setDialogSheet(false);
    setFitToPage(false);
    setRowSumsBelow(true);
    setShowAutoBreaks(true);
    setSyncHorizScrolling(false);
    setSyncVertScrolling(false);
}

WsBoolRecord::~WsBoolRecord()
{
    delete d;
}

WsBoolRecord::WsBoolRecord( const WsBoolRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

WsBoolRecord& WsBoolRecord::operator=( const WsBoolRecord& record )
{
    *d = *record.d;
    return *this;
}

bool WsBoolRecord::isAltExprEval() const
{
    return d->altExprEval;
}

void WsBoolRecord::setAltExprEval(bool altExprEval )
{
    d->altExprEval = altExprEval;
}

bool WsBoolRecord::isAltFormulaEntry() const
{
    return d->altFormulaEntry;
}

void WsBoolRecord::setAltFormulaEntry(bool altFormulaEntry )
{
    d->altFormulaEntry = altFormulaEntry;
}

bool WsBoolRecord::isApplyStylesInOutline() const
{
    return d->applyStylesInOutline;
}

void WsBoolRecord::setApplyStylesInOutline(bool applyStylesInOutline )
{
    d->applyStylesInOutline = applyStylesInOutline;
}

bool WsBoolRecord::isColSumsRight() const
{
    return d->colSumsRight;
}

void WsBoolRecord::setColSumsRight(bool colSumsRight )
{
    d->colSumsRight = colSumsRight;
}

bool WsBoolRecord::isDialogSheet() const
{
    return d->dialogSheet;
}

void WsBoolRecord::setDialogSheet(bool dialogSheet )
{
    d->dialogSheet = dialogSheet;
}

bool WsBoolRecord::isFitToPage() const
{
    return d->fitToPage;
}

void WsBoolRecord::setFitToPage(bool fitToPage )
{
    d->fitToPage = fitToPage;
}

bool WsBoolRecord::isRowSumsBelow() const
{
    return d->rowSumsBelow;
}

void WsBoolRecord::setRowSumsBelow(bool rowSumsBelow )
{
    d->rowSumsBelow = rowSumsBelow;
}

bool WsBoolRecord::isShowAutoBreaks() const
{
    return d->showAutoBreaks;
}

void WsBoolRecord::setShowAutoBreaks(bool showAutoBreaks )
{
    d->showAutoBreaks = showAutoBreaks;
}

bool WsBoolRecord::isSyncHorizScrolling() const
{
    return d->syncHorizScrolling;
}

void WsBoolRecord::setSyncHorizScrolling(bool syncHorizScrolling )
{
    d->syncHorizScrolling = syncHorizScrolling;
}

bool WsBoolRecord::isSyncVertScrolling() const
{
    return d->syncVertScrolling;
}

void WsBoolRecord::setSyncVertScrolling(bool syncVertScrolling )
{
    d->syncVertScrolling = syncVertScrolling;
}

void WsBoolRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setShowAutoBreaks(((readU8(data)) & 0x1) != 0);
    setDialogSheet(((readU8(data) >> 4) & 0x1) != 0);
    setApplyStylesInOutline(((readU8(data) >> 5) & 0x1) != 0);
    setRowSumsBelow(((readU8(data) >> 6) & 0x1) != 0);
    setColSumsRight(((readU8(data) >> 7) & 0x1) != 0);
    setFitToPage(((readU8(data + 1)) & 0x1) != 0);
    setSyncHorizScrolling(((readU8(data + 1) >> 4) & 0x1) != 0);
    setSyncVertScrolling(((readU8(data + 1) >> 5) & 0x1) != 0);
    setAltExprEval(((readU8(data + 1) >> 6) & 0x1) != 0);
    setAltFormulaEntry(((readU8(data + 1) >> 7) & 0x1) != 0);
}

void WsBoolRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(1, isShowAutoBreaks());
    out.writeUnsigned(3, 0);
    out.writeUnsigned(1, isDialogSheet());
    out.writeUnsigned(1, isApplyStylesInOutline());
    out.writeUnsigned(1, isRowSumsBelow());
    out.writeUnsigned(1, isColSumsRight());
    out.writeUnsigned(1, isFitToPage());
    out.writeUnsigned(1, 0);
    out.writeUnsigned(2, 0);
    out.writeUnsigned(1, isSyncHorizScrolling());
    out.writeUnsigned(1, isSyncVertScrolling());
    out.writeUnsigned(1, isAltExprEval());
    out.writeUnsigned(1, isAltFormulaEntry());
}

void WsBoolRecord::dump( std::ostream& out ) const
{
    out << "WsBool" << std::endl;
    out << "     ShowAutoBreaks : " << isShowAutoBreaks() << std::endl;
    out << "        DialogSheet : " << isDialogSheet() << std::endl;
    out << "ApplyStylesInOutline : " << isApplyStylesInOutline() << std::endl;
    out << "       RowSumsBelow : " << isRowSumsBelow() << std::endl;
    out << "       ColSumsRight : " << isColSumsRight() << std::endl;
    out << "          FitToPage : " << isFitToPage() << std::endl;
    out << " SyncHorizScrolling : " << isSyncHorizScrolling() << std::endl;
    out << "  SyncVertScrolling : " << isSyncVertScrolling() << std::endl;
    out << "        AltExprEval : " << isAltExprEval() << std::endl;
    out << "    AltFormulaEntry : " << isAltFormulaEntry() << std::endl;
}

static Record* createWsBoolRecord(Swinder::Workbook *book)
{
    return new WsBoolRecord(book);
}

// ========== FeatHdrRecord ==========

const unsigned FeatHdrRecord::id = 0x0867;

class FeatHdrRecord::Private
{
public:
};

FeatHdrRecord::FeatHdrRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

FeatHdrRecord::~FeatHdrRecord()
{
    delete d;
}

FeatHdrRecord::FeatHdrRecord( const FeatHdrRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

FeatHdrRecord& FeatHdrRecord::operator=( const FeatHdrRecord& record )
{
    *d = *record.d;
    return *this;
}

void FeatHdrRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void FeatHdrRecord::writeData( XlsRecordOutputStream& ) const
{
}

void FeatHdrRecord::dump( std::ostream& out ) const
{
    out << "FeatHdr" << std::endl;
}

static Record* createFeatHdrRecord(Swinder::Workbook *book)
{
    return new FeatHdrRecord(book);
}

// ========== HeaderFooterRecord ==========

const unsigned HeaderFooterRecord::id = 0x089c;

class HeaderFooterRecord::Private
{
public:
};

HeaderFooterRecord::HeaderFooterRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

HeaderFooterRecord::~HeaderFooterRecord()
{
    delete d;
}

HeaderFooterRecord::HeaderFooterRecord( const HeaderFooterRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

HeaderFooterRecord& HeaderFooterRecord::operator=( const HeaderFooterRecord& record )
{
    *d = *record.d;
    return *this;
}

void HeaderFooterRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void HeaderFooterRecord::writeData( XlsRecordOutputStream& ) const
{
}

void HeaderFooterRecord::dump( std::ostream& out ) const
{
    out << "HeaderFooter" << std::endl;
}

static Record* createHeaderFooterRecord(Swinder::Workbook *book)
{
    return new HeaderFooterRecord(book);
}

// ========== PLVRecord ==========

const unsigned PLVRecord::id = 0x088b;

class PLVRecord::Private
{
public:
};

PLVRecord::PLVRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

PLVRecord::~PLVRecord()
{
    delete d;
}

PLVRecord::PLVRecord( const PLVRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

PLVRecord& PLVRecord::operator=( const PLVRecord& record )
{
    *d = *record.d;
    return *this;
}

void PLVRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void PLVRecord::writeData( XlsRecordOutputStream& ) const
{
}

void PLVRecord::dump( std::ostream& out ) const
{
    out << "PLV" << std::endl;
}

static Record* createPLVRecord(Swinder::Workbook *book)
{
    return new PLVRecord(book);
}

// ========== BuiltInFnGroupCountRecord ==========

const unsigned BuiltInFnGroupCountRecord::id = 0x009c;

class BuiltInFnGroupCountRecord::Private
{
public:
};

BuiltInFnGroupCountRecord::BuiltInFnGroupCountRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

BuiltInFnGroupCountRecord::~BuiltInFnGroupCountRecord()
{
    delete d;
}

BuiltInFnGroupCountRecord::BuiltInFnGroupCountRecord( const BuiltInFnGroupCountRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

BuiltInFnGroupCountRecord& BuiltInFnGroupCountRecord::operator=( const BuiltInFnGroupCountRecord& record )
{
    *d = *record.d;
    return *this;
}

void BuiltInFnGroupCountRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void BuiltInFnGroupCountRecord::writeData( XlsRecordOutputStream& ) const
{
}

void BuiltInFnGroupCountRecord::dump( std::ostream& out ) const
{
    out << "BuiltInFnGroupCount" << std::endl;
}

static Record* createBuiltInFnGroupCountRecord(Swinder::Workbook *book)
{
    return new BuiltInFnGroupCountRecord(book);
}

// ========== RecalcIdRecord ==========

const unsigned RecalcIdRecord::id = 0x01c1;

class RecalcIdRecord::Private
{
public:
};

RecalcIdRecord::RecalcIdRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

RecalcIdRecord::~RecalcIdRecord()
{
    delete d;
}

RecalcIdRecord::RecalcIdRecord( const RecalcIdRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

RecalcIdRecord& RecalcIdRecord::operator=( const RecalcIdRecord& record )
{
    *d = *record.d;
    return *this;
}

void RecalcIdRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void RecalcIdRecord::writeData( XlsRecordOutputStream& ) const
{
}

void RecalcIdRecord::dump( std::ostream& out ) const
{
    out << "RecalcId" << std::endl;
}

static Record* createRecalcIdRecord(Swinder::Workbook *book)
{
    return new RecalcIdRecord(book);
}

// ========== StyleExtRecord ==========

const unsigned StyleExtRecord::id = 0x0892;

class StyleExtRecord::Private
{
public:
};

StyleExtRecord::StyleExtRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

StyleExtRecord::~StyleExtRecord()
{
    delete d;
}

StyleExtRecord::StyleExtRecord( const StyleExtRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

StyleExtRecord& StyleExtRecord::operator=( const StyleExtRecord& record )
{
    *d = *record.d;
    return *this;
}

void StyleExtRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void StyleExtRecord::writeData( XlsRecordOutputStream& ) const
{
}

void StyleExtRecord::dump( std::ostream& out ) const
{
    out << "StyleExt" << std::endl;
}

static Record* createStyleExtRecord(Swinder::Workbook *book)
{
    return new StyleExtRecord(book);
}

// ========== PhoneticInfoRecord ==========

const unsigned PhoneticInfoRecord::id = 0x00ef;

class PhoneticInfoRecord::Private
{
public:
};

PhoneticInfoRecord::PhoneticInfoRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

PhoneticInfoRecord::~PhoneticInfoRecord()
{
    delete d;
}

PhoneticInfoRecord::PhoneticInfoRecord( const PhoneticInfoRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

PhoneticInfoRecord& PhoneticInfoRecord::operator=( const PhoneticInfoRecord& record )
{
    *d = *record.d;
    return *this;
}

void PhoneticInfoRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void PhoneticInfoRecord::writeData( XlsRecordOutputStream& ) const
{
}

void PhoneticInfoRecord::dump( std::ostream& out ) const
{
    out << "PhoneticInfo" << std::endl;
}

static Record* createPhoneticInfoRecord(Swinder::Workbook *book)
{
    return new PhoneticInfoRecord(book);
}

// ========== SelectionRecord ==========

const unsigned SelectionRecord::id = 0x001d;

class SelectionRecord::Private
{
public:
    unsigned colAct;
    unsigned cref;
    unsigned irefAct;
    unsigned pnn;
    unsigned rwAct;
};

SelectionRecord::SelectionRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setColAct(0);
    setCref(0);
    setIrefAct(0);
    setPnn(0);
    setRwAct(0);
}

SelectionRecord::~SelectionRecord()
{
    delete d;
}

SelectionRecord::SelectionRecord( const SelectionRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

SelectionRecord& SelectionRecord::operator=( const SelectionRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned SelectionRecord::colAct() const
{
    return d->colAct;
}

void SelectionRecord::setColAct(unsigned colAct )
{
    d->colAct = colAct;
}

unsigned SelectionRecord::cref() const
{
    return d->cref;
}

void SelectionRecord::setCref(unsigned cref )
{
    d->cref = cref;
}

unsigned SelectionRecord::irefAct() const
{
    return d->irefAct;
}

void SelectionRecord::setIrefAct(unsigned irefAct )
{
    d->irefAct = irefAct;
}

unsigned SelectionRecord::pnn() const
{
    return d->pnn;
}

void SelectionRecord::setPnn(unsigned pnn )
{
    d->pnn = pnn;
}

unsigned SelectionRecord::rwAct() const
{
    return d->rwAct;
}

void SelectionRecord::setRwAct(unsigned rwAct )
{
    d->rwAct = rwAct;
}

void SelectionRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 9) {
        setIsValid(false);
        return;
    }
    setPnn(readU8(data));
    setRwAct(readU16(data + 1));
    setColAct(readU16(data + 3));
    setIrefAct(readU16(data + 5));
    setCref(readU16(data + 7));
}

void SelectionRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(8, pnn());
    out.writeUnsigned(16, rwAct());
    out.writeUnsigned(16, colAct());
    out.writeUnsigned(16, irefAct());
    out.writeUnsigned(16, cref());
}

void SelectionRecord::dump( std::ostream& out ) const
{
    out << "Selection" << std::endl;
    out << "                Pnn : " << pnn() << std::endl;
    out << "              RwAct : " << rwAct() << std::endl;
    out << "             ColAct : " << colAct() << std::endl;
    out << "            IrefAct : " << irefAct() << std::endl;
    out << "               Cref : " << cref() << std::endl;
}

static Record* createSelectionRecord(Swinder::Workbook *book)
{
    return new SelectionRecord(book);
}

// ========== PrinterSettingsRecord ==========

const unsigned PrinterSettingsRecord::id = 0x004d;

class PrinterSettingsRecord::Private
{
public:
};

PrinterSettingsRecord::PrinterSettingsRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

PrinterSettingsRecord::~PrinterSettingsRecord()
{
    delete d;
}

PrinterSettingsRecord::PrinterSettingsRecord( const PrinterSettingsRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

PrinterSettingsRecord& PrinterSettingsRecord::operator=( const PrinterSettingsRecord& record )
{
    *d = *record.d;
    return *this;
}

void PrinterSettingsRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void PrinterSettingsRecord::writeData( XlsRecordOutputStream& ) const
{
}

void PrinterSettingsRecord::dump( std::ostream& out ) const
{
    out << "PrinterSettings" << std::endl;
}

static Record* createPrinterSettingsRecord(Swinder::Workbook *book)
{
    return new PrinterSettingsRecord(book);
}

// ========== XFExtRecord ==========

const unsigned XFExtRecord::id = 0x087d;

class XFExtRecord::Private
{
public:
};

XFExtRecord::XFExtRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

XFExtRecord::~XFExtRecord()
{
    delete d;
}

XFExtRecord::XFExtRecord( const XFExtRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

XFExtRecord& XFExtRecord::operator=( const XFExtRecord& record )
{
    *d = *record.d;
    return *this;
}

void XFExtRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void XFExtRecord::writeData( XlsRecordOutputStream& ) const
{
}

void XFExtRecord::dump( std::ostream& out ) const
{
    out << "XFExt" << std::endl;
}

static Record* createXFExtRecord(Swinder::Workbook *book)
{
    return new XFExtRecord(book);
}

// ========== XFCRCRecord ==========

const unsigned XFCRCRecord::id = 0x087c;

class XFCRCRecord::Private
{
public:
};

XFCRCRecord::XFCRCRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

XFCRCRecord::~XFCRCRecord()
{
    delete d;
}

XFCRCRecord::XFCRCRecord( const XFCRCRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

XFCRCRecord& XFCRCRecord::operator=( const XFCRCRecord& record )
{
    *d = *record.d;
    return *this;
}

void XFCRCRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void XFCRCRecord::writeData( XlsRecordOutputStream& ) const
{
}

void XFCRCRecord::dump( std::ostream& out ) const
{
    out << "XFCRC" << std::endl;
}

static Record* createXFCRCRecord(Swinder::Workbook *book)
{
    return new XFCRCRecord(book);
}

// ========== TableStylesRecord ==========

const unsigned TableStylesRecord::id = 0x088e;

class TableStylesRecord::Private
{
public:
};

TableStylesRecord::TableStylesRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

TableStylesRecord::~TableStylesRecord()
{
    delete d;
}

TableStylesRecord::TableStylesRecord( const TableStylesRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

TableStylesRecord& TableStylesRecord::operator=( const TableStylesRecord& record )
{
    *d = *record.d;
    return *this;
}

void TableStylesRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void TableStylesRecord::writeData( XlsRecordOutputStream& ) const
{
}

void TableStylesRecord::dump( std::ostream& out ) const
{
    out << "TableStyles" << std::endl;
}

static Record* createTableStylesRecord(Swinder::Workbook *book)
{
    return new TableStylesRecord(book);
}

// ========== MTRSettingsRecord ==========

const unsigned MTRSettingsRecord::id = 0x089a;

class MTRSettingsRecord::Private
{
public:
};

MTRSettingsRecord::MTRSettingsRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

MTRSettingsRecord::~MTRSettingsRecord()
{
    delete d;
}

MTRSettingsRecord::MTRSettingsRecord( const MTRSettingsRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

MTRSettingsRecord& MTRSettingsRecord::operator=( const MTRSettingsRecord& record )
{
    *d = *record.d;
    return *this;
}

void MTRSettingsRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void MTRSettingsRecord::writeData( XlsRecordOutputStream& ) const
{
}

void MTRSettingsRecord::dump( std::ostream& out ) const
{
    out << "MTRSettings" << std::endl;
}

static Record* createMTRSettingsRecord(Swinder::Workbook *book)
{
    return new MTRSettingsRecord(book);
}

// ========== ForceFullCalculationRecord ==========

const unsigned ForceFullCalculationRecord::id = 0x08a3;

class ForceFullCalculationRecord::Private
{
public:
};

ForceFullCalculationRecord::ForceFullCalculationRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

ForceFullCalculationRecord::~ForceFullCalculationRecord()
{
    delete d;
}

ForceFullCalculationRecord::ForceFullCalculationRecord( const ForceFullCalculationRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ForceFullCalculationRecord& ForceFullCalculationRecord::operator=( const ForceFullCalculationRecord& record )
{
    *d = *record.d;
    return *this;
}

void ForceFullCalculationRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void ForceFullCalculationRecord::writeData( XlsRecordOutputStream& ) const
{
}

void ForceFullCalculationRecord::dump( std::ostream& out ) const
{
    out << "ForceFullCalculation" << std::endl;
}

static Record* createForceFullCalculationRecord(Swinder::Workbook *book)
{
    return new ForceFullCalculationRecord(book);
}

// ========== BookExtRecord ==========

const unsigned BookExtRecord::id = 0x0863;

class BookExtRecord::Private
{
public:
};

BookExtRecord::BookExtRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

BookExtRecord::~BookExtRecord()
{
    delete d;
}

BookExtRecord::BookExtRecord( const BookExtRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

BookExtRecord& BookExtRecord::operator=( const BookExtRecord& record )
{
    *d = *record.d;
    return *this;
}

void BookExtRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void BookExtRecord::writeData( XlsRecordOutputStream& ) const
{
}

void BookExtRecord::dump( std::ostream& out ) const
{
    out << "BookExt" << std::endl;
}

static Record* createBookExtRecord(Swinder::Workbook *book)
{
    return new BookExtRecord(book);
}

// ========== ThemeRecord ==========

const unsigned ThemeRecord::id = 0x0896;

class ThemeRecord::Private
{
public:
};

ThemeRecord::ThemeRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

ThemeRecord::~ThemeRecord()
{
    delete d;
}

ThemeRecord::ThemeRecord( const ThemeRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

ThemeRecord& ThemeRecord::operator=( const ThemeRecord& record )
{
    *d = *record.d;
    return *this;
}

void ThemeRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void ThemeRecord::writeData( XlsRecordOutputStream& ) const
{
}

void ThemeRecord::dump( std::ostream& out ) const
{
    out << "Theme" << std::endl;
}

static Record* createThemeRecord(Swinder::Workbook *book)
{
    return new ThemeRecord(book);
}

// ========== CompressPicturesRecord ==========

const unsigned CompressPicturesRecord::id = 0x089b;

class CompressPicturesRecord::Private
{
public:
};

CompressPicturesRecord::CompressPicturesRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

CompressPicturesRecord::~CompressPicturesRecord()
{
    delete d;
}

CompressPicturesRecord::CompressPicturesRecord( const CompressPicturesRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

CompressPicturesRecord& CompressPicturesRecord::operator=( const CompressPicturesRecord& record )
{
    *d = *record.d;
    return *this;
}

void CompressPicturesRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void CompressPicturesRecord::writeData( XlsRecordOutputStream& ) const
{
}

void CompressPicturesRecord::dump( std::ostream& out ) const
{
    out << "CompressPictures" << std::endl;
}

static Record* createCompressPicturesRecord(Swinder::Workbook *book)
{
    return new CompressPicturesRecord(book);
}

// ========== FilterModeRecord ==========

const unsigned FilterModeRecord::id = 0x009b;

class FilterModeRecord::Private
{
public:
};

FilterModeRecord::FilterModeRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

FilterModeRecord::~FilterModeRecord()
{
    delete d;
}

FilterModeRecord::FilterModeRecord( const FilterModeRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

FilterModeRecord& FilterModeRecord::operator=( const FilterModeRecord& record )
{
    *d = *record.d;
    return *this;
}

void FilterModeRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void FilterModeRecord::writeData( XlsRecordOutputStream& ) const
{
}

void FilterModeRecord::dump( std::ostream& out ) const
{
    out << "FilterMode" << std::endl;
}

static Record* createFilterModeRecord(Swinder::Workbook *book)
{
    return new FilterModeRecord(book);
}

// ========== AutoFilterRecord ==========

const unsigned AutoFilterRecord::id = 0x009e;

class AutoFilterRecord::Private
{
public:
    std::vector<unsigned> boolErrValue;
    std::vector<unsigned> charCount;
    unsigned entry;
    std::vector<bool> fCompare;
    std::vector<double> floatValue;
    std::vector<bool> isError;
    Join join;
    std::vector<Operation> operation;
    std::vector<unsigned> rkValue;
    bool simple1;
    bool simple2;
    std::vector<QString> string;
    TopDirection topDirection;
    bool topN;
    unsigned topNCount;
    bool topPercentage;
    std::vector<QByteArray> value;
    std::vector<ValueType> valueType;
};

AutoFilterRecord::AutoFilterRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setEntry(0);
    setJoin(JoinAnd);
    setSimple1(false);
    setSimple2(false);
    setTopDirection(TopNBottom);
    setTopN(false);
    setTopNCount(0);
    setTopPercentage(false);
}

AutoFilterRecord::~AutoFilterRecord()
{
    delete d;
}

AutoFilterRecord::AutoFilterRecord( const AutoFilterRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

AutoFilterRecord& AutoFilterRecord::operator=( const AutoFilterRecord& record )
{
    *d = *record.d;
    return *this;
}

QString AutoFilterRecord::joinToString(Join join)
{
    switch (join) {
        case JoinAnd: return QString("JoinAnd");
        case JoinOr: return QString("JoinOr");
        default: return QString("Unknown: %1").arg(join);
    }
}

QString AutoFilterRecord::topDirectionToString(TopDirection topDirection)
{
    switch (topDirection) {
        case TopNBottom: return QString("TopNBottom");
        case TopNTop: return QString("TopNTop");
        default: return QString("Unknown: %1").arg(topDirection);
    }
}

QString AutoFilterRecord::valueTypeToString(ValueType valueType)
{
    switch (valueType) {
        case UndefinedType: return QString("UndefinedType");
        case RkNumber: return QString("RkNumber");
        case XNumber: return QString("XNumber");
        case String: return QString("String");
        case BoolErr: return QString("BoolErr");
        case Blanks: return QString("Blanks");
        case NonBlanks: return QString("NonBlanks");
        default: return QString("Unknown: %1").arg(valueType);
    }
}

QString AutoFilterRecord::operationToString(Operation operation)
{
    switch (operation) {
        case Less: return QString("Less");
        case Equal: return QString("Equal");
        case LEqual: return QString("LEqual");
        case Greater: return QString("Greater");
        case NotEqual: return QString("NotEqual");
        case GEqual: return QString("GEqual");
        default: return QString("Unknown: %1").arg(operation);
    }
}

unsigned AutoFilterRecord::boolErrValue( unsigned index ) const
{
    return d->boolErrValue[index];
}

void AutoFilterRecord::setBoolErrValue( unsigned index, unsigned boolErrValue )
{
    d->boolErrValue[index] = boolErrValue;
}

unsigned AutoFilterRecord::charCount( unsigned index ) const
{
    return d->charCount[index];
}

void AutoFilterRecord::setCharCount( unsigned index, unsigned charCount )
{
    d->charCount[index] = charCount;
}

unsigned AutoFilterRecord::entry() const
{
    return d->entry;
}

void AutoFilterRecord::setEntry(unsigned entry )
{
    d->entry = entry;
}

bool AutoFilterRecord::isFCompare( unsigned index ) const
{
    return d->fCompare[index];
}

void AutoFilterRecord::setFCompare( unsigned index, bool fCompare )
{
    d->fCompare[index] = fCompare;
}

double AutoFilterRecord::floatValue( unsigned index ) const
{
    return d->floatValue[index];
}

void AutoFilterRecord::setFloatValue( unsigned index, double floatValue )
{
    d->floatValue[index] = floatValue;
}

bool AutoFilterRecord::isError( unsigned index ) const
{
    return d->isError[index];
}

void AutoFilterRecord::setIsError( unsigned index, bool isError )
{
    d->isError[index] = isError;
}

AutoFilterRecord::Join AutoFilterRecord::join() const
{
    return d->join;
}

void AutoFilterRecord::setJoin(Join join )
{
    d->join = join;
}

AutoFilterRecord::Operation AutoFilterRecord::operation( unsigned index ) const
{
    return d->operation[index];
}

void AutoFilterRecord::setOperation( unsigned index, Operation operation )
{
    d->operation[index] = operation;
}

unsigned AutoFilterRecord::rkValue( unsigned index ) const
{
    return d->rkValue[index];
}

void AutoFilterRecord::setRkValue( unsigned index, unsigned rkValue )
{
    d->rkValue[index] = rkValue;
}

bool AutoFilterRecord::isSimple1() const
{
    return d->simple1;
}

void AutoFilterRecord::setSimple1(bool simple1 )
{
    d->simple1 = simple1;
}

bool AutoFilterRecord::isSimple2() const
{
    return d->simple2;
}

void AutoFilterRecord::setSimple2(bool simple2 )
{
    d->simple2 = simple2;
}

QString AutoFilterRecord::string( unsigned index ) const
{
    return d->string[index];
}

void AutoFilterRecord::setString( unsigned index, QString string )
{
    d->string[index] = string;
}

AutoFilterRecord::TopDirection AutoFilterRecord::topDirection() const
{
    return d->topDirection;
}

void AutoFilterRecord::setTopDirection(TopDirection topDirection )
{
    d->topDirection = topDirection;
}

bool AutoFilterRecord::isTopN() const
{
    return d->topN;
}

void AutoFilterRecord::setTopN(bool topN )
{
    d->topN = topN;
}

unsigned AutoFilterRecord::topNCount() const
{
    return d->topNCount;
}

void AutoFilterRecord::setTopNCount(unsigned topNCount )
{
    d->topNCount = topNCount;
}

bool AutoFilterRecord::isTopPercentage() const
{
    return d->topPercentage;
}

void AutoFilterRecord::setTopPercentage(bool topPercentage )
{
    d->topPercentage = topPercentage;
}

QByteArray AutoFilterRecord::value( unsigned index ) const
{
    return d->value[index];
}

void AutoFilterRecord::setValue( unsigned index, QByteArray value )
{
    d->value[index] = value;
}

AutoFilterRecord::ValueType AutoFilterRecord::valueType( unsigned index ) const
{
    return d->valueType[index];
}

void AutoFilterRecord::setValueType( unsigned index, ValueType valueType )
{
    d->valueType[index] = valueType;
}

void AutoFilterRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    bool stringLengthError = false;
    unsigned stringSize;
    if (size < 4) {
        setIsValid(false);
        return;
    }
    setEntry(readU16(data));
    setJoin(static_cast<Join>(((readU8(data + 2)) & 0x3)));
    setSimple1(((readU8(data + 2) >> 2) & 0x1) != 0);
    setSimple2(((readU8(data + 2) >> 3) & 0x1) != 0);
    setTopN(((readU8(data + 2) >> 4) & 0x1) != 0);
    setTopDirection(static_cast<TopDirection>(((readU8(data + 2) >> 5) & 0x1)));
    setTopPercentage(((readU8(data + 2) >> 6) & 0x1) != 0);
    setTopNCount(((readU16(data + 2) >> 7) & 0x1ff));
    curOffset = 4;
    d->valueType.resize(2);
    d->operation.resize(2);
    d->rkValue.resize(2);
    d->floatValue.resize(2);
    d->charCount.resize(2);
    d->fCompare.resize(2);
    d->boolErrValue.resize(2);
    d->isError.resize(2);
    d->value.resize(2);
    for (unsigned i = 0, endi = 2; i < endi; ++i) {
        if (size < curOffset + 2) {
            setIsValid(false);
            return;
        }
        setValueType(i, static_cast<ValueType>(readU8(data + curOffset)));
        setOperation(i, static_cast<Operation>(readU8(data + curOffset + 1)));
        curOffset += 2;
        if (valueType(i) == RkNumber) {
            if (size < curOffset + 8) {
                setIsValid(false);
                return;
            }
            setRkValue(i, readU32(data + curOffset));
            curOffset += 8;
        } else if (valueType(i) == XNumber) {
            if (size < curOffset + 8) {
                setIsValid(false);
                return;
            }
            setFloatValue(i, readFloat64(data + curOffset));
            curOffset += 8;
        } else if (valueType(i) == String) {
            if (size < curOffset + 8) {
                setIsValid(false);
                return;
            }
            setCharCount(i, readU8(data + curOffset + 4));
            setFCompare(i, readU8(data + curOffset + 5) != 0);
            curOffset += 8;
        } else if (valueType(i) == BoolErr) {
            if (size < curOffset + 8) {
                setIsValid(false);
                return;
            }
            setBoolErrValue(i, readU8(data + curOffset));
            setIsError(i, readU8(data + curOffset + 1) != 0);
            curOffset += 8;
        } else {
            if (size < curOffset + 8) {
                setIsValid(false);
                return;
            }
            setValue(i, QByteArray(reinterpret_cast<const char*>(data + curOffset), 8));
            curOffset += 8;
        }
    }
    d->string.resize(2);
    for (unsigned i = 0, endi = 2; i < endi; ++i) {
        if (valueType(i) == String) {
            setString(i, readUnicodeString(data + curOffset, charCount(i), size - curOffset, &stringLengthError, &stringSize));
            if (stringLengthError) {
                setIsValid(false);
                return;
            }
            curOffset += stringSize;
        }
    }
}

void AutoFilterRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, entry());
    out.writeUnsigned(2, join());
    out.writeUnsigned(1, isSimple1());
    out.writeUnsigned(1, isSimple2());
    out.writeUnsigned(1, isTopN());
    out.writeUnsigned(1, topDirection());
    out.writeUnsigned(1, isTopPercentage());
    out.writeUnsigned(9, topNCount());
    for (unsigned i = 0, endi = d->valueType.size(); i < endi; ++i) {
        out.writeUnsigned(8, valueType(i));
        out.writeUnsigned(8, operation(i));
        if (valueType(i) == RkNumber) {
            out.writeUnsigned(32, rkValue(i));
            out.writeUnsigned(32, 0);
        } else if (valueType(i) == XNumber) {
            out.writeFloat(64, floatValue(i));
        } else if (valueType(i) == String) {
            out.writeUnsigned(32, 0);
            out.writeUnsigned(8, charCount(i));
            out.writeUnsigned(8, isFCompare(i));
            out.writeUnsigned(16, 0);
        } else if (valueType(i) == BoolErr) {
            out.writeUnsigned(8, boolErrValue(i));
            out.writeUnsigned(8, isError(i));
            out.writeUnsigned(48, 0);
        } else {
            out.writeBlob(value(i));
        }
    }
    for (unsigned i = 0, endi = 2; i < endi; ++i) {
        if (valueType(i) == String) {
            out.writeUnicodeStringWithFlags(string(i));
        }
    }
}

void AutoFilterRecord::dump( std::ostream& out ) const
{
    out << "AutoFilter" << std::endl;
    out << "              Entry : " << entry() << std::endl;
    out << "               Join : " << joinToString(join()) << std::endl;
    out << "            Simple1 : " << isSimple1() << std::endl;
    out << "            Simple2 : " << isSimple2() << std::endl;
    out << "               TopN : " << isTopN() << std::endl;
    out << "       TopDirection : " << topDirectionToString(topDirection()) << std::endl;
    out << "      TopPercentage : " << isTopPercentage() << std::endl;
    out << "          TopNCount : " << topNCount() << std::endl;
    for (unsigned i = 0, endi = d->valueType.size(); i < endi; ++i) {
        out << "      ValueType " << std::setw(3) << i <<" : " << valueTypeToString(valueType(i)) << std::endl;
        out << "      Operation " << std::setw(3) << i <<" : " << operationToString(operation(i)) << std::endl;
        if (valueType(i) == RkNumber) {
            out << "        RkValue " << std::setw(3) << i <<" : " << rkValue(i) << std::endl;
        } else if (valueType(i) == XNumber) {
            out << "     FloatValue " << std::setw(3) << i <<" : " << floatValue(i) << std::endl;
        } else if (valueType(i) == String) {
            out << "      CharCount " << std::setw(3) << i <<" : " << charCount(i) << std::endl;
            out << "       FCompare " << std::setw(3) << i <<" : " << isFCompare(i) << std::endl;
        } else if (valueType(i) == BoolErr) {
            out << "   BoolErrValue " << std::setw(3) << i <<" : " << boolErrValue(i) << std::endl;
            out << "        IsError " << std::setw(3) << i <<" : " << isError(i) << std::endl;
        } else {
            out << "          Value " << std::setw(3) << i <<" : " << value(i) << std::endl;
        }
    }
    for (unsigned i = 0, endi = 2; i < endi; ++i) {
        if (valueType(i) == String) {
            out << "         String " << std::setw(3) << i <<" : " << string(i) << std::endl;
        }
    }
}

static Record* createAutoFilterRecord(Swinder::Workbook *book)
{
    return new AutoFilterRecord(book);
}

// ========== AutoFilter12Record ==========

const unsigned AutoFilter12Record::id = 0x087e;

class AutoFilter12Record::Private
{
public:
};

AutoFilter12Record::AutoFilter12Record(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

AutoFilter12Record::~AutoFilter12Record()
{
    delete d;
}

AutoFilter12Record::AutoFilter12Record( const AutoFilter12Record& record )
    : Record(record), d(new Private)
{
    *this = record;
}

AutoFilter12Record& AutoFilter12Record::operator=( const AutoFilter12Record& record )
{
    *d = *record.d;
    return *this;
}

void AutoFilter12Record::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void AutoFilter12Record::writeData( XlsRecordOutputStream& ) const
{
}

void AutoFilter12Record::dump( std::ostream& out ) const
{
    out << "AutoFilter12" << std::endl;
}

static Record* createAutoFilter12Record(Swinder::Workbook *book)
{
    return new AutoFilter12Record(book);
}

// ========== AutoFilterInfoRecord ==========

const unsigned AutoFilterInfoRecord::id = 0x009d;

class AutoFilterInfoRecord::Private
{
public:
    unsigned entries;
};

AutoFilterInfoRecord::AutoFilterInfoRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setEntries(0);
}

AutoFilterInfoRecord::~AutoFilterInfoRecord()
{
    delete d;
}

AutoFilterInfoRecord::AutoFilterInfoRecord( const AutoFilterInfoRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

AutoFilterInfoRecord& AutoFilterInfoRecord::operator=( const AutoFilterInfoRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned AutoFilterInfoRecord::entries() const
{
    return d->entries;
}

void AutoFilterInfoRecord::setEntries(unsigned entries )
{
    d->entries = entries;
}

void AutoFilterInfoRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    if (size < 2) {
        setIsValid(false);
        return;
    }
    setEntries(readU16(data));
}

void AutoFilterInfoRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, entries());
}

void AutoFilterInfoRecord::dump( std::ostream& out ) const
{
    out << "AutoFilterInfo" << std::endl;
    out << "            Entries : " << entries() << std::endl;
}

static Record* createAutoFilterInfoRecord(Swinder::Workbook *book)
{
    return new AutoFilterInfoRecord(book);
}

// ========== VerticalPageBreaksRecord ==========

const unsigned VerticalPageBreaksRecord::id = 0x001a;

class VerticalPageBreaksRecord::Private
{
public:
    std::vector<unsigned> col;
    unsigned count;
    std::vector<unsigned> rowEnd;
    std::vector<unsigned> rowStart;
};

VerticalPageBreaksRecord::VerticalPageBreaksRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCount(0);
}

VerticalPageBreaksRecord::~VerticalPageBreaksRecord()
{
    delete d;
}

VerticalPageBreaksRecord::VerticalPageBreaksRecord( const VerticalPageBreaksRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

VerticalPageBreaksRecord& VerticalPageBreaksRecord::operator=( const VerticalPageBreaksRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned VerticalPageBreaksRecord::col( unsigned index ) const
{
    return d->col[index];
}

void VerticalPageBreaksRecord::setCol( unsigned index, unsigned col )
{
    d->col[index] = col;
}

unsigned VerticalPageBreaksRecord::count() const
{
    return d->count;
}

void VerticalPageBreaksRecord::setCount(unsigned count )
{
    d->count = count;
    d->col.resize(count);
    d->rowStart.resize(count);
    d->rowEnd.resize(count);
}

unsigned VerticalPageBreaksRecord::rowEnd( unsigned index ) const
{
    return d->rowEnd[index];
}

void VerticalPageBreaksRecord::setRowEnd( unsigned index, unsigned rowEnd )
{
    d->rowEnd[index] = rowEnd;
}

unsigned VerticalPageBreaksRecord::rowStart( unsigned index ) const
{
    return d->rowStart[index];
}

void VerticalPageBreaksRecord::setRowStart( unsigned index, unsigned rowStart )
{
    d->rowStart[index] = rowStart;
}

void VerticalPageBreaksRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    if (size < 2) {
        setIsValid(false);
        return;
    }
    setCount(readU16(data));
    curOffset = 2;
    for (unsigned i = 0, endi = count(); i < endi; ++i) {
        if (size < curOffset + 6) {
            setIsValid(false);
            return;
        }
        setCol(i, readU16(data + curOffset));
        setRowStart(i, readU16(data + curOffset + 2));
        setRowEnd(i, readU16(data + curOffset + 4));
        curOffset += 6;
    }
}

void VerticalPageBreaksRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, count());
    for (unsigned i = 0, endi = count(); i < endi; ++i) {
        out.writeUnsigned(16, col(i));
        out.writeUnsigned(16, rowStart(i));
        out.writeUnsigned(16, rowEnd(i));
    }
}

void VerticalPageBreaksRecord::dump( std::ostream& out ) const
{
    out << "VerticalPageBreaks" << std::endl;
    out << "              Count : " << count() << std::endl;
    for (unsigned i = 0, endi = count(); i < endi; ++i) {
        out << "            Col " << std::setw(3) << i <<" : " << col(i) << std::endl;
        out << "       RowStart " << std::setw(3) << i <<" : " << rowStart(i) << std::endl;
        out << "         RowEnd " << std::setw(3) << i <<" : " << rowEnd(i) << std::endl;
    }
}

static Record* createVerticalPageBreaksRecord(Swinder::Workbook *book)
{
    return new VerticalPageBreaksRecord(book);
}

// ========== HorizontalPageBreaksRecord ==========

const unsigned HorizontalPageBreaksRecord::id = 0x001b;

class HorizontalPageBreaksRecord::Private
{
public:
    std::vector<unsigned> colEnd;
    std::vector<unsigned> colStart;
    unsigned count;
    std::vector<unsigned> row;
};

HorizontalPageBreaksRecord::HorizontalPageBreaksRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setCount(0);
}

HorizontalPageBreaksRecord::~HorizontalPageBreaksRecord()
{
    delete d;
}

HorizontalPageBreaksRecord::HorizontalPageBreaksRecord( const HorizontalPageBreaksRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

HorizontalPageBreaksRecord& HorizontalPageBreaksRecord::operator=( const HorizontalPageBreaksRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned HorizontalPageBreaksRecord::colEnd( unsigned index ) const
{
    return d->colEnd[index];
}

void HorizontalPageBreaksRecord::setColEnd( unsigned index, unsigned colEnd )
{
    d->colEnd[index] = colEnd;
}

unsigned HorizontalPageBreaksRecord::colStart( unsigned index ) const
{
    return d->colStart[index];
}

void HorizontalPageBreaksRecord::setColStart( unsigned index, unsigned colStart )
{
    d->colStart[index] = colStart;
}

unsigned HorizontalPageBreaksRecord::count() const
{
    return d->count;
}

void HorizontalPageBreaksRecord::setCount(unsigned count )
{
    d->count = count;
    d->row.resize(count);
    d->colStart.resize(count);
    d->colEnd.resize(count);
}

unsigned HorizontalPageBreaksRecord::row( unsigned index ) const
{
    return d->row[index];
}

void HorizontalPageBreaksRecord::setRow( unsigned index, unsigned row )
{
    d->row[index] = row;
}

void HorizontalPageBreaksRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    if (size < 2) {
        setIsValid(false);
        return;
    }
    setCount(readU16(data));
    curOffset = 2;
    for (unsigned i = 0, endi = count(); i < endi; ++i) {
        if (size < curOffset + 6) {
            setIsValid(false);
            return;
        }
        setRow(i, readU16(data + curOffset));
        setColStart(i, readU16(data + curOffset + 2));
        setColEnd(i, readU16(data + curOffset + 4));
        curOffset += 6;
    }
}

void HorizontalPageBreaksRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, count());
    for (unsigned i = 0, endi = count(); i < endi; ++i) {
        out.writeUnsigned(16, row(i));
        out.writeUnsigned(16, colStart(i));
        out.writeUnsigned(16, colEnd(i));
    }
}

void HorizontalPageBreaksRecord::dump( std::ostream& out ) const
{
    out << "HorizontalPageBreaks" << std::endl;
    out << "              Count : " << count() << std::endl;
    for (unsigned i = 0, endi = count(); i < endi; ++i) {
        out << "            Row " << std::setw(3) << i <<" : " << row(i) << std::endl;
        out << "       ColStart " << std::setw(3) << i <<" : " << colStart(i) << std::endl;
        out << "         ColEnd " << std::setw(3) << i <<" : " << colEnd(i) << std::endl;
    }
}

static Record* createHorizontalPageBreaksRecord(Swinder::Workbook *book)
{
    return new HorizontalPageBreaksRecord(book);
}

// ========== FilepassRecord ==========

const unsigned FilepassRecord::id = 0x002f;

class FilepassRecord::Private
{
public:
    QByteArray encryptedVerifier;
    QByteArray encryptedVerifierHash;
    EncryptionType encryptionType;
    unsigned encryptionVersionMajor;
    unsigned encryptionVersionMinor;
    QByteArray salt;
};

FilepassRecord::FilepassRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setEncryptionType(XORObfuscation);
    setEncryptionVersionMajor(0);
    setEncryptionVersionMinor(0);
}

FilepassRecord::~FilepassRecord()
{
    delete d;
}

FilepassRecord::FilepassRecord( const FilepassRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

FilepassRecord& FilepassRecord::operator=( const FilepassRecord& record )
{
    *d = *record.d;
    return *this;
}

QString FilepassRecord::encryptionTypeToString(EncryptionType encryptionType)
{
    switch (encryptionType) {
        case XORObfuscation: return QString("XORObfuscation");
        case RC4Encryption: return QString("RC4Encryption");
        default: return QString("Unknown: %1").arg(encryptionType);
    }
}

QByteArray FilepassRecord::encryptedVerifier() const
{
    return d->encryptedVerifier;
}

void FilepassRecord::setEncryptedVerifier(QByteArray encryptedVerifier )
{
    d->encryptedVerifier = encryptedVerifier;
}

QByteArray FilepassRecord::encryptedVerifierHash() const
{
    return d->encryptedVerifierHash;
}

void FilepassRecord::setEncryptedVerifierHash(QByteArray encryptedVerifierHash )
{
    d->encryptedVerifierHash = encryptedVerifierHash;
}

FilepassRecord::EncryptionType FilepassRecord::encryptionType() const
{
    return d->encryptionType;
}

void FilepassRecord::setEncryptionType(EncryptionType encryptionType )
{
    d->encryptionType = encryptionType;
}

unsigned FilepassRecord::encryptionVersionMajor() const
{
    return d->encryptionVersionMajor;
}

void FilepassRecord::setEncryptionVersionMajor(unsigned encryptionVersionMajor )
{
    d->encryptionVersionMajor = encryptionVersionMajor;
}

unsigned FilepassRecord::encryptionVersionMinor() const
{
    return d->encryptionVersionMinor;
}

void FilepassRecord::setEncryptionVersionMinor(unsigned encryptionVersionMinor )
{
    d->encryptionVersionMinor = encryptionVersionMinor;
}

QByteArray FilepassRecord::salt() const
{
    return d->salt;
}

void FilepassRecord::setSalt(QByteArray salt )
{
    d->salt = salt;
}

void FilepassRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    if (size < 2) {
        setIsValid(false);
        return;
    }
    setEncryptionType(static_cast<EncryptionType>(readU16(data)));
    curOffset = 2;
    if (encryptionType() == RC4Encryption) {
        if (size < curOffset + 4) {
            setIsValid(false);
            return;
        }
        setEncryptionVersionMajor(readU16(data + curOffset));
        setEncryptionVersionMinor(readU16(data + curOffset + 2));
        curOffset += 4;
        if (encryptionVersionMajor() == 0x0001) {
            if (size < curOffset + 48) {
                setIsValid(false);
                return;
            }
            setSalt(QByteArray(reinterpret_cast<const char*>(data + curOffset), 16));
            setEncryptedVerifier(QByteArray(reinterpret_cast<const char*>(data + curOffset + 16), 16));
            setEncryptedVerifierHash(QByteArray(reinterpret_cast<const char*>(data + curOffset + 32), 16));
            curOffset += 48;
        }
    }
}

void FilepassRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, encryptionType());
    if (encryptionType() == RC4Encryption) {
        out.writeUnsigned(16, encryptionVersionMajor());
        out.writeUnsigned(16, encryptionVersionMinor());
        if (encryptionVersionMajor() == 0x0001) {
            out.writeBlob(salt());
            out.writeBlob(encryptedVerifier());
            out.writeBlob(encryptedVerifierHash());
        }
    }
}

void FilepassRecord::dump( std::ostream& out ) const
{
    out << "Filepass" << std::endl;
    out << "     EncryptionType : " << encryptionTypeToString(encryptionType()) << std::endl;
    if (encryptionType() == RC4Encryption) {
        out << "EncryptionVersionMajor : " << encryptionVersionMajor() << std::endl;
        out << "EncryptionVersionMinor : " << encryptionVersionMinor() << std::endl;
        if (encryptionVersionMajor() == 0x0001) {
            out << "               Salt : " << salt() << std::endl;
            out << "  EncryptedVerifier : " << encryptedVerifier() << std::endl;
            out << "EncryptedVerifierHash : " << encryptedVerifierHash() << std::endl;
        }
    }
}

static Record* createFilepassRecord(Swinder::Workbook *book)
{
    return new FilepassRecord(book);
}

// ========== UsrExclRecord ==========

const unsigned UsrExclRecord::id = 0x0194;

class UsrExclRecord::Private
{
public:
};

UsrExclRecord::UsrExclRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

UsrExclRecord::~UsrExclRecord()
{
    delete d;
}

UsrExclRecord::UsrExclRecord( const UsrExclRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

UsrExclRecord& UsrExclRecord::operator=( const UsrExclRecord& record )
{
    *d = *record.d;
    return *this;
}

void UsrExclRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void UsrExclRecord::writeData( XlsRecordOutputStream& ) const
{
}

void UsrExclRecord::dump( std::ostream& out ) const
{
    out << "UsrExcl" << std::endl;
}

static Record* createUsrExclRecord(Swinder::Workbook *book)
{
    return new UsrExclRecord(book);
}

// ========== FileLockRecord ==========

const unsigned FileLockRecord::id = 0x0195;

class FileLockRecord::Private
{
public:
};

FileLockRecord::FileLockRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

FileLockRecord::~FileLockRecord()
{
    delete d;
}

FileLockRecord::FileLockRecord( const FileLockRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

FileLockRecord& FileLockRecord::operator=( const FileLockRecord& record )
{
    *d = *record.d;
    return *this;
}

void FileLockRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void FileLockRecord::writeData( XlsRecordOutputStream& ) const
{
}

void FileLockRecord::dump( std::ostream& out ) const
{
    out << "FileLock" << std::endl;
}

static Record* createFileLockRecord(Swinder::Workbook *book)
{
    return new FileLockRecord(book);
}

// ========== RRDInfoRecord ==========

const unsigned RRDInfoRecord::id = 0x0196;

class RRDInfoRecord::Private
{
public:
};

RRDInfoRecord::RRDInfoRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

RRDInfoRecord::~RRDInfoRecord()
{
    delete d;
}

RRDInfoRecord::RRDInfoRecord( const RRDInfoRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

RRDInfoRecord& RRDInfoRecord::operator=( const RRDInfoRecord& record )
{
    *d = *record.d;
    return *this;
}

void RRDInfoRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void RRDInfoRecord::writeData( XlsRecordOutputStream& ) const
{
}

void RRDInfoRecord::dump( std::ostream& out ) const
{
    out << "RRDInfo" << std::endl;
}

static Record* createRRDInfoRecord(Swinder::Workbook *book)
{
    return new RRDInfoRecord(book);
}

// ========== RRDHeadRecord ==========

const unsigned RRDHeadRecord::id = 0x0138;

class RRDHeadRecord::Private
{
public:
};

RRDHeadRecord::RRDHeadRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
}

RRDHeadRecord::~RRDHeadRecord()
{
    delete d;
}

RRDHeadRecord::RRDHeadRecord( const RRDHeadRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

RRDHeadRecord& RRDHeadRecord::operator=( const RRDHeadRecord& record )
{
    *d = *record.d;
    return *this;
}

void RRDHeadRecord::setData( unsigned size, const unsigned char*, const unsigned int* )
{
    setRecordSize(size);

}

void RRDHeadRecord::writeData( XlsRecordOutputStream& ) const
{
}

void RRDHeadRecord::dump( std::ostream& out ) const
{
    out << "RRDHead" << std::endl;
}

static Record* createRRDHeadRecord(Swinder::Workbook *book)
{
    return new RRDHeadRecord(book);
}

// ========== HLinkRecord ==========

const unsigned HLinkRecord::id = 0x01b8;

class HLinkRecord::Private
{
public:
    bool absFromGetdataRel;
    QString displayName;
    unsigned firstColumn;
    unsigned firstRow;
    QString frameName;
    QUuid guid;
    bool hasCreationTime;
    bool hasDisplayName;
    bool hasFrameName;
    bool hasGUID;
    bool hasLocationStr;
    bool hasMoniker;
    QUuid hlinkClsid;
    bool isAbsolute;
    unsigned lastColumn;
    unsigned lastRow;
    QString location;
    QString moniker;
    bool monikerSavedAsStr;
    QUuid oleMonikerClsid;
    bool siteGaveDisplayName;
    unsigned streamVersion;
    QUuid urlMonikerSerialGUID;
    unsigned urlMonikerSerialVersion;
    unsigned urlMonikerSize;
    unsigned urlMonikerURIFlags;
    QString urlMonikerUrl;
};

HLinkRecord::HLinkRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setAbsFromGetdataRel(false);
    setFirstColumn(0);
    setFirstRow(0);
    setHasCreationTime(false);
    setHasDisplayName(false);
    setHasFrameName(false);
    setHasGUID(false);
    setHasLocationStr(false);
    setHasMoniker(false);
    setIsAbsolute(false);
    setLastColumn(0);
    setLastRow(0);
    setMonikerSavedAsStr(false);
    setSiteGaveDisplayName(false);
    setStreamVersion(0);
    setUrlMonikerSerialVersion(0);
    setUrlMonikerSize(0);
    setUrlMonikerURIFlags(0);
}

HLinkRecord::~HLinkRecord()
{
    delete d;
}

HLinkRecord::HLinkRecord( const HLinkRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

HLinkRecord& HLinkRecord::operator=( const HLinkRecord& record )
{
    *d = *record.d;
    return *this;
}

bool HLinkRecord::isAbsFromGetdataRel() const
{
    return d->absFromGetdataRel;
}

void HLinkRecord::setAbsFromGetdataRel(bool absFromGetdataRel )
{
    d->absFromGetdataRel = absFromGetdataRel;
}

QString HLinkRecord::displayName() const
{
    return d->displayName;
}

void HLinkRecord::setDisplayName(QString displayName )
{
    d->displayName = displayName;
}

unsigned HLinkRecord::firstColumn() const
{
    return d->firstColumn;
}

void HLinkRecord::setFirstColumn(unsigned firstColumn )
{
    d->firstColumn = firstColumn;
}

unsigned HLinkRecord::firstRow() const
{
    return d->firstRow;
}

void HLinkRecord::setFirstRow(unsigned firstRow )
{
    d->firstRow = firstRow;
}

QString HLinkRecord::frameName() const
{
    return d->frameName;
}

void HLinkRecord::setFrameName(QString frameName )
{
    d->frameName = frameName;
}

QUuid HLinkRecord::guid() const
{
    return d->guid;
}

void HLinkRecord::setGuid(QUuid guid )
{
    d->guid = guid;
}

bool HLinkRecord::hasCreationTime() const
{
    return d->hasCreationTime;
}

void HLinkRecord::setHasCreationTime(bool hasCreationTime )
{
    d->hasCreationTime = hasCreationTime;
}

bool HLinkRecord::hasDisplayName() const
{
    return d->hasDisplayName;
}

void HLinkRecord::setHasDisplayName(bool hasDisplayName )
{
    d->hasDisplayName = hasDisplayName;
}

bool HLinkRecord::hasFrameName() const
{
    return d->hasFrameName;
}

void HLinkRecord::setHasFrameName(bool hasFrameName )
{
    d->hasFrameName = hasFrameName;
}

bool HLinkRecord::hasGUID() const
{
    return d->hasGUID;
}

void HLinkRecord::setHasGUID(bool hasGUID )
{
    d->hasGUID = hasGUID;
}

bool HLinkRecord::hasLocationStr() const
{
    return d->hasLocationStr;
}

void HLinkRecord::setHasLocationStr(bool hasLocationStr )
{
    d->hasLocationStr = hasLocationStr;
}

bool HLinkRecord::hasMoniker() const
{
    return d->hasMoniker;
}

void HLinkRecord::setHasMoniker(bool hasMoniker )
{
    d->hasMoniker = hasMoniker;
}

QUuid HLinkRecord::hlinkClsid() const
{
    return d->hlinkClsid;
}

void HLinkRecord::setHlinkClsid(QUuid hlinkClsid )
{
    d->hlinkClsid = hlinkClsid;
}

bool HLinkRecord::isAbsolute() const
{
    return d->isAbsolute;
}

void HLinkRecord::setIsAbsolute(bool isAbsolute )
{
    d->isAbsolute = isAbsolute;
}

unsigned HLinkRecord::lastColumn() const
{
    return d->lastColumn;
}

void HLinkRecord::setLastColumn(unsigned lastColumn )
{
    d->lastColumn = lastColumn;
}

unsigned HLinkRecord::lastRow() const
{
    return d->lastRow;
}

void HLinkRecord::setLastRow(unsigned lastRow )
{
    d->lastRow = lastRow;
}

QString HLinkRecord::location() const
{
    return d->location;
}

void HLinkRecord::setLocation(QString location )
{
    d->location = location;
}

QString HLinkRecord::moniker() const
{
    return d->moniker;
}

void HLinkRecord::setMoniker(QString moniker )
{
    d->moniker = moniker;
}

bool HLinkRecord::isMonikerSavedAsStr() const
{
    return d->monikerSavedAsStr;
}

void HLinkRecord::setMonikerSavedAsStr(bool monikerSavedAsStr )
{
    d->monikerSavedAsStr = monikerSavedAsStr;
}

QUuid HLinkRecord::oleMonikerClsid() const
{
    return d->oleMonikerClsid;
}

void HLinkRecord::setOleMonikerClsid(QUuid oleMonikerClsid )
{
    d->oleMonikerClsid = oleMonikerClsid;
}

bool HLinkRecord::isSiteGaveDisplayName() const
{
    return d->siteGaveDisplayName;
}

void HLinkRecord::setSiteGaveDisplayName(bool siteGaveDisplayName )
{
    d->siteGaveDisplayName = siteGaveDisplayName;
}

unsigned HLinkRecord::streamVersion() const
{
    return d->streamVersion;
}

void HLinkRecord::setStreamVersion(unsigned streamVersion )
{
    d->streamVersion = streamVersion;
}

QUuid HLinkRecord::urlMonikerSerialGUID() const
{
    return d->urlMonikerSerialGUID;
}

void HLinkRecord::setUrlMonikerSerialGUID(QUuid urlMonikerSerialGUID )
{
    d->urlMonikerSerialGUID = urlMonikerSerialGUID;
}

unsigned HLinkRecord::urlMonikerSerialVersion() const
{
    return d->urlMonikerSerialVersion;
}

void HLinkRecord::setUrlMonikerSerialVersion(unsigned urlMonikerSerialVersion )
{
    d->urlMonikerSerialVersion = urlMonikerSerialVersion;
}

unsigned HLinkRecord::urlMonikerSize() const
{
    return d->urlMonikerSize;
}

void HLinkRecord::setUrlMonikerSize(unsigned urlMonikerSize )
{
    d->urlMonikerSize = urlMonikerSize;
}

unsigned HLinkRecord::urlMonikerURIFlags() const
{
    return d->urlMonikerURIFlags;
}

void HLinkRecord::setUrlMonikerURIFlags(unsigned urlMonikerURIFlags )
{
    d->urlMonikerURIFlags = urlMonikerURIFlags;
}

QString HLinkRecord::urlMonikerUrl() const
{
    return d->urlMonikerUrl;
}

void HLinkRecord::setUrlMonikerUrl(QString urlMonikerUrl )
{
    d->urlMonikerUrl = urlMonikerUrl;
}

void HLinkRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    bool stringLengthError = false;
    unsigned stringSize;
    if (size < 28) {
        setIsValid(false);
        return;
    }
    setFirstRow(readU16(data));
    setLastRow(readU16(data + 2));
    setFirstColumn(readU16(data + 4));
    setLastColumn(readU16(data + 6));
    setHlinkClsid(readUuid(data + 8));
    setStreamVersion(readU32(data + 24));
    curOffset = 28;
    if (streamVersion() != 2) {
        setIsValid(false);
        return;
    }
    if (size < curOffset + 4) {
        setIsValid(false);
        return;
    }
    setHasMoniker(((readU8(data + curOffset)) & 0x1) != 0);
    setIsAbsolute(((readU8(data + curOffset) >> 1) & 0x1) != 0);
    setSiteGaveDisplayName(((readU8(data + curOffset) >> 2) & 0x1) != 0);
    setHasLocationStr(((readU8(data + curOffset) >> 3) & 0x1) != 0);
    setHasDisplayName(((readU8(data + curOffset) >> 4) & 0x1) != 0);
    setHasGUID(((readU8(data + curOffset) >> 5) & 0x1) != 0);
    setHasCreationTime(((readU8(data + curOffset) >> 6) & 0x1) != 0);
    setHasFrameName(((readU8(data + curOffset) >> 7) & 0x1) != 0);
    setMonikerSavedAsStr(((readU8(data + curOffset + 1)) & 0x1) != 0);
    setAbsFromGetdataRel(((readU8(data + curOffset + 1) >> 1) & 0x1) != 0);
    curOffset += 4;
    if (hasDisplayName()) {
        if (size < curOffset + 4) {
            setIsValid(false);
            return;
        }
        unsigned displayNameLength = readU32(data + curOffset);
        curOffset += 4;
        setDisplayName(readUnicodeCharArray(data + curOffset, displayNameLength, size - curOffset, &stringLengthError, &stringSize));
        if (stringLengthError) {
            setIsValid(false);
            return;
        }
        curOffset += stringSize;
    }
    if (hasFrameName()) {
        if (size < curOffset + 4) {
            setIsValid(false);
            return;
        }
        unsigned frameNameLength = readU32(data + curOffset);
        curOffset += 4;
        setFrameName(readUnicodeCharArray(data + curOffset, frameNameLength, size - curOffset, &stringLengthError, &stringSize));
        if (stringLengthError) {
            setIsValid(false);
            return;
        }
        curOffset += stringSize;
    }
    if (hasMoniker()) {
        if (isMonikerSavedAsStr()) {
            if (size < curOffset + 4) {
                setIsValid(false);
                return;
            }
            unsigned monikerLength = readU32(data + curOffset);
            curOffset += 4;
            setMoniker(readUnicodeCharArray(data + curOffset, monikerLength, size - curOffset, &stringLengthError, &stringSize));
            if (stringLengthError) {
                setIsValid(false);
                return;
            }
            curOffset += stringSize;
        }
        if (!isMonikerSavedAsStr()) {
            if (size < curOffset + 16) {
                setIsValid(false);
                return;
            }
            setOleMonikerClsid(readUuid(data + curOffset));
            curOffset += 16;
            if (oleMonikerClsid() == "{79eac9e0-baf9-11ce-8282-00aa004ba90b}") {
                if (size < curOffset + 4) {
                    setIsValid(false);
                    return;
                }
                setUrlMonikerSize(readU32(data + curOffset));
                curOffset += 4;
                setUrlMonikerUrl(readUnicodeCharArray(data + curOffset, -1, size - curOffset, &stringLengthError, &stringSize));
                if (stringLengthError) {
                    setIsValid(false);
                    return;
                }
                curOffset += stringSize;
                if (int(urlMonikerSize()) == 2+24+urlMonikerUrl().length()*2) {
                    if (size < curOffset + 24) {
                        setIsValid(false);
                        return;
                    }
                    setUrlMonikerSerialGUID(readUuid(data + curOffset));
                    setUrlMonikerSerialVersion(readU32(data + curOffset + 16));
                    setUrlMonikerURIFlags(readU32(data + curOffset + 20));
                    curOffset += 24;
                } else if (int(urlMonikerSize()) == 2+urlMonikerUrl().length()*2) {
                } else {
                    setIsValid(false);
                    return;
                }
            } else {
                setIsValid(false);
                return;
            }
        }
    }
    if (hasLocationStr()) {
        if (size < curOffset + 4) {
            setIsValid(false);
            return;
        }
        unsigned locationLength = readU32(data + curOffset);
        curOffset += 4;
        setLocation(readUnicodeCharArray(data + curOffset, locationLength, size - curOffset, &stringLengthError, &stringSize));
        if (stringLengthError) {
            setIsValid(false);
            return;
        }
        curOffset += stringSize;
    }
    if (hasGUID()) {
        if (size < curOffset + 16) {
            setIsValid(false);
            return;
        }
        setGuid(readUuid(data + curOffset));
        curOffset += 16;
    }
}

void HLinkRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, firstRow());
    out.writeUnsigned(16, lastRow());
    out.writeUnsigned(16, firstColumn());
    out.writeUnsigned(16, lastColumn());
    // TODO hlinkClsid());
    out.writeUnsigned(32, streamVersion());
    if (streamVersion() != 2) {
    }
    out.writeUnsigned(1, hasMoniker());
    out.writeUnsigned(1, isAbsolute());
    out.writeUnsigned(1, isSiteGaveDisplayName());
    out.writeUnsigned(1, hasLocationStr());
    out.writeUnsigned(1, hasDisplayName());
    out.writeUnsigned(1, hasGUID());
    out.writeUnsigned(1, hasCreationTime());
    out.writeUnsigned(1, hasFrameName());
    out.writeUnsigned(1, isMonikerSavedAsStr());
    out.writeUnsigned(1, isAbsFromGetdataRel());
    out.writeUnsigned(22, 0);
    if (hasDisplayName()) {
        out.writeUnsigned(32, displayName().length());
        out.writeUnicodeString(displayName());
    }
    if (hasFrameName()) {
        out.writeUnsigned(32, frameName().length());
        out.writeUnicodeString(frameName());
    }
    if (hasMoniker()) {
        if (isMonikerSavedAsStr()) {
            out.writeUnsigned(32, moniker().length());
            out.writeUnicodeString(moniker());
        }
        if (!isMonikerSavedAsStr()) {
            // TODO oleMonikerClsid());
            if (oleMonikerClsid() == "{79eac9e0-baf9-11ce-8282-00aa004ba90b}") {
                out.writeUnsigned(32, urlMonikerSize());
                out.writeUnicodeString(urlMonikerUrl());
                if (int(urlMonikerSize()) == 2+24+urlMonikerUrl().length()*2) {
                    // TODO urlMonikerSerialGUID());
                    out.writeUnsigned(32, urlMonikerSerialVersion());
                    out.writeUnsigned(32, urlMonikerURIFlags());
                } else if (int(urlMonikerSize()) == 2+urlMonikerUrl().length()*2) {
                } else {
                }
            } else {
            }
        }
    }
    if (hasLocationStr()) {
        out.writeUnsigned(32, location().length());
        out.writeUnicodeString(location());
    }
    if (hasGUID()) {
        // TODO guid());
    }
}

void HLinkRecord::dump( std::ostream& out ) const
{
    out << "HLink" << std::endl;
    out << "           FirstRow : " << firstRow() << std::endl;
    out << "            LastRow : " << lastRow() << std::endl;
    out << "        FirstColumn : " << firstColumn() << std::endl;
    out << "         LastColumn : " << lastColumn() << std::endl;
    out << "         HlinkClsid : " << hlinkClsid() << std::endl;
    out << "      StreamVersion : " << streamVersion() << std::endl;
    if (streamVersion() != 2) {
    }
    out << "         HasMoniker : " << hasMoniker() << std::endl;
    out << "         IsAbsolute : " << isAbsolute() << std::endl;
    out << "SiteGaveDisplayName : " << isSiteGaveDisplayName() << std::endl;
    out << "     HasLocationStr : " << hasLocationStr() << std::endl;
    out << "     HasDisplayName : " << hasDisplayName() << std::endl;
    out << "            HasGUID : " << hasGUID() << std::endl;
    out << "    HasCreationTime : " << hasCreationTime() << std::endl;
    out << "       HasFrameName : " << hasFrameName() << std::endl;
    out << "  MonikerSavedAsStr : " << isMonikerSavedAsStr() << std::endl;
    out << "  AbsFromGetdataRel : " << isAbsFromGetdataRel() << std::endl;
    if (hasDisplayName()) {
        out << "        DisplayName : " << displayName() << std::endl;
    }
    if (hasFrameName()) {
        out << "          FrameName : " << frameName() << std::endl;
    }
    if (hasMoniker()) {
        if (isMonikerSavedAsStr()) {
            out << "            Moniker : " << moniker() << std::endl;
        }
        if (!isMonikerSavedAsStr()) {
            out << "    OleMonikerClsid : " << oleMonikerClsid() << std::endl;
            if (oleMonikerClsid() == "{79eac9e0-baf9-11ce-8282-00aa004ba90b}") {
                out << "     UrlMonikerSize : " << urlMonikerSize() << std::endl;
                out << "      UrlMonikerUrl : " << urlMonikerUrl() << std::endl;
                if (int(urlMonikerSize()) == 2+24+urlMonikerUrl().length()*2) {
                    out << "UrlMonikerSerialGUID : " << urlMonikerSerialGUID() << std::endl;
                    out << "UrlMonikerSerialVersion : " << urlMonikerSerialVersion() << std::endl;
                    out << " UrlMonikerURIFlags : " << urlMonikerURIFlags() << std::endl;
                } else if (int(urlMonikerSize()) == 2+urlMonikerUrl().length()*2) {
                } else {
                }
            } else {
            }
        }
    }
    if (hasLocationStr()) {
        out << "           Location : " << location() << std::endl;
    }
    if (hasGUID()) {
        out << "               Guid : " << guid() << std::endl;
    }
}

static Record* createHLinkRecord(Swinder::Workbook *book)
{
    return new HLinkRecord(book);
}

// ========== CondFmtRecord ==========

const unsigned CondFmtRecord::id = 0x01b0;

class CondFmtRecord::Private
{
public:
    unsigned bbFirstColumn;
    unsigned bbFirstRow;
    unsigned bbLastColumn;
    unsigned bbLastRow;
    unsigned cfCount;
    std::vector<unsigned> firstColumn;
    std::vector<unsigned> firstRow;
    std::vector<unsigned> lastColumn;
    std::vector<unsigned> lastRow;
    unsigned nID;
    unsigned refCount;
    bool toughRecalc;
};

CondFmtRecord::CondFmtRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setBbFirstColumn(0);
    setBbFirstRow(0);
    setBbLastColumn(0);
    setBbLastRow(0);
    setCfCount(0);
    setNID(0);
    setRefCount(0);
    setToughRecalc(false);
}

CondFmtRecord::~CondFmtRecord()
{
    delete d;
}

CondFmtRecord::CondFmtRecord( const CondFmtRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

CondFmtRecord& CondFmtRecord::operator=( const CondFmtRecord& record )
{
    *d = *record.d;
    return *this;
}

unsigned CondFmtRecord::bbFirstColumn() const
{
    return d->bbFirstColumn;
}

void CondFmtRecord::setBbFirstColumn(unsigned bbFirstColumn )
{
    d->bbFirstColumn = bbFirstColumn;
}

unsigned CondFmtRecord::bbFirstRow() const
{
    return d->bbFirstRow;
}

void CondFmtRecord::setBbFirstRow(unsigned bbFirstRow )
{
    d->bbFirstRow = bbFirstRow;
}

unsigned CondFmtRecord::bbLastColumn() const
{
    return d->bbLastColumn;
}

void CondFmtRecord::setBbLastColumn(unsigned bbLastColumn )
{
    d->bbLastColumn = bbLastColumn;
}

unsigned CondFmtRecord::bbLastRow() const
{
    return d->bbLastRow;
}

void CondFmtRecord::setBbLastRow(unsigned bbLastRow )
{
    d->bbLastRow = bbLastRow;
}

unsigned CondFmtRecord::cfCount() const
{
    return d->cfCount;
}

void CondFmtRecord::setCfCount(unsigned cfCount )
{
    d->cfCount = cfCount;
}

unsigned CondFmtRecord::firstColumn( unsigned index ) const
{
    return d->firstColumn[index];
}

void CondFmtRecord::setFirstColumn( unsigned index, unsigned firstColumn )
{
    d->firstColumn[index] = firstColumn;
}

unsigned CondFmtRecord::firstRow( unsigned index ) const
{
    return d->firstRow[index];
}

void CondFmtRecord::setFirstRow( unsigned index, unsigned firstRow )
{
    d->firstRow[index] = firstRow;
}

unsigned CondFmtRecord::lastColumn( unsigned index ) const
{
    return d->lastColumn[index];
}

void CondFmtRecord::setLastColumn( unsigned index, unsigned lastColumn )
{
    d->lastColumn[index] = lastColumn;
}

unsigned CondFmtRecord::lastRow( unsigned index ) const
{
    return d->lastRow[index];
}

void CondFmtRecord::setLastRow( unsigned index, unsigned lastRow )
{
    d->lastRow[index] = lastRow;
}

unsigned CondFmtRecord::nID() const
{
    return d->nID;
}

void CondFmtRecord::setNID(unsigned nID )
{
    d->nID = nID;
}

unsigned CondFmtRecord::refCount() const
{
    return d->refCount;
}

void CondFmtRecord::setRefCount(unsigned refCount )
{
    d->refCount = refCount;
    d->firstRow.resize(refCount);
    d->lastRow.resize(refCount);
    d->firstColumn.resize(refCount);
    d->lastColumn.resize(refCount);
}

bool CondFmtRecord::isToughRecalc() const
{
    return d->toughRecalc;
}

void CondFmtRecord::setToughRecalc(bool toughRecalc )
{
    d->toughRecalc = toughRecalc;
}

void CondFmtRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    if (size < 14) {
        setIsValid(false);
        return;
    }
    setCfCount(readU16(data));
    setToughRecalc(((readU8(data + 2)) & 0x1) != 0);
    setNID(((readU16(data + 2) >> 1) & 0x7fff));
    setBbFirstRow(readU16(data + 4));
    setBbLastRow(readU16(data + 6));
    setBbFirstColumn(readU16(data + 8));
    setBbLastColumn(readU16(data + 10));
    setRefCount(readU16(data + 12));
    curOffset = 14;
    for (unsigned i = 0, endi = refCount(); i < endi; ++i) {
        if (size < curOffset + 8) {
            setIsValid(false);
            return;
        }
        setFirstRow(i, readU16(data + curOffset));
        setLastRow(i, readU16(data + curOffset + 2));
        setFirstColumn(i, readU16(data + curOffset + 4));
        setLastColumn(i, readU16(data + curOffset + 6));
        curOffset += 8;
    }
}

void CondFmtRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(16, cfCount());
    out.writeUnsigned(1, isToughRecalc());
    out.writeUnsigned(15, nID());
    out.writeUnsigned(16, bbFirstRow());
    out.writeUnsigned(16, bbLastRow());
    out.writeUnsigned(16, bbFirstColumn());
    out.writeUnsigned(16, bbLastColumn());
    out.writeUnsigned(16, refCount());
    for (unsigned i = 0, endi = refCount(); i < endi; ++i) {
        out.writeUnsigned(16, firstRow(i));
        out.writeUnsigned(16, lastRow(i));
        out.writeUnsigned(16, firstColumn(i));
        out.writeUnsigned(16, lastColumn(i));
    }
}

void CondFmtRecord::dump( std::ostream& out ) const
{
    out << "CondFmt" << std::endl;
    out << "            CfCount : " << cfCount() << std::endl;
    out << "        ToughRecalc : " << isToughRecalc() << std::endl;
    out << "                NID : " << nID() << std::endl;
    out << "         BbFirstRow : " << bbFirstRow() << std::endl;
    out << "          BbLastRow : " << bbLastRow() << std::endl;
    out << "      BbFirstColumn : " << bbFirstColumn() << std::endl;
    out << "       BbLastColumn : " << bbLastColumn() << std::endl;
    out << "           RefCount : " << refCount() << std::endl;
    for (unsigned i = 0, endi = refCount(); i < endi; ++i) {
        out << "       FirstRow " << std::setw(3) << i <<" : " << firstRow(i) << std::endl;
        out << "        LastRow " << std::setw(3) << i <<" : " << lastRow(i) << std::endl;
        out << "    FirstColumn " << std::setw(3) << i <<" : " << firstColumn(i) << std::endl;
        out << "     LastColumn " << std::setw(3) << i <<" : " << lastColumn(i) << std::endl;
    }
}

static Record* createCondFmtRecord(Swinder::Workbook *book)
{
    return new CondFmtRecord(book);
}

// ========== CFRecord ==========

const unsigned CFRecord::id = 0x01b1;

class CFRecord::Private
{
public:
    bool alchNinch;
    bool alcvNinch;
    unsigned bottomBorderColor;
    BorderStyle bottomBorderStyle;
    bool cIndentNinch;
    unsigned characterSet;
    ConditionFunction conditionFunction;
    ConditionType conditionType;
    unsigned diagonalBorderColor;
    BorderStyle diagonalBorderStyle;
    bool diagonalBottomLeftBorder;
    bool diagonalTopLeftBorder;
    unsigned dxfnumusr_cb;
    bool fIfmtUser;
    bool fIfntNinch;
    bool fIsNinch;
    bool fMergeCellNinch;
    bool fNewBorder;
    bool fShrinkNicnh;
    bool fZeroInited;
    FillPattern fillPattern;
    QByteArray filler;
    int fontCharCount;
    int fontColor;
    FontFamily fontFamily;
    int fontFirstChar;
    int fontHeight;
    unsigned fontId;
    bool fontItalic;
    bool fontItalicNinch;
    QString fontName;
    bool fontNameIsUnicode;
    bool fontStrikeout;
    bool fontStrikeoutNinch;
    FontSuperSubScript fontSuperSubScript;
    int fontWeight;
    bool fontWeightNinch;
    QString formatString;
    bool glBottomNinch;
    bool glDiagDownNinch;
    bool glDiagUpNinch;
    bool glLeftNinch;
    bool glRightNinch;
    bool glTopNinch;
    bool hidden;
    bool hiddenNinch;
    HorizontalAlignment horizontalAlignment;
    bool iReadingOrderNinch;
    bool ibitAtrAlc;
    bool ibitAtrBdr;
    bool ibitAtrFnt;
    bool ibitAtrNum;
    bool ibitAtrPat;
    bool ibitAtrProt;
    bool icvBNinch;
    bool icvFNinch;
    unsigned ifmt;
    bool ifmtNinch;
    unsigned indentationLevel;
    bool kintoNinch;
    bool lastLineJustified;
    unsigned leftBorderColor;
    BorderStyle leftBorderStyle;
    bool locked;
    bool lockedNinch;
    bool mergeCell;
    unsigned patternBackColor;
    unsigned patternForeColor;
    unsigned rawRotation;
    ReadingOrder readingOrder;
    int relativeIndetationLevel;
    QByteArray rgce1;
    QByteArray rgce2;
    unsigned rightBorderColor;
    BorderStyle rightBorderStyle;
    bool shrinkToFit;
    bool superSubScriptNinch;
    bool textWrap;
    unsigned topBorderColor;
    BorderStyle topBorderStyle;
    bool trotNinch;
    Underline underline;
    bool underlineNinch;
    VerticalAlignment verticalAlignment;
    bool wrapNinch;
};

CFRecord::CFRecord(Swinder::Workbook *book)
    : Record(book), d(new Private)
{
    setAlchNinch(false);
    setAlcvNinch(false);
    setBottomBorderColor(0);
    setBottomBorderStyle(NoLine);
    setCIndentNinch(false);
    setCharacterSet(0);
    setConditionFunction(Between);
    setConditionType(Function);
    setDiagonalBorderColor(0);
    setDiagonalBorderStyle(NoLine);
    setDiagonalBottomLeftBorder(false);
    setDiagonalTopLeftBorder(false);
    setDxfnumusr_cb(0);
    setFIfmtUser(false);
    setFIfntNinch(false);
    setFIsNinch(false);
    setFMergeCellNinch(false);
    setFNewBorder(false);
    setFShrinkNicnh(false);
    setFZeroInited(false);
    setFillPattern(Null);
    setFontCharCount(0);
    setFontColor(0);
    setFontFamily(Unknown);
    setFontFirstChar(0);
    setFontHeight(0);
    setFontId(0);
    setFontItalic(false);
    setFontItalicNinch(false);
    setFontNameIsUnicode(false);
    setFontStrikeout(false);
    setFontStrikeoutNinch(false);
    setFontSuperSubScript(SSS_Ignore);
    setFontWeight(0);
    setFontWeightNinch(false);
    setGlBottomNinch(false);
    setGlDiagDownNinch(false);
    setGlDiagUpNinch(false);
    setGlLeftNinch(false);
    setGlRightNinch(false);
    setGlTopNinch(false);
    setHidden(false);
    setHiddenNinch(false);
    setHorizontalAlignment(General);
    setIReadingOrderNinch(false);
    setIbitAtrAlc(false);
    setIbitAtrBdr(false);
    setIbitAtrFnt(false);
    setIbitAtrNum(false);
    setIbitAtrPat(false);
    setIbitAtrProt(false);
    setIcvBNinch(false);
    setIcvFNinch(false);
    setIfmt(0);
    setIfmtNinch(false);
    setIndentationLevel(0);
    setKintoNinch(false);
    setLastLineJustified(false);
    setLeftBorderColor(0);
    setLeftBorderStyle(NoLine);
    setLocked(false);
    setLockedNinch(false);
    setMergeCell(false);
    setPatternBackColor(0);
    setPatternForeColor(0);
    setRawRotation(0);
    setReadingOrder(Context);
    setRelativeIndetationLevel(0);
    setRightBorderColor(0);
    setRightBorderStyle(NoLine);
    setShrinkToFit(false);
    setSuperSubScriptNinch(false);
    setTextWrap(false);
    setTopBorderColor(0);
    setTopBorderStyle(NoLine);
    setTrotNinch(false);
    setUnderline(UL_None);
    setUnderlineNinch(false);
    setVerticalAlignment(Bottom);
    setWrapNinch(false);
}

CFRecord::~CFRecord()
{
    delete d;
}

CFRecord::CFRecord( const CFRecord& record )
    : Record(record), d(new Private)
{
    *this = record;
}

CFRecord& CFRecord::operator=( const CFRecord& record )
{
    *d = *record.d;
    return *this;
}

QString CFRecord::conditionTypeToString(ConditionType conditionType)
{
    switch (conditionType) {
        case Function: return QString("Function");
        case Formula: return QString("Formula");
        default: return QString("Unknown: %1").arg(conditionType);
    }
}

QString CFRecord::conditionFunctionToString(ConditionFunction conditionFunction)
{
    switch (conditionFunction) {
        case Between: return QString("Between");
        case Outside: return QString("Outside");
        case Equal: return QString("Equal");
        case NotEqual: return QString("NotEqual");
        case Greater: return QString("Greater");
        case Less: return QString("Less");
        case GreaterOrEqual: return QString("GreaterOrEqual");
        case LessOrEqual: return QString("LessOrEqual");
        default: return QString("Unknown: %1").arg(conditionFunction);
    }
}

QString CFRecord::fontSuperSubScriptToString(FontSuperSubScript fontSuperSubScript)
{
    switch (fontSuperSubScript) {
        case SSS_Ignore: return QString("SSS_Ignore");
        case SSS_Normal: return QString("SSS_Normal");
        case SSS_Super: return QString("SSS_Super");
        case SSS_Sub: return QString("SSS_Sub");
        default: return QString("Unknown: %1").arg(fontSuperSubScript);
    }
}

QString CFRecord::underlineToString(Underline underline)
{
    switch (underline) {
        case UL_None: return QString("UL_None");
        case UL_Single: return QString("UL_Single");
        case UL_Double: return QString("UL_Double");
        case UL_SingleAccounting: return QString("UL_SingleAccounting");
        case UL_DoubleAccounting: return QString("UL_DoubleAccounting");
        case UL_Ignore: return QString("UL_Ignore");
        default: return QString("Unknown: %1").arg(underline);
    }
}

QString CFRecord::fontFamilyToString(FontFamily fontFamily)
{
    switch (fontFamily) {
        case Unknown: return QString("Unknown");
        case Roman: return QString("Roman");
        case Swiss: return QString("Swiss");
        case Modern: return QString("Modern");
        case Script: return QString("Script");
        case Decorative: return QString("Decorative");
        default: return QString("Unknown: %1").arg(fontFamily);
    }
}

QString CFRecord::horizontalAlignmentToString(HorizontalAlignment horizontalAlignment)
{
    switch (horizontalAlignment) {
        case Unspecified: return QString("Unspecified");
        case General: return QString("General");
        case Left: return QString("Left");
        case Centered: return QString("Centered");
        case Right: return QString("Right");
        case Filled: return QString("Filled");
        case Justified: return QString("Justified");
        case CenteredSelection: return QString("CenteredSelection");
        case Distributed: return QString("Distributed");
        default: return QString("Unknown: %1").arg(horizontalAlignment);
    }
}

QString CFRecord::verticalAlignmentToString(VerticalAlignment verticalAlignment)
{
    switch (verticalAlignment) {
        case Top: return QString("Top");
        case VCentered: return QString("VCentered");
        case Bottom: return QString("Bottom");
        case VJustified: return QString("VJustified");
        case VDistributed: return QString("VDistributed");
        default: return QString("Unknown: %1").arg(verticalAlignment);
    }
}

QString CFRecord::readingOrderToString(ReadingOrder readingOrder)
{
    switch (readingOrder) {
        case Context: return QString("Context");
        case LeftToRight: return QString("LeftToRight");
        case RightToLeft: return QString("RightToLeft");
        default: return QString("Unknown: %1").arg(readingOrder);
    }
}

QString CFRecord::fillPatternToString(FillPattern fillPattern)
{
    switch (fillPattern) {
        case Null: return QString("Null");
        case Solid: return QString("Solid");
        case MediumGray: return QString("MediumGray");
        case DarkGray: return QString("DarkGray");
        case LightGray: return QString("LightGray");
        case Horizontal: return QString("Horizontal");
        case Vertical: return QString("Vertical");
        case DiagonalDown: return QString("DiagonalDown");
        case DiagonalUp: return QString("DiagonalUp");
        case DiagonalGrid: return QString("DiagonalGrid");
        case ThickDiagonalGrid: return QString("ThickDiagonalGrid");
        case ThinHorizontal: return QString("ThinHorizontal");
        case ThinVertical: return QString("ThinVertical");
        case ThinDiagonalDown: return QString("ThinDiagonalDown");
        case ThinDiagonalUp: return QString("ThinDiagonalUp");
        case ThinGrid: return QString("ThinGrid");
        case ThinDiagonalGrid: return QString("ThinDiagonalGrid");
        case Gray1250: return QString("Gray1250");
        case Gray0625: return QString("Gray0625");
        default: return QString("Unknown: %1").arg(fillPattern);
    }
}

QString CFRecord::borderStyleToString(BorderStyle BorderStyle)
{
    switch (BorderStyle) {
        case NoLine: return QString("NoLine");
        case Thin: return QString("Thin");
        case Medium: return QString("Medium");
        case Dashed: return QString("Dashed");
        case Dotted: return QString("Dotted");
        case Thick: return QString("Thick");
        case Double: return QString("Double");
        case Hair: return QString("Hair");
        case MediumDashed: return QString("MediumDashed");
        case ThinDashDotted: return QString("ThinDashDotted");
        case MediumDashDotted: return QString("MediumDashDotted");
        case ThinDashDotDotted: return QString("ThinDashDotDotted");
        case MediumDashDotDotted: return QString("MediumDashDotDotted");
        case SlantedMediumDashDotted: return QString("SlantedMediumDashDotted");
        default: return QString("Unknown: %1").arg(BorderStyle);
    }
}

bool CFRecord::isAlchNinch() const
{
    return d->alchNinch;
}

void CFRecord::setAlchNinch(bool alchNinch )
{
    d->alchNinch = alchNinch;
}

bool CFRecord::isAlcvNinch() const
{
    return d->alcvNinch;
}

void CFRecord::setAlcvNinch(bool alcvNinch )
{
    d->alcvNinch = alcvNinch;
}

unsigned CFRecord::bottomBorderColor() const
{
    return d->bottomBorderColor;
}

void CFRecord::setBottomBorderColor(unsigned bottomBorderColor )
{
    d->bottomBorderColor = bottomBorderColor;
}

CFRecord::BorderStyle CFRecord::bottomBorderStyle() const
{
    return d->bottomBorderStyle;
}

void CFRecord::setBottomBorderStyle(BorderStyle bottomBorderStyle )
{
    d->bottomBorderStyle = bottomBorderStyle;
}

bool CFRecord::isCIndentNinch() const
{
    return d->cIndentNinch;
}

void CFRecord::setCIndentNinch(bool cIndentNinch )
{
    d->cIndentNinch = cIndentNinch;
}

unsigned CFRecord::characterSet() const
{
    return d->characterSet;
}

void CFRecord::setCharacterSet(unsigned characterSet )
{
    d->characterSet = characterSet;
}

CFRecord::ConditionFunction CFRecord::conditionFunction() const
{
    return d->conditionFunction;
}

void CFRecord::setConditionFunction(ConditionFunction conditionFunction )
{
    d->conditionFunction = conditionFunction;
}

CFRecord::ConditionType CFRecord::conditionType() const
{
    return d->conditionType;
}

void CFRecord::setConditionType(ConditionType conditionType )
{
    d->conditionType = conditionType;
}

unsigned CFRecord::diagonalBorderColor() const
{
    return d->diagonalBorderColor;
}

void CFRecord::setDiagonalBorderColor(unsigned diagonalBorderColor )
{
    d->diagonalBorderColor = diagonalBorderColor;
}

CFRecord::BorderStyle CFRecord::diagonalBorderStyle() const
{
    return d->diagonalBorderStyle;
}

void CFRecord::setDiagonalBorderStyle(BorderStyle diagonalBorderStyle )
{
    d->diagonalBorderStyle = diagonalBorderStyle;
}

bool CFRecord::isDiagonalBottomLeftBorder() const
{
    return d->diagonalBottomLeftBorder;
}

void CFRecord::setDiagonalBottomLeftBorder(bool diagonalBottomLeftBorder )
{
    d->diagonalBottomLeftBorder = diagonalBottomLeftBorder;
}

bool CFRecord::isDiagonalTopLeftBorder() const
{
    return d->diagonalTopLeftBorder;
}

void CFRecord::setDiagonalTopLeftBorder(bool diagonalTopLeftBorder )
{
    d->diagonalTopLeftBorder = diagonalTopLeftBorder;
}

unsigned CFRecord::dxfnumusr_cb() const
{
    return d->dxfnumusr_cb;
}

void CFRecord::setDxfnumusr_cb(unsigned dxfnumusr_cb )
{
    d->dxfnumusr_cb = dxfnumusr_cb;
}

bool CFRecord::isFIfmtUser() const
{
    return d->fIfmtUser;
}

void CFRecord::setFIfmtUser(bool fIfmtUser )
{
    d->fIfmtUser = fIfmtUser;
}

bool CFRecord::isFIfntNinch() const
{
    return d->fIfntNinch;
}

void CFRecord::setFIfntNinch(bool fIfntNinch )
{
    d->fIfntNinch = fIfntNinch;
}

bool CFRecord::isFIsNinch() const
{
    return d->fIsNinch;
}

void CFRecord::setFIsNinch(bool fIsNinch )
{
    d->fIsNinch = fIsNinch;
}

bool CFRecord::isFMergeCellNinch() const
{
    return d->fMergeCellNinch;
}

void CFRecord::setFMergeCellNinch(bool fMergeCellNinch )
{
    d->fMergeCellNinch = fMergeCellNinch;
}

bool CFRecord::isFNewBorder() const
{
    return d->fNewBorder;
}

void CFRecord::setFNewBorder(bool fNewBorder )
{
    d->fNewBorder = fNewBorder;
}

bool CFRecord::isFShrinkNicnh() const
{
    return d->fShrinkNicnh;
}

void CFRecord::setFShrinkNicnh(bool fShrinkNicnh )
{
    d->fShrinkNicnh = fShrinkNicnh;
}

bool CFRecord::isFZeroInited() const
{
    return d->fZeroInited;
}

void CFRecord::setFZeroInited(bool fZeroInited )
{
    d->fZeroInited = fZeroInited;
}

CFRecord::FillPattern CFRecord::fillPattern() const
{
    return d->fillPattern;
}

void CFRecord::setFillPattern(FillPattern fillPattern )
{
    d->fillPattern = fillPattern;
}

QByteArray CFRecord::filler() const
{
    return d->filler;
}

void CFRecord::setFiller(QByteArray filler )
{
    d->filler = filler;
}

int CFRecord::fontCharCount() const
{
    return d->fontCharCount;
}

void CFRecord::setFontCharCount(int fontCharCount )
{
    d->fontCharCount = fontCharCount;
}

int CFRecord::fontColor() const
{
    return d->fontColor;
}

void CFRecord::setFontColor(int fontColor )
{
    d->fontColor = fontColor;
}

CFRecord::FontFamily CFRecord::fontFamily() const
{
    return d->fontFamily;
}

void CFRecord::setFontFamily(FontFamily fontFamily )
{
    d->fontFamily = fontFamily;
}

int CFRecord::fontFirstChar() const
{
    return d->fontFirstChar;
}

void CFRecord::setFontFirstChar(int fontFirstChar )
{
    d->fontFirstChar = fontFirstChar;
}

int CFRecord::fontHeight() const
{
    return d->fontHeight;
}

void CFRecord::setFontHeight(int fontHeight )
{
    d->fontHeight = fontHeight;
}

unsigned CFRecord::fontId() const
{
    return d->fontId;
}

void CFRecord::setFontId(unsigned fontId )
{
    d->fontId = fontId;
}

bool CFRecord::isFontItalic() const
{
    return d->fontItalic;
}

void CFRecord::setFontItalic(bool fontItalic )
{
    d->fontItalic = fontItalic;
}

bool CFRecord::isFontItalicNinch() const
{
    return d->fontItalicNinch;
}

void CFRecord::setFontItalicNinch(bool fontItalicNinch )
{
    d->fontItalicNinch = fontItalicNinch;
}

QString CFRecord::fontName() const
{
    return d->fontName;
}

void CFRecord::setFontName(QString fontName )
{
    d->fontName = fontName;
}

bool CFRecord::isFontNameIsUnicode() const
{
    return d->fontNameIsUnicode;
}

void CFRecord::setFontNameIsUnicode(bool fontNameIsUnicode )
{
    d->fontNameIsUnicode = fontNameIsUnicode;
}

bool CFRecord::isFontStrikeout() const
{
    return d->fontStrikeout;
}

void CFRecord::setFontStrikeout(bool fontStrikeout )
{
    d->fontStrikeout = fontStrikeout;
}

bool CFRecord::isFontStrikeoutNinch() const
{
    return d->fontStrikeoutNinch;
}

void CFRecord::setFontStrikeoutNinch(bool fontStrikeoutNinch )
{
    d->fontStrikeoutNinch = fontStrikeoutNinch;
}

CFRecord::FontSuperSubScript CFRecord::fontSuperSubScript() const
{
    return d->fontSuperSubScript;
}

void CFRecord::setFontSuperSubScript(FontSuperSubScript fontSuperSubScript )
{
    d->fontSuperSubScript = fontSuperSubScript;
}

int CFRecord::fontWeight() const
{
    return d->fontWeight;
}

void CFRecord::setFontWeight(int fontWeight )
{
    d->fontWeight = fontWeight;
}

bool CFRecord::isFontWeightNinch() const
{
    return d->fontWeightNinch;
}

void CFRecord::setFontWeightNinch(bool fontWeightNinch )
{
    d->fontWeightNinch = fontWeightNinch;
}

QString CFRecord::formatString() const
{
    return d->formatString;
}

void CFRecord::setFormatString(QString formatString )
{
    d->formatString = formatString;
}

bool CFRecord::isGlBottomNinch() const
{
    return d->glBottomNinch;
}

void CFRecord::setGlBottomNinch(bool glBottomNinch )
{
    d->glBottomNinch = glBottomNinch;
}

bool CFRecord::isGlDiagDownNinch() const
{
    return d->glDiagDownNinch;
}

void CFRecord::setGlDiagDownNinch(bool glDiagDownNinch )
{
    d->glDiagDownNinch = glDiagDownNinch;
}

bool CFRecord::isGlDiagUpNinch() const
{
    return d->glDiagUpNinch;
}

void CFRecord::setGlDiagUpNinch(bool glDiagUpNinch )
{
    d->glDiagUpNinch = glDiagUpNinch;
}

bool CFRecord::isGlLeftNinch() const
{
    return d->glLeftNinch;
}

void CFRecord::setGlLeftNinch(bool glLeftNinch )
{
    d->glLeftNinch = glLeftNinch;
}

bool CFRecord::isGlRightNinch() const
{
    return d->glRightNinch;
}

void CFRecord::setGlRightNinch(bool glRightNinch )
{
    d->glRightNinch = glRightNinch;
}

bool CFRecord::isGlTopNinch() const
{
    return d->glTopNinch;
}

void CFRecord::setGlTopNinch(bool glTopNinch )
{
    d->glTopNinch = glTopNinch;
}

bool CFRecord::isHidden() const
{
    return d->hidden;
}

void CFRecord::setHidden(bool hidden )
{
    d->hidden = hidden;
}

bool CFRecord::isHiddenNinch() const
{
    return d->hiddenNinch;
}

void CFRecord::setHiddenNinch(bool hiddenNinch )
{
    d->hiddenNinch = hiddenNinch;
}

CFRecord::HorizontalAlignment CFRecord::horizontalAlignment() const
{
    return d->horizontalAlignment;
}

void CFRecord::setHorizontalAlignment(HorizontalAlignment horizontalAlignment )
{
    d->horizontalAlignment = horizontalAlignment;
}

bool CFRecord::isIReadingOrderNinch() const
{
    return d->iReadingOrderNinch;
}

void CFRecord::setIReadingOrderNinch(bool iReadingOrderNinch )
{
    d->iReadingOrderNinch = iReadingOrderNinch;
}

bool CFRecord::isIbitAtrAlc() const
{
    return d->ibitAtrAlc;
}

void CFRecord::setIbitAtrAlc(bool ibitAtrAlc )
{
    d->ibitAtrAlc = ibitAtrAlc;
}

bool CFRecord::isIbitAtrBdr() const
{
    return d->ibitAtrBdr;
}

void CFRecord::setIbitAtrBdr(bool ibitAtrBdr )
{
    d->ibitAtrBdr = ibitAtrBdr;
}

bool CFRecord::isIbitAtrFnt() const
{
    return d->ibitAtrFnt;
}

void CFRecord::setIbitAtrFnt(bool ibitAtrFnt )
{
    d->ibitAtrFnt = ibitAtrFnt;
}

bool CFRecord::isIbitAtrNum() const
{
    return d->ibitAtrNum;
}

void CFRecord::setIbitAtrNum(bool ibitAtrNum )
{
    d->ibitAtrNum = ibitAtrNum;
}

bool CFRecord::isIbitAtrPat() const
{
    return d->ibitAtrPat;
}

void CFRecord::setIbitAtrPat(bool ibitAtrPat )
{
    d->ibitAtrPat = ibitAtrPat;
}

bool CFRecord::isIbitAtrProt() const
{
    return d->ibitAtrProt;
}

void CFRecord::setIbitAtrProt(bool ibitAtrProt )
{
    d->ibitAtrProt = ibitAtrProt;
}

bool CFRecord::isIcvBNinch() const
{
    return d->icvBNinch;
}

void CFRecord::setIcvBNinch(bool icvBNinch )
{
    d->icvBNinch = icvBNinch;
}

bool CFRecord::isIcvFNinch() const
{
    return d->icvFNinch;
}

void CFRecord::setIcvFNinch(bool icvFNinch )
{
    d->icvFNinch = icvFNinch;
}

unsigned CFRecord::ifmt() const
{
    return d->ifmt;
}

void CFRecord::setIfmt(unsigned ifmt )
{
    d->ifmt = ifmt;
}

bool CFRecord::isIfmtNinch() const
{
    return d->ifmtNinch;
}

void CFRecord::setIfmtNinch(bool ifmtNinch )
{
    d->ifmtNinch = ifmtNinch;
}

unsigned CFRecord::indentationLevel() const
{
    return d->indentationLevel;
}

void CFRecord::setIndentationLevel(unsigned indentationLevel )
{
    d->indentationLevel = indentationLevel;
}

bool CFRecord::isKintoNinch() const
{
    return d->kintoNinch;
}

void CFRecord::setKintoNinch(bool kintoNinch )
{
    d->kintoNinch = kintoNinch;
}

bool CFRecord::isLastLineJustified() const
{
    return d->lastLineJustified;
}

void CFRecord::setLastLineJustified(bool lastLineJustified )
{
    d->lastLineJustified = lastLineJustified;
}

unsigned CFRecord::leftBorderColor() const
{
    return d->leftBorderColor;
}

void CFRecord::setLeftBorderColor(unsigned leftBorderColor )
{
    d->leftBorderColor = leftBorderColor;
}

CFRecord::BorderStyle CFRecord::leftBorderStyle() const
{
    return d->leftBorderStyle;
}

void CFRecord::setLeftBorderStyle(BorderStyle leftBorderStyle )
{
    d->leftBorderStyle = leftBorderStyle;
}

bool CFRecord::isLocked() const
{
    return d->locked;
}

void CFRecord::setLocked(bool locked )
{
    d->locked = locked;
}

bool CFRecord::isLockedNinch() const
{
    return d->lockedNinch;
}

void CFRecord::setLockedNinch(bool lockedNinch )
{
    d->lockedNinch = lockedNinch;
}

bool CFRecord::isMergeCell() const
{
    return d->mergeCell;
}

void CFRecord::setMergeCell(bool mergeCell )
{
    d->mergeCell = mergeCell;
}

unsigned CFRecord::patternBackColor() const
{
    return d->patternBackColor;
}

void CFRecord::setPatternBackColor(unsigned patternBackColor )
{
    d->patternBackColor = patternBackColor;
}

unsigned CFRecord::patternForeColor() const
{
    return d->patternForeColor;
}

void CFRecord::setPatternForeColor(unsigned patternForeColor )
{
    d->patternForeColor = patternForeColor;
}

unsigned CFRecord::rawRotation() const
{
    return d->rawRotation;
}

void CFRecord::setRawRotation(unsigned rawRotation )
{
    d->rawRotation = rawRotation;
}

CFRecord::ReadingOrder CFRecord::readingOrder() const
{
    return d->readingOrder;
}

void CFRecord::setReadingOrder(ReadingOrder readingOrder )
{
    d->readingOrder = readingOrder;
}

int CFRecord::relativeIndetationLevel() const
{
    return d->relativeIndetationLevel;
}

void CFRecord::setRelativeIndetationLevel(int relativeIndetationLevel )
{
    d->relativeIndetationLevel = relativeIndetationLevel;
}

QByteArray CFRecord::rgce1() const
{
    return d->rgce1;
}

void CFRecord::setRgce1(QByteArray rgce1 )
{
    d->rgce1 = rgce1;
}

QByteArray CFRecord::rgce2() const
{
    return d->rgce2;
}

void CFRecord::setRgce2(QByteArray rgce2 )
{
    d->rgce2 = rgce2;
}

unsigned CFRecord::rightBorderColor() const
{
    return d->rightBorderColor;
}

void CFRecord::setRightBorderColor(unsigned rightBorderColor )
{
    d->rightBorderColor = rightBorderColor;
}

CFRecord::BorderStyle CFRecord::rightBorderStyle() const
{
    return d->rightBorderStyle;
}

void CFRecord::setRightBorderStyle(BorderStyle rightBorderStyle )
{
    d->rightBorderStyle = rightBorderStyle;
}

bool CFRecord::isShrinkToFit() const
{
    return d->shrinkToFit;
}

void CFRecord::setShrinkToFit(bool shrinkToFit )
{
    d->shrinkToFit = shrinkToFit;
}

bool CFRecord::isSuperSubScriptNinch() const
{
    return d->superSubScriptNinch;
}

void CFRecord::setSuperSubScriptNinch(bool superSubScriptNinch )
{
    d->superSubScriptNinch = superSubScriptNinch;
}

bool CFRecord::isTextWrap() const
{
    return d->textWrap;
}

void CFRecord::setTextWrap(bool textWrap )
{
    d->textWrap = textWrap;
}

unsigned CFRecord::topBorderColor() const
{
    return d->topBorderColor;
}

void CFRecord::setTopBorderColor(unsigned topBorderColor )
{
    d->topBorderColor = topBorderColor;
}

CFRecord::BorderStyle CFRecord::topBorderStyle() const
{
    return d->topBorderStyle;
}

void CFRecord::setTopBorderStyle(BorderStyle topBorderStyle )
{
    d->topBorderStyle = topBorderStyle;
}

bool CFRecord::isTrotNinch() const
{
    return d->trotNinch;
}

void CFRecord::setTrotNinch(bool trotNinch )
{
    d->trotNinch = trotNinch;
}

CFRecord::Underline CFRecord::underline() const
{
    return d->underline;
}

void CFRecord::setUnderline(Underline underline )
{
    d->underline = underline;
}

bool CFRecord::isUnderlineNinch() const
{
    return d->underlineNinch;
}

void CFRecord::setUnderlineNinch(bool underlineNinch )
{
    d->underlineNinch = underlineNinch;
}

CFRecord::VerticalAlignment CFRecord::verticalAlignment() const
{
    return d->verticalAlignment;
}

void CFRecord::setVerticalAlignment(VerticalAlignment verticalAlignment )
{
    d->verticalAlignment = verticalAlignment;
}

bool CFRecord::isWrapNinch() const
{
    return d->wrapNinch;
}

void CFRecord::setWrapNinch(bool wrapNinch )
{
    d->wrapNinch = wrapNinch;
}

void CFRecord::setData( unsigned size, const unsigned char* data, const unsigned int* )
{
    setRecordSize(size);

    unsigned curOffset;
    bool stringLengthError = false;
    unsigned stringSize;
    setConditionType(static_cast<ConditionType>(readU8(data)));
    setConditionFunction(static_cast<ConditionFunction>(readU8(data + 1)));
    unsigned cce1 = readU16(data + 2);
    unsigned cce2 = readU16(data + 4);
    setAlchNinch(((readU8(data + 6)) & 0x1) != 0);
    setAlcvNinch(((readU8(data + 6) >> 1) & 0x1) != 0);
    setWrapNinch(((readU8(data + 6) >> 2) & 0x1) != 0);
    setTrotNinch(((readU8(data + 6) >> 3) & 0x1) != 0);
    setKintoNinch(((readU8(data + 6) >> 4) & 0x1) != 0);
    setCIndentNinch(((readU8(data + 6) >> 5) & 0x1) != 0);
    setFShrinkNicnh(((readU8(data + 6) >> 6) & 0x1) != 0);
    setFMergeCellNinch(((readU8(data + 6) >> 7) & 0x1) != 0);
    setLockedNinch(((readU8(data + 7)) & 0x1) != 0);
    setHiddenNinch(((readU8(data + 7) >> 1) & 0x1) != 0);
    setGlLeftNinch(((readU8(data + 7) >> 2) & 0x1) != 0);
    setGlRightNinch(((readU8(data + 7) >> 3) & 0x1) != 0);
    setGlTopNinch(((readU8(data + 7) >> 4) & 0x1) != 0);
    setGlBottomNinch(((readU8(data + 7) >> 5) & 0x1) != 0);
    setGlDiagDownNinch(((readU8(data + 7) >> 6) & 0x1) != 0);
    setGlDiagUpNinch(((readU8(data + 7) >> 7) & 0x1) != 0);
    setFIsNinch(((readU8(data + 8)) & 0x1) != 0);
    setIcvFNinch(((readU8(data + 8) >> 1) & 0x1) != 0);
    setIcvBNinch(((readU8(data + 8) >> 2) & 0x1) != 0);
    setIfmtNinch(((readU8(data + 8) >> 3) & 0x1) != 0);
    setFIfntNinch(((readU8(data + 8) >> 4) & 0x1) != 0);
    setIbitAtrNum(((readU8(data + 9) >> 1) & 0x1) != 0);
    setIbitAtrFnt(((readU8(data + 9) >> 2) & 0x1) != 0);
    setIbitAtrAlc(((readU8(data + 9) >> 3) & 0x1) != 0);
    setIbitAtrBdr(((readU8(data + 9) >> 4) & 0x1) != 0);
    setIbitAtrPat(((readU8(data + 9) >> 5) & 0x1) != 0);
    setIbitAtrProt(((readU8(data + 9) >> 6) & 0x1) != 0);
    setIReadingOrderNinch(((readU8(data + 9) >> 7) & 0x1) != 0);
    setFIfmtUser(((readU8(data + 10)) & 0x1) != 0);
    setFNewBorder(((readU8(data + 10) >> 2) & 0x1) != 0);
    setFZeroInited(((readU8(data + 11) >> 7) & 0x1) != 0);
    curOffset = 12;
    if (isIbitAtrNum()) {
        if (!isFIfmtUser()) {
            if (size < curOffset + 2) {
                setIsValid(false);
                return;
            }
            setIfmt(readU8(data + curOffset + 1));
            curOffset += 2;
        }
        if (isFIfmtUser()) {
            if (size < curOffset + 4) {
                setIsValid(false);
                return;
            }
            setDxfnumusr_cb(readU16(data + curOffset));
            unsigned formatStringLength = readU16(data + curOffset + 2);
            curOffset += 4;
            setFormatString(readUnicodeString(data + curOffset, formatStringLength, size - curOffset, &stringLengthError, &stringSize));
            if (stringLengthError) {
                setIsValid(false);
                return;
            }
            curOffset += stringSize;
        }
    }
    if (isIbitAtrFnt()) {
        if (size < curOffset + 2) {
            setIsValid(false);
            return;
        }
        unsigned cchFont = readU8(data + curOffset);
        setFontNameIsUnicode(((readU8(data + curOffset + 1)) & 0x1) != 0);
        curOffset += 2;
        if (isFontNameIsUnicode()) {
            setFontName(readUnicodeCharArray(data + curOffset, cchFont, size - curOffset, &stringLengthError, &stringSize));
            if (stringLengthError) {
                setIsValid(false);
                return;
            }
            curOffset += stringSize;
        }
        if (!isFontNameIsUnicode()) {
            setFontName(readByteString(data + curOffset, cchFont, size - curOffset, &stringLengthError, &stringSize));
            if (stringLengthError) {
                setIsValid(false);
                return;
            }
            curOffset += stringSize;
        }
        if (curOffset + (63 - (isFontNameIsUnicode() ? 2 : 1) * cchFont - 1) > size) {
            setIsValid(false);
            return;
        }
        setFiller(QByteArray(reinterpret_cast<const char*>(data + curOffset), 63 - (isFontNameIsUnicode() ? 2 : 1) * cchFont - 1));
        curOffset += 0 + 63 - (isFontNameIsUnicode() ? 2 : 1) * cchFont - 1;
        if (size < curOffset + 54) {
            setIsValid(false);
            return;
        }
        setFontHeight(readS32(data + curOffset));
        setFontItalic(((readU8(data + curOffset + 4) >> 1) & 0x1) != 0);
        setFontStrikeout(((readU8(data + curOffset + 4) >> 7) & 0x1) != 0);
        setFontWeight(readS16(data + curOffset + 8));
        setFontSuperSubScript(static_cast<FontSuperSubScript>(readS16(data + curOffset + 10)));
        setUnderline(static_cast<Underline>(readU8(data + curOffset + 12)));
        setFontFamily(static_cast<FontFamily>(readU8(data + curOffset + 13)));
        setCharacterSet(readU8(data + curOffset + 14));
        setFontColor(readS32(data + curOffset + 16));
        setFontItalicNinch(((readU8(data + curOffset + 24) >> 1) & 0x1) != 0);
        setFontStrikeoutNinch(((readU8(data + curOffset + 24) >> 7) & 0x1) != 0);
        setSuperSubScriptNinch(readU32(data + curOffset + 28) != 0);
        setUnderlineNinch(readU32(data + curOffset + 32) != 0);
        setFontWeightNinch(readU32(data + curOffset + 36) != 0);
        setFontFirstChar(readS32(data + curOffset + 44));
        setFontCharCount(readS32(data + curOffset + 48));
        setFontId(readU16(data + curOffset + 52));
        curOffset += 54;
    }
    if (isIbitAtrAlc()) {
        if (size < curOffset + 8) {
            setIsValid(false);
            return;
        }
        setHorizontalAlignment(static_cast<HorizontalAlignment>(((readU8(data + curOffset)) & 0x7)));
        setTextWrap(((readU8(data + curOffset) >> 3) & 0x1) != 0);
        setVerticalAlignment(static_cast<VerticalAlignment>(((readU8(data + curOffset) >> 4) & 0x7)));
        setLastLineJustified(((readU8(data + curOffset) >> 7) & 0x1) != 0);
        setRawRotation(readU8(data + curOffset + 1));
        setIndentationLevel(((readU8(data + curOffset + 2)) & 0xf));
        setShrinkToFit(((readU8(data + curOffset + 2) >> 4) & 0x1) != 0);
        setMergeCell(((readU8(data + curOffset + 2) >> 5) & 0x1) != 0);
        setReadingOrder(static_cast<ReadingOrder>(((readU8(data + curOffset + 2) >> 6) & 0x3)));
        setRelativeIndetationLevel(readS32(data + curOffset + 4));
        curOffset += 8;
    }
    if (isIbitAtrBdr()) {
        if (size < curOffset + 8) {
            setIsValid(false);
            return;
        }
        setLeftBorderStyle(static_cast<BorderStyle>(((readU8(data + curOffset)) & 0xf)));
        setRightBorderStyle(static_cast<BorderStyle>(((readU8(data + curOffset) >> 4) & 0xf)));
        setTopBorderStyle(static_cast<BorderStyle>(((readU8(data + curOffset + 1)) & 0xf)));
        setBottomBorderStyle(static_cast<BorderStyle>(((readU8(data + curOffset + 1) >> 4) & 0xf)));
        setLeftBorderColor(((readU8(data + curOffset + 2)) & 0x7f));
        setRightBorderColor(((readU16(data + curOffset + 2) >> 7) & 0x7f));
        setDiagonalTopLeftBorder(((readU8(data + curOffset + 3) >> 6) & 0x1) != 0);
        setDiagonalBottomLeftBorder(((readU8(data + curOffset + 3) >> 7) & 0x1) != 0);
        setTopBorderColor(((readU8(data + curOffset + 4)) & 0x7f));
        setBottomBorderColor(((readU16(data + curOffset + 4) >> 7) & 0x7f));
        setDiagonalBorderColor(((readU16(data + curOffset + 5) >> 6) & 0x7f));
        setDiagonalBorderStyle(static_cast<BorderStyle>(((readU16(data + curOffset + 6) >> 5) & 0xf)));
        curOffset += 8;
    }
    if (isIbitAtrPat()) {
        if (size < curOffset + 4) {
            setIsValid(false);
            return;
        }
        setFillPattern(static_cast<FillPattern>(((readU8(data + curOffset + 1) >> 2) & 0x3f)));
        setPatternForeColor(((readU8(data + curOffset + 2)) & 0x7f));
        setPatternBackColor(((readU16(data + curOffset + 2) >> 7) & 0x7f));
        curOffset += 4;
    }
    if (isIbitAtrProt()) {
        if (size < curOffset + 2) {
            setIsValid(false);
            return;
        }
        setLocked(((readU8(data + curOffset)) & 0x1) != 0);
        setHidden(((readU8(data + curOffset) >> 1) & 0x1) != 0);
        curOffset += 2;
    }
    if (curOffset + (cce1) > size) {
        setIsValid(false);
        return;
    }
    setRgce1(QByteArray(reinterpret_cast<const char*>(data + curOffset), cce1));
    curOffset += 0 + cce1;
    if (curOffset + (cce2) > size) {
        setIsValid(false);
        return;
    }
    setRgce2(QByteArray(reinterpret_cast<const char*>(data + curOffset), cce2));
    curOffset += 0 + cce2;
}

void CFRecord::writeData( XlsRecordOutputStream& out ) const
{
    out.writeUnsigned(8, conditionType());
    out.writeUnsigned(8, conditionFunction());
    out.writeUnsigned(16, rgce1().length());
    out.writeUnsigned(16, rgce2().length());
    out.writeUnsigned(1, isAlchNinch());
    out.writeUnsigned(1, isAlcvNinch());
    out.writeUnsigned(1, isWrapNinch());
    out.writeUnsigned(1, isTrotNinch());
    out.writeUnsigned(1, isKintoNinch());
    out.writeUnsigned(1, isCIndentNinch());
    out.writeUnsigned(1, isFShrinkNicnh());
    out.writeUnsigned(1, isFMergeCellNinch());
    out.writeUnsigned(1, isLockedNinch());
    out.writeUnsigned(1, isHiddenNinch());
    out.writeUnsigned(1, isGlLeftNinch());
    out.writeUnsigned(1, isGlRightNinch());
    out.writeUnsigned(1, isGlTopNinch());
    out.writeUnsigned(1, isGlBottomNinch());
    out.writeUnsigned(1, isGlDiagDownNinch());
    out.writeUnsigned(1, isGlDiagUpNinch());
    out.writeUnsigned(1, isFIsNinch());
    out.writeUnsigned(1, isIcvFNinch());
    out.writeUnsigned(1, isIcvBNinch());
    out.writeUnsigned(1, isIfmtNinch());
    out.writeUnsigned(1, isFIfntNinch());
    out.writeUnsigned(1, 0);
    out.writeUnsigned(3, 0);
    out.writeUnsigned(1, isIbitAtrNum());
    out.writeUnsigned(1, isIbitAtrFnt());
    out.writeUnsigned(1, isIbitAtrAlc());
    out.writeUnsigned(1, isIbitAtrBdr());
    out.writeUnsigned(1, isIbitAtrPat());
    out.writeUnsigned(1, isIbitAtrProt());
    out.writeUnsigned(1, isIReadingOrderNinch());
    out.writeUnsigned(1, isFIfmtUser());
    out.writeUnsigned(1, 0);
    out.writeUnsigned(1, isFNewBorder());
    out.writeUnsigned(12, 0);
    out.writeUnsigned(1, isFZeroInited());
    if (isIbitAtrNum()) {
        if (!isFIfmtUser()) {
            out.writeUnsigned(8, 0);
            out.writeUnsigned(8, ifmt());
        }
        if (isFIfmtUser()) {
            out.writeUnsigned(16, dxfnumusr_cb());
            out.writeUnsigned(16, formatString().length());
            out.writeUnicodeStringWithFlags(formatString());
        }
    }
    if (isIbitAtrFnt()) {
        out.writeUnsigned(8, fontName().length());
        out.writeUnsigned(1, isFontNameIsUnicode());
        out.writeUnsigned(7, 0);
        if (isFontNameIsUnicode()) {
            out.writeUnicodeString(fontName());
        }
        if (!isFontNameIsUnicode()) {
            out.writeByteString(fontName());
        }
        out.writeBlob(filler());
        out.writeSigned(32, fontHeight());
        out.writeUnsigned(1, 0);
        out.writeUnsigned(1, isFontItalic());
        out.writeUnsigned(5, 0);
        out.writeUnsigned(1, isFontStrikeout());
        out.writeUnsigned(24, 0);
        out.writeSigned(16, fontWeight());
        out.writeUnsigned(16, fontSuperSubScript());
        out.writeUnsigned(8, underline());
        out.writeUnsigned(8, fontFamily());
        out.writeUnsigned(8, characterSet());
        out.writeUnsigned(8, 0);
        out.writeSigned(32, fontColor());
        out.writeUnsigned(32, 0);
        out.writeUnsigned(1, 0);
        out.writeUnsigned(1, isFontItalicNinch());
        out.writeUnsigned(5, 0);
        out.writeUnsigned(1, isFontStrikeoutNinch());
        out.writeUnsigned(24, 0);
        out.writeUnsigned(32, isSuperSubScriptNinch());
        out.writeUnsigned(32, isUnderlineNinch());
        out.writeUnsigned(32, isFontWeightNinch());
        out.writeUnsigned(32, 0);
        out.writeSigned(32, fontFirstChar());
        out.writeSigned(32, fontCharCount());
        out.writeUnsigned(16, fontId());
    }
    if (isIbitAtrAlc()) {
        out.writeUnsigned(3, horizontalAlignment());
        out.writeUnsigned(1, isTextWrap());
        out.writeUnsigned(3, verticalAlignment());
        out.writeUnsigned(1, isLastLineJustified());
        out.writeUnsigned(8, rawRotation());
        out.writeUnsigned(4, indentationLevel());
        out.writeUnsigned(1, isShrinkToFit());
        out.writeUnsigned(1, isMergeCell());
        out.writeUnsigned(2, readingOrder());
        out.writeUnsigned(8, 0);
        out.writeSigned(32, relativeIndetationLevel());
    }
    if (isIbitAtrBdr()) {
        out.writeUnsigned(4, leftBorderStyle());
        out.writeUnsigned(4, rightBorderStyle());
        out.writeUnsigned(4, topBorderStyle());
        out.writeUnsigned(4, bottomBorderStyle());
        out.writeUnsigned(7, leftBorderColor());
        out.writeUnsigned(7, rightBorderColor());
        out.writeUnsigned(1, isDiagonalTopLeftBorder());
        out.writeUnsigned(1, isDiagonalBottomLeftBorder());
        out.writeUnsigned(7, topBorderColor());
        out.writeUnsigned(7, bottomBorderColor());
        out.writeUnsigned(7, diagonalBorderColor());
        out.writeUnsigned(4, diagonalBorderStyle());
        out.writeUnsigned(7, 0);
    }
    if (isIbitAtrPat()) {
        out.writeUnsigned(10, 0);
        out.writeUnsigned(6, fillPattern());
        out.writeUnsigned(7, patternForeColor());
        out.writeUnsigned(7, patternBackColor());
        out.writeUnsigned(2, 0);
    }
    if (isIbitAtrProt()) {
        out.writeUnsigned(1, isLocked());
        out.writeUnsigned(1, isHidden());
        out.writeUnsigned(14, 0);
    }
    out.writeBlob(rgce1());
    out.writeBlob(rgce2());
}

void CFRecord::dump( std::ostream& out ) const
{
    out << "CF" << std::endl;
    out << "      ConditionType : " << conditionTypeToString(conditionType()) << std::endl;
    out << "  ConditionFunction : " << conditionFunctionToString(conditionFunction()) << std::endl;
    out << "          AlchNinch : " << isAlchNinch() << std::endl;
    out << "          AlcvNinch : " << isAlcvNinch() << std::endl;
    out << "          WrapNinch : " << isWrapNinch() << std::endl;
    out << "          TrotNinch : " << isTrotNinch() << std::endl;
    out << "         KintoNinch : " << isKintoNinch() << std::endl;
    out << "       CIndentNinch : " << isCIndentNinch() << std::endl;
    out << "       FShrinkNicnh : " << isFShrinkNicnh() << std::endl;
    out << "    FMergeCellNinch : " << isFMergeCellNinch() << std::endl;
    out << "        LockedNinch : " << isLockedNinch() << std::endl;
    out << "        HiddenNinch : " << isHiddenNinch() << std::endl;
    out << "        GlLeftNinch : " << isGlLeftNinch() << std::endl;
    out << "       GlRightNinch : " << isGlRightNinch() << std::endl;
    out << "         GlTopNinch : " << isGlTopNinch() << std::endl;
    out << "      GlBottomNinch : " << isGlBottomNinch() << std::endl;
    out << "    GlDiagDownNinch : " << isGlDiagDownNinch() << std::endl;
    out << "      GlDiagUpNinch : " << isGlDiagUpNinch() << std::endl;
    out << "           FIsNinch : " << isFIsNinch() << std::endl;
    out << "          IcvFNinch : " << isIcvFNinch() << std::endl;
    out << "          IcvBNinch : " << isIcvBNinch() << std::endl;
    out << "          IfmtNinch : " << isIfmtNinch() << std::endl;
    out << "         FIfntNinch : " << isFIfntNinch() << std::endl;
    out << "         IbitAtrNum : " << isIbitAtrNum() << std::endl;
    out << "         IbitAtrFnt : " << isIbitAtrFnt() << std::endl;
    out << "         IbitAtrAlc : " << isIbitAtrAlc() << std::endl;
    out << "         IbitAtrBdr : " << isIbitAtrBdr() << std::endl;
    out << "         IbitAtrPat : " << isIbitAtrPat() << std::endl;
    out << "        IbitAtrProt : " << isIbitAtrProt() << std::endl;
    out << " IReadingOrderNinch : " << isIReadingOrderNinch() << std::endl;
    out << "          FIfmtUser : " << isFIfmtUser() << std::endl;
    out << "         FNewBorder : " << isFNewBorder() << std::endl;
    out << "        FZeroInited : " << isFZeroInited() << std::endl;
    if (isIbitAtrNum()) {
        if (!isFIfmtUser()) {
            out << "               Ifmt : " << ifmt() << std::endl;
        }
        if (isFIfmtUser()) {
            out << "       Dxfnumusr_cb : " << dxfnumusr_cb() << std::endl;
            out << "       FormatString : " << formatString() << std::endl;
        }
    }
    if (isIbitAtrFnt()) {
        out << "  FontNameIsUnicode : " << isFontNameIsUnicode() << std::endl;
        if (isFontNameIsUnicode()) {
            out << "           FontName : " << fontName() << std::endl;
        }
        if (!isFontNameIsUnicode()) {
            out << "           FontName : " << fontName() << std::endl;
        }
        out << "             Filler : " << filler() << std::endl;
        out << "         FontHeight : " << fontHeight() << std::endl;
        out << "         FontItalic : " << isFontItalic() << std::endl;
        out << "      FontStrikeout : " << isFontStrikeout() << std::endl;
        out << "         FontWeight : " << fontWeight() << std::endl;
        out << " FontSuperSubScript : " << fontSuperSubScriptToString(fontSuperSubScript()) << std::endl;
        out << "          Underline : " << underlineToString(underline()) << std::endl;
        out << "         FontFamily : " << fontFamilyToString(fontFamily()) << std::endl;
        out << "       CharacterSet : " << characterSet() << std::endl;
        out << "          FontColor : " << fontColor() << std::endl;
        out << "    FontItalicNinch : " << isFontItalicNinch() << std::endl;
        out << " FontStrikeoutNinch : " << isFontStrikeoutNinch() << std::endl;
        out << "SuperSubScriptNinch : " << isSuperSubScriptNinch() << std::endl;
        out << "     UnderlineNinch : " << isUnderlineNinch() << std::endl;
        out << "    FontWeightNinch : " << isFontWeightNinch() << std::endl;
        out << "      FontFirstChar : " << fontFirstChar() << std::endl;
        out << "      FontCharCount : " << fontCharCount() << std::endl;
        out << "             FontId : " << fontId() << std::endl;
    }
    if (isIbitAtrAlc()) {
        out << "HorizontalAlignment : " << horizontalAlignmentToString(horizontalAlignment()) << std::endl;
        out << "           TextWrap : " << isTextWrap() << std::endl;
        out << "  VerticalAlignment : " << verticalAlignmentToString(verticalAlignment()) << std::endl;
        out << "  LastLineJustified : " << isLastLineJustified() << std::endl;
        out << "        RawRotation : " << rawRotation() << std::endl;
        out << "   IndentationLevel : " << indentationLevel() << std::endl;
        out << "        ShrinkToFit : " << isShrinkToFit() << std::endl;
        out << "          MergeCell : " << isMergeCell() << std::endl;
        out << "       ReadingOrder : " << readingOrderToString(readingOrder()) << std::endl;
        out << "RelativeIndetationLevel : " << relativeIndetationLevel() << std::endl;
    }
    if (isIbitAtrBdr()) {
        out << "    LeftBorderStyle : " << borderStyleToString(leftBorderStyle()) << std::endl;
        out << "   RightBorderStyle : " << borderStyleToString(rightBorderStyle()) << std::endl;
        out << "     TopBorderStyle : " << borderStyleToString(topBorderStyle()) << std::endl;
        out << "  BottomBorderStyle : " << borderStyleToString(bottomBorderStyle()) << std::endl;
        out << "    LeftBorderColor : " << leftBorderColor() << std::endl;
        out << "   RightBorderColor : " << rightBorderColor() << std::endl;
        out << "DiagonalTopLeftBorder : " << isDiagonalTopLeftBorder() << std::endl;
        out << "DiagonalBottomLeftBorder : " << isDiagonalBottomLeftBorder() << std::endl;
        out << "     TopBorderColor : " << topBorderColor() << std::endl;
        out << "  BottomBorderColor : " << bottomBorderColor() << std::endl;
        out << "DiagonalBorderColor : " << diagonalBorderColor() << std::endl;
        out << "DiagonalBorderStyle : " << borderStyleToString(diagonalBorderStyle()) << std::endl;
    }
    if (isIbitAtrPat()) {
        out << "        FillPattern : " << fillPatternToString(fillPattern()) << std::endl;
        out << "   PatternForeColor : " << patternForeColor() << std::endl;
        out << "   PatternBackColor : " << patternBackColor() << std::endl;
    }
    if (isIbitAtrProt()) {
        out << "             Locked : " << isLocked() << std::endl;
        out << "             Hidden : " << isHidden() << std::endl;
    }
    out << "              Rgce1 : " << rgce1() << std::endl;
    out << "              Rgce2 : " << rgce2() << std::endl;
}

static Record* createCFRecord(Swinder::Workbook *book)
{
    return new CFRecord(book);
}

void registerRecordClasses()
{
    RecordRegistry::registerRecordClass(BackupRecord::id, createBackupRecord);
    RecordRegistry::registerRecordClass(BOFRecord::id, createBOFRecord);
    RecordRegistry::registerRecordClass(EOFRecord::id, createEOFRecord);
    RecordRegistry::registerRecordClass(BlankRecord::id, createBlankRecord);
    RecordRegistry::registerRecordClass(BoolErrRecord::id, createBoolErrRecord);
    RecordRegistry::registerRecordClass(StartBlockRecord::id, createStartBlockRecord);
    RecordRegistry::registerRecordClass(EndBlockRecord::id, createEndBlockRecord);
    RecordRegistry::registerRecordClass(ShapePropsStreamRecord::id, createShapePropsStreamRecord);
    RecordRegistry::registerRecordClass(TextPropsStreamRecord::id, createTextPropsStreamRecord);
    RecordRegistry::registerRecordClass(ChartFrtInfoRecord::id, createChartFrtInfoRecord);
    RecordRegistry::registerRecordClass(DataLabelExtContentsRecord::id, createDataLabelExtContentsRecord);
    RecordRegistry::registerRecordClass(ChartLayout12ARecord::id, createChartLayout12ARecord);
    RecordRegistry::registerRecordClass(LeftMarginRecord::id, createLeftMarginRecord);
    RecordRegistry::registerRecordClass(RightMarginRecord::id, createRightMarginRecord);
    RecordRegistry::registerRecordClass(TopMarginRecord::id, createTopMarginRecord);
    RecordRegistry::registerRecordClass(BottomMarginRecord::id, createBottomMarginRecord);
    RecordRegistry::registerRecordClass(BoundSheetRecord::id, createBoundSheetRecord);
    RecordRegistry::registerRecordClass(CalcModeRecord::id, createCalcModeRecord);
    RecordRegistry::registerRecordClass(ColInfoRecord::id, createColInfoRecord);
    RecordRegistry::registerRecordClass(DataTableRecord::id, createDataTableRecord);
    RecordRegistry::registerRecordClass(DateModeRecord::id, createDateModeRecord);
    RecordRegistry::registerRecordClass(DimensionRecord::id, createDimensionRecord);
    RecordRegistry::registerRecordClass(ExternSheetRecord::id, createExternSheetRecord);
    RecordRegistry::registerRecordClass(FontRecord::id, createFontRecord);
    RecordRegistry::registerRecordClass(HeaderRecord::id, createHeaderRecord);
    RecordRegistry::registerRecordClass(FooterRecord::id, createFooterRecord);
    RecordRegistry::registerRecordClass(FormatRecord::id, createFormatRecord);
    RecordRegistry::registerRecordClass(XFRecord::id, createXFRecord);
    RecordRegistry::registerRecordClass(LabelRecord::id, createLabelRecord);
    RecordRegistry::registerRecordClass(LabelSSTRecord::id, createLabelSSTRecord);
    RecordRegistry::registerRecordClass(MergedCellsRecord::id, createMergedCellsRecord);
    RecordRegistry::registerRecordClass(MulBlankRecord::id, createMulBlankRecord);
    RecordRegistry::registerRecordClass(NumberRecord::id, createNumberRecord);
    RecordRegistry::registerRecordClass(PaletteRecord::id, createPaletteRecord);
    RecordRegistry::registerRecordClass(RowRecord::id, createRowRecord);
    RecordRegistry::registerRecordClass(StringRecord::id, createStringRecord);
    RecordRegistry::registerRecordClass(NoteRecord::id, createNoteRecord);
    RecordRegistry::registerRecordClass(ProtectRecord::id, createProtectRecord);
    RecordRegistry::registerRecordClass(DefaultRowHeightRecord::id, createDefaultRowHeightRecord);
    RecordRegistry::registerRecordClass(DefaultColWidthRecord::id, createDefaultColWidthRecord);
    RecordRegistry::registerRecordClass(HCenterRecord::id, createHCenterRecord);
    RecordRegistry::registerRecordClass(VCenterRecord::id, createVCenterRecord);
    RecordRegistry::registerRecordClass(SetupRecord::id, createSetupRecord);
    RecordRegistry::registerRecordClass(CrtLineRecord::id, createCrtLineRecord);
    RecordRegistry::registerRecordClass(UnitsRecord::id, createUnitsRecord);
    RecordRegistry::registerRecordClass(PrintSizeRecord::id, createPrintSizeRecord);
    RecordRegistry::registerRecordClass(ChartRecord::id, createChartRecord);
    RecordRegistry::registerRecordClass(SheetExtRecord::id, createSheetExtRecord);
    RecordRegistry::registerRecordClass(BeginRecord::id, createBeginRecord);
    RecordRegistry::registerRecordClass(EndRecord::id, createEndRecord);
    RecordRegistry::registerRecordClass(DataFormatRecord::id, createDataFormatRecord);
    RecordRegistry::registerRecordClass(LineFormatRecord::id, createLineFormatRecord);
    RecordRegistry::registerRecordClass(MarkerFormatRecord::id, createMarkerFormatRecord);
    RecordRegistry::registerRecordClass(AreaFormatRecord::id, createAreaFormatRecord);
    RecordRegistry::registerRecordClass(PieRecord::id, createPieRecord);
    RecordRegistry::registerRecordClass(PieFormatRecord::id, createPieFormatRecord);
    RecordRegistry::registerRecordClass(AttachedLabelRecord::id, createAttachedLabelRecord);
    RecordRegistry::registerRecordClass(ChartFormatRecord::id, createChartFormatRecord);
    RecordRegistry::registerRecordClass(LegendRecord::id, createLegendRecord);
    RecordRegistry::registerRecordClass(SeriesListRecord::id, createSeriesListRecord);
    RecordRegistry::registerRecordClass(BarRecord::id, createBarRecord);
    RecordRegistry::registerRecordClass(LineRecord::id, createLineRecord);
    RecordRegistry::registerRecordClass(AreaRecord::id, createAreaRecord);
    RecordRegistry::registerRecordClass(ScatterRecord::id, createScatterRecord);
    RecordRegistry::registerRecordClass(AxisRecord::id, createAxisRecord);
    RecordRegistry::registerRecordClass(TickRecord::id, createTickRecord);
    RecordRegistry::registerRecordClass(ValueRangeRecord::id, createValueRangeRecord);
    RecordRegistry::registerRecordClass(CatSerRangeRecord::id, createCatSerRangeRecord);
    RecordRegistry::registerRecordClass(CrtLayout12Record::id, createCrtLayout12Record);
    RecordRegistry::registerRecordClass(CatLabRecord::id, createCatLabRecord);
    RecordRegistry::registerRecordClass(AxisLineRecord::id, createAxisLineRecord);
    RecordRegistry::registerRecordClass(CrtLinkRecord::id, createCrtLinkRecord);
    RecordRegistry::registerRecordClass(DefaultTextRecord::id, createDefaultTextRecord);
    RecordRegistry::registerRecordClass(TextRecord::id, createTextRecord);
    RecordRegistry::registerRecordClass(FontXRecord::id, createFontXRecord);
    RecordRegistry::registerRecordClass(ObjectLinkRecord::id, createObjectLinkRecord);
    RecordRegistry::registerRecordClass(PlotAreaRecord::id, createPlotAreaRecord);
    RecordRegistry::registerRecordClass(MsoDrawingSelectionRecord::id, createMsoDrawingSelectionRecord);
    RecordRegistry::registerRecordClass(Chart3dRecord::id, createChart3dRecord);
    RecordRegistry::registerRecordClass(PicFRecord::id, createPicFRecord);
    RecordRegistry::registerRecordClass(DropBarRecord::id, createDropBarRecord);
    RecordRegistry::registerRecordClass(RadarRecord::id, createRadarRecord);
    RecordRegistry::registerRecordClass(SurfRecord::id, createSurfRecord);
    RecordRegistry::registerRecordClass(RadarAreaRecord::id, createRadarAreaRecord);
    RecordRegistry::registerRecordClass(AxisParentRecord::id, createAxisParentRecord);
    RecordRegistry::registerRecordClass(LegendExceptionRecord::id, createLegendExceptionRecord);
    RecordRegistry::registerRecordClass(ShtPropsRecord::id, createShtPropsRecord);
    RecordRegistry::registerRecordClass(SerToCrtRecord::id, createSerToCrtRecord);
    RecordRegistry::registerRecordClass(AxesUsedRecord::id, createAxesUsedRecord);
    RecordRegistry::registerRecordClass(SBaseRefRecord::id, createSBaseRefRecord);
    RecordRegistry::registerRecordClass(SerParentRecord::id, createSerParentRecord);
    RecordRegistry::registerRecordClass(SerAuxTrendRecord::id, createSerAuxTrendRecord);
    RecordRegistry::registerRecordClass(IFmtRecord::id, createIFmtRecord);
    RecordRegistry::registerRecordClass(PosRecord::id, createPosRecord);
    RecordRegistry::registerRecordClass(AIRunsRecord::id, createAIRunsRecord);
    RecordRegistry::registerRecordClass(SerAuxErrBarRecord::id, createSerAuxErrBarRecord);
    RecordRegistry::registerRecordClass(ClrtClientRecord::id, createClrtClientRecord);
    RecordRegistry::registerRecordClass(SerFmtRecord::id, createSerFmtRecord);
    RecordRegistry::registerRecordClass(Chart3DBarShapeRecord::id, createChart3DBarShapeRecord);
    RecordRegistry::registerRecordClass(FbiRecord::id, createFbiRecord);
    RecordRegistry::registerRecordClass(BopPopRecord::id, createBopPopRecord);
    RecordRegistry::registerRecordClass(AxcExtRecord::id, createAxcExtRecord);
    RecordRegistry::registerRecordClass(DatRecord::id, createDatRecord);
    RecordRegistry::registerRecordClass(PlotGrowthRecord::id, createPlotGrowthRecord);
    RecordRegistry::registerRecordClass(SIIndexRecord::id, createSIIndexRecord);
    RecordRegistry::registerRecordClass(GelFrameRecord::id, createGelFrameRecord);
    RecordRegistry::registerRecordClass(BobPopCustomRecord::id, createBobPopCustomRecord);
    RecordRegistry::registerRecordClass(Fbi2Record::id, createFbi2Record);
    RecordRegistry::registerRecordClass(ZoomLevelRecord::id, createZoomLevelRecord);
    RecordRegistry::registerRecordClass(FrameRecord::id, createFrameRecord);
    RecordRegistry::registerRecordClass(SeriesRecord::id, createSeriesRecord);
    RecordRegistry::registerRecordClass(SeriesTextRecord::id, createSeriesTextRecord);
    RecordRegistry::registerRecordClass(GridSetReservedRecord::id, createGridSetReservedRecord);
    RecordRegistry::registerRecordClass(Excel9FileRecord::id, createExcel9FileRecord);
    RecordRegistry::registerRecordClass(Compat12Record::id, createCompat12Record);
    RecordRegistry::registerRecordClass(Window1Record::id, createWindow1Record);
    RecordRegistry::registerRecordClass(Window2Record::id, createWindow2Record);
    RecordRegistry::registerRecordClass(ObjProtectedRecord::id, createObjProtectedRecord);
    RecordRegistry::registerRecordClass(ScenarioProtectRecord::id, createScenarioProtectRecord);
    RecordRegistry::registerRecordClass(WinProtectRecord::id, createWinProtectRecord);
    RecordRegistry::registerRecordClass(Prot4RevRecord::id, createProt4RevRecord);
    RecordRegistry::registerRecordClass(Prot4RevPassRecord::id, createProt4RevPassRecord);
    RecordRegistry::registerRecordClass(PasswordRecord::id, createPasswordRecord);
    RecordRegistry::registerRecordClass(InterfaceHdrRecord::id, createInterfaceHdrRecord);
    RecordRegistry::registerRecordClass(MmsReservedRecord::id, createMmsReservedRecord);
    RecordRegistry::registerRecordClass(InterfaceEndRecord::id, createInterfaceEndRecord);
    RecordRegistry::registerRecordClass(LastWriteAccessRecord::id, createLastWriteAccessRecord);
    RecordRegistry::registerRecordClass(CodePageRecord::id, createCodePageRecord);
    RecordRegistry::registerRecordClass(DSFReservedRecord::id, createDSFReservedRecord);
    RecordRegistry::registerRecordClass(RRTabIdRecord::id, createRRTabIdRecord);
    RecordRegistry::registerRecordClass(HideObjRecord::id, createHideObjRecord);
    RecordRegistry::registerRecordClass(CalcPrecisionRecord::id, createCalcPrecisionRecord);
    RecordRegistry::registerRecordClass(RefreshAllRecord::id, createRefreshAllRecord);
    RecordRegistry::registerRecordClass(BookBoolRecord::id, createBookBoolRecord);
    RecordRegistry::registerRecordClass(StyleRecord::id, createStyleRecord);
    RecordRegistry::registerRecordClass(UsesELFsRecord::id, createUsesELFsRecord);
    RecordRegistry::registerRecordClass(CountryRecord::id, createCountryRecord);
    RecordRegistry::registerRecordClass(ExtSSTRecord::id, createExtSSTRecord);
    RecordRegistry::registerRecordClass(IndexRecord::id, createIndexRecord);
    RecordRegistry::registerRecordClass(DBCellRecord::id, createDBCellRecord);
    RecordRegistry::registerRecordClass(CalcCountRecord::id, createCalcCountRecord);
    RecordRegistry::registerRecordClass(CalcRefModeRecord::id, createCalcRefModeRecord);
    RecordRegistry::registerRecordClass(CalcIterRecord::id, createCalcIterRecord);
    RecordRegistry::registerRecordClass(CalcDeltaRecord::id, createCalcDeltaRecord);
    RecordRegistry::registerRecordClass(CalcSaveRecalcRecord::id, createCalcSaveRecalcRecord);
    RecordRegistry::registerRecordClass(PrintRowColRecord::id, createPrintRowColRecord);
    RecordRegistry::registerRecordClass(PrintGridRecord::id, createPrintGridRecord);
    RecordRegistry::registerRecordClass(GutsRecord::id, createGutsRecord);
    RecordRegistry::registerRecordClass(WsBoolRecord::id, createWsBoolRecord);
    RecordRegistry::registerRecordClass(FeatHdrRecord::id, createFeatHdrRecord);
    RecordRegistry::registerRecordClass(HeaderFooterRecord::id, createHeaderFooterRecord);
    RecordRegistry::registerRecordClass(PLVRecord::id, createPLVRecord);
    RecordRegistry::registerRecordClass(BuiltInFnGroupCountRecord::id, createBuiltInFnGroupCountRecord);
    RecordRegistry::registerRecordClass(RecalcIdRecord::id, createRecalcIdRecord);
    RecordRegistry::registerRecordClass(StyleExtRecord::id, createStyleExtRecord);
    RecordRegistry::registerRecordClass(PhoneticInfoRecord::id, createPhoneticInfoRecord);
    RecordRegistry::registerRecordClass(SelectionRecord::id, createSelectionRecord);
    RecordRegistry::registerRecordClass(PrinterSettingsRecord::id, createPrinterSettingsRecord);
    RecordRegistry::registerRecordClass(XFExtRecord::id, createXFExtRecord);
    RecordRegistry::registerRecordClass(XFCRCRecord::id, createXFCRCRecord);
    RecordRegistry::registerRecordClass(TableStylesRecord::id, createTableStylesRecord);
    RecordRegistry::registerRecordClass(MTRSettingsRecord::id, createMTRSettingsRecord);
    RecordRegistry::registerRecordClass(ForceFullCalculationRecord::id, createForceFullCalculationRecord);
    RecordRegistry::registerRecordClass(BookExtRecord::id, createBookExtRecord);
    RecordRegistry::registerRecordClass(ThemeRecord::id, createThemeRecord);
    RecordRegistry::registerRecordClass(CompressPicturesRecord::id, createCompressPicturesRecord);
    RecordRegistry::registerRecordClass(FilterModeRecord::id, createFilterModeRecord);
    RecordRegistry::registerRecordClass(AutoFilterRecord::id, createAutoFilterRecord);
    RecordRegistry::registerRecordClass(AutoFilter12Record::id, createAutoFilter12Record);
    RecordRegistry::registerRecordClass(AutoFilterInfoRecord::id, createAutoFilterInfoRecord);
    RecordRegistry::registerRecordClass(VerticalPageBreaksRecord::id, createVerticalPageBreaksRecord);
    RecordRegistry::registerRecordClass(HorizontalPageBreaksRecord::id, createHorizontalPageBreaksRecord);
    RecordRegistry::registerRecordClass(FilepassRecord::id, createFilepassRecord);
    RecordRegistry::registerRecordClass(UsrExclRecord::id, createUsrExclRecord);
    RecordRegistry::registerRecordClass(FileLockRecord::id, createFileLockRecord);
    RecordRegistry::registerRecordClass(RRDInfoRecord::id, createRRDInfoRecord);
    RecordRegistry::registerRecordClass(RRDHeadRecord::id, createRRDHeadRecord);
    RecordRegistry::registerRecordClass(HLinkRecord::id, createHLinkRecord);
    RecordRegistry::registerRecordClass(CondFmtRecord::id, createCondFmtRecord);
    RecordRegistry::registerRecordClass(CFRecord::id, createCFRecord);
}

} // namespace Swinder
