Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <stdlib.h>
21 : #include <hintids.hxx>
22 : #include <svl/intitem.hxx>
23 : #include <svl/stritem.hxx>
24 : #include <sfx2/docfile.hxx>
25 : #include <sfx2/docfilt.hxx>
26 : #include <editeng/protitem.hxx>
27 : #include <sfx2/linkmgr.hxx>
28 : #include <tools/urlobj.hxx>
29 : #include <sfx2/sfxsids.hrc>
30 : #include <sfx2/fcontnr.hxx>
31 : #include <docary.hxx>
32 : #include <fmtcntnt.hxx>
33 : #include <fmtpdsc.hxx>
34 : #include <doc.hxx>
35 : #include <IDocumentUndoRedo.hxx>
36 : #include <DocumentLinksAdministrationManager.hxx>
37 : #include <DocumentContentOperationsManager.hxx>
38 : #include <IDocumentRedlineAccess.hxx>
39 : #include <IDocumentFieldsAccess.hxx>
40 : #include <IDocumentStylePoolAccess.hxx>
41 : #include <IDocumentState.hxx>
42 : #include <IDocumentLayoutAccess.hxx>
43 : #include <node.hxx>
44 : #include <pam.hxx>
45 : #include <frmtool.hxx>
46 : #include <editsh.hxx>
47 : #include <hints.hxx>
48 : #include <docsh.hxx>
49 : #include <ndtxt.hxx>
50 : #include <section.hxx>
51 : #include <swserv.hxx>
52 : #include <shellio.hxx>
53 : #include <poolfmt.hxx>
54 : #include <expfld.hxx>
55 : #include <swbaslnk.hxx>
56 : #include <mvsave.hxx>
57 : #include <sectfrm.hxx>
58 : #include <fmtftntx.hxx>
59 : #include <ftnidx.hxx>
60 : #include <doctxm.hxx>
61 : #include <fmteiro.hxx>
62 : #include <swerror.h>
63 : #include <unosection.hxx>
64 : #include <switerator.hxx>
65 : #include <svl/smplhint.hxx>
66 : #include <algorithm>
67 : #include <ndsect.hxx>
68 :
69 : using namespace ::com::sun::star;
70 :
71 4 : class SwIntrnlSectRefLink : public SwBaseLink
72 : {
73 : SwSectionFmt& rSectFmt;
74 : public:
75 2 : SwIntrnlSectRefLink( SwSectionFmt& rFmt, sal_uInt16 nUpdateType, sal_uInt16 nFmt )
76 : : SwBaseLink( nUpdateType, nFmt ),
77 2 : rSectFmt( rFmt )
78 2 : {}
79 :
80 : virtual void Closed() SAL_OVERRIDE;
81 : virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(
82 : const OUString& rMimeType, const ::com::sun::star::uno::Any & rValue ) SAL_OVERRIDE;
83 :
84 : virtual const SwNode* GetAnchor() const SAL_OVERRIDE;
85 : virtual bool IsInRange( sal_uLong nSttNd, sal_uLong nEndNd, sal_Int32 nStt = 0,
86 : sal_Int32 nEnd = -1 ) const SAL_OVERRIDE;
87 :
88 0 : inline SwSectionNode* GetSectNode()
89 : {
90 0 : const SwNode* pSectNd( const_cast<SwIntrnlSectRefLink*>(this)->GetAnchor() );
91 0 : return const_cast<SwSectionNode*>( dynamic_cast<const SwSectionNode*>( pSectNd ) );
92 : }
93 : };
94 :
95 9806 : TYPEINIT1(SwSectionFmt,SwFrmFmt );
96 50778 : TYPEINIT1(SwSection,SwClient );
97 :
98 1148 : SwSectionData::SwSectionData(SectionType const eType, OUString const& rName)
99 : : m_eType(eType)
100 : , m_sSectionName(rName)
101 : , m_bHiddenFlag(false)
102 : , m_bProtectFlag(false)
103 : , m_bEditInReadonlyFlag(false) // edit in readonly sections
104 : , m_bHidden(false)
105 : , m_bCondHiddenFlag(true)
106 1148 : , m_bConnectFlag(true)
107 : {
108 1148 : }
109 :
110 : // this must have the same semantics as operator=()
111 542 : SwSectionData::SwSectionData(SwSection const& rSection)
112 542 : : m_eType(rSection.GetType())
113 : , m_sSectionName(rSection.GetSectionName())
114 : , m_sCondition(rSection.GetCondition())
115 : , m_sLinkFileName(rSection.GetLinkFileName())
116 : , m_sLinkFilePassword(rSection.GetLinkFilePassword())
117 542 : , m_Password(rSection.GetPassword())
118 542 : , m_bHiddenFlag(rSection.IsHiddenFlag())
119 542 : , m_bProtectFlag(rSection.IsProtect())
120 : // edit in readonly sections
121 542 : , m_bEditInReadonlyFlag(rSection.IsEditInReadonly())
122 542 : , m_bHidden(rSection.IsHidden())
123 : , m_bCondHiddenFlag(true)
124 3252 : , m_bConnectFlag(rSection.IsConnectFlag())
125 : {
126 542 : }
127 :
128 : // this must have the same semantics as operator=()
129 72 : SwSectionData::SwSectionData(SwSectionData const& rOther)
130 : : m_eType(rOther.m_eType)
131 : , m_sSectionName(rOther.m_sSectionName)
132 : , m_sCondition(rOther.m_sCondition)
133 : , m_sLinkFileName(rOther.m_sLinkFileName)
134 : , m_sLinkFilePassword(rOther.m_sLinkFilePassword)
135 : , m_Password(rOther.m_Password)
136 : , m_bHiddenFlag(rOther.m_bHiddenFlag)
137 : , m_bProtectFlag(rOther.m_bProtectFlag)
138 : // edit in readonly sections
139 : , m_bEditInReadonlyFlag(rOther.m_bEditInReadonlyFlag)
140 : , m_bHidden(rOther.m_bHidden)
141 : , m_bCondHiddenFlag(true)
142 72 : , m_bConnectFlag(rOther.m_bConnectFlag)
143 : {
144 72 : }
145 :
146 : // the semantics here are weird for reasons of backward compatibility
147 612 : SwSectionData & SwSectionData::operator= (SwSectionData const& rOther)
148 : {
149 612 : m_eType = rOther.m_eType;
150 612 : m_sSectionName = rOther.m_sSectionName;
151 612 : m_sCondition = rOther.m_sCondition;
152 612 : m_sLinkFileName = rOther.m_sLinkFileName;
153 612 : m_sLinkFilePassword = rOther.m_sLinkFilePassword;
154 612 : m_bConnectFlag = rOther.m_bConnectFlag;
155 612 : m_Password = rOther.m_Password;
156 :
157 612 : m_bEditInReadonlyFlag = rOther.m_bEditInReadonlyFlag;
158 612 : m_bProtectFlag = rOther.m_bProtectFlag;
159 :
160 612 : m_bHidden = rOther.m_bHidden;
161 : // FIXME: old code did not assign m_bHiddenFlag ?
162 : // FIXME: why should m_bCondHiddenFlag always default to true?
163 612 : m_bCondHiddenFlag = true;
164 :
165 612 : return *this;
166 : }
167 :
168 : // the semantics here are weird for reasons of backward compatibility
169 390 : bool SwSectionData::operator==(SwSectionData const& rOther) const
170 : {
171 390 : return (m_eType == rOther.m_eType)
172 382 : && (m_sSectionName == rOther.m_sSectionName)
173 368 : && (m_sCondition == rOther.m_sCondition)
174 364 : && (m_bHidden == rOther.m_bHidden)
175 360 : && (m_bProtectFlag == rOther.m_bProtectFlag)
176 356 : && (m_bEditInReadonlyFlag == rOther.m_bEditInReadonlyFlag)
177 352 : && (m_sLinkFileName == rOther.m_sLinkFileName)
178 340 : && (m_sLinkFilePassword == rOther.m_sLinkFilePassword)
179 730 : && (m_Password == rOther.m_Password);
180 : // FIXME: old code ignored m_bCondHiddenFlag m_bHiddenFlag m_bConnectFlag
181 : }
182 :
183 18 : OUString SwSectionData::CollapseWhiteSpaces(const OUString& sName)
184 : {
185 18 : const sal_Int32 nLen = sName.getLength();
186 18 : const sal_Unicode cRef = ' ';
187 18 : OUStringBuffer aBuf(nLen+1);
188 478 : for (sal_Int32 i = 0; i<nLen; )
189 : {
190 442 : const sal_Unicode cCur = sName[i++];
191 442 : aBuf.append(cCur);
192 442 : if (cCur!=cRef)
193 442 : continue;
194 0 : while (i<nLen && sName[i]==cRef)
195 0 : ++i;
196 : }
197 18 : return aBuf.makeStringAndClear();
198 : }
199 :
200 586 : SwSection::SwSection(
201 : SectionType const eType, OUString const& rName, SwSectionFmt & rFormat)
202 : : SwClient(& rFormat)
203 586 : , m_Data(eType, rName)
204 : {
205 586 : SwSection *const pParentSect = GetParent();
206 586 : if( pParentSect )
207 : {
208 66 : if( pParentSect->IsHiddenFlag() )
209 : {
210 8 : SetHidden( true );
211 : }
212 :
213 66 : m_Data.SetProtectFlag( pParentSect->IsProtectFlag() );
214 : // edit in readonly sections
215 66 : m_Data.SetEditInReadonlyFlag( pParentSect->IsEditInReadonlyFlag() );
216 : }
217 :
218 586 : if (!m_Data.IsProtectFlag())
219 : {
220 546 : m_Data.SetProtectFlag( rFormat.GetProtect().IsCntntProtected() );
221 : }
222 :
223 586 : if (!m_Data.IsEditInReadonlyFlag()) // edit in readonly sections
224 : {
225 586 : m_Data.SetEditInReadonlyFlag( rFormat.GetEditInReadonly().GetValue() );
226 : }
227 586 : }
228 :
229 1532 : SwSection::~SwSection()
230 : {
231 586 : SwSectionFmt* pFmt = GetFmt();
232 586 : if( !pFmt )
233 0 : return;
234 :
235 586 : SwDoc* pDoc = pFmt->GetDoc();
236 586 : if( pDoc->IsInDtor() )
237 : {
238 : // We reattach our Format to the default FrameFmt
239 : // to not get any dependencies
240 572 : if( pFmt->DerivedFrom() != pDoc->GetDfltFrmFmt() )
241 78 : pFmt->RegisterToFormat( *pDoc->GetDfltFrmFmt() );
242 : }
243 : else
244 : {
245 14 : pFmt->Remove( this ); // remove
246 :
247 14 : if (CONTENT_SECTION != m_Data.GetType())
248 : {
249 4 : pDoc->getIDocumentLinksAdministration().GetLinkManager().Remove( m_RefLink );
250 : }
251 :
252 14 : if (m_RefObj.Is())
253 : {
254 0 : pDoc->getIDocumentLinksAdministration().GetLinkManager().RemoveServer( &m_RefObj );
255 : }
256 :
257 : // If the Section is the last Client in the Format we can delete it
258 14 : SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, pFmt );
259 14 : pFmt->ModifyNotification( &aMsgHint, &aMsgHint );
260 14 : if( !pFmt->GetDepends() )
261 : {
262 : // Do not add to the Undo. This should've happened earlier.
263 12 : ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
264 12 : pDoc->DelSectionFmt( pFmt );
265 14 : }
266 : }
267 586 : if (m_RefObj.Is())
268 : {
269 0 : m_RefObj->Closed();
270 : }
271 946 : }
272 :
273 612 : void SwSection::SetSectionData(SwSectionData const& rData)
274 : {
275 612 : bool const bOldHidden( m_Data.IsHidden() );
276 612 : m_Data = rData;
277 : // The next two may actually overwrite the m_Data.m_bProtect or EditInReadonly Flag
278 : // in Modify, which should result in same flag value as the old code!
279 612 : SetProtect(m_Data.IsProtectFlag());
280 612 : SetEditInReadonly(m_Data.IsEditInReadonlyFlag());
281 612 : if (bOldHidden != m_Data.IsHidden()) // check if changed...
282 : {
283 18 : ImplSetHiddenFlag(m_Data.IsHidden(), m_Data.IsCondHidden());
284 : }
285 612 : }
286 :
287 390 : bool SwSection::DataEquals(SwSectionData const& rCmp) const
288 : {
289 : // note that the old code compared the flags of the parameter with the
290 : // format attributes of this; the following mess should do the same...
291 390 : (void) GetLinkFileName(); // updates m_sLinkFileName
292 390 : bool const bProtect(m_Data.IsProtectFlag());
293 390 : bool const bEditInReadonly(m_Data.IsEditInReadonlyFlag());
294 390 : m_Data.SetProtectFlag(IsProtect());
295 390 : m_Data.SetEditInReadonlyFlag(IsEditInReadonly());
296 390 : bool const bResult( m_Data == rCmp );
297 390 : m_Data.SetProtectFlag(bProtect);
298 390 : m_Data.SetEditInReadonlyFlag(bEditInReadonly);
299 390 : return bResult;
300 : }
301 :
302 48 : void SwSection::ImplSetHiddenFlag(bool const bTmpHidden, bool const bCondition)
303 : {
304 48 : SwSectionFmt* pFmt = GetFmt();
305 : OSL_ENSURE(pFmt, "ImplSetHiddenFlag: no format?");
306 48 : if( pFmt )
307 : {
308 48 : const bool bHide = bTmpHidden && bCondition;
309 :
310 48 : if (bHide) // should be hidden
311 : {
312 18 : if (!m_Data.IsHiddenFlag()) // is not hidden
313 : {
314 : // Is the Parent hidden?
315 : // This should be shown by the bHiddenFlag.
316 :
317 : // Tell all Children that they are hidden
318 18 : SwMsgPoolItem aMsgItem( RES_SECTION_HIDDEN );
319 18 : pFmt->ModifyNotification( &aMsgItem, &aMsgItem );
320 :
321 : // Delete all Frames
322 18 : pFmt->DelFrms();
323 : }
324 : }
325 30 : else if (m_Data.IsHiddenFlag()) // show Nodes again
326 : {
327 : // Show all Frames (Child Sections are accounted for by MakeFrms)
328 : // Only if the Parent Section is not restricting us!
329 16 : SwSection* pParentSect = pFmt->GetParentSection();
330 16 : if( !pParentSect || !pParentSect->IsHiddenFlag() )
331 : {
332 : // Tell all Children that the Parent is not hidden anymore
333 8 : SwMsgPoolItem aMsgItem( RES_SECTION_NOT_HIDDEN );
334 8 : pFmt->ModifyNotification( &aMsgItem, &aMsgItem );
335 :
336 8 : pFmt->MakeFrms();
337 : }
338 : }
339 : }
340 48 : }
341 :
342 646 : bool SwSection::CalcHiddenFlag() const
343 : {
344 646 : const SwSection* pSect = this;
345 754 : do {
346 754 : if( pSect->IsHidden() && pSect->IsCondHidden() )
347 0 : return true;
348 : } while( 0 != ( pSect = pSect->GetParent()) );
349 :
350 646 : return false;
351 : }
352 :
353 1858 : bool SwSection::IsProtect() const
354 : {
355 1858 : SwSectionFmt *const pFmt( GetFmt() );
356 : OSL_ENSURE(pFmt, "SwSection::IsProtect: no format?");
357 : return (pFmt)
358 1858 : ? pFmt->GetProtect().IsCntntProtected()
359 3716 : : IsProtectFlag();
360 : }
361 :
362 : // edit in readonly sections
363 1066 : bool SwSection::IsEditInReadonly() const
364 : {
365 1066 : SwSectionFmt *const pFmt( GetFmt() );
366 : OSL_ENSURE(pFmt, "SwSection::IsEditInReadonly: no format?");
367 : return (pFmt)
368 1066 : ? pFmt->GetEditInReadonly().GetValue()
369 2132 : : IsEditInReadonlyFlag();
370 : }
371 :
372 8 : void SwSection::SetHidden(bool const bFlag)
373 : {
374 8 : if (!m_Data.IsHidden() == !bFlag)
375 8 : return;
376 :
377 8 : m_Data.SetHidden(bFlag);
378 8 : ImplSetHiddenFlag(bFlag, m_Data.IsCondHidden());
379 : }
380 :
381 886 : void SwSection::SetProtect(bool const bFlag)
382 : {
383 886 : SwSectionFmt *const pFormat( GetFmt() );
384 : OSL_ENSURE(pFormat, "SwSection::SetProtect: no format?");
385 886 : if (pFormat)
386 : {
387 886 : SvxProtectItem aItem( RES_PROTECT );
388 886 : aItem.SetCntntProtect( bFlag );
389 886 : pFormat->SetFmtAttr( aItem );
390 : // note: this will call m_Data.SetProtectFlag via Modify!
391 : }
392 : else
393 : {
394 0 : m_Data.SetProtectFlag(bFlag);
395 : }
396 886 : }
397 :
398 : // edit in readonly sections
399 612 : void SwSection::SetEditInReadonly(bool const bFlag)
400 : {
401 612 : SwSectionFmt *const pFormat( GetFmt() );
402 : OSL_ENSURE(pFormat, "SwSection::SetEditInReadonly: no format?");
403 612 : if (pFormat)
404 : {
405 612 : SwFmtEditInReadonly aItem;
406 612 : aItem.SetValue( bFlag );
407 612 : pFormat->SetFmtAttr( aItem );
408 : // note: this will call m_Data.SetEditInReadonlyFlag via Modify!
409 : }
410 : else
411 : {
412 0 : m_Data.SetEditInReadonlyFlag(bFlag);
413 : }
414 612 : }
415 :
416 2132 : void SwSection::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
417 : {
418 2132 : bool bUpdateFtn = false;
419 2132 : switch( pOld ? pOld->Which() : pNew ? pNew->Which() : 0 )
420 : {
421 : case RES_ATTRSET_CHG:
422 590 : if (pNew && pOld)
423 : {
424 590 : SfxItemSet* pNewSet = ((SwAttrSetChg*)pNew)->GetChgSet();
425 590 : SfxItemSet* pOldSet = ((SwAttrSetChg*)pOld)->GetChgSet();
426 : const SfxPoolItem* pItem;
427 :
428 590 : if( SfxItemState::SET == pNewSet->GetItemState(
429 590 : RES_PROTECT, false, &pItem ) )
430 : {
431 : m_Data.SetProtectFlag( static_cast<SvxProtectItem const*>(pItem)
432 0 : ->IsCntntProtected() );
433 0 : pNewSet->ClearItem( RES_PROTECT );
434 0 : pOldSet->ClearItem( RES_PROTECT );
435 : }
436 :
437 : // --> edit in readonly sections
438 590 : if( SfxItemState::SET == pNewSet->GetItemState(
439 590 : RES_EDIT_IN_READONLY, false, &pItem ) )
440 : {
441 : m_Data.SetEditInReadonlyFlag(
442 0 : static_cast<SwFmtEditInReadonly const*>(pItem)->GetValue());
443 0 : pNewSet->ClearItem( RES_EDIT_IN_READONLY );
444 0 : pOldSet->ClearItem( RES_EDIT_IN_READONLY );
445 : }
446 :
447 590 : if( SfxItemState::SET == pNewSet->GetItemState(
448 1180 : RES_FTN_AT_TXTEND, false, &pItem ) ||
449 : SfxItemState::SET == pNewSet->GetItemState(
450 590 : RES_END_AT_TXTEND, false, &pItem ))
451 : {
452 0 : bUpdateFtn = true;
453 : }
454 :
455 590 : if( !pNewSet->Count() )
456 0 : return;
457 : }
458 590 : break;
459 :
460 : case RES_PROTECT:
461 834 : if( pNew )
462 : {
463 : bool bNewFlag =
464 834 : static_cast<const SvxProtectItem*>(pNew)->IsCntntProtected();
465 834 : if( !bNewFlag )
466 : {
467 : // Switching off: See if there is protection transferred
468 : // by the Parents
469 540 : const SwSection* pSect = this;
470 590 : do {
471 630 : if( pSect->IsProtect() )
472 : {
473 40 : bNewFlag = true;
474 40 : break;
475 : }
476 590 : pSect = pSect->GetParent();
477 : } while (pSect);
478 : }
479 :
480 834 : m_Data.SetProtectFlag( bNewFlag );
481 : }
482 834 : return;
483 : // edit in readonly sections
484 : case RES_EDIT_IN_READONLY:
485 566 : if( pNew )
486 : {
487 : const bool bNewFlag =
488 566 : static_cast<const SwFmtEditInReadonly*>(pNew)->GetValue();
489 566 : m_Data.SetEditInReadonlyFlag( bNewFlag );
490 : }
491 566 : return;
492 :
493 : case RES_SECTION_HIDDEN:
494 18 : m_Data.SetHiddenFlag(true);
495 18 : return;
496 :
497 : case RES_SECTION_NOT_HIDDEN:
498 : case RES_SECTION_RESETHIDDENFLAG:
499 8 : m_Data.SetHiddenFlag( m_Data.IsHidden() && m_Data.IsCondHidden() );
500 8 : return;
501 :
502 : case RES_COL:
503 : // Is handeled by the Layout, if appropriate
504 0 : break;
505 :
506 : case RES_FTN_AT_TXTEND:
507 30 : if( pNew && pOld )
508 : {
509 30 : bUpdateFtn = true;
510 : }
511 30 : break;
512 :
513 : case RES_END_AT_TXTEND:
514 40 : if( pNew && pOld )
515 : {
516 40 : bUpdateFtn = true;
517 : }
518 40 : break;
519 :
520 : default:
521 46 : CheckRegistration( pOld, pNew );
522 46 : break;
523 : }
524 :
525 706 : if( bUpdateFtn )
526 : {
527 70 : SwSectionNode* pSectNd = GetFmt()->GetSectionNode( false );
528 70 : if( pSectNd )
529 70 : pSectNd->GetDoc()->GetFtnIdxs().UpdateFtn(SwNodeIndex( *pSectNd ));
530 : }
531 : }
532 :
533 0 : void SwSection::SetRefObject( SwServerObject* pObj )
534 : {
535 0 : m_RefObj = pObj;
536 0 : }
537 :
538 48 : void SwSection::SetCondHidden(bool const bFlag)
539 : {
540 48 : if (!m_Data.IsCondHidden() == !bFlag)
541 74 : return;
542 :
543 22 : m_Data.SetCondHidden(bFlag);
544 22 : ImplSetHiddenFlag(m_Data.IsHidden(), bFlag);
545 : }
546 :
547 : // Set/remove the linked FileName
548 1028 : OUString SwSection::GetLinkFileName() const
549 : {
550 1028 : if (m_RefLink.Is())
551 : {
552 318 : OUString sTmp;
553 318 : switch (m_Data.GetType())
554 : {
555 : case DDE_LINK_SECTION:
556 200 : sTmp = m_RefLink->GetLinkSourceName();
557 200 : break;
558 :
559 : case FILE_LINK_SECTION:
560 : {
561 118 : OUString sRange;
562 236 : OUString sFilter;
563 236 : if (m_RefLink->GetLinkManager() &&
564 : m_RefLink->GetLinkManager()->GetDisplayNames(
565 118 : m_RefLink, 0, &sTmp, &sRange, &sFilter ))
566 : {
567 236 : sTmp += OUString(sfx2::cTokenSeparator) + sFilter
568 354 : + OUString(sfx2::cTokenSeparator) + sRange;
569 : }
570 0 : else if( GetFmt() && !GetFmt()->GetSectionNode() )
571 : {
572 : // If the Section is in the UndoNodesArray, the LinkManager
573 : // does not contain the Link, thus it cannot be queried for it.
574 : // Thus return the current Name.
575 0 : return m_Data.GetLinkFileName();
576 118 : }
577 : }
578 118 : break;
579 0 : default: break;
580 : }
581 318 : m_Data.SetLinkFileName(sTmp);
582 : }
583 1028 : return m_Data.GetLinkFileName();
584 : }
585 :
586 24 : void SwSection::SetLinkFileName(const OUString& rNew, OUString const*const pPassWd)
587 : {
588 24 : if (m_RefLink.Is())
589 : {
590 0 : m_RefLink->SetLinkSourceName( rNew );
591 : }
592 24 : m_Data.SetLinkFileName(rNew);
593 24 : if( pPassWd )
594 : {
595 0 : SetLinkFilePassword( *pPassWd );
596 : }
597 24 : }
598 :
599 : // If it was a Linked Section, we need to make all Child Links visible
600 0 : void SwSection::MakeChildLinksVisible( const SwSectionNode& rSectNd )
601 : {
602 : const SwNode* pNd;
603 0 : const ::sfx2::SvBaseLinks& rLnks = rSectNd.GetDoc()->getIDocumentLinksAdministration().GetLinkManager().GetLinks();
604 0 : for( sal_uInt16 n = rLnks.size(); n; )
605 : {
606 0 : ::sfx2::SvBaseLink* pBLnk = &(*rLnks[ --n ]);
607 0 : if( pBLnk && !pBLnk->IsVisible() &&
608 0 : pBLnk->ISA( SwBaseLink ) &&
609 0 : 0 != ( pNd = ((SwBaseLink*)pBLnk)->GetAnchor() ) )
610 : {
611 0 : pNd = pNd->StartOfSectionNode(); // If it's a SectionNode
612 : const SwSectionNode* pParent;
613 0 : while( 0 != ( pParent = pNd->FindSectionNode() ) &&
614 0 : ( CONTENT_SECTION == pParent->GetSection().GetType()
615 0 : || pNd == &rSectNd ))
616 0 : pNd = pParent->StartOfSectionNode();
617 :
618 : // It's within a normal Section, so show again
619 0 : if( !pParent )
620 0 : pBLnk->SetVisible( true );
621 : }
622 : }
623 0 : }
624 :
625 116 : const SwTOXBase* SwSection::GetTOXBase() const
626 : {
627 116 : const SwTOXBase* pRet = 0;
628 116 : if( TOX_CONTENT_SECTION == GetType() )
629 116 : pRet = dynamic_cast<const SwTOXBaseSection*>(this);
630 116 : return pRet;
631 : }
632 :
633 586 : SwSectionFmt::SwSectionFmt( SwFrmFmt* pDrvdFrm, SwDoc *pDoc )
634 586 : : SwFrmFmt( pDoc->GetAttrPool(), OUString(), pDrvdFrm )
635 : {
636 586 : LockModify();
637 586 : SetFmtAttr( *GetDfltAttr( RES_COL ) );
638 586 : UnlockModify();
639 586 : }
640 :
641 1758 : SwSectionFmt::~SwSectionFmt()
642 : {
643 586 : if( !GetDoc()->IsInDtor() )
644 : {
645 : SwSectionNode* pSectNd;
646 14 : const SwNodeIndex* pIdx = GetCntnt( false ).GetCntntIdx();
647 22 : if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() &&
648 8 : 0 != (pSectNd = pIdx->GetNode().GetSectionNode() ))
649 : {
650 8 : SwSection& rSect = pSectNd->GetSection();
651 : // If it was a linked Section, we need to make all Child Links
652 : // visible again
653 8 : if( rSect.IsConnected() )
654 0 : rSect.MakeChildLinksVisible( *pSectNd );
655 :
656 : // Check whether we need to be visible, before deleting the Nodes
657 8 : if( rSect.IsHiddenFlag() )
658 : {
659 0 : SwSection* pParentSect = rSect.GetParent();
660 0 : if( !pParentSect || !pParentSect->IsHiddenFlag() )
661 : {
662 : // Make Nodes visible again
663 0 : rSect.SetHidden(false);
664 : }
665 : }
666 : // mba: test iteration; objects are removed while iterating
667 : // use hint which allows to specify, if the content shall be saved or not
668 8 : CallSwClientNotify( SwSectionFrmMoveAndDeleteHint( true ) );
669 :
670 : // Raise the Section up
671 8 : SwNodeRange aRg( *pSectNd, 0, *pSectNd->EndOfSectionNode() );
672 8 : GetDoc()->GetNodes().SectionUp( &aRg );
673 : }
674 14 : LockModify();
675 14 : ResetFmtAttr( RES_CNTNT );
676 14 : UnlockModify();
677 : }
678 1172 : }
679 :
680 6318 : SwSection * SwSectionFmt::GetSection() const
681 : {
682 6318 : return SwIterator<SwSection,SwSectionFmt>::FirstElement( *this );
683 : }
684 :
685 : // Do not destroy all Frms in aDepend (Frms are recognized with a PTR_CAST).
686 82 : void SwSectionFmt::DelFrms()
687 : {
688 : SwSectionNode* pSectNd;
689 82 : const SwNodeIndex* pIdx = GetCntnt(false).GetCntntIdx();
690 156 : if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() &&
691 74 : 0 != (pSectNd = pIdx->GetNode().GetSectionNode() ))
692 : {
693 : // First delete the <SwSectionFrm> of the <SwSectionFmt> instance
694 : // mba: test iteration as objects are removed in iteration
695 : // use hint which allows to specify, if the content shall be saved or not
696 74 : CallSwClientNotify( SwSectionFrmMoveAndDeleteHint( false ) );
697 :
698 : // Then delete frames of the nested <SwSectionFmt> instances
699 74 : SwIterator<SwSectionFmt,SwSectionFmt> aIter( *this );
700 74 : SwSectionFmt *pLast = aIter.First();
701 156 : while ( pLast )
702 : {
703 8 : pLast->DelFrms();
704 8 : pLast = aIter.Next();
705 : }
706 :
707 74 : sal_uLong nEnde = pSectNd->EndOfSectionIndex();
708 74 : sal_uLong nStart = pSectNd->GetIndex()+1;
709 74 : sw_DeleteFtn( pSectNd, nStart, nEnde );
710 : }
711 82 : if( pIdx )
712 : {
713 : // Send Hint for PageDesc. Actually the Layout contained in the
714 : // Paste of the Framei tself would need to do this. But that leads
715 : // to subsequent errors, which we'd need to solve at run-time.
716 74 : SwNodeIndex aNextNd( *pIdx );
717 74 : SwCntntNode* pCNd = GetDoc()->GetNodes().GoNextSection( &aNextNd, true, false );
718 74 : if( pCNd )
719 : {
720 72 : const SfxPoolItem& rItem = pCNd->GetSwAttrSet().Get( RES_PAGEDESC );
721 72 : pCNd->ModifyNotification( (SfxPoolItem*)&rItem, (SfxPoolItem*)&rItem );
722 74 : }
723 : }
724 82 : }
725 :
726 : // Create the Views
727 8 : void SwSectionFmt::MakeFrms()
728 : {
729 : SwSectionNode* pSectNd;
730 8 : const SwNodeIndex* pIdx = GetCntnt(false).GetCntntIdx();
731 :
732 16 : if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() &&
733 8 : 0 != (pSectNd = pIdx->GetNode().GetSectionNode() ))
734 : {
735 8 : SwNodeIndex aIdx( *pIdx );
736 8 : pSectNd->MakeFrms( &aIdx );
737 : }
738 8 : }
739 :
740 2346 : void SwSectionFmt::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
741 : {
742 2346 : bool bClients = false;
743 2346 : sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
744 2346 : switch( nWhich )
745 : {
746 : case RES_ATTRSET_CHG:
747 2166 : if (GetDepends() && pOld && pNew)
748 : {
749 2040 : SfxItemSet* pNewSet = ((SwAttrSetChg*)pNew)->GetChgSet();
750 2040 : SfxItemSet* pOldSet = ((SwAttrSetChg*)pOld)->GetChgSet();
751 : const SfxPoolItem *pItem;
752 2040 : if( SfxItemState::SET == pNewSet->GetItemState(
753 2040 : RES_PROTECT, false, &pItem ))
754 : {
755 832 : ModifyBroadcast( (SfxPoolItem*)pItem, (SfxPoolItem*)pItem );
756 832 : pNewSet->ClearItem( RES_PROTECT );
757 832 : pOldSet->ClearItem( RES_PROTECT );
758 : }
759 :
760 : // --> edit in readonly sections
761 2040 : if( SfxItemState::SET == pNewSet->GetItemState(
762 2040 : RES_EDIT_IN_READONLY, false, &pItem ) )
763 : {
764 566 : ModifyBroadcast( (SfxPoolItem*)pItem, (SfxPoolItem*)pItem );
765 566 : pNewSet->ClearItem( RES_EDIT_IN_READONLY );
766 566 : pOldSet->ClearItem( RES_EDIT_IN_READONLY );
767 : }
768 :
769 2040 : if( SfxItemState::SET == pNewSet->GetItemState(
770 2040 : RES_FTN_AT_TXTEND, false, &pItem ))
771 : {
772 24 : ModifyBroadcast( (SfxPoolItem*)&pOldSet->Get( RES_FTN_AT_TXTEND ), (SfxPoolItem*)pItem );
773 24 : pNewSet->ClearItem( RES_FTN_AT_TXTEND );
774 24 : pOldSet->ClearItem( RES_FTN_AT_TXTEND );
775 : }
776 2040 : if( SfxItemState::SET == pNewSet->GetItemState(
777 2040 : RES_END_AT_TXTEND, false, &pItem ))
778 : {
779 26 : ModifyBroadcast( (SfxPoolItem*)&pOldSet->Get( RES_END_AT_TXTEND ), (SfxPoolItem*)pItem );
780 26 : pNewSet->ClearItem( RES_END_AT_TXTEND );
781 26 : pOldSet->ClearItem( RES_END_AT_TXTEND );
782 : }
783 2040 : if( !((SwAttrSetChg*)pOld)->GetChgSet()->Count() )
784 1448 : return;
785 : }
786 718 : break;
787 :
788 : case RES_SECTION_RESETHIDDENFLAG:
789 : case RES_FTN_AT_TXTEND:
790 20 : case RES_END_AT_TXTEND : bClients = true;
791 : // no break !!
792 : case RES_SECTION_HIDDEN:
793 : case RES_SECTION_NOT_HIDDEN:
794 : {
795 46 : SwSection* pSect = GetSection();
796 72 : if( pSect && ( bClients || ( RES_SECTION_HIDDEN == nWhich ?
797 26 : !pSect->IsHiddenFlag() : pSect->IsHiddenFlag() ) ) )
798 : {
799 46 : ModifyBroadcast( pOld, pNew );
800 : }
801 : }
802 46 : return ;
803 :
804 : case RES_PROTECT:
805 : case RES_EDIT_IN_READONLY: // edit in readonly sections
806 : // Pass through these Messages until the End of the tree!
807 2 : if( GetDepends() )
808 : {
809 2 : ModifyBroadcast( pOld, pNew );
810 : }
811 2 : return; // That's it!
812 :
813 : case RES_OBJECTDYING:
814 0 : if( !GetDoc()->IsInDtor() && pOld &&
815 0 : ((SwPtrMsgPoolItem *)pOld)->pObject == (void*)GetRegisteredIn() )
816 : {
817 : // My Parents will be destroyed, so get the Parent's Parent
818 : // and update
819 0 : SwFrmFmt::Modify( pOld, pNew ); // Rewire first!
820 0 : UpdateParent();
821 0 : return;
822 : }
823 0 : break;
824 :
825 : case RES_FMT_CHG:
826 264 : if( !GetDoc()->IsInDtor() &&
827 90 : ((SwFmtChg*)pNew)->pChangedFmt == (void*)GetRegisteredIn() &&
828 2 : ((SwFmtChg*)pNew)->pChangedFmt->IsA( TYPE( SwSectionFmt )) )
829 : {
830 : // My Parent will be changed, thus I need to update
831 0 : SwFrmFmt::Modify( pOld, pNew ); // Rewire first!
832 0 : UpdateParent();
833 0 : return;
834 : }
835 88 : break;
836 : }
837 850 : SwFrmFmt::Modify( pOld, pNew );
838 :
839 850 : if (pOld && (RES_REMOVE_UNO_OBJECT == pOld->Which()))
840 : { // invalidate cached uno object
841 44 : SetXTextSection(uno::Reference<text::XTextSection>(0));
842 : }
843 : }
844 :
845 : // Get info from the Format
846 24 : bool SwSectionFmt::GetInfo( SfxPoolItem& rInfo ) const
847 : {
848 24 : switch( rInfo.Which() )
849 : {
850 : case RES_FINDNEARESTNODE:
851 0 : if( ((SwFmtPageDesc&)GetFmtAttr( RES_PAGEDESC )).GetPageDesc() )
852 : {
853 0 : const SwSectionNode* pNd = GetSectionNode();
854 0 : if( pNd )
855 0 : ((SwFindNearestNode&)rInfo).CheckNode( *pNd );
856 : }
857 0 : return true;
858 :
859 : case RES_CONTENT_VISIBLE:
860 : {
861 0 : SwFrm* pFrm = SwIterator<SwFrm,SwFmt>::FirstElement(*this);
862 : // if the current section has no own frame search for the children
863 0 : if(!pFrm)
864 : {
865 0 : SwIterator<SwSectionFmt,SwSectionFmt> aFormatIter(*this);
866 0 : SwSectionFmt* pChild = aFormatIter.First();
867 0 : while(pChild && !pFrm)
868 : {
869 0 : pFrm = SwIterator<SwFrm,SwFmt>::FirstElement(*pChild);
870 0 : pChild = aFormatIter.Next();
871 0 : }
872 : }
873 0 : ((SwPtrMsgPoolItem&)rInfo).pObject = pFrm;
874 : }
875 0 : return false;
876 : }
877 24 : return SwModify::GetInfo( rInfo );
878 : }
879 :
880 0 : static bool lcl_SectionCmpPos( const SwSection *pFirst, const SwSection *pSecond)
881 : {
882 0 : const SwSectionFmt* pFSectFmt = pFirst->GetFmt();
883 0 : const SwSectionFmt* pSSectFmt = pSecond->GetFmt();
884 : OSL_ENSURE( pFSectFmt && pSSectFmt &&
885 : pFSectFmt->GetCntnt(false).GetCntntIdx() &&
886 : pSSectFmt->GetCntnt(false).GetCntntIdx(),
887 : "ungueltige Sections" );
888 0 : return pFSectFmt->GetCntnt(false).GetCntntIdx()->GetIndex() <
889 0 : pSSectFmt->GetCntnt(false).GetCntntIdx()->GetIndex();
890 : }
891 :
892 0 : static bool lcl_SectionCmpNm( const SwSection *pFSect, const SwSection *pSSect)
893 : {
894 : OSL_ENSURE( pFSect && pSSect, "Invalid Sections" );
895 0 : return pFSect->GetSectionName() < pSSect->GetSectionName();
896 : }
897 :
898 : // get all Sections that have been derived from this one
899 104 : sal_uInt16 SwSectionFmt::GetChildSections( SwSections& rArr,
900 : SectionSort eSort,
901 : bool bAllSections ) const
902 : {
903 104 : rArr.clear();
904 :
905 104 : if( GetDepends() )
906 : {
907 104 : SwIterator<SwSectionFmt,SwSectionFmt> aIter(*this);
908 : const SwNodeIndex* pIdx;
909 170 : for( SwSectionFmt* pLast = aIter.First(); pLast; pLast = aIter.Next() )
910 198 : if( bAllSections ||
911 66 : ( 0 != ( pIdx = pLast->GetCntnt(false).
912 66 : GetCntntIdx()) && &pIdx->GetNodes() == &GetDoc()->GetNodes() ))
913 : {
914 66 : SwSection* pDummy = pLast->GetSection();
915 66 : rArr.push_back( pDummy );
916 : }
917 :
918 : // Do we need any sorting?
919 104 : if( 1 < rArr.size() )
920 0 : switch( eSort )
921 : {
922 : case SORTSECT_NAME:
923 0 : std::sort( rArr.begin(), rArr.end(), lcl_SectionCmpNm );
924 0 : break;
925 :
926 : case SORTSECT_POS:
927 0 : std::sort( rArr.begin(), rArr.end(), lcl_SectionCmpPos );
928 0 : break;
929 0 : case SORTSECT_NOT: break;
930 104 : }
931 : }
932 104 : return rArr.size();
933 : }
934 :
935 : // See whether the Section is within the Nodes or the UndoNodes array
936 1151 : bool SwSectionFmt::IsInNodesArr() const
937 : {
938 1151 : const SwNodeIndex* pIdx = GetCntnt(false).GetCntntIdx();
939 1151 : return pIdx && &pIdx->GetNodes() == &GetDoc()->GetNodes();
940 : }
941 :
942 : // Parent was changed
943 0 : void SwSectionFmt::UpdateParent()
944 : {
945 0 : if( !GetDepends() )
946 0 : return;
947 :
948 0 : SwSection* pSection = 0;
949 0 : const SvxProtectItem* pProtect(0);
950 : // edit in readonly sections
951 0 : const SwFmtEditInReadonly* pEditInReadonly = 0;
952 0 : bool bIsHidden = false;
953 :
954 0 : SwClientIter aIter( *this ); // TODO
955 0 : ::SwClient * pLast = aIter.GoStart();
956 0 : if( pLast ) // Could we jump to the beginning?
957 0 : do {
958 0 : if( pLast->IsA( TYPE(SwSectionFmt) ) )
959 : {
960 0 : if( !pSection )
961 : {
962 0 : pSection = GetSection();
963 0 : if( GetRegisteredIn() )
964 : {
965 0 : const SwSection* pPS = GetParentSection();
966 0 : pProtect = &pPS->GetFmt()->GetProtect();
967 : // edit in readonly sections
968 0 : pEditInReadonly = &pPS->GetFmt()->GetEditInReadonly();
969 0 : bIsHidden = pPS->IsHiddenFlag();
970 : }
971 : else
972 : {
973 0 : pProtect = &GetProtect();
974 : // edit in readonly sections
975 0 : pEditInReadonly = &GetEditInReadonly();
976 0 : bIsHidden = pSection->IsHidden();
977 : }
978 : }
979 0 : if (!pProtect->IsCntntProtected() !=
980 0 : !pSection->IsProtectFlag())
981 : {
982 : pLast->ModifyNotification( (SfxPoolItem*)pProtect,
983 0 : (SfxPoolItem*)pProtect );
984 : }
985 :
986 : // edit in readonly sections
987 0 : if (!pEditInReadonly->GetValue() !=
988 0 : !pSection->IsEditInReadonlyFlag())
989 : {
990 : pLast->ModifyNotification( (SfxPoolItem*)pEditInReadonly,
991 0 : (SfxPoolItem*)pEditInReadonly );
992 : }
993 :
994 0 : if( bIsHidden == pSection->IsHiddenFlag() )
995 : {
996 : SwMsgPoolItem aMsgItem( static_cast<sal_uInt16>(bIsHidden
997 : ? RES_SECTION_HIDDEN
998 0 : : RES_SECTION_NOT_HIDDEN ) );
999 0 : pLast->ModifyNotification( &aMsgItem, &aMsgItem );
1000 : }
1001 : }
1002 0 : else if( !pSection &&
1003 0 : pLast->IsA( TYPE(SwSection) ) )
1004 : {
1005 0 : pSection = (SwSection*)pLast;
1006 0 : if( GetRegisteredIn() )
1007 : {
1008 0 : const SwSection* pPS = GetParentSection();
1009 0 : pProtect = &pPS->GetFmt()->GetProtect();
1010 : // edit in readonly sections
1011 0 : pEditInReadonly = &pPS->GetFmt()->GetEditInReadonly();
1012 0 : bIsHidden = pPS->IsHiddenFlag();
1013 : }
1014 : else
1015 : {
1016 0 : pProtect = &GetProtect();
1017 : // edit in readonly sections
1018 0 : pEditInReadonly = &GetEditInReadonly();
1019 0 : bIsHidden = pSection->IsHidden();
1020 : }
1021 : }
1022 0 : } while( 0 != ( pLast = ++aIter ));
1023 : }
1024 :
1025 2640 : SwSectionNode* SwSectionFmt::GetSectionNode(bool const bAlways)
1026 : {
1027 2640 : const SwNodeIndex* pIdx = GetCntnt(false).GetCntntIdx();
1028 2640 : if( pIdx && ( bAlways || &pIdx->GetNodes() == &GetDoc()->GetNodes() ))
1029 2640 : return pIdx->GetNode().GetSectionNode();
1030 0 : return 0;
1031 : }
1032 :
1033 : // Is this Section valid for the GlobalDocument?
1034 0 : const SwSection* SwSectionFmt::GetGlobalDocSection() const
1035 : {
1036 0 : const SwSectionNode* pNd = GetSectionNode();
1037 0 : if( pNd &&
1038 0 : ( FILE_LINK_SECTION == pNd->GetSection().GetType() ||
1039 0 : TOX_CONTENT_SECTION == pNd->GetSection().GetType() ) &&
1040 0 : pNd->GetIndex() > pNd->GetNodes().GetEndOfExtras().GetIndex() &&
1041 0 : !pNd->StartOfSectionNode()->IsSectionNode() &&
1042 0 : !pNd->StartOfSectionNode()->FindSectionNode() )
1043 0 : return &pNd->GetSection();
1044 0 : return 0;
1045 : }
1046 :
1047 : // sw::Metadatable
1048 64 : ::sfx2::IXmlIdRegistry& SwSectionFmt::GetRegistry()
1049 : {
1050 64 : return GetDoc()->GetXmlIdRegistry();
1051 : }
1052 :
1053 130 : bool SwSectionFmt::IsInClipboard() const
1054 : {
1055 130 : return GetDoc()->IsClipBoard();
1056 : }
1057 :
1058 130 : bool SwSectionFmt::IsInUndo() const
1059 : {
1060 130 : return !IsInNodesArr();
1061 : }
1062 :
1063 64 : bool SwSectionFmt::IsInContent() const
1064 : {
1065 64 : SwNodeIndex const*const pIdx = GetCntnt(false).GetCntntIdx();
1066 : OSL_ENSURE(pIdx, "SwSectionFmt::IsInContent: no index?");
1067 64 : return (pIdx) ? !GetDoc()->IsInHeaderFooter(*pIdx) : true;
1068 : }
1069 :
1070 : // n.b.: if the section format represents an index, then there is both a
1071 : // SwXDocumentIndex and a SwXTextSection instance for this single core object.
1072 : // these two can both implement XMetadatable and forward to the same core
1073 : // section format. but here only one UNO object can be returned,
1074 : // so always return the text section.
1075 : uno::Reference< rdf::XMetadatable >
1076 0 : SwSectionFmt::MakeUnoObject()
1077 : {
1078 0 : uno::Reference<rdf::XMetadatable> xMeta;
1079 0 : SwSection *const pSection( GetSection() );
1080 0 : if (pSection)
1081 : {
1082 : xMeta.set( SwXTextSection::CreateXTextSection(this,
1083 0 : TOX_HEADER_SECTION == pSection->GetType()),
1084 0 : uno::UNO_QUERY );
1085 : }
1086 0 : return xMeta;
1087 : }
1088 :
1089 : // Method to break section links inside a linked section
1090 14 : static void lcl_BreakSectionLinksInSect( const SwSectionNode& rSectNd )
1091 : {
1092 14 : if ( !rSectNd.GetDoc() )
1093 : {
1094 : OSL_FAIL( "method <lcl_RemoveSectionLinksInSect(..)> - no Doc at SectionNode" );
1095 0 : return;
1096 : }
1097 :
1098 14 : if ( !rSectNd.GetSection().IsConnected() )
1099 : {
1100 : OSL_FAIL( "method <lcl_RemoveSectionLinksInSect(..)> - no Link at Section of SectionNode" );
1101 0 : return;
1102 : }
1103 14 : const ::sfx2::SvBaseLink* pOwnLink( &(rSectNd.GetSection().GetBaseLink() ) );
1104 14 : const ::sfx2::SvBaseLinks& rLnks = rSectNd.GetDoc()->getIDocumentLinksAdministration().GetLinkManager().GetLinks();
1105 42 : for ( sal_uInt16 n = rLnks.size(); n > 0; )
1106 : {
1107 14 : SwIntrnlSectRefLink* pSectLnk = dynamic_cast<SwIntrnlSectRefLink*>(&(*rLnks[ --n ]));
1108 14 : if ( pSectLnk && pSectLnk != pOwnLink &&
1109 0 : pSectLnk->IsInRange( rSectNd.GetIndex(), rSectNd.EndOfSectionIndex() ) )
1110 : {
1111 : // break the link of the corresponding section.
1112 : // the link is also removed from the link manager
1113 0 : pSectLnk->GetSectNode()->GetSection().BreakLink();
1114 :
1115 : // for robustness, because link is removed from the link manager
1116 0 : if ( n > rLnks.size() )
1117 : {
1118 0 : n = rLnks.size();
1119 : }
1120 : }
1121 : }
1122 : }
1123 :
1124 14 : static void lcl_UpdateLinksInSect( SwBaseLink& rUpdLnk, SwSectionNode& rSectNd )
1125 : {
1126 14 : SwDoc* pDoc = rSectNd.GetDoc();
1127 14 : SwDocShell* pDShell = pDoc->GetDocShell();
1128 14 : if( !pDShell || !pDShell->GetMedium() )
1129 14 : return ;
1130 :
1131 14 : const OUString sName( pDShell->GetMedium()->GetName() );
1132 : SwBaseLink* pBLink;
1133 28 : const OUString sMimeType( SotExchange::GetFormatMimeType( FORMAT_FILE ));
1134 28 : uno::Any aValue;
1135 14 : aValue <<= sName; // Arbitrary name
1136 :
1137 14 : const ::sfx2::SvBaseLinks& rLnks = pDoc->getIDocumentLinksAdministration().GetLinkManager().GetLinks();
1138 42 : for( sal_uInt16 n = rLnks.size(); n; )
1139 : {
1140 14 : ::sfx2::SvBaseLink* pLnk = &(*rLnks[ --n ]);
1141 28 : if( pLnk && pLnk != &rUpdLnk &&
1142 0 : OBJECT_CLIENT_FILE == pLnk->GetObjType() &&
1143 14 : pLnk->ISA( SwBaseLink ) &&
1144 : ( pBLink = (SwBaseLink*)pLnk )->IsInRange( rSectNd.GetIndex(),
1145 0 : rSectNd.EndOfSectionIndex() ) )
1146 : {
1147 : // It's in the Section, so update. But only if it's not in the same File!
1148 0 : OUString sFName;
1149 0 : pDoc->getIDocumentLinksAdministration().GetLinkManager().GetDisplayNames( pBLink, 0, &sFName, 0, 0 );
1150 0 : if( sFName != sName )
1151 : {
1152 0 : pBLink->DataChanged( sMimeType, aValue );
1153 :
1154 : // If needed find the Link pointer to avoid skipping one or calling one twice
1155 0 : if( n >= rLnks.size() && 0 != ( n = rLnks.size() ))
1156 0 : --n;
1157 :
1158 0 : if( n && pLnk != &(*rLnks[ n ]) )
1159 : {
1160 : // Find - it can only precede it!
1161 0 : while( n )
1162 0 : if( pLnk == &(*rLnks[ --n ] ) )
1163 0 : break;
1164 : }
1165 0 : }
1166 : }
1167 14 : }
1168 : }
1169 :
1170 20 : ::sfx2::SvBaseLink::UpdateResult SwIntrnlSectRefLink::DataChanged(
1171 : const OUString& rMimeType, const uno::Any & rValue )
1172 : {
1173 20 : SwSectionNode* pSectNd = rSectFmt.GetSectionNode( false );
1174 20 : SwDoc* pDoc = rSectFmt.GetDoc();
1175 :
1176 20 : sal_uLong nDataFormat = SotExchange::GetFormatIdFromMimeType( rMimeType );
1177 :
1178 40 : if( !pSectNd || !pDoc || pDoc->IsInDtor() || ChkNoDataFlag() ||
1179 20 : sfx2::LinkManager::RegisterStatusInfoId() == nDataFormat )
1180 : {
1181 : // Should we be in the Undo already?
1182 2 : return SUCCESS;
1183 : }
1184 :
1185 : // #i38810# - Due to possible existing signatures, the
1186 : // document has to be modified after updating a link.
1187 18 : pDoc->getIDocumentState().SetModified();
1188 : // set additional flag that links have been updated, in order to check this
1189 : // during load.
1190 18 : pDoc->getIDocumentLinksAdministration().SetLinksUpdated( true );
1191 :
1192 : // Always switch off Undo
1193 18 : bool const bWasUndo = pDoc->GetIDocumentUndoRedo().DoesUndo();
1194 18 : pDoc->GetIDocumentUndoRedo().DoUndo(false);
1195 18 : bool bWasVisibleLinks = pDoc->getIDocumentLinksAdministration().IsVisibleLinks();
1196 18 : pDoc->getIDocumentLinksAdministration().SetVisibleLinks( false );
1197 :
1198 : SwPaM* pPam;
1199 18 : SwViewShell* pVSh = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
1200 18 : SwEditShell* pESh = pDoc->GetEditShell();
1201 18 : pDoc->getIDocumentFieldsAccess().LockExpFlds();
1202 : {
1203 : // Insert an empty TextNode at the Section's start
1204 18 : SwNodeIndex aIdx( *pSectNd, +1 );
1205 36 : SwNodeIndex aEndIdx( *pSectNd->EndOfSectionNode() );
1206 18 : SwTxtNode* pNewNd = pDoc->GetNodes().MakeTxtNode( aIdx,
1207 36 : pDoc->getIDocumentStylePoolAccess().GetTxtCollFromPool( RES_POOLCOLL_TEXT ) );
1208 :
1209 18 : if( pESh )
1210 18 : pESh->StartAllAction();
1211 0 : else if( pVSh )
1212 0 : pVSh->StartAction();
1213 :
1214 36 : SwPosition aPos( aIdx, SwIndex( pNewNd, 0 ));
1215 18 : aPos.nNode--;
1216 18 : pDoc->CorrAbs( aIdx, aEndIdx, aPos, true );
1217 :
1218 18 : pPam = new SwPaM( aPos );
1219 :
1220 : // Delete everything succeeding it
1221 18 : aIdx--;
1222 18 : DelFlyInRange( aIdx, aEndIdx );
1223 18 : _DelBookmarks(aIdx, aEndIdx);
1224 18 : ++aIdx;
1225 :
1226 36 : pDoc->GetNodes().Delete( aIdx, aEndIdx.GetIndex() - aIdx.GetIndex() );
1227 : }
1228 :
1229 18 : SwSection& rSection = pSectNd->GetSection();
1230 18 : rSection.SetConnectFlag(false);
1231 :
1232 18 : Reader* pRead = 0;
1233 18 : switch( nDataFormat )
1234 : {
1235 : case FORMAT_STRING:
1236 0 : pRead = ReadAscii;
1237 0 : break;
1238 :
1239 : case FORMAT_RTF:
1240 0 : pRead = SwReaderWriter::GetReader( READER_WRITER_RTF );
1241 0 : break;
1242 :
1243 : case FORMAT_FILE:
1244 18 : if ( rValue.hasValue() )
1245 : {
1246 18 : OUString sFileName;
1247 18 : if ( !(rValue >>= sFileName) )
1248 0 : break;
1249 36 : OUString sFilter;
1250 36 : OUString sRange;
1251 18 : pDoc->getIDocumentLinksAdministration().GetLinkManager().GetDisplayNames( this, 0, &sFileName,
1252 36 : &sRange, &sFilter );
1253 :
1254 18 : RedlineMode_t eOldRedlineMode = nsRedlineMode_t::REDLINE_NONE;
1255 36 : SfxObjectShellRef xDocSh;
1256 36 : SfxObjectShellLock xLockRef;
1257 : int nRet;
1258 18 : if( sFileName.isEmpty() )
1259 : {
1260 10 : xDocSh = pDoc->GetDocShell();
1261 10 : nRet = 1;
1262 : }
1263 : else
1264 : {
1265 : nRet = SwFindDocShell( xDocSh, xLockRef, sFileName,
1266 : rSection.GetLinkFilePassword(),
1267 8 : sFilter, 0, pDoc->GetDocShell() );
1268 8 : if( nRet )
1269 : {
1270 4 : SwDoc* pSrcDoc = ((SwDocShell*)&xDocSh)->GetDoc();
1271 4 : eOldRedlineMode = pSrcDoc->getIDocumentRedlineAccess().GetRedlineMode();
1272 4 : pSrcDoc->getIDocumentRedlineAccess().SetRedlineMode( nsRedlineMode_t::REDLINE_SHOW_INSERT );
1273 : }
1274 : }
1275 :
1276 18 : if( nRet )
1277 : {
1278 14 : rSection.SetConnectFlag(true);
1279 :
1280 14 : SwNodeIndex aSave( pPam->GetPoint()->nNode, -1 );
1281 14 : SwNodeRange* pCpyRg = 0;
1282 :
1283 56 : if( xDocSh->GetMedium() &&
1284 56 : rSection.GetLinkFilePassword().isEmpty() )
1285 : {
1286 : const SfxPoolItem* pItem;
1287 14 : if( SfxItemState::SET == xDocSh->GetMedium()->GetItemSet()->
1288 14 : GetItemState( SID_PASSWORD, false, &pItem ) )
1289 : rSection.SetLinkFilePassword(
1290 0 : ((SfxStringItem*)pItem)->GetValue() );
1291 : }
1292 :
1293 14 : SwDoc* pSrcDoc = ((SwDocShell*)&xDocSh)->GetDoc();
1294 :
1295 14 : if( !sRange.isEmpty() )
1296 : {
1297 : // Catch recursion
1298 10 : bool bRecursion = false;
1299 10 : if( pSrcDoc == pDoc )
1300 : {
1301 : tools::SvRef<SwServerObject> refObj( (SwServerObject*)
1302 10 : pDoc->getIDocumentLinksAdministration().CreateLinkSource( sRange ));
1303 10 : if( refObj.Is() )
1304 : {
1305 0 : bRecursion = refObj->IsLinkInServer( this ) ||
1306 0 : ChkNoDataFlag();
1307 10 : }
1308 : }
1309 :
1310 10 : SwNodeIndex& rInsPos = pPam->GetPoint()->nNode;
1311 :
1312 10 : SwPaM* pCpyPam = 0;
1313 30 : if( !bRecursion &&
1314 10 : pSrcDoc->GetDocumentLinksAdministrationManager().SelectServerObj( sRange, pCpyPam, pCpyRg )
1315 10 : && pCpyPam )
1316 : {
1317 0 : if( pSrcDoc != pDoc ||
1318 0 : pCpyPam->Start()->nNode > rInsPos ||
1319 0 : rInsPos >= pCpyPam->End()->nNode )
1320 : {
1321 0 : pSrcDoc->getIDocumentContentOperations().CopyRange( *pCpyPam, *pPam->GetPoint(),
1322 0 : false );
1323 : }
1324 0 : delete pCpyPam;
1325 : }
1326 10 : if( pCpyRg && pSrcDoc == pDoc &&
1327 10 : pCpyRg->aStart < rInsPos && rInsPos < pCpyRg->aEnd )
1328 0 : delete pCpyRg, pCpyRg = 0;
1329 : }
1330 4 : else if( pSrcDoc != pDoc )
1331 0 : pCpyRg = new SwNodeRange( pSrcDoc->GetNodes().GetEndOfExtras(), 2,
1332 0 : pSrcDoc->GetNodes().GetEndOfContent() );
1333 :
1334 : // #i81653#
1335 : // Update links of extern linked document or extern linked
1336 : // document section, if section is protected.
1337 14 : if ( pSrcDoc != pDoc &&
1338 0 : rSection.IsProtectFlag() )
1339 : {
1340 0 : pSrcDoc->getIDocumentLinksAdministration().GetLinkManager().UpdateAllLinks( false, true, false, 0 );
1341 : }
1342 :
1343 14 : if( pCpyRg )
1344 : {
1345 0 : SwNodeIndex& rInsPos = pPam->GetPoint()->nNode;
1346 0 : bool bCreateFrm = rInsPos.GetIndex() <=
1347 0 : pDoc->GetNodes().GetEndOfExtras().GetIndex() ||
1348 0 : rInsPos.GetNode().FindTableNode();
1349 :
1350 0 : SwTblNumFmtMerge aTNFM( *pSrcDoc, *pDoc );
1351 :
1352 0 : pSrcDoc->GetDocumentContentOperationsManager().CopyWithFlyInFly( *pCpyRg, 0, rInsPos, NULL, bCreateFrm );
1353 0 : ++aSave;
1354 :
1355 0 : if( !bCreateFrm )
1356 0 : ::MakeFrms( pDoc, aSave, rInsPos );
1357 :
1358 : // Delete last Node, only if it was copied successfully
1359 : // (the Section contains more than one Node)
1360 0 : if( 2 < pSectNd->EndOfSectionIndex() - pSectNd->GetIndex() )
1361 : {
1362 0 : aSave = rInsPos;
1363 0 : pPam->Move( fnMoveBackward, fnGoNode );
1364 0 : pPam->SetMark(); // Rewire both SwPositions
1365 :
1366 0 : pDoc->CorrAbs( aSave, *pPam->GetPoint(), 0, true );
1367 0 : pDoc->GetNodes().Delete( aSave, 1 );
1368 : }
1369 0 : delete pCpyRg;
1370 : }
1371 :
1372 14 : lcl_BreakSectionLinksInSect( *pSectNd );
1373 :
1374 : // Update all Links in this Section
1375 14 : lcl_UpdateLinksInSect( *this, *pSectNd );
1376 : }
1377 18 : if( xDocSh.Is() )
1378 : {
1379 14 : if( 2 == nRet )
1380 0 : xDocSh->DoClose();
1381 14 : else if( ((SwDocShell*)&xDocSh)->GetDoc() )
1382 14 : ((SwDocShell*)&xDocSh)->GetDoc()->getIDocumentRedlineAccess().SetRedlineMode(
1383 14 : eOldRedlineMode );
1384 18 : }
1385 : }
1386 18 : break;
1387 : }
1388 :
1389 : // Only create DDE if Shell is available!
1390 18 : uno::Sequence< sal_Int8 > aSeq;
1391 18 : if( pRead && rValue.hasValue() && ( rValue >>= aSeq ) )
1392 : {
1393 0 : if( pESh )
1394 : {
1395 0 : pESh->Push();
1396 0 : SwPaM* pCrsr = pESh->GetCrsr();
1397 0 : *pCrsr->GetPoint() = *pPam->GetPoint();
1398 0 : delete pPam;
1399 0 : pPam = pCrsr;
1400 : }
1401 :
1402 0 : SvMemoryStream aStrm( (void*)aSeq.getConstArray(), aSeq.getLength(),
1403 0 : STREAM_READ );
1404 0 : aStrm.Seek( 0 );
1405 :
1406 : // TODO/MBA: it's impossible to set a BaseURL here!
1407 0 : SwReader aTmpReader( aStrm, OUString(), pDoc->GetDocShell()->GetMedium()->GetBaseURL(), *pPam );
1408 :
1409 0 : if( !IsError( aTmpReader.Read( *pRead ) ))
1410 : {
1411 0 : rSection.SetConnectFlag(true);
1412 : }
1413 :
1414 0 : if( pESh )
1415 : {
1416 0 : pESh->Pop( false );
1417 0 : pPam = 0; // pam was deleted earlier
1418 0 : }
1419 : }
1420 :
1421 : // remove all undo actions and turn undo on again
1422 18 : pDoc->GetIDocumentUndoRedo().DelAllUndoObj();
1423 18 : pDoc->GetIDocumentUndoRedo().DoUndo(bWasUndo);
1424 18 : pDoc->getIDocumentLinksAdministration().SetVisibleLinks( bWasVisibleLinks );
1425 :
1426 18 : pDoc->getIDocumentFieldsAccess().UnlockExpFlds();
1427 18 : if( !pDoc->getIDocumentFieldsAccess().IsExpFldsLocked() )
1428 18 : pDoc->getIDocumentFieldsAccess().UpdateExpFlds(NULL, true);
1429 :
1430 18 : if( pESh )
1431 18 : pESh->EndAllAction();
1432 0 : else if( pVSh )
1433 0 : pVSh->EndAction();
1434 18 : delete pPam; // Was created at the start
1435 :
1436 18 : return SUCCESS;
1437 : }
1438 :
1439 0 : void SwIntrnlSectRefLink::Closed()
1440 : {
1441 0 : SwDoc* pDoc = rSectFmt.GetDoc();
1442 0 : if( pDoc && !pDoc->IsInDtor() )
1443 : {
1444 : // Advise says goodbye: mark the Section as not protected
1445 : // and change the Flag
1446 0 : const SwSectionFmts& rFmts = pDoc->GetSections();
1447 0 : for( sal_uInt16 n = rFmts.size(); n; )
1448 0 : if( rFmts[ --n ] == &rSectFmt )
1449 : {
1450 0 : SwViewShell* pSh = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
1451 0 : SwEditShell* pESh = pDoc->GetEditShell();
1452 :
1453 0 : if( pESh )
1454 0 : pESh->StartAllAction();
1455 : else
1456 0 : pSh->StartAction();
1457 :
1458 0 : SwSectionData aSectionData(*rSectFmt.GetSection());
1459 0 : aSectionData.SetType( CONTENT_SECTION );
1460 0 : aSectionData.SetLinkFileName( OUString() );
1461 0 : aSectionData.SetHidden( false );
1462 0 : aSectionData.SetProtectFlag( false );
1463 : // edit in readonly sections
1464 0 : aSectionData.SetEditInReadonlyFlag( false );
1465 :
1466 0 : aSectionData.SetConnectFlag( false );
1467 :
1468 0 : pDoc->UpdateSection( n, aSectionData );
1469 :
1470 : // Make all Links within the Section visible again
1471 0 : SwSectionNode* pSectNd = rSectFmt.GetSectionNode( false );
1472 0 : if( pSectNd )
1473 0 : pSectNd->GetSection().MakeChildLinksVisible( *pSectNd );
1474 :
1475 0 : if( pESh )
1476 0 : pESh->EndAllAction();
1477 : else
1478 0 : pSh->EndAction();
1479 0 : break;
1480 : }
1481 : }
1482 0 : SvBaseLink::Closed();
1483 0 : }
1484 :
1485 18 : void SwSection::CreateLink( LinkCreateType eCreateType )
1486 : {
1487 18 : SwSectionFmt* pFmt = GetFmt();
1488 : OSL_ENSURE(pFmt, "SwSection::CreateLink: no format?");
1489 18 : if (!pFmt || (CONTENT_SECTION == m_Data.GetType()))
1490 18 : return ;
1491 :
1492 18 : sal_uInt16 nUpdateType = sfx2::LINKUPDATE_ALWAYS;
1493 :
1494 18 : if (!m_RefLink.Is())
1495 : {
1496 : // create BaseLink
1497 2 : m_RefLink = new SwIntrnlSectRefLink( *pFmt, nUpdateType, FORMAT_RTF );
1498 : }
1499 : else
1500 : {
1501 16 : pFmt->GetDoc()->getIDocumentLinksAdministration().GetLinkManager().Remove( m_RefLink );
1502 : }
1503 :
1504 : SwIntrnlSectRefLink *const pLnk =
1505 18 : static_cast<SwIntrnlSectRefLink*>(& m_RefLink);
1506 :
1507 18 : const OUString sCmd(SwSectionData::CollapseWhiteSpaces(m_Data.GetLinkFileName()));
1508 18 : pLnk->SetUpdateMode( nUpdateType );
1509 18 : pLnk->SetVisible( pFmt->GetDoc()->getIDocumentLinksAdministration().IsVisibleLinks() );
1510 :
1511 18 : switch (m_Data.GetType())
1512 : {
1513 : case DDE_LINK_SECTION:
1514 12 : pLnk->SetLinkSourceName( sCmd );
1515 12 : pFmt->GetDoc()->getIDocumentLinksAdministration().GetLinkManager().InsertDDELink( pLnk );
1516 12 : break;
1517 : case FILE_LINK_SECTION:
1518 : {
1519 6 : pLnk->SetContentType( FORMAT_FILE );
1520 6 : sal_Int32 nIndex = 0;
1521 6 : const OUString sFile(sCmd.getToken( 0, sfx2::cTokenSeparator, nIndex ));
1522 12 : const OUString sFltr(sCmd.getToken( 0, sfx2::cTokenSeparator, nIndex ));
1523 12 : const OUString sRange(sCmd.getToken( 0, sfx2::cTokenSeparator, nIndex ));
1524 6 : pFmt->GetDoc()->getIDocumentLinksAdministration().GetLinkManager().InsertFileLink( *pLnk,
1525 6 : static_cast<sal_uInt16>(m_Data.GetType()),
1526 : sFile,
1527 6 : ( !sFltr.isEmpty() ? &sFltr : 0 ),
1528 30 : ( !sRange.isEmpty() ? &sRange : 0 ) );
1529 : }
1530 6 : break;
1531 : default:
1532 : OSL_ENSURE( false, "What kind of Link is this?" );
1533 : }
1534 :
1535 18 : switch( eCreateType )
1536 : {
1537 : case CREATE_CONNECT: // Connect Link right away
1538 0 : pLnk->Connect();
1539 0 : break;
1540 :
1541 : case CREATE_UPDATE: // Connect Link and update
1542 18 : pLnk->Update();
1543 18 : break;
1544 0 : case CREATE_NONE: break;
1545 18 : }
1546 : }
1547 :
1548 0 : void SwSection::BreakLink()
1549 : {
1550 0 : const SectionType eCurrentType( GetType() );
1551 0 : if ( eCurrentType == CONTENT_SECTION ||
1552 0 : eCurrentType == TOX_HEADER_SECTION ||
1553 : eCurrentType == TOX_CONTENT_SECTION )
1554 : {
1555 : // nothing to do
1556 0 : return;
1557 : }
1558 :
1559 : // Release link, if it exists
1560 0 : if (m_RefLink.Is())
1561 : {
1562 0 : SwSectionFmt *const pFormat( GetFmt() );
1563 : OSL_ENSURE(pFormat, "SwSection::BreakLink: no format?");
1564 0 : if (pFormat)
1565 : {
1566 0 : pFormat->GetDoc()->getIDocumentLinksAdministration().GetLinkManager().Remove( m_RefLink );
1567 : }
1568 0 : m_RefLink.Clear();
1569 : }
1570 : // change type
1571 0 : SetType( CONTENT_SECTION );
1572 : // reset linked file data
1573 0 : SetLinkFileName( OUString() );
1574 0 : SetLinkFilePassword( OUString() );
1575 : }
1576 :
1577 0 : const SwNode* SwIntrnlSectRefLink::GetAnchor() const
1578 : {
1579 0 : return rSectFmt.GetSectionNode( false );
1580 : }
1581 :
1582 0 : bool SwIntrnlSectRefLink::IsInRange( sal_uLong nSttNd, sal_uLong nEndNd,
1583 : sal_Int32 , sal_Int32 ) const
1584 : {
1585 0 : SwStartNode* pSttNd = rSectFmt.GetSectionNode( false );
1586 0 : return pSttNd &&
1587 0 : nSttNd < pSttNd->GetIndex() &&
1588 0 : pSttNd->EndOfSectionIndex() < nEndNd;
1589 : }
1590 :
1591 0 : sal_uInt16 SwSectionFmts::GetPos(const SwSectionFmt* p) const
1592 : {
1593 0 : const_iterator it = std::find(begin(), end(), p);
1594 0 : return it == end() ? USHRT_MAX : it - begin();
1595 : }
1596 :
1597 184 : bool SwSectionFmts::Contains(const SwSectionFmt* p) const
1598 : {
1599 184 : return std::find(begin(), end(), p) != end();
1600 : }
1601 :
1602 15155 : SwSectionFmts::~SwSectionFmts()
1603 : {
1604 5627 : for(const_iterator it = begin(); it != end(); ++it)
1605 572 : delete *it;
1606 10370 : }
1607 :
1608 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|