Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*************************************************************************
3 : *
4 : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : *
6 : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : *
8 : * OpenOffice.org - a multi-platform office productivity suite
9 : *
10 : * This file is part of OpenOffice.org.
11 : *
12 : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : * it under the terms of the GNU Lesser General Public License version 3
14 : * only, as published by the Free Software Foundation.
15 : *
16 : * OpenOffice.org is distributed in the hope that it will be useful,
17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : * GNU Lesser General Public License version 3 for more details
20 : * (a copy is included in the LICENSE file that accompanied this code).
21 : *
22 : * You should have received a copy of the GNU Lesser General Public License
23 : * version 3 along with OpenOffice.org. If not, see
24 : * <http://www.openoffice.org/license.html>
25 : * for a copy of the LGPLv3 License.
26 : *
27 : ************************************************************************/
28 :
29 :
30 : #include <com/sun/star/beans/XPropertySet.hpp>
31 : #include <com/sun/star/frame/Desktop.hpp>
32 : #include <com/sun/star/frame/DispatchHelper.hpp>
33 : #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
34 : #include <com/sun/star/frame/Frame.hpp>
35 : #include <com/sun/star/lang/SystemDependent.hpp>
36 : #include <com/sun/star/awt/Toolkit.hpp>
37 : #include <com/sun/star/awt/XVclWindowPeer.hpp>
38 : #include <com/sun/star/util/XCloseable.hpp>
39 : #include <com/sun/star/lang/DisposedException.hpp>
40 : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
41 : #include <com/sun/star/presentation/XPresentation.hpp>
42 : #include <com/sun/star/presentation/XPresentationSupplier.hpp>
43 : #include <comphelper/processfactory.hxx>
44 : #include <tools/color.hxx>
45 : #include <rtl/textenc.h>
46 : #include <rtl/locale.h>
47 : #include <osl/nlsupport.h>
48 :
49 : #include <stdio.h>
50 : #include <stdlib.h>
51 : #include <string.h>
52 : #include <errno.h>
53 :
54 : #include "so_instance.hxx"
55 : #include "ns_debug.hxx"
56 : #include "so_env.hxx"
57 : #include "nsp_windows.hxx"
58 : #include "so_closelistener.hxx"
59 : #include <osl/process.h>
60 :
61 : using namespace com::sun::star::uno;
62 : using namespace com::sun::star::lang;
63 : using namespace com::sun::star::connection;
64 : using namespace cppu;
65 : using namespace com::sun::star;
66 :
67 :
68 : char SoPluginInstance::sSO_Dir[] = {0};
69 0 : Reference< XMultiServiceFactory > SoPluginInstance::mxRemoteMSF = Reference< XMultiServiceFactory >(NULL);
70 :
71 0 : SoPluginInstance::SoPluginInstance(long pParent, Reference< XMultiServiceFactory > xMSF):
72 : m_xUnoWin(NULL),
73 : m_xComponent(NULL),
74 : m_xFrame(NULL),
75 : m_xFrames(NULL),
76 : m_xDispatcher(NULL),
77 : m_xDispatchProvider(NULL),
78 0 : m_pCloseListener(NULL)
79 : {
80 0 : m_nWidth = 0;
81 0 : m_nHeight = 0;
82 0 : m_nX = 0;
83 0 : m_nY = 0;
84 0 : m_nFlag = 15;
85 0 : m_bInit = sal_False;
86 0 : m_hParent = 0;
87 0 : m_pParent = pParent;
88 0 : m_dParentStyl = 0;
89 0 : mxRemoteMSF = xMSF;
90 0 : }
91 :
92 0 : SoPluginInstance::~SoPluginInstance()
93 : {
94 0 : }
95 :
96 0 : sal_Bool SoPluginInstance::SetURL(char* aURL)
97 : {
98 0 : debug_fprintf(NSP_LOG_APPEND, "SoPluginInstance::SetURL %s\n", aURL);
99 :
100 0 : rtl_Locale* pLocale = NULL;
101 0 : osl_getProcessLocale(&pLocale);
102 0 : sal_uInt16 encoding = osl_getTextEncodingFromLocale(pLocale);
103 :
104 0 : m_sURL = OUString(aURL, strlen(aURL), encoding);
105 : debug_fprintf(NSP_LOG_APPEND, "SetURL %s\nencoding is: %d\n", OUStringToOString(m_sURL,
106 0 : RTL_TEXTENCODING_GB_18030).getStr(), m_sURL.getLength(), encoding);
107 0 : return sal_True;
108 : }
109 :
110 : // plugin window UI part: create window, load document
111 0 : sal_Bool SoPluginInstance::LoadDocument(NSP_HWND hParent)
112 : {
113 : // If doc has been loaded, we just resize the window and return
114 0 : if(m_bInit)
115 : {
116 0 : debug_fprintf(NSP_LOG_APPEND, "only reset windows size\n");
117 0 : m_xUnoWin->setPosSize( m_nX, m_nY, m_nWidth, m_nHeight, m_nFlag );
118 : debug_fprintf(NSP_LOG_APPEND, "set windows to x:%d y:%d w:%d h%d falg:%d\n",
119 0 : m_nX, m_nY, m_nWidth, m_nHeight, m_nFlag);
120 0 : return sal_True;
121 : }
122 :
123 : // If mxRemoteMSF is not initialized, we assert and return sal_False
124 0 : if(!mxRemoteMSF.is())
125 : {
126 0 : debug_fprintf(NSP_LOG_APPEND, "Remote StarOfiice ServiceManager is not initilzed correctly!\n");
127 0 : return sal_False;
128 : }
129 :
130 : try
131 : {
132 0 : Reference< beans::XPropertySet > xFactoryProperties( mxRemoteMSF, uno::UNO_QUERY );
133 0 : Reference< uno::XComponentContext > xContext( xFactoryProperties->getPropertyValue( "DefaultContext" ), UNO_QUERY );
134 :
135 : // try to create netscape plugin window
136 0 : Reference< awt::XToolkit2 > xToolkit( awt::Toolkit::create(xContext) );
137 :
138 : // prepare parameters for plugin window
139 0 : css::uno::Any hwndParent = css::uno::makeAny((sal_Int32)hParent);
140 : #ifdef UNIX
141 0 : sal_Int16 nWindowType = css::lang::SystemDependent::SYSTEM_XWINDOW;
142 : #endif //end of UNIX
143 : #ifdef WNT
144 : sal_Int16 nWindowType = css::lang::SystemDependent::SYSTEM_WIN32;
145 : #endif //end of WNT
146 :
147 0 : debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, try to create plugin container window HWIN:%ld.\n", hParent);
148 :
149 : // create the plugin window
150 : Reference< awt::XWindowPeer > xNewWinPeer =
151 0 : xToolkit->createSystemChild( hwndParent,
152 0 : css::uno::Sequence<sal_Int8>(), nWindowType );
153 0 : if ( !xNewWinPeer.is() )
154 : {
155 0 : debug_fprintf(NSP_LOG_APPEND, "can not create first window\n", hParent);
156 0 : return sal_False;
157 : }
158 :
159 : // get interface of first window
160 0 : m_xUnoWin = Reference< awt::XWindow >( xNewWinPeer, uno::UNO_QUERY );
161 0 : if( !m_xUnoWin.is() )
162 : {
163 0 : debug_fprintf(NSP_LOG_APPEND, "can not get interface of first window\n", hParent);
164 0 : return sal_False;
165 : }
166 :
167 : // initialize window
168 0 : xNewWinPeer->setBackground( COL_GRAY );
169 0 : m_xUnoWin->setVisible( sal_True );
170 0 : m_xUnoWin->setPosSize( m_nX, m_nY, m_nWidth, m_nHeight, m_nFlag );
171 : debug_fprintf(NSP_LOG_APPEND, "set windows to x:%d y:%d w:%d h%d falg:%d\n",
172 0 : m_nX, m_nY, m_nWidth, m_nHeight, m_nFlag);
173 :
174 : // create frame
175 0 : m_xFrame = frame::Frame::create( xContext );
176 :
177 : // initialize frame
178 0 : m_xFrame->initialize( m_xUnoWin );
179 :
180 : try
181 : {
182 : // currently ignore errors in this code
183 0 : uno::Reference< beans::XPropertySet > xFrameProps( m_xFrame, uno::UNO_QUERY_THROW );
184 0 : uno::Reference< beans::XPropertySet > xLMProps;
185 0 : xFrameProps->getPropertyValue("LayoutManager") >>= xLMProps;
186 0 : if ( xLMProps.is() )
187 0 : xLMProps->setPropertyValue("AutomaticToolbars", uno::makeAny( (sal_Bool)sal_False ) );
188 : }
189 0 : catch( const uno::Exception& )
190 : {}
191 :
192 : // get frames supplier
193 0 : Reference< frame::XDesktop2 > xFramesSupplier = frame::Desktop::create( xContext );
194 :
195 : // get frames
196 0 : m_xFrames = xFramesSupplier->getFrames();
197 0 : if ( !m_xFrames.is() )
198 : {
199 0 : debug_fprintf(NSP_LOG_APPEND, "can not get frames from FramesSupplier\n");
200 0 : return sal_False;
201 : }
202 :
203 : // append m_xFrame to m_xFrames
204 0 : m_xFrames->append( Reference<frame::XFrame>(m_xFrame, uno::UNO_QUERY_THROW) );
205 :
206 : // create XComponentLoader
207 0 : Reference< frame::XComponentLoader > xLoader( m_xFrame, uno::UNO_QUERY );
208 0 : if ( !xLoader.is() )
209 : {
210 0 : debug_fprintf(NSP_LOG_APPEND, "can not get ComponentLoader to load URL\n");
211 0 : return sal_False;
212 : }
213 :
214 : //create stream for the document
215 0 : Reference< ucb::XSimpleFileAccess3 > xSimpleFileAccess( ucb::SimpleFileAccess::create(xContext) );
216 0 : Reference<io::XInputStream> xInputStream = xSimpleFileAccess->openFileRead( m_sURL );
217 :
218 0 : if(!xInputStream.is())
219 : {
220 0 : debug_fprintf(NSP_LOG_APPEND, "can not create XInputStream for URL\n");
221 0 : return sal_False;
222 : }
223 :
224 : // prepare to load document
225 0 : debug_fprintf(NSP_LOG_APPEND, "try to load document\n");
226 0 : Sequence< ::com::sun::star::beans::PropertyValue > setPropValues(3);
227 0 : setPropValues[0].Name = "ViewOnly";
228 0 : setPropValues[0].Value <<= sal_True;
229 0 : setPropValues[1].Name = "ReadOnly";
230 0 : setPropValues[1].Value <<= sal_True;
231 0 : setPropValues[2].Name = "InputStream";
232 0 : setPropValues[2].Value <<= xInputStream;
233 : /*
234 : setPropValues[ 3 ].Name = "FilterName";
235 : setPropValues[ 3 ].Value = "Flat XML File";*/
236 :
237 : debug_fprintf(NSP_LOG_APPEND, "try to load copy of URL from local file %s:%d\n",
238 : OUStringToOString( m_sURL, RTL_TEXTENCODING_ASCII_US ).getStr( ),
239 0 : m_sURL.getLength() );
240 :
241 : // load document
242 0 : Sequence< ::com::sun::star::beans::PropertyValue > setPropValues2(3);
243 0 : setPropValues2[0].Name = "ViewOnly";
244 0 : setPropValues2[0].Value <<= sal_True;
245 0 : setPropValues2[1].Name = "ReadOnly";
246 0 : setPropValues2[1].Value <<= sal_True;
247 0 : setPropValues2[2].Name = "AsTemplate";
248 0 : setPropValues2[2].Value <<= sal_False;
249 0 : m_xComponent = xLoader->loadComponentFromURL(
250 : m_sURL,
251 0 : m_xFrame->getName(), 0, setPropValues2 );
252 :
253 0 : if ( !m_xComponent.is() )
254 : {
255 0 : debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, Load Componment error\n");
256 0 : return sal_False;
257 : }
258 :
259 : // register the closelistener that will prevent closing of the component
260 0 : Reference< util::XCloseable > xCloseable( m_xFrame, uno::UNO_QUERY );
261 0 : if ( xCloseable.is() )
262 : {
263 0 : m_pCloseListener = new PluginDocumentClosePreventer();
264 0 : m_xCloseListener = Reference< util::XCloseListener >( m_pCloseListener );
265 0 : xCloseable->addCloseListener( m_xCloseListener );
266 : }
267 :
268 : //free the input stream, it is hold by the m_xComponent
269 0 : xInputStream.clear();
270 :
271 0 : debug_fprintf(NSP_LOG_APPEND, "load document success\n");
272 :
273 : // create frame::XDispatchHelper and frame::XDispatchProvider
274 0 : m_xDispatcher = Reference< frame::XDispatchHelper >( frame::DispatchHelper::create( xContext ) );
275 0 : m_xDispatchProvider = Reference< frame::XDispatchProvider >(m_xFrame, uno::UNO_QUERY);
276 0 : if(!m_xDispatchProvider.is())
277 : {
278 0 : debug_fprintf(NSP_LOG_APPEND, "m_xDispatchProvider can not be getten\n");
279 0 : return sal_False;
280 : }
281 :
282 : //try to enable toolbar and tool windows
283 0 : Sequence< ::com::sun::star::beans::PropertyValue > propertyValue(1);
284 0 : propertyValue[0].Name = "FunctionBarVisible";
285 0 : propertyValue[0].Value <<= sal_True;
286 0 : m_xDispatcher->executeDispatch(m_xDispatchProvider,
287 : OUString(".uno:FunctionBarVisible"),
288 0 : m_xFrame->getName(), 0,
289 0 : propertyValue );
290 :
291 : // reset window style of parent window
292 : #ifdef WNT
293 : m_dParentStyl = ::NSP_ResetWinStyl (m_hParent);
294 : #endif
295 0 : m_bInit = sal_True;
296 :
297 : try
298 : {
299 : // in case of presentation try to set the mode of slide-show, and start it
300 0 : uno::Reference< presentation::XPresentationSupplier > xPresSuppl( m_xComponent, uno::UNO_QUERY_THROW );
301 0 : uno::Reference< presentation::XPresentation > xPres( xPresSuppl->getPresentation(), uno::UNO_SET_THROW );
302 0 : uno::Reference< beans::XPropertySet > xProps( xPresSuppl->getPresentation(), uno::UNO_QUERY_THROW );
303 0 : xProps->setPropertyValue("IsFullScreen", uno::makeAny( sal_False ) );
304 0 : xPres->start();
305 : }
306 0 : catch( const uno::Exception& )
307 0 : {}
308 : }
309 0 : catch( const uno::Exception& e )
310 : {
311 0 : debug_fprintf(NSP_LOG_APPEND, "Unknown exception while loading document in netscape plugin windows\n");
312 0 : OString o = OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US );
313 0 : debug_fprintf(NSP_LOG_APPEND, "error: %s \n", o.pData->buffer );
314 0 : return sal_False;
315 : }
316 0 : return sal_True;
317 : }
318 :
319 0 : sal_Bool SoPluginInstance::SetWindow(NSP_HWND hParent, int x, int y, int w, int h)
320 : {
321 0 : sal_Bool bRetval(sal_True);
322 :
323 0 : if ( m_hParent && !hParent )
324 : {
325 : // the plugin instance has the parent window set already and now it becomes NULL as parent window
326 : // that means that the instance should be closed
327 0 : Destroy();
328 0 : m_hParent = hParent;
329 : }
330 : else
331 : {
332 0 : m_hParent = hParent;
333 :
334 : debug_fprintf(NSP_LOG_APPEND, "SoPluginInstance::SetWindow %s : %d\n",
335 : OUStringToOString(m_sURL, RTL_TEXTENCODING_ASCII_US).getStr(),
336 0 : m_sURL.getLength() );
337 0 : m_nWidth = w;
338 0 : m_nHeight =h;
339 0 : m_nX = x;
340 0 : m_nY = y;
341 :
342 0 : if ( m_sURL.isEmpty() )
343 0 : return sal_True;
344 :
345 0 : if(!mxRemoteMSF.is())
346 : {
347 0 : debug_fprintf(NSP_LOG_APPEND, "Remote StarOfiice ServiceManager is not initilzed correctly!\n");
348 0 : return sal_False;
349 : }
350 0 : debug_fprintf(NSP_LOG_APPEND, "in SoPluginInstance::SetWindow, begin LoadDocument(hParent)\n");
351 0 : bRetval = LoadDocument(hParent); // Load document into current window
352 0 : if(!bRetval){
353 : // try to reload document again
354 0 : debug_fprintf(NSP_LOG_APPEND, "load document error, try to reload it once again\n");
355 0 : mxRemoteMSF.clear();
356 0 : m_bInit = sal_False;
357 0 : bRetval = LoadDocument(hParent);
358 0 : debug_fprintf(NSP_LOG_APPEND, "load document again, return %d\n", bRetval);
359 : }
360 : }
361 :
362 0 : return bRetval;
363 : }
364 :
365 0 : sal_Bool SoPluginInstance::Destroy(void)
366 : {
367 : #ifdef WNT
368 : if(m_dParentStyl != 0)
369 : NSP_RestoreWinStyl(m_hParent, m_dParentStyl);
370 : #endif
371 :
372 0 : uno::Reference< util::XCloseable > xCloseable( m_xFrame, uno::UNO_QUERY );
373 :
374 : try
375 : {
376 0 : if ( m_xCloseListener.is() )
377 : {
378 0 : if ( m_pCloseListener )
379 0 : m_pCloseListener->StopPreventClose();
380 :
381 0 : if ( xCloseable.is() )
382 0 : xCloseable->removeCloseListener( m_xCloseListener );
383 : }
384 : }
385 0 : catch( const uno::Exception& )
386 : {}
387 :
388 : try
389 : {
390 0 : uno::Sequence< uno::Any > aArgs( 1 );
391 0 : aArgs[0] <<= m_xFrame;
392 : uno::Reference< lang::XComponent > xDocumentCloser(
393 0 : mxRemoteMSF->createInstanceWithArguments(
394 : OUString( "com.sun.star.embed.DocumentCloser" ),
395 0 : aArgs ),
396 0 : uno::UNO_QUERY_THROW );
397 :
398 0 : xDocumentCloser->dispose(); // this call should close the document
399 : }
400 0 : catch( const uno::Exception& )
401 : {
402 0 : debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin.exe, could not close the document correctly!\n");
403 : try
404 : {
405 0 : if ( xCloseable.is() )
406 0 : xCloseable->close( sal_True );
407 : else
408 : {
409 0 : uno::Reference< lang::XComponent > xDisposable( m_xFrame, uno::UNO_QUERY );
410 0 : if ( xDisposable.is() )
411 0 : xDisposable->dispose();
412 : }
413 : }
414 0 : catch (const uno::Exception&)
415 : {
416 : }
417 : }
418 :
419 0 : m_xUnoWin.clear();
420 0 : m_xComponent.clear();
421 0 : m_xFrame.clear();
422 0 : m_xFrames.clear();
423 0 : m_xDispatcher.clear();
424 0 : m_xDispatchProvider.clear();
425 0 : return sal_True;
426 : }
427 :
428 0 : sal_Bool SoPluginInstance::Print(void)
429 : {
430 0 : if(!m_xDispatcher.is())
431 0 : return sal_False;
432 :
433 0 : Sequence< ::com::sun::star::beans::PropertyValue > propertyValue(1);
434 0 : m_xDispatcher->executeDispatch(m_xDispatchProvider,
435 : OUString(".uno:PrintDefault"),
436 0 : m_xFrame->getName(), 0,
437 0 : propertyValue );
438 0 : return sal_True;
439 0 : }
440 :
441 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|