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