LCOV - code coverage report
Current view: top level - sw/source/core/edit - edfld.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 34 213 16.0 %
Date: 2015-06-13 12:38:46 Functions: 10 27 37.0 %
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 <config_features.h>
      21             : 
      22             : #include <unotools/charclass.hxx>
      23             : #include <editsh.hxx>
      24             : #include <fldbas.hxx>
      25             : #include <doc.hxx>
      26             : #include <IDocumentFieldsAccess.hxx>
      27             : #include <IDocumentState.hxx>
      28             : #include <docary.hxx>
      29             : #include <fmtfld.hxx>
      30             : #include <txtfld.hxx>
      31             : #include <edimp.hxx>
      32             : #include <dbfld.hxx>
      33             : #include <expfld.hxx>
      34             : #include <flddat.hxx>
      35             : #include <swundo.hxx>
      36             : #include <dbmgr.hxx>
      37             : #include <swddetbl.hxx>
      38             : #include <hints.hxx>
      39             : #include <calbck.hxx>
      40             : #include <fieldhint.hxx>
      41             : #include <DocumentSettingManager.hxx>
      42             : #include <IDocumentContentOperations.hxx>
      43             : 
      44             : /// count field types with a ResId, if 0 count all
      45           0 : size_t SwEditShell::GetFieldTypeCount(sal_uInt16 nResId, bool bUsed ) const
      46             : {
      47           0 :     const SwFieldTypes* pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
      48             : 
      49           0 :     if(nResId == USHRT_MAX)
      50             :     {
      51           0 :         if(!bUsed)
      52           0 :             return static_cast<sal_uInt16>(pFieldTypes->size());
      53             : 
      54           0 :         size_t nUsed = 0;
      55           0 :         for ( const auto pFieldType : *pFieldTypes )
      56             :         {
      57           0 :             if(IsUsed(*pFieldType))
      58           0 :                 nUsed++;
      59             :         }
      60           0 :         return nUsed;
      61             :     }
      62             : 
      63             :     // all types with the same ResId
      64           0 :     size_t nIdx  = 0;
      65           0 :     for(const auto pFieldType : *pFieldTypes)
      66             :     {
      67             :         // same ResId -> increment index
      68           0 :         if(pFieldType->Which() == nResId)
      69           0 :             nIdx++;
      70             :     }
      71           0 :     return nIdx;
      72             : }
      73             : 
      74             : /// get field types with a ResId, if 0 get all
      75           1 : SwFieldType* SwEditShell::GetFieldType(size_t nField, sal_uInt16 nResId, bool bUsed ) const
      76             : {
      77           1 :     const SwFieldTypes* pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
      78             : 
      79           1 :     if(nResId == USHRT_MAX && nField < pFieldTypes->size())
      80             :     {
      81           0 :         if(!bUsed)
      82           0 :             return (*pFieldTypes)[nField];
      83             : 
      84           0 :         size_t nUsed = 0;
      85           0 :         for ( const auto pFieldType : *pFieldTypes )
      86             :         {
      87           0 :             if(IsUsed(*pFieldType))
      88             :             {
      89           0 :                 if(nUsed == nField)
      90           0 :                     return pFieldType;
      91           0 :                 nUsed++;
      92             :             }
      93             :         }
      94           0 :         return nullptr;
      95             :     }
      96             : 
      97           1 :     size_t nIdx = 0;
      98          13 :     for(const auto pFieldType : *pFieldTypes)
      99             :     {
     100             :         // same ResId -> increment index
     101          13 :         if(pFieldType->Which() == nResId)
     102             :         {
     103           1 :             if (!bUsed || IsUsed(*pFieldType))
     104             :             {
     105           1 :                 if(nIdx == nField)
     106           1 :                     return pFieldType;
     107           0 :                 nIdx++;
     108             :             }
     109             :         }
     110             :     }
     111           0 :     return 0;
     112             : }
     113             : 
     114             : /// get first type with given ResId and name
     115           0 : SwFieldType* SwEditShell::GetFieldType(sal_uInt16 nResId, const OUString& rName) const
     116             : {
     117           0 :     return GetDoc()->getIDocumentFieldsAccess().GetFieldType( nResId, rName, false );
     118             : }
     119             : 
     120             : /// delete field type
     121           0 : void SwEditShell::RemoveFieldType(size_t nField, sal_uInt16 nResId)
     122             : {
     123           0 :     if( USHRT_MAX == nResId )
     124             :     {
     125           0 :         GetDoc()->getIDocumentFieldsAccess().RemoveFieldType(nField);
     126           0 :         return;
     127             :     }
     128             : 
     129           0 :     const SwFieldTypes* pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
     130           0 :     size_t nIdx = 0;
     131           0 :     const SwFieldTypes::size_type nSize = pFieldTypes->size();
     132           0 :     for( SwFieldTypes::size_type i = 0; i < nSize; ++i )
     133             :         // Gleiche ResId -> Index erhoehen
     134           0 :         if( (*pFieldTypes)[i]->Which() == nResId && nIdx++ == nField )
     135             :         {
     136           0 :             GetDoc()->getIDocumentFieldsAccess().RemoveFieldType( i );
     137           0 :             return;
     138             :         }
     139             : }
     140             : 
     141             : /// delete field type based on its name
     142           0 : void SwEditShell::RemoveFieldType(sal_uInt16 nResId, const OUString& rStr)
     143             : {
     144           0 :     const SwFieldTypes* pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
     145           0 :     const SwFieldTypes::size_type nSize = pFieldTypes->size();
     146           0 :     const CharClass& rCC = GetAppCharClass();
     147             : 
     148           0 :     OUString aTmp( rCC.lowercase( rStr ));
     149             : 
     150           0 :     for(SwFieldTypes::size_type i = 0; i < nSize; ++i)
     151             :     {
     152             :         // same ResId -> increment index
     153           0 :         SwFieldType* pFieldType = (*pFieldTypes)[i];
     154           0 :         if( pFieldType->Which() == nResId )
     155             :         {
     156           0 :             if( aTmp == rCC.lowercase( pFieldType->GetName() ) )
     157             :             {
     158           0 :                 GetDoc()->getIDocumentFieldsAccess().RemoveFieldType(i);
     159           0 :                 return;
     160             :             }
     161             :         }
     162           0 :     }
     163             : }
     164             : 
     165           0 : void SwEditShell::FieldToText( SwFieldType* pType )
     166             : {
     167           0 :     if( !pType->HasWriterListeners() )
     168           0 :         return;
     169             : 
     170           0 :     SET_CURR_SHELL( this );
     171           0 :     StartAllAction();
     172           0 :     StartUndo( UNDO_DELETE );
     173           0 :     Push();
     174           0 :     SwPaM* pPaM = GetCrsr();
     175             :     // TODO: this is really hackish
     176           0 :     SwFieldHint aHint( pPaM );
     177           0 :     SwIterator<SwClient,SwFieldType> aIter(*pType);
     178           0 :     for( SwClient* pClient = aIter.First(); pClient; pClient = aIter.Next() )
     179             :     {
     180           0 :         pPaM->DeleteMark();
     181           0 :         pClient->SwClientNotifyCall( *pType, aHint );
     182             :     }
     183             : 
     184           0 :     Pop( false );
     185           0 :     EndAllAction();
     186           0 :     EndUndo( UNDO_DELETE );
     187             : }
     188             : 
     189             : /// add a field at the cursor position
     190           1 : void SwEditShell::Insert2(SwField& rField, const bool bForceExpandHints)
     191             : {
     192           1 :     SET_CURR_SHELL( this );
     193           1 :     StartAllAction();
     194           2 :     SwFormatField aField( rField );
     195             : 
     196             :     const SetAttrMode nInsertFlags = (bForceExpandHints)
     197             :         ? SetAttrMode::FORCEHINTEXPAND
     198           1 :         : SetAttrMode::DEFAULT;
     199             : 
     200           2 :     for(SwPaM& rPaM : GetCrsr()->GetRingContainer()) // for each PaM
     201             :     {
     202           1 :         const bool bSuccess(GetDoc()->getIDocumentContentOperations().InsertPoolItem(rPaM, aField, nInsertFlags));
     203             :         OSL_ENSURE( bSuccess, "Doc->Insert(Field) failed");
     204             :         (void) bSuccess;
     205             :     }
     206             : 
     207           2 :     EndAllAction();
     208           1 : }
     209             : 
     210             : /// Are the PaMs positioned on fields?
     211           0 : static SwTextField* lcl_FindInputField( SwDoc* pDoc, SwField& rField )
     212             : {
     213             :     // Search field via its address. For input fields this needs to be done in protected fields.
     214           0 :     SwTextField* pTField = 0;
     215           0 :     if( RES_INPUTFLD == rField.Which() )
     216             :     {
     217             :         const sal_uInt32 nMaxItems =
     218           0 :             pDoc->GetAttrPool().GetItemCount2( RES_TXTATR_INPUTFIELD );
     219           0 :         for( sal_uInt32 n = 0; n < nMaxItems; ++n )
     220             :         {
     221           0 :             const SfxPoolItem* pItem = NULL;
     222           0 :             if( 0 != (pItem = pDoc->GetAttrPool().GetItem2( RES_TXTATR_INPUTFIELD, n ) )
     223           0 :                 && static_cast<const SwFormatField*>(pItem)->GetField() == &rField )
     224             :             {
     225           0 :                 pTField = const_cast<SwFormatField*>(static_cast<const SwFormatField*>(pItem))->GetTextField();
     226           0 :                 break;
     227             :             }
     228             :         }
     229             :     }
     230           0 :     else if( RES_SETEXPFLD == rField.Which()
     231           0 :         && static_cast<SwSetExpField&>(rField).GetInputFlag() )
     232             :     {
     233             :         const sal_uInt32 nMaxItems =
     234           0 :             pDoc->GetAttrPool().GetItemCount2( RES_TXTATR_FIELD );
     235           0 :         for( sal_uInt32 n = 0; n < nMaxItems; ++n )
     236             :         {
     237           0 :             const SfxPoolItem* pItem = NULL;
     238           0 :             if( 0 != (pItem = pDoc->GetAttrPool().GetItem2( RES_TXTATR_FIELD, n ) )
     239           0 :                 && static_cast<const SwFormatField*>(pItem)->GetField() == &rField )
     240             :             {
     241           0 :                 pTField = const_cast<SwFormatField*>(static_cast<const SwFormatField*>(pItem))->GetTextField();
     242           0 :                 break;
     243             :             }
     244             :         }
     245             :     }
     246           0 :     return pTField;
     247             : }
     248             : 
     249           0 : void SwEditShell::UpdateFields( SwField &rField )
     250             : {
     251           0 :     SET_CURR_SHELL( this );
     252           0 :     StartAllAction();
     253             :     {
     254             :         // // If there are no selections so take the value of the current cursor position.
     255           0 :         SwMsgPoolItem* pMsgHint = 0;
     256           0 :         SwRefMarkFieldUpdate aRefMkHt( GetOut() );
     257           0 :         sal_uInt16 nFieldWhich = rField.GetTyp()->Which();
     258           0 :         if( RES_GETREFFLD == nFieldWhich )
     259           0 :             pMsgHint = &aRefMkHt;
     260             : 
     261           0 :         SwPaM* pCrsr = GetCrsr();
     262             :         SwTextField *pTextField;
     263             :         SwFormatField *pFormatField;
     264             : 
     265           0 :         if ( !pCrsr->IsMultiSelection() && !pCrsr->HasMark())
     266             :         {
     267           0 :             pTextField = GetTextFieldAtPos( pCrsr->Start(), true );
     268             : 
     269           0 :             if (!pTextField) // #i30221#
     270           0 :                 pTextField = lcl_FindInputField( GetDoc(), rField);
     271             : 
     272           0 :             if (pTextField != 0)
     273           0 :                 GetDoc()->getIDocumentFieldsAccess().UpdateField(pTextField, rField, pMsgHint, true);
     274             :         }
     275             : 
     276             :         // bOkay (instead of return because of EndAllAction) becomes false,
     277             :         // 1) if only one PaM has more than one field or
     278             :         // 2) if there are mixed field types
     279           0 :         bool bOkay = true;
     280           0 :         bool bTableSelBreak = false;
     281             : 
     282           0 :         SwMsgPoolItem aFieldHint( RES_TXTATR_FIELD );  // Search-Hint
     283           0 :         SwMsgPoolItem aAnnotationFieldHint( RES_TXTATR_ANNOTATION );
     284           0 :         SwMsgPoolItem aInputFieldHint( RES_TXTATR_INPUTFIELD );
     285           0 :         for(SwPaM& rPaM : GetCrsr()->GetRingContainer()) // for each PaM
     286             :         {
     287           0 :             if( rPaM.HasMark() && bOkay )    // ... with selection
     288             :             {
     289             :                 // copy of the PaM
     290           0 :                 SwPaM aCurPam( *rPaM.GetMark(), *rPaM.GetPoint() );
     291           0 :                 SwPaM aPam( *rPaM.GetPoint() );
     292             : 
     293           0 :                 SwPosition *pCurStt = aCurPam.Start(), *pCurEnd =
     294           0 :                     aCurPam.End();
     295             :                 /*
     296             :                  * In case that there are two contiguous fields in a PaM, the aPam goes step by step
     297             :                  * to the end. aCurPam is reduced in each loop. If aCurPam was searched completely,
     298             :                  * the loop terminates because Start = End.
     299             :                  */
     300             : 
     301             :                 // Search for SwTextField ...
     302           0 :                 while(  bOkay
     303           0 :                      && pCurStt->nContent != pCurEnd->nContent
     304           0 :                      && ( aPam.Find( aFieldHint, false, fnMoveForward, &aCurPam, true )
     305           0 :                           || aPam.Find( aAnnotationFieldHint, false, fnMoveForward, &aCurPam )
     306           0 :                           || aPam.Find( aInputFieldHint, false, fnMoveForward, &aCurPam ) ) )
     307             :                 {
     308             :                     // if only one PaM has more than one field  ...
     309           0 :                     if( aPam.Start()->nContent != pCurStt->nContent )
     310           0 :                         bOkay = false;
     311             : 
     312           0 :                     if( 0 != (pTextField = GetTextFieldAtPos( pCurStt, true )) )
     313             :                     {
     314           0 :                         pFormatField = const_cast<SwFormatField*>(&pTextField->GetFormatField());
     315           0 :                         SwField *pCurField = pFormatField->GetField();
     316             : 
     317             :                         // if there are mixed field types
     318           0 :                         if( pCurField->GetTyp()->Which() !=
     319           0 :                             rField.GetTyp()->Which() )
     320           0 :                             bOkay = false;
     321             : 
     322           0 :                         bTableSelBreak = GetDoc()->getIDocumentFieldsAccess().UpdateField(pTextField, rField,
     323           0 :                                                            pMsgHint, false);
     324             :                     }
     325             :                     // The search area is reduced by the found area:
     326           0 :                     ++pCurStt->nContent;
     327           0 :                 }
     328             :             }
     329             : 
     330           0 :             if( bTableSelBreak ) // If table section and table formula are updated -> finish
     331           0 :                 break;
     332             : 
     333           0 :         }
     334             :     }
     335           0 :     GetDoc()->getIDocumentState().SetModified();
     336           0 :     EndAllAction();
     337           0 : }
     338             : 
     339           0 : SwDBData SwEditShell::GetDBData() const
     340             : {
     341           0 :     return GetDoc()->GetDBData();
     342             : }
     343             : 
     344           2 : const SwDBData& SwEditShell::GetDBDesc() const
     345             : {
     346           2 :     return GetDoc()->GetDBDesc();
     347             : }
     348             : 
     349           8 : void SwEditShell::ChgDBData(const SwDBData& rNewData)
     350             : {
     351           8 :     GetDoc()->ChgDBData(rNewData);
     352           8 : }
     353             : 
     354           0 : void SwEditShell::GetAllUsedDB( std::vector<OUString>& rDBNameList,
     355             :                                 std::vector<OUString>* pAllDBNames )
     356             : {
     357           0 :     GetDoc()->GetAllUsedDB( rDBNameList, pAllDBNames );
     358           0 : }
     359             : 
     360           0 : void SwEditShell::ChangeDBFields( const std::vector<OUString>& rOldNames,
     361             :                                   const OUString& rNewName )
     362             : {
     363           0 :     GetDoc()->ChangeDBFields( rOldNames, rNewName );
     364           0 : }
     365             : 
     366             : /// Update all expression fields
     367           0 : void SwEditShell::UpdateExpFields(bool bCloseDB)
     368             : {
     369           0 :     SET_CURR_SHELL( this );
     370           0 :     StartAllAction();
     371           0 :     GetDoc()->getIDocumentFieldsAccess().UpdateExpFields(NULL, true);
     372           0 :     if (bCloseDB)
     373             :     {
     374             : #if HAVE_FEATURE_DBCONNECTIVITY
     375           0 :         GetDoc()->GetDBManager()->CloseAll(); // close all database connections
     376             : #endif
     377             :     }
     378           0 :     EndAllAction();
     379           0 : }
     380             : 
     381           8 : SwDBManager* SwEditShell::GetDBManager() const
     382             : {
     383             : #if HAVE_FEATURE_DBCONNECTIVITY
     384           8 :     return GetDoc()->GetDBManager();
     385             : #else
     386             :     return NULL;
     387             : #endif
     388             : }
     389             : 
     390             : /// insert field type
     391           0 : SwFieldType* SwEditShell::InsertFieldType(const SwFieldType& rFieldType)
     392             : {
     393           0 :     return GetDoc()->getIDocumentFieldsAccess().InsertFieldType(rFieldType);
     394             : }
     395             : 
     396          47 : void SwEditShell::LockExpFields()
     397             : {
     398          47 :     GetDoc()->getIDocumentFieldsAccess().LockExpFields();
     399          47 : }
     400             : 
     401          47 : void SwEditShell::UnlockExpFields()
     402             : {
     403          47 :     GetDoc()->getIDocumentFieldsAccess().UnlockExpFields();
     404          47 : }
     405             : 
     406           0 : void SwEditShell::SetFieldUpdateFlags( SwFieldUpdateFlags eFlags )
     407             : {
     408           0 :     getIDocumentSettingAccess()->setFieldUpdateFlags( eFlags );
     409           0 : }
     410             : 
     411           0 : SwFieldUpdateFlags SwEditShell::GetFieldUpdateFlags(bool bDocSettings) const
     412             : {
     413           0 :     return getIDocumentSettingAccess()->getFieldUpdateFlags( !bDocSettings );
     414             : }
     415             : 
     416           0 : void SwEditShell::SetLabelDoc( bool bFlag )
     417             : {
     418           0 :     GetDoc()->GetDocumentSettingManager().set(DocumentSettingId::LABEL_DOCUMENT, bFlag );
     419           0 : }
     420             : 
     421        5849 : bool SwEditShell::IsLabelDoc() const
     422             : {
     423        5849 :     return getIDocumentSettingAccess()->get(DocumentSettingId::LABEL_DOCUMENT);
     424             : }
     425             : 
     426           0 : void SwEditShell::ChangeAuthorityData(const SwAuthEntry* pNewData)
     427             : {
     428           0 :     GetDoc()->ChangeAuthorityData(pNewData);
     429           0 : }
     430             : 
     431           0 : bool SwEditShell::IsAnyDatabaseFieldInDoc()const
     432             : {
     433           0 :     const SwFieldTypes * pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
     434           0 :     for(const auto pFieldType : *pFieldTypes)
     435             :     {
     436           0 :         if(IsUsed(*pFieldType))
     437             :         {
     438           0 :             switch(pFieldType->Which())
     439             :             {
     440             :                 case RES_DBFLD:
     441             :                 case RES_DBNEXTSETFLD:
     442             :                 case RES_DBNUMSETFLD:
     443             :                 case RES_DBSETNUMBERFLD:
     444             :                 {
     445           0 :                     SwIterator<SwFormatField,SwFieldType> aIter( *pFieldType );
     446           0 :                     SwFormatField* pField = aIter.First();
     447           0 :                     while(pField)
     448             :                     {
     449           0 :                         if(pField->IsFieldInDoc())
     450           0 :                             return true;
     451           0 :                         pField = aIter.Next();
     452           0 :                     }
     453             :                 }
     454           0 :                 break;
     455             :             }
     456             :         }
     457             :     }
     458           0 :     return false;
     459         177 : }
     460             : 
     461             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11