/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dbmgr.hxx" #include #include #include #include "view.hxx" #include "wrtsh.hxx" #include "swtypes.hxx" #include "cmdid.h" #include "swevent.hxx" #include "shells.hrc" #include "textsh.hxx" #include "swabstdlg.hxx" #include "dbui.hrc" #include #include using namespace ::svx; using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::container; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::sdb; using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::sdbcx; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::frame; struct DBTextStruct_Impl { SwDBData aDBData; Sequence aSelection; Reference xCursor; Reference xConnection; }; void SwTextShell::ExecDB(SfxRequest &rReq) { const SfxItemSet *pArgs = rReq.GetArgs(); SwDBManager* pDBManager = GetShell().GetDBManager(); OUString sSourceArg, sCommandArg; sal_Int32 nCommandTypeArg = 0; const SfxPoolItem* pSourceItem = nullptr; const SfxPoolItem* pCursorItem = nullptr; const SfxPoolItem* pConnectionItem = nullptr; const SfxPoolItem* pCommandItem = nullptr; const SfxPoolItem* pCommandTypeItem = nullptr; const SfxPoolItem* pSelectionItem = nullptr; // first get the selection of rows to be inserted pArgs->GetItemState(FN_DB_DATA_SELECTION_ANY, false, &pSelectionItem); Sequence aSelection; if(pSelectionItem) static_cast(pSelectionItem)->GetValue() >>= aSelection; // get the data source name pArgs->GetItemState(FN_DB_DATA_SOURCE_ANY, false, &pSourceItem); if(pSourceItem) static_cast(pSourceItem)->GetValue() >>= sSourceArg; // get the command pArgs->GetItemState(FN_DB_DATA_COMMAND_ANY, false, &pCommandItem); if(pCommandItem) static_cast(pCommandItem)->GetValue() >>= sCommandArg; // get the command type pArgs->GetItemState(FN_DB_DATA_COMMAND_TYPE_ANY, false, &pCommandTypeItem); if(pCommandTypeItem) static_cast(pCommandTypeItem)->GetValue() >>= nCommandTypeArg; Reference xConnection; pArgs->GetItemState(FN_DB_CONNECTION_ANY, false, &pConnectionItem); if ( pConnectionItem ) static_cast(pConnectionItem)->GetValue() >>= xConnection; // may be we even get no connection if ( !xConnection.is() ) { Reference xSource; xConnection = SwDBManager::GetConnection(sSourceArg, xSource); } if(!xConnection.is()) return ; // get the cursor, we use to travel, may be NULL Reference xCursor; pArgs->GetItemState(FN_DB_DATA_CURSOR_ANY, false, &pCursorItem); if ( pCursorItem ) static_cast(pCursorItem)->GetValue() >>= xCursor; switch (rReq.GetSlot()) { case FN_QRY_INSERT: { if(pSourceItem && pCommandItem && pCommandTypeItem) { DBTextStruct_Impl* pNew = new DBTextStruct_Impl; pNew->aDBData.sDataSource = sSourceArg; pNew->aDBData.sCommand = sCommandArg; pNew->aDBData.nCommandType = nCommandTypeArg; pNew->aSelection = aSelection; //if the cursor is NULL, it must be created inside InsertDBTextHdl // because it called via a PostUserEvent pNew->xCursor = xCursor; pNew->xConnection = xConnection; Application::PostUserEvent( LINK( this, SwBaseShell, InsertDBTextHdl ), pNew ); // the pNew will be removed in InsertDBTextHdl !! } } break; case FN_QRY_MERGE_FIELD: { // we don't get any cursor, so we must create our own bool bDisposeResultSet = false; if ( !xCursor.is() ) { xCursor = SwDBManager::createCursor(sSourceArg,sCommandArg,nCommandTypeArg,xConnection); bDisposeResultSet = xCursor.is(); } ODataAccessDescriptor aDescriptor; aDescriptor.setDataSource(sSourceArg); aDescriptor[DataAccessDescriptorProperty::Command] <<= sCommandArg; aDescriptor[DataAccessDescriptorProperty::Cursor] <<= xCursor; aDescriptor[DataAccessDescriptorProperty::Selection] <<= aSelection; aDescriptor[DataAccessDescriptorProperty::CommandType] <<= nCommandTypeArg; SwMergeDescriptor aMergeDesc( DBMGR_MERGE, *GetShellPtr(), aDescriptor ); pDBManager->Merge(aMergeDesc); if ( bDisposeResultSet ) ::comphelper::disposeComponent(xCursor); } break; case FN_QRY_INSERT_FIELD: { const SfxPoolItem* pColumnItem = nullptr; const SfxPoolItem* pColumnNameItem = nullptr; pArgs->GetItemState(FN_DB_COLUMN_ANY, false, &pColumnItem); pArgs->GetItemState(FN_DB_DATA_COLUMN_NAME_ANY, false, &pColumnNameItem); OUString sColumnName; if(pColumnNameItem) static_cast(pColumnNameItem)->GetValue() >>= sColumnName; OUString sDBName = sSourceArg + OUStringLiteral1(DB_DELIM) + sCommandArg + OUStringLiteral1(DB_DELIM) + OUString::number(nCommandTypeArg) + OUStringLiteral1(DB_DELIM) + sColumnName; SwFieldMgr aFieldMgr(GetShellPtr()); SwInsertField_Data aData(TYP_DBFLD, 0, sDBName, OUString(), 0); if(pConnectionItem) aData.m_aDBConnection = static_cast(pConnectionItem)->GetValue(); if(pColumnItem) aData.m_aDBColumn = static_cast(pColumnItem)->GetValue(); aFieldMgr.InsertField(aData); SfxViewFrame* pViewFrame = GetView().GetViewFrame(); uno::Reference< XDispatchRecorder > xRecorder = pViewFrame->GetBindings().GetRecorder(); if ( xRecorder.is() ) { SfxRequest aReq( pViewFrame, FN_INSERT_DBFIELD ); aReq.AppendItem( SfxUInt16Item(FN_PARAM_FIELD_TYPE, TYP_DBFLD)); aReq.AppendItem( SfxStringItem( FN_INSERT_DBFIELD, sDBName )); aReq.AppendItem( SfxStringItem( FN_PARAM_1, sCommandArg )); aReq.AppendItem( SfxStringItem( FN_PARAM_2, sColumnName )); aReq.AppendItem( SfxInt32Item( FN_PARAM_3, nCommandTypeArg)); aReq.Done(); } } break; default: OSL_ENSURE(false, "wrong dispatcher"); return; } } IMPL_LINK( SwBaseShell, InsertDBTextHdl, void*, p, void ) { DBTextStruct_Impl* pDBStruct = static_cast(p); if( pDBStruct ) { bool bDispose = false; Reference< sdbc::XConnection> xConnection = pDBStruct->xConnection; Reference xSource = SwDBManager::getDataSourceAsParent(xConnection,pDBStruct->aDBData.sDataSource); // #111987# the connection is disposed an so no parent has been found if(xConnection.is() && !xSource.is()) return; if ( !xConnection.is() ) { xConnection = SwDBManager::GetConnection(pDBStruct->aDBData.sDataSource, xSource); bDispose = true; } Reference< XColumnsSupplier> xColSupp; if(xConnection.is()) xColSupp = SwDBManager::GetColumnSupplier(xConnection, pDBStruct->aDBData.sCommand, pDBStruct->aDBData.nCommandType == CommandType::QUERY ? SwDBSelect::QUERY : SwDBSelect::TABLE); if( xColSupp.is() ) { SwDBData aDBData = pDBStruct->aDBData; SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); OSL_ENSURE(pFact, "SwAbstractDialogFactory fail!"); ScopedVclPtrpDlg (pFact->CreateSwInsertDBColAutoPilot(GetView(), xSource, xColSupp, aDBData)); if( RET_OK == pDlg->Execute() ) { Reference xResSet = pDBStruct->xCursor; pDlg->DataToDoc( pDBStruct->aSelection, xSource, xConnection, xResSet); } } if ( bDispose ) ::comphelper::disposeComponent(xConnection); } delete pDBStruct; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */