xref: /AOO41X/main/dbaccess/source/ui/misc/linkeddocuments.cxx (revision 96de54900b79e13b861fbc62cbf36018b54e21b7)
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     {
lcl_GetSequenceClassID(sal_uInt32 n1,sal_uInt16 n2,sal_uInt16 n3,sal_uInt8 b8,sal_uInt8 b9,sal_uInt8 b10,sal_uInt8 b11,sal_uInt8 b12,sal_uInt8 b13,sal_uInt8 b14,sal_uInt8 b15)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     //==================================================================
DBG_NAME(OLinkedDocumentsAccess)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     //------------------------------------------------------------------
~OLinkedDocumentsAccess()201     OLinkedDocumentsAccess::~OLinkedDocumentsAccess()
202     {
203         DBG_DTOR(OLinkedDocumentsAccess,NULL);
204     }
205     //------------------------------------------------------------------
impl_open(const::rtl::OUString & _rLinkName,Reference<XComponent> & _xDefinition,ElementOpenMode _eOpenMode,const::comphelper::NamedValueCollection & _rAdditionalArgs)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     //------------------------------------------------------------------
impl_newWithPilot(const char * _pWizardService,const sal_Int32 _nCommandType,const::rtl::OUString & _rObjectName)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     //------------------------------------------------------------------
newFormWithPilot(const sal_Int32 _nCommandType,const::rtl::OUString & _rObjectName)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     //------------------------------------------------------------------
newReportWithPilot(const sal_Int32 _nCommandType,const::rtl::OUString & _rObjectName)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     //------------------------------------------------------------------
newTableWithPilot()309     void OLinkedDocumentsAccess::newTableWithPilot()
310     {
311         impl_newWithPilot( "com.sun.star.wizards.table.CallTableWizard", -1, ::rtl::OUString() );
312     }
313     //------------------------------------------------------------------
newQueryWithPilot()314     void OLinkedDocumentsAccess::newQueryWithPilot()
315     {
316         impl_newWithPilot( "com.sun.star.wizards.query.CallQueryWizard", -1, ::rtl::OUString() );
317     }
318     //------------------------------------------------------------------
newDocument(sal_Int32 i_nActionID,const::comphelper::NamedValueCollection & i_rCreationArgs,Reference<XComponent> & o_rDefinition)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     //------------------------------------------------------------------
open(const::rtl::OUString & _rLinkName,Reference<XComponent> & _xDefinition,ElementOpenMode _eOpenMode,const::comphelper::NamedValueCollection & _rAdditionalArgs)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