diff --git a/src/MediaDeviceCache.cpp b/src/MediaDeviceCache.cpp index a4540ae07a..1d70c8993f 100644 --- a/src/MediaDeviceCache.cpp +++ b/src/MediaDeviceCache.cpp @@ -1,376 +1,374 @@ /**************************************************************************************** * Copyright (c) 2007 Jeff Mitchell * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #define DEBUG_PREFIX "MediaDeviceCache" #include "MediaDeviceCache.h" #include "core/support/Amarok.h" #include "core/support/Debug.h" #include #include #include #include #include #include #include #include #include #include #include -#include - #include #include #include #include MediaDeviceCache* MediaDeviceCache::s_instance = 0; MediaDeviceCache::MediaDeviceCache() : QObject() , m_type() , m_name() , m_volumes() { DEBUG_BLOCK s_instance = this; connect( Solid::DeviceNotifier::instance(), &Solid::DeviceNotifier::deviceAdded, this, &MediaDeviceCache::slotAddSolidDevice ); connect( Solid::DeviceNotifier::instance(), &Solid::DeviceNotifier::deviceRemoved, this, &MediaDeviceCache::slotRemoveSolidDevice ); } MediaDeviceCache::~MediaDeviceCache() { s_instance = 0; } void MediaDeviceCache::refreshCache() { DEBUG_BLOCK m_type.clear(); m_name.clear(); QList deviceList = Solid::Device::listFromType( Solid::DeviceInterface::PortableMediaPlayer ); foreach( const Solid::Device &device, deviceList ) { if( device.as() ) { debug() << "Found Solid PMP that is also a StorageDrive, skipping"; continue; } debug() << "Found Solid::DeviceInterface::PortableMediaPlayer with udi = " << device.udi(); debug() << "Device name is = " << device.product() << " and was made by " << device.vendor(); m_type[device.udi()] = MediaDeviceCache::SolidPMPType; m_name[device.udi()] = device.vendor() + " - " + device.product(); } deviceList = Solid::Device::listFromType( Solid::DeviceInterface::StorageAccess ); foreach( const Solid::Device &device, deviceList ) { debug() << "Found Solid::DeviceInterface::StorageAccess with udi = " << device.udi(); debug() << "Device name is = " << device.product() << " and was made by " << device.vendor(); const Solid::StorageAccess* ssa = device.as(); if( ssa ) { if( !m_volumes.contains( device.udi() ) ) { connect( ssa, &Solid::StorageAccess::accessibilityChanged, this, &MediaDeviceCache::slotAccessibilityChanged ); m_volumes.append( device.udi() ); } if( ssa->isAccessible() ) { m_type[device.udi()] = MediaDeviceCache::SolidVolumeType; m_name[device.udi()] = ssa->filePath(); m_accessibility[ device.udi() ] = true; } else { m_accessibility[ device.udi() ] = false; debug() << "Solid device is not accessible, will wait until it is to consider it added."; } } } deviceList = Solid::Device::listFromType( Solid::DeviceInterface::StorageDrive ); foreach( const Solid::Device &device, deviceList ) { debug() << "Found Solid::DeviceInterface::StorageDrive with udi = " << device.udi(); debug() << "Device name is = " << device.product() << " and was made by " << device.vendor(); if( device.as() ) { m_type[device.udi()] = MediaDeviceCache::SolidGenericType; m_name[device.udi()] = device.vendor() + " - " + device.product(); } } deviceList = Solid::Device::listFromType( Solid::DeviceInterface::OpticalDisc ); foreach( const Solid::Device &device, deviceList ) { debug() << "Found Solid::DeviceInterface::OpticalDisc with udi = " << device.udi(); debug() << "Device name is = " << device.product() << " and was made by " << device.vendor(); const Solid::OpticalDisc * opt = device.as(); if ( opt && opt->availableContent() & Solid::OpticalDisc::Audio ) { debug() << "device is an Audio CD"; m_type[device.udi()] = MediaDeviceCache::SolidAudioCdType; m_name[device.udi()] = device.vendor() + " - " + device.product(); } } KConfigGroup config = Amarok::config( "PortableDevices" ); const QStringList manualDeviceKeys = config.entryMap().keys(); foreach( const QString &udi, manualDeviceKeys ) { if( udi.startsWith( "manual" ) ) { debug() << "Found manual device with udi = " << udi; m_type[udi] = MediaDeviceCache::ManualType; m_name[udi] = udi.split( '|' )[1]; } } } void MediaDeviceCache::slotAddSolidDevice( const QString &udi ) { DEBUG_BLOCK Solid::Device device( udi ); debug() << "Found new Solid device with udi = " << device.udi(); debug() << "Device name is = " << device.product() << " and was made by " << device.vendor(); Solid::StorageAccess *ssa = device.as(); Solid::OpticalDisc * opt = device.as(); if ( opt && opt->availableContent() & Solid::OpticalDisc::Audio ) { debug() << "device is an Audio CD"; m_type[udi] = MediaDeviceCache::SolidAudioCdType; m_name[udi] = device.vendor() + " - " + device.product(); } else if( ssa ) { debug() << "volume is generic storage"; if( !m_volumes.contains( device.udi() ) ) { connect( ssa, &Solid::StorageAccess::accessibilityChanged, this, &MediaDeviceCache::slotAccessibilityChanged ); m_volumes.append( device.udi() ); } if( ssa->isAccessible() ) { m_type[udi] = MediaDeviceCache::SolidVolumeType; m_name[udi] = ssa->filePath(); } else { debug() << "storage volume is not accessible right now, not adding."; return; } } else if( device.is() ) { debug() << "device is a Storage drive, still need a volume"; m_type[udi] = MediaDeviceCache::SolidGenericType; m_name[udi] = device.vendor() + " - " + device.product(); } else if( device.is() ) { debug() << "device is a PMP"; m_type[udi] = MediaDeviceCache::SolidPMPType; m_name[udi] = device.vendor() + " - " + device.product(); } else if( const Solid::GenericInterface *generic = device.as() ) { const QMap properties = generic->allProperties(); /* At least iPod touch 3G and iPhone 3G do not advertise AFC (Apple File * Connection) capabilities. Therefore we have to white-list them so that they are * still recognised ad iPods * * @see IpodConnectionAssistant::identify() for a quirk that is currently also * needed for proper identification of iPhone-like devices. */ if ( !device.product().contains("iPod") && !device.product().contains("iPhone")) { if( !properties.contains("info.capabilities") ) { debug() << "udi " << udi << " does not describe a portable media player or storage volume"; return; } const QStringList capabilities = properties["info.capabilities"].toStringList(); if( !capabilities.contains("afc") ) { debug() << "udi " << udi << " does not describe a portable media player or storage volume"; return; } } debug() << "udi" << udi << "is AFC cabable (Apple mobile device)"; m_type[udi] = MediaDeviceCache::SolidGenericType; m_name[udi] = device.vendor() + " - " + device.product(); } else { debug() << "udi " << udi << " does not describe a portable media player or storage volume"; return; } emit deviceAdded( udi ); } void MediaDeviceCache::slotRemoveSolidDevice( const QString &udi ) { DEBUG_BLOCK debug() << "udi is: " << udi; Solid::Device device( udi ); if( m_volumes.contains( udi ) ) { disconnect( device.as(), &Solid::StorageAccess::accessibilityChanged, this, &MediaDeviceCache::slotAccessibilityChanged ); m_volumes.removeAll( udi ); emit deviceRemoved( udi ); } if( m_type.contains( udi ) ) { m_type.remove( udi ); m_name.remove( udi ); emit deviceRemoved( udi ); return; } debug() << "Odd, got a deviceRemoved at udi " << udi << " but it did not seem to exist in the first place..."; emit deviceRemoved( udi ); } void MediaDeviceCache::slotAccessibilityChanged( bool accessible, const QString &udi ) { debug() << "accessibility of device " << udi << " has changed to accessible = " << (accessible ? "true":"false"); if( accessible ) { Solid::Device device( udi ); m_type[udi] = MediaDeviceCache::SolidVolumeType; Solid::StorageAccess *ssa = device.as(); if( ssa ) m_name[udi] = ssa->filePath(); emit deviceAdded( udi ); return; } else { if( m_type.contains( udi ) ) { m_type.remove( udi ); m_name.remove( udi ); emit deviceRemoved( udi ); return; } debug() << "Got accessibility changed to false but was not there in the first place..."; } emit accessibilityChanged( accessible, udi ); } MediaDeviceCache::DeviceType MediaDeviceCache::deviceType( const QString &udi ) const { if( m_type.contains( udi ) ) { return m_type[udi]; } return MediaDeviceCache::InvalidType; } const QString MediaDeviceCache::deviceName( const QString &udi ) const { if( m_name.contains( udi ) ) { return m_name[udi]; } return "ERR_NO_NAME"; //Should never happen! } const QString MediaDeviceCache::device( const QString &udi ) const { DEBUG_BLOCK Solid::Device device( udi ); Solid::Device parent( device.parent() ); if( !parent.isValid() ) { debug() << udi << "has no parent, returning null string."; return QString(); } Solid::Block* sb = parent.as(); if( !sb ) { debug() << parent.udi() << "failed to convert to Block, returning null string."; return QString(); } return sb->device(); } bool MediaDeviceCache::isGenericEnabled( const QString &udi ) const { DEBUG_BLOCK if( m_type[udi] != MediaDeviceCache::SolidVolumeType ) { debug() << "Not SolidVolumeType, returning false"; return false; } Solid::Device device( udi ); Solid::StorageAccess* ssa = device.as(); if( !ssa || !ssa->isAccessible() ) { debug() << "Not able to convert to StorageAccess or not accessible, returning false"; return false; } if( device.parent().as() ) { debug() << "Could convert parent to PortableMediaPlayer, returning true"; return true; } if( QFile::exists( ssa->filePath() + QDir::separator() + ".is_audio_player" ) ) { return true; } return false; } const QString MediaDeviceCache::volumeMountPoint( const QString &udi ) const { DEBUG_BLOCK Solid::Device device( udi ); Solid::StorageAccess* ssa = device.as(); if( !ssa || !ssa->isAccessible() ) { debug() << "Not able to convert to StorageAccess or not accessible, returning empty"; return QString(); } return ssa->filePath(); } diff --git a/src/aboutdialog/ExtendedAboutDialog.cpp b/src/aboutdialog/ExtendedAboutDialog.cpp index 376fd82499..b8277f5531 100644 --- a/src/aboutdialog/ExtendedAboutDialog.cpp +++ b/src/aboutdialog/ExtendedAboutDialog.cpp @@ -1,429 +1,429 @@ /**************************************************************************************** * Copyright (c) 2007 Urs Wolfer * * Copyright (c) 2008 Friedrich W. H. Kossebau * * Copyright (c) 2009 Téo Mrnjavac * * * * Parts of this class have been take from the KAboutApplication class, which was * * Copyright (c) 2000 Waldo Bastian (bastian@kde.org) and Espen Sand (espen@kde.org) * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #include "ExtendedAboutDialog.h" #include "core/support/Amarok.h" #include "core/support/Debug.h" #include "OcsPersonItem.h" #include "libattica-ocsclient/providerinitjob.h" #include #include #include #include #include #include +#include #include #include #include #include #include #include #include #include #include #include #include #include -#include void ExtendedAboutDialog::Private::_k_showLicense( const QString &number ) { QDialog *dialog = new QDialog(q); QWidget *mainWidget = new QWidget; dialog->setWindowTitle(i18n("License Agreement")); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); dialog->connect(buttonBox, &QDialogButtonBox::accepted, dialog, &QDialog::accept); dialog->connect(buttonBox, &QDialogButtonBox::rejected, dialog, &QDialog::reject); buttonBox->button(QDialogButtonBox::Close)->setDefault(true); const QFont font = KGlobalSettings::fixedFont(); QFontMetrics metrics(font); const QString licenseText = aboutData->licenses().at(number.toInt()).text(); KTextBrowser *licenseBrowser = new KTextBrowser; licenseBrowser->setFont(font); licenseBrowser->setLineWrapMode(QTextEdit::NoWrap); licenseBrowser->setText(licenseText); QVBoxLayout *mainLayout = new QVBoxLayout; dialog->setLayout(mainLayout); mainLayout->addWidget(licenseBrowser); mainLayout->addWidget(mainWidget); mainLayout->addWidget(buttonBox); // try to set up the dialog such that the full width of the // document is visible without horizontal scroll-bars being required const qreal idealWidth = licenseBrowser->document()->idealWidth() + (2 * QApplication::style()->pixelMetric(QStyle::PM_DefaultChildMargin)) + licenseBrowser->verticalScrollBar()->width() * 2; //TODO KF5:PM_DefaultChildMargin is obsolete. Look in QStyle docs for correctly replacing it. // try to allow enough height for a reasonable number of lines to be shown const int idealHeight = metrics.height() * 30; dialog->resize(dialog->sizeHint().expandedTo(QSize((int)idealWidth,idealHeight))); dialog->show(); } ExtendedAboutDialog::ExtendedAboutDialog(const KAboutData about, const OcsData *ocsData, QWidget *parent) : QDialog(parent) , d(new Private(this)) { DEBUG_BLOCK const KAboutData *aboutData = &about; d->aboutData = aboutData; if (!aboutData) { QLabel *errorLabel = new QLabel(i18n("No information available.
" "The supplied KAboutData object does not exist.
"), this); errorLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); QVBoxLayout *mainLayout = new QVBoxLayout; setLayout(mainLayout); mainLayout->addWidget(errorLabel); return; } if( !ocsData ) { QLabel *errorLabel = new QLabel(i18n("No information available.
" "The supplied OcsData object does not exist.
"), this); errorLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); QVBoxLayout *mainLayout = new QVBoxLayout; setLayout(mainLayout); mainLayout->addWidget(errorLabel); return; } m_ocsData = *ocsData; setWindowTitle(i18n("About %1", aboutData->displayName())); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); QWidget *mainWidget = new QWidget(this); QVBoxLayout *mainLayout = new QVBoxLayout; setLayout(mainLayout); mainLayout->addWidget(mainWidget); connect(buttonBox, &QDialogButtonBox::accepted, this, &ExtendedAboutDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &ExtendedAboutDialog::reject); buttonBox->button(QDialogButtonBox::Close)->setDefault(true); setModal(false); //Set up the title widget... KTitleWidget *titleWidget = new KTitleWidget(this); QIcon windowIcon; if (!aboutData->programIconName().isEmpty()) { windowIcon = QIcon::fromTheme(aboutData->programIconName()); } else { windowIcon = qApp->windowIcon(); } titleWidget->setPixmap(windowIcon.pixmap(64, 64), KTitleWidget::ImageLeft); if (aboutData->programLogo().canConvert()) titleWidget->setPixmap(aboutData->programLogo().value(), KTitleWidget::ImageLeft); else if (aboutData->programLogo().canConvert()) titleWidget->setPixmap(QPixmap::fromImage(aboutData->programLogo().value()), KTitleWidget::ImageLeft); titleWidget->setText(i18n("%1
Version %2
Using KDE Frameworks %3", - aboutData->displayName(), aboutData->version(), KDE::versionString())); + aboutData->displayName(), aboutData->version(), KCoreAddons::versionString())); //Now let's add the tab bar... QTabWidget *tabWidget = new QTabWidget; tabWidget->setUsesScrollButtons(false); //Set up the first page... QString aboutPageText = aboutData->shortDescription() + '\n'; if (!aboutData->otherText().isEmpty()) aboutPageText += '\n' + aboutData->otherText() + '\n'; if (!aboutData->copyrightStatement().isEmpty()) aboutPageText += '\n' + aboutData->copyrightStatement() + '\n'; if (!aboutData->homepage().isEmpty()) aboutPageText += '\n' + QString("%1").arg(aboutData->homepage()) + '\n'; aboutPageText = aboutPageText.trimmed(); QLabel *aboutLabel = new QLabel; aboutLabel->setWordWrap(true); aboutLabel->setOpenExternalLinks(true); aboutLabel->setText(aboutPageText.replace('\n', "
")); aboutLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); QVBoxLayout *aboutLayout = new QVBoxLayout; aboutLayout->addStretch(); aboutLayout->addWidget(aboutLabel); const int licenseCount = aboutData->licenses().count(); debug()<< "About to show license stuff"; debug()<< "License count is"<licenses().at(i); QLabel *showLicenseLabel = new QLabel; showLicenseLabel->setText(QString("%2").arg(QString::number(i), i18n("License: %1", license.name(KAboutLicense::FullName)))); showLicenseLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); connect(showLicenseLabel, &QLabel::linkActivated, this, &ExtendedAboutDialog::showLicense); aboutLayout->addWidget(showLicenseLabel); } debug()<<"License widget added"; aboutLayout->addStretch(); QWidget *aboutWidget = new QWidget(this); aboutWidget->setLayout(aboutLayout); tabWidget->addTab(aboutWidget, i18n("&About")); //Stuff needed by both Authors and Credits pages: QPixmap openDesktopPixmap = QPixmap( KStandardDirs::locate( "data", "amarok/images/opendesktop-22.png" ) ); QIcon openDesktopIcon = QIcon( openDesktopPixmap ); //And now, the Authors page: const int authorCount = d->aboutData->authors().count(); if (authorCount) { m_authorWidget = new QWidget( this ); QVBoxLayout *authorLayout = new QVBoxLayout( m_authorWidget.data() ); m_showOcsAuthorButton = new AnimatedBarWidget( openDesktopIcon, i18n( "Get data from openDesktop.org to learn more about the team" ), "process-working", m_authorWidget.data() ); connect( m_showOcsAuthorButton.data(), &AnimatedBarWidget::clicked, this, &ExtendedAboutDialog::switchToOcsWidgets ); authorLayout->addWidget( m_showOcsAuthorButton.data() ); if (!aboutData->customAuthorTextEnabled() || !aboutData->customAuthorRichText().isEmpty()) { QLabel *bugsLabel = new QLabel( m_authorWidget.data() ); bugsLabel->setContentsMargins( 4, 2, 0, 4 ); if (!aboutData->customAuthorTextEnabled()) { if (aboutData->bugAddress().isEmpty() || aboutData->bugAddress() == "submit@bugs.kde.org") bugsLabel->setText( i18n("Please use http://bugs.kde.org to report bugs.\n") ); else { if(aboutData->authors().count() == 1 && (aboutData->authors().first().emailAddress() == aboutData->bugAddress())) { bugsLabel->setText( i18n("Please report bugs to %2.\n", aboutData->authors().first().emailAddress(), aboutData->authors().first().emailAddress())); } else { bugsLabel->setText( i18n("Please report bugs to %2.\n", aboutData->bugAddress(), aboutData->bugAddress())); } } } else bugsLabel->setText( aboutData->customAuthorRichText() ); authorLayout->addWidget( bugsLabel ); } m_authorListWidget = new OcsPersonListWidget( d->aboutData->authors(), m_ocsData.authors(), OcsPersonItem::Author, m_authorWidget.data() ); connect( m_authorListWidget.data(), &OcsPersonListWidget::switchedToOcs, m_showOcsAuthorButton.data(), &AnimatedBarWidget::stop ); connect( m_authorListWidget.data(), &OcsPersonListWidget::switchedToOcs, m_showOcsAuthorButton.data(), &AnimatedBarWidget::fold ); authorLayout->addWidget( m_authorListWidget.data() ); authorLayout->setMargin( 0 ); authorLayout->setSpacing( 2 ); m_authorWidget.data()->setLayout( authorLayout ); m_authorPageTitle = ( authorCount == 1 ) ? i18n("A&uthor") : i18n("A&uthors"); tabWidget->addTab(m_authorWidget.data(), m_authorPageTitle); m_isOfflineAuthorWidget = true; //is this still used? } //Then the Credits page: const int creditCount = aboutData->credits().count(); if (creditCount) { m_creditWidget = new QWidget( this ); QVBoxLayout *creditLayout = new QVBoxLayout( m_creditWidget.data() ); m_showOcsCreditButton = new AnimatedBarWidget( openDesktopIcon, i18n( "Get data from openDesktop.org to learn more about contributors" ), "process-working", m_creditWidget.data() ); connect( m_showOcsCreditButton.data(), &AnimatedBarWidget::clicked, this, &ExtendedAboutDialog::switchToOcsWidgets ); creditLayout->addWidget( m_showOcsCreditButton.data() ); m_creditListWidget = new OcsPersonListWidget( d->aboutData->credits(), m_ocsData.credits(), OcsPersonItem::Contributor, m_creditWidget.data() ); connect( m_creditListWidget.data(), &OcsPersonListWidget::switchedToOcs, m_showOcsCreditButton.data(), &AnimatedBarWidget::stop ); connect( m_creditListWidget.data(), &OcsPersonListWidget::switchedToOcs, m_showOcsCreditButton.data(), &AnimatedBarWidget::fold ); creditLayout->addWidget( m_creditListWidget.data() ); creditLayout->setMargin( 0 ); creditLayout->setSpacing( 2 ); m_creditWidget.data()->setLayout( creditLayout ); tabWidget->addTab( m_creditWidget.data(), i18n("&Contributors")); m_isOfflineCreditWidget = true; //is this still used? } //Finally, the Donors page: const int donorCount = ocsData->donors()->count(); if (donorCount) { m_donorWidget = new QWidget( this ); QVBoxLayout *donorLayout = new QVBoxLayout( m_donorWidget.data() ); m_showOcsDonorButton = new AnimatedBarWidget( openDesktopIcon, i18n( "Get data from openDesktop.org to learn more about our generous donors" ), "process-working", m_donorWidget.data() ); connect( m_showOcsDonorButton.data(), &AnimatedBarWidget::clicked, this, &ExtendedAboutDialog::switchToOcsWidgets ); donorLayout->addWidget( m_showOcsDonorButton.data() ); QList< KAboutPerson > donors; for( QList< QPair< QString, KAboutPerson > >::const_iterator it = m_ocsData.donors()->constBegin(); it != m_ocsData.donors()->constEnd(); ++it ) { donors << ( *it ).second; } m_donorListWidget = new OcsPersonListWidget( donors , m_ocsData.donors(), OcsPersonItem::Contributor, m_donorWidget.data() ); connect( m_donorListWidget.data(), &OcsPersonListWidget::switchedToOcs, m_showOcsDonorButton.data(), &AnimatedBarWidget::stop ); connect( m_donorListWidget.data(), &OcsPersonListWidget::switchedToOcs, m_showOcsDonorButton.data(), &AnimatedBarWidget::fold ); donorLayout->addWidget( m_donorListWidget.data() ); donorLayout->setMargin( 0 ); donorLayout->setSpacing( 2 ); QLabel *roktoberLabel = new QLabel(i18n("

Each year in October the Amarok team organizes a funding " "drive called Roktober.

" "

If you want your name mentioned on this list " " donate " "during Roktober and opt-in.

")); roktoberLabel->setOpenExternalLinks(true); donorLayout->addWidget(roktoberLabel); m_donorWidget.data()->setLayout( donorLayout ); tabWidget->addTab( m_donorWidget.data(), i18n("&Donors")); m_isOfflineDonorWidget = true; } //And the translators: QPalette transparentBackgroundPalette; transparentBackgroundPalette.setColor( QPalette::Base, Qt::transparent ); transparentBackgroundPalette.setColor( QPalette::Text, transparentBackgroundPalette.color( QPalette::WindowText ) ); const QList translatorList = aboutData->translators(); if(translatorList.count() > 0) { QString translatorPageText; QList::ConstIterator it; for(it = translatorList.begin(); it != translatorList.end(); ++it) { translatorPageText += QString("

%1

").arg((*it).name()); if (!(*it).emailAddress().isEmpty()) translatorPageText += QString("

%1

").arg((*it).emailAddress()); translatorPageText += "

 

"; } translatorPageText += KAboutData::aboutTranslationTeam(); KTextBrowser *translatorTextBrowser = new KTextBrowser; translatorTextBrowser->setFrameStyle(QFrame::NoFrame); translatorTextBrowser->setPalette(transparentBackgroundPalette); translatorTextBrowser->setHtml(translatorPageText); tabWidget->addTab(translatorTextBrowser, i18n("T&ranslation")); } //Jam everything together in a layout: mainLayout->addWidget(titleWidget); mainLayout->addWidget(tabWidget); mainLayout->setMargin(0); mainLayout->addWidget(buttonBox); resize( QSize( 480, 460 ) ); } ExtendedAboutDialog::~ExtendedAboutDialog() { delete d; } void ExtendedAboutDialog::switchToOcsWidgets() { if( !( Solid::Networking::status() == Solid::Networking::Connected || Solid::Networking::status() == Solid::Networking::Unknown ) ) { KMessageBox::error( this, i18n( "Internet connection not available" ), i18n( "Network error" ) ); return; } if( m_showOcsAuthorButton ) m_showOcsAuthorButton.data()->animate(); if( m_showOcsCreditButton ) m_showOcsCreditButton.data()->animate(); if( m_showOcsDonorButton ) m_showOcsDonorButton.data()->animate(); AmarokAttica::ProviderInitJob *providerJob = AmarokAttica::Provider::byId( m_ocsData.providerId() ); connect( providerJob, &AmarokAttica::ProviderInitJob::result, this, &ExtendedAboutDialog::onProviderFetched ); } void ExtendedAboutDialog::onProviderFetched( KJob *job ) { AmarokAttica::ProviderInitJob *providerJob = qobject_cast< AmarokAttica::ProviderInitJob * >( job ); if( providerJob->error() == 0 ) { debug()<<"Successfully fetched OCS provider"<< providerJob->provider().name(); debug()<<"About to request OCS data"; if( m_authorListWidget ) m_authorListWidget.data()->switchToOcs( providerJob->provider() ); if( m_creditListWidget ) m_creditListWidget.data()->switchToOcs( providerJob->provider() ); if( m_donorListWidget ) m_donorListWidget.data()->switchToOcs( providerJob->provider() ); } else warning() << "OCS provider fetch failed"; } void ExtendedAboutDialog::showLicense(const QString& number) { d->_k_showLicense(number); } diff --git a/src/dialogs/DiagnosticDialog.cpp b/src/dialogs/DiagnosticDialog.cpp index 5d3b59e632..7976d40679 100644 --- a/src/dialogs/DiagnosticDialog.cpp +++ b/src/dialogs/DiagnosticDialog.cpp @@ -1,140 +1,141 @@ /**************************************************************************************** * Copyright (c) 2012 Andrzej J. R. Hunt * * Copyright (c) Mark Kretschmann * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #include "DiagnosticDialog.h" #include "context/ContextView.h" #include "PluginManager.h" #include "scripting/scriptmanager/ScriptManager.h" #include +#include #include #include #include #include #include #include #include #include #include #include DiagnosticDialog::DiagnosticDialog( const KAboutData about, QWidget *parent ) : KDialog( parent ) { const KAboutData *aboutData = &about; m_textBox = new QPlainTextEdit( generateReport( aboutData ), this ); setPlainCaption( i18nc( "%1 is the program name", "%1 Diagnostics", KAboutData::applicationData().displayName() ) ); setButtons( Close | User1 ); setButtonText( User1, i18n( "Copy to Clipboard" ) ); m_textBox->setReadOnly( true ); setMainWidget( m_textBox ); setInitialSize( QSize( 480, 460 ) ); connect( this, &DiagnosticDialog::user1Clicked, this, &DiagnosticDialog::slotCopyToClipboard ); connect( this, &DiagnosticDialog::finished, this, &DiagnosticDialog::deleteLater ); } const QString DiagnosticDialog::generateReport( const KAboutData *aboutData ) { // Get scripts -- we have to assemble 3 lists into one KPluginInfo::List aScripts; const ScriptManager *aScriptManager = ScriptManager::instance(); aScripts.append( aScriptManager->scripts( QLatin1String( "Generic" ) ) ); aScripts.append( aScriptManager->scripts( QLatin1String( "Lyrics" ) ) ); aScripts.append( aScriptManager->scripts( QLatin1String( "Scriptable Service" ) ) ); // Format the data to be readable QString aScriptString; foreach( KPluginInfo aInfo, aScripts ) { if( aInfo.isPluginEnabled() ) aScriptString += " " + aInfo.name() + " (" + aInfo.version() + ")\n"; } // Get plugins -- we have to assemble a list again. KPluginInfo::List aPlugins; const Plugins::PluginManager *aPluginManager = Plugins::PluginManager::instance(); aPlugins.append( aPluginManager->plugins( Plugins::PluginManager::Collection ) ); aPlugins.append( aPluginManager->plugins( Plugins::PluginManager::Service ) ); aPlugins.append( aPluginManager->plugins( Plugins::PluginManager::Importer ) ); QString aPluginString; foreach( KPluginInfo aInfo, aPlugins ) { if( aInfo.isPluginEnabled() ) aPluginString += " " + aInfo.name() + " (" + aInfo.version() + ")\n"; } // Get applets QString appletString; /* FIXME: disabled temporarily for KF5 porting const QStringList appletList = Context::ContextView::self()->currentAppletNames(); foreach( const QString &applet, appletList ) { // Currently we cannot extract the applet version number this way appletString += " " + applet + '\n'; } */ const KService::Ptr aPhononBackend = KServiceTypeTrader::self()->preferredService( "PhononBackend" ); const bool hasPulse = Phonon::PulseSupport::getInstance()->isActive(); const QString pulse = hasPulse ? i18nc( "Usage", "Yes" ) : i18nc( "Usage", "No" ); return i18n( "%1 Diagnostics\n\nGeneral Information:\n" " %1 Version: %2\n" - " KDE Version: %3\n" + " KDE Frameworks Version: %3\n" " Qt Version: %4\n" " Phonon Version: %5\n" " Phonon Backend: %6 (%7)\n" " PulseAudio: %8\n\n", KAboutData::applicationData().displayName(), aboutData->version(), // Amarok - KDE::versionString(), // KDE - qVersion(), // QT + KCoreAddons::versionString(), // KDE Frameworks + qVersion(), // Qt Phonon::phononVersion(), // Phonon aPhononBackend.data()->name(), aPhononBackend.data()->property( "X-KDE-PhononBackendInfo-Version", QVariant::String ).toString(), // & Backend pulse // PulseAudio ) + i18n( "Enabled Scripts:\n%1\n" "Enabled Plugins:\n%2\n" "Enabled Applets:\n%3\n", aScriptString, aPluginString, appletString ); } void DiagnosticDialog::slotCopyToClipboard() const { QClipboard *clipboard = QApplication::clipboard(); clipboard->setText( m_textBox->toPlainText() ); }