1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ddefld.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <svx/linkmgr.hxx>
43 #include <swtable.hxx>
44 #include <swbaslnk.hxx>
45 #include <swddetbl.hxx>
47 #include <unofldmid.h>
52 using namespace ::com::sun::star
;
54 #define DDE_TXT_ENCODING gsl_getSystemTextEncoding()
56 /*--------------------------------------------------------------------
57 Beschreibung: Globale Variablen
58 --------------------------------------------------------------------*/
60 class SwIntrnlRefLink
: public SwBaseLink
62 SwDDEFieldType
& rFldType
;
64 SwIntrnlRefLink( SwDDEFieldType
& rType
, USHORT nUpdateType
, USHORT nFmt
)
65 : SwBaseLink( nUpdateType
, nFmt
),
69 virtual void Closed();
70 virtual void DataChanged( const String
& rMimeType
,
71 const uno::Any
& rValue
);
73 virtual const SwNode
* GetAnchor() const;
74 virtual BOOL
IsInRange( ULONG nSttNd
, ULONG nEndNd
, xub_StrLen nStt
= 0,
75 xub_StrLen nEnd
= STRING_NOTFOUND
) const;
79 void SwIntrnlRefLink::DataChanged( const String
& rMimeType
,
80 const uno::Any
& rValue
)
82 switch( SotExchange::GetFormatIdFromMimeType( rMimeType
) )
87 uno::Sequence
< sal_Int8
> aSeq
;
89 String
sStr( (sal_Char
*)aSeq
.getConstArray(), static_cast<xub_StrLen
>(aSeq
.getLength()),
92 // CR-LF am Ende entfernen, ist ueberfluessig!
93 xub_StrLen n
= sStr
.Len();
94 while( n
&& 0 == sStr
.GetChar( n
-1 ) )
96 if( n
&& 0x0a == sStr
.GetChar( n
-1 ) )
98 if( n
&& 0x0d == sStr
.GetChar( n
-1 ) )
101 BOOL bDel
= n
!= sStr
.Len();
105 rFldType
.SetExpansion( sStr
);
106 // erst Expansion setzen! (sonst wird das Flag geloescht!)
107 rFldType
.SetCRLFDelFlag( bDel
);
111 // weitere Formate ...
116 ASSERT( rFldType
.GetDoc(), "Kein pDoc" );
118 // keine Abhaengigen mehr?
119 if( rFldType
.GetDepends() && !rFldType
.IsModifyLocked() && !ChkNoDataFlag() )
122 SwEditShell
* pESh
= rFldType
.GetDoc()->GetEditShell( &pSh
);
124 // dann suchen wir uns mal alle Felder. Wird kein gueltiges
125 // gefunden, dann Disconnecten wir uns!
126 SwMsgPoolItem
aUpdateDDE( RES_UPDATEDDETBL
);
127 int bCallModify
= FALSE
;
128 rFldType
.LockModify();
130 SwClientIter
aIter( rFldType
);
131 SwClient
* pLast
= aIter
.GoStart();
132 if( pLast
) // konnte zum Anfang gesprungen werden ??
134 // eine DDE-Tabelle oder ein DDE-FeldAttribut im Text
135 if( !pLast
->IsA( TYPE( SwFmtFld
) ) ||
136 ((SwFmtFld
*)pLast
)->GetTxtFld() )
141 pESh
->StartAllAction();
145 pLast
->Modify( 0, &aUpdateDDE
);
148 } while( 0 != ( pLast
= aIter
++ ));
150 rFldType
.UnlockModify();
155 pESh
->EndAllAction();
160 pSh
->GetDoc()->SetModified();
165 void SwIntrnlRefLink::Closed()
167 if( rFldType
.GetDoc() && !rFldType
.GetDoc()->IsInDtor() )
169 // Advise verabschiedet sich, alle Felder in Text umwandeln ?
171 SwEditShell
* pESh
= rFldType
.GetDoc()->GetEditShell( &pSh
);
174 pESh
->StartAllAction();
175 pESh
->FieldToText( &rFldType
);
176 pESh
->EndAllAction();
181 // am Doc aufrufen ??
185 SvBaseLink::Closed();
188 const SwNode
* SwIntrnlRefLink::GetAnchor() const
190 // hier sollte irgend ein Anchor aus dem normalen Nodes-Array reichen
191 const SwNode
* pNd
= 0;
192 SwClientIter
aIter( rFldType
);
193 SwClient
* pLast
= aIter
.GoStart();
194 if( pLast
) // konnte zum Anfang gesprungen werden ??
196 // eine DDE-Tabelle oder ein DDE-FeldAttribut im Text
197 if( !pLast
->IsA( TYPE( SwFmtFld
) ))
199 SwDepend
* pDep
= (SwDepend
*)pLast
;
200 SwDDETable
* pDDETbl
= (SwDDETable
*)pDep
->GetToTell();
201 pNd
= pDDETbl
->GetTabSortBoxes()[0]->GetSttNd();
203 else if( ((SwFmtFld
*)pLast
)->GetTxtFld() )
204 pNd
= ((SwFmtFld
*)pLast
)->GetTxtFld()->GetpTxtNode();
206 if( pNd
&& &rFldType
.GetDoc()->GetNodes() == &pNd
->GetNodes() )
209 } while( 0 != ( pLast
= aIter
++ ));
214 BOOL
SwIntrnlRefLink::IsInRange( ULONG nSttNd
, ULONG nEndNd
,
215 xub_StrLen nStt
, xub_StrLen nEnd
) const
217 // hier sollte irgend ein Anchor aus dem normalen Nodes-Array reichen
218 SwNodes
* pNds
= &rFldType
.GetDoc()->GetNodes();
219 SwClientIter
aIter( rFldType
);
220 SwClient
* pLast
= aIter
.GoStart();
221 if( pLast
) // konnte zum Anfang gesprungen werden ??
223 // eine DDE-Tabelle oder ein DDE-FeldAttribut im Text
224 if( !pLast
->IsA( TYPE( SwFmtFld
) ))
226 SwDepend
* pDep
= (SwDepend
*)pLast
;
227 SwDDETable
* pDDETbl
= (SwDDETable
*)pDep
->GetToTell();
228 const SwTableNode
* pTblNd
= pDDETbl
->GetTabSortBoxes()[0]->
229 GetSttNd()->FindTableNode();
230 if( pTblNd
->GetNodes().IsDocNodes() &&
231 nSttNd
< pTblNd
->EndOfSectionIndex() &&
232 nEndNd
> pTblNd
->GetIndex() )
235 else if( ((SwFmtFld
*)pLast
)->GetTxtFld() )
237 const SwTxtFld
* pTFld
= ((SwFmtFld
*)pLast
)->GetTxtFld();
238 const SwTxtNode
* pNd
= pTFld
->GetpTxtNode();
239 if( pNd
&& pNds
== &pNd
->GetNodes() )
241 ULONG nNdPos
= pNd
->GetIndex();
242 if( nSttNd
<= nNdPos
&& nNdPos
<= nEndNd
&&
243 ( nNdPos
!= nSttNd
|| *pTFld
->GetStart() >= nStt
) &&
244 ( nNdPos
!= nEndNd
|| *pTFld
->GetStart() < nEnd
))
248 } while( 0 != ( pLast
= aIter
++ ));
253 SwDDEFieldType::SwDDEFieldType(const String
& rName
,
254 const String
& rCmd
, USHORT nUpdateType
)
255 : SwFieldType( RES_DDEFLD
),
256 aName( rName
), pDoc( 0 ), nRefCnt( 0 )
258 bCRLFFlag
= bDeleted
= FALSE
;
259 refLink
= new SwIntrnlRefLink( *this, nUpdateType
, FORMAT_STRING
);
263 SwDDEFieldType::~SwDDEFieldType()
265 if( pDoc
&& !pDoc
->IsInDtor() )
266 pDoc
->GetLinkManager().Remove( refLink
);
267 refLink
->Disconnect();
270 SwFieldType
* SwDDEFieldType::Copy() const
272 SwDDEFieldType
* pType
= new SwDDEFieldType( aName
, GetCmd(), GetType() );
273 pType
->aExpansion
= aExpansion
;
274 pType
->bCRLFFlag
= bCRLFFlag
;
275 pType
->bDeleted
= bDeleted
;
276 pType
->SetDoc( pDoc
);
280 const String
& SwDDEFieldType::GetName() const
285 void SwDDEFieldType::SetCmd( const String
& rStr
)
289 while( STRING_NOTFOUND
!= (nPos
= sCmd
.SearchAscii( " " )) )
290 sCmd
.Erase( nPos
, 1 );
291 refLink
->SetLinkSourceName( sCmd
);
294 String
SwDDEFieldType::GetCmd() const
296 return refLink
->GetLinkSourceName();
299 void SwDDEFieldType::SetDoc( SwDoc
* pNewDoc
)
301 if( pNewDoc
== pDoc
)
304 if( pDoc
&& refLink
.Is() )
306 ASSERT( !nRefCnt
, "wie kommen die Referenzen rueber?" );
307 pDoc
->GetLinkManager().Remove( refLink
);
311 if( pDoc
&& nRefCnt
)
313 refLink
->SetVisible( pDoc
->IsVisibleLinks() );
314 pDoc
->GetLinkManager().InsertDDELink( refLink
);
319 void SwDDEFieldType::_RefCntChgd()
323 refLink
->SetVisible( pDoc
->IsVisibleLinks() );
324 pDoc
->GetLinkManager().InsertDDELink( refLink
);
325 if( pDoc
->GetRootFrm() )
331 pDoc
->GetLinkManager().Remove( refLink
);
334 /* -----------------------------28.08.00 16:23--------------------------------
336 ---------------------------------------------------------------------------*/
337 BOOL
SwDDEFieldType::QueryValue( uno::Any
& rVal
, USHORT nWhichId
) const
342 case FIELD_PROP_PAR2
: nPart
= 3; break;
343 case FIELD_PROP_PAR4
: nPart
= 2; break;
344 case FIELD_PROP_SUBTYPE
: nPart
= 1; break;
345 case FIELD_PROP_BOOL1
:
347 sal_Bool bSet
= GetType() == sfx2::LINKUPDATE_ALWAYS
? TRUE
: FALSE
;
348 rVal
.setValue(&bSet
, ::getBooleanCppuType());
351 case FIELD_PROP_PAR5
:
352 rVal
<<= ::rtl::OUString(aExpansion
);
355 DBG_ERROR("illegal property");
358 rVal
<<= OUString(GetCmd().GetToken(nPart
-1, sfx2::cTokenSeperator
));
361 /* -----------------------------28.08.00 16:23--------------------------------
363 ---------------------------------------------------------------------------*/
364 BOOL
SwDDEFieldType::PutValue( const uno::Any
& rVal
, USHORT nWhichId
)
369 case FIELD_PROP_PAR2
: nPart
= 3; break;
370 case FIELD_PROP_PAR4
: nPart
= 2; break;
371 case FIELD_PROP_SUBTYPE
: nPart
= 1; break;
372 case FIELD_PROP_BOOL1
:
373 SetType( static_cast<USHORT
>(*(sal_Bool
*)rVal
.getValue() ?
374 sfx2::LINKUPDATE_ALWAYS
:
375 sfx2::LINKUPDATE_ONCALL
) );
377 case FIELD_PROP_PAR5
:
379 ::rtl::OUString sTemp
;
385 DBG_ERROR("illegal property");
389 String sTmp
, sCmd( GetCmd() );
390 while(3 > sCmd
.GetTokenCount(sfx2::cTokenSeperator
))
391 sCmd
+= sfx2::cTokenSeperator
;
392 sCmd
.SetToken( nPart
-1, sfx2::cTokenSeperator
, ::GetString( rVal
, sTmp
) );
397 /* ---------------------------------------------------------------------------
399 ---------------------------------------------------------------------------*/
400 SwDDEField::SwDDEField( SwDDEFieldType
* pInitType
)
405 SwDDEField::~SwDDEField()
407 if( GetTyp()->IsLastDepend() ) // der Letzte mach das
408 ((SwDDEFieldType
*)GetTyp())->Disconnect(); // Licht aus
411 String
SwDDEField::Expand() const
414 String
aStr( ((SwDDEFieldType
*)GetTyp())->GetExpansion() );
416 aStr
.EraseAllChars( '\r' );
417 while( (nPos
= aStr
.Search( '\t' )) != STRING_NOTFOUND
)
418 aStr
.SetChar( nPos
, ' ' );
419 while( (nPos
= aStr
.Search( '\n' )) != STRING_NOTFOUND
)
420 aStr
.SetChar( nPos
, '|' );
421 if( aStr
.Len() && ( aStr
.GetChar( aStr
.Len()-1 ) == '|') )
422 aStr
.Erase( aStr
.Len()-1, 1 );
426 SwField
* SwDDEField::Copy() const
428 return new SwDDEField((SwDDEFieldType
*)GetTyp());
431 /*--------------------------------------------------------------------
432 Beschreibung: Parameter des Typen erfragen
434 --------------------------------------------------------------------*/
435 const String
& SwDDEField::GetPar1() const
437 return ((SwDDEFieldType
*)GetTyp())->GetName();
440 /*--------------------------------------------------------------------
441 Beschreibung: Parameter des Typen erfragen
443 --------------------------------------------------------------------*/
444 String
SwDDEField::GetPar2() const
446 return ((SwDDEFieldType
*)GetTyp())->GetCmd();
449 void SwDDEField::SetPar2(const String
& rStr
)
451 ((SwDDEFieldType
*)GetTyp())->SetCmd(rStr
);