LibreOffice Module sw (master)  1
mmaddressblockpage.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include "mmaddressblockpage.hxx"
21 #include <mailmergewizard.hxx>
22 #include <swtypes.hxx>
23 #include "addresslistdialog.hxx"
24 #include <editeng/eeitem.hxx>
25 #include <o3tl/safeint.hxx>
26 #include <svl/grabbagitem.hxx>
27 #include <svl/itemset.hxx>
28 #include <vcl/event.hxx>
29 #include <vcl/svapp.hxx>
30 #include <vcl/weld.hxx>
31 #include <vcl/transfer.hxx>
32 #include <mmconfigitem.hxx>
33 #include <com/sun/star/container/XNameAccess.hpp>
34 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
35 #include <com/sun/star/sdbc/SQLException.hpp>
36 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
37 #include <com/sun/star/sdb/XColumn.hpp>
38 #include <comphelper/sequence.hxx>
39 #include <comphelper/string.hxx>
40 #include <tools/diagnose_ex.h>
41 
42 #include <vector>
43 #include <strings.hrc>
44 #include <mmaddressblockpage.hrc>
45 #include <helpids.h>
46 
47 using namespace svt;
48 using namespace ::com::sun::star;
49 using namespace ::com::sun::star::container;
50 using namespace ::com::sun::star::sdb;
51 using namespace ::com::sun::star::sdbc;
52 using namespace ::com::sun::star::sdbcx;
53 
55  : vcl::OWizardPage(pPage, pWizard, "modules/swriter/ui/mmaddressblockpage.ui", "MMAddressBlockPage")
56  , m_pWizard(pWizard)
57  , m_xAddressListPB(m_xBuilder->weld_button("addresslist"))
58  , m_xCurrentAddressFI(m_xBuilder->weld_label("currentaddress"))
59  , m_xStep2(m_xBuilder->weld_container("step2"))
60  , m_xStep3(m_xBuilder->weld_container("step3"))
61  , m_xStep4(m_xBuilder->weld_container("step4"))
62  , m_xSettingsFI(m_xBuilder->weld_label("settingsft"))
63  , m_xAddressCB(m_xBuilder->weld_check_button("address"))
64  , m_xSettingsPB(m_xBuilder->weld_button("settings"))
65  , m_xHideEmptyParagraphsCB(m_xBuilder->weld_check_button("hideempty"))
66  , m_xAssignPB(m_xBuilder->weld_button("assign"))
67  , m_xDocumentIndexFI(m_xBuilder->weld_label("documentindex"))
68  , m_xPrevSetIB(m_xBuilder->weld_button("prev"))
69  , m_xNextSetIB(m_xBuilder->weld_button("next"))
70  , m_xDifferentlist(m_xBuilder->weld_button("differentlist"))
71  , m_xSettings(new SwAddressPreview(m_xBuilder->weld_scrolled_window("settingspreviewwin", true)))
72  , m_xPreview(new SwAddressPreview(m_xBuilder->weld_scrolled_window("addresspreviewwin", true)))
73  , m_xSettingsWIN(new weld::CustomWeld(*m_xBuilder, "settingspreview", *m_xSettings))
74  , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, "addresspreview", *m_xPreview))
75 {
76  m_xSettingsWIN->set_size_request(m_xDifferentlist->get_approximate_digit_width() * 40,
77  m_xDifferentlist->get_text_height() * 6);
78  m_xPreviewWIN->set_size_request(m_xDifferentlist->get_approximate_digit_width() * 44,
79  m_xDifferentlist->get_text_height() * 6);
80  m_sChangeAddress = m_xDifferentlist->get_label();
81  m_sDocument = m_xDocumentIndexFI->get_label();
82 
84  m_xAddressListPB->connect_clicked(LINK(this, SwMailMergeAddressBlockPage, AddressListHdl_Impl));
85  m_xSettingsPB->connect_clicked(LINK(this, SwMailMergeAddressBlockPage, SettingsHdl_Impl));
86  m_xAssignPB->connect_clicked(LINK(this, SwMailMergeAddressBlockPage, AssignHdl_Impl ));
87  m_xAddressCB->connect_toggled(LINK(this, SwMailMergeAddressBlockPage, AddressBlockHdl_Impl));
88  m_xSettings->SetSelectHdl(LINK(this, SwMailMergeAddressBlockPage, AddressBlockSelectHdl_Impl));
89  m_xHideEmptyParagraphsCB->connect_toggled(LINK(this, SwMailMergeAddressBlockPage, HideParagraphsHdl_Impl));
90 
91  Link<weld::Button&,void> aLink = LINK(this, SwMailMergeAddressBlockPage, InsertDataHdl_Impl);
92  m_xPrevSetIB->connect_clicked(aLink);
93  m_xNextSetIB->connect_clicked(aLink);
94 
95  // lock in preferred size including current address line
96  Size aSize1(m_xContainer->get_preferred_size());
97 
98  OUString sOrigLabel = m_xAddressListPB->get_label();
100  Size aSize2(m_xContainer->get_preferred_size());
101  m_xAddressListPB->set_label(sOrigLabel);
102 
103  m_xCurrentAddressFI->hide();
104 
105  m_xContainer->set_size_request(std::max(aSize1.Width(), aSize2.Width()),
106  std::max(aSize1.Height(), aSize2.Height()));
107 }
108 
110 {
111  m_xPreviewWIN.reset();
112  m_xSettingsWIN.reset();
113  m_xPreview.reset();
114  m_xSettings.reset();
115 }
116 
118 {
119  return m_pWizard->GetConfigItem().GetResultSet().is();
120 }
121 
123 {
125  bool bIsLetter = rConfigItem.IsOutputToLetter();
126 
127  //no address block is created for e-Mail
128  m_xStep2->set_visible(bIsLetter);
129  m_xStep3->set_visible(bIsLetter);
130  m_xStep4->set_visible(bIsLetter);
131 
132  if (!bIsLetter)
133  return;
134 
135  m_xHideEmptyParagraphsCB->set_active( rConfigItem.IsHideEmptyParagraphs() );
136  m_xDocumentIndexFI->set_label(m_sDocument.replaceFirst("%1", "1"));
137 
138  m_xSettings->Clear();
139  const uno::Sequence< OUString> aBlocks =
141  for(const auto& rAddress : aBlocks)
142  m_xSettings->AddAddress(rAddress);
143  m_xSettings->SelectAddress(static_cast<sal_uInt16>(rConfigItem.GetCurrentAddressBlockIndex()));
144  m_xAddressCB->set_active(rConfigItem.IsAddressBlock());
145  AddressBlockHdl_Impl(*m_xAddressCB);
146  m_xSettings->SetLayout(1, 2);
147  InsertDataHdl(nullptr);
148 }
149 
151 {
152  return ::vcl::WizardTypes::eTravelForward != _eReason || m_pWizard->GetConfigItem().GetResultSet().is();
153 }
154 
156 {
157  try
158  {
159  SwAddressListDialog aAddrDialog(this);
160  if (RET_OK == aAddrDialog.run())
161  {
162  SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
163  rConfigItem.SetCurrentConnection(
164  aAddrDialog.GetSource(),
165  aAddrDialog.GetConnection(),
166  aAddrDialog.GetColumnsSupplier(),
167  aAddrDialog.GetDBData());
168  OUString sFilter = aAddrDialog.GetFilter();
169  rConfigItem.SetFilter( sFilter );
170  InsertDataHdl(nullptr);
171  GetWizard()->UpdateRoadmap();
172  GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
173  }
174  }
175  catch (const uno::Exception& e)
176  {
177  TOOLS_WARN_EXCEPTION("sw", "");
178  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_pWizard->getDialog(),
179  VclMessageType::Warning, VclButtonsType::Ok, e.Message));
180  xBox->run();
181  }
182 }
183 
185 {
186  SwSelectAddressBlockDialog aDlg(m_pWizard->getDialog(), m_pWizard->GetConfigItem());
187  SwMailMergeConfigItem& rConfig = m_pWizard->GetConfigItem();
188  aDlg.SetAddressBlocks(rConfig.GetAddressBlocks(), m_xSettings->GetSelectedAddress());
189  aDlg.SetSettings(rConfig.IsIncludeCountry(), rConfig.GetExcludeCountry());
190  if (aDlg.run() == RET_OK)
191  {
192  //the dialog provides the selected address at the first position!
193  const uno::Sequence< OUString> aBlocks = aDlg.GetAddressBlocks();
194  rConfig.SetAddressBlocks(aBlocks);
195  m_xSettings->Clear();
196  for(const auto& rAddress : aBlocks)
197  m_xSettings->AddAddress(rAddress);
198  m_xSettings->SelectAddress(0);
199  m_xSettings->Invalidate(); // #i40408
200  rConfig.SetCountrySettings(aDlg.IsIncludeCountry(), aDlg.GetCountry());
201  InsertDataHdl(nullptr);
202  }
203  GetWizard()->UpdateRoadmap();
204  GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
205 }
206 
208 {
209  SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
210  const sal_uInt16 nSel = m_xSettings->GetSelectedAddress();
211  const uno::Sequence< OUString> aBlocks = rConfigItem.GetAddressBlocks();
212  SwAssignFieldsDialog aDlg(m_pWizard->getDialog(), m_pWizard->GetConfigItem(), aBlocks[nSel], true);
213  if(RET_OK == aDlg.run())
214  {
215  //preview update
216  InsertDataHdl(nullptr);
217  GetWizard()->UpdateRoadmap();
218  GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
219  }
220 }
221 
222 void SwMailMergeAddressBlockPage::EnableAddressBlock(bool bAll, bool bSelective)
223 {
224  m_xSettingsFI->set_sensitive(bAll);
225  m_xAddressCB->set_sensitive(bAll);
226  bSelective &= bAll;
227  m_xHideEmptyParagraphsCB->set_sensitive(bSelective);
228  m_xSettingsWIN->set_sensitive(bSelective);
229  m_xSettingsPB->set_sensitive(bSelective);
230  m_xStep3->set_sensitive(bSelective);
231  m_xStep4->set_sensitive(bSelective);
232 }
233 
234 IMPL_LINK(SwMailMergeAddressBlockPage, AddressBlockHdl_Impl, weld::ToggleButton&, rBox, void)
235 {
236  EnableAddressBlock(rBox.get_sensitive(), rBox.get_active());
237  SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
238  rConfigItem.SetAddressBlock(m_xAddressCB->get_active());
239  m_pWizard->UpdateRoadmap();
240  GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
241 }
242 
243 IMPL_LINK_NOARG(SwMailMergeAddressBlockPage, AddressBlockSelectHdl_Impl, LinkParamNone*, void)
244 {
245  const sal_uInt16 nSel = m_xSettings->GetSelectedAddress();
246  const uno::Sequence< OUString> aBlocks =
247  m_pWizard->GetConfigItem().GetAddressBlocks();
248  m_xPreview->SetAddress(SwAddressPreview::FillData(aBlocks[nSel],
249  m_pWizard->GetConfigItem()));
250  m_pWizard->GetConfigItem().SetCurrentAddressBlockIndex( nSel );
251  GetWizard()->UpdateRoadmap();
252  GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
253 }
254 
255 IMPL_LINK(SwMailMergeAddressBlockPage, HideParagraphsHdl_Impl, weld::ToggleButton&, rBox, void)
256 {
257  SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
258  rConfigItem.SetHideEmptyParagraphs(rBox.get_active());
259 }
260 
262 {
263  //if no pButton is given, the first set has to be pre-set
265  std::unique_ptr<weld::WaitObject> xWaitObj(new weld::WaitObject(m_pWizard->getDialog()));
266  if(!pButton)
267  {
268  rConfig.GetResultSet();
269  }
270  else
271  {
272  bool bNext = pButton == m_xNextSetIB.get();
273  sal_Int32 nPos = rConfig.GetResultSetPosition();
274  rConfig.MoveResultSet( bNext ? ++nPos : --nPos);
275  }
276  xWaitObj.reset();
277  sal_Int32 nPos = rConfig.GetResultSetPosition();
278  bool bEnable = true;
279  if(nPos < 1)
280  {
281  bEnable = false;
282  nPos = 1;
283  }
284  else
285  {
286  //if output type is letter
287  if (m_xSettings->IsVisible())
288  {
289  //Fill data into preview
290  const sal_uInt16 nSel = m_xSettings->GetSelectedAddress();
291  const uno::Sequence< OUString> aBlocks =
293  m_xPreview->SetAddress(SwAddressPreview::FillData(aBlocks[nSel], rConfig));
294  }
295  }
296  m_xPrevSetIB->set_sensitive(bEnable);
297  m_xDocumentIndexFI->set_label(m_sDocument.replaceFirst("%1", OUString::number(nPos)));
298 
299  GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
300  bool bHasResultSet = rConfig.GetResultSet().is();
301  m_xCurrentAddressFI->set_visible(bHasResultSet);
302  if(bHasResultSet)
303  {
304  m_xCurrentAddressFI->set_label(m_sCurrentAddress.replaceFirst("%1", rConfig.GetCurrentDBData().sDataSource));
306  }
307  EnableAddressBlock(bHasResultSet, m_xAddressCB->get_active());
308 }
309 
310 IMPL_LINK(SwMailMergeAddressBlockPage, InsertDataHdl_Impl, weld::Button&, rButton, void)
311 {
312  InsertDataHdl(&rButton);
313 }
314 
316  : SfxDialogController(pParent, "modules/swriter/ui/selectblockdialog.ui", "SelectBlockDialog")
317  , m_rConfig(rConfig)
318  , m_xPreview(new SwAddressPreview(m_xBuilder->weld_scrolled_window("previewwin", true)))
319  , m_xNewPB(m_xBuilder->weld_button("new"))
320  , m_xCustomizePB(m_xBuilder->weld_button("edit"))
321  , m_xDeletePB(m_xBuilder->weld_button("delete"))
322  , m_xNeverRB(m_xBuilder->weld_radio_button("never"))
323  , m_xAlwaysRB(m_xBuilder->weld_radio_button("always"))
324  , m_xDependentRB(m_xBuilder->weld_radio_button("dependent"))
325  , m_xCountryED(m_xBuilder->weld_entry("country"))
326  , m_xPreviewWin(new weld::CustomWeld(*m_xBuilder, "preview", *m_xPreview))
327 {
328  m_xPreviewWin->set_size_request(m_xCountryED->get_approximate_digit_width() * 45,
329  m_xCountryED->get_text_height() * 12);
330 
331  Link<weld::Button&,void> aCustomizeHdl = LINK(this, SwSelectAddressBlockDialog, NewCustomizeHdl_Impl);
332  m_xNewPB->connect_clicked(aCustomizeHdl);
333  m_xCustomizePB->connect_clicked(aCustomizeHdl);
334 
335  m_xDeletePB->connect_clicked(LINK(this, SwSelectAddressBlockDialog, DeleteHdl_Impl));
336 
337  Link<weld::ToggleButton&,void> aLk = LINK(this, SwSelectAddressBlockDialog, IncludeHdl_Impl);
338  m_xNeverRB->connect_toggled(aLk);
339  m_xAlwaysRB->connect_toggled(aLk);
340  m_xDependentRB->connect_toggled(aLk);
341  m_xPreview->SetLayout(2, 2);
342  m_xPreview->EnableScrollBar();
343 }
344 
346 {
347 }
348 
349 void SwSelectAddressBlockDialog::SetAddressBlocks(const uno::Sequence< OUString>& rBlocks,
350  sal_uInt16 nSelectedAddress)
351 {
352  m_aAddressBlocks = rBlocks;
353  for (const auto& rAddressBlock : std::as_const(m_aAddressBlocks))
354  m_xPreview->AddAddress(rAddressBlock);
355  m_xPreview->SelectAddress(nSelectedAddress);
356 }
357 
358 // return the address blocks and put the selected one to the first position
359 const uno::Sequence< OUString >& SwSelectAddressBlockDialog::GetAddressBlocks()
360 {
361  //put the selected block to the first position
362  const sal_Int32 nSelect = static_cast<sal_Int32>(m_xPreview->GetSelectedAddress());
363  if(nSelect)
364  {
365  uno::Sequence< OUString >aTemp = m_aAddressBlocks;
366  aTemp[0] = m_aAddressBlocks[nSelect];
367  std::copy(m_aAddressBlocks.begin(), std::next(m_aAddressBlocks.begin(), nSelect), std::next(aTemp.begin()));
368  std::copy(std::next(m_aAddressBlocks.begin(), nSelect + 1), m_aAddressBlocks.end(), std::next(aTemp.begin(), nSelect + 1));
369  m_aAddressBlocks = aTemp;
370  }
371  return m_aAddressBlocks;
372 }
373 
375  bool bIsCountry, const OUString& rCountry)
376 {
377  weld::RadioButton *pActive = m_xNeverRB.get();
378  if(bIsCountry)
379  {
380  pActive = !rCountry.isEmpty() ? m_xDependentRB.get() : m_xAlwaysRB.get();
381  m_xCountryED->set_text(rCountry);
382  }
383  pActive->set_active(true);
384  IncludeHdl_Impl(*pActive);
385  m_xDeletePB->set_sensitive(m_aAddressBlocks.getLength() > 1);
386 }
387 
389 {
390  if (m_xDependentRB->get_active())
391  return m_xCountryED->get_text();
392  return OUString();
393 }
394 
395 IMPL_LINK(SwSelectAddressBlockDialog, DeleteHdl_Impl, weld::Button&, rButton, void)
396 {
397  if (m_aAddressBlocks.getLength())
398  {
399  const sal_Int32 nSelected = static_cast<sal_Int32>(m_xPreview->GetSelectedAddress());
400  comphelper::removeElementAt(m_aAddressBlocks, nSelected);
401  if (m_aAddressBlocks.getLength() <= 1)
402  rButton.set_sensitive(false);
403  m_xPreview->RemoveSelectedAddress();
404  }
405 }
406 
407 IMPL_LINK(SwSelectAddressBlockDialog, NewCustomizeHdl_Impl, weld::Button&, rButton, void)
408 {
409  bool bCustomize = &rButton == m_xCustomizePB.get();
413  std::unique_ptr<SwCustomizeAddressBlockDialog> xDlg(new SwCustomizeAddressBlockDialog(&rButton,
414  m_rConfig, nType));
415  if(bCustomize)
416  {
417  xDlg->SetAddress(m_aAddressBlocks[m_xPreview->GetSelectedAddress()]);
418  }
419  if (RET_OK != xDlg->run())
420  return;
421 
422  const OUString sNew = xDlg->GetAddress();
423  if(bCustomize)
424  {
425  m_xPreview->ReplaceSelectedAddress(sNew);
426  m_aAddressBlocks[m_xPreview->GetSelectedAddress()] = sNew;
427  }
428  else
429  {
430  m_xPreview->AddAddress(sNew);
431  m_aAddressBlocks.realloc(m_aAddressBlocks.getLength() + 1);
432  const sal_Int32 nSelect = m_aAddressBlocks.getLength() - 1;
433  m_aAddressBlocks[nSelect] = sNew;
434  m_xPreview->SelectAddress(static_cast<sal_uInt16>(nSelect));
435  }
436  m_xDeletePB->set_sensitive(m_aAddressBlocks.getLength() > 1);
437 }
438 
440 {
441  m_xCountryED->set_sensitive(m_xDependentRB->get_active());
442 }
443 
444 #define USER_DATA_SALUTATION -1
445 #define USER_DATA_PUNCTUATION -2
446 #define USER_DATA_TEXT -3
447 #define USER_DATA_NONE -4
448 
449 IMPL_LINK(SwCustomizeAddressBlockDialog, TextFilterHdl, OUString&, rTest, bool)
450 {
451  rTest = m_aTextFilter.filter(rTest);
452  return true;
453 }
454 
456  weld::Widget* pParent, SwMailMergeConfigItem& rConfig, DialogType eType)
457  : SfxDialogController(pParent, "modules/swriter/ui/addressblockdialog.ui",
458  "AddressBlockDialog")
459  , m_aTextFilter("<>")
460  , m_rConfigItem(rConfig)
461  , m_eType(eType)
462  , m_xAddressElementsFT(m_xBuilder->weld_label("addressesft"))
463  , m_xAddressElementsLB(m_xBuilder->weld_tree_view("addresses"))
464  , m_xInsertFieldIB(m_xBuilder->weld_button("toaddr"))
465  , m_xRemoveFieldIB(m_xBuilder->weld_button("fromaddr"))
466  , m_xDragFT(m_xBuilder->weld_label("addressdestft"))
467  , m_xUpIB(m_xBuilder->weld_button("up"))
468  , m_xLeftIB(m_xBuilder->weld_button("left"))
469  , m_xRightIB(m_xBuilder->weld_button("right"))
470  , m_xDownIB(m_xBuilder->weld_button("down"))
471  , m_xFieldFT(m_xBuilder->weld_label("customft"))
472  , m_xFieldCB(m_xBuilder->weld_combo_box("custom"))
473  , m_xOK(m_xBuilder->weld_button("ok"))
474  , m_xPreview(new SwAddressPreview(m_xBuilder->weld_scrolled_window("previewwin", true)))
475  , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, "addrpreview", *m_xPreview))
476  , m_xDragED(new AddressMultiLineEdit(this))
477  , m_xDragWIN(new weld::CustomWeld(*m_xBuilder, "addressdest", *m_xDragED))
478 {
479  m_aSelectionChangedIdle.SetInvokeHandler( LINK( this, SwCustomizeAddressBlockDialog, SelectionChangedIdleHdl ) );
480 
481  Size aSize(m_xDragED->GetDrawingArea()->get_size_request());
482  m_xPreview->set_size_request(aSize.Width(), aSize.Height());
483 
484  m_xFieldCB->connect_entry_insert_text(LINK(this, SwCustomizeAddressBlockDialog, TextFilterHdl));
485  m_xAddressElementsLB->set_size_request(-1, m_xAddressElementsLB->get_height_rows(16));
486 
487  if( eType >= GREETING_FEMALE )
488  {
489  m_xFieldFT->show();
490  m_xFieldCB->show();
491  m_xAddressElementsLB->append(OUString::number(USER_DATA_SALUTATION), SwResId(ST_SALUTATION));
492  m_xAddressElementsLB->append(OUString::number(USER_DATA_PUNCTUATION), SwResId(ST_PUNCTUATION));
493  m_xAddressElementsLB->append(OUString::number(USER_DATA_TEXT), SwResId(ST_TEXT));
494  for (size_t i = 0; i < SAL_N_ELEMENTS(RA_SALUTATION); ++i)
495  m_aSalutations.push_back(SwResId(RA_SALUTATION[i]));
496  for (size_t i = 0; i < SAL_N_ELEMENTS(RA_PUNCTUATION); ++i)
497  m_aPunctuations.push_back(SwResId(RA_PUNCTUATION[i]));
498  m_xDragED->SetText(" ");
499  m_xDialog->set_title(SwResId(eType == GREETING_MALE ? ST_TITLE_MALE : ST_TITLE_FEMALE));
500  m_xAddressElementsFT->set_label(SwResId(ST_SALUTATIONELEMENTS));
501  m_xInsertFieldIB->set_tooltip_text(SwResId(ST_INSERTSALUTATIONFIELD));
502  m_xRemoveFieldIB->set_tooltip_text(SwResId(ST_REMOVESALUTATIONFIELD));
503  m_xDragFT->set_label(SwResId(ST_DRAGSALUTATION));
504  }
505  else
506  {
507  if (eType == ADDRESSBLOCK_EDIT)
508  m_xDialog->set_title(SwResId(ST_TITLE_EDIT));
509  m_xDragED->SetText("\n\n\n\n\n");
510  /* Set custom HIDs for swriter/01/mm_newaddblo.xhp */
514  m_xDragWIN->set_help_id( HID_MM_ADDBLOCK_DRAG );
515  m_xPreviewWIN->set_help_id( HID_MM_ADDBLOCK_PREVIEW );
516  m_xRightIB->set_help_id( HID_MM_ADDBLOCK_MOVEBUTTONS );
517  m_xLeftIB->set_help_id( HID_MM_ADDBLOCK_MOVEBUTTONS );
518  m_xDownIB->set_help_id( HID_MM_ADDBLOCK_MOVEBUTTONS );
519  m_xUpIB->set_help_id( HID_MM_ADDBLOCK_MOVEBUTTONS );
520  }
521 
522  const std::vector<std::pair<OUString, int>>& rHeaders = m_rConfigItem.GetDefaultAddressHeaders();
523  for (size_t i = 0; i < rHeaders.size(); ++i)
524  m_xAddressElementsLB->append(OUString::number(i), rHeaders[i].first);
525  m_xOK->connect_clicked(LINK(this, SwCustomizeAddressBlockDialog, OKHdl_Impl));
526  m_xAddressElementsLB->connect_changed(LINK(this, SwCustomizeAddressBlockDialog, ListBoxSelectHdl_Impl));
527  if (m_xAddressElementsLB->n_children())
528  m_xAddressElementsLB->select(0);
529  m_xDragED->SetModifyHdl(LINK(this, SwCustomizeAddressBlockDialog, EditModifyHdl_Impl));
530  m_xDragED->SetSelectionChangedHdl( LINK( this, SwCustomizeAddressBlockDialog, SelectionChangedHdl_Impl));
531  m_xFieldCB->connect_changed(LINK(this, SwCustomizeAddressBlockDialog, FieldChangeComboBoxHdl_Impl));
532  Link<weld::Button&,void> aImgButtonHdl = LINK(this, SwCustomizeAddressBlockDialog, ImageButtonHdl_Impl);
533  m_xInsertFieldIB->connect_clicked(aImgButtonHdl);
534  m_xRemoveFieldIB->connect_clicked(aImgButtonHdl);
535  m_xUpIB->connect_clicked(aImgButtonHdl);
536  m_xLeftIB->connect_clicked(aImgButtonHdl);
537  m_xRightIB->connect_clicked(aImgButtonHdl);
538  m_xDownIB->connect_clicked(aImgButtonHdl);
540 }
541 
543 {
544  return m_xDragED->SetCursorLogicPosition(rPosition);
545 }
546 
548 {
549  m_xDragED->UpdateFields();
550 }
551 
553 {
554  m_xDragED->EndDropTarget();
555 }
556 
558 {
559  m_xDialog->response(RET_OK);
560 }
561 
562 IMPL_LINK(SwCustomizeAddressBlockDialog, ListBoxSelectHdl_Impl, weld::TreeView&, rBox, void)
563 {
564  sal_Int32 nUserData = rBox.get_selected_id().toInt32();
565  // Check if the selected entry is already in the address and then forbid inserting
566  m_xInsertFieldIB->set_sensitive(nUserData >= 0 || !HasItem(nUserData));
567 }
568 
570 {
571  m_xPreview->SetAddress(SwAddressPreview::FillData(GetAddress(), m_rConfigItem));
572  UpdateImageButtons_Impl();
573 }
574 
575 IMPL_LINK(SwCustomizeAddressBlockDialog, ImageButtonHdl_Impl, weld::Button&, rButton, void)
576 {
577  if (m_xInsertFieldIB.get() == &rButton)
578  {
579  int nEntry = m_xAddressElementsLB->get_selected_index();
580  if (nEntry != -1)
581  {
582  m_xDragED->InsertNewEntry("<" + m_xAddressElementsLB->get_text(nEntry) + ">");
583  }
584  }
585  else if (m_xRemoveFieldIB.get() == &rButton)
586  {
587  m_xDragED->RemoveCurrentEntry();
588  }
589  else
590  {
592  if (m_xUpIB.get() == &rButton)
593  nMove = MoveItemFlags::Up;
594  else if (m_xLeftIB.get() == &rButton)
595  nMove = MoveItemFlags::Left;
596  else if (m_xRightIB.get() == &rButton)
597  nMove = MoveItemFlags::Right;
598  m_xDragED->MoveCurrentItem(nMove);
599  }
600  UpdateImageButtons_Impl();
601 }
602 
604 {
605  sal_Int32 nRet = USER_DATA_NONE;
606  const OUString sSelected = m_xDragED->GetCurrentItem();
607  if(!sSelected.isEmpty())
608  {
609  for (int i = 0, nEntryCount = m_xAddressElementsLB->n_children(); i < nEntryCount; ++i)
610  {
611  const OUString sEntry = m_xAddressElementsLB->get_text(i);
612  if( sEntry == sSelected.subView( 1, sSelected.getLength() - 2 ) )
613  {
614  nRet = m_xAddressElementsLB->get_id(i).toInt32();
615  break;
616  }
617  }
618  }
619  return nRet;
620 }
621 
622 bool SwCustomizeAddressBlockDialog::HasItem(sal_Int32 nUserData)
623 {
624  //get the entry from the ListBox
625  OUString sEntry;
626  for (int i = 0, nEntryCount = m_xAddressElementsLB->n_children(); i < nEntryCount; ++i)
627  {
628  if (m_xAddressElementsLB->get_id(i).toInt32() == nUserData)
629  {
630  sEntry = m_xAddressElementsLB->get_text(i);
631  break;
632  }
633  }
634  //search for this entry in the content
635  return m_xDragED->GetText().indexOf(OUString("<" + sEntry + ">")) >= 0;
636 }
637 
638 IMPL_LINK_NOARG(SwCustomizeAddressBlockDialog, SelectionChangedIdleHdl, Timer*, void)
639 {
640  // called in case the selection of the edit field changes.
641  // determine selection - if it's one of the editable fields then
642  // enable the related ComboBox and fill it
643 
644  // don't trigger outself again
645  m_xDragED->SetSelectionChangedHdl(Link<bool, void>());
646 
647  sal_Int32 nSelected = GetSelectedItem_Impl();
648  if (USER_DATA_NONE != nSelected)
649  m_xDragED->SelectCurrentItem();
650 
651  if(m_xFieldCB->get_visible() && (USER_DATA_NONE != nSelected) && (nSelected < 0))
652  {
653  //search in ListBox if it's one of the first entries
654  OUString sSelect;
655  std::vector<OUString>* pVector = nullptr;
656  switch(nSelected) {
658  sSelect = m_sCurrentSalutation;
659  pVector = &m_aSalutations;
660  break;
662  sSelect = m_sCurrentPunctuation;
663  pVector = &m_aPunctuations;
664  break;
665  case USER_DATA_TEXT:
666  sSelect = m_sCurrentText;
667  break;
668  }
669  m_xFieldCB->clear();
670  if(pVector) {
671  for (const auto& rItem : *pVector)
672  m_xFieldCB->append_text(rItem);
673  }
674  m_xFieldCB->set_entry_text(sSelect);
675  m_xFieldCB->set_sensitive(true);
676  m_xFieldFT->set_sensitive(true);
677  }
678  else
679  {
680  m_xFieldCB->set_sensitive(false);
681  m_xFieldFT->set_sensitive(false);
682  }
683 
684  UpdateImageButtons_Impl();
685  m_xDragED->SetSelectionChangedHdl( LINK( this, SwCustomizeAddressBlockDialog, SelectionChangedHdl_Impl));
686 }
687 
688 IMPL_LINK(SwCustomizeAddressBlockDialog, SelectionChangedHdl_Impl, bool, bIdle, void)
689 {
690  if (bIdle)
691  m_aSelectionChangedIdle.Start();
692  else
693  {
694  m_aSelectionChangedIdle.Stop();
695  SelectionChangedIdleHdl(nullptr);
696  }
697 }
698 
699 IMPL_LINK_NOARG(SwCustomizeAddressBlockDialog, FieldChangeComboBoxHdl_Impl, weld::ComboBox&, void)
700 {
701  //changing the field content changes the related members, too
702  sal_Int32 nSelected = GetSelectedItem_Impl();
703  const OUString sContent = m_xFieldCB->get_active_text();
704  switch(nSelected) {
706  m_sCurrentSalutation = sContent;
707  break;
709  m_sCurrentPunctuation = sContent;
710  break;
711  case USER_DATA_TEXT:
712  m_sCurrentText = sContent;
713  break;
714  }
715  UpdateImageButtons_Impl();
716  m_xPreview->SetAddress(GetAddress());
717  EditModifyHdl_Impl(*m_xDragED);
718 }
719 
721 {
722  MoveItemFlags nMove = m_xDragED->IsCurrentItemMoveable();
723  m_xUpIB->set_sensitive( bool(nMove & MoveItemFlags::Up) );
724  m_xLeftIB->set_sensitive( bool(nMove & MoveItemFlags::Left) );
725  m_xRightIB->set_sensitive( bool(nMove & MoveItemFlags::Right) );
726  m_xDownIB->set_sensitive( bool(nMove & MoveItemFlags::Down) );
727  m_xRemoveFieldIB->set_sensitive(m_xDragED->HasCurrentItem());
728  int nEntry = m_xAddressElementsLB->get_selected_index();
729  m_xInsertFieldIB->set_sensitive( nEntry != -1 &&
730  (m_xAddressElementsLB->get_id(nEntry).toInt32() >= 0 || !m_xFieldCB->get_active_text().isEmpty()));
731 }
732 
733 void SwCustomizeAddressBlockDialog::SetAddress(const OUString& rAddress)
734 {
735  m_xDragED->SetText(rAddress);
737  EditModifyHdl_Impl(*m_xDragED);
738 }
739 
741 {
742  OUString sAddress(m_xDragED->GetAddress());
743  //remove placeholders by the actual content
744  if (m_xFieldFT->get_visible())
745  {
746  for (int i = 0, nEntryCount = m_xAddressElementsLB->n_children(); i < nEntryCount; ++i)
747  {
748  const OUString sEntry = "<" + m_xAddressElementsLB->get_text(i) + ">";
749  sal_Int32 nUserData = m_xAddressElementsLB->get_id(i).toInt32();
750  switch(nUserData)
751  {
753  sAddress = sAddress.replaceFirst(sEntry, m_sCurrentSalutation);
754  break;
756  sAddress = sAddress.replaceFirst(sEntry, m_sCurrentPunctuation);
757  break;
758  case USER_DATA_TEXT:
759  sAddress = sAddress.replaceFirst(sEntry, m_sCurrentText);
760  break;
761  }
762  }
763  }
764  return sAddress;
765 }
766 
767 namespace {
768 
769 struct SwAssignFragment
770 {
771  std::unique_ptr<weld::Builder> m_xBuilder;
772  std::unique_ptr<weld::Label> m_xLabel;
773  std::unique_ptr<weld::ComboBox> m_xComboBox;
774  std::unique_ptr<weld::Label> m_xPreview;
775 
776  SwAssignFragment(weld::Container* pGrid, int nLine)
777  : m_xBuilder(Application::CreateBuilder(pGrid, "modules/swriter/ui/assignfragment.ui"))
778  , m_xLabel(m_xBuilder->weld_label("label"))
779  , m_xComboBox(m_xBuilder->weld_combo_box("combobox"))
780  , m_xPreview(m_xBuilder->weld_label("preview"))
781  {
782  m_xLabel->set_grid_left_attach(0);
783  m_xLabel->set_grid_top_attach(nLine);
784 
785  m_xComboBox->set_grid_left_attach(1);
786  m_xComboBox->set_grid_top_attach(nLine);
787 
788  m_xPreview->set_grid_left_attach(2);
789  m_xPreview->set_grid_top_attach(nLine);
790  }
791 };
792 
793 }
794 
796 {
797  friend class SwAssignFieldsDialog;
798  std::unique_ptr<weld::ScrolledWindow> m_xVScroll;
799  std::unique_ptr<weld::Container> m_xGrid;
800 
801  std::vector<SwAssignFragment> m_aFields;
802 
804 
806 
807  DECL_LINK(MatchHdl_Impl, weld::ComboBox&, void);
808  DECL_LINK(GotFocusHdl_Impl, weld::Widget&, void);
809 
810  void MakeVisible(const tools::Rectangle & rRect);
811 public:
812  SwAssignFieldsControl(std::unique_ptr<weld::ScrolledWindow> xWindow,
813  std::unique_ptr<weld::Container> xGrid);
814 
815  void Init(SwAssignFieldsDialog* pDialog, SwMailMergeConfigItem& rConfigItem);
816  void SetModifyHdl(const Link<LinkParamNone*,void>& rModifyHdl)
817  {
818  m_aModifyHdl = rModifyHdl;
819  m_aModifyHdl.Call(nullptr);
820  }
821 };
822 
823 SwAssignFieldsControl::SwAssignFieldsControl(std::unique_ptr<weld::ScrolledWindow> xWindow,
824  std::unique_ptr<weld::Container> xGrid)
825  : m_xVScroll(std::move(xWindow))
826  , m_xGrid(std::move(xGrid))
827  , m_rConfigItem(nullptr)
828 {
829 }
830 
832 {
833  m_rConfigItem = &rConfigItem;
834 
835  //get the name of the default headers
836  const std::vector<std::pair<OUString, int>>& rHeaders = rConfigItem.GetDefaultAddressHeaders();
837  //get the actual data
838  uno::Reference< XColumnsSupplier > xColsSupp( rConfigItem.GetResultSet(), uno::UNO_QUERY);
839  //get the name of the actual columns
840  uno::Reference <XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : nullptr;
841  uno::Sequence< OUString > aFields;
842  if(xColAccess.is())
843  aFields = xColAccess->getElementNames();
844 
845  //get the current assignment list
846  //each position in this sequence matches the position in the header array rHeaders
847  //if no assignment is available an empty sequence will be returned
848  uno::Sequence< OUString> aAssignments = rConfigItem.GetColumnAssignment( rConfigItem.GetCurrentDBData() );
849  Link<weld::ComboBox&,void> aMatchHdl = LINK(this, SwAssignFieldsControl, MatchHdl_Impl);
850  Link<weld::Widget&,void> aFocusHdl = LINK(this, SwAssignFieldsControl, GotFocusHdl_Impl);
851 
852  int nLabelWidth(0), nComboBoxWidth(0), nPreviewWidth(0);
853 
854  //fill the controls
855  for (size_t i = 0; i < rHeaders.size(); ++i)
856  {
857  m_aFields.emplace_back(m_xGrid.get(), i);
858 
859  const OUString rHeader = rHeaders[i].first;
860  weld::ComboBox& rNewLB = *m_aFields.back().m_xComboBox;
861  rNewLB.append_text(SwResId(SW_STR_NONE));
862  rNewLB.set_active(0);
863 
864  for (const OUString& rField : std::as_const(aFields))
865  rNewLB.append_text(rField);
866  //select the ListBox
867  //if there is an assignment
868  if(o3tl::make_unsigned(aAssignments.getLength()) > i && !aAssignments[i].isEmpty())
869  rNewLB.set_active_text(aAssignments[i]);
870  else //otherwise the current column name may match one of the db columns
871  rNewLB.set_active_text(rHeader);
872 
873  weld::Label& rNewText = *m_aFields.back().m_xLabel;
874  rNewText.set_label("<" + rHeader + ">");
875 
876  weld::Label& rNewPreview = *m_aFields.back().m_xPreview;
877  //then the preview can be filled accordingly
878  if (xColAccess.is() && rNewLB.get_active() > 0 &&
879  xColAccess->hasByName(rNewLB.get_active_text()))
880  {
881  uno::Any aCol = xColAccess->getByName(rNewLB.get_active_text());
882  uno::Reference< XColumn > xColumn;
883  aCol >>= xColumn;
884  if(xColumn.is())
885  {
886  try
887  {
888  rNewPreview.set_label(xColumn->getString());
889  }
890  catch (const SQLException&)
891  {
892  }
893  }
894  }
895 
896  if (i == 0)
897  {
898  auto nLineHeight = m_xGrid->get_preferred_size().Height();
899  m_xVScroll->set_size_request(m_xVScroll->get_approximate_digit_width() * 65,
900  nLineHeight * 6);
901  nComboBoxWidth = rNewLB.get_preferred_size().Width();
902  }
903 
904  nLabelWidth = std::max<int>(nLabelWidth, rNewText.get_preferred_size().Width());
905  nPreviewWidth = std::max<int>(nPreviewWidth, rNewPreview.get_preferred_size().Width());
906 
907  rNewLB.connect_changed(aMatchHdl);
908  rNewLB.connect_focus_in(aFocusHdl);
909  rNewText.show();
910  rNewLB.show();
911  rNewPreview.show();
912  }
913  pDialog->ConnectSizeGroups(nLabelWidth, nComboBoxWidth, nPreviewWidth);
914 }
915 
917 {
918  //determine range of visible positions
919  auto nMinVisiblePos = m_xVScroll->vadjustment_get_value();
920  auto nMaxVisiblePos = nMinVisiblePos + m_xVScroll->vadjustment_get_page_size();
921  if (rRect.Top() < nMinVisiblePos || rRect.Bottom() > nMaxVisiblePos)
922  m_xVScroll->vadjustment_set_value(rRect.Top());
923 }
924 
925 IMPL_LINK(SwAssignFieldsControl, MatchHdl_Impl, weld::ComboBox&, rBox, void)
926 {
927  const OUString sColumn = rBox.get_active_text();
928  uno::Reference< XColumnsSupplier > xColsSupp( m_rConfigItem->GetResultSet(), uno::UNO_QUERY);
929  uno::Reference <XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : nullptr;
930  OUString sPreview;
931  if(xColAccess.is() && xColAccess->hasByName(sColumn))
932  {
933  uno::Any aCol = xColAccess->getByName(sColumn);
934  uno::Reference< XColumn > xColumn;
935  aCol >>= xColumn;
936  if(xColumn.is())
937  {
938  try
939  {
940  sPreview = xColumn->getString();
941  }
942  catch (const sdbc::SQLException&)
943  {
944  }
945  }
946  }
947  auto aLBIter = std::find_if(m_aFields.begin(), m_aFields.end(), [&rBox](const SwAssignFragment& rFragment){
948  return &rBox == rFragment.m_xComboBox.get(); });
949  if (aLBIter != m_aFields.end())
950  {
951  auto nIndex = static_cast<sal_Int32>(std::distance(m_aFields.begin(), aLBIter));
952  m_aFields[nIndex].m_xPreview->set_label(sPreview);
953  }
954  m_aModifyHdl.Call(nullptr);
955 }
956 
957 IMPL_LINK(SwAssignFieldsControl, GotFocusHdl_Impl, weld::Widget&, rBox, void)
958 {
959  int x, y, width, height;
960  rBox.get_extents_relative_to(*m_xGrid, x, y, width, height);
961  // the container has a border of 3 in the .ui
962  tools::Rectangle aRect(Point(x - 3, y - 3), Size(width + 6, height + 6));
963  MakeVisible(aRect);
964 }
965 
967  weld::Window* pParent, SwMailMergeConfigItem& rConfigItem,
968  const OUString& rPreview,
969  bool bIsAddressBlock)
970  : SfxDialogController(pParent, "modules/swriter/ui/assignfieldsdialog.ui", "AssignFieldsDialog")
971  , m_sNone(SwResId(SW_STR_NONE))
972  , m_rPreviewString(rPreview)
973  , m_rConfigItem(rConfigItem)
974  , m_xPreview(new SwAddressPreview(m_xBuilder->weld_scrolled_window("previewwin", true)))
975  , m_xMatchingFI(m_xBuilder->weld_label("MATCHING_LABEL"))
976  , m_xAddressTitle(m_xBuilder->weld_label("addresselem"))
977  , m_xMatchTitle(m_xBuilder->weld_label("matchelem"))
978  , m_xPreviewTitle(m_xBuilder->weld_label("previewelem"))
979  , m_xPreviewFI(m_xBuilder->weld_label("PREVIEW_LABEL"))
980  , m_xOK(m_xBuilder->weld_button("ok"))
981  , m_xPreviewWin(new weld::CustomWeld(*m_xBuilder, "PREVIEW", *m_xPreview))
982  , m_xFieldsControl(new SwAssignFieldsControl(m_xBuilder->weld_scrolled_window("scroll"),
983  m_xBuilder->weld_container("FIELDS")))
984 {
985  m_xPreviewWin->set_size_request(m_xMatchingFI->get_approximate_digit_width() * 45,
986  m_xMatchingFI->get_text_height() * 5);
987  m_xFieldsControl->Init(this, rConfigItem);
988 
989  const OUString sMatchesTo( SwResId(ST_MATCHESTO) );
990  if (!bIsAddressBlock)
991  {
992  m_xPreviewFI->set_label(SwResId(ST_SALUTATIONPREVIEW));
993  m_xMatchingFI->set_label(SwResId(ST_SALUTATIONMATCHING));
994  m_xAddressTitle->set_label(SwResId(ST_SALUTATIONELEMENT));
995  }
996 
997  m_xFieldsControl->SetModifyHdl(LINK(this, SwAssignFieldsDialog, AssignmentModifyHdl_Impl ));
998  m_xMatchingFI->set_label(m_xMatchingFI->get_label().replaceAll("%1", sMatchesTo));
999  m_xOK->connect_clicked(LINK(this, SwAssignFieldsDialog, OkHdl_Impl));
1000 }
1001 
1003 {
1004 }
1005 
1006 uno::Sequence< OUString > SwAssignFieldsDialog::CreateAssignments()
1007 {
1008  uno::Sequence< OUString > aAssignments(
1010  OUString* pAssignments = aAssignments.getArray();
1011  sal_Int32 nIndex = 0;
1012  for (const auto& rLBItem : m_xFieldsControl->m_aFields)
1013  {
1014  const OUString sSelect = rLBItem.m_xComboBox->get_active_text();
1015  pAssignments[nIndex] = (m_sNone != sSelect) ? sSelect : OUString();
1016  ++nIndex;
1017  }
1018  return aAssignments;
1019 }
1020 
1022 {
1025  CreateAssignments() );
1026  m_xDialog->response(RET_OK);
1027 }
1028 
1029 IMPL_LINK_NOARG(SwAssignFieldsDialog, AssignmentModifyHdl_Impl, LinkParamNone*, void)
1030 {
1031  uno::Sequence< OUString > aAssignments = CreateAssignments();
1032  const OUString sPreview = SwAddressPreview::FillData(
1033  m_rPreviewString, m_rConfigItem, &aAssignments);
1034  m_xPreview->SetAddress(sPreview);
1035 }
1036 
1037 void SwAssignFieldsDialog::ConnectSizeGroups(int nLabelWidth, int nComboBoxWidth, int nPreviewWidth)
1038 {
1039  m_xAddressTitle->set_size_request(nLabelWidth, -1);
1040  m_xMatchTitle->set_size_request(nComboBoxWidth, -1);
1041  m_xPreviewTitle->set_size_request(nPreviewWidth, -1);
1042 }
1043 
1044 namespace
1045 {
1046  const EECharAttrib* FindCharAttrib(int nStartPosition, std::vector<EECharAttrib>& rAttribList)
1047  {
1048  for (auto it = rAttribList.rbegin(); it != rAttribList.rend(); ++it)
1049  {
1050  const auto& rTextAtr = *it;
1051  if (rTextAtr.pAttr->Which() != EE_CHAR_GRABBAG)
1052  continue;
1053  if (rTextAtr.nStart <= nStartPosition && rTextAtr.nEnd >= nStartPosition)
1054  {
1055  return &rTextAtr;
1056  }
1057  }
1058 
1059  return nullptr;
1060  }
1061 }
1062 
1064  : m_pParentDialog(pParent)
1065 {
1066 }
1067 
1069 {
1070  if (m_xDropTarget.is())
1071  {
1072  auto xRealDropTarget = GetDrawingArea()->get_drop_target();
1073  uno::Reference<css::datatransfer::dnd::XDropTargetListener> xListener(m_xDropTarget, uno::UNO_QUERY);
1074  xRealDropTarget->removeDropTargetListener(xListener);
1075  m_xDropTarget.clear();
1076  }
1077 }
1078 
1080 {
1081  assert(!m_xDropTarget.is());
1082 }
1083 
1085 {
1086  Size aSize(pDrawingArea->get_ref_device().LogicToPixel(Size(160, 60), MapMode(MapUnit::MapAppFont)));
1087  pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
1088  WeldEditView::SetDrawingArea(pDrawingArea);
1089 }
1090 
1092 {
1093  if (rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE)
1094  return false; // we want default esc behaviour
1095  if (rKEvt.GetCharCode())
1096  return true; // handled
1097  return WeldEditView::KeyInput(rKEvt);
1098 }
1099 
1101 {
1102  if (rMEvt.GetClicks() >= 2)
1103  return true; // handled
1104  return WeldEditView::MouseButtonDown(rMEvt);
1105 }
1106 
1108 {
1109  return m_xEditEngine->GetText();
1110 }
1111 
1112 void AddressMultiLineEdit::SetText( const OUString& rStr )
1113 {
1114  m_xEditEngine->SetText(rStr);
1115  //set attributes to all address tokens
1116 
1117  sal_Int32 nSequence(0);
1118  SfxGrabBagItem aProtectAttr(EE_CHAR_GRABBAG);
1119  const sal_uInt32 nParaCount = m_xEditEngine->GetParagraphCount();
1120  for(sal_uInt32 nPara = 0; nPara < nParaCount; ++nPara)
1121  {
1122  sal_Int32 nIndex = 0;
1123  const OUString sPara = m_xEditEngine->GetText( nPara );
1124  if (!sPara.isEmpty() && !sPara.endsWith(" "))
1125  {
1126  ESelection aPaM(nPara, sPara.getLength(), nPara, sPara.getLength());
1127  m_xEditEngine->QuickInsertText(" ", aPaM);
1128  }
1129  for(;;)
1130  {
1131  const sal_Int32 nStart = sPara.indexOf( '<', nIndex );
1132  if (nStart < 0)
1133  break;
1134  const sal_Int32 nEnd = sPara.indexOf( '>', nStart );
1135  if (nEnd < 0)
1136  break;
1137  nIndex = nEnd;
1138  SfxItemSet aSet(m_xEditEngine->GetEmptyItemSet());
1139  // make each one different, so they are not collapsed together
1140  // as one attribute
1141  aProtectAttr.GetGrabBag()["Index"] <<= nSequence++;
1142  aSet.Put(aProtectAttr);
1143  m_xEditEngine->QuickSetAttribs(aSet, ESelection(nPara, nStart, nPara, nEnd + 1));
1144  }
1145 
1146  }
1147  // add two empty paragraphs at the end
1150  {
1151  sal_Int32 nLastLen = m_xEditEngine->GetText(nParaCount - 1).getLength();
1152  if(nLastLen)
1153  {
1154  int nPara = nParaCount ? nParaCount - 1 : 0;
1155  ESelection aPaM(nPara, nLastLen, nPara, nLastLen);
1156  m_xEditEngine->QuickInsertText("\n \n ", aPaM);
1157  }
1158  }
1159 
1160  m_xEditView->SetSelection(ESelection(0, 0, 0, 0));
1161 }
1162 
1163 // Insert the new entry in front of the entry at the beginning of the selection
1164 void AddressMultiLineEdit::InsertNewEntry( const OUString& rStr )
1165 {
1166  // insert new entry after current selected one.
1167  ESelection aSelection = m_xEditView->GetSelection();
1168  const sal_uInt32 nPara = aSelection.nStartPara;
1169 
1170  std::vector<EECharAttrib> aAttribList;
1171  m_xEditEngine->GetCharAttribs(nPara, aAttribList);
1172 
1173  sal_Int32 nIndex = aSelection.nEndPara;
1174  const EECharAttrib* pAttrib = FindCharAttrib(aSelection.nStartPos, aAttribList);
1175  if(nullptr != pAttrib)
1176  nIndex = pAttrib->nEnd;
1177  InsertNewEntryAtPosition( rStr, nPara, nIndex );
1178 
1179  // select the new entry
1180  m_xEditEngine->GetCharAttribs(nPara, aAttribList);
1181  pAttrib = FindCharAttrib(nIndex, aAttribList);
1182  const sal_Int32 nEnd = pAttrib ? pAttrib->nEnd : nIndex;
1183  ESelection aEntrySel(nPara, nIndex, nPara, nEnd);
1184  m_xEditView->SetSelection(aEntrySel);
1185  Invalidate();
1186  m_aModifyLink.Call(*this);
1187 }
1188 
1189 void AddressMultiLineEdit::InsertNewEntryAtPosition( const OUString& rStr, sal_uLong nPara, sal_uInt16 nIndex )
1190 {
1191  ESelection aInsertPos(nPara, nIndex, nPara, nIndex);
1192  m_xEditEngine->QuickInsertText(rStr, aInsertPos);
1193 
1194  //restore the attributes
1195  SetText( GetAddress() );
1196 
1197  //select the newly inserted/moved element
1198  m_xEditView->SetSelection(aInsertPos);
1199  m_aSelectionLink.Call(false);
1200 }
1201 
1203 {
1204  ESelection aSelection = m_xEditView->GetSelection();
1205 
1206  std::vector<EECharAttrib> aAttribList;
1207  m_xEditEngine->GetCharAttribs(aSelection.nStartPara, aAttribList);
1208 
1209  const EECharAttrib* pBeginAttrib = FindCharAttrib(aSelection.nStartPos, aAttribList);
1210  if(pBeginAttrib &&
1211  (pBeginAttrib->nStart <= aSelection.nStartPos
1212  && pBeginAttrib->nEnd >= aSelection.nEndPos))
1213  {
1214  const sal_uInt32 nPara = aSelection.nStartPara;
1215  ESelection aEntrySel(nPara, pBeginAttrib->nStart, nPara, pBeginAttrib->nEnd);
1216  m_xEditEngine->QuickInsertText(OUString(), aEntrySel);
1217  //restore the attributes
1218  SetText( GetAddress() );
1219  m_aModifyLink.Call(*this);
1220  }
1221 }
1222 
1224 {
1225  ESelection aSelection = m_xEditView->GetSelection();
1226 
1227  std::vector<EECharAttrib> aAttribList;
1228  m_xEditEngine->GetCharAttribs(aSelection.nStartPara, aAttribList);
1229 
1230  const EECharAttrib* pBeginAttrib = FindCharAttrib(aSelection.nStartPos, aAttribList);
1231  if(!pBeginAttrib ||
1232  pBeginAttrib->nStart > aSelection.nStartPos ||
1233  pBeginAttrib->nEnd < aSelection.nEndPos)
1234  return;
1235 
1236  //current item has been found
1237  sal_Int32 nPara = aSelection.nStartPara;
1238  sal_Int32 nIndex = pBeginAttrib->nStart;
1239  ESelection aEntrySel(nPara, pBeginAttrib->nStart, nPara, pBeginAttrib->nEnd);
1240  const OUString sCurrentItem = m_xEditEngine->GetText(aEntrySel);
1241  m_xEditEngine->RemoveAttribs(aEntrySel, false, EE_CHAR_GRABBAG);
1242  m_xEditEngine->QuickInsertText(OUString(), aEntrySel);
1243  m_xEditEngine->GetCharAttribs(nPara, aAttribList);
1244  switch (nMove)
1245  {
1246  case MoveItemFlags::Left :
1247  if(nIndex)
1248  {
1249  //go left to find a predecessor or simple text
1250  --nIndex;
1251  const OUString sPara = m_xEditEngine->GetText( nPara );
1252  sal_Int32 nSearchIndex = sPara.lastIndexOf( '>', nIndex+1 );
1253  if( nSearchIndex != -1 && nSearchIndex == nIndex )
1254  {
1255  nSearchIndex = sPara.lastIndexOf( '<', nIndex );
1256  if( nSearchIndex != -1 )
1257  nIndex = nSearchIndex;
1258  }
1259  }
1260  break;
1261  case MoveItemFlags::Right:
1262  {
1263  //go right to find a successor or simple text
1264  ++nIndex;
1265  const EECharAttrib* pEndAttrib = FindCharAttrib(aSelection.nStartPos, aAttribList);
1266  if(pEndAttrib && pEndAttrib->nEnd >= nIndex)
1267  {
1268  nIndex = pEndAttrib->nEnd;
1269  }
1270  }
1271  break;
1272  case MoveItemFlags::Up :
1273  --nPara;
1274  nIndex = 0;
1275  break;
1276  case MoveItemFlags::Down :
1277  ++nPara;
1278  nIndex = 0;
1279  break;
1280  default: break;
1281  }
1282  //add a new paragraph if there is none yet
1283  if (nPara >= m_xEditEngine->GetParagraphCount())
1284  {
1285  auto nInsPara = nPara - 1;
1286  auto nInsPos = m_xEditEngine->GetTextLen( nPara - 1 );
1287  ESelection aTemp(nInsPara, nInsPos, nInsPara, nInsPos);
1288  m_xEditEngine->QuickInsertText("\n", aTemp);
1289  }
1290  InsertNewEntryAtPosition( sCurrentItem, nPara, nIndex );
1291 
1292  // select the new entry [#i40817]
1293  m_xEditEngine->GetCharAttribs(nPara, aAttribList);
1294  const EECharAttrib* pAttrib = FindCharAttrib(nIndex, aAttribList);
1295  if (pAttrib)
1296  aEntrySel = ESelection(nPara, nIndex, nPara, pAttrib->nEnd);
1297  m_xEditView->SetSelection(aEntrySel);
1298  Invalidate();
1299  m_aModifyLink.Call(*this);
1300 }
1301 
1303 {
1305  ESelection aSelection = m_xEditView->GetSelection();
1306 
1307  std::vector<EECharAttrib> aAttribList;
1308  m_xEditEngine->GetCharAttribs(aSelection.nStartPara, aAttribList);
1309 
1310  const EECharAttrib* pBeginAttrib = FindCharAttrib(aSelection.nStartPos, aAttribList);
1311  if (pBeginAttrib &&
1312  (pBeginAttrib->nStart <= aSelection.nStartPos
1313  && pBeginAttrib->nEnd >= aSelection.nEndPos))
1314  {
1315  if (pBeginAttrib->nStart)
1316  nRet |= MoveItemFlags::Left;
1317  //if there is an entry it can always be move to the right and down
1319  if (aSelection.nStartPara > 0)
1320  nRet |= MoveItemFlags::Up;
1321  }
1322  return nRet;
1323 }
1324 
1326 {
1327  ESelection aSelection = m_xEditView->GetSelection();
1328 
1329  std::vector<EECharAttrib> aAttribList;
1330  m_xEditEngine->GetCharAttribs(aSelection.nStartPara, aAttribList);
1331 
1332  const EECharAttrib* pBeginAttrib = FindCharAttrib(aSelection.nStartPos, aAttribList);
1333  return (pBeginAttrib &&
1334  (pBeginAttrib->nStart <= aSelection.nStartPos
1335  && pBeginAttrib->nEnd >= aSelection.nEndPos));
1336 }
1337 
1339 {
1340  ESelection aSelection = m_xEditView->GetSelection();
1341 
1342  std::vector<EECharAttrib> aAttribList;
1343  m_xEditEngine->GetCharAttribs(aSelection.nStartPara, aAttribList);
1344 
1345  const EECharAttrib* pBeginAttrib = FindCharAttrib(aSelection.nStartPos, aAttribList);
1346  if (pBeginAttrib &&
1347  (pBeginAttrib->nStart <= aSelection.nStartPos
1348  && pBeginAttrib->nEnd >= aSelection.nEndPos))
1349  {
1350  const sal_uInt32 nPara = aSelection.nStartPara;
1351  ESelection aEntrySel(nPara, pBeginAttrib->nStart, nPara, pBeginAttrib->nEnd);
1352  return m_xEditEngine->GetText( aEntrySel );
1353  }
1354  return OUString();
1355 }
1356 
1358 {
1359  ESelection aSelection = m_xEditView->GetSelection();
1360 
1361  std::vector<EECharAttrib> aAttribList;
1362  m_xEditEngine->GetCharAttribs(aSelection.nStartPara, aAttribList);
1363 
1364  const EECharAttrib* pBeginAttrib = FindCharAttrib(aSelection.nStartPos, aAttribList);
1365  if (pBeginAttrib &&
1366  (pBeginAttrib->nStart <= aSelection.nStartPos
1367  && pBeginAttrib->nEnd >= aSelection.nEndPos))
1368  {
1369  const sal_uInt32 nPara = aSelection.nStartPara;
1370  ESelection aEntrySel(nPara, pBeginAttrib->nStart, nPara, pBeginAttrib->nEnd);
1371  m_xEditView->SetSelection(aEntrySel);
1372  Invalidate();
1373  }
1374 }
1375 
1377 {
1378  OUString sRet;
1379  const sal_uInt32 nParaCount = m_xEditEngine->GetParagraphCount();
1380  for(sal_uInt32 nPara = nParaCount; nPara; --nPara)
1381  {
1382  const OUString sPara = comphelper::string::stripEnd(m_xEditEngine->GetText(nPara - 1), ' ');
1383  //don't add empty trailing paragraphs
1384  if(!sRet.isEmpty() || !sPara.isEmpty())
1385  {
1386  sRet = sPara + sRet;
1387  //insert the para break
1388  if(nPara > 1)
1389  sRet = "\n" + sRet;
1390  }
1391  }
1392  return sRet;
1393 }
1394 
1396 {
1397  ESelection aSelection = m_xEditView->GetSelection();
1398 
1399  //restore the attributes
1400  SetText( GetAddress() );
1401 
1402  //reselect the element
1403  m_xEditView->SetSelection(aSelection);
1404  m_aSelectionLink.Call(false);
1405 }
1406 
1408 {
1410  m_aSelectionLink.Call(true);
1411 }
1412 
1413 namespace
1414 {
1415  // sit between the tree as drag source and the editview as drop target and translate
1416  // the tree dnd data to the simple string the editview wants
1417  class DropTargetListener : public cppu::WeakImplHelper< css::datatransfer::dnd::XDropTargetListener,
1418  css::datatransfer::dnd::XDropTarget >
1419  {
1420  private:
1421  css::uno::Reference<css::datatransfer::dnd::XDropTarget> m_xRealDropTarget;
1422  std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> m_aListeners;
1423  SwCustomizeAddressBlockDialog* m_pParentDialog;
1424 
1425  // XEventListener
1426  virtual void SAL_CALL disposing( const css::lang::EventObject& ) override
1427  {
1428  m_xRealDropTarget.clear();
1429  m_aListeners.clear();
1430  }
1431 
1432  // XDropTargetListener
1433  virtual void SAL_CALL drop( const css::datatransfer::dnd::DropTargetDropEvent& dtde ) override
1434  {
1435  SolarMutexGuard aGuard;
1436 
1437  auto aReplacement(dtde);
1438 
1439  Point aMousePos(dtde.LocationX, dtde.LocationY);
1440  bool bAllowed = m_pParentDialog->SetCursorLogicPosition(aMousePos);
1441  if (bAllowed)
1442  {
1443  if (weld::TreeView* pTree = m_pParentDialog->get_drag_source())
1444  {
1445  int nEntry = pTree->get_selected_index();
1446  if (nEntry != -1)
1447  {
1448  sal_Int32 nUserData = pTree->get_id(nEntry).toInt32();
1449  //special entries can only be once in the address / greeting
1450  if (nUserData >= 0 || !m_pParentDialog->HasItem(nUserData))
1451  {
1453  xContainer->CopyString( "<" + pTree->get_text(nEntry) + ">" );
1454 
1455  // replace what the treeview is offering with what ImpEditView::drop wants
1456  aReplacement.Transferable = xContainer.get();
1457  }
1458  }
1459  }
1460  }
1461 
1462  std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> aListeners(m_aListeners);
1463  for (auto const& listener : aListeners)
1464  listener->drop(aReplacement);
1465 
1466  if (bAllowed)
1467  m_pParentDialog->UpdateFields();
1468  }
1469 
1470  virtual void SAL_CALL dragEnter( const css::datatransfer::dnd::DropTargetDragEnterEvent& dtdee ) override
1471  {
1472  auto aReplacement(dtdee);
1473  // replace what the treeview is offering with what ImpEditView::dragEnter wants
1474  aReplacement.SupportedDataFlavors.realloc(1);
1475  SotExchange::GetFormatDataFlavor(SotClipboardFormatId::STRING, aReplacement.SupportedDataFlavors[0]);
1476 
1477  std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> aListeners(m_aListeners);
1478  for (auto const& listener : aListeners)
1479  listener->dragEnter(aReplacement);
1480  }
1481 
1482  virtual void SAL_CALL dragExit( const css::datatransfer::dnd::DropTargetEvent& dte ) override
1483  {
1484  std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> aListeners(m_aListeners);
1485  for (auto const& listener : aListeners)
1486  listener->dragExit( dte );
1487  }
1488 
1489  virtual void SAL_CALL dragOver( const css::datatransfer::dnd::DropTargetDragEvent& dtde ) override
1490  {
1491  std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> aListeners(m_aListeners);
1492  for (auto const& listener : aListeners)
1493  listener->dragOver( dtde );
1494  }
1495 
1496  virtual void SAL_CALL dropActionChanged( const css::datatransfer::dnd::DropTargetDragEvent& dtde ) override
1497  {
1498  std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> aListeners(m_aListeners);
1499  for (auto const& listener : aListeners)
1500  listener->dropActionChanged( dtde );
1501  }
1502 
1503  // XDropTarget
1504  virtual void SAL_CALL addDropTargetListener(const css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>& xListener) override
1505  {
1506  m_aListeners.push_back(xListener);
1507  }
1508 
1509  virtual void SAL_CALL removeDropTargetListener(const css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>& xListener) override
1510  {
1511  m_aListeners.erase(std::remove(m_aListeners.begin(), m_aListeners.end(), xListener), m_aListeners.end());
1512  }
1513 
1514  virtual sal_Bool SAL_CALL isActive() override
1515  {
1516  return m_xRealDropTarget->isActive();
1517  }
1518 
1519  virtual void SAL_CALL setActive(sal_Bool active) override
1520  {
1521  m_xRealDropTarget->setActive(active);
1522  }
1523 
1524  virtual sal_Int8 SAL_CALL getDefaultActions() override
1525  {
1526  return m_xRealDropTarget->getDefaultActions();
1527  }
1528 
1529  virtual void SAL_CALL setDefaultActions(sal_Int8 actions) override
1530  {
1531  m_xRealDropTarget->setDefaultActions(actions);
1532  }
1533 
1534  public:
1535  DropTargetListener(css::uno::Reference<css::datatransfer::dnd::XDropTarget> xRealDropTarget,
1536  SwCustomizeAddressBlockDialog* pParentDialog)
1537  : m_xRealDropTarget(xRealDropTarget)
1538  , m_pParentDialog(pParentDialog)
1539  {
1540  }
1541  };
1542 }
1543 
1544 css::uno::Reference<css::datatransfer::dnd::XDropTarget> AddressMultiLineEdit::GetDropTarget()
1545 {
1546  if (!m_xDropTarget.is())
1547  {
1548  auto xRealDropTarget = GetDrawingArea()->get_drop_target();
1549  DropTargetListener* pProxy = new DropTargetListener(xRealDropTarget, m_pParentDialog);
1550  uno::Reference<css::datatransfer::dnd::XDropTargetListener> xListener(pProxy);
1551  xRealDropTarget->addDropTargetListener(xListener);
1552  m_xDropTarget = uno::Reference<css::datatransfer::dnd::XDropTarget>(pProxy);
1553  }
1554  return m_xDropTarget;
1555 }
1556 
1558 {
1559  Point aMousePos = EditViewOutputDevice().PixelToLogic(rPosition);
1560  m_xEditView->SetCursorLogicPosition(aMousePos, false, true);
1561 
1562  ESelection aSelection = m_xEditView->GetSelection();
1563  std::vector<EECharAttrib> aAttribList;
1564  m_xEditEngine->GetCharAttribs(aSelection.nStartPara, aAttribList);
1565  return FindCharAttrib(aSelection.nStartPos, aAttribList) == nullptr;
1566 }
1567 
1568 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int32 nEnd
OString stripEnd(const OString &rIn, char c)
std::unique_ptr< weld::Button > m_xRightIB
std::unique_ptr< weld::Button > m_xInsertFieldIB
std::unique_ptr< weld::Container > m_xGrid
SwAssignFieldsControl(std::unique_ptr< weld::ScrolledWindow > xWindow, std::unique_ptr< weld::Container > xGrid)
bool IsHideEmptyParagraphs() const
std::unique_ptr< SwAddressPreview > m_xPreview
void SetAddress(const OUString &rAddress)
#define HID_MM_ADDBLOCK_DRAG
Definition: helpids.h:149
std::vector< OUString > m_aSalutations
sal_Int32 nStartPara
sal_Int32 nIndex
std::unique_ptr< weld::Button > m_xLeftIB
std::unique_ptr< weld::Button > m_xNewPB
void InsertDataHdl(const weld::Button *pButton)
sal_Int32 nStart
SwMailMergeConfigItem & GetConfigItem()
std::unique_ptr< weld::Label > m_xPreviewTitle
std::unique_ptr< weld::Button > m_xDifferentlist
#define HID_MM_ADDBLOCK_MOVEBUTTONS
Definition: helpids.h:151
virtual Dialog * getDialog() override
OUString GetAddress() const
std::unique_ptr< weld::Label > m_xMatchTitle
MoveItemFlags IsCurrentItemMoveable() const
std::unique_ptr< SwAssignFieldsControl > m_xFieldsControl
signed char sal_Int8
SwSelectAddressBlockDialog(weld::Window *pParent, SwMailMergeConfigItem &rConfig)
std::unique_ptr< weld::RadioButton > m_xNeverRB
virtual void EditViewSelectionChange() override
sal_uIntPtr sal_uLong
OUString sDataSource
Definition: swdbdata.hxx:30
sal_Int32 GetCurrentAddressBlockIndex() const
void SetCurrentConnection(css::uno::Reference< css::sdbc::XDataSource > const &xSource, const SharedConnection &rConnection, css::uno::Reference< css::sdbcx::XColumnsSupplier > const &xColumnsSupplier, const SwDBData &rDBData)
SwAssignFieldsDialog(weld::Window *pParent, SwMailMergeConfigItem &rConfigItem, const OUString &rPreview, bool bIsAddressBlock)
sal_uInt16 GetCode() const
const SwDBData & GetCurrentDBData() const
std::unique_ptr< weld::CheckButton > m_xAddressCB
#define USER_DATA_TEXT
std::vector< Reference< css::datatransfer::clipboard::XClipboardListener > > m_aListeners
Link< AddressMultiLineEdit &, void > m_aModifyLink
std::unique_ptr< weld::CustomWeld > m_xSettingsWIN
IMPL_LINK_NOARG(SwMailMergeAddressBlockPage, AddressListHdl_Impl, weld::Button &, void)
virtual int get_active() const =0
float x
void InsertNewEntry(const OUString &rStr)
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea) override
std::unique_ptr< weld::Label > m_xLabel
SwMailMergeWizard * GetWizard()
bool SetCursorLogicPosition(const Point &rPosition)
#define HID_MM_ADDBLOCK_REMOVE
Definition: helpids.h:148
sal_uInt16 GetClicks() const
std::vector< SwAssignFragment > m_aFields
void MoveCurrentItem(MoveItemFlags nMove)
std::unique_ptr< weld::CustomWeld > m_xPreviewWin
virtual void show()=0
css::uno::Reference< css::datatransfer::dnd::XDropTarget > m_xDropTarget
const css::uno::Sequence< OUString > & GetAddressBlocks()
std::vector< OUString > m_aPunctuations
css::uno::Sequence< OUString > GetAddressBlocks() const
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
std::unique_ptr< weld::Button > m_xUpIB
std::unique_ptr< weld::CustomWeld > m_xPreviewWIN
tools::Long Bottom() const
std::unique_ptr< weld::CustomWeld > m_xPreviewWin
virtual ~AddressMultiLineEdit() override
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea) override
std::unique_ptr< weld::Button > m_xNextSetIB
virtual bool MouseButtonDown(const MouseEvent &rMEvt) override
void MakeVisible(const tools::Rectangle &rRect)
virtual ~SwSelectAddressBlockDialog() override
virtual OutputDevice & get_ref_device()=0
sal_Int32 nEndPos
std::unique_ptr< weld::Button > m_xCustomizePB
Link< bool, void > m_aSelectionLink
std::unique_ptr< weld::Container > m_xStep3
#define MM_GREETINGSPAGE
constexpr TypedWhichId< SfxGrabBagItem > EE_CHAR_GRABBAG(EE_CHAR_START+31)
std::unique_ptr< weld::CustomWeld > m_xPreviewWIN
Listeners aListeners
virtual void set_active(bool active)=0
#define HID_MM_ADDBLOCK_PREVIEW
Definition: helpids.h:150
float y
IMPL_LINK(SwMailMergeAddressBlockPage, AddressBlockHdl_Impl, weld::ToggleButton &, rBox, void)
#define SAL_N_ELEMENTS(arr)
std::unique_ptr< weld::CustomWeld > m_xDragWIN
css::uno::Reference< css::sdbc::XResultSet > const & GetResultSet() const
std::unique_ptr< weld::ScrolledWindow > m_xVScroll
std::unique_ptr< weld::Container > m_xContainer
SwMailMergeAddressBlockPage(weld::Container *pPage, SwMailMergeWizard *pWizard)
const std::vector< std::pair< OUString, int > > & GetDefaultAddressHeaders() const
void set_active_text(const OUString &rStr)
std::unique_ptr< weld::ComboBox > m_xFieldCB
sal_Int32 nEndPara
#define TOOLS_WARN_EXCEPTION(area, stream)
SwCustomizeAddressBlockDialog(weld::Widget *pParent, SwMailMergeConfigItem &rConfig, DialogType)
virtual ~SwAssignFieldsDialog() override
const SwDBData & GetDBData() const
int i
weld::TreeView * get_drag_source() const
std::unique_ptr< weld::Button > m_xOK
std::unique_ptr< weld::Container > m_xStep2
void connect_changed(const Link< ComboBox &, void > &rLink)
std::unique_ptr< weld::Label > m_xDocumentIndexFI
std::unique_ptr< weld::Label > m_xPreviewFI
void SetHideEmptyParagraphs(bool bSet)
std::unique_ptr< weld::Label > m_xAddressElementsFT
std::unique_ptr< weld::Label > m_xFieldFT
tools::Long Width() const
void SetAddressBlock(bool bSet)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
unsigned char sal_Bool
OUString GetFilter() const
const std::map< OUString, css::uno::Any > & GetGrabBag() const
virtual bool KeyInput(const KeyEvent &rKEvt) override
std::unique_ptr< weld::Button > m_xPrevSetIB
std::unique_ptr< EditView > m_xEditView
sal_Int32 GetResultSetPosition() const
virtual ~SwMailMergeAddressBlockPage() override
virtual void connect_focus_in(const Link< Widget &, void > &rLink)
virtual void set_active(int pos)=0
void SetFilter(OUString const &)
OUString SwResId(const char *pId)
Definition: swmodule.cxx:165
std::unique_ptr< weld::Label > m_xMatchingFI
std::unique_ptr< SwAddressPreview > m_xPreview
std::unique_ptr< weld::Button > m_xRemoveFieldIB
tools::Long Top() const
std::unique_ptr< weld::Button > m_xDownIB
sal_Int32 MoveResultSet(sal_Int32 nTarget)
virtual Size get_preferred_size() const =0
void SetText(const OUString &rStr)
css::uno::Sequence< OUString > CreateAssignments()
#define USER_DATA_SALUTATION
std::unique_ptr< weld::RadioButton > m_xAlwaysRB
css::uno::Sequence< OUString > GetColumnAssignment(const SwDBData &rDBData) const
virtual void set_label(const OUString &rText)=0
std::unique_ptr< weld::Button > m_xOK
Point PixelToLogic(const Point &rDevicePt) const
Point LogicToPixel(const Point &rLogicPt) const
std::unique_ptr< weld::Label > m_xSettingsFI
css::uno::Reference< css::sdbcx::XColumnsSupplier > GetColumnsSupplier() const
AddressMultiLineEdit(SwCustomizeAddressBlockDialog *pParent)
virtual bool KeyInput(const KeyEvent &rKEvt) override
const vcl::KeyCode & GetKeyCode() const
virtual bool MouseButtonDown(const MouseEvent &rMEvt) override
std::unique_ptr< weld::RadioButton > m_xDependentRB
void SetSettings(bool bIsCountry, const OUString &sCountry)
void EnableAddressBlock(bool bAll, bool bSelective)
#define HID_MM_ADDBLOCK_INSERT
Definition: helpids.h:147
SwCustomizeAddressBlockDialog * m_pParentDialog
std::unique_ptr< weld::Label > m_xDragFT
void SetAddressBlocks(const css::uno::Sequence< OUString > &rBlocks, sal_uInt16 nSelected)
constexpr sal_uInt16 KEY_ESCAPE
void removeElementAt(css::uno::Sequence< T > &_rSeq, sal_Int32 _nPos)
virtual bool canAdvance() const override
std::unique_ptr< weld::Button > m_xAssignPB
const T * HasItem(const ww8::PoolItems &rItems, sal_uInt16 eType)
bool isActive()
std::unique_ptr< weld::Button > m_xDeletePB
sal_Unicode GetCharCode() const
RET_OK
Reference< XExecutableDialog > m_xDialog
bool SetCursorLogicPosition(const Point &rPosition)
std::unique_ptr< weld::Button > m_xSettingsPB
virtual void EditViewSelectionChange() override
QPRO_FUNC_TYPE nType
#define USER_DATA_PUNCTUATION
OUString GetCurrentItem() const
void SetInvokeHandler(const Link< Timer *, void > &rLink)
void SetColumnAssignment(const SwDBData &rDBData, const css::uno::Sequence< OUString > &)
void Init(SwAssignFieldsDialog *pDialog, SwMailMergeConfigItem &rConfigItem)
void enableButtons(WizardButtonFlags _nWizardButtonFlags, bool _bEnable)
std::unique_ptr< weld::CheckButton > m_xHideEmptyParagraphsCB
Reference< XColumn > xColumn
std::unique_ptr< SwAddressPreview > m_xPreview
void SetAddressBlocks(const css::uno::Sequence< OUString > &rBlocks)
virtual css::uno::Reference< css::datatransfer::dnd::XDropTarget > GetDropTarget() override
#define USER_DATA_NONE
css::uno::Reference< css::sdbc::XDataSource > GetSource() const
std::unique_ptr< AddressMultiLineEdit > m_xDragED
bool HasItem(sal_Int32 nUserData)
std::unique_ptr< EditEngine > m_xEditEngine
css::uno::Sequence< OUString > m_aAddressBlocks
std::unique_ptr< weld::Container > m_xStep4
void setActive(bool bActive)
void append_text(const OUString &rStr)
DECL_LINK(MatchHdl_Impl, weld::ComboBox &, void)
bool IsAddressBlock() const
virtual ~SwCustomizeAddressBlockDialog() override
SharedConnection GetConnection() const
const EnumerationType m_eType
void InsertNewEntryAtPosition(const OUString &rStr, sal_uLong nPara, sal_uInt16 nIndex)
std::unique_ptr< SwAddressPreview > m_xSettings
char const sPreview[]
void ConnectSizeGroups(int nLabelWidth, int nComboBoxWidth, int nPreviewWidth)
SwMailMergeConfigItem & m_rConfigItem
virtual OutputDevice & EditViewOutputDevice() const override
virtual void set_size_request(int nWidth, int nHeight)=0
SwMailMergeConfigItem * m_rConfigItem
void SetModifyHdl(const Link< LinkParamNone *, void > &rModifyHdl)
#define HID_MM_ADDBLOCK_ELEMENTS
Definition: helpids.h:146
std::unique_ptr< weld::Label > m_xCurrentAddressFI
std::unique_ptr< weld::TreeView > m_xAddressElementsLB
static OUString FillData(const OUString &rAddress, SwMailMergeConfigItem const &rConfigItem, const css::uno::Sequence< OUString > *pAssignments=nullptr)
std::unique_ptr< weld::Entry > m_xCountryED
virtual void Activate() override
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
SwMailMergeConfigItem & m_rConfigItem
Link< LinkParamNone *, void > m_aModifyHdl
sal_uInt16 nPos
virtual bool commitPage(::vcl::WizardTypes::CommitPageReason _eReason) override
bool IsOutputToLetter() const
virtual OUString get_active_text() const =0
std::unique_ptr< weld::Button > m_xAddressListPB
std::unique_ptr< weld::Label > m_xAddressTitle
sal_Int32 nStartPos
static bool GetFormatDataFlavor(SotClipboardFormatId nFormat, css::datatransfer::DataFlavor &rFlavor)