Add a comment to clarify what kind of inputs the class handles
[LibreOffice.git] / sw / source / uibase / dbui / mailmergehelper.cxx
blob00932257d5957aca5cc7c17dacc6918b68dfe945
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <swtypes.hxx>
21 #include <mailmergehelper.hxx>
22 #include <mmconfigitem.hxx>
23 #include <docsh.hxx>
24 #include <sfx2/filedlghelper.hxx>
25 #include <sfx2/docfile.hxx>
26 #include <com/sun/star/sdbc/SQLException.hpp>
27 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
28 #include <com/sun/star/sdb/XColumn.hpp>
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
31 #include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
32 #include <com/sun/star/mail/MailServiceProvider.hpp>
33 #include <com/sun/star/mail/XSmtpService.hpp>
34 #include <comphelper/processfactory.hxx>
35 #include <o3tl/safeint.hxx>
36 #include <utility>
37 #include <vcl/event.hxx>
38 #include <vcl/settings.hxx>
39 #include <vcl/weldutils.hxx>
40 #include <comphelper/diagnose_ex.hxx>
41 #include <o3tl/string_view.hxx>
43 #include <sfx2/passwd.hxx>
45 #include <dbui.hrc>
46 #include <strings.hrc>
48 using namespace ::com::sun::star;
49 using namespace ::com::sun::star::uno;
50 using namespace ::com::sun::star::container;
51 using namespace ::com::sun::star::sdb;
52 using namespace ::com::sun::star::sdbc;
53 using namespace ::com::sun::star::sdbcx;
55 namespace SwMailMergeHelper
58 OUString CallSaveAsDialog(weld::Window* pParent, OUString& rFilter)
60 ::sfx2::FileDialogHelper aDialog( ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION,
61 FileDialogFlags::NONE,
62 SwDocShell::Factory().GetFactoryName(), SfxFilterFlags::NONE, SfxFilterFlags::NONE, pParent);
63 aDialog.SetContext(sfx2::FileDialogHelper::WriterMailMergeSaveAs);
65 if (aDialog.Execute()!=ERRCODE_NONE)
67 return OUString();
70 rFilter = aDialog.GetRealFilter();
71 uno::Reference < ui::dialogs::XFilePicker3 > xFP = aDialog.GetFilePicker();
72 return xFP->getSelectedFiles().getConstArray()[0];
76 simple address check: check for '@'
77 for at least one '.' after the '@',
78 for at least one character before the dot
79 and for at least two characters after the dot
81 bool CheckMailAddress( std::u16string_view aMailAddress )
83 const size_t nPosAt = aMailAddress.find('@');
84 if (nPosAt == std::u16string_view::npos || aMailAddress.rfind('@')!=nPosAt)
85 return false;
86 const size_t nPosDot = aMailAddress.find('.', nPosAt);
87 return !(nPosDot==std::u16string_view::npos || nPosDot-nPosAt<2 || aMailAddress.size()-nPosDot<3);
90 uno::Reference< mail::XSmtpService > ConnectToSmtpServer(
91 SwMailMergeConfigItem const & rConfigItem,
92 uno::Reference< mail::XMailService >& rxInMailService,
93 const OUString& rInMailServerPassword,
94 const OUString& rOutMailServerPassword,
95 weld::Window* pDialogParentWindow )
97 uno::Reference< mail::XSmtpService > xSmtpServer;
98 const uno::Reference< uno::XComponentContext >& xContext = ::comphelper::getProcessComponentContext();
99 try
101 uno::Reference< mail::XMailServiceProvider > xMailServiceProvider(
102 mail::MailServiceProvider::create( xContext ) );
103 xSmtpServer.set(xMailServiceProvider->create(mail::MailServiceType_SMTP), uno::UNO_QUERY);
105 uno::Reference< mail::XConnectionListener> xConnectionListener(new SwConnectionListener);
107 if(rConfigItem.IsAuthentication() && rConfigItem.IsSMTPAfterPOP())
109 uno::Reference< mail::XMailService > xInMailService =
110 xMailServiceProvider->create(
111 rConfigItem.IsInServerPOP() ?
112 mail::MailServiceType_POP3 : mail::MailServiceType_IMAP);
113 //authenticate at the POP or IMAP server first
114 OUString sPasswd = rConfigItem.GetInServerPassword();
115 if(!rInMailServerPassword.isEmpty())
116 sPasswd = rInMailServerPassword;
117 uno::Reference<mail::XAuthenticator> xAuthenticator =
118 new SwAuthenticator(
119 rConfigItem.GetInServerUserName(),
120 sPasswd,
121 pDialogParentWindow);
123 xInMailService->addConnectionListener(xConnectionListener);
124 //check connection
125 uno::Reference< uno::XCurrentContext> xConnectionContext =
126 new SwConnectionContext(
127 rConfigItem.GetInServerName(),
128 rConfigItem.GetInServerPort(),
129 u"Insecure"_ustr);
130 xInMailService->connect(xConnectionContext, xAuthenticator);
131 rxInMailService = std::move(xInMailService);
133 uno::Reference< mail::XAuthenticator> xAuthenticator;
134 if(rConfigItem.IsAuthentication() &&
135 !rConfigItem.IsSMTPAfterPOP() &&
136 !rConfigItem.GetMailUserName().isEmpty())
138 OUString sPasswd = rConfigItem.GetMailPassword();
139 if(!rOutMailServerPassword.isEmpty())
140 sPasswd = rOutMailServerPassword;
141 xAuthenticator =
142 new SwAuthenticator(rConfigItem.GetMailUserName(),
143 sPasswd,
144 pDialogParentWindow);
146 else
147 xAuthenticator = new SwAuthenticator();
148 //just to check if the server exists
149 xSmtpServer->getSupportedConnectionTypes();
150 //check connection
152 uno::Reference< uno::XCurrentContext> xConnectionContext =
153 new SwConnectionContext(
154 rConfigItem.GetMailServer(),
155 rConfigItem.GetMailPort(),
156 rConfigItem.IsSecureConnection() ? u"Ssl"_ustr : u"Insecure"_ustr );
157 xSmtpServer->connect(xConnectionContext, xAuthenticator);
158 rxInMailService = xSmtpServer;
160 catch (const uno::Exception&)
162 TOOLS_WARN_EXCEPTION( "sw", "");
164 return xSmtpServer;
167 } //namespace
169 struct SwAddressPreview_Impl
171 std::vector< OUString > aAddresses;
172 sal_uInt16 nRows;
173 sal_uInt16 nColumns;
174 sal_uInt16 nSelectedAddress;
175 bool bEnableScrollBar;
177 SwAddressPreview_Impl() :
178 nRows(1),
179 nColumns(1),
180 nSelectedAddress(0),
181 bEnableScrollBar(false)
186 OUString SwAddressPreview::FillData(
187 const OUString& rAddress,
188 SwMailMergeConfigItem const & rConfigItem,
189 const Sequence< OUString>* pAssignments)
191 //find the column names in the address string (with name assignment!) and
192 //exchange the placeholder (like <Firstname>) with the database content
193 //unassigned columns are expanded to <not assigned>
194 Reference< XColumnsSupplier > xColsSupp( rConfigItem.GetResultSet(), UNO_QUERY);
195 Reference <XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : nullptr;
196 Sequence< OUString> aAssignment = pAssignments ?
197 *pAssignments :
198 rConfigItem.GetColumnAssignment(
199 rConfigItem.GetCurrentDBData() );
200 const OUString* pAssignment = aAssignment.getConstArray();
201 const std::vector<std::pair<OUString, int>>& rDefHeaders = rConfigItem.GetDefaultAddressHeaders();
203 bool bIncludeCountry = rConfigItem.IsIncludeCountry();
204 const OUString& rExcludeCountry = rConfigItem.GetExcludeCountry();
205 bool bSpecialReplacementForCountry = (!bIncludeCountry || !rExcludeCountry.isEmpty());
206 OUString sCountryColumn;
207 if( bSpecialReplacementForCountry )
209 sCountryColumn = rDefHeaders[MM_PART_COUNTRY].first;
210 Sequence< OUString> aSpecialAssignment =
211 rConfigItem.GetColumnAssignment( rConfigItem.GetCurrentDBData() );
212 if(aSpecialAssignment.getLength() > MM_PART_COUNTRY && aSpecialAssignment[MM_PART_COUNTRY].getLength())
213 sCountryColumn = aSpecialAssignment[MM_PART_COUNTRY];
216 SwAddressIterator aIter(rAddress);
217 OUStringBuffer sAddress;
218 while(aIter.HasMore())
220 SwMergeAddressItem aItem = aIter.Next();
221 if(aItem.bIsColumn)
223 //get the default column name
225 //find the appropriate assignment
226 OUString sConvertedColumn = aItem.sText;
227 auto nSize = std::min(sal_uInt32(rDefHeaders.size()), sal_uInt32(aAssignment.getLength()));
228 for(sal_uInt32 nColumn = 0; nColumn < nSize; ++nColumn)
230 if (rDefHeaders[nColumn].first == aItem.sText &&
231 !pAssignment[nColumn].isEmpty())
233 sConvertedColumn = pAssignment[nColumn];
234 break;
237 if(!sConvertedColumn.isEmpty() &&
238 xColAccess.is() &&
239 xColAccess->hasByName(sConvertedColumn))
241 //get the content and exchange it in the address string
242 Any aCol = xColAccess->getByName(sConvertedColumn);
243 Reference< XColumn > xColumn;
244 aCol >>= xColumn;
245 if(xColumn.is())
249 OUString sReplace = xColumn->getString();
251 if( bSpecialReplacementForCountry && sCountryColumn == sConvertedColumn )
253 if( !rExcludeCountry.isEmpty() && sReplace != rExcludeCountry )
254 aItem.sText = sReplace;
255 else
256 aItem.sText.clear();
258 else
260 aItem.sText = sReplace;
263 catch (const sdbc::SQLException&)
265 TOOLS_WARN_EXCEPTION( "sw", "");
269 else
271 aItem.sText = "<" + SwResId(STR_NOTASSIGNED) + ">";
275 sAddress.append(aItem.sText);
277 return sAddress.makeStringAndClear();
280 SwAddressPreview::SwAddressPreview(std::unique_ptr<weld::ScrolledWindow> xWindow)
281 : m_pImpl(new SwAddressPreview_Impl())
282 , m_xVScrollBar(std::move(xWindow))
284 m_xVScrollBar->connect_vadjustment_changed(LINK(this, SwAddressPreview, ScrollHdl));
287 SwAddressPreview::~SwAddressPreview()
291 IMPL_LINK_NOARG(SwAddressPreview, ScrollHdl, weld::ScrolledWindow&, void)
293 Invalidate();
296 void SwAddressPreview::AddAddress(const OUString& rAddress)
298 m_pImpl->aAddresses.push_back(rAddress);
299 UpdateScrollBar();
302 void SwAddressPreview::SetAddress(const OUString& rAddress)
304 m_pImpl->aAddresses.clear();
305 m_pImpl->aAddresses.push_back(rAddress);
306 m_xVScrollBar->set_vpolicy(VclPolicyType::NEVER);
307 Invalidate();
310 sal_uInt16 SwAddressPreview::GetSelectedAddress()const
312 OSL_ENSURE(m_pImpl->nSelectedAddress < m_pImpl->aAddresses.size(), "selection invalid");
313 return m_pImpl->nSelectedAddress;
316 void SwAddressPreview::SelectAddress(sal_uInt16 nSelect)
318 OSL_ENSURE(m_pImpl->nSelectedAddress < m_pImpl->aAddresses.size(), "selection invalid");
319 m_pImpl->nSelectedAddress = nSelect;
320 // now make it visible...
321 sal_uInt16 nSelectRow = nSelect / m_pImpl->nColumns;
322 sal_uInt16 nStartRow = m_xVScrollBar->vadjustment_get_value();
323 if( (nSelectRow < nStartRow) || (nSelectRow >= (nStartRow + m_pImpl->nRows) ))
324 m_xVScrollBar->vadjustment_set_value(nSelectRow);
327 void SwAddressPreview::Clear()
329 m_pImpl->aAddresses.clear();
330 m_pImpl->nSelectedAddress = 0;
331 UpdateScrollBar();
334 void SwAddressPreview::ReplaceSelectedAddress(const OUString& rNew)
336 m_pImpl->aAddresses[m_pImpl->nSelectedAddress] = rNew;
337 Invalidate();
340 void SwAddressPreview::RemoveSelectedAddress()
342 m_pImpl->aAddresses.erase(m_pImpl->aAddresses.begin() + m_pImpl->nSelectedAddress);
343 if(m_pImpl->nSelectedAddress)
344 --m_pImpl->nSelectedAddress;
345 UpdateScrollBar();
346 Invalidate();
349 void SwAddressPreview::SetLayout(sal_uInt16 nRows, sal_uInt16 nColumns)
351 m_pImpl->nRows = nRows;
352 m_pImpl->nColumns = nColumns;
353 UpdateScrollBar();
356 void SwAddressPreview::EnableScrollBar()
358 m_pImpl->bEnableScrollBar = true;
361 void SwAddressPreview::UpdateScrollBar()
363 if (m_pImpl->nColumns)
365 sal_uInt16 nResultingRows = o3tl::narrowing<sal_uInt16>(m_pImpl->aAddresses.size() + m_pImpl->nColumns - 1) / m_pImpl->nColumns;
366 ++nResultingRows;
367 auto nValue = m_xVScrollBar->vadjustment_get_value();
368 if (nValue > nResultingRows)
369 nValue = nResultingRows;
370 m_xVScrollBar->set_vpolicy(m_pImpl->bEnableScrollBar && nResultingRows > m_pImpl->nRows ? VclPolicyType::ALWAYS : VclPolicyType::NEVER);
371 m_xVScrollBar->vadjustment_configure(nValue, 0, nResultingRows, 1, 10, m_pImpl->nRows);
375 void SwAddressPreview::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
377 const StyleSettings& rSettings = rRenderContext.GetSettings().GetStyleSettings();
378 rRenderContext.SetFillColor(rSettings.GetWindowColor());
379 rRenderContext.SetLineColor(COL_TRANSPARENT);
380 rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), GetOutputSizePixel()));
381 Color aPaintColor(IsEnabled() ? rSettings.GetWindowTextColor() : rSettings.GetDisableColor());
382 rRenderContext.SetLineColor(aPaintColor);
384 weld::SetPointFont(rRenderContext, GetDrawingArea()->get_font());
385 vcl::Font aFont(rRenderContext.GetFont());
386 aFont.SetColor(aPaintColor);
387 rRenderContext.SetFont(aFont);
389 Size aSize(GetOutputSizePixel());
390 sal_uInt16 nStartRow = 0;
391 if (m_xVScrollBar->get_vpolicy() != VclPolicyType::NEVER)
393 aSize.AdjustWidth(-m_xVScrollBar->get_scroll_thickness());
394 nStartRow = m_xVScrollBar->vadjustment_get_value();
396 Size aPartSize(aSize.Width() / m_pImpl->nColumns,
397 aSize.Height() / m_pImpl->nRows);
398 aPartSize.AdjustWidth( -2 );
399 aPartSize.AdjustHeight( -2 );
401 sal_uInt16 nAddress = nStartRow * m_pImpl->nColumns;
402 const sal_uInt16 nNumAddresses = o3tl::narrowing<sal_uInt16>(m_pImpl->aAddresses.size());
403 for (sal_uInt16 nRow = 0; nRow < m_pImpl->nRows ; ++nRow)
405 for (sal_uInt16 nCol = 0; nCol < m_pImpl->nColumns; ++nCol)
407 if (nAddress >= nNumAddresses)
408 break;
409 Point aPos(nCol * aPartSize.Width(),
410 nRow * aPartSize.Height());
411 aPos.Move(1, 1);
412 bool bIsSelected = nAddress == m_pImpl->nSelectedAddress;
413 if ((m_pImpl->nColumns * m_pImpl->nRows) == 1)
414 bIsSelected = false;
415 OUString adr(m_pImpl->aAddresses[nAddress]);
416 DrawText_Impl(rRenderContext, adr, aPos, aPartSize, bIsSelected);
417 ++nAddress;
420 rRenderContext.SetClipRegion();
423 bool SwAddressPreview::MouseButtonDown( const MouseEvent& rMEvt )
425 if (rMEvt.IsLeft() && m_pImpl->nRows && m_pImpl->nColumns)
427 //determine the selected address
428 const Point& rMousePos = rMEvt.GetPosPixel();
429 Size aSize(GetOutputSizePixel());
430 Size aPartSize( aSize.Width()/m_pImpl->nColumns, aSize.Height()/m_pImpl->nRows );
431 sal_uInt32 nRow = rMousePos.Y() / aPartSize.Height() ;
432 if (m_xVScrollBar->get_vpolicy() != VclPolicyType::NEVER)
434 nRow += m_xVScrollBar->vadjustment_get_value();
436 sal_uInt32 nCol = rMousePos.X() / aPartSize.Width();
437 sal_uInt32 nSelect = nRow * m_pImpl->nColumns + nCol;
439 if( nSelect < m_pImpl->aAddresses.size() &&
440 m_pImpl->nSelectedAddress != o3tl::narrowing<sal_uInt16>(nSelect))
442 m_pImpl->nSelectedAddress = o3tl::narrowing<sal_uInt16>(nSelect);
443 m_aSelectHdl.Call(nullptr);
445 Invalidate();
447 return true;
450 bool SwAddressPreview::KeyInput( const KeyEvent& rKEvt )
452 sal_uInt16 nKey = rKEvt.GetKeyCode().GetCode();
453 bool bHandled = false;
454 if (m_pImpl->nRows && m_pImpl->nColumns)
456 sal_uInt32 nSelectedRow = m_pImpl->nSelectedAddress / m_pImpl->nColumns;
457 sal_uInt32 nSelectedColumn = m_pImpl->nSelectedAddress - (nSelectedRow * m_pImpl->nColumns);
458 switch(nKey)
460 case KEY_UP:
461 if(nSelectedRow)
462 --nSelectedRow;
463 bHandled = true;
464 break;
465 case KEY_DOWN:
466 if(m_pImpl->aAddresses.size() > o3tl::make_unsigned(m_pImpl->nSelectedAddress + m_pImpl->nColumns))
467 ++nSelectedRow;
468 bHandled = true;
469 break;
470 case KEY_LEFT:
471 if(nSelectedColumn)
472 --nSelectedColumn;
473 bHandled = true;
474 break;
475 case KEY_RIGHT:
476 if(nSelectedColumn < o3tl::make_unsigned(m_pImpl->nColumns - 1) &&
477 m_pImpl->aAddresses.size() - 1 > m_pImpl->nSelectedAddress )
478 ++nSelectedColumn;
479 bHandled = true;
480 break;
482 sal_uInt32 nSelect = nSelectedRow * m_pImpl->nColumns + nSelectedColumn;
483 if( nSelect < m_pImpl->aAddresses.size() &&
484 m_pImpl->nSelectedAddress != o3tl::narrowing<sal_uInt16>(nSelect))
486 m_pImpl->nSelectedAddress = o3tl::narrowing<sal_uInt16>(nSelect);
487 m_aSelectHdl.Call(nullptr);
488 Invalidate();
491 return bHandled;
494 void SwAddressPreview::DrawText_Impl(vcl::RenderContext& rRenderContext, std::u16string_view rAddress,
495 const Point& rTopLeft, const Size& rSize, bool bIsSelected)
497 rRenderContext.SetClipRegion(vcl::Region(tools::Rectangle(rTopLeft, rSize)));
498 if (bIsSelected)
500 //selection rectangle
501 rRenderContext.SetFillColor(COL_TRANSPARENT);
502 rRenderContext.DrawRect(tools::Rectangle(rTopLeft, rSize));
504 sal_Int32 nHeight = GetTextHeight();
505 Point aStart = rTopLeft;
506 //put it away from the border
507 aStart.Move(2, 2);
508 sal_Int32 nPos = 0;
511 rRenderContext.DrawText(aStart, OUString(o3tl::getToken(rAddress, 0, '\n', nPos)));
512 aStart.AdjustY(nHeight );
514 while (nPos >= 0);
517 SwMergeAddressItem SwAddressIterator::Next()
519 //currently the string may either start with a '<' then it's a column
520 //otherwise it's simple text maybe containing a return
521 SwMergeAddressItem aRet;
522 if(!m_sAddress.isEmpty())
524 if(m_sAddress[0] == '<')
526 aRet.bIsColumn = true;
527 sal_Int32 nClose = m_sAddress.indexOf('>');
528 OSL_ENSURE(nClose != -1, "closing '>' not found");
529 if( nClose != -1 )
531 aRet.sText = m_sAddress.copy(1, nClose - 1);
532 m_sAddress = m_sAddress.copy(nClose + 1);
534 else
536 aRet.sText = m_sAddress.copy(1, 1);
537 m_sAddress = m_sAddress.copy(1);
540 else
542 sal_Int32 nOpen = m_sAddress.indexOf('<');
543 sal_Int32 nReturn = m_sAddress.indexOf('\n');
544 if(nReturn == 0)
546 aRet.bIsReturn = true;
547 aRet.sText = "\n";
548 m_sAddress = m_sAddress.copy(1);
550 else if(-1 == nOpen && -1 == nReturn)
552 aRet.sText = m_sAddress;
553 m_sAddress.clear();
555 else
557 if (nOpen == -1)
558 nOpen = m_sAddress.getLength();
559 if (nReturn == -1)
560 nReturn = m_sAddress.getLength();
561 sal_Int32 nTarget = std::min(nOpen, nReturn);
562 aRet.sText = m_sAddress.copy(0, nTarget);
563 m_sAddress = m_sAddress.copy(nTarget);
567 return aRet;
571 SwAuthenticator::~SwAuthenticator()
575 OUString SwAuthenticator::getUserName( )
577 return m_aUserName;
580 OUString SwAuthenticator::getPassword( )
582 if(!m_aUserName.isEmpty() && m_aPassword.isEmpty() && m_pParentWindow)
584 SfxPasswordDialog aPasswdDlg(m_pParentWindow);
585 aPasswdDlg.SetMinLen(0);
586 if (RET_OK == aPasswdDlg.run())
587 m_aPassword = aPasswdDlg.GetPassword();
589 return m_aPassword;
592 SwConnectionContext::SwConnectionContext(
593 OUString aMailServer, sal_Int16 nPort,
594 OUString aConnectionType) :
595 m_sMailServer(std::move(aMailServer)),
596 m_nPort(nPort),
597 m_sConnectionType(std::move(aConnectionType))
601 SwConnectionContext::~SwConnectionContext()
605 uno::Any SwConnectionContext::getValueByName( const OUString& rName )
607 uno::Any aRet;
608 if( rName == "ServerName" )
609 aRet <<= m_sMailServer;
610 else if( rName == "Port" )
611 aRet <<= static_cast<sal_Int32>(m_nPort);
612 else if( rName == "ConnectionType" )
613 aRet <<= m_sConnectionType;
614 return aRet;
617 SwConnectionListener::~SwConnectionListener()
621 void SwConnectionListener::connected(const lang::EventObject& /*aEvent*/)
625 void SwConnectionListener::disconnected(const lang::EventObject& /*aEvent*/)
629 void SwConnectionListener::disposing(const lang::EventObject& /*aEvent*/)
633 SwMailTransferable::SwMailTransferable(OUString aBody, OUString aMimeType) :
634 m_aMimeType(std::move( aMimeType )),
635 m_sBody(std::move( aBody )),
636 m_bIsBody( true )
640 SwMailTransferable::SwMailTransferable(OUString aURL,
641 OUString aName, OUString aMimeType) :
642 m_aMimeType(std::move( aMimeType )),
643 m_aURL(std::move(aURL)),
644 m_aName(std::move( aName )),
645 m_bIsBody( false )
649 SwMailTransferable::~SwMailTransferable()
653 uno::Any SwMailTransferable::getTransferData( const datatransfer::DataFlavor& /*aFlavor*/ )
655 uno::Any aRet;
656 if( m_bIsBody )
657 aRet <<= m_sBody;
658 else
660 Sequence<sal_Int8> aData;
661 SfxMedium aMedium( m_aURL, StreamMode::STD_READ );
662 SvStream* pStream = aMedium.GetInStream();
663 if ( aMedium.GetErrorCode() == ERRCODE_NONE && pStream)
665 aData.realloc(pStream->TellEnd());
666 pStream->Seek(0);
667 sal_Int8 * pData = aData.getArray();
668 pStream->ReadBytes( pData, aData.getLength() );
670 aRet <<= aData;
672 return aRet;
675 uno::Sequence< datatransfer::DataFlavor > SwMailTransferable::getTransferDataFlavors( )
677 datatransfer::DataFlavor aRet;
678 aRet.MimeType = m_aMimeType;
679 if( m_bIsBody )
681 aRet.DataType = cppu::UnoType<OUString>::get();
683 else
685 aRet.HumanPresentableName = m_aName;
686 aRet.DataType = cppu::UnoType<uno::Sequence<sal_Int8>>::get();
688 return { std::move(aRet) };
691 sal_Bool SwMailTransferable::isDataFlavorSupported(
692 const datatransfer::DataFlavor& aFlavor )
694 return (aFlavor.MimeType == m_aMimeType);
697 uno::Reference< beans::XPropertySetInfo > SwMailTransferable::getPropertySetInfo( )
699 return uno::Reference< beans::XPropertySetInfo >();
702 void SwMailTransferable::setPropertyValue( const OUString& , const uno::Any& )
706 uno::Any SwMailTransferable::getPropertyValue( const OUString& rPropertyName )
708 uno::Any aRet;
709 if ( rPropertyName == "URL" )
710 aRet <<= m_aURL;
711 return aRet;
714 void SwMailTransferable::addPropertyChangeListener(
715 const OUString&, const uno::Reference< beans::XPropertyChangeListener >& )
719 void SwMailTransferable::removePropertyChangeListener(
720 const OUString&,
721 const uno::Reference< beans::XPropertyChangeListener >& )
725 void SwMailTransferable::addVetoableChangeListener(
726 const OUString&,
727 const uno::Reference< beans::XVetoableChangeListener >& )
731 void SwMailTransferable::removeVetoableChangeListener(
732 const OUString& ,
733 const uno::Reference< beans::XVetoableChangeListener >& )
737 SwMailMessage::SwMailMessage()
741 SwMailMessage::~SwMailMessage()
745 OUString SwMailMessage::getSenderName()
747 return m_sSenderName;
750 OUString SwMailMessage::getSenderAddress()
752 return m_sSenderAddress;
755 OUString SwMailMessage::getReplyToAddress()
757 return m_sReplyToAddress;
760 void SwMailMessage::setReplyToAddress( const OUString& _replytoaddress )
762 m_sReplyToAddress = _replytoaddress;
765 OUString SwMailMessage::getSubject()
767 return m_sSubject;
770 void SwMailMessage::setSubject( const OUString& _subject )
772 m_sSubject = _subject;
775 uno::Reference< datatransfer::XTransferable > SwMailMessage::getBody()
777 return m_xBody;
780 void SwMailMessage::setBody(
781 const uno::Reference< datatransfer::XTransferable >& rBody )
783 m_xBody = rBody;
786 void SwMailMessage::addRecipient( const OUString& rRecipientAddress )
788 m_aRecipients.realloc(m_aRecipients.getLength() + 1);
789 m_aRecipients.getArray()[m_aRecipients.getLength() - 1] = rRecipientAddress;
792 void SwMailMessage::addCcRecipient( const OUString& rRecipientAddress )
794 m_aCcRecipients.realloc(m_aCcRecipients.getLength() + 1);
795 m_aCcRecipients.getArray()[m_aCcRecipients.getLength() - 1] = rRecipientAddress;
799 void SwMailMessage::addBccRecipient( const OUString& rRecipientAddress )
801 m_aBccRecipients.realloc(m_aBccRecipients.getLength() + 1);
802 m_aBccRecipients.getArray()[m_aBccRecipients.getLength() - 1] = rRecipientAddress;
805 uno::Sequence< OUString > SwMailMessage::getRecipients( )
807 return m_aRecipients;
810 uno::Sequence< OUString > SwMailMessage::getCcRecipients( )
812 return m_aCcRecipients;
815 uno::Sequence< OUString > SwMailMessage::getBccRecipients( )
817 return m_aBccRecipients;
820 void SwMailMessage::addAttachment( const mail::MailAttachment& rMailAttachment )
822 m_aAttachments.realloc(m_aAttachments.getLength() + 1);
823 m_aAttachments.getArray()[m_aAttachments.getLength() - 1] = rMailAttachment;
826 uno::Sequence< mail::MailAttachment > SwMailMessage::getAttachments( )
828 return m_aAttachments;
831 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */