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