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 <svx/svdmodel.hxx>
21 #include <svx/svdpage.hxx>
22 #include <swmodule.hxx>
23 #include <svtools/accessibilityoptions.hxx>
24 #include <svx/svdpagv.hxx>
25 #include <fmtanchr.hxx>
28 #include <svx/svdoutl.hxx>
30 #include <drawdoc.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>
40 #include <vcl/svapp.hxx>
41 #include <vcl/settings.hxx>
42 #include <vcl/canvastools.hxx>
43 #include <sal/log.hxx>
45 #include <basegfx/range/b2irectangle.hxx>
47 #include <IDocumentDrawModelAccess.hxx>
49 void SwViewShellImp::StartAction()
53 CurrShell
aCurr( GetShell() );
54 if ( auto pFEShell
= dynamic_cast<SwFEShell
*>( m_pShell
) )
55 pFEShell
->HideChainMarker(); // might have changed
59 void SwViewShellImp::EndAction()
63 CurrShell
aCurr( GetShell() );
64 if ( auto pFEShell
= dynamic_cast<SwFEShell
*>(m_pShell
) )
65 pFEShell
->SetChainMarker(); // might have changed
69 void SwViewShellImp::LockPaint()
73 m_bResetHdlHiddenPaint
= !GetDrawView()->areMarkHandlesHidden();
74 GetDrawView()->hideMarkHandles();
78 m_bResetHdlHiddenPaint
= false;
82 void SwViewShellImp::UnlockPaint()
84 if ( m_bResetHdlHiddenPaint
)
85 GetDrawView()->showMarkHandles();
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
,
94 sdr::contact::ViewObjectContactRedirector
* pRedirector
)
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()))
106 pOutDev
->SetDrawMode( nOldDrawMode
| DrawModeFlags::SettingsLine
| DrawModeFlags::SettingsFill
|
107 DrawModeFlags::SettingsText
| DrawModeFlags::SettingsGradient
);
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
114 Color aOldOutlinerBackgrdColor
;
115 // set default horizontal text direction on painting <hell> or
117 EEHorizontalTextDirection aOldEEHoriTextDir
= EEHorizontalTextDirection::L2R
;
118 const IDocumentDrawModelAccess
& rIDDMA
= GetShell()->getIDocumentDrawModelAccess();
119 if ( (_nLayerID
== rIDDMA
.GetHellId()) ||
120 (_nLayerID
== rIDDMA
.GetHeavenId()) )
122 OSL_ENSURE( _pPageBackgrdColor
,
123 "incorrect usage of SwViewShellImp::PaintLayer: pPageBackgrdColor have to be set for painting layer <hell> or <heaven>");
124 if ( _pPageBackgrdColor
)
126 aOldOutlinerBackgrdColor
=
127 GetDrawView()->GetModel()->GetDrawOutliner().GetBackgroundColor();
128 GetDrawView()->GetModel()->GetDrawOutliner().SetBackgroundColor( *_pPageBackgrdColor
);
132 GetDrawView()->GetModel()->GetDrawOutliner().GetDefaultHorizontalTextDirection();
133 EEHorizontalTextDirection aEEHoriTextDirOfPage
=
134 _bIsPageRightToLeft
? EEHorizontalTextDirection::R2L
: EEHorizontalTextDirection::L2R
;
135 GetDrawView()->GetModel()->GetDrawOutliner().SetDefaultHorizontalTextDirection( aEEHoriTextDirOfPage
);
138 pOutDev
->Push( PushFlags::LINECOLOR
);
141 // hide drawings but not form controls (form controls are handled elsewhere)
142 SdrView
&rSdrView
= GetPageView()->GetView();
143 rSdrView
.setHideDraw( !pPrintData
->IsPrintDraw() );
145 basegfx::B2IRectangle
const pageFrame
= vcl::unotools::b2IRectangleFromRectangle(rPageFrame
.getFrameArea().SVRect());
146 GetPageView()->DrawLayer(_nLayerID
, pOutDev
, pRedirector
, aPaintRect
.SVRect(), &pageFrame
);
149 // reset background color of the outliner & default horiz. text dir.
150 if ( (_nLayerID
== rIDDMA
.GetHellId()) ||
151 (_nLayerID
== rIDDMA
.GetHeavenId()) )
153 GetDrawView()->GetModel()->GetDrawOutliner().SetBackgroundColor( aOldOutlinerBackgrdColor
);
154 GetDrawView()->GetModel()->GetDrawOutliner().SetDefaultHorizontalTextDirection( aOldEEHoriTextDir
);
157 pOutDev
->SetDrawMode( nOldDrawMode
);
161 #define FUZZY_EDGE 400
163 bool SwViewShellImp::IsDragPossible( const Point
&rPoint
)
165 if ( !HasDrawView() )
168 const SdrMarkList
&rMrkList
= GetDrawView()->GetMarkedObjectList();
170 if( !rMrkList
.GetMarkCount() )
173 SdrObject
*pO
= rMrkList
.GetMark(rMrkList
.GetMarkCount()-1)->GetMarkedSdrObj();
176 if( pO
&& ::CalcClipRect( pO
, aRect
, false ) )
179 ::CalcClipRect( pO
, aTmp
);
183 aRect
= GetShell()->GetLayout()->getFrameArea();
185 aRect
.AddTop (- FUZZY_EDGE
);
186 aRect
.AddBottom( FUZZY_EDGE
);
187 aRect
.AddLeft (- FUZZY_EDGE
);
188 aRect
.AddRight ( FUZZY_EDGE
);
189 return aRect
.IsInside( rPoint
);
192 void SwViewShellImp::NotifySizeChg( const Size
&rNewSz
)
194 if ( !HasDrawView() )
198 GetPageView()->GetPage()->SetSize( rNewSz
);
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
)
206 if ( rOldWork
.Bottom() > aDocRect
.Bottom() || rOldWork
.Right() > aDocRect
.Right())
207 bCheckDrawObjs
= true;
208 GetDrawView()->SetWorkArea( aDocRect
);
210 if ( !bCheckDrawObjs
)
213 OSL_ENSURE( m_pShell
->getIDocumentDrawModelAccess().GetDrawModel(), "NotifySizeChg without DrawModel" );
214 SdrPage
* pPage
= m_pShell
->getIDocumentDrawModelAccess().GetDrawModel()->GetPage( 0 );
215 const size_t nObjs
= pPage
->GetObjCount();
216 for( size_t nObj
= 0; nObj
< nObjs
; ++nObj
)
218 SdrObject
*pObj
= pPage
->GetObj( nObj
);
219 if( dynamic_cast<const SwVirtFlyDrawObj
*>( pObj
) == nullptr )
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 )
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()) )
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!" );
248 // no move for drawing objects in header/footer
249 if ( pAnchor
->FindFooterOrHeader() )
254 const tools::Rectangle
aObjBound( pObj
->GetCurrentBoundRect() );
255 if ( !aDocRect
.IsInside( aObjBound
) )
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() )
265 // Don't let large objects disappear to the top
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() )
279 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */