bump product version to 4.1.6.2
[LibreOffice.git] / sw / source / ui / shells / textsh2.cxx
blob8adea0bb43d3a0c8b50e78ed01888df852b920f7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <cstdarg>
22 #include <svtools/svmedit.hxx>
23 #include <svl/eitem.hxx>
24 #include <svl/whiter.hxx>
25 #include <sfx2/event.hxx>
26 #include <sfx2/dispatch.hxx>
27 #include <sfx2/viewfrm.hxx>
28 #include <vcl/msgbox.hxx>
29 #include <svl/stritem.hxx>
30 #include <svl/itemset.hxx>
31 #include <sfx2/request.hxx>
32 #include <com/sun/star/sdb/CommandType.hpp>
33 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34 #include <com/sun/star/container/XNameAccess.hpp>
35 #include <com/sun/star/sdbc/XDataSource.hpp>
36 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
37 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
38 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
39 #include <com/sun/star/sdb/XDatabaseAccess.hpp>
40 #include <com/sun/star/beans/XPropertySet.hpp>
41 #include <com/sun/star/container/XChild.hpp>
42 #include <comphelper/processfactory.hxx>
43 #include <com/sun/star/sdbc/XRowSet.hpp>
44 #include <sfx2/frame.hxx>
45 #include <fldmgr.hxx>
46 #include <fldbas.hxx>
47 #include "dbmgr.hxx"
48 #include <comphelper/uno3.hxx>
49 #include <svx/dataaccessdescriptor.hxx>
50 #include <memory>
52 #include <vcl/svapp.hxx>
54 #include "view.hxx"
55 #include "wrtsh.hxx"
56 #include "swtypes.hxx"
57 #include "cmdid.h"
58 #include "swevent.hxx"
59 #include "shells.hrc"
60 #include "textsh.hxx"
61 #include "swabstdlg.hxx"
62 #include "dbui.hrc"
64 #include <unomid.h>
66 using namespace ::svx;
67 using namespace ::com::sun::star;
68 using namespace ::com::sun::star::uno;
69 using namespace ::com::sun::star::container;
70 using namespace ::com::sun::star::lang;
71 using namespace ::com::sun::star::sdb;
72 using namespace ::com::sun::star::sdbc;
73 using namespace ::com::sun::star::sdbcx;
74 using namespace ::com::sun::star::beans;
75 using namespace ::com::sun::star::frame;
77 struct DBTextStruct_Impl
79 SwDBData aDBData;
80 Sequence<Any> aSelection;
81 Reference<XResultSet> xCursor;
82 Reference<XConnection> xConnection;
85 void SwTextShell::ExecDB(SfxRequest &rReq)
87 const SfxItemSet *pArgs = rReq.GetArgs();
88 SwNewDBMgr* pNewDBMgr = GetShell().GetNewDBMgr();
89 sal_uInt16 nSlot = rReq.GetSlot();
90 OUString sSourceArg, sCommandArg;
91 sal_Int32 nCommandTypeArg = 0;
93 const SfxPoolItem* pSourceItem = 0;
94 const SfxPoolItem* pCursorItem = 0;
95 const SfxPoolItem* pConnectionItem = 0;
96 const SfxPoolItem* pCommandItem = 0;
97 const SfxPoolItem* pCommandTypeItem = 0;
98 const SfxPoolItem* pSelectionItem = 0;
100 // first get the selection of rows to be inserted
101 pArgs->GetItemState(FN_DB_DATA_SELECTION_ANY, sal_False, &pSelectionItem);
103 Sequence<Any> aSelection;
104 if(pSelectionItem)
105 ((SfxUsrAnyItem*)pSelectionItem)->GetValue() >>= aSelection;
107 // get the data source name
108 pArgs->GetItemState(FN_DB_DATA_SOURCE_ANY, sal_False, &pSourceItem);
109 if(pSourceItem)
110 ((const SfxUsrAnyItem*)pSourceItem)->GetValue() >>= sSourceArg;
112 // get the command
113 pArgs->GetItemState(FN_DB_DATA_COMMAND_ANY, sal_False, &pCommandItem);
114 if(pCommandItem)
115 ((const SfxUsrAnyItem*)pCommandItem)->GetValue() >>= sCommandArg;
117 // get the command type
118 pArgs->GetItemState(FN_DB_DATA_COMMAND_TYPE_ANY, sal_False, &pCommandTypeItem);
119 if(pCommandTypeItem)
120 ((const SfxUsrAnyItem*)pCommandTypeItem)->GetValue() >>= nCommandTypeArg;
122 Reference<XConnection> xConnection;
123 pArgs->GetItemState(FN_DB_CONNECTION_ANY, sal_False, &pConnectionItem);
124 if ( pConnectionItem )
125 ((const SfxUsrAnyItem*)pConnectionItem)->GetValue() >>= xConnection;
126 // may be we even get no connection
127 if ( !xConnection.is() )
129 Reference<XDataSource> xSource;
130 xConnection = pNewDBMgr->GetConnection(sSourceArg, xSource);
132 if(!xConnection.is())
133 return ;
135 // get the cursor, we use to travel, may be NULL
136 Reference<XResultSet> xCursor;
137 pArgs->GetItemState(FN_DB_DATA_CURSOR_ANY, sal_False, &pCursorItem);
138 if ( pCursorItem )
139 ((const SfxUsrAnyItem*)pCursorItem)->GetValue() >>= xCursor;
141 switch (nSlot)
143 case FN_QRY_INSERT:
145 if(pSourceItem && pCommandItem && pCommandTypeItem)
147 DBTextStruct_Impl* pNew = new DBTextStruct_Impl;
148 pNew->aDBData.sDataSource = sSourceArg;
149 pNew->aDBData.sCommand = sCommandArg;
150 pNew->aDBData.nCommandType = nCommandTypeArg;
151 pNew->aSelection = aSelection;
152 //if the cursor is NULL, it must be created inside InsertDBTextHdl
153 // because it called via a PostUserEvent
154 pNew->xCursor = xCursor;
155 pNew->xConnection = xConnection;
157 Application::PostUserEvent( STATIC_LINK( this, SwBaseShell,
158 InsertDBTextHdl ), pNew );
159 // the pNew will be removed in InsertDBTextHdl !!
162 break;
164 case FN_QRY_MERGE_FIELD:
166 // we don't get any cursor, so we must create our own
167 sal_Bool bDisposeResultSet = sal_False;
168 if ( !xCursor.is() )
170 xCursor = SwNewDBMgr::createCursor(sSourceArg,sCommandArg,nCommandTypeArg,xConnection);
171 bDisposeResultSet = xCursor.is();
174 ODataAccessDescriptor aDescriptor;
175 aDescriptor.setDataSource(sSourceArg);
176 aDescriptor[daCommand] <<= sCommandArg;
177 aDescriptor[daCursor] <<= xCursor;
178 aDescriptor[daSelection] <<= aSelection;
179 aDescriptor[daCommandType] <<= nCommandTypeArg;
181 SwMergeDescriptor aMergeDesc( DBMGR_MERGE, *GetShellPtr(), aDescriptor );
182 pNewDBMgr->MergeNew(aMergeDesc);
184 if ( bDisposeResultSet )
185 ::comphelper::disposeComponent(xCursor);
187 break;
189 case FN_QRY_INSERT_FIELD:
191 const SfxPoolItem* pColumnItem = 0;
192 const SfxPoolItem* pColumnNameItem = 0;
194 pArgs->GetItemState(FN_DB_COLUMN_ANY, sal_False, &pColumnItem);
195 pArgs->GetItemState(FN_DB_DATA_COLUMN_NAME_ANY, sal_False, &pColumnNameItem);
197 OUString sColumnName;
198 if(pColumnNameItem)
199 ((SfxUsrAnyItem*)pColumnNameItem)->GetValue() >>= sColumnName;
200 String sDBName = sSourceArg;
201 sDBName += DB_DELIM;
202 sDBName += (String)sCommandArg;
203 sDBName += DB_DELIM;
204 sDBName += OUString::number(nCommandTypeArg);
205 sDBName += DB_DELIM;
206 sDBName += (String)sColumnName;
208 SwFldMgr aFldMgr(GetShellPtr());
209 SwInsertFld_Data aData(TYP_DBFLD, 0, sDBName, aEmptyStr, 0);
210 if(pConnectionItem)
211 aData.aDBConnection = ((SfxUsrAnyItem*)pConnectionItem)->GetValue();
212 if(pColumnItem)
213 aData.aDBColumn = ((SfxUsrAnyItem*)pColumnItem)->GetValue();
214 aFldMgr.InsertFld(aData);
215 SfxViewFrame* pViewFrame = GetView().GetViewFrame();
216 uno::Reference< XDispatchRecorder > xRecorder =
217 pViewFrame->GetBindings().GetRecorder();
218 if ( xRecorder.is() )
220 SfxRequest aReq( pViewFrame, FN_INSERT_DBFIELD );
221 aReq.AppendItem( SfxUInt16Item(FN_PARAM_FIELD_TYPE, TYP_DBFLD));
222 aReq.AppendItem( SfxStringItem( FN_INSERT_DBFIELD, sDBName ));
223 aReq.AppendItem( SfxStringItem( FN_PARAM_1, sCommandArg ));
224 aReq.AppendItem( SfxStringItem( FN_PARAM_2, sColumnName ));
225 aReq.AppendItem( SfxInt32Item( FN_PARAM_3, nCommandTypeArg));
226 aReq.Done();
229 break;
231 default:
232 OSL_ENSURE(!this, "wrong dispatcher");
233 return;
237 IMPL_STATIC_LINK( SwBaseShell, InsertDBTextHdl, DBTextStruct_Impl*, pDBStruct )
239 if( pDBStruct )
241 bool bDispose = false;
242 Reference< sdbc::XConnection> xConnection = pDBStruct->xConnection;
243 Reference<XDataSource> xSource = SwNewDBMgr::getDataSourceAsParent(xConnection,pDBStruct->aDBData.sDataSource);
244 // #111987# the connection is disposed an so no parent has been found
245 if(xConnection.is() && !xSource.is())
246 return 0;
248 if ( !xConnection.is() )
250 xConnection = SwNewDBMgr::GetConnection(pDBStruct->aDBData.sDataSource, xSource);
251 bDispose = true;
254 Reference< XColumnsSupplier> xColSupp;
255 if(xConnection.is())
256 xColSupp = SwNewDBMgr::GetColumnSupplier(xConnection,
257 pDBStruct->aDBData.sCommand,
258 pDBStruct->aDBData.nCommandType == CommandType::QUERY ?
259 SW_DB_SELECT_QUERY : SW_DB_SELECT_TABLE);
261 if( xColSupp.is() )
263 SwDBData aDBData = pDBStruct->aDBData;
264 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
265 OSL_ENSURE(pFact, "SwAbstractDialogFactory fail!");
266 ::std::auto_ptr<AbstractSwInsertDBColAutoPilot>pDlg (pFact->CreateSwInsertDBColAutoPilot( pThis->GetView(),
267 xSource,
268 xColSupp,
269 aDBData,
270 DLG_AP_INSERT_DB_SEL ));
271 if( RET_OK == pDlg->Execute() )
273 Reference <XResultSet> xResSet = pDBStruct->xCursor;
274 pDlg->DataToDoc( pDBStruct->aSelection, xSource, xConnection, xResSet);
277 if ( bDispose )
278 ::comphelper::disposeComponent(xConnection);
281 delete pDBStruct;
282 return 0;
285 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */