1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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"
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>
70 using namespace dbtools
;
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();
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
);
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
);
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
176 for (auto const& path
: _rPaths
)
178 if ( bHasAuthentication
|| ( path
!= PAGE_DBSETUPWIZARD_AUTHENTIFICATION
) )
179 aPath
.push_back(path
);
183 ::vcl::RoadmapWizardMachine::declarePath( _nPathId
, aPath
);
186 OUString
ODbTypeWizDialogSetup::getStateDisplayName(WizardState _nState
) const
188 OUString sRoadmapItem
;
191 case PAGE_DBSETUPWIZARD_INTRO
:
192 sRoadmapItem
= m_sRM_IntroText
;
195 case PAGE_DBSETUPWIZARD_DBASE
:
196 sRoadmapItem
= m_sRM_dBaseText
;
198 case PAGE_DBSETUPWIZARD_ADO
:
199 sRoadmapItem
= m_sRM_ADOText
;
201 case PAGE_DBSETUPWIZARD_TEXT
:
202 sRoadmapItem
= m_sRM_TextText
;
204 case PAGE_DBSETUPWIZARD_MSACCESS
:
205 sRoadmapItem
= m_sRM_MSAccessText
;
207 case PAGE_DBSETUPWIZARD_LDAP
:
208 sRoadmapItem
= m_sRM_LDAPText
;
210 case PAGE_DBSETUPWIZARD_JDBC
:
211 sRoadmapItem
= m_sRM_JDBCText
;
213 case PAGE_DBSETUPWIZARD_ORACLE
:
214 sRoadmapItem
= m_sRM_OracleText
;
216 case PAGE_DBSETUPWIZARD_POSTGRES
:
217 sRoadmapItem
= m_sRM_PostgresText
;
219 case PAGE_DBSETUPWIZARD_MYSQL_INTRO
:
220 sRoadmapItem
= m_sRM_MySQLText
;
222 case PAGE_DBSETUPWIZARD_MYSQL_JDBC
:
223 sRoadmapItem
= m_sRM_JDBCText
;
225 case PAGE_DBSETUPWIZARD_MYSQL_NATIVE
:
226 sRoadmapItem
= m_sRM_MySQLNativePageTitle
;
228 case PAGE_DBSETUPWIZARD_MYSQL_ODBC
:
229 sRoadmapItem
= m_sRM_ODBCText
;
231 case PAGE_DBSETUPWIZARD_ODBC
:
232 sRoadmapItem
= m_sRM_ODBCText
;
234 case PAGE_DBSETUPWIZARD_DOCUMENT_OR_SPREADSHEET
:
235 sRoadmapItem
= m_sRM_DocumentOrSpreadSheetText
;
237 case PAGE_DBSETUPWIZARD_AUTHENTIFICATION
:
238 sRoadmapItem
= m_sRM_AuthentificationText
;
240 case PAGE_DBSETUPWIZARD_USERDEFINED
:
241 sRoadmapItem
= DBA_RES(STR_PAGETITLE_CONNECTION
);
243 case PAGE_DBSETUPWIZARD_FINAL
:
244 sRoadmapItem
= m_sRM_FinalText
;
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
) )
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
);
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);
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();
319 case OGeneralPageWizard::eOpenExisting
:
321 activatePath( static_cast<PathId
>(m_pCollection
->size() + 1), true );
322 enableButtons( WizardButtonFlags::FINISH
, !m_pGeneralPage
->GetSelectedDocumentURL().isEmpty() );
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
)
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:";
422 case OMySQLIntroPageSetup::VIA_NATIVE
:
423 sRet
= "sdbc:mysql:mysqlc:";
425 case OMySQLIntroPageSetup::VIA_ODBC
:
426 sRet
= "sdbc:mysql:odbc:";
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
);
467 case PAGE_DBSETUPWIZARD_INTRO
:
468 xPage
= std::make_unique
<OGeneralPageWizard
>(pPageContainer
,this,*m_pOutSet
);
471 case PAGE_DBSETUPWIZARD_DBASE
:
472 xPage
= OConnectionTabPageSetup::CreateDbaseTabPage(pPageContainer
, this, *m_pOutSet
);
475 case PAGE_DBSETUPWIZARD_ADO
:
476 xPage
= OConnectionTabPageSetup::CreateADOTabPage(pPageContainer
, this, *m_pOutSet
);
479 case PAGE_DBSETUPWIZARD_TEXT
:
480 xPage
= OTextConnectionPageSetup::CreateTextTabPage(pPageContainer
, this, *m_pOutSet
);
483 case PAGE_DBSETUPWIZARD_ODBC
:
484 xPage
= OConnectionTabPageSetup::CreateODBCTabPage(pPageContainer
, this, *m_pOutSet
);
487 case PAGE_DBSETUPWIZARD_JDBC
:
488 xPage
= OJDBCConnectionPageSetup::CreateJDBCTabPage(pPageContainer
, this, *m_pOutSet
);
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
);
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
);
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
);
505 case PAGE_DBSETUPWIZARD_ORACLE
:
506 xPage
= OGeneralSpecialJDBCConnectionPageSetup::CreateOracleJDBCTabPage(pPageContainer
, this, *m_pOutSet
);
509 case PAGE_DBSETUPWIZARD_POSTGRES
:
510 xPage
= OPostgresConnectionPageSetup::CreatePostgresTabPage(pPageContainer
, this, *m_pOutSet
);
513 case PAGE_DBSETUPWIZARD_LDAP
:
514 xPage
= OLDAPConnectionPageSetup::CreateLDAPTabPage(pPageContainer
, this, *m_pOutSet
);
517 case PAGE_DBSETUPWIZARD_DOCUMENT_OR_SPREADSHEET
:
518 xPage
= OSpreadSheetConnectionPageSetup::CreateDocumentOrSpreadSheetTabPage(pPageContainer
, this, *m_pOutSet
);
521 case PAGE_DBSETUPWIZARD_MSACCESS
:
522 xPage
= OConnectionTabPageSetup::CreateMSAccessTabPage(pPageContainer
, this, *m_pOutSet
);
524 case PAGE_DBSETUPWIZARD_MYSQL_INTRO
:
525 xPage
= OMySQLIntroPageSetup::CreateMySQLIntroTabPage(pPageContainer
, this, *m_pOutSet
);
528 case PAGE_DBSETUPWIZARD_AUTHENTIFICATION
:
529 xPage
= OAuthentificationPageSetup::CreateAuthentificationTabPage(pPageContainer
, this, *m_pOutSet
);
532 case PAGE_DBSETUPWIZARD_USERDEFINED
:
533 xPage
= OConnectionTabPageSetup::CreateUserDefinedTabPage(pPageContainer
, this, *m_pOutSet
);
536 case PAGE_DBSETUPWIZARD_FINAL
:
537 xPage
= OFinalDBPageSetup::CreateFinalDBTabPageSetup(pPageContainer
, this, *m_pOutSet
);
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
));
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);
568 enableButtons( WizardButtonFlags::FINISH
, m_bIsConnectable
);
569 enableButtons( WizardButtonFlags::NEXT
, m_bIsConnectable
&& (getCurrentState() != PAGE_DBSETUPWIZARD_FINAL
));
572 IMPL_LINK(ODbTypeWizDialogSetup
, ImplClickHdl
, OMySQLIntroPageSetup
*, _pMySQLIntroPageSetup
, void)
575 switch( _pMySQLIntroPageSetup
->getMySQLMode() )
577 case OMySQLIntroPageSetup::VIA_ODBC
:
578 sURLPrefix
= "sdbc:mysql:odbc:";
580 case OMySQLIntroPageSetup::VIA_JDBC
:
581 sURLPrefix
= "sdbc:mysql:jdbc:";
583 case OMySQLIntroPageSetup::VIA_NATIVE
:
584 sURLPrefix
= "sdbc:mysql:mysqlc:";
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
))
606 void ODbTypeWizDialogSetup::enterState(WizardState _nState
)
608 m_sURL
= dbaui::ODbDataSourceAdministrationHelper::getDatasourceType(*m_pOutSet
);
609 RoadmapWizardMachine::enterState(_nState
);
612 case PAGE_DBSETUPWIZARD_INTRO
:
615 case PAGE_DBSETUPWIZARD_FINAL
:
616 enableButtons( WizardButtonFlags::FINISH
, true);
618 m_pFinalPage
->enableTableWizardCheckBox(m_pCollection
->supportsTableCreation(m_sURL
));
623 void ODbTypeWizDialogSetup::saveDatasource()
625 SfxTabPage
* pPage
= static_cast<SfxTabPage
*>(GetPage(getCurrentState()));
627 pPage
->FillItemSet(m_pOutSet
.get());
630 bool ODbTypeWizDialogSetup::leaveState(WizardState _nState
)
632 if (_nState
== PAGE_DBSETUPWIZARD_MYSQL_INTRO
)
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*/ )
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
)
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
);
693 catch ( const Exception
& e
)
695 Any aError
= ::cppu::getCaughtException();
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
) );
713 bool ODbTypeWizDialogSetup::IsDatabaseDocumentToBeOpened() const
715 if ( m_pGeneralPage
->GetDatabaseCreationMode() == OGeneralPageWizard::eOpenExisting
)
718 if ( m_pFinalPage
!= nullptr )
719 return m_pFinalPage
->IsDatabaseDocumentToBeOpened();
724 bool ODbTypeWizDialogSetup::IsTableWizardToBeStarted() const
726 if ( m_pGeneralPage
->GetDatabaseCreationMode() == OGeneralPageWizard::eOpenExisting
)
729 if ( m_pFinalPage
!= nullptr )
730 return m_pFinalPage
->IsTableWizardToBeStarted();
735 void ODbTypeWizDialogSetup::CreateDatabase()
738 const OUString eType
= m_pGeneralPage
->GetSelectedType();
739 if ( dbaccess::ODsnTypeCollection::isEmbeddedDatabase(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
);
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()
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();
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
));
809 void ODbTypeWizDialogSetup::createUniqueFolderName(INetURLObject
* pURL
)
811 Reference
< XSimpleFileAccess3
> xSimpleFileAccess(ucb::SimpleFileAccess::create(getORB()));
812 OUString sLastSegmentName
= pURL
->getName();
813 bool bFolderExists
= true;
815 while (bFolderExists
)
817 bFolderExists
= xSimpleFileAccess
->isFolder(pURL
->GetMainURL( INetURLObject::DecodeMechanism::NONE
));
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
) ));
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
);
854 typedef ::cppu::WeakImplHelper
< XTerminateListener
856 class AsyncLoader
: public AsyncLoader_Base
859 Reference
< XComponentLoader
> m_xFrameLoader
;
860 Reference
< XDesktop2
> m_xDesktop
;
861 Reference
< XInteractionHandler2
> m_xInteractionHandler
;
863 OAsynchronousLink m_aAsyncCaller
;
866 AsyncLoader( const Reference
< XComponentContext
>& _xORB
, OUString _aURL
);
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
;
874 virtual void SAL_CALL
disposing( const css::lang::EventObject
& Source
) override
;
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!" );
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
,
926 FrameSearchFlag::ALL
,
931 catch( const Exception
& )
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"); }
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() )
973 rtl::Reference
<AsyncLoader
> pAsyncLoader
= new AsyncLoader( getORB(), m_pGeneralPage
->GetSelectedDocumentURL() );
974 pAsyncLoader
->doLoadAsync();
976 catch( const Exception
& )
978 DBG_UNHANDLED_EXCEPTION("dbaccess");
984 if (getCurrentState() != PAGE_DBSETUPWIZARD_FINAL
)
986 skipUntil(PAGE_DBSETUPWIZARD_FINAL
);
988 if (getCurrentState() == PAGE_DBSETUPWIZARD_FINAL
)
989 return SaveDatabaseDocument() && WizardMachine::onFinish();
992 enableButtons( WizardButtonFlags::FINISH
, false );
999 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */