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