Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 192, column 9
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name mmresultdialogs.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sw/inc -I /home/maarten/src/libreoffice/core/sw/source/uibase/inc -I /home/maarten/src/libreoffice/core/sw/source/ui/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sw/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx

/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx

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 <mmresultdialogs.hxx>
21#include <mmconfigitem.hxx>
22#include <mailconfigpage.hxx>
23#include "mmgreetingspage.hxx"
24#include <printdata.hxx>
25#include <swmessdialog.hxx>
26#include <cmdid.h>
27#include <swtypes.hxx>
28#include <view.hxx>
29#include <wrtsh.hxx>
30#include <docsh.hxx>
31#include <IDocumentDeviceAccess.hxx>
32#include <hintids.hxx>
33#include <swmodule.hxx>
34
35#include <vcl/QueueInfo.hxx>
36#include <editeng/langitem.hxx>
37#include <o3tl/temporary.hxx>
38#include <svl/itemset.hxx>
39#include <svl/stritem.hxx>
40#include <svtools/ehdl.hxx>
41#include <svtools/sfxecode.hxx>
42#include <vcl/stdtext.hxx>
43#include <vcl/svapp.hxx>
44#include <vcl/weld.hxx>
45#include <vcl/scheduler.hxx>
46#include <sfx2/printer.hxx>
47#include <sfx2/fcontnr.hxx>
48#include <sfx2/viewfrm.hxx>
49#include <sfx2/docfile.hxx>
50#include <sfx2/docfilt.hxx>
51#include <tools/urlobj.hxx>
52#include <svl/urihelper.hxx>
53#include <vcl/print.hxx>
54#include <rtl/tencinfo.h>
55#include <sal/log.hxx>
56
57#include <unotools/tempfile.hxx>
58#include <osl/file.hxx>
59#include <com/sun/star/frame/XStorable.hpp>
60#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
61#include <com/sun/star/sdb/XColumn.hpp>
62#include <com/sun/star/task/ErrorCodeIOException.hpp>
63#include <dbmgr.hxx>
64#include <swunohelper.hxx>
65#include <shellio.hxx>
66#include <svtools/htmlcfg.hxx>
67#include <sfx2/event.hxx>
68#include <swevent.hxx>
69#include <dbui.hxx>
70#include <dbui.hrc>
71#include <doc.hxx>
72#include <sfx2/app.hxx>
73#include <strings.hrc>
74#include <comphelper/string.hxx>
75#include <iodetect.hxx>
76
77using namespace svt;
78using namespace ::com::sun::star;
79using namespace ::com::sun::star::uno;
80
81#define MM_DOCTYPE_OOO1 1
82#define MM_DOCTYPE_PDF2 2
83#define MM_DOCTYPE_WORD3 3
84#define MM_DOCTYPE_HTML4 4
85#define MM_DOCTYPE_TEXT5 5
86
87static OUString lcl_GetExtensionForDocType(sal_uLong nDocType)
88{
89 OUString sExtension;
90 switch( nDocType )
91 {
92 case MM_DOCTYPE_OOO1 : sExtension = "odt"; break;
93 case MM_DOCTYPE_PDF2 : sExtension = "pdf"; break;
94 case MM_DOCTYPE_WORD3: sExtension = "doc"; break;
95 case MM_DOCTYPE_HTML4: sExtension = "html"; break;
96 case MM_DOCTYPE_TEXT5: sExtension = "txt"; break;
97 }
98 return sExtension;
99}
100
101static OUString lcl_GetColumnValueOf(const OUString& rColumn, Reference < container::XNameAccess> const & rxColAccess )
102{
103 OUString sRet;
104 try
105 {
106 if (rxColAccess->hasByName(rColumn))
107 {
108 Any aCol = rxColAccess->getByName(rColumn);
109 Reference< sdb::XColumn > xColumn;
110 aCol >>= xColumn;
111 if(xColumn.is())
112 sRet = xColumn->getString();
113 }
114 }
115 catch (const uno::Exception&)
116 {
117 }
118 return sRet;
119}
120
121/**
122 * Replace email server settings in rConfigItem with those set in Writer's global
123 * mail merge config settings.
124 */
125static void lcl_UpdateEmailSettingsFromGlobalConfig(SwMailMergeConfigItem& rConfigItem)
126{
127 // newly created SwMailMergeConfigItem is initialized with values from (global) config
128 SwMailMergeConfigItem aConfigItem;
129
130 // take over email-related settings
131 rConfigItem.SetMailDisplayName(aConfigItem.GetMailDisplayName());
132 rConfigItem.SetMailAddress(aConfigItem.GetMailAddress());
133 rConfigItem.SetMailReplyTo(aConfigItem.GetMailReplyTo());
134 rConfigItem.SetMailReplyTo(aConfigItem.IsMailReplyTo());
135 rConfigItem.SetMailServer(aConfigItem.GetMailServer());
136 rConfigItem.SetMailPort(aConfigItem.GetMailPort());
137 rConfigItem.SetSecureConnection(aConfigItem.IsSecureConnection());
138 // authentication settings
139 rConfigItem.SetAuthentication(aConfigItem.IsAuthentication());
140 rConfigItem.SetSMTPAfterPOP(aConfigItem.IsSMTPAfterPOP());
141 rConfigItem.SetMailUserName(aConfigItem.GetMailUserName());
142 rConfigItem.SetMailPassword(aConfigItem.GetMailPassword());
143 rConfigItem.SetInServerName(aConfigItem.GetInServerName());
144 rConfigItem.SetInServerPort(aConfigItem.GetInServerPort());
145 rConfigItem.SetInServerPOP(aConfigItem.IsInServerPOP());
146 rConfigItem.SetInServerUserName(aConfigItem.GetInServerUserName());
147 rConfigItem.SetInServerPassword(aConfigItem.GetInServerPassword());
148}
149
150namespace {
151
152class SwSaveWarningBox_Impl : public SwMessageAndEditDialog
153{
154 DECL_LINK( ModifyHdl, weld::Entry&, void)static void LinkStubModifyHdl(void *, weld::Entry&); void
ModifyHdl(weld::Entry&)
;
155public:
156 SwSaveWarningBox_Impl(weld::Window* pParent, const OUString& rFileName);
157
158 OUString GetFileName() const
159 {
160 return m_xEdit->get_text();
161 }
162};
163
164class SwSendQueryBox_Impl : public SwMessageAndEditDialog
165{
166 bool bIsEmptyAllowed;
167 DECL_LINK( ModifyHdl, weld::Entry&, void)static void LinkStubModifyHdl(void *, weld::Entry&); void
ModifyHdl(weld::Entry&)
;
168public:
169 SwSendQueryBox_Impl(weld::Window* pParent, const OString& rID,
170 const OUString& rUIXMLDescription);
171
172 void SetValue(const OUString& rSet)
173 {
174 m_xEdit->set_text(rSet);
175 ModifyHdl(*m_xEdit);
176 }
177
178 OUString GetValue() const
179 {
180 return m_xEdit->get_text();
181 }
182
183 void SetIsEmptyTextAllowed(bool bSet)
184 {
185 bIsEmptyAllowed = bSet;
186 ModifyHdl(*m_xEdit);
187 }
188};
189
190}
191
192SwSaveWarningBox_Impl::SwSaveWarningBox_Impl(weld::Window* pParent, const OUString& rFileName)
193 : SwMessageAndEditDialog(pParent, "AlreadyExistsDialog",
194 "modules/swriter/ui/alreadyexistsdialog.ui")
195{
196 m_xEdit->set_text(rFileName);
197 m_xEdit->connect_changed(LINK(this, SwSaveWarningBox_Impl, ModifyHdl)::tools::detail::makeLink( ::tools::detail::castTo<SwSaveWarningBox_Impl
*>(this), &SwSaveWarningBox_Impl::LinkStubModifyHdl)
);
198
199 INetURLObject aTmp(rFileName);
200 m_xDialog->set_primary_text(m_xDialog->get_primary_text().replaceAll("%1", aTmp.getName(
201 INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset)));
202
203 ModifyHdl(*m_xEdit);
204}
205
206IMPL_LINK( SwSaveWarningBox_Impl, ModifyHdl, weld::Entry&, rEdit, void)void SwSaveWarningBox_Impl::LinkStubModifyHdl(void * instance
, weld::Entry& data) { return static_cast<SwSaveWarningBox_Impl
*>(instance)->ModifyHdl(data); } void SwSaveWarningBox_Impl
::ModifyHdl(weld::Entry& rEdit)
207{
208 m_xOKPB->set_sensitive(!rEdit.get_text().isEmpty());
209}
210
211SwSendQueryBox_Impl::SwSendQueryBox_Impl(weld::Window* pParent, const OString& rID,
212 const OUString& rUIXMLDescription)
213 : SwMessageAndEditDialog(pParent, rID, rUIXMLDescription)
214 , bIsEmptyAllowed(true)
215{
216 m_xEdit->connect_changed(LINK(this, SwSendQueryBox_Impl, ModifyHdl)::tools::detail::makeLink( ::tools::detail::castTo<SwSendQueryBox_Impl
*>(this), &SwSendQueryBox_Impl::LinkStubModifyHdl)
);
217 ModifyHdl(*m_xEdit);
218}
219
220IMPL_LINK( SwSendQueryBox_Impl, ModifyHdl, weld::Entry&, rEdit, void)void SwSendQueryBox_Impl::LinkStubModifyHdl(void * instance, weld
::Entry& data) { return static_cast<SwSendQueryBox_Impl
*>(instance)->ModifyHdl(data); } void SwSendQueryBox_Impl
::ModifyHdl(weld::Entry& rEdit)
221{
222 m_xOKPB->set_sensitive(bIsEmptyAllowed || !rEdit.get_text().isEmpty());
223}
224
225namespace {
226
227class SwCopyToDialog : public SfxDialogController
228{
229 std::unique_ptr<weld::Entry> m_xCCED;
230 std::unique_ptr<weld::Entry> m_xBCCED;
231
232public:
233 explicit SwCopyToDialog(weld::Window* pParent)
234 : SfxDialogController(pParent, "modules/swriter/ui/ccdialog.ui", "CCDialog")
235 , m_xCCED(m_xBuilder->weld_entry("cc"))
236 , m_xBCCED(m_xBuilder->weld_entry("bcc"))
237 {
238 }
239
240 OUString GetCC() const {return m_xCCED->get_text();}
241 void SetCC(const OUString& rSet) {m_xCCED->set_text(rSet);}
242
243 OUString GetBCC() const {return m_xBCCED->get_text();}
244 void SetBCC(const OUString& rSet) {m_xBCCED->set_text(rSet);}
245};
246
247}
248
249SwMMResultSaveDialog::SwMMResultSaveDialog(weld::Window* pParent)
250 : SfxDialogController(pParent, "modules/swriter/ui/mmresultsavedialog.ui", "MMResultSaveDialog")
251 , m_bCancelSaving(false)
252 , m_xSaveAsOneRB(m_xBuilder->weld_radio_button("singlerb"))
253 , m_xSaveIndividualRB(m_xBuilder->weld_radio_button("individualrb"))
254 , m_xFromRB(m_xBuilder->weld_radio_button("fromrb"))
255 , m_xFromNF(m_xBuilder->weld_spin_button("from"))
256 , m_xToFT(m_xBuilder->weld_label("toft"))
257 , m_xToNF(m_xBuilder->weld_spin_button("to"))
258 , m_xOKButton(m_xBuilder->weld_button("ok"))
259{
260 Link<weld::ToggleButton&,void> aLink = LINK(this, SwMMResultSaveDialog, DocumentSelectionHdl_Impl)::tools::detail::makeLink( ::tools::detail::castTo<SwMMResultSaveDialog
*>(this), &SwMMResultSaveDialog::LinkStubDocumentSelectionHdl_Impl
)
;
261 m_xSaveAsOneRB->connect_toggled(aLink);
262 m_xSaveIndividualRB->connect_toggled(aLink);
263 m_xFromRB->connect_toggled(aLink);
264 // m_pSaveAsOneRB is the default, so disable m_xFromNF and m_xToNF initially.
265 aLink.Call(*m_xSaveAsOneRB);
266 SwView* pView = ::GetActiveView();
267 const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem();
268 assert(xConfigItem)(static_cast <bool> (xConfigItem) ? void (0) : __assert_fail
("xConfigItem", "/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
, 268, __extension__ __PRETTY_FUNCTION__))
;
269 sal_Int32 nCount = xConfigItem->GetMergedDocumentCount();
270 m_xFromNF->set_max(nCount);
271 m_xToNF->set_max(nCount);
272 m_xToNF->set_value(nCount);
273
274 m_xOKButton->connect_clicked(LINK(this, SwMMResultSaveDialog, SaveOutputHdl_Impl)::tools::detail::makeLink( ::tools::detail::castTo<SwMMResultSaveDialog
*>(this), &SwMMResultSaveDialog::LinkStubSaveOutputHdl_Impl
)
);
275}
276
277SwMMResultSaveDialog::~SwMMResultSaveDialog()
278{
279}
280
281SwMMResultPrintDialog::SwMMResultPrintDialog(weld::Window* pParent)
282 : SfxDialogController(pParent, "modules/swriter/ui/mmresultprintdialog.ui", "MMResultPrintDialog")
283 , m_xPrinterFT(m_xBuilder->weld_label("printerft"))
284 , m_xPrinterLB(m_xBuilder->weld_combo_box("printers"))
285 , m_xPrinterSettingsPB(m_xBuilder->weld_button("printersettings"))
286 , m_xPrintAllRB(m_xBuilder->weld_radio_button("printallrb"))
287 , m_xFromRB(m_xBuilder->weld_radio_button("fromrb"))
288 , m_xFromNF(m_xBuilder->weld_spin_button("from"))
289 , m_xToFT(m_xBuilder->weld_label("toft"))
290 , m_xToNF(m_xBuilder->weld_spin_button("to"))
291 , m_xOKButton(m_xBuilder->weld_button("ok"))
292{
293 m_xPrinterLB->make_sorted();
294
295 m_xPrinterLB->connect_changed(LINK(this, SwMMResultPrintDialog, PrinterChangeHdl_Impl)::tools::detail::makeLink( ::tools::detail::castTo<SwMMResultPrintDialog
*>(this), &SwMMResultPrintDialog::LinkStubPrinterChangeHdl_Impl
)
);
296 m_xPrinterSettingsPB->connect_clicked(LINK(this, SwMMResultPrintDialog, PrinterSetupHdl_Impl)::tools::detail::makeLink( ::tools::detail::castTo<SwMMResultPrintDialog
*>(this), &SwMMResultPrintDialog::LinkStubPrinterSetupHdl_Impl
)
);
297
298 Link<weld::ToggleButton&,void> aLink = LINK(this, SwMMResultPrintDialog, DocumentSelectionHdl_Impl)::tools::detail::makeLink( ::tools::detail::castTo<SwMMResultPrintDialog
*>(this), &SwMMResultPrintDialog::LinkStubDocumentSelectionHdl_Impl
)
;
299 m_xPrintAllRB->connect_toggled(aLink);
300 m_xFromRB->connect_toggled(aLink);
301 // m_pPrintAllRB is the default, so disable m_xFromNF and m_xToNF initially.
302 aLink.Call(*m_xPrintAllRB);
303
304 m_xOKButton->connect_clicked(LINK(this, SwMMResultPrintDialog, PrintHdl_Impl)::tools::detail::makeLink( ::tools::detail::castTo<SwMMResultPrintDialog
*>(this), &SwMMResultPrintDialog::LinkStubPrintHdl_Impl
)
);
305
306 FillInPrinterSettings();
307}
308
309SwMMResultPrintDialog::~SwMMResultPrintDialog()
310{
311}
312
313SwMMResultEmailDialog::SwMMResultEmailDialog(weld::Window* pParent)
314 : SfxDialogController(pParent, "modules/swriter/ui/mmresultemaildialog.ui", "MMResultEmailDialog")
315 , m_sConfigureMail(SwResId(ST_CONFIGUREMAILreinterpret_cast<char const *>("ST_CONFIGUREMAIL" "\004"
u8"In order to be able to send mail merge documents by email, %PRODUCTNAME requires information about the email account to be used.\n\nDo you want to enter email account information now?"
)
))
316 , m_xMailToFT(m_xBuilder->weld_label("mailtoft"))
317 , m_xMailToLB(m_xBuilder->weld_combo_box("mailto"))
318 , m_xCopyToPB(m_xBuilder->weld_button("copyto"))
319 , m_xSubjectFT(m_xBuilder->weld_label("subjectft"))
320 , m_xSubjectED(m_xBuilder->weld_entry("subject"))
321 , m_xSendAsFT(m_xBuilder->weld_label("sendasft"))
322 , m_xSendAsLB(m_xBuilder->weld_combo_box("sendas"))
323 , m_xSendAsPB(m_xBuilder->weld_button("sendassettings"))
324 , m_xAttachmentGroup(m_xBuilder->weld_widget("attachgroup"))
325 , m_xAttachmentED(m_xBuilder->weld_entry("attach"))
326 , m_xPasswordFT(m_xBuilder->weld_label("passwordft"))
327 , m_xPasswordLB(m_xBuilder->weld_combo_box("password"))
328 , m_xPasswordCB(m_xBuilder->weld_check_button("passwordcb"))
329 , m_xSendAllRB(m_xBuilder->weld_radio_button("sendallrb"))
330 , m_xFromRB(m_xBuilder->weld_radio_button("fromrb"))
331 , m_xFromNF(m_xBuilder->weld_spin_button("from"))
332 , m_xToFT(m_xBuilder->weld_label("toft"))
333 , m_xToNF(m_xBuilder->weld_spin_button("to"))
334 , m_xOKButton(m_xBuilder->weld_button("ok"))
335{
336 m_xCopyToPB->connect_clicked(LINK(this, SwMMResultEmailDialog, CopyToHdl_Impl)::tools::detail::makeLink( ::tools::detail::castTo<SwMMResultEmailDialog
*>(this), &SwMMResultEmailDialog::LinkStubCopyToHdl_Impl
)
);
337 m_xSendAsPB->connect_clicked(LINK(this, SwMMResultEmailDialog, SendAsHdl_Impl)::tools::detail::makeLink( ::tools::detail::castTo<SwMMResultEmailDialog
*>(this), &SwMMResultEmailDialog::LinkStubSendAsHdl_Impl
)
);
338 m_xSendAsLB->connect_changed(LINK(this, SwMMResultEmailDialog, SendTypeHdl_Impl)::tools::detail::makeLink( ::tools::detail::castTo<SwMMResultEmailDialog
*>(this), &SwMMResultEmailDialog::LinkStubSendTypeHdl_Impl
)
);
339 m_xPasswordCB->connect_toggled( LINK( this, SwMMResultEmailDialog, CheckHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwMMResultEmailDialog
*>(this), &SwMMResultEmailDialog::LinkStubCheckHdl)
);
340
341 Link<weld::ToggleButton&,void> aLink = LINK(this, SwMMResultEmailDialog, DocumentSelectionHdl_Impl)::tools::detail::makeLink( ::tools::detail::castTo<SwMMResultEmailDialog
*>(this), &SwMMResultEmailDialog::LinkStubDocumentSelectionHdl_Impl
)
;
342 m_xSendAllRB->connect_toggled(aLink);
343 m_xFromRB->connect_toggled(aLink);
344 // m_xSendAllRB is the default, so disable m_xFromNF and m_xToNF initially.
345 aLink.Call(*m_xSendAllRB);
346
347 m_xOKButton->connect_clicked(LINK(this, SwMMResultEmailDialog, SendDocumentsHdl_Impl)::tools::detail::makeLink( ::tools::detail::castTo<SwMMResultEmailDialog
*>(this), &SwMMResultEmailDialog::LinkStubSendDocumentsHdl_Impl
)
);
348
349 m_xPasswordCB->set_sensitive(false);
350 m_xPasswordFT->set_sensitive(false);
351 m_xPasswordLB->set_sensitive(false);
352
353 FillInEmailSettings();
354}
355
356SwMMResultEmailDialog::~SwMMResultEmailDialog()
357{
358}
359
360void SwMMResultPrintDialog::FillInPrinterSettings()
361{
362 //fill printer ListBox
363 SwView* pView = ::GetActiveView();
364 const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem();
365 const std::vector<OUString>& rPrinters = Printer::GetPrinterQueues();
366 unsigned int nCount = rPrinters.size();
367 bool bMergePrinterExists = false;
368
369 for (unsigned int i = 0; i < nCount; ++i)
370 {
371 m_xPrinterLB->append_text( rPrinters[i] );
372 if( !bMergePrinterExists && rPrinters[i] == xConfigItem->GetSelectedPrinter() )
373 bMergePrinterExists = true;
374 }
375
376 assert(xConfigItem)(static_cast <bool> (xConfigItem) ? void (0) : __assert_fail
("xConfigItem", "/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
, 376, __extension__ __PRETTY_FUNCTION__))
;
377 if(!bMergePrinterExists)
378 {
379 SfxPrinter* pPrinter = pView->GetWrtShell().getIDocumentDeviceAccess().getPrinter( true );
380 m_xPrinterLB->set_active_text(pPrinter->GetName());
381 }
382 else
383 {
384 m_xPrinterLB->set_active_text(xConfigItem->GetSelectedPrinter());
385 }
386 PrinterChangeHdl_Impl(*m_xPrinterLB);
387
388 sal_Int32 count = xConfigItem->GetMergedDocumentCount();
389 m_xFromNF->set_max(count);
390 m_xToNF->set_value(count);
391 m_xToNF->set_max(count);
392}
393
394void SwMMResultEmailDialog::FillInEmailSettings()
395{
396 SwView* pView = ::GetActiveView();
397 const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem();
398 assert(xConfigItem)(static_cast <bool> (xConfigItem) ? void (0) : __assert_fail
("xConfigItem", "/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
, 398, __extension__ __PRETTY_FUNCTION__))
;
399
400 SwView* pSourceView = xConfigItem->GetSourceView();
401 OSL_ENSURE(pSourceView, "no source view exists")do { if (true && (!(pSourceView))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
":" "401" ": "), "%s", "no source view exists"); } } while (
false)
;
402 if (pSourceView)
403 {
404 SwDocShell* pDocShell = pSourceView->GetDocShell();
405 if (pDocShell->HasName())
406 {
407 INetURLObject aTmp(pDocShell->GetMedium()->GetName());
408 m_xAttachmentED->set_text(aTmp.getName(
409 INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset ));
410 }
411 }
412
413 if (m_xAttachmentED->get_text().isEmpty())
414 {
415 OUString sAttach = "." + lcl_GetExtensionForDocType(m_xSendAsLB->get_active_id().toUInt32());
416 m_xAttachmentED->set_text(sAttach);
417
418 }
419
420 //select first column
421 uno::Reference< sdbcx::XColumnsSupplier > xColsSupp(xConfigItem->GetResultSet(), uno::UNO_QUERY);
422 //get the name of the actual columns
423 uno::Reference < container::XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : nullptr;
424 uno::Sequence< OUString > aFields;
425 if (xColAccess.is())
426 aFields = xColAccess->getElementNames();
427
428 // fill mail address and password ListBox
429 assert(m_xMailToLB->get_count() == 0)(static_cast <bool> (m_xMailToLB->get_count() == 0) ?
void (0) : __assert_fail ("m_xMailToLB->get_count() == 0"
, "/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
, 429, __extension__ __PRETTY_FUNCTION__))
;
430 assert(m_xPasswordLB->get_count() == 0)(static_cast <bool> (m_xPasswordLB->get_count() == 0
) ? void (0) : __assert_fail ("m_xPasswordLB->get_count() == 0"
, "/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
, 430, __extension__ __PRETTY_FUNCTION__))
;
431 for (const OUString& rField : std::as_const(aFields))
432 {
433 m_xMailToLB->append_text(rField);
434 m_xPasswordLB->append_text(rField);
435 }
436
437 m_xMailToLB->set_active(0);
438 m_xPasswordLB->set_active(0);
439
440 // then select the right one - may not be available
441 const std::vector<std::pair<OUString, int>>& rHeaders = xConfigItem->GetDefaultAddressHeaders();
442 OUString sEMailColumn = rHeaders[MM_PART_E_MAIL12].first;
443 Sequence< OUString> aAssignment = xConfigItem->GetColumnAssignment(xConfigItem->GetCurrentDBData());
444 if (aAssignment.getLength() > MM_PART_E_MAIL12 && !aAssignment[MM_PART_E_MAIL12].isEmpty())
445 sEMailColumn = aAssignment[MM_PART_E_MAIL12];
446 m_xMailToLB->set_active_text(sEMailColumn);
447
448 // HTML format pre-selected
449 m_xSendAsLB->set_active(3);
450 SendTypeHdl_Impl(*m_xSendAsLB);
451
452 const sal_Int32 nCount = xConfigItem->GetMergedDocumentCount();
453 m_xFromNF->set_max(nCount);
454 m_xToNF->set_max(nCount);
455 m_xToNF->set_value(nCount);
456}
457
458IMPL_LINK_NOARG(SwMMResultSaveDialog, DocumentSelectionHdl_Impl, weld::ToggleButton&, void)void SwMMResultSaveDialog::LinkStubDocumentSelectionHdl_Impl(
void * instance, weld::ToggleButton& data) { return static_cast
<SwMMResultSaveDialog *>(instance)->DocumentSelectionHdl_Impl
(data); } void SwMMResultSaveDialog::DocumentSelectionHdl_Impl
(__attribute__ ((unused)) weld::ToggleButton&)
459{
460 bool bEnableFromTo = m_xFromRB->get_active();
461 m_xFromNF->set_sensitive(bEnableFromTo);
462 m_xToFT->set_sensitive(bEnableFromTo);
463 m_xToNF->set_sensitive(bEnableFromTo);
464}
465
466IMPL_LINK_NOARG(SwMMResultEmailDialog, CheckHdl, weld::ToggleButton&, void)void SwMMResultEmailDialog::LinkStubCheckHdl(void * instance,
weld::ToggleButton& data) { return static_cast<SwMMResultEmailDialog
*>(instance)->CheckHdl(data); } void SwMMResultEmailDialog
::CheckHdl(__attribute__ ((unused)) weld::ToggleButton&)
467{
468 bool bEnable = m_xPasswordCB->get_active();
469
470 m_xPasswordFT->set_sensitive(bEnable);
471 m_xPasswordLB->set_sensitive(bEnable);
472}
473
474IMPL_LINK_NOARG(SwMMResultPrintDialog, DocumentSelectionHdl_Impl, weld::ToggleButton&, void)void SwMMResultPrintDialog::LinkStubDocumentSelectionHdl_Impl
(void * instance, weld::ToggleButton& data) { return static_cast
<SwMMResultPrintDialog *>(instance)->DocumentSelectionHdl_Impl
(data); } void SwMMResultPrintDialog::DocumentSelectionHdl_Impl
(__attribute__ ((unused)) weld::ToggleButton&)
475{
476 bool bEnableFromTo = m_xFromRB->get_active();
477 m_xFromNF->set_sensitive(bEnableFromTo);
478 m_xToFT->set_sensitive(bEnableFromTo);
479 m_xToNF->set_sensitive(bEnableFromTo);
480}
481
482IMPL_LINK_NOARG(SwMMResultEmailDialog, DocumentSelectionHdl_Impl, weld::ToggleButton&, void)void SwMMResultEmailDialog::LinkStubDocumentSelectionHdl_Impl
(void * instance, weld::ToggleButton& data) { return static_cast
<SwMMResultEmailDialog *>(instance)->DocumentSelectionHdl_Impl
(data); } void SwMMResultEmailDialog::DocumentSelectionHdl_Impl
(__attribute__ ((unused)) weld::ToggleButton&)
483{
484 bool bEnableFromTo = m_xFromRB->get_active();
485 m_xFromNF->set_sensitive(bEnableFromTo);
486 m_xToFT->set_sensitive(bEnableFromTo);
487 m_xToNF->set_sensitive(bEnableFromTo);
488}
489
490IMPL_LINK_NOARG(SwMMResultEmailDialog, CopyToHdl_Impl, weld::Button&, void)void SwMMResultEmailDialog::LinkStubCopyToHdl_Impl(void * instance
, weld::Button& data) { return static_cast<SwMMResultEmailDialog
*>(instance)->CopyToHdl_Impl(data); } void SwMMResultEmailDialog
::CopyToHdl_Impl(__attribute__ ((unused)) weld::Button&)
491{
492 SwCopyToDialog aDlg(m_xDialog.get());
493 aDlg.SetCC(m_sCC );
494 aDlg.SetBCC(m_sBCC);
495 if (aDlg.run() == RET_OK)
496 {
497 m_sCC = aDlg.GetCC() ;
498 m_sBCC = aDlg.GetBCC();
499 }
500}
501
502namespace {
503
504int documentStartPageNumber(SwMailMergeConfigItem* pConfigItem, int document, bool bIgnoreEmpty)
505{
506 SwView* pTargetView = pConfigItem->GetTargetView();
507 assert( pTargetView )(static_cast <bool> (pTargetView) ? void (0) : __assert_fail
("pTargetView", "/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
, 507, __extension__ __PRETTY_FUNCTION__))
;
508 SwCursorShell& shell = pTargetView->GetWrtShell();
509 const SwDocMergeInfo& info = pConfigItem->GetDocumentMergeInfo(document);
510 sal_uInt16 page;
511 shell.Push();
512 shell.GotoMark( info.startPageInTarget );
513 if (!bIgnoreEmpty)
514 shell.GetPageNum(page, o3tl::temporary(sal_uInt16()));
515 else
516 page = shell.GetPageNumSeqNonEmpty();
517 shell.Pop(SwCursorShell::PopMode::DeleteCurrent);
518 return page;
519}
520
521int documentEndPageNumber(SwMailMergeConfigItem* pConfigItem, int document, bool bIgnoreEmpty)
522{
523 SwView* pTargetView = pConfigItem->GetTargetView();
524 assert( pTargetView )(static_cast <bool> (pTargetView) ? void (0) : __assert_fail
("pTargetView", "/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
, 524, __extension__ __PRETTY_FUNCTION__))
;
525 SwWrtShell& shell = pTargetView->GetWrtShell();
526 shell.Push();
527 if (document < int(pConfigItem->GetMergedDocumentCount()) - 1)
528 {
529 // Go to the page before the starting page of the next merged document.
530 const SwDocMergeInfo& info = pConfigItem->GetDocumentMergeInfo( document + 1 );
531 shell.GotoMark( info.startPageInTarget );
532 shell.EndPrvPg();
533 }
534 else
535 { // This is the last merged document, so it ends on the page at which the document ends.
536 shell.SttEndDoc( false ); // go to doc end
537 }
538 sal_uInt16 page;
539 if (!bIgnoreEmpty)
540 shell.GetPageNum(page, o3tl::temporary(sal_uInt16()));
541 else
542 page = shell.GetPageNumSeqNonEmpty();
543 shell.Pop(SwCursorShell::PopMode::DeleteCurrent);
544 return page;
545}
546
547} // anonymous namespace
548
549IMPL_LINK_NOARG(SwMMResultSaveDialog, SaveOutputHdl_Impl, weld::Button&, void)void SwMMResultSaveDialog::LinkStubSaveOutputHdl_Impl(void * instance
, weld::Button& data) { return static_cast<SwMMResultSaveDialog
*>(instance)->SaveOutputHdl_Impl(data); } void SwMMResultSaveDialog
::SaveOutputHdl_Impl(__attribute__ ((unused)) weld::Button&
)
550{
551 SwView* pView = ::GetActiveView();
552 std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem();
553 assert(xConfigItem)(static_cast <bool> (xConfigItem) ? void (0) : __assert_fail
("xConfigItem", "/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
, 553, __extension__ __PRETTY_FUNCTION__))
;
554 if (!xConfigItem->GetTargetView())
555 SwDBManager::PerformMailMerge(pView);
556
557 SwView* pTargetView = xConfigItem->GetTargetView();
558 assert(pTargetView)(static_cast <bool> (pTargetView) ? void (0) : __assert_fail
("pTargetView", "/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
, 558, __extension__ __PRETTY_FUNCTION__))
;
559
560 OUString sFilter;
561 OUString sPath = SwMailMergeHelper::CallSaveAsDialog(m_xDialog.get(), sFilter);
562 if (sPath.isEmpty())
563 {
564 // just return back to the dialog
565 return;
566 }
567
568 if (m_xSaveAsOneRB->get_active())
569 {
570 uno::Sequence< beans::PropertyValue > aValues(1);
571 beans::PropertyValue* pValues = aValues.getArray();
572 pValues[0].Name = "FilterName";
573 pValues[0].Value <<= sFilter;
574
575 uno::Reference< frame::XStorable > xStore( pTargetView->GetDocShell()->GetModel(), uno::UNO_QUERY);
576 ErrCode nErrorCode = ERRCODE_NONEErrCode(0);
577 try
578 {
579 xStore->storeToURL( sPath, aValues );
580 }
581 catch (const task::ErrorCodeIOException& rErrorEx)
582 {
583 nErrorCode = ErrCode(rErrorEx.ErrCode);
584 }
585 catch (const Exception&)
586 {
587 nErrorCode = ERRCODE_IO_GENERALErrCode( ErrCodeArea::Io, ErrCodeClass::General, 13 );
588 }
589 if( nErrorCode != ERRCODE_NONEErrCode(0) )
590 {
591 SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC3, pTargetView->GetDocShell()->GetTitle());
592 ErrorHandler::HandleError( nErrorCode );
593 }
594 }
595 else
596 {
597 const sal_uInt32 nDocumentCount = xConfigItem->GetMergedDocumentCount();
598 sal_uInt32 nBegin = 0;
599 sal_uInt32 nEnd = nDocumentCount;
600
601 if (!m_xSaveIndividualRB->get_active())
602 {
603 nBegin = static_cast< sal_Int32 >(m_xFromNF->get_value() - 1);
604 nEnd = static_cast< sal_Int32 >(m_xToNF->get_value());
605 if(nEnd > nDocumentCount)
606 nEnd = nDocumentCount;
607 }
608
609 OUString sTargetTempURL = URIHelper::SmartRel2Abs(
610 INetURLObject(), utl::TempFile::CreateTempName(),
611 URIHelper::GetMaybeFileHdl());
612 std::shared_ptr<const SfxFilter> pSfxFlt = SwIoSystem::GetFilterOfFormat(
613 FILTER_XML"CXML",
614 SwDocShell::Factory().GetFilterContainer() );
615
616 uno::Sequence< beans::PropertyValue > aValues(1);
617 beans::PropertyValue* pValues = aValues.getArray();
618 pValues[0].Name = "FilterName";
619 pValues[0].Value <<= pSfxFlt->GetFilterName();
620
621 uno::Reference< frame::XStorable > xStore( pTargetView->GetDocShell()->GetModel(), uno::UNO_QUERY);
622 ErrCode nErrorCode = ERRCODE_NONEErrCode(0);
623 try
624 {
625 xStore->storeToURL( sTargetTempURL, aValues );
626 }
627 catch (const task::ErrorCodeIOException& rErrorEx)
628 {
629 nErrorCode = ErrCode(rErrorEx.ErrCode);
630 }
631 catch (const Exception&)
632 {
633 nErrorCode = ERRCODE_IO_GENERALErrCode( ErrCodeArea::Io, ErrCodeClass::General, 13 );
634 }
635 if( nErrorCode != ERRCODE_NONEErrCode(0) )
636 {
637 SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC3, pTargetView->GetDocShell()->GetTitle());
638 ErrorHandler::HandleError( nErrorCode );
639 }
640
641 SwView* pSourceView = xConfigItem->GetSourceView();
642 auto xSaveMonitor = std::make_shared<SaveMonitor>(m_xDialog.get());
643 xSaveMonitor->m_xDocName->set_label(pSourceView->GetDocShell()->GetTitle(22));
644 xSaveMonitor->m_xPrinter->set_label( INetURLObject( sPath ).getFSysPath( FSysStyle::Detect ) );
645 m_bCancelSaving = false;
646 weld::DialogController::runAsync(xSaveMonitor, [this, &xSaveMonitor](sal_Int32 nResult){
647 if (nResult == RET_CANCEL)
648 m_bCancelSaving = true;
649 xSaveMonitor.reset();
650 });
651
652 for(sal_uInt32 nDoc = nBegin; nDoc < nEnd && !m_bCancelSaving; ++nDoc)
653 {
654 INetURLObject aURL(sPath);
655 OUString sExtension = aURL.getExtension();
656 if (sExtension.isEmpty())
657 {
658 sExtension = pSfxFlt->GetWildcard().getGlob().getToken(1, '.');
659 sPath += "." + sExtension;
660 }
661 OUString sStat = SwResId(STR_STATSTR_LETTERreinterpret_cast<char const *>("STR_STATSTR_LETTER" "\004"
u8"Letter")
) + " " + OUString::number( nDoc );
662 xSaveMonitor->m_xPrintInfo->set_label(sStat);
663
664 //now extract a document from the target document
665 // the shell will be closed at the end, but it is more safe to use SfxObjectShellLock here
666 SfxObjectShellLock xTempDocShell( new SwDocShell( SfxObjectCreateMode::STANDARD ) );
667 xTempDocShell->DoInitNew();
668 SfxViewFrame* pTempFrame = SfxViewFrame::LoadHiddenDocument( *xTempDocShell, SFX_INTERFACE_NONE );
669 SwView* pTempView = static_cast<SwView*>( pTempFrame->GetViewShell() );
670 pTargetView->GetWrtShell().StartAction();
671 SwgReaderOption aOpt;
672 aOpt.SetTextFormats( true );
673 aOpt.SetFrameFormats( true );
674 aOpt.SetPageDescs( true );
675 aOpt.SetNumRules( true );
676 aOpt.SetMerge( false );
677 pTempView->GetDocShell()->LoadStylesFromFile(
678 sTargetTempURL, aOpt, true );
679 pTempView->GetDocShell()->GetDoc()->ReplaceCompatibilityOptions( *pTargetView->GetDocShell()->GetDoc());
680 pTempView->GetDocShell()->GetDoc()->ReplaceDefaults( *pTargetView->GetDocShell()->GetDoc());
681 pTempView->GetDocShell()->GetDoc()->ReplaceDocumentProperties( *pTargetView->GetDocShell()->GetDoc(), true );
682
683 pTargetView->GetWrtShell().PastePages(
684 pTempView->GetWrtShell(), documentStartPageNumber(xConfigItem.get(), nDoc, false),
685 documentEndPageNumber(xConfigItem.get(), nDoc, false));
686 pTargetView->GetWrtShell().EndAction();
687 //then save it
688 OUString sOutPath = aURL.GetMainURL(INetURLObject::DecodeMechanism::ToIUri);
689 OUString sCounter = "_" + OUString::number(nDoc + 1);
690 sOutPath = sOutPath.replaceAt( sOutPath.getLength() - sExtension.getLength() - 1, 0, sCounter);
691
692 while(true)
693 {
694 //time for other slots is needed
695 Scheduler::ProcessEventsToIdle();
696
697 bool bFailed = false;
698 try
699 {
700 pValues[0].Value <<= sFilter;
701 uno::Reference< frame::XStorable > xTempStore( xTempDocShell->GetModel(), uno::UNO_QUERY);
702 xTempStore->storeToURL( sOutPath, aValues );
703 }
704 catch (const uno::Exception&)
705 {
706 bFailed = true;
707 }
708
709 if(bFailed)
710 {
711 std::unique_ptr<SwSaveWarningBox_Impl> xWarning(new SwSaveWarningBox_Impl(m_xDialog.get(), sOutPath));
712 if (RET_OK == xWarning->run())
713 sOutPath = xWarning->GetFileName();
714 else
715 {
716 xTempDocShell->DoClose();
717 m_xDialog->response(RET_OK);
718 return;
719 }
720 }
721 else
722 {
723 xTempDocShell->DoClose();
724 m_xDialog->response(RET_OK);
725 break;
726 }
727 }
728 }
729 if (xSaveMonitor)
730 xSaveMonitor->response(RET_OK);
731 ::osl::File::remove( sTargetTempURL );
732 }
733
734 m_xDialog->response(RET_OK);
735}
736
737IMPL_LINK(SwMMResultPrintDialog, PrinterChangeHdl_Impl, weld::ComboBox&, rBox, void)void SwMMResultPrintDialog::LinkStubPrinterChangeHdl_Impl(void
* instance, weld::ComboBox& data) { return static_cast<
SwMMResultPrintDialog *>(instance)->PrinterChangeHdl_Impl
(data); } void SwMMResultPrintDialog::PrinterChangeHdl_Impl(weld
::ComboBox& rBox)
1
Calling 'SwMMResultPrintDialog::PrinterChangeHdl_Impl'
738{
739 SwView* pView = ::GetActiveView();
740 const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem();
741 assert(xConfigItem)(static_cast <bool> (xConfigItem) ? void (0) : __assert_fail
("xConfigItem", "/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
, 741, __extension__ __PRETTY_FUNCTION__))
;
2
'?' condition is true
742 if (rBox.get_active() != -1)
3
Assuming the condition is true
4
Taking true branch
743 {
744 const QueueInfo* pInfo = Printer::GetQueueInfo( rBox.get_active_text(), false );
745
746 if( pInfo )
5
Assuming 'pInfo' is non-null
6
Taking true branch
747 {
748 if ( !m_pTempPrinter )
7
Taking false branch
749 {
750 m_pTempPrinter = VclPtr<Printer>::Create( *pInfo );
751 }
752 else
753 {
754 if( (m_pTempPrinter->GetName() != pInfo->GetPrinterName()) ||
755 (m_pTempPrinter->GetDriverName() != pInfo->GetDriver()) )
756 {
757 m_pTempPrinter.disposeAndClear();
8
Calling 'VclPtr::disposeAndClear'
758 m_pTempPrinter = VclPtr<Printer>::Create( *pInfo );
759 }
760 }
761 }
762 else if( ! m_pTempPrinter )
763 m_pTempPrinter = VclPtr<Printer>::Create();
764
765 m_xPrinterSettingsPB->set_sensitive(m_pTempPrinter->HasSupport(PrinterSupport::SetupDialog));
766 }
767 else
768 m_xPrinterSettingsPB->set_sensitive(false);
769
770 xConfigItem->SetSelectedPrinter(rBox.get_active_text());
771}
772
773IMPL_LINK_NOARG(SwMMResultPrintDialog, PrintHdl_Impl, weld::Button&, void)void SwMMResultPrintDialog::LinkStubPrintHdl_Impl(void * instance
, weld::Button& data) { return static_cast<SwMMResultPrintDialog
*>(instance)->PrintHdl_Impl(data); } void SwMMResultPrintDialog
::PrintHdl_Impl(__attribute__ ((unused)) weld::Button&)
774{
775 SwView* pView = ::GetActiveView();
776 std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem();
777 assert(xConfigItem)(static_cast <bool> (xConfigItem) ? void (0) : __assert_fail
("xConfigItem", "/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
, 777, __extension__ __PRETTY_FUNCTION__))
;
778 if(!xConfigItem->GetTargetView())
779 SwDBManager::PerformMailMerge(pView);
780
781 SwView* pTargetView = xConfigItem->GetTargetView();
782 assert(pTargetView)(static_cast <bool> (pTargetView) ? void (0) : __assert_fail
("pTargetView", "/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
, 782, __extension__ __PRETTY_FUNCTION__))
;
783
784 const sal_uInt32 nDocumentCount = xConfigItem->GetMergedDocumentCount();
785 sal_uInt32 nBegin = 0;
786 sal_uInt32 nEnd = nDocumentCount;
787
788 if (!m_xPrintAllRB->get_active())
789 {
790 nBegin = m_xFromNF->get_value() - 1;
791 nEnd = m_xToNF->get_value();
792 if(nEnd > nDocumentCount)
793 nEnd = nDocumentCount;
794 }
795
796 // If we skip autoinserted blanks, then the page numbers used in the print range string
797 // refer to the non-blank pages as they appear in the document (see tdf#89708).
798 const bool bIgnoreEmptyPages =
799 !pTargetView->GetDocShell()->GetDoc()->getIDocumentDeviceAccess().getPrintData().IsPrintEmptyPages();
800 const int nStartPage = documentStartPageNumber(xConfigItem.get(), nBegin, bIgnoreEmptyPages);
801 const int nEndPage = documentEndPageNumber(xConfigItem.get(), nEnd - 1, bIgnoreEmptyPages);
802
803 const OUString sPages(OUString::number(nStartPage) + "-" + OUString::number(nEndPage));
804
805 pTargetView->SetMailMergeConfigItem(xConfigItem);
806 if(m_pTempPrinter)
807 {
808 SfxPrinter *const pDocumentPrinter = pTargetView->GetWrtShell()
809 .getIDocumentDeviceAccess().getPrinter(true);
810 pDocumentPrinter->SetPrinterProps(m_pTempPrinter);
811 // this should be able to handle setting its own printer
812 pTargetView->SetPrinter(pDocumentPrinter);
813 }
814
815 SfxObjectShell* pObjSh = pTargetView->GetViewFrame()->GetObjectShell();
816 SfxGetpApp()->NotifyEvent(SfxEventHint(SfxEventHintId::SwMailMerge, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE1), pObjSh));
817
818 uno::Sequence < beans::PropertyValue > aProps( 2 );
819 aProps[0]. Name = "MonitorVisible";
820 aProps[0].Value <<= true;
821 aProps[1]. Name = "Pages";
822 aProps[1]. Value <<= sPages;
823
824 pTargetView->ExecPrint( aProps, false, true );
825 SfxGetpApp()->NotifyEvent(SfxEventHint(SfxEventHintId::SwMailMergeEnd, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE_END2), pObjSh));
826
827 m_xDialog->response(RET_OK);
828}
829
830IMPL_LINK_NOARG(SwMMResultPrintDialog, PrinterSetupHdl_Impl, weld::Button&, void)void SwMMResultPrintDialog::LinkStubPrinterSetupHdl_Impl(void
* instance, weld::Button& data) { return static_cast<
SwMMResultPrintDialog *>(instance)->PrinterSetupHdl_Impl
(data); } void SwMMResultPrintDialog::PrinterSetupHdl_Impl(__attribute__
((unused)) weld::Button&)
831{
832 if (m_pTempPrinter)
833 m_pTempPrinter->Setup(m_xDialog.get());
834}
835
836IMPL_LINK(SwMMResultEmailDialog, SendTypeHdl_Impl, weld::ComboBox&, rBox, void)void SwMMResultEmailDialog::LinkStubSendTypeHdl_Impl(void * instance
, weld::ComboBox& data) { return static_cast<SwMMResultEmailDialog
*>(instance)->SendTypeHdl_Impl(data); } void SwMMResultEmailDialog
::SendTypeHdl_Impl(weld::ComboBox& rBox)
837{
838 auto nDocType = rBox.get_active_id().toUInt32();
839 bool bEnable = MM_DOCTYPE_HTML4 != nDocType && MM_DOCTYPE_TEXT5 != nDocType;
840 bool bIsPDF = nDocType == MM_DOCTYPE_PDF2;
841 m_xSendAsPB->set_sensitive(bEnable);
842 m_xAttachmentGroup->set_sensitive(bEnable);
843 if(bEnable)
844 {
845 //add the correct extension
846 OUString sAttach(m_xAttachmentED->get_text());
847 //do nothing if the user has removed the name - the warning will come early enough
848 if (!sAttach.isEmpty())
849 {
850 sal_Int32 nTokenCount = comphelper::string::getTokenCount(sAttach, '.');
851 if( 2 > nTokenCount)
852 {
853 sAttach += ".";
854 ++nTokenCount;
855 }
856 sAttach = comphelper::string::setToken(sAttach, nTokenCount - 1, '.', lcl_GetExtensionForDocType( nDocType ));
857 m_xAttachmentED->set_text(sAttach);
858 }
859 }
860
861 if(bIsPDF)
862 {
863 m_xPasswordCB->set_sensitive(true);
864 m_xPasswordFT->set_sensitive(true);
865 m_xPasswordLB->set_sensitive(true);
866 CheckHdl(*m_xPasswordCB);
867 }
868 else
869 {
870 m_xPasswordCB->set_sensitive(false);
871 m_xPasswordFT->set_sensitive(false);
872 m_xPasswordLB->set_sensitive(false);
873 }
874}
875
876IMPL_LINK_NOARG(SwMMResultEmailDialog, SendAsHdl_Impl, weld::Button&, void)void SwMMResultEmailDialog::LinkStubSendAsHdl_Impl(void * instance
, weld::Button& data) { return static_cast<SwMMResultEmailDialog
*>(instance)->SendAsHdl_Impl(data); } void SwMMResultEmailDialog
::SendAsHdl_Impl(__attribute__ ((unused)) weld::Button&)
877{
878 SwMailBodyDialog aDlg(m_xDialog.get());
879 aDlg.SetBody(m_sBody);
880 if (RET_OK == aDlg.run())
881 {
882 m_sBody = aDlg.GetBody();
883 }
884}
885
886// Send documents as e-mail
887IMPL_LINK_NOARG(SwMMResultEmailDialog, SendDocumentsHdl_Impl, weld::Button&, void)void SwMMResultEmailDialog::LinkStubSendDocumentsHdl_Impl(void
* instance, weld::Button& data) { return static_cast<
SwMMResultEmailDialog *>(instance)->SendDocumentsHdl_Impl
(data); } void SwMMResultEmailDialog::SendDocumentsHdl_Impl(__attribute__
((unused)) weld::Button&)
888{
889 SwView* pView = ::GetActiveView();
890 std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem();
891 assert(xConfigItem)(static_cast <bool> (xConfigItem) ? void (0) : __assert_fail
("xConfigItem", "/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
, 891, __extension__ __PRETTY_FUNCTION__))
;
892 if (!xConfigItem->GetTargetView())
893 SwDBManager::PerformMailMerge(pView);
894
895 //get the composed document
896 SwView* pTargetView = xConfigItem->GetTargetView();
897 SAL_WARN_IF(!pTargetView, "sw.ui", "No TargetView in SwMailMergeConfigItem")do { if (true && (!pTargetView)) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "sw.ui")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "No TargetView in SwMailMergeConfigItem"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ui"
), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
":" "897" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "No TargetView in SwMailMergeConfigItem"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "No TargetView in SwMailMergeConfigItem"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ui"), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
":" "897" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "No TargetView in SwMailMergeConfigItem") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ui"), (
"/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
":" "897" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "No TargetView in SwMailMergeConfigItem"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "No TargetView in SwMailMergeConfigItem"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ui"), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
":" "897" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
898
899 if (xConfigItem->GetMailServer().isEmpty() ||
900 !SwMailMergeHelper::CheckMailAddress(xConfigItem->GetMailAddress()) )
901 {
902 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_xDialog.get(),
903 VclMessageType::Question, VclButtonsType::YesNo,
904 m_sConfigureMail));
905 xQueryBox->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL);
906 sal_uInt16 nRet = xQueryBox->run();
907 if (RET_YES == nRet )
908 {
909 SwView* pConfigView = pTargetView ? pTargetView : pView;
910 SfxAllItemSet aSet(pConfigView->GetPool());
911 SwMailConfigDlg aDlg(m_xDialog.get(), aSet);
912 nRet = aDlg.run();
913 }
914
915 if(nRet != RET_OK && nRet != RET_YES)
916 return; // back to the dialog
917
918 // SwMailConfigDlg writes mail merge email settings only to (global) config,
919 // so copy them to the existing config item
920 lcl_UpdateEmailSettingsFromGlobalConfig(*xConfigItem);
921 }
922 //add the documents
923 const sal_uInt32 nDocumentCount = xConfigItem->GetMergedDocumentCount();
924 sal_uInt32 nBegin = 0;
925 sal_uInt32 nEnd = nDocumentCount;
926 if (!m_xSendAllRB->get_active())
927 {
928 nBegin = static_cast< sal_Int32 >(m_xFromNF->get_value() - 1);
929 nEnd = static_cast< sal_Int32 >(m_xToNF->get_value());
930 if(nEnd > nDocumentCount)
931 nEnd = nDocumentCount;
932 }
933 bool bAsBody = false;
934 rtl_TextEncoding eEncoding = ::osl_getThreadTextEncoding();
935 SfxFilterContainer* pFilterContainer = SwDocShell::Factory().GetFilterContainer();
936 std::shared_ptr<const SfxFilter> pSfxFlt;
937 auto nDocType = m_xSendAsLB->get_active_id().toUInt32();
938 OUString sExtension = lcl_GetExtensionForDocType(nDocType);
939 switch( nDocType )
940 {
941 case MM_DOCTYPE_OOO1:
942 {
943 //Make sure we don't pick e.g. the flat xml filter
944 //for this format
945 pSfxFlt = pFilterContainer->GetFilter4FilterName(
946 "writer8",
947 SfxFilterFlags::EXPORT);
948 }
949 break;
950 case MM_DOCTYPE_PDF2:
951 {
952 pSfxFlt = pFilterContainer->GetFilter4FilterName(
953 "writer_pdf_Export",
954 SfxFilterFlags::EXPORT);
955 }
956 break;
957 case MM_DOCTYPE_WORD3:
958 {
959 //the method SwIOSystemGetFilterOfFormat( ) returns the template filter
960 //because it uses the same user data :-(
961 SfxFilterMatcher aMatcher( pFilterContainer->GetName() );
962 SfxFilterMatcherIter aIter( aMatcher );
963 std::shared_ptr<const SfxFilter> pFilter = aIter.First();
964 while ( pFilter )
965 {
966 if( pFilter->GetUserData() == FILTER_WW8"CWW8" && pFilter->CanExport() )
967 {
968 pSfxFlt = pFilter;
969 break;
970 }
971 pFilter = aIter.Next();
972 }
973
974 }
975 break;
976 case MM_DOCTYPE_HTML4:
977 {
978 bAsBody = true;
979 SvxHtmlOptions& rHtmlOptions = SvxHtmlOptions::Get();
980 eEncoding = rHtmlOptions.GetTextEncoding();
981 }
982 break;
983 case MM_DOCTYPE_TEXT5:
984 {
985 bAsBody = true;
986 pSfxFlt = pFilterContainer->GetFilter4FilterName(
987 "Text (encoded)", SfxFilterFlags::EXPORT);
988 }
989 break;
990 }
991 if(!pSfxFlt)
992 pSfxFlt = pFilterContainer->GetFilter4Extension(sExtension, SfxFilterFlags::EXPORT);
993
994 if(!pSfxFlt)
995 {
996 m_xDialog->response(RET_OK);
997 return;
998 }
999 OUString sMimeType = pSfxFlt->GetMimeType();
1000
1001 if (m_xSubjectED->get_text().isEmpty())
1002 {
1003 std::unique_ptr<SwSendQueryBox_Impl> xQuery(new SwSendQueryBox_Impl(m_xDialog.get(), "SubjectDialog",
1004 "modules/swriter/ui/subjectdialog.ui"));
1005 xQuery->SetIsEmptyTextAllowed(true);
1006 xQuery->SetValue("");
1007 if(RET_OK == xQuery->run())
1008 {
1009 if (!xQuery->GetValue().isEmpty())
1010 m_xSubjectED->set_text(xQuery->GetValue());
1011 }
1012 else
1013 return; // back to the dialog
1014 }
1015 if(!bAsBody && m_xAttachmentED->get_text().isEmpty())
1016 {
1017 std::unique_ptr<SwSendQueryBox_Impl> xQuery(new SwSendQueryBox_Impl(m_xDialog.get(), "AttachNameDialog",
1018 "modules/swriter/ui/attachnamedialog.ui"));
1019 xQuery->SetIsEmptyTextAllowed(false);
1020 if (RET_OK == xQuery->run())
1021 {
1022 OUString sAttach(xQuery->GetValue());
1023 sal_Int32 nTokenCount = comphelper::string::getTokenCount(sAttach, '.');
1024 if (2 > nTokenCount)
1025 {
1026 sAttach += ".";
1027 ++nTokenCount;
1028 }
1029 sAttach = comphelper::string::setToken(sAttach, nTokenCount - 1, '.', lcl_GetExtensionForDocType(
1030 m_xSendAsLB->get_active_id().toUInt32()));
1031 m_xAttachmentED->set_text(sAttach);
1032 }
1033 else
1034 return; // back to the dialog
1035 }
1036
1037 OUString sEMailColumn = m_xMailToLB->get_active_text();
1038 OSL_ENSURE( !sEMailColumn.isEmpty(), "No email column selected")do { if (true && (!(!sEMailColumn.isEmpty()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
":" "1038" ": "), "%s", "No email column selected"); } } while
(false)
;
1039 Reference< sdbcx::XColumnsSupplier > xColsSupp( xConfigItem->GetResultSet(), UNO_QUERY);
1040 Reference < container::XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : nullptr;
1041 if(sEMailColumn.isEmpty() || !xColAccess.is() || !xColAccess->hasByName(sEMailColumn))
1042 {
1043 m_xDialog->response(RET_OK);
1044 return;
1045 }
1046
1047 OUString sPasswordColumn = m_xPasswordLB->get_active_text();
1048 OSL_ENSURE( !sPasswordColumn.isEmpty(), "No password column selected")do { if (true && (!(!sPasswordColumn.isEmpty()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
":" "1048" ": "), "%s", "No password column selected"); } } while
(false)
;
1049 if(sPasswordColumn.isEmpty() || !xColAccess.is() || !xColAccess->hasByName(sPasswordColumn))
1050 {
1051 m_xDialog->response(RET_OK);
1052 return;
1053 }
1054
1055 OUString sFilterOptions;
1056 if(MM_DOCTYPE_TEXT5 == nDocType)
1057 {
1058 SwAsciiOptions aOpt;
1059 sal_uInt16 nAppScriptType = SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() );
1060 sal_uInt16 nWhich = GetWhichOfScript( RES_CHRATR_LANGUAGE, nAppScriptType);
1061 aOpt.SetLanguage( static_cast<const SvxLanguageItem&>(pTargetView->GetWrtShell().
1062 GetDefault( nWhich )).GetLanguage());
1063 aOpt.SetParaFlags( LINEEND_CR );
1064 aOpt.WriteUserData( sFilterOptions );
1065 }
1066 else if(MM_DOCTYPE_HTML4 == nDocType)
1067 {
1068 sFilterOptions = "EmbedImages";
1069 }
1070 OUString sTargetTempURL = URIHelper::SmartRel2Abs(
1071 INetURLObject(), utl::TempFile::CreateTempName(),
1072 URIHelper::GetMaybeFileHdl());
1073 std::shared_ptr<const SfxFilter> pTargetSfxFlt = SwIoSystem::GetFilterOfFormat(
1074 FILTER_XML"CXML",
1075 SwDocShell::Factory().GetFilterContainer() );
1076
1077 uno::Sequence< beans::PropertyValue > aValues(1);
1078 beans::PropertyValue* pValues = aValues.getArray();
1079 pValues[0].Name = "FilterName";
1080 pValues[0].Value <<= pTargetSfxFlt->GetFilterName();
1081
1082 uno::Reference< frame::XStorable > xStore( pTargetView->GetDocShell()->GetModel(), uno::UNO_QUERY);
1083 xStore->storeToURL( sTargetTempURL, aValues );
1084
1085 //create the send dialog
1086 vcl::Window* pParent = Application::GetDefDialogParent();
1087 std::shared_ptr<SwSendMailDialog> xDlg = std::make_shared<SwSendMailDialog>(pParent ? pParent->GetFrameWeld() : nullptr, *xConfigItem);
1088
1089 xDlg->StartSend(nEnd - nBegin);
1090 weld::DialogController::runAsync(xDlg, [](sal_Int32 /*nResult*/){});
1091
1092 //help to force painting the dialog
1093 //TODO/CLEANUP
1094 //predetermined breaking point
1095 Application::Reschedule( true );
1096 m_xDialog->response(RET_OK);
1097 for(sal_uInt32 nDoc = nBegin; nDoc < nEnd; ++nDoc)
1098 {
1099 SwDocMergeInfo& rInfo = xConfigItem->GetDocumentMergeInfo(nDoc);
1100
1101 //now extract a document from the target document
1102 // the shell will be closed at the end, but it is more safe to use SfxObjectShellLock here
1103 SfxObjectShellLock xTempDocShell( new SwDocShell( SfxObjectCreateMode::STANDARD ) );
1104 xTempDocShell->DoInitNew();
1105 SfxViewFrame* pTempFrame = SfxViewFrame::LoadHiddenDocument( *xTempDocShell, SFX_INTERFACE_NONE );
1106 SwView* pTempView = static_cast<SwView*>( pTempFrame->GetViewShell() );
1107 pTargetView->GetWrtShell().StartAction();
1108 SwgReaderOption aOpt;
1109 aOpt.SetTextFormats( true );
1110 aOpt.SetFrameFormats( true );
1111 aOpt.SetPageDescs( true );
1112 aOpt.SetNumRules( true );
1113 aOpt.SetMerge( false );
1114 pTempView->GetDocShell()->LoadStylesFromFile(
1115 sTargetTempURL, aOpt, true );
1116 pTempView->GetDocShell()->GetDoc()->ReplaceCompatibilityOptions( *pTargetView->GetDocShell()->GetDoc());
1117 pTempView->GetDocShell()->GetDoc()->ReplaceDefaults( *pTargetView->GetDocShell()->GetDoc());
1118 pTempView->GetDocShell()->GetDoc()->ReplaceDocumentProperties( *pTargetView->GetDocShell()->GetDoc(), true );
1119 pTargetView->GetWrtShell().PastePages(
1120 pTempView->GetWrtShell(), documentStartPageNumber(xConfigItem.get(), nDoc, false),
1121 documentEndPageNumber(xConfigItem.get(), nDoc, false));
1122 pTargetView->GetWrtShell().EndAction();
1123
1124 //then save it
1125 SfxStringItem aName(SID_FILE_NAME(5000 + 507),
1126 URIHelper::SmartRel2Abs(
1127 INetURLObject(), utl::TempFile::CreateTempName(),
1128 URIHelper::GetMaybeFileHdl()) );
1129
1130 {
1131 bool withFilterOptions = MM_DOCTYPE_TEXT5 == nDocType || MM_DOCTYPE_HTML4 == nDocType;
1132 bool withPasswordOptions = m_xPasswordCB->get_active();
1133
1134 sal_Int32 nTarget = xConfigItem->MoveResultSet(rInfo.nDBRow);
1135 OSL_ENSURE( nTarget == rInfo.nDBRow, "row of current document could not be selected")do { if (true && (!(nTarget == rInfo.nDBRow))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
":" "1135" ": "), "%s", "row of current document could not be selected"
); } } while (false)
;
1136 OUString sPassword = lcl_GetColumnValueOf(sPasswordColumn, xColAccess);
1137
1138 sal_Int32 nOptionCount = (withFilterOptions && withPasswordOptions) ? 4 : withPasswordOptions ? 3 : withFilterOptions ? 2 : 1;
1139 sal_Int32 nOpt = 0;
1140 uno::Sequence< beans::PropertyValue > aFilterValues(nOptionCount);
1141 beans::PropertyValue* pFilterValues = aFilterValues.getArray();
1142
1143 pFilterValues[nOpt].Name = "FilterName";
1144 pFilterValues[nOpt].Value <<= pSfxFlt->GetFilterName();
1145
1146 if(withFilterOptions)
1147 {
1148 nOpt++;
1149 pFilterValues[nOpt].Name = "FilterOptions";
1150 pFilterValues[nOpt].Value <<= sFilterOptions;
1151 }
1152
1153 if(withPasswordOptions)
1154 {
1155 nOpt++;
1156 pFilterValues[nOpt].Name = "EncryptFile";
1157 pFilterValues[nOpt].Value <<= true;
1158 nOpt++;
1159 pFilterValues[nOpt].Name = "DocumentOpenPassword";
1160 pFilterValues[nOpt].Value <<= sPassword;
1161 }
1162
1163 uno::Reference< frame::XStorable > xTempStore( pTempView->GetDocShell()->GetModel(), uno::UNO_QUERY);
1164 xTempStore->storeToURL( aName.GetValue(), aFilterValues );
1165 }
1166 xTempDocShell->DoClose();
1167
1168 sal_Int32 nTarget = xConfigItem->MoveResultSet(rInfo.nDBRow);
1169 OSL_ENSURE( nTarget == rInfo.nDBRow, "row of current document could not be selected")do { if (true && (!(nTarget == rInfo.nDBRow))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
":" "1169" ": "), "%s", "row of current document could not be selected"
); } } while (false)
;
1170 OSL_ENSURE( !sEMailColumn.isEmpty(), "No email column selected")do { if (true && (!(!sEMailColumn.isEmpty()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
":" "1170" ": "), "%s", "No email column selected"); } } while
(false)
;
1171 OUString sEMail = lcl_GetColumnValueOf(sEMailColumn, xColAccess);
1172 SwMailDescriptor aDesc;
1173 aDesc.sEMail = sEMail;
1174 OUStringBuffer sBody;
1175 if(bAsBody)
1176 {
1177 {
1178 //read in the temporary file and use it as mail body
1179 SfxMedium aMedium( aName.GetValue(), StreamMode::READ);
1180 SvStream* pInStream = aMedium.GetInStream();
1181 if(pInStream)
1182 pInStream->SetStreamCharSet( eEncoding );
1183 else
1184 {
1185 OSL_FAIL("no output file created?")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/ui/dbui/mmresultdialogs.cxx"
":" "1185" ": "), "%s", "no output file created?"); } } while
(false)
;
1186 continue;
1187 }
1188 OString sLine;
1189 bool bDone = pInStream->ReadLine( sLine );
1190 while ( bDone )
1191 {
1192 sBody.append( OStringToOUString(sLine, eEncoding) );
1193 sBody.append("\n");
1194 bDone = pInStream->ReadLine( sLine );
1195 }
1196 }
1197 //remove the temporary file
1198 SWUnoHelper::UCB_DeleteFile( aName.GetValue() );
1199 }
1200 else
1201 {
1202 sBody = m_sBody;
1203 aDesc.sAttachmentURL = aName.GetValue();
1204 OUString sAttachment(m_xAttachmentED->get_text());
1205 sal_Int32 nTokenCount = comphelper::string::getTokenCount(sAttachment, '.');
1206 if (2 > nTokenCount)
1207 {
1208 sAttachment += ".";
1209 sAttachment = comphelper::string::setToken(sAttachment, nTokenCount, '.', sExtension);
1210 }
1211 else if (sAttachment.getToken( nTokenCount - 1, '.') != sExtension)
1212 sAttachment += sExtension;
1213 aDesc.sAttachmentName = sAttachment;
1214 aDesc.sMimeType = sMimeType;
1215
1216 if (xConfigItem->IsGreetingLine(true))
1217 {
1218 OUString sNameColumn = xConfigItem->GetAssignedColumn(MM_PART_LASTNAME2);
1219 OUString sName = lcl_GetColumnValueOf(sNameColumn, xColAccess);
1220 OUString sGreeting;
1221 if(!sName.isEmpty() && xConfigItem->IsIndividualGreeting(true))
1222 {
1223 OUString sGenderColumn = xConfigItem->GetAssignedColumn(MM_PART_GENDER13);
1224 const OUString& sFemaleValue = xConfigItem->GetFemaleGenderValue();
1225 OUString sGenderValue = lcl_GetColumnValueOf(sGenderColumn, xColAccess);
1226 SwMailMergeConfigItem::Gender eGenderType = sGenderValue == sFemaleValue ?
1227 SwMailMergeConfigItem::FEMALE :
1228 SwMailMergeConfigItem::MALE;
1229
1230 sGreeting = SwAddressPreview::FillData(
1231 xConfigItem->GetGreetings(eGenderType)
1232 [xConfigItem->GetCurrentGreeting(eGenderType)],
1233 *xConfigItem);
1234 }
1235 else
1236 {
1237 sGreeting =
1238 xConfigItem->GetGreetings(SwMailMergeConfigItem::NEUTRAL)
1239 [xConfigItem->GetCurrentGreeting(SwMailMergeConfigItem::NEUTRAL)];
1240
1241 }
1242 sGreeting += "\n";
1243 sBody.insert(0, sGreeting);
1244 }
1245 }
1246 aDesc.sBodyContent = sBody.makeStringAndClear();
1247 if(MM_DOCTYPE_HTML4 == nDocType)
1248 {
1249 aDesc.sBodyMimeType = "text/html; charset=" +
1250 OUString::createFromAscii(rtl_getBestMimeCharsetFromTextEncoding( eEncoding ));
1251 }
1252 else
1253 aDesc.sBodyMimeType = "text/plain; charset=UTF-8; format=flowed";
1254
1255 aDesc.sSubject = m_xSubjectED->get_text();
1256 aDesc.sCC = m_sCC;
1257 aDesc.sBCC = m_sBCC;
1258 xDlg->AddDocument( aDesc );
1259 //help to force painting the dialog
1260 Application::Reschedule( true );
1261 //stop creating of data when dialog has been closed
1262 if (!xDlg->getDialog()->get_visible())
1263 {
1264 break;
1265 }
1266 }
1267 xDlg->EnableDestruction();
1268 ::osl::File::remove( sTargetTempURL );
1269}
1270
1271/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx

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#ifndef INCLUDED_VCL_PTR_HXX
21#define INCLUDED_VCL_PTR_HXX
22
23#include <sal/config.h>
24
25#include <rtl/ref.hxx>
26
27#include <utility>
28#include <type_traits>
29
30#ifdef DBG_UTIL
31#ifndef _WIN32
32#include <vcl/vclmain.hxx>
33#endif
34#endif
35
36class VclReferenceBase;
37
38namespace vcl::detail {
39
40template<typename>
41constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; }
42
43template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase(
44 int (*)[sizeof(T)])
45{ return std::is_base_of<VclReferenceBase, T>::value; }
46
47} // namespace vcl::detail
48
49/**
50 * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
51 *
52 * For more details on the design please see vcl/README.lifecycle
53 *
54 * @param reference_type must be a subclass of vcl::Window
55 */
56template <class reference_type>
57class VclPtr
58{
59 static_assert(
60 vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>(
61 nullptr),
62 "template argument type must be derived from VclReferenceBase");
63
64 ::rtl::Reference<reference_type> m_rInnerRef;
65
66public:
67 /** Constructor...
68 */
69 VclPtr()
70 : m_rInnerRef()
71 {}
72
73 /** Constructor...
74 */
75 VclPtr (reference_type * pBody)
76 : m_rInnerRef(pBody)
77 {}
78
79 /** Constructor... that doesn't take a ref.
80 */
81 VclPtr (reference_type * pBody, __sal_NoAcquire)
82 : m_rInnerRef(pBody, SAL_NO_ACQUIRE)
83 {}
84
85 /** Up-casting conversion constructor: Copies interface reference.
86
87 Does not work for up-casts to ambiguous bases. For the special case of
88 up-casting to Reference< XInterface >, see the corresponding conversion
89 operator.
90
91 @param rRef another reference
92 */
93 template< class derived_type >
94 VclPtr(
95 const VclPtr< derived_type > & rRef,
96 typename std::enable_if<
97 std::is_base_of<reference_type, derived_type>::value, int>::type
98 = 0 )
99 : m_rInnerRef( static_cast<reference_type*>(rRef) )
100 {
101 }
102
103#if defined(DBG_UTIL) && !defined(_WIN32)
104 virtual ~VclPtr()
105 {
106 assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain
::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 106, __extension__ __PRETTY_FUNCTION__))
;
107 // We can be one of the intermediate counts, but if we are the last
108 // VclPtr keeping this object alive, then something forgot to call dispose().
109 assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
110 && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
;
111 }
112 VclPtr(VclPtr const &) = default;
113 VclPtr(VclPtr &&) = default;
114 VclPtr & operator =(VclPtr const &) = default;
115 VclPtr & operator =(VclPtr &&) = default;
116#endif
117
118 /**
119 * A construction helper for VclPtr. Since VclPtr types are created
120 * with a reference-count of one - to help fit into the existing
121 * code-flow; this helps us to construct them easily.
122 *
123 * For more details on the design please see vcl/README.lifecycle
124 *
125 * @tparam reference_type must be a subclass of vcl::Window
126 */
127 template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg)
128 {
129 return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE );
130 }
131
132 /** Probably most common used: handle->someBodyOp().
133 */
134 reference_type * operator->() const
135 {
136 return m_rInnerRef.get();
137 }
138
139 /** Get the body. Can be used instead of operator->().
140 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
141 are the same.
142 */
143 reference_type * get() const
144 {
145 return m_rInnerRef.get();
146 }
147
148 void set(reference_type *pBody)
149 {
150 m_rInnerRef.set(pBody);
151 }
152
153 void reset(reference_type *pBody)
154 {
155 m_rInnerRef.set(pBody);
156 }
157
158 /** Up-casting copy assignment operator.
159
160 Does not work for up-casts to ambiguous bases.
161
162 @param rRef another reference
163 */
164 template<typename derived_type>
165 typename std::enable_if<
166 std::is_base_of<reference_type, derived_type>::value,
167 VclPtr &>::type
168 operator =(VclPtr<derived_type> const & rRef)
169 {
170 m_rInnerRef.set(rRef.get());
171 return *this;
172 }
173
174 VclPtr & operator =(reference_type * pBody)
175 {
176 m_rInnerRef.set(pBody);
177 return *this;
178 }
179
180 operator reference_type * () const
181 {
182 return m_rInnerRef.get();
183 }
184
185 explicit operator bool () const
186 {
187 return m_rInnerRef.get() != nullptr;
188 }
189
190 void clear()
191 {
192 m_rInnerRef.clear();
193 }
194
195 void reset()
196 {
197 m_rInnerRef.clear();
198 }
199
200 void disposeAndClear()
201 {
202 // hold it alive for the lifetime of this method
203 ::rtl::Reference<reference_type> aTmp(m_rInnerRef);
204 m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
9
Calling 'Reference::clear'
16
Returning; memory was released
205 if (aTmp.get()) {
17
Calling 'Reference::get'
206 aTmp->disposeOnce();
207 }
208 }
209
210 /** Needed to place VclPtr's into STL collection.
211 */
212 bool operator< (const VclPtr<reference_type> & handle) const
213 {
214 return (m_rInnerRef < handle.m_rInnerRef);
215 }
216}; // class VclPtr
217
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
261 return !(p1 == p2);
262}
263
264/**
265 * A construction helper for a temporary VclPtr. Since VclPtr types
266 * are created with a reference-count of one - to help fit into
267 * the existing code-flow; this helps us to construct them easily.
268 * see also VclPtr::Create and ScopedVclPtr
269 *
270 * For more details on the design please see vcl/README.lifecycle
271 *
272 * @param reference_type must be a subclass of vcl::Window
273 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
278 template<typename... Arg> VclPtrInstance(Arg &&... arg)
279 : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
280 {
281 }
282
283 /**
284 * Override and disallow this, to prevent people accidentally calling it and actually
285 * getting VclPtr::Create and getting a naked VclPtr<> instance
286 */
287 template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete;
288};
289
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
294 /** Constructor...
295 */
296 ScopedVclPtr()
297 : VclPtr<reference_type>()
298 {}
299
300 /** Constructor
301 */
302 ScopedVclPtr (reference_type * pBody)
303 : VclPtr<reference_type>(pBody)
304 {}
305
306 /** Copy constructor...
307 */
308 ScopedVclPtr (const VclPtr<reference_type> & handle)
309 : VclPtr<reference_type>(handle)
310 {}
311
312 /**
313 Assignment that releases the last reference.
314 */
315 void disposeAndReset(reference_type *pBody)
316 {
317 if (pBody != this->get()) {
318 VclPtr<reference_type>::disposeAndClear();
319 VclPtr<reference_type>::set(pBody);
320 }
321 }
322
323 /**
324 Assignment that releases the last reference.
325 */
326 ScopedVclPtr<reference_type>& operator = (reference_type * pBody)
327 {
328 disposeAndReset(pBody);
329 return *this;
330 }
331
332 /** Up-casting conversion constructor: Copies interface reference.
333
334 Does not work for up-casts to ambiguous bases. For the special case of
335 up-casting to Reference< XInterface >, see the corresponding conversion
336 operator.
337
338 @param rRef another reference
339 */
340 template< class derived_type >
341 ScopedVclPtr(
342 const VclPtr< derived_type > & rRef,
343 typename std::enable_if<
344 std::is_base_of<reference_type, derived_type>::value, int>::type
345 = 0 )
346 : VclPtr<reference_type>( rRef )
347 {
348 }
349
350 /** Up-casting assignment operator.
351
352 Does not work for up-casts to ambiguous bases.
353
354 @param rRef another VclPtr
355 */
356 template<typename derived_type>
357 typename std::enable_if<
358 std::is_base_of<reference_type, derived_type>::value,
359 ScopedVclPtr &>::type
360 operator =(VclPtr<derived_type> const & rRef)
361 {
362 disposeAndReset(rRef.get());
363 return *this;
364 }
365
366 /**
367 * Override and disallow this, to prevent people accidentally calling it and actually
368 * getting VclPtr::Create and getting a naked VclPtr<> instance
369 */
370 template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete;
371
372 ~ScopedVclPtr()
373 {
374 VclPtr<reference_type>::disposeAndClear();
375 assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get(
) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // make sure there are no lingering references
376 }
377
378private:
379 // Most likely we don't want this default copy-constructor.
380 ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete;
381 // And certainly we don't want a default assignment operator.
382 ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete;
383 // And disallow reset as that doesn't call disposeAndClear on the original reference
384 void reset() = delete;
385 void reset(reference_type *pBody) = delete;
386
387protected:
388 ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
389 : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
390 {}
391};
392
393/**
394 * A construction helper for ScopedVclPtr. Since VclPtr types are created
395 * with a reference-count of one - to help fit into the existing
396 * code-flow; this helps us to construct them easily.
397 *
398 * For more details on the design please see vcl/README.lifecycle
399 *
400 * @param reference_type must be a subclass of vcl::Window
401 */
402#if defined _MSC_VER
403#pragma warning(push)
404#pragma warning(disable: 4521) // " multiple copy constructors specified"
405#endif
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
410 template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
411 : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
412 {
413 }
414
415 /**
416 * Override and disallow this, to prevent people accidentally calling it and actually
417 * getting VclPtr::Create and getting a naked VclPtr<> instance
418 */
419 template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete;
420
421private:
422 // Prevent the above perfect forwarding ctor from hijacking (accidental)
423 // attempts at ScopedVclPtrInstance copy construction (where the hijacking
424 // would typically lead to somewhat obscure error messages); both non-const
425 // and const variants are needed here, as the ScopedVclPtr base class has a
426 // const--variant copy ctor, so the implicitly declared copy ctor for
427 // ScopedVclPtrInstance would also be the const variant, so non-const copy
428 // construction attempts would be hijacked by the perfect forwarding ctor;
429 // but if we only declared a non-const variant here, the const variant would
430 // no longer be implicitly declared (as there would already be an explicitly
431 // declared copy ctor), so const copy construction attempts would then be
432 // hijacked by the perfect forwarding ctor:
433 ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete;
434 ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete;
435};
436#if defined _MSC_VER
437#pragma warning(pop)
438#endif
439
440#endif // INCLUDED_VCL_PTR_HXX
441
442/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/ref.hxx

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#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody)
113 m_pBody->release();
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody
9.1
Field 'm_pBody' is non-null
9.1
Field 'm_pBody' is non-null
9.1
Field 'm_pBody' is non-null
9.1
Field 'm_pBody' is non-null
)
10
Taking true branch
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
11
Calling 'VclReferenceBase::release'
15
Returning; memory was released
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
18
Use of memory after it is freed
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.hxx

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_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
12
Assuming the condition is true
13
Taking true branch
40 delete this;
14
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif