1 /****************************************************************************************
2 * Copyright (c) 2009 John Atkinson <john@fauxnetic.co.uk> *
3 * *
4 * This program is free software; you can redistribute it and/or modify it under *
5 * the terms of the GNU General Public License as published by the Free Software *
6 * Foundation; either version 2 of the License, or (at your option) any later *
7 * version. *
8 * *
9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY *
10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
11 * PARTICULAR PURPOSE. See the GNU General Pulic License for more details. *
12 * *
13 * You should have received a copy of the GNU General Public License along with *
14 * this program. If not, see <http://www.gnu.org/licenses/>. *
15 ****************************************************************************************/
16
17 #include "DatabaseConfig.h"
18
19 #include <PluginManager.h>
20 #include <core/support/Amarok.h>
21 #include <core/support/Debug.h>
22 #include "core/support/PluginFactory.h"
23
24 #include <KConfigDialogManager>
25 #include <KMessageBox>
26 #include <KCMultiDialog>
27
28
DatabaseConfig(Amarok2ConfigDialog * parent,KConfigSkeleton * config)29 DatabaseConfig::DatabaseConfig( Amarok2ConfigDialog* parent, KConfigSkeleton *config )
30 : ConfigDialogBase( parent )
31 , m_configManager( new KConfigDialogManager( this, config ) )
32 {
33 setupUi( this );
34
35 // Fix some weird tab orderness
36 setTabOrder( kcfg_Host, kcfg_Port ); // host to port
37 setTabOrder( kcfg_Port, kcfg_User ); // port to username
38 setTabOrder( kcfg_User, kcfg_Password ); // username to password
39 setTabOrder( kcfg_Password, kcfg_Database ); // password to database
40
41 // enable the test button if one of the plugin factories has a correct testSettings slot
42 // get all storage factories
43 auto factories = Plugins::PluginManager::instance()->factories( Plugins::PluginManager::Storage );
44 bool testFunctionAvailable = false;
45 for( const auto &factory : factories )
46 {
47 // check the meta object if there is a testSettings slot available
48 if( factory->metaObject()->
49 indexOfMethod( QMetaObject::normalizedSignature("testSettings(QString, QString, QString, int, QString)" ) ) >= 0 )
50 testFunctionAvailable = true;
51 }
52 button_Test->setEnabled( testFunctionAvailable );
53
54 // connect slots
55 connect( kcfg_UseServer, &QCheckBox::stateChanged, this, &DatabaseConfig::toggleExternalConfigAvailable );
56
57 connect( kcfg_Database, &QLineEdit::textChanged, this, &DatabaseConfig::updateSQLQuery );
58 connect( kcfg_User, &QLineEdit::textChanged, this, &DatabaseConfig::updateSQLQuery );
59 connect( button_Test, &QAbstractButton::clicked, this, &DatabaseConfig::testDatabaseConnection );
60
61 toggleExternalConfigAvailable( kcfg_UseServer->checkState() );
62
63 updateSQLQuery();
64
65 m_configManager->addWidget( this );
66 }
67
~DatabaseConfig()68 DatabaseConfig::~DatabaseConfig()
69 {}
70
71 void
toggleExternalConfigAvailable(const int checkBoxState)72 DatabaseConfig::toggleExternalConfigAvailable( const int checkBoxState ) //SLOT
73 {
74 group_Connection->setEnabled( checkBoxState == Qt::Checked );
75 }
76
77 void
testDatabaseConnection()78 DatabaseConfig::testDatabaseConnection() //SLOT
79 {
80 // get all storage factories
81 auto factories = Plugins::PluginManager::instance()->factories( Plugins::PluginManager::Storage );
82
83 // try if they have a testSettings slot that we can call
84 for( const auto &factory : factories )
85 {
86 bool callSucceeded = false;
87 QStringList connectionErrors;
88
89 callSucceeded = QMetaObject::invokeMethod( factory.data(),
90 "testSettings",
91 Q_RETURN_ARG( QStringList, connectionErrors ),
92 Q_ARG( QString, kcfg_Host->text() ),
93 Q_ARG( QString, kcfg_User->text() ),
94 Q_ARG( QString, kcfg_Password->text() ),
95 Q_ARG( int, kcfg_Port->text().toInt() ),
96 Q_ARG( QString, kcfg_Database->text() )
97 );
98
99 if( callSucceeded )
100 {
101 if( connectionErrors.isEmpty() )
102 KMessageBox::messageBox( this, KMessageBox::Information,
103 i18n( "Amarok was able to establish a successful connection to the database." ),
104 i18n( "Success" ) );
105 else
106 KMessageBox::error( this, i18n( "The amarok database reported "
107 "the following errors:\n%1\nIn most cases you will need to resolve "
108 "these errors before Amarok will run properly.",
109 connectionErrors.join( QStringLiteral("\n") ) ),
110 i18n( "Database Error" ));
111 }
112 }
113 }
114
115 ///////////////////////////////////////////////////////////////
116 // REIMPLEMENTED METHODS from ConfigDialogBase
117 ///////////////////////////////////////////////////////////////
118
119 bool
hasChanged()120 DatabaseConfig::hasChanged()
121 {
122 return false;
123 }
124
125 bool
isDefault()126 DatabaseConfig::isDefault()
127 {
128 return false;
129 }
130
131 void
updateSettings()132 DatabaseConfig::updateSettings()
133 {
134 if( m_configManager->hasChanged() )
135 KMessageBox::messageBox( nullptr, KMessageBox::Information,
136 i18n( "Changes to database settings only take\neffect after Amarok is restarted." ),
137 i18n( "Database settings changed" ) );
138 }
139
140
141 ///////////////////////////////////////////////////////////////
142 // PRIVATE METHODS
143 ///////////////////////////////////////////////////////////////
144
145 void
updateSQLQuery()146 DatabaseConfig::updateSQLQuery() //SLOT
147 {
148 QString query;
149
150 if( isSQLInfoPresent() )
151 {
152 // Query template:
153 // GRANT ALL ON amarokdb.* TO 'amarokuser'@'localhost' IDENTIFIED BY 'mypassword'; FLUSH PRIVILEGES;
154
155 // Don't print the actual password!
156 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" );
157 query = QStringLiteral( "CREATE DATABASE %1;\nGRANT ALL PRIVILEGES ON %1.* TO '%2' IDENTIFIED BY '%3'; FLUSH PRIVILEGES;" )
158 .arg( kcfg_Database->text(), kcfg_User->text(), examplePassword );
159 }
160 text_SQL->setPlainText( query );
161 }
162
163
164 inline bool
isSQLInfoPresent() const165 DatabaseConfig::isSQLInfoPresent() const
166 {
167 return !kcfg_Database->text().isEmpty() && !kcfg_User->text().isEmpty() && !kcfg_Host->text().isEmpty();
168 }
169
170
171
172
173