1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #ifndef INCLUDED_SW_INC_DBMGR_HXX
20 #define INCLUDED_SW_INC_DBMGR_HXX
22 #include <rtl/ustring.hxx>
23 #include <tools/solar.h>
24 #include <tools/long.hxx>
25 #include <i18nlangtag/lang.h>
26 #include <com/sun/star/util/Date.hpp>
28 #include "swdbdata.hxx"
29 #include <com/sun/star/uno/Reference.h>
30 #include <com/sun/star/uno/Sequence.hxx>
31 #include <com/sun/star/lang/Locale.hpp>
32 #include <com/sun/star/beans/PropertyValue.hpp>
38 namespace com::sun::star
{
50 class XColumnsSupplier
;
53 class XNumberFormatter
;
58 namespace embed
{ class XStorage
; }
59 namespace frame
{ class XStorable
; }
62 class ODataAccessDescriptor
;
67 css::util::Date aNullDate
;
68 css::uno::Reference
< css::util::XNumberFormatter
> xFormatter
;
69 css::lang::Locale aLocale
;
80 class SvNumberFormatter
;
82 class SwMailMergeConfigItem
;
89 DBMGR_MERGE
, ///< Data records in fields.
90 DBMGR_MERGE_PRINTER
, ///< Print mail merge.
91 DBMGR_MERGE_EMAIL
, ///< Send mail merge as email.
92 DBMGR_MERGE_FILE
, ///< Save mail merge as files.
93 DBMGR_MERGE_SHELL
///< Create merge doc and keep the doc shell.
96 // Administration of (new) logical databases.
102 struct SwDSParam
: public SwDBData
104 css::util::Date aNullDate
;
106 css::uno::Reference
<css::util::XNumberFormatter
> xFormatter
;
107 css::uno::Reference
< css::sdbc::XConnection
> xConnection
;
108 css::uno::Reference
< css::sdbc::XStatement
> xStatement
;
109 css::uno::Reference
< css::sdbc::XResultSet
> xResultSet
;
110 css::uno::Sequence
< css::uno::Any
> aSelection
;
113 tools::Long nSelectionIndex
;
115 SwDSParam(const SwDBData
& rData
) :
122 SwDSParam(const SwDBData
& rData
,
123 css::uno::Reference
< css::sdbc::XResultSet
> xResSet
,
124 const css::uno::Sequence
< css::uno::Any
>& rSelection
) :
126 xResultSet(std::move(xResSet
)),
127 aSelection(rSelection
),
133 bool HasValidRecord() const
134 { return( !bEndOfDB
&& xResultSet
.is() ); }
137 typedef std::vector
<std::unique_ptr
<SwDSParam
>> SwDSParams_t
;
139 struct SwMergeDescriptor
141 const DBManagerOptions nMergeType
;
143 const svx::ODataAccessDescriptor
& rDescriptor
;
146 * Create a single or multiple results
148 * This currently just affects FILE, as EMAIL is always
149 * multiple and SHELL and PRINTER are always single.
151 bool bCreateSingleFile
;
154 * @defgroup save Export filter settings
157 OUString sSaveToFilter
;
158 OUString sSaveToFilterOptions
;
159 css::uno::Sequence
< css::beans::PropertyValue
> aSaveToFilterData
;
163 * @defgroup file Mail merge as File settings
168 * Basename incl. the path for the generated files.
170 * The final filename will be created by concatenating a number to prevent
171 * overwriting an existing file and the extension based on the filter
176 * Use the sPrefix as the target filename also overwriting an existing
179 * Just used for the internal mail merge dialogs as mail merge never
180 * overwrites existing files (see SwDBManager::ExecuteFormLetter).
182 bool bPrefixIsFilename
;
186 * @defgroup email Mail merge as eMail settings
191 OUString sAttachmentName
;
192 css::uno::Sequence
< OUString
> aCopiesTo
;
193 css::uno::Sequence
< OUString
> aBlindCopiesTo
;
194 css::uno::Reference
< css::mail::XSmtpService
> xSmtpServer
;
196 bool bSendAsAttachment
;
200 * @addtogroup file email
203 /** DB column to fetch EMail of Filename from
207 /** DB column to fetch password
209 OUString sDBPasswordColumn
;
214 * @defgroup print Mail merge to Printer
217 css::uno::Sequence
< css::beans::PropertyValue
> aPrintOptions
;
220 SwMailMergeConfigItem
* pMailMergeConfigItem
;
222 SwMergeDescriptor( const DBManagerOptions nType
,
224 const svx::ODataAccessDescriptor
& rDesc
) :
228 bCreateSingleFile( false ),
229 bPrefixIsFilename( false ),
231 bSendAsAttachment( false ),
232 pMailMergeConfigItem( nullptr )
234 if( nType
== DBMGR_MERGE_SHELL
|| nType
== DBMGR_MERGE_PRINTER
)
235 bCreateSingleFile
= true;
241 class SW_DLLPUBLIC SwDBManager
243 struct SwDBManager_Impl
;
244 class SAL_DLLPRIVATE ConnectionDisposedListener_Impl
;
245 class MailDispatcherListener_Impl
;
247 enum class MergeStatus
249 Ok
= 0, Cancel
, Error
252 MergeStatus m_aMergeStatus
; ///< current / last merge status
253 bool m_bInitDBFields
: 1;
254 bool m_bInMerge
: 1; ///< merge process active
255 bool m_bMergeSilent
: 1; ///< suppress display of dialogs/boxes (used when called over API)
256 SwDSParams_t m_DataSourceParams
;
257 std::unique_ptr
<SwDBManager_Impl
> m_pImpl
;
258 const SwXMailMerge
* m_pMergeEvtSrc
; ///< != 0 if mail merge events are to be send
259 /// Name of the embedded database that's included in the current document.
260 OUString m_sEmbeddedName
;
262 /// Store last registrations to revoke or commit
263 static std::vector
<std::pair
<SwDocShell
*, OUString
>> s_aUncommittedRegistrations
;
265 /// Not used connections.
266 std::vector
<OUString
> m_aNotUsedConnections
;
268 /// Set connection as used.
269 void SetAsUsed(const OUString
& rName
);
271 /// The document that owns this manager.
274 SAL_DLLPRIVATE SwDSParam
* FindDSData(const SwDBData
& rData
, bool bCreate
);
275 SAL_DLLPRIVATE SwDSParam
* FindDSConnection(const OUString
& rSource
, bool bCreate
);
277 /// Insert data record as text into document.
278 SAL_DLLPRIVATE
void ImportFromConnection( SwWrtShell
* pSh
);
280 /// Insert a single data record as text into document.
281 SAL_DLLPRIVATE
void ImportDBEntry(SwWrtShell
* pSh
);
283 /// Run the mail merge for defined modes, except DBMGR_MERGE
284 SAL_DLLPRIVATE
bool MergeMailFiles( SwWrtShell
* pSh
,
285 const SwMergeDescriptor
& rMergeDescriptor
);
287 SAL_DLLPRIVATE
bool ToNextMergeRecord();
288 SAL_DLLPRIVATE
bool IsValidMergeRecord() const;
289 SAL_DLLPRIVATE
void ImplDestroy();
291 SwDBManager(SwDBManager
const&) = delete;
292 SwDBManager
& operator=(SwDBManager
const&) = delete;
295 SwDBManager(SwDoc
* pDoc
);
298 /// MailMergeEvent source
299 const SwXMailMerge
* GetMailMergeEvtSrc() const { return m_pMergeEvtSrc
; }
300 void SetMailMergeEvtSrc( const SwXMailMerge
*pSrc
) { m_pMergeEvtSrc
= pSrc
; }
302 bool IsMergeSilent() const { return m_bMergeSilent
; }
303 void SetMergeSilent( bool bVal
) { m_bMergeSilent
= bVal
; }
305 /// Merging of data records into fields.
306 bool Merge( const SwMergeDescriptor
& rMergeDesc
);
309 bool IsMergeOk() const { return MergeStatus::Ok
== m_aMergeStatus
; }
310 bool IsMergeError() const { return MergeStatus::Error
<= m_aMergeStatus
; }
312 static std::shared_ptr
<SwMailMergeConfigItem
> PerformMailMerge(SwView
const * pView
);
314 /// Initialize data fields that lack name of database.
315 bool IsInitDBFields() const { return m_bInitDBFields
; }
316 void SetInitDBFields(bool b
) { m_bInitDBFields
= b
; }
318 /// Fill listbox with all table names of a database.
319 bool GetTableNames(weld::ComboBox
& rBox
, const OUString
& rDBName
);
321 /// Fill listbox with all column names of a database table.
322 void GetColumnNames(weld::ComboBox
& rBox
,
323 const OUString
& rDBName
, const OUString
& rTableName
);
324 static void GetColumnNames(weld::ComboBox
& rBox
,
325 css::uno::Reference
< css::sdbc::XConnection
> const & xConnection
,
326 const OUString
& rTableName
);
328 static sal_uLong
GetColumnFormat( css::uno::Reference
< css::sdbc::XDataSource
> const & xSource
,
329 css::uno::Reference
< css::sdbc::XConnection
> const & xConnection
,
330 css::uno::Reference
< css::beans::XPropertySet
> const & xColumn
,
331 SvNumberFormatter
* pNFormatr
,
332 LanguageType nLanguage
);
334 sal_uLong
GetColumnFormat( const OUString
& rDBName
,
335 const OUString
& rTableName
,
336 const OUString
& rColNm
,
337 SvNumberFormatter
* pNFormatr
,
338 LanguageType nLanguage
);
339 sal_Int32
GetColumnType( const OUString
& rDBName
,
340 const OUString
& rTableName
,
341 const OUString
& rColNm
);
343 bool IsInMerge() const { return m_bInMerge
; }
345 void ExecuteFormLetter(SwWrtShell
& rSh
,
346 const css::uno::Sequence
< css::beans::PropertyValue
>& rProperties
);
348 static void InsertText(SwWrtShell
& rSh
,
349 const css::uno::Sequence
< css::beans::PropertyValue
>& rProperties
);
351 /// check if a data source is open
352 bool IsDataSourceOpen(const OUString
& rDataSource
,
353 const OUString
& rTableOrQuery
, bool bMergeShell
);
355 /// open the source while fields are updated - for the calculator only!
356 bool OpenDataSource(const OUString
& rDataSource
, const OUString
& rTableOrQuery
);
357 sal_uInt32
GetSelectedRecordId(const OUString
& rDataSource
, const OUString
& rTableOrQuery
, sal_Int32 nCommandType
= -1);
358 bool GetColumnCnt(const OUString
& rSourceName
, const OUString
& rTableName
,
359 const OUString
& rColumnName
, sal_uInt32 nAbsRecordId
, LanguageType nLanguage
,
360 OUString
& rResult
, double* pNumber
);
361 /** create and store or find an already stored connection to a data source for use
362 in SwFieldMgr and SwDBTreeList */
363 css::uno::Reference
< css::sdbc::XConnection
> const &
364 RegisterConnection(OUString
const& rSource
);
366 void CreateDSData(const SwDBData
& rData
)
367 { FindDSData(rData
, true); }
368 const SwDSParams_t
& GetDSParamArray() const { return m_DataSourceParams
; }
370 /// close all data sources - after fields were updated
371 void CloseAll(bool bIncludingMerge
= true);
373 bool GetMergeColumnCnt(const OUString
& rColumnName
, LanguageType nLanguage
,
374 OUString
&rResult
, double *pNumber
);
375 bool FillCalcWithMergeData(SvNumberFormatter
*pDocFormatter
,
376 LanguageType nLanguage
, SwCalc
&aCalc
);
377 void ToNextRecord(const OUString
& rDataSource
, const OUString
& rTableOrQuery
);
379 sal_uInt32
GetSelectedRecordId();
380 bool ToRecordId(sal_Int32 nSet
);
382 static const SwDBData
& GetAddressDBName();
384 static OUString
GetDBField(
385 css::uno::Reference
< css::beans::XPropertySet
> const & xColumnProp
,
386 const SwDBFormatData
& rDBFormatData
,
387 double *pNumber
= nullptr);
389 static css::uno::Reference
< css::sdbc::XConnection
>
390 GetConnection(const OUString
& rDataSource
,
391 css::uno::Reference
< css::sdbc::XDataSource
>& rxSource
,
392 const SwView
* pView
);
394 static css::uno::Reference
< css::sdbcx::XColumnsSupplier
>
395 GetColumnSupplier(css::uno::Reference
< css::sdbc::XConnection
> const & xConnection
,
396 const OUString
& rTableOrQuery
,
397 SwDBSelect eTableOrQuery
= SwDBSelect::UNKNOWN
);
399 static css::uno::Sequence
<OUString
> GetExistingDatabaseNames();
402 Loads a data source from file and registers it.
404 This function requires GUI interaction, as it loads the data source from
405 the filename returned by a file picker and additional settings dialog.
406 In case of success it returns the registered name, otherwise an empty string.
408 static OUString
LoadAndRegisterDataSource(weld::Window
* pParent
, SwDocShell
* pDocShell
= nullptr);
411 Loads a data source from file and registers it.
413 Convenience function, which calls GetDBunoURI and has just one mandatory parameter.
414 In case of success it returns the registered name, otherwise an empty string.
416 static OUString
LoadAndRegisterDataSource(std::u16string_view rURI
, const OUString
*pDestDir
);
418 /// Load the embedded data source of the document and also register it.
419 void LoadAndRegisterEmbeddedDataSource(const SwDBData
& rData
, const SwDocShell
& rDocShell
);
421 /// Unregister a data source.
422 static void RevokeDataSource(const OUString
& rName
);
424 /** try to get the data source from the given connection through the XChild interface.
425 If this is not possible, the data source will be created through its name.
427 The connection which should support the XChild interface. (not a must)
428 @param _sDataSourceName
429 The data source name will be used to create the data source when the connection can not be used for it.
433 static css::uno::Reference
< css::sdbc::XDataSource
>
434 getDataSourceAsParent(const css::uno::Reference
< css::sdbc::XConnection
>& _xConnection
,const OUString
& _sDataSourceName
);
436 /** creates a RowSet, which must be disposed after use.
437 @param _sDataSourceName
442 The type of the command.
444 The active connection which may be <NULL/>.
446 The new created RowSet.
449 static css::uno::Reference
< css::sdbc::XResultSet
>
450 createCursor(const OUString
& _sDataSourceName
,
451 const OUString
& _sCommand
,
452 sal_Int32 _nCommandType
,
453 const css::uno::Reference
< css::sdbc::XConnection
>& _xConnection
,
454 const SwView
* pView
);
456 void setEmbeddedName(const OUString
& rEmbeddedName
, SwDocShell
& rDocShell
);
457 const OUString
& getEmbeddedName() const;
459 // rOwnURL should be taken using INetURLObject::GetMainURL(INetURLObject::DecodeMechanism::NONE)
460 static void StoreEmbeddedDataSource(const css::uno::Reference
<css::frame::XStorable
>& xStorable
,
461 const css::uno::Reference
<css::embed::XStorage
>& xStorage
,
462 const OUString
& rStreamRelPath
,
463 const OUString
& rOwnURL
, bool bCopyTo
= false);
465 SwDoc
* getDoc() const;
466 /// Stop reacting to removed database registrations.
467 void releaseRevokeListener();
469 /// Revoke not committed registrations in case of mail merge cancel
470 void RevokeLastRegistrations();
472 /// Accept not committed registrations
473 void CommitLastRegistrations();
475 /// Remove not used connections.
476 void RevokeNotUsedConnections();
481 enum class DBConnURIType
493 DBConnURIType SW_DLLPUBLIC
GetDBunoType(const INetURLObject
&rURL
);
498 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */