1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
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.
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).
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.
27 ************************************************************************/
30 #include "linkeddocuments.hxx"
31 #include <osl/diagnose.h>
32 #include <tools/diagnose_ex.h>
33 #include <unotools/confignode.hxx>
34 #include "dbustrings.hrc"
35 #include <comphelper/classids.hxx>
36 #include <comphelper/namedvaluecollection.hxx>
37 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
38 #include <com/sun/star/frame/XDispatchProvider.hpp>
39 #include <com/sun/star/frame/XComponentLoader.hpp>
40 #include <com/sun/star/util/URL.hpp>
41 #include <com/sun/star/frame/FrameSearchFlag.hpp>
42 #include <com/sun/star/container/XNameContainer.hpp>
43 #include <com/sun/star/ucb/XCommandProcessor.hpp>
44 #include <com/sun/star/ucb/OpenCommandArgument.hpp>
45 #include <com/sun/star/ucb/OpenMode.hpp>
46 #include <com/sun/star/task/XJobExecutor.hpp>
47 #include <comphelper/extract.hxx>
48 #include <comphelper/types.hxx>
49 #include <vcl/msgbox.hxx>
50 #include <ucbhelper/content.hxx>
51 #include "dbu_misc.hrc"
52 #include <svl/filenotation.hxx>
53 #include "browserids.hxx"
54 #include <sfx2/new.hxx>
55 #include "moduledbu.hxx"
58 #include <sfx2/app.hxx>
59 #include <basic/sbx.hxx>
60 #include <basic/sbuno.hxx>
61 #include <svtools/ehdl.hxx>
62 #include <svx/dataaccessdescriptor.hxx>
63 #include <com/sun/star/container/XHierarchicalNameContainer.hpp>
64 #include <vcl/waitobj.hxx>
65 #include <comphelper/mimeconfighelper.hxx>
67 #include <cppuhelper/exc_hlp.hxx>
68 #include <connectivity/dbtools.hxx>
69 #include <toolkit/helper/vclunohelper.hxx>
70 #include <com/sun/star/io/WrongFormatException.hpp>
71 #include "com/sun/star/sdb/RowSetVetoException.hpp"
73 //......................................................................
76 //......................................................................
78 using namespace ::com::sun::star::uno
;
79 using namespace ::com::sun::star::container
;
80 using namespace ::com::sun::star::lang
;
81 using namespace ::com::sun::star::frame
;
82 using namespace ::com::sun::star::beans
;
83 using namespace ::com::sun::star::util
;
84 using namespace ::com::sun::star::ucb
;
85 using namespace ::com::sun::star::sdbc
;
86 using namespace ::com::sun::star::sdb::application
;
87 using namespace ::com::sun::star::task
;
88 using namespace ::svt
;
92 Sequence
< sal_Int8
> lcl_GetSequenceClassID( sal_uInt32 n1
, sal_uInt16 n2
, sal_uInt16 n3
,
93 sal_uInt8 b8
, sal_uInt8 b9
, sal_uInt8 b10
, sal_uInt8 b11
,
94 sal_uInt8 b12
, sal_uInt8 b13
, sal_uInt8 b14
, sal_uInt8 b15
)
96 Sequence
< sal_Int8
> aResult( 16 );
97 aResult
[0] = static_cast<sal_Int8
>(n1
>> 24);
98 aResult
[1] = static_cast<sal_Int8
>(( n1
<< 8 ) >> 24);
99 aResult
[2] = static_cast<sal_Int8
>(( n1
<< 16 ) >> 24);
100 aResult
[3] = static_cast<sal_Int8
>(( n1
<< 24 ) >> 24);
101 aResult
[4] = static_cast<sal_Int8
>(n2
>> 8);
102 aResult
[5] = static_cast<sal_Int8
>(( n2
<< 8 ) >> 8);
103 aResult
[6] = static_cast<sal_Int8
>(n3
>> 8);
104 aResult
[7] = static_cast<sal_Int8
>(( n3
<< 8 ) >> 8);
119 //==================================================================
120 //= OLinkedDocumentsAccess
121 //==================================================================
122 DBG_NAME(OLinkedDocumentsAccess
)
123 //------------------------------------------------------------------
124 OLinkedDocumentsAccess::OLinkedDocumentsAccess( Window
* _pDialogParent
, const Reference
< XDatabaseDocumentUI
>& i_rDocumentUI
,
125 const Reference
< XMultiServiceFactory
>& _rxORB
, const Reference
< XNameAccess
>& _rxContainer
,
126 const Reference
< XConnection
>& _xConnection
, const ::rtl::OUString
& _sDataSourceName
)
128 ,m_xDocumentContainer(_rxContainer
)
129 ,m_xConnection(_xConnection
)
130 ,m_xDocumentUI( i_rDocumentUI
)
131 ,m_pDialogParent(_pDialogParent
)
132 ,m_sDataSourceName(_sDataSourceName
)
134 DBG_CTOR(OLinkedDocumentsAccess
,NULL
);
135 OSL_ENSURE(m_xORB
.is(), "OLinkedDocumentsAccess::OLinkedDocumentsAccess: invalid service factory!");
136 OSL_ENSURE(m_pDialogParent
, "OLinkedDocumentsAccess::OLinkedDocumentsAccess: really need a dialog parent!");
138 //------------------------------------------------------------------
139 OLinkedDocumentsAccess::~OLinkedDocumentsAccess()
141 DBG_DTOR(OLinkedDocumentsAccess
,NULL
);
143 //------------------------------------------------------------------
144 Reference
< XComponent
> OLinkedDocumentsAccess::impl_open( const ::rtl::OUString
& _rLinkName
, Reference
< XComponent
>& _xDefinition
,
145 ElementOpenMode _eOpenMode
, const ::comphelper::NamedValueCollection
& _rAdditionalArgs
)
147 Reference
< XComponent
> xRet
;
148 OSL_ENSURE(m_xDocumentContainer
.is(), "OLinkedDocumentsAccess::OLinkedDocumentsAccess: invalid document container!");
149 Reference
< XComponentLoader
> xComponentLoader(m_xDocumentContainer
,UNO_QUERY
);
150 if ( !xComponentLoader
.is() )
153 WaitObject
aWaitCursor( m_pDialogParent
);
155 ::comphelper::NamedValueCollection aArguments
;
156 ::rtl::OUString sOpenMode
;
157 switch ( _eOpenMode
)
160 sOpenMode
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) );
163 case E_OPEN_FOR_MAIL
:
164 aArguments
.put( "Hidden", true );
168 sOpenMode
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "openDesign" ) );
172 OSL_FAIL( "OLinkedDocumentsAccess::implOpen: invalid open mode!" );
175 aArguments
.put( "OpenMode", sOpenMode
);
177 aArguments
.put( (::rtl::OUString
)PROPERTY_ACTIVE_CONNECTION
, m_xConnection
);
180 Reference
<XHierarchicalNameContainer
> xHier(m_xDocumentContainer
,UNO_QUERY
);
181 if ( xHier
.is() && xHier
->hasByHierarchicalName(_rLinkName
) )
183 _xDefinition
.set(xHier
->getByHierarchicalName(_rLinkName
),UNO_QUERY
);
186 aArguments
.merge( _rAdditionalArgs
, true );
188 xRet
= xComponentLoader
->loadComponentFromURL( _rLinkName
, ::rtl::OUString(), 0, aArguments
.getPropertyValues() );
190 catch(const Exception
&)
197 //------------------------------------------------------------------
198 void OLinkedDocumentsAccess::impl_newWithPilot( const char* _pWizardService
,
199 const sal_Int32 _nCommandType
, const ::rtl::OUString
& _rObjectName
)
203 ::comphelper::NamedValueCollection aArgs
;
204 aArgs
.put( "DataSourceName", m_sDataSourceName
);
206 if ( m_xConnection
.is() )
207 aArgs
.put( "ActiveConnection", m_xConnection
);
209 if ( !_rObjectName
.isEmpty() && ( _nCommandType
!= -1 ) )
211 aArgs
.put( "CommandType", _nCommandType
);
212 aArgs
.put( "Command", _rObjectName
);
215 aArgs
.put( "DocumentUI", m_xDocumentUI
);
217 Reference
< XJobExecutor
> xWizard
;
219 WaitObject
aWaitCursor( m_pDialogParent
);
220 xWizard
.set( m_xORB
->createInstanceWithArguments(
221 ::rtl::OUString::createFromAscii( _pWizardService
),
222 aArgs
.getWrappedPropertyValues()
223 ), UNO_QUERY_THROW
);
226 xWizard
->trigger( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "start" ) ) );
227 ::comphelper::disposeComponent( xWizard
);
229 catch(const Exception
&)
231 DBG_UNHANDLED_EXCEPTION();
234 //------------------------------------------------------------------
235 void OLinkedDocumentsAccess::newFormWithPilot( const sal_Int32 _nCommandType
,const ::rtl::OUString
& _rObjectName
)
237 impl_newWithPilot( "com.sun.star.wizards.form.CallFormWizard", _nCommandType
, _rObjectName
);
240 //------------------------------------------------------------------
241 void OLinkedDocumentsAccess::newReportWithPilot( const sal_Int32 _nCommandType
, const ::rtl::OUString
& _rObjectName
)
243 impl_newWithPilot( "com.sun.star.wizards.report.CallReportWizard", _nCommandType
, _rObjectName
);
245 //------------------------------------------------------------------
246 void OLinkedDocumentsAccess::newTableWithPilot()
248 impl_newWithPilot( "com.sun.star.wizards.table.CallTableWizard", -1, ::rtl::OUString() );
250 //------------------------------------------------------------------
251 void OLinkedDocumentsAccess::newQueryWithPilot()
253 impl_newWithPilot( "com.sun.star.wizards.query.CallQueryWizard", -1, ::rtl::OUString() );
255 //------------------------------------------------------------------
256 Reference
< XComponent
> OLinkedDocumentsAccess::newDocument( sal_Int32 i_nActionID
,
257 const ::comphelper::NamedValueCollection
& i_rCreationArgs
, Reference
< XComponent
>& o_rDefinition
)
259 OSL_ENSURE(m_xDocumentContainer
.is(), "OLinkedDocumentsAccess::newDocument: invalid document container!");
260 // determine the class ID to use for the new document
261 Sequence
<sal_Int8
> aClassId
;
262 if ( !i_rCreationArgs
.has( "ClassID" )
263 && !i_rCreationArgs
.has( "MediaType" )
264 && !i_rCreationArgs
.has( "DocumentServiceName" )
267 switch ( i_nActionID
)
269 case ID_FORM_NEW_TEXT
:
270 aClassId
= lcl_GetSequenceClassID(SO3_SW_CLASSID
);
271 OSL_ENSURE(aClassId
== comphelper::MimeConfigurationHelper::GetSequenceClassID(SO3_SW_CLASSID
),"Not equal");
274 case ID_FORM_NEW_CALC
:
275 aClassId
= lcl_GetSequenceClassID(SO3_SC_CLASSID
);
278 case ID_FORM_NEW_IMPRESS
:
279 aClassId
= lcl_GetSequenceClassID(SO3_SIMPRESS_CLASSID
);
282 case ID_REPORT_NEW_TEXT
:
283 aClassId
= comphelper::MimeConfigurationHelper::GetSequenceClassID(SO3_RPT_CLASSID_90
);
287 OSL_FAIL( "OLinkedDocumentsAccess::newDocument: please use newFormWithPilot!" );
288 return Reference
< XComponent
>();
293 // load the document as template
294 Reference
< XComponent
> xNewDocument
;
296 { // get the desktop object
298 Reference
<XMultiServiceFactory
> xORB(m_xDocumentContainer
,UNO_QUERY
);
301 ::comphelper::NamedValueCollection
aCreationArgs( i_rCreationArgs
);
302 if ( aClassId
.getLength() )
303 aCreationArgs
.put( "ClassID", aClassId
);
304 aCreationArgs
.put( (::rtl::OUString
)PROPERTY_ACTIVE_CONNECTION
, m_xConnection
);
306 // separate values which are real creation args from args relevant for opening the doc
307 ::comphelper::NamedValueCollection aCommandArgs
;
308 if ( aCreationArgs
.has( "Hidden" ) )
310 aCommandArgs
.put( "Hidden", aCreationArgs
.get( "Hidden" ) );
311 aCreationArgs
.remove( "Hidden" );
314 Reference
< XCommandProcessor
> xContent( xORB
->createInstanceWithArguments(
315 SERVICE_SDB_DOCUMENTDEFINITION
,
316 aCreationArgs
.getWrappedPropertyValues()
320 o_rDefinition
.set( xContent
, UNO_QUERY
);
322 // put the OpenMode into the OpenArgs
323 OpenCommandArgument aOpenModeArg
;
324 aOpenModeArg
.Mode
= OpenMode::DOCUMENT
;
325 aCommandArgs
.put( "OpenMode", aOpenModeArg
);
328 aCommand
.Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "openDesign" ) );
329 aCommand
.Argument
<<= aCommandArgs
.getPropertyValues();
330 WaitObject
aWaitCursor( m_pDialogParent
);
331 xNewDocument
.set( xContent
->execute( aCommand
, xContent
->createCommandIdentifier(), NULL
), UNO_QUERY
);
334 catch(const Exception
&)
336 DBG_UNHANDLED_EXCEPTION();
342 //------------------------------------------------------------------
343 Reference
< XComponent
> OLinkedDocumentsAccess::open( const ::rtl::OUString
& _rLinkName
, Reference
< XComponent
>& _xDefinition
,
344 ElementOpenMode _eOpenMode
, const ::comphelper::NamedValueCollection
& _rAdditionalArgs
)
346 dbtools::SQLExceptionInfo aInfo
;
347 Reference
< XComponent
> xRet
;
350 xRet
= impl_open( _rLinkName
, _xDefinition
, _eOpenMode
, _rAdditionalArgs
);
353 String sMessage
= String(ModuleRes(STR_COULDNOTOPEN_LINKEDDOC
));
354 sMessage
.SearchAndReplaceAscii("$file$",_rLinkName
);
356 com::sun::star::sdbc::SQLException aSQLException
;
357 aSQLException
.Message
= sMessage
;
358 aInfo
= dbtools::SQLExceptionInfo(aSQLException
);
362 catch(const com::sun::star::io::WrongFormatException
&e
)
364 com::sun::star::sdbc::SQLException aSQLException
;
365 aSQLException
.Message
= e
.Message
;
366 aSQLException
.Context
= e
.Context
;
367 aInfo
= dbtools::SQLExceptionInfo(aSQLException
);
369 // more like a hack, insert an empty message
370 String
sText( ModuleRes( RID_STR_EXTENSION_NOT_PRESENT
) );
371 sText
.SearchAndReplaceAscii("$file$",_rLinkName
);
372 aInfo
.prepend(sText
);
374 String sMessage
= String(ModuleRes(STR_COULDNOTOPEN_LINKEDDOC
));
375 sMessage
.SearchAndReplaceAscii("$file$",_rLinkName
);
376 aInfo
.prepend(sMessage
);
378 catch(const Exception
& e
)
380 Any aAny
= ::cppu::getCaughtException();
381 com::sun::star::sdbc::SQLException a
;
382 if ( !(aAny
>>= a
) || (a
.ErrorCode
!= dbtools::ParameterInteractionCancelled
) )
384 com::sun::star::sdbc::SQLException aSQLException
;
385 aSQLException
.Message
= e
.Message
;
386 aSQLException
.Context
= e
.Context
;
387 aInfo
= dbtools::SQLExceptionInfo(aSQLException
);
389 // more like a hack, insert an empty message
390 aInfo
.prepend(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" \n")));
392 String sMessage
= String(ModuleRes(STR_COULDNOTOPEN_LINKEDDOC
));
393 sMessage
.SearchAndReplaceAscii("$file$",_rLinkName
);
394 aInfo
.prepend(sMessage
);
399 showError(aInfo
, VCLUnoHelper::GetInterface(m_pDialogParent
), m_xORB
);
405 //......................................................................
407 //......................................................................
409 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */