Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
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.
15 : : *
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).
21 : : *
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.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <cstdarg>
30 : :
31 : : #include <svtools/svmedit.hxx>
32 : : #include <svl/eitem.hxx>
33 : : #include <svl/whiter.hxx>
34 : : #include <sfx2/event.hxx>
35 : : #include <sfx2/dispatch.hxx>
36 : : #include <sfx2/viewfrm.hxx>
37 : : #include <vcl/msgbox.hxx>
38 : : #include <svl/stritem.hxx>
39 : : #include <svl/itemset.hxx>
40 : : #include <sfx2/request.hxx>
41 : : #include <com/sun/star/sdb/CommandType.hpp>
42 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
43 : : #include <com/sun/star/container/XNameAccess.hpp>
44 : : #include <com/sun/star/sdbc/XDataSource.hpp>
45 : : #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
46 : : #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
47 : : #include <com/sun/star/sdb/XQueriesSupplier.hpp>
48 : : #include <com/sun/star/sdb/XDatabaseAccess.hpp>
49 : : #include <com/sun/star/beans/XPropertySet.hpp>
50 : : #include <com/sun/star/container/XChild.hpp>
51 : : #include <comphelper/processfactory.hxx>
52 : : #include <com/sun/star/sdbc/XRowSet.hpp>
53 : : #include <sfx2/frame.hxx>
54 : : #include <fldmgr.hxx>
55 : : #include <fldbas.hxx>
56 : : #include "dbmgr.hxx"
57 : : #include <comphelper/uno3.hxx>
58 : : #include <svx/dataaccessdescriptor.hxx>
59 : : #include <memory>
60 : :
61 : : #include <vcl/svapp.hxx>
62 : :
63 : : #include "view.hxx"
64 : : #include "wrtsh.hxx"
65 : : #include "swtypes.hxx"
66 : : #include "cmdid.h"
67 : : #include "swevent.hxx"
68 : : #include "shells.hrc"
69 : : #include "textsh.hxx"
70 : : #include "swabstdlg.hxx"
71 : : #include "dbui.hrc"
72 : :
73 : : #include <unomid.h>
74 : :
75 : : using namespace ::svx;
76 : : using namespace ::com::sun::star;
77 : : using namespace ::com::sun::star::uno;
78 : : using namespace ::com::sun::star::container;
79 : : using namespace ::com::sun::star::lang;
80 : : using namespace ::com::sun::star::sdb;
81 : : using namespace ::com::sun::star::sdbc;
82 : : using namespace ::com::sun::star::sdbcx;
83 : : using namespace ::com::sun::star::beans;
84 : :
85 : : #define DB_DD_DELIM 0x0b
86 : :
87 [ # # ][ # # ]: 0 : struct DBTextStruct_Impl
88 : : {
89 : : SwDBData aDBData;
90 : : Sequence<Any> aSelection;
91 : : Reference<XResultSet> xCursor;
92 : : Reference<XConnection> xConnection;
93 : : };
94 : :
95 : 0 : void SwTextShell::ExecDB(SfxRequest &rReq)
96 : : {
97 : 0 : const SfxItemSet *pArgs = rReq.GetArgs();
98 [ # # ][ # # ]: 0 : SwNewDBMgr* pNewDBMgr = GetShell().GetNewDBMgr();
99 : 0 : sal_uInt16 nSlot = rReq.GetSlot();
100 : 0 : ::rtl::OUString sSourceArg, sCommandArg;
101 : 0 : sal_Int32 nCommandTypeArg = 0;
102 : :
103 : 0 : const SfxPoolItem* pSourceItem = 0;
104 : 0 : const SfxPoolItem* pCursorItem = 0;
105 : 0 : const SfxPoolItem* pConnectionItem = 0;
106 : 0 : const SfxPoolItem* pCommandItem = 0;
107 : 0 : const SfxPoolItem* pCommandTypeItem = 0;
108 : 0 : const SfxPoolItem* pSelectionItem = 0;
109 : :
110 : : // first get the selection of rows to be inserted
111 [ # # ]: 0 : pArgs->GetItemState(FN_DB_DATA_SELECTION_ANY, sal_False, &pSelectionItem);
112 : :
113 [ # # ]: 0 : Sequence<Any> aSelection;
114 [ # # ]: 0 : if(pSelectionItem)
115 [ # # ]: 0 : ((SfxUsrAnyItem*)pSelectionItem)->GetValue() >>= aSelection;
116 : :
117 : : // get the data source name
118 [ # # ]: 0 : pArgs->GetItemState(FN_DB_DATA_SOURCE_ANY, sal_False, &pSourceItem);
119 [ # # ]: 0 : if(pSourceItem)
120 : 0 : ((const SfxUsrAnyItem*)pSourceItem)->GetValue() >>= sSourceArg;
121 : :
122 : : // get the command
123 [ # # ]: 0 : pArgs->GetItemState(FN_DB_DATA_COMMAND_ANY, sal_False, &pCommandItem);
124 [ # # ]: 0 : if(pCommandItem)
125 : 0 : ((const SfxUsrAnyItem*)pCommandItem)->GetValue() >>= sCommandArg;
126 : :
127 : : // get the command type
128 [ # # ]: 0 : pArgs->GetItemState(FN_DB_DATA_COMMAND_TYPE_ANY, sal_False, &pCommandTypeItem);
129 [ # # ]: 0 : if(pCommandTypeItem)
130 : 0 : ((const SfxUsrAnyItem*)pCommandTypeItem)->GetValue() >>= nCommandTypeArg;
131 : :
132 : 0 : Reference<XConnection> xConnection;
133 [ # # ]: 0 : pArgs->GetItemState(FN_DB_CONNECTION_ANY, sal_False, &pConnectionItem);
134 [ # # ]: 0 : if ( pConnectionItem )
135 [ # # ]: 0 : ((const SfxUsrAnyItem*)pConnectionItem)->GetValue() >>= xConnection;
136 : : // may be we even get no connection
137 [ # # ]: 0 : if ( !xConnection.is() )
138 : : {
139 : 0 : Reference<XDataSource> xSource;
140 [ # # ][ # # ]: 0 : xConnection = pNewDBMgr->GetConnection(sSourceArg, xSource);
[ # # ][ # # ]
141 : : }
142 [ # # ]: 0 : if(!xConnection.is())
143 : : return ;
144 : :
145 : : // get the cursor, we use to travel, may be NULL
146 : 0 : Reference<XResultSet> xCursor;
147 [ # # ]: 0 : pArgs->GetItemState(FN_DB_DATA_CURSOR_ANY, sal_False, &pCursorItem);
148 [ # # ]: 0 : if ( pCursorItem )
149 [ # # ]: 0 : ((const SfxUsrAnyItem*)pCursorItem)->GetValue() >>= xCursor;
150 : :
151 [ # # # # ]: 0 : switch (nSlot)
152 : : {
153 : : case FN_QRY_INSERT:
154 : : {
155 [ # # ][ # # ]: 0 : if(pSourceItem && pCommandItem && pCommandTypeItem)
[ # # ]
156 : : {
157 [ # # ][ # # ]: 0 : DBTextStruct_Impl* pNew = new DBTextStruct_Impl;
158 : 0 : pNew->aDBData.sDataSource = sSourceArg;
159 : 0 : pNew->aDBData.sCommand = sCommandArg;
160 : 0 : pNew->aDBData.nCommandType = nCommandTypeArg;
161 [ # # ]: 0 : pNew->aSelection = aSelection;
162 : : //if the cursor is NULL, it must be created inside InsertDBTextHdl
163 : : // because it called via a PostUserEvent
164 [ # # ]: 0 : pNew->xCursor = xCursor;
165 [ # # ]: 0 : pNew->xConnection = xConnection;
166 : :
167 : : Application::PostUserEvent( STATIC_LINK( this, SwBaseShell,
168 [ # # ][ # # ]: 0 : InsertDBTextHdl ), pNew );
169 : : // the pNew will be removed in InsertDBTextHdl !!
170 : : }
171 : : }
172 : 0 : break;
173 : :
174 : : case FN_QRY_MERGE_FIELD:
175 : : {
176 : : // we don't get any cursor, so we must create our own
177 : 0 : sal_Bool bDisposeResultSet = sal_False;
178 [ # # ]: 0 : if ( !xCursor.is() )
179 : : {
180 [ # # ][ # # ]: 0 : xCursor = SwNewDBMgr::createCursor(sSourceArg,sCommandArg,nCommandTypeArg,xConnection);
181 : 0 : bDisposeResultSet = xCursor.is();
182 : : }
183 : :
184 [ # # ]: 0 : ODataAccessDescriptor aDescriptor;
185 [ # # ]: 0 : aDescriptor.setDataSource(sSourceArg);
186 [ # # ][ # # ]: 0 : aDescriptor[daCommand] <<= sCommandArg;
187 [ # # ][ # # ]: 0 : aDescriptor[daCursor] <<= xCursor;
188 [ # # ][ # # ]: 0 : aDescriptor[daSelection] <<= aSelection;
189 [ # # ][ # # ]: 0 : aDescriptor[daCommandType] <<= nCommandTypeArg;
190 : :
191 [ # # ][ # # ]: 0 : SwMergeDescriptor aMergeDesc( DBMGR_MERGE, *GetShellPtr(), aDescriptor );
192 [ # # ]: 0 : pNewDBMgr->MergeNew(aMergeDesc);
193 : :
194 [ # # ]: 0 : if ( bDisposeResultSet )
195 [ # # ][ # # ]: 0 : ::comphelper::disposeComponent(xCursor);
[ # # ]
196 : : }
197 : 0 : break;
198 : :
199 : : case FN_QRY_INSERT_FIELD:
200 : : {
201 : 0 : const SfxPoolItem* pColumnItem = 0;
202 : 0 : const SfxPoolItem* pColumnNameItem = 0;
203 : :
204 [ # # ]: 0 : pArgs->GetItemState(FN_DB_COLUMN_ANY, sal_False, &pColumnItem);
205 [ # # ]: 0 : pArgs->GetItemState(FN_DB_DATA_COLUMN_NAME_ANY, sal_False, &pColumnNameItem);
206 : :
207 : 0 : ::rtl::OUString sColumnName;
208 [ # # ]: 0 : if(pColumnNameItem)
209 : 0 : ((SfxUsrAnyItem*)pColumnNameItem)->GetValue() >>= sColumnName;
210 [ # # ]: 0 : String sDBName = sSourceArg;
211 [ # # ]: 0 : sDBName += DB_DELIM;
212 [ # # ][ # # ]: 0 : sDBName += (String)sCommandArg;
[ # # ]
213 [ # # ]: 0 : sDBName += DB_DELIM;
214 [ # # ][ # # ]: 0 : sDBName += String::CreateFromInt32(nCommandTypeArg);
[ # # ]
215 [ # # ]: 0 : sDBName += DB_DELIM;
216 [ # # ][ # # ]: 0 : sDBName += (String)sColumnName;
[ # # ]
217 : :
218 [ # # ][ # # ]: 0 : SwFldMgr aFldMgr(GetShellPtr());
219 [ # # ]: 0 : SwInsertFld_Data aData(TYP_DBFLD, 0, sDBName, aEmptyStr, 0, sal_False, sal_True);
220 [ # # ]: 0 : if(pConnectionItem)
221 : 0 : aData.aDBConnection = ((SfxUsrAnyItem*)pConnectionItem)->GetValue();
222 [ # # ]: 0 : if(pColumnItem)
223 : 0 : aData.aDBColumn = ((SfxUsrAnyItem*)pColumnItem)->GetValue();
224 [ # # ]: 0 : aFldMgr.InsertFld(aData);
225 : 0 : SfxViewFrame* pViewFrame = GetView().GetViewFrame();
226 : : uno::Reference< frame::XDispatchRecorder > xRecorder =
227 [ # # ]: 0 : pViewFrame->GetBindings().GetRecorder();
228 [ # # ]: 0 : if ( xRecorder.is() )
229 : : {
230 [ # # ]: 0 : SfxRequest aReq( pViewFrame, FN_INSERT_DBFIELD );
231 [ # # ][ # # ]: 0 : aReq.AppendItem( SfxUInt16Item(FN_PARAM_FIELD_TYPE, TYP_DBFLD));
[ # # ]
232 [ # # ][ # # ]: 0 : aReq.AppendItem( SfxStringItem( FN_INSERT_DBFIELD, sDBName ));
[ # # ]
233 [ # # ][ # # ]: 0 : aReq.AppendItem( SfxStringItem( FN_PARAM_1, sCommandArg ));
[ # # ][ # # ]
[ # # ]
234 [ # # ][ # # ]: 0 : aReq.AppendItem( SfxStringItem( FN_PARAM_2, sColumnName ));
[ # # ][ # # ]
[ # # ]
235 [ # # ][ # # ]: 0 : aReq.AppendItem( SfxInt32Item( FN_PARAM_3, nCommandTypeArg));
[ # # ]
236 [ # # ][ # # ]: 0 : aReq.Done();
237 [ # # ][ # # ]: 0 : }
[ # # ]
238 : : }
239 : 0 : break;
240 : :
241 : : default:
242 : : OSL_ENSURE(!this, "wrong dispatcher");
243 : : return;
244 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
[ # # ][ # # ]
245 : : }
246 : :
247 : 0 : IMPL_STATIC_LINK( SwBaseShell, InsertDBTextHdl, DBTextStruct_Impl*, pDBStruct )
248 : : {
249 [ # # ]: 0 : if( pDBStruct )
250 : : {
251 : 0 : sal_Bool bDispose = sal_False;
252 : 0 : Reference< sdbc::XConnection> xConnection = pDBStruct->xConnection;
253 [ # # ]: 0 : Reference<XDataSource> xSource = SwNewDBMgr::getDataSourceAsParent(xConnection,pDBStruct->aDBData.sDataSource);
254 : : // #111987# the connection is disposed an so no parent has been found
255 [ # # ][ # # ]: 0 : if(xConnection.is() && !xSource.is())
[ # # ]
256 : 0 : return 0;
257 : :
258 [ # # ]: 0 : if ( !xConnection.is() )
259 : : {
260 [ # # ][ # # ]: 0 : xConnection = SwNewDBMgr::GetConnection(pDBStruct->aDBData.sDataSource, xSource);
[ # # ][ # # ]
261 : 0 : bDispose = sal_True;
262 : : }
263 : :
264 : 0 : Reference< XColumnsSupplier> xColSupp;
265 [ # # ]: 0 : if(xConnection.is())
266 : : xColSupp = SwNewDBMgr::GetColumnSupplier(xConnection,
267 : : pDBStruct->aDBData.sCommand,
268 : : pDBStruct->aDBData.nCommandType == CommandType::QUERY ?
269 [ # # ][ # # ]: 0 : SW_DB_SELECT_QUERY : SW_DB_SELECT_TABLE);
[ # # ][ # # ]
[ # # ]
270 : :
271 [ # # ]: 0 : if( xColSupp.is() )
272 : : {
273 : 0 : SwDBData aDBData = pDBStruct->aDBData;
274 [ # # ]: 0 : SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
275 : : OSL_ENSURE(pFact, "SwAbstractDialogFactory fail!");
276 : 0 : ::std::auto_ptr<AbstractSwInsertDBColAutoPilot>pDlg (pFact->CreateSwInsertDBColAutoPilot( pThis->GetView(),
277 : : xSource,
278 : : xColSupp,
279 : : aDBData,
280 [ # # ]: 0 : DLG_AP_INSERT_DB_SEL ));
281 [ # # ][ # # ]: 0 : if( RET_OK == pDlg->Execute() )
282 : : {
283 : 0 : Reference <XResultSet> xResSet = pDBStruct->xCursor;
284 [ # # ]: 0 : pDlg->DataToDoc( pDBStruct->aSelection, xSource, xConnection, xResSet);
285 [ # # ]: 0 : }
286 : : }
287 [ # # ]: 0 : if ( bDispose )
288 [ # # ][ # # ]: 0 : ::comphelper::disposeComponent(xConnection);
[ # # ]
289 : : }
290 : :
291 [ # # ]: 0 : delete pDBStruct;
292 : 0 : return 0;
293 : : }
294 : :
295 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|