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