LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/core/crsr - bookmrk.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 117 209 56.0 %
Date: 2013-07-09 Functions: 30 54 55.6 %
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 <bookmrk.hxx>
      21             : #include <IDocumentMarkAccess.hxx>
      22             : #include <IDocumentUndoRedo.hxx>
      23             : #include <doc.hxx>
      24             : #include <ndtxt.hxx>
      25             : #include <pam.hxx>
      26             : #include <swserv.hxx>
      27             : #include <sfx2/linkmgr.hxx>
      28             : #include <swtypes.hxx>
      29             : #include <UndoBookmark.hxx>
      30             : #include <unobookmark.hxx>
      31             : #include <rtl/random.h>
      32             : #include <xmloff/odffields.hxx>
      33             : 
      34             : 
      35        4361 : SV_IMPL_REF( SwServerObject )
      36             : 
      37             : using namespace ::sw::mark;
      38             : using namespace ::com::sun::star;
      39             : using namespace ::com::sun::star::uno;
      40             : 
      41             : namespace
      42             : {
      43       21801 :     static void lcl_FixPosition(SwPosition& rPos)
      44             :     {
      45             :         // make sure the position has 1) the proper node, and 2) a proper index
      46       21801 :         SwTxtNode* pTxtNode = rPos.nNode.GetNode().GetTxtNode();
      47       21801 :         if(pTxtNode == NULL && rPos.nContent.GetIndex() > 0)
      48             :         {
      49             :             OSL_TRACE(
      50             :                 "bookmrk.cxx::lcl_FixPosition"
      51             :                 " - illegal position: %d without proper TxtNode", rPos.nContent.GetIndex());
      52           0 :             rPos.nContent.Assign(NULL, 0);
      53             :         }
      54       21801 :         else if(pTxtNode != NULL && rPos.nContent.GetIndex() > pTxtNode->Len())
      55             :         {
      56             :             OSL_TRACE(
      57             :                 "bookmrk.cxx::lcl_FixPosition"
      58             :                 " - illegal position: %d is beyond %d", rPos.nContent.GetIndex(), pTxtNode->Len());
      59           0 :             rPos.nContent.Assign(pTxtNode, pTxtNode->Len());
      60             :         }
      61       21801 :     }
      62             : 
      63          16 :     static void lcl_AssureFieldMarksSet(Fieldmark* const pField,
      64             :         SwDoc* const io_pDoc,
      65             :         const sal_Unicode aStartMark,
      66             :         const sal_Unicode aEndMark)
      67             :     {
      68          16 :         SwPosition& rStart = pField->GetMarkStart();
      69          16 :         SwPosition& rEnd = pField->GetMarkEnd();
      70             :         SwTxtNode const*const pStartTxtNode =
      71          16 :             rStart.nNode.GetNode().GetTxtNode();
      72          16 :         SwTxtNode const*const pEndTxtNode = rEnd.nNode.GetNode().GetTxtNode();
      73             :         const sal_Unicode ch_start =
      74          16 :             pStartTxtNode->GetTxt()[rStart.nContent.GetIndex()];
      75          28 :         xub_StrLen nEndPos = ( rEnd == rStart ||  rEnd.nContent.GetIndex() == 0 ) ?
      76          20 :             rEnd.nContent.GetIndex() : rEnd.nContent.GetIndex() - 1;
      77          16 :         const sal_Unicode ch_end = pEndTxtNode->GetTxt()[nEndPos];
      78          16 :         SwPaM aStartPaM(rStart);
      79          32 :         SwPaM aEndPaM(rEnd);
      80          16 :         io_pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_UI_REPLACE, NULL);
      81          16 :         if( ( ch_start != aStartMark ) && ( aEndMark != CH_TXT_ATR_FORMELEMENT ) )
      82             :         {
      83          12 :             io_pDoc->InsertString(aStartPaM, OUString(aStartMark));
      84          12 :             rStart.nContent--;
      85             :         }
      86          16 :         if ( aEndMark && ( ch_end != aEndMark ) )
      87             :         {
      88          16 :             io_pDoc->InsertString(aEndPaM, OUString(aEndMark));
      89          16 :             rEnd.nContent++;
      90             :         }
      91          32 :         io_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_UI_REPLACE, NULL);
      92          16 :     };
      93             : 
      94           0 :     static void lcl_RemoveFieldMarks(Fieldmark* const pField,
      95             :         SwDoc* const io_pDoc,
      96             :         const sal_Unicode aStartMark,
      97             :         const sal_Unicode aEndMark)
      98             :     {
      99           0 :         SwPosition& rStart = pField->GetMarkStart();
     100           0 :         SwPosition& rEnd = pField->GetMarkEnd();
     101             :         SwTxtNode const*const pStartTxtNode =
     102           0 :             rStart.nNode.GetNode().GetTxtNode();
     103           0 :         SwTxtNode const*const pEndTxtNode = rEnd.nNode.GetNode().GetTxtNode();
     104             :         const sal_Unicode ch_start =
     105           0 :             pStartTxtNode->GetTxt()[rStart.nContent.GetIndex()];
     106           0 :         xub_StrLen nEndPos = ( rEnd == rStart ||  rEnd.nContent.GetIndex() == 0 ) ?
     107           0 :             rEnd.nContent.GetIndex() : rEnd.nContent.GetIndex() - 1;
     108           0 :         const sal_Unicode ch_end = pEndTxtNode->GetTxt()[nEndPos];
     109           0 :         SwPaM aStartPaM(rStart);
     110           0 :         SwPaM aEndPaM(rEnd);
     111           0 :         io_pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_UI_REPLACE, NULL);
     112           0 :         if( ch_start == aStartMark )
     113             :         {
     114           0 :             SwPaM aStart(rStart, rStart);
     115           0 :             aStart.End()->nContent++;
     116           0 :             io_pDoc->DeleteRange(aStart);
     117             :         }
     118           0 :         if ( ch_end == aEndMark )
     119             :         {
     120           0 :             SwPaM aEnd(rEnd, rEnd);
     121           0 :             aEnd.Start()->nContent--;
     122           0 :             io_pDoc->DeleteRange(aEnd);
     123             :         }
     124           0 :         io_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_UI_REPLACE, NULL);
     125           0 :     };
     126             : }
     127             : 
     128             : namespace sw { namespace mark
     129             : {
     130       13793 :     MarkBase::MarkBase(const SwPaM& aPaM,
     131             :         const OUString& rName)
     132             :         : SwModify(0)
     133       13793 :         , m_pPos1(new SwPosition(*(aPaM.GetPoint())))
     134       27586 :         , m_aName(rName)
     135             :     {
     136       13793 :         lcl_FixPosition(*m_pPos1);
     137       13793 :         if (aPaM.HasMark() && (*aPaM.GetMark() != *aPaM.GetPoint()))
     138             :         {
     139        8008 :             MarkBase::SetOtherMarkPos(*(aPaM.GetMark()));
     140        8008 :             lcl_FixPosition(*m_pPos2);
     141             :         }
     142       13793 :     }
     143             : 
     144             :     // For fieldmarks, the CH_TXT_ATR_FIELDSTART and CH_TXT_ATR_FIELDEND
     145             :     // themselves are part of the covered range. This is guaranteed by
     146             :     // TextFieldmark::InitDoc/lcl_AssureFieldMarksSet.
     147         170 :     bool MarkBase::IsCoveringPosition(const SwPosition& rPos) const
     148             :     {
     149         170 :         return GetMarkStart() <= rPos && rPos < GetMarkEnd();
     150             :     }
     151             : 
     152         813 :     void MarkBase::SetMarkPos(const SwPosition& rNewPos)
     153             :     {
     154         813 :         ::boost::scoped_ptr<SwPosition>(new SwPosition(rNewPos)).swap(m_pPos1);
     155         813 :     }
     156             : 
     157        8812 :     void MarkBase::SetOtherMarkPos(const SwPosition& rNewPos)
     158             :     {
     159        8812 :         ::boost::scoped_ptr<SwPosition>(new SwPosition(rNewPos)).swap(m_pPos2);
     160        8812 :     }
     161             : 
     162           0 :     OUString MarkBase::ToString( ) const
     163             :     {
     164           0 :         OUStringBuffer buf;
     165           0 :         buf.append("Mark: ( Name, [ Node1, Index1 ] ): ( ");
     166           0 :         buf.append( m_aName ).append(", [ ");
     167           0 :         buf.append( sal_Int32( GetMarkPos().nNode.GetIndex( ) ) )
     168           0 :             .append(", ");
     169           0 :         buf.append( sal_Int32( GetMarkPos().nContent.GetIndex( ) ) )
     170           0 :             .append(" ] )");
     171             : 
     172           0 :         return buf.makeStringAndClear( );
     173             :     }
     174             : 
     175       13793 :     MarkBase::~MarkBase()
     176       13793 :     { }
     177             : 
     178       13797 :     OUString MarkBase::GenerateNewName(const OUString& rPrefix)
     179             :     {
     180       13797 :         static rtlRandomPool aPool = rtl_random_createPool();
     181       13797 :         static OUString sUniquePostfix;
     182             :         static sal_Int32 nCount = SAL_MAX_INT32;
     183       13797 :         OUStringBuffer aResult(rPrefix);
     184       13797 :         if(nCount == SAL_MAX_INT32)
     185             :         {
     186             :             sal_Int32 nRandom;
     187          24 :             rtl_random_getBytes(aPool, &nRandom, sizeof(nRandom));
     188          24 :             sUniquePostfix = OUStringBuffer(13).append('_').append(static_cast<sal_Int32>(abs(nRandom))).makeStringAndClear();
     189          24 :             nCount = 0;
     190             :         }
     191             :         // putting the counter in front of the random parts will speed up string comparisons
     192       13797 :         return aResult.append(nCount++).append(sUniquePostfix).makeStringAndClear();
     193             :     }
     194             : 
     195             : 
     196           0 :     void MarkBase::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew )
     197             :     {
     198           0 :         NotifyClients(pOld, pNew);
     199           0 :         if (pOld && (RES_REMOVE_UNO_OBJECT == pOld->Which()))
     200             :         {   // invalidate cached uno object
     201           0 :             SetXBookmark(uno::Reference<text::XTextContent>(0));
     202             :         }
     203           0 :     }
     204             : 
     205             :     // TODO: everything else uses MarkBase::GenerateNewName ?
     206           0 :     NavigatorReminder::NavigatorReminder(const SwPaM& rPaM)
     207           0 :         : MarkBase(rPaM, OUString("__NavigatorReminder__"))
     208           0 :     { }
     209             : 
     210       11731 :     UnoMark::UnoMark(const SwPaM& aPaM)
     211       11731 :         : MarkBase(aPaM, MarkBase::GenerateNewName(OUString("__UnoMark__")))
     212       11731 :     { }
     213             : 
     214        2046 :     DdeBookmark::DdeBookmark(const SwPaM& aPaM)
     215             :         : MarkBase(aPaM, MarkBase::GenerateNewName(OUString("__DdeLink__")))
     216        2046 :         , m_aRefObj(NULL)
     217        2046 :     { }
     218             : 
     219           0 :     void DdeBookmark::SetRefObject(SwServerObject* pObj)
     220             :     {
     221           0 :         m_aRefObj = pObj;
     222           0 :     }
     223             : 
     224          64 :     void DdeBookmark::DeregisterFromDoc(SwDoc* const pDoc)
     225             :     {
     226          64 :         if(m_aRefObj.Is())
     227           0 :             pDoc->GetLinkManager().RemoveServer(m_aRefObj);
     228          64 :     }
     229             : 
     230        4092 :     DdeBookmark::~DdeBookmark()
     231             :     {
     232        2046 :         if( m_aRefObj.Is() )
     233             :         {
     234           0 :             if(m_aRefObj->HasDataLinks())
     235             :             {
     236           0 :                 ::sfx2::SvLinkSource* p = &m_aRefObj;
     237           0 :                 p->SendDataChanged();
     238             :             }
     239           0 :             m_aRefObj->SetNoServer();
     240             :         }
     241        2046 :     }
     242             : 
     243        2046 :     Bookmark::Bookmark(const SwPaM& aPaM,
     244             :         const KeyCode& rCode,
     245             :         const OUString& rName,
     246             :         const OUString& rShortName)
     247             :         : DdeBookmark(aPaM)
     248             :         , ::sfx2::Metadatable()
     249             :         , m_aCode(rCode)
     250        2046 :         , m_sShortName(rShortName)
     251             :     {
     252        2046 :         m_aName = rName;
     253        2046 :     }
     254             : 
     255        2046 :     void Bookmark::InitDoc(SwDoc* const io_pDoc)
     256             :     {
     257        2046 :         if (io_pDoc->GetIDocumentUndoRedo().DoesUndo())
     258             :         {
     259        1038 :             io_pDoc->GetIDocumentUndoRedo().AppendUndo(
     260        1038 :                     new SwUndoInsBookmark(*this));
     261             :         }
     262        2046 :         io_pDoc->SetModified();
     263        2046 :     }
     264             : 
     265          14 :     ::sfx2::IXmlIdRegistry& Bookmark::GetRegistry()
     266             :     {
     267          14 :         SwDoc *const pDoc( GetMarkPos().GetDoc() );
     268             :         OSL_ENSURE(pDoc, "Bookmark::MakeUnoObject: no doc?");
     269          14 :         return pDoc->GetXmlIdRegistry();
     270             :     }
     271             : 
     272        1307 :     bool Bookmark::IsInClipboard() const
     273             :     {
     274        1307 :         SwDoc *const pDoc( GetMarkPos().GetDoc() );
     275             :         OSL_ENSURE(pDoc, "Bookmark::IsInClipboard: no doc?");
     276        1307 :         return pDoc->IsClipBoard();
     277             :     }
     278             : 
     279        1307 :     bool Bookmark::IsInUndo() const
     280             :     {
     281        1307 :         return false;
     282             :     }
     283             : 
     284          16 :     bool Bookmark::IsInContent() const
     285             :     {
     286          16 :         SwDoc *const pDoc( GetMarkPos().GetDoc() );
     287             :         OSL_ENSURE(pDoc, "Bookmark::IsInContent: no doc?");
     288          16 :         return !pDoc->IsInHeaderFooter( SwNodeIndex(GetMarkPos().nNode) );
     289             :     }
     290             : 
     291           0 :     uno::Reference< rdf::XMetadatable > Bookmark::MakeUnoObject()
     292             :     {
     293           0 :         SwDoc *const pDoc( GetMarkPos().GetDoc() );
     294             :         OSL_ENSURE(pDoc, "Bookmark::MakeUnoObject: no doc?");
     295             :         const uno::Reference< rdf::XMetadatable> xMeta(
     296           0 :                 SwXBookmark::CreateXBookmark(*pDoc, *this), uno::UNO_QUERY);
     297           0 :         return xMeta;
     298             :     }
     299             : 
     300          16 :     Fieldmark::Fieldmark(const SwPaM& rPaM)
     301          16 :         : MarkBase(rPaM, MarkBase::GenerateNewName(OUString("__Fieldmark__")))
     302             :     {
     303          16 :         if(!IsExpanded())
     304           4 :             SetOtherMarkPos(GetMarkPos());
     305          16 :     }
     306             : 
     307           0 :     OUString Fieldmark::ToString( ) const
     308             :     {
     309           0 :         OUStringBuffer buf;
     310             :         buf.append(
     311           0 :             "Fieldmark: ( Name, Type, [ Nd1, Id1 ], [ Nd2, Id2 ] ): ( ");
     312           0 :         buf.append( m_aName ).append(", ");
     313           0 :         buf.append( m_aFieldname ).append(", [ ");
     314           0 :         buf.append( sal_Int32( GetMarkPos().nNode.GetIndex( ) ) )
     315           0 :             .append(", ");
     316           0 :         buf.append( sal_Int32( GetMarkPos( ).nContent.GetIndex( ) ) )
     317           0 :             .append(" ], [");
     318           0 :         buf.append( sal_Int32( GetOtherMarkPos().nNode.GetIndex( ) ) )
     319           0 :             .append(", ");
     320           0 :         buf.append( sal_Int32( GetOtherMarkPos( ).nContent.GetIndex( ) ) )
     321           0 :             .append(" ] ) ");
     322             : 
     323           0 :         return buf.makeStringAndClear( );
     324             :     }
     325             : 
     326           0 :     void Fieldmark::Invalidate( )
     327             :     {
     328             :         // TODO: Does exist a better solution to trigger a format of the
     329             :         //       fieldmark portion? If yes, please use it.
     330           0 :         SwPaM aPaM( this->GetMarkPos(), this->GetOtherMarkPos() );
     331           0 :         aPaM.InvalidatePaM();
     332           0 :     }
     333             : 
     334          12 :     TextFieldmark::TextFieldmark(const SwPaM& rPaM)
     335          12 :         : Fieldmark(rPaM)
     336          12 :     { }
     337             : 
     338          12 :     void TextFieldmark::InitDoc(SwDoc* const io_pDoc)
     339             :     {
     340          12 :         lcl_AssureFieldMarksSet(this, io_pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
     341          12 :     }
     342             : 
     343           0 :     void TextFieldmark::ReleaseDoc(SwDoc* const pDoc)
     344             :     {
     345           0 :         lcl_RemoveFieldMarks(this, pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
     346           0 :     }
     347             : 
     348           4 :     CheckboxFieldmark::CheckboxFieldmark(const SwPaM& rPaM)
     349           4 :         : Fieldmark(rPaM)
     350           4 :     { }
     351             : 
     352           4 :     void CheckboxFieldmark::InitDoc(SwDoc* const io_pDoc)
     353             :     {
     354           4 :         lcl_AssureFieldMarksSet(this, io_pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT);
     355             : 
     356             :         // For some reason the end mark is moved from 1 by the Insert: we don't
     357             :         // want this for checkboxes
     358           4 :         this->GetMarkEnd( ).nContent--;
     359           4 :     }
     360             : 
     361           0 :     void CheckboxFieldmark::ReleaseDoc(SwDoc* const pDoc)
     362             :     {
     363             :         lcl_RemoveFieldMarks(this, pDoc,
     364           0 :                 CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT);
     365           0 :     }
     366             : 
     367           4 :     void CheckboxFieldmark::SetChecked(bool checked)
     368             :     {
     369           4 :         if ( IsChecked() != checked )
     370             :         {
     371           2 :             (*GetParameters())[OUString(ODF_FORMCHECKBOX_RESULT)] = makeAny(checked);
     372             :             // mark document as modified
     373           2 :             SwDoc *const pDoc( GetMarkPos().GetDoc() );
     374           2 :             if ( pDoc )
     375           2 :                 pDoc->SetModified();
     376             :         }
     377           4 :     }
     378             : 
     379           4 :     bool CheckboxFieldmark::IsChecked() const
     380             :     {
     381           4 :         bool bResult = false;
     382           4 :         parameter_map_t::const_iterator pResult = GetParameters()->find(OUString(ODF_FORMCHECKBOX_RESULT));
     383           4 :         if(pResult != GetParameters()->end())
     384           0 :             pResult->second >>= bResult;
     385           4 :         return bResult;
     386             :     }
     387             : 
     388           0 :     OUString CheckboxFieldmark::toString( ) const
     389             :     {
     390           0 :         OUStringBuffer buf;
     391             :         buf.append(
     392           0 :             "CheckboxFieldmark: ( Name, Type, [ Nd1, Id1 ], [ Nd2, Id2 ] ): ( ");
     393           0 :         buf.append( m_aName ).append(", ");
     394           0 :         buf.append( GetFieldname() ).append(", [ ");
     395           0 :         buf.append( sal_Int32( GetMarkPos().nNode.GetIndex( ) ) )
     396           0 :             .append(", ");
     397           0 :         buf.append( sal_Int32( GetMarkPos( ).nContent.GetIndex( ) ) )
     398           0 :             .append(" ], [");
     399           0 :         buf.append( sal_Int32( GetOtherMarkPos().nNode.GetIndex( ) ) )
     400           0 :             .append(", ");
     401           0 :         buf.append( sal_Int32( GetOtherMarkPos( ).nContent.GetIndex( ) ) )
     402           0 :             .append(" ] ) ");
     403             : 
     404           0 :         return buf.makeStringAndClear( );
     405             :     }
     406          99 : }}
     407             : 
     408             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10