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 <cstdarg>
21 
22 #include <svl/eitem.hxx>
23 #include <svl/whiter.hxx>
24 #include <sfx2/event.hxx>
25 #include <sfx2/dispatch.hxx>
26 #include <sfx2/viewfrm.hxx>
27 #include <svl/stritem.hxx>
28 #include <svl/itemset.hxx>
29 #include <sfx2/request.hxx>
30 #include <com/sun/star/sdb/CommandType.hpp>
31 #include <com/sun/star/sdbc/XDataSource.hpp>
32 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
33 #include <comphelper/types.hxx>
34 #include <sfx2/frame.hxx>
35 #include <fldmgr.hxx>
36 #include <fldbas.hxx>
37 #include <dbmgr.hxx>
39 
40 #include <vcl/svapp.hxx>
41 
42 #include <view.hxx>
43 #include <wrtsh.hxx>
44 #include <swtypes.hxx>
45 #include <cmdid.h>
46 #include <swevent.hxx>
47 #include <textsh.hxx>
48 #include <swabstdlg.hxx>
49 #include <dbui.hrc>
50 
51 #include <unomid.h>
52 
53 #include <memory>
54 
55 using namespace ::svx;
56 using namespace ::com::sun::star;
57 using namespace ::com::sun::star::uno;
58 using namespace ::com::sun::star::container;
59 using namespace ::com::sun::star::lang;
60 using namespace ::com::sun::star::sdb;
61 using namespace ::com::sun::star::sdbc;
62 using namespace ::com::sun::star::sdbcx;
63 using namespace ::com::sun::star::beans;
64 using namespace ::com::sun::star::frame;
65 
67 {
69  Sequence<Any> aSelection;
70  Reference<XResultSet> xCursor;
71  Reference<XConnection> xConnection;
72 };
73 
75 {
76  const SfxItemSet *pArgs = rReq.GetArgs();
77  SwDBManager* pDBManager = GetShell().GetDBManager();
78  OUString sSourceArg, sCommandArg;
79  sal_Int32 nCommandTypeArg = 0;
80 
81  const SfxPoolItem* pSourceItem = nullptr;
82  const SfxPoolItem* pCursorItem = nullptr;
83  const SfxPoolItem* pConnectionItem = nullptr;
84  const SfxPoolItem* pCommandItem = nullptr;
85  const SfxPoolItem* pCommandTypeItem = nullptr;
86  const SfxPoolItem* pSelectionItem = nullptr;
87 
88  // first get the selection of rows to be inserted
89  pArgs->GetItemState(FN_DB_DATA_SELECTION_ANY, false, &pSelectionItem);
90 
91  Sequence<Any> aSelection;
92  if(pSelectionItem)
93  static_cast<const SfxUnoAnyItem*>(pSelectionItem)->GetValue() >>= aSelection;
94 
95  // get the data source name
96  pArgs->GetItemState(FN_DB_DATA_SOURCE_ANY, false, &pSourceItem);
97  if(pSourceItem)
98  static_cast<const SfxUnoAnyItem*>(pSourceItem)->GetValue() >>= sSourceArg;
99 
100  // get the command
101  pArgs->GetItemState(FN_DB_DATA_COMMAND_ANY, false, &pCommandItem);
102  if(pCommandItem)
103  static_cast<const SfxUnoAnyItem*>(pCommandItem)->GetValue() >>= sCommandArg;
104 
105  // get the command type
106  pArgs->GetItemState(FN_DB_DATA_COMMAND_TYPE_ANY, false, &pCommandTypeItem);
107  if(pCommandTypeItem)
108  static_cast<const SfxUnoAnyItem*>(pCommandTypeItem)->GetValue() >>= nCommandTypeArg;
109 
110  Reference<XConnection> xConnection;
111  pArgs->GetItemState(FN_DB_CONNECTION_ANY, false, &pConnectionItem);
112  if ( pConnectionItem )
113  static_cast<const SfxUnoAnyItem*>(pConnectionItem)->GetValue() >>= xConnection;
114  // may be we even get no connection
115  if ( !xConnection.is() )
116  {
117  Reference<XDataSource> xSource;
118  SwView &rSwView = GetView();
119  xConnection = SwDBManager::GetConnection(sSourceArg, xSource, &rSwView);
120  }
121  if(!xConnection.is())
122  return ;
123 
124  // get the cursor, we use to travel, may be NULL
125  Reference<XResultSet> xCursor;
126  pArgs->GetItemState(FN_DB_DATA_CURSOR_ANY, false, &pCursorItem);
127  if ( pCursorItem )
128  static_cast<const SfxUnoAnyItem*>(pCursorItem)->GetValue() >>= xCursor;
129 
130  switch (rReq.GetSlot())
131  {
132  case FN_QRY_INSERT:
133  {
134  if(pSourceItem && pCommandItem && pCommandTypeItem)
135  {
137  pNew->aDBData.sDataSource = sSourceArg;
138  pNew->aDBData.sCommand = sCommandArg;
139  pNew->aDBData.nCommandType = nCommandTypeArg;
140  pNew->aSelection = aSelection;
141  //if the cursor is NULL, it must be created inside InsertDBTextHdl
142  // because it called via a PostUserEvent
143  pNew->xCursor = xCursor;
144  pNew->xConnection = xConnection;
145 
146  Application::PostUserEvent( LINK( this, SwBaseShell, InsertDBTextHdl ), pNew );
147  // the pNew will be removed in InsertDBTextHdl !!
148  }
149  }
150  break;
151 
152  case FN_QRY_MERGE_FIELD:
153  {
154  // we don't get any cursor, so we must create our own
155  bool bDisposeResultSet = false;
156  if ( !xCursor.is() )
157  {
158  SwView &rSwView = GetView();
159  xCursor = SwDBManager::createCursor(sSourceArg,sCommandArg,nCommandTypeArg,xConnection,&rSwView);
160  bDisposeResultSet = xCursor.is();
161  }
162 
163  ODataAccessDescriptor aDescriptor;
164  aDescriptor.setDataSource(sSourceArg);
165  aDescriptor[DataAccessDescriptorProperty::Command] <<= sCommandArg;
166  aDescriptor[DataAccessDescriptorProperty::Cursor] <<= xCursor;
167  aDescriptor[DataAccessDescriptorProperty::Selection] <<= aSelection;
168  aDescriptor[DataAccessDescriptorProperty::CommandType] <<= nCommandTypeArg;
169 
170  SwMergeDescriptor aMergeDesc( DBMGR_MERGE, *GetShellPtr(), aDescriptor );
171  pDBManager->Merge(aMergeDesc);
172 
173  if ( bDisposeResultSet )
174  ::comphelper::disposeComponent(xCursor);
175  }
176  break;
177 
178  case FN_QRY_INSERT_FIELD:
179  {
180  const SfxPoolItem* pColumnItem = nullptr;
181  const SfxPoolItem* pColumnNameItem = nullptr;
182 
183  pArgs->GetItemState(FN_DB_COLUMN_ANY, false, &pColumnItem);
184  pArgs->GetItemState(FN_DB_DATA_COLUMN_NAME_ANY, false, &pColumnNameItem);
185 
186  OUString sColumnName;
187  if(pColumnNameItem)
188  static_cast<const SfxUnoAnyItem*>(pColumnNameItem)->GetValue() >>= sColumnName;
189  OUString sDBName = sSourceArg + OUStringLiteral1(DB_DELIM)
190  + sCommandArg + OUStringLiteral1(DB_DELIM)
191  + OUString::number(nCommandTypeArg)
192  + OUStringLiteral1(DB_DELIM) + sColumnName;
193 
194  SwFieldMgr aFieldMgr(GetShellPtr());
195  SwInsertField_Data aData(TYP_DBFLD, 0, sDBName, OUString(), 0);
196  if(pConnectionItem)
197  aData.m_aDBConnection = static_cast<const SfxUnoAnyItem*>(pConnectionItem)->GetValue();
198  if(pColumnItem)
199  aData.m_aDBColumn = static_cast<const SfxUnoAnyItem*>(pColumnItem)->GetValue();
200  aFieldMgr.InsertField(aData);
201  SfxViewFrame* pViewFrame = GetView().GetViewFrame();
202  uno::Reference< XDispatchRecorder > xRecorder =
203  pViewFrame->GetBindings().GetRecorder();
204  if ( xRecorder.is() )
205  {
206  SfxRequest aReq( pViewFrame, FN_INSERT_DBFIELD );
208  aReq.AppendItem( SfxStringItem( FN_INSERT_DBFIELD, sDBName ));
209  aReq.AppendItem( SfxStringItem( FN_PARAM_1, sCommandArg ));
210  aReq.AppendItem( SfxStringItem( FN_PARAM_2, sColumnName ));
211  aReq.AppendItem( SfxInt32Item( FN_PARAM_3, nCommandTypeArg));
212  aReq.Done();
213  }
214  }
215  break;
216 
217  default:
218  OSL_ENSURE(false, "wrong dispatcher");
219  return;
220  }
221 }
222 
223 IMPL_LINK( SwBaseShell, InsertDBTextHdl, void*, p, void )
224 {
225  DBTextStruct_Impl* pDBStruct = static_cast<DBTextStruct_Impl*>(p);
226  if( pDBStruct )
227  {
228  bool bDispose = false;
229  Reference< sdbc::XConnection> xConnection = pDBStruct->xConnection;
231  // #111987# the connection is disposed an so no parent has been found
232  if(xConnection.is() && !xSource.is())
233  return;
234 
235  if ( !xConnection.is() )
236  {
237  SwView &rSwView = GetView();
238  xConnection = SwDBManager::GetConnection(pDBStruct->aDBData.sDataSource, xSource, &rSwView);
239  bDispose = true;
240  }
241 
242  Reference< XColumnsSupplier> xColSupp;
243  if(xConnection.is())
244  xColSupp = SwDBManager::GetColumnSupplier(xConnection,
245  pDBStruct->aDBData.sCommand,
246  pDBStruct->aDBData.nCommandType == CommandType::QUERY ?
248 
249  if( xColSupp.is() )
250  {
251  SwDBData aDBData = pDBStruct->aDBData;
254  xSource,
255  xColSupp,
256  aDBData));
257  if( RET_OK == pDlg->Execute() )
258  {
259  Reference <XResultSet> xResSet = pDBStruct->xCursor;
260  pDlg->DataToDoc( pDBStruct->aSelection, xSource, xConnection, xResSet);
261  }
262  }
263  if ( bDispose )
264  ::comphelper::disposeComponent(xConnection);
265  }
266 
267  delete pDBStruct;
268 }
269 
270 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SfxViewFrame * GetViewFrame() const
#define FN_DB_CONNECTION_ANY
Definition: cmdid.h:712
#define FN_DB_DATA_SOURCE_ANY
Definition: cmdid.h:714
sal_Int32 nCommandType
Definition: swdbdata.hxx:32
SwView & GetView()
Definition: basesh.hxx:57
css::uno::Any m_aDBColumn
Definition: fldmgr.hxx:80
void ExecDB(SfxRequest const &)
Definition: textsh2.cxx:74
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:1969
std::string GetValue
SwWrtShell * GetShellPtr()
Definition: basesh.cxx:2628
SwWrtShell & GetShell()
Definition: basesh.cxx:2623
OUString sDataSource
Definition: swdbdata.hxx:30
Sequence< Any > aSelection
Definition: textsh2.cxx:69
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
#define FN_DB_DATA_COMMAND_ANY
Definition: cmdid.h:715
void Done(bool bRemove=false)
Data records in fields.
Definition: dbmgr.hxx:87
const SfxItemSet * GetArgs() const
bool InsertField(const SwInsertField_Data &rData)
Definition: fldmgr.cxx:895
#define FN_QRY_MERGE_FIELD
Definition: cmdid.h:241
Reference< XConnection > xConnection
Definition: textsh2.cxx:71
css::uno::Any m_aDBConnection
Definition: fldmgr.hxx:79
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:3196
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:3177
bool Merge(const SwMergeDescriptor &rMergeDesc)
Merging of data records into fields.
Definition: dbmgr.cxx:433
SwDBManager * GetDBManager() const
For evaluation of DB fields (new DB-manager).
Definition: edfld.cxx:340
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:1946
static SwAbstractDialogFactory * Create()
Definition: swabstdlg.cxx:36
#define FN_DB_DATA_CURSOR_ANY
Definition: cmdid.h:719
GUIDCNamePair const aData
#define FN_INSERT_DBFIELD
Definition: cmdid.h:195
#define FN_QRY_INSERT_FIELD
Definition: cmdid.h:242
#define FN_DB_DATA_COLUMN_NAME_ANY
Definition: cmdid.h:717
#define FN_DB_DATA_SELECTION_ANY
Definition: cmdid.h:718
#define DB_DELIM
Definition: swtypes.hxx:141
sal_uInt16 GetSlot() const
const css::uno::Reference< css::frame::XDispatchRecorder > & GetRecorder() const
#define FN_DB_DATA_COMMAND_TYPE_ANY
Definition: cmdid.h:716
IMPL_LINK(SwBaseShell, InsertDBTextHdl, void *, p, void)
Definition: textsh2.cxx:223
#define FN_PARAM_FIELD_TYPE
Definition: cmdid.h:758
RET_OK
#define FN_DB_COLUMN_ANY
Definition: cmdid.h:713
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:240
void AppendItem(const SfxPoolItem &)
Reference< XResultSet > xCursor
Definition: textsh2.cxx:70
SwDBData aDBData
Definition: textsh2.cxx:68
OUString sCommand
Definition: swdbdata.hxx:31
Definition: view.hxx:146