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_slideshow.hxx"
30 
31 // must be first
32 #include <canvas/verbosetrace.hxx>
33 #include <tools/diagnose_ex.h>
34 #include <canvas/debug.hxx>
35 
36 #include <comphelper/anytostring.hxx>
37 #include <cppuhelper/exc_hlp.hxx>
38 
39 #include <basegfx/matrix/b2dhommatrix.hxx>
40 #include <basegfx/range/b2irange.hxx>
41 #include <basegfx/tools/canvastools.hxx>
42 
43 #include <cppcanvas/spritecanvas.hxx>
44 #include <canvas/canvastools.hxx>
45 
46 #include <com/sun/star/uno/XComponentContext.hpp>
47 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
48 #include <com/sun/star/rendering/XCanvas.hpp>
49 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
50 #include <com/sun/star/beans/XPropertySet.hpp>
51 #include <com/sun/star/beans/PropertyValue.hpp>
52 #include <com/sun/star/util/XCloseable.hpp>
53 #include <com/sun/star/awt/WindowDescriptor.hpp>
54 #include <com/sun/star/awt/XToolkit.hpp>
55 #include <com/sun/star/awt/XWindow2.hpp>
56 #include <com/sun/star/awt/XWindowPeer.hpp>
57 #include <com/sun/star/awt/WindowAttribute.hpp>
58 #include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
59 #include <com/sun/star/awt/PosSize.hpp>
60 #include <com/sun/star/frame/XFrame.hpp>
61 #include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
62 
63 #include "viewappletshape.hxx"
64 #include "tools.hxx"
65 
66 
67 using namespace ::com::sun::star;
68 
69 namespace slideshow
70 {
71     namespace internal
72     {
73         ViewAppletShape::ViewAppletShape( const ViewLayerSharedPtr&                       rViewLayer,
74                                           const uno::Reference< drawing::XShape >&        rxShape,
75                                           const ::rtl::OUString&                          rServiceName,
76                                           const char**                                    pPropCopyTable,
77                                           sal_Size                                        nNumPropEntries,
78                                           const uno::Reference< uno::XComponentContext >& rxContext ) :
79 			mpViewLayer( rViewLayer ),
80             mxViewer(),
81             mxFrame(),
82             mxComponentContext( rxContext )
83         {
84             ENSURE_OR_THROW( rxShape.is(), "ViewAppletShape::ViewAppletShape(): Invalid Shape" );
85             ENSURE_OR_THROW( mpViewLayer, "ViewAppletShape::ViewAppletShape(): Invalid View" );
86             ENSURE_OR_THROW( mpViewLayer->getCanvas(), "ViewAppletShape::ViewAppletShape(): Invalid ViewLayer canvas" );
87             ENSURE_OR_THROW( mxComponentContext.is(), "ViewAppletShape::ViewAppletShape(): Invalid component context" );
88 
89             uno::Reference<lang::XMultiComponentFactory> xFactory(
90                 mxComponentContext->getServiceManager(),
91                 uno::UNO_QUERY_THROW );
92 
93             mxViewer.set( xFactory->createInstanceWithContext( rServiceName,
94                                                                mxComponentContext),
95                           uno::UNO_QUERY_THROW );
96 
97             uno::Reference< beans::XPropertySet > xShapePropSet( rxShape,
98                                                                  uno::UNO_QUERY_THROW );
99             uno::Reference< beans::XPropertySet > mxViewerPropSet( mxViewer,
100                                                                    uno::UNO_QUERY_THROW );
101 
102             // copy shape properties to applet viewer
103             ::rtl::OUString aPropName;
104             for( sal_Size i=0; i<nNumPropEntries; ++i )
105             {
106                 aPropName = ::rtl::OUString::createFromAscii( pPropCopyTable[i] );
107                 mxViewerPropSet->setPropertyValue( aPropName,
108                                                    xShapePropSet->getPropertyValue(
109                                                        aPropName ));
110             }
111         }
112 
113 		// ---------------------------------------------------------------------
114 
115 		ViewAppletShape::~ViewAppletShape()
116 		{
117             try
118             {
119                 endApplet();
120             }
121             catch (uno::Exception &)
122             {
123                 OSL_ENSURE( false, rtl::OUStringToOString(
124                                 comphelper::anyToString(
125                                     cppu::getCaughtException() ),
126                                 RTL_TEXTENCODING_UTF8 ).getStr() );
127             }
128 		}
129 
130 		// ---------------------------------------------------------------------
131 
132         ViewLayerSharedPtr ViewAppletShape::getViewLayer() const
133         {
134             return mpViewLayer;
135         }
136 
137 		// ---------------------------------------------------------------------
138 
139         bool ViewAppletShape::startApplet( const ::basegfx::B2DRectangle& rBounds )
140         {
141             ENSURE_OR_RETURN_FALSE( mpViewLayer && mpViewLayer->getCanvas() && mpViewLayer->getCanvas()->getUNOCanvas().is(),
142                                "ViewAppletShape::startApplet(): Invalid or disposed view" );
143             try
144             {
145                 ::cppcanvas::CanvasSharedPtr pCanvas = mpViewLayer->getCanvas();
146 
147                 uno::Reference< beans::XPropertySet > xPropSet( pCanvas->getUNOCanvas()->getDevice(),
148                                                                 uno::UNO_QUERY_THROW );
149 
150                 uno::Reference< awt::XWindow2 > xParentWindow(
151                     xPropSet->getPropertyValue(
152                         ::rtl::OUString::createFromAscii( "Window" )),
153                     uno::UNO_QUERY_THROW );
154 
155                 uno::Reference<lang::XMultiComponentFactory> xFactory(
156                     mxComponentContext->getServiceManager() );
157 
158                 if( xFactory.is() )
159                 {
160                     // create an awt window to contain the applet
161                     // ==========================================
162 
163                     uno::Reference< awt::XToolkit > xToolkit(
164                         xFactory->createInstanceWithContext(
165                             ::rtl::OUString::createFromAscii( "com.sun.star.awt.Toolkit" ),
166                             mxComponentContext ),
167                         uno::UNO_QUERY_THROW );
168 
169                     awt::WindowDescriptor aOwnWinDescriptor( awt::WindowClass_SIMPLE,
170                                                              ::rtl::OUString(),
171                                                              uno::Reference< awt::XWindowPeer >(xParentWindow,
172                                                                                                 uno::UNO_QUERY_THROW),
173                                                              0,
174                                                              awt::Rectangle(),
175                                                              awt::WindowAttribute::SHOW
176                                                              | awt::VclWindowPeerAttribute::CLIPCHILDREN );
177 
178                     uno::Reference< awt::XWindowPeer > xNewWinPeer(
179                         xToolkit->createWindow( aOwnWinDescriptor ));
180                     uno::Reference< awt::XWindow > xOwnWindow( xNewWinPeer,
181                                                                uno::UNO_QUERY_THROW );
182 
183 
184                     // create a frame, and load the applet into it
185                     // ===========================================
186 
187                     mxFrame.set(
188                         xFactory->createInstanceWithContext(
189                             ::rtl::OUString::createFromAscii( "com.sun.star.frame.Frame" ),
190                             mxComponentContext ),
191                         uno::UNO_QUERY_THROW );
192 
193                     mxFrame->initialize( xOwnWindow );
194 
195                     uno::Reference < frame::XSynchronousFrameLoader > xLoader( mxViewer,
196                                                                                uno::UNO_QUERY_THROW );
197                     xLoader->load( uno::Sequence < beans::PropertyValue >(),
198                                    mxFrame );
199 
200 
201                     // resize surrounding window and applet to current shape size
202                     // ==========================================================
203 
204                     ::basegfx::B2DRange aTmpRange;
205                     ::canvas::tools::calcTransformedRectBounds( aTmpRange,
206                                                                 rBounds,
207                                                                 mpViewLayer->getTransformation() );
208                     const ::basegfx::B2IRange& rPixelBounds(
209                         ::basegfx::unotools::b2ISurroundingRangeFromB2DRange( aTmpRange ));
210 
211                     uno::Reference< awt::XWindow > xSurroundingWindow( mxFrame->getContainerWindow() );
212                     if( xSurroundingWindow.is() )
213                         xSurroundingWindow->setPosSize( static_cast<sal_Int32>(rPixelBounds.getMinX()),
214                                                         static_cast<sal_Int32>(rPixelBounds.getMinY()),
215                                                         static_cast<sal_Int32>(rPixelBounds.getWidth()),
216                                                         static_cast<sal_Int32>(rPixelBounds.getHeight()),
217                                                         awt::PosSize::POSSIZE );
218 
219                     uno::Reference< awt::XWindow > xAppletWindow( mxFrame->getComponentWindow() );
220                     if( xAppletWindow.is() )
221                         xAppletWindow->setPosSize( 0, 0,
222                                                    static_cast<sal_Int32>(rPixelBounds.getWidth()),
223                                                    static_cast<sal_Int32>(rPixelBounds.getHeight()),
224                                                    awt::PosSize::POSSIZE );
225                 }
226             }
227             catch (uno::Exception &)
228             {
229                 return false;
230             }
231 
232             return true;
233         }
234 
235 		// ---------------------------------------------------------------------
236 
237         void ViewAppletShape::endApplet()
238         {
239             uno::Reference<util::XCloseable> xCloseable(
240                 mxFrame,
241                 uno::UNO_QUERY );
242 
243             if( xCloseable.is() )
244             {
245                 xCloseable->close( sal_True );
246                 mxFrame.clear();
247             }
248         }
249 
250 		// ---------------------------------------------------------------------
251 
252         bool ViewAppletShape::render( const ::basegfx::B2DRectangle& rBounds ) const
253         {
254             ::cppcanvas::CanvasSharedPtr pCanvas = mpViewLayer->getCanvas();
255 
256             if( !pCanvas )
257                 return false;
258 
259             if( !mxFrame.is() )
260             {
261                 // fill the shape background with black
262                 fillRect( pCanvas,
263                           rBounds,
264                           0xFFFFFFFFU );
265             }
266 
267             return true;
268         }
269 
270         bool ViewAppletShape::resize( const ::basegfx::B2DRectangle& rBounds ) const
271         {
272             if( !mxFrame.is() )
273                 return false;
274 
275             ::basegfx::B2DRange aTmpRange;
276             ::canvas::tools::calcTransformedRectBounds( aTmpRange,
277                                                         rBounds,
278                                                         mpViewLayer->getTransformation() );
279             const ::basegfx::B2IRange& rPixelBounds(
280                 ::basegfx::unotools::b2ISurroundingRangeFromB2DRange( aTmpRange ));
281 
282             uno::Reference< awt::XWindow > xFrameWindow( mxFrame->getContainerWindow() );
283             if( xFrameWindow.is() )
284                 xFrameWindow->setPosSize( static_cast<sal_Int32>(rPixelBounds.getMinX()),
285                                           static_cast<sal_Int32>(rPixelBounds.getMinY()),
286                                           static_cast<sal_Int32>(rPixelBounds.getWidth()),
287                                           static_cast<sal_Int32>(rPixelBounds.getHeight()),
288                                           awt::PosSize::POSSIZE );
289 
290             uno::Reference< awt::XWindow > xAppletWindow( mxFrame->getComponentWindow() );
291             if( xAppletWindow.is() )
292                 xAppletWindow->setPosSize( 0, 0,
293                                            static_cast<sal_Int32>(rPixelBounds.getWidth()),
294                                            static_cast<sal_Int32>(rPixelBounds.getHeight()),
295                                            awt::PosSize::POSSIZE );
296 
297             return true;
298         }
299 	}
300 }
301