1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <DocumentDrawModelManager.hxx>
23 #include <IDocumentUndoRedo.hxx>
24 #include <IDocumentSettingAccess.hxx>
25 #include <IDocumentDeviceAccess.hxx>
26 #include <IDocumentLinksAdministration.hxx>
27 #include <IDocumentLayoutAccess.hxx>
30 #include <swtypes.hxx>
31 #include <svl/hint.hxx>
34 #include <drawdoc.hxx>
35 #include <rootfrm.hxx>
36 #include <fmtanchr.hxx>
37 #include <editeng/eeitem.hxx>
38 #include <editeng/fhgtitem.hxx>
39 #include <svx/svdlayer.hxx>
40 #include <svx/svdoutl.hxx>
41 #include <svx/svdpage.hxx>
42 #include <svx/svdpagv.hxx>
43 #include <svx/svdotext.hxx>
44 #include <svx/svdview.hxx>
45 #include <svl/srchitem.hxx>
46 #include <comphelper/configuration.hxx>
47 #include <sal/log.hxx>
48 #include <osl/diagnose.h>
55 DocumentDrawModelManager::DocumentDrawModelManager(SwDoc
& i_rSwdoc
)
59 , mnHeaderFooterHell(0)
61 , mnInvisibleHeaven(0)
63 , mnInvisibleControls(0)
67 // Is also called by the Sw3 Reader, if there was an error when reading the
68 // drawing layer. If it is called by the Sw3 Reader the layer is rebuilt
70 void DocumentDrawModelManager::InitDrawModel()
72 // !! Attention: there is similar code in the Sw3 Reader (sw3imp.cxx) that
73 // also has to be maintained!!
77 // set FontHeight pool defaults without changing static SdrEngineDefaults
78 m_rDoc
.GetAttrPool().SetUserDefaultItem(SvxFontHeightItem( 240, 100, EE_CHAR_FONTHEIGHT
));
80 SAL_INFO( "sw.doc", "before create DrawDocument" );
81 // The document owns the SwDrawModel. We always have two layers and one page.
82 mpDrawModel
.reset(new SwDrawModel(m_rDoc
));
84 mpDrawModel
->EnableUndo( m_rDoc
.GetIDocumentUndoRedo().DoesUndo() );
88 mnHell
= mpDrawModel
->GetLayerAdmin().NewLayer( sLayerNm
)->GetID();
90 sLayerNm
= "HeaderFooterHell";
91 mnHeaderFooterHell
= mpDrawModel
->GetLayerAdmin().NewLayer( sLayerNm
)->GetID();
94 mnHeaven
= mpDrawModel
->GetLayerAdmin().NewLayer( sLayerNm
)->GetID();
96 sLayerNm
= "Controls";
97 mnControls
= mpDrawModel
->GetLayerAdmin().NewLayer( sLayerNm
)->GetID();
98 mpDrawModel
->GetLayerAdmin().SetControlLayerName(sLayerNm
);
100 // add invisible layers corresponding to the visible ones.
102 sLayerNm
= "InvisibleHell";
103 mnInvisibleHell
= mpDrawModel
->GetLayerAdmin().NewLayer( sLayerNm
)->GetID();
105 sLayerNm
= "InvisibleHeaven";
106 mnInvisibleHeaven
= mpDrawModel
->GetLayerAdmin().NewLayer( sLayerNm
)->GetID();
108 sLayerNm
= "InvisibleControls";
109 mnInvisibleControls
= mpDrawModel
->GetLayerAdmin().NewLayer( sLayerNm
)->GetID();
112 rtl::Reference
<SdrPage
> pMasterPage
= mpDrawModel
->AllocPage( false );
113 mpDrawModel
->InsertPage( pMasterPage
.get() );
114 SAL_INFO( "sw.doc", "after create DrawDocument" );
115 SdrOutliner
& rOutliner
= mpDrawModel
->GetDrawOutliner();
116 if (!comphelper::IsFuzzing())
118 SAL_INFO( "sw.doc", "before create Spellchecker/Hyphenator" );
119 css::uno::Reference
< css::linguistic2::XSpellChecker1
> xSpell
= ::GetSpellChecker();
120 rOutliner
.SetSpeller( xSpell
);
121 css::uno::Reference
< css::linguistic2::XHyphenator
> xHyphenator( ::GetHyphenator() );
122 rOutliner
.SetHyphenator( xHyphenator
);
123 SAL_INFO( "sw.doc", "after create Spellchecker/Hyphenator" );
125 m_rDoc
.SetCalcFieldValueHdl(&rOutliner
);
126 m_rDoc
.SetCalcFieldValueHdl(&mpDrawModel
->GetHitTestOutliner());
128 // Set the LinkManager in the model so that linked graphics can be inserted.
129 // The WinWord import needs it too.
130 mpDrawModel
->SetLinkManager( & m_rDoc
.getIDocumentLinksAdministration().GetLinkManager() );
131 mpDrawModel
->SetAddExtLeading( m_rDoc
.getIDocumentSettingAccess().get(DocumentSettingId::ADD_EXT_LEADING
) );
133 OutputDevice
* pRefDev
= m_rDoc
.getIDocumentDeviceAccess().getReferenceDevice( false );
135 mpDrawModel
->SetRefDevice( pRefDev
);
137 mpDrawModel
->SetNotifyUndoActionHdl( std::bind( &SwDoc::AddDrawUndo
, &m_rDoc
, std::placeholders::_1
));
138 SwViewShell
* const pSh
= m_rDoc
.getIDocumentLayoutAccess().GetCurrentViewShell();
142 for(const SwViewShell
& rViewSh
: pSh
->GetRingContainer())
144 SwRootFrame
* pRoot
= rViewSh
.GetLayout();
145 if( pRoot
&& !pRoot
->GetDrawPage() )
147 // Disable "multiple layout" for the moment:
148 // use pMasterPage instead of a new created SdrPage
149 // mpDrawModel->AllocPage( FALSE );
150 // mpDrawModel->InsertPage( pDrawPage );
151 SdrPage
* pDrawPage
= pMasterPage
.get();
152 pRoot
->SetDrawPage( pDrawPage
);
153 pDrawPage
->SetSize( pRoot
->getFrameArea().SSize() );
159 void DocumentDrawModelManager::ReleaseDrawModel()
161 // !! Also maintain the code in the sw3io for inserting documents!!
166 const SwDrawModel
* DocumentDrawModelManager::GetDrawModel() const
168 return mpDrawModel
.get();
171 SwDrawModel
* DocumentDrawModelManager::GetDrawModel()
173 return mpDrawModel
.get();
176 SwDrawModel
& DocumentDrawModelManager::MakeDrawModel_()
178 OSL_ENSURE( !mpDrawModel
, "MakeDrawModel_: Why?" );
180 SwViewShell
* const pSh
= m_rDoc
.getIDocumentLayoutAccess().GetCurrentViewShell();
183 for(SwViewShell
& rViewSh
: pSh
->GetRingContainer())
184 rViewSh
.MakeDrawView();
186 // Broadcast, so that the FormShell can be connected to the DrawView
187 if( m_rDoc
.GetDocShell() )
189 SfxHint
aHint( SfxHintId::SwDrawViewsCreated
);
190 m_rDoc
.GetDocShell()->Broadcast( aHint
);
196 SwDrawModel
& DocumentDrawModelManager::GetOrCreateDrawModel()
198 return GetDrawModel() ? *GetDrawModel() : MakeDrawModel_();
201 SdrLayerID
DocumentDrawModelManager::GetHeavenId() const
206 SdrLayerID
DocumentDrawModelManager::GetHellId() const
211 SdrLayerID
DocumentDrawModelManager::GetHeaderFooterHellId() const
213 return mnHeaderFooterHell
;
216 SdrLayerID
DocumentDrawModelManager::GetControlsId() const
221 SdrLayerID
DocumentDrawModelManager::GetInvisibleHeavenId() const
223 return mnInvisibleHeaven
;
226 SdrLayerID
DocumentDrawModelManager::GetInvisibleHellId() const
228 return mnInvisibleHell
;
231 SdrLayerID
DocumentDrawModelManager::GetInvisibleControlsId() const
233 return mnInvisibleControls
;
236 void DocumentDrawModelManager::NotifyInvisibleLayers( SdrPageView
& _rSdrPageView
)
239 sLayerNm
= "InvisibleHell";
240 _rSdrPageView
.SetLayerVisible( sLayerNm
, false );
242 sLayerNm
= "InvisibleHeaven";
243 _rSdrPageView
.SetLayerVisible( sLayerNm
, false );
245 sLayerNm
= "InvisibleControls";
246 _rSdrPageView
.SetLayerVisible( sLayerNm
, false );
249 bool DocumentDrawModelManager::IsVisibleLayerId( SdrLayerID _nLayerId
) const
253 if ( _nLayerId
== GetHeavenId() ||
254 _nLayerId
== GetHeaderFooterHellId() ||
255 _nLayerId
== GetHellId() ||
256 _nLayerId
== GetControlsId() )
260 else if ( _nLayerId
== GetInvisibleHeavenId() ||
261 _nLayerId
== GetInvisibleHellId() ||
262 _nLayerId
== GetInvisibleControlsId() )
268 OSL_FAIL( "<SwDoc::IsVisibleLayerId(..)> - unknown layer ID." );
275 SdrLayerID
DocumentDrawModelManager::GetInvisibleLayerIdByVisibleOne( SdrLayerID _nVisibleLayerId
)
277 SdrLayerID nInvisibleLayerId
;
279 if ( _nVisibleLayerId
== GetHeavenId() )
281 nInvisibleLayerId
= GetInvisibleHeavenId();
283 //TODO: do we need an InvisbleHeaderFooterHell?
284 else if ( _nVisibleLayerId
== GetHellId() || _nVisibleLayerId
== GetHeaderFooterHellId())
286 nInvisibleLayerId
= GetInvisibleHellId();
288 else if ( _nVisibleLayerId
== GetControlsId() )
290 nInvisibleLayerId
= GetInvisibleControlsId();
292 else if ( _nVisibleLayerId
== GetInvisibleHeavenId() ||
293 _nVisibleLayerId
== GetInvisibleHellId() ||
294 _nVisibleLayerId
== GetInvisibleControlsId() )
296 OSL_FAIL( "<SwDoc::GetInvisibleLayerIdByVisibleOne(..)> - given layer ID already an invisible one." );
297 nInvisibleLayerId
= _nVisibleLayerId
;
301 OSL_FAIL( "<SwDoc::GetInvisibleLayerIdByVisibleOne(..)> - given layer ID is unknown." );
302 nInvisibleLayerId
= _nVisibleLayerId
;
305 return nInvisibleLayerId
;
308 bool DocumentDrawModelManager::Search(const SwPaM
& rPaM
, const SvxSearchItem
& rSearchItem
)
310 SwPosFlyFrames aFrames
= m_rDoc
.GetAllFlyFormats(&rPaM
, /*bDrawAlso=*/true);
312 for (const SwPosFlyFrame
& rPosFlyFrame
: aFrames
)
314 // Filter for at-paragraph anchored draw frames.
315 const SwFrameFormat
& rFrameFormat
= rPosFlyFrame
.GetFormat();
316 const SwFormatAnchor
& rAnchor
= rFrameFormat
.GetAnchor();
317 if (rAnchor
.GetAnchorId() != RndStdIds::FLY_AT_PARA
|| rFrameFormat
.Which() != RES_DRAWFRMFMT
)
320 // Does the shape have matching text?
321 SdrOutliner
& rOutliner
= GetDrawModel()->GetDrawOutliner();
322 SdrObject
* pObject
= const_cast<SdrObject
*>(rFrameFormat
.FindSdrObject());
323 SdrTextObj
* pTextObj
= DynCastSdrTextObj(pObject
);
326 const OutlinerParaObject
* pParaObj
= pTextObj
->GetOutlinerParaObject();
329 rOutliner
.SetText(*pParaObj
);
330 SwDocShell
* pDocShell
= m_rDoc
.GetDocShell();
333 SwWrtShell
* pWrtShell
= pDocShell
->GetWrtShell();
336 if (!rOutliner
.HasText(rSearchItem
))
339 // If so, then select highlight the search result.
340 pWrtShell
->SelectObj(Point(), 0, pObject
);
341 SwView
* pView
= pDocShell
->GetView();
344 if (!pView
->EnterShapeDrawTextMode(pObject
))
346 SdrView
* pSdrView
= pWrtShell
->GetDrawView();
349 OutlinerView
* pOutlinerView
= pSdrView
->GetTextEditOutlinerView();
350 if (!rSearchItem
.GetBackward())
351 pOutlinerView
->SetSelection(ESelection(0, 0));
353 pOutlinerView
->SetSelection(ESelection::AtEnd());
354 pOutlinerView
->StartSearchAndReplace(rSearchItem
);
361 void DocumentDrawModelManager::DrawNotifyUndoHdl()
363 mpDrawModel
->SetNotifyUndoActionHdl( nullptr );
368 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */