1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 #ifdef SW_DLLIMPLEMENTATION
27 #undef SW_DLLIMPLEMENTATION
28 #endif
29 #include <swtypes.hxx>
30 #include <createaddresslistdialog.hxx>
31 #include <customizeaddresslistdialog.hxx>
32 #include <mmconfigitem.hxx>
33 #include <vcl/scrbar.hxx>
34 #include <vcl/msgbox.hxx>
35 #ifndef _SVT_CONTROLDIMS_HRC_
36 #include <svtools/controldims.hrc>
37 #endif
38 #include <unotools/pathoptions.hxx>
39 #include <sfx2/filedlghelper.hxx>
40 #include <sfx2/docfilt.hxx>
41 #include <sfx2/fcontnr.hxx>
42 #include <sfx2/docfac.hxx>
43 #include <sfx2/docfile.hxx>
44 #include <rtl/textenc.h>
45 #include "com/sun/star/ui/dialogs/TemplateDescription.hpp"
46 #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
47 #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
48 #include <tools/urlobj.hxx>
49 #include <createaddresslistdialog.hrc>
50 #include <dbui.hrc>
51 #include <helpid.h>
52 #include <unomid.h>
53 
54 
55 using namespace ::com::sun::star;
56 using namespace ::com::sun::star::ui::dialogs;
57 using ::rtl::OUString;
58 
59 /*-- 19.04.2004 12:19:50---------------------------------------------------
60 
61   -----------------------------------------------------------------------*/
62 class SwAddressControl_Impl : public Control
63 {
64     ScrollBar                       m_aScrollBar;
65     Window                          m_aWindow;
66 
67     ::std::vector<FixedText*>       m_aFixedTexts;
68     ::std::vector<Edit*>            m_aEdits;
69 
70     SwCSVData*                      m_pData;
71     Size                            m_aWinOutputSize;
72     sal_Int32                       m_nLineHeight;
73     sal_uInt32                      m_nCurrentDataSet;
74 
75     bool                            m_bNoDataSet;
76 
77     DECL_LINK(ScrollHdl_Impl, ScrollBar*);
78     DECL_LINK(GotFocusHdl_Impl, Edit*);
79     DECL_LINK(EditModifyHdl_Impl, Edit*);
80 
81     void                MakeVisible(const Rectangle& aRect);
82 
83     virtual long        PreNotify( NotifyEvent& rNEvt );
84     virtual void        Command( const CommandEvent& rCEvt );
85 
86     using Window::SetData;
87 
88 public:
89     SwAddressControl_Impl(Window* pParent, const ResId& rResId );
90     ~SwAddressControl_Impl();
91 
92     void        SetData(SwCSVData& rDBData);
93 
94     void        SetCurrentDataSet(sal_uInt32 nSet);
GetCurrentDataSet() const95     sal_uInt32  GetCurrentDataSet() const { return m_nCurrentDataSet;}
96     void        SetCursorTo(sal_uInt32 nElement);
97 };
98 
99 /*-- 13.04.2004 10:09:42---------------------------------------------------
100 
101   -----------------------------------------------------------------------*/
SwAddressControl_Impl(Window * pParent,const ResId & rResId)102 SwAddressControl_Impl::SwAddressControl_Impl(Window* pParent, const ResId& rResId ) :
103     Control(pParent, rResId),
104 #ifdef MSC
105 #pragma warning (disable : 4355)
106 #endif
107     m_aScrollBar(this, ResId(SCR_1,*rResId.GetResMgr())),
108     m_aWindow(this, ResId(WIN_DATA,*rResId.GetResMgr())),
109 #ifdef MSC
110 #pragma warning (default : 4355)
111 #endif
112     m_pData(0),
113     m_aWinOutputSize( m_aWindow.GetOutputSizePixel() ),
114     m_nLineHeight(0),
115     m_nCurrentDataSet(0),
116     m_bNoDataSet(true)
117 {
118     FreeResource();
119     Link aScrollLink = LINK(this, SwAddressControl_Impl, ScrollHdl_Impl);
120     m_aScrollBar.SetScrollHdl(aScrollLink);
121     m_aScrollBar.SetEndScrollHdl(aScrollLink);
122     m_aScrollBar.EnableDrag();
123 
124 }
125 /*-- 13.04.2004 10:09:43---------------------------------------------------
126 
127   -----------------------------------------------------------------------*/
~SwAddressControl_Impl()128 SwAddressControl_Impl::~SwAddressControl_Impl()
129 {
130     ::std::vector<FixedText*>::iterator aTextIter;
131     for(aTextIter = m_aFixedTexts.begin(); aTextIter != m_aFixedTexts.end(); ++aTextIter)
132         delete *aTextIter;
133     ::std::vector<Edit*>::iterator aEditIter;
134     for(aEditIter = m_aEdits.begin(); aEditIter != m_aEdits.end(); ++aEditIter)
135         delete *aEditIter;
136 }
137 /*-- 19.04.2004 12:22:41---------------------------------------------------
138 
139   -----------------------------------------------------------------------*/
SetData(SwCSVData & rDBData)140 void SwAddressControl_Impl::SetData(SwCSVData& rDBData)
141 {
142     m_pData = &rDBData;
143     //when the address data is updated then remove the controls an build again
144     if(m_aFixedTexts.size())
145     {
146         ::std::vector<FixedText*>::iterator aTextIter;
147         for(aTextIter = m_aFixedTexts.begin(); aTextIter != m_aFixedTexts.end(); ++aTextIter)
148             delete *aTextIter;
149         ::std::vector<Edit*>::iterator aEditIter;
150         for(aEditIter = m_aEdits.begin(); aEditIter != m_aEdits.end(); ++aEditIter)
151             delete *aEditIter;
152         m_aFixedTexts.clear();
153         m_aEdits.clear();
154         m_bNoDataSet = true;
155     }
156     //now create appropriate controls
157 
158     ::std::vector< OUString >::iterator  aHeaderIter;
159 
160     long nFTXPos = m_aWindow.LogicToPixel(Point(RSC_SP_CTRL_X, RSC_SP_CTRL_X), MAP_APPFONT).X();
161     long nFTHeight = m_aWindow.LogicToPixel(Size(RSC_BS_CHARHEIGHT, RSC_BS_CHARHEIGHT), MAP_APPFONT).Height();
162     long nFTWidth = 0;
163 
164     //determine the width of the FixedTexts
165     for(aHeaderIter = m_pData->aDBColumnHeaders.begin();
166                 aHeaderIter != m_pData->aDBColumnHeaders.end();
167                 ++aHeaderIter)
168     {
169         sal_Int32 nTemp = m_aWindow.GetTextWidth(*aHeaderIter);
170         if(nTemp > nFTWidth)
171           nFTWidth = nTemp;
172     }
173     //add some pixels
174     nFTWidth += 2;
175     long nEDXPos = nFTWidth + nFTXPos +
176             m_aWindow.LogicToPixel(Size(RSC_SP_CTRL_DESC_X, RSC_SP_CTRL_DESC_X), MAP_APPFONT).Width();
177     long nEDHeight = m_aWindow.LogicToPixel(Size(RSC_CD_TEXTBOX_HEIGHT, RSC_CD_TEXTBOX_HEIGHT), MAP_APPFONT).Height();
178     long nEDWidth = m_aWinOutputSize.Width() - nEDXPos - nFTXPos;
179     m_nLineHeight = nEDHeight + m_aWindow.LogicToPixel(Size(RSC_SP_CTRL_GROUP_Y, RSC_SP_CTRL_GROUP_Y), MAP_APPFONT).Height();
180 
181     long nEDYPos = m_aWindow.LogicToPixel(Size(RSC_SP_CTRL_DESC_Y, RSC_SP_CTRL_DESC_Y), MAP_APPFONT).Height();
182     long nFTYPos = nEDYPos + nEDHeight - nFTHeight;
183 
184     Link aFocusLink = LINK(this, SwAddressControl_Impl, GotFocusHdl_Impl);
185     Link aEditModifyLink = LINK(this, SwAddressControl_Impl, EditModifyHdl_Impl);
186     Edit* pLastEdit = 0;
187     sal_Int32 nVisibleLines = 0;
188     sal_Int32 nLines = 0;
189     for(aHeaderIter = m_pData->aDBColumnHeaders.begin();
190                 aHeaderIter != m_pData->aDBColumnHeaders.end();
191                 ++aHeaderIter, nEDYPos += m_nLineHeight, nFTYPos += m_nLineHeight, nLines++)
192     {
193         FixedText* pNewFT = new FixedText(&m_aWindow, WB_RIGHT);
194         Edit* pNewED = new Edit(&m_aWindow, WB_BORDER);
195         //set nLines a position identifier - used in the ModifyHdl
196         pNewED->SetData((void*)nLines);
197         pNewED->SetGetFocusHdl(aFocusLink);
198         pNewED->SetModifyHdl(aEditModifyLink);
199 
200         pNewFT->SetPosSizePixel(Point(nFTXPos, nFTYPos), Size(nFTWidth, nFTHeight));
201         pNewED->SetPosSizePixel(Point(nEDXPos, nEDYPos), Size(nEDWidth, nEDHeight));
202         if(nEDYPos + nEDHeight < m_aWinOutputSize.Height())
203             ++nVisibleLines;
204 
205         pNewFT->SetText(*aHeaderIter);
206 
207         pNewFT->Show();
208         pNewED->Show();
209         m_aFixedTexts.push_back(pNewFT);
210         m_aEdits.push_back(pNewED);
211         pLastEdit = pNewED;
212     }
213     //scrollbar adjustment
214     if(pLastEdit)
215     {
216         //the m_aWindow has to be at least as high as the ScrollBar and it must include the last Edit
217         sal_Int32 nContentHeight = pLastEdit->GetPosPixel().Y() + nEDHeight +
218                 m_aWindow.LogicToPixel(Size(RSC_SP_CTRL_GROUP_Y, RSC_SP_CTRL_GROUP_Y), MAP_APPFONT).Height();
219         if(nContentHeight < m_aScrollBar.GetSizePixel().Height())
220         {
221             nContentHeight = m_aScrollBar.GetSizePixel().Height();
222             m_aScrollBar.Enable(sal_False);
223         }
224         else
225         {
226             m_aScrollBar.Enable(sal_True);
227             m_aScrollBar.SetRange(Range(0, nLines));
228             m_aScrollBar.SetThumbPos(0);
229             m_aScrollBar.SetVisibleSize(nVisibleLines);
230         }
231         Size aWinOutputSize(m_aWinOutputSize);
232         aWinOutputSize.Height() = nContentHeight;
233         m_aWindow.SetOutputSizePixel(aWinOutputSize);
234 
235     }
236 }
237 /*-- 21.04.2004 11:37:09---------------------------------------------------
238 
239   -----------------------------------------------------------------------*/
SetCurrentDataSet(sal_uInt32 nSet)240 void SwAddressControl_Impl::SetCurrentDataSet(sal_uInt32 nSet)
241 {
242     if(m_bNoDataSet || m_nCurrentDataSet != nSet)
243     {
244         m_bNoDataSet = false;
245         m_nCurrentDataSet = nSet;
246         DBG_ASSERT(m_pData->aDBData.size() > m_nCurrentDataSet, "wrong data set index");
247         if(m_pData->aDBData.size() > m_nCurrentDataSet)
248         {
249             ::std::vector<Edit*>::iterator aEditIter;
250             sal_uInt32 nIndex = 0;
251             for(aEditIter = m_aEdits.begin(); aEditIter != m_aEdits.end(); ++aEditIter, ++nIndex)
252             {
253                 DBG_ASSERT(nIndex < m_pData->aDBData[m_nCurrentDataSet].size(),
254                             "number of colums doesn't match number of Edits");
255                 (*aEditIter)->SetText(m_pData->aDBData[m_nCurrentDataSet][nIndex]);
256             }
257         }
258     }
259 }
260 
261 /*-- 19.04.2004 14:17:50---------------------------------------------------
262 
263   -----------------------------------------------------------------------*/
IMPL_LINK(SwAddressControl_Impl,ScrollHdl_Impl,ScrollBar *,pScroll)264 IMPL_LINK(SwAddressControl_Impl, ScrollHdl_Impl, ScrollBar*, pScroll)
265 {
266     long nThumb = pScroll->GetThumbPos();
267     m_aWindow.SetPosPixel(Point(0, - (m_nLineHeight * nThumb)));
268 
269     return 0;
270 }
271 /*-- 19.04.2004 16:16:25---------------------------------------------------
272 
273   -----------------------------------------------------------------------*/
IMPL_LINK(SwAddressControl_Impl,GotFocusHdl_Impl,Edit *,pEdit)274 IMPL_LINK(SwAddressControl_Impl, GotFocusHdl_Impl, Edit*, pEdit)
275 {
276     if(0 != (GETFOCUS_TAB & pEdit->GetGetFocusFlags()))
277     {
278         Rectangle aRect(pEdit->GetPosPixel(), pEdit->GetSizePixel());
279         MakeVisible(aRect);
280     }
281     return 0;
282 }
283 /*-- 21.04.2004 14:56:54---------------------------------------------------
284 
285   -----------------------------------------------------------------------*/
MakeVisible(const Rectangle & rRect)286 void SwAddressControl_Impl::MakeVisible(const Rectangle & rRect)
287 {
288     long nThumb = m_aScrollBar.GetThumbPos();
289     //determine range of visible positions
290     long nMinVisiblePos = - m_aWindow.GetPosPixel().Y();
291     long nMaxVisiblePos = m_aScrollBar.GetSizePixel().Height() + nMinVisiblePos;
292     if( rRect.TopLeft().Y() < nMinVisiblePos)
293     {
294         nThumb -= 1 + ((nMinVisiblePos - rRect.TopLeft().Y()) / m_nLineHeight);
295     }
296     else if(rRect.BottomLeft().Y() > nMaxVisiblePos)
297     {
298         nThumb += 1 + ((nMaxVisiblePos - rRect.BottomLeft().Y()) / m_nLineHeight);
299     }
300     if(nThumb != m_aScrollBar.GetThumbPos())
301     {
302         m_aScrollBar.SetThumbPos(nThumb);
303         ScrollHdl_Impl(&m_aScrollBar);
304     }
305 }
306 /*-- 19.04.2004 16:16:25---------------------------------------------------
307     copy data changes into database
308   -----------------------------------------------------------------------*/
IMPL_LINK(SwAddressControl_Impl,EditModifyHdl_Impl,Edit *,pEdit)309 IMPL_LINK(SwAddressControl_Impl, EditModifyHdl_Impl, Edit*, pEdit)
310 {
311     //get the data element number of the current set
312     sal_Int32 nIndex = (sal_Int32)(sal_IntPtr)pEdit->GetData();
313     //get the index of the set
314     DBG_ASSERT(m_pData->aDBData.size() > m_nCurrentDataSet, "wrong data set index" );
315     if(m_pData->aDBData.size() > m_nCurrentDataSet)
316     {
317         m_pData->aDBData[m_nCurrentDataSet][nIndex] = pEdit->GetText();
318     }
319     return 0;
320 }
321 /*-- 21.04.2004 14:51:54---------------------------------------------------
322 
323   -----------------------------------------------------------------------*/
SetCursorTo(sal_uInt32 nElement)324 void SwAddressControl_Impl::SetCursorTo(sal_uInt32 nElement)
325 {
326     if(nElement < m_aEdits.size())
327     {
328         Edit* pEdit = m_aEdits[nElement];
329         pEdit->GrabFocus();
330         Rectangle aRect(pEdit->GetPosPixel(), pEdit->GetSizePixel());
331         MakeVisible(aRect);
332     }
333 
334 }
335 /*-- 19.04.2004 16:16:25---------------------------------------------------
336 
337   -----------------------------------------------------------------------*/
Command(const CommandEvent & rCEvt)338 void SwAddressControl_Impl::Command( const CommandEvent& rCEvt )
339 {
340     switch ( rCEvt.GetCommand() )
341     {
342         case COMMAND_WHEEL:
343         case COMMAND_STARTAUTOSCROLL:
344         case COMMAND_AUTOSCROLL:
345         {
346             const CommandWheelData* pWheelData = rCEvt.GetWheelData();
347             if(pWheelData && !pWheelData->IsHorz() && COMMAND_WHEEL_ZOOM != pWheelData->GetMode())
348             {
349                 HandleScrollCommand( rCEvt, 0, &m_aScrollBar );
350             }
351         }
352         break;
353         default:
354             Control::Command(rCEvt);
355     }
356 }
357 /*-- 19.04.2004 16:16:25---------------------------------------------------
358 
359   -----------------------------------------------------------------------*/
PreNotify(NotifyEvent & rNEvt)360 long SwAddressControl_Impl::PreNotify( NotifyEvent& rNEvt )
361 {
362     if(rNEvt.GetType() == EVENT_COMMAND)
363     {
364         const CommandEvent* pCEvt = rNEvt.GetCommandEvent();
365         sal_uInt16 nCmd = pCEvt->GetCommand();
366         if( COMMAND_WHEEL == nCmd )
367         {
368             Command(*pCEvt);
369             return 1;
370         }
371     }
372     return Control::PreNotify(rNEvt);
373 }
374 /*-- 13.04.2004 10:08:59---------------------------------------------------
375 
376   -----------------------------------------------------------------------*/
SwCreateAddressListDialog(Window * pParent,const String & rURL,SwMailMergeConfigItem & rConfig)377 SwCreateAddressListDialog::SwCreateAddressListDialog(
378         Window* pParent, const String& rURL, SwMailMergeConfigItem& rConfig) :
379     SfxModalDialog(pParent, SW_RES(DLG_MM_CREATEADDRESSLIST)),
380 #ifdef MSC
381 #pragma warning (disable : 4355)
382 #endif
383     m_aAddressInformation( this, SW_RES(  FI_ADDRESSINFORMATION)),
384     m_pAddressControl(new SwAddressControl_Impl(this, SW_RES(CT_ADDRESS))),
385     m_aNewPB( this, SW_RES(               PB_NEW)),
386     m_aDeletePB( this, SW_RES(            PB_DELETE)),
387     m_aFindPB( this, SW_RES(              PB_FIND)),
388     m_aCustomizePB( this, SW_RES(         PB_CUSTOMIZE)),
389 
390     m_aViewEntriesFI( this, SW_RES(       FI_VIEWENTRIES)),
391     m_aStartPB( this, SW_RES(             PB_START)),
392     m_aPrevPB( this, SW_RES(              PB_PREV)),
393     m_aSetNoNF( this, SW_RES(             NF_SETNO)),
394     m_aNextPB( this, SW_RES(              PB_NEXT  )),
395     m_aEndPB( this, SW_RES(               PB_END)),
396 
397     m_aSeparatorFL( this, SW_RES(         FL_SEPARATOR)),
398 
399     m_aOK( this, SW_RES(                  PB_OK)),
400     m_aCancel( this, SW_RES(              PB_CANCEL)),
401     m_aHelp( this, SW_RES(                PB_HELP)),
402 #ifdef MSC
403 #pragma warning (default : 4355)
404 #endif
405     m_sAddressListFilterName( SW_RES(    ST_FILTERNAME)),
406     m_sURL(rURL),
407     m_pCSVData( new SwCSVData ),
408     m_pFindDlg(0)
409 {
410     FreeResource();
411     m_aNewPB.SetClickHdl(LINK(this, SwCreateAddressListDialog, NewHdl_Impl));
412     m_aDeletePB.SetClickHdl(LINK(this, SwCreateAddressListDialog, DeleteHdl_Impl));
413     m_aFindPB.SetClickHdl(LINK(this, SwCreateAddressListDialog, FindHdl_Impl));
414     m_aCustomizePB.SetClickHdl(LINK(this, SwCreateAddressListDialog, CustomizeHdl_Impl));
415     m_aOK.SetClickHdl(LINK(this, SwCreateAddressListDialog, OkHdl_Impl));
416 
417     Link aLk = LINK(this, SwCreateAddressListDialog, DBCursorHdl_Impl);
418     m_aStartPB.SetClickHdl(aLk);
419     m_aPrevPB.SetClickHdl(aLk);
420     m_aSetNoNF.SetModifyHdl(LINK(this, SwCreateAddressListDialog, DBNumCursorHdl_Impl));
421     m_aNextPB.SetClickHdl(aLk);
422     m_aEndPB.SetClickHdl(aLk);
423 
424     if(m_sURL.Len())
425     {
426         //file exists, has to be loaded here
427         SfxMedium aMedium( m_sURL, STREAM_READ, sal_True );
428         SvStream* pStream = aMedium.GetInStream();
429         if(pStream)
430         {
431             pStream->SetLineDelimiter( LINEEND_LF );
432             pStream->SetStreamCharSet(RTL_TEXTENCODING_UTF8);
433 
434             OUString sSemi(';');
435             OUString sQuote('"');
436             String sTempMiddle(sQuote);
437             sTempMiddle += sal_Unicode(9);
438             OUString sMiddle(sTempMiddle);
439 
440             String sLine;
441             sal_Bool bRead = pStream->ReadUniOrByteStringLine( sLine, RTL_TEXTENCODING_UTF8 );
442 
443             if(bRead)
444             {
445                 //header line
446                 xub_StrLen nHeaders = sLine.GetTokenCount('\t');
447                 xub_StrLen nIndex = 0;
448                 for( xub_StrLen nToken = 0; nToken < nHeaders; ++nToken)
449                 {
450                     String sHeader = sLine.GetToken( 0, '\t', nIndex );
451                     DBG_ASSERT(sHeader.Len() > 2 &&
452                             sHeader.GetChar(0) == '\"' && sHeader.GetChar(sHeader.Len() - 1) == '\"',
453                             "Wrong format of header");
454                     if(sHeader.Len() > 2)
455                     {
456                         m_pCSVData->aDBColumnHeaders.push_back( sHeader.Copy(1, sHeader.Len() -2));
457                     }
458                 }
459             }
460             while(pStream->ReadUniOrByteStringLine( sLine, RTL_TEXTENCODING_UTF8 ))
461             {
462                 ::std::vector<OUString> aNewData;
463                 //analyze data line
464                 xub_StrLen nDataCount = sLine.GetTokenCount('\t');
465                 xub_StrLen nIndex = 0;
466                 for( xub_StrLen nToken = 0; nToken < nDataCount; ++nToken)
467                 {
468                     String sData = sLine.GetToken( 0, '\t', nIndex );
469                     DBG_ASSERT(sData.Len() >= 2 &&
470                                 sData.GetChar(0) == '\"' && sData.GetChar(sData.Len() - 1) == '\"',
471                             "Wrong format of line");
472                     if(sData.Len() >= 2)
473                         aNewData.push_back(sData.Copy(1, sData.Len() - 2));
474                     else
475                         aNewData.push_back(sData);
476                 }
477                 m_pCSVData->aDBData.push_back( aNewData );
478             }
479         }
480     }
481     else
482     {
483         //database has to be created
484         const ResStringArray& rAddressHeader = rConfig.GetDefaultAddressHeaders();
485         sal_uInt32 nCount = rAddressHeader.Count();
486         for(sal_uInt16 nHeader = 0; nHeader < nCount; ++nHeader)
487             m_pCSVData->aDBColumnHeaders.push_back( rAddressHeader.GetString(nHeader));
488         ::std::vector<OUString> aNewData;
489         String sTemp;
490         aNewData.insert(aNewData.begin(), nCount, sTemp);
491         m_pCSVData->aDBData.push_back(aNewData);
492     }
493     //now fill the address control
494     m_pAddressControl->SetData(*m_pCSVData);
495     m_pAddressControl->SetCurrentDataSet(0);
496     m_aSetNoNF.SetMax(m_pCSVData->aDBData.size());
497     UpdateButtons();
498 }
499 /*-- 13.04.2004 10:08:59---------------------------------------------------
500 
501   -----------------------------------------------------------------------*/
~SwCreateAddressListDialog()502 SwCreateAddressListDialog::~SwCreateAddressListDialog()
503 {
504     delete m_pAddressControl;
505     delete m_pCSVData;
506     delete m_pFindDlg;
507 }
508 /*-- 13.04.2004 10:08:59---------------------------------------------------
509     add a new data set of empty strings and set the address input control
510     to that new set
511   -----------------------------------------------------------------------*/
IMPL_LINK(SwCreateAddressListDialog,NewHdl_Impl,PushButton *,EMPTYARG)512 IMPL_LINK(SwCreateAddressListDialog, NewHdl_Impl, PushButton*, EMPTYARG)
513 {
514     sal_uInt32 nCurrent = m_pAddressControl->GetCurrentDataSet();
515     ::std::vector<OUString> aNewData;
516     String sTemp;
517     aNewData.insert(aNewData.begin(), m_pCSVData->aDBColumnHeaders.size(), sTemp);
518     m_pCSVData->aDBData.insert(m_pCSVData->aDBData.begin() + ++nCurrent, aNewData);
519     m_aSetNoNF.SetMax(m_pCSVData->aDBData.size());
520     //the NumericField start at 1
521     m_aSetNoNF.SetValue(nCurrent + 1);
522     //the address control starts at 0
523     m_pAddressControl->SetCurrentDataSet(nCurrent);
524     UpdateButtons();
525     return 0;
526 }
527 /*-- 13.04.2004 10:09:00---------------------------------------------------
528 
529   -----------------------------------------------------------------------*/
IMPL_LINK(SwCreateAddressListDialog,DeleteHdl_Impl,PushButton *,EMPTYARG)530 IMPL_LINK(SwCreateAddressListDialog, DeleteHdl_Impl, PushButton*, EMPTYARG)
531 {
532     sal_uInt32 nCurrent = m_pAddressControl->GetCurrentDataSet();
533     if(m_pCSVData->aDBData.size() > 1)
534     {
535         m_pCSVData->aDBData.erase(m_pCSVData->aDBData.begin() + nCurrent);
536         if(nCurrent)
537             --nCurrent;
538     }
539     else
540     {
541         // if only one set is available then clear the data
542         String sTemp;
543         m_pCSVData->aDBData[0].assign(m_pCSVData->aDBData[0].size(), sTemp);
544         m_aDeletePB.Enable(sal_False);
545     }
546     m_pAddressControl->SetCurrentDataSet(nCurrent);
547     m_aSetNoNF.SetMax(m_pCSVData->aDBData.size());
548     UpdateButtons();
549     return 0;
550 }
551 /*-- 13.04.2004 10:09:00---------------------------------------------------
552 
553   -----------------------------------------------------------------------*/
IMPL_LINK(SwCreateAddressListDialog,FindHdl_Impl,PushButton *,EMPTYARG)554 IMPL_LINK(SwCreateAddressListDialog, FindHdl_Impl, PushButton*, EMPTYARG)
555 {
556     if(!m_pFindDlg)
557     {
558         m_pFindDlg = new SwFindEntryDialog(this);
559         ListBox& rColumnBox = m_pFindDlg->GetFieldsListBox();
560         ::std::vector< OUString >::iterator  aHeaderIter;
561         for(aHeaderIter = m_pCSVData->aDBColumnHeaders.begin();
562                     aHeaderIter != m_pCSVData->aDBColumnHeaders.end();
563                     ++aHeaderIter)
564             rColumnBox.InsertEntry(*aHeaderIter);
565         rColumnBox.SelectEntryPos( 0 );
566     }
567     else
568         m_pFindDlg->Show(!m_pFindDlg->IsVisible());
569     return 0;
570 }
571 /*-- 13.04.2004 10:09:00---------------------------------------------------
572 
573   -----------------------------------------------------------------------*/
IMPL_LINK(SwCreateAddressListDialog,CustomizeHdl_Impl,PushButton *,pButton)574 IMPL_LINK(SwCreateAddressListDialog, CustomizeHdl_Impl, PushButton*, pButton)
575 {
576     SwCustomizeAddressListDialog* pDlg = new SwCustomizeAddressListDialog(pButton, *m_pCSVData);
577     if(RET_OK == pDlg->Execute())
578     {
579         delete m_pCSVData;
580         m_pCSVData = pDlg->GetNewData();
581         m_pAddressControl->SetData(*m_pCSVData);
582         m_pAddressControl->SetCurrentDataSet(m_pAddressControl->GetCurrentDataSet());
583     }
584     delete pDlg;
585 
586     //update find dialog
587     if(m_pFindDlg)
588     {
589         ListBox& rColumnBox = m_pFindDlg->GetFieldsListBox();
590         rColumnBox.Clear();
591         ::std::vector< OUString >::iterator  aHeaderIter;
592         for(aHeaderIter = m_pCSVData->aDBColumnHeaders.begin();
593                     aHeaderIter != m_pCSVData->aDBColumnHeaders.end();
594                     ++aHeaderIter)
595             rColumnBox.InsertEntry(*aHeaderIter);
596     }
597     return 0;
598 }
599 /*-- 23.04.2004 09:02:51---------------------------------------------------
600     writes the data into a .csv file
601     encoding is UTF8, separator is tab, strings are enclosed into "
602   -----------------------------------------------------------------------*/
IMPL_LINK(SwCreateAddressListDialog,OkHdl_Impl,PushButton *,EMPTYARG)603 IMPL_LINK(SwCreateAddressListDialog, OkHdl_Impl, PushButton*, EMPTYARG)
604 {
605     if(!m_sURL.Len())
606     {
607         sfx2::FileDialogHelper aDlgHelper( TemplateDescription::FILESAVE_SIMPLE, 0 );
608         uno::Reference < XFilePicker > xFP = aDlgHelper.GetFilePicker();
609 
610         String sPath( SvtPathOptions().SubstituteVariable(
611                     String::CreateFromAscii("$(userurl)/database") ));
612         aDlgHelper.SetDisplayDirectory( sPath );
613         uno::Reference< XFilterManager > xFltMgr(xFP, uno::UNO_QUERY);
614         ::rtl::OUString sCSV(C2U("*.csv"));
615         xFltMgr->appendFilter( m_sAddressListFilterName, sCSV );
616         xFltMgr->setCurrentFilter( m_sAddressListFilterName ) ;
617 
618         if( ERRCODE_NONE == aDlgHelper.Execute() )
619         {
620             m_sURL = xFP->getFiles().getConstArray()[0];
621             INetURLObject aResult( m_sURL );
622             aResult.setExtension(String::CreateFromAscii("csv"));
623             m_sURL = aResult.GetMainURL(INetURLObject::NO_DECODE);
624         }
625     }
626     if(m_sURL.Len())
627     {
628         SfxMedium aMedium( m_sURL, STREAM_READWRITE|STREAM_TRUNC, sal_True );
629         SvStream* pStream = aMedium.GetOutStream();
630         pStream->SetLineDelimiter( LINEEND_LF );
631         pStream->SetStreamCharSet(RTL_TEXTENCODING_UTF8);
632 
633         OUString sSemi(';');
634         OUString sQuote('"');
635         String sTempMiddle(sQuote);
636         sTempMiddle += sal_Unicode(9);
637         OUString sMiddle(sTempMiddle);
638         sMiddle += sQuote;
639 
640         //create a string for the header line
641         OUString sLine(sQuote);
642         ::std::vector< OUString >::iterator  aHeaderIter;
643         for(aHeaderIter = m_pCSVData->aDBColumnHeaders.begin();
644                     aHeaderIter != m_pCSVData->aDBColumnHeaders.end();
645                     ++aHeaderIter)
646         {
647             sLine += *aHeaderIter;
648             sLine += sMiddle;
649         }
650         //remove tab and quote
651         sLine = sLine.copy( 0, sLine.getLength() - 2 );
652         pStream->WriteUnicodeOrByteText( sLine, RTL_TEXTENCODING_UTF8 );
653         endl(*pStream);
654 
655         ::std::vector< ::std::vector< OUString > >::iterator aDataIter;
656         for( aDataIter = m_pCSVData->aDBData.begin(); aDataIter != m_pCSVData->aDBData.end(); ++aDataIter)
657         {
658             sLine = sQuote;
659             ::std::vector< OUString >::iterator  aColumnIter;
660             for(aColumnIter = aDataIter->begin(); aColumnIter != aDataIter->end(); ++aColumnIter)
661             {
662                 sLine += *aColumnIter;
663                 sLine += sMiddle;
664             }
665             //remove tab and quote
666             sLine = sLine.copy( 0, sLine.getLength() - 2 );
667             pStream->WriteUnicodeOrByteText( sLine, RTL_TEXTENCODING_UTF8 );
668             endl(*pStream);
669         }
670         aMedium.Commit();
671         EndDialog(RET_OK);
672     }
673 
674     return 0;
675 }
676 /*-- 13.04.2004 10:09:01---------------------------------------------------
677 
678   -----------------------------------------------------------------------*/
IMPL_LINK(SwCreateAddressListDialog,DBCursorHdl_Impl,PushButton *,pButton)679 IMPL_LINK(SwCreateAddressListDialog, DBCursorHdl_Impl, PushButton*, pButton)
680 {
681     sal_uInt32 nValue = static_cast< sal_uInt32 >(m_aSetNoNF.GetValue());
682 
683     if(pButton == &m_aStartPB)
684         nValue = 1;
685     else if(pButton == &m_aPrevPB)
686     {
687         if(nValue > 1)
688             --nValue;
689     }
690     else if(pButton == &m_aNextPB)
691     {
692         if(nValue < (sal_uInt32)m_aSetNoNF.GetMax())
693             ++nValue;
694     }
695     else //m_aEndPB
696         nValue = static_cast< sal_uInt32 >(m_aSetNoNF.GetMax());
697     if(nValue != m_aSetNoNF.GetValue())
698     {
699         m_aSetNoNF.SetValue(nValue);
700         DBNumCursorHdl_Impl(&m_aSetNoNF);
701     }
702     return 0;
703 }
704 /*-- 21.04.2004 12:06:47---------------------------------------------------
705 
706   -----------------------------------------------------------------------*/
IMPL_LINK(SwCreateAddressListDialog,DBNumCursorHdl_Impl,NumericField *,EMPTYARG)707 IMPL_LINK(SwCreateAddressListDialog, DBNumCursorHdl_Impl, NumericField*, EMPTYARG)
708 {
709     m_pAddressControl->SetCurrentDataSet( static_cast< sal_uInt32 >(m_aSetNoNF.GetValue() - 1) );
710     UpdateButtons();
711     return 0;
712 }
713 /*-- 21.04.2004 13:22:27---------------------------------------------------
714 
715   -----------------------------------------------------------------------*/
UpdateButtons()716 void SwCreateAddressListDialog::UpdateButtons()
717 {
718     sal_uInt32 nCurrent = static_cast< sal_uInt32 >(m_aSetNoNF.GetValue() );
719     sal_uInt32 nSize = (sal_uInt32 )m_pCSVData->aDBData.size();
720     m_aStartPB.Enable(nCurrent != 1);
721     m_aPrevPB.Enable(nCurrent != 1);
722     m_aNextPB.Enable(nCurrent != nSize);
723     m_aEndPB.Enable(nCurrent != nSize);
724     m_aDeletePB.Enable(nSize > 0);
725 }
726 /*-- 21.04.2004 13:22:27---------------------------------------------------
727 
728   -----------------------------------------------------------------------*/
Find(const String & rSearch,sal_Int32 nColumn)729 void SwCreateAddressListDialog::Find(const String& rSearch, sal_Int32 nColumn)
730 {
731     OUString sSearch = rSearch;
732     sSearch.toAsciiLowerCase();
733     sal_uInt32 nCurrent = m_pAddressControl->GetCurrentDataSet();
734     //search forward
735     bool bFound = false;
736     sal_uInt32 nStart = nCurrent + 1;
737     sal_uInt32 nEnd = m_pCSVData->aDBData.size();
738     sal_uInt32 nElement = 0;
739     sal_uInt32 nPos = 0;
740     for(short nTemp = 0; nTemp < 2 && !bFound; nTemp++)
741     {
742         for(nPos = nStart; nPos < nEnd; ++nPos)
743         {
744             ::std::vector< OUString> aData = m_pCSVData->aDBData[nPos];
745             if(nColumn >=0)
746                 bFound = -1 != aData[(sal_uInt32)nColumn].toAsciiLowerCase().indexOf(sSearch);
747             else
748             {
749                 for( nElement = 0; nElement < aData.size(); ++nElement)
750                 {
751                     bFound = -1 != aData[nElement].toAsciiLowerCase().indexOf(sSearch);
752                     if(bFound)
753                     {
754                         nColumn = nElement;
755                         break;
756                     }
757                 }
758             }
759             if(bFound)
760                 break;
761         }
762         nStart = 0;
763         nEnd = nCurrent + 1;
764     }
765     if(bFound)
766     {
767         m_pAddressControl->SetCurrentDataSet(nPos);
768         m_aSetNoNF.SetValue( nPos + 1 );
769         UpdateButtons();
770         m_pAddressControl->SetCursorTo(nElement);
771     }
772 }
773 /*-- 13.04.2004 13:48:38---------------------------------------------------
774 
775   -----------------------------------------------------------------------*/
SwFindEntryDialog(SwCreateAddressListDialog * pParent)776 SwFindEntryDialog::SwFindEntryDialog(SwCreateAddressListDialog* pParent) :
777     ModelessDialog(pParent, SW_RES(DLG_MM_FIND_ENTRY)),
778 #ifdef MSC
779 #pragma warning (disable : 4355)
780 #endif
781     m_aFindFT( this, SW_RES(      FT_FIND      )),
782     m_aFindED( this, SW_RES(      ED_FIND      )),
783     m_aFindOnlyCB( this, SW_RES(  CB_FINDONLY )),
784     m_aFindOnlyLB( this, SW_RES(  LB_FINDONLY  )),
785     m_aFindPB( this, SW_RES(      PB_FIND)),
786     m_aCancel( this, SW_RES(      PB_CANCEL)),
787     m_aHelp( this, SW_RES(        PB_HELP)),
788 #ifdef MSC
789 #pragma warning (default : 4355)
790 #endif
791    m_pParent(pParent)
792 {
793     FreeResource();
794     m_aFindPB.SetClickHdl(LINK(this, SwFindEntryDialog, FindHdl_Impl));
795     m_aFindED.SetModifyHdl(LINK(this, SwFindEntryDialog, FindEnableHdl_Impl));
796     m_aCancel.SetClickHdl(LINK(this, SwFindEntryDialog, CloseHdl_Impl));
797 }
798 /*-- 13.04.2004 13:48:38---------------------------------------------------
799 
800   -----------------------------------------------------------------------*/
~SwFindEntryDialog()801 SwFindEntryDialog::~SwFindEntryDialog()
802 {
803 }
804 /*-- 21.04.2004 13:37:46---------------------------------------------------
805 
806   -----------------------------------------------------------------------*/
IMPL_LINK(SwFindEntryDialog,FindHdl_Impl,PushButton *,EMPTYARG)807 IMPL_LINK(SwFindEntryDialog, FindHdl_Impl, PushButton*, EMPTYARG)
808 {
809     sal_Int32 nColumn = -1;
810     if(m_aFindOnlyCB.IsChecked())
811         nColumn = m_aFindOnlyLB.GetSelectEntryPos();
812     if(nColumn != LISTBOX_ENTRY_NOTFOUND)
813         m_pParent->Find(m_aFindED.GetText(), nColumn);
814     return 0;
815 }
816 /*-- 21.04.2004 13:37:46---------------------------------------------------
817 
818   -----------------------------------------------------------------------*/
IMPL_LINK(SwFindEntryDialog,FindEnableHdl_Impl,Edit *,EMPTYARG)819 IMPL_LINK(SwFindEntryDialog, FindEnableHdl_Impl, Edit*, EMPTYARG)
820 {
821     m_aFindPB.Enable(m_aFindED.GetText().Len() > 0);
822     return 0;
823 }
824 /*-- 21.04.2004 15:36:36---------------------------------------------------
825 
826   -----------------------------------------------------------------------*/
IMPL_LINK(SwFindEntryDialog,CloseHdl_Impl,PushButton *,EMPTYARG)827 IMPL_LINK(SwFindEntryDialog, CloseHdl_Impl, PushButton*, EMPTYARG)
828 {
829     Show(sal_False);
830     return 0;
831 }
832