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