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