diff options
Diffstat (limited to 'sw/source/core/txtnode/atrfld.cxx')
-rw-r--r-- | sw/source/core/txtnode/atrfld.cxx | 284 |
1 files changed, 192 insertions, 92 deletions
diff --git a/sw/source/core/txtnode/atrfld.cxx b/sw/source/core/txtnode/atrfld.cxx index aac8a0476baa..4307fc2c95d6 100644 --- a/sw/source/core/txtnode/atrfld.cxx +++ b/sw/source/core/txtnode/atrfld.cxx @@ -46,13 +46,13 @@ TYPEINIT1(SwFmtFldHint, SfxHint); * ****************************************************************************/ - // Konstruktor fuers Default vom Attribut-Pool -SwFmtFld::SwFmtFld() - : SfxPoolItem( RES_TXTATR_FIELD ) - , SwClient( 0 ) +// constructor for default item in attribute-pool +SwFmtFld::SwFmtFld( sal_uInt16 nWhich ) + : SfxPoolItem( nWhich ) + , SwClient() , SfxBroadcaster() - , pField( 0 ) - , pTxtAttr( 0 ) + , mpField( NULL ) + , mpTxtFld( NULL ) { } @@ -60,10 +60,15 @@ SwFmtFld::SwFmtFld( const SwField &rFld ) : SfxPoolItem( RES_TXTATR_FIELD ) , SwClient( rFld.GetTyp() ) , SfxBroadcaster() - , pField( 0 ) - , pTxtAttr( 0 ) + , mpField( rFld.CopyField() ) + , mpTxtFld( NULL ) { - pField = rFld.CopyField(); + // input field in-place editing + if ( GetField()->GetTyp()->Which() == RES_INPUTFLD ) + { + SetWhich( RES_TXTATR_INPUTFIELD ); + dynamic_cast<SwInputField*>(GetField())->SetFmtFld( *this ); + } } // #i24434# @@ -74,25 +79,31 @@ SwFmtFld::SwFmtFld( const SwFmtFld& rAttr ) : SfxPoolItem( RES_TXTATR_FIELD ) , SwClient() , SfxBroadcaster() - , pField( 0 ) - , pTxtAttr( 0 ) + , mpField( NULL ) + , mpTxtFld( NULL ) { - if(rAttr.GetField()) + if ( rAttr.GetField() ) { rAttr.GetField()->GetTyp()->Add(this); - pField = rAttr.GetField()->CopyField(); + mpField = rAttr.GetField()->CopyField(); + // input field in-place editing + if ( GetField()->GetTyp()->Which() == RES_INPUTFLD ) + { + SetWhich( RES_TXTATR_INPUTFIELD ); + dynamic_cast<SwInputField*>(GetField())->SetFmtFld( *this ); + } } } SwFmtFld::~SwFmtFld() { - SwFieldType* pType = pField ? pField->GetTyp() : 0; + SwFieldType* pType = mpField ? mpField->GetTyp() : 0; if (pType && pType->Which() == RES_DBFLD) pType = 0; // DB-Feldtypen zerstoeren sich selbst Broadcast( SwFmtFldHint( this, SWFMTFLD_REMOVED ) ); - delete pField; + delete mpField; // bei einige FeldTypen muessen wir den FeldTypen noch loeschen if( pType && pType->IsLastDepend() ) @@ -129,21 +140,35 @@ void SwFmtFld::RegisterToFieldType( SwFieldType& rType ) // #111840# -void SwFmtFld::SetFld(SwField * _pField) +void SwFmtFld::SetField(SwField * _pField) { - delete pField; + delete mpField; - pField = _pField; + mpField = _pField; + if ( GetField()->GetTyp()->Which() == RES_INPUTFLD ) + { + dynamic_cast<SwInputField* >(GetField())->SetFmtFld( *this ); + } Broadcast( SwFmtFldHint( this, SWFMTFLD_CHANGED ) ); } +void SwFmtFld::SetTxtFld( SwTxtFld& rTxtFld ) +{ + mpTxtFld = &rTxtFld; +} + +void SwFmtFld::ClearTxtFld() +{ + mpTxtFld = NULL; +} + int SwFmtFld::operator==( const SfxPoolItem& rAttr ) const { OSL_ENSURE( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); - return ( ( pField && ((SwFmtFld&)rAttr).GetField() - && pField->GetTyp() == ((SwFmtFld&)rAttr).GetField()->GetTyp() - && pField->GetFormat() == ((SwFmtFld&)rAttr).GetField()->GetFormat() ) ) - || ( !pField && !((SwFmtFld&)rAttr).GetField() ); + return ( ( mpField && ((SwFmtFld&)rAttr).GetField() + && mpField->GetTyp() == ((SwFmtFld&)rAttr).GetField()->GetTyp() + && mpField->GetFormat() == ((SwFmtFld&)rAttr).GetField()->GetFormat() ) ) + || ( !mpField && !((SwFmtFld&)rAttr).GetField() ); } SfxPoolItem* SwFmtFld::Clone( SfxItemPool* ) const @@ -153,7 +178,7 @@ SfxPoolItem* SwFmtFld::Clone( SfxItemPool* ) const void SwFmtFld::SwClientNotify( const SwModify&, const SfxHint& rHint ) { - if( !pTxtAttr ) + if( !mpTxtFld ) return; const SwFieldHint* pHint = dynamic_cast<const SwFieldHint*>( &rHint ); @@ -162,9 +187,9 @@ void SwFmtFld::SwClientNotify( const SwModify&, const SfxHint& rHint ) // replace field content by text SwPaM* pPaM = pHint->GetPaM(); SwDoc* pDoc = pPaM->GetDoc(); - const SwTxtNode& rTxtNode = pTxtAttr->GetTxtNode(); + const SwTxtNode& rTxtNode = mpTxtFld->GetTxtNode(); pPaM->GetPoint()->nNode = rTxtNode; - pPaM->GetPoint()->nContent.Assign( (SwTxtNode*)&rTxtNode, *pTxtAttr->GetStart() ); + pPaM->GetPoint()->nContent.Assign( (SwTxtNode*)&rTxtNode, *mpTxtFld->GetStart() ); OUString const aEntry( GetField()->ExpandField( pDoc->IsClipBoard() ) ); pPaM->SetMark(); @@ -176,14 +201,14 @@ void SwFmtFld::SwClientNotify( const SwModify&, const SfxHint& rHint ) void SwFmtFld::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew ) { - if( !pTxtAttr ) + if( !mpTxtFld ) return; // don't do anything, especially not expand! if( pNew && pNew->Which() == RES_OBJECTDYING ) return; - SwTxtNode* pTxtNd = (SwTxtNode*)&pTxtAttr->GetTxtNode(); + SwTxtNode* pTxtNd = (SwTxtNode*)&mpTxtFld->GetTxtNode(); OSL_ENSURE( pTxtNd, "wo ist denn mein Node?" ); if( pNew ) { @@ -200,7 +225,7 @@ void SwFmtFld::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew ) { // #i81002# // ((SwGetRefField*)GetFld())->UpdateField(); - dynamic_cast<SwGetRefField*>(GetField())->UpdateField( pTxtAttr ); + dynamic_cast<SwGetRefField*>(GetField())->UpdateField( mpTxtFld ); } break; case RES_DOCPOS_UPDATE: @@ -239,14 +264,14 @@ void SwFmtFld::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew ) pType->GetValue( aCalc ); } } - pTxtAttr->Expand(); + mpTxtFld->ExpandTxtFld(); } bool SwFmtFld::GetInfo( SfxPoolItem& rInfo ) const { const SwTxtNode* pTxtNd; if( RES_AUTOFMT_DOCNODE != rInfo.Which() || - !pTxtAttr || 0 == ( pTxtNd = pTxtAttr->GetpTxtNode() ) || + !mpTxtFld || 0 == ( pTxtNd = mpTxtFld->GetpTxtNode() ) || &pTxtNd->GetNodes() != ((SwAutoFmtGetDocNode&)rInfo).pNodes ) return true; @@ -255,81 +280,69 @@ bool SwFmtFld::GetInfo( SfxPoolItem& rInfo ) const } -sal_Bool SwFmtFld::IsFldInDoc() const +bool SwFmtFld::IsFldInDoc() const { - const SwTxtNode* pTxtNd; - return pTxtAttr && 0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) && - pTxtNd->GetNodes().IsDocNodes(); + return mpTxtFld != NULL + && mpTxtFld->IsFldInDoc(); } sal_Bool SwFmtFld::IsProtect() const { - const SwTxtNode* pTxtNd; - return pTxtAttr && 0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) && - pTxtNd->IsProtect(); + return mpTxtFld != NULL + && mpTxtFld->GetpTxtNode() != NULL + && mpTxtFld->GetpTxtNode()->IsProtect(); } -/************************************************************************* -|* -|* SwTxtFld::SwTxtFld() -|* -|* Beschreibung Attribut fuer automatischen Text, Ctor -|* -*************************************************************************/ -SwTxtFld::SwTxtFld(SwFmtFld & rAttr, sal_Int32 const nStartPos, - bool const bInClipboard) +SwTxtFld::SwTxtFld( + SwFmtFld & rAttr, + sal_Int32 const nStartPos, + bool const bInClipboard) : SwTxtAttr( rAttr, nStartPos ) // fdo#39694 the ExpandField here may not give the correct result in all cases, // but is better than nothing , m_aExpand( rAttr.GetField()->ExpandField(bInClipboard) ) - , m_pTxtNode( 0 ) + , m_pTxtNode( NULL ) { - rAttr.pTxtAttr = this; + rAttr.SetTxtFld( *this ); SetHasDummyChar(true); } SwTxtFld::~SwTxtFld( ) { SwFmtFld & rFmtFld( static_cast<SwFmtFld &>(GetAttr()) ); - if (this == rFmtFld.pTxtAttr) + if ( this == rFmtFld.GetTxtFld() ) { - rFmtFld.pTxtAttr = 0; // #i110140# invalidate! + rFmtFld.ClearTxtFld(); } } -/************************************************************************* -|* -|* SwTxtFld::Expand() -|* -|* Beschreibung exandiert das Feld und tauscht den Text im Node -|* -*************************************************************************/ -void SwTxtFld::Expand() const +bool SwTxtFld::IsFldInDoc() const +{ + return GetpTxtNode() != NULL + && GetpTxtNode()->GetNodes().IsDocNodes(); +} + +void SwTxtFld::ExpandTxtFld() const { - // Wenn das expandierte Feld sich nicht veraendert hat, wird returnt OSL_ENSURE( m_pTxtNode, "SwTxtFld: where is my TxtNode?" ); const SwField* pFld = GetFmtFld().GetField(); - OUString aNewExpand( - pFld->ExpandField(m_pTxtNode->GetDoc()->IsClipBoard()) ); + const OUString aNewExpand( pFld->ExpandField(m_pTxtNode->GetDoc()->IsClipBoard()) ); if( aNewExpand == m_aExpand ) { // Bei Seitennummernfeldern const sal_uInt16 nWhich = pFld->GetTyp()->Which(); - if( RES_CHAPTERFLD != nWhich && RES_PAGENUMBERFLD != nWhich && - RES_REFPAGEGETFLD != nWhich && - // #122919# Page count fields to not use aExpand - // during formatting, therefore an invalidation of the text frame - // has to be triggered even if aNewExpand == aExpand: - ( RES_DOCSTATFLD != nWhich || DS_PAGE != static_cast<const SwDocStatField*>(pFld)->GetSubType() ) && - ( RES_GETEXPFLD != nWhich || ((SwGetExpField*)pFld)->IsInBodyTxt() ) ) + if ( RES_CHAPTERFLD != nWhich + && RES_PAGENUMBERFLD != nWhich + && RES_REFPAGEGETFLD != nWhich + // Page count fields to not use aExpand during formatting, + // therefore an invalidation of the text frame has to be triggered even if aNewExpand == aExpand: + && ( RES_DOCSTATFLD != nWhich || DS_PAGE != static_cast<const SwDocStatField*>(pFld)->GetSubType() ) + && ( RES_GETEXPFLD != nWhich || ((SwGetExpField*)pFld)->IsInBodyTxt() ) ) { - // BP: das muesste man noch optimieren! - //JP 12.06.97: stimmt, man sollte auf jedenfall eine Status- - // aenderung an die Frames posten if( m_pTxtNode->CalcHiddenParaField() ) { m_pTxtNode->ModifyNotification( 0, 0 ); @@ -340,15 +353,11 @@ void SwTxtFld::Expand() const m_aExpand = aNewExpand; - // 0, this for formatting - m_pTxtNode->ModifyNotification( 0, const_cast<SwFmtFld*>( &GetFmtFld() ) ); + const_cast<SwTxtFld*>(this)->NotifyContentChange( const_cast<SwFmtFld&>(GetFmtFld()) ); } -/************************************************************************* - * SwTxtFld::CopyFld() - *************************************************************************/ -void SwTxtFld::CopyFld( SwTxtFld *pDest ) const +void SwTxtFld::CopyTxtFld( SwTxtFld *pDest ) const { OSL_ENSURE( m_pTxtNode, "SwTxtFld: where is my TxtNode?" ); OSL_ENSURE( pDest->m_pTxtNode, "SwTxtFld: where is pDest's TxtNode?" ); @@ -356,8 +365,8 @@ void SwTxtFld::CopyFld( SwTxtFld *pDest ) const IDocumentFieldsAccess* pIDFA = m_pTxtNode->getIDocumentFieldsAccess(); IDocumentFieldsAccess* pDestIDFA = pDest->m_pTxtNode->getIDocumentFieldsAccess(); - SwFmtFld& rFmtFld = (SwFmtFld&)pDest->GetFmtFld(); - const sal_uInt16 nFldWhich = rFmtFld.GetField()->GetTyp()->Which(); + SwFmtFld& rDestFmtFld = (SwFmtFld&)pDest->GetFmtFld(); + const sal_uInt16 nFldWhich = rDestFmtFld.GetField()->GetTyp()->Which(); if( pIDFA != pDestIDFA ) { @@ -365,41 +374,50 @@ void SwTxtFld::CopyFld( SwTxtFld *pDest ) const // der Feldtyp muss im neuen Dokument angemeldet werden. // Z.B: Kopieren ins ClipBoard. SwFieldType* pFldType; - if( nFldWhich != RES_DBFLD && nFldWhich != RES_USERFLD && - nFldWhich != RES_SETEXPFLD && nFldWhich != RES_DDEFLD && - RES_AUTHORITY != nFldWhich ) + if( nFldWhich != RES_DBFLD + && nFldWhich != RES_USERFLD + && nFldWhich != RES_SETEXPFLD + && nFldWhich != RES_DDEFLD + && RES_AUTHORITY != nFldWhich ) + { pFldType = pDestIDFA->GetSysFldType( nFldWhich ); + } else - pFldType = pDestIDFA->InsertFldType( *rFmtFld.GetField()->GetTyp() ); + { + pFldType = pDestIDFA->InsertFldType( *rDestFmtFld.GetField()->GetTyp() ); + } // Sonderbehandlung fuer DDE-Felder if( RES_DDEFLD == nFldWhich ) { - if( rFmtFld.GetTxtFld() ) - ((SwDDEFieldType*)rFmtFld.GetField()->GetTyp())->DecRefCnt(); + if( rDestFmtFld.GetTxtFld() ) + { + ((SwDDEFieldType*)rDestFmtFld.GetField()->GetTyp())->DecRefCnt(); + } ((SwDDEFieldType*)pFldType)->IncRefCnt(); } OSL_ENSURE( pFldType, "unbekannter FieldType" ); - pFldType->Add( &rFmtFld ); // ummelden - rFmtFld.GetField()->ChgTyp( pFldType ); + pFldType->Add( &rDestFmtFld ); // ummelden + rDestFmtFld.GetField()->ChgTyp( pFldType ); } // Expressionfelder Updaten - if( nFldWhich == RES_SETEXPFLD || nFldWhich == RES_GETEXPFLD || - nFldWhich == RES_HIDDENTXTFLD ) + if( nFldWhich == RES_SETEXPFLD + || nFldWhich == RES_GETEXPFLD + || nFldWhich == RES_HIDDENTXTFLD ) { SwTxtFld* pFld = (SwTxtFld*)this; pDestIDFA->UpdateExpFlds( pFld, true ); } // Tabellenfelder auf externe Darstellung - else if( RES_TABLEFLD == nFldWhich && - ((SwTblField*)rFmtFld.GetField())->IsIntrnlName() ) + else if( RES_TABLEFLD == nFldWhich + && ((SwTblField*)rDestFmtFld.GetField())->IsIntrnlName() ) { // erzeuge aus der internen (fuer CORE) die externe (fuer UI) Formel const SwTableNode* pTblNd = m_pTxtNode->FindTableNode(); if( pTblNd ) // steht in einer Tabelle - ((SwTblField*)rFmtFld.GetField())->PtrToBoxNm( &pTblNd->GetTable() ); + ((SwTblField*)rDestFmtFld.GetField())->PtrToBoxNm( &pTblNd->GetTable() ); } } @@ -413,4 +431,86 @@ void SwTxtFld::NotifyContentChange(SwFmtFld& rFmtFld) } +// input field in-place editing +SwTxtInputFld::SwTxtInputFld( + SwFmtFld & rAttr, + sal_Int32 const nStart, + sal_Int32 const nEnd, + bool const bInClipboard ) + + : SwTxtFld( rAttr, nStart, bInClipboard ) + , m_nEnd( nEnd ) +{ + SetHasDummyChar( false ); + SetHasContent( true ); + + SetDontExpand( true ); + SetLockExpandFlag( true ); + SetDontExpandStartAttr( true ); + + SetNesting( true ); +} + +SwTxtInputFld::~SwTxtInputFld() +{ +} + +sal_Int32* SwTxtInputFld::GetEnd() +{ + return &m_nEnd; +} + +void SwTxtInputFld::NotifyContentChange( SwFmtFld& rFmtFld ) +{ + SwTxtFld::NotifyContentChange( rFmtFld ); + + UpdateTextNodeContent( GetFieldContent() ); +} + +const OUString SwTxtInputFld::GetFieldContent() const +{ + return GetFmtFld().GetField()->ExpandField(false); +} + +void SwTxtInputFld::UpdateFieldContent() +{ + if ( IsFldInDoc() + && (*GetStart()) != (*End()) ) + { + OSL_ENSURE( (*End()) - (*GetStart()) >= 2, + "<SwTxtInputFld::UpdateFieldContent()> - Are CH_TXT_ATR_INPUTFIELDSTART and/or CH_TXT_ATR_INPUTFIELDEND missing?" ); + // skip CH_TXT_ATR_INPUTFIELDSTART character + const xub_StrLen nIdx = (*GetStart()) + 1; + // skip CH_TXT_ATR_INPUTFIELDEND character + const xub_StrLen nLen = static_cast<xub_StrLen>(std::max( 0, ( (*End()) - 1 - nIdx ) )); + const OUString aNewFieldContent = GetTxtNode().GetExpandTxt( nIdx, nLen ); + + const SwInputField* pInputFld = dynamic_cast<const SwInputField*>(GetFmtFld().GetField()); + OSL_ENSURE( pInputFld != NULL, + "<SwTxtInputFld::GetContent()> - Missing <SwInputFld> instance!" ); + if ( pInputFld != NULL ) + { + const_cast<SwInputField*>(pInputFld)->applyFieldContent( aNewFieldContent ); + } + } +} + +void SwTxtInputFld::UpdateTextNodeContent( const OUString& rNewContent ) +{ + if ( !IsFldInDoc() ) + { + OSL_ENSURE( false, "<SwTxtInputFld::UpdateTextNodeContent(..)> - misusage as Input Field is not in document content." ); + return; + } + + OSL_ENSURE( (*End()) - (*GetStart()) >= 2, + "<SwTxtInputFld::UpdateTextNodeContent(..)> - Are CH_TXT_ATR_INPUTFIELDSTART and/or CH_TXT_ATR_INPUTFIELDEND missing?" ); + // skip CH_TXT_ATR_INPUTFIELDSTART character + const sal_Int32 nIdx = (*GetStart()) + 1; + // skip CH_TXT_ATR_INPUTFIELDEND character + const sal_Int32 nDelLen = std::max<sal_Int32>( 0, ( (*End()) - 1 - nIdx ) ); + SwIndex aIdx( &GetTxtNode(), nIdx ); + GetTxtNode().ReplaceText( aIdx, nDelLen, rNewContent ); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |