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