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