void OXMLi_ListenerState_Styles::endElement (OXMLi_EndElementRequest * rqst)
{
	UT_return_if_fail( _error_if_fail(rqst != NULL) );

	if (nameMatches(rqst->pName, NS_W_KEY, "docDefaults") || nameMatches(rqst->pName, NS_W_KEY, "style")) {
		UT_return_if_fail(_error_if_fail(m_pCurrentStyle != NULL));

		OXML_Document * doc = OXML_Document::getInstance();
		UT_return_if_fail( _error_if_fail(doc != NULL) );
		OXML_SharedStyle styl(m_pCurrentStyle);
		doc->addStyle(styl);
		m_pCurrentStyle = NULL;

		rqst->handled = true;
	} else if (nameMatches(rqst->pName, NS_W_KEY, "rPr") || 
			   nameMatches(rqst->pName, NS_W_KEY, "pPr") ||
			   nameMatches(rqst->pName, NS_W_KEY, "tblPr") ||
			   nameMatches(rqst->pName, NS_W_KEY, "trPr") ||
			   nameMatches(rqst->pName, NS_W_KEY, "tcPr")) {
		//Retrieve the formatting collected by the Common listener state.
		OXML_SharedElement dummy = rqst->stck->top();
		const gchar ** props = dummy->getProperties();
		if (props != NULL) {
			//Pass the retrieved properties to a new style object
			UT_return_if_fail(_error_if_fail(UT_OK == m_pCurrentStyle->appendProperties(props)));
		}
		rqst->stck->pop();

		rqst->handled = !nameMatches(rqst->pName, NS_W_KEY, "tblPr") &&
						!nameMatches(rqst->pName, NS_W_KEY, "trPr") &&
						!nameMatches(rqst->pName, NS_W_KEY, "tcPr");
	}
}
void OXMLi_ListenerState_Image::charData (OXMLi_CharDataRequest * rqst)
{
	if(m_isEmbeddedObject)
	{
		return;
	}
	if(rqst->stck->empty())
	{
		rqst->handled = false;
		rqst->valid = false;
		return;
	}
	if(!rqst)
	{
		UT_DEBUGMSG(("SERHAT: OpenXML importer invalid NULL request in OXMLi_ListenerState_Image.charData\n"));
		return;
	}

	std::string contextTag = "";
	if(!rqst->context->empty())
	{
		contextTag = rqst->context->back();
	}
	int posOffset = contextMatches(contextTag, NS_WP_KEY, "posOffset");
	if(posOffset && !m_isInlineImage)
	{
		OXML_SharedElement imgElem = rqst->stck->top();
		rqst->stck->pop();

		if(rqst->context->size() >= 2)
			contextTag = rqst->context->at(rqst->context->size() - 2);
		int positionH = contextMatches(contextTag, NS_WP_KEY, "positionH");
		int positionV = contextMatches(contextTag, NS_WP_KEY, "positionV");
		if(rqst->buffer == NULL)
		{
			UT_DEBUGMSG(("SERHAT: Unexpected situation, request with a null buffer\n"));
			return;
		}
		if(positionH)
		{
			std::string position(_EmusToInches(rqst->buffer));
			position += "in";
			imgElem->setProperty("xpos", position);
		}
		else if(positionV)
		{
			std::string position(_EmusToInches(rqst->buffer));
			position += "in";
			imgElem->setProperty("ypos", position);
		}
		rqst->stck->push(imgElem);
	}
}
Exemple #3
0
UT_Error OXML_Element::appendElement(const OXML_SharedElement & obj)
{
    UT_return_val_if_fail(obj.get() != NULL, UT_ERROR);

    try {
        m_children.push_back(obj);
    } catch(...) {
        UT_DEBUGMSG(("Bad alloc!\n"));
        return UT_OUTOFMEM;
    }

    obj->setTarget(TARGET); //propagate the target

    return UT_OK;
}
void OXMLi_ListenerState_HdrFtr::endElement (OXMLi_EndElementRequest * rqst)
{
	if (nameMatches(rqst->pName, NS_W_KEY, "hdr") || nameMatches(rqst->pName, NS_W_KEY, "ftr"))
	{
		OXML_SharedSection s(new OXML_Section(m_partId));

		if(!rqst->stck->empty())
		{
			OXML_SharedElement container = rqst->stck->top();
			s->setChildren( container->getChildren() );
		}

		OXML_Document * doc = OXML_Document::getInstance();
		UT_return_if_fail( this->_error_if_fail(doc != NULL) );

		if (nameMatches(rqst->pName, NS_W_KEY, "hdr"))
			doc->addHeader(s);
		else
			doc->addFooter(s);

		rqst->handled = true;
	}
}
void OXMLi_ListenerState_Numbering::endElement (OXMLi_EndElementRequest * rqst)
{
	if (
		nameMatches(rqst->pName, NS_W_KEY, "numbering") ||
		nameMatches(rqst->pName, NS_W_KEY, "abstractNum") ||
		nameMatches(rqst->pName, NS_W_KEY, "multiLevelType") ||
		nameMatches(rqst->pName, NS_W_KEY, "name") ||
		nameMatches(rqst->pName, NS_W_KEY, "nsid") ||
		nameMatches(rqst->pName, NS_W_KEY, "numStyleLink") ||
		nameMatches(rqst->pName, NS_W_KEY, "styleLink") ||
		nameMatches(rqst->pName, NS_W_KEY, "tmpl") ||
		nameMatches(rqst->pName, NS_W_KEY, "isLgl") ||
		nameMatches(rqst->pName, NS_W_KEY, "legacy") ||
		nameMatches(rqst->pName, NS_W_KEY, "lvlJc") ||
		nameMatches(rqst->pName, NS_W_KEY, "lvlPicBulletId") ||
		nameMatches(rqst->pName, NS_W_KEY, "lvlRestart") ||
		nameMatches(rqst->pName, NS_W_KEY, "lvlText") ||
		nameMatches(rqst->pName, NS_W_KEY, "numFmt") ||
		nameMatches(rqst->pName, NS_W_KEY, "start") ||
		nameMatches(rqst->pName, NS_W_KEY, "suff") ||
		nameMatches(rqst->pName, NS_W_KEY, "abstractNumId")
		)
	{
		//TODO: add functionality here
		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "lvl"))
	{
		OXML_Document * doc = OXML_Document::getInstance();		
		if(!doc)
		{
			doc = OXML_Document::getNewInstance();
		}			
		OXML_SharedList sharedList(m_currentList);
		doc->addList(sharedList);
		m_currentList = NULL;
		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "num"))
	{
		m_currentNumId.clear(); //set it to empty string
		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "pPr") || 
			nameMatches(rqst->pName, NS_W_KEY, "rPr"))
	{
		if(rqst->stck->empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}
		OXML_SharedElement dummy = rqst->stck->top();
		
		if(m_currentList)
		{
			m_currentList->setAttributes(dummy->getAttributes());
			m_currentList->setProperties(dummy->getProperties());
		}
		rqst->stck->pop(); //remove the dummy element
		rqst->handled = true;
	}
}
void OXMLi_ListenerState_Table::endElement (OXMLi_EndElementRequest * rqst)
{
	if (nameMatches(rqst->pName, NS_W_KEY, "tbl"))
	{
		if(m_tableStack.empty() || rqst->stck->empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}

		OXML_SharedElement table = rqst->stck->top();
		rqst->stck->pop(); //pop table
		if(rqst->stck->empty())
		{
			OXML_SharedSection last = rqst->sect_stck->top();
			last->appendElement(table);
		}
		else
		{
			OXML_SharedElement container = rqst->stck->top();
			container->appendElement(table);
		}
		m_tableStack.pop();
		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "tr"))
	{
		if(m_rowStack.empty() || (rqst->stck->size() < 2))
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}

		OXML_SharedElement row = rqst->stck->top();
		rqst->stck->pop(); //pop row
		OXML_SharedElement table = rqst->stck->top();
		table->appendElement(row);
		m_rowStack.pop();
		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "tc"))
	{
		if(m_tableStack.empty() || m_cellStack.empty() || (rqst->stck->size() < 2))
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}

		OXML_SharedElement cell = rqst->stck->top();
		rqst->stck->pop(); //pop cell
		OXML_SharedElement row = rqst->stck->top();
		OXML_Element_Cell* pCell = m_cellStack.top();
		if(!pCell->startsHorizontalMerge() && !pCell->startsVerticalMerge())
		{
			//do nothing in this case
		}
		else if(!pCell->startsVerticalMerge())
		{
			OXML_Element_Table* table = m_tableStack.top();
			if(!table->incrementBottomVerticalMergeStart(pCell))
			{
				//this means there is no cell before this starting a vertical merge
				//revert back to vertical merge start instead of continue
				pCell->setVerticalMergeStart(true);
				UT_DEBUGMSG(("FRT:OpenXML importer, invalid <vMerge val=continue> attribute.\n"));
			}
		}
		else if(!pCell->startsHorizontalMerge())
		{
			OXML_Element_Table* table = m_tableStack.top();
			if(!table->incrementRightHorizontalMergeStart(pCell))
			{
				//this means there is no cell before this starting a horizontal merge
				//revert back to horizontal merge start instead of continue
				pCell->setHorizontalMergeStart(true);
				UT_DEBUGMSG(("FRT:OpenXML importer, invalid <hMerge val=continue> attribute.\n"));
			}
		}
		else //(pCell->startsHorizontalMerge() && pCell->startsVerticalMerge())
		{
			OXML_Element_Row* pRow = m_rowStack.top();
			row->appendElement(cell);
		}
		m_cellStack.pop();
		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "gridSpan") ||
			nameMatches(rqst->pName, NS_W_KEY, "vMerge") ||
			nameMatches(rqst->pName, NS_W_KEY, "hMerge") ||
			nameMatches(rqst->pName, NS_W_KEY, "gridCol") ||
			nameMatches(rqst->pName, NS_W_KEY, "trHeight") ||
			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") ||
			nameMatches(rqst->pName, NS_W_KEY, "tblStyle"))
	{
		rqst->handled = true;
	}	
	else if(nameMatches(rqst->pName, NS_W_KEY, "tblPr"))
	{
		if(!rqst->context->empty() && !contextMatches(rqst->context->back(), NS_W_KEY, "tbl") && !m_tableStack.empty())
		{
			m_tableStack.pop(); //pop the dummy table
		}
		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "trPr"))
	{
		if(!rqst->context->empty() && !contextMatches(rqst->context->back(), NS_W_KEY, "tr") && !m_rowStack.empty())
		{
			m_rowStack.pop(); //pop the dummy row
		}
		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "tcPr"))
	{
		if(!rqst->context->empty() && !contextMatches(rqst->context->back(), NS_W_KEY, "tc") && !m_cellStack.empty())
		{
			m_cellStack.pop(); //pop the dummy cell
		}
		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_W_KEY, "shd"))
	{
		std::string contextTag = rqst->context->empty() ? "" : rqst->context->back();
		rqst->handled = contextMatches(contextTag, NS_W_KEY, "tcPr") || contextMatches(contextTag, NS_W_KEY, "tblPr");
	}
	//TODO: more coming here
}
void OXMLi_ListenerState_Image::startElement (OXMLi_StartElementRequest * rqst)
{
	if(nameMatches(rqst->pName, NS_W_KEY, "object"))
	{
		// Abiword doesn't support embedded objects, enable this boolean lock when needed
		m_isEmbeddedObject = true;
		rqst->handled = true;
	}
	if(m_isEmbeddedObject)
	{
		return;
	}

	if(nameMatches(rqst->pName, NS_W_KEY, "drawing"))
	{
		OXML_SharedElement imgElem(new OXML_Element_Image(""));
		rqst->stck->push(imgElem);
		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_WP_KEY, "inline"))
	{
		if(rqst->stck->empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}
		std::string contextTag = "";
		if(!rqst->context->empty())
		{
			contextTag = rqst->context->back();
		}
		int drawing = contextMatches(contextTag, NS_W_KEY, "drawing");
		if(drawing)
		{
			m_isInlineImage = true;
			rqst->handled = true;
		}
	}
	else if(nameMatches(rqst->pName, NS_WP_KEY, "anchor"))
	{
		if(rqst->stck->empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}
		std::string contextTag = "";
		if(!rqst->context->empty())
		{
			contextTag = rqst->context->back();
		}
		int drawing = contextMatches(contextTag, NS_W_KEY, "drawing");
		if(drawing)
		{
			m_isInlineImage = false;
			rqst->handled = true;
		}
	}
	else if(nameMatches(rqst->pName, NS_WP_KEY, "positionH"))
	{
		if(rqst->stck->empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}
		std::string contextTag = "";
		if(!rqst->context->empty())
		{
			contextTag = rqst->context->back();
		}
		int anchor = contextMatches(contextTag, NS_WP_KEY, "anchor");
		if(anchor)
		{
			rqst->handled = true;
		}
	}
	else if(nameMatches(rqst->pName, NS_WP_KEY, "positionV"))
	{
		if(rqst->stck->empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}
		std::string contextTag = "";
		if(!rqst->context->empty())
		{
			contextTag = rqst->context->back();
		}
		int anchor = contextMatches(contextTag, NS_WP_KEY, "anchor");
		if(anchor)
		{
			rqst->handled = true;
		}
	}
	else if(nameMatches(rqst->pName, NS_WP_KEY, "posOffset"))
	{
		if(rqst->stck->empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}
		std::string contextTag = "";
		if(!rqst->context->empty())
		{
			contextTag = rqst->context->back();
		}
		int positionH = contextMatches(contextTag, NS_WP_KEY, "positionH");
		int positionV = contextMatches(contextTag, NS_WP_KEY, "positionV");
		if(positionH || positionV)
		{
			rqst->handled = true;
		}
	}
	else if(nameMatches(rqst->pName, NS_WP_KEY, "extent"))
	{
		if(rqst->stck->empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}

		OXML_SharedElement imgElem = rqst->stck->top();
		if(!imgElem)
			return;

		const gchar * cx = attrMatches(NS_WP_KEY, "cx", rqst->ppAtts); //width
		if(cx)
		{
			std::string width(_EmusToInches(cx));
			width += "in";
			if(m_isInlineImage)
			{
				if(imgElem->setProperty("width", width) != UT_OK)
				{
					UT_DEBUGMSG(("SERHAT:OpenXML importer inline image width property can't be set\n"));
				}
			}
			else
			{
				if(imgElem->setProperty("frame-width", width) != UT_OK)
				{
					UT_DEBUGMSG(("SERHAT:OpenXML importer positioned image width property can't be set\n"));
				}
			}
		}

		const gchar * cy = attrMatches(NS_WP_KEY, "cy", rqst->ppAtts); //height
		if(cy)
		{
			std::string height(_EmusToInches(cy));
			height += "in";
			if(m_isInlineImage)
			{
				if(imgElem->setProperty("height", height) != UT_OK)
				{
					UT_DEBUGMSG(("SERHAT:OpenXML importer inline image height property can't be set\n"));
				}
			}
			else
			{
				if(imgElem->setProperty("frame-height", height) != UT_OK)
				{
					UT_DEBUGMSG(("SERHAT:OpenXML importer positioned image height property can't be set\n"));
				}
			}
		}

		rqst->handled = true;
	}
	else if(nameMatches(rqst->pName, NS_WP_KEY, "wrapSquare"))
	{
		if(rqst->stck->empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}

		OXML_SharedElement imgElem = rqst->stck->top();
		if(!imgElem)
			return;

		const gchar * wrapText = attrMatches(NS_WP_KEY, "wrapText", rqst->ppAtts);
		if(wrapText)
		{
			if(!strcmp(wrapText, "bothSides"))
			{
				if(imgElem->setProperty("wrap-mode", "wrapped-both") != UT_OK)
				{
					UT_DEBUGMSG(("SERHAT:OpenXML importer image wrap-mode property can't be set\n"));
				}
			}
			else if(!strcmp(wrapText, "right"))
			{
				if(imgElem->setProperty("wrap-mode", "wrapped-to-right") != UT_OK)
				{
					UT_DEBUGMSG(("SERHAT:OpenXML importer image wrap-mode property can't be set\n"));
				}
			}
			else if(!strcmp(wrapText, "left"))
			{
				if(imgElem->setProperty("wrap-mode", "wrapped-to-left") != UT_OK)
				{
					UT_DEBUGMSG(("SERHAT:OpenXML importer image wrap-mode property can't be set\n"));
				}
			}
		}
		rqst->handled = true;
	}
	else if (nameMatches(rqst->pName, NS_A_KEY, "blip"))
	{
		if(rqst->stck->empty())
		{
			rqst->handled = false;
			rqst->valid = false;
			return;
		}

		OXML_SharedElement imgElem = rqst->stck->top();
		if(!imgElem)
			return;

		const gchar * id = attrMatches(NS_R_KEY, "embed", rqst->ppAtts);
		if(id)
		{
			std::string imageId(id);
			imgElem->setId(id);
			rqst->handled = addImage(imageId);
		}
	}	
	else if(nameMatches(rqst->pName, NS_V_KEY, "shape"))
	{
		const gchar* style = attrMatches(NS_V_KEY, "style", rqst->ppAtts);
		if(style)
		{
			m_style = style;
		}
		//don't handle the request here in case shape contains some other structure, ex: textbox
	}
	else if(nameMatches(rqst->pName, NS_V_KEY, "imagedata"))
	{
		const gchar* id = attrMatches(NS_R_KEY, "id", rqst->ppAtts);
		if(id)
		{
			std::string imageId(id);
			OXML_SharedElement imgElem(new OXML_Element_Image(imageId));
			rqst->stck->push(imgElem);

			if(!addImage(imageId))
				return;

			if(m_style.compare(""))
			{
				//parse and apply style here
				std::string attrName("");
				std::string attrValue("");
				size_t attrStart = 0;
				size_t attrEnd = 0;
				while(attrStart < m_style.length())
				{
					attrEnd = m_style.find(';', attrStart);
					if(attrEnd == std::string::npos)
					{
						//this should be the last attribute
						attrEnd = m_style.length(); 
					}
					std::string attrNameValPair = m_style.substr(attrStart, attrEnd-attrStart);
					size_t seperator = attrNameValPair.find(':');
					if(seperator != std::string::npos)
					{
						attrName = attrNameValPair.substr(0, seperator);
						attrValue = attrNameValPair.substr(seperator+1);

						//convert and apply attributes here
						if(!attrName.compare("width"))
						{
							imgElem->setProperty("width", attrValue);
						}
						else if(!attrName.compare("height"))
						{
							imgElem->setProperty("height", attrValue);
						}
						//TODO: more attributes coming
					}	
					//finally update the start point for the next attribute
					attrStart = attrEnd+1;
				}
			}
			rqst->handled = true;
		}
	}

	//TODO: more coming here
}