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 "SdUnoDrawView.hxx"
32 
33 #include "DrawController.hxx"
34 #include "DrawDocShell.hxx"
35 #include "DrawViewShell.hxx"
36 #include "drawdoc.hxx"
37 #include "unolayer.hxx"
38 #include "unomodel.hxx"
39 #include "unopage.hxx"
40 #include "Window.hxx"
41 #include "pres.hxx"
42 
43 #include <cppuhelper/proptypehlp.hxx>
44 #include <comphelper/serviceinfohelper.hxx>
45 #include <sfx2/dispatch.hxx>
46 #include <sfx2/viewfrm.hxx>
47 #include <svx/svdpagv.hxx>
48 #include <svx/unoshape.hxx>
49 #include <svx/unoshcol.hxx>
50 #include <svx/zoomitem.hxx>
51 #include <com/sun/star/drawing/DrawViewMode.hpp>
52 #include <com/sun/star/drawing/XLayerManager.hpp>
53 #include <com/sun/star/view/DocumentZoomType.hpp>
54 
55 #include <vector>
56 
57 using rtl::OUString;
58 
59 using namespace ::com::sun::star;
60 using namespace ::com::sun::star::uno;
61 using namespace ::com::sun::star::drawing;
62 
63 
64 namespace sd {
65 
66 SdUnoDrawView::SdUnoDrawView(
67     DrawController& rController,
68     DrawViewShell& rViewShell,
69     View& rView) throw()
70     :	DrawSubControllerInterfaceBase(m_aMutex),
71         mrController(rController),
72         mrDrawViewShell(rViewShell),
73         mrView(rView)
74 {
75 }
76 
77 
78 
79 
80 SdUnoDrawView::~SdUnoDrawView() throw()
81 {
82 }
83 
84 
85 
86 
87 sal_Bool SdUnoDrawView::getMasterPageMode(void) const throw()
88 {
89     return (mrDrawViewShell.GetEditMode() == EM_MASTERPAGE);
90 }
91 
92 
93 
94 
95 void SdUnoDrawView::setMasterPageMode (sal_Bool bMasterPageMode) throw()
96 {
97 	if ((mrDrawViewShell.GetEditMode() == EM_MASTERPAGE) != bMasterPageMode)
98     {
99         mrDrawViewShell.ChangeEditMode (
100             bMasterPageMode ? EM_MASTERPAGE : EM_PAGE,
101             mrDrawViewShell.IsLayerModeActive());
102     }
103 }
104 
105 
106 
107 
108 sal_Bool SdUnoDrawView::getLayerMode(void) const throw()
109 {
110     return mrDrawViewShell.IsLayerModeActive();
111 }
112 
113 
114 
115 
116 void SdUnoDrawView::setLayerMode (sal_Bool bLayerMode) throw()
117 {
118 	if (mrDrawViewShell.IsLayerModeActive() != (bLayerMode==sal_True))
119     {
120         mrDrawViewShell.ChangeEditMode (
121             mrDrawViewShell.GetEditMode(),
122             bLayerMode);
123     }
124 }
125 
126 
127 
128 
129 Reference<drawing::XLayer> SdUnoDrawView::getActiveLayer (void) throw ()
130 {
131     Reference<drawing::XLayer> xCurrentLayer;
132 
133     do
134     {
135         // Retrieve the layer manager from the model.
136         SdXImpressDocument* pModel = GetModel();
137         if (pModel == NULL)
138             break;
139 
140         SdDrawDocument* pSdModel = pModel->GetDoc();
141         if (pSdModel == NULL)
142             break;
143 
144         // From the model get the current SdrLayer object via the layer admin.
145         SdrLayerAdmin& rLayerAdmin = pSdModel->GetLayerAdmin ();
146         SdrLayer* pLayer = rLayerAdmin.GetLayer (mrView.GetActiveLayer(), sal_True);
147         if (pLayer == NULL)
148             break;
149 
150         // Get the corresponding XLayer object from the implementation
151         // object of the layer manager.
152         Reference<drawing::XLayerManager> xManager (pModel->getLayerManager(), uno::UNO_QUERY);
153         SdLayerManager* pManager = SdLayerManager::getImplementation (xManager);
154         if (pManager != NULL)
155             xCurrentLayer = pManager->GetLayer (pLayer);
156     }
157     while (false);
158 
159     return xCurrentLayer;
160 }
161 
162 
163 
164 
165 void SdUnoDrawView::setActiveLayer (const Reference<drawing::XLayer>& rxLayer) throw ()
166 {
167     do
168     {
169         // Get the SdrLayer object corresponding to the given reference.
170         if ( ! rxLayer.is())
171             break;
172 
173         SdLayer* pLayer = SdLayer::getImplementation (rxLayer);
174         if (pLayer == NULL)
175             break;
176 
177         SdrLayer* pSdrLayer = pLayer->GetSdrLayer();
178         if (pSdrLayer == NULL)
179             break;
180 
181         // Set the new active layer and make the change visible.
182         mrView.SetActiveLayer (pSdrLayer->GetName());
183         mrDrawViewShell.ResetActualLayer ();
184     }
185     while (false);
186 }
187 
188 
189 
190 
191 // XSelectionSupplier
192 
193 
194 sal_Bool SAL_CALL SdUnoDrawView::select( const Any& aSelection )
195 	throw(lang::IllegalArgumentException, RuntimeException)
196 {
197     bool bOk = true;
198 
199     ::std::vector<SdrObject*> aObjects;
200 
201     SdrPage* pSdrPage = NULL;
202 
203     Reference< drawing::XShape > xShape;
204     aSelection >>= xShape;
205 
206     if(xShape.is())
207     {
208         SvxShape* pShape = SvxShape::getImplementation( xShape );
209         if( pShape && (pShape->GetSdrObject() != NULL) )
210         {
211             SdrObject* pObj = pShape->GetSdrObject();
212             pSdrPage = pObj->GetPage();
213             aObjects.push_back( pObj );
214         }
215         else
216         {
217             bOk = false;
218         }
219     }
220     else
221     {
222         Reference< drawing::XShapes > xShapes;
223         aSelection >>= xShapes;
224         if( xShapes.is() )
225         {
226             const sal_uInt32 nCount = xShapes->getCount();
227             for( sal_uInt32 i = 0; i < nCount; i++ )
228             {
229                 xShapes->getByIndex(i) >>= xShape;
230                 if( xShape.is() )
231                 {
232                     SvxShape* pShape = SvxShape::getImplementation(xShape);
233                     if( (pShape == NULL) || (pShape->GetSdrObject() == NULL) )
234                     {
235                         bOk = false;
236                         break;
237                     }
238 
239                     SdrObject* pObj = pShape->GetSdrObject();
240 
241                     if( pSdrPage == NULL )
242                     {
243                         pSdrPage = pObj->GetPage();
244                     }
245                     else if( pSdrPage != pObj->GetPage() )
246                     {
247                         bOk = false;
248                         break;
249                     }
250 
251                     aObjects.push_back( pObj );
252                 }
253             }
254         }
255     }
256 
257     if( bOk )
258     {
259         if( pSdrPage )
260         {
261             setMasterPageMode( pSdrPage->IsMasterPage() );
262             mrDrawViewShell.SwitchPage( (pSdrPage->GetPageNum() - 1) >> 1 );
263             mrDrawViewShell.WriteFrameViewData();
264         }
265 
266         SdrPageView *pPV = mrView.GetSdrPageView();
267 
268         if(pPV)
269         {
270             // first deselect all
271             mrView.UnmarkAllObj( pPV );
272 
273             ::std::vector<SdrObject*>::iterator aIter( aObjects.begin() );
274             const ::std::vector<SdrObject*>::iterator aEnd( aObjects.end() );
275             while( aIter != aEnd )
276             {
277                 SdrObject* pObj = (*aIter++);
278                 mrView.MarkObj( pObj, pPV );
279             }
280         }
281         else
282         {
283             bOk = false;
284         }
285     }
286 
287 	return bOk;
288 }
289 
290 //----------------------------------------------------------------------
291 
292 Any SAL_CALL SdUnoDrawView::getSelection()
293 	throw(RuntimeException)
294 {
295 	Any aAny;
296 
297     if( mrView.IsTextEdit() )
298         mrView.getTextSelection( aAny );
299 
300 
301     if( !aAny.hasValue() )
302     {
303         const SdrMarkList& rMarkList = mrView.GetMarkedObjectList();
304         sal_uInt32 nCount = rMarkList.GetMarkCount();
305         if( nCount )
306         {
307             Reference< drawing::XShapes > xShapes( SvxShapeCollection_NewInstance(), UNO_QUERY );
308             for( sal_uInt32 nNum = 0; nNum < nCount; nNum++)
309             {
310                 SdrMark *pMark = rMarkList.GetMark(nNum);
311                 if(pMark==NULL)
312                     continue;
313 
314                 SdrObject *pObj = pMark->GetMarkedSdrObj();
315                 if(pObj==NULL || pObj->GetPage() == NULL)
316                     continue;
317 
318                 Reference< drawing::XDrawPage > xPage( pObj->GetPage()->getUnoPage(), UNO_QUERY);
319 
320                 if(!xPage.is())
321                     continue;
322 
323                 SvxDrawPage* pDrawPage = SvxDrawPage::getImplementation( xPage );
324 
325                 if(pDrawPage==NULL)
326                     continue;
327 
328                 Reference< drawing::XShape > xShape( pObj->getUnoShape(), UNO_QUERY );
329 
330                 if(xShape.is())
331                     xShapes->add(xShape);
332             }
333             aAny <<= xShapes;
334         }
335     }
336 
337 	return aAny;
338 }
339 
340 
341 
342 
343 void SAL_CALL SdUnoDrawView::addSelectionChangeListener (
344     const css::uno::Reference<css::view::XSelectionChangeListener>& rxListener)
345     throw(css::uno::RuntimeException)
346 {
347     (void)rxListener;
348 }
349 
350 
351 
352 
353 void SAL_CALL SdUnoDrawView::removeSelectionChangeListener (
354     const css::uno::Reference<css::view::XSelectionChangeListener>& rxListener)
355     throw(css::uno::RuntimeException)
356 {
357     (void)rxListener;
358 }
359 
360 
361 
362 
363 void SdUnoDrawView::setFastPropertyValue (
364 	sal_Int32 nHandle,
365         const Any& rValue)
366     throw(css::beans::UnknownPropertyException,
367         css::beans::PropertyVetoException,
368         css::lang::IllegalArgumentException,
369         css::lang::WrappedTargetException,
370         css::uno::RuntimeException)
371 {
372 	switch( nHandle )
373 	{
374 		case DrawController::PROPERTY_CURRENTPAGE:
375 			{
376 				Reference< drawing::XDrawPage > xPage;
377 				rValue >>= xPage;
378 				setCurrentPage( xPage );
379 			}
380 			break;
381 
382 		case DrawController::PROPERTY_MASTERPAGEMODE:
383 			{
384 				sal_Bool bValue = sal_False;
385 				rValue >>= bValue;
386 				setMasterPageMode( bValue );
387 			}
388 			break;
389 
390 		case DrawController::PROPERTY_LAYERMODE:
391 			{
392 				sal_Bool bValue = sal_False;
393 				rValue >>= bValue;
394 				setLayerMode( bValue );
395 			}
396 
397 		case DrawController::PROPERTY_ACTIVE_LAYER:
398 			{
399 				Reference<drawing::XLayer> xLayer;
400 				rValue >>= xLayer;
401 				setActiveLayer (xLayer);
402 			}
403 			break;
404 		case DrawController::PROPERTY_ZOOMVALUE:
405 			{
406 				sal_Int16 nZoom = 0;
407 				rValue >>= nZoom;
408 				SetZoom( nZoom );
409 			}
410 			break;
411 		case DrawController::PROPERTY_ZOOMTYPE:
412 			{
413 				sal_Int16 nType = 0;
414 				rValue >>= nType;
415 				SetZoomType( nType );
416 			}
417 			break;
418 		case DrawController::PROPERTY_VIEWOFFSET:
419 			{
420 				awt::Point aOffset;
421 				rValue >>= aOffset;
422 				SetViewOffset( aOffset );
423 			}
424 			break;
425         default:
426             throw beans::UnknownPropertyException();
427 	}
428 }
429 
430 
431 
432 
433 Any SAL_CALL SdUnoDrawView::getFastPropertyValue (
434     sal_Int32 nHandle)
435     throw(css::beans::UnknownPropertyException,
436         css::lang::WrappedTargetException,
437         css::uno::RuntimeException)
438 {
439     Any aValue;
440 	switch( nHandle )
441 	{
442 		case DrawController::PROPERTY_CURRENTPAGE:
443 			aValue <<= (const_cast<SdUnoDrawView*>(this))->getCurrentPage();
444 			break;
445 
446 		case DrawController::PROPERTY_MASTERPAGEMODE:
447 			aValue <<= getMasterPageMode();
448 			break;
449 
450 		case DrawController::PROPERTY_LAYERMODE:
451 			aValue <<= getLayerMode();
452 			break;
453 
454 		case DrawController::PROPERTY_ACTIVE_LAYER:
455 			aValue <<= (const_cast<SdUnoDrawView*>(this))->getActiveLayer();
456 			break;
457 
458 		case DrawController::PROPERTY_ZOOMVALUE:
459 			aValue <<= GetZoom();
460 			break;
461 		case DrawController::PROPERTY_ZOOMTYPE:
462 			aValue <<= (sal_Int16)com::sun::star::view::DocumentZoomType::BY_VALUE;
463 			break;
464 		case DrawController::PROPERTY_VIEWOFFSET:
465 			aValue <<= GetViewOffset();
466 			break;
467 
468 		case DrawController::PROPERTY_DRAWVIEWMODE:
469 			aValue = getDrawViewMode();
470 			break;
471 
472         default:
473             throw beans::UnknownPropertyException();
474 	}
475 
476     return aValue;
477 }
478 
479 
480 
481 
482 // XDrawView
483 
484 
485 void SAL_CALL SdUnoDrawView::setCurrentPage (
486     const Reference< drawing::XDrawPage >& xPage )
487 	throw(RuntimeException)
488 {
489     SvxDrawPage* pDrawPage = SvxDrawPage::getImplementation( xPage );
490     SdrPage *pSdrPage = pDrawPage ? pDrawPage->GetSdrPage() : NULL;
491 
492     if(pSdrPage)
493     {
494         // End editing of text.  Otherwise the edited text object would
495         // still be visible on the new page.
496         mrDrawViewShell.GetView()->SdrEndTextEdit();
497 
498         setMasterPageMode( pSdrPage->IsMasterPage() );
499         mrDrawViewShell.SwitchPage( (pSdrPage->GetPageNum() - 1) >> 1 );
500         mrDrawViewShell.WriteFrameViewData();
501     }
502 }
503 
504 //----------------------------------------------------------------------
505 
506 Reference< drawing::XDrawPage > SAL_CALL SdUnoDrawView::getCurrentPage()
507 	throw(RuntimeException)
508 {
509 	Reference< drawing::XDrawPage >  xPage;
510 
511     SdrPageView *pPV = mrView.GetSdrPageView();
512     SdrPage* pPage = pPV ? pPV->GetPage() : NULL;
513 
514     if(pPage)
515         xPage = Reference< drawing::XDrawPage >::query( pPage->getUnoPage() );
516 
517 	return xPage;
518 }
519 
520 
521 sal_Int16 SdUnoDrawView::GetZoom(void) const
522 {
523 	if (mrDrawViewShell.GetActiveWindow() )
524 	{
525 		return (sal_Int16)mrDrawViewShell.GetActiveWindow()->GetZoom();
526 	}
527 	else
528 	{
529 		return 0;
530 	}
531 }
532 
533 void SdUnoDrawView::SetZoom( sal_Int16 nZoom )
534 {
535 	SvxZoomItem aZoomItem( SVX_ZOOM_PERCENT, nZoom );
536 
537     SfxViewFrame* pViewFrame = mrDrawViewShell.GetViewFrame();
538     if( pViewFrame )
539     {
540         SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
541         if( pDispatcher )
542         {
543             pDispatcher->Execute(SID_ATTR_ZOOM,SFX_CALLMODE_SYNCHRON,&aZoomItem, 0L);
544         }
545     }
546 }
547 
548 
549 void SdUnoDrawView::SetViewOffset(const awt::Point& rWinPos )
550 {
551     Point aWinPos( rWinPos.X, rWinPos.Y );
552     aWinPos += mrDrawViewShell.GetViewOrigin();
553     mrDrawViewShell.SetWinViewPos( aWinPos, true );
554 }
555 
556 awt::Point SdUnoDrawView::GetViewOffset() const
557 {
558 	Point aRet;
559 
560     aRet = mrDrawViewShell.GetWinViewPos();
561     aRet -= mrDrawViewShell.GetViewOrigin();
562 
563 	return awt::Point( aRet.X(), aRet.Y() );
564 }
565 
566 void SdUnoDrawView::SetZoomType ( sal_Int16 nType )
567 {
568     SfxViewFrame* pViewFrame = mrDrawViewShell.GetViewFrame();
569     if( pViewFrame )
570     {
571         SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
572         if( pDispatcher )
573         {
574             SvxZoomType eZoomType;
575             switch( nType )
576             {
577                 case com::sun::star::view::DocumentZoomType::OPTIMAL:
578                     eZoomType = SVX_ZOOM_OPTIMAL;
579                     break;
580 
581                 case com::sun::star::view::DocumentZoomType::PAGE_WIDTH:
582                 case com::sun::star::view::DocumentZoomType::PAGE_WIDTH_EXACT:
583                     eZoomType = SVX_ZOOM_PAGEWIDTH;
584                     break;
585 
586                 case com::sun::star::view::DocumentZoomType::ENTIRE_PAGE:
587                     eZoomType = SVX_ZOOM_WHOLEPAGE;
588                     break;
589 
590                 default:
591                     return;
592             }
593             SvxZoomItem aZoomItem( eZoomType );
594             pDispatcher->Execute(SID_ATTR_ZOOM,SFX_CALLMODE_SYNCHRON,&aZoomItem, 0L);
595         }
596     }
597 }
598 
599 
600 
601 
602 SdXImpressDocument* SdUnoDrawView::GetModel (void) const throw()
603 {
604 	if (mrView.GetDocSh()!=NULL)
605 	{
606 		Reference<frame::XModel> xModel (mrView.GetDocSh()->GetModel());
607 		return SdXImpressDocument::getImplementation(xModel);
608 	}
609 	else
610 		return NULL;
611 }
612 
613 Any SdUnoDrawView::getDrawViewMode() const
614 {
615 	Any aRet;
616 	switch( mrDrawViewShell.GetPageKind() )
617 	{
618 	case PK_NOTES:	aRet <<= DrawViewMode_NOTES; break;
619 	case PK_HANDOUT: aRet <<= DrawViewMode_HANDOUT; break;
620 	case PK_STANDARD: aRet <<= DrawViewMode_DRAW; break;
621 	}
622 	return aRet;
623 }
624 
625 // XServiceInfo
626 OUString SAL_CALL SdUnoDrawView::getImplementationName(  ) throw (RuntimeException)
627 {
628 	return OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.sd.SdUnoDrawView") );
629 }
630 
631 sal_Bool SAL_CALL SdUnoDrawView::supportsService( const OUString& ServiceName ) throw (RuntimeException)
632 {
633 	return comphelper::ServiceInfoHelper::supportsService( ServiceName, getSupportedServiceNames() );
634 }
635 
636 Sequence< OUString > SAL_CALL SdUnoDrawView::getSupportedServiceNames(  ) throw (RuntimeException)
637 {
638 	OUString aSN( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.DrawingDocumentDrawView") );
639 	uno::Sequence< OUString > aSeq( &aSN, 1 );
640 	return aSeq;
641 }
642 
643 } // end of namespace sd
644 
645