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

Generated by: LCOV version 1.10