Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <comphelper/string.hxx>
31 : : #include <sfx2/linkmgr.hxx>
32 : : #include <doc.hxx>
33 : : #include <editsh.hxx>
34 : : #include <ndtxt.hxx>
35 : : #include <fmtfld.hxx>
36 : : #include <txtfld.hxx>
37 : : #include <ddefld.hxx>
38 : : #include <swtable.hxx>
39 : : #include <swbaslnk.hxx>
40 : : #include <swddetbl.hxx>
41 : : #include <unofldmid.h>
42 : : #include <hints.hxx>
43 : :
44 : : using rtl::OUString;
45 : : using namespace ::com::sun::star;
46 : :
47 : : #define DDE_TXT_ENCODING osl_getThreadTextEncoding()
48 : :
49 : : /*--------------------------------------------------------------------
50 : : Beschreibung: Globale Variablen
51 : : --------------------------------------------------------------------*/
52 : :
53 [ # # ]: 0 : class SwIntrnlRefLink : public SwBaseLink
54 : : {
55 : : SwDDEFieldType& rFldType;
56 : : public:
57 : 0 : SwIntrnlRefLink( SwDDEFieldType& rType, sal_uInt16 nUpdateType, sal_uInt16 nFmt )
58 : : : SwBaseLink( nUpdateType, nFmt ),
59 : 0 : rFldType( rType )
60 : 0 : {}
61 : :
62 : : virtual void Closed();
63 : : virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(
64 : : const String& rMimeType, const ::com::sun::star::uno::Any & rValue );
65 : :
66 : : virtual const SwNode* GetAnchor() const;
67 : : virtual sal_Bool IsInRange( sal_uLong nSttNd, sal_uLong nEndNd, xub_StrLen nStt = 0,
68 : : xub_StrLen nEnd = STRING_NOTFOUND ) const;
69 : : };
70 : :
71 : :
72 : 0 : ::sfx2::SvBaseLink::UpdateResult SwIntrnlRefLink::DataChanged( const String& rMimeType,
73 : : const uno::Any & rValue )
74 : : {
75 [ # # ]: 0 : switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) )
76 : : {
77 : : case FORMAT_STRING:
78 [ # # ]: 0 : if( !IsNoDataFlag() )
79 : : {
80 [ # # ]: 0 : uno::Sequence< sal_Int8 > aSeq;
81 [ # # ]: 0 : rValue >>= aSeq;
82 : 0 : String sStr( (sal_Char*)aSeq.getConstArray(), static_cast<xub_StrLen>(aSeq.getLength()),
83 [ # # # # ]: 0 : DDE_TXT_ENCODING );
84 : :
85 : : // CR-LF am Ende entfernen, ist ueberfluessig!
86 : 0 : xub_StrLen n = sStr.Len();
87 [ # # ][ # # ]: 0 : while( n && 0 == sStr.GetChar( n-1 ) )
[ # # ]
88 : 0 : --n;
89 [ # # ][ # # ]: 0 : if( n && 0x0a == sStr.GetChar( n-1 ) )
[ # # ]
90 : 0 : --n;
91 [ # # ][ # # ]: 0 : if( n && 0x0d == sStr.GetChar( n-1 ) )
[ # # ]
92 : 0 : --n;
93 : :
94 : 0 : sal_Bool bDel = n != sStr.Len();
95 [ # # ]: 0 : if( bDel )
96 [ # # ]: 0 : sStr.Erase( n );
97 : :
98 [ # # ]: 0 : rFldType.SetExpansion( sStr );
99 : : // erst Expansion setzen! (sonst wird das Flag geloescht!)
100 [ # # ][ # # ]: 0 : rFldType.SetCRLFDelFlag( bDel );
101 : : }
102 : 0 : break;
103 : :
104 : : // weitere Formate ...
105 : : default:
106 : 0 : return SUCCESS;
107 : : }
108 : :
109 : : OSL_ENSURE( rFldType.GetDoc(), "Kein pDoc" );
110 : :
111 : : // keine Abhaengigen mehr?
112 [ # # ][ # # ]: 0 : if( rFldType.GetDepends() && !rFldType.IsModifyLocked() && !ChkNoDataFlag() )
[ # # ][ # # ]
113 : : {
114 : : ViewShell* pSh;
115 [ # # ]: 0 : SwEditShell* pESh = rFldType.GetDoc()->GetEditShell( &pSh );
116 : :
117 : : // dann suchen wir uns mal alle Felder. Wird kein gueltiges
118 : : // gefunden, dann Disconnecten wir uns!
119 [ # # ]: 0 : SwMsgPoolItem aUpdateDDE( RES_UPDATEDDETBL );
120 : 0 : int bCallModify = sal_False;
121 : 0 : rFldType.LockModify();
122 : :
123 [ # # ]: 0 : SwClientIter aIter( rFldType ); // TODO
124 [ # # ]: 0 : SwClient * pLast = aIter.GoStart();
125 [ # # ]: 0 : if( pLast ) // konnte zum Anfang gesprungen werden ??
126 [ # # ][ # # ]: 0 : do {
127 : : // eine DDE-Tabelle oder ein DDE-FeldAttribut im Text
128 [ # # ][ # # ]: 0 : if( !pLast->IsA( TYPE( SwFmtFld ) ) ||
[ # # # # ]
[ # # ]
129 [ # # ]: 0 : ((SwFmtFld*)pLast)->GetTxtFld() )
130 : : {
131 [ # # ]: 0 : if( !bCallModify )
132 : : {
133 [ # # ]: 0 : if( pESh )
134 [ # # ]: 0 : pESh->StartAllAction();
135 [ # # ]: 0 : else if( pSh )
136 [ # # ]: 0 : pSh->StartAction();
137 : : }
138 [ # # ]: 0 : pLast->ModifyNotification( 0, &aUpdateDDE );
139 : 0 : bCallModify = sal_True;
140 : : }
141 : : } while( 0 != ( pLast = aIter++ ));
142 : :
143 : 0 : rFldType.UnlockModify();
144 : :
145 [ # # ]: 0 : if( bCallModify )
146 : : {
147 [ # # ]: 0 : if( pESh )
148 [ # # ]: 0 : pESh->EndAllAction();
149 [ # # ]: 0 : else if( pSh )
150 [ # # ]: 0 : pSh->EndAction();
151 : :
152 [ # # ]: 0 : if( pSh )
153 [ # # ]: 0 : pSh->GetDoc()->SetModified();
154 [ # # ][ # # ]: 0 : }
155 : : }
156 : :
157 : 0 : return SUCCESS;
158 : : }
159 : :
160 : 0 : void SwIntrnlRefLink::Closed()
161 : : {
162 [ # # ][ # # ]: 0 : if( rFldType.GetDoc() && !rFldType.GetDoc()->IsInDtor() )
[ # # ]
163 : : {
164 : : // Advise verabschiedet sich, alle Felder in Text umwandeln ?
165 : : ViewShell* pSh;
166 [ # # ]: 0 : SwEditShell* pESh = rFldType.GetDoc()->GetEditShell( &pSh );
167 [ # # ]: 0 : if( pESh )
168 : : {
169 [ # # ]: 0 : pESh->StartAllAction();
170 [ # # ]: 0 : pESh->FieldToText( &rFldType );
171 [ # # ]: 0 : pESh->EndAllAction();
172 : : }
173 : : else
174 : : {
175 [ # # ]: 0 : pSh->StartAction();
176 : : // am Doc aufrufen ??
177 [ # # ]: 0 : pSh->EndAction();
178 : : }
179 : : }
180 : 0 : SvBaseLink::Closed();
181 : 0 : }
182 : :
183 : 0 : const SwNode* SwIntrnlRefLink::GetAnchor() const
184 : : {
185 : : // hier sollte irgend ein Anchor aus dem normalen Nodes-Array reichen
186 : 0 : const SwNode* pNd = 0;
187 [ # # ]: 0 : SwClientIter aIter( rFldType ); // TODO
188 [ # # ]: 0 : SwClient * pLast = aIter.GoStart();
189 [ # # ]: 0 : if( pLast ) // konnte zum Anfang gesprungen werden ??
190 [ # # ][ # # ]: 0 : do {
191 : : // eine DDE-Tabelle oder ein DDE-FeldAttribut im Text
192 [ # # ][ # # ]: 0 : if( !pLast->IsA( TYPE( SwFmtFld ) ))
[ # # ]
193 : : {
194 : 0 : SwDepend* pDep = (SwDepend*)pLast;
195 : 0 : SwDDETable* pDDETbl = (SwDDETable*)pDep->GetToTell();
196 [ # # ]: 0 : pNd = pDDETbl->GetTabSortBoxes()[0]->GetSttNd();
197 : : }
198 [ # # ][ # # ]: 0 : else if( ((SwFmtFld*)pLast)->GetTxtFld() )
199 [ # # ][ # # ]: 0 : pNd = ((SwFmtFld*)pLast)->GetTxtFld()->GetpTxtNode();
200 : :
201 [ # # ][ # # ]: 0 : if( pNd && &rFldType.GetDoc()->GetNodes() == &pNd->GetNodes() )
[ # # ][ # # ]
202 : 0 : break;
203 : 0 : pNd = 0;
204 : : } while( 0 != ( pLast = aIter++ ));
205 : :
206 [ # # ]: 0 : return pNd;
207 : : }
208 : :
209 : 0 : sal_Bool SwIntrnlRefLink::IsInRange( sal_uLong nSttNd, sal_uLong nEndNd,
210 : : xub_StrLen nStt, xub_StrLen nEnd ) const
211 : : {
212 : : // hier sollte irgend ein Anchor aus dem normalen Nodes-Array reichen
213 [ # # ]: 0 : SwNodes* pNds = &rFldType.GetDoc()->GetNodes();
214 [ # # ]: 0 : SwClientIter aIter( rFldType ); // TODO
215 [ # # ]: 0 : SwClient * pLast = aIter.GoStart();
216 [ # # ]: 0 : if( pLast ) // konnte zum Anfang gesprungen werden ??
217 [ # # ][ # # ]: 0 : do {
218 : : // eine DDE-Tabelle oder ein DDE-FeldAttribut im Text
219 [ # # ][ # # ]: 0 : if( !pLast->IsA( TYPE( SwFmtFld ) ))
[ # # ]
220 : : {
221 : 0 : SwDepend* pDep = (SwDepend*)pLast;
222 : 0 : SwDDETable* pDDETbl = (SwDDETable*)pDep->GetToTell();
223 [ # # ]: 0 : const SwTableNode* pTblNd = pDDETbl->GetTabSortBoxes()[0]->
224 [ # # ]: 0 : GetSttNd()->FindTableNode();
225 [ # # ][ # # : 0 : if( pTblNd->GetNodes().IsDocNodes() &&
# # # # ]
[ # # ]
226 : 0 : nSttNd < pTblNd->EndOfSectionIndex() &&
227 : 0 : nEndNd > pTblNd->GetIndex() )
228 : 0 : return sal_True;
229 : : }
230 [ # # ][ # # ]: 0 : else if( ((SwFmtFld*)pLast)->GetTxtFld() )
231 : : {
232 [ # # ]: 0 : const SwTxtFld* pTFld = ((SwFmtFld*)pLast)->GetTxtFld();
233 : 0 : const SwTxtNode* pNd = pTFld->GetpTxtNode();
234 [ # # ][ # # ]: 0 : if( pNd && pNds == &pNd->GetNodes() )
[ # # ]
235 : : {
236 : 0 : sal_uLong nNdPos = pNd->GetIndex();
237 [ # # ]: 0 : if( nSttNd <= nNdPos && nNdPos <= nEndNd &&
[ # # # # ]
[ # # # # ]
[ # # ][ # # ]
238 : 0 : ( nNdPos != nSttNd || *pTFld->GetStart() >= nStt ) &&
239 : 0 : ( nNdPos != nEndNd || *pTFld->GetStart() < nEnd ))
240 : 0 : return sal_True;
241 : : }
242 : : }
243 : : } while( 0 != ( pLast = aIter++ ));
244 : :
245 [ # # ]: 0 : return sal_False;
246 : : }
247 : :
248 : 0 : SwDDEFieldType::SwDDEFieldType(const String& rName,
249 : : const String& rCmd, sal_uInt16 nUpdateType )
250 : : : SwFieldType( RES_DDEFLD ),
251 [ # # ][ # # ]: 0 : aName( rName ), pDoc( 0 ), nRefCnt( 0 )
252 : : {
253 : 0 : bCRLFFlag = bDeleted = sal_False;
254 [ # # ][ # # ]: 0 : refLink = new SwIntrnlRefLink( *this, nUpdateType, FORMAT_STRING );
[ # # ]
255 [ # # ]: 0 : SetCmd( rCmd );
256 : 0 : }
257 : :
258 [ # # ][ # # ]: 0 : SwDDEFieldType::~SwDDEFieldType()
259 : : {
260 [ # # ][ # # ]: 0 : if( pDoc && !pDoc->IsInDtor() )
[ # # ]
261 [ # # ][ # # ]: 0 : pDoc->GetLinkManager().Remove( refLink );
262 [ # # ]: 0 : refLink->Disconnect();
263 [ # # ]: 0 : }
264 : :
265 : 0 : SwFieldType* SwDDEFieldType::Copy() const
266 : : {
267 [ # # ][ # # ]: 0 : SwDDEFieldType* pType = new SwDDEFieldType( aName, GetCmd(), GetType() );
[ # # ][ # # ]
[ # # ]
268 : 0 : pType->aExpansion = aExpansion;
269 : 0 : pType->bCRLFFlag = bCRLFFlag;
270 : 0 : pType->bDeleted = bDeleted;
271 : 0 : pType->SetDoc( pDoc );
272 : 0 : return pType;
273 : : }
274 : :
275 : 0 : const rtl::OUString& SwDDEFieldType::GetName() const
276 : : {
277 : 0 : return aName;
278 : : }
279 : :
280 : 0 : void SwDDEFieldType::SetCmd( const String& rStr )
281 : : {
282 [ # # ]: 0 : String sCmd( rStr );
283 : : xub_StrLen nPos;
284 [ # # ][ # # ]: 0 : while( STRING_NOTFOUND != (nPos = sCmd.SearchAscii( " " )) )
285 [ # # ]: 0 : sCmd.Erase( nPos, 1 );
286 [ # # ][ # # ]: 0 : refLink->SetLinkSourceName( sCmd );
287 : 0 : }
288 : :
289 : 0 : String SwDDEFieldType::GetCmd() const
290 : : {
291 : 0 : return refLink->GetLinkSourceName();
292 : : }
293 : :
294 : 0 : void SwDDEFieldType::SetDoc( SwDoc* pNewDoc )
295 : : {
296 [ # # ]: 0 : if( pNewDoc == pDoc )
297 : 0 : return;
298 : :
299 [ # # ][ # # ]: 0 : if( pDoc && refLink.Is() )
[ # # ]
300 : : {
301 : : OSL_ENSURE( !nRefCnt, "wie kommen die Referenzen rueber?" );
302 : 0 : pDoc->GetLinkManager().Remove( refLink );
303 : : }
304 : :
305 : 0 : pDoc = pNewDoc;
306 [ # # ][ # # ]: 0 : if( pDoc && nRefCnt )
307 : : {
308 : 0 : refLink->SetVisible( pDoc->IsVisibleLinks() );
309 : 0 : pDoc->GetLinkManager().InsertDDELink( refLink );
310 : : }
311 : : }
312 : :
313 : :
314 : 0 : void SwDDEFieldType::_RefCntChgd()
315 : : {
316 [ # # ]: 0 : if( nRefCnt )
317 : : {
318 : 0 : refLink->SetVisible( pDoc->IsVisibleLinks() );
319 : 0 : pDoc->GetLinkManager().InsertDDELink( refLink );
320 [ # # ]: 0 : if( pDoc->GetCurrentViewShell() ) //swmod 071108//swmod 071225
321 : 0 : UpdateNow();
322 : : }
323 : : else
324 : : {
325 : 0 : Disconnect();
326 : 0 : pDoc->GetLinkManager().Remove( refLink );
327 : : }
328 : 0 : }
329 : :
330 : 0 : bool SwDDEFieldType::QueryValue( uno::Any& rVal, sal_uInt16 nWhichId ) const
331 : : {
332 : 0 : sal_uInt8 nPart = 0;
333 [ # # # # : 0 : switch( nWhichId )
# # ]
334 : : {
335 : 0 : case FIELD_PROP_PAR2: nPart = 3; break;
336 : 0 : case FIELD_PROP_PAR4: nPart = 2; break;
337 : 0 : case FIELD_PROP_SUBTYPE: nPart = 1; break;
338 : : case FIELD_PROP_BOOL1:
339 : : {
340 [ # # ][ # # ]: 0 : sal_Bool bSet = GetType() == sfx2::LINKUPDATE_ALWAYS ? sal_True : sal_False;
341 [ # # ]: 0 : rVal.setValue(&bSet, ::getBooleanCppuType());
342 : : }
343 : 0 : break;
344 : : case FIELD_PROP_PAR5:
345 [ # # ]: 0 : rVal <<= ::rtl::OUString(aExpansion);
346 : 0 : break;
347 : : default:
348 : : OSL_FAIL("illegal property");
349 : : }
350 [ # # ]: 0 : if( nPart )
351 [ # # ][ # # ]: 0 : rVal <<= OUString(GetCmd().GetToken(nPart-1, sfx2::cTokenSeperator));
[ # # ][ # # ]
352 : 0 : return true;
353 : : }
354 : :
355 : 0 : bool SwDDEFieldType::PutValue( const uno::Any& rVal, sal_uInt16 nWhichId )
356 : : {
357 : 0 : sal_uInt8 nPart = 0;
358 [ # # # # : 0 : switch( nWhichId )
# # ]
359 : : {
360 : 0 : case FIELD_PROP_PAR2: nPart = 3; break;
361 : 0 : case FIELD_PROP_PAR4: nPart = 2; break;
362 : 0 : case FIELD_PROP_SUBTYPE: nPart = 1; break;
363 : : case FIELD_PROP_BOOL1:
364 : 0 : SetType( static_cast<sal_uInt16>(*(sal_Bool*)rVal.getValue() ?
365 : : sfx2::LINKUPDATE_ALWAYS :
366 [ # # ]: 0 : sfx2::LINKUPDATE_ONCALL ) );
367 : 0 : break;
368 : : case FIELD_PROP_PAR5:
369 : : {
370 : 0 : ::rtl::OUString sTemp;
371 : 0 : rVal >>= sTemp;
372 [ # # ]: 0 : aExpansion = sTemp;
373 : : }
374 : 0 : break;
375 : : default:
376 : : OSL_FAIL("illegal property");
377 : : }
378 [ # # ]: 0 : if( nPart )
379 : : {
380 [ # # ][ # # ]: 0 : String sTmp, sCmd( GetCmd() );
381 [ # # ][ # # ]: 0 : while(3 > comphelper::string::getTokenCount(sCmd, sfx2::cTokenSeperator))
[ # # ]
382 [ # # ]: 0 : sCmd += sfx2::cTokenSeperator;
383 [ # # ][ # # ]: 0 : sCmd.SetToken( nPart-1, sfx2::cTokenSeperator, ::GetString( rVal, sTmp ) );
384 [ # # ][ # # ]: 0 : SetCmd( sCmd );
[ # # ]
385 : : }
386 : 0 : return true;
387 : : }
388 : :
389 : 0 : SwDDEField::SwDDEField( SwDDEFieldType* pInitType )
390 : 0 : : SwField(pInitType)
391 : : {
392 : 0 : }
393 : :
394 : 0 : SwDDEField::~SwDDEField()
395 : : {
396 [ # # ]: 0 : if( GetTyp()->IsLastDepend() )
397 [ # # ]: 0 : ((SwDDEFieldType*)GetTyp())->Disconnect();
398 [ # # ]: 0 : }
399 : :
400 : 0 : String SwDDEField::Expand() const
401 : : {
402 : : xub_StrLen nPos;
403 [ # # ]: 0 : String aStr(comphelper::string::remove(((SwDDEFieldType*)GetTyp())->GetExpansion(), '\r'));
404 : :
405 [ # # ][ # # ]: 0 : while( (nPos = aStr.Search( '\t' )) != STRING_NOTFOUND )
406 [ # # ]: 0 : aStr.SetChar( nPos, ' ' );
407 [ # # ][ # # ]: 0 : while( (nPos = aStr.Search( '\n' )) != STRING_NOTFOUND )
408 [ # # ]: 0 : aStr.SetChar( nPos, '|' );
409 [ # # ][ # # ]: 0 : if( aStr.Len() && ( aStr.GetChar( aStr.Len()-1 ) == '|') )
[ # # ]
410 [ # # ]: 0 : aStr.Erase( aStr.Len()-1, 1 );
411 : 0 : return aStr;
412 : : }
413 : :
414 : 0 : SwField* SwDDEField::Copy() const
415 : : {
416 [ # # ]: 0 : return new SwDDEField((SwDDEFieldType*)GetTyp());
417 : : }
418 : :
419 : : /*--------------------------------------------------------------------
420 : : Beschreibung: Parameter des Typen erfragen
421 : : Name
422 : : --------------------------------------------------------------------*/
423 : 0 : const rtl::OUString& SwDDEField::GetPar1() const
424 : : {
425 : 0 : return ((const SwDDEFieldType*)GetTyp())->GetName();
426 : : }
427 : :
428 : : /*--------------------------------------------------------------------
429 : : Beschreibung: Parameter des Typen erfragen
430 : : Commando
431 : : --------------------------------------------------------------------*/
432 : 0 : rtl::OUString SwDDEField::GetPar2() const
433 : : {
434 [ # # ]: 0 : return ((const SwDDEFieldType*)GetTyp())->GetCmd();
435 : : }
436 : :
437 : 0 : void SwDDEField::SetPar2(const rtl::OUString& rStr)
438 : : {
439 [ # # ]: 0 : ((SwDDEFieldType*)GetTyp())->SetCmd(rStr);
440 : 0 : }
441 : :
442 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|