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