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