Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / svx / source / dialog / connctrl.cxx
blobebf0c44c27f9ac2cd8dd41a5e7da0acb204a4dc3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
34 #include <memory>
36 SvxXConnectionPreview::SvxXConnectionPreview()
37 : pView(nullptr)
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()
56 AdaptSize();
58 Invalidate();
61 void SvxXConnectionPreview::AdaptSize()
63 // Adapt size
64 if( !mxSdrPage )
65 return;
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 );
77 Point aNewPos;
78 Size aNewSize;
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)
83 return;
84 double fRectWH = static_cast<double>(aRect.GetWidth()) / aRect.GetHeight();
85 if (nHeight == 0)
86 return;
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 );
95 else
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 );
105 // Implement MapMode
106 aDisplayMap.SetScaleX( aMinFrac );
107 aDisplayMap.SetScaleY( aMinFrac );
109 // Centering
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 );
116 // Origin
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 )
135 bool bFound = false;
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 )
144 bFound = true;
146 // potential memory leak here (!). Create SdrObjList only when there is
147 // not yet one.
148 if(!mxSdrPage)
150 mxSdrPage = new SdrPage(
151 pView->getSdrModelFromSdrView(),
152 false);
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 );
167 if( pTmpObj1 )
169 rtl::Reference<SdrObject> pObj1 = pTmpObj1->CloneSdrObject(mxSdrPage->getSdrModelFromSdrPage());
170 mxSdrPage->InsertObject( pObj1.get() );
171 pEdgeObj->ConnectToNode( true, pObj1.get() );
174 if( pTmpObj2 )
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() );
186 if( !pEdgeObj )
188 pEdgeObj = new SdrEdgeObj(pView->getSdrModelFromSdrView());
191 AdaptSize();
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()));
204 if (mxSdrPage)
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
210 // mechanism.
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);
218 DBG_ASSERT(pObject,
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;
226 // do processing
227 aPainter.ProcessDisplay(aDisplayInfo);
230 rRenderContext.Pop();
233 void SvxXConnectionPreview::SetAttributes( const SfxItemSet& rInAttrs )
235 pEdgeObj->SetMergedItemSetAndBroadcast(rInAttrs);
237 Invalidate();
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();
250 return nCount;
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;
266 if( bZoomIn )
268 if( bCtrl )
269 pMultFrac.reset(new Fraction( 3, 2 ));
270 else
271 pMultFrac.reset(new Fraction( 11, 10 ));
273 else
275 if( bCtrl )
276 pMultFrac.reset(new Fraction( 2, 3 ));
277 else
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 );
296 aPt.AdjustX(nX );
297 aPt.AdjustY(nY );
299 aMapMode.SetOrigin( aPt );
300 SetMapMode( aMapMode );
302 Invalidate();
306 return true;
309 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */