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