UT_Error OXML_Element_Table::serialize(IE_Exp_OpenXML* exporter) { UT_Error err = UT_OK; err = exporter->startTable(); if(err != UT_OK) return err; err = this->serializeProperties(exporter); if(err != UT_OK) return err; //set the row numbers std::vector<OXML_Element*>::size_type i; OXML_ElementVector children = getChildren(); for (i = 0; i < children.size(); i++) { OXML_Element_Row* r = static_cast<OXML_Element_Row*>(get_pointer(children[i])); r->setRowNumber(i); } err = this->serializeChildren(exporter); if(err != UT_OK) return err; return exporter->finishTable(); }
bool OXML_Element_Table::incrementBottomVerticalMergeStart(OXML_Element_Cell* cell) { std::vector<OXML_Element_Row*>::reverse_iterator rit; for( rit=m_rows.rbegin(); rit < m_rows.rend(); ++rit ) { OXML_Element_Row* pRow = *rit; if(pRow->incrementBottomVerticalMergeStart(cell)) return true; } return false; }
bool OXML_Element_Table::incrementRightHorizontalMergeStart(OXML_Element_Cell* cell) { std::vector<OXML_Element_Row*>::reverse_iterator rit; for( rit=m_rows.rbegin(); rit < m_rows.rend(); ++rit ) { OXML_Element_Row* pRow = *rit; if(pRow->incrementRightHorizontalMergeStart(cell)) return true; cell->setTop(cell->getTop()-1); //decrement top if we can't find the starting cell in this row } return false; }
void OXML_Element_Table::addMissingCell(int rowNumber, OXML_Element_Cell* cell) { std::vector<OXML_Element*>::size_type i; OXML_ElementVector children = getChildren(); for (i = 0; i < children.size(); i++) { OXML_Element_Row* r = static_cast<OXML_Element_Row*>(get_pointer(children[i])); if(i == rowNumber) { r->addMissingCell(cell); return; } } }
bool IE_Exp_OpenXML_Listener::populateStrux(pf_Frag_Strux* sdh, const PX_ChangeRecord* pcr , fl_ContainerLayout** /* psfh */) { if(pcr->getType() != PX_ChangeRecord::PXT_InsertStrux) return false; const PX_ChangeRecord_Strux* pcrx = static_cast<const PX_ChangeRecord_Strux *> (pcr); PT_AttrPropIndex api = pcr->getIndexAP(); const PP_AttrProp* pAP = NULL; bool bHaveProp = pdoc->getAttrProp(api,&pAP); switch (pcrx->getStruxType()) { case PTX_Section: { section = new OXML_Section(); section->setTarget(TARGET_DOCUMENT); OXML_SharedSection shared_section(section); //add section properties if(bHaveProp && pAP) { const gchar* szValue; const gchar* szName; size_t propCount = pAP->getPropertyCount(); size_t i; for(i=0; i<propCount; i++) { if(pAP->getNthProperty(i, szName, szValue)) { //TODO: Take the debug message out when we are done UT_DEBUGMSG(("Section Property: %s=%s\n", szName, szValue)); if(section->setProperty(szName, szValue) != UT_OK) return false; } } size_t attrCount = pAP->getAttributeCount(); for(i=0; i<attrCount; i++) { if(pAP->getNthAttribute(i, szName, szValue)) { //TODO: Take the debug message out when we are done UT_DEBUGMSG(("Section Attribute: %s=%s\n", szName, szValue)); if(section->setAttribute(szName, szValue) != UT_OK) return false; } } } return document->appendSection(shared_section) == UT_OK; } case PTX_Block: { paragraph = new OXML_Element_Paragraph(getNextId()); OXML_SharedElement shared_paragraph(static_cast<OXML_Element*>(paragraph)); //add paragraph properties if(bHaveProp && pAP) { const gchar* szValue; const gchar* szName; size_t propCount = pAP->getPropertyCount(); size_t i; for(i=0; i<propCount; i++) { if(pAP->getNthProperty(i, szName, szValue)) { if(paragraph->setProperty(szName, szValue) != UT_OK) return false; } } size_t attrCount = pAP->getAttributeCount(); for(i=0; i<attrCount; i++) { if(pAP->getNthAttribute(i, szName, szValue)) { if(paragraph->setAttribute(szName, szValue) != UT_OK) return false; } } } if(!m_cellStack.empty()) { OXML_Element_Cell* cell = m_cellStack.top(); return cell->appendElement(shared_paragraph) == UT_OK; } else if(bInTextbox) return textbox->appendElement(shared_paragraph) == UT_OK; return section->appendElement(shared_paragraph) == UT_OK; } case PTX_SectionHdrFtr: { section = new OXML_Section(getNextId()); OXML_SharedSection shared_section(static_cast<OXML_Section*>(section)); if(bHaveProp && pAP) { const gchar* szValue; const gchar* szName; size_t propCount = pAP->getPropertyCount(); size_t i; for(i=0; i<propCount; i++) { if(pAP->getNthProperty(i, szName, szValue)) { //TODO: Take the debug message out when we are done UT_DEBUGMSG(("Header/Footer Property: %s=%s\n", szName, szValue)); if(section->setProperty(szName, szValue) != UT_OK) return false; } } size_t attrCount = pAP->getAttributeCount(); for(i=0; i<attrCount; i++) { if(pAP->getNthAttribute(i, szName, szValue)) { //TODO: Take the debug message out when we are done UT_DEBUGMSG(("Header/Footer Attribute: %s=%s\n", szName, szValue)); if(section->setAttribute(szName, szValue) != UT_OK) return false; } } if(pAP->getAttribute("type", szValue)) { if(strstr(szValue, "header")) { section->setTarget(TARGET_HEADER); return document->addHeader(shared_section) == UT_OK; } else if(strstr(szValue, "footer")) { section->setTarget(TARGET_FOOTER); return document->addFooter(shared_section) == UT_OK; } } } return true; } case PTX_SectionEndnote: { savedSection = section; //save the current section savedParagraph = paragraph; //save the current paragraph section = new OXML_Section(getNextId()); OXML_SharedSection shared_section(static_cast<OXML_Section*>(section)); section->setTarget(TARGET_ENDNOTE); if(bHaveProp && pAP) { const gchar* szValue; const gchar* szName; size_t propCount = pAP->getPropertyCount(); size_t i; for(i=0; i<propCount; i++) { if(pAP->getNthProperty(i, szName, szValue)) { //TODO: Take the debug message out when we are done UT_DEBUGMSG(("Endnote Property: %s=%s\n", szName, szValue)); if(section->setProperty(szName, szValue) != UT_OK) return false; } } size_t attrCount = pAP->getAttributeCount(); for(i=0; i<attrCount; i++) { if(pAP->getNthAttribute(i, szName, szValue)) { //TODO: Take the debug message out when we are done UT_DEBUGMSG(("Endnote Attribute: %s=%s\n", szName, szValue)); if(section->setAttribute(szName, szValue) != UT_OK) return false; } } } return document->addEndnote(shared_section) == UT_OK; } case PTX_SectionTable: { OXML_Element_Table* table = new OXML_Element_Table(getNextId()); OXML_SharedElement shared_table(static_cast<OXML_Element*>(table)); if(bHaveProp && pAP) { const gchar* szValue; const gchar* szName; size_t propCount = pAP->getPropertyCount(); size_t i; for(i=0; i<propCount; i++) { if(pAP->getNthProperty(i, szName, szValue)) { //TODO: Take the debug message out when we are done UT_DEBUGMSG(("Table Property: %s=%s\n", szName, szValue)); if(table->setProperty(szName, szValue) != UT_OK) return false; } } size_t attrCount = pAP->getAttributeCount(); for(i=0; i<attrCount; i++) { if(pAP->getNthAttribute(i, szName, szValue)) { //TODO: Take the debug message out when we are done UT_DEBUGMSG(("Table Attribute: %s=%s\n", szName, szValue)); if(table->setAttribute(szName, szValue) != UT_OK) return false; } } } tableHelper.OpenTable(sdh, pcr->getIndexAP()); bool tableInTable = !m_tableStack.empty(); m_tableStack.push(table); if(tableInTable) { //this is a table inside another table OXML_Element_Cell* cell = m_cellStack.top(); return cell->appendElement(shared_table) == UT_OK; } return section->appendElement(shared_table) == UT_OK; } case PTX_SectionCell: { OXML_Element_Table* table = NULL; if(!m_tableStack.empty()) table = m_tableStack.top(); if(!table) { UT_DEBUGMSG(("FRT: OpenXML exporter corrupted table layout. Invalid Cell Open.")); return false; } OXML_Element_Row* row = NULL; if(!m_rowStack.empty()) row = m_rowStack.top(); tableHelper.OpenCell(api); UT_sint32 left = tableHelper.getLeft(); UT_sint32 right = tableHelper.getRight(); UT_sint32 top = tableHelper.getTop(); UT_sint32 bottom = tableHelper.getBot(); if(!row || tableHelper.isNewRow()) { row = new OXML_Element_Row(getNextId(), table); m_rowStack.push(row); row->setNumCols(tableHelper.getNumCols()); OXML_SharedElement shared_row(static_cast<OXML_Element*>(row)); if(table->appendElement(shared_row) != UT_OK) return false; } OXML_Element_Cell* cell = new OXML_Element_Cell(getNextId(), table, row, left, right, top, bottom); m_cellStack.push(cell); OXML_SharedElement shared_cell(static_cast<OXML_Element*>(cell)); if(bHaveProp && pAP) { const gchar* szValue; const gchar* szName; size_t propCount = pAP->getPropertyCount(); size_t i; for(i=0; i<propCount; i++) { if(pAP->getNthProperty(i, szName, szValue)) { //TODO: Take the debug message out when we are done UT_DEBUGMSG(("Cell Property: %s=%s\n", szName, szValue)); if(cell->setProperty(szName, szValue) != UT_OK) return false; } } size_t attrCount = pAP->getAttributeCount(); for(i=0; i<attrCount; i++) { if(pAP->getNthAttribute(i, szName, szValue)) { //TODO: Take the debug message out when we are done UT_DEBUGMSG(("Cell Attribute: %s=%s\n", szName, szValue)); if(cell->setAttribute(szName, szValue) != UT_OK) return false; } } } return row->appendElement(shared_cell) == UT_OK; } case PTX_SectionFootnote: { savedSection = section; //save the current section savedParagraph = paragraph; //save the current paragraph section = new OXML_Section(getNextId()); OXML_SharedSection shared_section(static_cast<OXML_Section*>(section)); section->setTarget(TARGET_FOOTNOTE); if(bHaveProp && pAP) { const gchar* szValue; const gchar* szName; size_t propCount = pAP->getPropertyCount(); size_t i; for(i=0; i<propCount; i++) { if(pAP->getNthProperty(i, szName, szValue)) { //TODO: Take the debug message out when we are done UT_DEBUGMSG(("Footnote Property: %s=%s\n", szName, szValue)); if(section->setProperty(szName, szValue) != UT_OK) return false; } } size_t attrCount = pAP->getAttributeCount(); for(i=0; i<attrCount; i++) { if(pAP->getNthAttribute(i, szName, szValue)) { //TODO: Take the debug message out when we are done UT_DEBUGMSG(("Footnote Attribute: %s=%s\n", szName, szValue)); if(section->setAttribute(szName, szValue) != UT_OK) return false; } } } return document->addFootnote(shared_section) == UT_OK; } case PTX_SectionFrame: { const gchar* frameType = NULL; if(!(bHaveProp && pAP)) return true; if(!(pAP->getProperty("frame-type",frameType) && frameType && *frameType)) return true; if(!strcmp(frameType,"textbox")) { bInTextbox = true; } else if(!strcmp(frameType,"image")) { // TODO: handle positioned images } if(bInTextbox) { textbox = new OXML_Element_TextBox(getNextId()); OXML_SharedElement shared_textbox(static_cast<OXML_Element*>(textbox)); OXML_Element_Run* element_run = new OXML_Element_Run(getNextId()); OXML_SharedElement shared_element_run(static_cast<OXML_Element*>(element_run)); if(element_run->appendElement(shared_textbox) != UT_OK) return false; const gchar* szValue; const gchar* szName; size_t propCount = pAP->getPropertyCount(); size_t i; for(i=0; i<propCount; i++) { if(pAP->getNthProperty(i, szName, szValue)) { //TODO: Take the debug message out when we are done UT_DEBUGMSG(("TextBox Property: %s=%s\n", szName, szValue)); if(textbox->setProperty(szName, szValue) != UT_OK) return false; } } size_t attrCount = pAP->getAttributeCount(); for(i=0; i<attrCount; i++) { if(pAP->getNthAttribute(i, szName, szValue)) { //TODO: Take the debug message out when we are done UT_DEBUGMSG(("TextBox Attribute: %s=%s\n", szName, szValue)); if(textbox->setAttribute(szName, szValue) != UT_OK) return false; } } return paragraph->appendElement(shared_element_run) == UT_OK; } return true; } case PTX_EndCell: { tableHelper.CloseCell(); if(m_cellStack.empty()) return false; m_cellStack.pop(); return true; } case PTX_EndTable: { tableHelper.CloseTable(); if(m_tableStack.empty()) return false; //pop the rows that belong to this table int nRows = m_tableStack.top()->getNumberOfRows(); for(int i=0; i<nRows; i++) { if(m_rowStack.empty()) return false; m_rowStack.pop(); } //pop the table m_tableStack.pop(); return true; } case PTX_EndFootnote: { section = savedSection; //recover the last section paragraph = savedParagraph; //recover the last paragraph return true; } case PTX_EndEndnote: { section = savedSection; //recover the last section paragraph = savedParagraph; //recover the last paragraph return true; } case PTX_EndFrame: { if(bInTextbox) bInTextbox = false; return true; } case PTX_SectionMarginnote: case PTX_SectionAnnotation: case PTX_SectionTOC: case PTX_EndMarginnote: case PTX_EndAnnotation: case PTX_EndTOC: default: return true; } return true; }
void OXMLi_ListenerState_Table::startElement (OXMLi_StartElementRequest * rqst) { if (nameMatches(rqst->pName, NS_W_KEY, "tbl")) { OXML_Element_Table* pTable = new OXML_Element_Table(""); m_tableStack.push(pTable); OXML_SharedElement table(pTable); rqst->stck->push(table); rqst->handled = true; pTable->setCurrentRowNumber(-1); pTable->setCurrentColNumber(-1); } else if(nameMatches(rqst->pName, NS_W_KEY, "tr")) { if(m_tableStack.empty()) { rqst->handled = false; rqst->valid = false; return; } OXML_Element_Table* table = m_tableStack.top(); OXML_Element_Row* pRow = new OXML_Element_Row("", table); m_rowStack.push(pRow); OXML_SharedElement row(pRow); rqst->stck->push(row); rqst->handled = true; table->incrementCurrentRowNumber(); table->setCurrentColNumber(0); pRow->setRowNumber(table->getCurrentRowNumber()); } else if(nameMatches(rqst->pName, NS_W_KEY, "tc")) { if(m_tableStack.empty() || m_rowStack.empty()) { rqst->handled = false; rqst->valid = false; return; } OXML_Element_Table* table = m_tableStack.top(); OXML_Element_Row* row = m_rowStack.top(); OXML_Element_Cell* pCell = new OXML_Element_Cell("", table, row, table->getCurrentColNumber(), table->getCurrentColNumber()+1, //left right table->getCurrentRowNumber(), table->getCurrentRowNumber()+1); //top,bottom m_cellStack.push(pCell); OXML_SharedElement cell(pCell); rqst->stck->push(cell); rqst->handled = true; table->incrementCurrentColNumber(); } else if(nameMatches(rqst->pName, NS_W_KEY, "gridSpan")) { if(m_tableStack.empty() || m_cellStack.empty()) { rqst->handled = false; rqst->valid = false; return; } OXML_Element_Table* table = m_tableStack.top(); const gchar* val = attrMatches(NS_W_KEY, "val", rqst->ppAtts); if(val) { int span = atoi(val); int left = table->getCurrentColNumber()-1; int right = left + span; //change current cell's right index OXML_Element_Cell* cell = m_cellStack.top(); cell->setRight(right); //update column index of current table table->setCurrentColNumber(right); } rqst->handled = true; } else if(nameMatches(rqst->pName, NS_W_KEY, "vMerge")) { if(m_cellStack.empty()) { rqst->handled = false; rqst->valid = false; return; } OXML_Element_Cell* cell = m_cellStack.top(); cell->setVerticalMergeStart(false); //default to continue if the attribute is missing const gchar* val = attrMatches(NS_W_KEY, "val", rqst->ppAtts); if(val && !strcmp(val, "restart")) { cell->setVerticalMergeStart(true); } rqst->handled = true; } else if(nameMatches(rqst->pName, NS_W_KEY, "hMerge")) { if(m_cellStack.empty()) { rqst->handled = false; rqst->valid = false; return; } OXML_Element_Cell* cell = m_cellStack.top(); cell->setHorizontalMergeStart(false); //default to continue if the attribute is missing const gchar* val = attrMatches(NS_W_KEY, "val", rqst->ppAtts); if(val && !strcmp(val, "restart")) { cell->setHorizontalMergeStart(true); } rqst->handled = true; } //Table Properties else if(nameMatches(rqst->pName, NS_W_KEY, "gridCol") && contextMatches(rqst->context->back(), NS_W_KEY, "tblGrid")) { if(m_tableStack.empty()) { rqst->handled = false; rqst->valid = false; return; } OXML_Element_Table* table = m_tableStack.top(); const gchar* w = attrMatches(NS_W_KEY, "w", rqst->ppAtts); if(w) { //append this width to table-column-props property const gchar* tableColumnProps = NULL; UT_Error ret = table->getProperty("table-column-props", tableColumnProps); if((ret != UT_OK) || !tableColumnProps) tableColumnProps = ""; std::string cols(tableColumnProps); cols += _TwipsToPoints(w); cols += "pt/"; ret = table->setProperty("table-column-props", cols); if(ret != UT_OK) { UT_DEBUGMSG(("FRT:OpenXML importer can't set table-column-props:%s\n", cols.c_str())); } } rqst->handled = true; } else if(nameMatches(rqst->pName, NS_W_KEY, "trHeight") && contextMatches(rqst->context->back(), NS_W_KEY, "trPr")) { if(m_tableStack.empty()) { rqst->handled = false; rqst->valid = false; return; } OXML_Element_Table* table = m_tableStack.top(); const gchar* val = attrMatches(NS_W_KEY, "val", rqst->ppAtts); if(val) { const gchar* tableRowHeights = NULL; UT_Error ret = table->getProperty("table-row-heights", tableRowHeights); if((ret != UT_OK) || !tableRowHeights) tableRowHeights = ""; std::string rowHeights(tableRowHeights); rowHeights += _TwipsToPoints(val); rowHeights += "pt/"; ret = table->setProperty("table-row-heights", rowHeights); if(ret != UT_OK) { UT_DEBUGMSG(("FRT:OpenXML importer can't set table-row-heights:%s\n", rowHeights.c_str())); } } rqst->handled = true; } else if(nameMatches(rqst->pName, NS_W_KEY, "left") || nameMatches(rqst->pName, NS_W_KEY, "right") || nameMatches(rqst->pName, NS_W_KEY, "top") || nameMatches(rqst->pName, NS_W_KEY, "bottom")) { rqst->handled = true; const gchar* color = attrMatches(NS_W_KEY, "color", rqst->ppAtts); const gchar* sz = attrMatches(NS_W_KEY, "sz", rqst->ppAtts); const gchar* val = attrMatches(NS_W_KEY, "val", rqst->ppAtts); UT_Error ret = UT_OK; std::string borderName(rqst->pName); borderName = borderName.substr(strlen(NS_W_KEY)+1); if(!borderName.compare("bottom")) borderName = "bot"; std::string borderStyle = borderName + "-style"; std::string borderColor = borderName + "-color"; std::string borderThickness = borderName + "-thickness"; OXML_Element* element = NULL; if(rqst->context->empty()) { rqst->handled = false; rqst->valid = false; return; } if(contextMatches(rqst->context->back(), NS_W_KEY, "tcBorders")) element = m_cellStack.empty() ? NULL : m_cellStack.top(); else if(contextMatches(rqst->context->back(), NS_W_KEY, "tblBorders")) element = m_tableStack.empty() ? NULL : m_tableStack.top(); if(!element) { rqst->handled = false; rqst->valid = false; return; } if(color && strcmp(color, "auto")) { ret = element->setProperty(borderColor, color); if(ret != UT_OK) { UT_DEBUGMSG(("FRT:OpenXML importer can't set %s:%s\n", borderColor.c_str(), color)); } } if(sz) { std::string szVal(_EighthPointsToPoints(sz)); szVal += "pt"; ret = element->setProperty(borderThickness, szVal); if(ret != UT_OK) { UT_DEBUGMSG(("FRT:OpenXML importer can't set %s:%s\n", borderThickness.c_str(), color)); } } std::string styleValue = "1"; //single line border by default if(val) { if(!strcmp(val, "dashed")) styleValue = "0"; } ret = element->setProperty(borderStyle, styleValue); if(ret != UT_OK) { UT_DEBUGMSG(("FRT:OpenXML importer can't set %s:0\n", borderStyle.c_str())); } } else if(nameMatches(rqst->pName, NS_W_KEY, "shd")) { const gchar* fill = attrMatches(NS_W_KEY, "fill", rqst->ppAtts); UT_Error ret = UT_OK; OXML_Element* element = NULL; if(rqst->context->empty()) { rqst->handled = false; rqst->valid = false; return; } if(contextMatches(rqst->context->back(), NS_W_KEY, "tcPr")) element = m_cellStack.empty() ? NULL : m_cellStack.top(); else if(contextMatches(rqst->context->back(), NS_W_KEY, "tblPr")) element = m_tableStack.empty() ? NULL : m_tableStack.top(); if(!element) { rqst->handled = false; rqst->valid = false; return; } if(fill && strcmp(fill, "auto")) { ret = element->setProperty("background-color", fill); if(ret != UT_OK) { UT_DEBUGMSG(("FRT:OpenXML importer can't set background-color:%s\n", fill)); } } rqst->handled = true; } else if(nameMatches(rqst->pName, NS_W_KEY, "tblStyle")) { if(m_tableStack.empty()) { rqst->handled = false; rqst->valid = false; return; } OXML_Element_Table* table = m_tableStack.top(); const gchar* val = attrMatches(NS_W_KEY, "val", rqst->ppAtts); if(val && table) { std::string styleName(val); OXML_Document* doc = OXML_Document::getInstance(); if(doc) table->applyStyle(doc->getStyleById(styleName)); } rqst->handled = true; } else if(nameMatches(rqst->pName, NS_W_KEY, "tblPr")) { if(m_tableStack.empty()) { //we must be in tblStyle in styles, so let's push the table instance to m_tableStack OXML_Element_Table* tbl = static_cast<OXML_Element_Table*>(get_pointer(rqst->stck->top())); m_tableStack.push(tbl); } rqst->handled = true; } else if(nameMatches(rqst->pName, NS_W_KEY, "trPr")) { if(m_rowStack.empty()) { //we must be in styles, so let's push the row instance to m_rowStack OXML_Element_Row* row = static_cast<OXML_Element_Row*>(get_pointer(rqst->stck->top())); m_rowStack.push(row); } rqst->handled = true; } else if(nameMatches(rqst->pName, NS_W_KEY, "tcPr")) { if(m_cellStack.empty()) { //we must be in styles, so let's push the cell instance to m_cellStack OXML_Element_Cell* cell = static_cast<OXML_Element_Cell*>(get_pointer(rqst->stck->top())); m_cellStack.push(cell); } rqst->handled = true; } //TODO: more coming here }