• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

akonadi

selftestdialog.cpp

00001 /*
00002     Copyright (c) 2008 Volker Krause <vkrause@kde.org>
00003 
00004     This library is free software; you can redistribute it and/or modify it
00005     under the terms of the GNU Library General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or (at your
00007     option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful, but WITHOUT
00010     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00011     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00012     License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to the
00016     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017     02110-1301, USA.
00018 */
00019 
00020 #include "selftestdialog_p.h"
00021 #include "agentmanager.h"
00022 #include "session_p.h"
00023 #include "servermanager_p.h"
00024 
00025 #include <akonadi/private/xdgbasedirs_p.h>
00026 
00027 #include <KDebug>
00028 #include <KIcon>
00029 #include <KFileDialog>
00030 #include <KLocale>
00031 #include <KMessageBox>
00032 #include <KRun>
00033 #include <KStandardDirs>
00034 
00035 #include <QtCore/QFileInfo>
00036 #include <QtCore/QProcess>
00037 #include <QtCore/QSettings>
00038 #include <QtCore/QTextStream>
00039 #include <QtDBus/QtDBus>
00040 #include <QtGui/QApplication>
00041 #include <QtGui/QClipboard>
00042 #include <QtGui/QStandardItemModel>
00043 #include <QtSql/QSqlDatabase>
00044 
00045 // @cond PRIVATE
00046 
00047 #define AKONADI_CONTROL_SERVICE QLatin1String("org.freedesktop.Akonadi.Control")
00048 #define AKONADI_SERVER_SERVICE QLatin1String("org.freedesktop.Akonadi")
00049 
00050 using namespace Akonadi;
00051 
00052 static QString makeLink( const QString &file )
00053 {
00054   return QString::fromLatin1( "<a href=\"%1\">%2</a>" ).arg( file, file );
00055 }
00056 
00057 enum SelfTestRole {
00058   ResultTypeRole = Qt::UserRole,
00059   FileIncludeRole,
00060   ListDirectoryRole,
00061   EnvVarRole,
00062   SummaryRole,
00063   DetailsRole
00064 };
00065 
00066 SelfTestDialog::SelfTestDialog(QWidget * parent) :
00067     KDialog( parent )
00068 {
00069   setCaption( i18n( "Akonadi Server Self-Test" ) );
00070   setButtons( Close | User1 | User2 );
00071   setButtonText( User1, i18n( "Save Report..." ) );
00072   setButtonIcon( User1, KIcon( QString::fromLatin1("document-save") ) );
00073   setButtonText( User2, i18n( "Copy Report to Clipboard" ) );
00074   setButtonIcon( User2, KIcon( QString::fromLatin1("edit-copy") ) );
00075   showButtonSeparator( true );
00076   ui.setupUi( mainWidget() );
00077 
00078   mTestModel = new QStandardItemModel( this );
00079   ui.testView->setModel( mTestModel );
00080   connect( ui.testView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
00081            SLOT(selectionChanged(QModelIndex)) );
00082   connect( ui.detailsLabel, SIGNAL(linkActivated(QString)), SLOT(linkActivated(QString)) );
00083 
00084   connect( this, SIGNAL(user1Clicked()), SLOT(saveReport()) );
00085   connect( this, SIGNAL(user2Clicked()), SLOT(copyReport()) );
00086 
00087   runTests();
00088 }
00089 
00090 void SelfTestDialog::hideIntroduction()
00091 {
00092   ui.introductionLabel->hide();
00093 }
00094 
00095 QStandardItem* SelfTestDialog::report( ResultType type, const KLocalizedString & summary, const KLocalizedString & details)
00096 {
00097   QStandardItem *item = new QStandardItem( summary.toString() );
00098   switch ( type ) {
00099     case Skip:
00100       item->setIcon( KIcon( QString::fromLatin1("dialog-ok") ) );
00101       break;
00102     case Success:
00103       item->setIcon( KIcon( QString::fromLatin1("dialog-ok-apply") ) );
00104       break;
00105     case Warning:
00106       item->setIcon( KIcon( QString::fromLatin1("dialog-warning") ) );
00107       break;
00108     case Error:
00109     default:
00110       item->setIcon( KIcon( QString::fromLatin1("dialog-error") ) );
00111   }
00112   item->setEditable( false );
00113   item->setWhatsThis( details.toString() );
00114   item->setData( type, ResultTypeRole );
00115   item->setData( summary.toString( 0 ), SummaryRole );
00116   item->setData( details.toString( 0 ), DetailsRole );
00117   mTestModel->appendRow( item );
00118   return item;
00119 }
00120 
00121 void SelfTestDialog::selectionChanged(const QModelIndex &index )
00122 {
00123   if ( index.isValid() ) {
00124     ui.detailsLabel->setText( index.data( Qt::WhatsThisRole ).toString() );
00125     ui.detailsGroup->setEnabled( true );
00126   } else {
00127     ui.detailsLabel->setText( QString() );
00128     ui.detailsGroup->setEnabled( false );
00129   }
00130 }
00131 
00132 void SelfTestDialog::runTests()
00133 {
00134   testSQLDriver();
00135   testMySQLServer();
00136   testMySQLServerLog();
00137   testMySQLServerConfig();
00138   testAkonadiCtl();
00139   testServerStatus();
00140   testProtocolVersion();
00141   testResources();
00142   testServerLog();
00143   testControlLog();
00144 }
00145 
00146 QVariant SelfTestDialog::serverSetting(const QString & group, const char *key, const QVariant &def ) const
00147 {
00148   const QString serverConfigFile = XdgBaseDirs::akonadiServerConfigFile( XdgBaseDirs::ReadWrite );
00149   QSettings settings( serverConfigFile, QSettings::IniFormat );
00150   settings.beginGroup( group );
00151   return settings.value( QString::fromLatin1(key), def );
00152 }
00153 
00154 bool SelfTestDialog::useStandaloneMysqlServer() const
00155 {
00156   const QString driver = serverSetting( QLatin1String("General"), "Driver", QLatin1String("QMYSQL") ).toString();
00157   if ( driver != QLatin1String( "QMYSQL" ) )
00158     return false;
00159   const bool startServer = serverSetting( driver, "StartServer", true ).toBool();
00160   if ( !startServer )
00161     return false;
00162   return true;
00163 }
00164 
00165 bool SelfTestDialog::runProcess(const QString & app, const QStringList & args, QString & result) const
00166 {
00167   QProcess proc;
00168   proc.start( app, args );
00169   const bool rv = proc.waitForFinished();
00170   result.clear();
00171   result += QString::fromLocal8Bit( proc.readAllStandardError() );
00172   result += QString::fromLocal8Bit( proc.readAllStandardOutput() );
00173   return rv;
00174 }
00175 
00176 void SelfTestDialog::testSQLDriver()
00177 {
00178   const QString driver = serverSetting( QLatin1String("General"), "Driver", QLatin1String("QMYSQL") ).toString();
00179   const QStringList availableDrivers = QSqlDatabase::drivers();
00180   const KLocalizedString details = ki18n( "The QtSQL driver '%1' is required by your current Akonadi server configuration.\n"
00181       "The following drivers are installed: %2.\n"
00182       "Make sure the required driver is installed." )
00183       .subs( driver )
00184       .subs( availableDrivers.join( QLatin1String(", ") ) );
00185   QStandardItem *item = 0;
00186   if ( availableDrivers.contains( driver ) )
00187     item = report( Success, ki18n( "Database driver found." ), details );
00188   else
00189     item = report( Error, ki18n( "Database driver not found." ), details );
00190   item->setData( XdgBaseDirs::akonadiServerConfigFile( XdgBaseDirs::ReadWrite ), FileIncludeRole );
00191 }
00192 
00193 void SelfTestDialog::testMySQLServer()
00194 {
00195   if ( !useStandaloneMysqlServer() ) {
00196     report( Skip, ki18n( "MySQL server executable not tested." ),
00197             ki18n( "The current configuration does not require an internal MySQL server." ) );
00198     return;
00199   }
00200 
00201   const QString driver = serverSetting( QLatin1String("General"), "Driver", QLatin1String("QMYSQL") ).toString();
00202   const QString serverPath = serverSetting( driver,  "ServerPath", QLatin1String("") ).toString(); // ### default?
00203 
00204   const KLocalizedString details = ki18n( "You currently have configured Akonadi to use the MySQL server '%1'.\n"
00205       "Make sure you have the MySQL server installed, set the correct path and ensure you have the "
00206       "necessary read and execution rights on the server executable. The server executable is typically "
00207       "called 'mysqld', its locations varies depending on the distribution." ).subs( serverPath );
00208 
00209   QFileInfo info( serverPath );
00210   if ( !info.exists() )
00211     report( Error, ki18n( "MySQL server not found." ), details );
00212   else if ( !info.isReadable() )
00213     report( Error, ki18n( "MySQL server not readable." ), details );
00214   else if ( !info.isExecutable() )
00215     report( Error, ki18n( "MySQL server not executable." ), details );
00216   else if ( !serverPath.contains( QLatin1String("mysqld") ) )
00217     report( Warning, ki18n( "MySQL found with unexpected name." ), details );
00218   else
00219     report( Success, ki18n( "MySQL server found." ), details );
00220 
00221   // be extra sure and get the server version while we are at it
00222   QString result;
00223   if ( runProcess( serverPath, QStringList() << QLatin1String( "--version" ), result ) ) {
00224     const KLocalizedString details = ki18n( "MySQL server found: %1" ).subs( result );
00225     report( Success, ki18n( "MySQL server is executable." ), details );
00226   } else {
00227     const KLocalizedString details = ki18n( "Executing the MySQL server '%1' failed with the following error message: '%2'" )
00228         .subs( serverPath ).subs( result );
00229     report( Error, ki18n( "Executing the MySQL server failed." ), details );
00230   }
00231 }
00232 
00233 void SelfTestDialog::testMySQLServerLog()
00234 {
00235   if ( !useStandaloneMysqlServer() ) {
00236     report( Skip, ki18n( "MySQL server error log not tested." ),
00237             ki18n( "The current configuration does not require an internal MySQL server." ) );
00238     return;
00239   }
00240 
00241   const QString logFileName = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi/db_data" ) )
00242       + QDir::separator() + QString::fromLatin1( "mysql.err" );
00243   const QFileInfo logFileInfo( logFileName );
00244   if ( !logFileInfo.exists() || logFileInfo.size() == 0 ) {
00245     report( Success, ki18n( "No current MySQL error log found." ),
00246       ki18n( "The MySQL server did not report any errors during this startup into '%1'." ).subs( logFileName ) );
00247     return;
00248   }
00249   QFile logFile( logFileName );
00250   if ( !logFile.open( QFile::ReadOnly | QFile::Text  ) ) {
00251     report( Error, ki18n( "MySQL error log not readable." ),
00252       ki18n( "A MySQL server error log file was found but is not readable: %1" ).subs( makeLink( logFileName ) ) );
00253     return;
00254   }
00255   bool warningsFound = false;
00256   QStandardItem *item = 0;
00257   while ( !logFile.atEnd() ) {
00258     const QString line = QString::fromUtf8( logFile.readLine() );
00259     if ( line.contains( QLatin1String( "error" ), Qt::CaseInsensitive ) ) {
00260       item = report( Error, ki18n( "MySQL server log contains errors." ),
00261         ki18n( "The MySQL server error log file '%1' contains errors." ).subs( makeLink( logFileName ) ) );
00262       item->setData( logFileName, FileIncludeRole );
00263       return;
00264     }
00265     if ( !warningsFound && line.contains( QLatin1String( "warn" ), Qt::CaseInsensitive ) ) {
00266       warningsFound = true;
00267     }
00268   }
00269   if ( warningsFound ) {
00270     item = report( Warning, ki18n( "MySQL server log contains warnings." ),
00271                    ki18n( "The MySQL server log file '%1' contains warnings." ).subs( makeLink( logFileName ) ) );
00272   } else {
00273     item = report( Success, ki18n( "MySQL server log contains no errors." ),
00274                    ki18n( "The MySQL server log file '%1' does not contain any errors or warnings." )
00275                          .subs( makeLink( logFileName ) ) );
00276   }
00277   item->setData( logFileName, FileIncludeRole );
00278 
00279   logFile.close();
00280 }
00281 
00282 void SelfTestDialog::testMySQLServerConfig()
00283 {
00284   if ( !useStandaloneMysqlServer() ) {
00285     report( Skip, ki18n( "MySQL server configuration not tested." ),
00286             ki18n( "The current configuration does not require an internal MySQL server." ) );
00287     return;
00288   }
00289 
00290   QStandardItem *item = 0;
00291   const QString globalConfig = XdgBaseDirs::findResourceFile( "config", QLatin1String( "akonadi/mysql-global.conf" ) );
00292   const QFileInfo globalConfigInfo( globalConfig );
00293   if ( !globalConfig.isEmpty() && globalConfigInfo.exists() && globalConfigInfo.isReadable() ) {
00294     item = report( Success, ki18n( "MySQL server default configuration found." ),
00295                    ki18n( "The default configuration for the MySQL server was found and is readable at %1." )
00296                    .subs( makeLink( globalConfig ) ) );
00297     item->setData( globalConfig, FileIncludeRole );
00298   } else {
00299     report( Error, ki18n( "MySQL server default configuration not found." ),
00300             ki18n( "The default configuration for the MySQL server was not found or was not readable. "
00301                   "Check your Akonadi installation is complete and you have all required access rights." ) );
00302   }
00303 
00304   const QString localConfig  = XdgBaseDirs::findResourceFile( "config", QLatin1String( "akonadi/mysql-local.conf" ) );
00305   const QFileInfo localConfigInfo( localConfig );
00306   if ( localConfig.isEmpty() || !localConfigInfo.exists() ) {
00307     report( Skip, ki18n( "MySQL server custom configuration not available." ),
00308             ki18n( "The custom configuration for the MySQL server was not found but is optional." ) );
00309   } else if ( localConfigInfo.exists() && localConfigInfo.isReadable() ) {
00310     item = report( Success, ki18n( "MySQL server custom configuration found." ),
00311                    ki18n( "The custom configuration for the MySQL server was found and is readable at %1" )
00312                    .subs( makeLink( localConfig ) ) );
00313     item->setData( localConfig, FileIncludeRole );
00314   } else {
00315     report( Error, ki18n( "MySQL server custom configuration not readable." ),
00316             ki18n( "The custom configuration for the MySQL server was found at %1 but is not readable. "
00317                   "Check your access rights." ).subs( makeLink( localConfig ) ) );
00318   }
00319 
00320   const QString actualConfig = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi" ) ) + QLatin1String("/mysql.conf");
00321   const QFileInfo actualConfigInfo( actualConfig );
00322   if ( actualConfig.isEmpty() || !actualConfigInfo.exists() || !actualConfigInfo.isReadable() ) {
00323     report( Error, ki18n( "MySQL server configuration not found or not readable." ),
00324             ki18n( "The MySQL server configuration was not found or is not readable." ) );
00325   } else {
00326     item = report( Success, ki18n( "MySQL server configuration is usable." ),
00327                    ki18n( "The MySQL server configuration was found at %1 and is readable.").subs( makeLink( actualConfig ) ) );
00328     item->setData( actualConfig, FileIncludeRole );
00329   }
00330 }
00331 
00332 void SelfTestDialog::testAkonadiCtl()
00333 {
00334   const QString path = KStandardDirs::findExe( QLatin1String("akonadictl") );
00335   if ( path.isEmpty() ) {
00336     report( Error, ki18n( "akonadictl not found" ),
00337                  ki18n( "The program 'akonadictl' needs to be accessible in $PATH. "
00338                        "Make sure you have the Akonadi server installed." ) );
00339     return;
00340   }
00341   QString result;
00342   if ( runProcess( path, QStringList() << QLatin1String( "--version" ), result ) ) {
00343     report( Success, ki18n( "akonadictl found and usable" ),
00344                    ki18n( "The program '%1' to control the Akonadi server was found "
00345                          "and could be executed successfully.\nResult:\n%2" ).subs( path ).subs( result ) );
00346   } else {
00347     report( Error, ki18n( "akonadictl found but not usable" ),
00348                  ki18n( "The program '%1' to control the Akonadi server was found "
00349                        "but could not be executed successfully.\nResult:\n%2\n"
00350                        "Make sure the Akonadi server is installed correctly." ).subs( path ).subs( result ) );
00351   }
00352 }
00353 
00354 void SelfTestDialog::testServerStatus()
00355 {
00356   if ( QDBusConnection::sessionBus().interface()->isServiceRegistered( AKONADI_CONTROL_SERVICE ) ) {
00357     report( Success, ki18n( "Akonadi control process registered at D-Bus." ),
00358                    ki18n( "The Akonadi control process is registered at D-Bus which typically indicates it is operational." ) );
00359   } else {
00360     report( Error, ki18n( "Akonadi control process not registered at D-Bus." ),
00361                  ki18n( "The Akonadi control process is not registered at D-Bus which typically means it was not started "
00362                        "or encountered a fatal error during startup."  ) );
00363   }
00364 
00365   if ( QDBusConnection::sessionBus().interface()->isServiceRegistered( AKONADI_SERVER_SERVICE ) ) {
00366     report( Success, ki18n( "Akonadi server process registered at D-Bus." ),
00367                    ki18n( "The Akonadi server process is registered at D-Bus which typically indicates it is operational." ) );
00368   } else {
00369     report( Error, ki18n( "Akonadi server process not registered at D-Bus." ),
00370                  ki18n( "The Akonadi server process is not registered at D-Bus which typically means it was not started "
00371                        "or encountered a fatal error during startup."  ) );
00372   }
00373 }
00374 
00375 void SelfTestDialog::testProtocolVersion()
00376 {
00377   if ( Internal::serverProtocolVersion() < 0 ) {
00378     report( Skip, ki18n( "Protocol version check not possible." ),
00379             ki18n( "Without a connection to the server it is not possible to check if the protocol version meets the requirements." ) );
00380     return;
00381   }
00382   if ( Internal::serverProtocolVersion() < SessionPrivate::minimumProtocolVersion() ) {
00383     report( Error, ki18n( "Server protocol version is too old." ),
00384             ki18n( "The server protocol version is %1, but at least version %2 is required. "
00385                   "Install a newer version of the Akonadi server." )
00386                   .subs( Internal::serverProtocolVersion() )
00387                   .subs( SessionPrivate::minimumProtocolVersion() ) );
00388   } else {
00389     report( Success, ki18n( "Server protocol version is recent enough." ),
00390             ki18n( "The server Protocol version is %1, which equal or newer than the required version %2." )
00391                 .subs( Internal::serverProtocolVersion() )
00392                 .subs( SessionPrivate::minimumProtocolVersion() ) );
00393   }
00394 }
00395 
00396 void SelfTestDialog::testResources()
00397 {
00398   AgentType::List agentTypes = AgentManager::self()->types();
00399   bool resourceFound = false;
00400   foreach ( const AgentType &type, agentTypes ) {
00401     if ( type.capabilities().contains( QLatin1String("Resource") ) ) {
00402       resourceFound = true;
00403       break;
00404     }
00405   }
00406 
00407   const QStringList pathList = XdgBaseDirs::findAllResourceDirs( "data", QLatin1String( "akonadi/agents" ) );
00408   QStandardItem *item = 0;
00409   if ( resourceFound ) {
00410     item = report( Success, ki18n( "Resource agents found." ), ki18n( "At least one resource agent has been found." ) );
00411   } else {
00412     item = report( Error, ki18n( "No resource agents found." ),
00413       ki18n( "No resource agents have been found, Akonadi is not usable without at least one. "
00414             "This usually means that no resource agents are installed or that there is a setup problem. "
00415             "The following paths have been searched: '%1'. "
00416             "The XDG_DATA_DIRS environment variable is set to '%2', make sure this includes all paths "
00417             "where Akonadi agents are installed to." )
00418           .subs( pathList.join( QLatin1String(" ") ) )
00419           .subs( QString::fromLocal8Bit( qgetenv( "XDG_DATA_DIRS" ) ) ) );
00420   }
00421   item->setData( pathList, ListDirectoryRole );
00422   item->setData( QByteArray( "XDG_DATA_DIRS" ), EnvVarRole );
00423 }
00424 
00425 void Akonadi::SelfTestDialog::testServerLog()
00426 {
00427   QString serverLog = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi" ) )
00428       + QDir::separator() + QString::fromLatin1( "akonadiserver.error" );
00429   QFileInfo info( serverLog );
00430   if ( !info.exists() || info.size() <= 0 ) {
00431     report( Success, ki18n( "No current Akonadi server error log found." ),
00432                    ki18n( "The Akonadi server did not report any errors during its current startup." ) );
00433   } else {
00434     QStandardItem *item = report( Error, ki18n( "Current Akonadi server error log found." ),
00435       ki18n( "The Akonadi server did report error during startup into %1." ).subs( makeLink( serverLog ) ) );
00436     item->setData( serverLog, FileIncludeRole );
00437   }
00438 
00439   serverLog += QLatin1String(".old");
00440   info.setFile( serverLog );
00441   if ( !info.exists() || info.size() <= 0 ) {
00442     report( Success, ki18n( "No previous Akonadi server error log found." ),
00443                    ki18n( "The Akonadi server did not report any errors during its previous startup." ) );
00444   } else {
00445     QStandardItem *item = report( Error, ki18n( "Previous Akonadi server error log found." ),
00446       ki18n( "The Akonadi server did report error during its previous startup into %1." ).subs( makeLink( serverLog ) ) );
00447     item->setData( serverLog, FileIncludeRole );
00448   }
00449 }
00450 
00451 void SelfTestDialog::testControlLog()
00452 {
00453   QString controlLog = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi" ) )
00454       + QDir::separator() + QString::fromLatin1( "akonadi_control.error" );
00455   QFileInfo info( controlLog );
00456   if ( !info.exists() || info.size() <= 0 ) {
00457     report( Success, ki18n( "No current Akonadi control error log found." ),
00458                    ki18n( "The Akonadi control process did not report any errors during its current startup." ) );
00459   } else {
00460     QStandardItem *item = report( Error, ki18n( "Current Akonadi control error log found." ),
00461       ki18n( "The Akonadi control process did report error during startup into %1." ).subs( makeLink( controlLog ) ) );
00462     item->setData( controlLog, FileIncludeRole );
00463   }
00464 
00465   controlLog += QLatin1String(".old");
00466   info.setFile( controlLog );
00467   if ( !info.exists() || info.size() <= 0 ) {
00468     report( Success, ki18n( "No previous Akonadi control error log found." ),
00469                    ki18n( "The Akonadi control process did not report any errors during its previous startup." ) );
00470   } else {
00471     QStandardItem *item = report( Error, ki18n( "Previous Akonadi control error log found." ),
00472       ki18n( "The Akonadi control process did report error during its previous startup into %1." ).subs( makeLink( controlLog ) ) );
00473     item->setData( controlLog, FileIncludeRole );
00474   }
00475 }
00476 
00477 
00478 QString SelfTestDialog::createReport()
00479 {
00480   QString result;
00481   QTextStream s( &result );
00482   s << "Akonadi Server Self-Test Report" << endl;
00483   s << "===============================" << endl;
00484 
00485   for ( int i = 0; i < mTestModel->rowCount(); ++i ) {
00486     QStandardItem *item = mTestModel->item( i );
00487     s << endl;
00488     s << "Test " << (i + 1) << ":  ";
00489     switch ( item->data( ResultTypeRole ).toInt() ) {
00490       case Skip:
00491         s << "SKIP"; break;
00492       case Success:
00493         s << "SUCCESS"; break;
00494       case Warning:
00495         s << "WARNING"; break;
00496       case Error:
00497       default:
00498         s << "ERROR"; break;
00499     }
00500     s << endl << "--------" << endl;
00501     s << endl;
00502     s << item->data( SummaryRole ).toString() << endl;
00503     s << "Details: " << item->data( DetailsRole ).toString() << endl;
00504     if ( item->data( FileIncludeRole ).isValid() ) {
00505       s << endl;
00506       const QString fileName = item->data( FileIncludeRole ).toString();
00507       QFile f( fileName );
00508       if ( f.open( QFile::ReadOnly ) ) {
00509         s << "File content of '" << fileName << "':" << endl;
00510         s << f.readAll() << endl;
00511       } else {
00512         s << "File '" << fileName << "' could not be opened" << endl;
00513       }
00514     }
00515     if ( item->data( ListDirectoryRole ).isValid() ) {
00516       s << endl;
00517       const QStringList pathList = item->data( ListDirectoryRole ).toStringList();
00518       if ( pathList.isEmpty() )
00519         s << "Directory list is empty." << endl;
00520       foreach ( const QString &path, pathList ) {
00521         s << "Directory listing of '" << path << "':" << endl;
00522         QDir dir( path );
00523         dir.setFilter( QDir::AllEntries | QDir::NoDotAndDotDot );
00524         foreach ( const QString &entry, dir.entryList() )
00525           s << entry << endl;
00526       }
00527     }
00528     if ( item->data( EnvVarRole ).isValid() ) {
00529       s << endl;
00530       const QByteArray envVarName = item->data( EnvVarRole ).toByteArray();
00531       const QByteArray envVarValue = qgetenv( envVarName );
00532       s << "Environment variable " << envVarName << " is set to '" << envVarValue << "'" << endl;
00533     }
00534   }
00535 
00536   s << endl;
00537   s.flush();
00538   return result;
00539 }
00540 
00541 void SelfTestDialog::saveReport()
00542 {
00543   const QString fileName =  KFileDialog::getSaveFileName( KUrl(), QString(), this, i18n("Save Test Report") );
00544   if ( fileName.isEmpty() )
00545     return;
00546 
00547   QFile file( fileName );
00548   if ( !file.open( QFile::ReadWrite ) ) {
00549     KMessageBox::error( this, i18n( "Could not open file '%1'", fileName ) );
00550     return;
00551   }
00552 
00553   file.write( createReport().toUtf8() );
00554   file.close();
00555 }
00556 
00557 void SelfTestDialog::copyReport()
00558 {
00559   QApplication::clipboard()->setText( createReport() );
00560 }
00561 
00562 void SelfTestDialog::linkActivated(const QString & link)
00563 {
00564   KRun::runUrl( KUrl::fromPath( link ), QLatin1String("text/plain"), this );
00565 }
00566 
00567 // @endcond
00568 
00569 #include "selftestdialog_p.moc"

akonadi

Skip menu "akonadi"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  • kldap
  • kmime
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal