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