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 #ifndef INCLUDED_SW_INC_DBMGR_HXX 20 #define INCLUDED_SW_INC_DBMGR_HXX 21 22 #include <rtl/ustring.hxx> 23 #include <tools/solar.h> 24 #include <i18nlangtag/lang.h> 25 #include <com/sun/star/util/Date.hpp> 26 #include "swdllapi.h" 27 #include "swdbdata.hxx" 28 #include <com/sun/star/uno/Reference.h> 29 #include <com/sun/star/uno/Sequence.hxx> 30 #include <com/sun/star/lang/Locale.hpp> 31 #include <com/sun/star/beans/PropertyValue.hpp> 32 33 #include <memory> 34 #include <vector> 35 36 namespace com{namespace sun{namespace star{ 37 namespace sdbc{ 38 class XConnection; 39 class XStatement; 40 class XDataSource; 41 class XResultSet; 42 } 43 namespace beans{ 44 45 class XPropertySet; 46 } 47 namespace sdbcx{ 48 class XColumnsSupplier; 49 } 50 namespace util{ 51 class XNumberFormatter; 52 } 53 namespace mail{ 54 class XSmtpService; 55 } 56 namespace embed { class XStorage; } 57 namespace frame { class XStorable; } 58 }}} 59 namespace svx { 60 class ODataAccessDescriptor; 61 } 62 63 struct SwDBFormatData 64 { 65 css::util::Date aNullDate; 66 css::uno::Reference< css::util::XNumberFormatter> xFormatter; 67 css::lang::Locale aLocale; 68 }; 69 70 namespace weld { 71 class ComboBox; 72 class Window; 73 } 74 75 class SwView; 76 class SwWrtShell; 77 class ListBox; 78 class SvNumberFormatter; 79 class SwXMailMerge; 80 class SwMailMergeConfigItem; 81 class SwCalc; 82 class INetURLObject; 83 class SwDocShell; 84 85 enum DBManagerOptions 86 { 87 DBMGR_MERGE, ///< Data records in fields. 88 DBMGR_MERGE_PRINTER, ///< Print mail merge. 89 DBMGR_MERGE_EMAIL, ///< Send mail merge as email. 90 DBMGR_MERGE_FILE, ///< Save mail merge as files. 91 DBMGR_MERGE_SHELL ///< Create merge doc and keep the doc shell. 92 }; 93 94 // Administration of (new) logical databases. 95 enum class SwDBSelect 96 { 97 UNKNOWN, TABLE, QUERY 98 }; 99 100 struct SwDSParam : public SwDBData 101 { 102 css::util::Date aNullDate; 103 104 css::uno::Reference<css::util::XNumberFormatter> xFormatter; 105 css::uno::Reference< css::sdbc::XConnection> xConnection; 106 css::uno::Reference< css::sdbc::XStatement> xStatement; 107 css::uno::Reference< css::sdbc::XResultSet> xResultSet; 108 css::uno::Sequence< css::uno::Any > aSelection; 109 bool bScrollable; 110 bool bEndOfDB; 111 long nSelectionIndex; 112 SwDSParamSwDSParam113 SwDSParam(const SwDBData& rData) : 114 SwDBData(rData), 115 bScrollable(false), 116 bEndOfDB(false), 117 nSelectionIndex(0) 118 {} 119 SwDSParamSwDSParam120 SwDSParam(const SwDBData& rData, 121 const css::uno::Reference< css::sdbc::XResultSet>& xResSet, 122 const css::uno::Sequence< css::uno::Any >& rSelection) : 123 SwDBData(rData), 124 xResultSet(xResSet), 125 aSelection(rSelection), 126 bScrollable(true), 127 bEndOfDB(false), 128 nSelectionIndex(0) 129 {} 130 HasValidRecordSwDSParam131 bool HasValidRecord() const 132 { return( !bEndOfDB && xResultSet.is() ); } 133 }; 134 135 typedef std::vector<std::unique_ptr<SwDSParam>> SwDSParams_t; 136 137 struct SwMergeDescriptor 138 { 139 const DBManagerOptions nMergeType; 140 SwWrtShell& rSh; 141 const svx::ODataAccessDescriptor& rDescriptor; 142 143 /** 144 * Create a single or multiple results 145 * 146 * This currently just affects FILE, as EMAIL is always 147 * multiple and SHELL and PRINTER are always single. 148 */ 149 bool bCreateSingleFile; 150 151 /** 152 * @defgroup save Export filter settings 153 * @addtogroup save 154 * @{ */ 155 OUString sSaveToFilter; 156 OUString sSaveToFilterOptions; 157 css::uno::Sequence< css::beans::PropertyValue > aSaveToFilterData; 158 /** @} */ 159 160 /** 161 * @defgroup file Mail merge as File settings 162 * @addtogroup file 163 * @{ */ 164 165 /** 166 * Basename incl. the path for the generated files. 167 * 168 * The final filename will be created by concatenating a number to prevent 169 * overwriting an existing file and the extension based on the filter 170 * settings. 171 */ 172 OUString sPrefix; 173 /** 174 * Use the sPrefix as the target filename also overwriting an existing 175 * target file. 176 * 177 * Just used for the internal mail merge dialogs as mail merge never 178 * overwrites existing files (see SwDBManager::ExecuteFormLetter). 179 */ 180 bool bPrefixIsFilename; 181 /** @} */ 182 183 /** 184 * @defgroup email Mail merge as eMail settings 185 * @addtogroup email 186 * @{ */ 187 OUString sSubject; 188 OUString sMailBody; 189 OUString sAttachmentName; 190 css::uno::Sequence< OUString > aCopiesTo; 191 css::uno::Sequence< OUString > aBlindCopiesTo; 192 css::uno::Reference< css::mail::XSmtpService > xSmtpServer; 193 bool bSendAsHTML; 194 bool bSendAsAttachment; 195 /** @} */ 196 197 /** 198 * @addtogroup file email 199 * @{ */ 200 201 /** DB column to fetch EMail of Filename from 202 */ 203 OUString sDBcolumn; 204 205 /** @} */ 206 207 /** 208 * @defgroup print Mail merge to Printer 209 * @addtogroup print 210 * @{ */ 211 css::uno::Sequence< css::beans::PropertyValue > aPrintOptions; 212 /** @} */ 213 214 SwMailMergeConfigItem* pMailMergeConfigItem; 215 SwMergeDescriptorSwMergeDescriptor216 SwMergeDescriptor( const DBManagerOptions nType, 217 SwWrtShell& rShell, 218 const svx::ODataAccessDescriptor& rDesc ) : 219 nMergeType(nType), 220 rSh(rShell), 221 rDescriptor(rDesc), 222 bCreateSingleFile( false ), 223 bPrefixIsFilename( false ), 224 bSendAsHTML( true ), 225 bSendAsAttachment( false ), 226 pMailMergeConfigItem( nullptr ) 227 { 228 if( nType == DBMGR_MERGE_SHELL || nType == DBMGR_MERGE_PRINTER ) 229 bCreateSingleFile = true; 230 } 231 }; 232 233 class SwDoc; 234 235 class SW_DLLPUBLIC SwDBManager 236 { 237 struct SwDBManager_Impl; 238 class ConnectionDisposedListener_Impl; 239 class MailDispatcherListener_Impl; 240 241 enum class MergeStatus 242 { 243 Ok = 0, Cancel, Error 244 }; 245 246 MergeStatus m_aMergeStatus; ///< current / last merge status 247 bool m_bInitDBFields : 1; 248 bool m_bInMerge : 1; ///< merge process active 249 bool m_bMergeSilent : 1; ///< suppress display of dialogs/boxes (used when called over API) 250 SwDSParams_t m_DataSourceParams; 251 std::unique_ptr<SwDBManager_Impl> m_pImpl; 252 const SwXMailMerge* m_pMergeEvtSrc; ///< != 0 if mail merge events are to be send 253 /// Name of the embedded database that's included in the current document. 254 OUString m_sEmbeddedName; 255 256 /// Store last registrations to revoke or commit 257 static std::vector<std::pair<SwDocShell*, OUString>> m_aUncommittedRegistrations; 258 259 /// Not used connections. 260 std::vector<OUString> m_aNotUsedConnections; 261 262 /// Set connection as used. 263 void SetAsUsed(const OUString& rName); 264 265 /// The document that owns this manager. 266 SwDoc* m_pDoc; 267 268 SAL_DLLPRIVATE SwDSParam* FindDSData(const SwDBData& rData, bool bCreate); 269 SAL_DLLPRIVATE SwDSParam* FindDSConnection(const OUString& rSource, bool bCreate); 270 271 /// Insert data record as text into document. 272 SAL_DLLPRIVATE void ImportFromConnection( SwWrtShell* pSh); 273 274 /// Insert a single data record as text into document. 275 SAL_DLLPRIVATE void ImportDBEntry(SwWrtShell* pSh); 276 277 /// Run the mail merge for defined modes, except DBMGR_MERGE 278 SAL_DLLPRIVATE bool MergeMailFiles( SwWrtShell* pSh, 279 const SwMergeDescriptor& rMergeDescriptor ); 280 281 SAL_DLLPRIVATE bool ToNextMergeRecord(); 282 SAL_DLLPRIVATE bool IsValidMergeRecord() const; 283 284 SwDBManager(SwDBManager const&) = delete; 285 SwDBManager& operator=(SwDBManager const&) = delete; 286 287 public: 288 SwDBManager(SwDoc* pDoc); 289 ~SwDBManager() COVERITY_NOEXCEPT_FALSE; 290 291 /// MailMergeEvent source GetMailMergeEvtSrc() const292 const SwXMailMerge * GetMailMergeEvtSrc() const { return m_pMergeEvtSrc; } SetMailMergeEvtSrc(const SwXMailMerge * pSrc)293 void SetMailMergeEvtSrc( const SwXMailMerge *pSrc ) { m_pMergeEvtSrc = pSrc; } 294 IsMergeSilent() const295 bool IsMergeSilent() const { return m_bMergeSilent; } SetMergeSilent(bool bVal)296 void SetMergeSilent( bool bVal ) { m_bMergeSilent = bVal; } 297 298 /// Merging of data records into fields. 299 bool Merge( const SwMergeDescriptor& rMergeDesc ); 300 void MergeCancel(); 301 IsMergeOk() const302 bool IsMergeOk() const { return MergeStatus::Ok == m_aMergeStatus; } IsMergeError() const303 bool IsMergeError() const { return MergeStatus::Error <= m_aMergeStatus; } 304 305 static std::shared_ptr<SwMailMergeConfigItem> PerformMailMerge(SwView const * pView); 306 307 /// Initialize data fields that lack name of database. IsInitDBFields() const308 bool IsInitDBFields() const { return m_bInitDBFields; } SetInitDBFields(bool b)309 void SetInitDBFields(bool b) { m_bInitDBFields = b; } 310 311 /// Fill listbox with all table names of a database. 312 bool GetTableNames(weld::ComboBox& rBox, const OUString& rDBName); 313 314 /// Fill listbox with all column names of a database table. 315 void GetColumnNames(weld::ComboBox& rBox, 316 const OUString& rDBName, const OUString& rTableName); 317 static void GetColumnNames(weld::ComboBox& rBox, 318 css::uno::Reference< css::sdbc::XConnection> const & xConnection, 319 const OUString& rTableName); 320 321 static sal_uLong GetColumnFormat( css::uno::Reference< css::sdbc::XDataSource> const & xSource, 322 css::uno::Reference< css::sdbc::XConnection> const & xConnection, 323 css::uno::Reference< css::beans::XPropertySet> const & xColumn, 324 SvNumberFormatter* pNFormatr, 325 LanguageType nLanguage ); 326 327 sal_uLong GetColumnFormat( const OUString& rDBName, 328 const OUString& rTableName, 329 const OUString& rColNm, 330 SvNumberFormatter* pNFormatr, 331 LanguageType nLanguage ); 332 sal_Int32 GetColumnType( const OUString& rDBName, 333 const OUString& rTableName, 334 const OUString& rColNm ); 335 IsInMerge() const336 bool IsInMerge() const { return m_bInMerge; } 337 338 void ExecuteFormLetter(SwWrtShell& rSh, 339 const css::uno::Sequence< css::beans::PropertyValue>& rProperties); 340 341 static void InsertText(SwWrtShell& rSh, 342 const css::uno::Sequence< css::beans::PropertyValue>& rProperties); 343 344 /// check if a data source is open 345 bool IsDataSourceOpen(const OUString& rDataSource, 346 const OUString& rTableOrQuery, bool bMergeShell); 347 348 /// open the source while fields are updated - for the calculator only! 349 bool OpenDataSource(const OUString& rDataSource, const OUString& rTableOrQuery); 350 sal_uInt32 GetSelectedRecordId(const OUString& rDataSource, const OUString& rTableOrQuery, sal_Int32 nCommandType = -1); 351 bool GetColumnCnt(const OUString& rSourceName, const OUString& rTableName, 352 const OUString& rColumnName, sal_uInt32 nAbsRecordId, LanguageType nLanguage, 353 OUString& rResult, double* pNumber); 354 /** create and store or find an already stored connection to a data source for use 355 in SwFieldMgr and SwDBTreeList */ 356 css::uno::Reference< css::sdbc::XConnection> const & 357 RegisterConnection(OUString const& rSource); 358 CreateDSData(const SwDBData & rData)359 void CreateDSData(const SwDBData& rData) 360 { FindDSData(rData, true); } GetDSParamArray() const361 const SwDSParams_t& GetDSParamArray() const { return m_DataSourceParams; } 362 363 /// close all data sources - after fields were updated 364 void CloseAll(bool bIncludingMerge = true); 365 366 bool GetMergeColumnCnt(const OUString& rColumnName, LanguageType nLanguage, 367 OUString &rResult, double *pNumber); 368 bool FillCalcWithMergeData(SvNumberFormatter *pDocFormatter, 369 LanguageType nLanguage, SwCalc &aCalc); 370 void ToNextRecord(const OUString& rDataSource, const OUString& rTableOrQuery); 371 372 sal_uInt32 GetSelectedRecordId(); 373 bool ToRecordId(sal_Int32 nSet); 374 375 static const SwDBData& GetAddressDBName(); 376 377 static OUString GetDBField( 378 css::uno::Reference< css::beans::XPropertySet > const & xColumnProp, 379 const SwDBFormatData& rDBFormatData, 380 double *pNumber = nullptr); 381 382 static css::uno::Reference< css::sdbc::XConnection> 383 GetConnection(const OUString& rDataSource, 384 css::uno::Reference< css::sdbc::XDataSource>& rxSource, 385 const SwView* pView); 386 387 static css::uno::Reference< css::sdbcx::XColumnsSupplier> 388 GetColumnSupplier(css::uno::Reference< css::sdbc::XConnection> const & xConnection, 389 const OUString& rTableOrQuery, 390 SwDBSelect eTableOrQuery = SwDBSelect::UNKNOWN); 391 392 static css::uno::Sequence<OUString> GetExistingDatabaseNames(); 393 394 /** 395 Loads a data source from file and registers it. 396 397 This function requires GUI interaction, as it loads the data source from 398 the filename returned by a file picker and additional settings dialog. 399 In case of success it returns the registered name, otherwise an empty string. 400 */ 401 static OUString LoadAndRegisterDataSource(weld::Window* pParent, SwDocShell* pDocShell = nullptr); 402 403 /** 404 Loads a data source from file and registers it. 405 406 Convenience function, which calls GetDBunoURI and has just one mandatory parameter. 407 In case of success it returns the registered name, otherwise an empty string. 408 */ 409 static OUString LoadAndRegisterDataSource(const OUString& rURI, const OUString *pDestDir); 410 411 /// Load the embedded data source of the document and also register it. 412 void LoadAndRegisterEmbeddedDataSource(const SwDBData& rData, const SwDocShell& rDocShell); 413 414 /// Unregister a data source. 415 static void RevokeDataSource(const OUString& rName); 416 417 /** try to get the data source from the given connection through the XChild interface. 418 If this is not possible, the data source will be created through its name. 419 @param _xConnection 420 The connection which should support the XChild interface. (not a must) 421 @param _sDataSourceName 422 The data source name will be used to create the data source when the connection can not be used for it. 423 @return 424 The data source. 425 */ 426 static css::uno::Reference< css::sdbc::XDataSource> 427 getDataSourceAsParent(const css::uno::Reference< css::sdbc::XConnection>& _xConnection,const OUString& _sDataSourceName); 428 429 /** creates a RowSet, which must be disposed after use. 430 @param _sDataSourceName 431 The data source name 432 @param _sCommand 433 The command. 434 @param _nCommandType 435 The type of the command. 436 @param _xConnection 437 The active connection which may be <NULL/>. 438 @return 439 The new created RowSet. 440 441 */ 442 static css::uno::Reference< css::sdbc::XResultSet> 443 createCursor(const OUString& _sDataSourceName, 444 const OUString& _sCommand, 445 sal_Int32 _nCommandType, 446 const css::uno::Reference< css::sdbc::XConnection>& _xConnection, 447 const SwView* pView); 448 449 void setEmbeddedName(const OUString& rEmbeddedName, SwDocShell& rDocShell); 450 const OUString& getEmbeddedName() const; 451 452 // rOwnURL should be taken using INetURLObject::GetMainURL(INetURLObject::DecodeMechanism::NONE) 453 static void StoreEmbeddedDataSource(const css::uno::Reference<css::frame::XStorable>& xStorable, 454 const css::uno::Reference<css::embed::XStorage>& xStorage, 455 const OUString& rStreamRelPath, 456 const OUString& rOwnURL, bool bCopyTo = false); 457 458 SwDoc* getDoc() const; 459 /// Stop reacting to removed database registrations. 460 void releaseRevokeListener(); 461 462 /// Revoke not committed registrations in case of mail merge cancel 463 void RevokeLastRegistrations(); 464 465 /// Accept not committed registrations 466 void CommitLastRegistrations(); 467 468 /// Remove not used connections. 469 void RevokeNotUsedConnections(); 470 }; 471 472 namespace sw 473 { 474 enum class DBConnURIType 475 { 476 UNKNOWN = 0, 477 ODB, 478 CALC, 479 DBASE, 480 FLAT, 481 MSJET, 482 MSACE, 483 WRITER 484 }; 485 486 DBConnURIType SW_DLLPUBLIC GetDBunoType(const INetURLObject &rURL); 487 } 488 489 #endif 490 491 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 492