diff options
Diffstat (limited to 'sw/source/core/fields')
-rw-r--r-- | sw/source/core/fields/authfld.cxx | 831 | ||||
-rw-r--r-- | sw/source/core/fields/cellfml.cxx | 1232 | ||||
-rw-r--r-- | sw/source/core/fields/chpfld.cxx | 309 | ||||
-rw-r--r-- | sw/source/core/fields/dbfld.cxx | 1076 | ||||
-rw-r--r-- | sw/source/core/fields/ddefld.cxx | 450 | ||||
-rw-r--r-- | sw/source/core/fields/ddetbl.cxx | 187 | ||||
-rw-r--r-- | sw/source/core/fields/docufld.cxx | 2793 | ||||
-rw-r--r-- | sw/source/core/fields/expfld.cxx | 1330 | ||||
-rw-r--r-- | sw/source/core/fields/fldbas.cxx | 814 | ||||
-rw-r--r-- | sw/source/core/fields/flddat.cxx | 321 | ||||
-rw-r--r-- | sw/source/core/fields/flddropdown.cxx | 284 | ||||
-rw-r--r-- | sw/source/core/fields/fldlst.cxx | 233 | ||||
-rw-r--r-- | sw/source/core/fields/macrofld.cxx | 266 | ||||
-rw-r--r-- | sw/source/core/fields/makefile.mk | 94 | ||||
-rw-r--r-- | sw/source/core/fields/postithelper.cxx | 223 | ||||
-rw-r--r-- | sw/source/core/fields/reffld.cxx | 1099 | ||||
-rw-r--r-- | sw/source/core/fields/scrptfld.cxx | 153 | ||||
-rw-r--r-- | sw/source/core/fields/tblcalc.cxx | 264 | ||||
-rwxr-xr-x | sw/source/core/fields/textapi.cxx | 191 | ||||
-rw-r--r-- | sw/source/core/fields/usrfld.cxx | 378 |
20 files changed, 12528 insertions, 0 deletions
diff --git a/sw/source/core/fields/authfld.cxx b/sw/source/core/fields/authfld.cxx new file mode 100644 index 000000000000..630f8dc18e34 --- /dev/null +++ b/sw/source/core/fields/authfld.cxx @@ -0,0 +1,831 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + + +#define _SVSTDARR_STRINGSDTOR +#define _SVSTDARR_USHORTS +#define _SVSTDARR_LONGS +#define _SVSTDARR_ULONGS +#include <hintids.hxx> + +#include <svl/svstdarr.hxx> +#include <editeng/unolingu.hxx> +#include <editeng/langitem.hxx> +#include <swtypes.hxx> +#include <tools/resid.hxx> +#ifndef _COMCORE_HRC +#include <comcore.hrc> +#endif +#include <authfld.hxx> +#include <expfld.hxx> +#include <pam.hxx> +#include <cntfrm.hxx> +#include <tox.hxx> +#include <txmsrt.hxx> +#include <doctxm.hxx> +#include <fmtfld.hxx> +#include <txtfld.hxx> +#include <ndtxt.hxx> +#include <doc.hxx> +#ifndef _UNOFLDMID_H +#include <unofldmid.h> +#endif +#include <unoprnms.hxx> + +#include <unomid.h> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using rtl::OUString; + + +typedef SwAuthEntry* SwAuthEntryPtr; +SV_DECL_PTRARR_DEL( SwAuthDataArr, SwAuthEntryPtr, 5, 5 ) +SV_IMPL_PTRARR( SwAuthDataArr, SwAuthEntryPtr ) + + +typedef SwTOXSortKey* TOXSortKeyPtr; +SV_DECL_PTRARR_DEL( SortKeyArr, TOXSortKeyPtr, 5, 5 ) +SV_IMPL_PTRARR( SortKeyArr, TOXSortKeyPtr ) + + +/* -----------------16.09.99 11:53------------------- + + --------------------------------------------------*/ +SwAuthEntry::SwAuthEntry(const SwAuthEntry& rCopy) + : nRefCount(0) +{ + for(USHORT i = 0; i < AUTH_FIELD_END; i++) + aAuthFields[i] = rCopy.aAuthFields[i]; +} +// -------------------------------------------------------- +BOOL SwAuthEntry::operator==(const SwAuthEntry& rComp) +{ + for(USHORT i = 0; i < AUTH_FIELD_END; i++) + if(aAuthFields[i] != rComp.aAuthFields[i]) + return FALSE; + return TRUE; +} +// -------------------------------------------------------- + +/* -----------------14.09.99 16:15------------------- + + --------------------------------------------------*/ +SwAuthorityFieldType::SwAuthorityFieldType(SwDoc* pDoc) + : SwFieldType( RES_AUTHORITY ), + m_pDoc(pDoc), + m_pDataArr(new SwAuthDataArr ), + m_pSequArr(new SvLongs(5, 5)), + m_pSortKeyArr(new SortKeyArr(3, 3)), + m_cPrefix('['), + m_cSuffix(']'), + m_bIsSequence(FALSE), + m_bSortByDocument(TRUE), + m_eLanguage((LanguageType)::GetAppLanguage()) +{ +} + +SwAuthorityFieldType::SwAuthorityFieldType( const SwAuthorityFieldType& rFType) + : SwFieldType( RES_AUTHORITY ), + m_pDataArr(new SwAuthDataArr ), + m_pSequArr(new SvLongs(5, 5)), + m_pSortKeyArr(new SortKeyArr(3, 3)), + m_cPrefix(rFType.m_cPrefix), + m_cSuffix(rFType.m_cSuffix), + m_bIsSequence(rFType.m_bIsSequence), + m_bSortByDocument(rFType.m_bSortByDocument), + m_eLanguage(rFType.m_eLanguage), + m_sSortAlgorithm(rFType.m_sSortAlgorithm) +{ + for(USHORT i = 0; i < rFType.m_pSortKeyArr->Count(); i++) + m_pSortKeyArr->Insert((*rFType.m_pSortKeyArr)[i], i); +} + +/* -----------------17.09.99 13:52------------------- + + --------------------------------------------------*/ +SwAuthorityFieldType::~SwAuthorityFieldType() +{ +// DBG_ASSERT(!m_pDataArr->Count(), "Array is not empty"); + m_pSortKeyArr->DeleteAndDestroy(0, m_pSortKeyArr->Count()); + delete m_pSortKeyArr; + delete m_pSequArr; + delete m_pDataArr; +} +/*-- 14.09.99 16:22:09--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SwFieldType* SwAuthorityFieldType::Copy() const +{ + return new SwAuthorityFieldType(m_pDoc); +} +/* -----------------17.09.99 13:43------------------- + + --------------------------------------------------*/ +void SwAuthorityFieldType::RemoveField(long nHandle) +{ +#ifdef DBG_UTIL + BOOL bRemoved = FALSE; +#endif + for(USHORT j = 0; j < m_pDataArr->Count(); j++) + { + SwAuthEntry* pTemp = m_pDataArr->GetObject(j); + long nRet = (long)(void*)pTemp; + if(nRet == nHandle) + { +#ifdef DBG_UTIL + bRemoved = TRUE; +#endif + pTemp->RemoveRef(); + if(!pTemp->GetRefCount()) + { + m_pDataArr->DeleteAndDestroy(j, 1); + //re-generate positions of the fields + DelSequenceArray(); + } + break; + } + } +#ifdef DBG_UTIL + DBG_ASSERT(bRemoved, "Field unknown" ); +#endif +} +/* -----------------17.09.99 13:43------------------- + + --------------------------------------------------*/ +long SwAuthorityFieldType::AddField(const String& rFieldContents) +{ + long nRet = 0; + SwAuthEntry* pEntry = new SwAuthEntry; + for( USHORT i = 0; i < AUTH_FIELD_END; ++i ) + pEntry->SetAuthorField( (ToxAuthorityField)i, + rFieldContents.GetToken( i, TOX_STYLE_DELIMITER )); + + for(USHORT j = 0; j < m_pDataArr->Count() && pEntry; j++) + { + SwAuthEntry* pTemp = m_pDataArr->GetObject(j); + if(*pTemp == *pEntry) + { + DELETEZ(pEntry); + nRet = (long)(void*)pTemp; + pTemp->AddRef(); + } + } + //if it is a new Entry - insert + if(pEntry) + { + nRet = (long)(void*)pEntry; + pEntry->AddRef(); + m_pDataArr->Insert(pEntry, m_pDataArr->Count()); + //re-generate positions of the fields + DelSequenceArray(); + } + return nRet; +} +/* -----------------17.09.99 14:18------------------- + + --------------------------------------------------*/ +BOOL SwAuthorityFieldType::AddField(long nHandle) +{ + BOOL bRet = FALSE; + for( USHORT j = 0; j < m_pDataArr->Count(); j++ ) + { + SwAuthEntry* pTemp = m_pDataArr->GetObject(j); + long nTmp = (long)(void*)pTemp; + if( nTmp == nHandle ) + { + bRet = TRUE; + pTemp->AddRef(); + //re-generate positions of the fields + DelSequenceArray(); + break; + } + } + DBG_ASSERT(bRet, "::AddField(long) failed"); + return bRet; +} +/* -----------------17.09.99 14:52------------------- + + --------------------------------------------------*/ +const SwAuthEntry* SwAuthorityFieldType::GetEntryByHandle(long nHandle) const +{ + const SwAuthEntry* pRet = 0; + for(USHORT j = 0; j < m_pDataArr->Count(); j++) + { + const SwAuthEntry* pTemp = m_pDataArr->GetObject(j); + long nTmp = (long)(void*)pTemp; + if( nTmp == nHandle ) + { + pRet = pTemp; + break; + } + } + ASSERT( pRet, "invalid Handle" ); + return pRet; +} +/* -----------------21.09.99 13:34------------------- + + --------------------------------------------------*/ +void SwAuthorityFieldType::GetAllEntryIdentifiers( + SvStringsDtor& rToFill )const +{ + for(USHORT j = 0; j < m_pDataArr->Count(); j++) + { + SwAuthEntry* pTemp = m_pDataArr->GetObject(j); + rToFill.Insert( new String( pTemp->GetAuthorField( + AUTH_FIELD_IDENTIFIER )), rToFill.Count() ); + } +} +/* -----------------21.09.99 13:34------------------- + + --------------------------------------------------*/ +const SwAuthEntry* SwAuthorityFieldType::GetEntryByIdentifier( + const String& rIdentifier)const +{ + const SwAuthEntry* pRet = 0; + for( USHORT j = 0; j < m_pDataArr->Count(); ++j ) + { + const SwAuthEntry* pTemp = m_pDataArr->GetObject(j); + if( rIdentifier == pTemp->GetAuthorField( AUTH_FIELD_IDENTIFIER )) + { + pRet = pTemp; + break; + } + } + return pRet; +} +/* -----------------------------21.12.99 13:20-------------------------------- + + ---------------------------------------------------------------------------*/ +bool SwAuthorityFieldType::ChangeEntryContent(const SwAuthEntry* pNewEntry) +{ + bool bChanged = false; + for( USHORT j = 0; j < m_pDataArr->Count(); ++j ) + { + SwAuthEntry* pTemp = m_pDataArr->GetObject(j); + if(pTemp->GetAuthorField(AUTH_FIELD_IDENTIFIER) == + pNewEntry->GetAuthorField(AUTH_FIELD_IDENTIFIER)) + { + for(USHORT i = 0; i < AUTH_FIELD_END; i++) + pTemp->SetAuthorField((ToxAuthorityField) i, + pNewEntry->GetAuthorField((ToxAuthorityField)i)); + bChanged = true; + break; + } + } + return bChanged; +} +/*-- 11.10.99 08:49:22--------------------------------------------------- + Description: appends a new entry (if new) and returns the array position + + -----------------------------------------------------------------------*/ +USHORT SwAuthorityFieldType::AppendField( const SwAuthEntry& rInsert ) +{ + USHORT nRet = 0; + for( nRet = 0; nRet < m_pDataArr->Count(); ++nRet ) + { + SwAuthEntry* pTemp = m_pDataArr->GetObject( nRet ); + if( *pTemp == rInsert ) + { + break; + //ref count unchanged + } + } + + //if it is a new Entry - insert + if( nRet == m_pDataArr->Count() ) + m_pDataArr->Insert( new SwAuthEntry( rInsert ), nRet ); + + return nRet; +} + +/*-- 11.10.99 08:49:24--------------------------------------------------- + + -----------------------------------------------------------------------*/ +long SwAuthorityFieldType::GetHandle(USHORT nPos) +{ + long nRet = 0; + if( nPos < m_pDataArr->Count() ) + { + SwAuthEntry* pTemp = m_pDataArr->GetObject(nPos); + nRet = (long)(void*)pTemp; + } + return nRet; +} +/* -----------------19.10.99 13:46------------------- + + --------------------------------------------------*/ +USHORT SwAuthorityFieldType::GetSequencePos(long nHandle) +{ + //find the field in a sorted array of handles, +#ifdef DBG_UTIL + sal_Bool bCurrentFieldWithoutTextNode = sal_False; +#endif + if(m_pSequArr->Count() && m_pSequArr->Count() != m_pDataArr->Count()) + DelSequenceArray(); + if(!m_pSequArr->Count()) + { + SwTOXSortTabBases aSortArr; + SwClientIter aIter( *this ); + + SwTOXInternational aIntl(m_eLanguage, 0, m_sSortAlgorithm); + + for( SwFmtFld* pFmtFld = (SwFmtFld*)aIter.First( TYPE(SwFmtFld) ); + pFmtFld; pFmtFld = (SwFmtFld*)aIter.Next() ) + { + const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld(); + if(!pTxtFld || !pTxtFld->GetpTxtNode()) + { +#ifdef DBG_UTIL + if(nHandle == ((SwAuthorityField*)pFmtFld->GetFld())->GetHandle()) + bCurrentFieldWithoutTextNode = sal_True; +#endif + continue; + } + const SwTxtNode& rFldTxtNode = pTxtFld->GetTxtNode(); + SwPosition aFldPos(rFldTxtNode); + SwDoc& rDoc = *(SwDoc*)rFldTxtNode.GetDoc(); + SwCntntFrm *pFrm = rFldTxtNode.GetFrm(); + const SwTxtNode* pTxtNode = 0; + if(pFrm && !pFrm->IsInDocBody()) + pTxtNode = GetBodyTxtNode( rDoc, aFldPos, *pFrm ); + //if no text node could be found or the field is in the document + //body the directly available text node will be used + if(!pTxtNode) + pTxtNode = &rFldTxtNode; + if( pTxtNode->GetTxt().Len() && pTxtNode->GetFrm() && + pTxtNode->GetNodes().IsDocNodes() ) + { + SwTOXAuthority* pNew = new SwTOXAuthority( *pTxtNode, + *pFmtFld, aIntl ); + + for(short i = 0; i < aSortArr.Count(); ++i) + { + SwTOXSortTabBase* pOld = aSortArr[i]; + if(*pOld == *pNew) + { + //only the first occurence in the document + //has to be in the array + if(*pOld < *pNew) + DELETEZ(pNew); + else // remove the old content + aSortArr.DeleteAndDestroy( i, 1 ); + break; + } + } + //if it still exists - insert at the correct position + if(pNew) + { + short j; + + for( j = 0; j < aSortArr.Count(); ++j) + { + SwTOXSortTabBase* pOld = aSortArr[j]; + if(*pNew < *pOld) + break; + } + aSortArr.Insert(pNew, j ); + } + } + } + + for(USHORT i = 0; i < aSortArr.Count(); i++) + { + const SwTOXSortTabBase& rBase = *aSortArr[i]; + SwFmtFld& rFmtFld = ((SwTOXAuthority&)rBase).GetFldFmt(); + SwAuthorityField* pAFld = (SwAuthorityField*)rFmtFld.GetFld(); + m_pSequArr->Insert(pAFld->GetHandle(), i); + } + aSortArr.DeleteAndDestroy(0, aSortArr.Count()); + } + //find nHandle + USHORT nRet = 0; + for(USHORT i = 0; i < m_pSequArr->Count(); i++) + { + if((*m_pSequArr)[i] == nHandle) + { + nRet = i + 1; + break; + } + } + ASSERT(bCurrentFieldWithoutTextNode || nRet, "Handle not found") + return nRet; +} +/* -----------------------------15.11.00 17:33-------------------------------- + + ---------------------------------------------------------------------------*/ +BOOL SwAuthorityFieldType::QueryValue( Any& rVal, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + case FIELD_PROP_PAR2: + { + OUString sVal; + sal_Unicode uRet = FIELD_PROP_PAR1 == nWhichId ? m_cPrefix : m_cSuffix; + if(uRet) + sVal = OUString(uRet); + rVal <<= sVal; + } + break; + case FIELD_PROP_PAR3: + rVal <<= OUString(GetSortAlgorithm()); + break; + + case FIELD_PROP_BOOL1: + case FIELD_PROP_BOOL2: + { + sal_Bool bVal = FIELD_PROP_BOOL1 == nWhichId ? m_bIsSequence: m_bSortByDocument; + rVal.setValue(&bVal, ::getBooleanCppuType()); + } + break; + + case FIELD_PROP_LOCALE: + rVal <<= SvxCreateLocale(GetLanguage()); + break; + + case FIELD_PROP_PROP_SEQ: + { + Sequence<PropertyValues> aRet(m_pSortKeyArr->Count()); + PropertyValues* pValues = aRet.getArray(); + OUString sProp1( C2U(SW_PROP_NAME_STR(UNO_NAME_SORT_KEY)) ), + sProp2( C2U(SW_PROP_NAME_STR(UNO_NAME_IS_SORT_ASCENDING))); + for(sal_uInt16 i = 0; i < m_pSortKeyArr->Count(); i++) + { + const SwTOXSortKey* pKey = (*m_pSortKeyArr)[i]; + pValues[i].realloc(2); + PropertyValue* pValue = pValues[i].getArray(); + pValue[0].Name = sProp1; + pValue[0].Value <<= sal_Int16(pKey->eField); + pValue[1].Name = sProp2; + pValue[1].Value.setValue(&pKey->bSortAscending, ::getBooleanCppuType()); + } + rVal <<= aRet; + } + break; + default: + DBG_ERROR("illegal property"); + } + return TRUE; +} +/* -----------------------------15.11.00 17:33-------------------------------- + + ---------------------------------------------------------------------------*/ +BOOL SwAuthorityFieldType::PutValue( const Any& rAny, USHORT nWhichId ) +{ + sal_Bool bRet = TRUE; + String sTmp; + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + case FIELD_PROP_PAR2: + { + ::GetString( rAny, sTmp ); + sal_Unicode uSet = sTmp.GetChar(0); + if( FIELD_PROP_PAR1 == nWhichId ) + m_cPrefix = uSet; + else + m_cSuffix = uSet; + } + break; + case FIELD_PROP_PAR3: + SetSortAlgorithm( ::GetString( rAny, sTmp )); + break; + + case FIELD_PROP_BOOL1: + m_bIsSequence = *(sal_Bool*)rAny.getValue(); + break; + case FIELD_PROP_BOOL2: + m_bSortByDocument = *(sal_Bool*)rAny.getValue(); + break; + + case FIELD_PROP_LOCALE: + { + Locale aLocale; + if( 0 != (bRet = rAny >>= aLocale )) + SetLanguage( SvxLocaleToLanguage( aLocale )); + } + break; + + case FIELD_PROP_PROP_SEQ: + { + Sequence<PropertyValues> aSeq; + if( 0 != (bRet = rAny >>= aSeq) ) + { + m_pSortKeyArr->DeleteAndDestroy(0, m_pSortKeyArr->Count()); + const PropertyValues* pValues = aSeq.getConstArray(); + for(sal_Int32 i = 0; i < aSeq.getLength() && i < USHRT_MAX / 4; i++) + { + const PropertyValue* pValue = pValues[i].getConstArray(); + SwTOXSortKey* pSortKey = new SwTOXSortKey; + for(sal_Int32 j = 0; j < pValues[i].getLength(); j++) + { + if(pValue[j].Name.equalsAsciiL(SW_PROP_NAME(UNO_NAME_SORT_KEY))) + { + sal_Int16 nVal = -1; pValue[j].Value >>= nVal; + if(nVal >= 0 && nVal < AUTH_FIELD_END) + pSortKey->eField = (ToxAuthorityField) nVal; + else + bRet = FALSE; + } + else if(pValue[j].Name.equalsAsciiL(SW_PROP_NAME(UNO_NAME_IS_SORT_ASCENDING))) + { + pSortKey->bSortAscending = *(sal_Bool*)pValue[j].Value.getValue(); + } + } + m_pSortKeyArr->Insert(pSortKey, m_pSortKeyArr->Count()); + } + } + } + break; + default: + DBG_ERROR("illegal property"); + } + return bRet; +} +/* -----------------19.10.99 13:25------------------- + + --------------------------------------------------*/ +void SwAuthorityFieldType::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew ) +{ + //re-generate positions of the fields + DelSequenceArray(); + SwModify::Modify( pOld, pNew ); +} +/* -----------------20.10.99 13:38------------------- + + --------------------------------------------------*/ +USHORT SwAuthorityFieldType::GetSortKeyCount() const +{ + return m_pSortKeyArr->Count(); +} +/* -----------------20.10.99 13:38------------------- + + --------------------------------------------------*/ +const SwTOXSortKey* SwAuthorityFieldType::GetSortKey(USHORT nIdx) const +{ + SwTOXSortKey* pRet = 0; + if(m_pSortKeyArr->Count() > nIdx) + pRet = (*m_pSortKeyArr)[nIdx]; + DBG_ASSERT(pRet, "Sort key not found"); + return pRet; +} +/* -----------------20.10.99 13:38------------------- + + --------------------------------------------------*/ +void SwAuthorityFieldType::SetSortKeys(USHORT nKeyCount, SwTOXSortKey aKeys[]) +{ + m_pSortKeyArr->DeleteAndDestroy(0, m_pSortKeyArr->Count()); + USHORT nArrIdx = 0; + for(USHORT i = 0; i < nKeyCount; i++) + if(aKeys[i].eField < AUTH_FIELD_END) + m_pSortKeyArr->Insert(new SwTOXSortKey(aKeys[i]), nArrIdx++); +} + +/* -----------------14.09.99 16:15------------------- + + --------------------------------------------------*/ +SwAuthorityField::SwAuthorityField( SwAuthorityFieldType* pInitType, + const String& rFieldContents ) + : SwField(pInitType), + m_nTempSequencePos( -1 ) +{ + m_nHandle = pInitType->AddField( rFieldContents ); +} +/* -----------------17.09.99 14:24------------------- + + --------------------------------------------------*/ +SwAuthorityField::SwAuthorityField( SwAuthorityFieldType* pInitType, + long nSetHandle ) + : SwField( pInitType ), + m_nHandle( nSetHandle ), + m_nTempSequencePos( -1 ) +{ + pInitType->AddField( m_nHandle ); +} +/* -----------------15.09.99 15:00------------------- + + --------------------------------------------------*/ +SwAuthorityField::~SwAuthorityField() +{ + ((SwAuthorityFieldType* )GetTyp())->RemoveField(m_nHandle); +} +/*-- 14.09.99 16:20:59--------------------------------------------------- + + -----------------------------------------------------------------------*/ +String SwAuthorityField::Expand() const +{ + SwAuthorityFieldType* pAuthType = (SwAuthorityFieldType*)GetTyp(); + String sRet; + if(pAuthType->GetPrefix()) + sRet.Assign(pAuthType->GetPrefix()); + + if( pAuthType->IsSequence() ) + { + if(!pAuthType->GetDoc()->IsExpFldsLocked()) + m_nTempSequencePos = pAuthType->GetSequencePos( m_nHandle ); + if( m_nTempSequencePos >= 0 ) + sRet += String::CreateFromInt32( m_nTempSequencePos ); + } + else + { + const SwAuthEntry* pEntry = pAuthType->GetEntryByHandle(m_nHandle); + //TODO: Expand to: identifier, number sequence, ... + if(pEntry) + sRet += pEntry->GetAuthorField(AUTH_FIELD_IDENTIFIER); + } + if(pAuthType->GetSuffix()) + sRet += pAuthType->GetSuffix(); + return sRet; +} +/*-- 14.09.99 16:21:00--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SwField* SwAuthorityField::Copy() const +{ + SwAuthorityFieldType* pAuthType = (SwAuthorityFieldType*)GetTyp(); + return new SwAuthorityField(pAuthType, m_nHandle); +} +/* -----------------21.09.99 12:55------------------- + + --------------------------------------------------*/ +const String& SwAuthorityField::GetFieldText(ToxAuthorityField eField) const +{ + SwAuthorityFieldType* pAuthType = (SwAuthorityFieldType*)GetTyp(); + const SwAuthEntry* pEntry = pAuthType->GetEntryByHandle( m_nHandle ); + return pEntry->GetAuthorField( eField ); +} +/* -----------------21.09.99 14:57------------------- + + --------------------------------------------------*/ +void SwAuthorityField::SetPar1(const String& rStr) +{ + SwAuthorityFieldType* pInitType = (SwAuthorityFieldType* )GetTyp(); + pInitType->RemoveField(m_nHandle); + m_nHandle = pInitType->AddField(rStr); +} +/* -----------------11.10.99 09:43------------------- + + --------------------------------------------------*/ +String SwAuthorityField::GetDescription() const +{ + return SW_RES(STR_AUTHORITY_ENTRY); +} + + + +/* -----------------------------15.11.00 17:33-------------------------------- + + ---------------------------------------------------------------------------*/ +const char* aFieldNames[] = +{ + "Identifier", + "BibiliographicType", + "Address", + "Annote", + "Author", + "Booktitle", + "Chapter", + "Edition", + "Editor", + "Howpublished", + "Institution", + "Journal", + "Month", + "Note", + "Number", + "Organizations", + "Pages", + "Publisher", + "School", + "Series", + "Title", + "Report_Type", + "Volume", + "Year", + "URL", + "Custom1", + "Custom2", + "Custom3", + "Custom4", + "Custom5", + "ISBN" +}; +/* -----------------------------16.11.00 12:27-------------------------------- + + ---------------------------------------------------------------------------*/ +BOOL SwAuthorityField::QueryValue( Any& rAny, USHORT /*nWhichId*/ ) const +{ + if(!GetTyp()) + return FALSE; + const SwAuthEntry* pAuthEntry = ((SwAuthorityFieldType*)GetTyp())->GetEntryByHandle(m_nHandle); + if(!pAuthEntry) + return FALSE; + Sequence <PropertyValue> aRet(AUTH_FIELD_END); + PropertyValue* pValues = aRet.getArray(); + for(sal_Int16 i = 0; i < AUTH_FIELD_END; i++) + { + pValues[i].Name = C2U(aFieldNames[i]); + const String& rField = pAuthEntry->GetAuthorField((ToxAuthorityField) i); + if(i == AUTH_FIELD_AUTHORITY_TYPE) + pValues[i].Value <<= sal_Int16(rField.ToInt32()); + else + pValues[i].Value <<= OUString(rField); + } + rAny <<= aRet; + return FALSE; +} +/* -----------------------------15.11.00 17:33-------------------------------- + + ---------------------------------------------------------------------------*/ +sal_Int16 lcl_Find(const OUString& rFieldName) +{ + for(sal_Int16 i = 0; i < AUTH_FIELD_END; i++) + if(!rFieldName.compareToAscii(aFieldNames[i])) + return i; + return -1; +} +//---------------------------------------------------------------------------- +BOOL SwAuthorityField::PutValue( const Any& rAny, USHORT /*nWhichId*/ ) +{ + if(!GetTyp() || !((SwAuthorityFieldType*)GetTyp())->GetEntryByHandle(m_nHandle)) + return FALSE; + + Sequence <PropertyValue> aParam; + if(!(rAny >>= aParam)) + return FALSE; + + String sToSet; + sToSet.Fill(AUTH_FIELD_ISBN, TOX_STYLE_DELIMITER); + const PropertyValue* pParam = aParam.getConstArray(); + for(sal_Int32 i = 0; i < aParam.getLength(); i++) + { + sal_Int16 nFound = lcl_Find(pParam[i].Name); + if(nFound >= 0) + { + OUString sContent; + if(AUTH_FIELD_AUTHORITY_TYPE == nFound) + { + sal_Int16 nVal = 0; + pParam[i].Value >>= nVal; + sContent = OUString::valueOf((sal_Int32)nVal); + } + else + pParam[i].Value >>= sContent; + sToSet.SetToken(nFound, TOX_STYLE_DELIMITER, sContent); + } + } + + ((SwAuthorityFieldType*)GetTyp())->RemoveField(m_nHandle); + m_nHandle = ((SwAuthorityFieldType*)GetTyp())->AddField(sToSet); + + return FALSE; +} +/* -----------------11.10.99 09:43------------------- + + --------------------------------------------------*/ +SwFieldType* SwAuthorityField::ChgTyp( SwFieldType* pFldTyp ) +{ + SwAuthorityFieldType* pSrcTyp = (SwAuthorityFieldType*)GetTyp(), + * pDstTyp = (SwAuthorityFieldType*)pFldTyp; + if( pSrcTyp != pDstTyp ) + { + + const SwAuthEntry* pEntry = pSrcTyp->GetEntryByHandle( m_nHandle ); + USHORT nHdlPos = pDstTyp->AppendField( *pEntry ); + pSrcTyp->RemoveField( m_nHandle ); + m_nHandle = pDstTyp->GetHandle( nHdlPos ); + pDstTyp->AddField( m_nHandle ); + SwField::ChgTyp( pFldTyp ); + } + return pSrcTyp; +} + diff --git a/sw/source/core/fields/cellfml.cxx b/sw/source/core/fields/cellfml.cxx new file mode 100644 index 000000000000..182ed12d6ddd --- /dev/null +++ b/sw/source/core/fields/cellfml.cxx @@ -0,0 +1,1232 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + + +#include <float.h> +#include <hintids.hxx> +#include <hints.hxx> +#include <fmtfld.hxx> +#include <txtfld.hxx> +#include <frmfmt.hxx> +#include <layfrm.hxx> +#include <cntfrm.hxx> +#include <tabfrm.hxx> +#include <doc.hxx> +#include <docary.hxx> +#include <ndtxt.hxx> +#include <swtable.hxx> +#include <tblsel.hxx> +#include <cellfml.hxx> +#include <calc.hxx> +#include <expfld.hxx> +#include <usrfld.hxx> +#include <flddat.hxx> +#include <cellatr.hxx> +#include <ndindex.hxx> + +const sal_Unicode cRelTrenner = ','; +const sal_Unicode cRelKennung = ''; // CTRL-R + +const USHORT cMAXSTACKSIZE = 50; + +const SwFrm* lcl_GetBoxFrm( const SwTableBox& rBox ); +long lcl_GetLongBoxNum( String& rStr ); +const SwTableBox* lcl_RelToBox( const SwTable&, const SwTableBox*, const String& ); +String lcl_BoxNmToRel( const SwTable&, const SwTableNode&, + const String& , const String& , BOOL ); + + +/************************************************************************* +|* +|* double SwTableBox::GetValue() const +|* gebe den Wert dieser Box zurueck. Der Wert ergibt sich aus dem 1. +|* TextNode. Beginnt dieser mit einer Zahl/Formel, so berechne diese; +|* oder mit einem Feld, dann hole den Wert. +|* Alle anderen Bedingungen returnen einen Fehler (oder 0 ?) +|* +|* Ersterstellung JP 30. Jun. 93 +|* Letzte Aenderung JP 30. Jun. 93 +|* +|*************************************************************************/ + +double SwTableBox::GetValue( SwTblCalcPara& rCalcPara ) const +{ + double nRet = 0; + + if( rCalcPara.rCalc.IsCalcError() ) + return nRet; // schon ein Fehler in der Berechnung + + rCalcPara.rCalc.SetCalcError( CALC_SYNTAX ); // default immer Fehler + + // keine Content Box ? + if( !pSttNd ) + return nRet; + + if( rCalcPara.IncStackCnt() ) + return nRet; + + rCalcPara.SetLastTblBox( this ); + + // wird eine Rekursion erzeugt ? + SwTableBox* pBox = (SwTableBox*)this; + if( rCalcPara.pBoxStk->Seek_Entry( pBox )) + return nRet; // steht schon auf dem Stack: FEHLER + + // bei dieser Box nochmal aufsetzen + rCalcPara.SetLastTblBox( this ); + + rCalcPara.pBoxStk->Insert( pBox ); // eintragen + do { // Middle-Check-Loop, damit aus dieser gesprungen werden kann + // hier aufgespannt, damit am Ende der Box-Pointer aus dem + // Stack ausgetragen wird + SwDoc* pDoc = GetFrmFmt()->GetDoc(); + + const SfxPoolItem* pItem; + if( SFX_ITEM_SET == GetFrmFmt()->GetItemState( + RES_BOXATR_FORMULA, FALSE, &pItem ) ) + { + rCalcPara.rCalc.SetCalcError( CALC_NOERR ); // wieder zuruecksetzen + if( !((SwTblBoxFormula*)pItem)->IsValid() ) + { + // dann berechnen + const SwTable* pTmp = rCalcPara.pTbl; + rCalcPara.pTbl = &pBox->GetSttNd()->FindTableNode()->GetTable(); + ((SwTblBoxFormula*)pItem)->Calc( rCalcPara, nRet ); + + if( !rCalcPara.IsStackOverFlow() ) + { + SwFrmFmt* pFmt = pBox->ClaimFrmFmt(); + SfxItemSet aTmp( pDoc->GetAttrPool(), + RES_BOXATR_BEGIN,RES_BOXATR_END-1 ); + aTmp.Put( SwTblBoxValue( nRet ) ); + if( SFX_ITEM_SET != pFmt->GetItemState( RES_BOXATR_FORMAT )) + aTmp.Put( SwTblBoxNumFormat( 0 )); + pFmt->SetFmtAttr( aTmp ); + } + rCalcPara.pTbl = pTmp; + } + else + nRet = GetFrmFmt()->GetTblBoxValue().GetValue(); + break; + } + else if( SFX_ITEM_SET == pBox->GetFrmFmt()->GetItemState( + RES_BOXATR_VALUE, FALSE, &pItem ) ) + { + rCalcPara.rCalc.SetCalcError( CALC_NOERR ); // wieder zuruecksetzen + nRet = ((SwTblBoxValue*)pItem)->GetValue(); + break; + } + + SwTxtNode* pTxtNd = pDoc->GetNodes()[ pSttNd->GetIndex() + 1 ]->GetTxtNode(); + if( !pTxtNd ) + break; + + xub_StrLen nSttPos = 0; + const String& rTxt = pTxtNd->GetTxt(); + while( nSttPos < rTxt.Len() && + ( ' ' == rTxt.GetChar( nSttPos ) || '\t' == rTxt.GetChar( nSttPos ) ) ) + ++nSttPos; + + // beginnt an erster Position ein "RechenFeld", dann erfrage den Wert + // von diesem + sal_Unicode const Char = rTxt.GetChar(nSttPos); + if ( nSttPos < rTxt.Len() && + ( CH_TXTATR_BREAKWORD == Char || CH_TXTATR_INWORD == Char ) ) + { + SwIndex aIdx( pTxtNd, nSttPos ); + SwTxtFld * const pTxtFld = static_cast<SwTxtFld*>( + pTxtNd->GetTxtAttrForCharAt(aIdx.GetIndex(), RES_TXTATR_FIELD)); + if( !pTxtFld ) + break; + + rCalcPara.rCalc.SetCalcError( CALC_NOERR ); // wieder zuruecksetzen + + const SwField* pFld = pTxtFld->GetFld().GetFld(); + switch( pFld->GetTyp()->Which() ) + { + case RES_SETEXPFLD: + nRet = ((SwSetExpField*)pFld)->GetValue(); + break; + case RES_USERFLD: + nRet = ((SwUserFieldType*)pFld)->GetValue(); + break; + case RES_TABLEFLD: + { + SwTblField* pTblFld = (SwTblField*)pFld; + if( !pTblFld->IsValid() ) // ist der Wert gueltig ?? + { + // die richtige Tabelle mitgeben! + const SwTable* pTmp = rCalcPara.pTbl; + rCalcPara.pTbl = &pTxtNd->FindTableNode()->GetTable(); + pTblFld->CalcField( rCalcPara ); + rCalcPara.pTbl = pTmp; + } + nRet = pTblFld->GetValue(); + } + break; + + case RES_DATETIMEFLD: + nRet = ((SwDateTimeField*)pFld)->GetValue(); + break; + + case RES_JUMPEDITFLD: + //JP 14.09.98: Bug 56112 - der Platzhalter kann nie einen + // gueltigen Inhalt haben! + nRet = 0; + break; + + default: + String const value(pFld->ExpandField(pDoc->IsClipBoard())); + nRet = rCalcPara.rCalc.Calculate(value).GetDouble(); + } + } + else + { + // Ergebnis ist 0 und kein Fehler! + rCalcPara.rCalc.SetCalcError( CALC_NOERR ); // wieder zuruecksetzen + + double aNum; + String sTxt( rTxt.Copy( nSttPos ) ); + sal_uInt32 nFmtIndex = GetFrmFmt()->GetTblBoxNumFmt().GetValue(); + + SvNumberFormatter* pNumFmtr = pDoc->GetNumberFormatter(); + + if( NUMBERFORMAT_TEXT == nFmtIndex ) + nFmtIndex = 0; + // JP 22.04.98: Bug 49659 - Sonderbehandlung fuer Prozent + else if( sTxt.Len() && + NUMBERFORMAT_PERCENT == pNumFmtr->GetType( nFmtIndex )) + { + sal_uInt32 nTmpFmt = 0; + if( pNumFmtr->IsNumberFormat( sTxt, nTmpFmt, aNum ) && + NUMBERFORMAT_NUMBER == pNumFmtr->GetType( nTmpFmt )) + sTxt += '%'; + } + + if( pNumFmtr->IsNumberFormat( sTxt, nFmtIndex, aNum )) + nRet = aNum; + } + +// ?? sonst ist das ein Fehler + } while( FALSE ); + + if( !rCalcPara.IsStackOverFlow() ) + { + rCalcPara.pBoxStk->Remove( pBox ); // raus aus dem Stack + rCalcPara.DecStackCnt(); + } + + //JP 12.01.99: mit Fehlererkennung, Bug 60794 + if( DBL_MAX == nRet ) + rCalcPara.rCalc.SetCalcError( CALC_SYNTAX ); // Fehler setzen + + return nRet; +} + +/* */ + +// Struktur, die zum TabelleRechnen benoetigt wird + +SwTblCalcPara::SwTblCalcPara( SwCalc& rCalculator, const SwTable& rTable ) + : pLastTblBox( 0 ), nStackCnt( 0 ), nMaxSize( cMAXSTACKSIZE ), + rCalc( rCalculator ), pTbl( &rTable ) +{ + pBoxStk = new SwTableSortBoxes; +} + +SwTblCalcPara::~SwTblCalcPara() +{ + delete pBoxStk; +} + +BOOL SwTblCalcPara::CalcWithStackOverflow() +{ + // falls ein StackUeberlauf erkannt wurde, sollte mit + // der letzten Box noch mal aufgesetzt werden. Irgend + // ein Weg sollte dann + USHORT nSaveMaxSize = nMaxSize; + + nMaxSize = cMAXSTACKSIZE - 5; + USHORT nCnt = 0; + SwTableBoxes aStackOverFlows; + do { + SwTableBox* pBox = (SwTableBox*)pLastTblBox; + nStackCnt = 0; + rCalc.SetCalcError( CALC_NOERR ); + aStackOverFlows.C40_INSERT( SwTableBox, pBox, nCnt++ ); + + pBoxStk->Remove( pBox ); + pBox->GetValue( *this ); + } while( IsStackOverFlow() ); + + nMaxSize = cMAXSTACKSIZE - 3; // es muss mind. 1 Stufe tiefer gehen! + + // falls Rekursionen erkannt wurden + nStackCnt = 0; + rCalc.SetCalcError( CALC_NOERR ); + pBoxStk->Remove( USHORT(0), pBoxStk->Count() ); + + while( !rCalc.IsCalcError() && nCnt ) + { + aStackOverFlows[ --nCnt ]->GetValue( *this ); + if( IsStackOverFlow() && !CalcWithStackOverflow() ) + break; + } + + nMaxSize = nSaveMaxSize; + aStackOverFlows.Remove( 0, aStackOverFlows.Count() ); + return !rCalc.IsCalcError(); +} + +/* */ + +SwTableFormula::SwTableFormula( const String& rFormel ) + : sFormel( rFormel ) +{ + eNmType = EXTRNL_NAME; + bValidValue = FALSE; +} + +SwTableFormula::~SwTableFormula() +{ +} + +void SwTableFormula::_MakeFormel( const SwTable& rTbl, String& rNewStr, + String& rFirstBox, String* pLastBox, void* pPara ) const +{ + SwTblCalcPara* pCalcPara = (SwTblCalcPara*)pPara; + if( pCalcPara->rCalc.IsCalcError() ) // ist schon Fehler gesetzt ? + return; + + SwTableBox* pSttBox, *pEndBox = 0; + + rFirstBox.Erase(0,1); // Kennung fuer Box loeschen + // ein Bereich in dieser Klammer ? + if( pLastBox ) + { + pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64())); + + // ist das ueberhaupt ein gueltiger Pointer ?? + if( !rTbl.GetTabSortBoxes().Seek_Entry( pEndBox )) + pEndBox = 0; + rFirstBox.Erase( 0, pLastBox->Len()+1 ); + } + pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64())); + // ist das ueberhaupt ein gueltiger Pointer ?? + if( !rTbl.GetTabSortBoxes().Seek_Entry( pSttBox )) + pSttBox = 0; + + rNewStr += ' '; + if( pEndBox && pSttBox ) // Bereich ? + { + // hole ueber das Layout alle "selectierten" Boxen und berechne + // deren Werte + SwSelBoxes aBoxes; + GetBoxes( *pSttBox, *pEndBox, aBoxes ); + + rNewStr += '('; + bool bDelim = false; + for( USHORT n = 0; n < aBoxes.Count() && + !pCalcPara->rCalc.IsCalcError(); ++n ) + { + const SwTableBox* pTblBox = aBoxes[n]; + if ( pTblBox->getRowSpan() >= 1 ) + { + if( bDelim ) + rNewStr += cListDelim; + bDelim = true; + rNewStr += pCalcPara->rCalc.GetStrResult( + pTblBox->GetValue( *pCalcPara ), FALSE ); + } + } + rNewStr += ')'; + } + else if( pSttBox && !pLastBox ) // nur die StartBox ? + { + //JP 12.01.99: und keine EndBox in der Formel! + // Berechne den Wert der Box + if ( pSttBox->getRowSpan() >= 1 ) + { + rNewStr += pCalcPara->rCalc.GetStrResult( + pSttBox->GetValue( *pCalcPara ), FALSE ); + } + } + else + pCalcPara->rCalc.SetCalcError( CALC_SYNTAX ); // Fehler setzen + rNewStr += ' '; +} + +void SwTableFormula::RelNmsToBoxNms( const SwTable& rTbl, String& rNewStr, + String& rFirstBox, String* pLastBox, void* pPara ) const +{ + // relativen Namen zu Box-Namen (externe Darstellung) + SwNode* pNd = (SwNode*)pPara; + ASSERT( pNd, "Feld steht in keinem TextNode" ); + const SwTableBox *pRelBox, *pBox = (SwTableBox *)rTbl.GetTblBox( + pNd->FindTableBoxStartNode()->GetIndex() ); + + rNewStr += rFirstBox.Copy(0,1); // Kennung fuer Box erhalten + rFirstBox.Erase(0,1); + if( pLastBox ) + { + if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, *pLastBox )) ) + rNewStr += pRelBox->GetName(); + else + rNewStr.AppendAscii("A1"); + rNewStr += ':'; + rFirstBox.Erase( 0, pLastBox->Len()+1 ); + } + + if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, rFirstBox )) ) + rNewStr += pRelBox->GetName(); + else + rNewStr.AppendAscii("A1"); + + // Kennung fuer Box erhalten + rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 ); +} + +void SwTableFormula::RelBoxNmsToPtr( const SwTable& rTbl, String& rNewStr, + String& rFirstBox, String* pLastBox, void* pPara ) const +{ + // relativen Namen zu Box-Pointern (interne Darstellung) + SwNode* pNd = (SwNode*)pPara; + ASSERT( pNd, "Feld steht in keinem Node" ); + const SwTableBox *pRelBox, *pBox = (SwTableBox*)rTbl.GetTblBox( + pNd->FindTableBoxStartNode()->GetIndex() ); + + rNewStr += rFirstBox.Copy(0,1); // Kennung fuer Box erhalten + rFirstBox.Erase(0,1); + if( pLastBox ) + { + if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, *pLastBox )) ) + rNewStr += String::CreateFromInt64( (sal_PtrDiff)pRelBox ); + else + rNewStr += '0'; + rNewStr += ':'; + rFirstBox.Erase( 0, pLastBox->Len()+1 ); + } + + if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, rFirstBox )) ) + rNewStr += String::CreateFromInt64( (sal_PtrDiff)pRelBox ); + else + rNewStr += '0'; + + // Kennung fuer Box erhalten + rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 ); +} + + +void SwTableFormula::BoxNmsToRelNm( const SwTable& rTbl, String& rNewStr, + String& rFirstBox, String* pLastBox, void* pPara ) const +{ + // Box-Namen (externe Darstellung) zu relativen Namen + SwNode* pNd = (SwNode*)pPara; + ASSERT( pNd, "Feld steht in keinem Node" ); + const SwTableNode* pTblNd = pNd->FindTableNode(); + + String sRefBoxNm; + if( &pTblNd->GetTable() == &rTbl ) + { + const SwTableBox *pBox = rTbl.GetTblBox( + pNd->FindTableBoxStartNode()->GetIndex() ); + ASSERT( pBox, "Feld steht in keiner Tabelle" ); + sRefBoxNm = pBox->GetName(); + } + + rNewStr += rFirstBox.Copy(0,1); // Kennung fuer Box erhalten + rFirstBox.Erase(0,1); + if( pLastBox ) + { + rNewStr += lcl_BoxNmToRel( rTbl, *pTblNd, sRefBoxNm, *pLastBox, + eNmType == EXTRNL_NAME ); + rNewStr += ':'; + rFirstBox.Erase( 0, pLastBox->Len()+1 ); + } + + rNewStr += lcl_BoxNmToRel( rTbl, *pTblNd, sRefBoxNm, rFirstBox, + eNmType == EXTRNL_NAME ); + + // Kennung fuer Box erhalten + rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 ); +} + + +void SwTableFormula::PtrToBoxNms( const SwTable& rTbl, String& rNewStr, + String& rFirstBox, String* pLastBox, void* ) const +{ + // ein Bereich in dieser Klammer ? + SwTableBox* pBox; + + rNewStr += rFirstBox.Copy(0,1); // Kennung fuer Box erhalten + rFirstBox.Erase(0,1); + if( pLastBox ) + { + pBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64())); + + // ist das ueberhaupt ein gueltiger Pointer ?? + if( rTbl.GetTabSortBoxes().Seek_Entry( pBox )) + rNewStr += pBox->GetName(); + else + rNewStr += '?'; + rNewStr += ':'; + rFirstBox.Erase( 0, pLastBox->Len()+1 ); + } + + pBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64())); + // ist das ueberhaupt ein gueltiger Pointer ?? + if( rTbl.GetTabSortBoxes().Seek_Entry( pBox )) + rNewStr += pBox->GetName(); + else + rNewStr += '?'; + + // Kennung fuer Box erhalten + rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 ); +} + +void SwTableFormula::BoxNmsToPtr( const SwTable& rTbl, String& rNewStr, + String& rFirstBox, String* pLastBox, void* ) const +{ + // ein Bereich in dieser Klammer ? + const SwTableBox* pBox; + + rNewStr += rFirstBox.Copy(0,1); // Kennung fuer Box erhalten + rFirstBox.Erase(0,1); + if( pLastBox ) + { + pBox = rTbl.GetTblBox( *pLastBox ); + rNewStr += String::CreateFromInt64( (sal_PtrDiff)pBox ); + rNewStr += ':'; + rFirstBox.Erase( 0, pLastBox->Len()+1 ); + } + + pBox = rTbl.GetTblBox( rFirstBox ); + rNewStr += String::CreateFromInt64( (sal_PtrDiff)pBox ); + + // Kennung fuer Box erhalten + rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 ); +} + + // erzeuge die externe (fuer UI) Formel +void SwTableFormula::PtrToBoxNm( const SwTable* pTbl ) +{ + const SwNode* pNd = 0; + FnScanFormel fnFormel = 0; + switch( eNmType) + { + case INTRNL_NAME: + if( pTbl ) + fnFormel = &SwTableFormula::PtrToBoxNms; + break; + case REL_NAME: + if( pTbl ) + { + fnFormel = &SwTableFormula::RelNmsToBoxNms; + pNd = GetNodeOfFormula(); + } + break; + case EXTRNL_NAME: + return; + } + sFormel = ScanString( fnFormel, *pTbl, (void*)pNd ); + eNmType = EXTRNL_NAME; +} + + // erzeuge die interne (in CORE) Formel +void SwTableFormula::BoxNmToPtr( const SwTable* pTbl ) +{ + const SwNode* pNd = 0; + FnScanFormel fnFormel = 0; + switch( eNmType) + { + case EXTRNL_NAME: + if( pTbl ) + fnFormel = &SwTableFormula::BoxNmsToPtr; + break; + case REL_NAME: + if( pTbl ) + { + fnFormel = &SwTableFormula::RelBoxNmsToPtr; + pNd = GetNodeOfFormula(); + } + break; + case INTRNL_NAME: + return; + } + sFormel = ScanString( fnFormel, *pTbl, (void*)pNd ); + eNmType = INTRNL_NAME; +} + + // erzeuge die relative (fuers Kopieren) Formel +void SwTableFormula::ToRelBoxNm( const SwTable* pTbl ) +{ + const SwNode* pNd = 0; + FnScanFormel fnFormel = 0; + switch( eNmType) + { + case INTRNL_NAME: + case EXTRNL_NAME: + if( pTbl ) + { + fnFormel = &SwTableFormula::BoxNmsToRelNm; + pNd = GetNodeOfFormula(); + } + break; + case REL_NAME: + return; + } + sFormel = ScanString( fnFormel, *pTbl, (void*)pNd ); + eNmType = REL_NAME; +} + + +String SwTableFormula::ScanString( FnScanFormel fnFormel, const SwTable& rTbl, + void* pPara ) const +{ + String aStr; + USHORT nFml = 0, nStt = 0, nEnd = 0, nTrenner; + + do { + // falls der Formel ein Name vorangestellt ist, diese Tabelle + // benutzen !! + const SwTable* pTbl = &rTbl; + + nStt = sFormel.Search( '<', nFml ); + if( STRING_NOTFOUND != nStt ) + { + while( STRING_NOTFOUND != nStt && + ( ' ' == sFormel.GetChar( nStt + 1 ) || + '=' == sFormel.GetChar( nStt + 1 ) ) ) + nStt = sFormel.Search( '<', nStt + 1 ); + + if( STRING_NOTFOUND != nStt ) + nEnd = sFormel.Search( '>', nStt+1 ); + } + if( STRING_NOTFOUND == nStt || STRING_NOTFOUND == nEnd ) + { + // den Rest setzen und beenden + aStr.Insert( sFormel, nFml, sFormel.Len() - nFml ); + break; + } + aStr.Insert( sFormel, nFml, nStt - nFml ); // Anfang schreiben + + if( fnFormel != NULL ) + { + // ist ein TabellenName vorangestellt ?? + // JP 16.02.99: SplitMergeBoxNm behandeln den Namen selbst + // JP 22.02.99: der CAST muss fuer den Linux-Compiler sein + // JP 28.06.99: rel. BoxName have no preceding tablename! + if( fnFormel != (FnScanFormel)&SwTableFormula::_SplitMergeBoxNm && + 1 < sFormel.Len() && cRelKennung != sFormel.GetChar( 1 ) && + STRING_NOTFOUND != ( nTrenner = sFormel.Search( '.', nStt )) + && nTrenner < nEnd ) + { + String sTblNm( sFormel.Copy( nStt, nEnd - nStt )); + + // falls im Namen schon die Punkte enthalten sind, + // treten diese immer paarig auf!!! (A1.1.1 !!) + if( (sTblNm.GetTokenCount( '.' ) - 1 ) & 1 ) + { + sTblNm.Erase( nTrenner - nStt ); + + // beim Bauen der Formel ist der TabellenName unerwuenscht + //JP 22.02.99: der CAST muss fuer den Linux-Compiler sein + if( fnFormel != (FnScanFormel)&SwTableFormula::_MakeFormel ) + aStr += sTblNm; + nStt = nTrenner; + + sTblNm.Erase( 0, 1 ); // Trenner loeschen + if( sTblNm != rTbl.GetFrmFmt()->GetName() ) + { + // dann suchen wir uns mal unsere Tabelle: + const SwTable* pFnd = FindTable( + *rTbl.GetFrmFmt()->GetDoc(), + sTblNm ); + if( pFnd ) + pTbl = pFnd; + // ?? + ASSERT( pFnd, "Tabelle nicht gefunden, was nun?" ); + } + } + } + + String sBox( sFormel.Copy( nStt, nEnd - nStt + 1 )); + // ein Bereich in dieser Klammer ? + if( STRING_NOTFOUND != ( nTrenner = sFormel.Search( ':', nStt )) + && nTrenner < nEnd ) + { + // ohne die Anfangsklammer + String aFirstBox( sFormel.Copy( nStt+1, nTrenner - nStt - 1 )); + (this->*fnFormel)( *pTbl, aStr, sBox, &aFirstBox, pPara ); + } + else + (this->*fnFormel)( *pTbl, aStr, sBox, 0, pPara ); + } + + nFml = nEnd+1; + } while( TRUE ); + return aStr; +} + +const SwTable* SwTableFormula::FindTable( SwDoc& rDoc, const String& rNm ) const +{ + const SwFrmFmts& rTblFmts = *rDoc.GetTblFrmFmts(); + const SwTable* pTmpTbl, *pRet = 0; + for( USHORT nFmtCnt = rTblFmts.Count(); nFmtCnt; ) + { + SwFrmFmt* pFmt = rTblFmts[ --nFmtCnt ]; + // falls wir von Sw3Writer gerufen werden, dann ist dem + // FormatNamen eine Nummer anhaengig + SwTableBox* pFBox; + if( COMPARE_EQUAL == rNm.CompareTo( pFmt->GetName(), + pFmt->GetName().Search( 0x0a ) ) && + 0 != ( pTmpTbl = SwTable::FindTable( pFmt ) ) && + 0 != (pFBox = pTmpTbl->GetTabSortBoxes()[0] ) && + pFBox->GetSttNd() && + pFBox->GetSttNd()->GetNodes().IsDocNodes() ) + { + // eine Tabelle im normalen NodesArr + pRet = pTmpTbl; + break; + } + } + return pRet; +} + +/* */ + +const SwFrm* lcl_GetBoxFrm( const SwTableBox& rBox ) +{ +/* + + // oder besser ueber die Box den Frame suchen + + SwClientIter aIter( *pBox->GetFrmFmt() ); + ULONG nMinPos = ULONG_MAX; + const SwFrm* pFnd = 0; + for( SwFrm* pF = (SwFrm*)aIter.First( TYPE( SwCellFrm )); pF; + pF = (SwFrm*)aIter.Next() ) + { + if( pF->Frm().Y() < + } +*/ + + SwNodeIndex aIdx( *rBox.GetSttNd() ); + SwCntntNode* pCNd = aIdx.GetNodes().GoNext( &aIdx ); + ASSERT( pCNd, "Box hat keinen TextNode" ); + Point aPt; // den im Layout 1. Frame returnen - Tab.Kopfzeile !! + return pCNd->GetFrm( &aPt, NULL, FALSE ); +} + +long lcl_GetLongBoxNum( String& rStr ) +{ + USHORT nPos; + long nRet; + if( STRING_NOTFOUND == ( nPos = rStr.Search( cRelTrenner ) )) + { + nRet = rStr.ToInt32(); + rStr.Erase(); + } + else + { + nRet = rStr.Copy( 0, nPos ).ToInt32(); + rStr.Erase( 0, nPos+1 ); + } + return nRet; +} + +const SwTableBox* lcl_RelToBox( const SwTable& rTbl, + const SwTableBox* pRefBox, + const String& rGetName ) +{ + // hole die Line + const SwTableBox* pBox = 0; + String sGetName( rGetName ); + + // ist es denn wirklich eine relative Angabe?? + if( cRelKennung == sGetName.GetChar(0) ) // ja, ... + { + if( !pRefBox ) + return 0; + + sGetName.Erase( 0, 1 ); + + const SwTableLines* pLines = (SwTableLines*)&rTbl.GetTabLines(); + const SwTableBoxes* pBoxes; + const SwTableLine* pLine; + + // bestimme erst mal die Start-Werte der Box: + pBox = (SwTableBox*)pRefBox; + pLine = pBox->GetUpper(); + while( pLine->GetUpper() ) + { + pBox = pLine->GetUpper(); + pLine = pBox->GetUpper(); + } + USHORT nSttBox = pLine->GetTabBoxes().GetPos( pBox ); + USHORT nSttLine = rTbl.GetTabLines().GetPos( pLine ); + + long nBoxOffset = lcl_GetLongBoxNum( sGetName ) + nSttBox; + long nLineOffset = lcl_GetLongBoxNum( sGetName ) + nSttLine; + + if( nBoxOffset < 0 || nBoxOffset >= USHRT_MAX || + nLineOffset < 0 || nLineOffset >= USHRT_MAX ) + return 0; + + if( nLineOffset >= long(pLines->Count()) ) + return 0; + + pLine = (*pLines)[ USHORT(nLineOffset) ]; + + // dann suche die Box + pBoxes = &pLine->GetTabBoxes(); + if( nBoxOffset >= long(pBoxes->Count()) ) + return 0; + pBox = (*pBoxes)[ USHORT(nBoxOffset) ]; + + while( sGetName.Len() ) + { + nSttBox = SwTable::_GetBoxNum( sGetName ); + pLines = &pBox->GetTabLines(); + if( nSttBox ) + --nSttBox; + + nSttLine = SwTable::_GetBoxNum( sGetName ); + + // bestimme die Line + if( !nSttLine || nSttLine > pLines->Count() ) + break; + pLine = (*pLines)[ nSttLine-1 ]; + + // bestimme die Box + pBoxes = &pLine->GetTabBoxes(); + if( nSttBox >= pBoxes->Count() ) + break; + pBox = (*pBoxes)[ nSttBox ]; + } + + if( pBox ) + { + if( !pBox->GetSttNd() ) + // "herunterfallen lassen" bis zur ersten Box + while( pBox->GetTabLines().Count() ) + pBox = pBox->GetTabLines()[0]->GetTabBoxes()[0]; + } + } + else + { + // sonst ist es eine absolute externe Darstellung: + pBox = rTbl.GetTblBox( sGetName ); + } + return pBox; +} + +String lcl_BoxNmToRel( const SwTable& rTbl, const SwTableNode& rTblNd, + const String& rRefBoxNm, const String& rGetStr, + BOOL bExtrnlNm ) +{ + String sCpy( rRefBoxNm ); + String sTmp( rGetStr ); + if( !bExtrnlNm ) + { + // in die Externe Darstellung umwandeln. + SwTableBox* pBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(sTmp.ToInt64())); + if( !rTbl.GetTabSortBoxes().Seek_Entry( pBox )) + return '?'; + sTmp = pBox->GetName(); + } + + // sollte die es eine Tabellen uebergreifende Formel sein, dann behalte + // die externe Darstellung bei: + if( &rTbl == &rTblNd.GetTable() ) + { + long nBox = SwTable::_GetBoxNum( sTmp, TRUE ); + nBox -= SwTable::_GetBoxNum( sCpy, TRUE ); + long nLine = SwTable::_GetBoxNum( sTmp ); + nLine -= SwTable::_GetBoxNum( sCpy ); + + sCpy = sTmp; //JP 01.11.95: den Rest aus dem BoxNamen anhaengen + + sTmp = cRelKennung; + sTmp += String::CreateFromInt32( nBox ); + sTmp += cRelTrenner; + sTmp += String::CreateFromInt32( nLine ); + + if( sCpy.Len() ) + { + sTmp += cRelTrenner; + sTmp += sCpy; + } + } + + if( sTmp.Len() && '>' == sTmp.GetChar( sTmp.Len() - 1 )) + sTmp.Erase( sTmp.Len()-1 ); + + return sTmp; +} + +USHORT SwTableFormula::GetBoxesOfFormula( const SwTable& rTbl, + SwSelBoxes& rBoxes ) +{ + if( rBoxes.Count() ) + rBoxes.Remove( USHORT(0), rBoxes.Count() ); + + BoxNmToPtr( &rTbl ); + ScanString( &SwTableFormula::_GetFmlBoxes, rTbl, &rBoxes ); + return rBoxes.Count(); +} + +void SwTableFormula::_GetFmlBoxes( const SwTable& rTbl, String& , + String& rFirstBox, String* pLastBox, void* pPara ) const +{ + SwSelBoxes* pBoxes = (SwSelBoxes*)pPara; + SwTableBox* pSttBox, *pEndBox = 0; + + rFirstBox.Erase(0,1); // Kennung fuer Box loeschen + // ein Bereich in dieser Klammer ? + if( pLastBox ) + { + pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64())); + + // ist das ueberhaupt ein gueltiger Pointer ?? + if( !rTbl.GetTabSortBoxes().Seek_Entry( pEndBox )) + pEndBox = 0; + rFirstBox.Erase( 0, pLastBox->Len()+1 ); + } + + pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64())); + // ist das ueberhaupt ein gueltiger Pointer ?? + if( !rTbl.GetTabSortBoxes().Seek_Entry( pSttBox )) + pSttBox = 0; + + if( pEndBox && pSttBox ) // Bereich ? + { + // ueber das Layout alle "selectierten" Boxen und berechne + // deren Werte + SwSelBoxes aBoxes; + GetBoxes( *pSttBox, *pEndBox, aBoxes ); + pBoxes->Insert( &aBoxes ); + } + else if( pSttBox ) // nur die StartBox ? + pBoxes->Insert( pSttBox ); +} + +void SwTableFormula::GetBoxes( const SwTableBox& rSttBox, + const SwTableBox& rEndBox, + SwSelBoxes& rBoxes ) const +{ + // hole ueber das Layout alle "selektierten" Boxen + const SwLayoutFrm *pStt, *pEnd; + const SwFrm* pFrm = lcl_GetBoxFrm( rSttBox ); + pStt = pFrm ? pFrm->GetUpper() : 0; + pEnd = ( 0 != (pFrm = lcl_GetBoxFrm( rEndBox ))) ? pFrm->GetUpper() : 0; + if( !pStt || !pEnd ) + return ; // no valid selection + + GetTblSel( pStt, pEnd, rBoxes, 0 ); + + const SwTable* pTbl = pStt->FindTabFrm()->GetTable(); + + // filter die Kopfzeilen-Boxen heraus: + if( pTbl->GetRowsToRepeat() > 0 ) + { + do { // middle-check loop + const SwTableLine* pLine = rSttBox.GetUpper(); + while( pLine->GetUpper() ) + pLine = pLine->GetUpper()->GetUpper(); + + if( pTbl->IsHeadline( *pLine ) ) + break; // Headline mit im Bereich ! + + // vielleicht ist ja Start und Ende vertauscht + pLine = rEndBox.GetUpper(); + while ( pLine->GetUpper() ) + pLine = pLine->GetUpper()->GetUpper(); + + if( pTbl->IsHeadline( *pLine ) ) + break; // Headline mit im Bereich ! + + const SwTabFrm *pTable = pStt->FindTabFrm(); + const SwTabFrm *pEndTable = pEnd->FindTabFrm(); + + if( pTable == pEndTable ) // keine gespl. Tabelle + break; + + // dann mal die Tabellenkoepfe raus: + for( USHORT n = 0; n < rBoxes.Count(); ++n ) + { + pLine = rBoxes[n]->GetUpper(); + while( pLine->GetUpper() ) + pLine = pLine->GetUpper()->GetUpper(); + + if( pTbl->IsHeadline( *pLine ) ) + rBoxes.Remove( n--, 1 ); + } + } while( FALSE ); + } +} + + // sind alle Boxen gueltig, auf die sich die Formel bezieht? +void SwTableFormula::_HasValidBoxes( const SwTable& rTbl, String& , + String& rFirstBox, String* pLastBox, void* pPara ) const +{ + BOOL* pBValid = (BOOL*)pPara; + if( *pBValid ) // einmal falsch, immer falsch + { + SwTableBox* pSttBox = 0, *pEndBox = 0; + rFirstBox.Erase(0,1); // Kennung fuer Box loeschen + + // ein Bereich in dieser Klammer ? + if( pLastBox ) + rFirstBox.Erase( 0, pLastBox->Len()+1 ); + + switch( eNmType) + { + case INTRNL_NAME: + if( pLastBox ) + pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64())); + pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64())); + break; + + case REL_NAME: + { + const SwNode* pNd = GetNodeOfFormula(); + const SwTableBox* pBox = !pNd ? 0 + : (SwTableBox *)rTbl.GetTblBox( + pNd->FindTableBoxStartNode()->GetIndex() ); + if( pLastBox ) + pEndBox = (SwTableBox*)lcl_RelToBox( rTbl, pBox, *pLastBox ); + pSttBox = (SwTableBox*)lcl_RelToBox( rTbl, pBox, rFirstBox ); + } + break; + + case EXTRNL_NAME: + if( pLastBox ) + pEndBox = (SwTableBox*)rTbl.GetTblBox( *pLastBox ); + pSttBox = (SwTableBox*)rTbl.GetTblBox( rFirstBox ); + break; + } + + // sind das gueltige Pointer ? + if( ( pLastBox && + ( !pEndBox || !rTbl.GetTabSortBoxes().Seek_Entry( pEndBox ) ) ) || + ( !pSttBox || !rTbl.GetTabSortBoxes().Seek_Entry( pSttBox ) ) ) + *pBValid = FALSE; + } +} + +BOOL SwTableFormula::HasValidBoxes() const +{ + BOOL bRet = TRUE; + const SwNode* pNd = GetNodeOfFormula(); + if( pNd && 0 != ( pNd = pNd->FindTableNode() ) ) + ScanString( &SwTableFormula::_HasValidBoxes, + ((SwTableNode*)pNd)->GetTable(), &bRet ); + return bRet; +} + + +USHORT SwTableFormula::GetLnPosInTbl( const SwTable& rTbl, const SwTableBox* pBox ) +{ + USHORT nRet = USHRT_MAX; + if( pBox ) + { + const SwTableLine* pLn = pBox->GetUpper(); + while( pLn->GetUpper() ) + pLn = pLn->GetUpper()->GetUpper(); + nRet = rTbl.GetTabLines().GetPos( pLn ); + } + return nRet; +} + +void SwTableFormula::_SplitMergeBoxNm( const SwTable& rTbl, String& rNewStr, + String& rFirstBox, String* pLastBox, void* pPara ) const +{ + SwTableFmlUpdate& rTblUpd = *(SwTableFmlUpdate*)pPara; + + rNewStr += rFirstBox.Copy(0,1); // Kennung fuer Box erhalten + rFirstBox.Erase(0,1); + + String sTblNm; + const SwTable* pTbl = &rTbl; + + String* pTblNmBox = pLastBox ? pLastBox : &rFirstBox; + + USHORT nLastBoxLen = pTblNmBox->Len(); + USHORT nTrenner = pTblNmBox->Search( '.' ); + if( STRING_NOTFOUND != nTrenner && + // falls im Namen schon die Punkte enthalten sind, + // treten diese immer paarig auf!!! (A1.1.1 !!) + (pTblNmBox->GetTokenCount( '.' ) - 1 ) & 1 ) + { + sTblNm = pTblNmBox->Copy( 0, nTrenner ); + pTblNmBox->Erase( 0, nTrenner + 1);// den Punkt entfernen + const SwTable* pFnd = FindTable( *rTbl.GetFrmFmt()->GetDoc(), sTblNm ); + if( pFnd ) + pTbl = pFnd; + + if( TBL_MERGETBL == rTblUpd.eFlags ) + { + if( pFnd ) + { + if( pFnd == rTblUpd.DATA.pDelTbl ) + { + if( rTblUpd.pTbl != &rTbl ) // es ist nicht die akt. + (rNewStr += rTblUpd.pTbl->GetFrmFmt()->GetName() ) + += '.'; // den neuen Tabellen Namen setzen + rTblUpd.bModified = TRUE; + } + else if( pFnd != rTblUpd.pTbl || + ( rTblUpd.pTbl != &rTbl && &rTbl != rTblUpd.DATA.pDelTbl)) + (rNewStr += sTblNm ) += '.'; // den Tabellen Namen behalten + else + rTblUpd.bModified = TRUE; + } + else + (rNewStr += sTblNm ) += '.'; // den Tabellen Namen behalten + + } + } + if( pTblNmBox == pLastBox ) + rFirstBox.Erase( 0, nLastBoxLen + 1 ); + + SwTableBox* pSttBox = 0, *pEndBox = 0; + switch( eNmType ) + { + case INTRNL_NAME: + if( pLastBox ) + pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64())); + pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64())); + break; + + case REL_NAME: + { + const SwNode* pNd = GetNodeOfFormula(); + const SwTableBox* pBox = pNd ? pTbl->GetTblBox( + pNd->FindTableBoxStartNode()->GetIndex() ) : 0; + if( pLastBox ) + pEndBox = (SwTableBox*)lcl_RelToBox( *pTbl, pBox, *pLastBox ); + pSttBox = (SwTableBox*)lcl_RelToBox( *pTbl, pBox, rFirstBox ); + } + break; + + case EXTRNL_NAME: + if( pLastBox ) + pEndBox = (SwTableBox*)pTbl->GetTblBox( *pLastBox ); + pSttBox = (SwTableBox*)pTbl->GetTblBox( rFirstBox ); + break; + } + + if( pLastBox && !pTbl->GetTabSortBoxes().Seek_Entry( pEndBox )) + pEndBox = 0; + if( !pTbl->GetTabSortBoxes().Seek_Entry( pSttBox )) + pSttBox = 0; + + if( TBL_SPLITTBL == rTblUpd.eFlags ) + { + // wo liegen die Boxen, in der "alten" oder in der neuen Tabelle? + BOOL bInNewTbl = FALSE; + if( pLastBox ) + { + // das ist die "erste" Box in der Selektion. Die bestimmt ob die + // Formel in der alten oder neuen Tabelle steht. + USHORT nEndLnPos = SwTableFormula::GetLnPosInTbl( *pTbl, pEndBox ), + nSttLnPos = SwTableFormula::GetLnPosInTbl( *pTbl, pSttBox ); + + if( USHRT_MAX != nSttLnPos && USHRT_MAX != nEndLnPos && + ((rTblUpd.nSplitLine <= nSttLnPos) == + (rTblUpd.nSplitLine <= nEndLnPos)) ) + { + // bleiben in der gleichen Tabelle + bInNewTbl = rTblUpd.nSplitLine <= nEndLnPos && + pTbl == rTblUpd.pTbl; + } + else + { + // das ist aufjedenfall eine ungueltige Formel, also fuers + // Undo auf Modified setzen + rTblUpd.bModified = TRUE; + if( pEndBox ) + bInNewTbl = USHRT_MAX != nEndLnPos && + rTblUpd.nSplitLine <= nEndLnPos && + pTbl == rTblUpd.pTbl; + } + } + else + { + USHORT nSttLnPos = SwTableFormula::GetLnPosInTbl( *pTbl, pSttBox ); + // dann landet das Teil in der neuen Tabelle? + bInNewTbl = USHRT_MAX != nSttLnPos && + rTblUpd.nSplitLine <= nSttLnPos && + pTbl == rTblUpd.pTbl; + } + + // wenn die Formel selbst in der neuen Tabellen landet + if( rTblUpd.bBehindSplitLine ) + { + if( !bInNewTbl ) + { + rTblUpd.bModified = TRUE; + ( rNewStr += rTblUpd.pTbl->GetFrmFmt()->GetName() ) += '.'; + } + else if( sTblNm.Len() ) + ( rNewStr += sTblNm ) += '.'; + } + else if( bInNewTbl ) + { + rTblUpd.bModified = TRUE; + ( rNewStr += *rTblUpd.DATA.pNewTblNm ) += '.'; + } + else if( sTblNm.Len() ) + ( rNewStr += sTblNm ) += '.'; + } + + if( pLastBox ) + ( rNewStr += String::CreateFromInt64((sal_PtrDiff)pEndBox)) += ':'; + ( rNewStr += String::CreateFromInt64((sal_PtrDiff)pSttBox)) + += rFirstBox.GetChar( rFirstBox.Len() - 1 ); +} + + // erzeuge die externe Formel, beachte aber das die Formel + // in einer gesplitteten/gemergten Tabelle landet +void SwTableFormula::ToSplitMergeBoxNm( SwTableFmlUpdate& rTblUpd ) +{ + const SwTable* pTbl; + const SwNode* pNd = GetNodeOfFormula(); + if( pNd && 0 != ( pNd = pNd->FindTableNode() )) + pTbl = &((SwTableNode*)pNd)->GetTable(); + else + pTbl = rTblUpd.pTbl; + + sFormel = ScanString( &SwTableFormula::_SplitMergeBoxNm, *pTbl, (void*)&rTblUpd ); + eNmType = INTRNL_NAME; +} + + diff --git a/sw/source/core/fields/chpfld.cxx b/sw/source/core/fields/chpfld.cxx new file mode 100644 index 000000000000..bfc14af1a7aa --- /dev/null +++ b/sw/source/core/fields/chpfld.cxx @@ -0,0 +1,309 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + + +#include <com/sun/star/text/ChapterFormat.hpp> +#include <doc.hxx> +#include <frame.hxx> // SwChapterFieldType::ChangeExpansion() +#include <pam.hxx> // fuer GetBodyTxtNode +#include <ndtxt.hxx> +#include <chpfld.hxx> +#include <expfld.hxx> // fuer GetBodyTxtNode +#ifndef _UNOFLDMID_H +#include <unofldmid.h> +#endif +#include <numrule.hxx> + +using namespace ::com::sun::star; + +/*-------------------------------------------------------------------- + Beschreibung: SwChapterFieldType + --------------------------------------------------------------------*/ + + +SwChapterFieldType::SwChapterFieldType() + : SwFieldType( RES_CHAPTERFLD ) +{ +} + + +SwFieldType* SwChapterFieldType::Copy() const +{ + return new SwChapterFieldType(); +} + + +/*-------------------------------------------------------------------- + Beschreibung: Kapittelfeld + --------------------------------------------------------------------*/ + + +SwChapterField::SwChapterField(SwChapterFieldType* pTyp, sal_uInt32 nFmt) + : SwField(pTyp, nFmt), nLevel( 0 ) +{} + + +String SwChapterField::Expand() const +{ + String sStr( sNumber ); + switch( GetFormat() ) + { + case CF_TITLE: sStr = sTitle; break; + + case CF_NUMBER: + case CF_NUM_TITLE: sStr.Insert( sPre, 0 ); + sStr += sPost; + if( CF_NUM_TITLE == GetFormat() ) + sStr += sTitle; + break; + + case CF_NUM_NOPREPST_TITLE: sStr += sTitle; break; + } + return sStr; +} + + +SwField* SwChapterField::Copy() const +{ + SwChapterField *pTmp = + new SwChapterField((SwChapterFieldType*)GetTyp(), GetFormat()); + pTmp->nLevel = nLevel; + pTmp->sTitle = sTitle; + pTmp->sNumber = sNumber; + pTmp->sPost = sPost; + pTmp->sPre = sPre; + + return pTmp; +} + +// --> OD 2008-02-14 #i53420# +//void SwChapterField::ChangeExpansion( const SwFrm* pFrm, +// const SwTxtNode* pTxtNd, +// sal_Bool bSrchNum ) +//{ +// ASSERT( pFrm, "in welchem Frame stehe ich denn?" ) +// SwDoc* pDoc = (SwDoc*)pTxtNd->GetDoc(); +// SwPosition aPos( pDoc->GetNodes().GetEndOfContent() ); + +// if( pFrm->IsInDocBody() ) +// aPos.nNode = *pTxtNd; +// else if( 0 == (pTxtNd = GetBodyTxtNode( *pDoc, aPos, *pFrm )) ) +// // kein TxtNode (Formatierung Kopf/Fusszeile) +// return; +// ChangeExpansion(*pTxtNd, bSrchNum); +//} +void SwChapterField::ChangeExpansion(const SwFrm* pFrm, + const SwCntntNode* pCntntNode, + sal_Bool bSrchNum ) +{ + ASSERT( pFrm, "in welchem Frame stehe ich denn?" ) + SwDoc* pDoc = (SwDoc*)pCntntNode->GetDoc(); + + const SwTxtNode* pTxtNode = dynamic_cast<const SwTxtNode*>(pCntntNode); + if ( !pTxtNode || !pFrm->IsInDocBody() ) + { + SwPosition aDummyPos( pDoc->GetNodes().GetEndOfContent() ); + pTxtNode = GetBodyTxtNode( *pDoc, aDummyPos, *pFrm ); + } + + if ( pTxtNode ) + { + ChangeExpansion( *pTxtNode, bSrchNum ); + } +} +// <-- + +void SwChapterField::ChangeExpansion(const SwTxtNode &rTxtNd, sal_Bool bSrchNum) +{ + SwDoc* pDoc = (SwDoc*)rTxtNd.GetDoc(); + const SwTxtNode *pTxtNd = rTxtNd.FindOutlineNodeOfLevel( nLevel ); + if( pTxtNd ) + { + if( bSrchNum ) + { + const SwTxtNode* pONd = pTxtNd; + do { + if( pONd && pONd->GetTxtColl() ) + { + BYTE nPrevLvl = nLevel; + + // --> OD 2008-04-02 #refactorlists# +// nLevel = GetRealLevel( pONd->GetTxtColl()-> +// GetOutlineLevel() ); + //ASSERT( pONd->GetOutlineLevel() >= 0 && pONd->GetOutlineLevel() < MAXLEVEL, //#outline level,zhaojianwei + // "<SwChapterField::ChangeExpansion(..)> - outline node with inconsistent outline level. Serious defect -> please inform OD." ); + //nLevel = static_cast<BYTE>(pONd->GetOutlineLevel()); + ASSERT( pONd->GetAttrOutlineLevel() >= 0 && pONd->GetAttrOutlineLevel() <= MAXLEVEL, + "<SwChapterField::ChangeExpansion(..)> - outline node with inconsistent outline level. Serious defect -> please inform OD." ); + nLevel = static_cast<BYTE>(pONd->GetAttrOutlineLevel()); //<-end,zhaojianwei + // <-- + + if( nPrevLvl < nLevel ) + nLevel = nPrevLvl; + else if( SVX_NUM_NUMBER_NONE != pDoc->GetOutlineNumRule() + ->Get( nLevel ).GetNumberingType() ) + { + pTxtNd = pONd; + break; + } + + if( !nLevel-- ) + break; + pONd = pTxtNd->FindOutlineNodeOfLevel( nLevel ); + } + else + break; + } while( sal_True ); + } + + // nur die Nummer besorgen, ohne Pre-/Post-fixstrings + + if ( pTxtNd->IsOutline() ) + { + // --> OD 2005-11-17 #128041# + // correction of refactoring done by cws swnumtree: + // retrieve numbering string without prefix and suffix strings + // as stated in the above german comment. + sNumber = pTxtNd->GetNumString( false ); + // <-- + + SwNumRule* pRule( pTxtNd->GetNumRule() ); + if ( pTxtNd->IsCountedInList() && pRule ) + { + const SwNumFmt& rNFmt = pRule->Get( static_cast<USHORT>(pTxtNd->GetActualListLevel()) ); + sPost = rNFmt.GetSuffix(); + sPre = rNFmt.GetPrefix(); + } + else + sPost = aEmptyStr, sPre = aEmptyStr; + } + else + { + sPost = aEmptyStr; + sPre = aEmptyStr; + sNumber = String("??", RTL_TEXTENCODING_ASCII_US); + } + + sTitle = pTxtNd->GetExpandTxt(); + + for( xub_StrLen i = 0; i < sTitle.Len(); ++i ) + if( ' ' > sTitle.GetChar( i ) ) + sTitle.Erase( i--, 1 ); + } + else + { + sNumber = aEmptyStr; + sTitle = aEmptyStr; + sPost = aEmptyStr; + sPre = aEmptyStr; + } +} + +/*-----------------05.03.98 16:19------------------- + +--------------------------------------------------*/ +BOOL SwChapterField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_BYTE1: + rAny <<= (sal_Int8)nLevel; + break; + + case FIELD_PROP_USHORT1: + { + sal_Int16 nRet; + switch( GetFormat() ) + { + case CF_NUMBER: nRet = text::ChapterFormat::NUMBER; break; + case CF_TITLE: nRet = text::ChapterFormat::NAME; break; + case CF_NUMBER_NOPREPST: + nRet = text::ChapterFormat::DIGIT; + break; + case CF_NUM_NOPREPST_TITLE: + nRet = text::ChapterFormat::NO_PREFIX_SUFFIX; + break; + case CF_NUM_TITLE: + default: nRet = text::ChapterFormat::NAME_NUMBER; + } + rAny <<= nRet; + } + break; + + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} +/*-----------------05.03.98 16:19------------------- + +--------------------------------------------------*/ +BOOL SwChapterField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + BOOL bRet = TRUE; + switch( nWhichId ) + { + case FIELD_PROP_BYTE1: + { + sal_Int8 nTmp = 0; + rAny >>= nTmp; + if(nTmp >= 0 && nTmp < MAXLEVEL) + nLevel = nTmp; + else + bRet = FALSE; + break; + } + + case FIELD_PROP_USHORT1: + { + sal_Int16 nVal = 0; + rAny >>= nVal; + switch( nVal ) + { + case text::ChapterFormat::NAME: SetFormat(CF_TITLE); break; + case text::ChapterFormat::NUMBER: SetFormat(CF_NUMBER); break; + case text::ChapterFormat::NO_PREFIX_SUFFIX: + SetFormat(CF_NUM_NOPREPST_TITLE); + break; + case text::ChapterFormat::DIGIT: + SetFormat(CF_NUMBER_NOPREPST); + break; + //case text::ChapterFormat::NAME_NUMBER: + default: SetFormat(CF_NUM_TITLE); + } + } + break; + + default: + DBG_ERROR("illegal property"); + bRet = FALSE; + } + return bRet; +} diff --git a/sw/source/core/fields/dbfld.cxx b/sw/source/core/fields/dbfld.cxx new file mode 100644 index 000000000000..15c44286921c --- /dev/null +++ b/sw/source/core/fields/dbfld.cxx @@ -0,0 +1,1076 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + + +#include <float.h> +#include <sfx2/app.hxx> +#include <svl/zforlist.hxx> +#include <svx/pageitem.hxx> +#include <svx/dataaccessdescriptor.hxx> +#include <com/sun/star/sdbc/DataType.hpp> +#include <fmtfld.hxx> +#include <txtfld.hxx> +#include <doc.hxx> +#include <docary.hxx> +#include <frame.hxx> +#include <fldbas.hxx> +#include <pam.hxx> +#include <ndtxt.hxx> +#include <dbfld.hxx> +#ifndef _DBMGR_HXX +#include <dbmgr.hxx> +#endif +#include <docfld.hxx> +#include <expfld.hxx> +#include <txtatr.hxx> +#ifndef _UNOFLDMID_H +#include <unofldmid.h> +#endif + + +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star; +using ::rtl::OUString; + +/*-------------------------------------------------------------------- + Beschreibung: Datenbanktrenner durch Punkte fuer Anzeige ersetzen + --------------------------------------------------------------------*/ + +String lcl_DBTrennConv(const String& aContent) +{ + String sTmp(aContent); + sal_Unicode* pStr = sTmp.GetBufferAccess(); + for( USHORT i = sTmp.Len(); i; --i, ++pStr ) + if( DB_DELIM == *pStr ) + *pStr = '.'; + return sTmp; +} + +/*-------------------------------------------------------------------- + Beschreibung: DatenbankFeldTyp + --------------------------------------------------------------------*/ + +SwDBFieldType::SwDBFieldType(SwDoc* pDocPtr, const String& rNam, const SwDBData& rDBData ) : + SwValueFieldType( pDocPtr, RES_DBFLD ), + aDBData(rDBData), + sColumn(rNam), + nRefCnt(0) +{ + if(aDBData.sDataSource.getLength() || aDBData.sCommand.getLength()) + { + sName = aDBData.sDataSource; + sName += DB_DELIM; + sName += (String)aDBData.sCommand; + sName += DB_DELIM; + } + sName += GetColumnName(); +} +//------------------------------------------------------------------------------ +SwDBFieldType::~SwDBFieldType() +{ +} +//------------------------------------------------------------------------------ + +SwFieldType* SwDBFieldType::Copy() const +{ + SwDBFieldType* pTmp = new SwDBFieldType(GetDoc(), sColumn, aDBData); + return pTmp; +} + +//------------------------------------------------------------------------------ +const String& SwDBFieldType::GetName() const +{ + return sName; +} + +//------------------------------------------------------------------------------ + +void SwDBFieldType::ReleaseRef() +{ + ASSERT(nRefCnt > 0, "RefCount kleiner 0!"); + + if (--nRefCnt <= 0) + { + USHORT nPos = GetDoc()->GetFldTypes()->GetPos(this); + + if (nPos != USHRT_MAX) + { + GetDoc()->RemoveFldType(nPos); + delete this; + } + } +} + +/* -----------------24.02.99 14:51------------------- + * + * --------------------------------------------------*/ +BOOL SwDBFieldType::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + rAny <<= aDBData.sDataSource; + break; + case FIELD_PROP_PAR2: + rAny <<= aDBData.sCommand; + break; + case FIELD_PROP_PAR3: + rAny <<= OUString(sColumn); + break; + case FIELD_PROP_SHORT1: + rAny <<= aDBData.nCommandType; + break; + default: + DBG_ERROR("illegal property"); + } + return TRUE; +} +/* -----------------24.02.99 14:51------------------- + * + * --------------------------------------------------*/ +BOOL SwDBFieldType::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + rAny >>= aDBData.sDataSource; + break; + case FIELD_PROP_PAR2: + rAny >>= aDBData.sCommand; + break; + case FIELD_PROP_PAR3: + { + String sTmp; + ::GetString( rAny, sTmp ); + if( sTmp != sColumn ) + { + sColumn = sTmp; + SwClientIter aIter( *this ); + SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); + while(pFld) + { + // Feld im Undo? + SwTxtFld *pTxtFld = pFld->GetTxtFld(); + if(pTxtFld && pTxtFld->GetTxtNode().GetNodes().IsDocNodes() ) + { + SwDBField* pDBField = (SwDBField*)pFld->GetFld(); + pDBField->ClearInitialized(); + pDBField->InitContent(); + } + pFld = (SwFmtFld*)aIter.Next(); + } + } + } + break; + case FIELD_PROP_SHORT1: + rAny >>= aDBData.nCommandType; + break; + default: + DBG_ERROR("illegal property"); + } + return TRUE; +} +/*-------------------------------------------------------------------- + Beschreibung: SwDBField + --------------------------------------------------------------------*/ + +SwDBField::SwDBField(SwDBFieldType* pTyp, ULONG nFmt) + : SwValueField(pTyp, nFmt), + nSubType(0), + bIsInBodyTxt(TRUE), + bValidValue(FALSE), + bInitialized(FALSE) +{ + if (GetTyp()) + ((SwDBFieldType*)GetTyp())->AddRef(); + InitContent(); +} + +//------------------------------------------------------------------------------ + +SwDBField::~SwDBField() +{ + if (GetTyp()) + ((SwDBFieldType*)GetTyp())->ReleaseRef(); +} + +//------------------------------------------------------------------------------ + +void SwDBField::InitContent() +{ + if (!IsInitialized()) + { + aContent = '<'; + aContent += ((SwDBFieldType*)GetTyp())->GetColumnName(); + aContent += '>'; + } +} + +//------------------------------------------------------------------------------ + +void SwDBField::InitContent(const String& rExpansion) +{ + if (rExpansion.Len() > 2) + { + if (rExpansion.GetChar(0) == '<' && + rExpansion.GetChar(rExpansion.Len() - 1) == '>') + { + String sColumn( rExpansion.Copy( 1, rExpansion.Len() - 2 ) ); + if( ::GetAppCmpStrIgnore().isEqual( sColumn, + ((SwDBFieldType *)GetTyp())->GetColumnName() )) + { + InitContent(); + return; + } + } + } + SetExpansion( rExpansion ); +} + +//------------------------------------------------------------------------------ + +String SwDBField::Expand() const +{ + String sRet; + + if(0 ==(GetSubType() & nsSwExtendedSubType::SUB_INVISIBLE)) + sRet = lcl_DBTrennConv(aContent); + return sRet; +} + +//------------------------------------------------------------------------------ + +SwField* SwDBField::Copy() const +{ + SwDBField *pTmp = new SwDBField((SwDBFieldType*)GetTyp(), GetFormat()); + pTmp->aContent = aContent; + pTmp->bIsInBodyTxt = bIsInBodyTxt; + pTmp->bValidValue = bValidValue; + pTmp->bInitialized = bInitialized; + pTmp->nSubType = nSubType; + pTmp->SetValue(GetValue()); + pTmp->sFieldCode = sFieldCode; + + return pTmp; +} + +String SwDBField::GetCntnt(BOOL bName) const +{ + if(bName) + { + const String& rDBName = ((SwDBFieldType*)GetTyp())->GetName(); + //TODO/CLEANUP + //Funktion tut nichts! + //String sContent( SFX_APP()->LocalizeDBName(INI2NATIONAL, + // rDBName.GetToken(0, DB_DELIM))); + String sContent( rDBName.GetToken(0, DB_DELIM) ); + + if (sContent.Len() > 1) + { + sContent += DB_DELIM; + sContent += rDBName.GetToken(1, DB_DELIM); + sContent += DB_DELIM; + sContent += rDBName.GetToken(2, DB_DELIM); + } + return lcl_DBTrennConv(sContent); + } + return Expand(); +} + +//------------------------------------------------------------------------------ + +void SwDBField::ChgValue( double d, BOOL bVal ) +{ + bValidValue = bVal; + SetValue(d); + + if( bValidValue ) + aContent = ((SwValueFieldType*)GetTyp())->ExpandValue(d, GetFormat(), GetLanguage()); +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +SwFieldType* SwDBField::ChgTyp( SwFieldType* pNewType ) +{ + SwFieldType* pOld = SwValueField::ChgTyp( pNewType ); + + ((SwDBFieldType*)pNewType)->AddRef(); + ((SwDBFieldType*)pOld)->ReleaseRef(); + + return pOld; +} + +/*-------------------------------------------------------------------- + Beschreibung: Aktuellen Field-Value holen und chachen + --------------------------------------------------------------------*/ + +void SwDBField::Evaluate() +{ + SwNewDBMgr* pMgr = GetDoc()->GetNewDBMgr(); + + // erstmal loeschen + bValidValue = FALSE; + double nValue = DBL_MAX; + const SwDBData& aTmpData = GetDBData(); + + if(!pMgr || !pMgr->IsDataSourceOpen(aTmpData.sDataSource, aTmpData.sCommand, sal_True)) + return ; + + sal_uInt32 nFmt; + + // Passenden Spaltennamen suchen + String aColNm( ((SwDBFieldType*)GetTyp())->GetColumnName() ); + + SvNumberFormatter* pDocFormatter = GetDoc()->GetNumberFormatter(); + pMgr->GetMergeColumnCnt(aColNm, GetLanguage(), aContent, &nValue, &nFmt); + if( !( nSubType & nsSwExtendedSubType::SUB_OWN_FMT ) ) + SetFormat( nFmt = pMgr->GetColumnFmt( aTmpData.sDataSource, aTmpData.sCommand, + aColNm, pDocFormatter, GetLanguage() )); + + if( DBL_MAX != nValue ) + { + sal_Int32 nColumnType = pMgr->GetColumnType(aTmpData.sDataSource, aTmpData.sCommand, aColNm); + if( DataType::DATE == nColumnType || DataType::TIME == nColumnType || + DataType::TIMESTAMP == nColumnType) + + { + Date aStandard(1,1,1900); + if (*pDocFormatter->GetNullDate() != aStandard) + nValue += (aStandard - *pDocFormatter->GetNullDate()); + } + bValidValue = TRUE; + SetValue(nValue); + aContent = ((SwValueFieldType*)GetTyp())->ExpandValue(nValue, GetFormat(), GetLanguage()); + } + else + { + SwSbxValue aVal; + aVal.PutString( aContent ); + + if (aVal.IsNumeric()) + { + SetValue(aVal.GetDouble()); + + SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter(); + if (nFmt && nFmt != SAL_MAX_UINT32 && !pFormatter->IsTextFormat(nFmt)) + bValidValue = TRUE; // Wegen Bug #60339 nicht mehr bei allen Strings + } + else + { + // Bei Strings TRUE wenn Laenge > 0 sonst FALSE + SetValue(aContent.Len() ? 1 : 0); + } + } + bInitialized = TRUE; +} + +/*-------------------------------------------------------------------- + Beschreibung: Namen erfragen + --------------------------------------------------------------------*/ + +const String& SwDBField::GetPar1() const +{ + return ((SwDBFieldType*)GetTyp())->GetName(); +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +USHORT SwDBField::GetSubType() const +{ + return nSubType; +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SwDBField::SetSubType(USHORT nType) +{ + nSubType = nType; +} + +/*-----------------06.03.98 16:15------------------- + +--------------------------------------------------*/ +BOOL SwDBField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_BOOL1: + { + BOOL bTemp = 0 == (GetSubType()&nsSwExtendedSubType::SUB_OWN_FMT); + rAny.setValue(&bTemp, ::getBooleanCppuType()); + } + break; + case FIELD_PROP_BOOL2: + { + sal_Bool bVal = 0 == (GetSubType() & nsSwExtendedSubType::SUB_INVISIBLE); + rAny.setValue(&bVal, ::getBooleanCppuType()); + } + break; + case FIELD_PROP_FORMAT: + rAny <<= (sal_Int32)GetFormat(); + break; + case FIELD_PROP_PAR1: + rAny <<= OUString(aContent); + break; + case FIELD_PROP_PAR2: + rAny <<= OUString(sFieldCode); + break; + default: + DBG_ERROR("illegal property"); + } + return TRUE; + +} +/*-----------------06.03.98 16:15------------------- + +--------------------------------------------------*/ +BOOL SwDBField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + switch( nWhichId ) + { + case FIELD_PROP_BOOL1: + if( *(sal_Bool*)rAny.getValue() ) + SetSubType(GetSubType()&~nsSwExtendedSubType::SUB_OWN_FMT); + else + SetSubType(GetSubType()|nsSwExtendedSubType::SUB_OWN_FMT); + break; + case FIELD_PROP_BOOL2: + { + USHORT nSubTyp = GetSubType(); + sal_Bool bVisible = sal_False; + if(!(rAny >>= bVisible)) + return FALSE; + if(bVisible) + nSubTyp &= ~nsSwExtendedSubType::SUB_INVISIBLE; + else + nSubTyp |= nsSwExtendedSubType::SUB_INVISIBLE; + SetSubType(nSubTyp); + //invalidate text node + if(GetTyp()) + { + SwClientIter aIter( *GetTyp() ); + SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); + while(pFld) + { + SwTxtFld *pTxtFld = pFld->GetTxtFld(); + if(pTxtFld && (SwDBField*)pFld->GetFld() == this ) + { + //notify the change + pTxtFld->NotifyContentChange(*pFld); + break; + } + pFld = (SwFmtFld*)aIter.Next(); + } + } + } + break; + case FIELD_PROP_FORMAT: + { + sal_Int32 nTemp = 0; + rAny >>= nTemp; + SetFormat(nTemp); + } + break; + case FIELD_PROP_PAR1: + ::GetString( rAny, aContent ); + break; + case FIELD_PROP_PAR2: + ::GetString( rAny, sFieldCode ); + break; + default: + DBG_ERROR("illegal property"); + } + return TRUE; +} + +/*-------------------------------------------------------------------- + Beschreibung: Basisklasse fuer alle weiteren Datenbankfelder + --------------------------------------------------------------------*/ + +SwDBNameInfField::SwDBNameInfField(SwFieldType* pTyp, const SwDBData& rDBData, ULONG nFmt) : + SwField(pTyp, nFmt), + aDBData(rDBData), + nSubType(0) +{ +} + +//------------------------------------------------------------------------------ + +SwDBData SwDBNameInfField::GetDBData(SwDoc* pDoc) +{ + SwDBData aRet; + if(aDBData.sDataSource.getLength()) + aRet = aDBData; + else + aRet = pDoc->GetDBData(); + return aRet; +} + +// #111840# +void SwDBNameInfField::SetDBData(const SwDBData & rDBData) +{ + aDBData = rDBData; +} + +//------------------------------------------------------------------------------ + +String SwDBNameInfField::GetCntnt(BOOL bName) const +{ + String sStr(SwField::GetCntnt(bName)); + + if(bName) + { + if (aDBData.sDataSource.getLength()) + { + sStr += ':'; + sStr += String(aDBData.sDataSource); + sStr += DB_DELIM; + sStr += String(aDBData.sCommand); + } + } + return lcl_DBTrennConv(sStr); +} + +/*-----------------06.03.98 16:55------------------- + +--------------------------------------------------*/ +BOOL SwDBNameInfField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + rAny <<= aDBData.sDataSource; + break; + case FIELD_PROP_PAR2: + rAny <<= aDBData.sCommand; + break; + case FIELD_PROP_SHORT1: + rAny <<= aDBData.nCommandType; + break; + case FIELD_PROP_BOOL2: + { + sal_Bool bVal = 0 == (GetSubType() & nsSwExtendedSubType::SUB_INVISIBLE); + rAny.setValue(&bVal, ::getBooleanCppuType()); + } + break; + default: + DBG_ERROR("illegal property"); + } + return TRUE; +} +/*-----------------06.03.98 16:55------------------- + +--------------------------------------------------*/ +BOOL SwDBNameInfField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + rAny >>= aDBData.sDataSource; + break; + case FIELD_PROP_PAR2: + rAny >>= aDBData.sCommand; + break; + case FIELD_PROP_SHORT1: + rAny >>= aDBData.nCommandType; + break; + case FIELD_PROP_BOOL2: + { + USHORT nSubTyp = GetSubType(); + sal_Bool bVisible = sal_False; + if(!(rAny >>= bVisible)) + return FALSE; + if(bVisible) + nSubTyp &= ~nsSwExtendedSubType::SUB_INVISIBLE; + else + nSubTyp |= nsSwExtendedSubType::SUB_INVISIBLE; + SetSubType(nSubTyp); + } + break; + default: + DBG_ERROR("illegal property"); + } + return TRUE; +} +/* -----------------4/10/2003 15:03------------------ + + --------------------------------------------------*/ +USHORT SwDBNameInfField::GetSubType() const +{ + return nSubType; +} +/* -----------------4/10/2003 15:03------------------ + + --------------------------------------------------*/ +void SwDBNameInfField::SetSubType(USHORT nType) +{ + nSubType = nType; +} + +/*-------------------------------------------------------------------- + Beschreibung: NaechsterDatensatz + --------------------------------------------------------------------*/ + +SwDBNextSetFieldType::SwDBNextSetFieldType() + : SwFieldType( RES_DBNEXTSETFLD ) +{ +} + +//------------------------------------------------------------------------------ + +SwFieldType* SwDBNextSetFieldType::Copy() const +{ + SwDBNextSetFieldType* pTmp = new SwDBNextSetFieldType(); + return pTmp; +} +/*-------------------------------------------------------------------- + Beschreibung: SwDBSetField + --------------------------------------------------------------------*/ + +SwDBNextSetField::SwDBNextSetField(SwDBNextSetFieldType* pTyp, + const String& rCond, + const String& , + const SwDBData& rDBData) : + SwDBNameInfField(pTyp, rDBData), aCond(rCond), bCondValid(TRUE) +{} + +//------------------------------------------------------------------------------ + +String SwDBNextSetField::Expand() const +{ + return aEmptyStr; +} + +//------------------------------------------------------------------------------ + +SwField* SwDBNextSetField::Copy() const +{ + SwDBNextSetField *pTmp = new SwDBNextSetField((SwDBNextSetFieldType*)GetTyp(), + aCond, aEmptyStr, GetDBData()); + pTmp->SetSubType(GetSubType()); + pTmp->bCondValid = bCondValid; + return pTmp; +} +//------------------------------------------------------------------------------ + +void SwDBNextSetField::Evaluate(SwDoc* pDoc) +{ + SwNewDBMgr* pMgr = pDoc->GetNewDBMgr(); + const SwDBData& rData = GetDBData(); + if( !bCondValid || + !pMgr || !pMgr->IsDataSourceOpen(rData.sDataSource, rData.sCommand, sal_False)) + return ; + pMgr->ToNextRecord(rData.sDataSource, rData.sCommand); +} + +/*-------------------------------------------------------------------- + Beschreibung: Bedingung + --------------------------------------------------------------------*/ + +const String& SwDBNextSetField::GetPar1() const +{ + return aCond; +} + +void SwDBNextSetField::SetPar1(const String& rStr) +{ + aCond = rStr; +} +/*-----------------06.03.98 16:16------------------- + +--------------------------------------------------*/ +BOOL SwDBNextSetField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + BOOL bRet = TRUE; + switch( nWhichId ) + { + case FIELD_PROP_PAR3: + rAny <<= OUString(aCond); + break; + default: + bRet = SwDBNameInfField::QueryValue( rAny, nWhichId ); + } + return bRet; +} +/*-----------------06.03.98 16:16------------------- + +--------------------------------------------------*/ +BOOL SwDBNextSetField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + BOOL bRet = TRUE; + switch( nWhichId ) + { + case FIELD_PROP_PAR3: + ::GetString( rAny, aCond ); + break; + default: + bRet = SwDBNameInfField::PutValue( rAny, nWhichId ); + } + return bRet; +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ +/* +String SwDBNextSetField::GetPar2() const +{ + return GetDBName(); +} + +void SwDBNextSetField::SetPar2(const String& rStr) +{ + GetDBName() = rStr; +} +*/ + +/*-------------------------------------------------------------------- + Beschreibung: Datensatz mit bestimmter ID + --------------------------------------------------------------------*/ + +SwDBNumSetFieldType::SwDBNumSetFieldType() : + SwFieldType( RES_DBNUMSETFLD ) +{ +} + +//------------------------------------------------------------------------------ + +SwFieldType* SwDBNumSetFieldType::Copy() const +{ + SwDBNumSetFieldType* pTmp = new SwDBNumSetFieldType(); + return pTmp; +} + +/*-------------------------------------------------------------------- + Beschreibung: SwDBSetField + --------------------------------------------------------------------*/ + +SwDBNumSetField::SwDBNumSetField(SwDBNumSetFieldType* pTyp, + const String& rCond, + const String& rDBNum, + const SwDBData& rDBData) : + SwDBNameInfField(pTyp, rDBData), + aCond(rCond), + aPar2(rDBNum), + bCondValid(TRUE) +{} + +//------------------------------------------------------------------------------ + +String SwDBNumSetField::Expand() const +{ + return aEmptyStr; +} + +//------------------------------------------------------------------------------ + +SwField* SwDBNumSetField::Copy() const +{ + SwDBNumSetField *pTmp = new SwDBNumSetField((SwDBNumSetFieldType*)GetTyp(), + aCond, aPar2, GetDBData()); + pTmp->bCondValid = bCondValid; + pTmp->SetSubType(GetSubType()); + return pTmp; +} + +void SwDBNumSetField::Evaluate(SwDoc* pDoc) +{ + SwNewDBMgr* pMgr = pDoc->GetNewDBMgr(); + const SwDBData& aTmpData = GetDBData(); + + if( bCondValid && pMgr && pMgr->IsInMerge() && + pMgr->IsDataSourceOpen(aTmpData.sDataSource, aTmpData.sCommand, sal_True)) + { // Bedingug OK -> aktuellen Set einstellen + pMgr->ToRecordId(Max((USHORT)aPar2.ToInt32(), USHORT(1))-1); + } +} + +/*-------------------------------------------------------------------- + Beschreibung: LogDBName + --------------------------------------------------------------------*/ + +const String& SwDBNumSetField::GetPar1() const +{ + return aCond; +} + +void SwDBNumSetField::SetPar1(const String& rStr) +{ + aCond = rStr; +} + +/*-------------------------------------------------------------------- + Beschreibung: Bedingung + --------------------------------------------------------------------*/ + +String SwDBNumSetField::GetPar2() const +{ + return aPar2; +} + +void SwDBNumSetField::SetPar2(const String& rStr) +{ + aPar2 = rStr; +} +/*-----------------06.03.98 16:16------------------- + +--------------------------------------------------*/ +BOOL SwDBNumSetField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + BOOL bRet = TRUE; + switch( nWhichId ) + { + case FIELD_PROP_PAR3: + rAny <<= OUString(aCond); + break; + case FIELD_PROP_FORMAT: + rAny <<= (sal_Int32)aPar2.ToInt32(); + break; + default: + bRet = SwDBNameInfField::QueryValue(rAny, nWhichId ); + } + return bRet; +} +/*-----------------06.03.98 16:16------------------- + +--------------------------------------------------*/ +BOOL SwDBNumSetField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + BOOL bRet = TRUE; + switch( nWhichId ) + { + case FIELD_PROP_PAR3: + ::GetString( rAny, aCond ); + break; + case FIELD_PROP_FORMAT: + { + sal_Int32 nVal = 0; + rAny >>= nVal; + aPar2 = String::CreateFromInt32(nVal); + } + break; + default: + bRet = SwDBNameInfField::PutValue(rAny, nWhichId ); + } + return bRet; +} + +/*-------------------------------------------------------------------- + Beschreibung: SwDBNameFieldType + --------------------------------------------------------------------*/ + +SwDBNameFieldType::SwDBNameFieldType(SwDoc* pDocument) + : SwFieldType( RES_DBNAMEFLD ) +{ + pDoc = pDocument; +} +//------------------------------------------------------------------------------ + +String SwDBNameFieldType::Expand(ULONG ) const +{ + const SwDBData aData = pDoc->GetDBData(); + String sRet(aData.sDataSource); + sRet += '.'; + sRet += (String)aData.sCommand; + return sRet; +} +//------------------------------------------------------------------------------ + +SwFieldType* SwDBNameFieldType::Copy() const +{ + SwDBNameFieldType *pTmp = new SwDBNameFieldType(pDoc); + return pTmp; +} + +//------------------------------------------------------------------------------ + +/*-------------------------------------------------------------------- + Beschreibung: Name der angedockten DB + --------------------------------------------------------------------*/ + +SwDBNameField::SwDBNameField(SwDBNameFieldType* pTyp, const SwDBData& rDBData, ULONG nFmt) + : SwDBNameInfField(pTyp, rDBData, nFmt) +{} + +//------------------------------------------------------------------------------ + +String SwDBNameField::Expand() const +{ + String sRet; + if(0 ==(GetSubType() & nsSwExtendedSubType::SUB_INVISIBLE)) + sRet = ((SwDBNameFieldType*)GetTyp())->Expand(GetFormat()); + return sRet; +} + +//------------------------------------------------------------------------------ + +SwField* SwDBNameField::Copy() const +{ + SwDBNameField *pTmp = new SwDBNameField((SwDBNameFieldType*)GetTyp(), GetDBData()); + pTmp->ChangeFormat(GetFormat()); + pTmp->SetLanguage(GetLanguage()); + pTmp->SetSubType(GetSubType()); + return pTmp; +} + +/*-----------------06.03.98 16:16------------------- + +--------------------------------------------------*/ +BOOL SwDBNameField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + return SwDBNameInfField::QueryValue(rAny, nWhichId ); +} +/*-----------------06.03.98 16:16------------------- + +--------------------------------------------------*/ +BOOL SwDBNameField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + return SwDBNameInfField::PutValue(rAny, nWhichId ); +} +/*-------------------------------------------------------------------- + Beschreibung: SwDBNameFieldType + --------------------------------------------------------------------*/ + +SwDBSetNumberFieldType::SwDBSetNumberFieldType() + : SwFieldType( RES_DBSETNUMBERFLD ) +{ +} + +//------------------------------------------------------------------------------ + +SwFieldType* SwDBSetNumberFieldType::Copy() const +{ + SwDBSetNumberFieldType *pTmp = new SwDBSetNumberFieldType; + return pTmp; +} + +//------------------------------------------------------------------------------ + +/*-------------------------------------------------------------------- + Beschreibung: SetNumber der angedockten DB + --------------------------------------------------------------------*/ + +SwDBSetNumberField::SwDBSetNumberField(SwDBSetNumberFieldType* pTyp, + const SwDBData& rDBData, + ULONG nFmt) + : SwDBNameInfField(pTyp, rDBData, nFmt), nNumber(0) +{} + +//------------------------------------------------------------------------------ + +String SwDBSetNumberField::Expand() const +{ + if(0 !=(GetSubType() & nsSwExtendedSubType::SUB_INVISIBLE) || nNumber == 0) + return aEmptyStr; + else + return FormatNumber((USHORT)nNumber, GetFormat()); + //return(nNumber == 0 ? aEmptyStr : FormatNumber(nNumber, GetFormat())); +} + +//------------------------------------------------------------------------------ + +void SwDBSetNumberField::Evaluate(SwDoc* pDoc) +{ + SwNewDBMgr* pMgr = pDoc->GetNewDBMgr(); + + const SwDBData& aTmpData = GetDBData(); + if (!pMgr || !pMgr->IsInMerge() || + !pMgr->IsDataSourceOpen(aTmpData.sDataSource, aTmpData.sCommand, sal_False)) + return; + nNumber = pMgr->GetSelectedRecordId(); +} + + +//------------------------------------------------------------------------------ + +SwField* SwDBSetNumberField::Copy() const +{ + SwDBSetNumberField *pTmp = + new SwDBSetNumberField((SwDBSetNumberFieldType*)GetTyp(), GetDBData(), GetFormat()); + pTmp->SetLanguage(GetLanguage()); + pTmp->SetSetNumber(nNumber); + pTmp->SetSubType(GetSubType()); + return pTmp; +} +/*-----------------06.03.98 16:15------------------- + +--------------------------------------------------*/ +BOOL SwDBSetNumberField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + BOOL bRet = TRUE; + switch( nWhichId ) + { + case FIELD_PROP_USHORT1: + rAny <<= (sal_Int16)GetFormat(); + break; + case FIELD_PROP_FORMAT: + rAny <<= nNumber; + break; + default: + bRet = SwDBNameInfField::QueryValue( rAny, nWhichId ); + } + return bRet; +} +/*-----------------06.03.98 16:15------------------- + +--------------------------------------------------*/ +BOOL SwDBSetNumberField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + BOOL bRet = TRUE; + switch( nWhichId ) + { + case FIELD_PROP_USHORT1: + { + sal_Int16 nSet = 0; + rAny >>= nSet; + if(nSet < (INT16) SVX_NUMBER_NONE ) + SetFormat(nSet); + else { + //exception(wrong_value) + ; + } + } + break; + case FIELD_PROP_FORMAT: + rAny >>= nNumber; + break; + default: + bRet = SwDBNameInfField::PutValue( rAny, nWhichId ); + } + return bRet; +} + + diff --git a/sw/source/core/fields/ddefld.cxx b/sw/source/core/fields/ddefld.cxx new file mode 100644 index 000000000000..c9811352b062 --- /dev/null +++ b/sw/source/core/fields/ddefld.cxx @@ -0,0 +1,450 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + + +#include <sfx2/linkmgr.hxx> +#include <doc.hxx> +#include <editsh.hxx> +#include <errhdl.hxx> +#include <ndtxt.hxx> +#include <fmtfld.hxx> +#include <txtfld.hxx> +#include <ddefld.hxx> +#include <swtable.hxx> +#include <swbaslnk.hxx> +#include <swddetbl.hxx> +#ifndef _UNOFLDMID_H +#include <unofldmid.h> +#endif +#include <hints.hxx> + +using rtl::OUString; +using namespace ::com::sun::star; + +#define DDE_TXT_ENCODING gsl_getSystemTextEncoding() + +/*-------------------------------------------------------------------- + Beschreibung: Globale Variablen + --------------------------------------------------------------------*/ + +class SwIntrnlRefLink : public SwBaseLink +{ + SwDDEFieldType& rFldType; +public: + SwIntrnlRefLink( SwDDEFieldType& rType, USHORT nUpdateType, USHORT nFmt ) + : SwBaseLink( nUpdateType, nFmt ), + rFldType( rType ) + {} + + virtual void Closed(); + virtual void DataChanged( const String& rMimeType, + const uno::Any & rValue ); + + virtual const SwNode* GetAnchor() const; + virtual BOOL IsInRange( ULONG nSttNd, ULONG nEndNd, xub_StrLen nStt = 0, + xub_StrLen nEnd = STRING_NOTFOUND ) const; +}; + + +void SwIntrnlRefLink::DataChanged( const String& rMimeType, + const uno::Any & rValue ) +{ + switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) ) + { + case FORMAT_STRING: + if( !IsNoDataFlag() ) + { + uno::Sequence< sal_Int8 > aSeq; + rValue >>= aSeq; + String sStr( (sal_Char*)aSeq.getConstArray(), static_cast<xub_StrLen>(aSeq.getLength()), + DDE_TXT_ENCODING ); + + // CR-LF am Ende entfernen, ist ueberfluessig! + xub_StrLen n = sStr.Len(); + while( n && 0 == sStr.GetChar( n-1 ) ) + --n; + if( n && 0x0a == sStr.GetChar( n-1 ) ) + --n; + if( n && 0x0d == sStr.GetChar( n-1 ) ) + --n; + + BOOL bDel = n != sStr.Len(); + if( bDel ) + sStr.Erase( n ); + + rFldType.SetExpansion( sStr ); + // erst Expansion setzen! (sonst wird das Flag geloescht!) + rFldType.SetCRLFDelFlag( bDel ); + } + break; + + // weitere Formate ... + default: + return; + } + + ASSERT( rFldType.GetDoc(), "Kein pDoc" ); + + // keine Abhaengigen mehr? + if( rFldType.GetDepends() && !rFldType.IsModifyLocked() && !ChkNoDataFlag() ) + { + ViewShell* pSh; + SwEditShell* pESh = rFldType.GetDoc()->GetEditShell( &pSh ); + + // dann suchen wir uns mal alle Felder. Wird kein gueltiges + // gefunden, dann Disconnecten wir uns! + SwMsgPoolItem aUpdateDDE( RES_UPDATEDDETBL ); + int bCallModify = FALSE; + rFldType.LockModify(); + + SwClientIter aIter( rFldType ); + SwClient * pLast = aIter.GoStart(); + if( pLast ) // konnte zum Anfang gesprungen werden ?? + do { + // eine DDE-Tabelle oder ein DDE-FeldAttribut im Text + if( !pLast->IsA( TYPE( SwFmtFld ) ) || + ((SwFmtFld*)pLast)->GetTxtFld() ) + { + if( !bCallModify ) + { + if( pESh ) + pESh->StartAllAction(); + else if( pSh ) + pSh->StartAction(); + } + pLast->Modify( 0, &aUpdateDDE ); + bCallModify = TRUE; + } + } while( 0 != ( pLast = aIter++ )); + + rFldType.UnlockModify(); + + if( bCallModify ) + { + if( pESh ) + pESh->EndAllAction(); + else if( pSh ) + pSh->EndAction(); + + if( pSh ) + pSh->GetDoc()->SetModified(); + } + } +} + +void SwIntrnlRefLink::Closed() +{ + if( rFldType.GetDoc() && !rFldType.GetDoc()->IsInDtor() ) + { + // Advise verabschiedet sich, alle Felder in Text umwandeln ? + ViewShell* pSh; + SwEditShell* pESh = rFldType.GetDoc()->GetEditShell( &pSh ); + if( pESh ) + { + pESh->StartAllAction(); + pESh->FieldToText( &rFldType ); + pESh->EndAllAction(); + } + else + { + pSh->StartAction(); + // am Doc aufrufen ?? + pSh->EndAction(); + } + } + SvBaseLink::Closed(); +} + +const SwNode* SwIntrnlRefLink::GetAnchor() const +{ + // hier sollte irgend ein Anchor aus dem normalen Nodes-Array reichen + const SwNode* pNd = 0; + SwClientIter aIter( rFldType ); + SwClient * pLast = aIter.GoStart(); + if( pLast ) // konnte zum Anfang gesprungen werden ?? + do { + // eine DDE-Tabelle oder ein DDE-FeldAttribut im Text + if( !pLast->IsA( TYPE( SwFmtFld ) )) + { + SwDepend* pDep = (SwDepend*)pLast; + SwDDETable* pDDETbl = (SwDDETable*)pDep->GetToTell(); + pNd = pDDETbl->GetTabSortBoxes()[0]->GetSttNd(); + } + else if( ((SwFmtFld*)pLast)->GetTxtFld() ) + pNd = ((SwFmtFld*)pLast)->GetTxtFld()->GetpTxtNode(); + + if( pNd && &rFldType.GetDoc()->GetNodes() == &pNd->GetNodes() ) + break; + pNd = 0; + } while( 0 != ( pLast = aIter++ )); + + return pNd; +} + +BOOL SwIntrnlRefLink::IsInRange( ULONG nSttNd, ULONG nEndNd, + xub_StrLen nStt, xub_StrLen nEnd ) const +{ + // hier sollte irgend ein Anchor aus dem normalen Nodes-Array reichen + SwNodes* pNds = &rFldType.GetDoc()->GetNodes(); + SwClientIter aIter( rFldType ); + SwClient * pLast = aIter.GoStart(); + if( pLast ) // konnte zum Anfang gesprungen werden ?? + do { + // eine DDE-Tabelle oder ein DDE-FeldAttribut im Text + if( !pLast->IsA( TYPE( SwFmtFld ) )) + { + SwDepend* pDep = (SwDepend*)pLast; + SwDDETable* pDDETbl = (SwDDETable*)pDep->GetToTell(); + const SwTableNode* pTblNd = pDDETbl->GetTabSortBoxes()[0]-> + GetSttNd()->FindTableNode(); + if( pTblNd->GetNodes().IsDocNodes() && + nSttNd < pTblNd->EndOfSectionIndex() && + nEndNd > pTblNd->GetIndex() ) + return TRUE; + } + else if( ((SwFmtFld*)pLast)->GetTxtFld() ) + { + const SwTxtFld* pTFld = ((SwFmtFld*)pLast)->GetTxtFld(); + const SwTxtNode* pNd = pTFld->GetpTxtNode(); + if( pNd && pNds == &pNd->GetNodes() ) + { + ULONG nNdPos = pNd->GetIndex(); + if( nSttNd <= nNdPos && nNdPos <= nEndNd && + ( nNdPos != nSttNd || *pTFld->GetStart() >= nStt ) && + ( nNdPos != nEndNd || *pTFld->GetStart() < nEnd )) + return TRUE; + } + } + } while( 0 != ( pLast = aIter++ )); + + return FALSE; +} + +SwDDEFieldType::SwDDEFieldType(const String& rName, + const String& rCmd, USHORT nUpdateType ) + : SwFieldType( RES_DDEFLD ), + aName( rName ), pDoc( 0 ), nRefCnt( 0 ) +{ + bCRLFFlag = bDeleted = FALSE; + refLink = new SwIntrnlRefLink( *this, nUpdateType, FORMAT_STRING ); + SetCmd( rCmd ); +} + +SwDDEFieldType::~SwDDEFieldType() +{ + if( pDoc && !pDoc->IsInDtor() ) + pDoc->GetLinkManager().Remove( refLink ); + refLink->Disconnect(); +} + +SwFieldType* SwDDEFieldType::Copy() const +{ + SwDDEFieldType* pType = new SwDDEFieldType( aName, GetCmd(), GetType() ); + pType->aExpansion = aExpansion; + pType->bCRLFFlag = bCRLFFlag; + pType->bDeleted = bDeleted; + pType->SetDoc( pDoc ); + return pType; +} + +const String& SwDDEFieldType::GetName() const +{ + return aName; +} + +void SwDDEFieldType::SetCmd( const String& rStr ) +{ + String sCmd( rStr ); + xub_StrLen nPos; + while( STRING_NOTFOUND != (nPos = sCmd.SearchAscii( " " )) ) + sCmd.Erase( nPos, 1 ); + refLink->SetLinkSourceName( sCmd ); +} + +String SwDDEFieldType::GetCmd() const +{ + return refLink->GetLinkSourceName(); +} + +void SwDDEFieldType::SetDoc( SwDoc* pNewDoc ) +{ + if( pNewDoc == pDoc ) + return; + + if( pDoc && refLink.Is() ) + { + ASSERT( !nRefCnt, "wie kommen die Referenzen rueber?" ); + pDoc->GetLinkManager().Remove( refLink ); + } + + pDoc = pNewDoc; + if( pDoc && nRefCnt ) + { + refLink->SetVisible( pDoc->IsVisibleLinks() ); + pDoc->GetLinkManager().InsertDDELink( refLink ); + } +} + + +void SwDDEFieldType::_RefCntChgd() +{ + if( nRefCnt ) + { + refLink->SetVisible( pDoc->IsVisibleLinks() ); + pDoc->GetLinkManager().InsertDDELink( refLink ); + if( pDoc->GetRootFrm() ) + UpdateNow(); + } + else + { + Disconnect(); + pDoc->GetLinkManager().Remove( refLink ); + } +} +/* -----------------------------28.08.00 16:23-------------------------------- + + ---------------------------------------------------------------------------*/ +BOOL SwDDEFieldType::QueryValue( uno::Any& rVal, USHORT nWhichId ) const +{ + BYTE nPart = 0; + switch( nWhichId ) + { + case FIELD_PROP_PAR2: nPart = 3; break; + case FIELD_PROP_PAR4: nPart = 2; break; + case FIELD_PROP_SUBTYPE: nPart = 1; break; + case FIELD_PROP_BOOL1: + { + sal_Bool bSet = GetType() == sfx2::LINKUPDATE_ALWAYS ? TRUE : FALSE; + rVal.setValue(&bSet, ::getBooleanCppuType()); + } + break; + case FIELD_PROP_PAR5: + rVal <<= ::rtl::OUString(aExpansion); + break; + default: + DBG_ERROR("illegal property"); + } + if( nPart ) + rVal <<= OUString(GetCmd().GetToken(nPart-1, sfx2::cTokenSeperator)); + return TRUE; +} +/* -----------------------------28.08.00 16:23-------------------------------- + + ---------------------------------------------------------------------------*/ +BOOL SwDDEFieldType::PutValue( const uno::Any& rVal, USHORT nWhichId ) +{ + BYTE nPart = 0; + switch( nWhichId ) + { + case FIELD_PROP_PAR2: nPart = 3; break; + case FIELD_PROP_PAR4: nPart = 2; break; + case FIELD_PROP_SUBTYPE: nPart = 1; break; + case FIELD_PROP_BOOL1: + SetType( static_cast<USHORT>(*(sal_Bool*)rVal.getValue() ? + sfx2::LINKUPDATE_ALWAYS : + sfx2::LINKUPDATE_ONCALL ) ); + break; + case FIELD_PROP_PAR5: + { + ::rtl::OUString sTemp; + rVal >>= sTemp; + aExpansion = sTemp; + } + break; + default: + DBG_ERROR("illegal property"); + } + if( nPart ) + { + String sTmp, sCmd( GetCmd() ); + while(3 > sCmd.GetTokenCount(sfx2::cTokenSeperator)) + sCmd += sfx2::cTokenSeperator; + sCmd.SetToken( nPart-1, sfx2::cTokenSeperator, ::GetString( rVal, sTmp ) ); + SetCmd( sCmd ); + } + return TRUE; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwDDEField::SwDDEField( SwDDEFieldType* pInitType ) + : SwField(pInitType) +{ +} + +SwDDEField::~SwDDEField() +{ + if( GetTyp()->IsLastDepend() ) // der Letzte mach das + ((SwDDEFieldType*)GetTyp())->Disconnect(); // Licht aus +} + +String SwDDEField::Expand() const +{ + xub_StrLen nPos; + String aStr( ((SwDDEFieldType*)GetTyp())->GetExpansion() ); + + aStr.EraseAllChars( '\r' ); + while( (nPos = aStr.Search( '\t' )) != STRING_NOTFOUND ) + aStr.SetChar( nPos, ' ' ); + while( (nPos = aStr.Search( '\n' )) != STRING_NOTFOUND ) + aStr.SetChar( nPos, '|' ); + if( aStr.Len() && ( aStr.GetChar( aStr.Len()-1 ) == '|') ) + aStr.Erase( aStr.Len()-1, 1 ); + return aStr; +} + +SwField* SwDDEField::Copy() const +{ + return new SwDDEField((SwDDEFieldType*)GetTyp()); +} + +/*-------------------------------------------------------------------- + Beschreibung: Parameter des Typen erfragen + Name + --------------------------------------------------------------------*/ +const String& SwDDEField::GetPar1() const +{ + return ((SwDDEFieldType*)GetTyp())->GetName(); +} + +/*-------------------------------------------------------------------- + Beschreibung: Parameter des Typen erfragen + Commando + --------------------------------------------------------------------*/ +String SwDDEField::GetPar2() const +{ + return ((SwDDEFieldType*)GetTyp())->GetCmd(); +} + +void SwDDEField::SetPar2(const String& rStr) +{ + ((SwDDEFieldType*)GetTyp())->SetCmd(rStr); +} + diff --git a/sw/source/core/fields/ddetbl.cxx b/sw/source/core/fields/ddetbl.cxx new file mode 100644 index 000000000000..c10a8b18c5cb --- /dev/null +++ b/sw/source/core/fields/ddetbl.cxx @@ -0,0 +1,187 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + + +#include <frmfmt.hxx> +#include <doc.hxx> +#include <index.hxx> +#include <ndtxt.hxx> +#include <swtable.hxx> +#include <swddetbl.hxx> +#include <ddefld.hxx> // fuer den FieldType +#include <ndindex.hxx> +#include <fldupde.hxx> +#include <swtblfmt.hxx> + + +TYPEINIT1( SwDDETable, SwTable ); + + // Constructor movet alle Lines/Boxen aus der SwTable zu sich. + // Die SwTable ist danach Leer und muss geloescht werden. +SwDDETable::SwDDETable( SwTable& rTable, SwDDEFieldType* pDDEType, + BOOL bUpdate ) + : SwTable( rTable ), aDepend( this, pDDEType ) +{ + // Kopiere/move die Daten der Tabelle + aSortCntBoxes.Insert( &rTable.GetTabSortBoxes(), 0, + rTable.GetTabSortBoxes().Count() ); // move die Inh. Boxen + rTable.GetTabSortBoxes().Remove( (USHORT)0, rTable.GetTabSortBoxes().Count() ); + + aLines.Insert( &rTable.GetTabLines(),0 ); // move die Lines + rTable.GetTabLines().Remove( 0, rTable.GetTabLines().Count() ); + + if( aLines.Count() ) + { + const SwNode& rNd = *GetTabSortBoxes()[0]->GetSttNd(); + if( rNd.GetNodes().IsDocNodes() ) + { + // "aktivieren der Updates" (Modify nicht noch mal rufen) + aDepend.LockModify(); + pDDEType->IncRefCnt(); + aDepend.UnlockModify(); + + // Setzen der Werte in die einzelnen Boxen + // update box content only if update flag is set (false in import) + if (bUpdate) + ChangeContent(); + } + } +} + +__EXPORT SwDDETable::~SwDDETable() +{ + SwDDEFieldType* pFldTyp = (SwDDEFieldType*)aDepend.GetRegisteredIn(); + SwDoc* pDoc = GetFrmFmt()->GetDoc(); + if( !pDoc->IsInDtor() && aLines.Count() && + GetTabSortBoxes()[0]->GetSttNd()->GetNodes().IsDocNodes() ) + pFldTyp->DecRefCnt(); + + // sind wir der letzte Abhaengige vom "geloeschten Feld" dann loesche dieses + if( pFldTyp->IsDeleted() && pFldTyp->IsLastDepend() ) + { + pFldTyp->Remove( &aDepend ); + delete pFldTyp; + } +} + +void SwDDETable::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew ) +{ + if( pNew && RES_UPDATEDDETBL == pNew->Which() ) + ChangeContent(); + else + SwTable::Modify( pOld, pNew ); +} + +void SwDDETable::ChangeContent() +{ + ASSERT( GetFrmFmt(), "Kein FrameFormat" ); + + // Stehen wir im richtigen NodesArray (Wegen UNDO) + if( !aLines.Count() ) + return; + ASSERT( GetTabSortBoxes().Count(), "Tabelle ohne Inhalt?" ); + if( !GetTabSortBoxes()[0]->GetSttNd()->GetNodes().IsDocNodes() ) + return; + + // zugriff auf den DDEFldType + SwDDEFieldType* pDDEType = (SwDDEFieldType*)aDepend.GetRegisteredIn(); + + String aExpand = pDDEType->GetExpansion(); + aExpand.EraseAllChars( '\r' ); + + for( USHORT n = 0; n < aLines.Count(); ++n ) + { + String aLine = aExpand.GetToken( n, '\n' ); + SwTableLine* pLine = aLines[ n ]; + for( USHORT i = 0; i < pLine->GetTabBoxes().Count(); ++i ) + { + SwTableBox* pBox = pLine->GetTabBoxes()[ i ]; + ASSERT( pBox->GetSttIdx(), "keine InhaltsBox" ); + SwNodeIndex aNdIdx( *pBox->GetSttNd(), 1 ); + SwTxtNode* pTxtNode = aNdIdx.GetNode().GetTxtNode(); + ASSERT( pTxtNode, "Kein Node" ); + SwIndex aCntIdx( pTxtNode, 0 ); + pTxtNode->EraseText( aCntIdx ); + pTxtNode->InsertText( aLine.GetToken( i, '\t' ), aCntIdx ); + + SwTableBoxFmt* pBoxFmt = (SwTableBoxFmt*)pBox->GetFrmFmt(); + pBoxFmt->LockModify(); + pBoxFmt->ResetFmtAttr( RES_BOXATR_VALUE ); + pBoxFmt->UnlockModify(); + } + } + + const IDocumentSettingAccess* pIDSA = GetFrmFmt()->getIDocumentSettingAccess(); + SwDoc* pDoc = GetFrmFmt()->GetDoc(); + if( AUTOUPD_FIELD_AND_CHARTS == pIDSA->getFieldUpdateFlags(true) ) + pDoc->SetFieldsDirty( true, NULL, 0 ); +} + +SwDDEFieldType* SwDDETable::GetDDEFldType() +{ + return (SwDDEFieldType*)aDepend.GetRegisteredIn(); +} + +BOOL SwDDETable::NoDDETable() +{ + // suche den TabellenNode + ASSERT( GetFrmFmt(), "Kein FrameFormat" ); + SwDoc* pDoc = GetFrmFmt()->GetDoc(); + + // Stehen wir im richtigen NodesArray (Wegen UNDO) + if( !aLines.Count() ) + return FALSE; + ASSERT( GetTabSortBoxes().Count(), "Tabelle ohne Inhalt?" ); + SwNode* pNd = (SwNode*)GetTabSortBoxes()[0]->GetSttNd(); + if( !pNd->GetNodes().IsDocNodes() ) + return FALSE; + + SwTableNode* pTblNd = pNd->FindTableNode(); + ASSERT( pTblNd, "wo steht denn die Tabelle ?"); + + SwTable* pNewTbl = new SwTable( *this ); + + // Kopiere/move die Daten der Tabelle + pNewTbl->GetTabSortBoxes().Insert( &GetTabSortBoxes(), 0, + GetTabSortBoxes().Count() ); // move die Inh. Boxen + GetTabSortBoxes().Remove( (USHORT)0, GetTabSortBoxes().Count() ); + + pNewTbl->GetTabLines().Insert( &GetTabLines(),0 ); // move die Lines + GetTabLines().Remove( 0, GetTabLines().Count() ); + + if( pDoc->GetRootFrm() ) + ((SwDDEFieldType*)aDepend.GetRegisteredIn())->DecRefCnt(); + + pTblNd->SetNewTable( pNewTbl ); // setze die Tabelle + + return TRUE; +} + + diff --git a/sw/source/core/fields/docufld.cxx b/sw/source/core/fields/docufld.cxx new file mode 100644 index 000000000000..fba7115075e8 --- /dev/null +++ b/sw/source/core/fields/docufld.cxx @@ -0,0 +1,2793 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + +#include <textapi.hxx> + +#include <tools/pstm.hxx> +#include <hintids.hxx> +#include <com/sun/star/text/XText.hpp> +#include <com/sun/star/script/XTypeConverter.hpp> +#include <com/sun/star/text/SetVariableType.hpp> +#include <com/sun/star/text/XTextFieldsSupplier.hpp> +#include <com/sun/star/text/UserDataPart.hpp> +#include <com/sun/star/text/ChapterFormat.hpp> +#include <com/sun/star/text/XTextField.hpp> +#include <com/sun/star/text/PlaceholderType.hpp> +#include <com/sun/star/text/TemplateDisplayFormat.hpp> +#include <com/sun/star/text/UserFieldFormat.hpp> +#include <com/sun/star/text/PageNumberType.hpp> +#include <com/sun/star/text/ReferenceFieldPart.hpp> +#include <com/sun/star/text/FilenameDisplayFormat.hpp> +#include <com/sun/star/text/XDependentTextField.hpp> +#include <com/sun/star/text/DocumentStatistic.hpp> +#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> +#include <com/sun/star/document/XDocumentProperties.hpp> +#include <com/sun/star/util/Date.hpp> +#include <com/sun/star/util/Duration.hpp> +#include <unotools/localedatawrapper.hxx> +#include <editeng/unolingu.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/types.hxx> +#include <comphelper/string.hxx> +#include <tools/urlobj.hxx> +#include <vcl/svapp.hxx> +#include <svl/urihelper.hxx> +#include <unotools/useroptions.hxx> +#include <unotools/syslocale.hxx> +#include <svl/zforlist.hxx> + +#include <tools/time.hxx> +#include <tools/datetime.hxx> + +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/util/Date.hpp> +#include <com/sun/star/util/DateTime.hpp> +#include <com/sun/star/util/Time.hpp> + +#include <tools/shl.hxx> +#include <swmodule.hxx> +#include <sfx2/app.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/doctempl.hxx> +#include <fmtfld.hxx> +#include <txtfld.hxx> +#include <charfmt.hxx> +#include <docstat.hxx> +#include <pagedesc.hxx> +#include <fmtpdsc.hxx> +#include <doc.hxx> +#include <rootfrm.hxx> // AuthorField +#include <pagefrm.hxx> // +#include <cntfrm.hxx> // +#include <pam.hxx> +#include <viewsh.hxx> +#include <dbmgr.hxx> +#include <shellres.hxx> +#include <docufld.hxx> +#include <flddat.hxx> +#include <docfld.hxx> +#include <ndtxt.hxx> +#include <expfld.hxx> +#include <poolfmt.hxx> +#include <docsh.hxx> +#include <unofldmid.h> +#include <swunohelper.hxx> +#include <comcore.hrc> + +#include <editeng/outliner.hxx> +#include <editeng/outlobj.hxx> + +#define URL_DECODE INetURLObject::DECODE_UNAMBIGUOUS + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace nsSwDocInfoSubType; + +/*-------------------------------------------------------------------- + Beschreibung: SwPageNumberFieldType + --------------------------------------------------------------------*/ + +SwPageNumberFieldType::SwPageNumberFieldType() + : SwFieldType( RES_PAGENUMBERFLD ), + nNumberingType( SVX_NUM_ARABIC ), + nNum( 0 ), + nMax( USHRT_MAX ), + bVirtuell( sal_False ) +{ +} + +String& SwPageNumberFieldType::Expand( sal_uInt32 nFmt, short nOff, + const String& rUserStr, String& rRet ) const +{ + sal_uInt32 nTmpFmt = (SVX_NUM_PAGEDESC == nFmt) ? (sal_uInt32)nNumberingType : nFmt; + long nTmp = nNum + nOff; + + if( 0 >= nTmp || SVX_NUM_NUMBER_NONE == nTmpFmt || (!bVirtuell && nTmp > nMax) ) + rRet = aEmptyStr; + else if( SVX_NUM_CHAR_SPECIAL == nTmpFmt ) + rRet = rUserStr; + else + rRet = FormatNumber( (sal_uInt16)nTmp, nTmpFmt ); + return rRet; +} + +SwFieldType* SwPageNumberFieldType::Copy() const +{ + SwPageNumberFieldType *pTmp = new SwPageNumberFieldType(); + + pTmp->nNum = nNum; + pTmp->nMax = nMax; + pTmp->nNumberingType = nNumberingType; + pTmp->bVirtuell = bVirtuell; + + return pTmp; +} + +/*-------------------------------------------------------------------- + Beschreibung: Verschiedene Expandierung + --------------------------------------------------------------------*/ + +void SwPageNumberFieldType::ChangeExpansion( SwDoc* pDoc, sal_uInt16 nPage, + sal_uInt16 nNumPages, sal_Bool bVirt, + const sal_Int16* pNumFmt ) +{ + nNum = nPage; + nMax = nNumPages; + if( pNumFmt ) + nNumberingType = *pNumFmt; + + bVirtuell = sal_False; + if( bVirt ) + { + // dann muss das Flag ueberprueft werden, denn das Layout setzt + // es NIE zurueck + const SfxItemPool &rPool = pDoc->GetAttrPool(); + const SwFmtPageDesc *pDesc; + sal_uInt16 nMaxItems = rPool.GetItemCount( RES_PAGEDESC ); + for( sal_uInt16 n = 0; n < nMaxItems; ++n ) + if( 0 != (pDesc = (SwFmtPageDesc*)rPool.GetItem( RES_PAGEDESC, n ) ) + && pDesc->GetNumOffset() && pDesc->GetDefinedIn() ) + { + if( pDesc->GetDefinedIn()->ISA( SwCntntNode )) + { + SwClientIter aIter( *(SwModify*)pDesc->GetDefinedIn() ); + if( aIter.First( TYPE( SwFrm ) ) ) + { + bVirtuell = sal_True; + break; + } + } + else if( pDesc->GetDefinedIn()->ISA( SwFmt )) + { + SwAutoFmtGetDocNode aGetHt( &pDoc->GetNodes() ); + bVirtuell = !pDesc->GetDefinedIn()->GetInfo( aGetHt ); + break; + } + } + } +} + +/*-------------------------------------------------------------------- + Beschreibung: SwPageNumberField + --------------------------------------------------------------------*/ + +SwPageNumberField::SwPageNumberField(SwPageNumberFieldType* pTyp, + sal_uInt16 nSub, sal_uInt32 nFmt, short nOff) + : SwField(pTyp, nFmt), nSubType(nSub), nOffset(nOff) +{ +} + +String SwPageNumberField::Expand() const +{ + String sRet; + SwPageNumberFieldType* pFldType = (SwPageNumberFieldType*)GetTyp(); + + if( PG_NEXT == nSubType && 1 != nOffset ) + { + if( pFldType->Expand( GetFormat(), 1, sUserStr, sRet ).Len() ) + pFldType->Expand( GetFormat(), nOffset, sUserStr, sRet ); + } + else if( PG_PREV == nSubType && -1 != nOffset ) + { + if( pFldType->Expand( GetFormat(), -1, sUserStr, sRet ).Len() ) + pFldType->Expand( GetFormat(), nOffset, sUserStr, sRet ); + } + else + pFldType->Expand( GetFormat(), nOffset, sUserStr, sRet ); + return sRet; +} + +SwField* SwPageNumberField::Copy() const +{ + SwPageNumberField *pTmp = + new SwPageNumberField((SwPageNumberFieldType*)GetTyp(), nSubType, GetFormat(), nOffset); + pTmp->SetLanguage( GetLanguage() ); + pTmp->SetUserString( sUserStr ); + return pTmp; +} + +String SwPageNumberField::GetPar2() const +{ + return String::CreateFromInt32(nOffset); +} + +void SwPageNumberField::SetPar2(const String& rStr) +{ + nOffset = (short)rStr.ToInt32(); +} + +sal_uInt16 SwPageNumberField::GetSubType() const +{ + return nSubType; +} + +/*-----------------05.03.98 10:25------------------- + +--------------------------------------------------*/ +BOOL SwPageNumberField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_FORMAT: + rAny <<= (sal_Int16)GetFormat(); + break; + case FIELD_PROP_USHORT1: + rAny <<= nOffset; + break; + case FIELD_PROP_SUBTYPE: + { + text::PageNumberType eType; + eType = text::PageNumberType_CURRENT; + if(nSubType == PG_PREV) + eType = text::PageNumberType_PREV; + else if(nSubType == PG_NEXT) + eType = text::PageNumberType_NEXT; + rAny.setValue(&eType, ::getCppuType((const text::PageNumberType*)0)); + } + break; + case FIELD_PROP_PAR1: + rAny <<= OUString(sUserStr); + break; + + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} +/*-----------------05.03.98 10:25------------------- + +--------------------------------------------------*/ +BOOL SwPageNumberField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + BOOL bRet = TRUE; + sal_Int16 nSet = 0; + switch( nWhichId ) + { + case FIELD_PROP_FORMAT: + rAny >>= nSet; + + // TODO: woher kommen die defines? + if(nSet <= SVX_NUM_PAGEDESC ) + SetFormat(nSet); + else { + //exception(wrong_value) + ; + } + break; + case FIELD_PROP_USHORT1: + rAny >>= nSet; + nOffset = nSet; + break; + case FIELD_PROP_SUBTYPE: + switch( SWUnoHelper::GetEnumAsInt32( rAny ) ) + { + case text::PageNumberType_CURRENT: + nSubType = PG_RANDOM; + break; + case text::PageNumberType_PREV: + nSubType = PG_PREV; + break; + case text::PageNumberType_NEXT: + nSubType = PG_NEXT; + break; + default: + bRet = FALSE; + } + break; + case FIELD_PROP_PAR1: + ::GetString( rAny, sUserStr ); + break; + + default: + DBG_ERROR("illegal property"); + } + return bRet; +} +/*-------------------------------------------------------------------- + Beschreibung: SwAuthorFieldType + --------------------------------------------------------------------*/ + +SwAuthorFieldType::SwAuthorFieldType() + : SwFieldType( RES_AUTHORFLD ) +{ +} + +String SwAuthorFieldType::Expand(ULONG nFmt) const +{ + String sRet; + SvtUserOptions& rOpt = SW_MOD()->GetUserOptions(); + if((nFmt & 0xff) == AF_NAME) + sRet = rOpt.GetFullName(); + else + sRet = rOpt.GetID(); + return sRet; +} + +SwFieldType* SwAuthorFieldType::Copy() const +{ + return new SwAuthorFieldType; +} + +/*-------------------------------------------------------------------- + Beschreibung: SwAuthorField + --------------------------------------------------------------------*/ + +SwAuthorField::SwAuthorField(SwAuthorFieldType* pTyp, sal_uInt32 nFmt) + : SwField(pTyp, nFmt) +{ + aContent = ((SwAuthorFieldType*)GetTyp())->Expand(GetFormat()); +} + +String SwAuthorField::Expand() const +{ + if (!IsFixed()) + ((SwAuthorField*)this)->aContent = + ((SwAuthorFieldType*)GetTyp())->Expand(GetFormat()); + + return aContent; +} + +SwField* SwAuthorField::Copy() const +{ + SwAuthorField *pTmp = new SwAuthorField( (SwAuthorFieldType*)GetTyp(), + GetFormat()); + pTmp->SetExpansion(aContent); + return pTmp; +} + +/*-----------------05.03.98 11:15------------------- + +--------------------------------------------------*/ +BOOL SwAuthorField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + sal_Bool bVal; + switch( nWhichId ) + { + case FIELD_PROP_BOOL1: + bVal = (GetFormat() & 0xff) == AF_NAME; + rAny.setValue(&bVal, ::getBooleanCppuType()); + break; + + case FIELD_PROP_BOOL2: + bVal = IsFixed(); + rAny.setValue(&bVal, ::getBooleanCppuType()); + break; + + case FIELD_PROP_PAR1: + rAny <<= rtl::OUString(GetContent()); + break; + + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} +/*-----------------05.03.98 11:15------------------- + +--------------------------------------------------*/ +BOOL SwAuthorField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + switch( nWhichId ) + { + case FIELD_PROP_BOOL1: + SetFormat( *(sal_Bool*)rAny.getValue() ? AF_NAME : AF_SHORTCUT ); + break; + + case FIELD_PROP_BOOL2: + if( *(sal_Bool*)rAny.getValue() ) + SetFormat( GetFormat() | AF_FIXED); + else + SetFormat( GetFormat() & ~AF_FIXED); + break; + + case FIELD_PROP_PAR1: + ::GetString( rAny, aContent ); + break; + + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} + +/*-------------------------------------------------------------------- + Beschreibung: SwFileNameFieldType + --------------------------------------------------------------------*/ + +SwFileNameFieldType::SwFileNameFieldType(SwDoc *pDocument) + : SwFieldType( RES_FILENAMEFLD ) +{ + pDoc = pDocument; +} + +String SwFileNameFieldType::Expand(ULONG nFmt) const +{ + String aRet; + const SwDocShell* pDShell = pDoc->GetDocShell(); + if( pDShell && pDShell->HasName() ) + { + const INetURLObject& rURLObj = pDShell->GetMedium()->GetURLObject(); + switch( nFmt & ~FF_FIXED ) + { + case FF_PATH: + { + if( INET_PROT_FILE == rURLObj.GetProtocol() ) + { + INetURLObject aTemp(rURLObj); + aTemp.removeSegment(); + // #101947# last slash should belong to the pathname + aRet = aTemp.PathToFileName();//GetFull(); + } + else + { + aRet = URIHelper::removePassword( + rURLObj.GetMainURL( INetURLObject::NO_DECODE ), + INetURLObject::WAS_ENCODED, URL_DECODE ); + aRet.Erase( aRet.Search( String(rURLObj.GetLastName( + URL_DECODE )) ) ); + } + } + break; + + case FF_NAME: + aRet = rURLObj.GetLastName( URL_DECODE ); + break; + + case FF_NAME_NOEXT: + aRet = rURLObj.GetBase(); + break; + + default: + if( INET_PROT_FILE == rURLObj.GetProtocol() ) + aRet = rURLObj.GetFull(); + else + aRet = URIHelper::removePassword( + rURLObj.GetMainURL( INetURLObject::NO_DECODE ), + INetURLObject::WAS_ENCODED, URL_DECODE ); + } + } + return aRet; +} + +SwFieldType* SwFileNameFieldType::Copy() const +{ + SwFieldType *pTmp = new SwFileNameFieldType(pDoc); + return pTmp; +} +/*-------------------------------------------------------------------- + Beschreibung: SwFileNameField + --------------------------------------------------------------------*/ + +SwFileNameField::SwFileNameField(SwFileNameFieldType* pTyp, sal_uInt32 nFmt) + : SwField(pTyp, nFmt) +{ + aContent = ((SwFileNameFieldType*)GetTyp())->Expand(GetFormat()); +} + +String SwFileNameField::Expand() const +{ + if (!IsFixed()) + ((SwFileNameField*)this)->aContent = ((SwFileNameFieldType*)GetTyp())->Expand(GetFormat()); + + return aContent; +} + +SwField* SwFileNameField::Copy() const +{ + SwFileNameField *pTmp = + new SwFileNameField((SwFileNameFieldType*)GetTyp(), GetFormat()); + pTmp->SetExpansion(aContent); + + return pTmp; +} + +/*-----------------05.03.98 08:59------------------- + +--------------------------------------------------*/ +BOOL SwFileNameField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_FORMAT: + { + sal_Int16 nRet; + switch( GetFormat() &(~FF_FIXED) ) + { + case FF_PATH: + nRet = text::FilenameDisplayFormat::PATH; + break; + case FF_NAME_NOEXT: + nRet = text::FilenameDisplayFormat::NAME; + break; + case FF_NAME: + nRet = text::FilenameDisplayFormat::NAME_AND_EXT; + break; + default: nRet = text::FilenameDisplayFormat::FULL; + } + rAny <<= nRet; + } + break; + + case FIELD_PROP_BOOL2: + { + BOOL bVal = IsFixed(); + rAny.setValue(&bVal, ::getBooleanCppuType()); + } + break; + + case FIELD_PROP_PAR3: + rAny <<= OUString(GetContent()); + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} +/*-----------------05.03.98 09:01------------------- + +--------------------------------------------------*/ +BOOL SwFileNameField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + switch( nWhichId ) + { + case FIELD_PROP_FORMAT: + { + //JP 24.10.2001: int32 because in UnoField.cxx a putvalue is + // called with a int32 value! But normally we need + // here only a int16 + sal_Int32 nType = 0; + rAny >>= nType; + BOOL bFixed = IsFixed(); + switch( nType ) + { + case text::FilenameDisplayFormat::PATH: + nType = FF_PATH; + break; + case text::FilenameDisplayFormat::NAME: + nType = FF_NAME_NOEXT; + break; + case text::FilenameDisplayFormat::NAME_AND_EXT: + nType = FF_NAME; + break; + default: nType = FF_PATHNAME; + } + if(bFixed) + nType |= FF_FIXED; + SetFormat(nType); + } + break; + + case FIELD_PROP_BOOL2: + if( *(sal_Bool*)rAny.getValue() ) + SetFormat( GetFormat() | FF_FIXED); + else + SetFormat( GetFormat() & ~FF_FIXED); + break; + + case FIELD_PROP_PAR3: + ::GetString( rAny, aContent ); + break; + + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} +/*-------------------------------------------------------------------- + Beschreibung: SwTemplNameFieldType + --------------------------------------------------------------------*/ + +SwTemplNameFieldType::SwTemplNameFieldType(SwDoc *pDocument) + : SwFieldType( RES_TEMPLNAMEFLD ) +{ + pDoc = pDocument; +} + +String SwTemplNameFieldType::Expand(ULONG nFmt) const +{ + ASSERT( nFmt < FF_END, "Expand: kein guelt. Fmt!" ); + + String aRet; + SwDocShell *pDocShell(pDoc->GetDocShell()); + DBG_ASSERT(pDocShell, "no SwDocShell"); + if (pDocShell) { + uno::Reference<document::XDocumentPropertiesSupplier> xDPS( + pDocShell->GetModel(), uno::UNO_QUERY_THROW); + uno::Reference<document::XDocumentProperties> xDocProps( + xDPS->getDocumentProperties()); + DBG_ASSERT(xDocProps.is(), "Doc has no DocumentProperties"); + + if( FF_UI_NAME == nFmt ) + aRet = xDocProps->getTemplateName(); + else if( !xDocProps->getTemplateURL().equalsAscii("") ) + { + if( FF_UI_RANGE == nFmt ) + { + // fuers besorgen vom RegionNamen !! + SfxDocumentTemplates aFac; + aFac.Construct(); + String sTmp; + aFac.GetLogicNames( xDocProps->getTemplateURL(), aRet, sTmp ); + } + else + { + INetURLObject aPathName( xDocProps->getTemplateURL() ); + if( FF_NAME == nFmt ) + aRet = aPathName.GetName(URL_DECODE); + else if( FF_NAME_NOEXT == nFmt ) + aRet = aPathName.GetBase(); + else + { + if( FF_PATH == nFmt ) + { + aPathName.removeSegment(); + aRet = aPathName.GetFull(); + } + else + aRet = aPathName.GetFull(); + } + } + } + } + return aRet; +} + +SwFieldType* SwTemplNameFieldType::Copy() const +{ + SwFieldType *pTmp = new SwTemplNameFieldType(pDoc); + return pTmp; +} +/*-------------------------------------------------------------------- + Beschreibung: SwTemplNameField + --------------------------------------------------------------------*/ + +SwTemplNameField::SwTemplNameField(SwTemplNameFieldType* pTyp, sal_uInt32 nFmt) + : SwField(pTyp, nFmt) +{} + +String SwTemplNameField::Expand() const +{ + return((SwTemplNameFieldType*)GetTyp())->Expand(GetFormat()); +} + +SwField* SwTemplNameField::Copy() const +{ + SwTemplNameField *pTmp = + new SwTemplNameField((SwTemplNameFieldType*)GetTyp(), GetFormat()); + return pTmp; +} + +/*-----------------05.03.98 08:59------------------- + +--------------------------------------------------*/ +BOOL SwTemplNameField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch ( nWhichId ) + { + case FIELD_PROP_FORMAT: + { + sal_Int16 nRet; + switch( GetFormat() ) + { + case FF_PATH: nRet = text::FilenameDisplayFormat::PATH; break; + case FF_NAME_NOEXT: nRet = text::FilenameDisplayFormat::NAME; break; + case FF_NAME: nRet = text::FilenameDisplayFormat::NAME_AND_EXT; break; + case FF_UI_RANGE: nRet = text::TemplateDisplayFormat::AREA; break; + case FF_UI_NAME: nRet = text::TemplateDisplayFormat::TITLE; break; + default: nRet = text::FilenameDisplayFormat::FULL; + + } + rAny <<= nRet; + } + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} +/*-----------------05.03.98 09:01------------------- + +--------------------------------------------------*/ +BOOL SwTemplNameField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + switch ( nWhichId ) + { + case FIELD_PROP_FORMAT: + { + //JP 24.10.2001: int32 because in UnoField.cxx a putvalue is + // called with a int32 value! But normally we need + // here only a int16 + sal_Int32 nType = 0; + rAny >>= nType; + switch( nType ) + { + case text::FilenameDisplayFormat::PATH: + SetFormat(FF_PATH); + break; + case text::FilenameDisplayFormat::NAME: + SetFormat(FF_NAME_NOEXT); + break; + case text::FilenameDisplayFormat::NAME_AND_EXT: + SetFormat(FF_NAME); + break; + case text::TemplateDisplayFormat::AREA : + SetFormat(FF_UI_RANGE); + break; + case text::TemplateDisplayFormat::TITLE : + SetFormat(FF_UI_NAME); + break; + default: SetFormat(FF_PATHNAME); + } + } + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} +/*-------------------------------------------------------------------- + Beschreibung: SwDocStatFieldType + --------------------------------------------------------------------*/ + +SwDocStatFieldType::SwDocStatFieldType(SwDoc* pDocument) + : SwFieldType( RES_DOCSTATFLD ), nNumberingType( SVX_NUM_ARABIC ) +{ + pDoc = pDocument; +} + +String SwDocStatFieldType::Expand(sal_uInt16 nSubType, sal_uInt32 nFmt) const +{ + sal_uInt32 nVal = 0; + const SwDocStat& rDStat = pDoc->GetDocStat(); + switch( nSubType ) + { + case DS_TBL: nVal = rDStat.nTbl; break; + case DS_GRF: nVal = rDStat.nGrf; break; + case DS_OLE: nVal = rDStat.nOLE; break; + case DS_PARA: nVal = rDStat.nPara; break; + case DS_WORD: nVal = rDStat.nWord; break; + case DS_CHAR: nVal = rDStat.nChar; break; + case DS_PAGE: + if( pDoc->GetRootFrm() ) + ((SwDocStat &)rDStat).nPage = pDoc->GetRootFrm()->GetPageNum(); + nVal = rDStat.nPage; + if( SVX_NUM_PAGEDESC == nFmt ) + nFmt = (sal_uInt32)nNumberingType; + break; + default: + ASSERT( sal_False, "SwDocStatFieldType::Expand: unbekannter SubType" ); + } + + String sRet; + if( nVal <= SHRT_MAX ) + sRet = FormatNumber( (sal_uInt16)nVal, nFmt ); + else + sRet = String::CreateFromInt32( nVal ); + return sRet; +} + +SwFieldType* SwDocStatFieldType::Copy() const +{ + SwDocStatFieldType *pTmp = new SwDocStatFieldType(pDoc); + return pTmp; +} + +/*-------------------------------------------------------------------- + Beschreibung: SwDocStatFieldType + Aus historischen Gruenden steht in nFormat der + SubType + --------------------------------------------------------------------*/ + +SwDocStatField::SwDocStatField(SwDocStatFieldType* pTyp, sal_uInt16 nSub, sal_uInt32 nFmt) + : SwField(pTyp, nFmt), + nSubType(nSub) +{} + +String SwDocStatField::Expand() const +{ + return((SwDocStatFieldType*)GetTyp())->Expand(nSubType, GetFormat()); +} + +SwField* SwDocStatField::Copy() const +{ + SwDocStatField *pTmp = new SwDocStatField( + (SwDocStatFieldType*)GetTyp(), nSubType, GetFormat() ); + return pTmp; +} + +sal_uInt16 SwDocStatField::GetSubType() const +{ + return nSubType; +} + +void SwDocStatField::SetSubType(sal_uInt16 nSub) +{ + nSubType = nSub; +} + +void SwDocStatField::ChangeExpansion( const SwFrm* pFrm ) +{ + if( DS_PAGE == nSubType && SVX_NUM_PAGEDESC == GetFormat() ) + ((SwDocStatFieldType*)GetTyp())->SetNumFormat( + pFrm->FindPageFrm()->GetPageDesc()->GetNumType().GetNumberingType() ); +} + +/*-----------------05.03.98 11:38------------------- + +--------------------------------------------------*/ +BOOL SwDocStatField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch ( nWhichId ) + { + case FIELD_PROP_USHORT2: + rAny <<= (sal_Int16)GetFormat(); + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} +/*-----------------05.03.98 11:38------------------- + +--------------------------------------------------*/ +BOOL SwDocStatField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + BOOL bRet = FALSE; + switch ( nWhichId ) + { + case FIELD_PROP_USHORT2: + { + sal_Int16 nSet = 0; + rAny >>= nSet; + if(nSet <= SVX_NUM_CHARS_LOWER_LETTER_N && + nSet != SVX_NUM_CHAR_SPECIAL && + nSet != SVX_NUM_BITMAP) + { + SetFormat(nSet); + bRet = TRUE; + } + } + break; + + default: + DBG_ERROR("illegal property"); + } + return bRet; +} + +/*-------------------------------------------------------------------- + Beschreibung: DokumentinfoFields + --------------------------------------------------------------------*/ + +SwDocInfoFieldType::SwDocInfoFieldType(SwDoc* pDc) + : SwValueFieldType( pDc, RES_DOCINFOFLD ) +{ +} + +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwFieldType* SwDocInfoFieldType::Copy() const +{ + SwDocInfoFieldType* pTyp = new SwDocInfoFieldType(GetDoc()); + return pTyp; +} + +void lcl_GetLocalDataWrapper( ULONG nLang, + const LocaleDataWrapper **ppAppLocalData, + const LocaleDataWrapper **ppLocalData ) +{ + SvtSysLocale aLocale; + *ppAppLocalData = &aLocale.GetLocaleData(); + *ppLocalData = *ppAppLocalData; + if( nLang != SvxLocaleToLanguage( (*ppLocalData)->getLocale() ) ) + *ppLocalData = new LocaleDataWrapper( + ::comphelper::getProcessServiceFactory(), + SvxCreateLocale( static_cast<LanguageType>(nLang) ) ); +} + +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +String SwDocInfoFieldType::Expand( sal_uInt16 nSub, sal_uInt32 nFormat, + sal_uInt16 nLang, const String& rName ) const +{ + String aStr; + const LocaleDataWrapper *pAppLocalData = 0, *pLocalData = 0; + SwDocShell *pDocShell(GetDoc()->GetDocShell()); + DBG_ASSERT(pDocShell, "no SwDocShell"); + if (!pDocShell) { return aStr; } + + uno::Reference<document::XDocumentPropertiesSupplier> xDPS( + pDocShell->GetModel(), uno::UNO_QUERY_THROW); + uno::Reference<document::XDocumentProperties> xDocProps( + xDPS->getDocumentProperties()); + DBG_ASSERT(xDocProps.is(), "Doc has no DocumentProperties"); + + sal_uInt16 nExtSub = nSub & 0xff00; + nSub &= 0xff; // ExtendedSubTypes nicht beachten + + switch(nSub) + { + case DI_TITEL: aStr = xDocProps->getTitle(); break; + case DI_THEMA: aStr = xDocProps->getSubject(); break; + case DI_KEYS: aStr = ::comphelper::string::convertCommaSeparated( + xDocProps->getKeywords()); + break; + case DI_COMMENT:aStr = xDocProps->getDescription(); break; + case DI_DOCNO: aStr = String::CreateFromInt32( + xDocProps->getEditingCycles() ); + break; + case DI_EDIT: + if ( !nFormat ) + { + lcl_GetLocalDataWrapper( nLang, &pAppLocalData, &pLocalData ); + sal_Int32 dur = xDocProps->getEditingDuration(); + aStr = pLocalData->getTime( Time(dur/3600, (dur%3600)/60, dur%60), + sal_False, sal_False); + } + else + { + sal_Int32 dur = xDocProps->getEditingDuration(); + double fVal = Time(dur/3600, (dur%3600)/60, dur%60).GetTimeInDays(); + aStr = ExpandValue(fVal, nFormat, nLang); + } + break; + case DI_CUSTOM: + { + ::rtl::OUString sVal; + try + { + uno::Any aAny; + uno::Reference < beans::XPropertySet > xSet( + xDocProps->getUserDefinedProperties(), + uno::UNO_QUERY_THROW); + aAny = xSet->getPropertyValue( rName ); + + uno::Reference < script::XTypeConverter > xConverter( comphelper::getProcessServiceFactory() + ->createInstance(::rtl::OUString::createFromAscii("com.sun.star.script.Converter")), uno::UNO_QUERY ); + uno::Any aNew; + aNew = xConverter->convertToSimpleType( aAny, uno::TypeClass_STRING ); + aNew >>= sVal; + } + catch (uno::Exception&) {} + return sVal; + } + + default: + { + String aName( xDocProps->getAuthor() ); + util::DateTime uDT( xDocProps->getCreationDate() ); + Date aD(uDT.Day, uDT.Month, uDT.Year); + Time aT(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.HundredthSeconds); + DateTime aDate(aD,aT); + if( nSub == DI_CREATE ) + ; // das wars schon!! + else if( nSub == DI_CHANGE ) + { + aName = xDocProps->getModifiedBy(); + uDT = xDocProps->getModificationDate(); + Date bD(uDT.Day, uDT.Month, uDT.Year); + Time bT(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.HundredthSeconds); + DateTime bDate(bD,bT); + aDate = bDate; + } + else if( nSub == DI_PRINT ) + { + aName = xDocProps->getPrintedBy(); + uDT = xDocProps->getPrintDate(); + Date bD(uDT.Day, uDT.Month, uDT.Year); + Time bT(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.HundredthSeconds); + DateTime bDate(bD,bT); + aDate = bDate; + } + else + break; + + if (aDate.IsValid()) + { + switch (nExtSub & ~DI_SUB_FIXED) + { + case DI_SUB_AUTHOR: + aStr = aName; + break; + + case DI_SUB_TIME: + if (!nFormat) + { + lcl_GetLocalDataWrapper( nLang, &pAppLocalData, + &pLocalData ); + aStr = pLocalData->getTime( aDate, + sal_False, sal_False); + } + else + { + // Numberformatter anwerfen! + double fVal = SwDateTimeField::GetDateTime( GetDoc(), + aDate); + aStr = ExpandValue(fVal, nFormat, nLang); + } + break; + + case DI_SUB_DATE: + if (!nFormat) + { + lcl_GetLocalDataWrapper( nLang, &pAppLocalData, + &pLocalData ); + aStr = pLocalData->getDate( aDate ); + } + else + { + // Numberformatter anwerfen! + double fVal = SwDateTimeField::GetDateTime( GetDoc(), + aDate); + aStr = ExpandValue(fVal, nFormat, nLang); + } + break; + } + } + } + break; + } + + if( pAppLocalData != pLocalData ) + delete pLocalData; + + return aStr; +} + +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwDocInfoField::SwDocInfoField(SwDocInfoFieldType* pTyp, sal_uInt16 nSub, const String& rName, sal_uInt32 nFmt) : + SwValueField(pTyp, nFmt), nSubType(nSub) +{ + aName = rName; + aContent = ((SwDocInfoFieldType*)GetTyp())->Expand(nSubType, nFmt, GetLanguage(), aName); +} + +SwDocInfoField::SwDocInfoField(SwDocInfoFieldType* pTyp, sal_uInt16 nSub, const String& rName, const String& rValue, sal_uInt32 nFmt) : + SwValueField(pTyp, nFmt), nSubType(nSub) +{ + aName = rName; + aContent = rValue; +} + +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +template<class T> +double lcl_TimeToDouble( const T& rTime ) +{ + const double fMilliSecondsPerDay = 86400000.0; + return ((rTime.Hours*3600000)+(rTime.Minutes*60000)+(rTime.Seconds*1000)+(rTime.HundredthSeconds*10)) / fMilliSecondsPerDay; +} + +template<class D> +double lcl_DateToDouble( const D& rDate, const Date& rNullDate ) +{ + long nDate = Date::DateToDays( rDate.Day, rDate.Month, rDate.Year ); + long nNullDate = Date::DateToDays( rNullDate.GetDay(), rNullDate.GetMonth(), rNullDate.GetYear() ); + return double( nDate - nNullDate ); +} + +String SwDocInfoField::Expand() const +{ + if ( ( nSubType & 0xFF ) == DI_CUSTOM ) + { + // custom properties currently need special treatment + // we don't have a secure way to detect "real" custom properties in Word Import of text fields + // so we treat *every* unknown property as a custom property, even the "built-in" section in Word's document summary information stream + // as these properties have not been inserted when the document summary information was imported, we do it here + // this approach is still a lot better than the old one to import such fields as "user fields" and simple text + SwDocShell* pDocShell = GetDoc()->GetDocShell(); + if( !pDocShell ) + return aContent; + try + { + uno::Reference<document::XDocumentPropertiesSupplier> xDPS( pDocShell->GetModel(), uno::UNO_QUERY_THROW); + uno::Reference<document::XDocumentProperties> xDocProps( xDPS->getDocumentProperties()); + uno::Reference < beans::XPropertySet > xSet( xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); + uno::Reference < beans::XPropertySetInfo > xSetInfo = xSet->getPropertySetInfo(); + + uno::Any aAny; + if( xSetInfo->hasPropertyByName( aName ) ) + aAny = xSet->getPropertyValue( aName ); + if ( aAny.getValueType() != ::getVoidCppuType() ) + { + // "void" type means that the property has not been inserted until now + if ( !IsFixed() ) + { + // if the field is "fixed" we don't update it from the property + ::rtl::OUString sVal; + uno::Reference < script::XTypeConverter > xConverter( comphelper::getProcessServiceFactory() + ->createInstance(::rtl::OUString::createFromAscii("com.sun.star.script.Converter")), uno::UNO_QUERY ); + util::Date aDate; + util::DateTime aDateTime; + util::Duration aDuration; + if( aAny >>= aDate) + { + SvNumberFormatter* pFormatter = pDocShell->GetDoc()->GetNumberFormatter(); + Date* pNullDate = pFormatter->GetNullDate(); + sVal = ExpandValue( lcl_DateToDouble<util::Date>( aDate, *pNullDate ), GetFormat(), GetLanguage()); + } + else if( aAny >>= aDateTime ) + { + double fDateTime = lcl_TimeToDouble<util::DateTime>( aDateTime ); + SvNumberFormatter* pFormatter = pDocShell->GetDoc()->GetNumberFormatter(); + Date* pNullDate = pFormatter->GetNullDate(); + fDateTime += lcl_DateToDouble<util::DateTime>( aDateTime, *pNullDate ); + sVal = ExpandValue( fDateTime, GetFormat(), GetLanguage()); + } + else if( aAny >>= aDuration ) + { + String sText(aDuration.Negative ? '-' : '+'); + sText += ViewShell::GetShellRes()->sDurationFormat; + sText.SearchAndReplace(String::CreateFromAscii( "%1"), String::CreateFromInt32( aDuration.Years ) ); + sText.SearchAndReplace(String::CreateFromAscii( "%2"), String::CreateFromInt32( aDuration.Months ) ); + sText.SearchAndReplace(String::CreateFromAscii( "%3"), String::CreateFromInt32( aDuration.Days ) ); + sText.SearchAndReplace(String::CreateFromAscii( "%4"), String::CreateFromInt32( aDuration.Hours ) ); + sText.SearchAndReplace(String::CreateFromAscii( "%5"), String::CreateFromInt32( aDuration.Minutes) ); + sText.SearchAndReplace(String::CreateFromAscii( "%6"), String::CreateFromInt32( aDuration.Seconds) ); + sVal = sText; + } + else + { + uno::Any aNew = xConverter->convertToSimpleType( aAny, uno::TypeClass_STRING ); + aNew >>= sVal; + } + ((SwDocInfoField*)this)->aContent = sVal; + } + } + } + catch (uno::Exception&) {} + } + else if ( !IsFixed() ) + ((SwDocInfoField*)this)->aContent = ((SwDocInfoFieldType*)GetTyp())->Expand(nSubType, GetFormat(), GetLanguage(), aName); + + return aContent; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +String SwDocInfoField::GetCntnt(sal_Bool bName) const +{ + if ( bName ) + { + String aStr(SwFieldType::GetTypeStr(GetTypeId())); + aStr += ':'; + + sal_uInt16 nSub = nSubType & 0xff; + + switch(nSub) + { + case DI_CUSTOM: + aStr += aName; + break; + + default: + aStr += *ViewShell::GetShellRes()->aDocInfoLst[ nSub - DI_SUBTYPE_BEGIN ]; + break; + } + if( IsFixed() ) + ( aStr += ' ' ) += ViewShell::GetShellRes()->aFixedStr; + return aStr; + } + return Expand(); +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwField* SwDocInfoField::Copy() const +{ + SwDocInfoField* pFld = new SwDocInfoField((SwDocInfoFieldType*)GetTyp(), nSubType, aName, GetFormat()); + pFld->SetAutomaticLanguage(IsAutomaticLanguage()); + pFld->aContent = aContent; + + return pFld; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +sal_uInt16 SwDocInfoField::GetSubType() const +{ + return nSubType; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +void SwDocInfoField::SetSubType(sal_uInt16 nSub) +{ + nSubType = nSub; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +void SwDocInfoField::SetLanguage(sal_uInt16 nLng) +{ + if (!GetFormat()) + SwField::SetLanguage(nLng); + else + SwValueField::SetLanguage(nLng); +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +BOOL SwDocInfoField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + rAny <<= OUString(aContent); + break; + + case FIELD_PROP_PAR4: + rAny <<= OUString(aName); + break; + + case FIELD_PROP_USHORT1: + rAny <<= (sal_Int16)aContent.ToInt32(); + break; + + case FIELD_PROP_BOOL1: + { + sal_Bool bVal = 0 != (nSubType & DI_SUB_FIXED); + rAny.setValue(&bVal, ::getBooleanCppuType()); + } + break; + case FIELD_PROP_FORMAT: + rAny <<= (sal_Int32)GetFormat(); + break; + + case FIELD_PROP_DOUBLE: + { + double fVal = GetValue(); + rAny.setValue(&fVal, ::getCppuType(&fVal)); + } + break; + case FIELD_PROP_PAR3: + rAny <<= rtl::OUString(Expand()); + break; + case FIELD_PROP_BOOL2: + { + sal_uInt16 nExtSub = (nSubType & 0xff00) & ~DI_SUB_FIXED; + sal_Bool bVal = (nExtSub == DI_SUB_DATE); + rAny.setValue(&bVal, ::getBooleanCppuType()); + } + break; + default: + return SwField::QueryValue(rAny, nWhichId); + } + return sal_True; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +BOOL SwDocInfoField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + sal_Int32 nValue = 0; + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + if( nSubType & DI_SUB_FIXED ) + ::GetString( rAny, aContent ); + break; + + case FIELD_PROP_USHORT1: + if( nSubType & DI_SUB_FIXED ) + { + rAny >>= nValue; + aContent = String::CreateFromInt32(nValue); + } + break; + + case FIELD_PROP_BOOL1: + if(*(sal_Bool*)rAny.getValue()) + nSubType |= DI_SUB_FIXED; + else + nSubType &= ~DI_SUB_FIXED; + break; + case FIELD_PROP_FORMAT: + { + rAny >>= nValue; + if( nValue >= 0) + SetFormat(nValue); + } + break; + + case FIELD_PROP_PAR3: + ::GetString( rAny, aContent ); + break; + case FIELD_PROP_BOOL2: + nSubType &= 0xf0ff; + if(*(sal_Bool*)rAny.getValue()) + nSubType |= DI_SUB_DATE; + else + nSubType |= DI_SUB_TIME; + break; + default: + return SwField::PutValue(rAny, nWhichId); + } + return sal_True; +} + +/*-------------------------------------------------------------------- + Beschreibung: SwHiddenTxtFieldType by JP + --------------------------------------------------------------------*/ + +SwHiddenTxtFieldType::SwHiddenTxtFieldType( sal_Bool bSetHidden ) + : SwFieldType( RES_HIDDENTXTFLD ), bHidden( bSetHidden ) +{ +} + +SwFieldType* SwHiddenTxtFieldType::Copy() const +{ + return new SwHiddenTxtFieldType( bHidden ); +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +void SwHiddenTxtFieldType::SetHiddenFlag( sal_Bool bSetHidden ) +{ + if( bHidden != bSetHidden ) + { + bHidden = bSetHidden; + UpdateFlds(); // alle HiddenText benachrichtigen + } +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwHiddenTxtField::SwHiddenTxtField( SwHiddenTxtFieldType* pFldType, + sal_Bool bConditional, + const String& rCond, + const String& rStr, + sal_Bool bHidden, + sal_uInt16 nSub) : + SwField( pFldType ), aCond(rCond), nSubType(nSub), + bCanToggle(bConditional), bIsHidden(bHidden), bValid(sal_False) +{ + if(nSubType == TYP_CONDTXTFLD) + { + sal_uInt16 nPos = 0; + aTRUETxt = rStr.GetToken(0, '|', nPos); + + if(nPos != STRING_NOTFOUND) + { + aFALSETxt = rStr.GetToken(0, '|', nPos); + if(nPos != STRING_NOTFOUND) + { + aContent = rStr.GetToken(0, '|', nPos); + bValid = sal_True; + } + } + } + else + aTRUETxt = rStr; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwHiddenTxtField::SwHiddenTxtField( SwHiddenTxtFieldType* pFldType, + const String& rCond, + const String& rTrue, + const String& rFalse, + sal_uInt16 nSub) + : SwField( pFldType ), aTRUETxt(rTrue), aFALSETxt(rFalse), aCond(rCond), nSubType(nSub), + bIsHidden(sal_True), bValid(sal_False) +{ + bCanToggle = aCond.Len() > 0; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +String SwHiddenTxtField::Expand() const +{ + // Type: !Hidden -> immer anzeigen + // Hide -> Werte die Bedingung aus + + if( TYP_CONDTXTFLD == nSubType ) + { + if( bValid ) + return aContent; + + if( bCanToggle && !bIsHidden ) + return aTRUETxt; + } + else if( !((SwHiddenTxtFieldType*)GetTyp())->GetHiddenFlag() || + ( bCanToggle && bIsHidden )) + return aTRUETxt; + + return aFALSETxt; +} + +/*-------------------------------------------------------------------- + Beschreibung: Aktuellen Field-Value holen und cachen + --------------------------------------------------------------------*/ + +void SwHiddenTxtField::Evaluate(SwDoc* pDoc) +{ + ASSERT(pDoc, Wo ist das Dokument Seniore); + + if( TYP_CONDTXTFLD == nSubType ) + { + SwNewDBMgr* pMgr = pDoc->GetNewDBMgr(); + + bValid = sal_False; + String sTmpName; + + if (bCanToggle && !bIsHidden) + sTmpName = aTRUETxt; + else + sTmpName = aFALSETxt; + +// OS 21.08.97: #42943# Datenbankausdruecke muessen sich von +// einfachem Text unterscheiden. also wird der einfache Text +// bevorzugt in Anfuehrungszeichen gesetzt. +// Sind diese vorhanden werden umschliessende entfernt. +// Wenn nicht, dann wird auf die Tauglichkeit als Datenbankname +// geprueft. Nur wenn zwei oder mehr Punkte vorhanden sind und kein +// Anfuehrungszeichen enthalten ist, gehen wir von einer DB aus. + if(sTmpName.Len() > 1 && sTmpName.GetChar(0) == '\"' && + sTmpName.GetChar((sTmpName.Len() - 1))== '\"') + { + aContent = sTmpName.Copy(1, sTmpName.Len() - 2); + bValid = sal_True; + } + else if(sTmpName.Search('\"') == STRING_NOTFOUND && + sTmpName.GetTokenCount('.') > 2) + { + ::ReplacePoint(sTmpName); + if(sTmpName.GetChar(0) == '[' && sTmpName.GetChar(sTmpName.Len()-1) == ']') + { // Eckige Klammern entfernen + sTmpName.Erase(0, 1); + sTmpName.Erase(sTmpName.Len()-1, 1); + } + + if( pMgr) + { + String sDBName( GetDBName( sTmpName, pDoc )); + String sDataSource(sDBName.GetToken(0, DB_DELIM)); + String sDataTableOrQuery(sDBName.GetToken(1, DB_DELIM)); + if( pMgr->IsInMerge() && sDBName.Len() && + pMgr->IsDataSourceOpen( sDataSource, + sDataTableOrQuery, sal_False)) + { + double fNumber; + sal_uInt32 nTmpFormat; + pMgr->GetMergeColumnCnt(GetColumnName( sTmpName ), + GetLanguage(), aContent, &fNumber, &nTmpFormat ); + bValid = sal_True; + } + else if( sDBName.Len() && sDataSource.Len() && + sDataTableOrQuery.Len() ) + bValid = sal_True; + } + } + } +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +String SwHiddenTxtField::GetCntnt(sal_Bool bName) const +{ + if ( bName ) + { + String aStr(SwFieldType::GetTypeStr(nSubType)); + aStr += ' '; + aStr += aCond; + aStr += ' '; + aStr += aTRUETxt; + + if(nSubType == TYP_CONDTXTFLD) + { +static char __READONLY_DATA cTmp[] = " : "; + aStr.AppendAscii(cTmp); + aStr += aFALSETxt; + } + return aStr; + } + return Expand(); +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwField* SwHiddenTxtField::Copy() const +{ + SwHiddenTxtField* pFld = + new SwHiddenTxtField((SwHiddenTxtFieldType*)GetTyp(), aCond, + aTRUETxt, aFALSETxt); + pFld->bIsHidden = bIsHidden; + pFld->bValid = bValid; + pFld->aContent = aContent; + pFld->SetFormat(GetFormat()); + pFld->nSubType = nSubType; + return pFld; +} + + +/*-------------------------------------------------------------------- + Beschreibung: Bedingung setzen + --------------------------------------------------------------------*/ + +void SwHiddenTxtField::SetPar1(const String& rStr) +{ + aCond = rStr; + bCanToggle = aCond.Len() > 0; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +const String& SwHiddenTxtField::GetPar1() const +{ + return aCond; +} + +/*-------------------------------------------------------------------- + Beschreibung: True/False Text + --------------------------------------------------------------------*/ + +void SwHiddenTxtField::SetPar2(const String& rStr) +{ + if(nSubType == TYP_CONDTXTFLD) + { + sal_uInt16 nPos = rStr.Search('|'); + aTRUETxt = rStr.Copy(0, nPos); + + if(nPos != STRING_NOTFOUND) + aFALSETxt = rStr.Copy(nPos + 1); + } + else + aTRUETxt = rStr; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +String SwHiddenTxtField::GetPar2() const +{ + String aRet(aTRUETxt); + if(nSubType == TYP_CONDTXTFLD) + { + aRet += '|'; + aRet += aFALSETxt; + } + return aRet; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +sal_uInt16 SwHiddenTxtField::GetSubType() const +{ + return nSubType; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +BOOL SwHiddenTxtField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + const String* pOut = 0; + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + pOut = &aCond; + break; + case FIELD_PROP_PAR2: + pOut = &aTRUETxt; + break; + case FIELD_PROP_PAR3: + pOut = &aFALSETxt; + break; + case FIELD_PROP_PAR4 : + pOut = &aContent; + break; + case FIELD_PROP_BOOL1: + { + sal_Bool bHidden = bIsHidden; + rAny.setValue(&bHidden, ::getBooleanCppuType()); + } + break; + default: + DBG_ERROR("illegal property"); + } + if( pOut ) + rAny <<= OUString( *pOut ); + return sal_True; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +BOOL SwHiddenTxtField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + { + String sVal; + SetPar1(::GetString( rAny, sVal )); + } + break; + case FIELD_PROP_PAR2: + ::GetString( rAny, aTRUETxt ); + break; + case FIELD_PROP_PAR3: + ::GetString( rAny, aFALSETxt ); + break; + case FIELD_PROP_BOOL1: + bIsHidden = *(sal_Bool*)rAny.getValue(); + break; + case FIELD_PROP_PAR4: + ::GetString( rAny, aContent); + bValid = TRUE; + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} + +//------------------------------------------------------------------------------ + +String SwHiddenTxtField::GetColumnName(const String& rName) +{ + sal_uInt16 nPos = rName.Search(DB_DELIM); + if( STRING_NOTFOUND != nPos ) + { + nPos = rName.Search(DB_DELIM, nPos + 1); + + if( STRING_NOTFOUND != nPos ) + return rName.Copy(nPos + 1); + } + return rName; +} + +//------------------------------------------------------------------------------ + +String SwHiddenTxtField::GetDBName(const String& rName, SwDoc *pDoc) +{ + sal_uInt16 nPos = rName.Search(DB_DELIM); + if( STRING_NOTFOUND != nPos ) + { + nPos = rName.Search(DB_DELIM, nPos + 1); + + if( STRING_NOTFOUND != nPos ) + return rName.Copy( 0, nPos ); + } + SwDBData aData = pDoc->GetDBData(); + String sRet = aData.sDataSource; + sRet += DB_DELIM; + sRet += String(aData.sCommand); + return sRet; +} + +/*-------------------------------------------------------------------- + Beschreibung: Der Feldtyp fuer Zeilenhoehe 0 + --------------------------------------------------------------------*/ + +SwHiddenParaFieldType::SwHiddenParaFieldType() + : SwFieldType( RES_HIDDENPARAFLD ) +{ +} + +SwFieldType* SwHiddenParaFieldType::Copy() const +{ + SwHiddenParaFieldType* pTyp = new SwHiddenParaFieldType(); + return pTyp; +} + +/*-------------------------------------------------------------------- + Beschreibung: Das Feld Zeilenhoehe 0 + --------------------------------------------------------------------*/ + +SwHiddenParaField::SwHiddenParaField(SwHiddenParaFieldType* pTyp, const String& rStr) + : SwField(pTyp), aCond(rStr) +{ + bIsHidden = sal_False; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +String SwHiddenParaField::Expand() const +{ + return aEmptyStr; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwField* SwHiddenParaField::Copy() const +{ + SwHiddenParaField* pFld = new SwHiddenParaField((SwHiddenParaFieldType*)GetTyp(), aCond); + pFld->bIsHidden = bIsHidden; + + return pFld; +} +/*-----------------05.03.98 13:25------------------- + +--------------------------------------------------*/ +BOOL SwHiddenParaField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch ( nWhichId ) + { + case FIELD_PROP_PAR1: + rAny <<= OUString(aCond); + break; + case FIELD_PROP_BOOL1: + { + sal_Bool bHidden = bIsHidden; + rAny.setValue(&bHidden, ::getBooleanCppuType()); + } + break; + + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} +/*-----------------05.03.98 13:25------------------- + +--------------------------------------------------*/ +BOOL SwHiddenParaField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + switch ( nWhichId ) + { + case FIELD_PROP_PAR1: + ::GetString( rAny, aCond ); + break; + case FIELD_PROP_BOOL1: + bIsHidden = *(sal_Bool*)rAny.getValue(); + break; + + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} + +/*-------------------------------------------------------------------- + Beschreibung: Bedingung setzen + --------------------------------------------------------------------*/ + +void SwHiddenParaField::SetPar1(const String& rStr) +{ + aCond = rStr; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +const String& SwHiddenParaField::GetPar1() const +{ + return aCond; +} + +/*-------------------------------------------------------------------- + Beschreibung: PostIt + --------------------------------------------------------------------*/ + +SwPostItFieldType::SwPostItFieldType(SwDoc *pDoc) + : SwFieldType( RES_POSTITFLD ),mpDoc(pDoc) +{} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwFieldType* SwPostItFieldType::Copy() const +{ + return new SwPostItFieldType(mpDoc); +} + + +/*-------------------------------------------------------------------- + Beschreibung: SwPostItFieldType + --------------------------------------------------------------------*/ + +SwPostItField::SwPostItField( SwPostItFieldType* pT, + const String& rAuthor, const String& rTxt, const DateTime& rDateTime ) + : SwField( pT ), sTxt( rTxt ), sAuthor( rAuthor ), aDateTime( rDateTime ), mpText(0), m_pTextObject(0) +{ +} + + +SwPostItField::~SwPostItField() +{ + if ( m_pTextObject ) + { + m_pTextObject->DisposeEditSource(); + m_pTextObject->release(); + } +} + +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +String SwPostItField::Expand() const +{ + return aEmptyStr; +} + + +String SwPostItField::GetDescription() const +{ + return SW_RES(STR_NOTE); +} + +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwField* SwPostItField::Copy() const +{ + SwPostItField* pRet = new SwPostItField( (SwPostItFieldType*)GetTyp(), sAuthor, + sTxt, aDateTime); + if (mpText) + pRet->SetTextObject( new OutlinerParaObject(*mpText) ); + return pRet; +} +/*-------------------------------------------------------------------- + Beschreibung: Author setzen + --------------------------------------------------------------------*/ + +void SwPostItField::SetPar1(const String& rStr) +{ + sAuthor = rStr; +} + +const String& SwPostItField::GetPar1() const +{ + return sAuthor; +} + +/*-------------------------------------------------------------------- + Beschreibung: Text fuers PostIt setzen + --------------------------------------------------------------------*/ + +void SwPostItField::SetPar2(const String& rStr) +{ + sTxt = rStr; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +String SwPostItField::GetPar2() const +{ + return sTxt; +} + +const OutlinerParaObject* SwPostItField::GetTextObject() const +{ + return mpText; +} + +void SwPostItField::SetTextObject( OutlinerParaObject* pText ) +{ + delete mpText; + mpText = pText; +} + +sal_uInt32 SwPostItField::GetNumberOfParagraphs() const +{ + return (mpText) ? mpText->Count() : 1; +} + +/*-----------------05.03.98 13:42------------------- + +--------------------------------------------------*/ +BOOL SwPostItField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + rAny <<= OUString(sAuthor); + break; + case FIELD_PROP_PAR2: + { + rAny <<= OUString(sTxt); + break; + } + case FIELD_PROP_TEXT: + { + if ( !m_pTextObject ) + { + SwPostItFieldType* pGetType = (SwPostItFieldType*)GetTyp(); + SwDoc* pDoc = pGetType->GetDoc(); + SwTextAPIEditSource* pObj = new SwTextAPIEditSource( pDoc ); + const_cast <SwPostItField*> (this)->m_pTextObject = new SwTextAPIObject( pObj ); + m_pTextObject->acquire(); + } + + if ( mpText ) + m_pTextObject->SetText( *mpText ); + else + m_pTextObject->SetString( sTxt ); + + uno::Reference < text::XText > xText( m_pTextObject ); + rAny <<= xText; + break; + } + case FIELD_PROP_DATE: + { + util::Date aSetDate; + aSetDate.Day = aDateTime.GetDay(); + aSetDate.Month = aDateTime.GetMonth(); + aSetDate.Year = aDateTime.GetYear(); + rAny.setValue(&aSetDate, ::getCppuType((util::Date*)0)); + } + break; + case FIELD_PROP_DATE_TIME: + { + util::DateTime DateTimeValue; + DateTimeValue.HundredthSeconds = aDateTime.Get100Sec(); + DateTimeValue.Seconds = aDateTime.GetSec(); + DateTimeValue.Minutes = aDateTime.GetMin(); + DateTimeValue.Hours = aDateTime.GetHour(); + DateTimeValue.Day = aDateTime.GetDay(); + DateTimeValue.Month = aDateTime.GetMonth(); + DateTimeValue.Year = aDateTime.GetYear(); + rAny <<= DateTimeValue; + } + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} + + +/*-----------------05.03.98 13:42------------------- + +--------------------------------------------------*/ +BOOL SwPostItField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + ::GetString( rAny, sAuthor ); + break; + case FIELD_PROP_PAR2: + ::GetString( rAny, sTxt ); + //#i100374# new string via api, delete complex text object so SwPostItNote picks up the new string + if (mpText) + { + delete mpText; + mpText = 0; + } + break; + case FIELD_PROP_TEXT: + DBG_ERROR("Not implemented!"); + // ::GetString( rAny, sTxt ); + break; + case FIELD_PROP_DATE: + if( rAny.getValueType() == ::getCppuType((util::Date*)0) ) + { + util::Date aSetDate = *(util::Date*)rAny.getValue(); + aDateTime = Date(aSetDate.Day, aSetDate.Month, aSetDate.Year); + } + break; + case FIELD_PROP_DATE_TIME: + { + util::DateTime aDateTimeValue; + if(!(rAny >>= aDateTimeValue)) + return FALSE; + aDateTime.Set100Sec(aDateTimeValue.HundredthSeconds); + aDateTime.SetSec(aDateTimeValue.Seconds); + aDateTime.SetMin(aDateTimeValue.Minutes); + aDateTime.SetHour(aDateTimeValue.Hours); + aDateTime.SetDay(aDateTimeValue.Day); + aDateTime.SetMonth(aDateTimeValue.Month); + aDateTime.SetYear(aDateTimeValue.Year); + } + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} +/*-------------------------------------------------------------------- + Beschreibung: DokumentinfoFields + --------------------------------------------------------------------*/ + +SwExtUserFieldType::SwExtUserFieldType() + : SwFieldType( RES_EXTUSERFLD ) +{ +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwFieldType* SwExtUserFieldType::Copy() const +{ + SwExtUserFieldType* pTyp = new SwExtUserFieldType; + return pTyp; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +String SwExtUserFieldType::Expand(sal_uInt16 nSub, sal_uInt32 ) const +{ + String aRet; + sal_uInt16 nRet = USHRT_MAX; + switch(nSub) + { + case EU_FIRSTNAME: nRet = USER_OPT_FIRSTNAME; break; + case EU_NAME: nRet = USER_OPT_LASTNAME; break; + case EU_SHORTCUT: nRet = USER_OPT_ID; break; + + case EU_COMPANY: nRet = USER_OPT_COMPANY; break; + case EU_STREET: nRet = USER_OPT_STREET; break; + case EU_TITLE: nRet = USER_OPT_TITLE; break; + case EU_POSITION: nRet = USER_OPT_POSITION; break; + case EU_PHONE_PRIVATE: nRet = USER_OPT_TELEPHONEHOME; break; + case EU_PHONE_COMPANY: nRet = USER_OPT_TELEPHONEWORK; break; + case EU_FAX: nRet = USER_OPT_FAX; break; + case EU_EMAIL: nRet = USER_OPT_EMAIL; break; + case EU_COUNTRY: nRet = USER_OPT_COUNTRY; break; + case EU_ZIP: nRet = USER_OPT_ZIP; break; + case EU_CITY: nRet = USER_OPT_CITY; break; + case EU_STATE: nRet = USER_OPT_STATE; break; + case EU_FATHERSNAME: nRet = USER_OPT_FATHERSNAME; break; + case EU_APARTMENT: nRet = USER_OPT_APARTMENT; break; + default: ASSERT( !this, "Field unknown"); + } + if( USHRT_MAX != nRet ) + { + SvtUserOptions& rUserOpt = SW_MOD()->GetUserOptions(); + aRet = rUserOpt.GetToken( nRet ); + } + return aRet; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwExtUserField::SwExtUserField(SwExtUserFieldType* pTyp, sal_uInt16 nSubTyp, sal_uInt32 nFmt) : + SwField(pTyp, nFmt), nType(nSubTyp) +{ + aContent = ((SwExtUserFieldType*)GetTyp())->Expand(nType, GetFormat()); +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +String SwExtUserField::Expand() const +{ + if (!IsFixed()) + ((SwExtUserField*)this)->aContent = ((SwExtUserFieldType*)GetTyp())->Expand(nType, GetFormat()); + + return aContent; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwField* SwExtUserField::Copy() const +{ + SwExtUserField* pFld = new SwExtUserField((SwExtUserFieldType*)GetTyp(), nType, GetFormat()); + pFld->SetExpansion(aContent); + + return pFld; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +sal_uInt16 SwExtUserField::GetSubType() const +{ + return nType; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +void SwExtUserField::SetSubType(sal_uInt16 nSub) +{ + nType = nSub; +} + +/*-----------------05.03.98 14:14------------------- + +--------------------------------------------------*/ +BOOL SwExtUserField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + rAny <<= OUString(aContent); + break; + + case FIELD_PROP_USHORT1: + { + sal_Int16 nTmp = nType; + rAny <<= nTmp; + } + break; + case FIELD_PROP_BOOL1: + { + sal_Bool bTmp = IsFixed(); + rAny.setValue(&bTmp, ::getBooleanCppuType()); + } + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} +/*-----------------05.03.98 14:14------------------- + +--------------------------------------------------*/ +BOOL SwExtUserField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + ::GetString( rAny, aContent ); + break; + + case FIELD_PROP_USHORT1: + { + sal_Int16 nTmp = 0; + rAny >>= nTmp; + nType = nTmp; + } + break; + case FIELD_PROP_BOOL1: + if( *(sal_Bool*)rAny.getValue() ) + SetFormat(GetFormat() | AF_FIXED); + else + SetFormat(GetFormat() & ~AF_FIXED); + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} +//------------------------------------------------------------------------- + +/*-------------------------------------------------------------------- + Beschreibung: Relatives Seitennummern - Feld + --------------------------------------------------------------------*/ + +SwRefPageSetFieldType::SwRefPageSetFieldType() + : SwFieldType( RES_REFPAGESETFLD ) +{ +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwFieldType* SwRefPageSetFieldType::Copy() const +{ + return new SwRefPageSetFieldType; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +// ueberlagert, weil es nichts zum Updaten gibt! +void SwRefPageSetFieldType::Modify( SfxPoolItem *, SfxPoolItem * ) +{ +} + +/*-------------------------------------------------------------------- + Beschreibung: Relative Seitennummerierung + --------------------------------------------------------------------*/ + +SwRefPageSetField::SwRefPageSetField( SwRefPageSetFieldType* pTyp, + short nOff, sal_Bool bFlag ) + : SwField( pTyp ), nOffset( nOff ), bOn( bFlag ) +{ +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +String SwRefPageSetField::Expand() const +{ + return aEmptyStr; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwField* SwRefPageSetField::Copy() const +{ + return new SwRefPageSetField( (SwRefPageSetFieldType*)GetTyp(), nOffset, bOn ); +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +String SwRefPageSetField::GetPar2() const +{ + return String::CreateFromInt32( GetOffset() ); +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +void SwRefPageSetField::SetPar2(const String& rStr) +{ + SetOffset( (short) rStr.ToInt32() ); +} + +/*-----------------05.03.98 14:52------------------- + +--------------------------------------------------*/ +BOOL SwRefPageSetField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_BOOL1: + rAny.setValue(&bOn, ::getBooleanCppuType()); + break; + case FIELD_PROP_USHORT1: + rAny <<= (sal_Int16)nOffset; + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} +/*-----------------05.03.98 14:52------------------- + +--------------------------------------------------*/ +BOOL SwRefPageSetField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + switch( nWhichId ) + { + case FIELD_PROP_BOOL1: + bOn = *(sal_Bool*)rAny.getValue(); + break; + case FIELD_PROP_USHORT1: + rAny >>=nOffset; + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} +/*-------------------------------------------------------------------- + Beschreibung: relatives Seitennummern - Abfrage Feld + --------------------------------------------------------------------*/ + +SwRefPageGetFieldType::SwRefPageGetFieldType( SwDoc* pDc ) + : SwFieldType( RES_REFPAGEGETFLD ), pDoc( pDc ), nNumberingType( SVX_NUM_ARABIC ) +{ +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwFieldType* SwRefPageGetFieldType::Copy() const +{ + SwRefPageGetFieldType* pNew = new SwRefPageGetFieldType( pDoc ); + pNew->nNumberingType = nNumberingType; + return pNew; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +void SwRefPageGetFieldType::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew ) +{ + // Update auf alle GetReferenz-Felder + if( !pNew && !pOld && GetDepends() ) + { + // sammel erstmal alle SetPageRefFelder ein. + _SetGetExpFlds aTmpLst( 10, 5 ); + if( MakeSetList( aTmpLst ) ) + { + SwClientIter aIter( *this ); + if( aIter.GoStart() ) + do { + // nur die GetRef-Felder Updaten + SwFmtFld* pFmtFld = (SwFmtFld*)aIter(); + if( pFmtFld->GetTxtFld() ) + UpdateField( pFmtFld->GetTxtFld(), aTmpLst ); + } while( aIter++ ); + } + } + + // weiter an die Text-Felder, diese "Expandieren" den Text + SwModify::Modify( pOld, pNew ); +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +sal_uInt16 SwRefPageGetFieldType::MakeSetList( _SetGetExpFlds& rTmpLst ) +{ + SwClientIter aIter( *pDoc->GetSysFldType( RES_REFPAGESETFLD)); + if( aIter.GoStart() ) + do { + // nur die GetRef-Felder Updaten + SwFmtFld* pFmtFld = (SwFmtFld*)aIter(); + const SwTxtFld* pTFld = pFmtFld->GetTxtFld(); + if( pTFld ) + { + const SwTxtNode& rTxtNd = pTFld->GetTxtNode(); + + // immer den ersten !! (in Tab-Headline, Kopf-/Fuss ) + Point aPt; + const SwCntntFrm* pFrm = rTxtNd.GetFrm( &aPt, 0, sal_False ); + + _SetGetExpFld* pNew; + + if( !pFrm || + pFrm->IsInDocBody() || + // --> FME 2004-07-27 #i31868# + // Check if pFrm is not yet connected to the layout. + !pFrm->FindPageFrm() ) + // <-- + { + // einen sdbcx::Index fuers bestimmen vom TextNode anlegen + SwNodeIndex aIdx( rTxtNd ); + pNew = new _SetGetExpFld( aIdx, pTFld ); + } + else + { + // einen sdbcx::Index fuers bestimmen vom TextNode anlegen + SwPosition aPos( pDoc->GetNodes().GetEndOfPostIts() ); +#ifdef DBG_UTIL + ASSERT( GetBodyTxtNode( *pDoc, aPos, *pFrm ), + "wo steht das Feld" ); +#else + GetBodyTxtNode( *pDoc, aPos, *pFrm ); +#endif + pNew = new _SetGetExpFld( aPos.nNode, pTFld, + &aPos.nContent ); + } + + if( !rTmpLst.Insert( pNew )) + delete pNew; + } + } while( aIter++ ); + + return rTmpLst.Count(); +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +void SwRefPageGetFieldType::UpdateField( SwTxtFld* pTxtFld, + _SetGetExpFlds& rSetList ) +{ + SwRefPageGetField* pGetFld = (SwRefPageGetField*)pTxtFld->GetFld().GetFld(); + pGetFld->SetText( aEmptyStr ); + + // dann suche mal das richtige RefPageSet-Field + SwTxtNode* pTxtNode = (SwTxtNode*)&pTxtFld->GetTxtNode(); + if( pTxtNode->StartOfSectionIndex() > + pDoc->GetNodes().GetEndOfExtras().GetIndex() ) + { + SwNodeIndex aIdx( *pTxtNode ); + _SetGetExpFld aEndFld( aIdx, pTxtFld ); + + sal_uInt16 nLast; + rSetList.Seek_Entry( &aEndFld, &nLast ); + + if( nLast-- ) + { + const SwTxtFld* pRefTxtFld = rSetList[ nLast ]->GetFld(); + const SwRefPageSetField* pSetFld = + (SwRefPageSetField*)pRefTxtFld->GetFld().GetFld(); + if( pSetFld->IsOn() ) + { + // dann bestimme mal den entsp. Offset + Point aPt; + const SwCntntFrm* pFrm = pTxtNode->GetFrm( &aPt, 0, sal_False ); + const SwCntntFrm* pRefFrm = pRefTxtFld->GetTxtNode().GetFrm( &aPt, 0, sal_False ); + const SwPageFrm* pPgFrm = 0; + sal_uInt16 nDiff = ( pFrm && pRefFrm ) + ? (pPgFrm = pFrm->FindPageFrm())->GetPhyPageNum() - + pRefFrm->FindPageFrm()->GetPhyPageNum() + 1 + : 1; + + sal_uInt32 nTmpFmt = SVX_NUM_PAGEDESC == pGetFld->GetFormat() + ? ( !pPgFrm + ? (sal_uInt32)SVX_NUM_ARABIC + : pPgFrm->GetPageDesc()->GetNumType().GetNumberingType() ) + : pGetFld->GetFormat(); + short nPageNum = static_cast<short>(Max(0, pSetFld->GetOffset() + (short)nDiff)); + pGetFld->SetText( FormatNumber( nPageNum, nTmpFmt ) ); + } + } + } + // dann die Formatierung anstossen + ((SwFmtFld&)pTxtFld->GetFld()).Modify( 0, 0 ); +} + +/*-------------------------------------------------------------------- + Beschreibung: Relative Seitennummerierung Abfragen + --------------------------------------------------------------------*/ + +SwRefPageGetField::SwRefPageGetField( SwRefPageGetFieldType* pTyp, + sal_uInt32 nFmt ) + : SwField( pTyp, nFmt ) +{ +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +String SwRefPageGetField::Expand() const +{ + return sTxt; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwField* SwRefPageGetField::Copy() const +{ + SwRefPageGetField* pCpy = new SwRefPageGetField( + (SwRefPageGetFieldType*)GetTyp(), GetFormat() ); + pCpy->SetText( sTxt ); + return pCpy; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +void SwRefPageGetField::ChangeExpansion( const SwFrm* pFrm, + const SwTxtFld* pFld ) +{ + // nur Felder in Footer, Header, FootNote, Flys + SwTxtNode* pTxtNode = (SwTxtNode*)&pFld->GetTxtNode(); + SwRefPageGetFieldType* pGetType = (SwRefPageGetFieldType*)GetTyp(); + SwDoc* pDoc = pGetType->GetDoc(); + if( pFld->GetTxtNode().StartOfSectionIndex() > + pDoc->GetNodes().GetEndOfExtras().GetIndex() ) + return; + + sTxt.Erase(); + + ASSERT( !pFrm->IsInDocBody(), "Flag ist nicht richtig, Frame steht im DocBody" ); + + // sammel erstmal alle SetPageRefFelder ein. + _SetGetExpFlds aTmpLst( 10, 5 ); + if( !pGetType->MakeSetList( aTmpLst ) ) + return ; + + // einen sdbcx::Index fuers bestimmen vom TextNode anlegen + SwPosition aPos( SwNodeIndex( pDoc->GetNodes() ) ); + pTxtNode = (SwTxtNode*) GetBodyTxtNode( *pDoc, aPos, *pFrm ); + + // Wenn kein Layout vorhanden, kommt es in Kopf und Fusszeilen dazu + // das ChangeExpansion uebers Layout-Formatieren aufgerufen wird + // aber kein TxtNode vorhanden ist + // + if(!pTxtNode) + return; + + _SetGetExpFld aEndFld( aPos.nNode, pFld, &aPos.nContent ); + + sal_uInt16 nLast; + aTmpLst.Seek_Entry( &aEndFld, &nLast ); + + if( !nLast-- ) + return ; // es gibt kein entsprechendes Set - Feld vor mir + + const SwTxtFld* pRefTxtFld = aTmpLst[ nLast ]->GetFld(); + const SwRefPageSetField* pSetFld = + (SwRefPageSetField*)pRefTxtFld->GetFld().GetFld(); + Point aPt; + const SwCntntFrm* pRefFrm = pRefTxtFld ? pRefTxtFld->GetTxtNode().GetFrm( &aPt, 0, sal_False ) : 0; + if( pSetFld->IsOn() && pRefFrm ) + { + // dann bestimme mal den entsp. Offset + const SwPageFrm* pPgFrm = pFrm->FindPageFrm(); + sal_uInt16 nDiff = pPgFrm->GetPhyPageNum() - + pRefFrm->FindPageFrm()->GetPhyPageNum() + 1; + + SwRefPageGetField* pGetFld = (SwRefPageGetField*)pFld->GetFld().GetFld(); + sal_uInt32 nTmpFmt = SVX_NUM_PAGEDESC == pGetFld->GetFormat() + ? pPgFrm->GetPageDesc()->GetNumType().GetNumberingType() + : pGetFld->GetFormat(); + short nPageNum = static_cast<short>(Max(0, pSetFld->GetOffset() + (short)nDiff )); + pGetFld->SetText( FormatNumber( nPageNum, nTmpFmt ) ); + } +} +/*-----------------05.03.98 14:52------------------- + +--------------------------------------------------*/ +BOOL SwRefPageGetField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_USHORT1: + rAny <<= (sal_Int16)GetFormat(); + break; + case FIELD_PROP_PAR1: + rAny <<= OUString(sTxt); + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} +/*-----------------05.03.98 14:52------------------- + +--------------------------------------------------*/ +BOOL SwRefPageGetField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + switch( nWhichId ) + { + case FIELD_PROP_USHORT1: + { + sal_Int16 nSet = 0; + rAny >>= nSet; + if(nSet <= SVX_NUM_PAGEDESC ) + SetFormat(nSet); + else { + //exception(wrong_value) + ; + } + } + break; + case FIELD_PROP_PAR1: + { + OUString sTmp; + rAny >>= sTmp; + sTxt = sTmp; + } + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} + +/*-------------------------------------------------------------------- + Beschreibung: Feld zum Anspringen und Editieren + --------------------------------------------------------------------*/ + +SwJumpEditFieldType::SwJumpEditFieldType( SwDoc* pD ) + : SwFieldType( RES_JUMPEDITFLD ), pDoc( pD ), aDep( this, 0 ) +{ +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwFieldType* SwJumpEditFieldType::Copy() const +{ + return new SwJumpEditFieldType( pDoc ); +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwCharFmt* SwJumpEditFieldType::GetCharFmt() +{ + SwCharFmt* pFmt = pDoc->GetCharFmtFromPool( RES_POOLCHR_JUMPEDIT ); + + // noch nicht registriert ? + if( !aDep.GetRegisteredIn() ) + pFmt->Add( &aDep ); // anmelden + + return pFmt; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwJumpEditField::SwJumpEditField( SwJumpEditFieldType* pTyp, sal_uInt32 nForm, + const String& rTxt, const String& rHelp ) + : SwField( pTyp, nForm ), sTxt( rTxt ), sHelp( rHelp ) +{ +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +String SwJumpEditField::Expand() const +{ + String sTmp( '<' ); + sTmp += sTxt; + return sTmp += '>'; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +SwField* SwJumpEditField::Copy() const +{ + return new SwJumpEditField( (SwJumpEditFieldType*)GetTyp(), GetFormat(), + sTxt, sHelp ); +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +// Platzhalter-Text + +const String& SwJumpEditField::GetPar1() const +{ + return sTxt; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +void SwJumpEditField::SetPar1(const String& rStr) +{ + sTxt = rStr; +} + +// HinweisText +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +String SwJumpEditField::GetPar2() const +{ + return sHelp; +} +/* --------------------------------------------------------------------------- + + ---------------------------------------------------------------------------*/ +void SwJumpEditField::SetPar2(const String& rStr) +{ + sHelp = rStr; +} + +/*-----------------05.03.98 15:00------------------- + +--------------------------------------------------*/ +BOOL SwJumpEditField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_USHORT1: + { + sal_Int16 nRet; + switch( GetFormat() ) + { + case JE_FMT_TABLE: nRet = text::PlaceholderType::TABLE; break; + case JE_FMT_FRAME: nRet = text::PlaceholderType::TEXTFRAME; break; + case JE_FMT_GRAPHIC:nRet = text::PlaceholderType::GRAPHIC; break; + case JE_FMT_OLE: nRet = text::PlaceholderType::OBJECT; break; +// case JE_FMT_TEXT: + default: + nRet = text::PlaceholderType::TEXT; break; + } + rAny <<= nRet; + } + break; + case FIELD_PROP_PAR1 : + rAny <<= OUString(sHelp); + break; + case FIELD_PROP_PAR2 : + rAny <<= OUString(sTxt); + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} +/*-----------------05.03.98 15:00------------------- + +--------------------------------------------------*/ +BOOL SwJumpEditField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + switch( nWhichId ) + { + case FIELD_PROP_USHORT1: + { + //JP 24.10.2001: int32 because in UnoField.cxx a putvalue is + // called with a int32 value! But normally we need + // here only a int16 + sal_Int32 nSet = 0; + rAny >>= nSet; + switch( nSet ) + { + case text::PlaceholderType::TEXT : SetFormat(JE_FMT_TEXT); break; + case text::PlaceholderType::TABLE : SetFormat(JE_FMT_TABLE); break; + case text::PlaceholderType::TEXTFRAME: SetFormat(JE_FMT_FRAME); break; + case text::PlaceholderType::GRAPHIC : SetFormat(JE_FMT_GRAPHIC); break; + case text::PlaceholderType::OBJECT : SetFormat(JE_FMT_OLE); break; + } + } + break; + case FIELD_PROP_PAR1 : + ::GetString( rAny, sHelp ); + break; + case FIELD_PROP_PAR2 : + ::GetString( rAny, sTxt); + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} + + +/*-------------------------------------------------------------------- + Beschreibung: Combined Character Fieldtype / Field + --------------------------------------------------------------------*/ + +SwCombinedCharFieldType::SwCombinedCharFieldType() + : SwFieldType( RES_COMBINED_CHARS ) +{ +} + +SwFieldType* SwCombinedCharFieldType::Copy() const +{ + return new SwCombinedCharFieldType; +} + +/* --------------------------------------------------------------------*/ + +SwCombinedCharField::SwCombinedCharField( SwCombinedCharFieldType* pFTyp, + const String& rChars ) + : SwField( pFTyp, 0 ), + sCharacters( rChars.Copy( 0, MAX_COMBINED_CHARACTERS )) +{ +} + +String SwCombinedCharField::Expand() const +{ + return sCharacters; +} + +SwField* SwCombinedCharField::Copy() const +{ + return new SwCombinedCharField( (SwCombinedCharFieldType*)GetTyp(), + sCharacters ); +} + +const String& SwCombinedCharField::GetPar1() const +{ + return sCharacters; +} + +void SwCombinedCharField::SetPar1(const String& rStr) +{ + sCharacters = rStr.Copy( 0, MAX_COMBINED_CHARACTERS ); +} + +BOOL SwCombinedCharField::QueryValue( uno::Any& rAny, + USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + rAny <<= rtl::OUString( sCharacters ); + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} + +BOOL SwCombinedCharField::PutValue( const uno::Any& rAny, + USHORT nWhichId ) +{ + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + ::GetString( rAny, sCharacters ).Erase( MAX_COMBINED_CHARACTERS ); + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} + diff --git a/sw/source/core/fields/expfld.cxx b/sw/source/core/fields/expfld.cxx new file mode 100644 index 000000000000..25b0cf932e83 --- /dev/null +++ b/sw/source/core/fields/expfld.cxx @@ -0,0 +1,1330 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + +#include <hintids.hxx> +#include <unotools/collatorwrapper.hxx> +#include <unotools/charclass.hxx> +#include <editeng/unolingu.hxx> +#include <svx/pageitem.hxx> +#include <editeng/langitem.hxx> +#include <editeng/fontitem.hxx> +#include <com/sun/star/text/SetVariableType.hpp> +#include <unofield.hxx> +#include <frmfmt.hxx> +#include <fmtfld.hxx> +#include <txtfld.hxx> +#include <fmtanchr.hxx> +#include <txtftn.hxx> +#include <doc.hxx> +#include <layfrm.hxx> +#include <pagefrm.hxx> +#include <cntfrm.hxx> +#include <rootfrm.hxx> +#include <tabfrm.hxx> +#include <flyfrm.hxx> +#include <ftnfrm.hxx> +#include <rowfrm.hxx> +#include <expfld.hxx> +#include <usrfld.hxx> +#include <ndtxt.hxx> +#include <calc.hxx> +#include <pam.hxx> +#include <docfld.hxx> +#include <swcache.hxx> +#include <swtable.hxx> +#include <breakit.hxx> +#include <SwStyleNameMapper.hxx> +#include <unofldmid.h> +#include <numrule.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::text; +using ::rtl::OUString; + +SV_IMPL_PTRARR( _SwSeqFldList, _SeqFldLstElem* ) + +//----------------------------------------------------------------------------- +sal_Int16 lcl_SubTypeToAPI(USHORT nSubType) +{ + sal_Int16 nRet = 0; + switch(nSubType) + { + case nsSwGetSetExpType::GSE_EXPR : nRet = SetVariableType::VAR /*0*/; break; + case nsSwGetSetExpType::GSE_SEQ : nRet = SetVariableType::SEQUENCE /*1*/; break; + case nsSwGetSetExpType::GSE_FORMULA : nRet = SetVariableType::FORMULA /*2*/; break; + case nsSwGetSetExpType::GSE_STRING : nRet = SetVariableType::STRING /*3*/; break; + } + return nRet; +} +//----------------------------------------------------------------------------- +sal_Int32 lcl_APIToSubType(const uno::Any& rAny) +{ + sal_Int16 nVal = 0; + rAny >>= nVal; + sal_Int32 nSet = 0; + switch(nVal) + { + case SetVariableType::VAR: nSet = nsSwGetSetExpType::GSE_EXPR; break; + case SetVariableType::SEQUENCE: nSet = nsSwGetSetExpType::GSE_SEQ; break; + case SetVariableType::FORMULA: nSet = nsSwGetSetExpType::GSE_FORMULA; break; + case SetVariableType::STRING: nSet = nsSwGetSetExpType::GSE_STRING; break; + default: + DBG_ERROR("wrong value"); + nSet = -1; + } + return nSet; +} + +//----------------------------------------------------------------------------- + +void ReplacePoint( String& rTmpName, BOOL bWithCommandType ) +{ + // replace first and last (if bWithCommandType: last two) dot Ersten und letzten Punkt ersetzen, da in Tabellennamen Punkte erlaubt sind + // since table names may contain dots + + xub_StrLen nLen = rTmpName.Len(); + sal_Unicode *pStr = rTmpName.GetBufferAccess(), *pBackStr = pStr + nLen; + + long nBackCount = bWithCommandType ? 2 : 1; + xub_StrLen i; + + for( i = nLen; i; --i, pBackStr-- ) + if( '.' == *pBackStr ) + { + *pBackStr = DB_DELIM; + if(!--nBackCount) + break; + } + for( i = 0; i < nLen; ++i, ++pStr ) + if( '.' == *pStr ) + { + *pStr = DB_DELIM; + break; + } +} + +SwTxtNode* GetFirstTxtNode( const SwDoc& rDoc, SwPosition& rPos, + const SwCntntFrm *pCFrm, Point &rPt ) +{ + SwTxtNode* pTxtNode = 0; + if ( !pCFrm ) + { + const SwNodes& rNodes = rDoc.GetNodes(); + rPos.nNode = *rNodes.GetEndOfContent().StartOfSectionNode(); + SwCntntNode* pCNd; + while( 0 != (pCNd = rNodes.GoNext( &rPos.nNode ) ) && + 0 == ( pTxtNode = pCNd->GetTxtNode() ) ) + ; + ASSERT( pTxtNode, "wo ist der 1.TextNode" ); + rPos.nContent.Assign( pTxtNode, 0 ); + } + else if ( !pCFrm->IsValid() ) + { + pTxtNode = (SwTxtNode*)pCFrm->GetNode(); + rPos.nNode = *pTxtNode; + rPos.nContent.Assign( pTxtNode, 0 ); + } + else + { + pCFrm->GetCrsrOfst( &rPos, rPt ); + pTxtNode = rPos.nNode.GetNode().GetTxtNode(); + } + return pTxtNode; +} + +const SwTxtNode* GetBodyTxtNode( const SwDoc& rDoc, SwPosition& rPos, + const SwFrm& rFrm ) +{ + const SwLayoutFrm* pLayout = (SwLayoutFrm*)rFrm.GetUpper(); + const SwTxtNode* pTxtNode = 0; + + while( pLayout ) + { + if( pLayout->IsFlyFrm() ) + { + // hole das FlyFormat + SwFrmFmt* pFlyFmt = ((SwFlyFrm*)pLayout)->GetFmt(); + ASSERT( pFlyFmt, "kein FlyFormat gefunden, wo steht das Feld" ); + + const SwFmtAnchor &rAnchor = pFlyFmt->GetAnchor(); + + if( FLY_AT_FLY == rAnchor.GetAnchorId() ) + { + // und der Fly muss irgendwo angehaengt sein, also + // den befragen + pLayout = (SwLayoutFrm*)((SwFlyFrm*)pLayout)->GetAnchorFrm(); + continue; + } + else if ((FLY_AT_PARA == rAnchor.GetAnchorId()) || + (FLY_AT_CHAR == rAnchor.GetAnchorId()) || + (FLY_AS_CHAR == rAnchor.GetAnchorId())) + { + ASSERT( rAnchor.GetCntntAnchor(), "keine gueltige Position" ); + rPos = *rAnchor.GetCntntAnchor(); + pTxtNode = rPos.nNode.GetNode().GetTxtNode(); + if ( FLY_AT_PARA == rAnchor.GetAnchorId() ) + { + const_cast<SwTxtNode*>(pTxtNode)->MakeStartIndex( + &rPos.nContent ); +// oder doch besser das Ende vom (Anker-)TextNode nehmen ?? +// ((SwTxtNode*)pTxtNode)->MakeEndIndex( &rPos.nContent ); + } + + // noch nicht abbrechen, kann ja auch noch im + // Header/Footer/Footnote/Fly stehen !! + pLayout = ((SwFlyFrm*)pLayout)->GetAnchorFrm() + ? ((SwFlyFrm*)pLayout)->GetAnchorFrm()->GetUpper() : 0; + continue; + } + else + { + pLayout->FindPageFrm()->GetCntntPosition( + pLayout->Frm().Pos(), rPos ); + pTxtNode = rPos.nNode.GetNode().GetTxtNode(); + } + } + else if( pLayout->IsFtnFrm() ) + { + // hole den Node vom Anker + const SwTxtFtn* pFtn = ((SwFtnFrm*)pLayout)->GetAttr(); + pTxtNode = &pFtn->GetTxtNode(); + rPos.nNode = *pTxtNode; + rPos.nContent = *pFtn->GetStart(); + } + else if( pLayout->IsHeaderFrm() || pLayout->IsFooterFrm() ) + { + const SwCntntFrm* pCntFrm; + const SwPageFrm* pPgFrm = pLayout->FindPageFrm(); + if( pLayout->IsHeaderFrm() ) + { + const SwTabFrm *pTab; + if( 0 != ( pCntFrm = pPgFrm->FindFirstBodyCntnt()) && + 0 != (pTab = pCntFrm->FindTabFrm()) && pTab->IsFollow() && + pTab->GetTable()->GetRowsToRepeat() > 0 && + pTab->IsInHeadline( *pCntFrm ) ) + { + // take the next line + const SwLayoutFrm* pRow = pTab->GetFirstNonHeadlineRow(); + pCntFrm = pRow->ContainsCntnt(); + } + } + else + pCntFrm = pPgFrm->FindLastBodyCntnt(); + + if( pCntFrm ) + { + pTxtNode = pCntFrm->GetNode()->GetTxtNode(); + rPos.nNode = *pTxtNode; + ((SwTxtNode*)pTxtNode)->MakeEndIndex( &rPos.nContent ); + } + else + { + Point aPt( pLayout->Frm().Pos() ); + aPt.Y()++; // aus dem Header raus + pCntFrm = pPgFrm->GetCntntPos( aPt, FALSE, TRUE, FALSE ); + pTxtNode = GetFirstTxtNode( rDoc, rPos, pCntFrm, aPt ); + } + } + else + { + pLayout = pLayout->GetUpper(); + continue; + } + break; // gefunden und beende die Schleife + } + return pTxtNode; +} + +/*-------------------------------------------------------------------- + Beschreibung: SwSetExpFieldType by JP + --------------------------------------------------------------------*/ + +SwGetExpFieldType::SwGetExpFieldType(SwDoc* pDc) + : SwValueFieldType( pDc, RES_GETEXPFLD ) +{ +} + +SwFieldType* SwGetExpFieldType::Copy() const +{ + return new SwGetExpFieldType(GetDoc()); +} + +void SwGetExpFieldType::Modify( SfxPoolItem*, SfxPoolItem* pNew ) +{ + if( pNew && RES_DOCPOS_UPDATE == pNew->Which() ) + SwModify::Modify( 0, pNew ); + // sonst nichts weiter expandieren +} + +/*-------------------------------------------------------------------- + Beschreibung: SwGetExpField by JP + --------------------------------------------------------------------*/ + +SwGetExpField::SwGetExpField(SwGetExpFieldType* pTyp, const String& rFormel, + USHORT nSub, ULONG nFmt) + : SwFormulaField( pTyp, nFmt, 0.0 ), + bIsInBodyTxt( TRUE ), + nSubType(nSub), + bLateInitialization( false ) +{ + SetFormula( rFormel ); +} + +String SwGetExpField::Expand() const +{ + if(nSubType & nsSwExtendedSubType::SUB_CMD) + return GetFormula(); + else + return sExpand; +} + +String SwGetExpField::GetCntnt(BOOL bName) const +{ + if ( bName ) + { + String aStr( SwFieldType::GetTypeStr( static_cast<USHORT>(nsSwGetSetExpType::GSE_FORMULA & nSubType + ? TYP_FORMELFLD + : TYP_GETFLD ) )); + aStr += ' '; + aStr += GetFormula(); + return aStr; + } + return Expand(); +} + +SwField* SwGetExpField::Copy() const +{ + SwGetExpField *pTmp = new SwGetExpField((SwGetExpFieldType*)GetTyp(), + GetFormula(), nSubType, GetFormat()); + pTmp->SetLanguage(GetLanguage()); + pTmp->SwValueField::SetValue(GetValue()); + pTmp->sExpand = sExpand; + pTmp->bIsInBodyTxt = bIsInBodyTxt; + pTmp->SetAutomaticLanguage(IsAutomaticLanguage()); + if( bLateInitialization ) + pTmp->SetLateInitialization(); + + return pTmp; +} + +void SwGetExpField::ChangeExpansion( const SwFrm& rFrm, const SwTxtFld& rFld ) +{ + if( bIsInBodyTxt ) // nur Felder in Footer, Header, FootNote, Flys + return; + + ASSERT( !rFrm.IsInDocBody(), "Flag ist nicht richtig, Frame steht im DocBody" ); + + // bestimme mal das Dokument (oder geht es noch einfacher?) + const SwTxtNode* pTxtNode = &rFld.GetTxtNode(); + SwDoc& rDoc = *(SwDoc*)pTxtNode->GetDoc(); + + // einen Index fuers bestimmen vom TextNode anlegen + SwPosition aPos( SwNodeIndex( rDoc.GetNodes() ) ); + pTxtNode = GetBodyTxtNode( rDoc, aPos, rFrm ); + + // Wenn kein Layout vorhanden, kommt es in Kopf und Fusszeilen dazu + // das ChnageExpansion uebers Layout-Formatieren aufgerufen wird + // aber kein TxtNode vorhanden ist + // + if(!pTxtNode) + return; + // #i82544# + if( bLateInitialization ) + { + SwFieldType* pSetExpFld = rDoc.GetFldType(RES_SETEXPFLD, GetFormula(), sal_False); + if( pSetExpFld ) + { + bLateInitialization = false; + if( !(GetSubType() & nsSwGetSetExpType::GSE_STRING) && + static_cast< SwSetExpFieldType* >(pSetExpFld)->GetType() == nsSwGetSetExpType::GSE_STRING ) + SetSubType( nsSwGetSetExpType::GSE_STRING ); + } + } + + _SetGetExpFld aEndFld( aPos.nNode, &rFld, &aPos.nContent ); + if(GetSubType() & nsSwGetSetExpType::GSE_STRING) + { + SwHash** ppHashTbl; + USHORT nSize; + rDoc.FldsToExpand( ppHashTbl, nSize, aEndFld ); + LookString( ppHashTbl, nSize, GetFormula(), sExpand ); + ::DeleteHashTable( ppHashTbl, nSize ); // HashTabelle loeschen + } + else + { + // fuelle den Calculator mit den Werten + SwCalc aCalc( rDoc ); + rDoc.FldsToCalc(aCalc, aEndFld); + + // Wert berechnen + SetValue(aCalc.Calculate(GetFormula()).GetDouble()); + + // Auswertung nach Format + sExpand = ((SwValueFieldType*)GetTyp())->ExpandValue( + GetValue(), GetFormat(), GetLanguage()); + } +} + +String SwGetExpField::GetPar2() const +{ + return GetFormula(); +} + +void SwGetExpField::SetPar2(const String& rStr) +{ + SetFormula(rStr); +} + +USHORT SwGetExpField::GetSubType() const +{ + return nSubType; +} + +void SwGetExpField::SetSubType(USHORT nType) +{ + nSubType = nType; +} + +void SwGetExpField::SetLanguage(USHORT nLng) +{ + if (nSubType & nsSwExtendedSubType::SUB_CMD) + SwField::SetLanguage(nLng); + else + SwValueField::SetLanguage(nLng); +} + +/*-----------------07.03.98 16:08------------------- + +--------------------------------------------------*/ +BOOL SwGetExpField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_DOUBLE: + rAny <<= GetValue(); + break; + case FIELD_PROP_FORMAT: + rAny <<= (sal_Int32)GetFormat(); + break; + case FIELD_PROP_USHORT1: + rAny <<= (sal_Int16)nSubType; + break; + case FIELD_PROP_PAR1: + rAny <<= OUString( GetFormula() ); + break; + case FIELD_PROP_SUBTYPE: + { + sal_Int16 nRet = lcl_SubTypeToAPI(GetSubType() & 0xff); + rAny <<= nRet; + } + break; + case FIELD_PROP_BOOL2: + { + BOOL bTmp = 0 != (nSubType & nsSwExtendedSubType::SUB_CMD); + rAny.setValue(&bTmp, ::getBooleanCppuType()); + } + break; + case FIELD_PROP_PAR4: + rAny <<= rtl::OUString(GetExpStr()); + break; + default: + return SwField::QueryValue(rAny, nWhichId); + } + return TRUE; +} +/*-----------------07.03.98 16:08------------------- + +--------------------------------------------------*/ +BOOL SwGetExpField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + sal_Int32 nTmp = 0; + String sTmp; + switch( nWhichId ) + { + case FIELD_PROP_DOUBLE: + SwValueField::SetValue(*(double*) rAny.getValue()); + break; + case FIELD_PROP_FORMAT: + rAny >>= nTmp; + SetFormat(nTmp); + break; + case FIELD_PROP_USHORT1: + rAny >>= nTmp; + nSubType = static_cast<USHORT>(nTmp); + break; + case FIELD_PROP_PAR1: + SetFormula( ::GetString( rAny, sTmp )); + break; + case FIELD_PROP_SUBTYPE: + nTmp = lcl_APIToSubType(rAny); + if( nTmp >=0 ) + SetSubType( static_cast<USHORT>((GetSubType() & 0xff00) | nTmp)); + break; + case FIELD_PROP_BOOL2: + if(*(sal_Bool*) rAny.getValue()) + nSubType |= nsSwExtendedSubType::SUB_CMD; + else + nSubType &= (~nsSwExtendedSubType::SUB_CMD); + break; + case FIELD_PROP_PAR4: + ChgExpStr(::GetString( rAny, sTmp )); + break; + default: + return SwField::PutValue(rAny, nWhichId); + } + return TRUE; +} + +/*-----------------JP: 17.06.93 ------------------- + Set-Expression-Type + --------------------------------------------------*/ + +SwSetExpFieldType::SwSetExpFieldType( SwDoc* pDc, const String& rName, USHORT nTyp ) + : SwValueFieldType( pDc, RES_SETEXPFLD ), + sName( rName ), + pOutlChgNd( 0 ), + sDelim( String::CreateFromAscii( "." ) ), + nType(nTyp), nLevel( UCHAR_MAX ), + bDeleted( FALSE ) +{ + if( ( nsSwGetSetExpType::GSE_SEQ | nsSwGetSetExpType::GSE_STRING ) & nType ) + EnableFormat(FALSE); // Numberformatter nicht einsetzen +} + +SwFieldType* SwSetExpFieldType::Copy() const +{ + SwSetExpFieldType* pNew = new SwSetExpFieldType(GetDoc(), sName, nType); + pNew->bDeleted = bDeleted; + pNew->sDelim = sDelim; + pNew->nLevel = nLevel; + + return pNew; +} + +const String& SwSetExpFieldType::GetName() const +{ + return sName; +} + +void SwSetExpFieldType::Modify( SfxPoolItem*, SfxPoolItem* ) +{ + return; // nicht weiter expandieren +} + +void SwSetExpFieldType::SetSeqFormat(ULONG nFmt) +{ + SwClientIter aIter(*this); + for( SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE(SwFmtFld) ); + pFld; pFld = (SwFmtFld*)aIter.Next() ) + pFld->GetFld()->ChangeFormat( nFmt ); +} + +ULONG SwSetExpFieldType::GetSeqFormat() +{ + if( !GetDepends() ) + return SVX_NUM_ARABIC; + + SwField *pFld = ((SwFmtFld*)GetDepends())->GetFld(); + return pFld->GetFormat(); +} + +USHORT SwSetExpFieldType::SetSeqRefNo( SwSetExpField& rFld ) +{ + if( !GetDepends() || !(nsSwGetSetExpType::GSE_SEQ & nType) ) + return USHRT_MAX; + +extern void InsertSort( SvUShorts& rArr, USHORT nIdx, USHORT* pInsPos = 0 ); + SvUShorts aArr( 64 ); + + USHORT n; + + // dann testmal, ob die Nummer schon vergeben ist oder ob eine neue + // bestimmt werden muss. + SwClientIter aIter( *this ); + const SwTxtNode* pNd; + for( SwFmtFld* pF = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); pF; + pF = (SwFmtFld*)aIter.Next() ) + if( pF->GetFld() != &rFld && pF->GetTxtFld() && + 0 != ( pNd = pF->GetTxtFld()->GetpTxtNode() ) && + pNd->GetNodes().IsDocNodes() ) + InsertSort( aArr, ((SwSetExpField*)pF->GetFld())->GetSeqNumber() ); + + + // teste erstmal ob die Nummer schon vorhanden ist: + USHORT nNum = rFld.GetSeqNumber(); + if( USHRT_MAX != nNum ) + { + for( n = 0; n < aArr.Count(); ++n ) + if( aArr[ n ] > nNum ) + return nNum; // nicht vorhanden -> also benutzen + else if( aArr[ n ] == nNum ) + break; // schon vorhanden -> neue erzeugen + + if( n == aArr.Count() ) + return nNum; // nicht vorhanden -> also benutzen + } + + // alle Nummern entsprechend geflag, also bestimme die richtige Nummer + for( n = 0; n < aArr.Count(); ++n ) + if( n != aArr[ n ] ) + break; + + rFld.SetSeqNumber( n ); + return n; +} + +USHORT SwSetExpFieldType::GetSeqFldList( SwSeqFldList& rList ) +{ + if( rList.Count() ) + rList.Remove( 0, rList.Count() ); + + SwClientIter aIter( *this ); + const SwTxtNode* pNd; + for( SwFmtFld* pF = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); pF; + pF = (SwFmtFld*)aIter.Next() ) + if( pF->GetTxtFld() && + 0 != ( pNd = pF->GetTxtFld()->GetpTxtNode() ) && + pNd->GetNodes().IsDocNodes() ) + { + _SeqFldLstElem* pNew = new _SeqFldLstElem( + pNd->GetExpandTxt( 0, (*pF->GetTxtFld()->GetStart()) + 1 ), + ((SwSetExpField*)pF->GetFld())->GetSeqNumber() ); + rList.InsertSort( pNew ); + } + + return rList.Count(); +} + + +void SwSetExpFieldType::SetChapter( SwSetExpField& rFld, const SwNode& rNd ) +{ + const SwTxtNode* pTxtNd = rNd.FindOutlineNodeOfLevel( nLevel ); + if( pTxtNd ) + { + SwNumRule * pRule = pTxtNd->GetNumRule(); + + if (pRule) + { + // --> OD 2005-11-02 #i51089 - TUNING# + if ( pTxtNd->GetNum() ) + { + const SwNodeNum & aNum = *(pTxtNd->GetNum()); + + // nur die Nummer besorgen, ohne Pre-/Post-fixstrings + String sNumber( pRule->MakeNumString(aNum, FALSE )); + + if( sNumber.Len() ) + rFld.ChgExpStr( ( sNumber += sDelim ) += rFld.GetExpStr() ); + } + else + { + ASSERT( false, + "<SwSetExpFieldType::SetChapter(..)> - text node with numbering rule, but without number. This is a serious defect -> inform OD" ); + } + } + } +} + +/* -----------------24.03.99 09:44------------------- + * + * --------------------------------------------------*/ +BOOL SwSetExpFieldType::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_SUBTYPE: + { + sal_Int16 nRet = lcl_SubTypeToAPI(GetType()); + rAny <<= nRet; + } + break; + case FIELD_PROP_PAR2: + rAny <<= OUString(GetDelimiter()); + break; + case FIELD_PROP_SHORT1: + { + sal_Int8 nRet = nLevel < MAXLEVEL? nLevel : -1; + rAny <<= nRet; + } + break; + default: + DBG_ERROR("illegal property"); + } + return TRUE; +} + +BOOL SwSetExpFieldType::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + switch( nWhichId ) + { + case FIELD_PROP_SUBTYPE: + { + sal_Int32 nSet = lcl_APIToSubType(rAny); + if(nSet >=0) + SetType(static_cast<USHORT>(nSet)); + } + break; + case FIELD_PROP_PAR2: + { + String sTmp; + if( ::GetString( rAny, sTmp ).Len() ) +// SetDelimiter( sTmp.GetChar( 0 )); + SetDelimiter( sTmp ); + else + SetDelimiter(String::CreateFromAscii( " ")); + } + break; + case FIELD_PROP_SHORT1: + { + sal_Int8 nLvl = 0; + rAny >>= nLvl; + if(nLvl < 0 || nLvl >= MAXLEVEL) + SetOutlineLvl(UCHAR_MAX); + else + SetOutlineLvl(nLvl); + } + break; + default: + DBG_ERROR("illegal property"); + } + return TRUE; +} + +BOOL SwSeqFldList::InsertSort( _SeqFldLstElem* pNew ) +{ + sal_Unicode* p = pNew->sDlgEntry.GetBufferAccess(); + while( *p ) + { + if( *p < 0x20 ) + *p = 0x20; + ++p; + } + + USHORT nPos; + BOOL bRet = SeekEntry( *pNew, &nPos ); + if( !bRet ) + C40_INSERT( _SeqFldLstElem, pNew, nPos ); + return bRet; +} + +BOOL SwSeqFldList::SeekEntry( const _SeqFldLstElem& rNew, USHORT* pP ) +{ + USHORT nO = Count(), nM, nU = 0; + if( nO > 0 ) + { + CollatorWrapper & rCaseColl = ::GetAppCaseCollator(), + & rColl = ::GetAppCollator(); + const CharClass& rCC = GetAppCharClass(); + + //#59900# Die Sortierung soll die Nummer korrekt einordnen + //also "10" nach "9" und nicht "10" nach "1" + const String& rTmp2 = rNew.sDlgEntry; + xub_StrLen nFndPos2 = 0; + String sNum2( rTmp2.GetToken( 0, ' ', nFndPos2 )); + BOOL bIsNum2IsNumeric = rCC.isAsciiNumeric( sNum2 ); + sal_Int32 nNum2 = bIsNum2IsNumeric ? sNum2.ToInt32() : 0; + + nO--; + while( nU <= nO ) + { + nM = nU + ( nO - nU ) / 2; + + //#59900# Die Sortierung soll die Nummer korrekt einordnen + //also "10" nach "9" und nicht "10" nach "1" + const String& rTmp1 = (*((_SeqFldLstElem**)pData + nM))->sDlgEntry; + xub_StrLen nFndPos1 = 0; + String sNum1( rTmp1.GetToken( 0, ' ', nFndPos1 )); + sal_Int32 nCmp; + + if( bIsNum2IsNumeric && rCC.isNumeric( sNum1 ) ) + { + sal_Int32 nNum1 = sNum1.ToInt32(); + nCmp = nNum2 - nNum1; + if( 0 == nCmp ) + nCmp = rCaseColl.compareString( rTmp2.Copy( nFndPos2 ), + rTmp1.Copy( nFndPos1 )); + } + else + nCmp = rColl.compareString( rTmp2, rTmp1 ); + + if( 0 == nCmp ) + { + if( pP ) *pP = nM; + return TRUE; + } + else if( 0 < nCmp ) + nU = nM + 1; + else if( nM == 0 ) + break; + else + nO = nM - 1; + } + } + if( pP ) *pP = nU; + return FALSE; +} + +/*-------------------------------------------------------------------- + Beschreibung: SwSetExpField by JP + --------------------------------------------------------------------*/ + +SwSetExpField::SwSetExpField(SwSetExpFieldType* pTyp, const String& rFormel, + ULONG nFmt) + : SwFormulaField( pTyp, nFmt, 0.0 ), nSeqNo( USHRT_MAX ), + nSubType(0) +{ + SetFormula(rFormel); + // SubType ignorieren !!! + bInput = FALSE; + if( IsSequenceFld() ) + { + SwValueField::SetValue(1.0); + if( !rFormel.Len() ) + { + String sFormel(rFormel); + sFormel += pTyp->GetName(); + sFormel += '+'; + sFormel += '1'; + SetFormula(sFormel); + } + } +} + +String SwSetExpField::Expand() const +{ + String aStr; + if (nSubType & nsSwExtendedSubType::SUB_CMD) + { // Der CommandString ist gefragt + aStr = GetTyp()->GetName(); + aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " = " )); + aStr += GetFormula(); + } + else if(!(nSubType & nsSwExtendedSubType::SUB_INVISIBLE)) + { // Der Wert ist sichtbar + aStr = sExpand; + } + return aStr; +} + +/*-------------------------------------------------------------------- + Beschreibung: liefert den Namen oder den Inhalt + --------------------------------------------------------------------*/ + +String SwSetExpField::GetCntnt(BOOL bName) const +{ + if( bName ) + { + USHORT nStrType; + + if( IsSequenceFld() ) + nStrType = TYP_SEQFLD; + else if( bInput ) + nStrType = TYP_SETINPFLD; + else + nStrType = TYP_SETFLD; + + String aStr( SwFieldType::GetTypeStr( nStrType ) ); + aStr += ' '; + aStr += GetTyp()->GetName(); + + if( TYP_SEQFLD != nStrType ) + { + // Sequence nicht die Formel ausgeben + aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " = " )); + aStr += GetFormula(); + } + return aStr; + } + return Expand(); +} + +SwField* SwSetExpField::Copy() const +{ + SwSetExpField *pTmp = new SwSetExpField((SwSetExpFieldType*)GetTyp(), + GetFormula(), GetFormat()); + pTmp->SwValueField::SetValue(GetValue()); + pTmp->sExpand = sExpand; + pTmp->SetAutomaticLanguage(IsAutomaticLanguage()); + pTmp->SetLanguage(GetLanguage()); + pTmp->aPText = aPText; + pTmp->bInput = bInput; + pTmp->nSeqNo = nSeqNo; + pTmp->SetSubType(GetSubType()); + + return pTmp; +} + +void SwSetExpField::SetSubType(USHORT nSub) +{ + ((SwSetExpFieldType*)GetTyp())->SetType(nSub & 0xff); + nSubType = nSub & 0xff00; + + DBG_ASSERT( (nSub & 0xff) != 3, "SubType ist illegal!" ); +} + +USHORT SwSetExpField::GetSubType() const +{ + return ((SwSetExpFieldType*)GetTyp())->GetType() | nSubType; +} + +void SwSetExpField::SetValue( const double& rAny ) +{ + SwValueField::SetValue(rAny); + + if( IsSequenceFld() ) + sExpand = FormatNumber( (USHORT)GetValue(), GetFormat() ); + else + sExpand = ((SwValueFieldType*)GetTyp())->ExpandValue( rAny, + GetFormat(), GetLanguage()); +} + +void SwGetExpField::SetValue( const double& rAny ) +{ + SwValueField::SetValue(rAny); + sExpand = ((SwValueFieldType*)GetTyp())->ExpandValue( rAny, GetFormat(), + GetLanguage()); +} +/* -----------------14.07.99 12:21------------------- + Description: Find the index of the reference text + following the current field + --------------------------------------------------*/ +xub_StrLen SwGetExpField::GetReferenceTextPos( const SwFmtFld& rFmt, SwDoc& rDoc) +{ + // + const SwTxtFld* pTxtFld = rFmt.GetTxtFld(); + const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode(); + // + xub_StrLen nRet = *pTxtFld->GetStart() + 1; + String sNodeText = rTxtNode.GetTxt(); + sNodeText.Erase(0, nRet); + if(sNodeText.Len()) + { + //now check if sNodeText starts with a non-alphanumeric character plus a blank + USHORT nSrcpt = pBreakIt->GetRealScriptOfText( sNodeText, 0 ); + + static USHORT nIds[] = + { + RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE, + RES_CHRATR_FONT, RES_CHRATR_FONT, + RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, + RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONT, + RES_CHRATR_CTL_LANGUAGE, RES_CHRATR_CTL_LANGUAGE, + RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONT, + 0, 0 + }; + SwAttrSet aSet(rDoc.GetAttrPool(), nIds); + rTxtNode.GetAttr(aSet, nRet, nRet+1); + + if( RTL_TEXTENCODING_SYMBOL != ((SvxFontItem&)aSet.Get( + GetWhichOfScript( RES_CHRATR_FONT, nSrcpt )) ).GetCharSet() ) + { + LanguageType eLang = ((SvxLanguageItem&)aSet.Get( + GetWhichOfScript( RES_CHRATR_LANGUAGE, nSrcpt )) ).GetLanguage(); + CharClass aCC( SvxCreateLocale( eLang )); + sal_Unicode c0 = sNodeText.GetChar(0); + BOOL bIsAlphaNum = aCC.isAlphaNumeric( sNodeText, 0 ); + if( !bIsAlphaNum || + (c0 == ' ' || c0 == '\t')) + { + nRet++; + if( sNodeText.Len() > 1 && + (sNodeText.GetChar(1) == ' ' || + sNodeText.GetChar(1) == '\t')) + nRet++; + } + } + } + return nRet; +} + + +/*-------------------------------------------------------------------- + Beschreibung: Parameter setzen + --------------------------------------------------------------------*/ + +const String& SwSetExpField::GetPar1() const +{ + return ((SwSetExpFieldType*)GetTyp())->GetName(); +} + +String SwSetExpField::GetPar2() const +{ + USHORT nType = ((SwSetExpFieldType*)GetTyp())->GetType(); + + if (nType & nsSwGetSetExpType::GSE_STRING) + return GetFormula(); + return GetExpandedFormula(); +} + +void SwSetExpField::SetPar2(const String& rStr) +{ + USHORT nType = ((SwSetExpFieldType*)GetTyp())->GetType(); + + if( !(nType & nsSwGetSetExpType::GSE_SEQ) || rStr.Len() ) + { + if (nType & nsSwGetSetExpType::GSE_STRING) + SetFormula(rStr); + else + SetExpandedFormula(rStr); + } +} + +/*-------------------------------------------------------------------- + Beschreibung: Eingabefeld Type + ---------------------------------------------------------------------*/ + +SwInputFieldType::SwInputFieldType( SwDoc* pD ) + : SwFieldType( RES_INPUTFLD ), pDoc( pD ) +{ +} + +SwFieldType* SwInputFieldType::Copy() const +{ + SwInputFieldType* pType = new SwInputFieldType( pDoc ); + return pType; +} + +/*-------------------------------------------------------------------- + Beschreibung: Eingabefeld + --------------------------------------------------------------------*/ + +SwInputField::SwInputField(SwInputFieldType* pTyp, const String& rContent, + const String& rPrompt, USHORT nSub, ULONG nFmt) : + SwField(pTyp, nFmt), aContent(rContent), aPText(rPrompt), nSubType(nSub) +{ +} + +String SwInputField::GetCntnt(BOOL bName) const +{ + if ( bName ) + { + String aStr(SwField::GetCntnt(bName)); + if ((nSubType & 0x00ff) == INP_USR) + { + aStr += GetTyp()->GetName(); + aStr += ' '; + aStr += aContent; + } + return aStr; + } + return Expand(); +} + +SwField* SwInputField::Copy() const +{ + SwInputField* pFld = new SwInputField((SwInputFieldType*)GetTyp(), aContent, + aPText, GetSubType(), GetFormat()); + + pFld->SetHelp(aHelp); + pFld->SetToolTip(aToolTip); + + pFld->SetAutomaticLanguage(IsAutomaticLanguage()); + return pFld; +} + +String SwInputField::Expand() const +{ + String sRet; + if((nSubType & 0x00ff) == INP_TXT) + sRet = aContent; + + else if( (nSubType & 0x00ff) == INP_USR ) + { + SwUserFieldType* pUserTyp = (SwUserFieldType*) + ((SwInputFieldType*)GetTyp())->GetDoc()-> + GetFldType( RES_USERFLD, aContent, false ); + if( pUserTyp ) + sRet = pUserTyp->GetContent(); + } + return sRet; +} + +/*-----------------06.03.98 11:12------------------- + +--------------------------------------------------*/ +BOOL SwInputField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + rAny <<= OUString( aContent ); + break; + case FIELD_PROP_PAR2: + rAny <<= OUString( aPText ); + break; + case FIELD_PROP_PAR3: + rAny <<= OUString( aHelp ); + break; + case FIELD_PROP_PAR4: + rAny <<= OUString( aToolTip ); + break; + default: + DBG_ERROR("illegal property"); + } + return TRUE; +} +/*-----------------06.03.98 11:12------------------- + +--------------------------------------------------*/ +BOOL SwInputField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + ::GetString( rAny, aContent ); + break; + case FIELD_PROP_PAR2: + ::GetString( rAny, aPText ); + break; + case FIELD_PROP_PAR3: + ::GetString( rAny, aHelp ); + break; + case FIELD_PROP_PAR4: + ::GetString( rAny, aToolTip ); + break; + default: + DBG_ERROR("illegal property"); + } + return TRUE; +} +/*-------------------------------------------------------------------- + Beschreibung: Bedingung setzen + --------------------------------------------------------------------*/ + +void SwInputField::SetPar1(const String& rStr) +{ + aContent = rStr; +} + +const String& SwInputField::GetPar1() const +{ + return aContent; +} + +/*-------------------------------------------------------------------- + Beschreibung: True/False Text + --------------------------------------------------------------------*/ + +void SwInputField::SetPar2(const String& rStr) +{ + aPText = rStr; +} + +String SwInputField::GetPar2() const +{ + return aPText; +} + +void SwInputField::SetHelp(const String & rStr) +{ + aHelp = rStr; +} + +String SwInputField::GetHelp() const +{ + return aHelp; +} + +void SwInputField::SetToolTip(const String & rStr) +{ + aToolTip = rStr; +} + +String SwInputField::GetToolTip() const +{ + return aToolTip; +} + +BOOL SwInputField::isFormField() const +{ + return aHelp.Len() > 0 || aToolTip.Len() > 0; +} + +USHORT SwInputField::GetSubType() const +{ + return nSubType; +} + +void SwInputField::SetSubType(USHORT nSub) +{ + nSubType = nSub; +} +/*-----------------05.03.98 17:22------------------- + +--------------------------------------------------*/ +BOOL SwSetExpField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_BOOL2: + { + sal_Bool bVal = 0 == (nSubType & nsSwExtendedSubType::SUB_INVISIBLE); + rAny.setValue(&bVal, ::getBooleanCppuType()); + } + break; + case FIELD_PROP_FORMAT: + rAny <<= (sal_Int32)GetFormat(); + break; + case FIELD_PROP_USHORT2: + rAny <<= (sal_Int16)GetFormat(); + break; + case FIELD_PROP_USHORT1: + rAny <<= (sal_Int16)nSeqNo; + break; + case FIELD_PROP_PAR1: + rAny <<= OUString ( SwStyleNameMapper::GetProgName(GetPar1(), nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL ) ); + break; + case FIELD_PROP_PAR2: + { + //I18N - if the formula contains only "TypeName+1" + //and it's one of the initially created sequence fields + //then the localized names has to be replaced by a programmatic name + OUString sMyFormula = SwXFieldMaster::LocalizeFormula(*this, GetFormula(), TRUE); + rAny <<= OUString( sMyFormula ); + } + break; + case FIELD_PROP_DOUBLE: + rAny <<= (double)GetValue(); + break; + case FIELD_PROP_SUBTYPE: + { + sal_Int16 nRet = 0; + nRet = lcl_SubTypeToAPI(GetSubType() & 0xff); + rAny <<= nRet; + } + break; + case FIELD_PROP_PAR3: + rAny <<= OUString( aPText ); + break; + case FIELD_PROP_BOOL3: + { + BOOL bTmp = 0 != (nSubType & nsSwExtendedSubType::SUB_CMD); + rAny.setValue(&bTmp, ::getBooleanCppuType()); + } + break; + case FIELD_PROP_BOOL1: + { + BOOL bTmp = GetInputFlag(); + rAny.setValue(&bTmp, ::getBooleanCppuType()); + } + break; + case FIELD_PROP_PAR4: + rAny <<= rtl::OUString(GetExpStr()); + break; + default: + return SwField::QueryValue(rAny, nWhichId); + } + return TRUE; +} +/*-----------------05.03.98 17:22------------------- + +--------------------------------------------------*/ +BOOL SwSetExpField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + sal_Int32 nTmp32 = 0; + sal_Int16 nTmp16 = 0; + String sTmp; + switch( nWhichId ) + { + case FIELD_PROP_BOOL2: + if(*(sal_Bool*)rAny.getValue()) + nSubType &= ~nsSwExtendedSubType::SUB_INVISIBLE; + else + nSubType |= nsSwExtendedSubType::SUB_INVISIBLE; + break; + case FIELD_PROP_FORMAT: + rAny >>= nTmp32; + SetFormat(nTmp32); + break; + case FIELD_PROP_USHORT2: + { + rAny >>= nTmp16; + if(nTmp16 <= SVX_NUMBER_NONE ) + SetFormat(nTmp16); + else { + //exception(wrong_value) + ; + } + } + break; + case FIELD_PROP_USHORT1: + rAny >>= nTmp16; + nSeqNo = nTmp16; + break; + case FIELD_PROP_PAR1: + SetPar1( SwStyleNameMapper::GetUIName( + ::GetString( rAny, sTmp ), nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL ) ); + break; + case FIELD_PROP_PAR2: + { + OUString uTmp; + rAny >>= uTmp; + //I18N - if the formula contains only "TypeName+1" + //and it's one of the initially created sequence fields + //then the localized names has to be replaced by a programmatic name + OUString sMyFormula = SwXFieldMaster::LocalizeFormula(*this, uTmp, FALSE); + SetFormula( sMyFormula ); + } + break; + case FIELD_PROP_DOUBLE: + { + double fVal = 0.0; + rAny >>= fVal; + SetValue(fVal); + } + break; + case FIELD_PROP_SUBTYPE: + nTmp32 = lcl_APIToSubType(rAny); + if(nTmp32 >= 0) + SetSubType(static_cast<USHORT>((GetSubType() & 0xff00) | nTmp32)); + break; + case FIELD_PROP_PAR3: + ::GetString( rAny, aPText ); + break; + case FIELD_PROP_BOOL3: + if(*(sal_Bool*) rAny.getValue()) + nSubType |= nsSwExtendedSubType::SUB_CMD; + else + nSubType &= (~nsSwExtendedSubType::SUB_CMD); + break; + case FIELD_PROP_BOOL1: + SetInputFlag(*(sal_Bool*) rAny.getValue()); + break; + case FIELD_PROP_PAR4: + ChgExpStr( ::GetString( rAny, sTmp )); + break; + default: + return SwField::PutValue(rAny, nWhichId); + } + return TRUE; +} + + + diff --git a/sw/source/core/fields/fldbas.cxx b/sw/source/core/fields/fldbas.cxx new file mode 100644 index 000000000000..e35c27d0464b --- /dev/null +++ b/sw/source/core/fields/fldbas.cxx @@ -0,0 +1,814 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + + +// #include <math.h> +#include <float.h> +#include <rtl/math.hxx> +#include <svl/zforlist.hxx> +#include <svl/zformat.hxx> +#include <editeng/unolingu.hxx> +#ifndef _UNOFLDMID_H +#include <unofldmid.h> +#endif +#include <doc.hxx> +#include <editsh.hxx> +#include <frame.hxx> +#include <fldbas.hxx> +#include <flddat.hxx> +#include <ndtxt.hxx> +#include <fmtfld.hxx> +#include <txtfld.hxx> +#include <pam.hxx> +#include <docfld.hxx> +#include <swtable.hxx> +#include <docufld.hxx> +#include <expfld.hxx> +#include <shellres.hxx> +#include <calc.hxx> +#ifndef _COMCORE_HRC +#include <comcore.hrc> +#endif + +#include <math.h> +#include <float.h> + +using namespace ::com::sun::star; +using namespace nsSwDocInfoSubType; + +USHORT lcl_GetLanguageOfFormat( USHORT nLng, ULONG nFmt, + const SvNumberFormatter& rFormatter ) +{ + if( nLng == LANGUAGE_NONE ) // wegen Bug #60010 + nLng = LANGUAGE_SYSTEM; + else if( nLng == ::GetAppLanguage() ) + switch( rFormatter.GetIndexTableOffset( nFmt )) + { + case NF_NUMBER_SYSTEM: + case NF_DATE_SYSTEM_SHORT: + case NF_DATE_SYSTEM_LONG: + case NF_DATETIME_SYSTEM_SHORT_HHMM: + nLng = LANGUAGE_SYSTEM; + break; + default: break; + } + return nLng; +} + +/*-------------------------------------------------------------------- + Beschreibung: Globals + --------------------------------------------------------------------*/ +// Array der Feldname + +SvStringsDtor* SwFieldType::pFldNames = 0; + +DBG_NAME(SwFieldType) + + USHORT __FAR_DATA aTypeTab[] = { + /* RES_DBFLD */ TYP_DBFLD, + /* RES_USERFLD */ TYP_USERFLD, + /* RES_FILENAMEFLD */ TYP_FILENAMEFLD, + /* RES_DBNAMEFLD */ TYP_DBNAMEFLD, + /* RES_DATEFLD */ TYP_DATEFLD, + /* RES_TIMEFLD */ TYP_TIMEFLD, + /* RES_PAGENUMBERFLD */ TYP_PAGENUMBERFLD, // dynamisch + /* RES_AUTHORFLD */ TYP_AUTHORFLD, + /* RES_CHAPTERFLD */ TYP_CHAPTERFLD, + /* RES_DOCSTATFLD */ TYP_DOCSTATFLD, + /* RES_GETEXPFLD */ TYP_GETFLD, // dynamisch + /* RES_SETEXPFLD */ TYP_SETFLD, // dynamisch + /* RES_GETREFFLD */ TYP_GETREFFLD, + /* RES_HIDDENTXTFLD */ TYP_HIDDENTXTFLD, + /* RES_POSTITFLD */ TYP_POSTITFLD, + /* RES_FIXDATEFLD */ TYP_FIXDATEFLD, + /* RES_FIXTIMEFLD */ TYP_FIXTIMEFLD, + /* RES_REGFLD */ 0, // alt + /* RES_VARREGFLD */ 0, // alt + /* RES_SETREFFLD */ TYP_SETREFFLD, + /* RES_INPUTFLD */ TYP_INPUTFLD, + /* RES_MACROFLD */ TYP_MACROFLD, + /* RES_DDEFLD */ TYP_DDEFLD, + /* RES_TABLEFLD */ TYP_FORMELFLD, + /* RES_HIDDENPARAFLD */ TYP_HIDDENPARAFLD, + /* RES_DOCINFOFLD */ TYP_DOCINFOFLD, + /* RES_TEMPLNAMEFLD */ TYP_TEMPLNAMEFLD, + /* RES_DBNEXTSETFLD */ TYP_DBNEXTSETFLD, + /* RES_DBNUMSETFLD */ TYP_DBNUMSETFLD, + /* RES_DBSETNUMBERFLD */ TYP_DBSETNUMBERFLD, + /* RES_EXTUSERFLD */ TYP_EXTUSERFLD, + /* RES_REFPAGESETFLD */ TYP_SETREFPAGEFLD, + /* RES_REFPAGEGETFLD */ TYP_GETREFPAGEFLD, + /* RES_INTERNETFLD */ TYP_INTERNETFLD, + /* RES_JUMPEDITFLD */ TYP_JUMPEDITFLD, + /* RES_SCRIPTFLD */ TYP_SCRIPTFLD, + /* RES_DATETIMEFLD */ 0, // dynamisch + /* RES_AUTHORITY */ TYP_AUTHORITY, + /* RES_COMBINED_CHARS */ TYP_COMBINED_CHARS, + /* RES_DROPDOWN */ TYP_DROPDOWN + }; + // ????? TYP_USRINPFLD, + + + +const String& SwFieldType::GetTypeStr(USHORT nTypeId) +{ + if( !pFldNames ) + _GetFldName(); + + if( nTypeId < SwFieldType::pFldNames->Count() ) + return *SwFieldType::pFldNames->GetObject( nTypeId ); + else + return aEmptyStr; +} + + +/*--------------------------------------------------- + Jedes Feld referenziert einen Feldtypen, der fuer + jedes Dokument einmalig ist. + --------------------------------------------------*/ + +SwFieldType::SwFieldType( USHORT nWhichId ) + : SwModify(0), + nWhich( nWhichId ) +{ + DBG_CTOR( SwFieldType, 0 ); +} + +#ifdef DBG_UTIL + +SwFieldType::~SwFieldType() +{ + DBG_DTOR( SwFieldType, 0 ); +} + +#endif + +const String& SwFieldType::GetName() const +{ + return aEmptyStr; +} + +BOOL SwFieldType::QueryValue( uno::Any&, USHORT ) const +{ + return FALSE; +} +BOOL SwFieldType::PutValue( const uno::Any& , USHORT ) +{ + return FALSE; +} + +/*-------------------------------------------------------------------- + Beschreibung: Basisklasse aller Felder + Felder referenzieren einen Feldtyp + Felder sind n-mal vorhanden, Feldtypen nur einmal + --------------------------------------------------------------------*/ + +SwField::SwField(SwFieldType* pTyp, sal_uInt32 nFmt, USHORT nLng) : + nLang(nLng), + bIsAutomaticLanguage(TRUE), + nFormat(nFmt) +{ + ASSERT( pTyp, "SwField: ungueltiger SwFieldType" ); + pType = pTyp; +} + +SwField::~SwField() +{ +} + +/*-------------------------------------------------------------------- + Beschreibung: Statt Umweg ueber den Typ + --------------------------------------------------------------------*/ + +#ifdef DBG_UTIL +USHORT SwField::Which() const +{ + ASSERT(pType, "Kein Typ vorhanden"); + return pType->Which(); +} +#endif + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +USHORT SwField::GetTypeId() const +{ + + USHORT nRet; + switch( pType->Which() ) + { + case RES_DATETIMEFLD: + if (GetSubType() & FIXEDFLD) + nRet = static_cast<USHORT>(GetSubType() & DATEFLD ? TYP_FIXDATEFLD : TYP_FIXTIMEFLD); + else + nRet = static_cast<USHORT>(GetSubType() & DATEFLD ? TYP_DATEFLD : TYP_TIMEFLD); + break; + case RES_GETEXPFLD: + nRet = static_cast<USHORT>(nsSwGetSetExpType::GSE_FORMULA & GetSubType() ? TYP_FORMELFLD : TYP_GETFLD); + break; + + case RES_HIDDENTXTFLD: + nRet = GetSubType(); + break; + + case RES_SETEXPFLD: + if( nsSwGetSetExpType::GSE_SEQ & GetSubType() ) + nRet = TYP_SEQFLD; + else if( ((SwSetExpField*)this)->GetInputFlag() ) + nRet = TYP_SETINPFLD; + else + nRet = TYP_SETFLD; + break; + + case RES_PAGENUMBERFLD: + nRet = GetSubType(); + if( PG_NEXT == nRet ) + nRet = TYP_NEXTPAGEFLD; + else if( PG_PREV == nRet ) + nRet = TYP_PREVPAGEFLD; + else + nRet = TYP_PAGENUMBERFLD; + break; + + default: + nRet = aTypeTab[ pType->Which() ]; + } + return nRet; +} + + +/*-------------------------------------------------------------------- + Beschreibung: liefert den Namen oder den Inhalt + --------------------------------------------------------------------*/ + +String SwField::GetCntnt( BOOL bName ) const +{ + String sRet; + if( bName ) + { + USHORT nTypeId = GetTypeId(); + if( RES_DATETIMEFLD == GetTyp()->Which() ) + nTypeId = static_cast<USHORT>(GetSubType() & DATEFLD ? TYP_DATEFLD : TYP_TIMEFLD); + + sRet = SwFieldType::GetTypeStr( nTypeId ); + if( IsFixed() ) + ( sRet += ' ' ) += ViewShell::GetShellRes()->aFixedStr; + } + else + sRet = Expand(); + return sRet; +} + +/*-------------------------------------------------------------------- + Beschreibung: Parameter setzen auslesen + --------------------------------------------------------------------*/ + +const String& SwField::GetPar1() const +{ + return aEmptyStr; +} + +String SwField::GetPar2() const +{ + return aEmptyStr; +} + +String SwField::GetFormula() const +{ + return GetPar2(); +} + +void SwField::SetPar1(const String& ) +{} + +void SwField::SetPar2(const String& ) +{} + +USHORT SwField::GetSubType() const +{ +// ASSERT(0, "Sorry Not implemented"); + return 0; +} + +void SwField::SetSubType(USHORT ) +{ +// ASSERT(0, "Sorry Not implemented"); +} + +BOOL SwField::QueryValue( uno::Any& rVal, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_BOOL4: + { + BOOL bFixed = !bIsAutomaticLanguage; + rVal.setValue(&bFixed, ::getCppuBooleanType()); + } + break; + default: + DBG_ERROR("illegal property"); + } + return TRUE; +} +BOOL SwField::PutValue( const uno::Any& rVal, USHORT nWhichId ) +{ + switch( nWhichId ) + { + case FIELD_PROP_BOOL4: + { + BOOL bFixed = FALSE; + if(rVal >>= bFixed) + bIsAutomaticLanguage = !bFixed; + } + break; + default: + DBG_ERROR("illegal property"); + } + return TRUE; +} + + +/*-------------------------------------------------------------------- + Beschreibung: neuen Typ setzen + (wird fuer das Kopieren zwischen Dokumenten benutzt) + muss immer vom gleichen Typ sein. + --------------------------------------------------------------------*/ + +SwFieldType* SwField::ChgTyp( SwFieldType* pNewType ) +{ + ASSERT( pNewType && pNewType->Which() == pType->Which(), + "kein Typ oder ungleiche Typen" ); + + SwFieldType* pOld = pType; + pType = pNewType; + return pOld; +} + + // hat das Feld eine Action auf dem ClickHandler ? (z.B. INetFelder,..) +BOOL SwField::HasClickHdl() const +{ + BOOL bRet = FALSE; + switch( pType->Which() ) + { + case RES_INTERNETFLD: + case RES_JUMPEDITFLD: + case RES_GETREFFLD: + case RES_MACROFLD: + case RES_INPUTFLD: + case RES_DROPDOWN : + bRet = TRUE; + break; + + case RES_SETEXPFLD: + bRet = ((SwSetExpField*)this)->GetInputFlag(); + break; + } + return bRet; +} + +void SwField::SetLanguage(USHORT nLng) +{ + nLang = nLng; +} + +void SwField::ChangeFormat(sal_uInt32 n) +{ + nFormat = n; +} + +BOOL SwField::IsFixed() const +{ + BOOL bRet = FALSE; + switch( pType->Which() ) + { + case RES_FIXDATEFLD: + case RES_FIXTIMEFLD: + bRet = TRUE; + break; + + case RES_DATETIMEFLD: + bRet = 0 != (GetSubType() & FIXEDFLD); + break; + + case RES_EXTUSERFLD: + case RES_AUTHORFLD: + bRet = 0 != (GetFormat() & AF_FIXED); + break; + + case RES_FILENAMEFLD: + bRet = 0 != (GetFormat() & FF_FIXED); + break; + + case RES_DOCINFOFLD: + bRet = 0 != (GetSubType() & DI_SUB_FIXED); + break; + } + return bRet; +} + +String SwField::ExpandField(bool const bInClipboard) const +{ + if (!bInClipboard) // #i85766# do not expand fields in clipboard documents + { + m_Cache = Expand(); + } + return m_Cache; +} + +SwField * SwField::CopyField() const +{ + SwField *const pNew = Copy(); + // #i85766# cache expansion of source (for clipboard) + pNew->m_Cache = Expand(); + return pNew; +} + +/*-------------------------------------------------------------------- + Beschreibung: Numerierung expandieren + --------------------------------------------------------------------*/ + +String FormatNumber(USHORT nNum, sal_uInt32 nFormat) +{ + if(SVX_NUM_PAGEDESC == nFormat) + return String::CreateFromInt32( nNum ); + SvxNumberType aNumber; + + ASSERT(nFormat != SVX_NUM_NUMBER_NONE, "Falsches Nummern-Format" ); + + aNumber.SetNumberingType((sal_Int16)nFormat); + return aNumber.GetNumStr(nNum); +} + +/*-------------------------------------------------------------------- + Beschreibung: CTOR SwValueFieldType + --------------------------------------------------------------------*/ + +SwValueFieldType::SwValueFieldType( SwDoc* pDocPtr, USHORT nWhichId ) + : SwFieldType(nWhichId), + pDoc(pDocPtr), + bUseFormat(TRUE) +{ +} + +SwValueFieldType::SwValueFieldType( const SwValueFieldType& rTyp ) + : SwFieldType(rTyp.Which()), + pDoc(rTyp.GetDoc()), + bUseFormat(rTyp.UseFormat()) +{ +} + +/*-------------------------------------------------------------------- + Beschreibung: Wert formatiert als String zurueckgeben + --------------------------------------------------------------------*/ + +String SwValueFieldType::ExpandValue( const double& rVal, + sal_uInt32 nFmt, USHORT nLng) const +{ + if (rVal >= DBL_MAX) // FehlerString fuer Calculator + return ViewShell::GetShellRes()->aCalc_Error; + + String sExpand; + SvNumberFormatter* pFormatter = pDoc->GetNumberFormatter(); + Color* pCol = 0; + + // wegen Bug #60010 + USHORT nFmtLng = ::lcl_GetLanguageOfFormat( nLng, nFmt, *pFormatter ); + + if( nFmt < SV_COUNTRY_LANGUAGE_OFFSET && LANGUAGE_SYSTEM != nFmtLng ) + { + short nType = NUMBERFORMAT_DEFINED; + xub_StrLen nDummy; + + const SvNumberformat* pEntry = pFormatter->GetEntry(nFmt); + + if (pEntry && nLng != pEntry->GetLanguage()) + { + sal_uInt32 nNewFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nFmt, + (LanguageType)nFmtLng); + + if (nNewFormat == nFmt) + { + // Warscheinlich benutzerdefiniertes Format + String sFmt(pEntry->GetFormatstring()); + + pFormatter->PutandConvertEntry(sFmt, nDummy, nType, nFmt, + pEntry->GetLanguage(), nFmtLng ); + } + else + nFmt = nNewFormat; + } + ASSERT(pEntry, "Unbekanntes Zahlenformat!"); + } + + if( pFormatter->IsTextFormat( nFmt ) ) + { + String sValue; + DoubleToString(sValue, rVal, nFmtLng); + pFormatter->GetOutputString(sValue, nFmt, sExpand, &pCol); + } + else + pFormatter->GetOutputString(rVal, nFmt, sExpand, &pCol); + + return sExpand; +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SwValueFieldType::DoubleToString( String &rValue, const double &rVal, + sal_uInt32 nFmt) const +{ + SvNumberFormatter* pFormatter = pDoc->GetNumberFormatter(); + const SvNumberformat* pEntry = pFormatter->GetEntry(nFmt); + + if (pEntry) + DoubleToString(rValue, rVal, pEntry->GetLanguage()); +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SwValueFieldType::DoubleToString( String &rValue, const double &rVal, + USHORT nLng ) const +{ + SvNumberFormatter* pFormatter = pDoc->GetNumberFormatter(); + + // wegen Bug #60010 + if( nLng == LANGUAGE_NONE ) // wegen Bug #60010 + nLng = LANGUAGE_SYSTEM; + + pFormatter->ChangeIntl( nLng ); // Separator in der richtigen Sprache besorgen + rValue = ::rtl::math::doubleToUString( rVal, rtl_math_StringFormat_F, 12, + pFormatter->GetDecSep(), true ); +} + +/*-------------------------------------------------------------------- + Beschreibung: CTOR SwValueField + --------------------------------------------------------------------*/ + +SwValueField::SwValueField( SwValueFieldType* pFldType, sal_uInt32 nFmt, + USHORT nLng, const double fVal ) + : SwField(pFldType, nFmt, nLng), + fValue(fVal) +{ +} + +SwValueField::SwValueField( const SwValueField& rFld ) + : SwField(rFld), + fValue(rFld.GetValue()) +{ +} + +SwValueField::~SwValueField() +{ +} +/*-------------------------------------------------------------------- + Beschreibung: neuen Typ setzen + (wird fuer das Kopieren zwischen Dokumenten benutzt) + muss immer vom gleichen Typ sein. + --------------------------------------------------------------------*/ + +SwFieldType* SwValueField::ChgTyp( SwFieldType* pNewType ) +{ + SwDoc* pNewDoc = ((SwValueFieldType *)pNewType)->GetDoc(); + SwDoc* pDoc = GetDoc(); + + if( pNewDoc && pDoc && pDoc != pNewDoc) + { + SvNumberFormatter* pFormatter = pNewDoc->GetNumberFormatter(); + + if( pFormatter && pFormatter->HasMergeFmtTbl() && + ((SwValueFieldType *)GetTyp())->UseFormat() ) + SetFormat(pFormatter->GetMergeFmtIndex( GetFormat() )); + } + + return SwField::ChgTyp(pNewType); +} + +/*-------------------------------------------------------------------- + Beschreibung: Format in Office-Sprache ermitteln + --------------------------------------------------------------------*/ + +sal_uInt32 SwValueField::GetSystemFormat(SvNumberFormatter* pFormatter, sal_uInt32 nFmt) +{ + const SvNumberformat* pEntry = pFormatter->GetEntry(nFmt); + USHORT nLng = SvxLocaleToLanguage( SvtSysLocale().GetLocaleData().getLocale() ); + + if (pEntry && nLng != pEntry->GetLanguage()) + { + sal_uInt32 nNewFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nFmt, + (LanguageType)nLng); + + if (nNewFormat == nFmt) + { + // Warscheinlich benutzerdefiniertes Format + short nType = NUMBERFORMAT_DEFINED; + xub_StrLen nDummy; + + String sFmt(pEntry->GetFormatstring()); + + sal_uInt32 nFormat = nFmt; + pFormatter->PutandConvertEntry(sFmt, nDummy, nType, + nFormat, pEntry->GetLanguage(), nLng); + nFmt = nFormat; + } + else + nFmt = nNewFormat; + } + + return nFmt; +} + +/*-------------------------------------------------------------------- + Beschreibung: Sprache im Format anpassen + --------------------------------------------------------------------*/ + +void SwValueField::SetLanguage( USHORT nLng ) +{ + if( IsAutomaticLanguage() && + ((SwValueFieldType *)GetTyp())->UseFormat() && + GetFormat() != SAL_MAX_UINT32 ) + { + // wegen Bug #60010 + SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter(); + USHORT nFmtLng = ::lcl_GetLanguageOfFormat( nLng, GetFormat(), + *pFormatter ); + + if( (GetFormat() >= SV_COUNTRY_LANGUAGE_OFFSET || + LANGUAGE_SYSTEM != nFmtLng ) && + !(Which() == RES_USERFLD && (GetSubType()&nsSwExtendedSubType::SUB_CMD) ) ) + { + const SvNumberformat* pEntry = pFormatter->GetEntry(GetFormat()); + + if( pEntry && nFmtLng != pEntry->GetLanguage() ) + { + sal_uInt32 nNewFormat = pFormatter->GetFormatForLanguageIfBuiltIn( + GetFormat(), (LanguageType)nFmtLng ); + + if( nNewFormat == GetFormat() ) + { + // Warscheinlich benutzerdefiniertes Format + short nType = NUMBERFORMAT_DEFINED; + xub_StrLen nDummy; + String sFmt( pEntry->GetFormatstring() ); + pFormatter->PutandConvertEntry( sFmt, nDummy, nType, + nNewFormat, + pEntry->GetLanguage(), + nFmtLng ); + } + SetFormat( nNewFormat ); + } + ASSERT(pEntry, "Unbekanntes Zahlenformat!"); + } + } + + SwField::SetLanguage(nLng); +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +double SwValueField::GetValue() const +{ + return fValue; +} + +void SwValueField::SetValue( const double& rVal ) +{ + fValue = rVal; +} + +/*-------------------------------------------------------------------- + Beschreibung: SwFormulaField + --------------------------------------------------------------------*/ + +SwFormulaField::SwFormulaField( SwValueFieldType* pFldType, sal_uInt32 nFmt, const double fVal) + : SwValueField(pFldType, nFmt, LANGUAGE_SYSTEM, fVal) +{ +} + +SwFormulaField::SwFormulaField( const SwFormulaField& rFld ) + : SwValueField((SwValueFieldType *)rFld.GetTyp(), rFld.GetFormat(), + rFld.GetLanguage(), rFld.GetValue()) +{ +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +String SwFormulaField::GetFormula() const +{ + return sFormula; +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SwFormulaField::SetFormula(const String& rStr) +{ + sFormula = rStr; + + ULONG nFmt(GetFormat()); + + if( nFmt && SAL_MAX_UINT32 != nFmt ) + { + xub_StrLen nPos = 0; + double fTmpValue; + if( SwCalc::Str2Double( rStr, nPos, fTmpValue, GetDoc() ) ) + SwValueField::SetValue( fTmpValue ); + } +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SwFormulaField::SetExpandedFormula( const String& rStr ) +{ + sal_uInt32 nFmt(GetFormat()); + + if (nFmt && nFmt != SAL_MAX_UINT32 && ((SwValueFieldType *)GetTyp())->UseFormat()) + { + double fTmpValue; + + SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter(); + + if (pFormatter->IsNumberFormat(rStr, nFmt, fTmpValue)) + { + SwValueField::SetValue(fTmpValue); + sFormula.Erase(); + + ((SwValueFieldType *)GetTyp())->DoubleToString(sFormula, fTmpValue, nFmt); + return; + } + } + sFormula = rStr; +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +String SwFormulaField::GetExpandedFormula() const +{ + sal_uInt32 nFmt(GetFormat()); + + if (nFmt && nFmt != SAL_MAX_UINT32 && ((SwValueFieldType *)GetTyp())->UseFormat()) + { + String sFormattedValue; + Color* pCol = 0; + + SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter(); + + if (pFormatter->IsTextFormat(nFmt)) + { + String sValue; + ((SwValueFieldType *)GetTyp())->DoubleToString(sValue, GetValue(), nFmt); + pFormatter->GetOutputString(sValue, nFmt, sFormattedValue, &pCol); + } + else + pFormatter->GetOutputString(GetValue(), nFmt, sFormattedValue, &pCol); + + return sFormattedValue; + } + else + return GetFormula(); +} + +String SwField::GetDescription() const +{ + return SW_RES(STR_FIELD); +} diff --git a/sw/source/core/fields/flddat.cxx b/sw/source/core/fields/flddat.cxx new file mode 100644 index 000000000000..f932a1110820 --- /dev/null +++ b/sw/source/core/fields/flddat.cxx @@ -0,0 +1,321 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + +// #include <math.h> +#include <tools/datetime.hxx> +#include <svl/zforlist.hxx> +#include <com/sun/star/util/DateTime.hpp> +#include <doc.hxx> +#include <fldbas.hxx> +#include <flddat.hxx> +#include <unofldmid.h> + +using namespace ::com::sun::star; +/*-------------------------------------------------- + Beschreibung: Datum/Zeit-Typ + ---------------------------------------------------*/ + +SwDateTimeFieldType::SwDateTimeFieldType(SwDoc* pInitDoc) + : SwValueFieldType( pInitDoc, RES_DATETIMEFLD ) +{} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +SwFieldType* SwDateTimeFieldType::Copy() const +{ + SwDateTimeFieldType *pTmp = new SwDateTimeFieldType(GetDoc()); + return pTmp; +} + +/*-------------------------------------------------------------------- + Beschreibung: Datum/Zeit-Feld + --------------------------------------------------------------------*/ + +SwDateTimeField::SwDateTimeField(SwDateTimeFieldType* pInitType, USHORT nSub, ULONG nFmt, USHORT nLng) + : SwValueField(pInitType, nFmt, nLng, 0.0), + nSubType(nSub), + nOffset(0) +{ + if (!nFmt) + { + SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter(); + if (nSubType & DATEFLD) + ChangeFormat(pFormatter->GetFormatIndex(NF_DATE_SYSTEM_SHORT, GetLanguage())); + else + ChangeFormat(pFormatter->GetFormatIndex(NF_TIME_HHMMSS, GetLanguage())); + } + if (IsFixed()) + { + DateTime aDateTime; + SetDateTime(aDateTime); + } +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +String SwDateTimeField::Expand() const +{ + double fVal; + + if (!(IsFixed())) + { + DateTime aDateTime; + fVal = GetDateTime(GetDoc(), aDateTime); + } + else + fVal = GetValue(); + + if (nOffset) + fVal += (double)(nOffset * 60L) / 86400.0; + + return ExpandValue(fVal, GetFormat(), GetLanguage()); +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +SwField* SwDateTimeField::Copy() const +{ + SwDateTimeField *pTmp = + new SwDateTimeField((SwDateTimeFieldType*)GetTyp(), nSubType, + GetFormat(), GetLanguage()); + + pTmp->SetValue(GetValue()); + pTmp->SetOffset(nOffset); + pTmp->SetAutomaticLanguage(IsAutomaticLanguage()); + + return pTmp; +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +USHORT SwDateTimeField::GetSubType() const +{ + return nSubType; +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SwDateTimeField::SetSubType(USHORT nType) +{ + nSubType = nType; +} +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SwDateTimeField::SetPar2(const String& rStr) +{ + nOffset = rStr.ToInt32(); +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +String SwDateTimeField::GetPar2() const +{ + if (nOffset) + return String::CreateFromInt32(nOffset); + else + return aEmptyStr; +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +void SwDateTimeField::SetDateTime(const DateTime& rDT) +{ + SetValue(GetDateTime(GetDoc(), rDT)); +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +double SwDateTimeField::GetDateTime(SwDoc* pDoc, const DateTime& rDT) +{ + SvNumberFormatter* pFormatter = pDoc->GetNumberFormatter(); + Date* pNullDate = pFormatter->GetNullDate(); + + double fResult = rDT - DateTime(*pNullDate); + + return fResult; +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +double SwDateTimeField::GetValue() const +{ + if (IsFixed()) + return SwValueField::GetValue(); + else + return GetDateTime(GetDoc(), DateTime()); +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +Date SwDateTimeField::GetDate(BOOL bUseOffset) const +{ + SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter(); + Date* pNullDate = pFormatter->GetNullDate(); + + long nVal = static_cast<long>( GetValue() ); + + if (bUseOffset && nOffset) + nVal += nOffset / 60 / 24; + + Date aDate = *pNullDate + nVal; + + return aDate; +} + +/*-------------------------------------------------------------------- + Beschreibung: + --------------------------------------------------------------------*/ + +Time SwDateTimeField::GetTime(BOOL bUseOffset) const +{ + double fDummy; + double fFract = modf(GetValue(), &fDummy); + DateTime aDT((long)fDummy, 0); + aDT += fFract; + if (bUseOffset) + aDT += Time(0, nOffset); + return (Time)aDT; +} + +/*-----------------04.03.98 11:05------------------- + +--------------------------------------------------*/ +BOOL SwDateTimeField::QueryValue( uno::Any& rVal, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_BOOL1: + { + BOOL bTmp = IsFixed(); + rVal.setValue(&bTmp, ::getCppuBooleanType()); + } + break; + case FIELD_PROP_BOOL2: + { + BOOL bTmp = IsDate(); + rVal.setValue(&bTmp, ::getCppuBooleanType()); + } + break; + case FIELD_PROP_FORMAT: + rVal <<= (sal_Int32)GetFormat(); + break; + case FIELD_PROP_SUBTYPE: + rVal <<= (sal_Int32)nOffset; + break; + case FIELD_PROP_DATE_TIME: + { + DateTime aDateTime(GetDate(), GetTime()); + + util::DateTime DateTimeValue; + DateTimeValue.HundredthSeconds = aDateTime.Get100Sec(); + DateTimeValue.Seconds = aDateTime.GetSec(); + DateTimeValue.Minutes = aDateTime.GetMin(); + DateTimeValue.Hours = aDateTime.GetHour(); + DateTimeValue.Day = aDateTime.GetDay(); + DateTimeValue.Month = aDateTime.GetMonth(); + DateTimeValue.Year = aDateTime.GetYear(); + rVal <<= DateTimeValue; + } + break; + default: + return SwField::QueryValue(rVal, nWhichId); + } + return TRUE; +} +/*-----------------04.03.98 11:05------------------- + +--------------------------------------------------*/ +BOOL SwDateTimeField::PutValue( const uno::Any& rVal, USHORT nWhichId ) +{ + sal_Int32 nTmp = 0; + switch( nWhichId ) + { + case FIELD_PROP_BOOL1: + if(*(sal_Bool*)rVal.getValue()) + nSubType |= FIXEDFLD; + else + nSubType &= ~FIXEDFLD; + break; + case FIELD_PROP_BOOL2: + nSubType &= ~(DATEFLD|TIMEFLD); + nSubType |= *(sal_Bool*)rVal.getValue() ? DATEFLD : TIMEFLD; + break; + case FIELD_PROP_FORMAT: + rVal >>= nTmp; + ChangeFormat(nTmp); + break; + case FIELD_PROP_SUBTYPE: + rVal >>= nTmp; + nOffset = nTmp; + break; + case FIELD_PROP_DATE_TIME: + { + util::DateTime aDateTimeValue; + if(!(rVal >>= aDateTimeValue)) + return FALSE; + DateTime aDateTime; + aDateTime.Set100Sec(aDateTimeValue.HundredthSeconds); + aDateTime.SetSec(aDateTimeValue.Seconds); + aDateTime.SetMin(aDateTimeValue.Minutes); + aDateTime.SetHour(aDateTimeValue.Hours); + aDateTime.SetDay(aDateTimeValue.Day); + aDateTime.SetMonth(aDateTimeValue.Month); + aDateTime.SetYear(aDateTimeValue.Year); + SetDateTime(aDateTime); + } + break; + default: + return SwField::PutValue(rVal, nWhichId); + } + return TRUE; +} + diff --git a/sw/source/core/fields/flddropdown.cxx b/sw/source/core/fields/flddropdown.cxx new file mode 100644 index 000000000000..15b35c7999de --- /dev/null +++ b/sw/source/core/fields/flddropdown.cxx @@ -0,0 +1,284 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + +#include <flddropdown.hxx> + +#ifndef INCLUDED_ALGORITHM +#include <algorithm> +#define INCLUDED_ALGORITHM +#endif +#include <svl/poolitem.hxx> + +#ifndef _UNOFLDMID_H +#include <unofldmid.h> +#endif +#include <unoprnms.hxx> + +using namespace com::sun::star; + +using rtl::OUString; +using std::vector; + +static String aEmptyString; + +SwDropDownFieldType::SwDropDownFieldType() + : SwFieldType(RES_DROPDOWN) +{ +} + +SwDropDownFieldType::~SwDropDownFieldType() +{ +} + +SwFieldType * SwDropDownFieldType::Copy() const +{ + return new SwDropDownFieldType; +} + +SwDropDownField::SwDropDownField(SwFieldType * pTyp) + : SwField(pTyp, 0, LANGUAGE_SYSTEM) +{ +} + +SwDropDownField::SwDropDownField(const SwDropDownField & rSrc) + : SwField(rSrc.GetTyp(), rSrc.GetFormat(), rSrc.GetLanguage()), + aValues(rSrc.aValues), aSelectedItem(rSrc.aSelectedItem), + aName(rSrc.aName), aHelp(rSrc.aHelp), aToolTip(rSrc.aToolTip) +{ +} + +SwDropDownField::~SwDropDownField() +{ +} + +String SwDropDownField::Expand() const +{ + String sSelect = GetSelectedItem(); + if(!sSelect.Len()) + { + vector<String>::const_iterator aIt = aValues.begin(); + if ( aIt != aValues.end()) + sSelect = *aIt; + } + //if still no list value is available a default text of 10 spaces is to be set + if(!sSelect.Len()) + sSelect.AppendAscii ( RTL_CONSTASCII_STRINGPARAM (" ")); + return sSelect; +} + +SwField * SwDropDownField::Copy() const +{ + return new SwDropDownField(*this); +} + +const String & SwDropDownField::GetPar1() const +{ + return GetSelectedItem(); +} + +String SwDropDownField::GetPar2() const +{ + return GetName(); +} + +void SwDropDownField::SetPar1(const String & rStr) +{ + SetSelectedItem(rStr); +} + +void SwDropDownField::SetPar2(const String & rName) +{ + SetName(rName); +} + +void SwDropDownField::SetItems(const vector<String> & rItems) +{ + aValues = rItems; + aSelectedItem = aEmptyString; +} + +void SwDropDownField::SetItems(const uno::Sequence<OUString> & rItems) +{ + aValues.clear(); + + sal_Int32 aCount = rItems.getLength(); + for (int i = 0; i < aCount; i++) + aValues.push_back(rItems[i]); + + aSelectedItem = aEmptyString; +} + +uno::Sequence<OUString> SwDropDownField::GetItemSequence() const +{ + uno::Sequence<OUString> aSeq( aValues.size() ); + OUString* pSeq = aSeq.getArray(); + int i = 0; + vector<String>::const_iterator aIt; + + for (aIt = aValues.begin(); aIt != aValues.end(); aIt++) + { + pSeq[i] = rtl::OUString(*aIt); + + i++; + } + + return aSeq; +} + +const String & SwDropDownField::GetSelectedItem() const +{ + return aSelectedItem; +} + +const String & SwDropDownField::GetName() const +{ + return aName; +} + +const String & SwDropDownField::GetHelp() const +{ + return aHelp; +} + +const String & SwDropDownField::GetToolTip() const +{ + return aToolTip; +} + +BOOL SwDropDownField::SetSelectedItem(const String & rItem) +{ + vector<String>::const_iterator aIt = + std::find(aValues.begin(), aValues.end(), rItem); + + if (aIt != aValues.end()) + aSelectedItem = *aIt; + else + aSelectedItem = String(); + + return (aIt != aValues.end()); +} + +void SwDropDownField::SetName(const String & rName) +{ + aName = rName; +} + +void SwDropDownField::SetHelp(const String & rHelp) +{ + aHelp = rHelp; +} + +void SwDropDownField::SetToolTip(const String & rToolTip) +{ + aToolTip = rToolTip; +} + +BOOL SwDropDownField::QueryValue(::uno::Any &rVal, USHORT nWhich) const +{ + nWhich &= ~CONVERT_TWIPS; + switch( nWhich ) + { + case FIELD_PROP_PAR1: + rVal <<= rtl::OUString(GetSelectedItem()); + break; + case FIELD_PROP_PAR2: + rVal <<= rtl::OUString(GetName()); + break; + case FIELD_PROP_PAR3: + rVal <<= rtl::OUString(GetHelp()); + break; + case FIELD_PROP_PAR4: + rVal <<= rtl::OUString(GetToolTip()); + break; + case FIELD_PROP_STRINGS: + rVal <<= GetItemSequence(); + + break; + + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} + +BOOL SwDropDownField::PutValue(const uno::Any &rVal, + USHORT nWhich) +{ + switch( nWhich ) + { + case FIELD_PROP_PAR1: + { + String aTmpStr; + ::GetString( rVal, aTmpStr ); + + SetSelectedItem(aTmpStr); + } + break; + + case FIELD_PROP_PAR2: + { + String aTmpStr; + ::GetString( rVal, aTmpStr ); + + SetName(aTmpStr); + } + break; + + case FIELD_PROP_PAR3: + { + String aTmpStr; + ::GetString( rVal, aTmpStr ); + + SetHelp(aTmpStr); + } + break; + + case FIELD_PROP_PAR4: + { + String aTmpStr; + ::GetString( rVal, aTmpStr ); + + SetToolTip(aTmpStr); + } + break; + + case FIELD_PROP_STRINGS: + { + uno::Sequence<OUString> aSeq; + rVal >>= aSeq; + SetItems(aSeq); + } + break; + + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} diff --git a/sw/source/core/fields/fldlst.cxx b/sw/source/core/fields/fldlst.cxx new file mode 100644 index 000000000000..abf688cbbf5f --- /dev/null +++ b/sw/source/core/fields/fldlst.cxx @@ -0,0 +1,233 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + + +#include "editsh.hxx" +#include "doc.hxx" +#include <docary.hxx> +#include <fmtfld.hxx> +#include <txtfld.hxx> +#include "edimp.hxx" +#include "expfld.hxx" +#include "pam.hxx" +#include "docfld.hxx" +#include "ndtxt.hxx" + + +/*-------------------------------------------------------------------- + Beschreibung: Sortieren der Input-Eintraege + --------------------------------------------------------------------*/ + +SwInputFieldList::SwInputFieldList( SwEditShell* pShell, BOOL bBuildTmpLst ) + : pSh(pShell) +{ + // Hier die Liste aller Eingabefelder sortiert erstellen + pSrtLst = new _SetGetExpFlds(); + + const SwFldTypes& rFldTypes = *pSh->GetDoc()->GetFldTypes(); + const USHORT nSize = rFldTypes.Count(); + + // Alle Typen abklappern + + for(USHORT i=0; i < nSize; ++i) + { + SwFieldType* pFldType = (SwFieldType*)rFldTypes[ i ]; + USHORT nType = pFldType->Which(); + + if( RES_SETEXPFLD == nType || RES_INPUTFLD == nType || RES_DROPDOWN == nType ) + { + SwClientIter aIter( *pFldType ); + for( SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE(SwFmtFld) ); + pFld; pFld = (SwFmtFld*)aIter.Next() ) + + { + const SwTxtFld* pTxtFld = pFld->GetTxtFld(); + + // nur InputFields und interaktive SetExpFlds bearbeiten + // and DropDown fields + if( !pTxtFld || ( RES_SETEXPFLD == nType && + !((SwSetExpField*)pFld->GetFld())->GetInputFlag())) + continue; + + const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode(); + if( rTxtNode.GetNodes().IsDocNodes() ) + { + if( bBuildTmpLst ) + { + VoidPtr pTmp = (VoidPtr)pTxtFld; + aTmpLst.Insert( pTmp, aTmpLst.Count() ); + } + else + { + SwNodeIndex aIdx( rTxtNode ); + _SetGetExpFld* pNew = new _SetGetExpFld(aIdx, pTxtFld ); + pSrtLst->Insert( pNew ); + } + } + } + } + } +} + +SwInputFieldList::~SwInputFieldList() +{ + delete pSrtLst; +} + +/*-------------------------------------------------------------------- + Beschreibung: Felder aus der Liste in sortierter Reihenfolge + --------------------------------------------------------------------*/ + +USHORT SwInputFieldList::Count() const +{ + return pSrtLst->Count(); +} + + +SwField* SwInputFieldList::GetField(USHORT nId) +{ + const SwTxtFld* pTxtFld = (*pSrtLst)[ nId ]->GetFld(); + ASSERT( pTxtFld, "kein TextFld" ); + return (SwField*)pTxtFld->GetFld().GetFld(); +} + +/*-------------------------------------------------------------------- + Beschreibung: Cursor sichern + --------------------------------------------------------------------*/ + +void SwInputFieldList::PushCrsr() +{ + pSh->Push(); + pSh->ClearMark(); +} + +void SwInputFieldList::PopCrsr() +{ + pSh->Pop(FALSE); +} + +/*-------------------------------------------------------------------- + Beschreibung: Position eines Feldes ansteuern + --------------------------------------------------------------------*/ + +void SwInputFieldList::GotoFieldPos(USHORT nId) +{ + pSh->StartAllAction(); + (*pSrtLst)[ nId ]->GetPosOfContent( *pSh->GetCrsr()->GetPoint() ); + pSh->EndAllAction(); +} + + // vergleiche TmpLst mit akt Feldern. Alle neue kommen in die SortLst + // damit sie geupdatet werden koennen. Returnt die Anzahl. + // (Fuer Textbausteine: nur seine Input-Felder aktualisieren) +USHORT SwInputFieldList::BuildSortLst() +{ + const SwFldTypes& rFldTypes = *pSh->GetDoc()->GetFldTypes(); + USHORT nSize = rFldTypes.Count(); + + // Alle Typen abklappern + + for( USHORT i = 0; i < nSize; ++i ) + { + SwFieldType* pFldType = (SwFieldType*)rFldTypes[ i ]; + USHORT nType = pFldType->Which(); + + if( RES_SETEXPFLD == nType || RES_INPUTFLD == nType ) + { + SwClientIter aIter( *pFldType ); + for( SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE(SwFmtFld) ); + pFld; pFld = (SwFmtFld*)aIter.Next() ) + { + const SwTxtFld* pTxtFld = pFld->GetTxtFld(); + + // nur InputFields und interaktive SetExpFlds bearbeiten + if( !pTxtFld || ( RES_SETEXPFLD == nType && + !((SwSetExpField*)pFld->GetFld())->GetInputFlag())) + continue; + + const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode(); + if( rTxtNode.GetNodes().IsDocNodes() ) + { + VoidPtr pTmp = (VoidPtr)pTxtFld; + // nicht in der TempListe vorhanden, also in die SortListe + // aufnehemen + USHORT nFndPos = aTmpLst.GetPos( pTmp ); + if( USHRT_MAX == nFndPos ) + { + SwNodeIndex aIdx( rTxtNode ); + _SetGetExpFld* pNew = new _SetGetExpFld(aIdx, pTxtFld ); + pSrtLst->Insert( pNew ); + } + else + aTmpLst.Remove( nFndPos ); + } + } + } + } + + // die Pointer werden nicht mehr gebraucht + aTmpLst.Remove( 0, aTmpLst.Count() ); + return pSrtLst->Count(); +} + +/*-------------------------------------------------------------------- + Beschreibung: Alle Felder auáerhalb von Selektionen aus Liste entfernen + --------------------------------------------------------------------*/ + +void SwInputFieldList::RemoveUnselectedFlds() +{ + _SetGetExpFlds* pNewLst = new _SetGetExpFlds(); + + FOREACHPAM_START(pSh) + { + for (USHORT i = 0; i < Count();) + { + _SetGetExpFld* pFld = (*pSrtLst)[i]; + SwPosition aPos(*PCURCRSR->GetPoint()); + + pFld->GetPos( aPos ); + + if (aPos >= *PCURCRSR->Start() && aPos < *PCURCRSR->End()) + { + // Feld innerhalb der Selektion + pNewLst->Insert( (*pSrtLst)[i] ); + pSrtLst->Remove(i, 1); + } + else + i++; + } + } + FOREACHPAM_END() + + delete pSrtLst; + pSrtLst = pNewLst; +} + + diff --git a/sw/source/core/fields/macrofld.cxx b/sw/source/core/fields/macrofld.cxx new file mode 100644 index 000000000000..70a0d2dcf689 --- /dev/null +++ b/sw/source/core/fields/macrofld.cxx @@ -0,0 +1,266 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + + +#include <hintids.hxx> +#include <doc.hxx> +#include <docufld.hxx> +#ifndef _UNOFLDMID_H +#include <unofldmid.h> +#endif +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/uri/XUriReferenceFactory.hpp> +#include <com/sun/star/uri/XVndSunStarScriptUrl.hpp> +#include <comphelper/processfactory.hxx> + +using namespace ::com::sun::star; +using ::rtl::OUString; +/*-------------------------------------------------------------------- + Beschreibung: MacroFeldtypen + --------------------------------------------------------------------*/ + +SwMacroFieldType::SwMacroFieldType(SwDoc* pDocument) + : SwFieldType( RES_MACROFLD ), + pDoc(pDocument) +{ +} + +SwFieldType* SwMacroFieldType::Copy() const +{ + SwMacroFieldType* pType = new SwMacroFieldType(pDoc); + return pType; +} + +/*-------------------------------------------------------------------- + Beschreibung: Das Macrofeld selbst + --------------------------------------------------------------------*/ + +SwMacroField::SwMacroField(SwMacroFieldType* pInitType, + const String& rLibAndName, const String& rTxt) : + SwField(pInitType), aMacro(rLibAndName), aText(rTxt), bIsScriptURL(FALSE) +{ + bIsScriptURL = isScriptURL(aMacro); +} + +String SwMacroField::Expand() const +{ // Button malen anstatt von + return aText ; +} + +SwField* SwMacroField::Copy() const +{ + return new SwMacroField((SwMacroFieldType*)GetTyp(), aMacro, aText); +} + +String SwMacroField::GetCntnt(BOOL bName) const +{ + if(bName) + { + String aStr(GetTyp()->GetName()); + aStr += ' '; + aStr += aMacro; + return aStr; + } + return Expand(); +} + +String SwMacroField::GetLibName() const +{ + // if it is a Scripting Framework macro return an empty string + if (bIsScriptURL) + { + return String(); + } + + if (aMacro.Len()) + { + USHORT nPos = aMacro.Len(); + + for (USHORT i = 0; i < 3 && nPos > 0; i++) + while (aMacro.GetChar(--nPos) != '.' && nPos > 0) ; + + return aMacro.Copy(0, nPos ); + } + + DBG_ASSERT(0, "Kein Macroname vorhanden"); + return aEmptyStr; +} + +String SwMacroField::GetMacroName() const +{ + if (aMacro.Len()) + { + if (bIsScriptURL) + { + return aMacro.Copy( 0 ); + } + else + { + USHORT nPos = aMacro.Len(); + + for (USHORT i = 0; i < 3 && nPos > 0; i++) + while (aMacro.GetChar(--nPos) != '.' && nPos > 0) ; + + return aMacro.Copy( ++nPos ); + } + } + + DBG_ASSERT(0, "Kein Macroname vorhanden"); + return aEmptyStr; +} + +SvxMacro SwMacroField::GetSvxMacro() const +{ + if (bIsScriptURL) + { + return SvxMacro(aMacro, String(), EXTENDED_STYPE); + } + else + { + return SvxMacro(GetMacroName(), GetLibName(), STARBASIC); + } +} + +/*-------------------------------------------------------------------- + Beschreibung: LibName und MacroName + --------------------------------------------------------------------*/ + +void SwMacroField::SetPar1(const String& rStr) +{ + aMacro = rStr; + bIsScriptURL = isScriptURL(aMacro); +} + +const String& SwMacroField::GetPar1() const +{ + return aMacro; +} + +/*-------------------------------------------------------------------- + Beschreibung: Macrotext + --------------------------------------------------------------------*/ + +void SwMacroField::SetPar2(const String& rStr) +{ + aText = rStr; +} + +String SwMacroField::GetPar2() const +{ + return aText; +} + +/*-----------------05.03.98 13:38------------------- + +--------------------------------------------------*/ +BOOL SwMacroField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + rAny <<= OUString(GetMacroName()); + break; + case FIELD_PROP_PAR2: + rAny <<= OUString(aText); + break; + case FIELD_PROP_PAR3: + rAny <<= OUString(GetLibName()); + break; + case FIELD_PROP_PAR4: + rAny <<= bIsScriptURL ? OUString(GetMacroName()): OUString(); + break; + default: + DBG_ERROR("illegal property"); + } + return TRUE; +} +/*-----------------05.03.98 13:38------------------- + +--------------------------------------------------*/ +BOOL SwMacroField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + String sTmp; + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + CreateMacroString( aMacro, ::GetString(rAny, sTmp), GetLibName()); + break; + case FIELD_PROP_PAR2: + ::GetString( rAny, aText ); + break; + case FIELD_PROP_PAR3: + CreateMacroString(aMacro, GetMacroName(), ::GetString(rAny, sTmp) ); + break; + case FIELD_PROP_PAR4: + ::GetString(rAny, aMacro); + bIsScriptURL = isScriptURL(aMacro); + break; + default: + DBG_ERROR("illegal property"); + } + + return TRUE; +} + +// create an internally used macro name from the library and macro name parts +void SwMacroField::CreateMacroString( + String& rMacro, + const String& rMacroName, + const String& rLibraryName ) +{ + // concatenate library and name; use dot only if both strings have content + rMacro = rLibraryName; + if ( rLibraryName.Len() > 0 && rMacroName.Len() > 0 ) + rMacro += '.'; + rMacro += rMacroName; +} + +BOOL SwMacroField::isScriptURL( const String& str ) +{ + uno::Reference< lang::XMultiServiceFactory > xSMgr = + ::comphelper::getProcessServiceFactory(); + + uno::Reference< uri::XUriReferenceFactory > + xFactory( xSMgr->createInstance( + OUString::createFromAscii( + "com.sun.star.uri.UriReferenceFactory" ) ), uno::UNO_QUERY ); + + if ( xFactory.is() ) + { + uno::Reference< uri::XVndSunStarScriptUrl > + xUrl( xFactory->parse( str ), uno::UNO_QUERY ); + + if ( xUrl.is() ) + { + return TRUE; + } + } + return FALSE; +} diff --git a/sw/source/core/fields/makefile.mk b/sw/source/core/fields/makefile.mk new file mode 100644 index 000000000000..280fff6aae88 --- /dev/null +++ b/sw/source/core/fields/makefile.mk @@ -0,0 +1,94 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=sw +TARGET=fields + +AUTOSEG=true + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/inc$/swpre.mk +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/inc$/sw.mk + +# --- Files -------------------------------------------------------- + +CXXFILES = \ + authfld.cxx \ + cellfml.cxx \ + chpfld.cxx \ + dbfld.cxx \ + ddefld.cxx \ + ddetbl.cxx \ + docufld.cxx \ + expfld.cxx \ + fldbas.cxx \ + flddat.cxx \ + flddropdown.cxx \ + scrptfld.cxx \ + macrofld.cxx \ + fldlst.cxx \ + postithelper.cxx \ + reffld.cxx \ + tblcalc.cxx \ + usrfld.cxx + + + +SLOFILES = \ + $(SLO)$/textapi.obj \ + $(SLO)$/authfld.obj \ + $(SLO)$/cellfml.obj \ + $(SLO)$/chpfld.obj \ + $(SLO)$/dbfld.obj \ + $(SLO)$/ddefld.obj \ + $(SLO)$/ddetbl.obj \ + $(SLO)$/docufld.obj \ + $(SLO)$/expfld.obj \ + $(SLO)$/fldbas.obj \ + $(SLO)$/flddat.obj \ + $(SLO)$/flddropdown.obj \ + $(SLO)$/fldlst.obj \ + $(SLO)$/scrptfld.obj \ + $(SLO)$/macrofld.obj \ + $(SLO)$/postithelper.obj \ + $(SLO)$/reffld.obj \ + $(SLO)$/tblcalc.obj \ + $(SLO)$/usrfld.obj + +EXCEPTIONSFILES = \ + $(SLO)$/flddropdown.obj \ + $(SLO)$/postithelper.obj \ + $(SLO)$/docufld.obj + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/sw/source/core/fields/postithelper.cxx b/sw/source/core/fields/postithelper.cxx new file mode 100644 index 000000000000..1d76dce43117 --- /dev/null +++ b/sw/source/core/fields/postithelper.cxx @@ -0,0 +1,223 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + +#include <tools/gen.hxx> + +#include <postithelper.hxx> +#include <PostItMgr.hxx> +#include <AnnotationWin.hxx> + +#include <fmtfld.hxx> +#include <txtfld.hxx> +#include <docufld.hxx> +#include <ndtxt.hxx> +#include <cntfrm.hxx> +#include <pagefrm.hxx> +#include <rootfrm.hxx> +#include <txtfrm.hxx> +#include <tabfrm.hxx> +#include <IDocumentRedlineAccess.hxx> +#include <redline.hxx> +#include <scriptinfo.hxx> +#include <editeng/charhiddenitem.hxx> + + +namespace { + +struct LayoutInfoOrder +{ + bool operator()( const SwLayoutInfo& rLayoutInfo, + const SwLayoutInfo& rNewLayoutInfo ) + { + if ( rLayoutInfo.mnPageNumber != rNewLayoutInfo.mnPageNumber ) + { + // corresponding <SwFrm> instances are on different pages + return rLayoutInfo.mnPageNumber < rNewLayoutInfo.mnPageNumber; + } + else + { + // corresponding <SwFrm> instances are in different repeating table header rows + ASSERT( rLayoutInfo.mpAnchorFrm->FindTabFrm(), + "<LayoutInfoOrder::operator()> - table frame not found" ); + ASSERT( rNewLayoutInfo.mpAnchorFrm->FindTabFrm(), + "<LayoutInfoOrder::operator()> - table frame not found" ); + const SwTabFrm* pLayoutInfoTabFrm( rLayoutInfo.mpAnchorFrm->FindTabFrm() ); + const SwTabFrm* pNewLayoutInfoTabFrm( rNewLayoutInfo.mpAnchorFrm->FindTabFrm() ); + const SwTabFrm* pTmpTabFrm( pNewLayoutInfoTabFrm ); + while ( pTmpTabFrm && pTmpTabFrm->GetFollow() ) + { + pTmpTabFrm = static_cast<const SwTabFrm*>(pTmpTabFrm->GetFollow()->GetFrm()); + if ( pTmpTabFrm == pLayoutInfoTabFrm ) + { + return false; + } + } + return true; + } + } +}; + +} // eof anonymous namespace + +SwPostItHelper::SwLayoutStatus SwPostItHelper::getLayoutInfos( std::vector< SwLayoutInfo >& rInfo, SwPosition& rPos ) +{ + SwLayoutStatus aRet = INVISIBLE; + const SwTxtNode* pTxtNode = rPos.nNode.GetNode().GetTxtNode(); + SwCntntNode* pNode = rPos.nNode.GetNode().GetCntntNode(); // getfirstcontentnode // getnext... + if( !pNode ) + return aRet; + SwClientIter aIter( *pNode ); + SwTxtFrm *pTxtFrm; + for( pTxtFrm = (SwTxtFrm*)aIter.First( TYPE( SwTxtFrm )); pTxtFrm; pTxtFrm = (SwTxtFrm*)aIter.Next() ) + { + if( !pTxtFrm->IsFollow() ) + { + pTxtFrm = ((SwTxtFrm*)pTxtFrm)->GetFrmAtPos( rPos ); + SwPageFrm *pPage = pTxtFrm ? pTxtFrm->FindPageFrm() : 0; + // #i103490# + if ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() ) + { + SwLayoutInfo aInfo; + pTxtFrm->GetCharRect( aInfo.mPosition, rPos, 0 ); + aInfo.mpAnchorFrm = pTxtFrm; + aInfo.mPageFrame = pPage->Frm(); + aInfo.mPagePrtArea = pPage->Prt(); + aInfo.mPagePrtArea.Pos() += aInfo.mPageFrame.Pos(); + aInfo.mnPageNumber = pPage->GetPhyPageNum(); + aInfo.meSidebarPosition = pPage->SidebarPosition(); + aInfo.mRedlineAuthor = 0; + + if( aRet == INVISIBLE ) + { + aRet = VISIBLE; + const IDocumentRedlineAccess* pIDRA = pNode->getIDocumentRedlineAccess(); + if( IDocumentRedlineAccess::IsShowChanges( pIDRA->GetRedlineMode() ) ) + { + const SwRedline* pRedline = pIDRA->GetRedline( rPos, 0 ); + if( pRedline ) + { + if( nsRedlineType_t::REDLINE_INSERT == pRedline->GetType() ) + aRet = INSERTED; + else if( nsRedlineType_t::REDLINE_DELETE == pRedline->GetType() ) + aRet = DELETED; + aInfo.mRedlineAuthor = pRedline->GetAuthor(); + } + } + } + + { + std::vector< SwLayoutInfo >::iterator aInsPosIter = + std::lower_bound( rInfo.begin(), rInfo.end(), + aInfo, LayoutInfoOrder() ); + + rInfo.insert( aInsPosIter, aInfo ); + } + } + } + } + return ((aRet==VISIBLE) && SwScriptInfo::IsInHiddenRange( *pTxtNode , rPos.nContent.GetIndex()) ) ? HIDDEN : aRet; +} + +long SwPostItHelper::getLayoutHeight( const SwRootFrm* pRoot ) +{ + long nRet = pRoot ? pRoot->Frm().Height() : 0; + return nRet; +} + +void SwPostItHelper::setSidebarChanged( SwRootFrm* pRoot, bool bBrowseMode ) +{ + if( pRoot ) + { + pRoot->SetSidebarChanged(); + if( bBrowseMode ) + pRoot->InvalidateBrowseWidth(); + } +} + +unsigned long SwPostItHelper::getPageInfo( SwRect& rPageFrm, const SwRootFrm* pRoot, const Point& rPoint ) +{ + unsigned long nRet = 0; + const SwFrm* pPage = pRoot->GetPageAtPos( rPoint, 0, true ); + if( pPage ) + { + nRet = pPage->GetPhyPageNum(); + rPageFrm = pPage->Frm(); + } + return nRet; +} + +SwPosition SwAnnotationItem::GetAnchorPosition() const +{ + SwTxtFld* pFld = pFmtFld->GetTxtFld(); + //if( pFld ) + //{ + SwTxtNode* pTNd = pFld->GetpTxtNode(); + // if( pTNd ) + // { + SwPosition aPos( *pTNd ); + aPos.nContent.Assign( pTNd, *pFld->GetStart() ); + return aPos; + // } + //} +} + +bool SwAnnotationItem::UseElement() +{ + return pFmtFld->IsFldInDoc(); +} + +sw::sidebarwindows::SwSidebarWin* SwAnnotationItem::GetSidebarWindow( + SwEditWin& rEditWin, + WinBits nBits, + SwPostItMgr& aMgr, + SwPostItBits aBits) +{ + return new sw::annotation::SwAnnotationWin( rEditWin, nBits, + aMgr, aBits, + *this, + pFmtFld ); +} + +/* +SwPosition SwRedCommentItem::GetAnchorPosition() +{ + return *pRedline->Start(); +} + +SwSidebarWin* SwRedCommentItem::GetSidebarWindow(Window* pParent, WinBits nBits,SwPostItMgr* aMgr,SwPostItBits aBits) +{ + return new SwRedComment(pParent,nBits,aMgr,aBits,pRedline); +} + +bool SwRedCommentItem::UseElement() +{ + return true; +} +*/ diff --git a/sw/source/core/fields/reffld.cxx b/sw/source/core/fields/reffld.cxx new file mode 100644 index 000000000000..8b03b7e54664 --- /dev/null +++ b/sw/source/core/fields/reffld.cxx @@ -0,0 +1,1099 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + + +#define _SVSTDARR_USHORTSSORT +#define _SVSTDARR_USHORTS +#include <svl/svstdarr.hxx> +#include <com/sun/star/text/ReferenceFieldPart.hpp> +#include <com/sun/star/text/ReferenceFieldSource.hpp> +#include <unotools/localedatawrapper.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <comphelper/processfactory.hxx> +#include <editeng/unolingu.hxx> +#include <doc.hxx> +#include <pam.hxx> +#include <cntfrm.hxx> +#include <pagefrm.hxx> +#include <docary.hxx> +#include <fmtfld.hxx> +#include <txtfld.hxx> +#include <txtftn.hxx> +#include <fmtrfmrk.hxx> +#include <txtrfmrk.hxx> +#include <fmtftn.hxx> +#include <ndtxt.hxx> +#include <chpfld.hxx> +#include <reffld.hxx> +#include <expfld.hxx> +#include <txtfrm.hxx> +#include <flyfrm.hxx> +#include <pagedesc.hxx> +#include <IMark.hxx> +// --> OD 2007-10-18 #i81002# +#include <crossrefbookmark.hxx> +// <-- +#include <ftnidx.hxx> +#include <viewsh.hxx> +#ifndef _UNOFLDMID_H +#include <unofldmid.h> +#endif +#include <SwStyleNameMapper.hxx> +#include <shellres.hxx> +#include <poolfmt.hxx> +#ifndef _POOLFMT_HRC +#include <poolfmt.hrc> +#endif +#ifndef _COMCORE_HRC +#include <comcore.hrc> +#endif +#include <numrule.hxx> +#include <SwNodeNum.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::text; +using namespace ::com::sun::star::lang; +using ::rtl::OUString; + +extern void InsertSort( SvUShorts& rArr, USHORT nIdx, USHORT* pInsPos = 0 ); + +void lcl_GetLayTree( const SwFrm* pFrm, SvPtrarr& rArr ) +{ + while( pFrm ) + { + if( pFrm->IsBodyFrm() ) // soll uns nicht weiter interessieren + pFrm = pFrm->GetUpper(); + else + { + void* p = (void*)pFrm; + rArr.Insert( p, rArr.Count() ); + + // bei der Seite ist schluss + if( pFrm->IsPageFrm() ) + break; + + if( pFrm->IsFlyFrm() ) + pFrm = ((SwFlyFrm*)pFrm)->GetAnchorFrm(); + else + pFrm = pFrm->GetUpper(); + } + } +} + + +BOOL IsFrameBehind( const SwTxtNode& rMyNd, USHORT nMySttPos, + const SwTxtNode& rBehindNd, USHORT nSttPos ) +{ + const SwTxtFrm *pMyFrm = (SwTxtFrm*)rMyNd.GetFrm(0,0,FALSE), + *pFrm = (SwTxtFrm*)rBehindNd.GetFrm(0,0,FALSE); + + while( pFrm && !pFrm->IsInside( nSttPos ) ) + pFrm = (SwTxtFrm*)pFrm->GetFollow(); + while( pMyFrm && !pMyFrm->IsInside( nMySttPos ) ) + pMyFrm = (SwTxtFrm*)pMyFrm->GetFollow(); + + if( !pFrm || !pMyFrm || pFrm == pMyFrm ) + return FALSE; + + SvPtrarr aRefArr( 10, 10 ), aArr( 10, 10 ); + ::lcl_GetLayTree( pFrm, aRefArr ); + ::lcl_GetLayTree( pMyFrm, aArr ); + + USHORT nRefCnt = aRefArr.Count() - 1, nCnt = aArr.Count() - 1; + BOOL bVert = FALSE; + BOOL bR2L = FALSE; + + // solange bis ein Frame ungleich ist ? + while( nRefCnt && nCnt && aRefArr[ nRefCnt ] == aArr[ nCnt ] ) + { + const SwFrm* pTmpFrm = (const SwFrm*)aArr[ nCnt ]; + bVert = pTmpFrm->IsVertical(); + bR2L = pTmpFrm->IsRightToLeft(); + --nCnt, --nRefCnt; + } + + // sollte einer der Counter ueberlaeufen? + if( aRefArr[ nRefCnt ] == aArr[ nCnt ] ) + { + if( nCnt ) + --nCnt; + else + --nRefCnt; + } + + const SwFrm* pRefFrm = (const SwFrm*)aRefArr[ nRefCnt ]; + const SwFrm* pFldFrm = (const SwFrm*)aArr[ nCnt ]; + + // unterschiedliche Frames, dann ueberpruefe deren Y-/X-Position + BOOL bRefIsLower = FALSE; + if( ( FRM_COLUMN | FRM_CELL ) & pFldFrm->GetType() || + ( FRM_COLUMN | FRM_CELL ) & pRefFrm->GetType() ) + { + if( pFldFrm->GetType() == pRefFrm->GetType() ) + { + // hier ist die X-Pos wichtiger! + if( bVert ) + { + if( bR2L ) + bRefIsLower = pRefFrm->Frm().Top() < pFldFrm->Frm().Top() || + ( pRefFrm->Frm().Top() == pFldFrm->Frm().Top() && + pRefFrm->Frm().Left() < pFldFrm->Frm().Left() ); + else + bRefIsLower = pRefFrm->Frm().Top() < pFldFrm->Frm().Top() || + ( pRefFrm->Frm().Top() == pFldFrm->Frm().Top() && + pRefFrm->Frm().Left() > pFldFrm->Frm().Left() ); + } + else if( bR2L ) + bRefIsLower = pRefFrm->Frm().Left() > pFldFrm->Frm().Left() || + ( pRefFrm->Frm().Left() == pFldFrm->Frm().Left() && + pRefFrm->Frm().Top() < pFldFrm->Frm().Top() ); + else + bRefIsLower = pRefFrm->Frm().Left() < pFldFrm->Frm().Left() || + ( pRefFrm->Frm().Left() == pFldFrm->Frm().Left() && + pRefFrm->Frm().Top() < pFldFrm->Frm().Top() ); + pRefFrm = 0; + } + else if( ( FRM_COLUMN | FRM_CELL ) & pFldFrm->GetType() ) + pFldFrm = (const SwFrm*)aArr[ nCnt - 1 ]; + else + pRefFrm = (const SwFrm*)aRefArr[ nRefCnt - 1 ]; + } + + if( pRefFrm ) // als Flag missbrauchen + { + if( bVert ) + { + if( bR2L ) + bRefIsLower = pRefFrm->Frm().Left() < pFldFrm->Frm().Left() || + ( pRefFrm->Frm().Left() == pFldFrm->Frm().Left() && + pRefFrm->Frm().Top() < pFldFrm->Frm().Top() ); + else + bRefIsLower = pRefFrm->Frm().Left() > pFldFrm->Frm().Left() || + ( pRefFrm->Frm().Left() == pFldFrm->Frm().Left() && + pRefFrm->Frm().Top() < pFldFrm->Frm().Top() ); + } + else if( bR2L ) + bRefIsLower = pRefFrm->Frm().Top() < pFldFrm->Frm().Top() || + ( pRefFrm->Frm().Top() == pFldFrm->Frm().Top() && + pRefFrm->Frm().Left() > pFldFrm->Frm().Left() ); + else + bRefIsLower = pRefFrm->Frm().Top() < pFldFrm->Frm().Top() || + ( pRefFrm->Frm().Top() == pFldFrm->Frm().Top() && + pRefFrm->Frm().Left() < pFldFrm->Frm().Left() ); + } + return bRefIsLower; +} + +/*-------------------------------------------------------------------- + Beschreibung: Referenzen holen + --------------------------------------------------------------------*/ + + +SwGetRefField::SwGetRefField( SwGetRefFieldType* pFldType, + const String& rSetRef, USHORT nSubTyp, + USHORT nSeqenceNo, ULONG nFmt ) + : SwField( pFldType, nFmt ), + sSetRefName( rSetRef ), + nSubType( nSubTyp ), + nSeqNo( nSeqenceNo ) +{ +} + +SwGetRefField::~SwGetRefField() +{ +} + +String SwGetRefField::GetDescription() const +{ + return SW_RES(STR_REFERENCE); +} + +USHORT SwGetRefField::GetSubType() const +{ + return nSubType; +} + +void SwGetRefField::SetSubType( USHORT n ) +{ + nSubType = n; +} + +// --> OD 2007-11-09 #i81002# +bool SwGetRefField::IsRefToHeadingCrossRefBookmark() const +{ + return GetSubType() == REF_BOOKMARK && + ::sw::mark::CrossRefHeadingBookmark::IsLegalName(sSetRefName); +} + +bool SwGetRefField::IsRefToNumItemCrossRefBookmark() const +{ + return GetSubType() == REF_BOOKMARK && + ::sw::mark::CrossRefNumItemBookmark::IsLegalName(sSetRefName); +} + +const SwTxtNode* SwGetRefField::GetReferencedTxtNode() const +{ + SwDoc* pDoc = dynamic_cast<SwGetRefFieldType*>(GetTyp())->GetDoc(); + USHORT nDummy = USHRT_MAX; + return SwGetRefFieldType::FindAnchor( pDoc, sSetRefName, nSubType, nSeqNo, &nDummy ); +} +// <-- +// --> OD 2008-01-09 #i85090# +String SwGetRefField::GetExpandedTxtOfReferencedTxtNode() const +{ + const SwTxtNode* pReferencedTxtNode( GetReferencedTxtNode() ); + return pReferencedTxtNode + ? pReferencedTxtNode->GetExpandTxt( 0, STRING_LEN, true, true ) + : aEmptyStr; +} + +String SwGetRefField::Expand() const +{ + return sTxt; +} + + +String SwGetRefField::GetCntnt(BOOL bName) const +{ + if( !bName ) + return Expand(); + + String aStr(GetTyp()->GetName()); + aStr += ' '; + aStr += sSetRefName; + return aStr; +} + +// --> OD 2007-09-07 #i81002# - parameter <pFldTxtAttr> added +void SwGetRefField::UpdateField( const SwTxtFld* pFldTxtAttr ) +{ + sTxt.Erase(); + + SwDoc* pDoc = ((SwGetRefFieldType*)GetTyp())->GetDoc(); + USHORT nStt = USHRT_MAX; + USHORT nEnd = USHRT_MAX; + SwTxtNode* pTxtNd = SwGetRefFieldType::FindAnchor( pDoc, sSetRefName, + nSubType, nSeqNo, &nStt, &nEnd ); + if ( !pTxtNd ) + { + sTxt = ViewShell::GetShellRes()->aGetRefFld_RefItemNotFound; + return ; + } + + switch( GetFormat() ) + { + case REF_CONTENT: + case REF_ONLYNUMBER: + case REF_ONLYCAPTION: + case REF_ONLYSEQNO: + { + switch( nSubType ) + { + case REF_SEQUENCEFLD: + nEnd = pTxtNd->GetTxt().Len(); + switch( GetFormat() ) + { + case REF_ONLYNUMBER: + if( nStt + 1 < nEnd ) + nEnd = nStt + 1; + nStt = 0; + break; + + case REF_ONLYCAPTION: + { + const SwTxtAttr* const pTxtAttr = + pTxtNd->GetTxtAttrForCharAt(nStt, RES_TXTATR_FIELD); + if( pTxtAttr ) + nStt = SwGetExpField::GetReferenceTextPos( + pTxtAttr->GetFld(), *pDoc ); + else if( nStt + 1 < nEnd ) + ++nStt; + } + break; + + case REF_ONLYSEQNO: + if( nStt + 1 < nEnd ) + nEnd = nStt + 1; + break; + + default: + nStt = 0; + break; + } + break; + + case REF_BOOKMARK: + if( USHRT_MAX == nEnd ) + { + // Text steht ueber verschiedene Nodes verteilt. + // Gesamten Text oder nur bis zum Ende vom Node? + nEnd = pTxtNd->GetTxt().Len(); + } + break; + + case REF_OUTLINE: + break; + + case REF_FOOTNOTE: + case REF_ENDNOTE: + { + // die Nummer oder den NumString besorgen + USHORT n, nFtnCnt = pDoc->GetFtnIdxs().Count(); + SwTxtFtn* pFtnIdx; + for( n = 0; n < nFtnCnt; ++n ) + if( nSeqNo == (pFtnIdx = pDoc->GetFtnIdxs()[ n ])->GetSeqRefNo() ) + { + sTxt = pFtnIdx->GetFtn().GetViewNumStr( *pDoc ); + break; + } + nStt = nEnd; // kein Bereich, der String ist fertig + } + break; + } + + if( nStt != nEnd ) // ein Bereich? + { + sTxt = pTxtNd->GetExpandTxt( nStt, nEnd - nStt ); + + // alle Sonderzeichen entfernen (durch Blanks ersetzen): + if( sTxt.Len() ) + { + sTxt.EraseAllChars( 0xad ); + for( sal_Unicode* p = sTxt.GetBufferAccess(); *p; ++p ) + { + if( *p < 0x20 ) + *p = 0x20; + else if(*p == 0x2011) + *p = '-'; + } + } + } + } + break; + + case REF_PAGE: + case REF_PAGE_PGDESC: + { + const SwTxtFrm* pFrm = (SwTxtFrm*)pTxtNd->GetFrm(0,0,FALSE), + *pSave = pFrm; + while( pFrm && !pFrm->IsInside( nStt ) ) + pFrm = (SwTxtFrm*)pFrm->GetFollow(); + + if( pFrm || 0 != ( pFrm = pSave )) + { + USHORT nPageNo = pFrm->GetVirtPageNum(); + const SwPageFrm *pPage; + if( REF_PAGE_PGDESC == GetFormat() && + 0 != ( pPage = pFrm->FindPageFrm() ) && + pPage->GetPageDesc() ) + sTxt = pPage->GetPageDesc()->GetNumType().GetNumStr( nPageNo ); + else + sTxt = String::CreateFromInt32(nPageNo); + } + } + break; + + case REF_CHAPTER: + { + // ein bischen trickreich: suche irgend einen Frame + const SwFrm* pFrm = pTxtNd->GetFrm(); + if( pFrm ) + { + SwChapterFieldType aFldTyp; + SwChapterField aFld( &aFldTyp, 0 ); + aFld.SetLevel( MAXLEVEL - 1 ); + aFld.ChangeExpansion( pFrm, pTxtNd, TRUE ); + sTxt = aFld.GetNumber(); + } + } + break; + + case REF_UPDOWN: + { + // --> OD 2007-09-07 #i81002# + // simplified: use parameter <pFldTxtAttr> + if( !pFldTxtAttr || !pFldTxtAttr->GetpTxtNode() ) + break; + + LocaleDataWrapper aLocaleData( + ::comphelper::getProcessServiceFactory(), + SvxCreateLocale( GetLanguage() ) ); + + // erstmal ein "Kurz" - Test - falls beide im selben + // Node stehen! + if( pFldTxtAttr->GetpTxtNode() == pTxtNd ) + { + sTxt = nStt < *pFldTxtAttr->GetStart() + ? aLocaleData.getAboveWord() + : aLocaleData.getBelowWord(); + break; + } + + sTxt = ::IsFrameBehind( *pFldTxtAttr->GetpTxtNode(), *pFldTxtAttr->GetStart(), + *pTxtNd, nStt ) + ? aLocaleData.getAboveWord() + : aLocaleData.getBelowWord(); + } + break; + // --> OD 2007-08-24 #i81002# + case REF_NUMBER: + case REF_NUMBER_NO_CONTEXT: + case REF_NUMBER_FULL_CONTEXT: + { + if ( pFldTxtAttr && pFldTxtAttr->GetpTxtNode() ) + { + sTxt = MakeRefNumStr( pFldTxtAttr->GetTxtNode(), *pTxtNd, GetFormat() ); + } + } + break; + // <-- + default: + DBG_ERROR("<SwGetRefField::UpdateField(..)> - unknown format type"); + } +} + +// --> OD 2007-09-06 #i81002# +String SwGetRefField::MakeRefNumStr( const SwTxtNode& rTxtNodeOfField, + const SwTxtNode& rTxtNodeOfReferencedItem, + const sal_uInt32 nRefNumFormat ) const +{ + if ( rTxtNodeOfReferencedItem.HasNumber() && + rTxtNodeOfReferencedItem.IsCountedInList() ) + { + ASSERT( rTxtNodeOfReferencedItem.GetNum(), + "<SwGetRefField::MakeRefNumStr(..)> - referenced paragraph has number, but no <SwNodeNum> instance --> please inform OD!" ); + + // Determine, up to which level the superior list labels have to be + // included - default is to include all superior list labels. + sal_uInt8 nRestrictInclToThisLevel( 0 ); + // Determine for format REF_NUMBER the level, up to which the superior + // list labels have to be restricted, if the text node of the reference + // field and the text node of the referenced item are in the same + // document context. + if ( nRefNumFormat == REF_NUMBER && + rTxtNodeOfField.FindFlyStartNode() + == rTxtNodeOfReferencedItem.FindFlyStartNode() && + rTxtNodeOfField.FindFootnoteStartNode() + == rTxtNodeOfReferencedItem.FindFootnoteStartNode() && + rTxtNodeOfField.FindHeaderStartNode() + == rTxtNodeOfReferencedItem.FindHeaderStartNode() && + rTxtNodeOfField.FindFooterStartNode() + == rTxtNodeOfReferencedItem.FindFooterStartNode() ) + { + const SwNodeNum* pNodeNumForTxtNodeOfField( 0 ); + if ( rTxtNodeOfField.HasNumber() && + rTxtNodeOfField.GetNumRule() == rTxtNodeOfReferencedItem.GetNumRule() ) + { + pNodeNumForTxtNodeOfField = rTxtNodeOfField.GetNum(); + } + else + { + pNodeNumForTxtNodeOfField = + rTxtNodeOfReferencedItem.GetNum()->GetPrecedingNodeNumOf( rTxtNodeOfField ); + } + if ( pNodeNumForTxtNodeOfField ) + { + const SwNumberTree::tNumberVector rFieldNumVec = pNodeNumForTxtNodeOfField->GetNumberVector(); + const SwNumberTree::tNumberVector rRefItemNumVec = rTxtNodeOfReferencedItem.GetNum()->GetNumberVector(); + sal_uInt8 nLevel( 0 ); + while ( nLevel < rFieldNumVec.size() && nLevel < rRefItemNumVec.size() ) + { + if ( rRefItemNumVec[nLevel] == rFieldNumVec[nLevel] ) + { + nRestrictInclToThisLevel = nLevel + 1; + } + else + { + break; + } + ++nLevel; + } + } + } + + // Determine, if superior list labels have to be included + const bool bInclSuperiorNumLabels( + ( nRestrictInclToThisLevel < rTxtNodeOfReferencedItem.GetActualListLevel() && + ( nRefNumFormat == REF_NUMBER || nRefNumFormat == REF_NUMBER_FULL_CONTEXT ) ) ); + + ASSERT( rTxtNodeOfReferencedItem.GetNumRule(), + "<SwGetRefField::MakeRefNumStr(..)> - referenced numbered paragraph has no numbering rule set --> please inform OD!" ); + return rTxtNodeOfReferencedItem.GetNumRule()->MakeRefNumString( + *(rTxtNodeOfReferencedItem.GetNum()), + bInclSuperiorNumLabels, + nRestrictInclToThisLevel ); + } + + return String(); +} +// <-- + +SwField* SwGetRefField::Copy() const +{ + SwGetRefField* pFld = new SwGetRefField( (SwGetRefFieldType*)GetTyp(), + sSetRefName, nSubType, + nSeqNo, GetFormat() ); + pFld->sTxt = sTxt; + return pFld; +} + +/*-------------------------------------------------------------------- + Beschreibung: ReferenzName holen + --------------------------------------------------------------------*/ + + +const String& SwGetRefField::GetPar1() const +{ + return sSetRefName; +} + + +void SwGetRefField::SetPar1( const String& rName ) +{ + sSetRefName = rName; +} + + +String SwGetRefField::GetPar2() const +{ + return Expand(); +} + +/*-----------------06.03.98 13:34------------------- + +--------------------------------------------------*/ +BOOL SwGetRefField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_USHORT1: + { + sal_Int16 nPart = 0; + switch(GetFormat()) + { + case REF_PAGE : nPart = ReferenceFieldPart::PAGE ; break; + case REF_CHAPTER : nPart = ReferenceFieldPart::CHAPTER ; break; + case REF_CONTENT : nPart = ReferenceFieldPart::TEXT ; break; + case REF_UPDOWN : nPart = ReferenceFieldPart::UP_DOWN ; break; + case REF_PAGE_PGDESC: nPart = ReferenceFieldPart::PAGE_DESC ; break; + case REF_ONLYNUMBER : nPart = ReferenceFieldPart::CATEGORY_AND_NUMBER ; break; + case REF_ONLYCAPTION: nPart = ReferenceFieldPart::ONLY_CAPTION ; break; + case REF_ONLYSEQNO : nPart = ReferenceFieldPart::ONLY_SEQUENCE_NUMBER; break; + // --> OD 2007-09-06 #i81002# + case REF_NUMBER: nPart = ReferenceFieldPart::NUMBER; break; + case REF_NUMBER_NO_CONTEXT: nPart = ReferenceFieldPart::NUMBER_NO_CONTEXT; break; + case REF_NUMBER_FULL_CONTEXT: nPart = ReferenceFieldPart::NUMBER_FULL_CONTEXT; break; + // <-- + } + rAny <<= nPart; + } + break; + case FIELD_PROP_USHORT2: + { + sal_Int16 nSource = 0; + switch(nSubType) + { + case REF_SETREFATTR : nSource = ReferenceFieldSource::REFERENCE_MARK; break; + case REF_SEQUENCEFLD: nSource = ReferenceFieldSource::SEQUENCE_FIELD; break; + case REF_BOOKMARK : nSource = ReferenceFieldSource::BOOKMARK; break; + case REF_OUTLINE : DBG_ERROR("not implemented"); break; + case REF_FOOTNOTE : nSource = ReferenceFieldSource::FOOTNOTE; break; + case REF_ENDNOTE : nSource = ReferenceFieldSource::ENDNOTE; break; + } + rAny <<= nSource; + } + break; + case FIELD_PROP_PAR1: + { + String sTmp(GetPar1()); + if(REF_SEQUENCEFLD == nSubType) + { + sal_uInt16 nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( sTmp, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL ); + switch( nPoolId ) + { + case RES_POOLCOLL_LABEL_ABB: + case RES_POOLCOLL_LABEL_TABLE: + case RES_POOLCOLL_LABEL_FRAME: + case RES_POOLCOLL_LABEL_DRAWING: + SwStyleNameMapper::FillProgName(nPoolId, sTmp) ; + break; + } + } + rAny <<= rtl::OUString(sTmp); + } + break; + case FIELD_PROP_PAR3: + rAny <<= rtl::OUString(Expand()); + break; + case FIELD_PROP_SHORT1: + rAny <<= (sal_Int16)nSeqNo; + break; + default: + DBG_ERROR("illegal property"); + } + return TRUE; +} +/*-----------------06.03.98 13:34------------------- + +--------------------------------------------------*/ +BOOL SwGetRefField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + String sTmp; + switch( nWhichId ) + { + case FIELD_PROP_USHORT1: + { + sal_Int16 nPart = 0; + rAny >>= nPart; + switch(nPart) + { + case ReferenceFieldPart::PAGE: nPart = REF_PAGE; break; + case ReferenceFieldPart::CHAPTER: nPart = REF_CHAPTER; break; + case ReferenceFieldPart::TEXT: nPart = REF_CONTENT; break; + case ReferenceFieldPart::UP_DOWN: nPart = REF_UPDOWN; break; + case ReferenceFieldPart::PAGE_DESC: nPart = REF_PAGE_PGDESC; break; + case ReferenceFieldPart::CATEGORY_AND_NUMBER: nPart = REF_ONLYNUMBER; break; + case ReferenceFieldPart::ONLY_CAPTION: nPart = REF_ONLYCAPTION; break; + case ReferenceFieldPart::ONLY_SEQUENCE_NUMBER : nPart = REF_ONLYSEQNO; break; + // --> OD 2007-09-06 #i81002# + case ReferenceFieldPart::NUMBER: nPart = REF_NUMBER; break; + case ReferenceFieldPart::NUMBER_NO_CONTEXT: nPart = REF_NUMBER_NO_CONTEXT; break; + case ReferenceFieldPart::NUMBER_FULL_CONTEXT: nPart = REF_NUMBER_FULL_CONTEXT; break; + // <-- + default: return FALSE; + } + SetFormat(nPart); + } + break; + case FIELD_PROP_USHORT2: + { + sal_Int16 nSource = 0; + rAny >>= nSource; + switch(nSource) + { + case ReferenceFieldSource::REFERENCE_MARK : nSubType = REF_SETREFATTR ; break; + case ReferenceFieldSource::SEQUENCE_FIELD : + { + if(REF_SEQUENCEFLD == nSubType) + break; + nSubType = REF_SEQUENCEFLD; + ConvertProgrammaticToUIName(); + } + break; + case ReferenceFieldSource::BOOKMARK : nSubType = REF_BOOKMARK ; break; + case ReferenceFieldSource::FOOTNOTE : nSubType = REF_FOOTNOTE ; break; + case ReferenceFieldSource::ENDNOTE : nSubType = REF_ENDNOTE ; break; + } + } + break; + case FIELD_PROP_PAR1: + { + OUString sTmpStr; + rAny >>= sTmpStr; + SetPar1(sTmpStr); + ConvertProgrammaticToUIName(); + } + break; + case FIELD_PROP_PAR3: + SetExpand( ::GetString( rAny, sTmp )); + break; + case FIELD_PROP_SHORT1: + { + sal_Int16 nSetSeq = 0; + rAny >>= nSetSeq; + if(nSetSeq >= 0) + nSeqNo = nSetSeq; + } + break; + default: + DBG_ERROR("illegal property"); + } + return TRUE; +} +/* -----------------------------11.01.2002 12:50------------------------------ + + ---------------------------------------------------------------------------*/ +void SwGetRefField::ConvertProgrammaticToUIName() +{ + if(GetTyp() && REF_SEQUENCEFLD == nSubType) + { + SwDoc* pDoc = ((SwGetRefFieldType*)GetTyp())->GetDoc(); + const String& rPar1 = GetPar1(); + //don't convert when the name points to an existing field type + if(!pDoc->GetFldType(RES_SETEXPFLD, rPar1, false)) + { + sal_uInt16 nPoolId = SwStyleNameMapper::GetPoolIdFromProgName( rPar1, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL ); + USHORT nResId = USHRT_MAX; + switch( nPoolId ) + { + case RES_POOLCOLL_LABEL_ABB: + nResId = STR_POOLCOLL_LABEL_ABB; + break; + case RES_POOLCOLL_LABEL_TABLE: + nResId = STR_POOLCOLL_LABEL_TABLE; + break; + case RES_POOLCOLL_LABEL_FRAME: + nResId = STR_POOLCOLL_LABEL_FRAME; + break; + case RES_POOLCOLL_LABEL_DRAWING: + nResId = STR_POOLCOLL_LABEL_DRAWING; + break; + } + if( nResId != USHRT_MAX ) + SetPar1(SW_RESSTR( nResId )); + } + } +} +/*-----------------JP: 18.06.93 ------------------- + Get-Referenz-Type + --------------------------------------------------*/ + + +SwGetRefFieldType::SwGetRefFieldType( SwDoc* pDc ) + : SwFieldType( RES_GETREFFLD ), pDoc( pDc ) +{} + + +SwFieldType* SwGetRefFieldType::Copy() const +{ + return new SwGetRefFieldType( pDoc ); +} + + +void SwGetRefFieldType::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew ) +{ + // Update auf alle GetReferenz-Felder + if( !pNew && !pOld ) + { + SwClientIter aIter( *this ); + for( SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE(SwFmtFld) ); + pFld; pFld = (SwFmtFld*)aIter.Next() ) + { + // nur die GetRef-Felder Updaten + //JP 3.4.2001: Task 71231 - we need the correct language + SwGetRefField* pGRef = (SwGetRefField*)pFld->GetFld(); + const SwTxtFld* pTFld; + if( !pGRef->GetLanguage() && + 0 != ( pTFld = pFld->GetTxtFld()) && + pTFld->GetpTxtNode() ) + { + pGRef->SetLanguage( pTFld->GetpTxtNode()->GetLang( + *pTFld->GetStart() ) ); + } + + // --> OD 2007-09-06 #i81002# + pGRef->UpdateField( pFld->GetTxtFld() ); + // <-- + } + } + // weiter an die Text-Felder, diese "Expandieren" den Text + SwModify::Modify( pOld, pNew ); +} + +SwTxtNode* SwGetRefFieldType::FindAnchor( SwDoc* pDoc, const String& rRefMark, + USHORT nSubType, USHORT nSeqNo, + USHORT* pStt, USHORT* pEnd ) +{ + ASSERT( pStt, "warum wird keine StartPos abgefragt?" ); + + SwTxtNode* pTxtNd = 0; + switch( nSubType ) + { + case REF_SETREFATTR: + { + const SwFmtRefMark *pRef = pDoc->GetRefMark( rRefMark ); + if( pRef && pRef->GetTxtRefMark() ) + { + pTxtNd = (SwTxtNode*)&pRef->GetTxtRefMark()->GetTxtNode(); + *pStt = *pRef->GetTxtRefMark()->GetStart(); + if( pEnd ) + *pEnd = *pRef->GetTxtRefMark()->GetAnyEnd(); + } + } + break; + + case REF_SEQUENCEFLD: + { + SwFieldType* pFldType = pDoc->GetFldType( RES_SETEXPFLD, rRefMark, false ); + if( pFldType && pFldType->GetDepends() && + nsSwGetSetExpType::GSE_SEQ & ((SwSetExpFieldType*)pFldType)->GetType() ) + { + SwClientIter aIter( *pFldType ); + for( SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE(SwFmtFld) ); + pFld; pFld = (SwFmtFld*)aIter.Next() ) + { + if( pFld->GetTxtFld() && nSeqNo == + ((SwSetExpField*)pFld->GetFld())->GetSeqNumber() ) + { + SwTxtFld* pTxtFld = pFld->GetTxtFld(); + pTxtNd = (SwTxtNode*)pTxtFld->GetpTxtNode(); + *pStt = *pTxtFld->GetStart(); + if( pEnd ) + *pEnd = (*pStt) + 1; + break; + } + } + } + } + break; + + case REF_BOOKMARK: + { + IDocumentMarkAccess::const_iterator_t ppMark = pDoc->getIDocumentMarkAccess()->findMark(rRefMark); + if(ppMark != pDoc->getIDocumentMarkAccess()->getMarksEnd()) + { + const ::sw::mark::IMark* pBkmk = ppMark->get(); + const SwPosition* pPos = &pBkmk->GetMarkStart(); + + pTxtNd = pDoc->GetNodes()[ pPos->nNode ]->GetTxtNode(); + *pStt = pPos->nContent.GetIndex(); + if(pEnd) + { + if(!pBkmk->IsExpanded()) + { + *pEnd = *pStt; + // --> OD 2007-10-18 #i81002# + if(dynamic_cast< ::sw::mark::CrossRefBookmark const *>(pBkmk)) + { + ASSERT( pTxtNd, + "<SwGetRefFieldType::FindAnchor(..)> - node marked by cross-reference bookmark isn't a text node --> crash" ); + *pEnd = pTxtNd->Len(); + } + // <-- + } + else if(pBkmk->GetOtherMarkPos().nNode == pBkmk->GetMarkPos().nNode) + *pEnd = pBkmk->GetMarkEnd().nContent.GetIndex(); + else + *pEnd = USHRT_MAX; + } + } + } + break; + + case REF_OUTLINE: + break; + + case REF_FOOTNOTE: + case REF_ENDNOTE: + { + USHORT n, nFtnCnt = pDoc->GetFtnIdxs().Count(); + SwTxtFtn* pFtnIdx; + for( n = 0; n < nFtnCnt; ++n ) + if( nSeqNo == (pFtnIdx = pDoc->GetFtnIdxs()[ n ])->GetSeqRefNo() ) + { + SwNodeIndex* pIdx = pFtnIdx->GetStartNode(); + if( pIdx ) + { + SwNodeIndex aIdx( *pIdx, 1 ); + if( 0 == ( pTxtNd = aIdx.GetNode().GetTxtNode())) + pTxtNd = (SwTxtNode*)pDoc->GetNodes().GoNext( &aIdx ); + } + *pStt = 0; + if( pEnd ) + *pEnd = 0; + break; + } + } + break; + } + + return pTxtNd; +} + + +struct _RefIdsMap +{ + String aName; + SvUShortsSort aIds, aDstIds, aIdsMap; + SvUShorts aMap; + BOOL bInit; + + _RefIdsMap( const String& rName ) + : aName( rName ), aIds( 16, 16 ), aIdsMap( 16, 16 ), aMap( 16, 16 ), + bInit( FALSE ) + {} + + void Check( SwDoc& rDoc, SwDoc& rDestDoc, SwGetRefField& rFld, + BOOL bField = TRUE ); + + BOOL IsInit() const { return bInit; } +}; + +SV_DECL_PTRARR_DEL( _RefIdsMaps, _RefIdsMap*, 5, 5 ) +SV_IMPL_PTRARR( _RefIdsMaps, _RefIdsMap* ) + +void _RefIdsMap::Check( SwDoc& rDoc, SwDoc& rDestDoc, SwGetRefField& rFld, + BOOL bField ) +{ + + if( !bInit ) + { + if( bField ) + { + const SwTxtNode* pNd; + SwModify* pMod; + if( 0 != ( pMod = rDestDoc.GetFldType( RES_SETEXPFLD, aName, false ) )) + { + SwClientIter aIter( *pMod ); + for( SwFmtFld* pF = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); pF; + pF = (SwFmtFld*)aIter.Next() ) + if( pF->GetTxtFld() && + 0 != ( pNd = pF->GetTxtFld()->GetpTxtNode() ) && + pNd->GetNodes().IsDocNodes() ) + aIds.Insert( ((SwSetExpField*)pF->GetFld())->GetSeqNumber() ); + } + if( 0 != ( pMod = rDoc.GetFldType( RES_SETEXPFLD, aName, false ) )) + { + SwClientIter aIter( *pMod ); + for( SwFmtFld* pF = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); pF; + pF = (SwFmtFld*)aIter.Next() ) + if( pF->GetTxtFld() && + 0 != ( pNd = pF->GetTxtFld()->GetpTxtNode() ) && + pNd->GetNodes().IsDocNodes() ) + aDstIds.Insert( ((SwSetExpField*)pF->GetFld())->GetSeqNumber() ); + } + } + else + { + USHORT n; + + for( n = rDestDoc.GetFtnIdxs().Count(); n; ) + aIds.Insert( rDestDoc.GetFtnIdxs()[ --n ]->GetSeqRefNo() ); + for( n = rDoc.GetFtnIdxs().Count(); n; ) + aDstIds.Insert( rDoc.GetFtnIdxs()[ --n ]->GetSeqRefNo() ); + } + bInit = TRUE; + } + + // dann teste mal, ob die Nummer schon vergeben ist + // oder ob eine neue bestimmt werden muss. + USHORT nPos, nSeqNo = rFld.GetSeqNo(); + if( aIds.Seek_Entry( nSeqNo ) && aDstIds.Seek_Entry( nSeqNo )) + { + // ist schon vergeben, also muss eine neue + // erzeugt werden. + if( aIdsMap.Seek_Entry( nSeqNo, &nPos )) + rFld.SetSeqNo( aMap[ nPos ] ); + else + { + USHORT n; + + for( n = 0; n < aIds.Count(); ++n ) + if( n != aIds[ n ] ) + break; + + // die neue SeqNo eintragen, damit die "belegt" ist + aIds.Insert( n ); + aIdsMap.Insert( nSeqNo, nPos ); + aMap.Insert( n, nPos ); + rFld.SetSeqNo( n ); + + // und noch die Felder oder Fuss-/EndNote auf die neue + // Id umsetzen + if( bField ) + { + SwModify* pMod = rDoc.GetFldType( RES_SETEXPFLD, aName, false ); + if( pMod ) + { + SwClientIter aIter( *pMod ); + for( SwFmtFld* pF = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); pF; + pF = (SwFmtFld*)aIter.Next() ) + if( pF->GetTxtFld() && nSeqNo == + ((SwSetExpField*)pF->GetFld())->GetSeqNumber() ) + ((SwSetExpField*)pF->GetFld())->SetSeqNumber( n ); + } + } + else + { + SwTxtFtn* pFtnIdx; + for( USHORT i = 0, nCnt = rDoc.GetFtnIdxs().Count(); i < nCnt; ++i ) + if( nSeqNo == (pFtnIdx = rDoc.GetFtnIdxs()[ i ])->GetSeqRefNo() ) + { + pFtnIdx->SetSeqNo( n ); + break; + } + } + } + } + else + { + aIds.Insert( nSeqNo ); + aIdsMap.Insert( nSeqNo, nPos ); + aMap.Insert( nSeqNo, nPos ); + } +} + + +void SwGetRefFieldType::MergeWithOtherDoc( SwDoc& rDestDoc ) +{ + if( &rDestDoc != pDoc && + rDestDoc.GetSysFldType( RES_GETREFFLD )->GetDepends() ) + { + // dann gibt es im DestDoc RefFelder, also muessen im SourceDoc + // alle RefFelder auf einduetige Ids in beiden Docs umgestellt + // werden. + _RefIdsMap aFntMap( aEmptyStr ); + _RefIdsMaps aFldMap; + + SwClientIter aIter( *this ); + for( SwClient* pFld = aIter.First( TYPE( SwFmtFld )); + pFld; pFld = aIter.Next() ) + { + SwGetRefField& rRefFld = *(SwGetRefField*)((SwFmtFld*)pFld)->GetFld(); + switch( rRefFld.GetSubType() ) + { + case REF_SEQUENCEFLD: + { + _RefIdsMap* pMap = 0; + for( USHORT n = aFldMap.Count(); n; ) + if( aFldMap[ --n ]->aName == rRefFld.GetSetRefName() ) + { + pMap = aFldMap[ n ]; + break; + } + if( !pMap ) + { + pMap = new _RefIdsMap( rRefFld.GetSetRefName() ); + aFldMap.C40_INSERT( _RefIdsMap, pMap, aFldMap.Count() ); + } + + pMap->Check( *pDoc, rDestDoc, rRefFld, TRUE ); + } + break; + + case REF_FOOTNOTE: + case REF_ENDNOTE: + aFntMap.Check( *pDoc, rDestDoc, rRefFld, FALSE ); + break; + } + } + } +} + diff --git a/sw/source/core/fields/scrptfld.cxx b/sw/source/core/fields/scrptfld.cxx new file mode 100644 index 000000000000..f9d8258edcec --- /dev/null +++ b/sw/source/core/fields/scrptfld.cxx @@ -0,0 +1,153 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + + +#include <docufld.hxx> +#ifndef _UNOFLDMID_H +#include <unofldmid.h> +#endif +#ifndef _COMCORE_HRC +#include <comcore.hrc> +#endif +#include <tools/resid.hxx> + +using namespace ::com::sun::star; +using ::rtl::OUString; +/*-------------------------------------------------------------------- + Beschreibung: ScriptField + --------------------------------------------------------------------*/ + +SwScriptFieldType::SwScriptFieldType( SwDoc* pD ) + : SwFieldType( RES_SCRIPTFLD ), pDoc( pD ) +{} + +SwFieldType* SwScriptFieldType::Copy() const +{ + return new SwScriptFieldType( pDoc ); +} + + +/*-------------------------------------------------------------------- + Beschreibung: SwScriptField + --------------------------------------------------------------------*/ + +SwScriptField::SwScriptField( SwScriptFieldType* pInitType, + const String& rType, const String& rCode, + BOOL bURL ) + : SwField( pInitType ), sType( rType ), sCode( rCode ), bCodeURL( bURL ) +{ +} + +String SwScriptField::GetDescription() const +{ + return SW_RES(STR_SCRIPT); +} + +String SwScriptField::Expand() const +{ + return aEmptyStr; +} + +SwField* SwScriptField::Copy() const +{ + return new SwScriptField( (SwScriptFieldType*)GetTyp(), sType, sCode, bCodeURL ); +} + +/*-------------------------------------------------------------------- + Beschreibung: Type setzen + --------------------------------------------------------------------*/ + +void SwScriptField::SetPar1( const String& rStr ) +{ + sType = rStr; +} + +const String& SwScriptField::GetPar1() const +{ + return sType; +} + +/*-------------------------------------------------------------------- + Beschreibung: Code setzen + --------------------------------------------------------------------*/ + +void SwScriptField::SetPar2( const String& rStr ) +{ + sCode = rStr; +} + + +String SwScriptField::GetPar2() const +{ + return sCode; +} +/*-----------------05.03.98 15:00------------------- + +--------------------------------------------------*/ +BOOL SwScriptField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + rAny <<= OUString( sType ); + break; + case FIELD_PROP_PAR2: + rAny <<= OUString( sCode ); + break; + case FIELD_PROP_BOOL1: + rAny.setValue(&bCodeURL, ::getBooleanCppuType()); + break; + default: + DBG_ERROR("illegal property"); + } + return TRUE; +} +/*-----------------05.03.98 15:00------------------- + +--------------------------------------------------*/ +BOOL SwScriptField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + switch( nWhichId ) + { + case FIELD_PROP_PAR1: + ::GetString( rAny, sType ); + break; + case FIELD_PROP_PAR2: + ::GetString( rAny, sCode ); + break; + case FIELD_PROP_BOOL1: + bCodeURL = *(sal_Bool*)rAny.getValue(); + break; + default: + DBG_ERROR("illegal property"); + } + return TRUE; +} + diff --git a/sw/source/core/fields/tblcalc.cxx b/sw/source/core/fields/tblcalc.cxx new file mode 100644 index 000000000000..ae340b9a7ba5 --- /dev/null +++ b/sw/source/core/fields/tblcalc.cxx @@ -0,0 +1,264 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + + +#include <cntfrm.hxx> +#include <doc.hxx> +#include <pam.hxx> // fuer GetBodyTxtNode +#include <ndtxt.hxx> +#include <fmtfld.hxx> +#include <txtfld.hxx> +#include <expfld.hxx> +#include <docfld.hxx> // fuer _SetGetExpFld +#ifndef _UNOFLDMID_H +#include <unofldmid.h> +#endif + +using namespace ::com::sun::star; +using ::rtl::OUString; + + +SwTblFieldType::SwTblFieldType(SwDoc* pDocPtr) + : SwValueFieldType( pDocPtr, RES_TABLEFLD ) +{} + + +SwFieldType* SwTblFieldType::Copy() const +{ + return new SwTblFieldType(GetDoc()); +} + + + +void SwTblField::CalcField( SwTblCalcPara& rCalcPara ) +{ + if( rCalcPara.rCalc.IsCalcError() ) // ist schon Fehler gesetzt ? + return; + + // erzeuge aus den BoxNamen die Pointer + BoxNmToPtr( rCalcPara.pTbl ); + String sFml( MakeFormel( rCalcPara )); + SetValue( rCalcPara.rCalc.Calculate( sFml ).GetDouble() ); + ChgValid( !rCalcPara.IsStackOverFlow() ); // ist der Wert wieder gueltig? +} + + + +SwTblField::SwTblField( SwTblFieldType* pInitType, const String& rFormel, + USHORT nType, ULONG nFmt ) + : SwValueField( pInitType, nFmt ), SwTableFormula( rFormel ), + sExpand( '0' ), nSubType(nType) +{ +} + + +SwField* SwTblField::Copy() const +{ + SwTblField* pTmp = new SwTblField( (SwTblFieldType*)GetTyp(), + SwTableFormula::GetFormula(), nSubType, GetFormat() ); + pTmp->sExpand = sExpand; + pTmp->SwValueField::SetValue(GetValue()); + pTmp->SwTableFormula::operator=( *this ); + pTmp->SetAutomaticLanguage(IsAutomaticLanguage()); + return pTmp; +} + + +String SwTblField::GetCntnt(BOOL bName) const +{ + if( bName ) + { + String aStr(GetTyp()->GetName()); + aStr += ' '; + + USHORT nOldSubType = nSubType; + SwTblField* pThis = (SwTblField*)this; + pThis->nSubType |= nsSwExtendedSubType::SUB_CMD; + aStr += Expand(); + pThis->nSubType = nOldSubType; + + return aStr; + } + return Expand(); +} + +// suche den TextNode, in dem das Feld steht +const SwNode* SwTblField::GetNodeOfFormula() const +{ + if( !GetTyp()->GetDepends() ) + return 0; + + SwClientIter aIter( *GetTyp() ); + SwClient * pLast = aIter.GoStart(); + if( pLast ) // konnte zum Anfang gesprungen werden ?? + do { + const SwFmtFld* pFmtFld = (SwFmtFld*)pLast; + if( this == pFmtFld->GetFld() ) + return (SwTxtNode*)&pFmtFld->GetTxtFld()->GetTxtNode(); + + } while( 0 != ( pLast = aIter++ )); + return 0; +} + + +String SwTblField::Expand() const +{ + String aStr; + if (nSubType & nsSwExtendedSubType::SUB_CMD) + { + if( EXTRNL_NAME != GetNameType() ) + { + const SwNode* pNd = GetNodeOfFormula(); + const SwTableNode* pTblNd = pNd ? pNd->FindTableNode() : 0; + if( pTblNd ) + ((SwTblField*)this)->PtrToBoxNm( &pTblNd->GetTable() ); + } + if( EXTRNL_NAME == GetNameType() ) + aStr = SwTableFormula::GetFormula(); + } + else + { + aStr = sExpand; + if(nSubType & nsSwGetSetExpType::GSE_STRING) + { + // es ist ein String + aStr = sExpand; + aStr.Erase( 0,1 ); + aStr.Erase( aStr.Len()-1, 1 ); + } + } + return aStr; +} + +USHORT SwTblField::GetSubType() const +{ + return nSubType; +} + +void SwTblField::SetSubType(USHORT nType) +{ + nSubType = nType; +} + + +void SwTblField::SetValue( const double& rVal ) +{ + SwValueField::SetValue(rVal); + sExpand = ((SwValueFieldType*)GetTyp())->ExpandValue(rVal, GetFormat(), GetLanguage()); +} + +/*-------------------------------------------------------------------- + Beschreibung: Parameter setzen + --------------------------------------------------------------------*/ + + +String SwTblField::GetPar2() const +{ + return SwTableFormula::GetFormula(); +} + + +void SwTblField::SetPar2(const String& rStr) +{ + SetFormula( rStr ); +} + + +/*-----------------04.03.98 10:33------------------- + +--------------------------------------------------*/ +BOOL SwTblField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + BOOL bRet = TRUE; + switch ( nWhichId ) + { + case FIELD_PROP_PAR2: + { + USHORT nOldSubType = nSubType; + SwTblField* pThis = (SwTblField*)this; + pThis->nSubType |= nsSwExtendedSubType::SUB_CMD; + rAny <<= rtl::OUString( Expand() ); + pThis->nSubType = nOldSubType; + } + break; + case FIELD_PROP_BOOL1: + { + BOOL bFormula = 0 != (nsSwExtendedSubType::SUB_CMD & nSubType); + rAny.setValue(&bFormula, ::getBooleanCppuType()); + } + break; + case FIELD_PROP_PAR1: + rAny <<= rtl::OUString(GetExpStr()); + break; + case FIELD_PROP_FORMAT: + rAny <<= (sal_Int32)GetFormat(); + break; + default: + bRet = sal_False; + } + return bRet; +} +/*-----------------04.03.98 10:33------------------- + +--------------------------------------------------*/ +BOOL SwTblField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + BOOL bRet = TRUE; + String sTmp; + switch ( nWhichId ) + { + case FIELD_PROP_PAR2: + SetFormula( ::GetString( rAny, sTmp )); + break; + case FIELD_PROP_BOOL1: + if(*(sal_Bool*)rAny.getValue()) + nSubType = nsSwGetSetExpType::GSE_FORMULA|nsSwExtendedSubType::SUB_CMD; + else + nSubType = nsSwGetSetExpType::GSE_FORMULA; + break; + case FIELD_PROP_PAR1: + ChgExpStr( ::GetString( rAny, sTmp )); + break; + case FIELD_PROP_FORMAT: + { + sal_Int32 nTmp = 0; + rAny >>= nTmp; + SetFormat(nTmp); + } + break; + default: + bRet = sal_False; + } + return bRet; +} + + + + diff --git a/sw/source/core/fields/textapi.cxx b/sw/source/core/fields/textapi.cxx new file mode 100755 index 000000000000..1e994f536801 --- /dev/null +++ b/sw/source/core/fields/textapi.cxx @@ -0,0 +1,191 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + +#include <textapi.hxx> +#include <doc.hxx> +#include <docsh.hxx> +#include <editeng/eeitem.hxx> +#include <editeng/editeng.hxx> + +#include <com/sun/star/text/XTextField.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> + +using namespace com::sun::star; + +static const SvxItemPropertySet* ImplGetSvxTextPortionPropertySet() +{ + static const SfxItemPropertyMapEntry aSvxTextPortionPropertyMap[] = + { + SVX_UNOEDIT_CHAR_PROPERTIES, + SVX_UNOEDIT_FONT_PROPERTIES, + SVX_UNOEDIT_OUTLINER_PROPERTIES, + SVX_UNOEDIT_PARA_PROPERTIES, + {MAP_CHAR_LEN("TextField"), EE_FEATURE_FIELD, &::getCppuType((const uno::Reference< text::XTextField >*)0), beans::PropertyAttribute::READONLY, 0 }, + {MAP_CHAR_LEN("TextPortionType"), WID_PORTIONTYPE, &::getCppuType((const ::rtl::OUString*)0), beans::PropertyAttribute::READONLY, 0 }, + {MAP_CHAR_LEN("TextUserDefinedAttributes"), EE_CHAR_XMLATTRIBS, &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >*)0) , 0, 0}, + {MAP_CHAR_LEN("ParaUserDefinedAttributes"), EE_PARA_XMLATTRIBS, &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >*)0) , 0, 0}, + {0,0,0,0,0,0} + }; + static SvxItemPropertySet aSvxTextPortionPropertySet( aSvxTextPortionPropertyMap, EditEngine::GetGlobalItemPool() ); + return &aSvxTextPortionPropertySet; +} + +SwTextAPIObject::SwTextAPIObject( SwTextAPIEditSource* p ) +: SvxUnoText( p, ImplGetSvxTextPortionPropertySet(), uno::Reference < text::XText >() ) +, pSource(p) +{ +} + +SwTextAPIObject::~SwTextAPIObject() throw() +{ + pSource->Dispose(); + delete pSource; +} + +struct SwTextAPIEditSource_Impl +{ + // needed for "internal" refcounting + SfxItemPool* mpPool; + SwDoc* mpDoc; + Outliner* mpOutliner; + SvxOutlinerForwarder* mpTextForwarder; + sal_Int32 mnRef; +}; + +SwTextAPIEditSource::SwTextAPIEditSource( const SwTextAPIEditSource& rSource ) +: SvxEditSource( *this ) +{ + // shallow copy; uses internal refcounting + pImpl = rSource.pImpl; + pImpl->mnRef++; +} + +SvxEditSource* SwTextAPIEditSource::Clone() const +{ + return new SwTextAPIEditSource( *this ); +} + +void SwTextAPIEditSource::UpdateData() +{ + // data is kept in outliner all the time +} + +SwTextAPIEditSource::SwTextAPIEditSource(SwDoc* pDoc) +: pImpl(new SwTextAPIEditSource_Impl) +{ + pImpl->mpPool = &pDoc->GetDocShell()->GetPool(); + pImpl->mpDoc = pDoc; + pImpl->mpOutliner = 0; + pImpl->mpTextForwarder = 0; + pImpl->mnRef = 1; +} + +SwTextAPIEditSource::~SwTextAPIEditSource() +{ + if (!--pImpl->mnRef) + delete pImpl; +} + +void SwTextAPIEditSource::Dispose() +{ + pImpl->mpPool=0; + pImpl->mpDoc=0; + DELETEZ(pImpl->mpTextForwarder); + DELETEZ(pImpl->mpOutliner); +} + +SvxTextForwarder* SwTextAPIEditSource::GetTextForwarder() +{ + if( !pImpl->mpPool ) + return 0; // mpPool == 0 can be used to flag this as disposed + + if( !pImpl->mpOutliner ) + { + //init draw model first + pImpl->mpDoc->GetOrCreateDrawModel(); + pImpl->mpOutliner = new Outliner( pImpl->mpPool, OUTLINERMODE_TEXTOBJECT ); + pImpl->mpDoc->SetCalcFieldValueHdl( pImpl->mpOutliner ); + } + + if( !pImpl->mpTextForwarder ) + pImpl->mpTextForwarder = new SvxOutlinerForwarder( *pImpl->mpOutliner, 0 ); + + return pImpl->mpTextForwarder; +} + +void SwTextAPIEditSource::SetText( OutlinerParaObject& rText ) +{ + if ( pImpl->mpPool ) + { + if( !pImpl->mpOutliner ) + { + //init draw model first + pImpl->mpDoc->GetOrCreateDrawModel(); + pImpl->mpOutliner = new Outliner( pImpl->mpPool, OUTLINERMODE_TEXTOBJECT ); + pImpl->mpDoc->SetCalcFieldValueHdl( pImpl->mpOutliner ); + } + + pImpl->mpOutliner->SetText( rText ); + } +} + +void SwTextAPIEditSource::SetString( const String& rText ) +{ + if ( pImpl->mpPool ) + { + if( !pImpl->mpOutliner ) + { + //init draw model first + pImpl->mpDoc->GetOrCreateDrawModel(); + pImpl->mpOutliner = new Outliner( pImpl->mpPool, OUTLINERMODE_TEXTOBJECT ); + pImpl->mpDoc->SetCalcFieldValueHdl( pImpl->mpOutliner ); + } + else + pImpl->mpOutliner->Clear(); + pImpl->mpOutliner->Insert( rText ); + } +} + +OutlinerParaObject* SwTextAPIEditSource::CreateText() +{ + if ( pImpl->mpPool && pImpl->mpOutliner ) + return pImpl->mpOutliner->CreateParaObject(); + else + return 0; +} + +String SwTextAPIEditSource::GetText() +{ + if ( pImpl->mpPool && pImpl->mpOutliner ) + return pImpl->mpOutliner->GetEditEngine().GetText(); + else + return String(); +} diff --git a/sw/source/core/fields/usrfld.cxx b/sw/source/core/fields/usrfld.cxx new file mode 100644 index 000000000000..f9437cd0fbd5 --- /dev/null +++ b/sw/source/core/fields/usrfld.cxx @@ -0,0 +1,378 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + + +#include <svl/zforlist.hxx> +#include <svl/zformat.hxx> +#include <svx/svdmodel.hxx> + + +#include <calbck.hxx> +#include <calc.hxx> +#include <usrfld.hxx> +#include <doc.hxx> +#include <editsh.hxx> +#include <dpage.hxx> +#ifndef _UNOFLDMID_H +#include <unofldmid.h> +#endif + +using namespace ::com::sun::star; +using ::rtl::OUString; +/*-------------------------------------------------------------------- + Beschreibung: Benutzerfelder + --------------------------------------------------------------------*/ + +SwUserField::SwUserField(SwUserFieldType* pTyp, sal_uInt16 nSub, sal_uInt32 nFmt) + : SwValueField(pTyp, nFmt), + nSubType(nSub) +{ +} + +String SwUserField::Expand() const +{ + String sStr; + if(!(nSubType & nsSwExtendedSubType::SUB_INVISIBLE)) + sStr = ((SwUserFieldType*)GetTyp())->Expand(GetFormat(), nSubType, GetLanguage()); + + return sStr; +} + +SwField* SwUserField::Copy() const +{ + SwField* pTmp = new SwUserField((SwUserFieldType*)GetTyp(), nSubType, GetFormat()); + pTmp->SetAutomaticLanguage(IsAutomaticLanguage()); + return pTmp; +} + +String SwUserField::GetCntnt(sal_Bool bName) const +{ + if ( bName ) + { String aStr(SwFieldType::GetTypeStr(TYP_USERFLD)); + aStr += ' '; + aStr += GetTyp()->GetName(); + aStr.AppendAscii(" = "); + aStr += ((SwUserFieldType*)GetTyp())->GetContent(); + return aStr; + } + return Expand(); +} + +double SwUserField::GetValue() const +{ + return ((SwUserFieldType*)GetTyp())->GetValue(); +} + +void SwUserField::SetValue( const double& rVal ) +{ + ((SwUserFieldType*)GetTyp())->SetValue(rVal); +} + +/*-------------------------------------------------------------------- + Beschreibung: Name + --------------------------------------------------------------------*/ + +const String& SwUserField::GetPar1() const +{ + return ((SwUserFieldType*)GetTyp())->GetName(); +} + +/*-------------------------------------------------------------------- + Beschreibung: Content + --------------------------------------------------------------------*/ + +String SwUserField::GetPar2() const +{ + return ((SwUserFieldType*)GetTyp())->GetContent(GetFormat()); +} + +void SwUserField::SetPar2(const String& rStr) +{ + ((SwUserFieldType*)GetTyp())->SetContent(rStr, GetFormat()); +} + +sal_uInt16 SwUserField::GetSubType() const +{ + return ((SwUserFieldType*)GetTyp())->GetType() | nSubType; +} + +void SwUserField::SetSubType(sal_uInt16 nSub) +{ + ((SwUserFieldType*)GetTyp())->SetType(nSub & 0x00ff); + nSubType = nSub & 0xff00; +} + +/*-----------------09.03.98 08:04------------------- + +--------------------------------------------------*/ +BOOL SwUserField::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_BOOL2: + { + BOOL bTmp = 0 != (nSubType & nsSwExtendedSubType::SUB_CMD); + rAny.setValue(&bTmp, ::getBooleanCppuType()); + } + break; + case FIELD_PROP_BOOL1: + { + BOOL bTmp = 0 == (nSubType & nsSwExtendedSubType::SUB_INVISIBLE); + rAny.setValue(&bTmp, ::getBooleanCppuType()); + } + break; + case FIELD_PROP_FORMAT: + rAny <<= (sal_Int32)GetFormat(); + break; + default: + return SwField::QueryValue(rAny, nWhichId); + } + return sal_True; +} +/*-----------------09.03.98 08:04------------------- + +--------------------------------------------------*/ +sal_Bool SwUserField::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + switch( nWhichId ) + { + case FIELD_PROP_BOOL1: + if(*(sal_Bool*) rAny.getValue()) + nSubType &= (~nsSwExtendedSubType::SUB_INVISIBLE); + else + nSubType |= nsSwExtendedSubType::SUB_INVISIBLE; + break; + case FIELD_PROP_BOOL2: + if(*(sal_Bool*) rAny.getValue()) + nSubType |= nsSwExtendedSubType::SUB_CMD; + else + nSubType &= (~nsSwExtendedSubType::SUB_CMD); + break; + case FIELD_PROP_FORMAT: + { + sal_Int32 nTmp = 0; + rAny >>= nTmp; + SetFormat(nTmp); + } + break; + default: + return SwField::PutValue(rAny, nWhichId); + } + return sal_True; +} + +/*-------------------------------------------------------------------- + Beschreibung: Benutzerfeldtypen + --------------------------------------------------------------------*/ + +SwUserFieldType::SwUserFieldType( SwDoc* pDocPtr, const String& aNam ) + : SwValueFieldType( pDocPtr, RES_USERFLD ), + nValue( 0 ), + nType(nsSwGetSetExpType::GSE_STRING) +{ + bValidValue = bDeleted = sal_False; + aName = aNam; + + if (nType & nsSwGetSetExpType::GSE_STRING) + EnableFormat(sal_False); // Numberformatter nicht einsetzen +} + +String SwUserFieldType::Expand(sal_uInt32 nFmt, sal_uInt16 nSubType, sal_uInt16 nLng) +{ + String aStr(aContent); + if((nType & nsSwGetSetExpType::GSE_EXPR) && !(nSubType & nsSwExtendedSubType::SUB_CMD)) + { + EnableFormat(sal_True); + aStr = ExpandValue(nValue, nFmt, nLng); + } + else + EnableFormat(sal_False); // Numberformatter nicht einsetzen + + return aStr; +} + +SwFieldType* SwUserFieldType::Copy() const +{ + SwUserFieldType *pTmp = new SwUserFieldType( GetDoc(), aName ); + pTmp->aContent = aContent; + pTmp->nType = nType; + pTmp->bValidValue = bValidValue; + pTmp->nValue = nValue; + pTmp->bDeleted = bDeleted; + + return pTmp; +} + +const String& SwUserFieldType::GetName() const +{ + return aName; +} + +void SwUserFieldType::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew ) +{ + if( !pOld && !pNew ) + ChgValid( sal_False ); + + SwModify::Modify( pOld, pNew ); + // und ggfs. am UserFeld haengende InputFelder updaten! + GetDoc()->GetSysFldType( RES_INPUTFLD )->UpdateFlds(); +} + +double SwUserFieldType::GetValue( SwCalc& rCalc ) +{ + if(bValidValue) + return nValue; + + if(!rCalc.Push( this )) + { + rCalc.SetCalcError( CALC_SYNTAX ); + return 0; + } + nValue = rCalc.Calculate( aContent ).GetDouble(); + rCalc.Pop( this ); + + if( !rCalc.IsCalcError() ) + bValidValue = sal_True; + else + nValue = 0; + + return nValue; +} + +String SwUserFieldType::GetContent( sal_uInt32 nFmt ) +{ + if (nFmt && nFmt != SAL_MAX_UINT32) + { + String sFormattedValue; + Color* pCol = 0; + + SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter(); + + pFormatter->GetOutputString(GetValue(), nFmt, sFormattedValue, &pCol); + return sFormattedValue; + } + else + return aContent; +} + +void SwUserFieldType::SetContent( const String& rStr, sal_uInt32 nFmt ) +{ + if( aContent != rStr ) + { + aContent = rStr; + + if (nFmt && nFmt != SAL_MAX_UINT32) + { + double fValue; + + SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter(); + + if (pFormatter->IsNumberFormat(rStr, nFmt, fValue)) + { + SetValue(fValue); + aContent.Erase(); + DoubleToString(aContent, fValue, nFmt); + } + } + + sal_Bool bModified = GetDoc()->IsModified(); + GetDoc()->SetModified(); + if( !bModified ) // Bug 57028 + GetDoc()->SetUndoNoResetModified(); + } +} + +/*-----------------04.03.98 17:05------------------- + +--------------------------------------------------*/ +BOOL SwUserFieldType::QueryValue( uno::Any& rAny, USHORT nWhichId ) const +{ + switch( nWhichId ) + { + case FIELD_PROP_DOUBLE: + rAny <<= (double) nValue; + break; + case FIELD_PROP_PAR2: + rAny <<= rtl::OUString(aContent); + break; + case FIELD_PROP_BOOL1: + { + BOOL bExpression = 0 != (nsSwGetSetExpType::GSE_EXPR&nType); + rAny.setValue(&bExpression, ::getBooleanCppuType()); + } + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} +/*-----------------04.03.98 17:05------------------- + +--------------------------------------------------*/ +BOOL SwUserFieldType::PutValue( const uno::Any& rAny, USHORT nWhichId ) +{ + switch( nWhichId ) + { + case FIELD_PROP_DOUBLE: + { + double fVal = 0; + rAny >>= fVal; + nValue = fVal; + + // Folgende Zeile ist eigentlich falsch, da die Sprache unbekannt ist + // (haengt am Feld) und aContent daher auch eigentlich ans Feld gehoeren + // muesste. Jedes Feld kann eine andere Sprache, aber den gleichen Inhalt + // haben, nur die Formatierung ist unterschiedlich. + DoubleToString(aContent, nValue, (sal_uInt16)LANGUAGE_SYSTEM); + } + break; + case FIELD_PROP_PAR2: + ::GetString( rAny, aContent ); + break; + case FIELD_PROP_BOOL1: + if(*(sal_Bool*)rAny.getValue()) + { + nType |= nsSwGetSetExpType::GSE_EXPR; + nType &= ~nsSwGetSetExpType::GSE_STRING; + } + else + { + nType &= ~nsSwGetSetExpType::GSE_EXPR; + nType |= nsSwGetSetExpType::GSE_STRING; + } + break; + default: + DBG_ERROR("illegal property"); + } + return sal_True; +} + + + |