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