xref: /trunk/main/sw/source/ui/shells/textsh2.cxx (revision 870262e3)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 #include <cstdarg>
28 
29 #include <svtools/svmedit.hxx>
30 #include <svl/eitem.hxx>
31 #include <svl/whiter.hxx>
32 #include <sfx2/event.hxx>
33 #include <sfx2/dispatch.hxx>
34 #include <sfx2/viewfrm.hxx>
35 #ifndef _MSGBOX_HXX //autogen
36 #include <vcl/msgbox.hxx>
37 #endif
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 
86 #define DB_DD_DELIM 0x0b
87 
88 struct DBTextStruct_Impl
89 {
90     SwDBData aDBData;
91     Sequence<Any> aSelection;
92 	Reference<XResultSet>	xCursor;
93 	Reference<XConnection>	xConnection;
94 };
AddSelList(List & rLst,long nRow)95 inline void AddSelList( List& rLst, long nRow )
96 {
97 	rLst.Insert( (void*)nRow , LIST_APPEND );
98 }
ExecDB(SfxRequest & rReq)99 void SwTextShell::ExecDB(SfxRequest &rReq)
100 {
101 	const SfxItemSet *pArgs = rReq.GetArgs();
102 	SwNewDBMgr* pNewDBMgr = GetShell().GetNewDBMgr();
103 	sal_uInt16 nSlot = rReq.GetSlot();
104     ::rtl::OUString sSourceArg, sCommandArg;
105     sal_Int32 nCommandTypeArg = 0;
106 
107     const SfxPoolItem* pSourceItem = 0;
108 	const SfxPoolItem* pCursorItem = 0;
109 	const SfxPoolItem* pConnectionItem = 0;
110     const SfxPoolItem* pCommandItem = 0;
111     const SfxPoolItem* pCommandTypeItem = 0;
112     const SfxPoolItem* pSelectionItem = 0;
113 
114 	// first get the selection of rows to be inserted
115     pArgs->GetItemState(FN_DB_DATA_SELECTION_ANY, sal_False, &pSelectionItem);
116 
117     Sequence<Any> aSelection;
118     if(pSelectionItem)
119         ((SfxUsrAnyItem*)pSelectionItem)->GetValue() >>= aSelection;
120 
121 	// get the data source name
122     pArgs->GetItemState(FN_DB_DATA_SOURCE_ANY, sal_False, &pSourceItem);
123     if(pSourceItem)
124         ((const SfxUsrAnyItem*)pSourceItem)->GetValue() >>= sSourceArg;
125 
126 	// get the command
127     pArgs->GetItemState(FN_DB_DATA_COMMAND_ANY, sal_False, &pCommandItem);
128     if(pCommandItem)
129         ((const SfxUsrAnyItem*)pCommandItem)->GetValue() >>= sCommandArg;
130 
131 	// get the command type
132     pArgs->GetItemState(FN_DB_DATA_COMMAND_TYPE_ANY, sal_False, &pCommandTypeItem);
133     if(pCommandTypeItem)
134         ((const SfxUsrAnyItem*)pCommandTypeItem)->GetValue() >>= nCommandTypeArg;
135 
136 	Reference<XConnection> xConnection;
137 	pArgs->GetItemState(FN_DB_CONNECTION_ANY, sal_False, &pConnectionItem);
138 	if ( pConnectionItem )
139         ((const SfxUsrAnyItem*)pConnectionItem)->GetValue() >>= xConnection;
140 	// may be we even get no connection
141 	if ( !xConnection.is() )
142 	{
143 		Reference<XDataSource> xSource;
144 		xConnection = pNewDBMgr->GetConnection(sSourceArg, xSource);
145 	}
146     if(!xConnection.is())
147         return ;
148 
149 	// get the cursor, we use to travel, may be NULL
150 	Reference<XResultSet> xCursor;
151 	pArgs->GetItemState(FN_DB_DATA_CURSOR_ANY, sal_False, &pCursorItem);
152 	if ( pCursorItem )
153         ((const SfxUsrAnyItem*)pCursorItem)->GetValue() >>= xCursor;
154 
155 	switch (nSlot)
156 	{
157 		case FN_QRY_INSERT:
158 			{
159                 if(pSourceItem && pCommandItem && pCommandTypeItem)
160                 {
161                     DBTextStruct_Impl* pNew		= new DBTextStruct_Impl;
162                     pNew->aDBData.sDataSource	= sSourceArg;
163                     pNew->aDBData.sCommand		= sCommandArg;
164                     pNew->aDBData.nCommandType	= nCommandTypeArg;
165                     pNew->aSelection			= aSelection;
166 					//if the cursor is NULL, it must be created inside InsertDBTextHdl
167 					// because it called via a PostUserEvent
168 					pNew->xCursor				= xCursor;
169 					pNew->xConnection			= xConnection;
170 
171                     Application::PostUserEvent( STATIC_LINK( this, SwBaseShell,
172 											InsertDBTextHdl ), pNew );
173                     // the pNew will be removed in InsertDBTextHdl !!
174                 }
175 			}
176 			break;
177 
178 		case FN_QRY_MERGE_FIELD:
179 			{
180 				// we don't get any cursor, so we must create our own
181 				sal_Bool bDisposeResultSet = sal_False;
182 				if ( !xCursor.is() )
183 				{
184 					xCursor = SwNewDBMgr::createCursor(sSourceArg,sCommandArg,nCommandTypeArg,xConnection);
185 					bDisposeResultSet = xCursor.is();
186 				}
187 
188 				ODataAccessDescriptor aDescriptor;
189 				aDescriptor.setDataSource(sSourceArg);
190 				aDescriptor[daCommand]		<<= sCommandArg;
191 				aDescriptor[daCursor]		<<= xCursor;
192 				aDescriptor[daSelection]	<<= aSelection;
193 				aDescriptor[daCommandType]	<<= nCommandTypeArg;
194 
195                 SwMergeDescriptor aMergeDesc( DBMGR_MERGE, *GetShellPtr(), aDescriptor );
196                 pNewDBMgr->MergeNew(aMergeDesc);
197 
198 				if ( bDisposeResultSet )
199 					::comphelper::disposeComponent(xCursor);
200             }
201 			break;
202 
203 		case FN_QRY_INSERT_FIELD:
204 			{
205                 const SfxPoolItem* pColumnItem = 0;
206                 const SfxPoolItem* pColumnNameItem = 0;
207 
208                 pArgs->GetItemState(FN_DB_COLUMN_ANY, sal_False, &pColumnItem);
209                 pArgs->GetItemState(FN_DB_DATA_COLUMN_NAME_ANY, sal_False, &pColumnNameItem);
210 
211                 ::rtl::OUString sColumnName;
212                 if(pColumnNameItem)
213                     ((SfxUsrAnyItem*)pColumnNameItem)->GetValue() >>= sColumnName;
214                 String sDBName = sSourceArg;
215                 sDBName += DB_DELIM;
216                 sDBName += (String)sCommandArg;
217                 sDBName += DB_DELIM;
218                 sDBName += String::CreateFromInt32(nCommandTypeArg);
219                 sDBName += DB_DELIM;
220                 sDBName += (String)sColumnName;
221 
222                 SwFldMgr aFldMgr(GetShellPtr());
223                 SwInsertFld_Data aData(TYP_DBFLD, 0, sDBName, aEmptyStr, 0, NULL, sal_True);
224                 if(pConnectionItem)
225                     aData.aDBConnection = ((SfxUsrAnyItem*)pConnectionItem)->GetValue();
226                 if(pColumnItem)
227                     aData.aDBColumn = ((SfxUsrAnyItem*)pColumnItem)->GetValue();
228                 aFldMgr.InsertFld(aData);
229                 SfxViewFrame* pViewFrame = GetView().GetViewFrame();
230                 uno::Reference< frame::XDispatchRecorder > xRecorder =
231                         pViewFrame->GetBindings().GetRecorder();
232                 if ( xRecorder.is() )
233                 {
234                     SfxRequest aReq( pViewFrame, FN_INSERT_DBFIELD );
235                     aReq.AppendItem( SfxUInt16Item(FN_PARAM_FIELD_TYPE, TYP_DBFLD));
236                     aReq.AppendItem( SfxStringItem( FN_INSERT_DBFIELD, sDBName ));
237                     aReq.AppendItem( SfxStringItem( FN_PARAM_1, sCommandArg ));
238                     aReq.AppendItem( SfxStringItem( FN_PARAM_2, sColumnName ));
239                     aReq.AppendItem( SfxInt32Item( FN_PARAM_3, nCommandTypeArg));
240                     aReq.Done();
241                 }
242 			}
243 			break;
244 
245 		default:
246 			ASSERT(sal_False, "wrong dispatcher");
247 			return;
248 	}
249 }
250 
251 /*--------------------------------------------------------------------
252 	Beschreibung:
253  --------------------------------------------------------------------*/
254 
IMPL_STATIC_LINK(SwBaseShell,InsertDBTextHdl,DBTextStruct_Impl *,pDBStruct)255 IMPL_STATIC_LINK( SwBaseShell, InsertDBTextHdl, DBTextStruct_Impl*, pDBStruct )
256 {
257     if( pDBStruct )
258 	{
259 		sal_Bool bDispose = sal_False;
260 		Reference< sdbc::XConnection> xConnection = pDBStruct->xConnection;
261 		Reference<XDataSource> xSource = SwNewDBMgr::getDataSourceAsParent(xConnection,pDBStruct->aDBData.sDataSource);
262         // #111987# the connection is disposed an so no parent has been found
263         if(xConnection.is() && !xSource.is())
264             return 0;
265 
266         if ( !xConnection.is()  )
267 		{
268             xConnection = SwNewDBMgr::GetConnection(pDBStruct->aDBData.sDataSource, xSource);
269 			bDispose = sal_True;
270 		}
271 
272 		Reference< XColumnsSupplier> xColSupp;
273 		if(xConnection.is())
274 			xColSupp = SwNewDBMgr::GetColumnSupplier(xConnection,
275                                     pDBStruct->aDBData.sCommand,
276                                     pDBStruct->aDBData.nCommandType == CommandType::QUERY ?
277                                         SW_DB_SELECT_QUERY : SW_DB_SELECT_TABLE);
278 
279 		if( xColSupp.is() )
280 		{
281             SwDBData aDBData = pDBStruct->aDBData;
282             SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
283             DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!");
284 			::std::auto_ptr<AbstractSwInsertDBColAutoPilot>pDlg (pFact->CreateSwInsertDBColAutoPilot( pThis->GetView(),
285 																								xSource,
286 																								xColSupp,
287 																								aDBData,
288                                                                                                 DLG_AP_INSERT_DB_SEL ));
289 			if( RET_OK == pDlg->Execute() )
290 			{
291                 Reference <XResultSet> xResSet = pDBStruct->xCursor;
292                 pDlg->DataToDoc( pDBStruct->aSelection, xSource, xConnection, xResSet);
293 			}
294 		}
295 		if ( bDispose )
296 			::comphelper::disposeComponent(xConnection);
297 	}
298 
299     delete pDBStruct;
300 	return 0;
301 }
302 
303 
304 
305