summaryrefslogtreecommitdiff
path: root/sw/source/core/fields/expfld.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/fields/expfld.cxx')
-rw-r--r--sw/source/core/fields/expfld.cxx1300
1 files changed, 1300 insertions, 0 deletions
diff --git a/sw/source/core/fields/expfld.cxx b/sw/source/core/fields/expfld.cxx
new file mode 100644
index 000000000000..9027ee7bf412
--- /dev/null
+++ b/sw/source/core/fields/expfld.cxx
@@ -0,0 +1,1300 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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>
+#include <switerator.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::text;
+using ::rtl::OUString;
+
+SV_IMPL_PTRARR( _SwSeqFldList, _SeqFldLstElem* )
+
+//-----------------------------------------------------------------------------
+sal_Int16 lcl_SubTypeToAPI(sal_uInt16 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:
+ OSL_FAIL("wrong value");
+ nSet = -1;
+ }
+ return nSet;
+}
+
+//-----------------------------------------------------------------------------
+
+void ReplacePoint( String& rTmpName, sal_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() ) )
+ ;
+ OSL_ENSURE( 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();
+ OSL_ENSURE( 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()))
+ {
+ OSL_ENSURE( 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, sal_False, sal_True, sal_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( const SfxPoolItem*, const SfxPoolItem* pNew )
+{
+ if( pNew && RES_DOCPOS_UPDATE == pNew->Which() )
+ NotifyClients( 0, pNew );
+ // sonst nichts weiter expandieren
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: SwGetExpField by JP
+ --------------------------------------------------------------------*/
+
+SwGetExpField::SwGetExpField(SwGetExpFieldType* pTyp, const String& rFormel,
+ sal_uInt16 nSub, sal_uLong nFmt)
+ : SwFormulaField( pTyp, nFmt, 0.0 ),
+ bIsInBodyTxt( sal_True ),
+ nSubType(nSub),
+ bLateInitialization( false )
+{
+ SetFormula( rFormel );
+}
+
+String SwGetExpField::Expand() const
+{
+ if(nSubType & nsSwExtendedSubType::SUB_CMD)
+ return GetFormula();
+ else
+ return sExpand;
+}
+
+String SwGetExpField::GetFieldName() const
+{
+ String aStr( SwFieldType::GetTypeStr(
+ static_cast<sal_uInt16>(((nsSwGetSetExpType::GSE_FORMULA & nSubType) != 0)
+ ? TYP_FORMELFLD
+ : TYP_GETFLD ) ));
+ aStr += ' ';
+ aStr += GetFormula();
+ return aStr;
+}
+
+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;
+
+ OSL_ENSURE( !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;
+ sal_uInt16 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);
+}
+
+sal_uInt16 SwGetExpField::GetSubType() const
+{
+ return nSubType;
+}
+
+void SwGetExpField::SetSubType(sal_uInt16 nType)
+{
+ nSubType = nType;
+}
+
+void SwGetExpField::SetLanguage(sal_uInt16 nLng)
+{
+ if (nSubType & nsSwExtendedSubType::SUB_CMD)
+ SwField::SetLanguage(nLng);
+ else
+ SwValueField::SetLanguage(nLng);
+}
+
+bool SwGetExpField::QueryValue( uno::Any& rAny, sal_uInt16 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:
+ {
+ sal_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;
+}
+
+bool SwGetExpField::PutValue( const uno::Any& rAny, sal_uInt16 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<sal_uInt16>(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<sal_uInt16>((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;
+}
+
+SwSetExpFieldType::SwSetExpFieldType( SwDoc* pDc, const String& rName, sal_uInt16 nTyp )
+ : SwValueFieldType( pDc, RES_SETEXPFLD ),
+ sName( rName ),
+ pOutlChgNd( 0 ),
+ sDelim( String::CreateFromAscii( "." ) ),
+ nType(nTyp), nLevel( UCHAR_MAX ),
+ bDeleted( sal_False )
+{
+ if( ( nsSwGetSetExpType::GSE_SEQ | nsSwGetSetExpType::GSE_STRING ) & nType )
+ EnableFormat(sal_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( const SfxPoolItem*, const SfxPoolItem* )
+{
+ return; // nicht weiter expandieren
+}
+
+void SwSetExpFieldType::SetSeqFormat(sal_uLong nFmt)
+{
+ SwIterator<SwFmtFld,SwFieldType> aIter(*this);
+ for( SwFmtFld* pFld = aIter.First(); pFld; pFld = aIter.Next() )
+ pFld->GetFld()->ChangeFormat( nFmt );
+}
+
+sal_uLong SwSetExpFieldType::GetSeqFormat()
+{
+ if( !GetDepends() )
+ return SVX_NUM_ARABIC;
+
+ SwField *pFld = ((SwFmtFld*)GetDepends())->GetFld();
+ return pFld->GetFormat();
+}
+
+sal_uInt16 SwSetExpFieldType::SetSeqRefNo( SwSetExpField& rFld )
+{
+ if( !GetDepends() || !(nsSwGetSetExpType::GSE_SEQ & nType) )
+ return USHRT_MAX;
+
+extern void InsertSort( SvUShorts& rArr, sal_uInt16 nIdx, sal_uInt16* pInsPos = 0 );
+ SvUShorts aArr( 64 );
+
+ sal_uInt16 n;
+
+ // dann testmal, ob die Nummer schon vergeben ist oder ob eine neue
+ // bestimmt werden muss.
+ SwIterator<SwFmtFld,SwFieldType> aIter( *this );
+ const SwTxtNode* pNd;
+ for( SwFmtFld* pF = aIter.First(); pF; pF = 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:
+ sal_uInt16 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;
+}
+
+sal_uInt16 SwSetExpFieldType::GetSeqFldList( SwSeqFldList& rList )
+{
+ if( rList.Count() )
+ rList.Remove( 0, rList.Count() );
+
+ SwIterator<SwFmtFld,SwFieldType> aIter( *this );
+ const SwTxtNode* pNd;
+ for( SwFmtFld* pF = aIter.First(); pF; pF = 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, sal_False ));
+
+ if( sNumber.Len() )
+ rFld.ChgExpStr( ( sNumber += sDelim ) += rFld.GetExpStr() );
+ }
+ else
+ {
+ OSL_FAIL( "<SwSetExpFieldType::SetChapter(..)> - text node with numbering rule, but without number. This is a serious defect -> inform OD" );
+ }
+ }
+ }
+}
+
+bool SwSetExpFieldType::QueryValue( uno::Any& rAny, sal_uInt16 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:
+ OSL_FAIL("illegal property");
+ }
+ return true;
+}
+
+bool SwSetExpFieldType::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
+{
+ switch( nWhichId )
+ {
+ case FIELD_PROP_SUBTYPE:
+ {
+ sal_Int32 nSet = lcl_APIToSubType(rAny);
+ if(nSet >=0)
+ SetType(static_cast<sal_uInt16>(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:
+ OSL_FAIL("illegal property");
+ }
+ return true;
+}
+
+sal_Bool SwSeqFldList::InsertSort( _SeqFldLstElem* pNew )
+{
+ sal_Unicode* p = pNew->sDlgEntry.GetBufferAccess();
+ while( *p )
+ {
+ if( *p < 0x20 )
+ *p = 0x20;
+ ++p;
+ }
+
+ sal_uInt16 nPos;
+ sal_Bool bRet = SeekEntry( *pNew, &nPos );
+ if( !bRet )
+ C40_INSERT( _SeqFldLstElem, pNew, nPos );
+ return bRet;
+}
+
+sal_Bool SwSeqFldList::SeekEntry( const _SeqFldLstElem& rNew, sal_uInt16* pP )
+{
+ sal_uInt16 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 ));
+ sal_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 sal_True;
+ }
+ else if( 0 < nCmp )
+ nU = nM + 1;
+ else if( nM == 0 )
+ break;
+ else
+ nO = nM - 1;
+ }
+ }
+ if( pP ) *pP = nU;
+ return sal_False;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: SwSetExpField by JP
+ --------------------------------------------------------------------*/
+
+SwSetExpField::SwSetExpField(SwSetExpFieldType* pTyp, const String& rFormel,
+ sal_uLong nFmt)
+ : SwFormulaField( pTyp, nFmt, 0.0 ), nSeqNo( USHRT_MAX ),
+ nSubType(0)
+{
+ SetFormula(rFormel);
+ // SubType ignorieren !!!
+ bInput = sal_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;
+}
+
+/*--------------------------------------------------------------------
+ @return the field name
+ --------------------------------------------------------------------*/
+
+String SwSetExpField::GetFieldName() const
+{
+ SwFldTypesEnum const nStrType( (IsSequenceFld())
+ ? TYP_SEQFLD
+ : (bInput)
+ ? TYP_SETINPFLD
+ : TYP_SETFLD );
+
+ String aStr( SwFieldType::GetTypeStr( static_cast<sal_uInt16>(nStrType) ) );
+ aStr += ' ';
+ aStr += GetTyp()->GetName();
+
+ // Sequence: without formula
+ if (TYP_SEQFLD != nStrType)
+ {
+ aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " = " ) );
+ aStr += GetFormula();
+ }
+ return aStr;
+}
+
+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(sal_uInt16 nSub)
+{
+ ((SwSetExpFieldType*)GetTyp())->SetType(nSub & 0xff);
+ nSubType = nSub & 0xff00;
+
+ DBG_ASSERT( (nSub & 0xff) != 3, "SubType ist illegal!" );
+}
+
+sal_uInt16 SwSetExpField::GetSubType() const
+{
+ return ((SwSetExpFieldType*)GetTyp())->GetType() | nSubType;
+}
+
+void SwSetExpField::SetValue( const double& rAny )
+{
+ SwValueField::SetValue(rAny);
+
+ if( IsSequenceFld() )
+ sExpand = FormatNumber( (sal_uInt16)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());
+}
+/* --------------------------------------------------
+ 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
+ sal_uInt16 nSrcpt = pBreakIt->GetRealScriptOfText( sNodeText, 0 );
+
+ static sal_uInt16 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);
+ sal_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
+{
+ sal_uInt16 nType = ((SwSetExpFieldType*)GetTyp())->GetType();
+
+ if (nType & nsSwGetSetExpType::GSE_STRING)
+ return GetFormula();
+ return GetExpandedFormula();
+}
+
+void SwSetExpField::SetPar2(const String& rStr)
+{
+ sal_uInt16 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, sal_uInt16 nSub, sal_uLong nFmt) :
+ SwField(pTyp, nFmt), aContent(rContent), aPText(rPrompt), nSubType(nSub)
+{
+}
+
+String SwInputField::GetFieldName() const
+{
+ String aStr(SwField::GetFieldName());
+ if ((nSubType & 0x00ff) == INP_USR)
+ {
+ aStr += GetTyp()->GetName();
+ aStr += ' ';
+ aStr += aContent;
+ }
+ return aStr;
+}
+
+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;
+}
+
+bool SwInputField::QueryValue( uno::Any& rAny, sal_uInt16 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:
+ OSL_FAIL("illegal property");
+ }
+ return true;
+}
+
+bool SwInputField::PutValue( const uno::Any& rAny, sal_uInt16 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:
+ OSL_FAIL("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;
+}
+
+sal_Bool SwInputField::isFormField() const
+{
+ return aHelp.Len() > 0 || aToolTip.Len() > 0;
+}
+
+sal_uInt16 SwInputField::GetSubType() const
+{
+ return nSubType;
+}
+
+void SwInputField::SetSubType(sal_uInt16 nSub)
+{
+ nSubType = nSub;
+}
+
+bool SwSetExpField::QueryValue( uno::Any& rAny, sal_uInt16 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(), sal_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:
+ {
+ sal_Bool bTmp = 0 != (nSubType & nsSwExtendedSubType::SUB_CMD);
+ rAny.setValue(&bTmp, ::getBooleanCppuType());
+ }
+ break;
+ case FIELD_PROP_BOOL1:
+ {
+ sal_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;
+}
+
+bool SwSetExpField::PutValue( const uno::Any& rAny, sal_uInt16 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 {
+ }
+ }
+ 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, sal_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<sal_uInt16>((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;
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */