LCOV - code coverage report
Current view: top level - libreoffice/xmloff/source/text - XMLSectionImportContext.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 107 138 77.5 %
Date: 2012-12-27 Functions: 7 12 58.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "XMLSectionImportContext.hxx"
      21             : #include "XMLSectionSourceImportContext.hxx"
      22             : #include "XMLSectionSourceDDEImportContext.hxx"
      23             : #include <xmloff/xmlictxt.hxx>
      24             : #include <xmloff/xmlimp.hxx>
      25             : #include <xmloff/txtimp.hxx>
      26             : #include <xmloff/nmspmap.hxx>
      27             : #include "xmloff/xmlnmspe.hxx"
      28             : #include <xmloff/xmltoken.hxx>
      29             : #include <xmloff/prstylei.hxx>
      30             : #include <sax/tools/converter.hxx>
      31             : #include <com/sun/star/container/XNamed.hpp>
      32             : #include <com/sun/star/uno/Reference.h>
      33             : #include <com/sun/star/text/XTextContent.hpp>
      34             : #include <com/sun/star/beans/XPropertySet.hpp>
      35             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      36             : #include <com/sun/star/text/ControlCharacter.hpp>
      37             : 
      38             : 
      39             : using ::rtl::OUString;
      40             : using ::com::sun::star::beans::XPropertySet;
      41             : using ::com::sun::star::uno::Reference;
      42             : using ::com::sun::star::xml::sax::XAttributeList;
      43             : using ::com::sun::star::lang::XMultiServiceFactory;
      44             : using ::com::sun::star::container::XNamed;
      45             : 
      46             : using namespace ::com::sun::star::uno;
      47             : using namespace ::com::sun::star::text;
      48             : using namespace ::xmloff::token;
      49             : 
      50             : 
      51           0 : TYPEINIT1( XMLSectionImportContext, SvXMLImportContext );
      52             : 
      53             : const sal_Char sAPI_TextSection[] = "com.sun.star.text.TextSection";
      54             : const sal_Char sAPI_IndexHeaderSection[] = "com.sun.star.text.IndexHeaderSection";
      55             : const sal_Char sAPI_IsProtected[] = "IsProtected";
      56             : const sal_Char sAPI_Condition[] = "Condition";
      57             : const sal_Char sAPI_IsVisible[] = "IsVisible";
      58             : const sal_Char sAPI_IsCurrentlyVisible[] = "IsCurrentlyVisible";
      59             : const sal_Char sAPI_ProtectionKey[] = "ProtectionKey";
      60             : 
      61             : enum XMLSectionToken
      62             : {
      63             :     XML_TOK_SECTION_XMLID,
      64             :     XML_TOK_SECTION_STYLE_NAME,
      65             :     XML_TOK_SECTION_NAME,
      66             :     XML_TOK_SECTION_CONDITION,
      67             :     XML_TOK_SECTION_DISPLAY,
      68             :     XML_TOK_SECTION_PROTECT,
      69             :     XML_TOK_SECTION_PROTECTION_KEY,
      70             :     XML_TOK_SECTION_IS_HIDDEN
      71             : };
      72             : 
      73             : static SvXMLTokenMapEntry aSectionTokenMap[] =
      74             : {
      75             :     { XML_NAMESPACE_XML , XML_ID, XML_TOK_SECTION_XMLID },
      76             :     { XML_NAMESPACE_TEXT, XML_STYLE_NAME, XML_TOK_SECTION_STYLE_NAME },
      77             :     { XML_NAMESPACE_TEXT, XML_NAME, XML_TOK_SECTION_NAME },
      78             :     { XML_NAMESPACE_TEXT, XML_CONDITION, XML_TOK_SECTION_CONDITION },
      79             :     { XML_NAMESPACE_TEXT, XML_DISPLAY, XML_TOK_SECTION_DISPLAY },
      80             :     { XML_NAMESPACE_TEXT, XML_PROTECTED, XML_TOK_SECTION_PROTECT },
      81             :     { XML_NAMESPACE_TEXT, XML_PROTECTION_KEY, XML_TOK_SECTION_PROTECTION_KEY},
      82             :     { XML_NAMESPACE_TEXT, XML_IS_HIDDEN, XML_TOK_SECTION_IS_HIDDEN },
      83             :     // compatibility with SRC629 (or earlier) versions
      84             :     { XML_NAMESPACE_TEXT, XML_PROTECT, XML_TOK_SECTION_PROTECT },
      85             :     XML_TOKEN_MAP_END
      86             : };
      87             : 
      88             : 
      89             : // section import: This one is fairly tricky due to a variety of
      90             : // limits of the core or the API. The main problem is that if you
      91             : // insert a section within another section, you can't move the cursor
      92             : // between the ends of the inner and the enclosing section. To avoid
      93             : // these problems, additional markers are first inserted and later deleted.
      94           1 : XMLSectionImportContext::XMLSectionImportContext(
      95             :     SvXMLImport& rImport,
      96             :     sal_uInt16 nPrfx,
      97             :     const OUString& rLocalName )
      98             : :   SvXMLImportContext(rImport, nPrfx, rLocalName)
      99             : ,   sTextSection(RTL_CONSTASCII_USTRINGPARAM(sAPI_TextSection))
     100             : ,   sIndexHeaderSection(RTL_CONSTASCII_USTRINGPARAM(sAPI_IndexHeaderSection))
     101             : ,   sCondition(RTL_CONSTASCII_USTRINGPARAM(sAPI_Condition))
     102             : ,   sIsVisible(RTL_CONSTASCII_USTRINGPARAM(sAPI_IsVisible))
     103             : ,   sProtectionKey(RTL_CONSTASCII_USTRINGPARAM(sAPI_ProtectionKey))
     104             : ,   sIsProtected(RTL_CONSTASCII_USTRINGPARAM(sAPI_IsProtected))
     105             : ,   sIsCurrentlyVisible(RTL_CONSTASCII_USTRINGPARAM(sAPI_IsCurrentlyVisible))
     106             : ,   bProtect(sal_False)
     107             : ,   bCondOK(sal_False)
     108             : ,   bIsVisible(sal_True)
     109             : ,   bValid(sal_False)
     110             : ,   bSequenceOK(sal_False)
     111             : ,   bIsCurrentlyVisible(sal_True)
     112             : ,   bIsCurrentlyVisibleOK(sal_False)
     113           1 : ,   bHasContent(sal_False)
     114             : {
     115           1 : }
     116             : 
     117           2 : XMLSectionImportContext::~XMLSectionImportContext()
     118             : {
     119           2 : }
     120             : 
     121           1 : void XMLSectionImportContext::StartElement(
     122             :     const Reference<XAttributeList> & xAttrList)
     123             : {
     124             :     // process attributes
     125           1 :     ProcessAttributes(xAttrList);
     126             : 
     127             :     // process index headers:
     128           1 :     sal_Bool bIsIndexHeader = IsXMLToken( GetLocalName(), XML_INDEX_TITLE );
     129           1 :     if (bIsIndexHeader)
     130             :     {
     131           0 :         bValid = sal_True;
     132             :     }
     133             : 
     134           1 :     UniReference<XMLTextImportHelper> rHelper = GetImport().GetTextImport();
     135             : 
     136             :     // valid?
     137           1 :     if (bValid)
     138             :     {
     139             :         // create text section (as XPropertySet)
     140             :         Reference<XMultiServiceFactory> xFactory(
     141           1 :             GetImport().GetModel(),UNO_QUERY);
     142           1 :         if (xFactory.is())
     143             :         {
     144             :             Reference<XInterface> xIfc =
     145           1 :                 xFactory->createInstance( bIsIndexHeader ? sIndexHeaderSection
     146           1 :                                                         : sTextSection );
     147           1 :             if (xIfc.is())
     148             :             {
     149           1 :                 Reference<XPropertySet> xPropSet(xIfc, UNO_QUERY);
     150             : 
     151             :                 // save PropertySet (for CreateChildContext)
     152           1 :                 xSectionPropertySet = xPropSet;
     153             : 
     154             :                 // name
     155           1 :                 Reference<XNamed> xNamed(xPropSet, UNO_QUERY);
     156           1 :                 xNamed->setName(sName);
     157             : 
     158             :                 // stylename?
     159           1 :                 if (!sStyleName.isEmpty())
     160             :                 {
     161             :                     XMLPropStyleContext* pStyle = rHelper->
     162           1 :                         FindSectionStyle(sStyleName);
     163             : 
     164           1 :                     if (pStyle != NULL)
     165             :                     {
     166           1 :                         pStyle->FillPropertySet( xPropSet );
     167             :                     }
     168             :                 }
     169             : 
     170             :                 // IsVisible and condition (not for index headers)
     171           1 :                 if (! bIsIndexHeader)
     172             :                 {
     173           1 :                     Any aAny;
     174           1 :                     aAny.setValue( &bIsVisible, ::getBooleanCppuType() );
     175           1 :                     xPropSet->setPropertyValue( sIsVisible, aAny );
     176             : 
     177             :                     // #97450# hidden sections must be hidden on reload
     178             :                     // For backwards compatibilty, set flag only if it is
     179             :                     // present
     180           1 :                     if( bIsCurrentlyVisibleOK )
     181             :                     {
     182             :                         aAny.setValue( &bIsCurrentlyVisible,
     183           0 :                                        ::getBooleanCppuType() );
     184           0 :                         xPropSet->setPropertyValue( sIsCurrentlyVisible, aAny);
     185             :                     }
     186             : 
     187           1 :                     if (bCondOK)
     188             :                     {
     189           1 :                         aAny <<= sCond;
     190           1 :                         xPropSet->setPropertyValue( sCondition, aAny );
     191           1 :                     }
     192             :                 }
     193             : 
     194             :                 // password (only for regular sections)
     195           1 :                 if ( bSequenceOK &&
     196           0 :                      IsXMLToken(GetLocalName(), XML_SECTION) )
     197             :                 {
     198           0 :                     Any aAny;
     199           0 :                     aAny <<= aSequence;
     200           0 :                     xPropSet->setPropertyValue(sProtectionKey, aAny);
     201             :                 }
     202             : 
     203             :                 // protection
     204           1 :                 Any aAny;
     205           1 :                 aAny.setValue( &bProtect, ::getBooleanCppuType() );
     206           1 :                 xPropSet->setPropertyValue( sIsProtected, aAny );
     207             : 
     208             :                 // insert marker, <paragraph>, marker; then insert
     209             :                 // section over the first marker character, and delete the
     210             :                 // last paragraph (and marker) when closing a section.
     211             :                 Reference<XTextRange> xStart =
     212           1 :                     rHelper->GetCursor()->getStart();
     213             : #ifndef DBG_UTIL
     214             :                 static const sal_Char sMarker[] = " ";
     215             : #else
     216             :                 static const sal_Char sMarker[] = "X";
     217             : #endif
     218           1 :                 OUString sMarkerString(RTL_CONSTASCII_USTRINGPARAM(sMarker));
     219           1 :                 rHelper->InsertString(sMarkerString);
     220             :                 rHelper->InsertControlCharacter(
     221           1 :                     ControlCharacter::APPEND_PARAGRAPH );
     222           1 :                 rHelper->InsertString(sMarkerString);
     223             : 
     224             :                 // select first marker
     225           1 :                 rHelper->GetCursor()->gotoRange(xStart, sal_False);
     226           1 :                 rHelper->GetCursor()->goRight(1, sal_True);
     227             : 
     228             :                 // convert section to XTextContent
     229             :                 Reference<XTextContent> xTextContent(xSectionPropertySet,
     230           1 :                                                      UNO_QUERY);
     231             : 
     232             :                 // and insert (over marker)
     233           1 :                 rHelper->GetText()->insertTextContent(
     234           1 :                     rHelper->GetCursorAsRange(), xTextContent, sal_True );
     235             : 
     236             :                 // and delete first marker (in section)
     237           1 :                 rHelper->GetText()->insertString(
     238           1 :                     rHelper->GetCursorAsRange(), sEmpty, sal_True);
     239             : 
     240             :                 // finally, check for redlines that should start at
     241             :                 // the section start node
     242           1 :                 rHelper->RedlineAdjustStartNodeCursor(sal_True); // start ???
     243             : 
     244             :                 // xml:id for RDF metadata
     245           1 :                 GetImport().SetXmlId(xIfc, sXmlId);
     246           1 :             }
     247           1 :         }
     248           1 :     }
     249           1 : }
     250             : 
     251           1 : void XMLSectionImportContext::ProcessAttributes(
     252             :     const Reference<XAttributeList> & xAttrList )
     253             : {
     254           1 :     SvXMLTokenMap aTokenMap(aSectionTokenMap);
     255             : 
     256           1 :     sal_Int16 nLength = xAttrList->getLength();
     257           5 :     for(sal_Int16 nAttr = 0; nAttr < nLength; nAttr++)
     258             :     {
     259           4 :         OUString sLocalName;
     260           4 :         sal_uInt16 nNamePrefix = GetImport().GetNamespaceMap().
     261           4 :             GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
     262           8 :                               &sLocalName );
     263           4 :         OUString sAttr = xAttrList->getValueByIndex(nAttr);
     264             : 
     265           4 :         switch (aTokenMap.Get(nNamePrefix, sLocalName))
     266             :         {
     267             :             case XML_TOK_SECTION_XMLID:
     268           0 :                 sXmlId = sAttr;
     269           0 :                 break;
     270             :             case XML_TOK_SECTION_STYLE_NAME:
     271           1 :                 sStyleName = sAttr;
     272           1 :                 break;
     273             :             case XML_TOK_SECTION_NAME:
     274           1 :                 sName = sAttr;
     275           1 :                 bValid = sal_True;
     276           1 :                 break;
     277             :             case XML_TOK_SECTION_CONDITION:
     278             :                 {
     279           1 :                     OUString sTmp;
     280           1 :                     sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
     281           1 :                                     _GetKeyByAttrName( sAttr, &sTmp, sal_False );
     282           1 :                     if( XML_NAMESPACE_OOOW == nPrefix )
     283             :                     {
     284           1 :                         sCond = sTmp;
     285           1 :                         bCondOK = sal_True;
     286             :                     }
     287             :                     else
     288           0 :                         sCond = sAttr;
     289             :                 }
     290           1 :                 break;
     291             :             case XML_TOK_SECTION_DISPLAY:
     292           1 :                 if (IsXMLToken(sAttr, XML_TRUE))
     293             :                 {
     294           0 :                     bIsVisible = sal_True;
     295             :                 }
     296           2 :                 else if ( IsXMLToken(sAttr, XML_NONE) ||
     297           1 :                           IsXMLToken(sAttr, XML_CONDITION) )
     298             :                 {
     299           1 :                     bIsVisible = sal_False;
     300             :                 }
     301             :                 // else: ignore
     302           1 :                 break;
     303             :             case XML_TOK_SECTION_IS_HIDDEN:
     304             :                 {
     305           0 :                     bool bTmp(false);
     306           0 :                     if (::sax::Converter::convertBool(bTmp, sAttr))
     307             :                     {
     308           0 :                         bIsCurrentlyVisible = !bTmp;
     309           0 :                         bIsCurrentlyVisibleOK = sal_True;
     310             :                     }
     311             :                 }
     312           0 :                 break;
     313             :             case XML_TOK_SECTION_PROTECTION_KEY:
     314           0 :                 ::sax::Converter::decodeBase64(aSequence, sAttr);
     315           0 :                 bSequenceOK = sal_True;
     316           0 :                 break;
     317             :             case XML_TOK_SECTION_PROTECT:
     318             :             {
     319           0 :                 bool bTmp(false);
     320           0 :                 if (::sax::Converter::convertBool(bTmp, sAttr))
     321             :                 {
     322           0 :                     bProtect = bTmp;
     323             :                 }
     324             :                 break;
     325             :             }
     326             :             default:
     327             :                 ; // ignore
     328           0 :                 break;
     329             :         }
     330           5 :     }
     331           1 : }
     332             : 
     333           1 : void XMLSectionImportContext::EndElement()
     334             : {
     335             :     // get rid of last paragraph
     336             :     // (unless it's the only paragraph in the section)
     337           1 :     UniReference<XMLTextImportHelper> rHelper = GetImport().GetTextImport();
     338           1 :     rHelper->GetCursor()->goRight(1, sal_False);
     339           1 :     if (bHasContent)
     340             :     {
     341           1 :         rHelper->GetCursor()->goLeft(1, sal_True);
     342           2 :         rHelper->GetText()->insertString(rHelper->GetCursorAsRange(),
     343           2 :                                          sEmpty, sal_True);
     344             :     }
     345             : 
     346             :     // and delete second marker
     347           1 :     rHelper->GetCursor()->goRight(1, sal_True);
     348           2 :     rHelper->GetText()->insertString(rHelper->GetCursorAsRange(),
     349           2 :                                      sEmpty, sal_True);
     350             : 
     351             :     // check for redlines to our endnode
     352           1 :     rHelper->RedlineAdjustStartNodeCursor(sal_False);
     353           1 : }
     354             : 
     355           1 : SvXMLImportContext* XMLSectionImportContext::CreateChildContext(
     356             :     sal_uInt16 nPrefix,
     357             :     const OUString& rLocalName,
     358             :     const Reference<XAttributeList> & xAttrList )
     359             : {
     360           1 :     SvXMLImportContext* pContext = NULL;
     361             : 
     362             :     // section-source (-dde) elements
     363           2 :     if ( (XML_NAMESPACE_TEXT == nPrefix) &&
     364           1 :          IsXMLToken(rLocalName, XML_SECTION_SOURCE) )
     365             :     {
     366           0 :         pContext = new XMLSectionSourceImportContext(GetImport(),
     367             :                                                      nPrefix, rLocalName,
     368           0 :                                                      xSectionPropertySet);
     369             :     }
     370           1 :     else if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
     371           0 :               IsXMLToken(rLocalName, XML_DDE_SOURCE) )
     372             :     {
     373           0 :         pContext = new XMLSectionSourceDDEImportContext(GetImport(),
     374             :                                                         nPrefix, rLocalName,
     375           0 :                                                         xSectionPropertySet);
     376             :     }
     377             :     else
     378             :     {
     379             :         // otherwise: text context
     380           1 :         pContext = GetImport().GetTextImport()->CreateTextChildContext(
     381           1 :             GetImport(), nPrefix, rLocalName, xAttrList,
     382           2 :             XML_TEXT_TYPE_SECTION );
     383             : 
     384             :         // if that fails, default context
     385           1 :         if (NULL == pContext)
     386             :         {
     387           0 :             pContext = new SvXMLImportContext( GetImport(),
     388           0 :                                                nPrefix, rLocalName );
     389             :         }
     390             :         else
     391           1 :             bHasContent = sal_True;
     392             :     }
     393             : 
     394           1 :     return pContext;
     395             : }
     396             : 
     397             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10