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 <sfx2/bindings.hxx>
21 #include <sfx2/viewfrm.hxx>
22 #include <svl/stritem.hxx>
23 #include <svl/itemset.hxx>
24 #include <sfx2/request.hxx>
25 #include <com/sun/star/sdb/CommandType.hpp>
26 #include <com/sun/star/sdbc/XDataSource.hpp>
27 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
28 #include <comphelper/types.hxx>
29 #include <sfx2/frame.hxx>
33 #include <svx/dataaccessdescriptor.hxx>
34 #include <osl/diagnose.h>
36 #include <vcl/svapp.hxx>
40 #include <swtypes.hxx>
43 #include <swabstdlg.hxx>
45 using namespace ::svx
;
46 using namespace ::com::sun::star
;
47 using namespace ::com::sun::star::uno
;
48 using namespace ::com::sun::star::container
;
49 using namespace ::com::sun::star::lang
;
50 using namespace ::com::sun::star::sdb
;
51 using namespace ::com::sun::star::sdbc
;
52 using namespace ::com::sun::star::sdbcx
;
53 using namespace ::com::sun::star::beans
;
54 using namespace ::com::sun::star::frame
;
56 struct DBTextStruct_Impl
59 Sequence
<Any
> aSelection
;
60 Reference
<XResultSet
> xCursor
;
61 Reference
<XConnection
> xConnection
;
64 void SwTextShell::ExecDB(SfxRequest
const &rReq
)
66 const SfxItemSet
*pArgs
= rReq
.GetArgs();
67 SwDBManager
* pDBManager
= GetShell().GetDBManager();
68 OUString sSourceArg
, sCommandArg
;
69 sal_Int32 nCommandTypeArg
= 0;
70 const SfxUnoAnyItem
* pSourceItem
= nullptr;
71 const SfxUnoAnyItem
* pCommandItem
= nullptr;
72 const SfxUnoAnyItem
* pCommandTypeItem
= nullptr;
73 const SfxUnoAnyItem
* pConnectionItem
= nullptr;
75 // first get the selection of rows to be inserted
77 Sequence
<Any
> aSelection
;
78 if(const SfxUnoAnyItem
* pSelectionItem
= pArgs
->GetItemIfSet(FN_DB_DATA_SELECTION_ANY
, false))
79 pSelectionItem
->GetValue() >>= aSelection
;
81 // get the data source name
82 pSourceItem
= pArgs
->GetItemIfSet(FN_DB_DATA_SOURCE_ANY
, false);
84 pSourceItem
->GetValue() >>= sSourceArg
;
87 pCommandItem
= pArgs
->GetItemIfSet(FN_DB_DATA_COMMAND_ANY
, false);
89 pCommandItem
->GetValue() >>= sCommandArg
;
91 // get the command type
92 pCommandTypeItem
= pArgs
->GetItemIfSet(FN_DB_DATA_COMMAND_TYPE_ANY
, false);
94 pCommandTypeItem
->GetValue() >>= nCommandTypeArg
;
96 Reference
<XConnection
> xConnection
;
97 pConnectionItem
= pArgs
->GetItemIfSet(FN_DB_CONNECTION_ANY
, false);
99 pConnectionItem
->GetValue() >>= xConnection
;
100 // may be we even get no connection
101 if ( !xConnection
.is() )
103 Reference
<XDataSource
> xSource
;
104 SwView
&rSwView
= GetView();
105 xConnection
= SwDBManager::GetConnection(sSourceArg
, xSource
, &rSwView
);
107 if(!xConnection
.is())
110 // get the cursor, we use to travel, may be NULL
111 Reference
<XResultSet
> xCursor
;
112 if ( const SfxUnoAnyItem
* pCursorItem
= pArgs
->GetItemIfSet(FN_DB_DATA_CURSOR_ANY
, false) )
113 pCursorItem
->GetValue() >>= xCursor
;
115 switch (rReq
.GetSlot())
119 if(pSourceItem
&& pCommandItem
&& pCommandTypeItem
)
121 DBTextStruct_Impl
* pNew
= new DBTextStruct_Impl
;
122 pNew
->aDBData
.sDataSource
= sSourceArg
;
123 pNew
->aDBData
.sCommand
= sCommandArg
;
124 pNew
->aDBData
.nCommandType
= nCommandTypeArg
;
125 pNew
->aSelection
= aSelection
;
126 //if the cursor is NULL, it must be created inside InsertDBTextHdl
127 // because it called via a PostUserEvent
128 pNew
->xCursor
= xCursor
;
129 pNew
->xConnection
= xConnection
;
131 Application::PostUserEvent( LINK( this, SwBaseShell
, InsertDBTextHdl
), pNew
);
132 // the pNew will be removed in InsertDBTextHdl !!
137 case FN_QRY_MERGE_FIELD
:
139 // we don't get any cursor, so we must create our own
140 bool bDisposeResultSet
= false;
143 SwView
&rSwView
= GetView();
144 xCursor
= SwDBManager::createCursor(sSourceArg
,sCommandArg
,nCommandTypeArg
,xConnection
,&rSwView
);
145 bDisposeResultSet
= xCursor
.is();
148 ODataAccessDescriptor aDescriptor
;
149 aDescriptor
.setDataSource(sSourceArg
);
150 aDescriptor
[DataAccessDescriptorProperty::Command
] <<= sCommandArg
;
151 aDescriptor
[DataAccessDescriptorProperty::Cursor
] <<= xCursor
;
152 aDescriptor
[DataAccessDescriptorProperty::Selection
] <<= aSelection
;
153 aDescriptor
[DataAccessDescriptorProperty::CommandType
] <<= nCommandTypeArg
;
155 SwMergeDescriptor
aMergeDesc( DBMGR_MERGE
, *GetShellPtr(), aDescriptor
);
156 pDBManager
->Merge(aMergeDesc
);
158 if ( bDisposeResultSet
)
159 ::comphelper::disposeComponent(xCursor
);
163 case FN_QRY_INSERT_FIELD
:
165 const SfxUnoAnyItem
* pColumnItem
= pArgs
->GetItemIfSet(FN_DB_COLUMN_ANY
, false);
166 const SfxUnoAnyItem
* pColumnNameItem
=
167 pArgs
->GetItemIfSet(FN_DB_DATA_COLUMN_NAME_ANY
, false);
169 OUString sColumnName
;
171 pColumnNameItem
->GetValue() >>= sColumnName
;
172 OUString sDBName
= sSourceArg
+ OUStringChar(DB_DELIM
)
173 + sCommandArg
+ OUStringChar(DB_DELIM
)
174 + OUString::number(nCommandTypeArg
)
175 + OUStringChar(DB_DELIM
) + sColumnName
;
177 SwFieldMgr
aFieldMgr(GetShellPtr());
178 SwInsertField_Data
aData(SwFieldTypesEnum::Database
, 0, sDBName
, OUString(), 0);
180 aData
.m_aDBConnection
= pConnectionItem
->GetValue();
182 aData
.m_aDBColumn
= pColumnItem
->GetValue();
183 aFieldMgr
.InsertField(aData
);
184 SfxViewFrame
& rViewFrame
= GetView().GetViewFrame();
185 uno::Reference
< XDispatchRecorder
> xRecorder
=
186 rViewFrame
.GetBindings().GetRecorder();
187 if ( xRecorder
.is() )
189 SfxRequest
aReq(rViewFrame
, FN_INSERT_DBFIELD
);
190 aReq
.AppendItem( SfxUInt16Item(FN_PARAM_FIELD_TYPE
, static_cast<sal_uInt16
>(SwFieldTypesEnum::Database
)));
191 aReq
.AppendItem( SfxStringItem( FN_INSERT_DBFIELD
, sDBName
));
192 aReq
.AppendItem( SfxStringItem( FN_PARAM_1
, sCommandArg
));
193 aReq
.AppendItem( SfxStringItem( FN_PARAM_2
, sColumnName
));
194 aReq
.AppendItem( SfxInt32Item( FN_PARAM_3
, nCommandTypeArg
));
201 OSL_ENSURE(false, "wrong dispatcher");
206 IMPL_LINK( SwBaseShell
, InsertDBTextHdl
, void*, p
, void )
208 DBTextStruct_Impl
* pDBStruct
= static_cast<DBTextStruct_Impl
*>(p
);
211 bool bDispose
= false;
212 Reference
< sdbc::XConnection
> xConnection
= pDBStruct
->xConnection
;
213 Reference
<XDataSource
> xSource
= SwDBManager::getDataSourceAsParent(xConnection
,pDBStruct
->aDBData
.sDataSource
);
214 // #111987# the connection is disposed and so no parent has been found
215 if(xConnection
.is() && !xSource
.is())
218 if ( !xConnection
.is() )
220 SwView
&rSwView
= GetView();
221 xConnection
= SwDBManager::GetConnection(pDBStruct
->aDBData
.sDataSource
, xSource
, &rSwView
);
225 Reference
< XColumnsSupplier
> xColSupp
;
227 xColSupp
= SwDBManager::GetColumnSupplier(xConnection
,
228 pDBStruct
->aDBData
.sCommand
,
229 pDBStruct
->aDBData
.nCommandType
== CommandType::QUERY
?
230 SwDBSelect::QUERY
: SwDBSelect::TABLE
);
234 SwDBData aDBData
= pDBStruct
->aDBData
;
235 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
236 ScopedVclPtr
<AbstractSwInsertDBColAutoPilot
>pDlg (pFact
->CreateSwInsertDBColAutoPilot(GetView(),
240 if( RET_OK
== pDlg
->Execute() )
242 Reference
<XResultSet
> xResSet
= pDBStruct
->xCursor
;
243 pDlg
->DataToDoc( pDBStruct
->aSelection
, xSource
, xConnection
, xResSet
);
247 ::comphelper::disposeComponent(xConnection
);
253 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */