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