tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / dbaccess / source / ui / dlg / dbwizsetup.cxx
blobec6c9040fd030b40e135ae0015cbb121b47132b8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <core_resource.hxx>
21 #include <dbwizsetup.hxx>
22 #include <dsmeta.hxx>
23 #include "DBSetupConnectionPages.hxx"
24 #include <strings.hrc>
25 #include <strings.hxx>
26 #include <dsitems.hxx>
27 #include "dsnItem.hxx"
29 #include <unotools/pathoptions.hxx>
30 #include <svl/stritem.hxx>
31 #include "adminpages.hxx"
32 #include <sfx2/docfilt.hxx>
33 #include <unotools/ucbhelper.hxx>
34 #include "generalpage.hxx"
35 #include <unotools/confignode.hxx>
36 #include "DbAdminImpl.hxx"
37 #include <helpids.h>
38 #include "ConnectionPageSetup.hxx"
39 #include <UITools.hxx>
40 #include <dbaccess/AsynchronousLink.hxx>
41 #include <sfx2/filedlghelper.hxx>
42 #include <cppuhelper/exc_hlp.hxx>
43 #include <cppuhelper/implbase.hxx>
44 #include <com/sun/star/frame/TerminationVetoException.hpp>
45 #include <com/sun/star/frame/XStorable.hpp>
46 #include <com/sun/star/sdb/DatabaseContext.hpp>
47 #include <com/sun/star/frame/Desktop.hpp>
48 #include <com/sun/star/frame/FrameSearchFlag.hpp>
49 #include <com/sun/star/frame/XComponentLoader.hpp>
50 #include <com/sun/star/frame/XModel.hpp>
51 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
52 #include <com/sun/star/ucb/InteractiveIOException.hpp>
53 #include <com/sun/star/io/IOException.hpp>
54 #include <com/sun/star/frame/XTerminateListener.hpp>
55 #include <com/sun/star/document/MacroExecMode.hpp>
56 #include <com/sun/star/ucb/IOErrorCode.hpp>
57 #include <com/sun/star/task/InteractionHandler.hpp>
58 #include <com/sun/star/task/XInteractionHandler2.hpp>
59 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
61 #include <comphelper/interaction.hxx>
62 #include <comphelper/namedvaluecollection.hxx>
63 #include <comphelper/diagnose_ex.hxx>
64 #include <osl/diagnose.h>
65 #include <connectivity/DriversConfig.hxx>
66 #include <utility>
68 namespace dbaui
70 using namespace dbtools;
71 using namespace vcl;
72 using namespace com::sun::star;
73 using namespace com::sun::star::uno;
74 using namespace com::sun::star::sdbc;
75 using namespace com::sun::star::task;
76 using namespace com::sun::star::lang;
77 using namespace com::sun::star::io;
78 using namespace com::sun::star::util;
79 using namespace com::sun::star::beans;
80 using namespace com::sun::star::container;
81 using namespace com::sun::star::frame;
82 using namespace com::sun::star::ucb;
83 using namespace ::com::sun::star::sdb;
84 using namespace ::com::sun::star::document;
85 using namespace ::comphelper;
86 using namespace ::cppu;
88 using vcl::RoadmapWizardTypes::WizardPath;
90 // ODbTypeWizDialogSetup
91 ODbTypeWizDialogSetup::ODbTypeWizDialogSetup(weld::Window* _pParent
92 ,SfxItemSet const * _pItems
93 ,const Reference< XComponentContext >& _rxORB
94 ,const css::uno::Any& _aDataSourceName
96 : vcl::RoadmapWizardMachine( _pParent )
98 , m_bIsConnectable( false)
99 , m_sRM_IntroText( DBA_RES( STR_PAGETITLE_INTROPAGE ) )
100 , m_sRM_dBaseText( DBA_RES( STR_PAGETITLE_DBASE ) )
101 , m_sRM_TextText( DBA_RES( STR_PAGETITLE_TEXT ) )
102 , m_sRM_MSAccessText( DBA_RES( STR_PAGETITLE_MSACCESS ) )
103 , m_sRM_LDAPText( DBA_RES( STR_PAGETITLE_LDAP ) )
104 , m_sRM_ADOText( DBA_RES( STR_PAGETITLE_ADO ) )
105 , m_sRM_JDBCText( DBA_RES( STR_PAGETITLE_JDBC ) )
106 , m_sRM_MySQLNativePageTitle( DBA_RES( STR_PAGETITLE_MYSQL_NATIVE ) )
107 , m_sRM_OracleText( DBA_RES( STR_PAGETITLE_ORACLE ) )
108 , m_sRM_PostgresText( DBA_RES( STR_PAGETITLE_POSTGRES ) )
109 , m_sRM_MySQLText( DBA_RES( STR_PAGETITLE_MYSQL ) )
110 , m_sRM_ODBCText( DBA_RES( STR_PAGETITLE_ODBC ) )
111 , m_sRM_DocumentOrSpreadSheetText( DBA_RES( STR_PAGETITLE_DOCUMENT_OR_SPREADSHEET ) )
112 , m_sRM_AuthentificationText( DBA_RES( STR_PAGETITLE_AUTHENTIFICATION ) )
113 , m_sRM_FinalText( DBA_RES( STR_PAGETITLE_FINAL ) )
114 , m_sWorkPath( SvtPathOptions().GetWorkPath() )
115 , m_pGeneralPage( nullptr )
116 , m_pMySQLIntroPage( nullptr )
117 , m_pFinalPage( nullptr )
119 // no local resources needed anymore
120 // extract the datasource type collection from the item set
121 const DbuTypeCollectionItem* pCollectionItem = dynamic_cast<const DbuTypeCollectionItem*>(_pItems->GetItem(DSID_TYPECOLLECTION));
122 assert(pCollectionItem && "must exist");
123 m_pCollection = pCollectionItem->getCollection();
125 assert(m_pCollection && "ODbTypeWizDialogSetup::ODbTypeWizDialogSetup : really need a DSN type collection !");
127 m_pImpl.reset(new ODbDataSourceAdministrationHelper(_rxORB, m_xAssistant.get(), _pParent, this));
128 m_pImpl->setDataSourceOrName(_aDataSourceName);
129 Reference< XPropertySet > xDatasource = m_pImpl->getCurrentDataSource();
130 m_pOutSet.reset( new SfxItemSet( *_pItems->GetPool(), _pItems->GetRanges() ) );
132 m_pImpl->translateProperties(xDatasource, *m_pOutSet);
134 defaultButton(WizardButtonFlags::NEXT);
135 enableButtons(WizardButtonFlags::FINISH, true);
136 enableAutomaticNextButtonState();
138 ::dbaccess::ODsnTypeCollection::TypeIterator aIter = m_pCollection->begin();
139 ::dbaccess::ODsnTypeCollection::TypeIterator aEnd = m_pCollection->end();
140 for(auto i = 1;aIter != aEnd;++aIter,++i)
142 const OUString& sURLPrefix = aIter.getURLPrefix();
143 WizardPath aPath;
144 aPath.push_back(PAGE_DBSETUPWIZARD_INTRO);
145 m_pCollection->fillPageIds(sURLPrefix,aPath);
146 aPath.push_back(PAGE_DBSETUPWIZARD_AUTHENTIFICATION);
147 aPath.push_back(PAGE_DBSETUPWIZARD_FINAL);
149 declareAuthDepPath(sURLPrefix,static_cast<PathId>(i),aPath);
152 WizardPath aPath;
153 aPath.push_back(PAGE_DBSETUPWIZARD_INTRO);
154 declarePath( static_cast<PathId>(m_pCollection->size()+1), aPath);
156 // Set general help ID for the roadmap
157 SetRoadmapHelpId(HID_DBWIZ_ROADMAP);
159 m_xPrevPage->set_help_id(HID_DBWIZ_PREVIOUS);
160 m_xNextPage->set_help_id(HID_DBWIZ_NEXT);
161 m_xCancel->set_help_id(HID_DBWIZ_CANCEL);
162 m_xFinish->set_help_id(HID_DBWIZ_FINISH);
163 m_xHelp->set_help_id(HID_DBWIZ_HELP);
164 ActivatePage();
165 setTitleBase(DBA_RES(STR_DBWIZARDTITLE));
166 m_xAssistant->set_current_page(0);
169 void ODbTypeWizDialogSetup::declareAuthDepPath( const OUString& _sURL, PathId _nPathId, const WizardPath& _rPaths)
171 bool bHasAuthentication = DataSourceMetaData::getAuthentication( _sURL ) != AuthNone;
173 // collect the elements of the path
174 WizardPath aPath;
176 for (auto const& path : _rPaths)
178 if ( bHasAuthentication || ( path != PAGE_DBSETUPWIZARD_AUTHENTIFICATION ) )
179 aPath.push_back(path);
182 // call base method
183 ::vcl::RoadmapWizardMachine::declarePath( _nPathId, aPath );
186 OUString ODbTypeWizDialogSetup::getStateDisplayName(WizardState _nState) const
188 OUString sRoadmapItem;
189 switch( _nState )
191 case PAGE_DBSETUPWIZARD_INTRO:
192 sRoadmapItem = m_sRM_IntroText;
193 break;
195 case PAGE_DBSETUPWIZARD_DBASE:
196 sRoadmapItem = m_sRM_dBaseText;
197 break;
198 case PAGE_DBSETUPWIZARD_ADO:
199 sRoadmapItem = m_sRM_ADOText;
200 break;
201 case PAGE_DBSETUPWIZARD_TEXT:
202 sRoadmapItem = m_sRM_TextText;
203 break;
204 case PAGE_DBSETUPWIZARD_MSACCESS:
205 sRoadmapItem = m_sRM_MSAccessText;
206 break;
207 case PAGE_DBSETUPWIZARD_LDAP:
208 sRoadmapItem = m_sRM_LDAPText;
209 break;
210 case PAGE_DBSETUPWIZARD_JDBC:
211 sRoadmapItem = m_sRM_JDBCText;
212 break;
213 case PAGE_DBSETUPWIZARD_ORACLE:
214 sRoadmapItem = m_sRM_OracleText;
215 break;
216 case PAGE_DBSETUPWIZARD_POSTGRES:
217 sRoadmapItem = m_sRM_PostgresText;
218 break;
219 case PAGE_DBSETUPWIZARD_MYSQL_INTRO:
220 sRoadmapItem = m_sRM_MySQLText;
221 break;
222 case PAGE_DBSETUPWIZARD_MYSQL_JDBC:
223 sRoadmapItem = m_sRM_JDBCText;
224 break;
225 case PAGE_DBSETUPWIZARD_MYSQL_NATIVE:
226 sRoadmapItem = m_sRM_MySQLNativePageTitle;
227 break;
228 case PAGE_DBSETUPWIZARD_MYSQL_ODBC:
229 sRoadmapItem = m_sRM_ODBCText;
230 break;
231 case PAGE_DBSETUPWIZARD_ODBC:
232 sRoadmapItem = m_sRM_ODBCText;
233 break;
234 case PAGE_DBSETUPWIZARD_DOCUMENT_OR_SPREADSHEET:
235 sRoadmapItem = m_sRM_DocumentOrSpreadSheetText;
236 break;
237 case PAGE_DBSETUPWIZARD_AUTHENTIFICATION:
238 sRoadmapItem = m_sRM_AuthentificationText;
239 break;
240 case PAGE_DBSETUPWIZARD_USERDEFINED:
241 sRoadmapItem = DBA_RES(STR_PAGETITLE_CONNECTION);
242 break;
243 case PAGE_DBSETUPWIZARD_FINAL:
244 sRoadmapItem = m_sRM_FinalText;
245 break;
246 default:
247 break;
249 return sRoadmapItem;
252 ODbTypeWizDialogSetup::~ODbTypeWizDialogSetup()
256 IMPL_LINK_NOARG(ODbTypeWizDialogSetup, OnTypeSelected, OGeneralPage&, void)
258 activateDatabasePath();
261 static void lcl_removeUnused(const ::comphelper::NamedValueCollection& _aOld,const ::comphelper::NamedValueCollection& _aNew,::comphelper::NamedValueCollection& _rDSInfo)
263 _rDSInfo.merge(_aNew,true);
264 for (auto& val : _aOld.getNamedValues())
265 if (!_aNew.has(val.Name))
266 _rDSInfo.remove(val.Name);
269 void DataSourceInfoConverter::convert(const Reference<XComponentContext> & xContext, const ::dbaccess::ODsnTypeCollection* _pCollection, std::u16string_view _sOldURLPrefix, std::u16string_view _sNewURLPrefix,const css::uno::Reference< css::beans::XPropertySet >& _xDatasource)
271 if ( _pCollection->getPrefix(_sOldURLPrefix) == _pCollection->getPrefix(_sNewURLPrefix) )
272 return ;
273 uno::Sequence< beans::PropertyValue> aInfo;
274 _xDatasource->getPropertyValue(PROPERTY_INFO) >>= aInfo;
275 ::comphelper::NamedValueCollection aDS(aInfo);
277 ::connectivity::DriversConfig aDriverConfig(xContext);
279 const ::comphelper::NamedValueCollection& aOldProperties = aDriverConfig.getProperties(_sOldURLPrefix);
280 const ::comphelper::NamedValueCollection& aNewProperties = aDriverConfig.getProperties(_sNewURLPrefix);
281 lcl_removeUnused(aOldProperties,aNewProperties,aDS);
283 aDS >>= aInfo;
284 _xDatasource->setPropertyValue(PROPERTY_INFO,uno::Any(aInfo));
287 void ODbTypeWizDialogSetup::activateDatabasePath()
289 switch ( m_pGeneralPage->GetDatabaseCreationMode() )
291 case OGeneralPageWizard::eCreateNew:
293 sal_Int32 nCreateNewDBIndex = m_pCollection->getIndexOf( m_pGeneralPage->GetSelectedType() );
294 if ( nCreateNewDBIndex == -1 )
295 nCreateNewDBIndex = m_pCollection->getIndexOf( u"sdbc:dbase:" );
296 OSL_ENSURE( nCreateNewDBIndex != -1, "ODbTypeWizDialogSetup::activateDatabasePath: the GeneralPage should have prevented this!" );
297 activatePath( static_cast< PathId >( nCreateNewDBIndex + 1 ), true );
299 enableState(PAGE_DBSETUPWIZARD_FINAL );
300 enableButtons( WizardButtonFlags::FINISH, true);
302 break;
303 case OGeneralPageWizard::eConnectExternal:
305 OUString sOld = m_sURL;
306 m_sURL = m_pGeneralPage->GetSelectedType();
307 if (m_sURL.startsWith("sdbc:mysql:") && sOld.startsWith("sdbc:mysql:"))
308 m_sURL = sOld; // The type of MySQL connection was already set elsewhere; just use it,
309 // instead of the hardcoded one from the selector
310 DataSourceInfoConverter::convert(getORB(), m_pCollection,sOld,m_sURL,m_pImpl->getCurrentDataSource());
311 ::dbaccess::DATASOURCE_TYPE eType = VerifyDataSourceType(m_pCollection->determineType(m_sURL));
312 if (eType == ::dbaccess::DST_UNKNOWN)
313 m_pCollection->determineType(m_sOldURL);
315 activatePath( static_cast<PathId>(m_pCollection->getIndexOf(m_sURL) + 1), true);
316 updateTypeDependentStates();
318 break;
319 case OGeneralPageWizard::eOpenExisting:
321 activatePath( static_cast<PathId>(m_pCollection->size() + 1), true );
322 enableButtons( WizardButtonFlags::FINISH, !m_pGeneralPage->GetSelectedDocumentURL().isEmpty() );
324 break;
325 default:
326 OSL_FAIL( "ODbTypeWizDialogSetup::activateDatabasePath: unknown creation mode!" );
329 enableButtons( WizardButtonFlags::NEXT, m_pGeneralPage->GetDatabaseCreationMode() != OGeneralPageWizard::eOpenExisting );
330 // TODO: this should go into the base class. Point is, we activate a path whose *last*
331 // step is also the current one. The base class should automatically disable
332 // the Next button in such a case. However, not for this patch ...
335 void ODbTypeWizDialogSetup::updateTypeDependentStates()
337 bool bDoEnable = false;
338 bool bIsConnectionRequired = m_pCollection->isConnectionUrlRequired(m_sURL);
339 if (!bIsConnectionRequired)
341 bDoEnable = true;
343 else if ( m_sURL == m_sOldURL )
345 bDoEnable = m_bIsConnectable;
347 enableState(PAGE_DBSETUPWIZARD_AUTHENTIFICATION, bDoEnable);
348 enableState(PAGE_DBSETUPWIZARD_FINAL, bDoEnable );
349 enableButtons( WizardButtonFlags::FINISH, bDoEnable);
352 void ODbTypeWizDialogSetup::resetPages(const Reference< XPropertySet >& _rxDatasource)
354 // remove all items which relate to indirect properties from the input set
355 // (without this, the following may happen: select an arbitrary data source where some indirect properties
356 // are set. Select another data source of the same type, where the indirect props are not set (yet). Then,
357 // the indirect property values of the first ds are shown in the second ds ...)
358 const ODbDataSourceAdministrationHelper::MapInt2String& rMap = m_pImpl->getIndirectProperties();
359 for (auto const& elem : rMap)
360 getWriteOutputSet()->ClearItem( static_cast<sal_uInt16>(elem.first) );
362 // extract all relevant data from the property set of the data source
363 m_pImpl->translateProperties(_rxDatasource, *getWriteOutputSet());
366 const SfxItemSet* ODbTypeWizDialogSetup::getOutputSet() const
368 return m_pOutSet.get();
371 SfxItemSet* ODbTypeWizDialogSetup::getWriteOutputSet()
373 return m_pOutSet.get();
376 std::pair< Reference<XConnection>,bool> ODbTypeWizDialogSetup::createConnection()
378 return m_pImpl->createConnection();
381 Reference< XComponentContext > ODbTypeWizDialogSetup::getORB() const
383 return m_pImpl->getORB();
386 Reference< XDriver > ODbTypeWizDialogSetup::getDriver()
388 return m_pImpl->getDriver();
391 ::dbaccess::DATASOURCE_TYPE ODbTypeWizDialogSetup::VerifyDataSourceType(const ::dbaccess::DATASOURCE_TYPE DatabaseType) const
393 ::dbaccess::DATASOURCE_TYPE LocDatabaseType = DatabaseType;
394 if ((LocDatabaseType == ::dbaccess::DST_MYSQL_JDBC) || (LocDatabaseType == ::dbaccess::DST_MYSQL_ODBC) || (LocDatabaseType == ::dbaccess::DST_MYSQL_NATIVE))
396 if (m_pMySQLIntroPage != nullptr)
398 switch( m_pMySQLIntroPage->getMySQLMode() )
400 case OMySQLIntroPageSetup::VIA_JDBC:
401 return ::dbaccess::DST_MYSQL_JDBC;
402 case OMySQLIntroPageSetup::VIA_NATIVE:
403 return ::dbaccess::DST_MYSQL_NATIVE;
404 case OMySQLIntroPageSetup::VIA_ODBC:
405 return ::dbaccess::DST_MYSQL_ODBC;
409 return LocDatabaseType;
412 OUString ODbTypeWizDialogSetup::getDatasourceType(const SfxItemSet& _rSet) const
414 OUString sRet = dbaui::ODbDataSourceAdministrationHelper::getDatasourceType(_rSet);
415 if (m_pMySQLIntroPage && m_pMySQLIntroPage->IsVisible())
417 switch( m_pMySQLIntroPage->getMySQLMode() )
419 case OMySQLIntroPageSetup::VIA_JDBC:
420 sRet = "sdbc:mysql:jdbc:";
421 break;
422 case OMySQLIntroPageSetup::VIA_NATIVE:
423 sRet = "sdbc:mysql:mysqlc:";
424 break;
425 case OMySQLIntroPageSetup::VIA_ODBC:
426 sRet = "sdbc:mysql:odbc:";
427 break;
430 return sRet;
433 void ODbTypeWizDialogSetup::clearPassword()
435 m_pImpl->clearPassword();
438 void ODbTypeWizDialogSetup::SetIntroPage(OMySQLIntroPageSetup* pPage)
440 m_pMySQLIntroPage = pPage;
441 m_pMySQLIntroPage->SetClickHdl(LINK( this, ODbTypeWizDialogSetup, ImplClickHdl ) );
444 void ODbTypeWizDialogSetup::SetGeneralPage(OGeneralPageWizard* pPage)
446 m_pGeneralPage = pPage;
447 m_pGeneralPage->SetTypeSelectHandler(LINK(this, ODbTypeWizDialogSetup, OnTypeSelected));
448 m_pGeneralPage->SetCreationModeHandler(LINK( this, ODbTypeWizDialogSetup, OnChangeCreationMode ) );
449 m_pGeneralPage->SetDocumentSelectionHandler(LINK( this, ODbTypeWizDialogSetup, OnRecentDocumentSelected ) );
450 m_pGeneralPage->SetChooseDocumentHandler(LINK( this, ODbTypeWizDialogSetup, OnSingleDocumentChosen ) );
453 void ODbTypeWizDialogSetup::SetFinalPage(OFinalDBPageSetup* pPage)
455 m_pFinalPage = pPage;
458 std::unique_ptr<BuilderPage> ODbTypeWizDialogSetup::createPage(WizardState _nState)
460 std::unique_ptr<OGenericAdministrationPage> xPage;
462 OUString sIdent(OUString::number(_nState));
463 weld::Container* pPageContainer = m_xAssistant->append_page(sIdent);
465 switch(_nState)
467 case PAGE_DBSETUPWIZARD_INTRO:
468 xPage = std::make_unique<OGeneralPageWizard>(pPageContainer,this,*m_pOutSet);
469 break;
471 case PAGE_DBSETUPWIZARD_DBASE:
472 xPage = OConnectionTabPageSetup::CreateDbaseTabPage(pPageContainer, this, *m_pOutSet);
473 break;
475 case PAGE_DBSETUPWIZARD_ADO:
476 xPage = OConnectionTabPageSetup::CreateADOTabPage(pPageContainer, this, *m_pOutSet);
477 break;
479 case PAGE_DBSETUPWIZARD_TEXT:
480 xPage = OTextConnectionPageSetup::CreateTextTabPage(pPageContainer, this, *m_pOutSet);
481 break;
483 case PAGE_DBSETUPWIZARD_ODBC:
484 xPage = OConnectionTabPageSetup::CreateODBCTabPage(pPageContainer, this, *m_pOutSet);
485 break;
487 case PAGE_DBSETUPWIZARD_JDBC:
488 xPage = OJDBCConnectionPageSetup::CreateJDBCTabPage(pPageContainer, this, *m_pOutSet);
489 break;
491 case PAGE_DBSETUPWIZARD_MYSQL_ODBC:
492 m_pOutSet->Put(SfxStringItem(DSID_CONNECTURL, m_pCollection->getPrefix(u"sdbc:mysql:odbc:")));
493 xPage = OConnectionTabPageSetup::CreateODBCTabPage(pPageContainer, this, *m_pOutSet);
494 break;
496 case PAGE_DBSETUPWIZARD_MYSQL_JDBC:
497 m_pOutSet->Put(SfxStringItem(DSID_CONNECTURL, m_pCollection->getPrefix(u"sdbc:mysql:jdbc:")));
498 xPage = OGeneralSpecialJDBCConnectionPageSetup::CreateMySQLJDBCTabPage(pPageContainer, this, *m_pOutSet);
499 break;
500 case PAGE_DBSETUPWIZARD_MYSQL_NATIVE:
501 m_pOutSet->Put(SfxStringItem(DSID_CONNECTURL, m_pCollection->getPrefix(u"sdbc:mysql:mysqlc:")));
502 xPage = MySQLNativeSetupPage::Create(pPageContainer, this, *m_pOutSet);
503 break;
505 case PAGE_DBSETUPWIZARD_ORACLE:
506 xPage = OGeneralSpecialJDBCConnectionPageSetup::CreateOracleJDBCTabPage(pPageContainer, this, *m_pOutSet);
507 break;
509 case PAGE_DBSETUPWIZARD_POSTGRES:
510 xPage = OPostgresConnectionPageSetup::CreatePostgresTabPage(pPageContainer, this, *m_pOutSet);
511 break;
513 case PAGE_DBSETUPWIZARD_LDAP:
514 xPage = OLDAPConnectionPageSetup::CreateLDAPTabPage(pPageContainer, this, *m_pOutSet);
515 break;
517 case PAGE_DBSETUPWIZARD_DOCUMENT_OR_SPREADSHEET:
518 xPage = OSpreadSheetConnectionPageSetup::CreateDocumentOrSpreadSheetTabPage(pPageContainer, this, *m_pOutSet);
519 break;
521 case PAGE_DBSETUPWIZARD_MSACCESS:
522 xPage = OConnectionTabPageSetup::CreateMSAccessTabPage(pPageContainer, this, *m_pOutSet);
523 break;
524 case PAGE_DBSETUPWIZARD_MYSQL_INTRO:
525 xPage = OMySQLIntroPageSetup::CreateMySQLIntroTabPage(pPageContainer, this, *m_pOutSet);
526 break;
528 case PAGE_DBSETUPWIZARD_AUTHENTIFICATION:
529 xPage = OAuthentificationPageSetup::CreateAuthentificationTabPage(pPageContainer, this, *m_pOutSet);
530 break;
532 case PAGE_DBSETUPWIZARD_USERDEFINED:
533 xPage = OConnectionTabPageSetup::CreateUserDefinedTabPage(pPageContainer, this, *m_pOutSet);
534 break;
536 case PAGE_DBSETUPWIZARD_FINAL:
537 xPage = OFinalDBPageSetup::CreateFinalDBTabPageSetup(pPageContainer, this, *m_pOutSet);
538 break;
541 if ( xPage )
543 if ((_nState != PAGE_DBSETUPWIZARD_INTRO) && (_nState != PAGE_DBSETUPWIZARD_AUTHENTIFICATION))
545 xPage->SetModifiedHandler(LINK( this, ODbTypeWizDialogSetup, ImplModifiedHdl ) );
548 xPage->SetServiceFactory( m_pImpl->getORB() );
549 xPage->SetAdminDialog(this, this);
551 defaultButton( _nState == PAGE_DBSETUPWIZARD_FINAL ? WizardButtonFlags::FINISH : WizardButtonFlags::NEXT );
552 enableButtons( WizardButtonFlags::FINISH, _nState == PAGE_DBSETUPWIZARD_FINAL );
553 enableButtons( WizardButtonFlags::NEXT, _nState != PAGE_DBSETUPWIZARD_FINAL );
555 m_xAssistant->set_page_title(sIdent, getStateDisplayName(_nState));
557 return xPage;
560 IMPL_LINK(ODbTypeWizDialogSetup, ImplModifiedHdl, OGenericAdministrationPage const *, _pConnectionPageSetup, void)
562 m_bIsConnectable = _pConnectionPageSetup->GetRoadmapStateValue( );
563 enableState(PAGE_DBSETUPWIZARD_FINAL, m_bIsConnectable);
564 enableState(PAGE_DBSETUPWIZARD_AUTHENTIFICATION, m_bIsConnectable);
565 if (getCurrentState() == PAGE_DBSETUPWIZARD_FINAL)
566 enableButtons( WizardButtonFlags::FINISH, true);
567 else
568 enableButtons( WizardButtonFlags::FINISH, m_bIsConnectable);
569 enableButtons( WizardButtonFlags::NEXT, m_bIsConnectable && (getCurrentState() != PAGE_DBSETUPWIZARD_FINAL));
572 IMPL_LINK(ODbTypeWizDialogSetup, ImplClickHdl, OMySQLIntroPageSetup*, _pMySQLIntroPageSetup, void)
574 OUString sURLPrefix;
575 switch( _pMySQLIntroPageSetup->getMySQLMode() )
577 case OMySQLIntroPageSetup::VIA_ODBC:
578 sURLPrefix = "sdbc:mysql:odbc:";
579 break;
580 case OMySQLIntroPageSetup::VIA_JDBC:
581 sURLPrefix = "sdbc:mysql:jdbc:";
582 break;
583 case OMySQLIntroPageSetup::VIA_NATIVE:
584 sURLPrefix = "sdbc:mysql:mysqlc:";
585 break;
587 activatePath( static_cast<PathId>(m_pCollection->getIndexOf(sURLPrefix) + 1), true);
590 IMPL_LINK_NOARG(ODbTypeWizDialogSetup, OnChangeCreationMode, OGeneralPageWizard&, void)
592 activateDatabasePath();
595 IMPL_LINK_NOARG(ODbTypeWizDialogSetup, OnRecentDocumentSelected, OGeneralPageWizard&, void)
597 enableButtons( WizardButtonFlags::FINISH, !m_pGeneralPage->GetSelectedDocumentURL().isEmpty() );
600 IMPL_LINK_NOARG(ODbTypeWizDialogSetup, OnSingleDocumentChosen, OGeneralPageWizard&, void)
602 if (prepareLeaveCurrentState(WizardTypes::eFinish))
603 onFinish();
606 void ODbTypeWizDialogSetup::enterState(WizardState _nState)
608 m_sURL = dbaui::ODbDataSourceAdministrationHelper::getDatasourceType(*m_pOutSet);
609 RoadmapWizardMachine::enterState(_nState);
610 switch(_nState)
612 case PAGE_DBSETUPWIZARD_INTRO:
613 m_sOldURL = m_sURL;
614 break;
615 case PAGE_DBSETUPWIZARD_FINAL:
616 enableButtons( WizardButtonFlags::FINISH, true);
617 if ( m_pFinalPage )
618 m_pFinalPage->enableTableWizardCheckBox(m_pCollection->supportsTableCreation(m_sURL));
619 break;
623 void ODbTypeWizDialogSetup::saveDatasource()
625 SfxTabPage* pPage = static_cast<SfxTabPage*>(GetPage(getCurrentState()));
626 if ( pPage )
627 pPage->FillItemSet(m_pOutSet.get());
630 bool ODbTypeWizDialogSetup::leaveState(WizardState _nState)
632 if (_nState == PAGE_DBSETUPWIZARD_MYSQL_INTRO)
633 return true;
634 if ( _nState == PAGE_DBSETUPWIZARD_INTRO && m_sURL != m_sOldURL )
636 resetPages(m_pImpl->getCurrentDataSource());
638 SfxTabPage* pPage = static_cast<SfxTabPage*>(GetPage(_nState));
639 return pPage && pPage->DeactivatePage(m_pOutSet.get()) != DeactivateRC::KeepPage;
642 void ODbTypeWizDialogSetup::setTitle(const OUString& _sTitle)
644 m_xAssistant->set_title(_sTitle);
647 void ODbTypeWizDialogSetup::enableConfirmSettings( bool /*_bEnable*/ )
651 namespace
653 bool lcl_handle( const Reference< XInteractionHandler2 >& _rxHandler, const Any& _rRequest )
655 rtl::Reference<OInteractionRequest> pRequest = new OInteractionRequest( _rRequest );
656 rtl::Reference<OInteractionAbort> pAbort = new OInteractionAbort;
657 pRequest->addContinuation( pAbort );
659 return _rxHandler->handleInteractionRequest( pRequest );
663 bool ODbTypeWizDialogSetup::SaveDatabaseDocument()
665 Reference< XInteractionHandler2 > xHandler( InteractionHandler::createWithParent(getORB(), nullptr) );
668 if (callSaveAsDialog())
670 m_pImpl->saveChanges(*m_pOutSet);
671 Reference< XPropertySet > xDatasource = m_pImpl->getCurrentDataSource();
672 Reference< XModel > xModel( getDataSourceOrModel( xDatasource ), UNO_QUERY_THROW );
673 Reference< XStorable > xStore( xModel, UNO_QUERY_THROW );
675 if ( m_pGeneralPage->GetDatabaseCreationMode() == OGeneralPageWizard::eCreateNew )
676 CreateDatabase();
678 ::comphelper::NamedValueCollection aArgs( xModel->getArgs() );
679 aArgs.put( u"Overwrite"_ustr, true );
680 aArgs.put( u"InteractionHandler"_ustr, xHandler );
681 aArgs.put( u"MacroExecutionMode"_ustr, MacroExecMode::USE_CONFIG );
682 aArgs.put( u"IgnoreFirebirdMigration"_ustr, true );
684 OUString sPath = ODbDataSourceAdministrationHelper::getDocumentUrl( *m_pOutSet );
685 xStore->storeAsURL( sPath, aArgs.getPropertyValues() );
687 if ( !m_pFinalPage || m_pFinalPage->IsDatabaseDocumentToBeRegistered() )
688 RegisterDataSourceByLocation( sPath );
690 return true;
693 catch ( const Exception& e )
695 Any aError = ::cppu::getCaughtException();
696 if ( xHandler.is() )
698 if ( !lcl_handle( xHandler, aError ) )
700 css::ucb::IOErrorCode code
701 = aError.isExtractableTo(::cppu::UnoType<IOException>::get())
702 ? IOErrorCode_CANT_WRITE // assume saving the document failed
703 : IOErrorCode_GENERAL;
704 InteractiveIOException aRequest(e.Message, e.Context,
705 InteractionClassification_ERROR, code);
706 lcl_handle( xHandler, Any( aRequest ) );
710 return false;
713 bool ODbTypeWizDialogSetup::IsDatabaseDocumentToBeOpened() const
715 if ( m_pGeneralPage->GetDatabaseCreationMode() == OGeneralPageWizard::eOpenExisting )
716 return true;
718 if ( m_pFinalPage != nullptr )
719 return m_pFinalPage->IsDatabaseDocumentToBeOpened();
721 return true;
724 bool ODbTypeWizDialogSetup::IsTableWizardToBeStarted() const
726 if ( m_pGeneralPage->GetDatabaseCreationMode() == OGeneralPageWizard::eOpenExisting )
727 return false;
729 if ( m_pFinalPage != nullptr )
730 return m_pFinalPage->IsTableWizardToBeStarted();
732 return false;
735 void ODbTypeWizDialogSetup::CreateDatabase()
737 OUString sUrl;
738 const OUString eType = m_pGeneralPage->GetSelectedType();
739 if ( dbaccess::ODsnTypeCollection::isEmbeddedDatabase(eType) )
741 sUrl = eType;
742 Reference< XPropertySet > xDatasource = m_pImpl->getCurrentDataSource();
743 OSL_ENSURE(xDatasource.is(),"DataSource is null!");
744 if ( xDatasource.is() )
745 xDatasource->setPropertyValue( PROPERTY_INFO, Any( m_pCollection->getDefaultDBSettings( eType ) ) );
746 m_pImpl->translateProperties(xDatasource,*m_pOutSet);
748 else if ( m_pCollection->isFileSystemBased(eType) )
750 Reference< XSimpleFileAccess3 > xSimpleFileAccess(ucb::SimpleFileAccess::create(getORB()));
751 INetURLObject aDBPathURL(m_sWorkPath);
752 aDBPathURL.Append(m_aDocURL.getBase());
753 createUniqueFolderName(&aDBPathURL);
754 sUrl = aDBPathURL.GetMainURL( INetURLObject::DecodeMechanism::NONE);
755 xSimpleFileAccess->createFolder(sUrl);
756 sUrl = eType + sUrl;
758 m_pOutSet->Put(SfxStringItem(DSID_CONNECTURL, sUrl));
759 m_pImpl->saveChanges(*m_pOutSet);
762 void ODbTypeWizDialogSetup::RegisterDataSourceByLocation(std::u16string_view _sPath)
764 Reference< XPropertySet > xDatasource = m_pImpl->getCurrentDataSource();
765 Reference< XDatabaseContext > xDatabaseContext( DatabaseContext::create(getORB()) );
766 INetURLObject aURL( _sPath );
767 OUString sFilename = aURL.getBase( INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset );
768 OUString sDatabaseName = ::dbtools::createUniqueName(xDatabaseContext, sFilename, false);
769 xDatabaseContext->registerObject(sDatabaseName, xDatasource);
772 bool ODbTypeWizDialogSetup::callSaveAsDialog()
774 bool bRet = false;
775 ::sfx2::FileDialogHelper aFileDlg(
776 ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION,
777 FileDialogFlags::NONE, m_xAssistant.get());
778 aFileDlg.SetContext(sfx2::FileDialogHelper::BaseSaveAs);
779 std::shared_ptr<const SfxFilter> pFilter = getStandardDatabaseFilter();
780 if ( pFilter )
782 OUString sDefaultName = DBA_RES( STR_DATABASEDEFAULTNAME );
783 OUString sExtension = pFilter->GetDefaultExtension();
784 sDefaultName += sExtension.replaceAt( 0, 1, u"" );
785 INetURLObject aWorkURL( m_sWorkPath );
786 aWorkURL.Append( sDefaultName );
787 sDefaultName = createUniqueFileName( aWorkURL );
788 aFileDlg.SetFileName( sDefaultName );
790 aFileDlg.AddFilter(pFilter->GetUIName(),pFilter->GetDefaultExtension());
791 aFileDlg.SetCurrentFilter(pFilter->GetUIName());
793 if ( aFileDlg.Execute() == ERRCODE_NONE )
795 m_aDocURL = INetURLObject(aFileDlg.GetPath());
797 if( m_aDocURL.GetProtocol() != INetProtocol::NotValid )
799 OUString sFileName = m_aDocURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
800 if ( ::utl::UCBContentHelper::IsDocument(sFileName) )
801 ::utl::UCBContentHelper::Kill(sFileName);
802 m_pOutSet->Put(SfxStringItem(DSID_DOCUMENT_URL, sFileName));
803 bRet = true;
806 return bRet;
809 void ODbTypeWizDialogSetup::createUniqueFolderName(INetURLObject* pURL)
811 Reference< XSimpleFileAccess3 > xSimpleFileAccess(ucb::SimpleFileAccess::create(getORB()));
812 OUString sLastSegmentName = pURL->getName();
813 bool bFolderExists = true;
814 sal_Int32 i = 1;
815 while (bFolderExists)
817 bFolderExists = xSimpleFileAccess->isFolder(pURL->GetMainURL( INetURLObject::DecodeMechanism::NONE ));
818 if (bFolderExists)
820 i++;
821 pURL->setName(Concat2View(sLastSegmentName + OUString::number(i)));
826 OUString ODbTypeWizDialogSetup::createUniqueFileName(const INetURLObject& _rURL)
828 Reference< XSimpleFileAccess3 > xSimpleFileAccess(ucb::SimpleFileAccess::create(getORB()));
829 OUString BaseName = _rURL.getBase();
831 bool bElementExists = true;
833 INetURLObject aExistenceCheck( _rURL );
834 for ( sal_Int32 i = 1; bElementExists; )
836 bElementExists = xSimpleFileAccess->exists( aExistenceCheck.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
837 if ( bElementExists )
839 aExistenceCheck.setBase( Concat2View(BaseName + OUString::number( i ) ));
840 ++i;
843 return aExistenceCheck.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset );
846 vcl::IWizardPageController* ODbTypeWizDialogSetup::getPageController(BuilderPage* pCurrentPage) const
848 OGenericAdministrationPage* pPage = static_cast<OGenericAdministrationPage*>(pCurrentPage);
849 return pPage;
852 namespace
854 typedef ::cppu::WeakImplHelper< XTerminateListener
855 > AsyncLoader_Base;
856 class AsyncLoader : public AsyncLoader_Base
858 private:
859 Reference< XComponentLoader > m_xFrameLoader;
860 Reference< XDesktop2 > m_xDesktop;
861 Reference< XInteractionHandler2 > m_xInteractionHandler;
862 OUString m_sURL;
863 OAsynchronousLink m_aAsyncCaller;
865 public:
866 AsyncLoader( const Reference< XComponentContext >& _xORB, OUString _aURL );
868 void doLoadAsync();
870 // XTerminateListener
871 virtual void SAL_CALL queryTermination( const css::lang::EventObject& Event ) override;
872 virtual void SAL_CALL notifyTermination( const css::lang::EventObject& Event ) override;
873 // XEventListener
874 virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
876 private:
877 DECL_LINK( OnOpenDocument, void*, void );
880 AsyncLoader::AsyncLoader( const Reference< XComponentContext >& _rxORB, OUString _aURL )
881 :m_sURL(std::move( _aURL ))
882 ,m_aAsyncCaller( LINK( this, AsyncLoader, OnOpenDocument ) )
886 m_xDesktop.set( Desktop::create(_rxORB) );
887 m_xFrameLoader.set( m_xDesktop, UNO_QUERY_THROW );
888 m_xInteractionHandler = InteractionHandler::createWithParent(_rxORB, nullptr);
890 catch( const Exception& )
892 DBG_UNHANDLED_EXCEPTION("dbaccess");
896 void AsyncLoader::doLoadAsync()
898 OSL_ENSURE( !m_aAsyncCaller.IsRunning(), "AsyncLoader:doLoadAsync: already running!" );
900 acquire();
903 if ( m_xDesktop.is() )
904 m_xDesktop->addTerminateListener( this );
906 catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION("dbaccess"); }
908 m_aAsyncCaller.Call();
911 IMPL_LINK_NOARG( AsyncLoader, OnOpenDocument, void*, void )
915 if ( m_xFrameLoader.is() )
917 ::comphelper::NamedValueCollection aLoadArgs;
918 aLoadArgs.put( u"InteractionHandler"_ustr, m_xInteractionHandler );
919 aLoadArgs.put( u"MacroExecutionMode"_ustr, MacroExecMode::USE_CONFIG );
921 Sequence< PropertyValue > aLoadArgPV;
922 aLoadArgs >>= aLoadArgPV;
924 m_xFrameLoader->loadComponentFromURL( m_sURL,
925 u"_default"_ustr,
926 FrameSearchFlag::ALL,
927 aLoadArgPV
931 catch( const Exception& )
933 // do not assert.
934 // Such an exception happens for instance of the to-be-loaded document does not exist anymore.
939 if ( m_xDesktop.is() )
940 m_xDesktop->removeTerminateListener( this );
942 catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION("dbaccess"); }
944 release();
947 void SAL_CALL AsyncLoader::queryTermination( const css::lang::EventObject& /*Event*/ )
949 throw TerminationVetoException();
952 void SAL_CALL AsyncLoader::notifyTermination( const css::lang::EventObject& /*Event*/ )
955 void SAL_CALL AsyncLoader::disposing( const css::lang::EventObject& /*Source*/ )
960 bool ODbTypeWizDialogSetup::onFinish()
962 if ( m_pGeneralPage->GetDatabaseCreationMode() == OGeneralPageWizard::eOpenExisting )
964 // we're not going to re-use the XModel we have - since the document the user
965 // wants us to load could be a non-database document. Instead, we asynchronously
966 // open the selected document. Thus, the wizard's return value is RET_CANCEL,
967 // which means to not continue loading the database document
968 if ( !WizardMachine::Finish() )
969 return false;
973 rtl::Reference<AsyncLoader> pAsyncLoader = new AsyncLoader( getORB(), m_pGeneralPage->GetSelectedDocumentURL() );
974 pAsyncLoader->doLoadAsync();
976 catch( const Exception& )
978 DBG_UNHANDLED_EXCEPTION("dbaccess");
981 return true;
984 if (getCurrentState() != PAGE_DBSETUPWIZARD_FINAL)
986 skipUntil(PAGE_DBSETUPWIZARD_FINAL);
988 if (getCurrentState() == PAGE_DBSETUPWIZARD_FINAL)
989 return SaveDatabaseDocument() && WizardMachine::onFinish();
990 else
992 enableButtons( WizardButtonFlags::FINISH, false );
993 return false;
997 } // namespace dbaui
999 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */