File indexing completed on 2024-05-05 04:48:24
0001 /**************************************************************************************** 0002 * Copyright (c) 2012 Andrzej J. R. Hunt <andrzej at ahunt.org> * 0003 * Copyright (c) Mark Kretschmann <kretschmann@kde.org> * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify it under * 0006 * the terms of the GNU General Public License as published by the Free Software * 0007 * Foundation; either version 2 of the License, or (at your option) any later * 0008 * version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0011 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0012 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU General Public License along with * 0015 * this program. If not, see <http://www.gnu.org/licenses/>. * 0016 ****************************************************************************************/ 0017 0018 #include "DiagnosticDialog.h" 0019 0020 #include "context/ContextView.h" 0021 #include "PluginManager.h" 0022 #include "scripting/scriptmanager/ScriptManager.h" 0023 0024 #include <QApplication> 0025 #include <QClipboard> 0026 #include <QDialogButtonBox> 0027 #include <QDir> 0028 #include <QPlainTextEdit> 0029 #include <QPushButton> 0030 #include <QSettings> 0031 #include <QVBoxLayout> 0032 0033 #include <KAboutData> 0034 #include <KCoreAddons> 0035 #include <KLocalizedString> 0036 #include <KPluginInfo> 0037 0038 #include <algorithm> 0039 #include <phonon/pulsesupport.h> 0040 0041 0042 0043 BackendDescriptor::BackendDescriptor(const QString &path) 0044 : isValid(false) 0045 { 0046 QPluginLoader loader(path); 0047 0048 iid = loader.metaData().value(QStringLiteral("IID")).toString(); 0049 0050 const QJsonObject metaData = loader.metaData().value(QStringLiteral("MetaData")).toObject(); 0051 name = metaData.value(QStringLiteral("Name")).toString(); 0052 version = metaData.value(QStringLiteral("Version")).toString(); 0053 website = metaData.value(QStringLiteral("Website")).toString(); 0054 preference = metaData.value(QStringLiteral("InitialPreference")).toDouble(); 0055 0056 pluginPath = path; 0057 0058 if (name.isEmpty()) 0059 name = QFileInfo(path).baseName(); 0060 0061 if (iid.isEmpty()) 0062 return; // Not valid. 0063 0064 isValid = true; 0065 } 0066 0067 bool BackendDescriptor::operator <(const BackendDescriptor &rhs) const 0068 { 0069 return this->preference < rhs.preference; 0070 } 0071 0072 0073 0074 DiagnosticDialog::DiagnosticDialog( const KAboutData &about, QWidget *parent ) 0075 : QDialog( parent ) 0076 { 0077 setLayout( new QVBoxLayout ); 0078 m_textBox = new QPlainTextEdit( generateReport( &about ), this ); 0079 m_textBox->setReadOnly( true ); 0080 layout()->addWidget( m_textBox ); 0081 0082 auto buttonBox = new QDialogButtonBox( this ); 0083 auto closeButton = buttonBox->addButton( QDialogButtonBox::Close ); 0084 auto copyButton = new QPushButton( i18n( "Copy to Clipboard" ) ); 0085 buttonBox->addButton( copyButton, QDialogButtonBox::ActionRole ); 0086 layout()->addWidget( buttonBox ); 0087 0088 setWindowTitle( i18nc( "%1 is the program name", "%1 Diagnostics", KAboutData::applicationData().displayName() ) ); 0089 0090 resize( QSize( 480, 460 ) ); 0091 0092 connect( closeButton, &QPushButton::clicked, this, &DiagnosticDialog::close ); 0093 connect( copyButton, &QPushButton::clicked, this, &DiagnosticDialog::slotCopyToClipboard ); 0094 0095 setAttribute( Qt::WA_DeleteOnClose ); 0096 } 0097 0098 const QString 0099 DiagnosticDialog::generateReport( const KAboutData *aboutData ) 0100 { 0101 // Get scripts -- we have to assemble 3 lists into one 0102 KPluginInfo::List aScripts; 0103 const auto aScriptManager = ScriptManager::instance(); 0104 aScripts.append( aScriptManager->scripts( QStringLiteral( "Generic" ) ) ); 0105 aScripts.append( aScriptManager->scripts( QStringLiteral( "Lyrics" ) ) ); 0106 aScripts.append( aScriptManager->scripts( QStringLiteral( "Scriptable Service" ) ) ); 0107 0108 // Format the data to be readable 0109 QString aScriptString; 0110 foreach( KPluginInfo aInfo, aScripts ) 0111 { 0112 if( aInfo.isPluginEnabled() ) 0113 aScriptString += " " + aInfo.name() + " (" + aInfo.version() + ")\n"; 0114 } 0115 0116 0117 // Get plugins -- we have to assemble a list again. 0118 QVector<KPluginMetaData> aPlugins; 0119 const auto aPluginManager = Plugins::PluginManager::instance(); 0120 aPlugins.append( aPluginManager->enabledPlugins( Plugins::PluginManager::Collection ) ); 0121 aPlugins.append( aPluginManager->enabledPlugins( Plugins::PluginManager::Service ) ); 0122 aPlugins.append( aPluginManager->enabledPlugins( Plugins::PluginManager::Importer ) ); 0123 0124 QString aPluginString; 0125 for( const auto &aInfo : qAsConst(aPlugins) ) 0126 { 0127 aPluginString += " " + aInfo.name() + " (" + aInfo.version() + ")\n"; 0128 } 0129 0130 // Get applets 0131 QString appletString; 0132 const QStringList appletList = Context::ContextView::self()->currentAppletNames(); 0133 0134 for ( const QString &applet : appletList ) 0135 { 0136 // Currently we cannot extract the applet version number this way 0137 appletString += " " + applet + '\n'; 0138 } 0139 0140 const BackendDescriptor aPhononBackend = getPreferredBackend(); 0141 0142 const bool hasPulse = Phonon::PulseSupport::getInstance()->isActive(); 0143 const QString pulse = hasPulse ? i18nc( "Usage", "Yes" ) : i18nc( "Usage", "No" ); 0144 0145 return i18n( 0146 "%1 Diagnostics\n\nGeneral Information:\n" 0147 " %1 Version: %2\n" 0148 " KDE Frameworks Version: %3\n" 0149 " Qt Version: %4\n" 0150 " Phonon Version: %5\n" 0151 " Phonon Backend: %6 (%7, %8)\n" 0152 " PulseAudio: %9\n\n", 0153 0154 KAboutData::applicationData().displayName(), aboutData->version(), // Amarok 0155 KCoreAddons::versionString(), // KDE Frameworks 0156 qVersion(), // Qt 0157 Phonon::phononVersion(), // Phonon 0158 aPhononBackend.name, 0159 aPhononBackend.version, 0160 aPhononBackend.website, // & Backend 0161 pulse // PulseAudio 0162 ) + i18n( 0163 "Enabled Scripts:\n%1\n" 0164 "Enabled Plugins:\n%2\n" 0165 "Enabled Applets:\n%3\n", 0166 aScriptString, aPluginString, appletString 0167 ); 0168 } 0169 0170 const BackendDescriptor 0171 DiagnosticDialog::getPreferredBackend() const 0172 { 0173 QList<QString> iidPreference; 0174 QSettings settings("kde.org", "libphonon"); 0175 const int size = settings.beginReadArray("Backends"); 0176 for (int i = 0; i < size; ++i) { 0177 settings.setArrayIndex(i); 0178 iidPreference.append(settings.value(QStringLiteral("iid")).toString()); 0179 } 0180 settings.endArray(); 0181 0182 const QLatin1String suffix("/" PHONON_LIB_SONAME "_backend/"); 0183 const QStringList paths = QCoreApplication::libraryPaths(); 0184 0185 QList<struct BackendDescriptor> backendList; 0186 0187 foreach (const QString &path, paths) { 0188 const QString libPath = path + suffix; 0189 const QDir dir(libPath); 0190 if (!dir.exists()) { 0191 continue; 0192 } 0193 0194 const QStringList plugins(dir.entryList(QDir::Files)); 0195 0196 for (const QString &plugin : plugins) { 0197 BackendDescriptor bd = BackendDescriptor(libPath + plugin); 0198 if (bd.isValid) { 0199 int preference = iidPreference.indexOf(bd.iid); 0200 if (preference != -1) { 0201 bd.preference = preference; 0202 } 0203 backendList.append(bd); 0204 } 0205 } 0206 } 0207 0208 std::sort(backendList.begin(), backendList.end()); 0209 0210 return backendList.first(); 0211 } 0212 0213 void 0214 DiagnosticDialog::slotCopyToClipboard() const 0215 { 0216 QClipboard *clipboard = QApplication::clipboard(); 0217 clipboard->setText( m_textBox->toPlainText() ); 0218 }