1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <core_resource.hxx>
21 #include <linkeddocuments.hxx>
22 #include <osl/diagnose.h>
23 #include <comphelper/diagnose_ex.hxx>
24 #include <unotools/confignode.hxx>
25 #include <comphelper/classids.hxx>
26 #include <comphelper/namedvaluecollection.hxx>
27 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
28 #include <com/sun/star/frame/XComponentLoader.hpp>
29 #include <com/sun/star/sdbc/SQLException.hpp>
30 #include <com/sun/star/ucb/XCommandProcessor.hpp>
31 #include <com/sun/star/ucb/OpenCommandArgument.hpp>
32 #include <com/sun/star/ucb/OpenMode.hpp>
33 #include <com/sun/star/task/XJobExecutor.hpp>
34 #include <comphelper/types.hxx>
35 #include <strings.hrc>
36 #include <strings.hxx>
37 #include <svl/filenotation.hxx>
38 #include <browserids.hxx>
39 #include <com/sun/star/container/XHierarchicalNameContainer.hpp>
40 #include <comphelper/mimeconfighelper.hxx>
42 #include <vcl/weld.hxx>
44 #include <cppuhelper/exc_hlp.hxx>
45 #include <connectivity/dbtools.hxx>
46 #include <com/sun/star/io/WrongFormatException.hpp>
51 using namespace ::com::sun::star::uno
;
52 using namespace ::com::sun::star::container
;
53 using namespace ::com::sun::star::lang
;
54 using namespace ::com::sun::star::frame
;
55 using namespace ::com::sun::star::beans
;
56 using namespace ::com::sun::star::util
;
57 using namespace ::com::sun::star::ucb
;
58 using namespace ::com::sun::star::sdbc
;
59 using namespace ::com::sun::star::sdb::application
;
60 using namespace ::com::sun::star::task
;
61 using namespace ::svt
;
65 Sequence
< sal_Int8
> lcl_GetSequenceClassID( sal_uInt32 n1
, sal_uInt16 n2
, sal_uInt16 n3
,
66 sal_uInt8 b8
, sal_uInt8 b9
, sal_uInt8 b10
, sal_uInt8 b11
,
67 sal_uInt8 b12
, sal_uInt8 b13
, sal_uInt8 b14
, sal_uInt8 b15
)
69 Sequence
< sal_Int8
> aResult
{ /* [ 0] */ static_cast<sal_Int8
>(n1
>> 24),
70 /* [ 1] */ static_cast<sal_Int8
>(( n1
<< 8 ) >> 24),
71 /* [ 2] */ static_cast<sal_Int8
>(( n1
<< 16 ) >> 24),
72 /* [ 3] */ static_cast<sal_Int8
>(( n1
<< 24 ) >> 24),
73 /* [ 4] */ static_cast<sal_Int8
>(n2
>> 8),
74 /* [ 5] */ static_cast<sal_Int8
>(( n2
<< 8 ) >> 8),
75 /* [ 6] */ static_cast<sal_Int8
>(n3
>> 8),
76 /* [ 7] */ static_cast<sal_Int8
>(( n3
<< 8 ) >> 8),
77 /* [ 8] */ static_cast<sal_Int8
>(b8
),
78 /* [ 9] */ static_cast<sal_Int8
>(b9
),
79 /* [10] */ static_cast<sal_Int8
>(b10
),
80 /* [11] */ static_cast<sal_Int8
>(b11
),
81 /* [12] */ static_cast<sal_Int8
>(b12
),
82 /* [13] */ static_cast<sal_Int8
>(b13
),
83 /* [14] */ static_cast<sal_Int8
>(b14
),
84 /* [15] */ static_cast<sal_Int8
>(b15
) };
89 // OLinkedDocumentsAccess
90 OLinkedDocumentsAccess::OLinkedDocumentsAccess( weld::Window
* pDialogParent
, const Reference
< XDatabaseDocumentUI
>& i_rDocumentUI
,
91 const Reference
< XComponentContext
>& _rxContext
, const Reference
< XNameAccess
>& _rxContainer
,
92 const Reference
< XConnection
>& _xConnection
, OUString _sDataSourceName
)
93 :m_xContext(_rxContext
)
94 ,m_xDocumentContainer(_rxContainer
)
95 ,m_xConnection(_xConnection
)
96 ,m_xDocumentUI( i_rDocumentUI
)
97 ,m_pDialogParent(pDialogParent
)
98 ,m_sDataSourceName(std::move(_sDataSourceName
))
100 OSL_ENSURE(m_xContext
.is(), "OLinkedDocumentsAccess::OLinkedDocumentsAccess: invalid service factory!");
101 assert(m_pDialogParent
&& "OLinkedDocumentsAccess::OLinkedDocumentsAccess: really need a dialog parent!");
103 OLinkedDocumentsAccess::~OLinkedDocumentsAccess()
106 Reference
< XComponent
> OLinkedDocumentsAccess::impl_open( const OUString
& _rLinkName
, Reference
< XComponent
>& _xDefinition
,
107 ElementOpenMode _eOpenMode
, const ::comphelper::NamedValueCollection
& _rAdditionalArgs
)
109 Reference
< XComponent
> xRet
;
110 OSL_ENSURE(m_xDocumentContainer
.is(), "OLinkedDocumentsAccess::OLinkedDocumentsAccess: invalid document container!");
111 Reference
< XComponentLoader
> xComponentLoader(m_xDocumentContainer
,UNO_QUERY
);
112 if ( !xComponentLoader
.is() )
115 weld::WaitObject
aWaitCursor(m_pDialogParent
);
117 ::comphelper::NamedValueCollection aArguments
;
119 switch ( _eOpenMode
)
121 case ElementOpenMode::Normal
:
125 case ElementOpenMode::Mail
:
126 aArguments
.put( "Hidden", true );
129 case ElementOpenMode::Design
:
130 sOpenMode
= "openDesign";
134 OSL_FAIL( "OLinkedDocumentsAccess::implOpen: invalid open mode!" );
137 aArguments
.put( "OpenMode", sOpenMode
);
139 aArguments
.put( PROPERTY_ACTIVE_CONNECTION
, m_xConnection
);
141 Reference
<XHierarchicalNameContainer
> xHier(m_xDocumentContainer
,UNO_QUERY
);
142 if ( xHier
.is() && xHier
->hasByHierarchicalName(_rLinkName
) )
144 _xDefinition
.set(xHier
->getByHierarchicalName(_rLinkName
),UNO_QUERY
);
147 aArguments
.merge( _rAdditionalArgs
, true );
149 xRet
= xComponentLoader
->loadComponentFromURL( _rLinkName
, OUString(), 0, aArguments
.getPropertyValues() );
153 void OLinkedDocumentsAccess::impl_newWithPilot( const char* _pWizardService
,
154 const sal_Int32 _nCommandType
, const OUString
& _rObjectName
)
158 ::comphelper::NamedValueCollection aArgs
;
159 aArgs
.put( "DataSourceName", m_sDataSourceName
);
161 if ( m_xConnection
.is() )
162 aArgs
.put( "ActiveConnection", m_xConnection
);
164 if ( !_rObjectName
.isEmpty() && ( _nCommandType
!= -1 ) )
166 aArgs
.put( "CommandType", _nCommandType
);
167 aArgs
.put( "Command", _rObjectName
);
170 aArgs
.put( "DocumentUI", m_xDocumentUI
);
172 Reference
< XJobExecutor
> xWizard
;
174 weld::WaitObject
aWaitCursor(m_pDialogParent
);
175 xWizard
.set( m_xContext
->getServiceManager()->createInstanceWithArgumentsAndContext(
176 OUString::createFromAscii( _pWizardService
),
177 aArgs
.getWrappedPropertyValues(),
179 ), UNO_QUERY_THROW
);
182 xWizard
->trigger( "start" );
183 ::comphelper::disposeComponent( xWizard
);
185 catch(const Exception
&)
187 DBG_UNHANDLED_EXCEPTION("dbaccess");
190 void OLinkedDocumentsAccess::newFormWithPilot( const sal_Int32 _nCommandType
,const OUString
& _rObjectName
)
192 impl_newWithPilot( "com.sun.star.wizards.form.CallFormWizard", _nCommandType
, _rObjectName
);
195 void OLinkedDocumentsAccess::newReportWithPilot( const sal_Int32 _nCommandType
, const OUString
& _rObjectName
)
197 impl_newWithPilot( "com.sun.star.wizards.report.CallReportWizard", _nCommandType
, _rObjectName
);
199 void OLinkedDocumentsAccess::newTableWithPilot()
201 impl_newWithPilot( "com.sun.star.wizards.table.CallTableWizard", -1, OUString() );
203 void OLinkedDocumentsAccess::newQueryWithPilot()
205 impl_newWithPilot( "com.sun.star.wizards.query.CallQueryWizard", -1, OUString() );
207 Reference
< XComponent
> OLinkedDocumentsAccess::newDocument( sal_Int32 i_nActionID
,
208 const ::comphelper::NamedValueCollection
& i_rCreationArgs
, Reference
< XComponent
>& o_rDefinition
)
210 OSL_ENSURE(m_xDocumentContainer
.is(), "OLinkedDocumentsAccess::newDocument: invalid document container!");
211 // determine the class ID to use for the new document
212 Sequence
<sal_Int8
> aClassId
;
213 if ( !i_rCreationArgs
.has( "ClassID" )
214 && !i_rCreationArgs
.has( "MediaType" )
215 && !i_rCreationArgs
.has( "DocumentServiceName" )
218 switch ( i_nActionID
)
220 case ID_FORM_NEW_TEXT
:
221 aClassId
= lcl_GetSequenceClassID(SO3_SW_CLASSID
);
222 OSL_ENSURE(aClassId
== comphelper::MimeConfigurationHelper::GetSequenceClassID(SO3_SW_CLASSID
),"Not equal");
225 case ID_FORM_NEW_CALC
:
226 aClassId
= lcl_GetSequenceClassID(SO3_SC_CLASSID
);
229 case ID_FORM_NEW_IMPRESS
:
230 aClassId
= lcl_GetSequenceClassID(SO3_SIMPRESS_CLASSID
);
233 case ID_REPORT_NEW_TEXT
:
234 aClassId
= comphelper::MimeConfigurationHelper::GetSequenceClassID(SO3_RPT_CLASSID_90
);
238 OSL_FAIL( "OLinkedDocumentsAccess::newDocument: please use newFormWithPilot!" );
239 return Reference
< XComponent
>();
244 // load the document as template
245 Reference
< XComponent
> xNewDocument
;
247 { // get the desktop object
249 Reference
<XMultiServiceFactory
> xORB(m_xDocumentContainer
,UNO_QUERY
);
252 ::comphelper::NamedValueCollection
aCreationArgs( i_rCreationArgs
);
253 if ( aClassId
.hasElements() )
254 aCreationArgs
.put( "ClassID", aClassId
);
255 aCreationArgs
.put( PROPERTY_ACTIVE_CONNECTION
, m_xConnection
);
257 // separate values which are real creation args from args relevant for opening the doc
258 ::comphelper::NamedValueCollection aCommandArgs
;
259 if ( aCreationArgs
.has( "Hidden" ) )
261 aCommandArgs
.put( "Hidden", aCreationArgs
.get( "Hidden" ) );
262 aCreationArgs
.remove( "Hidden" );
265 Reference
< XCommandProcessor
> xContent( xORB
->createInstanceWithArguments(
266 SERVICE_SDB_DOCUMENTDEFINITION
,
267 aCreationArgs
.getWrappedPropertyValues()
271 o_rDefinition
.set( xContent
, UNO_QUERY
);
273 // put the OpenMode into the OpenArgs
274 OpenCommandArgument aOpenModeArg
;
275 aOpenModeArg
.Mode
= OpenMode::DOCUMENT
;
276 aCommandArgs
.put( "OpenMode", aOpenModeArg
);
279 aCommand
.Name
= "openDesign";
280 aCommand
.Argument
<<= aCommandArgs
.getPropertyValues();
281 weld::WaitObject
aWaitCursor(m_pDialogParent
);
282 xNewDocument
.set( xContent
->execute( aCommand
, xContent
->createCommandIdentifier(), nullptr ), UNO_QUERY
);
285 catch(const Exception
&)
287 DBG_UNHANDLED_EXCEPTION("dbaccess");
293 Reference
< XComponent
> OLinkedDocumentsAccess::open( const OUString
& _rLinkName
, Reference
< XComponent
>& _xDefinition
,
294 ElementOpenMode _eOpenMode
, const ::comphelper::NamedValueCollection
& _rAdditionalArgs
)
296 dbtools::SQLExceptionInfo aInfo
;
297 Reference
< XComponent
> xRet
;
300 xRet
= impl_open( _rLinkName
, _xDefinition
, _eOpenMode
, _rAdditionalArgs
);
303 OUString sMessage
= DBA_RES(STR_COULDNOTOPEN_LINKEDDOC
);
304 sMessage
= sMessage
.replaceFirst("$file$",_rLinkName
);
306 css::sdbc::SQLException aSQLException
;
307 aSQLException
.Message
= sMessage
;
308 aInfo
= dbtools::SQLExceptionInfo(aSQLException
);
311 catch(const css::io::WrongFormatException
&e
)
313 css::sdbc::SQLException aSQLException
;
314 aSQLException
.Message
= e
.Message
;
315 aSQLException
.Context
= e
.Context
;
316 aInfo
= dbtools::SQLExceptionInfo(aSQLException
);
318 // more like a hack, insert an empty message
319 OUString
sText( DBA_RES( RID_STR_EXTENSION_NOT_PRESENT
) );
320 sText
= sText
.replaceFirst("$file$",_rLinkName
);
321 aInfo
.prepend(sText
);
323 OUString sMessage
= DBA_RES(STR_COULDNOTOPEN_LINKEDDOC
);
324 sMessage
= sMessage
.replaceFirst("$file$",_rLinkName
);
325 aInfo
.prepend(sMessage
);
327 catch(const Exception
& e
)
329 Any aAny
= ::cppu::getCaughtException();
330 css::sdbc::SQLException a
;
331 if ( !(aAny
>>= a
) || (a
.ErrorCode
!= dbtools::ParameterInteractionCancelled
) )
333 css::sdbc::SQLException aSQLException
;
334 aSQLException
.Message
= e
.Message
;
335 aSQLException
.Context
= e
.Context
;
336 aInfo
= dbtools::SQLExceptionInfo(aSQLException
);
338 // more like a hack, insert an empty message
339 aInfo
.prepend(" \n");
341 OUString sMessage
= DBA_RES(STR_COULDNOTOPEN_LINKEDDOC
);
342 sMessage
= sMessage
.replaceFirst("$file$",_rLinkName
);
343 aInfo
.prepend(sMessage
);
348 showError(aInfo
, m_pDialogParent
->GetXWindow(), m_xContext
);
355 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */