xref: /aoo41x/main/svx/source/dialog/connctrl.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 // include ---------------------------------------------------------------
32 
33 #include <svx/svdoedge.hxx>
34 #include <svx/svdattrx.hxx>
35 #include <svx/svdmark.hxx>
36 #include <svx/svdview.hxx>
37 
38 #include <svx/svdpage.hxx> // SdrObjList
39 
40 #include "svx/connctrl.hxx"
41 #include <svx/dialmgr.hxx>
42 #include "svx/dlgutil.hxx"
43 
44 // #110094#
45 #include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
46 
47 // #110094#
48 #include <svx/sdr/contact/displayinfo.hxx>
49 #include <vcl/svapp.hxx>
50 
51 /*************************************************************************
52 |*
53 |* Ctor SvxXConnectionPreview
54 |*
55 *************************************************************************/
56 
57 SvxXConnectionPreview::SvxXConnectionPreview( Window* pParent, const ResId& rResId,
58 							const SfxItemSet& rInAttrs ) :
59 							Control	( pParent, rResId ),
60                             rAttrs  ( rInAttrs ),
61                             pEdgeObj( NULL ),
62 							pObjList( NULL ),
63                             pView   ( NULL )
64 {
65 	SetMapMode( MAP_100TH_MM );
66 	SetStyles();
67 }
68 
69 /*************************************************************************
70 |*
71 |* Dtor SvxXConnectionPreview
72 |*
73 *************************************************************************/
74 
75 SvxXConnectionPreview::~SvxXConnectionPreview()
76 {
77 	delete pObjList;
78 }
79 
80 /*************************************************************************
81 |*
82 |* Dtor SvxXConnectionPreview
83 |*
84 *************************************************************************/
85 
86 void SvxXConnectionPreview::Construct()
87 {
88 	DBG_ASSERT( pView, "Keine gueltige View Uebergeben!" );
89 
90 	const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
91 	sal_uIntPtr nMarkCount = rMarkList.GetMarkCount();
92 
93 	if( nMarkCount >= 1 )
94 	{
95 		sal_Bool bFound = sal_False;
96 		const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
97 
98 
99 		for( sal_uInt16 i = 0; i < nMarkCount && !bFound; i++ )
100 		{
101 			pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
102 			sal_uInt32 nInv = pObj->GetObjInventor();
103 			sal_uInt16 nId = pObj->GetObjIdentifier();
104 			if( nInv == SdrInventor && nId == OBJ_EDGE )
105 			{
106 				bFound = sal_True;
107 				SdrEdgeObj* pTmpEdgeObj = (SdrEdgeObj*) pObj;
108 				pEdgeObj = (SdrEdgeObj*) pTmpEdgeObj->Clone();
109 
110 				SdrObjConnection& rConn1 = (SdrObjConnection&)pEdgeObj->GetConnection( sal_True );
111 				SdrObjConnection& rConn2 = (SdrObjConnection&)pEdgeObj->GetConnection( sal_False );
112 
113 				rConn1 = pTmpEdgeObj->GetConnection( sal_True );
114 				rConn2 = pTmpEdgeObj->GetConnection( sal_False );
115 
116 				SdrObject* pTmpObj1 = pTmpEdgeObj->GetConnectedNode( sal_True );
117 				SdrObject* pTmpObj2 = pTmpEdgeObj->GetConnectedNode( sal_False );
118 
119 				// #110094#
120 				// potential memory leak here (!). Create SdrObjList only when there is
121 				// not yet one.
122 				if(!pObjList)
123 				{
124 					pObjList = new SdrObjList( pView->GetModel(), NULL );
125 				}
126 
127 				if( pTmpObj1 )
128 				{
129 					SdrObject* pObj1 = pTmpObj1->Clone();
130 					pObjList->InsertObject( pObj1 );
131 					pEdgeObj->ConnectToNode( sal_True, pObj1 );
132 				}
133 				if( pTmpObj2 )
134 				{
135 					SdrObject* pObj2 = pTmpObj2->Clone();
136 					pObjList->InsertObject( pObj2 );
137 					pEdgeObj->ConnectToNode( sal_False, pObj2 );
138 				}
139 				pObjList->InsertObject( pEdgeObj );
140 			}
141 		}
142 	}
143 
144 	if( !pEdgeObj )
145 		pEdgeObj = new SdrEdgeObj();
146 
147 	// Groesse anpassen
148 	if( pObjList )
149 	{
150 		OutputDevice* pOD = pView->GetFirstOutputDevice(); // GetWin( 0 );
151 		Rectangle aRect = pObjList->GetAllObjBoundRect();
152 
153 		MapMode aMapMode = GetMapMode();
154 		aMapMode.SetMapUnit( pOD->GetMapMode().GetMapUnit() );
155 		SetMapMode( aMapMode );
156 
157 		MapMode			aDisplayMap( aMapMode );
158 		Point			aNewPos;
159 		Size			aNewSize;
160 		const Size		aWinSize = PixelToLogic( GetOutputSizePixel(), aDisplayMap );
161 		const long		nWidth = aWinSize.Width();
162 		const long		nHeight = aWinSize.Height();
163 		double          fRectWH = (double) aRect.GetWidth() / aRect.GetHeight();
164 		double          fWinWH = (double) nWidth / nHeight;
165 
166 		// Bitmap an Thumbgroesse anpassen (hier nicht!)
167 		if ( fRectWH < fWinWH)
168 		{
169 			aNewSize.Width() = (long) ( (double) nHeight * fRectWH );
170 			aNewSize.Height()= nHeight;
171 		}
172 		else
173 		{
174 			aNewSize.Width() = nWidth;
175 			aNewSize.Height()= (long) ( (double) nWidth / fRectWH );
176 		}
177 
178 		Fraction aFrac1( aWinSize.Width(), aRect.GetWidth() );
179 		Fraction aFrac2( aWinSize.Height(), aRect.GetHeight() );
180 		Fraction aMinFrac( aFrac1 <= aFrac2 ? aFrac1 : aFrac2 );
181 
182 		// MapMode umsetzen
183 		aDisplayMap.SetScaleX( aMinFrac );
184 		aDisplayMap.SetScaleY( aMinFrac );
185 
186 		// Zentrierung
187 		aNewPos.X() = ( nWidth - aNewSize.Width() )  >> 1;
188 		aNewPos.Y() = ( nHeight - aNewSize.Height() ) >> 1;
189 
190 		aDisplayMap.SetOrigin( LogicToLogic( aNewPos, aMapMode, aDisplayMap ) );
191 		SetMapMode( aDisplayMap );
192 
193 		// Ursprung
194 		aNewPos = aDisplayMap.GetOrigin();
195 		aNewPos -= Point( aRect.TopLeft().X(), aRect.TopLeft().Y() );
196 		aDisplayMap.SetOrigin( aNewPos );
197 		SetMapMode( aDisplayMap );
198 
199 
200 		Point aPos;
201 		MouseEvent aMEvt( aPos, 1, 0, MOUSE_RIGHT );
202 		MouseButtonDown( aMEvt );
203 		/*
204 		Point aPt( -aRect.TopLeft().X(), -aRect.TopLeft().Y() );
205 		aMapMode.SetOrigin( aPt );
206 
207 		// Skalierung
208 		Size aSize = GetOutputSize();
209 		Fraction aFrac1( aSize.Width(), aRect.GetWidth() );
210 		Fraction aFrac2( aSize.Height(), aRect.GetHeight() );
211 		Fraction aMaxFrac( aFrac1 > aFrac2 ? aFrac1 : aFrac2 );
212 		Fraction aMinFrac( aFrac1 <= aFrac2 ? aFrac1 : aFrac2 );
213 		sal_Bool bChange = (sal_Bool) ( (double)aMinFrac > 1.0 );
214 		aMapMode.SetScaleX( aMinFrac );
215 		aMapMode.SetScaleY( aMinFrac );
216 
217 		// zentrieren
218 		long nXXL = aSize.Width() > aRect.GetWidth() ? aSize.Width() : aRect.GetWidth();
219 		long nXS = aSize.Width() <= aRect.GetWidth() ? aSize.Width() : aRect.GetWidth();
220 		if( bChange )
221 		{
222 			long nTmp = nXXL; nXXL = nXS; nXS = nTmp;
223 		}
224 		long nX = (long) ( (double)aMinFrac * (double)nXXL );
225 		nX = (long) ( (double)labs( nXS - nX ) / (double)aMinFrac / 2.0 );
226 
227 		long nYXL = aSize.Height() > aRect.GetHeight() ? aSize.Height() : aRect.GetHeight();
228 		long nYS = aSize.Height() <= aRect.GetHeight() ? aSize.Height() : aRect.GetHeight();
229 		if( bChange )
230 		{
231 			long nTmp = nXXL; nXXL = nXS; nXS = nTmp;
232 		}
233 		long nY = (long) ( (double)aMinFrac * (double)nYXL );
234 		nY = (long) ( (double)labs( nYS - nY ) / (double)aMinFrac / 2.0 );
235 
236 		aPt += Point( nX, nY );
237 		aMapMode.SetOrigin( aPt );
238 
239 		SetMapMode( aMapMode );
240 		*/
241 	}
242 }
243 
244 /*************************************************************************
245 |*
246 |* SvxXConnectionPreview: Paint()
247 |*
248 *************************************************************************/
249 
250 void SvxXConnectionPreview::Paint( const Rectangle& )
251 {
252 	if( pObjList )
253 	{
254 		// #110094#
255 		// This will not work anymore. To not start at Adam and Eve, i will
256 		// ATM not try to change all this stuff to really using an own model
257 		// and a view. I will just try to provide a mechanism to paint such
258 		// objects without own model and without a page/view with the new
259 		// mechanism.
260 
261 		// New stuff: Use a ObjectContactOfObjListPainter.
262 		sdr::contact::SdrObjectVector aObjectVector;
263 
264 		for(sal_uInt32 a(0L); a < pObjList->GetObjCount(); a++)
265 		{
266 			SdrObject* pObject = pObjList->GetObj(a);
267 			DBG_ASSERT(pObject,
268 				"SvxXConnectionPreview::Paint: Corrupt ObjectList (!)");
269 			aObjectVector.push_back(pObject);
270 		}
271 
272 		sdr::contact::ObjectContactOfObjListPainter aPainter(*this, aObjectVector, 0);
273 		sdr::contact::DisplayInfo aDisplayInfo;
274 
275 		// do processing
276 		aPainter.ProcessDisplay(aDisplayInfo);
277 	}
278 }
279 
280 /*************************************************************************
281 |*
282 |* SvxXConnectionPreview: SetAttributes()
283 |*
284 *************************************************************************/
285 
286 void SvxXConnectionPreview::SetAttributes( const SfxItemSet& rInAttrs )
287 {
288 	//pEdgeObj->SetItemSetAndBroadcast(rInAttrs);
289 	pEdgeObj->SetMergedItemSetAndBroadcast(rInAttrs);
290 
291 	Invalidate();
292 }
293 
294 /*************************************************************************
295 |*
296 |* Ermittelt die Anzahl der Linienversaetze anhand des Preview-Objektes
297 |*
298 *************************************************************************/
299 
300 sal_uInt16 SvxXConnectionPreview::GetLineDeltaAnz()
301 {
302 	const SfxItemSet& rSet = pEdgeObj->GetMergedItemSet();
303 	sal_uInt16 nCount(0);
304 
305 	if(SFX_ITEM_DONTCARE != rSet.GetItemState(SDRATTR_EDGELINEDELTAANZ))
306 		nCount = ((const SdrEdgeLineDeltaAnzItem&)rSet.Get(SDRATTR_EDGELINEDELTAANZ)).GetValue();
307 
308 	return nCount;
309 }
310 
311 /*************************************************************************
312 |*
313 |* SvxXConnectionPreview: MouseButtonDown()
314 |*
315 *************************************************************************/
316 
317 void SvxXConnectionPreview::MouseButtonDown( const MouseEvent& rMEvt )
318 {
319 	sal_Bool bZoomIn  = rMEvt.IsLeft() && !rMEvt.IsShift();
320 	sal_Bool bZoomOut = rMEvt.IsRight() || rMEvt.IsShift();
321 	sal_Bool bCtrl	  = rMEvt.IsMod1();
322 
323 	if( bZoomIn || bZoomOut )
324 	{
325 		MapMode aMapMode = GetMapMode();
326 		Fraction aXFrac = aMapMode.GetScaleX();
327 		Fraction aYFrac = aMapMode.GetScaleY();
328 		Fraction* pMultFrac;
329 
330 		if( bZoomIn )
331 		{
332 			if( bCtrl )
333 				pMultFrac = new Fraction( 3, 2 );
334 			else
335 				pMultFrac = new Fraction( 11, 10 );
336 		}
337 		else
338 		{
339 			if( bCtrl )
340 				pMultFrac = new Fraction( 2, 3 );
341 			else
342 				pMultFrac = new Fraction( 10, 11 );
343 		}
344 
345 		aXFrac *= *pMultFrac;
346 		aYFrac *= *pMultFrac;
347 		if( (double)aXFrac > 0.001 && (double)aXFrac < 1000.0 &&
348 			(double)aYFrac > 0.001 && (double)aYFrac < 1000.0 )
349 		{
350 			aMapMode.SetScaleX( aXFrac );
351 			aMapMode.SetScaleY( aYFrac );
352 			SetMapMode( aMapMode );
353 
354 			Size aOutSize( GetOutputSize() );
355 
356 			Point aPt( aMapMode.GetOrigin() );
357 			long nX = (long)( ( (double)aOutSize.Width() - ( (double)aOutSize.Width() * (double)*pMultFrac  ) ) / 2.0 + 0.5 );
358 			long nY = (long)( ( (double)aOutSize.Height() - ( (double)aOutSize.Height() * (double)*pMultFrac  ) ) / 2.0 + 0.5 );
359 			aPt.X() +=  nX;
360 			aPt.Y() +=  nY;
361 
362 			aMapMode.SetOrigin( aPt );
363 			SetMapMode( aMapMode );
364 
365 			Invalidate();
366 		}
367 		delete pMultFrac;
368 	}
369 }
370 
371 void SvxXConnectionPreview::SetStyles()
372 {
373 	const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings();
374 	SetDrawMode( GetSettings().GetStyleSettings().GetHighContrastMode() ? OUTPUT_DRAWMODE_CONTRAST : OUTPUT_DRAWMODE_COLOR );
375 	SetBackground( Wallpaper( Color( rStyles.GetFieldColor() ) ) );
376 }
377 
378 void SvxXConnectionPreview::DataChanged( const DataChangedEvent& rDCEvt )
379 {
380 	Control::DataChanged( rDCEvt );
381 
382 	if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
383 	{
384 		SetStyles();
385 	}
386 }
387 
388