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 <vcl/svapp.hxx>
22 #include <svx/connctrl.hxx>
23 #include <svx/dlgutil.hxx>
25 #include <svx/sdr/contact/displayinfo.hxx>
26 #include <sdr/contact/objectcontactofobjlistpainter.hxx>
27 #include <svx/svdmark.hxx>
28 #include <svx/svdoedge.hxx>
29 #include <svx/svdpage.hxx>
30 #include <svx/svdview.hxx>
31 #include <svx/sxelditm.hxx>
33 #include <vcl/settings.hxx>
36 SvxXConnectionPreview::SvxXConnectionPreview()
39 SetMapMode(MapMode(MapUnit::Map100thMM
));
42 void SvxXConnectionPreview::SetDrawingArea(weld::DrawingArea
* pDrawingArea
)
44 weld::CustomWidgetController::SetDrawingArea(pDrawingArea
);
45 Size
aSize(pDrawingArea
->get_ref_device().LogicToPixel(Size(118 , 121), MapMode(MapUnit::MapAppFont
)));
46 pDrawingArea
->set_size_request(aSize
.Width(), aSize
.Height());
47 SetOutputSizePixel(aSize
);
50 SvxXConnectionPreview::~SvxXConnectionPreview()
54 void SvxXConnectionPreview::Resize()
61 void SvxXConnectionPreview::AdaptSize()
67 SetMapMode(MapMode(MapUnit::Map100thMM
));
69 OutputDevice
* pOD
= pView
->GetFirstOutputDevice(); // GetWin( 0 );
70 tools::Rectangle aRect
= mxSdrPage
->GetAllObjBoundRect();
72 MapMode aMapMode
= GetMapMode();
73 aMapMode
.SetMapUnit( pOD
->GetMapMode().GetMapUnit() );
74 SetMapMode( aMapMode
);
76 MapMode
aDisplayMap( aMapMode
);
79 const Size aWinSize
= GetDrawingArea()->get_ref_device().PixelToLogic(GetOutputSizePixel(), aDisplayMap
);
80 const tools::Long nWidth
= aWinSize
.Width();
81 const tools::Long nHeight
= aWinSize
.Height();
82 if (aRect
.GetHeight() == 0)
84 double fRectWH
= static_cast<double>(aRect
.GetWidth()) / aRect
.GetHeight();
87 double fWinWH
= static_cast<double>(nWidth
) / nHeight
;
89 // Adapt bitmap to Thumb size (not here!)
90 if ( fRectWH
< fWinWH
)
92 aNewSize
.setWidth( static_cast<tools::Long
>( static_cast<double>(nHeight
) * fRectWH
) );
93 aNewSize
.setHeight( nHeight
);
97 aNewSize
.setWidth( nWidth
);
98 aNewSize
.setHeight( static_cast<tools::Long
>( static_cast<double>(nWidth
) / fRectWH
) );
101 Fraction
aFrac1( aWinSize
.Width(), aRect
.GetWidth() );
102 Fraction
aFrac2( aWinSize
.Height(), aRect
.GetHeight() );
103 Fraction
aMinFrac( aFrac1
<= aFrac2
? aFrac1
: aFrac2
);
106 aDisplayMap
.SetScaleX( aMinFrac
);
107 aDisplayMap
.SetScaleY( aMinFrac
);
110 aNewPos
.setX( ( nWidth
- aNewSize
.Width() ) >> 1 );
111 aNewPos
.setY( ( nHeight
- aNewSize
.Height() ) >> 1 );
113 aDisplayMap
.SetOrigin(OutputDevice::LogicToLogic(aNewPos
, aMapMode
, aDisplayMap
));
114 SetMapMode( aDisplayMap
);
117 aNewPos
= aDisplayMap
.GetOrigin();
118 aNewPos
-= Point( aRect
.Left(), aRect
.Top() );
119 aDisplayMap
.SetOrigin( aNewPos
);
120 SetMapMode( aDisplayMap
);
122 MouseEvent
aMEvt( Point(), 1, MouseEventModifiers::NONE
, MOUSE_RIGHT
);
123 MouseButtonDown( aMEvt
);
126 void SvxXConnectionPreview::Construct()
128 DBG_ASSERT( pView
, "No valid view is passed on! ");
130 const SdrMarkList
& rMarkList
= pView
->GetMarkedObjectList();
131 const size_t nMarkCount
= rMarkList
.GetMarkCount();
133 if( nMarkCount
>= 1 )
137 for( size_t i
= 0; i
< nMarkCount
&& !bFound
; ++i
)
139 const SdrObject
* pObj
= rMarkList
.GetMark( i
)->GetMarkedSdrObj();
140 SdrInventor nInv
= pObj
->GetObjInventor();
141 SdrObjKind nId
= pObj
->GetObjIdentifier();
142 if( nInv
== SdrInventor::Default
&& nId
== SdrObjKind::Edge
)
146 // potential memory leak here (!). Create SdrObjList only when there is
150 mxSdrPage
= new SdrPage(
151 pView
->getSdrModelFromSdrView(),
155 const SdrEdgeObj
* pTmpEdgeObj
= static_cast<const SdrEdgeObj
*>(pObj
);
156 pEdgeObj
= SdrObject::Clone(*pTmpEdgeObj
, mxSdrPage
->getSdrModelFromSdrPage());
158 SdrObjConnection
& rConn1
= pEdgeObj
->GetConnection( true );
159 SdrObjConnection
& rConn2
= pEdgeObj
->GetConnection( false );
161 rConn1
= pTmpEdgeObj
->GetConnection( true );
162 rConn2
= pTmpEdgeObj
->GetConnection( false );
164 SdrObject
* pTmpObj1
= pTmpEdgeObj
->GetConnectedNode( true );
165 SdrObject
* pTmpObj2
= pTmpEdgeObj
->GetConnectedNode( false );
169 rtl::Reference
<SdrObject
> pObj1
= pTmpObj1
->CloneSdrObject(mxSdrPage
->getSdrModelFromSdrPage());
170 mxSdrPage
->InsertObject( pObj1
.get() );
171 pEdgeObj
->ConnectToNode( true, pObj1
.get() );
176 rtl::Reference
<SdrObject
> pObj2
= pTmpObj2
->CloneSdrObject(mxSdrPage
->getSdrModelFromSdrPage());
177 mxSdrPage
->InsertObject( pObj2
.get() );
178 pEdgeObj
->ConnectToNode( false, pObj2
.get() );
181 mxSdrPage
->InsertObject( pEdgeObj
.get() );
188 pEdgeObj
= new SdrEdgeObj(pView
->getSdrModelFromSdrView());
194 void SvxXConnectionPreview::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
&)
196 rRenderContext
.Push(vcl::PushFlags::ALL
);
198 rRenderContext
.SetMapMode(GetMapMode());
200 const StyleSettings
& rStyles
= Application::GetSettings().GetStyleSettings();
201 rRenderContext
.SetDrawMode(rStyles
.GetHighContrastMode() ? OUTPUT_DRAWMODE_CONTRAST
: OUTPUT_DRAWMODE_COLOR
);
202 rRenderContext
.SetBackground(Wallpaper(rStyles
.GetFieldColor()));
206 // This will not work anymore. To not start at Adam and Eve, i will
207 // ATM not try to change all this stuff to really using an own model
208 // and a view. I will just try to provide a mechanism to paint such
209 // objects without own model and without a page/view with the new
212 // New stuff: Use an ObjectContactOfObjListPainter.
213 sdr::contact::SdrObjectVector aObjectVector
;
215 for (size_t a
= 0; a
< mxSdrPage
->GetObjCount(); ++a
)
217 SdrObject
* pObject
= mxSdrPage
->GetObj(a
);
219 "SvxXConnectionPreview::Paint: Corrupt ObjectList (!)");
220 aObjectVector
.push_back(pObject
);
223 sdr::contact::ObjectContactOfObjListPainter
aPainter(rRenderContext
, std::move(aObjectVector
), nullptr);
224 sdr::contact::DisplayInfo aDisplayInfo
;
227 aPainter
.ProcessDisplay(aDisplayInfo
);
230 rRenderContext
.Pop();
233 void SvxXConnectionPreview::SetAttributes( const SfxItemSet
& rInAttrs
)
235 pEdgeObj
->SetMergedItemSetAndBroadcast(rInAttrs
);
240 // Get number of lines which are offset based on the preview object
242 sal_uInt16
SvxXConnectionPreview::GetLineDeltaCount() const
244 const SfxItemSet
& rSet
= pEdgeObj
->GetMergedItemSet();
245 sal_uInt16
nCount(0);
247 if(SfxItemState::DONTCARE
!= rSet
.GetItemState(SDRATTR_EDGELINEDELTACOUNT
))
248 nCount
= rSet
.Get(SDRATTR_EDGELINEDELTACOUNT
).GetValue();
253 bool SvxXConnectionPreview::MouseButtonDown( const MouseEvent
& rMEvt
)
255 bool bZoomIn
= rMEvt
.IsLeft() && !rMEvt
.IsShift();
256 bool bZoomOut
= rMEvt
.IsRight() || rMEvt
.IsShift();
257 bool bCtrl
= rMEvt
.IsMod1();
259 if( bZoomIn
|| bZoomOut
)
261 MapMode aMapMode
= GetMapMode();
262 Fraction aXFrac
= aMapMode
.GetScaleX();
263 Fraction aYFrac
= aMapMode
.GetScaleY();
264 std::unique_ptr
<Fraction
> pMultFrac
;
269 pMultFrac
.reset(new Fraction( 3, 2 ));
271 pMultFrac
.reset(new Fraction( 11, 10 ));
276 pMultFrac
.reset(new Fraction( 2, 3 ));
278 pMultFrac
.reset(new Fraction( 10, 11 ));
281 aXFrac
*= *pMultFrac
;
282 aYFrac
*= *pMultFrac
;
283 if( static_cast<double>(aXFrac
) > 0.001 && static_cast<double>(aXFrac
) < 1000.0 &&
284 static_cast<double>(aYFrac
) > 0.001 && static_cast<double>(aYFrac
) < 1000.0 )
286 aMapMode
.SetScaleX( aXFrac
);
287 aMapMode
.SetScaleY( aYFrac
);
288 SetMapMode( aMapMode
);
290 Size
aOutSize(GetOutputSizePixel());
291 aOutSize
= GetDrawingArea()->get_ref_device().PixelToLogic(aOutSize
);
293 Point
aPt( aMapMode
.GetOrigin() );
294 tools::Long nX
= static_cast<tools::Long
>( ( static_cast<double>(aOutSize
.Width()) - ( static_cast<double>(aOutSize
.Width()) * static_cast<double>(*pMultFrac
) ) ) / 2.0 + 0.5 );
295 tools::Long nY
= static_cast<tools::Long
>( ( static_cast<double>(aOutSize
.Height()) - ( static_cast<double>(aOutSize
.Height()) * static_cast<double>(*pMultFrac
) ) ) / 2.0 + 0.5 );
299 aMapMode
.SetOrigin( aPt
);
300 SetMapMode( aMapMode
);
309 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */