LibreOffice Module sw (master)  1
vdraw.cxx
Go to the documentation of this file.
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 <officecfg/Office/Common.hxx>
21 #include <svx/svdmodel.hxx>
22 #include <svx/svdpage.hxx>
23 #include <swmodule.hxx>
25 #include <svx/svdpagv.hxx>
26 #include <fmtanchr.hxx>
27 #include <frmfmt.hxx>
28 
29 #include <svx/svdoutl.hxx>
30 
31 #include <drawdoc.hxx>
32 #include <fesh.hxx>
33 #include <pagefrm.hxx>
34 #include <rootfrm.hxx>
35 #include <viewimp.hxx>
36 #include <dflyobj.hxx>
37 #include <printdata.hxx>
38 #include <dcontact.hxx>
39 #include <dview.hxx>
40 #include <flyfrm.hxx>
41 #include <vcl/svapp.hxx>
42 #include <vcl/settings.hxx>
43 #include <vcl/canvastools.hxx>
44 #include <sal/log.hxx>
45 #include <osl/diagnose.h>
46 
48 
50 
52 {
53  if ( HasDrawView() )
54  {
55  CurrShell aCurr( GetShell() );
56  if ( auto pFEShell = dynamic_cast<SwFEShell*>( m_pShell) )
57  pFEShell->HideChainMarker(); // might have changed
58  }
59 }
60 
62 {
63  if ( HasDrawView() )
64  {
65  CurrShell aCurr( GetShell() );
66  if ( auto pFEShell = dynamic_cast<SwFEShell*>(m_pShell) )
67  pFEShell->SetChainMarker(); // might have changed
68  }
69 }
70 
72 {
73  if ( HasDrawView() )
74  {
77  }
78  else
79  {
80  m_bResetHdlHiddenPaint = false;
81  }
82 }
83 
85 {
88 }
89 
90 void SwViewShellImp::PaintLayer( const SdrLayerID _nLayerID,
91  SwPrintData const*const pPrintData,
92  SwPageFrame const& rPageFrame,
93  const SwRect& aPaintRect,
94  const Color* _pPageBackgrdColor,
95  const bool _bIsPageRightToLeft,
97 {
98  if ( !HasDrawView() )
99  return;
100 
101  //change the draw mode in high contrast mode
102  OutputDevice* pOutDev = GetShell()->GetOut();
103  DrawModeFlags nOldDrawMode = pOutDev->GetDrawMode();
104  if( GetShell()->GetWin() &&
105  Application::GetSettings().GetStyleSettings().GetHighContrastMode() &&
107  {
108  pOutDev->SetDrawMode( nOldDrawMode | DrawModeFlags::SettingsLine | DrawModeFlags::SettingsFill |
109  DrawModeFlags::SettingsText | DrawModeFlags::SettingsGradient );
110  }
111 
112  // For correct handling of accessibility, high contrast, the
113  // page background color is set as the background color at the
114  // outliner of the draw view. Only necessary for the layers
115  // hell and heaven
116  Color aOldOutlinerBackgroundColor;
117  // set default horizontal text direction on painting <hell> or
118  // <heaven>.
119  EEHorizontalTextDirection aOldEEHoriTextDir = EEHorizontalTextDirection::L2R;
121  if ( (_nLayerID == rIDDMA.GetHellId()) ||
122  (_nLayerID == rIDDMA.GetHeavenId()) )
123  {
124  OSL_ENSURE( _pPageBackgrdColor,
125  "incorrect usage of SwViewShellImp::PaintLayer: pPageBackgrdColor have to be set for painting layer <hell> or <heaven>");
126  if ( _pPageBackgrdColor )
127  {
128  aOldOutlinerBackgroundColor =
129  GetDrawView()->GetModel()->GetDrawOutliner().GetBackgroundColor();
130  GetDrawView()->GetModel()->GetDrawOutliner().SetBackgroundColor( *_pPageBackgrdColor );
131  }
132 
133  aOldEEHoriTextDir =
134  GetDrawView()->GetModel()->GetDrawOutliner().GetDefaultHorizontalTextDirection();
135  EEHorizontalTextDirection aEEHoriTextDirOfPage =
136  _bIsPageRightToLeft ? EEHorizontalTextDirection::R2L : EEHorizontalTextDirection::L2R;
137  GetDrawView()->GetModel()->GetDrawOutliner().SetDefaultHorizontalTextDirection( aEEHoriTextDirOfPage );
138  }
139 
140  pOutDev->Push( vcl::PushFlags::LINECOLOR );
141  if (pPrintData)
142  {
143  // hide drawings but not form controls (form controls are handled elsewhere)
144  SdrView &rSdrView = GetPageView()->GetView();
145  rSdrView.setHideDraw( !pPrintData->IsPrintDraw() );
146  }
148  GetPageView()->DrawLayer(_nLayerID, pOutDev, pRedirector, aPaintRect.SVRect(), &pageFrame);
149  pOutDev->Pop();
150 
151  // reset background color of the outliner & default horiz. text dir.
152  if ( (_nLayerID == rIDDMA.GetHellId()) ||
153  (_nLayerID == rIDDMA.GetHeavenId()) )
154  {
155  GetDrawView()->GetModel()->GetDrawOutliner().SetBackgroundColor( aOldOutlinerBackgroundColor );
156  GetDrawView()->GetModel()->GetDrawOutliner().SetDefaultHorizontalTextDirection( aOldEEHoriTextDir );
157  }
158 
159  pOutDev->SetDrawMode( nOldDrawMode );
160 
161 }
162 
163 #define FUZZY_EDGE 400
164 
165 bool SwViewShellImp::IsDragPossible( const Point &rPoint )
166 {
167  if ( !HasDrawView() )
168  return false;
169 
170  const SdrMarkList &rMrkList = GetDrawView()->GetMarkedObjectList();
171 
172  if( !rMrkList.GetMarkCount() )
173  return false;
174 
175  SdrObject *pO = rMrkList.GetMark(rMrkList.GetMarkCount()-1)->GetMarkedSdrObj();
176 
177  SwRect aRect;
178  if( pO && ::CalcClipRect( pO, aRect, false ) )
179  {
180  SwRect aTmp;
181  ::CalcClipRect( pO, aTmp );
182  aRect.Union( aTmp );
183  }
184  else
185  aRect = GetShell()->GetLayout()->getFrameArea();
186 
187  aRect.AddTop (- FUZZY_EDGE );
188  aRect.AddBottom( FUZZY_EDGE );
189  aRect.AddLeft (- FUZZY_EDGE );
190  aRect.AddRight ( FUZZY_EDGE );
191  return aRect.Contains( rPoint );
192 }
193 
194 void SwViewShellImp::NotifySizeChg( const Size &rNewSz )
195 {
196  if ( !HasDrawView() )
197  return;
198 
199  if ( GetPageView() )
200  GetPageView()->GetPage()->SetSize( rNewSz );
201 
202  // Limitation of the work area
203  const tools::Rectangle aDocRect( Point( DOCUMENTBORDER, DOCUMENTBORDER ), rNewSz );
204  const tools::Rectangle &rOldWork = GetDrawView()->GetWorkArea();
205  bool bCheckDrawObjs = false;
206  if ( aDocRect != rOldWork )
207  {
208  if ( rOldWork.Bottom() > aDocRect.Bottom() || rOldWork.Right() > aDocRect.Right())
209  bCheckDrawObjs = true;
210  GetDrawView()->SetWorkArea( aDocRect );
211  }
212  if ( !bCheckDrawObjs )
213  return;
214 
215  OSL_ENSURE( m_pShell->getIDocumentDrawModelAccess().GetDrawModel(), "NotifySizeChg without DrawModel" );
217  const size_t nObjs = pPage->GetObjCount();
218  for( size_t nObj = 0; nObj < nObjs; ++nObj )
219  {
220  SdrObject *pObj = pPage->GetObj( nObj );
221  if( dynamic_cast<const SwVirtFlyDrawObj*>( pObj) == nullptr )
222  {
223  // Objects not anchored to the frame, do not need to be adjusted
224  const SwContact *pCont = GetUserCall(pObj);
225  // this function might be called by the InsertDocument, when
226  // a PageDesc-Attribute is set on a node. Then the SdrObject
227  // must not have an UserCall.
228  if( !pCont )
229  continue;
230  auto pDrawContact = dynamic_cast<const SwDrawContact*>( pCont);
231  if( !pDrawContact )
232  continue;
233 
234  const SwFrame *pAnchor = pDrawContact->GetAnchorFrame();
235  if ( !pAnchor || pAnchor->IsInFly() || !pAnchor->isFrameAreaDefinitionValid() ||
236  !pAnchor->GetUpper() || !pAnchor->FindPageFrame() ||
237  (RndStdIds::FLY_AS_CHAR == pCont->GetFormat()->GetAnchor().GetAnchorId()) )
238  {
239  continue;
240  }
241  else
242  {
243  // Actually this should never happen but currently layouting
244  // is broken. So don't move anchors, if the page is invalid.
245  // This should be turned into a DBG_ASSERT, once layouting is fixed!
246  const SwPageFrame *pPageFrame = pAnchor->FindPageFrame();
247  if (!pPageFrame || pPageFrame->IsInvalid() ) {
248  SAL_WARN( "sw.core", "Trying to move anchor from invalid page - fix layouting!" );
249  continue;
250  }
251  }
252 
253  // no move for drawing objects in header/footer
254  if ( pAnchor->FindFooterOrHeader() )
255  {
256  continue;
257  }
258 
259  const tools::Rectangle aObjBound( pObj->GetCurrentBoundRect() );
260  if ( !aDocRect.Contains( aObjBound ) )
261  {
262  Size aSz;
263  if ( aObjBound.Left() > aDocRect.Right() )
264  aSz.setWidth( (aDocRect.Right() - aObjBound.Left()) - MINFLY );
265  if ( aObjBound.Top() > aDocRect.Bottom() )
266  aSz.setHeight( (aDocRect.Bottom() - aObjBound.Top()) - MINFLY );
267  if ( aSz.Width() || aSz.Height() )
268  pObj->Move( aSz );
269 
270  // Don't let large objects disappear to the top
271  aSz.setWidth(0);
272  aSz.setHeight(0);
273  if ( aObjBound.Right() < aDocRect.Left() )
274  aSz.setWidth( (aDocRect.Left() - aObjBound.Right()) + MINFLY );
275  if ( aObjBound.Bottom() < aDocRect.Top() )
276  aSz.setHeight( (aDocRect.Top() - aObjBound.Bottom()) + MINFLY );
277  if ( aSz.Width() || aSz.Height() )
278  pObj->Move( aSz );
279  }
280  }
281  }
282 }
283 
284 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SdrOutliner & GetDrawOutliner(const SdrTextObj *pObj=nullptr) const
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:339
SwFrame * FindFooterOrHeader()
Definition: findfrm.cxx:580
Base class for the following contact objects (frame + draw objects).
Definition: dcontact.hxx:66
Base class of the Writer layout elements.
Definition: frame.hxx:315
size_t GetMarkCount() const
virtual void SetSize(const Size &aSiz)
virtual const tools::Rectangle & GetCurrentBoundRect() const
bool IsInFly() const
Definition: frame.hxx:962
SwRect & Union(const SwRect &rRect)
Definition: swrect.cxx:35
void setWidth(tools::Long nWidth)
constexpr SwTwips DOCUMENTBORDER
Definition: swtypes.hxx:80
constexpr tools::Long Left() const
SdrView & GetView()
bool Contains(const Point &rPOINT) const
#define MINFLY
Definition: swtypes.hxx:62
static const AllSettings & GetSettings()
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
virtual SdrLayerID GetHeavenId() const =0
size_t GetObjCount() const
void NotifySizeChg(const Size &rNewSz)
Definition: vdraw.cxx:194
SdrMark * GetMark(size_t nNum) const
bool CalcClipRect(const SdrObject *pSdrObj, SwRect &rRect, bool bMove=true)
calculate rectangle in that the object can be moved or rather be resized
Definition: flylay.cxx:1144
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
SwContact * GetUserCall(const SdrObject *pObj)
Returns the UserCall if applicable from the group object.
Definition: dcontact.cxx:171
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:172
void AddTop(const tools::Long nAdd)
Definition: swrect.cxx:128
void SetDrawMode(DrawModeFlags nDrawMode)
constexpr tools::Long Width() const
const SwRect & getFrameArea() const
Definition: frame.hxx:180
void PaintLayer(const SdrLayerID _nLayerID, SwPrintData const *const pPrintData, SwPageFrame const &rPageFrame, const SwRect &_rRect, const Color *_pPageBackgrdColor, const bool _bIsPageRightToLeft, sdr::contact::ViewObjectContactRedirector *pRedirector)
Definition: vdraw.cxx:90
void UnlockPaint()
Definition: vdraw.cxx:84
void showMarkHandles()
const IDocumentDrawModelAccess & getIDocumentDrawModelAccess() const
Provides access to the document draw model interface.
Definition: viewsh.cxx:2766
const SwViewShell * GetShell() const
Only for SwViewShell::Init()
Definition: viewimp.hxx:140
bool m_bResetHdlHiddenPaint
Definition: viewimp.hxx:80
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
SwFrameFormat * GetFormat()
Definition: dcontact.hxx:112
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
void AddBottom(const tools::Long nAdd)
Definition: swrect.cxx:130
SwPageFrame * FindPageFrame()
Definition: frame.hxx:681
void hideMarkHandles()
const SdrMarkList & GetMarkedObjectList() const
const SdrPage * GetPage(sal_uInt16 nPgNum) const
void StartAction()
Definition: vdraw.cxx:51
SwLayoutFrame * GetUpper()
Definition: frame.hxx:679
virtual const SwDrawModel * GetDrawModel() const =0
Draw Model and id accessors.
constexpr tools::Long Right() const
EEHorizontalTextDirection
basegfx::B2IRectangle b2IRectangleFromRectangle(tools::Rectangle const &rRect)
constexpr tools::Long Top() const
virtual void Move(const Size &rSiz)
void AddRight(const tools::Long nAdd)
Definition: swrect.cxx:127
DrawModeFlags GetDrawMode() const
A page of the document layout.
Definition: pagefrm.hxx:57
bool Contains(const Point &rPOINT) const
Definition: swrect.hxx:356
void EndAction()
Definition: vdraw.cxx:61
virtual SdrLayerID GetHellId() const =0
constexpr tools::Long Bottom() const
void AddLeft(const tools::Long nAdd)
Definition: swrect.cxx:125
tools::Rectangle SVRect() const
Definition: swrect.hxx:292
bool IsPrintDraw() const
Definition: printdata.hxx:133
SwDrawView * GetDrawView()
Definition: viewimp.hxx:161
SwViewShell * m_pShell
Definition: viewimp.hxx:60
constexpr tools::Long Height() const
SdrPage * GetPage() const
void LockPaint()
Definition: vdraw.cxx:71
void SetWorkArea(const tools::Rectangle &rRect)
void DrawLayer(SdrLayerID nID, OutputDevice *pGivenTarget, sdr::contact::ViewObjectContactRedirector *pRedirector=nullptr, const tools::Rectangle &rRect=tools::Rectangle(), basegfx::B2IRectangle const *pPageFrame=nullptr)
bool areMarkHandlesHidden() const
bool HasDrawView() const
New Interface for StarView Drawing.
Definition: viewimp.hxx:160
void setHideDraw(bool bNew)
void setHeight(tools::Long nHeight)
#define SAL_WARN(area, stream)
bool IsInvalid() const
Definition: pagefrm.hxx:439
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2166
SdrModel * GetModel() const
bool IsDragPossible(const Point &rPoint)
Is passed to the DrawEngine as a Link and decides what is painted or not and in what way...
Definition: vdraw.cxx:165
const tools::Rectangle & GetWorkArea() const
DrawModeFlags
#define FUZZY_EDGE
Definition: vdraw.cxx:163
SdrPageView * GetPageView()
Definition: viewimp.hxx:163