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