tdf#35361 Add a Quick Look plugins for .od* files on macOS
[LibreOffice.git] / sw / source / core / doc / DocumentDrawModelManager.cxx
blob0c48cdc1db0522c0a7c73247ff7e0cf29d7f2202
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
22 #include <doc.hxx>
23 #include <IDocumentUndoRedo.hxx>
24 #include <IDocumentSettingAccess.hxx>
25 #include <IDocumentDeviceAccess.hxx>
26 #include <IDocumentLinksAdministration.hxx>
27 #include <IDocumentLayoutAccess.hxx>
28 #include <docsh.hxx>
29 #include <wrtsh.hxx>
30 #include <swtypes.hxx>
31 #include <svl/hint.hxx>
32 #include <viewsh.hxx>
33 #include <view.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>
50 class SdrOutliner;
52 namespace sw
55 DocumentDrawModelManager::DocumentDrawModelManager(SwDoc& i_rSwdoc)
56 : m_rDoc(i_rSwdoc)
57 , mnHeaven(0)
58 , mnHell(0)
59 , mnHeaderFooterHell(0)
60 , mnControls(0)
61 , mnInvisibleHeaven(0)
62 , mnInvisibleHell(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
69 // from scratch.
70 void DocumentDrawModelManager::InitDrawModel()
72 // !! Attention: there is similar code in the Sw3 Reader (sw3imp.cxx) that
73 // also has to be maintained!!
74 if ( mpDrawModel )
75 ReleaseDrawModel();
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() );
86 OUString sLayerNm;
87 sLayerNm = "Hell";
88 mnHell = mpDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
90 sLayerNm = "HeaderFooterHell";
91 mnHeaderFooterHell = mpDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
93 sLayerNm = "Heaven";
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 );
134 if ( pRefDev )
135 mpDrawModel->SetRefDevice( pRefDev );
137 mpDrawModel->SetNotifyUndoActionHdl( std::bind( &SwDoc::AddDrawUndo, &m_rDoc, std::placeholders::_1 ));
138 SwViewShell* const pSh = m_rDoc.getIDocumentLayoutAccess().GetCurrentViewShell();
139 if ( !pSh )
140 return;
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!!
162 mpDrawModel.reset();
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?" );
179 InitDrawModel();
180 SwViewShell* const pSh = m_rDoc.getIDocumentLayoutAccess().GetCurrentViewShell();
181 if ( pSh )
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 );
193 return *mpDrawModel;
196 SwDrawModel& DocumentDrawModelManager::GetOrCreateDrawModel()
198 return GetDrawModel() ? *GetDrawModel() : MakeDrawModel_();
201 SdrLayerID DocumentDrawModelManager::GetHeavenId() const
203 return mnHeaven;
206 SdrLayerID DocumentDrawModelManager::GetHellId() const
208 return mnHell;
211 SdrLayerID DocumentDrawModelManager::GetHeaderFooterHellId() const
213 return mnHeaderFooterHell;
216 SdrLayerID DocumentDrawModelManager::GetControlsId() const
218 return mnControls;
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 )
238 OUString sLayerNm;
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
251 bool bRetVal;
253 if ( _nLayerId == GetHeavenId() ||
254 _nLayerId == GetHeaderFooterHellId() ||
255 _nLayerId == GetHellId() ||
256 _nLayerId == GetControlsId() )
258 bRetVal = true;
260 else if ( _nLayerId == GetInvisibleHeavenId() ||
261 _nLayerId == GetInvisibleHellId() ||
262 _nLayerId == GetInvisibleControlsId() )
264 bRetVal = false;
266 else
268 OSL_FAIL( "<SwDoc::IsVisibleLayerId(..)> - unknown layer ID." );
269 bRetVal = false;
272 return bRetVal;
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;
299 else
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)
318 continue;
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);
324 if (!pTextObj)
325 continue;
326 const OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject();
327 if (!pParaObj)
328 continue;
329 rOutliner.SetText(*pParaObj);
330 SwDocShell* pDocShell = m_rDoc.GetDocShell();
331 if (!pDocShell)
332 return false;
333 SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
334 if (!pWrtShell)
335 return false;
336 if (!rOutliner.HasText(rSearchItem))
337 continue;
339 // If so, then select highlight the search result.
340 pWrtShell->SelectObj(Point(), 0, pObject);
341 SwView* pView = pDocShell->GetView();
342 if (!pView)
343 return false;
344 if (!pView->EnterShapeDrawTextMode(pObject))
345 continue;
346 SdrView* pSdrView = pWrtShell->GetDrawView();
347 if (!pSdrView)
348 return false;
349 OutlinerView* pOutlinerView = pSdrView->GetTextEditOutlinerView();
350 if (!rSearchItem.GetBackward())
351 pOutlinerView->SetSelection(ESelection(0, 0));
352 else
353 pOutlinerView->SetSelection(ESelection::AtEnd());
354 pOutlinerView->StartSearchAndReplace(rSearchItem);
355 return true;
358 return false;
361 void DocumentDrawModelManager::DrawNotifyUndoHdl()
363 mpDrawModel->SetNotifyUndoActionHdl( nullptr );
368 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */