diff options
author | ALONSO Laurent <laurent.alonso@inria.fr> | 2021-08-27 09:59:11 +0200 |
---|---|---|
committer | ALONSO Laurent <laurent.alonso@inria.fr> | 2021-08-27 09:59:11 +0200 |
commit | dec0350b76a57bca4615f6a944332910c25459b5 (patch) | |
tree | 6a206d070a6708d237c4e13ff03a3db36a875cca | |
parent | 8ecbf0e820eeeaa779f90409fc1385720df8a1b4 (diff) |
iwa[tile]: use the new cells' definition if its exists.
Change-Id: Ic66b7d34433383182f81d5b649cea2debeac17df
-rw-r--r-- | src/lib/IWAParser.cpp | 146 | ||||
-rw-r--r-- | src/lib/IWAParser.h | 1 |
2 files changed, 82 insertions, 65 deletions
diff --git a/src/lib/IWAParser.cpp b/src/lib/IWAParser.cpp index c644273..d3244c1 100644 --- a/src/lib/IWAParser.cpp +++ b/src/lib/IWAParser.cpp @@ -150,6 +150,7 @@ IWAParser::TableInfo::TableInfo(const shared_ptr<IWORKTable> &table, const unsig , m_formattedTextList() , m_formulaList() , m_formatList() + , m_newFormatList() , m_commentList() { } @@ -2474,7 +2475,6 @@ void IWAParser::parseTabularModel(const unsigned id) const optional<unsigned> &formulaListRef = readRef(grid, 6); if (formulaListRef) parseDataList(get(formulaListRef), m_currentTable->m_formulaList); - // unsure, maybe we want to read 22 const optional<unsigned> &formatListRef = readRef(grid, 11); if (formatListRef) parseDataList(get(formatListRef), m_currentTable->m_formatList); @@ -2484,6 +2484,9 @@ void IWAParser::parseTabularModel(const unsigned id) const optional<unsigned> &commentListRef = readRef(grid, 19); if (commentListRef) parseDataList(get(commentListRef), m_currentTable->m_commentList); + const optional<unsigned> &newFormatListRef = readRef(grid, 22); + if (newFormatListRef) + parseDataList(get(newFormatListRef), m_currentTable->m_newFormatList); m_currentTable->m_table->setSizes(makeSizes(m_currentTable->m_columnHeader.m_sizes), makeSizes(m_currentTable->m_rowHeader.m_sizes)); @@ -2693,9 +2696,8 @@ void IWAParser::parseDataList(const unsigned id, DataList_t &dataList) void IWAParser::parseTileDefinition(unsigned row, unsigned column, RVNGInputStreamPtr_t &input, unsigned endPos, bool oldFormat) { IWORKCellType cellType = IWORK_CELL_TYPE_TEXT; - optional<unsigned> cellStyleId, paragraphStyleId; + optional<unsigned> cellStyleId, formatId, paragraphStyleId; optional<unsigned> commentId, formulaId, textId, textFormattedId; - optional<Format> format; optional<string> text; bool numberSet=false; @@ -2717,6 +2719,7 @@ void IWAParser::parseTileDefinition(unsigned row, unsigned column, RVNGInputStre { case 2: case 8: // nan + case 10: // devise cellType=IWORK_CELL_TYPE_NUMBER; break; case 7: // duration @@ -2751,23 +2754,7 @@ void IWAParser::parseTileDefinition(unsigned row, unsigned column, RVNGInputStre if (flags & 0x400) // condition 2 readU32(input); if (flags & 0x4) // format - { - const unsigned formatId=readU32(input); - auto const formatIt=m_currentTable->m_formatList.find(formatId); - if (formatIt !=m_currentTable->m_formatList.end()) - { - if (auto ref = boost::get<Format>(&formatIt->second)) - { - format=*ref; - if (format->m_type && get(format->m_type)==IWORK_CELL_TYPE_NUMBER && cellType!=IWORK_CELL_TYPE_TEXT) - format->m_type=cellType; - } - } - else - { - ETONYEK_DEBUG_MSG(("IWAParser::parseTileDefinition: can not find format %d\n", int(formatId))); - } - } + formatId=readU32(input); if (flags & 0x8) // formula formulaId = readU32(input); if (flags & 0x1000) // comment @@ -2853,8 +2840,8 @@ void IWAParser::parseTileDefinition(unsigned row, unsigned column, RVNGInputStre case 1: cellType=IWORK_CELL_TYPE_NUMBER; break; - case 2: // checkme - cellType=IWORK_CELL_TYPE_BOOL; + case 2: // devise(changeme) + cellType=IWORK_CELL_TYPE_NUMBER; break; case 3: cellType=IWORK_CELL_TYPE_DATE_TIME; @@ -2876,23 +2863,11 @@ void IWAParser::parseTileDefinition(unsigned row, unsigned column, RVNGInputStre { if ((flags & hBytes)==0) continue; - const unsigned formatId=readU32(input); + const unsigned id=readU32(input); + // checkme, unclear which format id we need to choose when resType=2 or 6 if (w+1!=resType) continue; - auto const formatIt=m_currentTable->m_formatList.find(formatId); - if (formatIt !=m_currentTable->m_formatList.end()) - { - if (auto ref = boost::get<Format>(&formatIt->second)) - { - format=*ref; - if (format->m_type && get(format->m_type)==IWORK_CELL_TYPE_NUMBER && cellType!=IWORK_CELL_TYPE_TEXT) - format->m_type=cellType; - } - } - else - { - ETONYEK_DEBUG_MSG(("IWAParser::parseTileDefinition[new]: can not find format[%d] %d\n", w, int(formatId))); - } + formatId=id; } if (flags & 0x80000) commentId=readU32(input); @@ -2976,6 +2951,27 @@ void IWAParser::parseTileDefinition(unsigned row, unsigned column, RVNGInputStre paragraphStyle = queryParagraphStyle(*ref); } } + optional<Format> format; + if (bool(formatId)) + { + auto const &formatList=oldFormat ? m_currentTable->m_formatList : m_currentTable->m_newFormatList; + auto const formatIt=formatList.find(get(formatId)); + if (formatIt != formatList.end()) + { + if (auto ref = boost::get<Format>(&formatIt->second)) + { + format=*ref; + if (format->m_type && get(format->m_type)==IWORK_CELL_TYPE_NUMBER && cellType!=IWORK_CELL_TYPE_TEXT) + format->m_type=cellType; + } + } + else + { + ETONYEK_DEBUG_MSG(("IWAParser::parseTileDefinition: can not find format %d\n", int(get(formatId)))); + } + } + IWORKPropertyMap props; + bool addPropsToCellStyle=false; if (format && !textSet) { if (get(format).m_type) @@ -2983,8 +2979,7 @@ void IWAParser::parseTileDefinition(unsigned row, unsigned column, RVNGInputStre auto type=get(get(format).m_type); if (!numberSet || (type!=IWORK_CELL_TYPE_TEXT && type!=IWORK_CELL_TYPE_NUMBER)) cellType=type; } - IWORKPropertyMap props; - bool addProps=true; + addPropsToCellStyle=true; if (cellType==IWORK_CELL_TYPE_DATE_TIME && boost::get<IWORKDateTimeFormat>(&get(format).m_format)) props.put<property::SFTCellStylePropertyDateTimeFormat>(*boost::get<IWORKDateTimeFormat>(&get(format).m_format)); else if (cellType==IWORK_CELL_TYPE_DURATION && boost::get<IWORKDurationFormat>(&get(format).m_format)) @@ -2992,9 +2987,7 @@ void IWAParser::parseTileDefinition(unsigned row, unsigned column, RVNGInputStre else if (cellType!=IWORK_CELL_TYPE_TEXT && boost::get<IWORKNumberFormat>(&get(format).m_format)) props.put<property::SFTCellStylePropertyNumberFormat>(*boost::get<IWORKNumberFormat>(&get(format).m_format)); else - addProps=false; - if (addProps) - cellStyle.reset(new IWORKStyle(props, none, cellStyle)); + addPropsToCellStyle=false; } bool needText=bool(textRef) || (bool(text) && !formula && cellType == IWORK_CELL_TYPE_TEXT); @@ -3019,10 +3012,11 @@ void IWAParser::parseTileDefinition(unsigned row, unsigned column, RVNGInputStre } else if (paragraphStyle) { - IWORKPropertyMap props; + addPropsToCellStyle=true; props.put<property::SFTCellStylePropertyParagraphStyle>(paragraphStyle); - cellStyle.reset(new IWORKStyle(props, none, cellStyle)); } + if (addPropsToCellStyle) + cellStyle.reset(new IWORKStyle(props, none, cellStyle)); optional<IWORKDateTimeData> dateTime; m_currentTable->m_table->insertCell(column, row, text, m_currentText, dateTime, 1, 1, formula, unsigned(row*256+column), cellStyle, cellType); if (bool(commentId)) @@ -3075,32 +3069,39 @@ void IWAParser::parseTile(const unsigned id, const unsigned decalY) // process rows for (auto it : rows) { - RVNGInputStreamPtr_t input = get(it.second->bytes(3)); - auto length = unsigned(getLength(input)); - if (length >= 0xffff) - { - ETONYEK_DEBUG_MSG(("IWAParser::parseTile: invalid column data length: %u\n", length)); - length = 0xffff; - } - bool useNewFormat=false; map<unsigned,unsigned> offsets; - if (/*1 || */(!parseColumnOffsets(get(it.second->bytes(4)), length, offsets) && get(it.second->bytes(6)))) + RVNGInputStreamPtr_t input; + unsigned length=0; + + /* first check if we can use the new definitions: data=6,offset=7,flag=[8], + if this is not possible, use the old definitions: data=3,offset=4 */ + for (auto wh : + { + 6, 3 + }) { offsets.clear(); + if (!bool(it.second->bytes(unsigned(wh)+1))) + continue; + input = get(it.second->bytes(unsigned(wh))); + if (!input) continue; + length = unsigned(getLength(input)); unsigned factor=1; - if (it.second->bool_(8) && get(it.second->bool_(8))) + if (wh==6 && it.second->bool_(8) && get(it.second->bool_(8))) factor=4; - input = get(it.second->bytes(6)); - length = unsigned(getLength(input)); + if (length >= factor*0xffff) { - ETONYEK_DEBUG_MSG(("IWAParser::parseTile: invalid new column data length: %u\n", length)); + ETONYEK_DEBUG_MSG(("IWAParser::parseTile: invalid column data length: %u\n", length)); length = factor*0xffff; } - useNewFormat=true; - parseColumnOffsets(get(it.second->bytes(7)), length, offsets, factor); + + useNewFormat=wh==6; + if (!parseColumnOffsets(get(it.second->bytes(unsigned(wh)+1)), length, offsets, factor)) + continue; + break; } for (auto offIt=offsets.begin(); offIt!=offsets.end() ;) @@ -3220,16 +3221,31 @@ bool IWAParser::parseFormat(const IWAMessage &msg, IWAParser::Format &format) auto type=get(msg.uint32(1)); format.m_type=IWORK_CELL_TYPE_NUMBER; IWORKCellNumberType nType=IWORK_CELL_NUMBER_TYPE_DOUBLE; + if (type==265) // check if data's type is defined + { + if (msg.uint32(24)) + type=get(msg.uint32(24)); + } switch (type) { case 1: // automatic return true; case 263: // checkbox + format.m_type=IWORK_CELL_TYPE_BOOL; + return true; case 264: // stepper case 265: // slider case 266: // pop-up menu - case 267: // star rating + case 267: // star rating + { + static bool first=true; + if (first) + { + ETONYEK_DEBUG_MSG(("IWAParser::parseFormat: using type=%d is not implemented\n", int(type))); + first=false; + } return false; + } case 257: // currency nType=IWORK_CELL_NUMBER_TYPE_CURRENCY; break; @@ -3293,7 +3309,7 @@ bool IWAParser::parseFormat(const IWAMessage &msg, IWAParser::Format &format) return true; } default: - ETONYEK_DEBUG_MSG(("IWAParser::parseFormat: find unknown type\n")); + ETONYEK_DEBUG_MSG(("IWAParser::parseFormat: find unknown type=%d\n", int(type))); return false; } IWORKNumberFormat nFormat; @@ -3561,7 +3577,7 @@ bool IWAParser::parseFormula(const IWAMessage &msg, IWORKFormulaPtr_t &formula) case 35: // arg end break; default: - if ((get(type)>=1 && get(type)<=15) || get(type)==29) + if ((get(type)>=1 && get(type)<=15) || get(type)==29 || get(type)==45) { char const *wh[] = { @@ -3570,13 +3586,13 @@ bool IWAParser::parseFormula(const IWAMessage &msg, IWORKFormulaPtr_t &formula) "<", "<=", "=", "<>", "-", "+", "%" }; - if (get(type)!=29 && !wh[get(type)]) + if (get(type)<=15 && !wh[get(type)]) { ETONYEK_DEBUG_MSG(("IWAParser::parseFormula: find unexpected type=%u\n", get(type))); ok=false; break; } - size_t numArgs=(get(type)<13 || get(type)==29) ? 2 : 1; + size_t numArgs=(get(type)<13 || get(type)>=29) ? 2 : 1; size_t numData=stack.size(); if (numData<numArgs) { @@ -3588,7 +3604,7 @@ bool IWAParser::parseFormula(const IWAMessage &msg, IWORKFormulaPtr_t &formula) if (numArgs==2) { child.insert(child.end(), stack[numData-2].begin(),stack[numData-2].end()); - child.push_back(IWORKFormula::Token(get(type)==29 ? ":" : wh[get(type)], IWORKFormula::Token::Operator)); + child.push_back(IWORKFormula::Token(get(type)>=29 ? ":" : wh[get(type)], IWORKFormula::Token::Operator)); child.insert(child.end(), stack[numData-1].begin(),stack[numData-1].end()); } else if (get(type)<15) diff --git a/src/lib/IWAParser.h b/src/lib/IWAParser.h index 506ad7b..d747e1b 100644 --- a/src/lib/IWAParser.h +++ b/src/lib/IWAParser.h @@ -178,6 +178,7 @@ private: DataList_t m_formattedTextList; DataList_t m_formulaList; DataList_t m_formatList; + DataList_t m_newFormatList; DataList_t m_commentList; }; |