File indexing completed on 2024-05-19 04:48:45

0001 /****************************************************************************************
0002  * Copyright (c) 2009 John Atkinson <john@fauxnetic.co.uk>                              *
0003  *                                                                                      *
0004  * This program is free software; you can redistribute it and/or modify it under        *
0005  * the terms of the GNU General Public License as published by the Free Software        *
0006  * Foundation; either version 2 of the License, or (at your option) any later           *
0007  * version.                                                                             *
0008  *                                                                                      *
0009  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0010  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0011  * PARTICULAR PURPOSE. See the GNU General Pulic License for more details.              *
0012  *                                                                                      *
0013  * You should have received a copy of the GNU General Public License along with         *
0014  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0015  ****************************************************************************************/
0016 
0017 #include "DatabaseConfig.h"
0018 
0019 #include <PluginManager.h>
0020 #include <core/support/Amarok.h>
0021 #include <core/support/Debug.h>
0022 #include "core/support/PluginFactory.h"
0023 
0024 #include <KConfigDialogManager>
0025 #include <KMessageBox>
0026 #include <KCMultiDialog>
0027 
0028 
0029 DatabaseConfig::DatabaseConfig( Amarok2ConfigDialog* parent, KCoreConfigSkeleton *config )
0030     : ConfigDialogBase( parent )
0031     , m_configManager( new KConfigDialogManager( this, config ) )
0032 {
0033     setupUi( this );
0034 
0035     // Fix some weird tab orderness
0036     setTabOrder( kcfg_Host,     kcfg_Port );        // host to port
0037     setTabOrder( kcfg_Port,     kcfg_User );        // port to username
0038     setTabOrder( kcfg_User,     kcfg_Password );    // username to password
0039     setTabOrder( kcfg_Password, kcfg_Database );    // password to database
0040 
0041     // enable the test button if one of the plugin factories has a correct testSettings slot
0042     // get all storage factories
0043     auto factories = Plugins::PluginManager::instance()->factories( Plugins::PluginManager::Storage );
0044     bool testFunctionAvailable = false;
0045     for( const auto &factory : factories )
0046     {
0047         // check the meta object if there is a testSettings slot available
0048         if( factory->metaObject()->
0049             indexOfMethod( QMetaObject::normalizedSignature("testSettings(QString, QString, QString, int, QString)" ) ) >= 0 )
0050             testFunctionAvailable = true;
0051     }
0052     button_Test->setEnabled( testFunctionAvailable );
0053 
0054     // connect slots
0055     connect( kcfg_UseServer, &QCheckBox::stateChanged, this, &DatabaseConfig::toggleExternalConfigAvailable );
0056 
0057     connect( kcfg_Database, &QLineEdit::textChanged, this, &DatabaseConfig::updateSQLQuery );
0058     connect( kcfg_User,     &QLineEdit::textChanged, this, &DatabaseConfig::updateSQLQuery );
0059     connect( button_Test,   &QAbstractButton::clicked,  this, &DatabaseConfig::testDatabaseConnection );
0060 
0061     toggleExternalConfigAvailable( kcfg_UseServer->checkState() );
0062 
0063     updateSQLQuery();
0064 
0065     m_configManager->addWidget( this );
0066 }
0067 
0068 DatabaseConfig::~DatabaseConfig()
0069 {}
0070 
0071 void
0072 DatabaseConfig::toggleExternalConfigAvailable( const int checkBoxState ) //SLOT
0073 {
0074     group_Connection->setEnabled( checkBoxState == Qt::Checked );
0075 }
0076 
0077 void
0078 DatabaseConfig::testDatabaseConnection() //SLOT
0079 {
0080     // get all storage factories
0081     auto factories = Plugins::PluginManager::instance()->factories( Plugins::PluginManager::Storage );
0082 
0083     // try if they have a testSettings slot that we can call
0084     for( const auto &factory : factories )
0085     {
0086         bool callSucceeded = false;
0087         QStringList connectionErrors;
0088 
0089         callSucceeded = QMetaObject::invokeMethod( factory.data(),
0090                                "testSettings",
0091                                Q_RETURN_ARG( QStringList, connectionErrors ),
0092                                Q_ARG( QString, kcfg_Host->text() ),
0093                                Q_ARG( QString, kcfg_User->text() ),
0094                                Q_ARG( QString, kcfg_Password->text() ),
0095                                Q_ARG( int, kcfg_Port->text().toInt() ),
0096                                Q_ARG( QString, kcfg_Database->text() )
0097                                );
0098 
0099         if( callSucceeded )
0100         {
0101             if( connectionErrors.isEmpty() )
0102                 KMessageBox::information(this,
0103                                          i18n( "Amarok was able to establish a successful connection to the database." ),
0104                                          i18n( "Success" ) );
0105             else
0106                 KMessageBox::error( this, i18n( "The amarok database reported "
0107                                                 "the following errors:\n%1\nIn most cases you will need to resolve "
0108                                                 "these errors before Amarok will run properly.",
0109                                     connectionErrors.join( QStringLiteral("\n") ) ),
0110                                     i18n( "Database Error" ));
0111         }
0112     }
0113 }
0114 
0115 ///////////////////////////////////////////////////////////////
0116 // REIMPLEMENTED METHODS from ConfigDialogBase
0117 ///////////////////////////////////////////////////////////////
0118 
0119 bool
0120 DatabaseConfig::hasChanged()
0121 {
0122     return false;
0123 }
0124 
0125 bool
0126 DatabaseConfig::isDefault()
0127 {
0128     return false;
0129 }
0130 
0131 void
0132 DatabaseConfig::updateSettings()
0133 {
0134     if( m_configManager->hasChanged() )
0135         KMessageBox::information( nullptr,
0136                  i18n( "Changes to database settings only take\neffect after Amarok is restarted." ),
0137                  i18n( "Database settings changed" ) );
0138 }
0139 
0140 
0141 ///////////////////////////////////////////////////////////////
0142 // PRIVATE METHODS
0143 ///////////////////////////////////////////////////////////////
0144 
0145 void
0146 DatabaseConfig::updateSQLQuery() //SLOT
0147 {
0148     QString query;
0149 
0150     if( isSQLInfoPresent() )
0151     {
0152         // Query template:
0153         // GRANT ALL ON amarokdb.* TO 'amarokuser'@'localhost' IDENTIFIED BY 'mypassword'; FLUSH PRIVILEGES;
0154 
0155         // Don't print the actual password!
0156         const QString examplePassword = i18nc( "A default password for insertion into an example SQL command (so as not to print the real one). To be manually replaced by the user.", "password" );
0157         query = QStringLiteral( "CREATE DATABASE %1;\nGRANT ALL PRIVILEGES ON %1.* TO '%2' IDENTIFIED BY '%3'; FLUSH PRIVILEGES;" )
0158                    .arg( kcfg_Database->text(), kcfg_User->text(), examplePassword );
0159     }
0160     text_SQL->setPlainText( query );
0161 }
0162 
0163 
0164 inline bool
0165 DatabaseConfig::isSQLInfoPresent() const
0166 {
0167     return !kcfg_Database->text().isEmpty() && !kcfg_User->text().isEmpty() && !kcfg_Host->text().isEmpty();
0168 }
0169 
0170 
0171 
0172