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