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