xref: /core/dbaccess/source/ui/dlg/generalpage.cxx (revision 32ca8708)
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 <core_resource.hxx>
21 #include "dsnItem.hxx"
22 #include "generalpage.hxx"
23 #include <connectivity/dbexception.hxx>
24 #include <dbu_dlg.hxx>
25 #include <strings.hrc>
26 #include <dsitems.hxx>
27 #include <stringconstants.hxx>
28 #include <dbadmin.hxx>
29 #include <sfx2/filedlghelper.hxx>
30 #include <sfx2/docfilt.hxx>
31 #include <vcl/stdtext.hxx>
32 #include <vcl/weld.hxx>
33 #include <svl/stritem.hxx>
34 #include <vcl/waitobj.hxx>
35 #include <com/sun/star/sdbc/XDriverAccess.hpp>
36 #include <com/sun/star/beans/PropertyValue.hpp>
37 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
38 #include <com/sun/star/container/XNameAccess.hpp>
39 #include "DriverSettings.hxx"
40 #include <UITools.hxx>
41 #include <comphelper/processfactory.hxx>
42 #include <unotools/confignode.hxx>
43 #include <osl/diagnose.h>
44 #include <svtools/miscopt.hxx>
45 #include <sal/log.hxx>
46 
47 namespace dbaui
48 {
49     using namespace ::com::sun::star;
50     using namespace ::com::sun::star::uno;
51     using namespace ::com::sun::star::sdbc;
52     using namespace ::com::sun::star::beans;
53     using namespace ::com::sun::star::container;
54 
55     // OGeneralPage
56     OGeneralPage::OGeneralPage( vcl::Window* pParent, const OUString& _rUIXMLDescription, const SfxItemSet& _rItems )
57         :OGenericAdministrationPage( pParent, "PageGeneral", _rUIXMLDescription, _rItems )
58         ,m_pSpecialMessage              ( nullptr )
59         ,m_eLastMessage                 ( smNone )
60         ,m_bInitTypeList                ( true )
61         ,m_pDatasourceType              ( nullptr )
62         ,m_pCollection                  ( nullptr )
63     {
64         get( m_pDatasourceType, "datasourceType" );
65         get( m_pSpecialMessage, "specialMessage" );
66 
67         // extract the datasource type collection from the item set
68         const DbuTypeCollectionItem* pCollectionItem = dynamic_cast<const DbuTypeCollectionItem*>( _rItems.GetItem(DSID_TYPECOLLECTION) );
69         if (pCollectionItem)
70             m_pCollection = pCollectionItem->getCollection();
71         SAL_WARN_IF(!m_pCollection, "dbaccess.ui.generalpage", "OGeneralPage::OGeneralPage : really need a DSN type collection !");
72 
73         // do some knittings
74         m_pDatasourceType->SetSelectHdl(LINK(this, OGeneralPage, OnDatasourceTypeSelected));
75     }
76 
77     OGeneralPage::~OGeneralPage()
78     {
79         disposeOnce();
80     }
81 
82     void OGeneralPage::dispose()
83     {
84         m_pSpecialMessage.clear();
85         m_pDatasourceType.clear();
86         OGenericAdministrationPage::dispose();
87     }
88 
89     namespace
90     {
91         struct DisplayedType
92         {
93             OUString eType;
94             OUString sDisplayName;
95 
96             DisplayedType( const OUString& _eType, const OUString& _rDisplayName ) : eType( _eType ), sDisplayName( _rDisplayName ) { }
97         };
98         typedef std::vector< DisplayedType > DisplayedTypes;
99 
100         struct DisplayedTypeLess
101         {
102             bool operator() ( const DisplayedType& _rLHS, const DisplayedType& _rRHS )
103             {
104                 return _rLHS.eType < _rRHS.eType;
105             }
106         };
107     }
108 
109     void OGeneralPage::initializeTypeList()
110     {
111         if ( m_bInitTypeList )
112         {
113             m_bInitTypeList = false;
114             m_pDatasourceType->Clear();
115 
116             if ( m_pCollection )
117             {
118                 DisplayedTypes aDisplayedTypes;
119 
120                 ::dbaccess::ODsnTypeCollection::TypeIterator aEnd = m_pCollection->end();
121                 for (   ::dbaccess::ODsnTypeCollection::TypeIterator aTypeLoop =  m_pCollection->begin();
122                         aTypeLoop != aEnd;
123                         ++aTypeLoop
124                     )
125                 {
126                     const OUString& sURLPrefix = aTypeLoop.getURLPrefix();
127                     if ( !sURLPrefix.isEmpty() )
128                     {
129                         // skip mysql connection variations. It is handled in another window.
130                         if(sURLPrefix.startsWith("sdbc:mysql:") && !sURLPrefix.startsWith("sdbc:mysql:jdbc:"))
131                             continue;
132 
133                         OUString sDisplayName = aTypeLoop.getDisplayName();
134                         if (   m_pDatasourceType->GetEntryPos( sDisplayName ) == LISTBOX_ENTRY_NOTFOUND
135                             && approveDatasourceType( sURLPrefix, sDisplayName ) )
136                         {
137                             aDisplayedTypes.emplace_back( sURLPrefix, sDisplayName );
138                         }
139                     }
140                 }
141                 std::sort( aDisplayedTypes.begin(), aDisplayedTypes.end(), DisplayedTypeLess() );
142                 DisplayedTypes::const_iterator aDisplayEnd = aDisplayedTypes.end();
143                 for (   DisplayedTypes::const_iterator loop = aDisplayedTypes.begin();
144                         loop != aDisplayEnd;
145                         ++loop
146                     )
147                     insertDatasourceTypeEntryData( loop->eType, loop->sDisplayName );
148             }
149         }
150     }
151 
152     void OGeneralPageWizard::initializeEmbeddedDBList()
153     {
154         if ( m_bInitEmbeddedDBList )
155         {
156             m_bInitEmbeddedDBList = false;
157             m_pEmbeddedDBType->Clear();
158 
159             if ( m_pCollection )
160             {
161                 DisplayedTypes aDisplayedTypes;
162 
163                 ::dbaccess::ODsnTypeCollection::TypeIterator aEnd = m_pCollection->end();
164                 for (   ::dbaccess::ODsnTypeCollection::TypeIterator aTypeLoop =  m_pCollection->begin();
165                         aTypeLoop != aEnd;
166                         ++aTypeLoop
167                     )
168                 {
169                     const OUString& sURLPrefix = aTypeLoop.getURLPrefix();
170                     if ( !sURLPrefix.isEmpty() )
171                     {
172                         OUString sDisplayName = aTypeLoop.getDisplayName();
173                         if ( m_pEmbeddedDBType->GetEntryPos( sDisplayName ) == LISTBOX_ENTRY_NOTFOUND
174                             && dbaccess::ODsnTypeCollection::isEmbeddedDatabase( sURLPrefix ) )
175                         {
176                             aDisplayedTypes.emplace_back( sURLPrefix, sDisplayName );
177                         }
178                     }
179                 }
180                 std::sort( aDisplayedTypes.begin(), aDisplayedTypes.end(), DisplayedTypeLess() );
181                 for (auto const& displayedType : aDisplayedTypes)
182                     insertEmbeddedDBTypeEntryData( displayedType.eType, displayedType.sDisplayName );
183             }
184         }
185     }
186 
187     void OGeneralPage::setParentTitle(const OUString&)
188     {
189     }
190 
191     void OGeneralPage::switchMessage(const OUString& _sURLPrefix)
192     {
193         SPECIAL_MESSAGE eMessage = smNone;
194         if ( _sURLPrefix.isEmpty()/*_eType == m_eNotSupportedKnownType*/ )
195         {
196             eMessage = smUnsupportedType;
197         }
198 
199         if ( eMessage != m_eLastMessage )
200         {
201             const char* pResId = nullptr;
202             if ( smUnsupportedType == eMessage )
203                 pResId = STR_UNSUPPORTED_DATASOURCE_TYPE;
204             OUString sMessage;
205             if ( pResId )
206                 sMessage = DBA_RES(pResId);
207 
208             m_pSpecialMessage->SetText( sMessage );
209             m_eLastMessage = eMessage;
210         }
211     }
212 
213     void OGeneralPage::onTypeSelected(const OUString& _sURLPrefix)
214     {
215         // the new URL text as indicated by the selection history
216         implSetCurrentType( _sURLPrefix );
217 
218         switchMessage(_sURLPrefix);
219 
220         m_aTypeSelectHandler.Call(*this);
221     }
222 
223     void OGeneralPage::implInitControls( const SfxItemSet& _rSet, bool _bSaveValue )
224     {
225         initializeTypeList();
226 
227         m_pDatasourceType->SelectEntry( getDatasourceName( _rSet ) );
228 
229         // notify our listener that our type selection has changed (if so)
230         // FIXME: how to detect that it did not changed? (fdo#62937)
231         setParentTitle( m_eCurrentSelection );
232         onTypeSelected( m_eCurrentSelection );
233 
234         // a special message for the current page state
235         switchMessage( m_eCurrentSelection );
236 
237         OGenericAdministrationPage::implInitControls( _rSet, _bSaveValue );
238     }
239 
240     OUString OGeneralPageWizard::getEmbeddedDBName( const SfxItemSet& _rSet )
241     {
242         // first check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
243         bool bValid, bReadonly;
244         getFlags( _rSet, bValid, bReadonly );
245 
246         // if the selection is invalid, disable everything
247 
248         implSetCurrentType(  OUString() );
249 
250         // compare the DSN prefix with the registered ones
251         OUString sDisplayName;
252 
253         if (m_pCollection && bValid)
254         {
255             implSetCurrentType( m_pCollection->getEmbeddedDatabase() );
256             sDisplayName = m_pCollection->getTypeDisplayName( m_eCurrentSelection );
257         }
258 
259         // select the correct datasource type
260         if  (  dbaccess::ODsnTypeCollection::isEmbeddedDatabase( m_eCurrentSelection )
261             &&  ( LISTBOX_ENTRY_NOTFOUND == m_pEmbeddedDBType->GetEntryPos( sDisplayName ) )
262             )
263         {   // this indicates it's really a type which is known in general, but not supported on the current platform
264             // show a message saying so
265             //  eSpecialMessage = smUnsupportedType;
266             insertEmbeddedDBTypeEntryData( m_eCurrentSelection, sDisplayName );
267         }
268 
269         return sDisplayName;
270     }
271 
272     OUString OGeneralPage::getDatasourceName( const SfxItemSet& _rSet )
273     {
274         // first check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
275         bool bValid, bReadonly;
276         getFlags( _rSet, bValid, bReadonly );
277 
278         // if the selection is invalid, disable everything
279         OUString sConnectURL;
280         if ( bValid )
281         {
282             // collect some items and some values
283             const SfxStringItem* pUrlItem = _rSet.GetItem<SfxStringItem>(DSID_CONNECTURL);
284             assert( pUrlItem );
285             sConnectURL = pUrlItem->GetValue();
286         }
287 
288         implSetCurrentType(  OUString() );
289 
290         // compare the DSN prefix with the registered ones
291         OUString sDisplayName;
292 
293         if (m_pCollection && bValid)
294         {
295             implSetCurrentType( m_pCollection->getPrefix( sConnectURL ) );
296             sDisplayName = m_pCollection->getTypeDisplayName( m_eCurrentSelection );
297         }
298 
299         // select the correct datasource type
300         if  (   approveDatasourceType( m_eCurrentSelection, sDisplayName )
301             &&  ( LISTBOX_ENTRY_NOTFOUND == m_pDatasourceType->GetEntryPos( sDisplayName ) )
302             )
303         {   // this indicates it's really a type which is known in general, but not supported on the current platform
304             // show a message saying so
305             //  eSpecialMessage = smUnsupportedType;
306             insertDatasourceTypeEntryData( m_eCurrentSelection, sDisplayName );
307         }
308 
309         return sDisplayName;
310     }
311 
312     // For the databaseWizard we only have one entry for the MySQL Database,
313     // because we have a separate tabpage to retrieve the respective datasource type
314     // ( ::dbaccess::DST_MYSQL_ODBC ||  ::dbaccess::DST_MYSQL_JDBC). Therefore we use  ::dbaccess::DST_MYSQL_JDBC as a temporary
315     // representative for all MySQl databases)
316     // Also, embedded databases (embedded HSQL, at the moment), are not to appear in the list of
317     // databases to connect to.
318     bool OGeneralPage::approveDatasourceType( const OUString& _sURLPrefix, OUString& _inout_rDisplayName )
319     {
320         return approveDatasourceType( m_pCollection->determineType(_sURLPrefix), _inout_rDisplayName );
321     }
322 
323     bool OGeneralPage::approveDatasourceType( ::dbaccess::DATASOURCE_TYPE eType, OUString& _inout_rDisplayName )
324     {
325         if ( eType == ::dbaccess::DST_MYSQL_NATIVE_DIRECT )
326         {
327             // do not display the Connector/OOo driver itself, it is always wrapped via the MySQL-Driver, if
328             // this driver is installed
329             if ( m_pCollection->hasDriver( "sdbc:mysql:mysqlc:" ) )
330                 _inout_rDisplayName.clear();
331         }
332 
333         if ( eType ==  ::dbaccess::DST_EMBEDDED_HSQLDB
334                 || eType ==  ::dbaccess::DST_EMBEDDED_FIREBIRD )
335             _inout_rDisplayName.clear();
336 
337         return _inout_rDisplayName.getLength() > 0;
338     }
339 
340     void OGeneralPage::insertDatasourceTypeEntryData(const OUString& _sType, const OUString& sDisplayName)
341     {
342         // insert a (temporary) entry
343         const sal_Int32 nPos = m_pDatasourceType->InsertEntry(sDisplayName);
344         if ( static_cast<size_t>(nPos) >= m_aURLPrefixes.size() )
345             m_aURLPrefixes.resize(nPos+1);
346         m_aURLPrefixes[nPos] = _sType;
347     }
348 
349     void OGeneralPageWizard::insertEmbeddedDBTypeEntryData(const OUString& _sType, const OUString& sDisplayName)
350     {
351         // insert a (temporary) entry
352         const sal_Int32 nPos = m_pEmbeddedDBType->InsertEntry(sDisplayName);
353         if ( static_cast<size_t>(nPos) >= m_aEmbeddedURLPrefixes.size() )
354             m_aEmbeddedURLPrefixes.resize(nPos+1);
355         m_aEmbeddedURLPrefixes[nPos] = _sType;
356     }
357 
358     void OGeneralPage::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
359     {
360         _rControlList.emplace_back( new ODisableWrapper<FixedText>( m_pSpecialMessage ) );
361     }
362 
363     void OGeneralPage::fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList)
364     {
365         _rControlList.emplace_back( new OSaveValueWrapper<ListBox>( m_pDatasourceType ) );
366     }
367 
368     void OGeneralPage::implSetCurrentType( const OUString& _eType )
369     {
370         if ( _eType == m_eCurrentSelection )
371             return;
372 
373         m_eCurrentSelection = _eType;
374     }
375 
376     void OGeneralPage::Reset(const SfxItemSet* _rCoreAttrs)
377     {
378         // reset all locale data
379         implSetCurrentType(  OUString() );
380             // this ensures that our type selection link will be called, even if the new one is the same as the
381             // current one
382         OGenericAdministrationPage::Reset(_rCoreAttrs);
383     }
384 
385     IMPL_LINK( OGeneralPageWizard, OnEmbeddedDBTypeSelected, ListBox&, _rBox, void )
386     {
387         // get the type from the entry data
388         const sal_Int32 nSelected = _rBox.GetSelectedEntryPos();
389         if (static_cast<size_t>(nSelected) >= m_aEmbeddedURLPrefixes.size() )
390         {
391             SAL_WARN("dbaccess.ui.generalpage", "Got out-of-range value '" << nSelected <<  "' from the DatasourceType selection ListBox's GetSelectedEntryPos(): no corresponding URL prefix");
392             return;
393         }
394         const OUString sURLPrefix = m_aEmbeddedURLPrefixes[ nSelected ];
395 
396         setParentTitle( sURLPrefix );
397         // let the impl method do all the stuff
398         onTypeSelected( sURLPrefix );
399         // tell the listener we were modified
400         callModifiedHdl();
401     }
402 
403     IMPL_LINK( OGeneralPage, OnDatasourceTypeSelected, ListBox&, _rBox, void )
404     {
405         // get the type from the entry data
406         const sal_Int32 nSelected = _rBox.GetSelectedEntryPos();
407         if ( nSelected == LISTBOX_ENTRY_NOTFOUND)
408             return;
409         if (static_cast<size_t>(nSelected) >= m_aURLPrefixes.size() )
410         {
411             SAL_WARN("dbaccess.ui.generalpage", "Got out-of-range value '" << nSelected <<  "' from the DatasourceType selection ListBox's GetSelectedEntryPos(): no corresponding URL prefix");
412             return;
413         }
414         const OUString sURLPrefix = m_aURLPrefixes[ nSelected ];
415 
416         setParentTitle( sURLPrefix );
417         // let the impl method do all the stuff
418         onTypeSelected( sURLPrefix );
419         // tell the listener we were modified
420         callModifiedHdl();
421     }
422 
423     // OGeneralPageDialog
424     OGeneralPageDialog::OGeneralPageDialog( vcl::Window* pParent, const SfxItemSet& _rItems )
425         :OGeneralPage( pParent, "dbaccess/ui/generalpagedialog.ui", _rItems )
426     {
427     }
428 
429     void OGeneralPageDialog::setParentTitle( const OUString& _sURLPrefix )
430     {
431         const OUString sName = m_pCollection->getTypeDisplayName( _sURLPrefix );
432         if ( m_pAdminDialog )
433         {
434             OUString sMessage = DBA_RES(STR_PARENTTITLE_GENERAL);
435             m_pAdminDialog->setTitle( sMessage.replaceAll( "#", sName ) );
436         }
437     }
438 
439     void OGeneralPageDialog::implInitControls( const SfxItemSet& _rSet, bool _bSaveValue )
440     {
441         OGeneralPage::implInitControls( _rSet, _bSaveValue );
442 
443         // first check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
444         bool bValid, bReadonly;
445         getFlags(_rSet, bValid, bReadonly );
446 
447         m_pDatasourceType->Enable( bValid );
448     }
449 
450     bool OGeneralPageDialog::FillItemSet( SfxItemSet* _rCoreAttrs )
451     {
452         bool bChangedSomething = false;
453 
454         const sal_Int32 nEntry = m_pDatasourceType->GetSelectedEntryPos();
455         OUString sURLPrefix = m_aURLPrefixes[ nEntry ];
456 
457         if ( m_pDatasourceType->IsValueChangedFromSaved() )
458         {
459             _rCoreAttrs->Put( SfxStringItem( DSID_CONNECTURL, sURLPrefix ) );
460             bChangedSomething = true;
461         }
462 
463         return bChangedSomething;
464     }
465 
466     // OGeneralPageWizard
467     OGeneralPageWizard::OGeneralPageWizard( vcl::Window* pParent, const SfxItemSet& _rItems )
468         :OGeneralPage( pParent, "dbaccess/ui/generalpagewizard.ui", _rItems )
469         ,m_pRB_CreateDatabase           ( nullptr )
470         ,m_pRB_OpenExistingDatabase     ( nullptr )
471         ,m_pRB_ConnectDatabase          ( nullptr )
472         ,m_pFT_EmbeddedDBLabel          ( nullptr )
473         ,m_pEmbeddedDBType              ( nullptr )
474         ,m_pFT_DocListLabel             ( nullptr )
475         ,m_pLB_DocumentList             ( nullptr )
476         ,m_pPB_OpenDatabase             ( nullptr )
477         ,m_eOriginalCreationMode        ( eCreateNew )
478         ,m_bInitEmbeddedDBList          ( true )
479     {
480         get( m_pRB_CreateDatabase, "createDatabase" );
481         get( m_pRB_OpenExistingDatabase, "openExistingDatabase" );
482         get( m_pRB_ConnectDatabase, "connectDatabase" );
483         get( m_pFT_EmbeddedDBLabel, "embeddeddbLabel" );
484         get( m_pEmbeddedDBType, "embeddeddbList" );
485         get( m_pFT_DocListLabel, "docListLabel" );
486         get( m_pLB_DocumentList, "documentList" );
487         get( m_pPB_OpenDatabase, "openDatabase" );
488 
489         // If no driver for embedded DBs is installed, and no dBase driver, then hide the "Create new database" option
490         sal_Int32 nCreateNewDBIndex = m_pCollection->getIndexOf( m_pCollection->getEmbeddedDatabase() );
491         if ( nCreateNewDBIndex == -1 )
492             nCreateNewDBIndex = m_pCollection->getIndexOf( "sdbc:dbase:" );
493         bool bHideCreateNew = ( nCreateNewDBIndex == -1 );
494 
495         // also, if our application policies tell us to hide the option, do it
496         ::utl::OConfigurationTreeRoot aConfig( ::utl::OConfigurationTreeRoot::createWithComponentContext(
497             ::comphelper::getProcessComponentContext(),
498             "/org.openoffice.Office.DataAccess/Policies/Features/Base"
499         ) );
500         bool bAllowCreateLocalDatabase( true );
501         OSL_VERIFY( aConfig.getNodeValue( "CreateLocalDatabase" ) >>= bAllowCreateLocalDatabase );
502         if ( !bAllowCreateLocalDatabase )
503             bHideCreateNew = true;
504 
505         if ( bHideCreateNew )
506         {
507             m_pRB_CreateDatabase->Hide();
508             m_pRB_ConnectDatabase->Check();
509         }
510         else
511             m_pRB_CreateDatabase->Check();
512 
513         // do some knittings
514         m_pEmbeddedDBType->SetSelectHdl(LINK(this, OGeneralPageWizard, OnEmbeddedDBTypeSelected));
515         m_pRB_CreateDatabase->SetClickHdl( LINK( this, OGeneralPageWizard, OnCreateDatabaseModeSelected ) );
516         m_pRB_ConnectDatabase->SetClickHdl( LINK( this, OGeneralPageWizard, OnSetupModeSelected ) );
517         m_pRB_OpenExistingDatabase->SetClickHdl( LINK( this, OGeneralPageWizard, OnSetupModeSelected ) );
518         m_pLB_DocumentList->SetSelectHdl( LINK( this, OGeneralPageWizard, OnDocumentSelected ) );
519         m_pPB_OpenDatabase->SetClickHdl( LINK( this, OGeneralPageWizard, OnOpenDocument ) );
520     }
521 
522     OGeneralPageWizard::~OGeneralPageWizard()
523     {
524         disposeOnce();
525     }
526 
527     void OGeneralPageWizard::dispose()
528     {
529         m_pRB_CreateDatabase.clear();
530         m_pRB_OpenExistingDatabase.clear();
531         m_pRB_ConnectDatabase.clear();
532         m_pFT_EmbeddedDBLabel.clear();
533         m_pEmbeddedDBType.clear();
534         m_pFT_DocListLabel.clear();
535         m_pLB_DocumentList.clear();
536         m_pPB_OpenDatabase.clear();
537         OGeneralPage::dispose();
538     }
539 
540     OGeneralPageWizard::CreationMode OGeneralPageWizard::GetDatabaseCreationMode() const
541     {
542         if ( m_pRB_CreateDatabase->IsChecked() )
543             return eCreateNew;
544         if ( m_pRB_ConnectDatabase->IsChecked() )
545             return eConnectExternal;
546         return eOpenExisting;
547     }
548 
549     void OGeneralPageWizard::GetFocus()
550     {
551         OGeneralPage::GetFocus();
552         if ( m_pLB_DocumentList && m_pLB_DocumentList->IsEnabled() )
553             m_pLB_DocumentList->GrabFocus();
554         else if ( m_pDatasourceType && m_pDatasourceType->IsEnabled() )
555             m_pDatasourceType->GrabFocus();
556     }
557 
558     void OGeneralPageWizard::implInitControls( const SfxItemSet& _rSet, bool _bSaveValue )
559     {
560         OGeneralPage::implInitControls( _rSet, _bSaveValue );
561 
562         initializeEmbeddedDBList();
563         m_pEmbeddedDBType->SelectEntry( getEmbeddedDBName( _rSet ) );
564 
565         // first check whether or not the selection is invalid or readonly (invalid implies readonly, but not vice versa)
566         bool bValid, bReadonly;
567         getFlags( _rSet, bValid, bReadonly );
568 
569         SetText( OUString() );
570 
571         LayoutHelper::positionBelow( *m_pRB_ConnectDatabase, *m_pDatasourceType, INDENT_BELOW_RADIO );
572 
573         if ( !bValid || bReadonly )
574         {
575             m_pFT_EmbeddedDBLabel->Enable( false );
576             m_pDatasourceType->Enable( false );
577             m_pPB_OpenDatabase->Enable( false );
578             m_pFT_DocListLabel->Enable( false );
579             m_pLB_DocumentList->Enable( false );
580         }
581         else
582         {
583             m_aControlDependencies.enableOnRadioCheck( *m_pRB_CreateDatabase, *m_pEmbeddedDBType, *m_pFT_EmbeddedDBLabel );
584             m_aControlDependencies.enableOnRadioCheck( *m_pRB_ConnectDatabase, *m_pDatasourceType );
585             m_aControlDependencies.enableOnRadioCheck( *m_pRB_OpenExistingDatabase, *m_pPB_OpenDatabase, *m_pFT_DocListLabel, *m_pLB_DocumentList );
586         }
587 
588         m_pLB_DocumentList->SetDropDownLineCount( 20 );
589         if ( m_pLB_DocumentList->GetEntryCount() )
590             m_pLB_DocumentList->SelectEntryPos( 0 );
591 
592         m_eOriginalCreationMode = GetDatabaseCreationMode();
593     }
594 
595     OUString OGeneralPageWizard::getDatasourceName(const SfxItemSet& _rSet)
596     {
597         // Sets the default selected database on startup.
598         if (m_pRB_CreateDatabase->IsChecked() )
599         {
600             SvtMiscOptions aMiscOptions;
601             if( aMiscOptions.IsExperimentalMode() )
602                 return m_pCollection->getTypeDisplayName( "sdbc:embedded:firebird" );
603             else
604                 return m_pCollection->getTypeDisplayName( "jdbc:" );
605         }
606 
607         return OGeneralPage::getDatasourceName( _rSet );
608     }
609 
610     bool OGeneralPageWizard::approveDatasourceType( ::dbaccess::DATASOURCE_TYPE eType, OUString& _inout_rDisplayName )
611     {
612         switch ( eType )
613         {
614         case ::dbaccess::DST_MYSQL_JDBC:
615         case ::dbaccess::DST_MYSQL_ODBC:
616         case ::dbaccess::DST_MYSQL_NATIVE:
617             _inout_rDisplayName = "MySQL";
618             break;
619         default:
620             break;
621         }
622 
623         return OGeneralPage::approveDatasourceType( eType, _inout_rDisplayName );
624     }
625 
626     bool OGeneralPageWizard::FillItemSet(SfxItemSet* _rCoreAttrs)
627     {
628         bool bChangedSomething = false;
629 
630         bool bCommitTypeSelection = true;
631 
632         if ( m_pRB_CreateDatabase->IsChecked() )
633         {
634             _rCoreAttrs->Put( SfxStringItem( DSID_CONNECTURL, OUString( "sdbc:dbase:" ) ) );
635             bChangedSomething = true;
636             bCommitTypeSelection = false;
637         }
638         else if ( m_pRB_OpenExistingDatabase->IsChecked() )
639         {
640             if ( m_pRB_OpenExistingDatabase->IsValueChangedFromSaved() )
641                 bChangedSomething = true;
642 
643             // TODO
644             bCommitTypeSelection = false;
645         }
646 
647         if ( bCommitTypeSelection )
648         {
649             const sal_Int32 nEntry = m_pDatasourceType->GetSelectedEntryPos();
650             OUString sURLPrefix = m_aURLPrefixes[nEntry];
651 
652             if  (  m_pDatasourceType->IsValueChangedFromSaved()
653                 || ( GetDatabaseCreationMode() != m_eOriginalCreationMode )
654                 )
655             {
656                 _rCoreAttrs->Put( SfxStringItem( DSID_CONNECTURL,sURLPrefix ) );
657                 bChangedSomething = true;
658             }
659             else
660                 implSetCurrentType( sURLPrefix );
661         }
662         return bChangedSomething;
663     }
664 
665     OGeneralPageWizard::DocumentDescriptor OGeneralPageWizard::GetSelectedDocument() const
666     {
667         DocumentDescriptor aDocument;
668         if ( !m_aBrowsedDocument.sURL.isEmpty() )
669             aDocument = m_aBrowsedDocument;
670         else
671         {
672             aDocument.sURL = m_pLB_DocumentList->GetSelectedDocumentURL();
673             aDocument.sFilter = m_pLB_DocumentList->GetSelectedDocumentFilter();
674         }
675         return aDocument;
676     }
677 
678     IMPL_LINK_NOARG( OGeneralPageWizard, OnCreateDatabaseModeSelected, Button*, void )
679     {
680         m_aCreationModeHandler.Call( *this );
681 
682         OnEmbeddedDBTypeSelected( *m_pEmbeddedDBType );
683     }
684 
685     IMPL_LINK_NOARG( OGeneralPageWizard, OnSetupModeSelected, Button*, void )
686     {
687         m_aCreationModeHandler.Call( *this );
688         OnDatasourceTypeSelected(*m_pDatasourceType);
689     }
690 
691     IMPL_LINK_NOARG( OGeneralPageWizard, OnDocumentSelected, ListBox&, void )
692     {
693         m_aDocumentSelectionHandler.Call( *this );
694     }
695 
696     IMPL_LINK_NOARG( OGeneralPageWizard, OnOpenDocument, Button*, void )
697     {
698         ::sfx2::FileDialogHelper aFileDlg(
699                 ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION,
700                 FileDialogFlags::NONE, "sdatabase", SfxFilterFlags::NONE, SfxFilterFlags::NONE, GetFrameWeld());
701         std::shared_ptr<const SfxFilter> pFilter = getStandardDatabaseFilter();
702         if ( pFilter )
703         {
704             aFileDlg.SetCurrentFilter(pFilter->GetUIName());
705         }
706         if ( aFileDlg.Execute() == ERRCODE_NONE )
707         {
708             OUString sPath = aFileDlg.GetPath();
709             if ( aFileDlg.GetCurrentFilter() != pFilter->GetUIName() || !pFilter->GetWildcard().Matches(sPath) )
710             {
711                 OUString sMessage(DBA_RES(STR_ERR_USE_CONNECT_TO));
712                 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetFrameWeld(),
713                                                               VclMessageType::Info, VclButtonsType::Ok,
714                                                               sMessage));
715                 xInfoBox->run();
716                 m_pRB_ConnectDatabase->Check();
717                 OnSetupModeSelected( m_pRB_ConnectDatabase );
718                 return;
719             }
720             m_aBrowsedDocument.sURL = sPath;
721             m_aBrowsedDocument.sFilter.clear();
722             m_aChooseDocumentHandler.Call( *this );
723         }
724     }
725 
726 }   // namespace dbaui
727 
728 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
729