xref: /aoo42x/main/sd/source/ui/func/fuconbez.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_sd.hxx"
30 
31 #include <com/sun/star/presentation/EffectNodeType.hpp>
32 
33 #include "fuconbez.hxx"
34 #include <svl/aeitem.hxx>
35 #include <svx/svdopath.hxx>
36 #include <svl/intitem.hxx>
37 #include <sfx2/dispatch.hxx>
38 #include <svx/svdobj.hxx>
39 #include <sfx2/bindings.hxx>
40 #include <sfx2/request.hxx>
41 #include <sfx2/viewfrm.hxx>
42 
43 
44 #include <svx/svxids.hrc>
45 #include <svx/svdpagv.hxx>
46 
47 #include "app.hrc"
48 #include "ViewShell.hxx"
49 #include "ViewShellBase.hxx"
50 #include "View.hxx"
51 #include "Window.hxx"
52 #include "ToolBarManager.hxx"
53 #include "drawdoc.hxx"
54 #include "res_bmp.hrc"
55 #include <basegfx/polygon/b2dpolygon.hxx>
56 #include <basegfx/polygon/b2dpolygontools.hxx>
57 
58 #include "CustomAnimationEffect.hxx"
59 
60 using namespace ::com::sun::star::uno;
61 
62 namespace sd {
63 
64 TYPEINIT1( FuConstructBezierPolygon, FuConstruct );
65 
66 
67 /*************************************************************************
68 |*
69 |* Konstruktor
70 |*
71 \************************************************************************/
72 
73 FuConstructBezierPolygon::FuConstructBezierPolygon (
74     ViewShell* pViewSh,
75     ::sd::Window* pWin,
76     ::sd::View* pView,
77     SdDrawDocument* pDoc,
78     SfxRequest& rReq)
79 	: FuConstruct(pViewSh, pWin, pView, pDoc, rReq),
80       nEditMode(SID_BEZIER_MOVE)
81 {
82 }
83 
84 FunctionReference FuConstructBezierPolygon::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq, bool bPermanent )
85 {
86 	FuConstructBezierPolygon* pFunc;
87 	FunctionReference xFunc( pFunc = new FuConstructBezierPolygon( pViewSh, pWin, pView, pDoc, rReq ) );
88 	xFunc->DoExecute(rReq);
89 	pFunc->SetPermanent(bPermanent);
90 	return xFunc;
91 }
92 
93 void FuConstructBezierPolygon::DoExecute( SfxRequest& rReq )
94 {
95 	FuConstruct::DoExecute( rReq );
96 
97 	const SfxItemSet* pArgs = rReq.GetArgs();
98 	if( pArgs )
99 	{
100 		const SfxPoolItem*  pPoolItem = NULL;
101 		if( SFX_ITEM_SET == pArgs->GetItemState( SID_ADD_MOTION_PATH, sal_True, &pPoolItem ) )
102 			maTargets = ( ( const SfxUnoAnyItem* ) pPoolItem )->GetValue();
103 	}
104 }
105 
106 /*************************************************************************
107 |*
108 |* MouseButtonDown-event
109 |*
110 \************************************************************************/
111 
112 sal_Bool FuConstructBezierPolygon::MouseButtonDown(const MouseEvent& rMEvt)
113 {
114 	sal_Bool bReturn = FuConstruct::MouseButtonDown(rMEvt);
115 
116 	SdrViewEvent aVEvt;
117 	SdrHitKind eHit = mpView->PickAnything(rMEvt, SDRMOUSEBUTTONDOWN, aVEvt);
118 
119 	if (eHit == SDRHIT_HANDLE || rMEvt.IsMod1())
120 	{
121 		mpView->SetEditMode(SDREDITMODE_EDIT);
122 	}
123 	else
124 	{
125 		mpView->SetEditMode(SDREDITMODE_CREATE);
126 	}
127 
128 	if (aVEvt.eEvent == SDREVENT_BEGTEXTEDIT)
129 	{
130 		// Texteingabe hier nicht zulassen
131 		aVEvt.eEvent = SDREVENT_BEGDRAGOBJ;
132 		mpView->EnableExtendedMouseEventDispatcher(sal_False);
133 	}
134 	else
135 	{
136 		mpView->EnableExtendedMouseEventDispatcher(sal_True);
137 	}
138 
139 	if (eHit == SDRHIT_MARKEDOBJECT && nEditMode == SID_BEZIER_INSERT)
140 	{
141 		/******************************************************************
142 		* Klebepunkt einfuegen
143 		******************************************************************/
144 		mpView->BegInsObjPoint(aMDPos, rMEvt.IsMod1());
145 	}
146 	else
147 	{
148 		mpView->MouseButtonDown(rMEvt, mpWindow);
149 
150 		SdrObject* pObj = mpView->GetCreateObj();
151 
152 		if (pObj)
153 		{
154 			SfxItemSet aAttr(mpDoc->GetPool());
155 			SetStyleSheet(aAttr, pObj);
156 			pObj->SetMergedItemSet(aAttr);
157 		}
158 	}
159 
160 	return(bReturn);
161 }
162 
163 /*************************************************************************
164 |*
165 |* MouseMove-event
166 |*
167 \************************************************************************/
168 
169 sal_Bool FuConstructBezierPolygon::MouseMove(const MouseEvent& rMEvt)
170 {
171 	sal_Bool bReturn = FuConstruct::MouseMove(rMEvt);
172 	return(bReturn);
173 }
174 
175 /*************************************************************************
176 |*
177 |* MouseButtonUp-event
178 |*
179 \************************************************************************/
180 
181 sal_Bool FuConstructBezierPolygon::MouseButtonUp(const MouseEvent& rMEvt )
182 {
183 	sal_Bool bReturn = sal_False;
184 	sal_Bool bCreated = sal_False;
185 
186 	SdrViewEvent aVEvt;
187 	mpView->PickAnything(rMEvt, SDRMOUSEBUTTONUP, aVEvt);
188 
189 	sal_uLong nCount = mpView->GetSdrPageView()->GetObjList()->GetObjCount();
190 
191 	if (mpView->IsInsObjPoint())
192 	{
193 		mpView->EndInsObjPoint(SDRCREATE_FORCEEND);
194 	}
195 	else
196 	{
197 		mpView->MouseButtonUp(rMEvt, mpWindow);
198 	}
199 
200 	if (aVEvt.eEvent == SDREVENT_ENDCREATE)
201 	{
202 		bReturn = sal_True;
203 
204 		if (nCount == (mpView->GetSdrPageView()->GetObjList()->GetObjCount() - 1))
205 		{
206 			bCreated = sal_True;
207 		}
208 
209 		// Trick, um FuDraw::DoubleClick nicht auszuloesen
210 		bMBDown = sal_False;
211 
212 	}
213 
214 	bReturn = FuConstruct::MouseButtonUp(rMEvt) || bReturn;
215 
216 	bool bDeleted = false;
217 	if( bCreated && maTargets.hasValue() )
218 	{
219 		SdrPathObj* pPathObj = dynamic_cast< SdrPathObj* >( mpView->GetSdrPageView()->GetObjList()->GetObj( nCount ) );
220 		SdPage* pPage = dynamic_cast< SdPage* >( pPathObj ? pPathObj->GetPage() : 0 );
221 		if( pPage )
222 		{
223 			boost::shared_ptr< sd::MainSequence > pMainSequence( pPage->getMainSequence() );
224 			if( pMainSequence.get() )
225 			{
226 				Sequence< Any > aTargets;
227 				maTargets >>= aTargets;
228 
229 				sal_Int32 nTCount = aTargets.getLength();
230 				if( nTCount > 1 )
231 				{
232 					const Any* pTarget = aTargets.getConstArray();
233 					double fDuration = 0.0;
234 					*pTarget++ >>= fDuration;
235 					bool bFirst = true;
236 					while( --nTCount )
237 					{
238 						CustomAnimationEffectPtr pCreated( pMainSequence->append( *pPathObj, *pTarget++, fDuration ) );
239 						if( bFirst )
240 							bFirst = false;
241 						else
242 							pCreated->setNodeType( ::com::sun::star::presentation::EffectNodeType::WITH_PREVIOUS );
243 					}
244 				}
245 			}
246 		}
247 		mpView->DeleteMarked();
248 		bDeleted = true;
249 	}
250 
251 	if ((!bPermanent && bCreated) || bDeleted)
252 	{
253 		mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SFX_CALLMODE_ASYNCHRON);
254 	}
255 
256 	return(bReturn);
257 }
258 
259 /*************************************************************************
260 |*
261 |* Tastaturereignisse bearbeiten
262 |*
263 |* Wird ein KeyEvent bearbeitet, so ist der Return-Wert sal_True, andernfalls
264 |* sal_False.
265 |*
266 \************************************************************************/
267 
268 sal_Bool FuConstructBezierPolygon::KeyInput(const KeyEvent& rKEvt)
269 {
270 	sal_Bool bReturn = FuConstruct::KeyInput(rKEvt);
271 
272 	return(bReturn);
273 }
274 
275 /*************************************************************************
276 |*
277 |* Function aktivieren
278 |*
279 \************************************************************************/
280 
281 void FuConstructBezierPolygon::Activate()
282 {
283 	mpView->EnableExtendedMouseEventDispatcher(sal_True);
284 
285 	SdrObjKind eKind;
286 
287 	switch (nSlotId)
288 	{
289 		case SID_DRAW_POLYGON_NOFILL:
290 		case SID_DRAW_XPOLYGON_NOFILL:
291 		{
292 			eKind = OBJ_PLIN;
293 		}
294 		break;
295 
296 		case SID_DRAW_POLYGON:
297 		case SID_DRAW_XPOLYGON:
298 		{
299 			eKind = OBJ_POLY;
300 		}
301 		break;
302 
303 		case SID_DRAW_BEZIER_NOFILL:
304 		{
305 			eKind = OBJ_PATHLINE;
306 		}
307 		break;
308 
309 		case SID_DRAW_BEZIER_FILL:
310 		{
311 			eKind = OBJ_PATHFILL;
312 		}
313 		break;
314 
315 		case SID_DRAW_FREELINE_NOFILL:
316 		{
317 			eKind = OBJ_FREELINE;
318 		}
319 		break;
320 
321 		case SID_DRAW_FREELINE:
322 		{
323 			eKind = OBJ_FREEFILL;
324 		}
325 		break;
326 
327 		default:
328 		{
329 			eKind = OBJ_PATHLINE;
330 		}
331 		break;
332 	}
333 
334 	mpView->SetCurrentObj((sal_uInt16)eKind);
335 
336 	FuConstruct::Activate();
337 }
338 
339 /*************************************************************************
340 |*
341 |* Function deaktivieren
342 |*
343 \************************************************************************/
344 
345 void FuConstructBezierPolygon::Deactivate()
346 {
347 	mpView->EnableExtendedMouseEventDispatcher(sal_False);
348 
349 	FuConstruct::Deactivate();
350 }
351 
352 
353 /*************************************************************************
354 |*
355 |* Selektion hat sich geaendert
356 |*
357 \************************************************************************/
358 
359 void FuConstructBezierPolygon::SelectionHasChanged()
360 {
361 	FuDraw::SelectionHasChanged();
362 
363 	mpViewShell->GetViewShellBase().GetToolBarManager()->SelectionHasChanged(
364         *mpViewShell,
365         *mpView);
366 }
367 
368 
369 
370 /*************************************************************************
371 |*
372 |* Aktuellen Bezier-Editmodus setzen
373 |*
374 \************************************************************************/
375 
376 void FuConstructBezierPolygon::SetEditMode(sal_uInt16 nMode)
377 {
378 	nEditMode = nMode;
379 	ForcePointer();
380 
381 	SfxBindings& rBindings = mpViewShell->GetViewFrame()->GetBindings();
382 	rBindings.Invalidate(SID_BEZIER_MOVE);
383 	rBindings.Invalidate(SID_BEZIER_INSERT);
384 }
385 
386 // #97016#
387 SdrObject* FuConstructBezierPolygon::CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle)
388 {
389 	// case SID_DRAW_POLYGON:
390 	// case SID_DRAW_POLYGON_NOFILL:
391 	// case SID_DRAW_XPOLYGON:
392 	// case SID_DRAW_XPOLYGON_NOFILL:
393 	// case SID_DRAW_FREELINE:
394 	// case SID_DRAW_FREELINE_NOFILL:
395 	// case SID_DRAW_BEZIER_FILL:          // BASIC
396 	// case SID_DRAW_BEZIER_NOFILL:        // BASIC
397 
398 	SdrObject* pObj = SdrObjFactory::MakeNewObject(
399 		mpView->GetCurrentObjInventor(), mpView->GetCurrentObjIdentifier(),
400 		0L, mpDoc);
401 
402 	if(pObj)
403 	{
404 		if(pObj->ISA(SdrPathObj))
405 		{
406 			basegfx::B2DPolyPolygon aPoly;
407 
408 			switch(nID)
409 			{
410 				case SID_DRAW_BEZIER_FILL:
411 				{
412 					const sal_Int32 nWdt(rRectangle.GetWidth() / 2);
413 					const sal_Int32 nHgt(rRectangle.GetHeight() / 2);
414 					const basegfx::B2DPolygon aInnerPoly(basegfx::tools::createPolygonFromEllipse(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y()), nWdt, nHgt));
415 
416 					aPoly.append(aInnerPoly);
417 					break;
418 				}
419 				case SID_DRAW_BEZIER_NOFILL:
420 				{
421 					basegfx::B2DPolygon aInnerPoly;
422 
423 					aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
424 
425 					const basegfx::B2DPoint aCenterBottom(rRectangle.Center().X(), rRectangle.Bottom());
426 					aInnerPoly.appendBezierSegment(
427 						aCenterBottom,
428 						aCenterBottom,
429 						basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y()));
430 
431 					const basegfx::B2DPoint aCenterTop(rRectangle.Center().X(), rRectangle.Top());
432 					aInnerPoly.appendBezierSegment(
433 						aCenterTop,
434 						aCenterTop,
435 						basegfx::B2DPoint(rRectangle.Right(), rRectangle.Top()));
436 
437 					aPoly.append(aInnerPoly);
438 					break;
439 				}
440 				case SID_DRAW_FREELINE:
441 				case SID_DRAW_FREELINE_NOFILL:
442 				{
443 					basegfx::B2DPolygon aInnerPoly;
444 
445 					aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
446 
447 					aInnerPoly.appendBezierSegment(
448 						basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top()),
449 						basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Top()),
450 						basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y()));
451 
452 					aInnerPoly.appendBezierSegment(
453 						basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Bottom()),
454 						basegfx::B2DPoint(rRectangle.Right(), rRectangle.Bottom()),
455 						basegfx::B2DPoint(rRectangle.Right(), rRectangle.Top()));
456 
457 					if(SID_DRAW_FREELINE == nID)
458 					{
459 						aInnerPoly.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Bottom()));
460 					}
461 					else
462 					{
463 						aInnerPoly.setClosed(true);
464 					}
465 
466 					aPoly.append(aInnerPoly);
467 					break;
468 				}
469 				case SID_DRAW_XPOLYGON:
470 				case SID_DRAW_XPOLYGON_NOFILL:
471 				{
472 					basegfx::B2DPolygon aInnerPoly;
473 
474 					aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
475 					aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top()));
476 					aInnerPoly.append(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Top()));
477 					aInnerPoly.append(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y()));
478 					aInnerPoly.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Center().Y()));
479 					aInnerPoly.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Bottom()));
480 
481 					if(SID_DRAW_XPOLYGON_NOFILL == nID)
482 					{
483 						aInnerPoly.append(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Bottom()));
484 					}
485 					else
486 					{
487 						aInnerPoly.setClosed(true);
488 					}
489 
490 					aPoly.append(aInnerPoly);
491 					break;
492 				}
493 				case SID_DRAW_POLYGON:
494 				case SID_DRAW_POLYGON_NOFILL:
495 				{
496 					basegfx::B2DPolygon aInnerPoly;
497 					const sal_Int32 nWdt(rRectangle.GetWidth());
498 					const sal_Int32 nHgt(rRectangle.GetHeight());
499 
500 					aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
501 					aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 30) / 100, rRectangle.Top() + (nHgt * 70) / 100));
502 					aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top() + (nHgt * 15) / 100));
503 					aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 65) / 100, rRectangle.Top()));
504 					aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + nWdt, rRectangle.Top() + (nHgt * 30) / 100));
505 					aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 80) / 100, rRectangle.Top() + (nHgt * 50) / 100));
506 					aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 80) / 100, rRectangle.Top() + (nHgt * 75) / 100));
507 					aInnerPoly.append(basegfx::B2DPoint(rRectangle.Bottom(), rRectangle.Right()));
508 
509 					if(SID_DRAW_POLYGON_NOFILL == nID)
510 					{
511 						aInnerPoly.append(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Bottom()));
512 					}
513 					else
514 					{
515 						aInnerPoly.setClosed(true);
516 					}
517 
518 					aPoly.append(aInnerPoly);
519 					break;
520 				}
521 			}
522 
523 			((SdrPathObj*)pObj)->SetPathPoly(aPoly);
524 		}
525 		else
526 		{
527 			DBG_ERROR("Object is NO path object");
528 		}
529 
530 		pObj->SetLogicRect(rRectangle);
531 	}
532 
533 	return pObj;
534 }
535 
536 } // end of namespace sd
537 
538 // eof
539