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