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_dbaccess.hxx"
30 
31 #ifndef _DBAUI_LINKEDDOCUMENTS_HXX_
32 #include "linkeddocuments.hxx"
33 #endif
34 #ifndef _OSL_DIAGNOSE_H_
35 #include <osl/diagnose.h>
36 #endif
37 #include <tools/diagnose_ex.h>
38 #include <unotools/confignode.hxx>
39 #ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
40 #include "dbustrings.hrc"
41 #endif
42 #include <comphelper/classids.hxx>
43 #ifndef COMPHELPER_NAMEDVALUECOLLECTION_HXX
44 #include <comphelper/namedvaluecollection.hxx>
45 #endif
46 #ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
47 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
48 #endif
49 #ifndef _COM_SUN_STAR_FRAME_XDISPATCHPROVIDER_HPP_
50 #include <com/sun/star/frame/XDispatchProvider.hpp>
51 #endif
52 #ifndef _COM_SUN_STAR_FRAME_XCOMPONENTLOADER_HPP_
53 #include <com/sun/star/frame/XComponentLoader.hpp>
54 #endif
55 #ifndef _COM_SUN_STAR_UTIL_URL_HPP_
56 #include <com/sun/star/util/URL.hpp>
57 #endif
58 #ifndef _COM_SUN_STAR_FRAME_FRAMESEARCHFLAG_HPP_
59 #include <com/sun/star/frame/FrameSearchFlag.hpp>
60 #endif
61 #ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
62 #include <com/sun/star/container/XNameContainer.hpp>
63 #endif
64 #ifndef _COM_SUN_STAR_UCB_XCOMMANDPROCESSOR_HPP_
65 #include <com/sun/star/ucb/XCommandProcessor.hpp>
66 #endif
67 #ifndef _COM_SUN_STAR_UCB_OPENCOMMANDARGUMENT_HPP_
68 #include <com/sun/star/ucb/OpenCommandArgument.hpp>
69 #endif
70 #ifndef _COM_SUN_STAR_UCB_OPENMODE_HPP_
71 #include <com/sun/star/ucb/OpenMode.hpp>
72 #endif
73 #ifndef _COM_SUN_STAR_TASK_XJOBEXECUTOR_HPP_
74 #include <com/sun/star/task/XJobExecutor.hpp>
75 #endif
76 #ifndef _COMPHELPER_EXTRACT_HXX_
77 #include <comphelper/extract.hxx>
78 #endif
79 #ifndef _COMPHELPER_TYPES_HXX_
80 #include <comphelper/types.hxx>
81 #endif
82 #ifndef _SV_MSGBOX_HXX
83 #include <vcl/msgbox.hxx>
84 #endif
85 #ifndef _UCBHELPER_CONTENT_HXX
86 #include <ucbhelper/content.hxx>
87 #endif
88 #ifndef _DBU_MISC_HRC_
89 #include "dbu_misc.hrc"
90 #endif
91 #ifndef SVTOOLS_FILENOTATION_HXX_
92 #include <svl/filenotation.hxx>
93 #endif
94 #ifndef DBACCESS_UI_BROWSER_ID_HXX
95 #include "browserids.hxx"
96 #endif
97 #ifndef _SFXNEW_HXX
98 #include <sfx2/new.hxx>
99 #endif
100 #ifndef _SVTOOLS_TEMPLDLG_HXX
101 #include <svtools/templdlg.hxx>
102 #endif
103 #ifndef _DBAUI_MODULE_DBU_HXX_
104 #include "moduledbu.hxx"
105 #endif
106 // -----------------
107 // for calling basic
108 #ifndef _SFXAPP_HXX
109 #include <sfx2/app.hxx>
110 #endif
111 #ifndef _SBXCLASS_HXX
112 #include <basic/sbx.hxx>
113 #endif
114 #ifndef _SB_SBUNO_HXX
115 #include <basic/sbuno.hxx>
116 #endif
117 #ifndef _EHDL_HXX
118 #include <svtools/ehdl.hxx>
119 #endif
120 #ifndef _SVX_DATACCESSDESCRIPTOR_HXX_
121 #include <svx/dataaccessdescriptor.hxx>
122 #endif
123 #ifndef _COM_SUN_STAR_CONTAINER_XHIERARCHICALNAMECONTAINER_HPP_
124 #include <com/sun/star/container/XHierarchicalNameContainer.hpp>
125 #endif
126 #ifndef _SV_WAITOBJ_HXX
127 #include <vcl/waitobj.hxx>
128 #endif
129 #ifndef _COMPHELPER_MIMECONFIGHELPER_HXX_
130 #include <comphelper/mimeconfighelper.hxx>
131 #endif
132 
133 #include <cppuhelper/exc_hlp.hxx>
134 #include <connectivity/dbtools.hxx>
135 #include <toolkit/helper/vclunohelper.hxx>
136 #include <com/sun/star/io/WrongFormatException.hpp>
137 #include "com/sun/star/sdb/RowSetVetoException.hpp"
138 
139 //......................................................................
140 namespace dbaui
141 {
142 //......................................................................
143 
144 	using namespace ::com::sun::star::uno;
145 	using namespace ::com::sun::star::container;
146 	using namespace ::com::sun::star::lang;
147 	using namespace ::com::sun::star::frame;
148 	using namespace ::com::sun::star::beans;
149 	using namespace ::com::sun::star::util;
150 	using namespace ::com::sun::star::ucb;
151 	using namespace ::com::sun::star::sdbc;
152     using namespace ::com::sun::star::sdb::application;
153 	using namespace ::com::sun::star::task;
154 	using namespace ::svt;
155 
156 	namespace
157 	{
158 		Sequence< sal_Int8 > lcl_GetSequenceClassID( sal_uInt32 n1, sal_uInt16 n2, sal_uInt16 n3,
159 													sal_uInt8 b8, sal_uInt8 b9, sal_uInt8 b10, sal_uInt8 b11,
160 													sal_uInt8 b12, sal_uInt8 b13, sal_uInt8 b14, sal_uInt8 b15 )
161 		{
162 			Sequence< sal_Int8 > aResult( 16 );
163 			aResult[0] = static_cast<sal_Int8>(n1 >> 24);
164 			aResult[1] = static_cast<sal_Int8>(( n1 << 8 ) >> 24);
165 			aResult[2] = static_cast<sal_Int8>(( n1 << 16 ) >> 24);
166 			aResult[3] = static_cast<sal_Int8>(( n1 << 24 ) >> 24);
167 			aResult[4] = static_cast<sal_Int8>(n2 >> 8);
168 			aResult[5] = static_cast<sal_Int8>(( n2 << 8 ) >> 8);
169 			aResult[6] = static_cast<sal_Int8>(n3 >> 8);
170 			aResult[7] = static_cast<sal_Int8>(( n3 << 8 ) >> 8);
171 			aResult[8] = b8;
172 			aResult[9] = b9;
173 			aResult[10] = b10;
174 			aResult[11] = b11;
175 			aResult[12] = b12;
176 			aResult[13] = b13;
177 			aResult[14] = b14;
178 			aResult[15] = b15;
179 
180 			return aResult;
181 		}
182 	}
183 
184 
185 	//==================================================================
186 	//= OLinkedDocumentsAccess
187 	//==================================================================
188 	DBG_NAME(OLinkedDocumentsAccess)
189 	//------------------------------------------------------------------
190 	OLinkedDocumentsAccess::OLinkedDocumentsAccess( Window* _pDialogParent, const Reference< XDatabaseDocumentUI >& i_rDocumentUI,
191         const Reference< XMultiServiceFactory >& _rxORB, const Reference< XNameAccess >& _rxContainer,
192         const Reference< XConnection>& _xConnection, const ::rtl::OUString& _sDataSourceName )
193 		:m_xORB(_rxORB)
194 		,m_xDocumentContainer(_rxContainer)
195 		,m_xConnection(_xConnection)
196         ,m_xDocumentUI( i_rDocumentUI )
197 		,m_pDialogParent(_pDialogParent)
198         ,m_sDataSourceName(_sDataSourceName)
199 	{
200 		DBG_CTOR(OLinkedDocumentsAccess,NULL);
201 		OSL_ENSURE(m_xORB.is(), "OLinkedDocumentsAccess::OLinkedDocumentsAccess: invalid service factory!");
202 		OSL_ENSURE(m_pDialogParent, "OLinkedDocumentsAccess::OLinkedDocumentsAccess: really need a dialog parent!");
203 	}
204 	//------------------------------------------------------------------
205 	OLinkedDocumentsAccess::~OLinkedDocumentsAccess()
206 	{
207 		DBG_DTOR(OLinkedDocumentsAccess,NULL);
208 	}
209 	//------------------------------------------------------------------
210 	Reference< XComponent> OLinkedDocumentsAccess::impl_open( const ::rtl::OUString& _rLinkName, Reference< XComponent >& _xDefinition,
211         ElementOpenMode _eOpenMode, const ::comphelper::NamedValueCollection& _rAdditionalArgs )
212 	{
213 		Reference< XComponent> xRet;
214         OSL_ENSURE(m_xDocumentContainer.is(), "OLinkedDocumentsAccess::OLinkedDocumentsAccess: invalid document container!");
215 		Reference< XComponentLoader > xComponentLoader(m_xDocumentContainer,UNO_QUERY);
216 		if ( !xComponentLoader.is() )
217 			return xRet;
218 
219 		WaitObject aWaitCursor( m_pDialogParent );
220 
221         ::comphelper::NamedValueCollection aArguments;
222         ::rtl::OUString sOpenMode;
223 		switch ( _eOpenMode )
224 		{
225             case E_OPEN_NORMAL:
226                 sOpenMode = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) );
227                 break;
228 
229             case E_OPEN_FOR_MAIL:
230                 aArguments.put( "Hidden", true );
231                 // fall through
232 
233             case E_OPEN_DESIGN:
234                 sOpenMode = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "openDesign" ) );
235                 break;
236 
237             default:
238                 OSL_ENSURE( false, "OLinkedDocumentsAccess::implOpen: invalid open mode!" );
239                 break;
240         }
241         aArguments.put( "OpenMode", sOpenMode );
242 
243         aArguments.put( (::rtl::OUString)PROPERTY_ACTIVE_CONNECTION, m_xConnection );
244 		try
245 		{
246 			Reference<XHierarchicalNameContainer> xHier(m_xDocumentContainer,UNO_QUERY);
247 			if ( xHier.is() && xHier->hasByHierarchicalName(_rLinkName) )
248 			{
249 				_xDefinition.set(xHier->getByHierarchicalName(_rLinkName),UNO_QUERY);
250 			}
251 
252             aArguments.merge( _rAdditionalArgs, true );
253 
254 			xRet = xComponentLoader->loadComponentFromURL( _rLinkName, ::rtl::OUString(), 0, aArguments.getPropertyValues() );
255 		}
256 		catch(Exception& e)
257 		{
258 			(void)e;
259 			throw;
260 		}
261 
262 		return xRet;
263 	}
264     //------------------------------------------------------------------
265     void OLinkedDocumentsAccess::impl_newWithPilot( const char* _pWizardService,
266         const sal_Int32 _nCommandType, const ::rtl::OUString& _rObjectName )
267 	{
268 		try
269 		{
270             ::comphelper::NamedValueCollection aArgs;
271             aArgs.put( "DataSourceName", m_sDataSourceName );
272 
273 			if ( m_xConnection.is() )
274                 aArgs.put( "ActiveConnection", m_xConnection );
275 
276             if ( _rObjectName.getLength() && ( _nCommandType != -1 ) )
277             {
278                 aArgs.put( "CommandType", _nCommandType );
279                 aArgs.put( "Command", _rObjectName );
280             }
281 
282             aArgs.put( "DocumentUI", m_xDocumentUI );
283 
284 			Reference< XJobExecutor > xWizard;
285 			{
286 				WaitObject aWaitCursor( m_pDialogParent );
287                 xWizard.set( m_xORB->createInstanceWithArguments(
288                     ::rtl::OUString::createFromAscii( _pWizardService ),
289                     aArgs.getWrappedPropertyValues()
290                     ), UNO_QUERY_THROW );
291 			}
292 
293 			xWizard->trigger( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "start" ) ) );
294             ::comphelper::disposeComponent( xWizard );
295 		}
296 		catch(const Exception& e)
297 		{
298             DBG_UNHANDLED_EXCEPTION();
299 		}
300 	}
301 	//------------------------------------------------------------------
302 	void OLinkedDocumentsAccess::newFormWithPilot( const sal_Int32 _nCommandType,const ::rtl::OUString& _rObjectName )
303 	{
304         impl_newWithPilot( "com.sun.star.wizards.form.CallFormWizard", _nCommandType, _rObjectName );
305 	}
306 
307     //------------------------------------------------------------------
308 	void OLinkedDocumentsAccess::newReportWithPilot( const sal_Int32 _nCommandType, const ::rtl::OUString& _rObjectName )
309 	{
310         impl_newWithPilot( "com.sun.star.wizards.report.CallReportWizard", _nCommandType, _rObjectName );
311 	}
312     //------------------------------------------------------------------
313 	void OLinkedDocumentsAccess::newTableWithPilot()
314 	{
315         impl_newWithPilot( "com.sun.star.wizards.table.CallTableWizard", -1, ::rtl::OUString() );
316 	}
317     //------------------------------------------------------------------
318 	void OLinkedDocumentsAccess::newQueryWithPilot()
319 	{
320         impl_newWithPilot( "com.sun.star.wizards.query.CallQueryWizard", -1, ::rtl::OUString() );
321 	}
322 	//------------------------------------------------------------------
323     Reference< XComponent > OLinkedDocumentsAccess::newDocument( sal_Int32 i_nActionID,
324         const ::comphelper::NamedValueCollection& i_rCreationArgs, Reference< XComponent >& o_rDefinition )
325 	{
326         OSL_ENSURE(m_xDocumentContainer.is(), "OLinkedDocumentsAccess::newDocument: invalid document container!");
327 		// determine the class ID to use for the new document
328 		Sequence<sal_Int8> aClassId;
329         if  (   !i_rCreationArgs.has( "ClassID" )
330             &&  !i_rCreationArgs.has( "MediaType" )
331             &&  !i_rCreationArgs.has( "DocumentServiceName" )
332             )
333         {
334 		    switch ( i_nActionID )
335 		    {
336 			    case ID_FORM_NEW_TEXT:
337 				    aClassId = lcl_GetSequenceClassID(SO3_SW_CLASSID);
338 				    OSL_ENSURE(aClassId == comphelper::MimeConfigurationHelper::GetSequenceClassID(SO3_SW_CLASSID),"Not equal");
339 				    break;
340 
341 			    case ID_FORM_NEW_CALC:
342 				    aClassId = lcl_GetSequenceClassID(SO3_SC_CLASSID);
343 				    break;
344 
345 			    case ID_FORM_NEW_IMPRESS:
346 				    aClassId = lcl_GetSequenceClassID(SO3_SIMPRESS_CLASSID);
347 				    break;
348 
349 			    case ID_REPORT_NEW_TEXT:
350 				    aClassId = comphelper::MimeConfigurationHelper::GetSequenceClassID(SO3_RPT_CLASSID_90);
351 				    break;
352 
353 			    default:
354 				    OSL_ENSURE( sal_False, "OLinkedDocumentsAccess::newDocument: please use newFormWithPilot!" );
355 				    return Reference< XComponent >();
356 
357 		    }
358         }
359 
360 		// load the document as template
361 		Reference< XComponent > xNewDocument;
362 		try
363 		{	// get the desktop object
364 
365 			Reference<XMultiServiceFactory> xORB(m_xDocumentContainer,UNO_QUERY);
366 			if ( xORB.is() )
367 			{
368                 ::comphelper::NamedValueCollection aCreationArgs( i_rCreationArgs );
369                 if ( aClassId.getLength() )
370                     aCreationArgs.put( "ClassID", aClassId );
371                 aCreationArgs.put( (::rtl::OUString)PROPERTY_ACTIVE_CONNECTION, m_xConnection );
372 
373                 // separate values which are real creation args from args relevant for opening the doc
374                 ::comphelper::NamedValueCollection aCommandArgs;
375                 if ( aCreationArgs.has( "Hidden" ) )
376                 {
377                     aCommandArgs.put( "Hidden", aCreationArgs.get( "Hidden" ) );
378                     aCreationArgs.remove( "Hidden" );
379                 }
380 
381 				Reference< XCommandProcessor > xContent( xORB->createInstanceWithArguments(
382                         SERVICE_SDB_DOCUMENTDEFINITION,
383                         aCreationArgs.getWrappedPropertyValues()
384                     ),
385                     UNO_QUERY_THROW
386                 );
387 				o_rDefinition.set( xContent, UNO_QUERY );
388 
389                 // put the OpenMode into the OpenArgs
390                 OpenCommandArgument aOpenModeArg;
391 			    aOpenModeArg.Mode = OpenMode::DOCUMENT;
392                 aCommandArgs.put( "OpenMode", aOpenModeArg );
393 
394 			    Command aCommand;
395 			    aCommand.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "openDesign" ) );
396 			    aCommand.Argument <<= aCommandArgs.getPropertyValues();
397 			    WaitObject aWaitCursor( m_pDialogParent );
398 			    xNewDocument.set( xContent->execute( aCommand, xContent->createCommandIdentifier(), NULL ), UNO_QUERY );
399 			}
400 		}
401 		catch(const Exception& )
402 		{
403 			DBG_UNHANDLED_EXCEPTION();
404 		}
405 
406 		return xNewDocument;
407 	}
408 
409 	//------------------------------------------------------------------
410 	Reference< XComponent > OLinkedDocumentsAccess::open( const ::rtl::OUString& _rLinkName, Reference< XComponent >& _xDefinition,
411         ElementOpenMode _eOpenMode, const ::comphelper::NamedValueCollection& _rAdditionalArgs )
412 	{
413 		dbtools::SQLExceptionInfo aInfo;
414         Reference< XComponent > xRet;
415 		try
416 		{
417 			xRet = impl_open( _rLinkName, _xDefinition, _eOpenMode, _rAdditionalArgs );
418 			if ( !xRet.is() )
419 			{
420                 String sMessage = String(ModuleRes(STR_COULDNOTOPEN_LINKEDDOC));
421                 sMessage.SearchAndReplaceAscii("$file$",_rLinkName);
422 
423                 com::sun::star::sdbc::SQLException aSQLException;
424                 aSQLException.Message = sMessage;
425                 // aSQLException.Context = e.Context;
426                 aInfo = dbtools::SQLExceptionInfo(aSQLException);
427 			}
428 			return xRet;
429 		}
430 		catch (com::sun::star::io::WrongFormatException e)
431 		{
432             com::sun::star::sdbc::SQLException aSQLException;
433             aSQLException.Message = e.Message;
434             aSQLException.Context = e.Context;
435 			aInfo = dbtools::SQLExceptionInfo(aSQLException);
436 
437 			// more like a hack, insert an empty message
438             String sText( ModuleRes( RID_STR_EXTENSION_NOT_PRESENT ) );
439             sText.SearchAndReplaceAscii("$file$",_rLinkName);
440             aInfo.prepend(sText);
441 
442 			String sMessage = String(ModuleRes(STR_COULDNOTOPEN_LINKEDDOC));
443 			sMessage.SearchAndReplaceAscii("$file$",_rLinkName);
444             aInfo.prepend(sMessage);
445         }
446         catch(Exception& e)
447         {
448             Any aAny = ::cppu::getCaughtException();
449             com::sun::star::sdbc::SQLException a;
450             if ( !(aAny >>= a) || (a.ErrorCode != dbtools::ParameterInteractionCancelled) )
451             {
452                 com::sun::star::sdbc::SQLException aSQLException;
453                 aSQLException.Message = e.Message;
454                 aSQLException.Context = e.Context;
455                 aInfo = dbtools::SQLExceptionInfo(aSQLException);
456 
457                 // more like a hack, insert an empty message
458                 aInfo.prepend(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" \n")));
459 
460                 String sMessage = String(ModuleRes(STR_COULDNOTOPEN_LINKEDDOC));
461                 sMessage.SearchAndReplaceAscii("$file$",_rLinkName);
462                 aInfo.prepend(sMessage);
463             }
464         }
465         if (aInfo.isValid())
466         {
467             showError(aInfo, VCLUnoHelper::GetInterface(m_pDialogParent), m_xORB );
468         }
469         return xRet;
470     }
471 
472 
473 //......................................................................
474 }	// namespace dbaui
475 //......................................................................
476 
477