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