Update ooo320-m1
[ooovba.git] / sw / source / core / fields / ddefld.cxx
blob04cb0c77557bbb98d54d4192b65f939231d530ad
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ddefld.cxx,v $
10 * $Revision: 1.19 $
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>
36 #include <doc.hxx>
37 #include <editsh.hxx>
38 #include <errhdl.hxx>
39 #include <ndtxt.hxx>
40 #include <fmtfld.hxx>
41 #include <txtfld.hxx>
42 #include <ddefld.hxx>
43 #include <swtable.hxx>
44 #include <swbaslnk.hxx>
45 #include <swddetbl.hxx>
46 #ifndef _UNOFLDMID_H
47 #include <unofldmid.h>
48 #endif
49 #include <hints.hxx>
51 using rtl::OUString;
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;
63 public:
64 SwIntrnlRefLink( SwDDEFieldType& rType, USHORT nUpdateType, USHORT nFmt )
65 : SwBaseLink( nUpdateType, nFmt ),
66 rFldType( rType )
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 ) )
84 case FORMAT_STRING:
85 if( !IsNoDataFlag() )
87 uno::Sequence< sal_Int8 > aSeq;
88 rValue >>= aSeq;
89 String sStr( (sal_Char*)aSeq.getConstArray(), static_cast<xub_StrLen>(aSeq.getLength()),
90 DDE_TXT_ENCODING );
92 // CR-LF am Ende entfernen, ist ueberfluessig!
93 xub_StrLen n = sStr.Len();
94 while( n && 0 == sStr.GetChar( n-1 ) )
95 --n;
96 if( n && 0x0a == sStr.GetChar( n-1 ) )
97 --n;
98 if( n && 0x0d == sStr.GetChar( n-1 ) )
99 --n;
101 BOOL bDel = n != sStr.Len();
102 if( bDel )
103 sStr.Erase( n );
105 rFldType.SetExpansion( sStr );
106 // erst Expansion setzen! (sonst wird das Flag geloescht!)
107 rFldType.SetCRLFDelFlag( bDel );
109 break;
111 // weitere Formate ...
112 default:
113 return;
116 ASSERT( rFldType.GetDoc(), "Kein pDoc" );
118 // keine Abhaengigen mehr?
119 if( rFldType.GetDepends() && !rFldType.IsModifyLocked() && !ChkNoDataFlag() )
121 ViewShell* pSh;
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 ??
133 do {
134 // eine DDE-Tabelle oder ein DDE-FeldAttribut im Text
135 if( !pLast->IsA( TYPE( SwFmtFld ) ) ||
136 ((SwFmtFld*)pLast)->GetTxtFld() )
138 if( !bCallModify )
140 if( pESh )
141 pESh->StartAllAction();
142 else if( pSh )
143 pSh->StartAction();
145 pLast->Modify( 0, &aUpdateDDE );
146 bCallModify = TRUE;
148 } while( 0 != ( pLast = aIter++ ));
150 rFldType.UnlockModify();
152 if( bCallModify )
154 if( pESh )
155 pESh->EndAllAction();
156 else if( pSh )
157 pSh->EndAction();
159 if( pSh )
160 pSh->GetDoc()->SetModified();
165 void SwIntrnlRefLink::Closed()
167 if( rFldType.GetDoc() && !rFldType.GetDoc()->IsInDtor() )
169 // Advise verabschiedet sich, alle Felder in Text umwandeln ?
170 ViewShell* pSh;
171 SwEditShell* pESh = rFldType.GetDoc()->GetEditShell( &pSh );
172 if( pESh )
174 pESh->StartAllAction();
175 pESh->FieldToText( &rFldType );
176 pESh->EndAllAction();
178 else
180 pSh->StartAction();
181 // am Doc aufrufen ??
182 pSh->EndAction();
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 ??
195 do {
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() )
207 break;
208 pNd = 0;
209 } while( 0 != ( pLast = aIter++ ));
211 return pNd;
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 ??
222 do {
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() )
233 return TRUE;
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 ))
245 return TRUE;
248 } while( 0 != ( pLast = aIter++ ));
250 return FALSE;
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 );
260 SetCmd( rCmd );
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 );
277 return pType;
280 const String& SwDDEFieldType::GetName() const
282 return aName;
285 void SwDDEFieldType::SetCmd( const String& rStr )
287 String sCmd( rStr );
288 xub_StrLen nPos;
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 )
302 return;
304 if( pDoc && refLink.Is() )
306 ASSERT( !nRefCnt, "wie kommen die Referenzen rueber?" );
307 pDoc->GetLinkManager().Remove( refLink );
310 pDoc = pNewDoc;
311 if( pDoc && nRefCnt )
313 refLink->SetVisible( pDoc->IsVisibleLinks() );
314 pDoc->GetLinkManager().InsertDDELink( refLink );
319 void SwDDEFieldType::_RefCntChgd()
321 if( nRefCnt )
323 refLink->SetVisible( pDoc->IsVisibleLinks() );
324 pDoc->GetLinkManager().InsertDDELink( refLink );
325 if( pDoc->GetRootFrm() )
326 UpdateNow();
328 else
330 Disconnect();
331 pDoc->GetLinkManager().Remove( refLink );
334 /* -----------------------------28.08.00 16:23--------------------------------
336 ---------------------------------------------------------------------------*/
337 BOOL SwDDEFieldType::QueryValue( uno::Any& rVal, USHORT nWhichId ) const
339 BYTE nPart = 0;
340 switch( nWhichId )
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());
350 break;
351 case FIELD_PROP_PAR5:
352 rVal <<= ::rtl::OUString(aExpansion);
353 break;
354 default:
355 DBG_ERROR("illegal property");
357 if( nPart )
358 rVal <<= OUString(GetCmd().GetToken(nPart-1, sfx2::cTokenSeperator));
359 return TRUE;
361 /* -----------------------------28.08.00 16:23--------------------------------
363 ---------------------------------------------------------------------------*/
364 BOOL SwDDEFieldType::PutValue( const uno::Any& rVal, USHORT nWhichId )
366 BYTE nPart = 0;
367 switch( 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 ) );
376 break;
377 case FIELD_PROP_PAR5:
379 ::rtl::OUString sTemp;
380 rVal >>= sTemp;
381 aExpansion = sTemp;
383 break;
384 default:
385 DBG_ERROR("illegal property");
387 if( nPart )
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 ) );
393 SetCmd( sCmd );
395 return TRUE;
397 /* ---------------------------------------------------------------------------
399 ---------------------------------------------------------------------------*/
400 SwDDEField::SwDDEField( SwDDEFieldType* pInitType )
401 : SwField(pInitType)
405 SwDDEField::~SwDDEField()
407 if( GetTyp()->IsLastDepend() ) // der Letzte mach das
408 ((SwDDEFieldType*)GetTyp())->Disconnect(); // Licht aus
411 String SwDDEField::Expand() const
413 xub_StrLen nPos;
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 );
423 return aStr;
426 SwField* SwDDEField::Copy() const
428 return new SwDDEField((SwDDEFieldType*)GetTyp());
431 /*--------------------------------------------------------------------
432 Beschreibung: Parameter des Typen erfragen
433 Name
434 --------------------------------------------------------------------*/
435 const String& SwDDEField::GetPar1() const
437 return ((SwDDEFieldType*)GetTyp())->GetName();
440 /*--------------------------------------------------------------------
441 Beschreibung: Parameter des Typen erfragen
442 Commando
443 --------------------------------------------------------------------*/
444 String SwDDEField::GetPar2() const
446 return ((SwDDEFieldType*)GetTyp())->GetCmd();
449 void SwDDEField::SetPar2(const String& rStr)
451 ((SwDDEFieldType*)GetTyp())->SetCmd(rStr);