/* AbiSource * * Copyright (C) 2005 Daniel d'Andrada T. de Carvalho * * Copyright (C) 2009 Hubert Figuiere * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #include "ut_std_map.h" // Class definition include #include "ODi_Office_Styles.h" // Internal inlcudes #include "ODi_Style_Style.h" #include "ODi_Style_PageLayout.h" #include "ODi_Style_MasterPage.h" #include "ODi_Style_List.h" #include "ODi_NotesConfiguration.h" #include "ODi_ListLevelStyle.h" #include "ODi_ElementStack.h" #include "ODi_Abi_Data.h" // AbiWord includes #include #include #include /** * Destructor */ ODi_Office_Styles::~ODi_Office_Styles() { UT_map_delete_all_second(m_listStyles); UT_map_delete_all_second(m_pageLayoutStyles); UT_map_delete_all_second(m_masterPageStyles); UT_map_delete_all_second(m_notesConfigurations); } /** * Adds a (ODi_Style_Style class). * * @param bAutomatic true if the style is an OpenDocument "automatic style". * * @return The address of the newly created ODi_Style_Style or NULL, if the * specified style is not currently supported (like graphic styles). */ ODi_Style_Style* ODi_Office_Styles::addStyle(const gchar** ppAtts, ODi_ElementStack& rElementStack, ODi_Abi_Data & rAbiData) { const gchar* pFamily; const gchar* pName; const gchar* pDisplayName; ODi_Style_Style* pStyle = NULL; const ODi_Style_Style* pConstStyle; UT_UTF8String replacementName; UT_UTF8String replacementDisplayName; pFamily = UT_getAttribute("style:family", ppAtts); pName = UT_getAttribute("style:name", ppAtts); pDisplayName = UT_getAttribute("style:display-name", ppAtts); UT_ASSERT(pName); UT_return_val_if_fail(pFamily, pStyle); if(!strcmp(pFamily, "text")) { // AbiWord doesn't support two styles with the same name, differing only // on its type (eg: A "Example" character style and a "Example" // paragraph style). // Do I already have a paragraph style with this name? pConstStyle = m_paragraphStyleStyles.getStyle(pName, true); if (pConstStyle) { replacementName = pName; replacementName += "_text"; if (pDisplayName) { replacementDisplayName = pDisplayName; replacementDisplayName += "_text"; } pStyle = m_textStyleStyles.addStyle(ppAtts, rElementStack, rAbiData, &replacementName, &replacementDisplayName); } else { pStyle = m_textStyleStyles.addStyle(ppAtts, rElementStack,rAbiData); } } else if(!strcmp(pFamily, "paragraph")) { // AbiWord doesn't support two styles with the same name, differing only // on its type (eg: A "Example" character style and a "Example" // paragraph style). // Do I already have a text style with this name? pConstStyle = m_textStyleStyles.getStyle(pName, true); if (pConstStyle) { replacementName = pName; replacementName += "_paragraph"; if (pDisplayName) { replacementDisplayName = pDisplayName; replacementDisplayName += "_paragraph"; } pStyle = m_paragraphStyleStyles.addStyle(ppAtts, rElementStack, rAbiData, &replacementName, &replacementDisplayName); } else { pStyle = m_paragraphStyleStyles.addStyle(ppAtts, rElementStack,rAbiData); } } else if(!strcmp(pFamily, "section")) { pStyle = m_sectionStyleStyles.addStyle(ppAtts, rElementStack,rAbiData); } else if(!strcmp(pFamily, "graphic")) { pStyle = m_graphicStyleStyles.addStyle(ppAtts, rElementStack,rAbiData); } else if(!strcmp(pFamily, "table")) { pStyle = m_tableStyleStyles.addStyle(ppAtts, rElementStack,rAbiData); } else if(!strcmp(pFamily, "table-column")) { pStyle = m_tableColumnStyleStyles.addStyle(ppAtts, rElementStack,rAbiData); } else if(!strcmp(pFamily, "table-row")) { pStyle = m_tableRowStyleStyles.addStyle(ppAtts, rElementStack,rAbiData); } else if(!strcmp(pFamily, "table-cell")) { pStyle = m_tableCellStyleStyles.addStyle(ppAtts, rElementStack,rAbiData); } return pStyle; } /** * Adds a (ODi_Style_PageLayout class) * * @return The address of the newly created ODi_Style_PageLayout. */ ODi_Style_PageLayout* ODi_Office_Styles::addPageLayout(const gchar** ppAtts, ODi_ElementStack& rElementStack, ODi_Abi_Data& rAbiData) { const gchar* pAttrValue; ODi_Style_PageLayout* pStyle; pStyle = new ODi_Style_PageLayout(rElementStack, rAbiData); pAttrValue = UT_getAttribute("style:name", ppAtts); m_pageLayoutStyles.insert(std::make_pair(pAttrValue, pStyle)); return pStyle; } /** * Adds a (ODi_Style_MasterPage class) * * @return The address of the newly created ODi_Style_MasterPage. */ ODi_Style_MasterPage* ODi_Office_Styles::addMasterPage(const gchar** ppAtts, PD_Document* pDocument, ODi_ElementStack& rElementStack) { const gchar* pAttrValue; ODi_Style_MasterPage* pStyle; pStyle = new ODi_Style_MasterPage(pDocument, rElementStack); pAttrValue = UT_getAttribute("style:name", ppAtts); m_masterPageStyles.insert(std::make_pair(pAttrValue, pStyle)); return pStyle; } /** * */ ODi_Style_Style* ODi_Office_Styles::addDefaultStyle(const gchar** ppAtts, ODi_ElementStack& rElementStack, ODi_Abi_Data & rAbiData) { const gchar* pAttr = NULL; pAttr = UT_getAttribute("style:family", ppAtts); if (pAttr && !strcmp("paragraph", pAttr)) { return m_paragraphStyleStyles.addDefaultStyle(rElementStack,rAbiData); } else if (pAttr && !strcmp("table", pAttr)) { return m_tableStyleStyles.addDefaultStyle(rElementStack,rAbiData); } else { // Not currently supported return NULL; } } /** * Links every style with its parent and next ones. */ void ODi_Office_Styles::_linkStyles() { m_textStyleStyles.linkStyles(); m_paragraphStyleStyles.linkStyles(); m_sectionStyleStyles.linkStyles(); m_graphicStyleStyles.linkStyles(); m_tableStyleStyles.linkStyles(); m_tableColumnStyleStyles.linkStyles(); m_tableRowStyleStyles.linkStyles(); m_tableCellStyleStyles.linkStyles(); _linkMasterStyles(); _linkListStyles(); } /** * Link the master styles to their page layouts */ void ODi_Office_Styles::_linkMasterStyles() { ODi_Style_MasterPage* pMasterStyle; for(MasterPageMap::const_iterator iter = m_masterPageStyles.begin(); iter != m_masterPageStyles.end(); ++iter) { pMasterStyle = iter->second; PageLayoutMap::const_iterator l_iter = m_pageLayoutStyles.find(pMasterStyle->getLayoutName().utf8_str()); if(l_iter != m_pageLayoutStyles.end()) { pMasterStyle->setLayoutStylePointer(l_iter->second); } } } /** * Link list level styles to the text styles that they refer to. */ void ODi_Office_Styles::_linkListStyles() const { UT_sint32 count2; ODi_ListLevelStyle* pLevelStyle; ODi_Style_List* pListStyle; const ODi_Style_Style* pStyle; for(ListMap::const_iterator iter = m_listStyles.begin(); iter != m_listStyles.end(); ++iter) { pListStyle = iter->second; UT_continue_if_fail(pListStyle); count2 = pListStyle->getLevelCount(); // List levels start from 1. for (UT_sint32 j = 1; j <= count2; j++) { pLevelStyle = pListStyle->getLevelStyle(j); pStyle = getTextStyle( pLevelStyle->getTextStyleName()->utf8_str(), false); pLevelStyle->setTextStyle(pStyle); } } } /** * */ void ODi_Office_Styles::_defineAbiStyles(PD_Document* pDocument) const { m_textStyleStyles.defineAbiStyles(pDocument); m_paragraphStyleStyles.defineAbiStyles(pDocument); // AbiWord doesn't have section, graphic and table styles. // All styles defined on the content stream are automatic, so, I'm not // defining them. for(ListMap::const_iterator iter = m_listStyles.begin(); iter != m_listStyles.end(); ++iter) { iter->second->defineAbiList(pDocument); } if (!m_listStyles.empty()) { bool ok = pDocument->fixListHierarchy(); UT_ASSERT(ok); } // I will just use the first master page style (if there is one). if (!m_masterPageStyles.empty()) { ODi_Style_MasterPage* masterPage = m_masterPageStyles.begin()->second; masterPage->definePageSizeTag(pDocument); } } /** * */ void ODi_Office_Styles::_buildAbiPropsAttrString( ODi_FontFaceDecls& rFontFaceDecls) { m_textStyleStyles.buildAbiPropsAttrString(rFontFaceDecls); m_paragraphStyleStyles.buildAbiPropsAttrString(rFontFaceDecls); m_sectionStyleStyles.buildAbiPropsAttrString(rFontFaceDecls); m_tableStyleStyles.buildAbiPropsAttrString(rFontFaceDecls); for(ListMap::const_iterator iter = m_listStyles.begin(); iter != m_listStyles.end(); ++iter) { iter->second->buildAbiPropertiesString(); } } /** * Fix any problems encountered on the added styles */ void ODi_Office_Styles::_fixStyles() { m_textStyleStyles.fixStyles(); m_paragraphStyleStyles.fixStyles(); } /** * Returns the specified paragraph style * * @param pStyleName The name of the style wanted. */ const ODi_Style_Style* ODi_Office_Styles::getParagraphStyle( const gchar* pStyleName, bool bOnContentStream) const { return m_paragraphStyleStyles.getStyle(pStyleName, bOnContentStream); } /** * */ const ODi_Style_Style* ODi_Office_Styles::getTextStyle(const gchar* pStyleName, bool bOnContentStream) const { return m_textStyleStyles.getStyle(pStyleName, bOnContentStream); } /** * */ const ODi_Style_Style* ODi_Office_Styles::getSectionStyle(const gchar* pStyleName, bool bOnContentStream) const { return m_sectionStyleStyles.getStyle(pStyleName, bOnContentStream); } /** * */ const ODi_Style_Style* ODi_Office_Styles::getGraphicStyle(const gchar* pStyleName, bool bOnContentStream) const { return m_graphicStyleStyles.getStyle(pStyleName, bOnContentStream); } /** * */ const ODi_Style_Style* ODi_Office_Styles::getTableStyle(const gchar* pStyleName, bool bOnContentStream) const { return m_tableStyleStyles.getStyle(pStyleName, bOnContentStream); } /** * */ const ODi_Style_Style* ODi_Office_Styles::getTableColumnStyle( const gchar* pStyleName, bool bOnContentStream) const { return m_tableColumnStyleStyles.getStyle(pStyleName, bOnContentStream); } /** * */ const ODi_Style_Style* ODi_Office_Styles::getTableRowStyle( const gchar* pStyleName, bool bOnContentStream) const { return m_tableRowStyleStyles.getStyle(pStyleName, bOnContentStream); } /** * */ const ODi_Style_Style* ODi_Office_Styles::getTableCellStyle( const gchar* pStyleName, bool bOnContentStream) const { return m_tableCellStyleStyles.getStyle(pStyleName, bOnContentStream); } /** * Adds a list style () */ ODi_Style_List* ODi_Office_Styles::addList(const gchar** ppAtts, ODi_ElementStack& rElementStack) { const gchar* pAttrValue = NULL; ODi_Style_List* pStyle = NULL; pStyle = new ODi_Style_List(rElementStack); pAttrValue = UT_getAttribute("style:name", ppAtts); UT_DEBUGMSG(("Adding list |%s| to outline collection \n",pAttrValue)); m_listStyles.insert(std::make_pair(pAttrValue, pStyle)); return pStyle; } /** * Adds a notes configuration () */ ODi_NotesConfiguration* ODi_Office_Styles::addNotesConfiguration( const gchar** ppAtts, ODi_ElementStack& rElementStack) { const gchar* pAttrValue = NULL; ODi_NotesConfiguration* pNotesConfig = NULL; pNotesConfig = new ODi_NotesConfiguration(rElementStack); pAttrValue = UT_getAttribute("text:note-class", ppAtts); m_notesConfigurations.insert(std::make_pair(pAttrValue, pNotesConfig)); return pNotesConfig; }