xref: /trunk/main/svx/source/dialog/connctrl.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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