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