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 <addresslistdialog.hxx>
22 : #include <selectdbtabledialog.hxx>
23 : #include <createaddresslistdialog.hxx>
24 : #include <mailmergewizard.hxx>
25 : #include <mmconfigitem.hxx>
26 : #include <mmaddressblockpage.hxx>
27 : #include <dbmgr.hxx>
28 : #include <dbconfig.hxx>
29 : #include <unotools/tempfile.hxx>
30 : #include <vcl/msgbox.hxx>
31 : #include <vcl/svapp.hxx>
32 : #include <tools/urlobj.hxx>
33 : #include <comphelper/processfactory.hxx>
34 : #include <comphelper/types.hxx>
35 : #include "svtools/treelistentry.hxx"
36 : #include <com/sun/star/sdbc/XCloseable.hpp>
37 : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
38 : #include <com/sun/star/container/XNameAccess.hpp>
39 : #include <com/sun/star/uno/XNamingService.hpp>
40 : #include <com/sun/star/sdb/DatabaseContext.hpp>
41 : #include <com/sun/star/sdb/XCompletedConnection.hpp>
42 : #include <com/sun/star/sdb/CommandType.hpp>
43 : #include <com/sun/star/sdb/XDocumentDataSource.hpp>
44 : #include <com/sun/star/sdbc/XRowSet.hpp>
45 : #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
46 : #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
47 : #include <com/sun/star/sdb/XQueriesSupplier.hpp>
48 : #include <com/sun/star/task/InteractionHandler.hpp>
49 : #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
50 : #include <com/sun/star/frame/XStorable.hpp>
51 : #include <swunohelper.hxx>
52 : #include <vcl/waitobj.hxx>
53 : #include <unotools/pathoptions.hxx>
54 : #include <svl/urihelper.hxx>
55 : #include <addresslistdialog.hrc>
56 : #include <dbui.hrc>
57 :
58 : #include <helpid.h>
59 : #include <unomid.h>
60 :
61 :
62 : using namespace ::com::sun::star;
63 : using namespace ::com::sun::star::uno;
64 : using namespace ::com::sun::star::lang;
65 : using namespace ::com::sun::star::container;
66 : using namespace ::com::sun::star::sdb;
67 : using namespace ::com::sun::star::sdbc;
68 : using namespace ::com::sun::star::sdbcx;
69 : using namespace ::com::sun::star::task;
70 : using namespace ::com::sun::star::beans;
71 : using namespace ::com::sun::star::ui::dialogs;
72 : using namespace ::rtl;
73 :
74 : #define ITEMID_NAME 1
75 : #define ITEMID_TABLE 2
76 :
77 : static const char* cUTF8 = "UTF-8";
78 :
79 0 : struct AddressUserData_Impl
80 : {
81 : uno::Reference<XDataSource> xSource;
82 : SharedConnection xConnection;
83 : uno::Reference< XColumnsSupplier> xColumnsSupplier;
84 : uno::Reference< sdbc::XResultSet> xResultSet;
85 : ::rtl::OUString sFilter;
86 : ::rtl::OUString sURL; // data is editable
87 : sal_Int32 nCommandType;
88 : sal_Int32 nTableAndQueryCount;
89 0 : AddressUserData_Impl() :
90 : nCommandType(0),
91 0 : nTableAndQueryCount(-1)
92 0 : {}
93 : };
94 :
95 0 : static ::rtl::OUString lcl_getFlatURL( uno::Reference<beans::XPropertySet>& xSourceProperties )
96 : {
97 0 : ::rtl::OUString sURL;
98 0 : if(xSourceProperties.is())
99 : {
100 0 : rtl::OUString sDBURL;
101 0 : xSourceProperties->getPropertyValue(C2U("URL")) >>= sDBURL;
102 0 : if(String(sDBURL).SearchAscii("sdbc:flat:") == 0)
103 : {
104 0 : uno::Sequence<OUString> aFilters;
105 0 : xSourceProperties->getPropertyValue(C2U("TableFilter")) >>= aFilters;
106 0 : uno::Sequence<PropertyValue> aInfo;
107 0 : xSourceProperties->getPropertyValue(C2U("Info")) >>= aInfo;
108 0 : if(aFilters.getLength() == 1 && aInfo.getLength() )
109 : {
110 0 : ::rtl::OUString sFieldDelim;
111 0 : ::rtl::OUString sStringDelim;
112 0 : ::rtl::OUString sExtension;
113 0 : ::rtl::OUString sCharSet;
114 0 : for(sal_Int32 nInfo = 0; nInfo < aInfo.getLength(); ++nInfo)
115 : {
116 0 : if(aInfo[nInfo].Name == C2U("FieldDelimiter"))
117 0 : aInfo[nInfo].Value >>= sFieldDelim;
118 0 : else if(aInfo[nInfo].Name == C2U("StringDelimiter"))
119 0 : aInfo[nInfo].Value >>= sStringDelim;
120 0 : else if(aInfo[nInfo].Name == C2U("Extension"))
121 0 : aInfo[nInfo].Value >>= sExtension;
122 0 : else if(aInfo[nInfo].Name == C2U("CharSet"))
123 0 : aInfo[nInfo].Value >>= sCharSet;
124 : }
125 0 : if(!sCharSet.compareToAscii( cUTF8 ))
126 : {
127 0 : sURL = String(sDBURL).Copy( 10 );
128 : //#i97577# at this point the 'URL' can also be a file name!
129 0 : sURL = URIHelper::SmartRel2Abs( INetURLObject(), sURL );
130 0 : sURL += C2U("/");
131 0 : sURL += aFilters[0];
132 0 : sURL += C2U(".");
133 0 : sURL += sExtension;
134 0 : }
135 0 : }
136 0 : }
137 : }
138 0 : return sURL;
139 : }
140 :
141 0 : SwAddressListDialog::SwAddressListDialog(SwMailMergeAddressBlockPage* pParent) :
142 : SfxModalDialog(pParent, SW_RES(DLG_MM_ADDRESSLISTDIALOG)),
143 : #ifdef MSC
144 : #pragma warning (disable : 4355)
145 : #endif
146 : m_aDescriptionFI( this, SW_RES( FI_DESCRIPTION )),
147 : m_aListFT( this, SW_RES( FT_LIST )),
148 : m_aListHB( this, WB_BUTTONSTYLE | WB_BOTTOMBORDER),
149 : m_aListLB( this, SW_RES( LB_LIST )),
150 : m_aLoadListPB( this, SW_RES( PB_LOADLIST )),
151 : m_aCreateListPB(this, SW_RES( PB_CREATELIST )),
152 : m_aFilterPB( this, SW_RES( PB_FILTER )),
153 : m_aEditPB(this, SW_RES( PB_EDIT )),
154 : m_aTablePB(this, SW_RES( PB_TABLE )),
155 : m_aSeparatorFL(this, SW_RES( FL_SEPARATOR )),
156 : m_aOK( this, SW_RES( PB_OK )),
157 : m_aCancel( this, SW_RES( PB_CANCEL )),
158 : m_aHelp( this, SW_RES( PB_HELP )),
159 : #ifdef MSC
160 : #pragma warning (default : 4355)
161 : #endif
162 : m_sName( SW_RES( ST_NAME )),
163 : m_sTable( SW_RES( ST_TABLE )),
164 : m_sConnecting( SW_RES( ST_CONNECTING )),
165 : m_pCreatedDataSource(0),
166 : m_bInSelectHdl(false),
167 0 : m_pAddressPage(pParent)
168 : {
169 0 : FreeResource();
170 0 : String sTemp(m_aDescriptionFI.GetText());
171 0 : sTemp.SearchAndReplaceAscii("%1", m_aLoadListPB.GetText());
172 0 : sTemp.SearchAndReplaceAscii("%2", m_aCreateListPB.GetText());
173 0 : m_aDescriptionFI.SetText(sTemp);
174 0 : m_aFilterPB.SetClickHdl( LINK( this, SwAddressListDialog, FilterHdl_Impl ));
175 0 : m_aLoadListPB.SetClickHdl( LINK( this, SwAddressListDialog, LoadHdl_Impl ));
176 0 : m_aCreateListPB.SetClickHdl( LINK( this, SwAddressListDialog,CreateHdl_Impl ));
177 0 : m_aEditPB.SetClickHdl(LINK( this, SwAddressListDialog, EditHdl_Impl));
178 0 : m_aTablePB.SetClickHdl(LINK( this, SwAddressListDialog, TableSelectHdl_Impl));
179 :
180 0 : Size aLBSize(m_aListLB.GetSizePixel());
181 0 : m_aListHB.SetSizePixel(aLBSize);
182 0 : Size aHeadSize(m_aListHB.CalcWindowSizePixel());
183 0 : aHeadSize.Width() = aLBSize.Width();
184 0 : m_aListHB.SetSizePixel(aHeadSize);
185 0 : Point aLBPos(m_aListLB.GetPosPixel());
186 0 : m_aListHB.SetPosPixel(aLBPos);
187 0 : aLBPos.Y() += aHeadSize.Height();
188 0 : aLBSize.Height() -= aHeadSize.Height();
189 0 : m_aListLB.SetPosSizePixel(aLBPos, aLBSize);
190 :
191 0 : Size aSz(m_aListHB.GetOutputSizePixel());
192 : m_aListHB.InsertItem( ITEMID_NAME, m_sName,
193 0 : aSz.Width()/2,
194 0 : HIB_LEFT | HIB_VCENTER | HIB_FIXED | HIB_FIXEDPOS/*| HIB_CLICKABLE | HIB_UPARROW */);
195 : m_aListHB.InsertItem( ITEMID_TABLE, m_sTable,
196 0 : aSz.Width()/2,
197 0 : HIB_LEFT | HIB_VCENTER | HIB_FIXED | HIB_FIXEDPOS /*| HIB_CLICKABLE | HIB_UPARROW */);
198 0 : m_aListHB.SetHelpId(HID_MM_ADDRESSLIST_HB );
199 0 : m_aListHB.Show();
200 :
201 0 : m_aListLB.SetHelpId(HID_MM_ADDRESSLIST_TLB);
202 0 : static long nTabs[] = {2, 0, aSz.Width()/2 };
203 0 : m_aListLB.SetStyle( m_aListLB.GetStyle() | WB_SORT | WB_HSCROLL | WB_CLIPCHILDREN | WB_TABSTOP );
204 0 : m_aListLB.SetSelectionMode( SINGLE_SELECTION );
205 0 : m_aListLB.SetTabs(&nTabs[0], MAP_PIXEL);
206 0 : m_aOK.SetClickHdl( LINK( this, SwAddressListDialog, OKHdl_Impl));
207 :
208 0 : uno::Reference<XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
209 0 : m_xDBContext = DatabaseContext::create(xContext);
210 :
211 0 : SwMailMergeConfigItem& rConfigItem = m_pAddressPage->GetWizard()->GetConfigItem();
212 0 : const SwDBData& rCurrentData = rConfigItem.GetCurrentDBData();
213 :
214 0 : sal_Bool bEnableEdit = sal_False;
215 0 : sal_Bool bEnableOK = sal_True;
216 0 : m_aListLB.SelectAll( sal_False );
217 :
218 0 : SwDBConfig aDb;
219 0 : ::rtl::OUString sBibliography = aDb.GetBibliographySource().sDataSource;
220 0 : uno::Sequence< ::rtl::OUString> aNames = m_xDBContext->getElementNames();
221 0 : const ::rtl::OUString* pNames = aNames.getConstArray();
222 0 : for(sal_Int32 nName = 0; nName < aNames.getLength(); ++nName)
223 : {
224 0 : if ( pNames[nName] == sBibliography )
225 0 : continue;
226 0 : SvTreeListEntry* pEntry = m_aListLB.InsertEntry(pNames[nName]);
227 0 : AddressUserData_Impl* pUserData = new AddressUserData_Impl();
228 0 : pEntry->SetUserData(pUserData);
229 0 : if(pNames[nName] == rCurrentData.sDataSource)
230 : {
231 0 : m_aListLB.Select(pEntry);
232 0 : m_aListLB.SetEntryText(rCurrentData.sCommand, pEntry, ITEMID_TABLE - 1);
233 0 : pUserData->nCommandType = rCurrentData.nCommandType;
234 0 : pUserData->xSource = rConfigItem.GetSource();
235 0 : pUserData->xConnection = rConfigItem.GetConnection();
236 0 : pUserData->xColumnsSupplier = rConfigItem.GetColumnsSupplier();
237 0 : pUserData->xResultSet = rConfigItem.GetResultSet();
238 0 : pUserData->sFilter = rConfigItem.GetFilter();
239 : //is the data source editable (csv, Unicode, single table)
240 0 : uno::Reference<beans::XPropertySet> xSourceProperties;
241 : try
242 : {
243 0 : m_xDBContext->getByName(pNames[nName]) >>= xSourceProperties;
244 0 : pUserData->sURL = lcl_getFlatURL( xSourceProperties );
245 0 : bEnableEdit = !pUserData->sURL.isEmpty() &&
246 0 : SWUnoHelper::UCB_IsFile( pUserData->sURL ) && //#i97577#
247 0 : !SWUnoHelper::UCB_IsReadOnlyFileName( pUserData->sURL );
248 : }
249 0 : catch (const uno::Exception&)
250 : {
251 0 : bEnableOK = sal_False;
252 : }
253 0 : m_aDBData = rCurrentData;
254 : }
255 : }
256 :
257 0 : m_aOK.Enable(m_aListLB.GetEntryCount()>0 && bEnableOK);
258 0 : m_aEditPB.Enable(bEnableEdit);
259 0 : m_aListLB.SetSelectHdl(LINK(this, SwAddressListDialog, ListBoxSelectHdl_Impl));
260 0 : TableSelectHdl_Impl(NULL);
261 0 : }
262 :
263 0 : SwAddressListDialog::~SwAddressListDialog()
264 : {
265 0 : SvTreeListEntry* pEntry = m_aListLB.First();
266 0 : while(pEntry)
267 : {
268 0 : AddressUserData_Impl* pUserData = static_cast<AddressUserData_Impl*>(pEntry->GetUserData());
269 0 : delete pUserData;
270 0 : pEntry = m_aListLB.Next( pEntry );
271 : }
272 0 : }
273 :
274 0 : IMPL_LINK_NOARG(SwAddressListDialog, FilterHdl_Impl)
275 : {
276 0 : SvTreeListEntry* pSelect = m_aListLB.FirstSelected();
277 0 : uno::Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
278 0 : if(pSelect && xMgr.is())
279 : {
280 0 : String sCommand = m_aListLB.GetEntryText(pSelect, ITEMID_TABLE - 1);
281 0 : if ( !sCommand.Len() )
282 0 : return 0;
283 :
284 0 : AddressUserData_Impl* pUserData = static_cast<AddressUserData_Impl*>(pSelect->GetUserData());
285 0 : if(pUserData->xConnection.is() )
286 : {
287 : try
288 : {
289 0 : uno::Reference<lang::XMultiServiceFactory> xConnectFactory(pUserData->xConnection, UNO_QUERY_THROW);
290 : uno::Reference<XSingleSelectQueryComposer> xComposer(
291 0 : xConnectFactory->createInstance(C2U("com.sun.star.sdb.SingleSelectQueryComposer")), UNO_QUERY_THROW);
292 :
293 0 : PropertyValue aSecond;
294 0 : aSecond.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RowSet" ) );
295 : uno::Reference<XRowSet> xRowSet(
296 0 : xMgr->createInstance(C2U("com.sun.star.sdb.RowSet")), UNO_QUERY);
297 0 : uno::Reference<XPropertySet> xRowProperties(xRowSet, UNO_QUERY);
298 0 : xRowProperties->setPropertyValue(C2U("DataSourceName"),
299 0 : makeAny(OUString(m_aListLB.GetEntryText(pSelect, ITEMID_NAME - 1))));
300 0 : xRowProperties->setPropertyValue(C2U("Command"), makeAny(
301 0 : OUString(sCommand)));
302 0 : xRowProperties->setPropertyValue(C2U("CommandType"), makeAny(pUserData->nCommandType));
303 0 : xRowProperties->setPropertyValue(C2U("ActiveConnection"), makeAny(pUserData->xConnection.getTyped()));
304 0 : xRowSet->execute();
305 0 : aSecond.Value <<= xRowSet;
306 :
307 0 : PropertyValue aFirst;
308 0 : aFirst.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "QueryComposer" ) );
309 0 : ::rtl::OUString sQuery;
310 0 : xRowProperties->getPropertyValue(C2U("ActiveCommand"))>>= sQuery;
311 0 : xComposer->setQuery(sQuery);
312 0 : if(!pUserData->sFilter.isEmpty())
313 0 : xComposer->setFilter(pUserData->sFilter);
314 0 : aFirst.Value <<= xComposer;
315 :
316 0 : uno::Sequence<Any> aInit(2);
317 0 : aInit[0] <<= aFirst;
318 0 : aInit[1] <<= aSecond;
319 :
320 0 : ::rtl::OUString sDialogServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.FilterDialog" ) );
321 : uno::Reference< XExecutableDialog> xDialog(
322 0 : xMgr->createInstanceWithArguments( sDialogServiceName, aInit ), UNO_QUERY);
323 :
324 0 : if ( RET_OK == xDialog->execute() )
325 : {
326 0 : WaitObject aWO( NULL );
327 0 : pUserData->sFilter = xComposer->getFilter();
328 : }
329 0 : ::comphelper::disposeComponent(xRowSet);
330 : }
331 0 : catch (const Exception&)
332 : {
333 : OSL_FAIL("exception caught in SwAddressListDialog::FilterHdl_Impl");
334 : }
335 0 : }
336 : }
337 0 : return 0;
338 : }
339 :
340 0 : IMPL_LINK_NOARG(SwAddressListDialog, LoadHdl_Impl)
341 : {
342 0 : String sNewSource = SwNewDBMgr::LoadAndRegisterDataSource();
343 0 : if(sNewSource.Len())
344 : {
345 0 : SvTreeListEntry* pNewSource = m_aListLB.InsertEntry(sNewSource);
346 0 : pNewSource->SetUserData(new AddressUserData_Impl());
347 0 : m_aListLB.Select(pNewSource);
348 : }
349 0 : return 0;
350 : }
351 :
352 0 : IMPL_LINK(SwAddressListDialog, CreateHdl_Impl, PushButton*, pButton)
353 : {
354 0 : String sInputURL;
355 : SwCreateAddressListDialog* pDlg =
356 : new SwCreateAddressListDialog(
357 : pButton,
358 : sInputURL,
359 0 : m_pAddressPage->GetWizard()->GetConfigItem());
360 0 : if(RET_OK == pDlg->Execute())
361 : {
362 : //register the URL a new datasource
363 0 : OUString sURL = pDlg->GetURL();
364 : try
365 : {
366 0 : uno::Reference<XSingleServiceFactory> xFact( m_xDBContext, UNO_QUERY);
367 0 : uno::Reference<XInterface> xNewInstance = xFact->createInstance();
368 0 : INetURLObject aURL( sURL );
369 0 : OUString sNewName = aURL.getBase();
370 : //find a unique name if sNewName already exists
371 0 : OUString sFind(sNewName);
372 0 : sal_Int32 nIndex = 0;
373 0 : while(m_xDBContext->hasByName(sFind))
374 : {
375 0 : sFind = sNewName;
376 0 : sFind += OUString::valueOf(++nIndex);
377 : }
378 0 : uno::Reference<XPropertySet> xDataProperties(xNewInstance, UNO_QUERY);
379 :
380 0 : OUString sDBURL(C2U("sdbc:flat:"));
381 : //only the 'path' has to be added
382 0 : INetURLObject aTempURL(aURL);
383 0 : aTempURL.removeSegment();
384 0 : aTempURL.removeFinalSlash();
385 0 : sDBURL += aTempURL.GetMainURL(INetURLObject::NO_DECODE);
386 0 : Any aAny(&sDBURL, ::getCppuType(&sDBURL));
387 0 : xDataProperties->setPropertyValue(C2U("URL"), aAny);
388 : //set the filter to the file name without extension
389 0 : uno::Sequence<OUString> aFilters(1);
390 0 : aFilters[0] = sNewName;
391 0 : aAny <<= aFilters;
392 0 : xDataProperties->setPropertyValue(C2U("TableFilter"), aAny);
393 :
394 0 : uno::Sequence<PropertyValue> aInfo(4);
395 0 : PropertyValue* pInfo = aInfo.getArray();
396 0 : pInfo[0].Name = C2U("FieldDelimiter");
397 0 : pInfo[0].Value <<= OUString('\t');
398 0 : pInfo[1].Name = C2U("StringDelimiter");
399 0 : pInfo[1].Value <<= OUString('"');
400 0 : pInfo[2].Name = C2U("Extension");
401 0 : pInfo[2].Value <<= ::rtl::OUString(aURL.getExtension());//C2U("csv");
402 0 : pInfo[3].Name = C2U("CharSet");
403 0 : pInfo[3].Value <<= rtl::OUString::createFromAscii(cUTF8);
404 0 : aAny <<= aInfo;
405 0 : xDataProperties->setPropertyValue(C2U("Info"), aAny);
406 :
407 0 : uno::Reference<sdb::XDocumentDataSource> xDS(xNewInstance, UNO_QUERY_THROW);
408 0 : uno::Reference<frame::XStorable> xStore(xDS->getDatabaseDocument(), UNO_QUERY_THROW);
409 0 : String sExt = rtl::OUString(".odb");
410 0 : String sTmpName;
411 : {
412 0 : String sHomePath(SvtPathOptions().GetWorkPath());
413 0 : utl::TempFile aTempFile(sFind , &sExt, &sHomePath);
414 0 : aTempFile.EnableKillingFile(sal_True);
415 0 : sTmpName = aTempFile.GetURL();
416 : }
417 0 : xStore->storeAsURL(sTmpName, Sequence< PropertyValue >());
418 :
419 :
420 0 : uno::Reference<XNamingService> xNaming(m_xDBContext, UNO_QUERY);
421 0 : xNaming->registerObject( sFind, xNewInstance );
422 : //now insert the new source into the ListBox
423 0 : String sEntry(sFind);
424 0 : sEntry += '\t';
425 0 : sEntry += String(aFilters[0]);
426 0 : m_pCreatedDataSource = m_aListLB.InsertEntry(sEntry);
427 0 : AddressUserData_Impl* pUserData = new AddressUserData_Impl();
428 0 : pUserData->sURL = sURL;
429 0 : m_pCreatedDataSource->SetUserData(pUserData);
430 0 : m_aListLB.Select(m_pCreatedDataSource);
431 0 : m_aCreateListPB.Enable(sal_False);
432 :
433 : }
434 0 : catch (const Exception&)
435 : {
436 0 : }
437 : }
438 0 : delete pDlg;
439 0 : return 0;
440 : }
441 :
442 0 : IMPL_LINK(SwAddressListDialog, EditHdl_Impl, PushButton*, pButton)
443 : {
444 0 : SvTreeListEntry* pEntry = m_aListLB.FirstSelected();
445 0 : AddressUserData_Impl* pUserData = pEntry ? static_cast<AddressUserData_Impl*>(pEntry->GetUserData()) : 0;
446 0 : if(pUserData && !pUserData->sURL.isEmpty())
447 : {
448 0 : if(pUserData->xResultSet.is())
449 : {
450 0 : SwMailMergeConfigItem& rConfigItem = m_pAddressPage->GetWizard()->GetConfigItem();
451 0 : if(rConfigItem.GetResultSet() != pUserData->xResultSet)
452 0 : ::comphelper::disposeComponent( pUserData->xResultSet );
453 0 : pUserData->xResultSet = 0;
454 :
455 0 : rConfigItem.DisposeResultSet();
456 : }
457 0 : pUserData->xSource.clear();
458 0 : pUserData->xColumnsSupplier.clear();
459 0 : pUserData->xConnection.clear();
460 : // will automatically close if it was the las reference
461 : SwCreateAddressListDialog* pDlg =
462 : new SwCreateAddressListDialog(
463 : pButton,
464 : pUserData->sURL,
465 0 : m_pAddressPage->GetWizard()->GetConfigItem());
466 0 : if(RET_OK == pDlg->Execute())
467 : {
468 : }
469 0 : delete pDlg;
470 : }
471 0 : return 0;
472 : };
473 :
474 0 : IMPL_LINK_NOARG(SwAddressListDialog, ListBoxSelectHdl_Impl)
475 : {
476 0 : SvTreeListEntry* pSelect = m_aListLB.FirstSelected();
477 : Application::PostUserEvent( STATIC_LINK( this, SwAddressListDialog,
478 0 : StaticListBoxSelectHdl_Impl ), pSelect );
479 0 : return 0;
480 : }
481 :
482 0 : IMPL_STATIC_LINK(SwAddressListDialog, StaticListBoxSelectHdl_Impl, SvTreeListEntry*, pSelect)
483 : {
484 : //prevent nested calls of the select handler
485 0 : if(pThis->m_bInSelectHdl)
486 0 : return 0;
487 0 : pThis->EnterWait();
488 0 : pThis->m_bInSelectHdl = true;
489 0 : AddressUserData_Impl* pUserData = 0;
490 0 : if(pSelect)
491 : {
492 0 : String sTable = pThis->m_aListLB.GetEntryText(pSelect, ITEMID_TABLE - 1);
493 0 : if(!sTable.Len())
494 : {
495 0 : pThis->m_aListLB.SetEntryText(pThis->m_sConnecting, pSelect, ITEMID_TABLE - 1);
496 : // allow painting of the new entry
497 0 : pThis->m_aListLB.Window::Invalidate(INVALIDATE_UPDATE);
498 0 : for (sal_uInt16 i = 0; i < 10; i++)
499 0 : Application::Reschedule();
500 : }
501 :
502 0 : pUserData = static_cast<AddressUserData_Impl*>(pSelect->GetUserData());
503 0 : if(pUserData->nTableAndQueryCount > 1 || pUserData->nTableAndQueryCount == -1)
504 : {
505 : /*
506 : * We're a callback from a selection from a list box, which takes
507 : * place on mouse down before mouse up. The next dialog also has a
508 : * list box. Spawning it means this list box doesn't get the mouse
509 : * down event. So it sticks on "making selection" mode. So if you
510 : * cancel the next dialog and just move the mouse out of this entry
511 : * and back then the dialog pops up again, without requiring a click
512 : *
513 : * Most expedient thing to do is to manually end the parent selection
514 : * here.
515 : */
516 0 : pThis->m_aListLB.EndSelection();
517 0 : pThis->DetectTablesAndQueries(pSelect, !sTable.Len());
518 : }
519 : else
520 : {
521 : //otherwise set the selected db-data
522 0 : pThis->m_aDBData.sDataSource = pThis->m_aListLB.GetEntryText(pSelect, ITEMID_NAME - 1);
523 0 : pThis->m_aDBData.sCommand = pThis->m_aListLB.GetEntryText(pSelect, ITEMID_TABLE - 1);
524 0 : pThis->m_aDBData.nCommandType = pUserData->nCommandType;
525 0 : pThis->m_aOK.Enable(sal_True);
526 : }
527 0 : sTable = pThis->m_aListLB.GetEntryText(pSelect, ITEMID_TABLE - 1);
528 0 : if(sTable == pThis->m_sConnecting)
529 0 : pThis->m_aListLB.SetEntryText(String(), pSelect, ITEMID_TABLE - 1);
530 : }
531 0 : pThis->m_aEditPB.Enable(pUserData && !pUserData->sURL.isEmpty() &&
532 0 : SWUnoHelper::UCB_IsFile( pUserData->sURL ) && //#i97577#
533 0 : !SWUnoHelper::UCB_IsReadOnlyFileName( pUserData->sURL ) );
534 0 : pThis->m_bInSelectHdl = false;
535 0 : pThis->LeaveWait();
536 0 : return 0;
537 : }
538 :
539 : // detect the number of tables for a data source
540 : // if only one is available then set it at the entry
541 0 : void SwAddressListDialog::DetectTablesAndQueries(
542 : SvTreeListEntry* pSelect,
543 : bool bWidthDialog)
544 : {
545 : try
546 : {
547 0 : AddressUserData_Impl* pUserData = static_cast<AddressUserData_Impl*>(pSelect->GetUserData());
548 0 : uno::Reference<XCompletedConnection> xComplConnection;
549 0 : if(!pUserData->xConnection.is())
550 : {
551 0 : m_aDBData.sDataSource = m_aListLB.GetEntryText(pSelect, ITEMID_NAME - 1);
552 0 : m_xDBContext->getByName(m_aDBData.sDataSource) >>= xComplConnection;
553 0 : pUserData->xSource = uno::Reference<XDataSource>(xComplConnection, UNO_QUERY);
554 :
555 0 : uno::Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
556 0 : uno::Reference< XInteractionHandler > xHandler( InteractionHandler::createWithParent(xContext, 0), UNO_QUERY );
557 0 : pUserData->xConnection = SharedConnection( xComplConnection->connectWithCompletion( xHandler ) );
558 : }
559 0 : if(pUserData->xConnection.is())
560 : {
561 0 : sal_Int32 nTables = 0;
562 0 : uno::Sequence<rtl::OUString> aTables;
563 0 : uno::Sequence<rtl::OUString> aQueries;
564 0 : uno::Reference<XTablesSupplier> xTSupplier(pUserData->xConnection, UNO_QUERY);
565 0 : if(xTSupplier.is())
566 : {
567 0 : uno::Reference<XNameAccess> xTbls = xTSupplier->getTables();
568 0 : aTables = xTbls->getElementNames();
569 0 : nTables += aTables.getLength();
570 : }
571 0 : uno::Reference<XQueriesSupplier> xQSupplier(pUserData->xConnection, UNO_QUERY);
572 0 : if(xQSupplier.is())
573 : {
574 0 : uno::Reference<XNameAccess> xQueries = xQSupplier->getQueries();
575 0 : aQueries = xQueries->getElementNames();
576 0 : nTables += aQueries.getLength();
577 : }
578 0 : pUserData->nTableAndQueryCount = nTables;
579 0 : if(nTables > 1 && bWidthDialog)
580 : {
581 : //now call the table select dialog - if more than one table exists
582 0 : SwSelectDBTableDialog* pDlg = new SwSelectDBTableDialog(this, pUserData->xConnection);
583 0 : String sTable = m_aListLB.GetEntryText(pSelect, ITEMID_TABLE - 1);
584 0 : if(sTable.Len())
585 0 : pDlg->SetSelectedTable(sTable, pUserData->nCommandType == CommandType::TABLE);
586 0 : if(RET_OK == pDlg->Execute())
587 : {
588 : bool bIsTable;
589 0 : m_aDBData.sCommand = pDlg->GetSelectedTable(bIsTable);
590 0 : m_aDBData.nCommandType = bIsTable ? CommandType::TABLE : CommandType::QUERY;
591 0 : pUserData->nCommandType = m_aDBData.nCommandType;
592 : }
593 0 : delete pDlg;
594 : }
595 0 : else if(nTables == 1)
596 : {
597 0 : if(aTables.getLength())
598 : {
599 0 : m_aDBData.sCommand = aTables[0];
600 0 : m_aDBData.nCommandType = CommandType::TABLE;
601 : }
602 : else
603 : {
604 0 : m_aDBData.sCommand = aQueries[0];
605 0 : m_aDBData.nCommandType = CommandType::QUERY;
606 : }
607 0 : }
608 : }
609 0 : if ( !m_aDBData.sCommand.isEmpty() )
610 : {
611 0 : uno::Reference<beans::XPropertySet> xSourceProperties;
612 0 : m_xDBContext->getByName(m_aDBData.sDataSource) >>= xSourceProperties;
613 0 : pUserData->sURL = lcl_getFlatURL( xSourceProperties );
614 :
615 : pUserData->xColumnsSupplier = SwNewDBMgr::GetColumnSupplier(pUserData->xConnection,
616 : m_aDBData.sCommand,
617 : m_aDBData.nCommandType == CommandType::TABLE ?
618 0 : SW_DB_SELECT_TABLE : SW_DB_SELECT_QUERY );
619 : //#i97577#
620 0 : if( pUserData->xColumnsSupplier.is() )
621 0 : m_aListLB.SetEntryText(m_aDBData.sCommand, pSelect, ITEMID_TABLE - 1);
622 : else
623 0 : m_aListLB.SetEntryText(String(), pSelect, ITEMID_TABLE - 1);
624 : }
625 0 : String sCommand = m_aListLB.GetEntryText(pSelect, ITEMID_TABLE - 1);
626 0 : m_aOK.Enable(pSelect && sCommand.Len());
627 0 : m_aFilterPB.Enable( pUserData->xConnection.is() && sCommand.Len() );
628 0 : m_aTablePB.Enable( pUserData->nTableAndQueryCount > 1 );
629 : }
630 0 : catch (const Exception&)
631 : {
632 : OSL_FAIL("exception caught in SwAddressListDialog::DetectTablesAndQueries");
633 0 : m_aOK.Enable( sal_False );
634 : }
635 0 : }
636 :
637 0 : IMPL_LINK(SwAddressListDialog, TableSelectHdl_Impl, PushButton*, pButton)
638 : {
639 0 : EnterWait();
640 0 : SvTreeListEntry* pSelect = m_aListLB.FirstSelected();
641 0 : if(pSelect)
642 : {
643 0 : AddressUserData_Impl* pUserData = static_cast<AddressUserData_Impl*>(pSelect->GetUserData());
644 : //only call the table select dialog if tables have not been searched for or there
645 : //are more than 1
646 0 : String sTable = m_aListLB.GetEntryText(pSelect, ITEMID_TABLE - 1);
647 0 : if( pUserData->nTableAndQueryCount > 1 || pUserData->nTableAndQueryCount == -1)
648 : {
649 0 : DetectTablesAndQueries(pSelect, (pButton != 0) || (!sTable.Len()));
650 0 : }
651 : }
652 :
653 0 : LeaveWait();
654 0 : return 0;
655 : }
656 :
657 0 : IMPL_LINK_NOARG(SwAddressListDialog, OKHdl_Impl)
658 : {
659 0 : EndDialog(sal_True);
660 0 : return 0;
661 : }
662 :
663 0 : uno::Reference< XDataSource> SwAddressListDialog::GetSource()
664 : {
665 0 : uno::Reference< XDataSource> xRet;
666 0 : SvTreeListEntry* pSelect = m_aListLB.FirstSelected();
667 0 : if(pSelect)
668 : {
669 0 : AddressUserData_Impl* pUserData = static_cast<AddressUserData_Impl*>(pSelect->GetUserData());
670 0 : xRet = pUserData->xSource;
671 : }
672 0 : return xRet;
673 :
674 : }
675 :
676 0 : SharedConnection SwAddressListDialog::GetConnection()
677 : {
678 0 : SharedConnection xRet;
679 0 : SvTreeListEntry* pSelect = m_aListLB.FirstSelected();
680 0 : if(pSelect)
681 : {
682 0 : AddressUserData_Impl* pUserData = static_cast<AddressUserData_Impl*>(pSelect->GetUserData());
683 0 : xRet = pUserData->xConnection;
684 : }
685 0 : return xRet;
686 : }
687 :
688 0 : uno::Reference< XColumnsSupplier> SwAddressListDialog::GetColumnsSupplier()
689 : {
690 0 : uno::Reference< XColumnsSupplier> xRet;
691 0 : SvTreeListEntry* pSelect = m_aListLB.FirstSelected();
692 0 : if(pSelect)
693 : {
694 0 : AddressUserData_Impl* pUserData = static_cast<AddressUserData_Impl*>(pSelect->GetUserData());
695 0 : xRet = pUserData->xColumnsSupplier;
696 : }
697 0 : return xRet;
698 : }
699 :
700 0 : ::rtl::OUString SwAddressListDialog::GetFilter()
701 : {
702 0 : ::rtl::OUString sRet;
703 0 : SvTreeListEntry* pSelect = m_aListLB.FirstSelected();
704 0 : if(pSelect)
705 : {
706 0 : AddressUserData_Impl* pUserData = static_cast<AddressUserData_Impl*>(pSelect->GetUserData());
707 0 : sRet = pUserData->sFilter;
708 : }
709 0 : return sRet;
710 : }
711 :
712 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|