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  const SfxUnoAnyItem* pSourceItem = nullptr;
71  const SfxUnoAnyItem* pCommandItem = nullptr;
72  const SfxUnoAnyItem* pCommandTypeItem = nullptr;
73  const SfxUnoAnyItem* pConnectionItem = nullptr;
74 
75  // first get the selection of rows to be inserted
76 
77  Sequence<Any> aSelection;
78  if(const SfxUnoAnyItem* pSelectionItem = pArgs->GetItemIfSet(FN_DB_DATA_SELECTION_ANY, false))
79  pSelectionItem->GetValue() >>= aSelection;
80 
81  // get the data source name
82  pSourceItem = pArgs->GetItemIfSet(FN_DB_DATA_SOURCE_ANY, false);
83  if(pSourceItem)
84  pSourceItem->GetValue() >>= sSourceArg;
85 
86  // get the command
87  pCommandItem = pArgs->GetItemIfSet(FN_DB_DATA_COMMAND_ANY, false);
88  if(pCommandItem)
89  pCommandItem->GetValue() >>= sCommandArg;
90 
91  // get the command type
92  pCommandTypeItem = pArgs->GetItemIfSet(FN_DB_DATA_COMMAND_TYPE_ANY, false);
93  if(pCommandTypeItem)
94  pCommandTypeItem->GetValue() >>= nCommandTypeArg;
95 
96  Reference<XConnection> xConnection;
97  pConnectionItem = pArgs->GetItemIfSet(FN_DB_CONNECTION_ANY, false);
98  if(pConnectionItem)
99  pConnectionItem->GetValue() >>= xConnection;
100  // may be we even get no connection
101  if ( !xConnection.is() )
102  {
103  Reference<XDataSource> xSource;
104  SwView &rSwView = GetView();
105  xConnection = SwDBManager::GetConnection(sSourceArg, xSource, &rSwView);
106  }
107  if(!xConnection.is())
108  return ;
109 
110  // get the cursor, we use to travel, may be NULL
111  Reference<XResultSet> xCursor;
112  if ( const SfxUnoAnyItem* pCursorItem = pArgs->GetItemIfSet(FN_DB_DATA_CURSOR_ANY, false) )
113  pCursorItem->GetValue() >>= xCursor;
114 
115  switch (rReq.GetSlot())
116  {
117  case FN_QRY_INSERT:
118  {
119  if(pSourceItem && pCommandItem && pCommandTypeItem)
120  {
122  pNew->aDBData.sDataSource = sSourceArg;
123  pNew->aDBData.sCommand = sCommandArg;
124  pNew->aDBData.nCommandType = nCommandTypeArg;
125  pNew->aSelection = aSelection;
126  //if the cursor is NULL, it must be created inside InsertDBTextHdl
127  // because it called via a PostUserEvent
128  pNew->xCursor = xCursor;
129  pNew->xConnection = xConnection;
130 
131  Application::PostUserEvent( LINK( this, SwBaseShell, InsertDBTextHdl ), pNew );
132  // the pNew will be removed in InsertDBTextHdl !!
133  }
134  }
135  break;
136 
137  case FN_QRY_MERGE_FIELD:
138  {
139  // we don't get any cursor, so we must create our own
140  bool bDisposeResultSet = false;
141  if ( !xCursor.is() )
142  {
143  SwView &rSwView = GetView();
144  xCursor = SwDBManager::createCursor(sSourceArg,sCommandArg,nCommandTypeArg,xConnection,&rSwView);
145  bDisposeResultSet = xCursor.is();
146  }
147 
148  ODataAccessDescriptor aDescriptor;
149  aDescriptor.setDataSource(sSourceArg);
150  aDescriptor[DataAccessDescriptorProperty::Command] <<= sCommandArg;
151  aDescriptor[DataAccessDescriptorProperty::Cursor] <<= xCursor;
152  aDescriptor[DataAccessDescriptorProperty::Selection] <<= aSelection;
153  aDescriptor[DataAccessDescriptorProperty::CommandType] <<= nCommandTypeArg;
154 
155  SwMergeDescriptor aMergeDesc( DBMGR_MERGE, *GetShellPtr(), aDescriptor );
156  pDBManager->Merge(aMergeDesc);
157 
158  if ( bDisposeResultSet )
159  ::comphelper::disposeComponent(xCursor);
160  }
161  break;
162 
163  case FN_QRY_INSERT_FIELD:
164  {
165  const SfxUnoAnyItem* pColumnItem = pArgs->GetItemIfSet(FN_DB_COLUMN_ANY, false);
166  const SfxUnoAnyItem* pColumnNameItem =
168 
169  OUString sColumnName;
170  if(pColumnNameItem)
171  pColumnNameItem->GetValue() >>= sColumnName;
172  OUString sDBName = sSourceArg + OUStringChar(DB_DELIM)
173  + sCommandArg + OUStringChar(DB_DELIM)
174  + OUString::number(nCommandTypeArg)
175  + OUStringChar(DB_DELIM) + sColumnName;
176 
177  SwFieldMgr aFieldMgr(GetShellPtr());
178  SwInsertField_Data aData(SwFieldTypesEnum::Database, 0, sDBName, OUString(), 0);
179  if(pConnectionItem)
180  aData.m_aDBConnection = pConnectionItem->GetValue();
181  if(pColumnItem)
182  aData.m_aDBColumn = pColumnItem->GetValue();
183  aFieldMgr.InsertField(aData);
184  SfxViewFrame* pViewFrame = GetView().GetViewFrame();
185  uno::Reference< XDispatchRecorder > xRecorder =
186  pViewFrame->GetBindings().GetRecorder();
187  if ( xRecorder.is() )
188  {
189  SfxRequest aReq( pViewFrame, FN_INSERT_DBFIELD );
191  aReq.AppendItem( SfxStringItem( FN_INSERT_DBFIELD, sDBName ));
192  aReq.AppendItem( SfxStringItem( FN_PARAM_1, sCommandArg ));
193  aReq.AppendItem( SfxStringItem( FN_PARAM_2, sColumnName ));
194  aReq.AppendItem( SfxInt32Item( FN_PARAM_3, nCommandTypeArg));
195  aReq.Done();
196  }
197  }
198  break;
199 
200  default:
201  OSL_ENSURE(false, "wrong dispatcher");
202  return;
203  }
204 }
205 
206 IMPL_LINK( SwBaseShell, InsertDBTextHdl, void*, p, void )
207 {
208  DBTextStruct_Impl* pDBStruct = static_cast<DBTextStruct_Impl*>(p);
209  if( pDBStruct )
210  {
211  bool bDispose = false;
212  Reference< sdbc::XConnection> xConnection = pDBStruct->xConnection;
214  // #111987# the connection is disposed and so no parent has been found
215  if(xConnection.is() && !xSource.is())
216  return;
217 
218  if ( !xConnection.is() )
219  {
220  SwView &rSwView = GetView();
221  xConnection = SwDBManager::GetConnection(pDBStruct->aDBData.sDataSource, xSource, &rSwView);
222  bDispose = true;
223  }
224 
225  Reference< XColumnsSupplier> xColSupp;
226  if(xConnection.is())
227  xColSupp = SwDBManager::GetColumnSupplier(xConnection,
228  pDBStruct->aDBData.sCommand,
229  pDBStruct->aDBData.nCommandType == CommandType::QUERY ?
231 
232  if( xColSupp.is() )
233  {
234  SwDBData aDBData = pDBStruct->aDBData;
237  xSource,
238  xColSupp,
239  aDBData));
240  if( RET_OK == pDlg->Execute() )
241  {
242  Reference <XResultSet> xResSet = pDBStruct->xCursor;
243  pDlg->DataToDoc( pDBStruct->aSelection, xSource, xConnection, xResSet);
244  }
245  }
246  if ( bDispose )
247  ::comphelper::disposeComponent(xConnection);
248  }
249 
250  delete pDBStruct;
251 }
252 
253 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SfxViewFrame * GetViewFrame() const
#define FN_DB_CONNECTION_ANY
Definition: cmdid.h:752
#define FN_DB_DATA_SOURCE_ANY
Definition: cmdid.h:754
sal_Int32 nCommandType
Definition: swdbdata.hxx:32
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
SwView & GetView()
Definition: basesh.hxx:59
css::uno::Any m_aDBColumn
Definition: fldmgr.hxx:80
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:1877
SwWrtShell * GetShellPtr()
Definition: basesh.cxx:2825
SwWrtShell & GetShell()
Definition: basesh.cxx:2820
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:755
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:895
#define FN_QRY_MERGE_FIELD
Definition: cmdid.h:262
Reference< XConnection > xConnection
Definition: textsh2.cxx:61
css::uno::Any m_aDBConnection
Definition: fldmgr.hxx:79
const css::uno::Any & GetValue() const
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:3097
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:3079
constexpr OUStringLiteral aData
Definition: ww8scan.hxx:48
bool Merge(const SwMergeDescriptor &rMergeDesc)
Merging of data records into fields.
Definition: dbmgr.cxx:417
SwDBManager * GetDBManager() const
For evaluation of DB fields (new DB-manager).
Definition: edfld.cxx:328
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:1854
static SwAbstractDialogFactory * Create()
Definition: swabstdlg.cxx:36
#define FN_DB_DATA_CURSOR_ANY
Definition: cmdid.h:759
#define FN_INSERT_DBFIELD
Definition: cmdid.h:211
#define FN_QRY_INSERT_FIELD
Definition: cmdid.h:263
#define FN_DB_DATA_COLUMN_NAME_ANY
Definition: cmdid.h:757
#define FN_DB_DATA_SELECTION_ANY
Definition: cmdid.h:758
#define DB_DELIM
Definition: swtypes.hxx:130
sal_uInt16 GetSlot() const
const css::uno::Reference< css::frame::XDispatchRecorder > & GetRecorder() const
#define FN_DB_DATA_COMMAND_TYPE_ANY
Definition: cmdid.h:756
IMPL_LINK(SwBaseShell, InsertDBTextHdl, void *, p, void)
Definition: textsh2.cxx:206
#define FN_PARAM_FIELD_TYPE
Definition: cmdid.h:800
RET_OK
void * p
#define FN_DB_COLUMN_ANY
Definition: cmdid.h:753
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:261
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