LibreOffice Module sw (master)  1
textsh2.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <sfx2/bindings.hxx>
21 #include <sfx2/viewfrm.hxx>
22 #include <svl/stritem.hxx>
23 #include <svl/itemset.hxx>
24 #include <sfx2/request.hxx>
25 #include <com/sun/star/sdb/CommandType.hpp>
26 #include <com/sun/star/sdbc/XDataSource.hpp>
27 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
28 #include <comphelper/types.hxx>
29 #include <sfx2/frame.hxx>
30 #include <fldmgr.hxx>
31 #include <fldbas.hxx>
32 #include <dbmgr.hxx>
34 #include <osl/diagnose.h>
35 
36 #include <vcl/svapp.hxx>
37 
38 #include <view.hxx>
39 #include <wrtsh.hxx>
40 #include <swtypes.hxx>
41 #include <cmdid.h>
42 #include <textsh.hxx>
43 #include <swabstdlg.hxx>
44 
45 using namespace ::svx;
46 using namespace ::com::sun::star;
47 using namespace ::com::sun::star::uno;
48 using namespace ::com::sun::star::container;
49 using namespace ::com::sun::star::lang;
50 using namespace ::com::sun::star::sdb;
51 using namespace ::com::sun::star::sdbc;
52 using namespace ::com::sun::star::sdbcx;
53 using namespace ::com::sun::star::beans;
54 using namespace ::com::sun::star::frame;
55 
57 {
59  Sequence<Any> aSelection;
60  Reference<XResultSet> xCursor;
62 };
63 
65 {
66  const SfxItemSet *pArgs = rReq.GetArgs();
67  SwDBManager* pDBManager = GetShell().GetDBManager();
68  OUString sSourceArg, sCommandArg;
69  sal_Int32 nCommandTypeArg = 0;
70 
71  const SfxPoolItem* pSourceItem = nullptr;
72  const SfxPoolItem* pCursorItem = nullptr;
73  const SfxPoolItem* pConnectionItem = nullptr;
74  const SfxPoolItem* pCommandItem = nullptr;
75  const SfxPoolItem* pCommandTypeItem = nullptr;
76  const SfxPoolItem* pSelectionItem = nullptr;
77 
78  // first get the selection of rows to be inserted
79  pArgs->GetItemState(FN_DB_DATA_SELECTION_ANY, false, &pSelectionItem);
80 
81  Sequence<Any> aSelection;
82  if(pSelectionItem)
83  static_cast<const SfxUnoAnyItem*>(pSelectionItem)->GetValue() >>= aSelection;
84 
85  // get the data source name
86  pArgs->GetItemState(FN_DB_DATA_SOURCE_ANY, false, &pSourceItem);
87  if(pSourceItem)
88  static_cast<const SfxUnoAnyItem*>(pSourceItem)->GetValue() >>= sSourceArg;
89 
90  // get the command
91  pArgs->GetItemState(FN_DB_DATA_COMMAND_ANY, false, &pCommandItem);
92  if(pCommandItem)
93  static_cast<const SfxUnoAnyItem*>(pCommandItem)->GetValue() >>= sCommandArg;
94 
95  // get the command type
96  pArgs->GetItemState(FN_DB_DATA_COMMAND_TYPE_ANY, false, &pCommandTypeItem);
97  if(pCommandTypeItem)
98  static_cast<const SfxUnoAnyItem*>(pCommandTypeItem)->GetValue() >>= nCommandTypeArg;
99 
100  Reference<XConnection> xConnection;
101  pArgs->GetItemState(FN_DB_CONNECTION_ANY, false, &pConnectionItem);
102  if ( pConnectionItem )
103  static_cast<const SfxUnoAnyItem*>(pConnectionItem)->GetValue() >>= xConnection;
104  // may be we even get no connection
105  if ( !xConnection.is() )
106  {
107  Reference<XDataSource> xSource;
108  SwView &rSwView = GetView();
109  xConnection = SwDBManager::GetConnection(sSourceArg, xSource, &rSwView);
110  }
111  if(!xConnection.is())
112  return ;
113 
114  // get the cursor, we use to travel, may be NULL
115  Reference<XResultSet> xCursor;
116  pArgs->GetItemState(FN_DB_DATA_CURSOR_ANY, false, &pCursorItem);
117  if ( pCursorItem )
118  static_cast<const SfxUnoAnyItem*>(pCursorItem)->GetValue() >>= xCursor;
119 
120  switch (rReq.GetSlot())
121  {
122  case FN_QRY_INSERT:
123  {
124  if(pSourceItem && pCommandItem && pCommandTypeItem)
125  {
127  pNew->aDBData.sDataSource = sSourceArg;
128  pNew->aDBData.sCommand = sCommandArg;
129  pNew->aDBData.nCommandType = nCommandTypeArg;
130  pNew->aSelection = aSelection;
131  //if the cursor is NULL, it must be created inside InsertDBTextHdl
132  // because it called via a PostUserEvent
133  pNew->xCursor = xCursor;
134  pNew->xConnection = xConnection;
135 
136  Application::PostUserEvent( LINK( this, SwBaseShell, InsertDBTextHdl ), pNew );
137  // the pNew will be removed in InsertDBTextHdl !!
138  }
139  }
140  break;
141 
142  case FN_QRY_MERGE_FIELD:
143  {
144  // we don't get any cursor, so we must create our own
145  bool bDisposeResultSet = false;
146  if ( !xCursor.is() )
147  {
148  SwView &rSwView = GetView();
149  xCursor = SwDBManager::createCursor(sSourceArg,sCommandArg,nCommandTypeArg,xConnection,&rSwView);
150  bDisposeResultSet = xCursor.is();
151  }
152 
153  ODataAccessDescriptor aDescriptor;
154  aDescriptor.setDataSource(sSourceArg);
155  aDescriptor[DataAccessDescriptorProperty::Command] <<= sCommandArg;
156  aDescriptor[DataAccessDescriptorProperty::Cursor] <<= xCursor;
157  aDescriptor[DataAccessDescriptorProperty::Selection] <<= aSelection;
158  aDescriptor[DataAccessDescriptorProperty::CommandType] <<= nCommandTypeArg;
159 
160  SwMergeDescriptor aMergeDesc( DBMGR_MERGE, *GetShellPtr(), aDescriptor );
161  pDBManager->Merge(aMergeDesc);
162 
163  if ( bDisposeResultSet )
164  ::comphelper::disposeComponent(xCursor);
165  }
166  break;
167 
168  case FN_QRY_INSERT_FIELD:
169  {
170  const SfxPoolItem* pColumnItem = nullptr;
171  const SfxPoolItem* pColumnNameItem = nullptr;
172 
173  pArgs->GetItemState(FN_DB_COLUMN_ANY, false, &pColumnItem);
174  pArgs->GetItemState(FN_DB_DATA_COLUMN_NAME_ANY, false, &pColumnNameItem);
175 
176  OUString sColumnName;
177  if(pColumnNameItem)
178  static_cast<const SfxUnoAnyItem*>(pColumnNameItem)->GetValue() >>= sColumnName;
179  OUString sDBName = sSourceArg + OUStringChar(DB_DELIM)
180  + sCommandArg + OUStringChar(DB_DELIM)
181  + OUString::number(nCommandTypeArg)
182  + OUStringChar(DB_DELIM) + sColumnName;
183 
184  SwFieldMgr aFieldMgr(GetShellPtr());
185  SwInsertField_Data aData(SwFieldTypesEnum::Database, 0, sDBName, OUString(), 0);
186  if(pConnectionItem)
187  aData.m_aDBConnection = static_cast<const SfxUnoAnyItem*>(pConnectionItem)->GetValue();
188  if(pColumnItem)
189  aData.m_aDBColumn = static_cast<const SfxUnoAnyItem*>(pColumnItem)->GetValue();
190  aFieldMgr.InsertField(aData);
191  SfxViewFrame* pViewFrame = GetView().GetViewFrame();
192  uno::Reference< XDispatchRecorder > xRecorder =
193  pViewFrame->GetBindings().GetRecorder();
194  if ( xRecorder.is() )
195  {
196  SfxRequest aReq( pViewFrame, FN_INSERT_DBFIELD );
198  aReq.AppendItem( SfxStringItem( FN_INSERT_DBFIELD, sDBName ));
199  aReq.AppendItem( SfxStringItem( FN_PARAM_1, sCommandArg ));
200  aReq.AppendItem( SfxStringItem( FN_PARAM_2, sColumnName ));
201  aReq.AppendItem( SfxInt32Item( FN_PARAM_3, nCommandTypeArg));
202  aReq.Done();
203  }
204  }
205  break;
206 
207  default:
208  OSL_ENSURE(false, "wrong dispatcher");
209  return;
210  }
211 }
212 
213 IMPL_LINK( SwBaseShell, InsertDBTextHdl, void*, p, void )
214 {
215  DBTextStruct_Impl* pDBStruct = static_cast<DBTextStruct_Impl*>(p);
216  if( pDBStruct )
217  {
218  bool bDispose = false;
219  Reference< sdbc::XConnection> xConnection = pDBStruct->xConnection;
221  // #111987# the connection is disposed and so no parent has been found
222  if(xConnection.is() && !xSource.is())
223  return;
224 
225  if ( !xConnection.is() )
226  {
227  SwView &rSwView = GetView();
228  xConnection = SwDBManager::GetConnection(pDBStruct->aDBData.sDataSource, xSource, &rSwView);
229  bDispose = true;
230  }
231 
232  Reference< XColumnsSupplier> xColSupp;
233  if(xConnection.is())
234  xColSupp = SwDBManager::GetColumnSupplier(xConnection,
235  pDBStruct->aDBData.sCommand,
236  pDBStruct->aDBData.nCommandType == CommandType::QUERY ?
238 
239  if( xColSupp.is() )
240  {
241  SwDBData aDBData = pDBStruct->aDBData;
244  xSource,
245  xColSupp,
246  aDBData));
247  if( RET_OK == pDlg->Execute() )
248  {
249  Reference <XResultSet> xResSet = pDBStruct->xCursor;
250  pDlg->DataToDoc( pDBStruct->aSelection, xSource, xConnection, xResSet);
251  }
252  }
253  if ( bDispose )
254  ::comphelper::disposeComponent(xConnection);
255  }
256 
257  delete pDBStruct;
258 }
259 
260 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SfxViewFrame * GetViewFrame() const
#define FN_DB_CONNECTION_ANY
Definition: cmdid.h:735
#define FN_DB_DATA_SOURCE_ANY
Definition: cmdid.h:737
sal_Int32 nCommandType
Definition: swdbdata.hxx:32
SwView & GetView()
Definition: basesh.hxx:59
css::uno::Any m_aDBColumn
Definition: fldmgr.hxx:81
void ExecDB(SfxRequest const &)
Definition: textsh2.cxx:64
static css::uno::Reference< css::sdbcx::XColumnsSupplier > GetColumnSupplier(css::uno::Reference< css::sdbc::XConnection > const &xConnection, const OUString &rTableOrQuery, SwDBSelect eTableOrQuery=SwDBSelect::UNKNOWN)
Definition: dbmgr.cxx:1878
std::string GetValue
SwWrtShell * GetShellPtr()
Definition: basesh.cxx:2712
SwWrtShell & GetShell()
Definition: basesh.cxx:2707
OUString sDataSource
Definition: swdbdata.hxx:30
Sequence< Any > aSelection
Definition: textsh2.cxx:59
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
#define FN_DB_DATA_COMMAND_ANY
Definition: cmdid.h:738
void Done(bool bRemove=false)
Data records in fields.
Definition: dbmgr.hxx:88
const SfxItemSet * GetArgs() const
bool InsertField(const SwInsertField_Data &rData)
Definition: fldmgr.cxx:891
#define FN_QRY_MERGE_FIELD
Definition: cmdid.h:250
Reference< XConnection > xConnection
Definition: textsh2.cxx:61
css::uno::Any m_aDBConnection
Definition: fldmgr.hxx:80
static css::uno::Reference< css::sdbc::XResultSet > createCursor(const OUString &_sDataSourceName, const OUString &_sCommand, sal_Int32 _nCommandType, const css::uno::Reference< css::sdbc::XConnection > &_xConnection, const SwView *pView)
creates a RowSet, which must be disposed after use.
Definition: dbmgr.cxx:3099
static css::uno::Reference< css::sdbc::XDataSource > getDataSourceAsParent(const css::uno::Reference< css::sdbc::XConnection > &_xConnection, const OUString &_sDataSourceName)
try to get the data source from the given connection through the XChild interface.
Definition: dbmgr.cxx:3081
constexpr OUStringLiteral aData
Definition: ww8scan.hxx:47
bool Merge(const SwMergeDescriptor &rMergeDesc)
Merging of data records into fields.
Definition: dbmgr.cxx:415
SwDBManager * GetDBManager() const
For evaluation of DB fields (new DB-manager).
Definition: edfld.cxx:326
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
SfxBindings & GetBindings()
static css::uno::Reference< css::sdbc::XConnection > GetConnection(const OUString &rDataSource, css::uno::Reference< css::sdbc::XDataSource > &rxSource, const SwView *pView)
Definition: dbmgr.cxx:1855
static SwAbstractDialogFactory * Create()
Definition: swabstdlg.cxx:36
#define FN_DB_DATA_CURSOR_ANY
Definition: cmdid.h:742
#define FN_INSERT_DBFIELD
Definition: cmdid.h:204
#define FN_QRY_INSERT_FIELD
Definition: cmdid.h:251
#define FN_DB_DATA_COLUMN_NAME_ANY
Definition: cmdid.h:740
#define FN_DB_DATA_SELECTION_ANY
Definition: cmdid.h:741
#define DB_DELIM
Definition: swtypes.hxx:135
sal_uInt16 GetSlot() const
const css::uno::Reference< css::frame::XDispatchRecorder > & GetRecorder() const
#define FN_DB_DATA_COMMAND_TYPE_ANY
Definition: cmdid.h:739
IMPL_LINK(SwBaseShell, InsertDBTextHdl, void *, p, void)
Definition: textsh2.cxx:213
#define FN_PARAM_FIELD_TYPE
Definition: cmdid.h:784
RET_OK
void * p
#define FN_DB_COLUMN_ANY
Definition: cmdid.h:736
virtual VclPtr< AbstractSwInsertDBColAutoPilot > CreateSwInsertDBColAutoPilot(SwView &rView, css::uno::Reference< css::sdbc::XDataSource > rxSource, css::uno::Reference< css::sdbcx::XColumnsSupplier > xColSupp, const SwDBData &rData)=0
#define FN_QRY_INSERT
Definition: cmdid.h:249
void AppendItem(const SfxPoolItem &)
Reference< XResultSet > xCursor
Definition: textsh2.cxx:60
SwDBData aDBData
Definition: textsh2.cxx:58
OUString sCommand
Definition: swdbdata.hxx:31
Definition: view.hxx:144