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 <sal/config.h>
21 
22 #include <cstddef>
23 
24 #include <osl/diagnose.h>
25 #include <swtypes.hxx>
26 #include "createaddresslistdialog.hxx"
27 #include "customizeaddresslistdialog.hxx"
28 #include <mmconfigitem.hxx>
29 #include <vcl/svapp.hxx>
30 #include <unotools/pathoptions.hxx>
31 #include <sfx2/filedlghelper.hxx>
32 #include <sfx2/docfile.hxx>
33 #include <rtl/textenc.h>
34 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
35 #include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
36 #include <tools/urlobj.hxx>
37 #include <strings.hrc>
38 #include <map>
39 
40 using namespace ::com::sun::star;
41 using namespace ::com::sun::star::ui::dialogs;
42 
43 namespace {
44 
45 struct SwAddressFragment
46 {
47     std::unique_ptr<weld::Builder> m_xBuilder;
48     std::unique_ptr<weld::Label> m_xLabel;
49     std::unique_ptr<weld::Entry> m_xEntry;
50     weld::Container* m_pGrid;
51 
SwAddressFragment__anon3dffa80d0111::SwAddressFragment52     SwAddressFragment(weld::Container* pGrid, int nLine)
53         : m_xBuilder(Application::CreateBuilder(pGrid, "modules/swriter/ui/addressfragment.ui"))
54         , m_xLabel(m_xBuilder->weld_label("label"))
55         , m_xEntry(m_xBuilder->weld_entry("entry"))
56         , m_pGrid(pGrid)
57     {
58         m_xLabel->set_grid_left_attach(0);
59         m_xLabel->set_grid_top_attach(nLine);
60 
61         m_xEntry->set_grid_left_attach(1);
62         m_xEntry->set_grid_top_attach(nLine);
63     }
64 
~SwAddressFragment__anon3dffa80d0111::SwAddressFragment65     ~SwAddressFragment()
66     {
67         m_pGrid->move(m_xEntry.get(), nullptr);
68         m_pGrid->move(m_xLabel.get(), nullptr);
69     }
70 };
71 
72 }
73 
74 class SwAddressControl_Impl
75 {
76     std::map<weld::Entry*, sal_Int32> m_aEditLines;
77 
78     SwCSVData*                      m_pData;
79     sal_uInt32                      m_nCurrentDataSet;
80 
81     bool                            m_bNoDataSet;
82 
83     std::unique_ptr<weld::ScrolledWindow> m_xScrollBar;
84     std::unique_ptr<weld::Container> m_xWindow;
85     std::vector<std::unique_ptr<SwAddressFragment>> m_aLines;
86 
87     DECL_LINK(GotFocusHdl_Impl, weld::Widget&, void);
88     DECL_LINK(EditModifyHdl_Impl, weld::Entry&, void);
89 
90     void                MakeVisible(const tools::Rectangle& aRect);
91 
92 public:
93     SwAddressControl_Impl(weld::Builder& rBuilder);
94 
95     void        SetData(SwCSVData& rDBData);
96 
97     void        SetCurrentDataSet(sal_uInt32 nSet);
CurrentDataSetInvalidated()98     void        CurrentDataSetInvalidated() { m_nCurrentDataSet = std::numeric_limits<sal_uInt32>::max(); }
GetCurrentDataSet() const99     sal_uInt32  GetCurrentDataSet() const { return m_nCurrentDataSet; }
100     void        SetCursorTo(std::size_t nElement);
101 };
102 
SwAddressControl_Impl(weld::Builder & rBuilder)103 SwAddressControl_Impl::SwAddressControl_Impl(weld::Builder& rBuilder)
104     : m_pData(nullptr)
105     , m_nCurrentDataSet(0)
106     , m_bNoDataSet(true)
107     , m_xScrollBar(rBuilder.weld_scrolled_window("scrollwin"))
108     , m_xWindow(rBuilder.weld_container("CONTAINER"))
109 {
110 }
111 
SetData(SwCSVData & rDBData)112 void SwAddressControl_Impl::SetData(SwCSVData& rDBData)
113 {
114     m_pData = &rDBData;
115     //when the address data is updated then remove the controls and build again
116     if (!m_aLines.empty())
117     {
118         m_aLines.clear();
119         m_bNoDataSet = true;
120     }
121 
122     Link<weld::Widget&,void> aFocusLink = LINK(this, SwAddressControl_Impl, GotFocusHdl_Impl);
123     Link<weld::Entry&,void> aEditModifyLink = LINK(this, SwAddressControl_Impl, EditModifyHdl_Impl);
124     sal_Int32 nLines = 0;
125     for (const auto& rHeader : m_pData->aDBColumnHeaders)
126     {
127         m_aLines.emplace_back(new SwAddressFragment(m_xWindow.get(), nLines));
128 
129         // when we have one line, measure it to get the line height to use as
130         // the basis for overall size request
131         if (nLines == 0)
132         {
133             auto nLineHeight = m_xWindow->get_preferred_size().Height();
134             m_xScrollBar->set_size_request(m_xScrollBar->get_approximate_digit_width() * 65,
135                                            nLineHeight * 10);
136         }
137 
138         weld::Label* pNewFT = m_aLines.back()->m_xLabel.get();
139         weld::Entry* pNewED = m_aLines.back()->m_xEntry.get();
140         //set nLines a position identifier - used in the ModifyHdl
141         m_aEditLines[pNewED] = nLines;
142         pNewED->connect_focus_in(aFocusLink);
143         pNewED->connect_changed(aEditModifyLink);
144 
145         pNewFT->set_label(rHeader);
146 
147         nLines++;
148     }
149 }
150 
SetCurrentDataSet(sal_uInt32 nSet)151 void SwAddressControl_Impl::SetCurrentDataSet(sal_uInt32 nSet)
152 {
153     if(!(m_bNoDataSet || m_nCurrentDataSet != nSet))
154         return;
155 
156     m_bNoDataSet = false;
157     m_nCurrentDataSet = nSet;
158     OSL_ENSURE(m_pData->aDBData.size() > m_nCurrentDataSet, "wrong data set index");
159     if(m_pData->aDBData.size() > m_nCurrentDataSet)
160     {
161         sal_uInt32 nIndex = 0;
162         for(auto& rLine : m_aLines)
163         {
164             OSL_ENSURE(nIndex < m_pData->aDBData[m_nCurrentDataSet].size(),
165                         "number of columns doesn't match number of Edits");
166             rLine->m_xEntry->set_text(m_pData->aDBData[m_nCurrentDataSet][nIndex]);
167             ++nIndex;
168         }
169     }
170 }
171 
IMPL_LINK(SwAddressControl_Impl,GotFocusHdl_Impl,weld::Widget &,rEdit,void)172 IMPL_LINK(SwAddressControl_Impl, GotFocusHdl_Impl, weld::Widget&, rEdit, void)
173 {
174     int x, y, width, height;
175     rEdit.get_extents_relative_to(*m_xWindow, x, y, width, height);
176     // the container has a border of 3 in the .ui
177     tools::Rectangle aRect(Point(x - 3, y - 3), Size(width + 6, height + 6));
178     MakeVisible(aRect);
179 }
180 
MakeVisible(const tools::Rectangle & rRect)181 void SwAddressControl_Impl::MakeVisible(const tools::Rectangle & rRect)
182 {
183     //determine range of visible positions
184     auto nMinVisiblePos = m_xScrollBar->vadjustment_get_value();
185     auto nMaxVisiblePos = nMinVisiblePos + m_xScrollBar->vadjustment_get_page_size();
186     if (rRect.Top() < nMinVisiblePos || rRect.Bottom() > nMaxVisiblePos)
187         m_xScrollBar->vadjustment_set_value(rRect.Top());
188 }
189 
190 // copy data changes into database
IMPL_LINK(SwAddressControl_Impl,EditModifyHdl_Impl,weld::Entry &,rEdit,void)191 IMPL_LINK(SwAddressControl_Impl, EditModifyHdl_Impl, weld::Entry&, rEdit, void)
192 {
193     //get the data element number of the current set
194     sal_Int32 nIndex = m_aEditLines[&rEdit];
195     //get the index of the set
196     OSL_ENSURE(m_pData->aDBData.size() > m_nCurrentDataSet, "wrong data set index" );
197     if (m_pData->aDBData.size() > m_nCurrentDataSet)
198     {
199         m_pData->aDBData[m_nCurrentDataSet][nIndex] = rEdit.get_text();
200     }
201 }
202 
SetCursorTo(std::size_t nElement)203 void SwAddressControl_Impl::SetCursorTo(std::size_t nElement)
204 {
205     if (nElement < m_aLines.size())
206     {
207         weld::Entry* pEdit = m_aLines[nElement]->m_xEntry.get();
208         pEdit->grab_focus();
209     }
210 
211 }
212 
SwCreateAddressListDialog(weld::Window * pParent,const OUString & rURL,SwMailMergeConfigItem const & rConfig)213 SwCreateAddressListDialog::SwCreateAddressListDialog(
214         weld::Window* pParent, const OUString& rURL, SwMailMergeConfigItem const & rConfig)
215     : SfxDialogController(pParent, "modules/swriter/ui/createaddresslist.ui", "CreateAddressList")
216     , m_sAddressListFilterName(SwResId(ST_FILTERNAME))
217     , m_sURL(rURL)
218     , m_pCSVData(new SwCSVData)
219     , m_xAddressControl(new SwAddressControl_Impl(*m_xBuilder))
220     , m_xNewPB(m_xBuilder->weld_button("NEW"))
221     , m_xDeletePB(m_xBuilder->weld_button("DELETE"))
222     , m_xFindPB(m_xBuilder->weld_button("FIND"))
223     , m_xCustomizePB(m_xBuilder->weld_button("CUSTOMIZE"))
224     , m_xStartPB(m_xBuilder->weld_button("START"))
225     , m_xPrevPB(m_xBuilder->weld_button("PREV"))
226     , m_xSetNoED(m_xBuilder->weld_entry("SETNOED"))
227     , m_xSetNoNF(m_xBuilder->weld_spin_button("SETNOSB"))
228     , m_xNextPB(m_xBuilder->weld_button("NEXT"))
229     , m_xEndPB(m_xBuilder->weld_button("END"))
230     , m_xOK(m_xBuilder->weld_button("ok"))
231 {
232     m_xSetNoNF->set_min(1);
233 
234     m_xNewPB->connect_clicked(LINK(this, SwCreateAddressListDialog, NewHdl_Impl));
235     m_xDeletePB->connect_clicked(LINK(this, SwCreateAddressListDialog, DeleteHdl_Impl));
236     m_xFindPB->connect_clicked(LINK(this, SwCreateAddressListDialog, FindHdl_Impl));
237     m_xCustomizePB->connect_clicked(LINK(this, SwCreateAddressListDialog, CustomizeHdl_Impl));
238     m_xOK->connect_clicked(LINK(this, SwCreateAddressListDialog, OkHdl_Impl));
239 
240     Link<weld::Button&,void> aLk = LINK(this, SwCreateAddressListDialog, DBCursorHdl_Impl);
241     m_xStartPB->connect_clicked(aLk);
242     m_xPrevPB->connect_clicked(aLk);
243     m_xSetNoED->connect_changed(LINK(this, SwCreateAddressListDialog, DBNumCursorHdl_Impl));
244     m_xSetNoED->connect_focus_out(LINK(this, SwCreateAddressListDialog, RefreshNum_Impl));
245     m_xNextPB->connect_clicked(aLk);
246     m_xEndPB->connect_clicked(aLk);
247 
248     if (!m_sURL.isEmpty())
249     {
250         //file exists, has to be loaded here
251         SfxMedium aMedium( m_sURL, StreamMode::READ );
252         SvStream* pStream = aMedium.GetInStream();
253         if(pStream)
254         {
255             pStream->SetLineDelimiter( LINEEND_LF );
256             pStream->SetStreamCharSet(RTL_TEXTENCODING_UTF8);
257 
258             OUString sLine;
259             bool bRead = pStream->ReadByteStringLine( sLine, RTL_TEXTENCODING_UTF8 );
260 
261             if(bRead && !sLine.isEmpty())
262             {
263                 sal_Int32 nIndex = 0;
264                 do
265                 {
266                     const OUString sHeader = sLine.getToken( 0, '\t', nIndex );
267                     OSL_ENSURE(sHeader.getLength() > 2 &&
268                             sHeader.startsWith("\"") && sHeader.endsWith("\""),
269                             "Wrong format of header");
270                     if(sHeader.getLength() > 2)
271                     {
272                         m_pCSVData->aDBColumnHeaders.push_back( sHeader.copy(1, sHeader.getLength() -2));
273                     }
274                 }
275                 while (nIndex > 0);
276             }
277             while(pStream->ReadByteStringLine( sLine, RTL_TEXTENCODING_UTF8 ))
278             {
279                 std::vector<OUString> aNewData;
280                 //analyze data line
281                 sal_Int32 nIndex = { sLine.isEmpty() ? -1 : 0 };
282                 while (nIndex >= 0)
283                 {
284                     const OUString sData = sLine.getToken( 0, '\t', nIndex );
285                     OSL_ENSURE( sData.startsWith("\"") && sData.endsWith("\""),
286                             "Wrong format of line");
287                     if(sData.getLength() >= 2)
288                         aNewData.push_back(sData.copy(1, sData.getLength() - 2));
289                     else
290                         aNewData.push_back(sData);
291                 }
292                 m_pCSVData->aDBData.push_back( aNewData );
293             }
294         }
295     }
296     else
297     {
298         //database has to be created
299         const std::vector<std::pair<OUString, int>>& rAddressHeader = rConfig.GetDefaultAddressHeaders();
300         const sal_uInt32 nCount = rAddressHeader.size();
301         for(sal_uInt32 nHeader = 0; nHeader < nCount; ++nHeader)
302             m_pCSVData->aDBColumnHeaders.push_back(rAddressHeader[nHeader].first);
303         std::vector<OUString> aNewData;
304         aNewData.insert(aNewData.begin(), nCount, OUString());
305         m_pCSVData->aDBData.push_back(aNewData);
306     }
307     //now fill the address control
308     m_xAddressControl->SetData(*m_pCSVData);
309     m_xAddressControl->SetCurrentDataSet(0);
310     m_xSetNoNF->set_max(m_pCSVData->aDBData.size());
311 
312     m_xSetNoNF->set_value(1);
313     RefreshNum_Impl(*m_xSetNoED);
314 
315     UpdateButtons();
316 }
317 
~SwCreateAddressListDialog()318 SwCreateAddressListDialog::~SwCreateAddressListDialog()
319 {
320 }
321 
IMPL_LINK_NOARG(SwCreateAddressListDialog,NewHdl_Impl,weld::Button &,void)322 IMPL_LINK_NOARG(SwCreateAddressListDialog, NewHdl_Impl, weld::Button&, void)
323 {
324     sal_uInt32 nCurrent = m_xAddressControl->GetCurrentDataSet();
325     std::vector<OUString> aNewData;
326     aNewData.insert(aNewData.begin(), m_pCSVData->aDBColumnHeaders.size(), OUString());
327     m_pCSVData->aDBData.insert(m_pCSVData->aDBData.begin() + ++nCurrent, aNewData);
328     m_xSetNoNF->set_max(m_pCSVData->aDBData.size());
329     //the NumericField start at 1
330     m_xSetNoNF->set_value(nCurrent + 1);
331     RefreshNum_Impl(*m_xSetNoED);
332     //the address control starts at 0
333     m_xAddressControl->SetCurrentDataSet(nCurrent);
334     UpdateButtons();
335 }
336 
IMPL_LINK_NOARG(SwCreateAddressListDialog,DeleteHdl_Impl,weld::Button &,void)337 IMPL_LINK_NOARG(SwCreateAddressListDialog, DeleteHdl_Impl, weld::Button&, void)
338 {
339     sal_uInt32 nCurrent = m_xAddressControl->GetCurrentDataSet();
340     if (m_pCSVData->aDBData.size() > 1)
341     {
342         m_pCSVData->aDBData.erase(m_pCSVData->aDBData.begin() + nCurrent);
343         if (nCurrent)
344             --nCurrent;
345     }
346     else
347     {
348         // if only one set is available then clear the data
349         m_pCSVData->aDBData[0].assign(m_pCSVData->aDBData[0].size(), OUString());
350         m_xDeletePB->set_sensitive(false);
351     }
352     m_xAddressControl->CurrentDataSetInvalidated();
353     m_xAddressControl->SetCurrentDataSet(nCurrent);
354     m_xSetNoNF->set_max(m_pCSVData->aDBData.size());
355     UpdateButtons();
356 }
357 
IMPL_LINK_NOARG(SwCreateAddressListDialog,FindHdl_Impl,weld::Button &,void)358 IMPL_LINK_NOARG(SwCreateAddressListDialog, FindHdl_Impl, weld::Button&, void)
359 {
360     if (!m_xFindDlg)
361     {
362         m_xFindDlg.reset(new SwFindEntryDialog(this));
363         weld::ComboBox& rColumnBox = m_xFindDlg->GetFieldsListBox();
364         for(const auto& rHeader : m_pCSVData->aDBColumnHeaders)
365             rColumnBox.append_text(rHeader);
366         rColumnBox.set_active(0);
367         m_xFindDlg->show();
368     }
369     else
370         m_xFindDlg->set_visible(!m_xFindDlg->get_visible());
371 }
372 
IMPL_LINK_NOARG(SwCreateAddressListDialog,CustomizeHdl_Impl,weld::Button &,void)373 IMPL_LINK_NOARG(SwCreateAddressListDialog, CustomizeHdl_Impl, weld::Button&, void)
374 {
375     SwCustomizeAddressListDialog aDlg(m_xDialog.get(), *m_pCSVData);
376     if (aDlg.run() == RET_OK)
377     {
378         m_pCSVData = aDlg.ReleaseNewData();
379         m_xAddressControl->SetData(*m_pCSVData);
380         m_xAddressControl->SetCurrentDataSet(m_xAddressControl->GetCurrentDataSet());
381     }
382 
383     //update find dialog
384     if (m_xFindDlg)
385     {
386         weld::ComboBox& rColumnBox = m_xFindDlg->GetFieldsListBox();
387         rColumnBox.clear();
388         for(const auto& rHeader : m_pCSVData->aDBColumnHeaders)
389             rColumnBox.append_text(rHeader);
390     }
391 }
392 
393 namespace
394 {
395 
lcl_WriteValues(const std::vector<OUString> * pFields,SvStream * pStream)396 void lcl_WriteValues(const std::vector<OUString> *pFields, SvStream* pStream)
397 {
398     OUStringBuffer sLine;
399     const std::vector< OUString >::const_iterator aBegin = pFields->begin();
400     const std::vector< OUString >::const_iterator aEnd = pFields->end();
401     for(std::vector< OUString >::const_iterator aIter = aBegin; aIter != aEnd; ++aIter)
402     {
403         if (aIter==aBegin)
404         {
405             sLine.append("\"" + *aIter + "\"");
406         }
407         else
408         {
409             sLine.append("\t\"" + *aIter + "\"");
410         }
411     }
412     pStream->WriteByteStringLine( sLine.makeStringAndClear(), RTL_TEXTENCODING_UTF8 );
413 }
414 
415 }
416 
IMPL_LINK_NOARG(SwCreateAddressListDialog,OkHdl_Impl,weld::Button &,void)417 IMPL_LINK_NOARG(SwCreateAddressListDialog, OkHdl_Impl, weld::Button&, void)
418 {
419     if(m_sURL.isEmpty())
420     {
421         sfx2::FileDialogHelper aDlgHelper(TemplateDescription::FILESAVE_SIMPLE,
422                                           FileDialogFlags::NONE, m_xDialog.get());
423         uno::Reference < XFilePicker3 > xFP = aDlgHelper.GetFilePicker();
424 
425         const OUString sPath( SvtPathOptions().SubstituteVariable("$(userurl)/database") );
426         aDlgHelper.SetDisplayDirectory( sPath );
427         xFP->appendFilter( m_sAddressListFilterName, "*.csv" );
428         xFP->setCurrentFilter( m_sAddressListFilterName ) ;
429 
430         if( ERRCODE_NONE == aDlgHelper.Execute() )
431         {
432             m_sURL = xFP->getSelectedFiles().getConstArray()[0];
433             INetURLObject aResult( m_sURL );
434             aResult.setExtension(u"csv");
435             m_sURL = aResult.GetMainURL(INetURLObject::DecodeMechanism::NONE);
436         }
437     }
438     if(m_sURL.isEmpty())
439         return;
440 
441     SfxMedium aMedium( m_sURL, StreamMode::READWRITE|StreamMode::TRUNC );
442     SvStream* pStream = aMedium.GetOutStream();
443     pStream->SetLineDelimiter( LINEEND_LF );
444     pStream->SetStreamCharSet(RTL_TEXTENCODING_UTF8);
445 
446     lcl_WriteValues(&(m_pCSVData->aDBColumnHeaders), pStream);
447 
448     for(const auto& rData : m_pCSVData->aDBData)
449     {
450         lcl_WriteValues(&rData, pStream);
451     }
452     aMedium.Commit();
453     m_xDialog->response(RET_OK);
454 }
455 
IMPL_LINK(SwCreateAddressListDialog,DBCursorHdl_Impl,weld::Button &,rButton,void)456 IMPL_LINK(SwCreateAddressListDialog, DBCursorHdl_Impl, weld::Button&, rButton, void)
457 {
458     int nValue = m_xSetNoNF->get_value();
459 
460     if (&rButton == m_xStartPB.get())
461         nValue = 1;
462     else if (&rButton == m_xPrevPB.get())
463     {
464         if (nValue > 1)
465             --nValue;
466     }
467     else if (&rButton == m_xNextPB.get())
468     {
469         if (nValue < m_xSetNoNF->get_max())
470             ++nValue;
471     }
472     else //m_aEndPB
473         nValue = m_xSetNoNF->get_max();
474     if (nValue != m_xSetNoNF->get_value())
475     {
476         m_xSetNoNF->set_value(nValue);
477         RefreshNum_Impl(*m_xSetNoED);
478         DBNumCursor();
479     }
480 }
481 
IMPL_LINK_NOARG(SwCreateAddressListDialog,DBNumCursorHdl_Impl,weld::Entry &,void)482 IMPL_LINK_NOARG(SwCreateAddressListDialog, DBNumCursorHdl_Impl, weld::Entry&, void)
483 {
484     m_xSetNoNF->set_text(m_xSetNoED->get_text());
485     DBNumCursor();
486 }
487 
IMPL_LINK_NOARG(SwCreateAddressListDialog,RefreshNum_Impl,weld::Widget &,void)488 IMPL_LINK_NOARG(SwCreateAddressListDialog, RefreshNum_Impl, weld::Widget&, void)
489 {
490     m_xSetNoED->set_text(OUString::number(m_xSetNoNF->get_value()));
491 }
492 
DBNumCursor()493 void SwCreateAddressListDialog::DBNumCursor()
494 {
495     m_xAddressControl->SetCurrentDataSet(m_xSetNoNF->get_value() - 1);
496     UpdateButtons();
497 }
498 
UpdateButtons()499 void SwCreateAddressListDialog::UpdateButtons()
500 {
501     sal_uInt32 nCurrent = static_cast< sal_uInt32 >(m_xSetNoNF->get_value() );
502     sal_uInt32 nSize = static_cast<sal_uInt32>(m_pCSVData->aDBData.size());
503     m_xStartPB->set_sensitive(nCurrent != 1);
504     m_xPrevPB->set_sensitive(nCurrent != 1);
505     m_xNextPB->set_sensitive(nCurrent != nSize);
506     m_xEndPB->set_sensitive(nCurrent != nSize);
507     m_xDeletePB->set_sensitive(nSize > 0);
508 }
509 
Find(const OUString & rSearch,sal_Int32 nColumn)510 void SwCreateAddressListDialog::Find(const OUString& rSearch, sal_Int32 nColumn)
511 {
512     const OUString sSearch = rSearch.toAsciiLowerCase();
513     sal_uInt32 nCurrent = m_xAddressControl->GetCurrentDataSet();
514     //search forward
515     bool bFound = false;
516     sal_uInt32 nStart = nCurrent + 1;
517     sal_uInt32 nEnd = m_pCSVData->aDBData.size();
518     std::size_t nElement = 0;
519     sal_uInt32 nPos = 0;
520     for(short nTemp = 0; nTemp < 2 && !bFound; nTemp++)
521     {
522         for(nPos = nStart; nPos < nEnd; ++nPos)
523         {
524             std::vector< OUString> const & aData = m_pCSVData->aDBData[nPos];
525             if(nColumn >=0)
526                 bFound = -1 != aData[static_cast<sal_uInt32>(nColumn)].toAsciiLowerCase().indexOf(sSearch);
527             else
528             {
529                 for( nElement = 0; nElement < aData.size(); ++nElement)
530                 {
531                     bFound = -1 != aData[nElement].toAsciiLowerCase().indexOf(sSearch);
532                     if(bFound)
533                     {
534                         nColumn = nElement; //TODO: std::size_t -> sal_Int32!
535                         break;
536                     }
537                 }
538             }
539             if(bFound)
540                 break;
541         }
542         nStart = 0;
543         nEnd = nCurrent + 1;
544     }
545     if(bFound)
546     {
547         m_xAddressControl->SetCurrentDataSet(nPos);
548         m_xSetNoNF->set_value( nPos + 1 );
549         RefreshNum_Impl(*m_xSetNoED);
550         UpdateButtons();
551         m_xAddressControl->SetCursorTo(nElement);
552     }
553 }
554 
SwFindEntryDialog(SwCreateAddressListDialog * pParent)555 SwFindEntryDialog::SwFindEntryDialog(SwCreateAddressListDialog* pParent)
556     : GenericDialogController(pParent->getDialog(), "modules/swriter/ui/findentrydialog.ui", "FindEntryDialog")
557     , m_pParent(pParent)
558     , m_xFindED(m_xBuilder->weld_entry("entry"))
559     , m_xFindOnlyCB(m_xBuilder->weld_check_button("findin"))
560     , m_xFindOnlyLB(m_xBuilder->weld_combo_box("area"))
561     , m_xFindPB(m_xBuilder->weld_button("find"))
562     , m_xCancel(m_xBuilder->weld_button("cancel"))
563 {
564     m_xFindPB->connect_clicked(LINK(this, SwFindEntryDialog, FindHdl_Impl));
565     m_xFindED->connect_changed(LINK(this, SwFindEntryDialog, FindEnableHdl_Impl));
566     m_xCancel->connect_clicked(LINK(this, SwFindEntryDialog, CloseHdl_Impl));
567 }
568 
~SwFindEntryDialog()569 SwFindEntryDialog::~SwFindEntryDialog()
570 {
571 }
572 
IMPL_LINK_NOARG(SwFindEntryDialog,FindHdl_Impl,weld::Button &,void)573 IMPL_LINK_NOARG(SwFindEntryDialog, FindHdl_Impl, weld::Button&, void)
574 {
575     sal_Int32 nColumn = -1;
576     if (m_xFindOnlyCB->get_active())
577         nColumn = m_xFindOnlyLB->get_active();
578     m_pParent->Find(m_xFindED->get_text(), nColumn);
579 }
580 
IMPL_LINK_NOARG(SwFindEntryDialog,FindEnableHdl_Impl,weld::Entry &,void)581 IMPL_LINK_NOARG(SwFindEntryDialog, FindEnableHdl_Impl, weld::Entry&, void)
582 {
583     m_xFindPB->set_sensitive(!m_xFindED->get_text().isEmpty());
584 }
585 
IMPL_LINK_NOARG(SwFindEntryDialog,CloseHdl_Impl,weld::Button &,void)586 IMPL_LINK_NOARG(SwFindEntryDialog, CloseHdl_Impl, weld::Button&, void)
587 {
588     m_xDialog->hide();
589 }
590 
591 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
592