LCOV - code coverage report
Current view: top level - libreoffice/sw/source/filter/ww8 - writerwordglue.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 248 400 62.0 %
Date: 2012-12-17 Functions: 36 39 92.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 <msfilter.hxx>
      21             : #include "writerwordglue.hxx"
      22             : #include <doc.hxx>
      23             : #include "writerhelper.hxx"
      24             : 
      25             : #include <algorithm>                //std::find_if
      26             : #include <functional>               //std::unary_function
      27             : 
      28             : #include <unicode/ubidi.h>          //ubidi_getLogicalRun
      29             : #include <tools/tenccvt.hxx>        //GetExtendedTextEncoding
      30             : #include <com/sun/star/i18n/ScriptType.hpp> //ScriptType
      31             : 
      32             : #include <unotools/fontcvt.hxx>  //GetSubsFontName
      33             : #include <editeng/paperinf.hxx>  //lA0Width...
      34             : #include <editeng/lrspitem.hxx>  //SvxLRSpaceItem
      35             : #include <editeng/ulspitem.hxx>  //SvxULSpaceItem
      36             : #include <editeng/boxitem.hxx>   //SvxBoxItem
      37             : #include <editeng/fontitem.hxx>  //SvxFontItem
      38             : #include <frmfmt.hxx>            //SwFrmFmt
      39             : #include <fmtclds.hxx>           //SwFmtCol
      40             : #include <hfspacingitem.hxx>     //SwHeaderAndFooterEatSpacingItem
      41             : #include <fmtfsize.hxx>          //SwFmtFrmSize
      42             : #include <swrect.hxx>            //SwRect
      43             : #include <fmthdft.hxx>           //SwFmtHeader/SwFmtFooter
      44             : #include <frmatr.hxx>            //GetLRSpace...
      45             : #include <ndtxt.hxx>             //SwTxtNode
      46             : #include <breakit.hxx>           //pBreakIt
      47             : #include <i18npool/mslangid.hxx>
      48             : 
      49             : #define ASSIGN_CONST_ASC(s) AssignAscii(s)
      50             : 
      51             : namespace myImplHelpers
      52             : {
      53          44 :     SwTwips CalcHdFtDist(const SwFrmFmt& rFmt, sal_uInt16 nSpacing)
      54             :     {
      55             :         /*
      56             :         The normal case for reexporting word docs is to have dynamic spacing,
      57             :         as this is word's only setting, and the reason for the existance of the
      58             :         dynamic spacing features. If we have dynamic spacing active then we can
      59             :         add its spacing to the value height of the h/f and get the wanted total
      60             :         size for word.
      61             : 
      62             :         Otherwise we have to get the real layout rendered
      63             :         height, which is totally nonoptimum, but the best we can do.
      64             :         */
      65          44 :         long nDist=0;
      66          44 :         const SwFmtFrmSize& rSz = rFmt.GetFrmSize();
      67             : 
      68             :         const SwHeaderAndFooterEatSpacingItem &rSpacingCtrl =
      69             :             sw::util::ItemGet<SwHeaderAndFooterEatSpacingItem>
      70          44 :             (rFmt, RES_HEADER_FOOTER_EAT_SPACING);
      71          44 :         if (rSpacingCtrl.GetValue())
      72          44 :             nDist += rSz.GetHeight();
      73             :         else
      74             :         {
      75           0 :             SwRect aRect(rFmt.FindLayoutRect(false));
      76           0 :             if (aRect.Height())
      77           0 :                 nDist += aRect.Height();
      78             :             else
      79             :             {
      80           0 :                 const SwFmtFrmSize& rSize = rFmt.GetFrmSize();
      81           0 :                 if (ATT_VAR_SIZE != rSize.GetHeightSizeType())
      82           0 :                     nDist += rSize.GetHeight();
      83             :                 else
      84             :                 {
      85           0 :                     nDist += 274;       // default for 12pt text
      86           0 :                     nDist += nSpacing;
      87             :                 }
      88             :             }
      89             :         }
      90          44 :         return nDist;
      91             :     }
      92             : 
      93          22 :     SwTwips CalcHdDist(const SwFrmFmt& rFmt)
      94             :     {
      95          22 :         return CalcHdFtDist(rFmt, rFmt.GetULSpace().GetUpper());
      96             :     }
      97             : 
      98          22 :     SwTwips CalcFtDist(const SwFrmFmt& rFmt)
      99             :     {
     100          22 :         return CalcHdFtDist(rFmt, rFmt.GetULSpace().GetLower());
     101             :     }
     102             : 
     103             :     /*
     104             :      SwTxtFmtColl and SwCharFmt are quite distinct types and how they are
     105             :      gotten is also distinct, but the algorithm to match word's eqivalents into
     106             :      them is the same, so we put the different stuff into two seperate helper
     107             :      implementations and a core template that uses the helpers that uses the
     108             :      same algorithm to do the work. We'll make the helpers specializations of a
     109             :      non existing template so I can let the compiler figure out the right one
     110             :      to use from a simple argument to the algorithm class
     111             :     */
     112             :     template <class C> class MapperImpl;
     113             :     template<> class MapperImpl<SwTxtFmtColl>
     114             :     {
     115             :     private:
     116             :         SwDoc &mrDoc;
     117             :     public:
     118          78 :         MapperImpl(SwDoc &rDoc) : mrDoc(rDoc) {}
     119             :         SwTxtFmtColl* GetBuiltInStyle(ww::sti eSti);
     120             :         SwTxtFmtColl* GetStyle(const String &rName);
     121             :         SwTxtFmtColl* MakeStyle(const String &rName);
     122             :     };
     123             : 
     124         530 :     SwTxtFmtColl* MapperImpl<SwTxtFmtColl>::GetBuiltInStyle(ww::sti eSti)
     125             :     {
     126         530 :         const RES_POOL_COLLFMT_TYPE RES_NONE  = RES_POOLCOLL_DOC_END;
     127             :         static const RES_POOL_COLLFMT_TYPE aArr[]=
     128             :         {
     129             :             RES_POOLCOLL_STANDARD, RES_POOLCOLL_HEADLINE1,
     130             :             RES_POOLCOLL_HEADLINE2, RES_POOLCOLL_HEADLINE3,
     131             :             RES_POOLCOLL_HEADLINE4, RES_POOLCOLL_HEADLINE5,
     132             :             RES_POOLCOLL_HEADLINE6, RES_POOLCOLL_HEADLINE7,
     133             :             RES_POOLCOLL_HEADLINE8, RES_POOLCOLL_HEADLINE9,
     134             :             RES_POOLCOLL_TOX_IDX1, RES_POOLCOLL_TOX_IDX2,
     135             :             RES_POOLCOLL_TOX_IDX3, RES_NONE, RES_NONE, RES_NONE, RES_NONE,
     136             :             RES_NONE, RES_NONE, RES_POOLCOLL_TOX_CNTNT1,
     137             :             RES_POOLCOLL_TOX_CNTNT2, RES_POOLCOLL_TOX_CNTNT3,
     138             :             RES_POOLCOLL_TOX_CNTNT4, RES_POOLCOLL_TOX_CNTNT5,
     139             :             RES_POOLCOLL_TOX_CNTNT6, RES_POOLCOLL_TOX_CNTNT7,
     140             :             RES_POOLCOLL_TOX_CNTNT8, RES_POOLCOLL_TOX_CNTNT9, RES_NONE,
     141             :             RES_POOLCOLL_FOOTNOTE, RES_NONE, RES_POOLCOLL_HEADER,
     142             :             RES_POOLCOLL_FOOTER, RES_POOLCOLL_TOX_IDXH, RES_NONE, RES_NONE,
     143             :             RES_POOLCOLL_JAKETADRESS, RES_POOLCOLL_SENDADRESS, RES_NONE,
     144             :             RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_POOLCOLL_ENDNOTE,
     145             :             RES_NONE, RES_NONE, RES_NONE, RES_POOLCOLL_LISTS_BEGIN,
     146             :             RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE,
     147             :             RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE,
     148             :             RES_NONE, RES_NONE, RES_POOLCOLL_HEADLINE_BASE, RES_NONE,
     149             :             RES_POOLCOLL_SIGNATURE, RES_NONE, RES_POOLCOLL_TEXT,
     150             :             RES_POOLCOLL_TEXT_MOVE, RES_NONE, RES_NONE, RES_NONE, RES_NONE,
     151             :             RES_NONE, RES_NONE, RES_POOLCOLL_DOC_SUBTITEL
     152             :         };
     153             : 
     154             :         OSL_ENSURE(SAL_N_ELEMENTS(aArr) == 75, "Style Array has false size");
     155             : 
     156         530 :         SwTxtFmtColl* pRet = 0;
     157             :         //If this is a built-in word style that has a built-in writer
     158             :         //equivalent, then map it to one of our built in styles regardless
     159             :         //of its name
     160         530 :         if (sal::static_int_cast< size_t >(eSti) < SAL_N_ELEMENTS(aArr) && aArr[eSti] != RES_NONE)
     161         346 :             pRet = mrDoc.GetTxtCollFromPool( static_cast< sal_uInt16 >(aArr[eSti]), false);
     162         530 :         return pRet;
     163             :     }
     164             : 
     165         312 :     SwTxtFmtColl* MapperImpl<SwTxtFmtColl>::GetStyle(const String &rName)
     166             :     {
     167         312 :         return sw::util::GetParaStyle(mrDoc, rName);
     168             :     }
     169             : 
     170         126 :     SwTxtFmtColl* MapperImpl<SwTxtFmtColl>::MakeStyle(const String &rName)
     171             :     {
     172             :         return mrDoc.MakeTxtFmtColl(rName,
     173         126 :             const_cast<SwTxtFmtColl *>(mrDoc.GetDfltTxtFmtColl()));
     174             :     }
     175             : 
     176             :     template<> class MapperImpl<SwCharFmt>
     177             :     {
     178             :     private:
     179             :         SwDoc &mrDoc;
     180             :     public:
     181          78 :         MapperImpl(SwDoc &rDoc) : mrDoc(rDoc) {}
     182             :         SwCharFmt* GetBuiltInStyle(ww::sti eSti);
     183             :         SwCharFmt* GetStyle(const String &rName);
     184             :         SwCharFmt* MakeStyle(const String &rName);
     185             :     };
     186             : 
     187         188 :     SwCharFmt* MapperImpl<SwCharFmt>::GetBuiltInStyle(ww::sti eSti)
     188             :     {
     189         188 :         RES_POOL_CHRFMT_TYPE eLookup = RES_POOLCHR_NORMAL_END;
     190         188 :         switch (eSti)
     191             :         {
     192             :             case ww::stiFtnRef:
     193           2 :                 eLookup = RES_POOLCHR_FOOTNOTE;
     194           2 :                 break;
     195             :             case ww::stiLnn:
     196           0 :                 eLookup = RES_POOLCHR_LINENUM;
     197           0 :                 break;
     198             :             case ww::stiPgn:
     199          18 :                 eLookup = RES_POOLCHR_PAGENO;
     200          18 :                 break;
     201             :             case ww::stiEdnRef:
     202           2 :                 eLookup = RES_POOLCHR_ENDNOTE;
     203           2 :                 break;
     204             :             case ww::stiHyperlink:
     205          18 :                 eLookup = RES_POOLCHR_INET_NORMAL;
     206          18 :                 break;
     207             :             case ww::stiHyperlinkFollowed:
     208           2 :                 eLookup = RES_POOLCHR_INET_VISIT;
     209           2 :                 break;
     210             :             case ww::stiStrong:
     211           2 :                 eLookup = RES_POOLCHR_HTML_STRONG;
     212           2 :                 break;
     213             :             case ww::stiEmphasis:
     214           2 :                 eLookup = RES_POOLCHR_HTML_EMPHASIS;
     215           2 :                 break;
     216             :             default:
     217         142 :                 eLookup = RES_POOLCHR_NORMAL_END;
     218         142 :                 break;
     219             :         }
     220         188 :         SwCharFmt *pRet = 0;
     221         188 :         if (eLookup != RES_POOLCHR_NORMAL_END)
     222          46 :             pRet = mrDoc.GetCharFmtFromPool( static_cast< sal_uInt16 >(eLookup) );
     223         188 :         return pRet;
     224             :     }
     225             : 
     226         274 :     SwCharFmt* MapperImpl<SwCharFmt>::GetStyle(const String &rName)
     227             :     {
     228         274 :         return sw::util::GetCharStyle(mrDoc, rName);
     229             :     }
     230             : 
     231         128 :     SwCharFmt* MapperImpl<SwCharFmt>::MakeStyle(const String &rName)
     232             :     {
     233         128 :         return mrDoc.MakeCharFmt(rName, mrDoc.GetDfltCharFmt());
     234             :     }
     235             : 
     236         156 :     template<class C> class StyleMapperImpl
     237             :     {
     238             :     private:
     239             :         MapperImpl<C> maHelper;
     240             :         std::set<const C*> maUsedStyles;
     241             :         C* MakeNonCollidingStyle(const String& rName);
     242             :     public:
     243             :         typedef std::pair<C*, bool> StyleResult;
     244         156 :         StyleMapperImpl(SwDoc &rDoc) : maHelper(rDoc) {}
     245             :         StyleResult GetStyle(const String& rName, ww::sti eSti);
     246             :     };
     247             : 
     248             :     template<class C>
     249             :     typename StyleMapperImpl<C>::StyleResult
     250         718 :     StyleMapperImpl<C>::GetStyle(const String& rName, ww::sti eSti)
     251             :     {
     252         718 :         C *pRet = maHelper.GetBuiltInStyle(eSti);
     253             : 
     254             :         //If we've used it once, don't reuse it
     255         718 :         if (pRet && (maUsedStyles.end() != maUsedStyles.find(pRet)))
     256           4 :             pRet = 0;
     257             : 
     258         718 :         if (!pRet)
     259             :         {
     260         330 :             pRet = maHelper.GetStyle(rName);
     261             :             //If we've used it once, don't reuse it
     262         330 :             if (pRet && (maUsedStyles.end() != maUsedStyles.find(pRet)))
     263           2 :                 pRet = 0;
     264             :         }
     265             : 
     266         718 :         bool bStyExist = pRet ? true : false;
     267             : 
     268         718 :         if (!pRet)
     269             :         {
     270         254 :             String aName(rName);
     271         254 :             xub_StrLen nPos = aName.Search(',');
     272             :             // No commas allow in SW style names
     273         254 :             if (STRING_NOTFOUND != nPos)
     274           0 :                 aName.Erase(nPos);
     275         254 :             pRet = MakeNonCollidingStyle(aName);
     276             :         }
     277             : 
     278         718 :         if (pRet)
     279         718 :             maUsedStyles.insert(pRet);
     280             : 
     281         718 :         return StyleResult(pRet, bStyExist);
     282             :     }
     283             : 
     284             :     template<class C>
     285         254 :     C* StyleMapperImpl<C>::MakeNonCollidingStyle(const String& rName)
     286             :     {
     287         254 :         String aName(rName);
     288         254 :         C* pColl = 0;
     289             : 
     290         254 :         if (0 != (pColl = maHelper.GetStyle(aName)))
     291             :         {
     292             :             //If the style collides first stick WW- in front of it, unless
     293             :             //it already has it and then successively add a larger and
     294             :             //larger number after it, its got to work at some stage!
     295           2 :             if (!aName.EqualsIgnoreCaseAscii("WW-", 0, 3))
     296           2 :                 aName.InsertAscii("WW-" , 0);
     297             : 
     298           2 :             sal_Int32 nI = 1;
     299           4 :             while (
     300             :                     0 != (pColl = maHelper.GetStyle(aName)) &&
     301             :                     (nI < SAL_MAX_INT32)
     302             :                   )
     303             :             {
     304           0 :                 aName += String::CreateFromInt32(nI++);
     305             :             }
     306             :         }
     307             : 
     308         254 :         return pColl ? 0 : maHelper.MakeStyle(aName);
     309             :     }
     310             : 
     311        2032 :     String FindBestMSSubstituteFont(const String &rFont)
     312             :     {
     313        2032 :         String sRet;
     314        2032 :         if (sw::util::IsStarSymbol(rFont))
     315           6 :             sRet.ASSIGN_CONST_ASC("Arial Unicode MS");
     316             :         else
     317        2026 :             sRet = GetSubsFontName(rFont, SUBSFONT_ONLYONE | SUBSFONT_MS);
     318        2032 :         return sRet;
     319             :     }
     320             : 
     321             :     //Utility to remove entries before a given starting position
     322             :     class IfBeforeStart
     323             :         : public std::unary_function<const sw::util::CharRunEntry&, bool>
     324             :     {
     325             :     private:
     326             :         xub_StrLen mnStart;
     327             :     public:
     328         256 :         IfBeforeStart(xub_StrLen nStart) : mnStart(nStart) {}
     329         256 :         bool operator()(const sw::util::CharRunEntry &rEntry) const
     330             :         {
     331         256 :             return rEntry.mnEndPos < mnStart;
     332             :         }
     333             :     };
     334             : }
     335             : 
     336             : namespace sw
     337             : {
     338             :     namespace util
     339             :     {
     340             : 
     341           8 :         bool IsPlausableSingleWordSection(const SwFrmFmt &rTitleFmt,
     342             :             const SwFrmFmt &rFollowFmt)
     343             :         {
     344           8 :             bool bPlausableTitlePage = true;
     345             : 
     346           8 :             const SwFmtCol& rFirstCols = rTitleFmt.GetCol();
     347           8 :             const SwFmtCol& rFollowCols = rFollowFmt.GetCol();
     348           8 :             const SwColumns& rFirstColumns = rFirstCols.GetColumns();
     349           8 :             const SwColumns& rFollowColumns = rFollowCols.GetColumns();
     350           8 :             const SvxLRSpaceItem &rOneLR = rTitleFmt.GetLRSpace();
     351           8 :             const SvxLRSpaceItem &rTwoLR= rFollowFmt.GetLRSpace();
     352           8 :             const SwFmtFrmSize& rFirstFrmSize = rTitleFmt.GetFrmSize();
     353           8 :             const SwFmtFrmSize& rFollowFrmSize = rFollowFmt.GetFrmSize();
     354             : 
     355           8 :             if (rFirstColumns.size() != rFollowColumns.size())
     356             :             {
     357             :                 //e.g. #i4320#
     358           0 :                 bPlausableTitlePage = false;
     359             :             }
     360           8 :             else if (rOneLR != rTwoLR)
     361           0 :                 bPlausableTitlePage = false;
     362           8 :             else if (rFirstFrmSize != rFollowFrmSize)
     363           0 :                 bPlausableTitlePage = false;
     364             :             else
     365             :             {
     366           8 :                 HdFtDistanceGlue aOne(rTitleFmt.GetAttrSet());
     367           8 :                 HdFtDistanceGlue aTwo(rFollowFmt.GetAttrSet());
     368             :                 //e.g. #i14509#
     369           8 :                 if (!aOne.EqualTopBottom(aTwo))
     370           0 :                     bPlausableTitlePage = false;
     371             :             }
     372           8 :             return bPlausableTitlePage;
     373             :         }
     374             : 
     375         198 :         HdFtDistanceGlue::HdFtDistanceGlue(const SfxItemSet &rPage)
     376             :         {
     377         198 :             if (const SvxBoxItem *pBox = HasItem<SvxBoxItem>(rPage, RES_BOX))
     378             :             {
     379         198 :                 dyaHdrTop = pBox->CalcLineSpace(BOX_LINE_TOP);
     380         198 :                 dyaHdrBottom = pBox->CalcLineSpace(BOX_LINE_BOTTOM);
     381             :             }
     382             :             else
     383             :             {
     384           0 :                 dyaHdrTop = dyaHdrBottom = 0;
     385           0 :                 dyaHdrBottom = 0;
     386             :             }
     387             :             const SvxULSpaceItem &rUL =
     388         198 :                 ItemGet<SvxULSpaceItem>(rPage, RES_UL_SPACE);
     389         198 :             dyaHdrTop = dyaHdrTop + rUL.GetUpper();
     390         198 :             dyaHdrBottom = dyaHdrBottom + rUL.GetLower();
     391             : 
     392         198 :             dyaTop = dyaHdrTop;
     393         198 :             dyaBottom = dyaHdrBottom;
     394             : 
     395             :             using sw::types::msword_cast;
     396             : 
     397         198 :             const SwFmtHeader *pHd = HasItem<SwFmtHeader>(rPage, RES_HEADER);
     398         198 :             if (pHd && pHd->IsActive() && pHd->GetHeaderFmt())
     399             :             {
     400          22 :                 mbHasHeader = true;
     401          22 :                 dyaTop = dyaTop + static_cast< sal_uInt16 >( (myImplHelpers::CalcHdDist(*(pHd->GetHeaderFmt()))) );
     402             :             }
     403             :             else
     404         176 :                 mbHasHeader = false;
     405             : 
     406         198 :             const SwFmtFooter *pFt = HasItem<SwFmtFooter>(rPage, RES_FOOTER);
     407         198 :             if (pFt && pFt->IsActive() && pFt->GetFooterFmt())
     408             :             {
     409          22 :                 mbHasFooter = true;
     410          22 :                 dyaBottom = dyaBottom + static_cast< sal_uInt16 >( (myImplHelpers::CalcFtDist(*(pFt->GetFooterFmt()))) );
     411             :             }
     412             :             else
     413         176 :                 mbHasFooter = false;
     414         198 :         }
     415             : 
     416           8 :         bool HdFtDistanceGlue::EqualTopBottom(const HdFtDistanceGlue &rOther)
     417             :             const
     418             :         {
     419           8 :             return (dyaTop == rOther.dyaTop && dyaBottom == rOther.dyaBottom);
     420             :         }
     421             : 
     422          78 :         ParaStyleMapper::ParaStyleMapper(SwDoc &rDoc)
     423          78 :             : mpImpl(new myImplHelpers::StyleMapperImpl<SwTxtFmtColl>(rDoc))
     424             :         {
     425          78 :         }
     426             : 
     427          78 :         ParaStyleMapper::~ParaStyleMapper()
     428             :         {
     429          78 :             delete mpImpl;
     430          78 :         }
     431             : 
     432         530 :         ParaStyleMapper::StyleResult ParaStyleMapper::GetStyle(
     433             :             const String& rName, ww::sti eSti)
     434             :         {
     435         530 :             return mpImpl->GetStyle(rName, eSti);
     436             :         }
     437             : 
     438          78 :         CharStyleMapper::CharStyleMapper(SwDoc &rDoc)
     439          78 :             : mpImpl(new myImplHelpers::StyleMapperImpl<SwCharFmt>(rDoc))
     440             :         {
     441          78 :         }
     442             : 
     443          78 :         CharStyleMapper::~CharStyleMapper()
     444             :         {
     445          78 :             delete mpImpl;
     446          78 :         }
     447             : 
     448         188 :         CharStyleMapper::StyleResult CharStyleMapper::GetStyle(
     449             :             const String& rName, ww::sti eSti)
     450             :         {
     451         188 :             return mpImpl->GetStyle(rName, eSti);
     452             :         }
     453             : 
     454        2032 :         FontMapExport::FontMapExport(const String &rFamilyName)
     455             :         {
     456        2032 :             xub_StrLen nIndex = 0;
     457        2032 :             msPrimary = GetNextFontToken(rFamilyName, nIndex);
     458        2032 :             msSecondary = myImplHelpers::FindBestMSSubstituteFont(msPrimary);
     459        2032 :             if (!msSecondary.Len() && nIndex != STRING_NOTFOUND)
     460           0 :                 msSecondary = GetNextFontToken(rFamilyName, nIndex);
     461        2032 :         }
     462             : 
     463       51010 :         bool ItemSort::operator()(sal_uInt16 nA, sal_uInt16 nB) const
     464             :         {
     465             :             /*
     466             :              #i24291#
     467             :              All we want to do is ensure for now is that if a charfmt exist
     468             :              in the character properties that it rises to the top and is
     469             :              exported first.  In the future we might find more ordering
     470             :              depandancies for export, in which case this is the place to do
     471             :              it
     472             :             */
     473       51010 :             if (nA == nB)
     474           4 :                 return false;
     475       51006 :             if (nA == RES_TXTATR_CHARFMT)
     476         184 :                 return true;
     477       50822 :             if (nB == RES_TXTATR_CHARFMT)
     478         182 :                 return false;
     479       50640 :             return nA < nB;
     480             :         }
     481             : 
     482         390 :         CharRuns GetPseudoCharRuns(const SwTxtNode& rTxtNd,
     483             :             xub_StrLen nTxtStart, bool bSplitOnCharSet)
     484             :         {
     485         390 :             const String &rTxt = rTxtNd.GetTxt();
     486             : 
     487         390 :             bool bParaIsRTL = false;
     488             :             OSL_ENSURE(rTxtNd.GetDoc(), "No document for node?, suspicious");
     489         390 :             if (rTxtNd.GetDoc())
     490             :             {
     491         780 :                 if (FRMDIR_HORI_RIGHT_TOP ==
     492         780 :                     rTxtNd.GetDoc()->GetTextDirection(SwPosition(rTxtNd)))
     493             :                 {
     494           0 :                     bParaIsRTL = true;
     495             :                 }
     496             :             }
     497             : 
     498             :             using namespace ::com::sun::star::i18n;
     499             : 
     500         390 :             sal_uInt16 nScript = i18n::ScriptType::LATIN;
     501         390 :             if (rTxt.Len() && pBreakIt && pBreakIt->GetBreakIter().is())
     502         256 :                 nScript = pBreakIt->GetBreakIter()->getScriptType(rTxt, 0);
     503             : 
     504             :             rtl_TextEncoding eChrSet = ItemGet<SvxFontItem>(rTxtNd,
     505         390 :                 GetWhichOfScript(RES_CHRATR_FONT, nScript)).GetCharSet();
     506         390 :             eChrSet = GetExtendedTextEncoding(eChrSet);
     507             : 
     508         390 :             CharRuns aRunChanges;
     509             : 
     510         390 :             if (!rTxt.Len())
     511             :             {
     512             :                 aRunChanges.push_back(CharRunEntry(0, nScript, eChrSet,
     513         134 :                     bParaIsRTL));
     514             :                 return aRunChanges;
     515             :             }
     516             : 
     517             :             typedef std::pair<int32_t, bool> DirEntry;
     518             :             typedef std::vector<DirEntry> DirChanges;
     519             :             typedef DirChanges::const_iterator cDirIter;
     520             : 
     521             :             typedef std::pair<xub_StrLen, sal_Int16> CharSetEntry;
     522             :             typedef std::vector<CharSetEntry> CharSetChanges;
     523             :             typedef CharSetChanges::const_iterator cCharSetIter;
     524             : 
     525             :             typedef std::pair<xub_StrLen, sal_uInt16> ScriptEntry;
     526             :             typedef std::vector<ScriptEntry> ScriptChanges;
     527             :             typedef ScriptChanges::const_iterator cScriptIter;
     528             : 
     529         256 :             DirChanges aDirChanges;
     530         256 :             CharSetChanges aCharSets;
     531         256 :             ScriptChanges aScripts;
     532             : 
     533         256 :             UBiDiDirection eDefaultDir = bParaIsRTL ? UBIDI_RTL : UBIDI_LTR;
     534         256 :             UErrorCode nError = U_ZERO_ERROR;
     535         256 :             UBiDi* pBidi = ubidi_openSized(rTxt.Len(), 0, &nError);
     536         512 :             ubidi_setPara(pBidi, reinterpret_cast<const UChar *>(rTxt.GetBuffer()), rTxt.Len(),
     537         768 :                     static_cast< UBiDiLevel >(eDefaultDir), 0, &nError);
     538             : 
     539         256 :             sal_Int32 nCount = ubidi_countRuns(pBidi, &nError);
     540         256 :             aDirChanges.reserve(nCount);
     541             : 
     542         256 :             int32_t nStart = 0;
     543             :             int32_t nEnd;
     544             :             UBiDiLevel nCurrDir;
     545             : 
     546         512 :             for (sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx)
     547             :             {
     548         256 :                 ubidi_getLogicalRun(pBidi, nStart, &nEnd, &nCurrDir);
     549             :                 /*
     550             :                 UBiDiLevel is the type of the level values in this BiDi
     551             :                 implementation.
     552             : 
     553             :                 It holds an embedding level and indicates the visual direction
     554             :                 by its bit 0 (even/odd value).
     555             : 
     556             :                 The value for UBIDI_DEFAULT_LTR is even and the one for
     557             :                 UBIDI_DEFAULT_RTL is odd
     558             :                 */
     559         256 :                 aDirChanges.push_back(DirEntry(nEnd, nCurrDir & 0x1));
     560         256 :                 nStart = nEnd;
     561             :             }
     562         256 :             ubidi_close(pBidi);
     563             : 
     564         256 :             if (bSplitOnCharSet)
     565             :             {
     566             :                 //Split unicode text into plausable 8bit ranges for export to
     567             :                 //older non unicode aware format
     568           0 :                 xub_StrLen nLen = rTxt.Len();
     569           0 :                 xub_StrLen nPos = 0;
     570           0 :                 while (nPos != nLen)
     571             :                 {
     572             :                     rtl_TextEncoding ScriptType =
     573           0 :                         getBestMSEncodingByChar(rTxt.GetChar(nPos++));
     574           0 :                     while (
     575             :                             (nPos != nLen) &&
     576           0 :                             (ScriptType == getBestMSEncodingByChar(rTxt.GetChar(nPos)))
     577             :                           )
     578             :                     {
     579           0 :                         ++nPos;
     580             :                     }
     581             : 
     582           0 :                     aCharSets.push_back(CharSetEntry(nPos, ScriptType));
     583             :                 }
     584             :             }
     585             : 
     586             :             using sw::types::writer_cast;
     587             : 
     588         256 :             if (pBreakIt && pBreakIt->GetBreakIter().is())
     589             :             {
     590         256 :                 xub_StrLen nLen = rTxt.Len();
     591         256 :                 xub_StrLen nPos = 0;
     592         768 :                 while (nPos < nLen)
     593             :                 {
     594         512 :                     sal_Int32 nEnd2 = pBreakIt->GetBreakIter()->endOfScript(rTxt, nPos,
     595         256 :                         nScript);
     596         256 :                     if (nEnd2 < 0)
     597           0 :                         break;
     598         256 :                     nPos = static_cast< xub_StrLen >(nEnd2);
     599         256 :                     aScripts.push_back(ScriptEntry(nPos, nScript));
     600         256 :                     nScript = pBreakIt->GetBreakIter()->getScriptType(rTxt, nPos);
     601             :                 }
     602             :             }
     603             : 
     604         256 :             cDirIter aBiDiEnd = aDirChanges.end();
     605         256 :             cCharSetIter aCharSetEnd = aCharSets.end();
     606         256 :             cScriptIter aScriptEnd = aScripts.end();
     607             : 
     608         256 :             cDirIter aBiDiIter = aDirChanges.begin();
     609         256 :             cCharSetIter aCharSetIter = aCharSets.begin();
     610         256 :             cScriptIter aScriptIter = aScripts.begin();
     611             : 
     612         256 :             bool bCharIsRTL = bParaIsRTL;
     613             : 
     614        1280 :             while (
     615         512 :                     aBiDiIter != aBiDiEnd ||
     616         256 :                     aCharSetIter != aCharSetEnd ||
     617         256 :                     aScriptIter != aScriptEnd
     618             :                   )
     619             :             {
     620         256 :                 xub_StrLen nMinPos = rTxt.Len();
     621             : 
     622         256 :                 if (aBiDiIter != aBiDiEnd)
     623             :                 {
     624         256 :                     if (aBiDiIter->first < nMinPos)
     625           0 :                         nMinPos = static_cast< xub_StrLen >(aBiDiIter->first);
     626         256 :                     bCharIsRTL = aBiDiIter->second;
     627             :                 }
     628             : 
     629         256 :                 if (aCharSetIter != aCharSetEnd)
     630             :                 {
     631           0 :                     if (aCharSetIter->first < nMinPos)
     632           0 :                         nMinPos = aCharSetIter->first;
     633           0 :                     eChrSet = aCharSetIter->second;
     634             :                 }
     635             : 
     636         256 :                 if (aScriptIter != aScriptEnd)
     637             :                 {
     638         256 :                     if (aScriptIter->first < nMinPos)
     639           0 :                         nMinPos = aScriptIter->first;
     640         256 :                     nScript = aScriptIter->second;
     641             :                 }
     642             : 
     643             :                 aRunChanges.push_back(
     644         256 :                     CharRunEntry(nMinPos, nScript, eChrSet, bCharIsRTL));
     645             : 
     646         256 :                 if (aBiDiIter != aBiDiEnd)
     647             :                 {
     648         256 :                     if (aBiDiIter->first == nMinPos)
     649         256 :                         ++aBiDiIter;
     650             :                 }
     651             : 
     652         256 :                 if (aCharSetIter != aCharSetEnd)
     653             :                 {
     654           0 :                     if (aCharSetIter->first == nMinPos)
     655           0 :                         ++aCharSetIter;
     656             :                 }
     657             : 
     658         256 :                 if (aScriptIter != aScriptEnd)
     659             :                 {
     660         256 :                     if (aScriptIter->first == nMinPos)
     661         256 :                         ++aScriptIter;
     662             :                 }
     663             :             }
     664             : 
     665             :             aRunChanges.erase(std::remove_if(aRunChanges.begin(),
     666         256 :                 aRunChanges.end(), myImplHelpers::IfBeforeStart(nTxtStart)), aRunChanges.end());
     667             : 
     668         256 :             return aRunChanges;
     669             :         }
     670             :     }
     671             : 
     672             :     namespace ms
     673             :     {
     674        2424 :         sal_uInt8 rtl_TextEncodingToWinCharset(rtl_TextEncoding eTextEncoding)
     675             :         {
     676             :             sal_uInt8 nRet =
     677        2424 :                 rtl_getBestWindowsCharsetFromTextEncoding(eTextEncoding);
     678        2424 :             switch (eTextEncoding)
     679             :             {
     680             :                 case RTL_TEXTENCODING_DONTKNOW:
     681             :                 case RTL_TEXTENCODING_UCS2:
     682             :                 case RTL_TEXTENCODING_UTF7:
     683             :                 case RTL_TEXTENCODING_UTF8:
     684             :                 case RTL_TEXTENCODING_JAVA_UTF8:
     685             :                     OSL_ENSURE(nRet != 0x80, "This method may be redundant");
     686        1876 :                     nRet = 0x80;
     687        1876 :                     break;
     688             :                 default:
     689         548 :                     break;
     690             :             }
     691        2424 :             return nRet;
     692             :         }
     693             : 
     694          26 :         long DateTime2DTTM( const DateTime& rDT )
     695             :         {
     696             :         /*
     697             :         mint    short   :6  0000003F    minutes (0-59)
     698             :         hr      short   :5  000007C0    hours (0-23)
     699             :         dom     short   :5  0000F800    days of month (1-31)
     700             :         mon     short   :4  000F0000    months (1-12)
     701             :         yr      short   :9  1FF00000    years (1900-2411)-1900
     702             :         wdy     short   :3  E0000000    weekday(Sunday=0
     703             :                                                 Monday=1
     704             :         ( wdy can be ignored )                  Tuesday=2
     705             :                                                 Wednesday=3
     706             :                                                 Thursday=4
     707             :                                                 Friday=5
     708             :                                                 Saturday=6)
     709             :         */
     710             : 
     711          26 :             if ( rDT.GetDate() == 0L )
     712           8 :                 return 0L;
     713          18 :             long nDT = ( rDT.GetDayOfWeek() + 1 ) % 7;
     714          18 :             nDT <<= 9;
     715          18 :             nDT += ( rDT.GetYear() - 1900 ) & 0x1ff;
     716          18 :             nDT <<= 4;
     717          18 :             nDT += rDT.GetMonth() & 0xf;
     718          18 :             nDT <<= 5;
     719          18 :             nDT += rDT.GetDay() & 0x1f;
     720          18 :             nDT <<= 5;
     721          18 :             nDT += rDT.GetHour() & 0x1f;
     722          18 :             nDT <<= 6;
     723          18 :             nDT += rDT.GetMin() & 0x3f;
     724          18 :             return nDT;
     725             :         }
     726             : 
     727           0 :         sal_uLong MSDateTimeFormatToSwFormat(String& rParams,
     728             :             SvNumberFormatter *pFormatter, sal_uInt16 &rLang, bool bHijri,
     729             :             sal_uInt16 nDocLang)
     730             :         {
     731             :             // tell the Formatter about the new entry
     732           0 :             sal_Int32 nCheckPos = 0;
     733           0 :             short  nType = NUMBERFORMAT_DEFINED;
     734           0 :             sal_uInt32  nKey = 0;
     735             : 
     736           0 :             SwapQuotesInField(rParams);
     737             : 
     738             :             // Force to Japanese when finding one of 'geaE'
     739           0 :             rtl::OUString sJChars( "geE" );
     740           0 :             bool bForceJapanese = ( STRING_NOTFOUND != rParams.SearchChar( sJChars.getStr() ) );
     741           0 :             if ( bForceJapanese )
     742             :             {
     743             :                 rParams.SearchAndReplaceAll( rtl::OUString( "ee" ),
     744           0 :                                              rtl::OUString( "yyyy" ) );
     745             :                 rParams.SearchAndReplaceAll( rtl::OUString( "EE" ),
     746           0 :                                              rtl::OUString( "YYYY" ) );
     747             :             }
     748           0 :             if (LANGUAGE_FRENCH != nDocLang)
     749             :             {
     750             :                 // Handle the 'a' case here
     751           0 :                 xub_StrLen nLastPos = 0;
     752           0 :                 do
     753             :                 {
     754           0 :                     xub_StrLen nPos = rParams.Search( 'a', nLastPos + 1 );
     755           0 :                     bForceJapanese |= ( nPos != STRING_NOTFOUND && IsNotAM( rParams, nPos ) );
     756           0 :                     nLastPos = nPos;
     757             :                 } while ( STRING_NOTFOUND != nLastPos );
     758             :             }
     759             : 
     760             :             // Force to NatNum when finding one of 'oOA'
     761           0 :             String sOldParams( rParams );
     762             :             rParams.SearchAndReplaceAll( rtl::OUString( "o" ),
     763           0 :                                          rtl::OUString( "m" ) );
     764             :             rParams.SearchAndReplaceAll( rtl::OUString( "O" ),
     765           0 :                                          rtl::OUString( "M" ) );
     766           0 :             bool bForceNatNum = !sOldParams.Equals( rParams );
     767           0 :             if (LANGUAGE_FRENCH != nDocLang)
     768             :             {
     769             :                 // Handle the 'A' case here
     770           0 :                 xub_StrLen nLastPos = 0;
     771           0 :                 do
     772             :                 {
     773           0 :                     xub_StrLen nPos = rParams.Search( 'A', nLastPos + 1 );
     774           0 :                     bool bIsCharA = ( nPos != STRING_NOTFOUND && IsNotAM( rParams, nPos ) );
     775           0 :                     bForceNatNum |= bIsCharA;
     776           0 :                     if ( bIsCharA )
     777           0 :                         rParams.SetChar( nPos, 'D' );
     778           0 :                     nLastPos = nPos;
     779             :                 } while ( STRING_NOTFOUND != nLastPos );
     780             :             }
     781             : 
     782           0 :             xub_StrLen nLen = rParams.Len();
     783           0 :             xub_StrLen nI = 0;
     784           0 :             while (nI < nLen)
     785             :             {
     786           0 :                 if (rParams.GetChar(nI) == '\\')
     787           0 :                     nI++;
     788           0 :                 else if (rParams.GetChar(nI) == '\"')
     789             :                 {
     790           0 :                     ++nI;
     791             :                     //While not at the end and not at an unescaped end quote
     792           0 :                     while ((nI < nLen) && (!(rParams.GetChar(nI) == '\"') && (rParams.GetChar(nI-1) != '\\')))
     793           0 :                         ++nI;
     794             :                 }
     795             :                 else //normal unquoted section
     796             :                 {
     797           0 :                     sal_Unicode nChar = rParams.GetChar(nI);
     798             : 
     799             :                     // Change the localized word string to english
     800           0 :                     switch ( nDocLang )
     801             :                     {
     802             :                         case LANGUAGE_FRENCH:
     803           0 :                             if ( ( nChar == 'a' || nChar == 'A' ) && IsNotAM(rParams, nI) )
     804           0 :                                 rParams.SetChar(nI, 'Y');
     805           0 :                             break;
     806             :                         default:
     807             :                             ;
     808             :                     }
     809           0 :                     if (nChar == '/')
     810             :                     {
     811             :                         // MM We have to escape '/' in case it's used as a char
     812           0 :                         rParams.Replace(nI, 1, rtl::OUString("\\/"));
     813           0 :                         nI++;
     814           0 :                         nLen++;
     815             :                     }
     816             : 
     817             :                     // Deal with language differences in date format expression.
     818             :                     // Should be made with i18n framework.
     819             :                     // The list of the mappings and of those "special" locales is to be found at:
     820             :                     // http://l10n.openoffice.org/i18n_framework/LocaleData.html
     821           0 :                     if ( !bForceJapanese && !bForceNatNum )
     822             :                     {
     823             :                         // Convert to the localized equivalent for OOo
     824           0 :                         switch ( rLang )
     825             :                         {
     826             :                         case LANGUAGE_FINNISH:
     827             :                             {
     828           0 :                                 if (nChar == 'y' || nChar == 'Y')
     829           0 :                                     rParams.SetChar (nI, 'V');
     830           0 :                                 else if (nChar == 'm' || nChar == 'M')
     831           0 :                                     rParams.SetChar (nI, 'K');
     832           0 :                                 else if (nChar == 'd' || nChar == 'D')
     833           0 :                                     rParams.SetChar (nI, 'P');
     834           0 :                                 else if (nChar == 'h' || nChar == 'H')
     835           0 :                                     rParams.SetChar (nI, 'T');
     836             :                             }
     837           0 :                             break;
     838             :                         case LANGUAGE_DANISH:
     839             :                         case LANGUAGE_NORWEGIAN:
     840             :                         case LANGUAGE_NORWEGIAN_BOKMAL:
     841             :                         case LANGUAGE_NORWEGIAN_NYNORSK:
     842             :                         case LANGUAGE_SWEDISH:
     843             :                         case LANGUAGE_SWEDISH_FINLAND:
     844             :                             {
     845           0 :                                 if (nChar == 'h' || nChar == 'H')
     846           0 :                                     rParams.SetChar (nI, 'T');
     847             :                             }
     848           0 :                             break;
     849             :                         case LANGUAGE_PORTUGUESE:
     850             :                         case LANGUAGE_PORTUGUESE_BRAZILIAN:
     851             :                         case LANGUAGE_SPANISH_MODERN:
     852             :                         case LANGUAGE_SPANISH_DATED:
     853             :                         case LANGUAGE_SPANISH_MEXICAN:
     854             :                         case LANGUAGE_SPANISH_GUATEMALA:
     855             :                         case LANGUAGE_SPANISH_COSTARICA:
     856             :                         case LANGUAGE_SPANISH_PANAMA:
     857             :                         case LANGUAGE_SPANISH_DOMINICAN_REPUBLIC:
     858             :                         case LANGUAGE_SPANISH_VENEZUELA:
     859             :                         case LANGUAGE_SPANISH_COLOMBIA:
     860             :                         case LANGUAGE_SPANISH_PERU:
     861             :                         case LANGUAGE_SPANISH_ARGENTINA:
     862             :                         case LANGUAGE_SPANISH_ECUADOR:
     863             :                         case LANGUAGE_SPANISH_CHILE:
     864             :                         case LANGUAGE_SPANISH_URUGUAY:
     865             :                         case LANGUAGE_SPANISH_PARAGUAY:
     866             :                         case LANGUAGE_SPANISH_BOLIVIA:
     867             :                         case LANGUAGE_SPANISH_EL_SALVADOR:
     868             :                         case LANGUAGE_SPANISH_HONDURAS:
     869             :                         case LANGUAGE_SPANISH_NICARAGUA:
     870             :                         case LANGUAGE_SPANISH_PUERTO_RICO:
     871             :                             {
     872           0 :                                 if (nChar == 'a' || nChar == 'A')
     873           0 :                                     rParams.SetChar (nI, 'O');
     874           0 :                                 else if (nChar == 'y' || nChar == 'Y')
     875           0 :                                     rParams.SetChar (nI, 'A');
     876             :                             }
     877           0 :                             break;
     878             :                         case LANGUAGE_DUTCH:
     879             :                         case LANGUAGE_DUTCH_BELGIAN:
     880             :                             {
     881           0 :                                 if (nChar == 'y' || nChar == 'Y')
     882           0 :                                     rParams.SetChar (nI, 'J');
     883           0 :                                 else if (nChar == 'u' || nChar == 'U')
     884           0 :                                     rParams.SetChar (nI, 'H');
     885             :                             }
     886           0 :                             break;
     887             :                         case LANGUAGE_ITALIAN:
     888             :                         case LANGUAGE_ITALIAN_SWISS:
     889             :                             {
     890           0 :                                 if (nChar == 'a' || nChar == 'A')
     891           0 :                                     rParams.SetChar (nI, 'O');
     892           0 :                                 else if (nChar == 'g' || nChar == 'G')
     893           0 :                                     rParams.SetChar (nI, 'X');
     894           0 :                                 else if (nChar == 'y' || nChar == 'Y')
     895           0 :                                     rParams.SetChar(nI, 'A');
     896           0 :                                 else if (nChar == 'd' || nChar == 'D')
     897           0 :                                     rParams.SetChar (nI, 'G');
     898             :                             }
     899           0 :                             break;
     900             :                         case LANGUAGE_GERMAN:
     901             :                         case LANGUAGE_GERMAN_SWISS:
     902             :                         case LANGUAGE_GERMAN_AUSTRIAN:
     903             :                         case LANGUAGE_GERMAN_LUXEMBOURG:
     904             :                         case LANGUAGE_GERMAN_LIECHTENSTEIN:
     905             :                             {
     906           0 :                                 if (nChar == 'y' || nChar == 'Y')
     907           0 :                                     rParams.SetChar (nI, 'J');
     908           0 :                                 else if (nChar == 'd' || nChar == 'D')
     909           0 :                                     rParams.SetChar (nI, 'T');
     910             :                             }
     911           0 :                             break;
     912             :                         case LANGUAGE_FRENCH:
     913             :                         case LANGUAGE_FRENCH_BELGIAN:
     914             :                         case LANGUAGE_FRENCH_CANADIAN:
     915             :                         case LANGUAGE_FRENCH_SWISS:
     916             :                         case LANGUAGE_FRENCH_LUXEMBOURG:
     917             :                         case LANGUAGE_FRENCH_MONACO:
     918             :                             {
     919           0 :                                 if (nChar == 'y' || nChar == 'Y' || nChar == 'a')
     920           0 :                                     rParams.SetChar (nI, 'A');
     921           0 :                                 else if (nChar == 'd' || nChar == 'D' || nChar == 'j')
     922           0 :                                     rParams.SetChar (nI, 'J');
     923             :                             }
     924           0 :                             break;
     925             :                         default:
     926             :                             {
     927             :                                 ; // Nothing
     928             :                             }
     929             :                         }
     930             :                     }
     931             :                 }
     932           0 :                 ++nI;
     933             :             }
     934             : 
     935           0 :             if (bForceNatNum)
     936           0 :                 bForceJapanese = true;
     937             : 
     938           0 :             if (bForceJapanese)
     939           0 :                 rLang = LANGUAGE_JAPANESE;
     940             : 
     941           0 :             if (bForceNatNum)
     942           0 :                 rParams.Insert(rtl::OUString("[NatNum1][$-411]"),0);
     943             : 
     944           0 :             if (bHijri)
     945           0 :                 rParams.Insert(rtl::OUString("[~hijri]"), 0);
     946             : 
     947           0 :             OUString sTemp(rParams);
     948           0 :             pFormatter->PutEntry(sTemp, nCheckPos, nType, nKey, rLang);
     949           0 :             rParams = sTemp;
     950             : 
     951           0 :             return nKey;
     952             :         }
     953             : 
     954           0 :         bool IsNotAM(String& rParams, xub_StrLen nPos)
     955             :         {
     956             :             return (
     957           0 :                     (nPos == rParams.Len() - 1) ||
     958             :                     (
     959           0 :                     (rParams.GetChar(nPos+1) != 'M') &&
     960           0 :                     (rParams.GetChar(nPos+1) != 'm')
     961             :                     )
     962           0 :                 );
     963             :         }
     964             : 
     965           0 :         void SwapQuotesInField(String &rFmt)
     966             :         {
     967             :             //Swap unescaped " and ' with ' and "
     968           0 :             xub_StrLen nLen = rFmt.Len();
     969           0 :             for (xub_StrLen nI = 0; nI < nLen; ++nI)
     970             :             {
     971           0 :                 if ((rFmt.GetChar(nI) == '\"') && (!nI || rFmt.GetChar(nI-1) != '\\'))
     972           0 :                     rFmt.SetChar(nI, '\'');
     973           0 :                 else if ((rFmt.GetChar(nI) == '\'') && (!nI || rFmt.GetChar(nI-1) != '\\'))
     974           0 :                     rFmt.SetChar(nI, '\"');
     975             :             }
     976           0 :         }
     977             : 
     978             :     }
     979             : }
     980             : 
     981             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10