Line data Source code
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 <vcl/layout.hxx>
25 : #include <vcl/txtattr.hxx>
26 : #include <vcl/xtextedt.hxx>
27 : #include <vcl/builderfactory.hxx>
28 : #include <mmconfigitem.hxx>
29 : #include <com/sun/star/container/XNameAccess.hpp>
30 : #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
31 : #include <com/sun/star/sdb/XColumn.hpp>
32 : #include <comphelper/string.hxx>
33 : #include <svtools/treelistentry.hxx>
34 :
35 : #include <vector>
36 : #include <boost/scoped_ptr.hpp>
37 : #include <globals.hrc>
38 : #include <dbui.hrc>
39 : #include <helpid.h>
40 :
41 : using namespace svt;
42 : using namespace ::com::sun::star;
43 : using namespace ::com::sun::star::container;
44 : using namespace ::com::sun::star::sdb;
45 : using namespace ::com::sun::star::sdbc;
46 : using namespace ::com::sun::star::sdbcx;
47 :
48 0 : static void lcl_Move(Control* pCtrl, long nYOffset)
49 : {
50 0 : Point aPos(pCtrl->GetPosPixel());
51 0 : aPos.Y() += nYOffset;
52 0 : pCtrl->SetPosPixel(aPos);
53 0 : }
54 :
55 0 : SwMailMergeAddressBlockPage::SwMailMergeAddressBlockPage( SwMailMergeWizard* _pParent) :
56 : svt::OWizardPage(_pParent, "MMAddressBlockPage",
57 : "modules/swriter/ui/mmaddressblockpage.ui")
58 0 : , m_pWizard(_pParent)
59 : {
60 0 : get(m_pAddressListPB, "addresslist");
61 0 : get(m_pCurrentAddressFI, "currentaddress");
62 0 : get(m_pStep2, "step2");
63 0 : get(m_pStep3, "step3");
64 0 : get(m_pStep4, "step4");
65 0 : get(m_pSettingsFI, "settingsft");
66 0 : get(m_pAddressCB, "address");
67 0 : get(m_pSettingsWIN, "settingspreview");
68 0 : Size aSize(LogicToPixel(Size(164 , 45), MAP_APPFONT));
69 0 : m_pSettingsWIN->set_width_request(aSize.Width());
70 0 : m_pSettingsWIN->set_height_request(aSize.Height());
71 0 : get(m_pSettingsPB, "settings");
72 0 : get(m_pHideEmptyParagraphsCB, "hideempty");
73 0 : get(m_pAssignPB, "assign");
74 0 : get(m_pPreviewWIN, "addresspreview");
75 0 : aSize = LogicToPixel(Size(176, 46), MAP_APPFONT);
76 0 : m_pPreviewWIN->set_width_request(aSize.Width());
77 0 : m_pPreviewWIN->set_height_request(aSize.Height());
78 0 : get(m_pDocumentIndexFI, "documentindex");
79 0 : get(m_pPrevSetIB, "prev");
80 0 : get(m_pNextSetIB, "next");
81 0 : m_sDocument = m_pDocumentIndexFI->GetText();
82 0 : m_sChangeAddress = get<Button>("differentlist")->GetText();
83 :
84 0 : m_sCurrentAddress = m_pCurrentAddressFI->GetText();
85 0 : m_pAddressListPB->SetClickHdl(LINK(this, SwMailMergeAddressBlockPage, AddressListHdl_Impl));
86 0 : m_pSettingsPB->SetClickHdl(LINK(this, SwMailMergeAddressBlockPage, SettingsHdl_Impl));
87 0 : m_pAssignPB->SetClickHdl(LINK(this, SwMailMergeAddressBlockPage, AssignHdl_Impl ));
88 0 : m_pAddressCB->SetClickHdl(LINK(this, SwMailMergeAddressBlockPage, AddressBlockHdl_Impl));
89 0 : m_pSettingsWIN->SetSelectHdl(LINK(this, SwMailMergeAddressBlockPage, AddressBlockSelectHdl_Impl));
90 0 : m_pHideEmptyParagraphsCB->SetClickHdl(LINK(this, SwMailMergeAddressBlockPage, HideParagraphsHdl_Impl));
91 :
92 0 : Link<> aLink = LINK(this, SwMailMergeAddressBlockPage, InsertDataHdl_Impl);
93 0 : m_pPrevSetIB->SetClickHdl(aLink);
94 0 : m_pNextSetIB->SetClickHdl(aLink);
95 0 : }
96 :
97 0 : SwMailMergeAddressBlockPage::~SwMailMergeAddressBlockPage()
98 : {
99 0 : disposeOnce();
100 0 : }
101 :
102 0 : void SwMailMergeAddressBlockPage::dispose()
103 : {
104 0 : m_pAddressListPB.clear();
105 0 : m_pCurrentAddressFI.clear();
106 0 : m_pStep2.clear();
107 0 : m_pStep3.clear();
108 0 : m_pStep4.clear();
109 0 : m_pSettingsFI.clear();
110 0 : m_pAddressCB.clear();
111 0 : m_pSettingsWIN.clear();
112 0 : m_pSettingsPB.clear();
113 0 : m_pHideEmptyParagraphsCB.clear();
114 0 : m_pAssignPB.clear();
115 0 : m_pPreviewWIN.clear();
116 0 : m_pDocumentIndexFI.clear();
117 0 : m_pPrevSetIB.clear();
118 0 : m_pNextSetIB.clear();
119 0 : m_pWizard.clear();
120 0 : svt::OWizardPage::dispose();
121 0 : }
122 :
123 0 : bool SwMailMergeAddressBlockPage::canAdvance() const
124 : {
125 0 : return m_pWizard->GetConfigItem().GetResultSet().is();
126 : }
127 :
128 0 : void SwMailMergeAddressBlockPage::ActivatePage()
129 : {
130 0 : SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
131 0 : bool bIsLetter = rConfigItem.IsOutputToLetter();
132 :
133 : //no address block is created for e-Mail
134 0 : m_pStep2->Show(bIsLetter);
135 0 : m_pStep3->Show(bIsLetter);
136 0 : m_pStep4->Show(bIsLetter);
137 :
138 0 : if (bIsLetter)
139 : {
140 0 : m_pHideEmptyParagraphsCB->Check( rConfigItem.IsHideEmptyParagraphs() );
141 0 : m_pDocumentIndexFI->SetText(m_sDocument.replaceFirst("%1", "1"));
142 :
143 0 : m_pSettingsWIN->Clear();
144 : const uno::Sequence< OUString> aBlocks =
145 0 : m_pWizard->GetConfigItem().GetAddressBlocks();
146 0 : for(sal_Int32 nAddress = 0; nAddress < aBlocks.getLength(); ++nAddress)
147 0 : m_pSettingsWIN->AddAddress(aBlocks[nAddress]);
148 0 : m_pSettingsWIN->SelectAddress((sal_uInt16)rConfigItem.GetCurrentAddressBlockIndex());
149 0 : m_pAddressCB->Check(rConfigItem.IsAddressBlock());
150 0 : AddressBlockHdl_Impl(m_pAddressCB);
151 0 : m_pSettingsWIN->SetLayout(1, 2);
152 0 : InsertDataHdl_Impl(0);
153 : }
154 0 : }
155 :
156 0 : bool SwMailMergeAddressBlockPage::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
157 : {
158 0 : if ( ::svt::WizardTypes::eTravelForward == _eReason && !m_pWizard->GetConfigItem().GetResultSet().is() )
159 0 : return false;
160 0 : return true;
161 : }
162 :
163 0 : IMPL_LINK_NOARG(SwMailMergeAddressBlockPage, AddressListHdl_Impl)
164 : {
165 : try
166 : {
167 0 : VclPtrInstance< SwAddressListDialog > xAddrDialog(this);
168 0 : if(RET_OK == xAddrDialog->Execute())
169 : {
170 0 : SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
171 : rConfigItem.SetCurrentConnection(
172 : xAddrDialog->GetSource(),
173 : xAddrDialog->GetConnection(),
174 : xAddrDialog->GetColumnsSupplier(),
175 0 : xAddrDialog->GetDBData());
176 0 : OUString sFilter = xAddrDialog->GetFilter();
177 0 : rConfigItem.SetFilter( sFilter );
178 0 : InsertDataHdl_Impl(0);
179 0 : GetWizard()->UpdateRoadmap();
180 0 : GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
181 0 : }
182 : }
183 0 : catch (const uno::Exception& e)
184 : {
185 : OSL_FAIL(OUStringToOString(e.Message, osl_getThreadTextEncoding()).getStr());
186 0 : ScopedVclPtrInstance<MessageDialog>::Create(this, e.Message)->Execute();
187 : }
188 0 : return 0;
189 : }
190 :
191 0 : IMPL_LINK(SwMailMergeAddressBlockPage, SettingsHdl_Impl, PushButton*, pButton)
192 : {
193 : VclPtr<SwSelectAddressBlockDialog> pDlg(
194 0 : VclPtr<SwSelectAddressBlockDialog>::Create(pButton, m_pWizard->GetConfigItem()));
195 0 : SwMailMergeConfigItem& rConfig = m_pWizard->GetConfigItem();
196 0 : pDlg->SetAddressBlocks(rConfig.GetAddressBlocks(), m_pSettingsWIN->GetSelectedAddress());
197 0 : pDlg->SetSettings(rConfig.IsIncludeCountry(), rConfig.GetExcludeCountry());
198 0 : if(RET_OK == pDlg->Execute())
199 : {
200 : //the dialog provides the selected address at the first position!
201 : const uno::Sequence< OUString> aBlocks =
202 0 : pDlg->GetAddressBlocks();
203 0 : rConfig.SetAddressBlocks(aBlocks);
204 0 : m_pSettingsWIN->Clear();
205 0 : for(sal_Int32 nAddress = 0; nAddress < aBlocks.getLength(); ++nAddress)
206 0 : m_pSettingsWIN->AddAddress(aBlocks[nAddress]);
207 0 : m_pSettingsWIN->SelectAddress(0);
208 0 : m_pSettingsWIN->Invalidate(); // #i40408
209 0 : rConfig.SetCountrySettings(pDlg->IsIncludeCountry(), pDlg->GetCountry());
210 0 : InsertDataHdl_Impl(0);
211 : }
212 0 : pDlg.reset();
213 0 : GetWizard()->UpdateRoadmap();
214 0 : GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
215 0 : return 0;
216 : }
217 :
218 0 : IMPL_LINK(SwMailMergeAddressBlockPage, AssignHdl_Impl, PushButton*, pButton)
219 : {
220 0 : SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
221 0 : const sal_uInt16 nSel = m_pSettingsWIN->GetSelectedAddress();
222 0 : const uno::Sequence< OUString> aBlocks = rConfigItem.GetAddressBlocks();
223 : VclPtr<SwAssignFieldsDialog> pDlg(
224 0 : VclPtr<SwAssignFieldsDialog>::Create(pButton, m_pWizard->GetConfigItem(), aBlocks[nSel], true));
225 0 : if(RET_OK == pDlg->Execute())
226 : {
227 : //preview update
228 0 : InsertDataHdl_Impl(0);
229 0 : GetWizard()->UpdateRoadmap();
230 0 : GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
231 : }
232 0 : return 0;
233 : }
234 :
235 0 : void SwMailMergeAddressBlockPage::EnableAddressBlock(bool bAll, bool bSelective)
236 : {
237 0 : m_pSettingsFI->Enable(bAll);
238 0 : m_pAddressCB->Enable(bAll);
239 0 : bSelective &= bAll;
240 0 : m_pHideEmptyParagraphsCB->Enable(bSelective);
241 0 : m_pSettingsWIN->Enable(bSelective);
242 0 : m_pSettingsPB->Enable(bSelective);
243 0 : m_pStep3->Enable(bSelective);
244 0 : m_pStep4->Enable(bSelective);
245 0 : }
246 :
247 0 : IMPL_LINK(SwMailMergeAddressBlockPage, AddressBlockHdl_Impl, CheckBox*, pBox)
248 : {
249 0 : EnableAddressBlock(pBox->IsEnabled(), pBox->IsChecked());
250 0 : SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
251 0 : rConfigItem.SetAddressBlock(m_pAddressCB->IsChecked());
252 0 : m_pWizard->UpdateRoadmap();
253 0 : return 0;
254 : }
255 :
256 0 : IMPL_LINK_NOARG(SwMailMergeAddressBlockPage, AddressBlockSelectHdl_Impl)
257 : {
258 0 : const sal_uInt16 nSel = m_pSettingsWIN->GetSelectedAddress();
259 : const uno::Sequence< OUString> aBlocks =
260 0 : m_pWizard->GetConfigItem().GetAddressBlocks();
261 0 : m_pPreviewWIN->SetAddress(SwAddressPreview::FillData(aBlocks[nSel],
262 0 : m_pWizard->GetConfigItem()));
263 0 : m_pWizard->GetConfigItem().SetCurrentAddressBlockIndex( nSel );
264 0 : GetWizard()->UpdateRoadmap();
265 0 : GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
266 0 : return 0;
267 : }
268 :
269 0 : IMPL_LINK(SwMailMergeAddressBlockPage, HideParagraphsHdl_Impl, CheckBox*, pBox)
270 : {
271 0 : SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
272 0 : rConfigItem.SetHideEmptyParagraphs( pBox->IsChecked() );
273 0 : return 0;
274 : }
275 :
276 0 : IMPL_LINK(SwMailMergeAddressBlockPage, InsertDataHdl_Impl, ImageButton*, pButton)
277 : {
278 : //if no pButton is given, the first set has to be pre-set
279 0 : SwMailMergeConfigItem& rConfig = m_pWizard->GetConfigItem();
280 0 : m_pWizard->EnterWait();
281 0 : if(!pButton)
282 : {
283 0 : rConfig.GetResultSet();
284 : }
285 : else
286 : {
287 0 : bool bNext = pButton == m_pNextSetIB;
288 0 : sal_Int32 nPos = rConfig.GetResultSetPosition();
289 0 : rConfig.MoveResultSet( bNext ? ++nPos : --nPos);
290 : }
291 0 : m_pWizard->LeaveWait();
292 0 : sal_Int32 nPos = rConfig.GetResultSetPosition();
293 0 : bool bEnable = true;
294 0 : if(nPos < 1)
295 : {
296 0 : bEnable = false;
297 0 : nPos = 1;
298 : }
299 : else
300 : {
301 : //if output type is letter
302 0 : if(m_pSettingsWIN->IsVisible())
303 : {
304 : //Fill data into preview
305 0 : const sal_uInt16 nSel = m_pSettingsWIN->GetSelectedAddress();
306 : const uno::Sequence< OUString> aBlocks =
307 0 : m_pWizard->GetConfigItem().GetAddressBlocks();
308 0 : m_pPreviewWIN->SetAddress(SwAddressPreview::FillData(aBlocks[nSel], rConfig));
309 : }
310 : }
311 0 : m_pPrevSetIB->Enable(bEnable);
312 0 : m_pDocumentIndexFI->SetText(m_sDocument.replaceFirst("%1", OUString::number(nPos)));
313 :
314 0 : GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
315 0 : bool bHasResultSet = rConfig.GetResultSet().is();
316 0 : m_pCurrentAddressFI->Show(bHasResultSet);
317 0 : if(bHasResultSet)
318 : {
319 0 : m_pCurrentAddressFI->SetText(m_sCurrentAddress.replaceFirst("%1", rConfig.GetCurrentDBData().sDataSource));
320 0 : m_pAddressListPB->SetText(m_sChangeAddress);
321 : }
322 0 : EnableAddressBlock(bHasResultSet, m_pAddressCB->IsChecked());
323 0 : return 0;
324 : }
325 :
326 0 : SwSelectAddressBlockDialog::SwSelectAddressBlockDialog(
327 : vcl::Window* pParent, SwMailMergeConfigItem& rConfig)
328 : : SfxModalDialog(pParent, "SelectBlockDialog",
329 : "modules/swriter/ui/selectblockdialog.ui")
330 0 : , m_rConfig(rConfig)
331 : {
332 0 : get(m_pPreview, "preview");
333 0 : Size aSize(m_pPreview->LogicToPixel(Size(192, 100), MAP_APPFONT));
334 0 : m_pPreview->set_width_request(aSize.Width());
335 0 : m_pPreview->set_height_request(aSize.Height());
336 0 : get(m_pNewPB, "new");
337 0 : get(m_pCustomizePB, "edit");
338 0 : get(m_pDeletePB, "delete");
339 0 : get(m_pNeverRB, "never");
340 0 : get(m_pAlwaysRB, "always");
341 0 : get(m_pDependentRB, "dependent");
342 0 : get(m_pCountryED, "country");
343 :
344 0 : Link<> aCustomizeHdl = LINK(this, SwSelectAddressBlockDialog, NewCustomizeHdl_Impl);
345 0 : m_pNewPB->SetClickHdl(aCustomizeHdl);
346 0 : m_pCustomizePB->SetClickHdl(aCustomizeHdl);
347 :
348 0 : m_pDeletePB->SetClickHdl(LINK(this, SwSelectAddressBlockDialog, DeleteHdl_Impl));
349 :
350 0 : Link<> aLk = LINK(this, SwSelectAddressBlockDialog, IncludeHdl_Impl);
351 0 : m_pNeverRB->SetClickHdl(aLk);
352 0 : m_pAlwaysRB->SetClickHdl(aLk);
353 0 : m_pDependentRB->SetClickHdl(aLk);
354 0 : m_pPreview->SetLayout(2, 2);
355 0 : m_pPreview->EnableScrollBar();
356 0 : }
357 :
358 0 : SwSelectAddressBlockDialog::~SwSelectAddressBlockDialog()
359 : {
360 0 : disposeOnce();
361 0 : }
362 :
363 0 : void SwSelectAddressBlockDialog::dispose()
364 : {
365 0 : m_pPreview.clear();
366 0 : m_pNewPB.clear();
367 0 : m_pCustomizePB.clear();
368 0 : m_pDeletePB.clear();
369 0 : m_pNeverRB.clear();
370 0 : m_pAlwaysRB.clear();
371 0 : m_pDependentRB.clear();
372 0 : m_pCountryED.clear();
373 0 : SfxModalDialog::dispose();
374 0 : }
375 :
376 0 : void SwSelectAddressBlockDialog::SetAddressBlocks(const uno::Sequence< OUString>& rBlocks,
377 : sal_uInt16 nSelectedAddress)
378 : {
379 0 : m_aAddressBlocks = rBlocks;
380 0 : for(sal_Int32 nAddress = 0; nAddress < m_aAddressBlocks.getLength(); ++nAddress)
381 0 : m_pPreview->AddAddress(m_aAddressBlocks[nAddress]);
382 0 : m_pPreview->SelectAddress(nSelectedAddress);
383 0 : }
384 :
385 : // return the address blocks and put the selected one to the first position
386 0 : const uno::Sequence< OUString >& SwSelectAddressBlockDialog::GetAddressBlocks()
387 : {
388 : //put the selected block to the first position
389 0 : const sal_Int32 nSelect = static_cast<sal_Int32>(m_pPreview->GetSelectedAddress());
390 0 : if(nSelect)
391 : {
392 0 : uno::Sequence< OUString >aTemp = m_aAddressBlocks;
393 0 : OUString* pTemp = aTemp.getArray();
394 0 : pTemp[0] = m_aAddressBlocks[nSelect];
395 0 : sal_Int32 nIndex = 0;
396 0 : const sal_Int32 nNumBlocks = m_aAddressBlocks.getLength();
397 0 : for(sal_Int32 nAddress = 1; nAddress < nNumBlocks; ++nAddress)
398 : {
399 0 : if(nIndex == nSelect)
400 0 : ++nIndex;
401 0 : pTemp[nAddress] = m_aAddressBlocks[nIndex];
402 0 : nIndex++;
403 : }
404 0 : m_aAddressBlocks = aTemp;
405 : }
406 0 : return m_aAddressBlocks;
407 : }
408 :
409 0 : void SwSelectAddressBlockDialog::SetSettings(
410 : bool bIsCountry, const OUString& rCountry)
411 : {
412 0 : RadioButton *pActive = m_pNeverRB;
413 0 : if(bIsCountry)
414 : {
415 0 : pActive = !rCountry.isEmpty() ? m_pDependentRB : m_pAlwaysRB;
416 0 : m_pCountryED->SetText(rCountry);
417 : }
418 0 : pActive->Check();
419 0 : IncludeHdl_Impl(pActive);
420 0 : m_pDeletePB->Enable(m_aAddressBlocks.getLength() > 1);
421 0 : }
422 :
423 0 : OUString SwSelectAddressBlockDialog::GetCountry() const
424 : {
425 0 : if(m_pDependentRB->IsChecked())
426 0 : return m_pCountryED->GetText();
427 0 : return OUString();
428 : }
429 :
430 0 : IMPL_LINK(SwSelectAddressBlockDialog, DeleteHdl_Impl, PushButton*, pButton)
431 : {
432 0 : if(m_aAddressBlocks.getLength())
433 : {
434 0 : const sal_Int32 nSelected = static_cast<sal_Int32>(m_pPreview->GetSelectedAddress());
435 0 : OUString* pAddressBlocks = m_aAddressBlocks.getArray();
436 0 : sal_Int32 nSource = 0;
437 0 : for(sal_Int32 nTarget = 0; nTarget < m_aAddressBlocks.getLength() - 1; nTarget++)
438 : {
439 0 : if(nSource == nSelected)
440 0 : ++nSource;
441 0 : pAddressBlocks[nTarget] = pAddressBlocks[nSource++];
442 : }
443 0 : m_aAddressBlocks.realloc(m_aAddressBlocks.getLength() - 1);
444 0 : if(m_aAddressBlocks.getLength() <= 1)
445 0 : pButton->Enable(false);
446 0 : m_pPreview->RemoveSelectedAddress();
447 : }
448 0 : return 0;
449 : }
450 :
451 0 : IMPL_LINK(SwSelectAddressBlockDialog, NewCustomizeHdl_Impl, PushButton*, pButton)
452 : {
453 0 : bool bCustomize = pButton == m_pCustomizePB;
454 : SwCustomizeAddressBlockDialog::DialogType nType = bCustomize ?
455 : SwCustomizeAddressBlockDialog::ADDRESSBLOCK_EDIT :
456 0 : SwCustomizeAddressBlockDialog::ADDRESSBLOCK_NEW;
457 : VclPtr<SwCustomizeAddressBlockDialog> pDlg(
458 0 : VclPtr<SwCustomizeAddressBlockDialog>::Create(pButton,m_rConfig,nType));
459 0 : if(bCustomize)
460 : {
461 0 : pDlg->SetAddress(m_aAddressBlocks[m_pPreview->GetSelectedAddress()]);
462 : }
463 0 : if(RET_OK == pDlg->Execute())
464 : {
465 0 : const OUString sNew = pDlg->GetAddress();
466 0 : if(bCustomize)
467 : {
468 0 : m_pPreview->ReplaceSelectedAddress(sNew);
469 0 : m_aAddressBlocks[m_pPreview->GetSelectedAddress()] = sNew;
470 : }
471 : else
472 : {
473 0 : m_pPreview->AddAddress(sNew);
474 0 : m_aAddressBlocks.realloc(m_aAddressBlocks.getLength() + 1);
475 0 : const sal_Int32 nSelect = m_aAddressBlocks.getLength() - 1;
476 0 : m_aAddressBlocks[nSelect] = sNew;
477 0 : m_pPreview->SelectAddress(static_cast<sal_uInt16>(nSelect));
478 : }
479 0 : m_pDeletePB->Enable( m_aAddressBlocks.getLength() > 1);
480 : }
481 0 : return 0;
482 : }
483 :
484 0 : IMPL_LINK(SwSelectAddressBlockDialog, IncludeHdl_Impl, RadioButton*, pButton)
485 : {
486 0 : m_pCountryED->Enable(m_pDependentRB == pButton);
487 0 : return 0;
488 : }
489 :
490 : #define USER_DATA_SALUTATION -1
491 : #define USER_DATA_PUNCTUATION -2
492 : #define USER_DATA_TEXT -3
493 : #define USER_DATA_NONE -4
494 :
495 0 : SwCustomizeAddressBlockDialog::SwCustomizeAddressBlockDialog(
496 : vcl::Window* pParent, SwMailMergeConfigItem& rConfig, DialogType eType)
497 : : SfxModalDialog(pParent, "AddressBlockDialog",
498 : "modules/swriter/ui/addressblockdialog.ui")
499 : , m_aTextFilter("<>")
500 : , m_rConfigItem(rConfig)
501 0 : , m_eType(eType)
502 : {
503 0 : get(m_pOK, "ok");
504 0 : get(m_pPreviewWIN, "addrpreview");
505 0 : get(m_pFieldCB, "custom");
506 0 : m_pFieldCB->SetTextFilter(&m_aTextFilter);
507 0 : get(m_pFieldFT, "customft");
508 0 : get(m_pDownIB, "down");
509 0 : get(m_pRightIB, "right");
510 0 : get(m_pLeftIB, "left");
511 0 : get(m_pUpIB, "up");
512 0 : get(m_pDragED, "addressdest");
513 0 : m_pDragED->SetAddressDialog(this);
514 0 : get(m_pDragFT, "addressdestft");
515 0 : get(m_pRemoveFieldIB, "fromaddr");
516 0 : get(m_pInsertFieldIB, "toaddr");
517 0 : get(m_pAddressElementsLB, "addresses");
518 0 : m_pAddressElementsLB->set_height_request(16 * m_pAddressElementsLB->GetTextHeight());
519 0 : m_pAddressElementsLB->SetAddressDialog(this);
520 0 : get(m_pAddressElementsFT, "addressesft");
521 :
522 0 : if( eType >= GREETING_FEMALE )
523 : {
524 0 : m_pFieldFT->Show();
525 0 : m_pFieldCB->Show();
526 0 : SvTreeListEntry* pEntry = m_pAddressElementsLB->InsertEntry(SW_RESSTR(ST_SALUTATION));
527 0 : pEntry->SetUserData(reinterpret_cast<void*>((sal_Int32)USER_DATA_SALUTATION) );
528 0 : pEntry = m_pAddressElementsLB->InsertEntry(SW_RESSTR(ST_PUNCTUATION));
529 0 : pEntry->SetUserData(reinterpret_cast<void*>((sal_Int32)USER_DATA_PUNCTUATION) );
530 0 : pEntry = m_pAddressElementsLB->InsertEntry(SW_RESSTR(ST_TEXT));
531 0 : pEntry->SetUserData(reinterpret_cast<void*>((sal_Int32)USER_DATA_TEXT) );
532 0 : ResStringArray aSalutArr(SW_RES(RA_SALUTATION));
533 0 : for(sal_uInt32 i = 0; i < aSalutArr.Count(); ++i)
534 0 : m_aSalutations.push_back(aSalutArr.GetString(i));
535 0 : ResStringArray aPunctArr(SW_RES(RA_PUNCTUATION));
536 0 : for(sal_uInt32 i = 0; i < aPunctArr.Count(); ++i)
537 0 : m_aPunctuations.push_back(aPunctArr.GetString(i));
538 0 : m_pDragED->SetText(" ");
539 0 : SetText(SW_RESSTR(eType == GREETING_MALE ? ST_TITLE_MALE : ST_TITLE_FEMALE));
540 0 : m_pAddressElementsFT->SetText(SW_RESSTR(ST_SALUTATIONELEMENTS));
541 0 : m_pInsertFieldIB->SetQuickHelpText(SW_RESSTR(ST_INSERTSALUTATIONFIELD));
542 0 : m_pRemoveFieldIB->SetQuickHelpText(SW_RESSTR(ST_REMOVESALUTATIONFIELD));
543 0 : m_pDragFT->SetText(SW_RESSTR(ST_DRAGSALUTATION));
544 : }
545 : else
546 : {
547 0 : if(eType == ADDRESSBLOCK_EDIT)
548 0 : SetText(SW_RESSTR(ST_TITLE_EDIT));
549 0 : m_pDragED->SetText("\n\n\n\n\n");
550 : }
551 :
552 0 : const ResStringArray& rHeaders = m_rConfigItem.GetDefaultAddressHeaders();
553 0 : for(sal_uInt32 i = 0; i < rHeaders.Count(); ++i)
554 : {
555 0 : SvTreeListEntry* pEntry = m_pAddressElementsLB->InsertEntry(rHeaders.GetString( i ));
556 0 : pEntry->SetUserData(reinterpret_cast<void*>((sal_IntPtr)i));
557 : }
558 0 : m_pOK->SetClickHdl(LINK(this, SwCustomizeAddressBlockDialog, OKHdl_Impl));
559 0 : m_pAddressElementsLB->SetSelectHdl(LINK(this, SwCustomizeAddressBlockDialog, ListBoxSelectHdl_Impl ));
560 0 : m_pDragED->SetModifyHdl(LINK(this, SwCustomizeAddressBlockDialog, EditModifyHdl_Impl));
561 0 : m_pDragED->SetSelectionChangedHdl( LINK( this, SwCustomizeAddressBlockDialog, SelectionChangedHdl_Impl));
562 0 : Link<> aFieldsLink = LINK(this, SwCustomizeAddressBlockDialog, FieldChangeHdl_Impl);
563 0 : m_pFieldCB->SetModifyHdl(aFieldsLink);
564 0 : m_pFieldCB->SetSelectHdl(aFieldsLink);
565 0 : Link<> aImgButtonHdl = LINK(this, SwCustomizeAddressBlockDialog, ImageButtonHdl_Impl);
566 0 : m_pInsertFieldIB->SetClickHdl(aImgButtonHdl);
567 0 : m_pRemoveFieldIB->SetClickHdl(aImgButtonHdl);
568 0 : m_pUpIB->SetClickHdl(aImgButtonHdl);
569 0 : m_pLeftIB->SetClickHdl(aImgButtonHdl);
570 0 : m_pRightIB->SetClickHdl(aImgButtonHdl);
571 0 : m_pDownIB->SetClickHdl(aImgButtonHdl);
572 0 : UpdateImageButtons_Impl();
573 0 : }
574 :
575 0 : SwCustomizeAddressBlockDialog::~SwCustomizeAddressBlockDialog()
576 : {
577 0 : disposeOnce();
578 0 : }
579 :
580 0 : void SwCustomizeAddressBlockDialog::dispose()
581 : {
582 0 : m_pAddressElementsFT.clear();
583 0 : m_pAddressElementsLB.clear();
584 0 : m_pInsertFieldIB.clear();
585 0 : m_pRemoveFieldIB.clear();
586 0 : m_pDragFT.clear();
587 0 : m_pDragED.clear();
588 0 : m_pUpIB.clear();
589 0 : m_pLeftIB.clear();
590 0 : m_pRightIB.clear();
591 0 : m_pDownIB.clear();
592 0 : m_pFieldFT.clear();
593 0 : m_pFieldCB.clear();
594 0 : m_pPreviewWIN.clear();
595 0 : m_pOK.clear();
596 0 : SfxModalDialog::dispose();
597 0 : }
598 :
599 0 : IMPL_LINK_NOARG(SwCustomizeAddressBlockDialog, OKHdl_Impl)
600 : {
601 0 : EndDialog(RET_OK);
602 0 : return 0;
603 : }
604 :
605 0 : IMPL_LINK(SwCustomizeAddressBlockDialog, ListBoxSelectHdl_Impl, DDListBox*, pBox)
606 : {
607 0 : sal_Int32 nUserData = (sal_Int32)reinterpret_cast<sal_IntPtr>(pBox->FirstSelected()->GetUserData());
608 : // Check if the selected entry is already in the address and then forbid inserting
609 0 : m_pInsertFieldIB->Enable(nUserData >= 0 || !HasItem_Impl(nUserData));
610 0 : return 0;
611 : }
612 :
613 0 : IMPL_LINK_NOARG(SwCustomizeAddressBlockDialog, EditModifyHdl_Impl)
614 : {
615 0 : m_pPreviewWIN->SetAddress(SwAddressPreview::FillData(GetAddress(), m_rConfigItem));
616 0 : UpdateImageButtons_Impl();
617 0 : return 0;
618 : }
619 :
620 0 : IMPL_LINK(SwCustomizeAddressBlockDialog, ImageButtonHdl_Impl, ImageButton*, pButton)
621 : {
622 0 : if (m_pInsertFieldIB == pButton)
623 : {
624 0 : SvTreeListEntry* pEntry = m_pAddressElementsLB->GetCurEntry();
625 0 : if(pEntry)
626 : {
627 0 : m_pDragED->InsertNewEntry("<" + m_pAddressElementsLB->GetEntryText(pEntry) + ">");
628 : }
629 : }
630 0 : else if (m_pRemoveFieldIB == pButton)
631 : {
632 0 : m_pDragED->RemoveCurrentEntry();
633 : }
634 : else
635 : {
636 0 : sal_uInt16 nMove = MOVE_ITEM_DOWN;
637 0 : if (m_pUpIB == pButton)
638 0 : nMove = MOVE_ITEM_UP;
639 0 : else if (m_pLeftIB == pButton)
640 0 : nMove = MOVE_ITEM_LEFT;
641 0 : else if (m_pRightIB == pButton)
642 0 : nMove = MOVE_ITEM_RIGHT;
643 0 : m_pDragED->MoveCurrentItem(nMove);
644 : }
645 0 : UpdateImageButtons_Impl();
646 0 : return 0;
647 : }
648 :
649 0 : sal_Int32 SwCustomizeAddressBlockDialog::GetSelectedItem_Impl()
650 : {
651 0 : sal_Int32 nRet = USER_DATA_NONE;
652 0 : const OUString sSelected = m_pDragED->GetCurrentItem();
653 0 : if(!sSelected.isEmpty())
654 0 : for(sal_uLong i = 0; i < m_pAddressElementsLB->GetEntryCount(); ++i)
655 : {
656 0 : SvTreeListEntry* pEntry = m_pAddressElementsLB->GetEntry(i);
657 0 : const OUString sEntry = m_pAddressElementsLB->GetEntryText(pEntry);
658 0 : if( sEntry == sSelected.copy( 1, sSelected.getLength() - 2 ) )
659 : {
660 0 : nRet = (sal_Int32)reinterpret_cast<sal_IntPtr>(pEntry->GetUserData());
661 0 : break;
662 : }
663 0 : }
664 0 : return nRet;
665 : }
666 :
667 0 : bool SwCustomizeAddressBlockDialog::HasItem_Impl(sal_Int32 nUserData)
668 : {
669 : //get the entry from the ListBox
670 0 : OUString sEntry;
671 0 : for(sal_uLong i = 0; i < m_pAddressElementsLB->GetEntryCount(); ++i)
672 : {
673 0 : SvTreeListEntry* pEntry = m_pAddressElementsLB->GetEntry(i);
674 0 : if((sal_Int32)reinterpret_cast<sal_IntPtr>(pEntry->GetUserData()) == nUserData)
675 : {
676 0 : sEntry = m_pAddressElementsLB->GetEntryText(pEntry);
677 0 : break;
678 : }
679 : }
680 : //search for this entry in the content
681 0 : return m_pDragED->GetText().indexOf("<" + sEntry + ">") >= 0;
682 : }
683 :
684 0 : IMPL_LINK(SwCustomizeAddressBlockDialog, SelectionChangedHdl_Impl, AddressMultiLineEdit*, pEdit)
685 : {
686 : // called in case the selection of the edit field changes.
687 : // determine selection - if it's one of the editable fields then
688 : // enable the related ComboBox and fill it
689 : static bool bOnEntry = false;
690 0 : if(bOnEntry)
691 0 : return 0;
692 :
693 0 : bOnEntry = true;
694 0 : sal_Int32 nSelected = GetSelectedItem_Impl();
695 0 : if(USER_DATA_NONE != nSelected)
696 0 : pEdit->SelectCurrentItem();
697 :
698 0 : if(m_pFieldCB->IsVisible() && (USER_DATA_NONE != nSelected) && (nSelected < 0))
699 : {
700 : //search in ListBox if it's one of the first entries
701 0 : OUString sSelect;
702 0 : ::std::vector<OUString>* pVector = 0;
703 0 : switch(nSelected) {
704 : case USER_DATA_SALUTATION:
705 0 : sSelect = m_sCurrentSalutation;
706 0 : pVector = &m_aSalutations;
707 0 : break;
708 : case USER_DATA_PUNCTUATION:
709 0 : sSelect = m_sCurrentPunctuation;
710 0 : pVector = &m_aPunctuations;
711 0 : break;
712 : case USER_DATA_TEXT:
713 0 : sSelect = m_sCurrentText;
714 0 : break;
715 : }
716 0 : m_pFieldCB->Clear();
717 0 : if(pVector) {
718 0 : ::std::vector<OUString>::iterator aIterator;
719 0 : for( aIterator = pVector->begin(); aIterator != pVector->end(); ++aIterator)
720 0 : m_pFieldCB->InsertEntry(*aIterator);
721 : }
722 0 : m_pFieldCB->SetText(sSelect);
723 0 : m_pFieldCB->Enable(true);
724 0 : m_pFieldFT->Enable(true);
725 : }
726 : else
727 : {
728 0 : m_pFieldCB->Enable(false);
729 0 : m_pFieldFT->Enable(false);
730 : }
731 :
732 0 : UpdateImageButtons_Impl();
733 0 : bOnEntry = false;
734 0 : return 0;
735 : }
736 :
737 0 : IMPL_LINK_NOARG(SwCustomizeAddressBlockDialog, FieldChangeHdl_Impl)
738 : {
739 : //changing the field content changes the related members, too
740 0 : sal_Int32 nSelected = GetSelectedItem_Impl();
741 0 : const OUString sContent = m_pFieldCB->GetText();
742 0 : switch(nSelected) {
743 : case USER_DATA_SALUTATION:
744 0 : m_sCurrentSalutation = sContent;
745 0 : break;
746 : case USER_DATA_PUNCTUATION:
747 0 : m_sCurrentPunctuation = sContent;
748 0 : break;
749 : case USER_DATA_TEXT:
750 0 : m_sCurrentText = sContent;
751 0 : break;
752 : }
753 0 : UpdateImageButtons_Impl();
754 0 : m_pPreviewWIN->SetAddress(GetAddress());
755 0 : m_pDragED->Modify();
756 0 : return 0;
757 : }
758 :
759 0 : void SwCustomizeAddressBlockDialog::UpdateImageButtons_Impl()
760 : {
761 0 : sal_uInt16 nMove = m_pDragED->IsCurrentItemMoveable();
762 0 : m_pUpIB->Enable(nMove & MOVE_ITEM_UP );
763 0 : m_pLeftIB->Enable(nMove & MOVE_ITEM_LEFT );
764 0 : m_pRightIB->Enable(nMove & MOVE_ITEM_RIGHT );
765 0 : m_pDownIB->Enable(nMove & MOVE_ITEM_DOWN);
766 0 : m_pRemoveFieldIB->Enable(m_pDragED->HasCurrentItem());
767 0 : SvTreeListEntry* pEntry = m_pAddressElementsLB->GetCurEntry();
768 0 : m_pInsertFieldIB->Enable( pEntry &&
769 0 : (0 < (sal_Int32)reinterpret_cast<sal_IntPtr>(pEntry->GetUserData()) || !m_pFieldCB->GetText().isEmpty()));
770 0 : }
771 :
772 0 : void SwCustomizeAddressBlockDialog::SetAddress(const OUString& rAddress)
773 : {
774 0 : m_pDragED->SetText( rAddress );
775 0 : UpdateImageButtons_Impl();
776 0 : m_pDragED->Modify();
777 0 : }
778 :
779 0 : OUString SwCustomizeAddressBlockDialog::GetAddress()
780 : {
781 0 : OUString sAddress(m_pDragED->GetAddress());
782 : //remove placeholders by the actual content
783 0 : if(m_pFieldFT->IsVisible())
784 : {
785 0 : for(sal_uLong i = 0; i < m_pAddressElementsLB->GetEntryCount(); ++i)
786 : {
787 0 : SvTreeListEntry* pEntry = m_pAddressElementsLB->GetEntry(i);
788 0 : const OUString sEntry = "<" + m_pAddressElementsLB->GetEntryText(pEntry) + ">";
789 0 : sal_Int32 nUserData = (sal_Int32)reinterpret_cast<sal_IntPtr>(pEntry->GetUserData());
790 0 : switch(nUserData)
791 : {
792 : case USER_DATA_SALUTATION:
793 0 : sAddress = sAddress.replaceFirst(sEntry, m_sCurrentSalutation);
794 0 : break;
795 : case USER_DATA_PUNCTUATION:
796 0 : sAddress = sAddress.replaceFirst(sEntry, m_sCurrentPunctuation);
797 0 : break;
798 : case USER_DATA_TEXT:
799 0 : sAddress = sAddress.replaceFirst(sEntry, m_sCurrentText);
800 0 : break;
801 : }
802 0 : }
803 : }
804 0 : return sAddress;
805 : }
806 :
807 : class SwAssignFieldsControl : public Control
808 : {
809 : friend class SwAssignFieldsDialog;
810 : VclPtr<ScrollBar> m_aVScroll;
811 : VclPtr<HeaderBar> m_aHeaderHB;
812 : VclPtr<Window> m_aWindow;
813 :
814 : ::std::vector<VclPtr<FixedText> > m_aFieldNames;
815 : ::std::vector<VclPtr<ListBox> > m_aMatches;
816 : ::std::vector<VclPtr<FixedText> > m_aPreviews;
817 :
818 : SwMailMergeConfigItem* m_rConfigItem;
819 :
820 : Link<> m_aModifyHdl;
821 :
822 : long m_nLBStartTopPos;
823 : long m_nYOffset;
824 : long m_nFirstYPos;
825 :
826 : DECL_LINK(ScrollHdl_Impl, ScrollBar*);
827 : DECL_LINK(MatchHdl_Impl, ListBox*);
828 : DECL_LINK(GotFocusHdl_Impl, ListBox*);
829 :
830 : virtual bool PreNotify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
831 : virtual void Command( const CommandEvent& rCEvt ) SAL_OVERRIDE;
832 :
833 : void MakeVisible( sal_Int32 nIndex );
834 : public:
835 : SwAssignFieldsControl(vcl::Window* pParent, WinBits nBits);
836 : virtual ~SwAssignFieldsControl();
837 : virtual void dispose() SAL_OVERRIDE;
838 :
839 : void Init(SwMailMergeConfigItem& rConfigItem);
840 0 : void SetModifyHdl(const Link<>& rModifyHdl)
841 : {
842 0 : m_aModifyHdl = rModifyHdl;
843 0 : m_aModifyHdl.Call(this);
844 0 : }
845 : virtual void Resize() SAL_OVERRIDE;
846 : virtual Size GetOptimalSize() const SAL_OVERRIDE;
847 : };
848 :
849 0 : VCL_BUILDER_FACTORY_ARGS(SwAssignFieldsControl, WB_BORDER)
850 :
851 0 : SwAssignFieldsControl::SwAssignFieldsControl(vcl::Window* pParent, WinBits nBits) :
852 : Control(pParent, nBits | WB_DIALOGCONTROL | WB_TABSTOP | WB_DIALOGCONTROL),
853 : m_aVScroll(VclPtr<ScrollBar>::Create(this)),
854 : m_aHeaderHB(VclPtr<HeaderBar>::Create(this, WB_BUTTONSTYLE | WB_BOTTOMBORDER)),
855 : m_aWindow(VclPtr<vcl::Window>::Create(this, WB_BORDER | WB_DIALOGCONTROL)),
856 : m_rConfigItem(NULL),
857 : m_nLBStartTopPos(0),
858 : m_nYOffset(0),
859 0 : m_nFirstYPos(0)
860 : {
861 0 : long nHBHeight = m_aHeaderHB->CalcWindowSizePixel().Height();
862 0 : Size aOutputSize(GetOutputSize());
863 0 : m_aVScroll->Show();
864 0 : m_aHeaderHB->SetSizePixel(
865 0 : Size(aOutputSize.Width(), nHBHeight));
866 0 : m_aHeaderHB->Show();
867 0 : m_aWindow->SetPosPixel(Point( 0, nHBHeight) );
868 0 : m_aWindow->SetSizePixel(Size(aOutputSize.Width() - m_aVScroll->GetSizePixel().Width(), aOutputSize.Height() - nHBHeight));
869 0 : m_aWindow->Show();
870 0 : }
871 :
872 0 : Size SwAssignFieldsControl::GetOptimalSize() const
873 : {
874 0 : return LogicToPixel(Size(248 , 120), MAP_APPFONT);
875 : }
876 :
877 0 : void SwAssignFieldsControl::Init(SwMailMergeConfigItem& rConfigItem)
878 : {
879 0 : m_rConfigItem = &rConfigItem;
880 0 : Size aOutputSize(GetOutputSize());
881 0 : long nHBHeight = m_aHeaderHB->CalcWindowSizePixel().Height();
882 :
883 : //get the name of the default headers
884 0 : const ResStringArray& rHeaders = rConfigItem.GetDefaultAddressHeaders();
885 : //get the actual data
886 0 : uno::Reference< XColumnsSupplier > xColsSupp( rConfigItem.GetResultSet(), uno::UNO_QUERY);
887 : //get the name of the actual columns
888 0 : uno::Reference <XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : 0;
889 0 : uno::Sequence< OUString > aFields;
890 0 : if(xColAccess.is())
891 0 : aFields = xColAccess->getElementNames();
892 0 : const OUString* pFields = aFields.getConstArray();
893 :
894 : //get the current assignment list
895 : //each position in this sequence matches the position in the header array rHeaders
896 : //if no assignment is available an empty sequence will be returned
897 0 : uno::Sequence< OUString> aAssignments = rConfigItem.GetColumnAssignment( rConfigItem.GetCurrentDBData() );
898 0 : Link<> aMatchHdl = LINK(this, SwAssignFieldsControl, MatchHdl_Impl);
899 0 : Link<> aFocusHdl = LINK(this, SwAssignFieldsControl, GotFocusHdl_Impl);
900 :
901 : //fill the controls
902 0 : long nControlWidth = aOutputSize.Width() / 3;
903 0 : long nControlHeight = -1;
904 0 : for(sal_uInt32 i = 0; i < rHeaders.Count(); ++i)
905 : {
906 0 : const OUString rHeader = rHeaders.GetString( i );
907 0 : VclPtr<FixedText> pNewText = VclPtr<FixedText>::Create(m_aWindow.get(), WB_VCENTER);
908 0 : pNewText->SetText("<" + rHeader + ">");
909 0 : VclPtr<ListBox> pNewLB = VclPtr<ListBox>::Create(m_aWindow.get(), WB_DROPDOWN | WB_VCENTER | WB_TABSTOP);
910 0 : pNewText->set_mnemonic_widget(pNewLB);
911 0 : pNewLB->InsertEntry(SW_RESSTR(SW_STR_NONE));
912 0 : pNewLB->SelectEntryPos(0);
913 0 : pNewLB->SetDropDownLineCount(5);
914 :
915 0 : if (nControlHeight == -1) //first time
916 : {
917 0 : nControlHeight = std::max(pNewLB->get_preferred_size().Height(),
918 0 : pNewText->get_preferred_size().Height());
919 : }
920 :
921 0 : for(sal_Int32 nField = 0; nField < aFields.getLength(); ++nField)
922 0 : pNewLB->InsertEntry(pFields[nField]);
923 0 : VclPtr<FixedText> pNewPreview = VclPtr<FixedText>::Create(m_aWindow.get(), WB_VCENTER);
924 0 : pNewText->SetSizePixel(Size(nControlWidth - 6, nControlHeight));
925 0 : pNewLB->SetSizePixel(Size(nControlWidth - 6, nControlHeight));
926 0 : pNewPreview->SetSizePixel(Size(aOutputSize.Width() - 2 * nControlWidth, nControlHeight));
927 : //select the ListBox
928 : //if there is an assignment
929 0 : if(static_cast<sal_uInt32>(aAssignments.getLength()) > i && !aAssignments[i].isEmpty())
930 0 : pNewLB->SelectEntry(aAssignments[i]);
931 : else //otherwise the current column name may match one of the db columns
932 0 : pNewLB->SelectEntry(rHeader);
933 : //then the preview can be filled accordingly
934 0 : if(xColAccess.is() && pNewLB->GetSelectEntryPos() > 0 &&
935 0 : xColAccess->hasByName(pNewLB->GetSelectEntry()))
936 : {
937 0 : uno::Any aCol = xColAccess->getByName(pNewLB->GetSelectEntry());
938 0 : uno::Reference< XColumn > xColumn;
939 0 : aCol >>= xColumn;
940 0 : if(xColumn.is())
941 : {
942 : try
943 : {
944 0 : pNewPreview->SetText(xColumn->getString());
945 : }
946 0 : catch (const SQLException&)
947 : {
948 : }
949 0 : }
950 : }
951 0 : if(!i)
952 : {
953 : //determine the vertical offset, use the bottom position of the ListBox
954 0 : m_nFirstYPos = m_nYOffset = pNewLB->GetPosPixel().Y();
955 0 : m_nLBStartTopPos = m_nYOffset;
956 0 : m_nYOffset += pNewLB->GetSizePixel().Height() + 6;
957 : }
958 :
959 0 : long nMove = m_nYOffset * i;
960 0 : pNewLB->SetSelectHdl(aMatchHdl);
961 0 : pNewLB->SetGetFocusHdl(aFocusHdl);
962 :
963 0 : m_aFieldNames.push_back(pNewText);
964 0 : m_aMatches.push_back(pNewLB);
965 0 : m_aPreviews.push_back(pNewPreview);
966 0 : pNewText->Show();
967 0 : pNewText->SetPosPixel(Point(6, nMove));
968 0 : pNewLB->Show();
969 0 : pNewLB->SetPosPixel(Point(nControlWidth, nMove));
970 0 : pNewPreview->Show();
971 0 : pNewPreview->SetPosPixel(Point(2 * nControlWidth + 6, nMove));
972 0 : }
973 0 : m_aVScroll->SetRange(Range(0, rHeaders.Count()));
974 0 : m_aVScroll->SetPageSize((aOutputSize.Height() - nHBHeight - m_nLBStartTopPos)/ m_nYOffset);
975 0 : m_aVScroll->EnableDrag();
976 0 : m_aVScroll->SetVisibleSize(m_aVScroll->GetPageSize());
977 0 : m_aVScroll->SetScrollHdl(LINK(this, SwAssignFieldsControl, ScrollHdl_Impl));
978 :
979 0 : m_aVScroll->SetPosPixel(Point(aOutputSize.Width() - m_aVScroll->GetSizePixel().Width(), nHBHeight));
980 0 : m_aVScroll->SetSizePixel(Size(m_aVScroll->GetSizePixel().Width(), aOutputSize.Height() - nHBHeight));
981 0 : }
982 :
983 0 : SwAssignFieldsControl::~SwAssignFieldsControl()
984 : {
985 0 : disposeOnce();
986 0 : }
987 :
988 0 : void SwAssignFieldsControl::dispose()
989 : {
990 0 : for(auto aFIIter = m_aFieldNames.begin(); aFIIter != m_aFieldNames.end(); ++aFIIter)
991 0 : aFIIter->disposeAndClear();
992 0 : for(auto aLBIter = m_aMatches.begin(); aLBIter != m_aMatches.end(); ++aLBIter)
993 0 : aLBIter->disposeAndClear();
994 0 : for(auto aFIIter = m_aPreviews.begin(); aFIIter != m_aPreviews.end(); ++aFIIter)
995 0 : aFIIter->disposeAndClear();
996 :
997 0 : m_aFieldNames.clear();
998 0 : m_aMatches.clear();
999 0 : m_aPreviews.clear();
1000 :
1001 0 : m_aVScroll.disposeAndClear();
1002 0 : m_aHeaderHB.disposeAndClear();
1003 0 : m_aWindow.disposeAndClear();
1004 0 : Control::dispose();
1005 0 : }
1006 :
1007 0 : void SwAssignFieldsControl::Resize()
1008 : {
1009 0 : Window::Resize();
1010 :
1011 0 : Size aOutputSize = GetOutputSize();
1012 0 : long nHBHeight = m_aHeaderHB->CalcWindowSizePixel().Height();
1013 :
1014 0 : m_aWindow->SetSizePixel(Size(aOutputSize.Width() - m_aVScroll->GetSizePixel().Width(), aOutputSize.Height() - nHBHeight));
1015 :
1016 0 : m_aVScroll->SetPosPixel(Point(aOutputSize.Width() - m_aVScroll->GetSizePixel().Width(), nHBHeight));
1017 0 : m_aVScroll->SetSizePixel(Size(m_aVScroll->GetSizePixel().Width(), aOutputSize.Height() - nHBHeight));
1018 0 : if(m_nYOffset)
1019 0 : m_aVScroll->SetPageSize((aOutputSize.Height() - nHBHeight - m_nLBStartTopPos)/ m_nYOffset);
1020 0 : m_aVScroll->SetVisibleSize(m_aVScroll->GetPageSize());
1021 0 : m_aVScroll->DoScroll(0);
1022 :
1023 0 : sal_Int32 nColWidth = aOutputSize.Width() / 3;
1024 0 : m_aHeaderHB->SetSizePixel(Size(aOutputSize.Width(), nHBHeight));
1025 0 : m_aHeaderHB->SetItemSize(1, nColWidth);
1026 0 : m_aHeaderHB->SetItemSize(2, nColWidth);
1027 0 : m_aHeaderHB->SetItemSize(3, nColWidth);
1028 :
1029 0 : if (m_aFieldNames.empty() || m_aMatches.empty())
1030 0 : return;
1031 :
1032 0 : long nControlHeight = std::max(m_aFieldNames[0]->get_preferred_size().Height(),
1033 0 : m_aMatches[0]->get_preferred_size().Height());
1034 :
1035 0 : for(auto aFIIter = m_aFieldNames.begin(); aFIIter != m_aFieldNames.end(); ++aFIIter)
1036 0 : (*aFIIter)->SetSizePixel(Size(nColWidth - 6, nControlHeight));
1037 0 : for(auto aLBIter = m_aMatches.begin(); aLBIter != m_aMatches.end(); ++aLBIter)
1038 : {
1039 0 : long nPosY = (*aLBIter)->GetPosPixel().Y();
1040 0 : (*aLBIter)->SetPosSizePixel(Point(nColWidth, nPosY), Size(nColWidth - 6, nControlHeight));
1041 : }
1042 0 : for(auto aFIIter = m_aPreviews.begin(); aFIIter != m_aPreviews.end(); ++aFIIter)
1043 : {
1044 0 : long nPosY = (*aFIIter)->GetPosPixel().Y();
1045 0 : (*aFIIter)->SetPosSizePixel(Point(2 * nColWidth + 6, nPosY), Size(nColWidth, nControlHeight));
1046 : }
1047 : }
1048 :
1049 0 : void SwAssignFieldsControl::Command( const CommandEvent& rCEvt )
1050 : {
1051 0 : switch ( rCEvt.GetCommand() )
1052 : {
1053 : case CommandEventId::Wheel:
1054 : case CommandEventId::StartAutoScroll:
1055 : case CommandEventId::AutoScroll:
1056 : {
1057 0 : const CommandWheelData* pWheelData = rCEvt.GetWheelData();
1058 0 : if(pWheelData && !pWheelData->IsHorz() && CommandWheelMode::ZOOM != pWheelData->GetMode())
1059 : {
1060 0 : HandleScrollCommand( rCEvt, 0, m_aVScroll.get() );
1061 : }
1062 : }
1063 0 : break;
1064 : default:
1065 0 : Control::Command(rCEvt);
1066 : }
1067 0 : }
1068 :
1069 0 : bool SwAssignFieldsControl::PreNotify( NotifyEvent& rNEvt )
1070 : {
1071 0 : if(rNEvt.GetType() == MouseNotifyEvent::COMMAND)
1072 : {
1073 0 : const CommandEvent* pCEvt = rNEvt.GetCommandEvent();
1074 0 : if( pCEvt->GetCommand() == CommandEventId::Wheel )
1075 : {
1076 0 : Command(*pCEvt);
1077 0 : return true;
1078 : }
1079 : }
1080 0 : return Control::PreNotify(rNEvt);
1081 : }
1082 :
1083 0 : void SwAssignFieldsControl::MakeVisible( sal_Int32 nIndex )
1084 : {
1085 0 : long nThumb = m_aVScroll->GetThumbPos();
1086 0 : long nPage = m_aVScroll->GetPageSize();
1087 0 : if(nThumb > nIndex)
1088 0 : m_aVScroll->SetThumbPos( nIndex );
1089 0 : else if( (nThumb + nPage) < nIndex)
1090 0 : m_aVScroll->SetThumbPos( nIndex - nPage );
1091 : else
1092 0 : return;
1093 0 : ScrollHdl_Impl( m_aVScroll.get() );
1094 : }
1095 :
1096 0 : IMPL_LINK(SwAssignFieldsControl, ScrollHdl_Impl, ScrollBar*, pScroll)
1097 : {
1098 0 : long nThumb = pScroll->GetThumbPos();
1099 : // the scrollbar moves on a per line basis
1100 : // the height of a line is stored in m_nYOffset
1101 : // nThumb determines which line has to be set at the top (m_nYOffset)
1102 : // The first line has to be -(nThumb * m_nYOffset) in the negative
1103 0 : long nMove = m_nFirstYPos - (*m_aMatches.begin())->GetPosPixel().Y() - (nThumb * m_nYOffset);
1104 :
1105 0 : SetUpdateMode(false);
1106 0 : for(auto aFIIter = m_aFieldNames.begin(); aFIIter != m_aFieldNames.end(); ++aFIIter)
1107 0 : lcl_Move(*aFIIter, nMove);
1108 0 : for(auto aLBIter = m_aMatches.begin(); aLBIter != m_aMatches.end(); ++aLBIter)
1109 0 : lcl_Move(*aLBIter, nMove);
1110 0 : for(auto aFIIter = m_aPreviews.begin(); aFIIter != m_aPreviews.end(); ++aFIIter)
1111 0 : lcl_Move(*aFIIter, nMove);
1112 0 : SetUpdateMode(true);
1113 :
1114 0 : return 0;
1115 : }
1116 :
1117 0 : IMPL_LINK(SwAssignFieldsControl, MatchHdl_Impl, ListBox*, pBox)
1118 : {
1119 0 : const OUString sColumn = pBox->GetSelectEntry();
1120 0 : uno::Reference< XColumnsSupplier > xColsSupp( m_rConfigItem->GetResultSet(), uno::UNO_QUERY);
1121 0 : uno::Reference <XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : 0;
1122 0 : OUString sPreview;
1123 0 : if(xColAccess.is() && xColAccess->hasByName(sColumn))
1124 : {
1125 0 : uno::Any aCol = xColAccess->getByName(sColumn);
1126 0 : uno::Reference< XColumn > xColumn;
1127 0 : aCol >>= xColumn;
1128 0 : if(xColumn.is())
1129 : {
1130 : try
1131 : {
1132 0 : sPreview = xColumn->getString();
1133 : }
1134 0 : catch (const sdbc::SQLException&)
1135 : {
1136 : }
1137 0 : }
1138 : }
1139 0 : sal_Int32 nIndex = 0;
1140 0 : for(auto aLBIter = m_aMatches.begin(); aLBIter != m_aMatches.end(); ++aLBIter, ++nIndex)
1141 : {
1142 0 : if(*aLBIter == pBox)
1143 : {
1144 0 : m_aPreviews[nIndex]->SetText(sPreview);
1145 0 : break;
1146 : }
1147 : }
1148 0 : m_aModifyHdl.Call(0);
1149 0 : return 0;
1150 : }
1151 :
1152 0 : IMPL_LINK(SwAssignFieldsControl, GotFocusHdl_Impl, ListBox*, pBox)
1153 : {
1154 0 : if(GetFocusFlags::Tab & pBox->GetGetFocusFlags())
1155 : {
1156 0 : sal_Int32 nIndex = 0;
1157 0 : for(auto aLBIter = m_aMatches.begin(); aLBIter != m_aMatches.end(); ++aLBIter, ++nIndex)
1158 : {
1159 0 : if(*aLBIter == pBox)
1160 : {
1161 0 : MakeVisible(nIndex);
1162 0 : break;
1163 : }
1164 : }
1165 : }
1166 0 : return 0;
1167 : }
1168 :
1169 0 : SwAssignFieldsDialog::SwAssignFieldsDialog(
1170 : vcl::Window* pParent, SwMailMergeConfigItem& rConfigItem,
1171 : const OUString& rPreview,
1172 : bool bIsAddressBlock) :
1173 : SfxModalDialog(pParent, "AssignFieldsDialog", "modules/swriter/ui/assignfieldsdialog.ui"),
1174 : m_sNone(SW_RESSTR(SW_STR_NONE)),
1175 : m_rPreviewString(rPreview),
1176 0 : m_rConfigItem(rConfigItem)
1177 : {
1178 0 : get(m_pMatchingFI, "MATCHING_LABEL");
1179 0 : get(m_pPreviewFI, "PREVIEW_LABEL");
1180 0 : get(m_pOK, "ok");
1181 0 : get(m_pPreviewWIN, "PREVIEW");
1182 0 : Size aSize(LogicToPixel(Size(248 , 45), MAP_APPFONT));
1183 0 : m_pPreviewWIN->set_width_request(aSize.Width());
1184 0 : m_pPreviewWIN->set_height_request(aSize.Height());
1185 0 : get(m_pFieldsControl, "FIELDS");
1186 0 : m_pFieldsControl->Init(rConfigItem);
1187 : //resize the HeaderBar
1188 0 : OUString sAddressElement( SW_RESSTR(ST_ADDRESSELEMENT) );
1189 0 : const OUString sMatchesTo( SW_RESSTR(ST_MATCHESTO) );
1190 0 : const OUString sPreview( SW_RESSTR(ST_PREVIEW) );
1191 0 : if(!bIsAddressBlock)
1192 : {
1193 0 : m_pPreviewFI->SetText(SW_RESSTR(ST_SALUTATIONPREVIEW));
1194 0 : m_pMatchingFI->SetText(SW_RESSTR(ST_SALUTATIONMATCHING));
1195 0 : sAddressElement = SW_RESSTR(ST_SALUTATIONELEMENT);
1196 : }
1197 :
1198 0 : Size aOutputSize(m_pFieldsControl->m_aHeaderHB->GetSizePixel());
1199 : sal_Int32 nFirstWidth;
1200 0 : sal_Int32 nSecondWidth = nFirstWidth = aOutputSize.Width() / 3;
1201 0 : const HeaderBarItemBits nHeadBits = HeaderBarItemBits::VCENTER | HeaderBarItemBits::FIXED| HeaderBarItemBits::FIXEDPOS;
1202 0 : m_pFieldsControl->m_aHeaderHB->InsertItem( 1, sAddressElement, nFirstWidth, nHeadBits|HeaderBarItemBits::LEFT);
1203 0 : m_pFieldsControl->m_aHeaderHB->InsertItem( 2, sMatchesTo, nSecondWidth, nHeadBits|HeaderBarItemBits::LEFT);
1204 0 : m_pFieldsControl->m_aHeaderHB->InsertItem( 3, sPreview,
1205 0 : aOutputSize.Width() - nFirstWidth - nSecondWidth, nHeadBits|HeaderBarItemBits::LEFT);
1206 :
1207 0 : m_pFieldsControl->SetModifyHdl(LINK(this, SwAssignFieldsDialog, AssignmentModifyHdl_Impl ));
1208 :
1209 0 : m_pMatchingFI->SetText(m_pMatchingFI->GetText().replaceAll("%1", sMatchesTo));
1210 :
1211 0 : m_pOK->SetClickHdl(LINK(this, SwAssignFieldsDialog, OkHdl_Impl));
1212 0 : }
1213 :
1214 0 : SwAssignFieldsDialog::~SwAssignFieldsDialog()
1215 : {
1216 0 : disposeOnce();
1217 0 : }
1218 :
1219 0 : void SwAssignFieldsDialog::dispose()
1220 : {
1221 0 : m_pMatchingFI.clear();
1222 0 : m_pFieldsControl.clear();
1223 0 : m_pPreviewFI.clear();
1224 0 : m_pPreviewWIN.clear();
1225 0 : m_pOK.clear();
1226 0 : SfxModalDialog::dispose();
1227 0 : }
1228 :
1229 0 : uno::Sequence< OUString > SwAssignFieldsDialog::CreateAssignments()
1230 : {
1231 : uno::Sequence< OUString > aAssignments(
1232 0 : m_rConfigItem.GetDefaultAddressHeaders().Count());
1233 0 : OUString* pAssignments = aAssignments.getArray();
1234 0 : sal_Int32 nIndex = 0;
1235 0 : for(auto aLBIter = m_pFieldsControl->m_aMatches.begin();
1236 0 : aLBIter != m_pFieldsControl->m_aMatches.end();
1237 : ++aLBIter, ++nIndex)
1238 : {
1239 0 : const OUString sSelect = (*aLBIter)->GetSelectEntry();
1240 0 : pAssignments[nIndex] = (m_sNone != sSelect) ? sSelect : OUString();
1241 0 : }
1242 0 : return aAssignments;
1243 : }
1244 :
1245 0 : IMPL_LINK_NOARG(SwAssignFieldsDialog, OkHdl_Impl)
1246 : {
1247 : m_rConfigItem.SetColumnAssignment(
1248 0 : m_rConfigItem.GetCurrentDBData(),
1249 0 : CreateAssignments() );
1250 0 : EndDialog(RET_OK);
1251 0 : return 0;
1252 : }
1253 :
1254 0 : IMPL_LINK_NOARG(SwAssignFieldsDialog, AssignmentModifyHdl_Impl)
1255 : {
1256 0 : uno::Sequence< OUString > aAssignments = CreateAssignments();
1257 : const OUString sPreview = SwAddressPreview::FillData(
1258 0 : m_rPreviewString, m_rConfigItem, &aAssignments);
1259 0 : m_pPreviewWIN->SetAddress(sPreview);
1260 0 : return 0;
1261 : }
1262 :
1263 0 : DDListBox::DDListBox(vcl::Window* pParent, WinBits nStyle)
1264 : : SvTreeListBox(pParent, nStyle)
1265 0 : , m_pParentDialog(NULL)
1266 : {
1267 0 : SetStyle( GetStyle() | /*WB_HASBUTTONS|WB_HASBUTTONSATROOT|*/
1268 0 : WB_CLIPCHILDREN );
1269 0 : SetSelectionMode( SINGLE_SELECTION );
1270 0 : SetDragDropMode( DragDropMode::CTRL_COPY );
1271 0 : EnableAsyncDrag(true);
1272 : // expand selection to the complete width of the ListBox
1273 0 : SetHighlightRange();
1274 0 : Show();
1275 :
1276 0 : }
1277 :
1278 0 : DDListBox::~DDListBox()
1279 : {
1280 0 : disposeOnce();
1281 0 : }
1282 :
1283 0 : void DDListBox::dispose()
1284 : {
1285 0 : m_pParentDialog.clear();
1286 0 : SvTreeListBox::dispose();
1287 0 : }
1288 :
1289 0 : VCL_BUILDER_DECL_FACTORY(DDListBox)
1290 : {
1291 0 : WinBits nWinStyle = WB_TABSTOP;
1292 0 : OString sBorder = VclBuilder::extractCustomProperty(rMap);
1293 0 : if (!sBorder.isEmpty())
1294 0 : nWinStyle |= WB_BORDER;
1295 0 : rRet = VclPtr<DDListBox>::Create(pParent, nWinStyle);
1296 0 : }
1297 :
1298 0 : void DDListBox::SetAddressDialog(SwCustomizeAddressBlockDialog *pParent)
1299 : {
1300 0 : m_pParentDialog = pParent;
1301 0 : }
1302 :
1303 0 : void DDListBox::StartDrag( sal_Int8 /*nAction*/, const Point& /*rPosPixel*/ )
1304 : {
1305 0 : SvTreeListEntry* pEntry = GetCurEntry();
1306 0 : if(pEntry)
1307 : {
1308 0 : ReleaseMouse();
1309 :
1310 0 : TransferDataContainer* pContainer = new TransferDataContainer;
1311 : uno::Reference<
1312 0 : datatransfer::XTransferable > xRef( pContainer );
1313 :
1314 0 : sal_Int32 nUserData = (sal_Int32)reinterpret_cast<sal_IntPtr>(pEntry->GetUserData());
1315 : //special entries can only be once in the address / greeting
1316 0 : if(nUserData >= 0 || !m_pParentDialog->HasItem_Impl(nUserData))
1317 : {
1318 0 : pContainer->CopyString( "<" + GetEntryText(pEntry) + ">" );
1319 0 : pContainer->StartDrag( this, DND_ACTION_COPY, GetDragFinishedHdl() );
1320 0 : }
1321 : }
1322 0 : }
1323 :
1324 0 : AddressMultiLineEdit::AddressMultiLineEdit(vcl::Window* pParent, WinBits nBits)
1325 : : VclMultiLineEdit(pParent, nBits)
1326 0 : , m_pParentDialog(NULL)
1327 : {
1328 0 : GetTextView()->SupportProtectAttribute(true);
1329 0 : StartListening(*GetTextEngine());
1330 0 : EnableFocusSelectionHide(false);
1331 0 : }
1332 :
1333 0 : AddressMultiLineEdit::~AddressMultiLineEdit()
1334 : {
1335 0 : disposeOnce();
1336 0 : }
1337 :
1338 0 : void AddressMultiLineEdit::dispose()
1339 : {
1340 0 : EndListening(*GetTextEngine());
1341 0 : m_pParentDialog.clear();
1342 0 : VclMultiLineEdit::dispose();
1343 0 : }
1344 :
1345 :
1346 0 : Size AddressMultiLineEdit::GetOptimalSize() const
1347 : {
1348 0 : return LogicToPixel(Size(160, 60), MAP_APPFONT);
1349 : }
1350 :
1351 0 : VCL_BUILDER_DECL_FACTORY(AddressMultiLineEdit)
1352 : {
1353 0 : WinBits nWinStyle = WB_LEFT|WB_TABSTOP;
1354 0 : OString sBorder = VclBuilder::extractCustomProperty(rMap);
1355 0 : if (!sBorder.isEmpty())
1356 0 : nWinStyle |= WB_BORDER;
1357 0 : rRet = VclPtr<AddressMultiLineEdit>::Create(pParent, nWinStyle);
1358 0 : }
1359 :
1360 0 : void AddressMultiLineEdit::SetAddressDialog(SwCustomizeAddressBlockDialog *pParent)
1361 : {
1362 0 : m_pParentDialog = pParent;
1363 0 : }
1364 :
1365 0 : void AddressMultiLineEdit::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
1366 : {
1367 0 : if (m_aSelectionLink.IsSet() && dynamic_cast<const TextHint*>(&rHint))
1368 : {
1369 0 : const TextHint& rTextHint = static_cast<const TextHint&>(rHint);
1370 0 : if (rTextHint.GetId() == TEXT_HINT_VIEWSELECTIONCHANGED ||
1371 0 : rTextHint.GetId() == TEXT_HINT_VIEWCARETCHANGED)
1372 : {
1373 0 : m_aSelectionLink.Call(this);
1374 : }
1375 : }
1376 0 : }
1377 :
1378 0 : bool AddressMultiLineEdit::PreNotify( NotifyEvent& rNEvt )
1379 : {
1380 0 : bool nHandled = false;
1381 0 : if( MouseNotifyEvent::KEYINPUT == rNEvt.GetType() &&
1382 0 : rNEvt.GetKeyEvent()->GetCharCode())
1383 : {
1384 0 : nHandled = true;
1385 : }
1386 0 : else if(MouseNotifyEvent::MOUSEBUTTONDOWN == rNEvt.GetType()) {
1387 0 : const MouseEvent *pMEvt = rNEvt.GetMouseEvent();
1388 0 : if(pMEvt->GetClicks() >= 2)
1389 0 : nHandled = true;
1390 : }
1391 0 : if(!nHandled)
1392 0 : nHandled = VclMultiLineEdit::PreNotify( rNEvt );
1393 0 : return nHandled;
1394 :
1395 : }
1396 :
1397 0 : void AddressMultiLineEdit::SetText( const OUString& rStr )
1398 : {
1399 0 : VclMultiLineEdit::SetText(rStr);
1400 : //set attributes to all address tokens
1401 :
1402 0 : ExtTextEngine* pTextEngine = GetTextEngine();
1403 0 : TextAttribProtect aProtectAttr;
1404 0 : sal_uLong nParaCount = pTextEngine->GetParagraphCount();
1405 0 : for(sal_uLong nPara = 0; nPara < nParaCount; ++nPara)
1406 : {
1407 0 : sal_Int32 nIndex = 0;
1408 0 : const OUString sPara = pTextEngine->GetText( nPara );
1409 0 : if(!sPara.isEmpty() && !sPara.endsWith(" "))
1410 : {
1411 0 : TextPaM aPaM(nPara, sPara.getLength());
1412 0 : pTextEngine->ReplaceText(TextSelection( aPaM ), " ");
1413 : }
1414 : while(true)
1415 : {
1416 0 : sal_Int32 nStart = sPara.indexOf( '<', nIndex );
1417 0 : sal_Int32 nEnd = nStart == -1 ? -1 : sPara.indexOf( '>', nStart );
1418 0 : nIndex = nEnd;
1419 0 : if(nStart != -1 && nEnd != -1)
1420 0 : pTextEngine->SetAttrib( aProtectAttr, nPara, nStart, nEnd + 1, false );
1421 : else
1422 : break;
1423 : }
1424 :
1425 0 : }
1426 : // add two empty paragraphs at the end
1427 0 : if(m_pParentDialog->m_eType == SwCustomizeAddressBlockDialog::ADDRESSBLOCK_NEW ||
1428 0 : m_pParentDialog->m_eType == SwCustomizeAddressBlockDialog::ADDRESSBLOCK_EDIT)
1429 : {
1430 0 : sal_Int32 nLastLen = pTextEngine->GetText(nParaCount - 1).getLength();
1431 0 : if(nLastLen)
1432 : {
1433 0 : TextPaM aPaM(nParaCount ? nParaCount - 1 : 0, nLastLen);
1434 0 : pTextEngine->ReplaceText(TextSelection( aPaM ), "\n \n ");
1435 : }
1436 0 : }
1437 0 : }
1438 :
1439 : // Insert the new entry in front of the entry at the beginning of the selection
1440 0 : void AddressMultiLineEdit::InsertNewEntry( const OUString& rStr )
1441 : {
1442 : // insert new entry after current selected one.
1443 0 : ExtTextView* pTextView = GetTextView();
1444 0 : const TextSelection& rSelection = pTextView->GetSelection();
1445 0 : sal_uLong nPara = rSelection.GetStart().GetPara();
1446 0 : sal_uInt16 nIndex = rSelection.GetEnd().GetIndex();
1447 0 : ExtTextEngine *pTextEngine = GetTextEngine();
1448 : const TextCharAttrib *pAttrib;
1449 0 : if(0 != (pAttrib = pTextEngine->FindCharAttrib( rSelection.GetStart(), TEXTATTR_PROTECTED )))
1450 0 : nIndex = pAttrib->GetEnd();
1451 0 : InsertNewEntryAtPosition( rStr, nPara, nIndex );
1452 :
1453 : // select the new entry
1454 0 : pAttrib = pTextEngine->FindCharAttrib(TextPaM(nPara, nIndex),TEXTATTR_PROTECTED);
1455 0 : const sal_uInt16 nEnd = pAttrib ? pAttrib->GetEnd() : nIndex;
1456 0 : TextSelection aEntrySel(TextPaM(nPara, nIndex), TextPaM(nPara, nEnd));
1457 0 : pTextView->SetSelection(aEntrySel);
1458 0 : Invalidate();
1459 0 : Modify();
1460 0 : }
1461 :
1462 0 : void AddressMultiLineEdit::InsertNewEntryAtPosition( const OUString& rStr, sal_uLong nPara, sal_uInt16 nIndex )
1463 : {
1464 0 : ExtTextEngine* pTextEngine = GetTextEngine();
1465 0 : TextPaM aInsertPos( nPara, nIndex );
1466 :
1467 0 : pTextEngine->ReplaceText( aInsertPos, rStr );
1468 :
1469 : //restore the attributes
1470 0 : SetText( GetAddress() );
1471 : //select the newly inserted/moved element
1472 0 : TextSelection aEntrySel(aInsertPos);
1473 0 : ExtTextView* pTextView = GetTextView();
1474 0 : pTextView->SetSelection(aEntrySel);
1475 0 : m_aSelectionLink.Call(this);
1476 0 : }
1477 :
1478 0 : void AddressMultiLineEdit::RemoveCurrentEntry()
1479 : {
1480 0 : ExtTextEngine* pTextEngine = GetTextEngine();
1481 0 : ExtTextView* pTextView = GetTextView();
1482 0 : const TextSelection& rSelection = pTextView->GetSelection();
1483 0 : const TextCharAttrib* pBeginAttrib = pTextEngine->FindCharAttrib( rSelection.GetStart(), TEXTATTR_PROTECTED );
1484 0 : if(pBeginAttrib &&
1485 0 : (pBeginAttrib->GetStart() <= rSelection.GetStart().GetIndex()
1486 0 : && pBeginAttrib->GetEnd() >= rSelection.GetEnd().GetIndex()))
1487 : {
1488 0 : sal_uLong nPara = rSelection.GetStart().GetPara();
1489 0 : TextSelection aEntrySel(TextPaM( nPara, pBeginAttrib->GetStart()), TextPaM(nPara, pBeginAttrib->GetEnd()));
1490 0 : pTextEngine->ReplaceText(aEntrySel, OUString());
1491 : //restore the attributes
1492 0 : SetText( GetAddress() );
1493 0 : Modify();
1494 : }
1495 0 : }
1496 :
1497 0 : void AddressMultiLineEdit::MoveCurrentItem(sal_uInt16 nMove)
1498 : {
1499 0 : ExtTextEngine* pTextEngine = GetTextEngine();
1500 0 : ExtTextView* pTextView = GetTextView();
1501 0 : const TextSelection& rSelection = pTextView->GetSelection();
1502 0 : const TextCharAttrib* pBeginAttrib = pTextEngine->FindCharAttrib( rSelection.GetStart(), TEXTATTR_PROTECTED );
1503 0 : if(pBeginAttrib &&
1504 0 : (pBeginAttrib->GetStart() <= rSelection.GetStart().GetIndex()
1505 0 : && pBeginAttrib->GetEnd() >= rSelection.GetEnd().GetIndex()))
1506 : {
1507 : //current item has been found
1508 0 : sal_uLong nPara = rSelection.GetStart().GetPara();
1509 0 : sal_uInt16 nIndex = pBeginAttrib->GetStart();
1510 0 : TextSelection aEntrySel(TextPaM( nPara, pBeginAttrib->GetStart()), TextPaM(nPara, pBeginAttrib->GetEnd()));
1511 0 : const OUString sCurrentItem = pTextEngine->GetText(aEntrySel);
1512 0 : pTextEngine->RemoveAttrib( nPara, *pBeginAttrib );
1513 0 : pTextEngine->ReplaceText(aEntrySel, OUString());
1514 0 : switch(nMove)
1515 : {
1516 : case MOVE_ITEM_LEFT :
1517 0 : if(nIndex)
1518 : {
1519 : //go left to find a predecessor or simple text
1520 0 : --nIndex;
1521 0 : const OUString sPara = pTextEngine->GetText( nPara );
1522 0 : sal_Int32 nSearchIndex = sPara.lastIndexOf( '>', nIndex+1 );
1523 0 : if( nSearchIndex != -1 && nSearchIndex == nIndex )
1524 : {
1525 0 : nSearchIndex = sPara.lastIndexOf( '<', nIndex );
1526 0 : if( nSearchIndex != -1 )
1527 0 : nIndex = nSearchIndex;
1528 0 : }
1529 : }
1530 0 : break;
1531 : case MOVE_ITEM_RIGHT:
1532 : {
1533 : //go right to find a successor or simple text
1534 0 : ++nIndex;
1535 0 : const TextCharAttrib* pEndAttrib = pTextEngine->FindCharAttrib( rSelection.GetStart(), TEXTATTR_PROTECTED );
1536 0 : if(pEndAttrib && pEndAttrib->GetEnd() >= nIndex)
1537 : {
1538 0 : nIndex = pEndAttrib->GetEnd();
1539 : }
1540 : }
1541 0 : break;
1542 : case MOVE_ITEM_UP :
1543 0 : --nPara;
1544 0 : nIndex = 0;
1545 0 : break;
1546 : case MOVE_ITEM_DOWN :
1547 0 : ++nPara;
1548 0 : nIndex = 0;
1549 0 : break;
1550 : }
1551 : //add a new paragraph if there is none yet
1552 0 : if(nPara >= pTextEngine->GetParagraphCount())
1553 : {
1554 :
1555 0 : TextPaM aTemp(nPara - 1, pTextEngine->GetTextLen( nPara - 1 ));
1556 0 : pTextEngine->ReplaceText(aTemp, "\n");
1557 : }
1558 0 : InsertNewEntryAtPosition( sCurrentItem, nPara, nIndex );
1559 :
1560 : // select the new entry [#i40817]
1561 0 : const TextCharAttrib *pAttrib = pTextEngine->FindCharAttrib(TextPaM(nPara, nIndex),TEXTATTR_PROTECTED);
1562 0 : if (pAttrib)
1563 0 : aEntrySel = TextSelection(TextPaM(nPara, nIndex), TextPaM(nPara, pAttrib->GetEnd()));
1564 0 : pTextView->SetSelection(aEntrySel);
1565 0 : Invalidate();
1566 0 : Modify();
1567 : }
1568 0 : }
1569 :
1570 0 : sal_uInt16 AddressMultiLineEdit::IsCurrentItemMoveable()
1571 : {
1572 0 : sal_uInt16 nRet = 0;
1573 0 : ExtTextEngine* pTextEngine = GetTextEngine();
1574 0 : ExtTextView* pTextView = GetTextView();
1575 0 : const TextSelection& rSelection = pTextView->GetSelection();
1576 0 : const TextCharAttrib* pBeginAttrib = pTextEngine->FindCharAttrib( rSelection.GetStart(), TEXTATTR_PROTECTED );
1577 0 : if(pBeginAttrib &&
1578 0 : (pBeginAttrib->GetStart() <= rSelection.GetStart().GetIndex()
1579 0 : && pBeginAttrib->GetEnd() >= rSelection.GetEnd().GetIndex()))
1580 : {
1581 0 : if(pBeginAttrib->GetStart())
1582 0 : nRet |= MOVE_ITEM_LEFT;
1583 : //if there is an entry it can always be move to the right and down
1584 0 : nRet |= MOVE_ITEM_RIGHT|MOVE_ITEM_DOWN;
1585 0 : if(rSelection.GetStart().GetPara() > 0)
1586 0 : nRet |= MOVE_ITEM_UP;
1587 : }
1588 0 : return nRet;
1589 : }
1590 :
1591 0 : bool AddressMultiLineEdit::HasCurrentItem()
1592 : {
1593 0 : ExtTextEngine* pTextEngine = GetTextEngine();
1594 0 : ExtTextView* pTextView = GetTextView();
1595 0 : const TextSelection& rSelection = pTextView->GetSelection();
1596 0 : const TextCharAttrib* pBeginAttrib = pTextEngine->FindCharAttrib( rSelection.GetStart(), TEXTATTR_PROTECTED );
1597 0 : return (pBeginAttrib &&
1598 0 : (pBeginAttrib->GetStart() <= rSelection.GetStart().GetIndex()
1599 0 : && pBeginAttrib->GetEnd() >= rSelection.GetEnd().GetIndex()));
1600 : }
1601 :
1602 0 : OUString AddressMultiLineEdit::GetCurrentItem()
1603 : {
1604 0 : ExtTextEngine* pTextEngine = GetTextEngine();
1605 0 : ExtTextView* pTextView = GetTextView();
1606 0 : const TextSelection& rSelection = pTextView->GetSelection();
1607 0 : const TextCharAttrib* pBeginAttrib = pTextEngine->FindCharAttrib( rSelection.GetStart(), TEXTATTR_PROTECTED );
1608 0 : if(pBeginAttrib &&
1609 0 : (pBeginAttrib->GetStart() <= rSelection.GetStart().GetIndex()
1610 0 : && pBeginAttrib->GetEnd() >= rSelection.GetEnd().GetIndex()))
1611 : {
1612 0 : sal_uLong nPara = rSelection.GetStart().GetPara();
1613 0 : TextSelection aEntrySel(TextPaM( nPara, pBeginAttrib->GetStart()), TextPaM(nPara, pBeginAttrib->GetEnd()));
1614 0 : return pTextEngine->GetText( aEntrySel );
1615 : }
1616 0 : return OUString();
1617 : }
1618 :
1619 0 : void AddressMultiLineEdit::SelectCurrentItem()
1620 : {
1621 0 : ExtTextEngine* pTextEngine = GetTextEngine();
1622 0 : ExtTextView* pTextView = GetTextView();
1623 0 : const TextSelection& rSelection = pTextView->GetSelection();
1624 0 : const TextCharAttrib* pBeginAttrib = pTextEngine->FindCharAttrib( rSelection.GetStart(), TEXTATTR_PROTECTED );
1625 0 : if(pBeginAttrib &&
1626 0 : (pBeginAttrib->GetStart() <= rSelection.GetStart().GetIndex()
1627 0 : && pBeginAttrib->GetEnd() >= rSelection.GetEnd().GetIndex()))
1628 : {
1629 0 : sal_uLong nPara = rSelection.GetStart().GetPara();
1630 0 : TextSelection aEntrySel(TextPaM( nPara, pBeginAttrib->GetStart()), TextPaM(nPara, pBeginAttrib->GetEnd()));
1631 0 : pTextView->SetSelection(aEntrySel);
1632 0 : Invalidate();
1633 : }
1634 0 : }
1635 :
1636 0 : OUString AddressMultiLineEdit::GetAddress()
1637 : {
1638 0 : OUString sRet;
1639 0 : ExtTextEngine* pTextEngine = GetTextEngine();
1640 0 : sal_uLong nParaCount = pTextEngine->GetParagraphCount();
1641 0 : for(sal_uLong nPara = nParaCount; nPara; --nPara)
1642 : {
1643 0 : const OUString sPara = comphelper::string::stripEnd(pTextEngine->GetText(nPara - 1), ' ');
1644 : //don't add empty trailing paragraphs
1645 0 : if(!sRet.isEmpty() || !sPara.isEmpty())
1646 : {
1647 0 : sRet = sPara + sRet;
1648 : //insert the para break
1649 0 : if(nPara > 1)
1650 0 : sRet = "\n" + sRet;
1651 : }
1652 0 : }
1653 0 : return sRet;
1654 0 : }
1655 :
1656 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|