• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KIO

global.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002    Copyright (C) 2000 David Faure <faure@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License version 2 as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    along with this library; see the file COPYING.LIB.  If not, write to
00015    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016    Boston, MA 02110-1301, USA.
00017 */
00018 
00019 #include "global.h"
00020 #include "job.h"
00021 #include "thumbcreator.h"   // needed to create a reference to ThumbCreator class in the export lib
00022                             // other solution: don't use KIO_EXPORT there...
00023 
00024 #include <config.h>
00025 
00026 #include <kdebug.h>
00027 #include <klocale.h>
00028 #include <kglobal.h>
00029 #include <kiconloader.h>
00030 #include <kprotocolmanager.h>
00031 #include <kde_file.h>
00032 #include <kmimetype.h>
00033 #include <kwidgetjobtracker.h>
00034 
00035 #include <QtCore/QByteArray>
00036 #include <QtCore/QDate>
00037 #include <QtGui/QTextDocument>
00038 
00039 #include <sys/types.h>
00040 #include <sys/wait.h>
00041 #include <sys/uio.h>
00042 
00043 #include <assert.h>
00044 #include <signal.h>
00045 #include <stdlib.h>
00046 #include <string.h>
00047 #include <unistd.h>
00048 #include <stdio.h>
00049 
00050 K_GLOBAL_STATIC(KWidgetJobTracker, globalJobTracker)
00051 
00052 // If someone wants the SI-standard prefixes kB/MB/GB/TB, I would recommend
00053 // a hidden kconfig option and getting the code from #57240 into the same
00054 // method, so that all KDE apps use the same unit, instead of letting each app decide.
00055 
00056 KIO_EXPORT QString KIO::convertSize( KIO::filesize_t size )
00057 {
00058     return KGlobal::locale()->formatByteSize(size);
00059 }
00060 
00061 KIO_EXPORT QString KIO::convertSizeFromKiB( KIO::filesize_t kibSize )
00062 {
00063     return KGlobal::locale()->formatByteSize(kibSize * 1024);
00064 }
00065 
00066 KIO_EXPORT QString KIO::number( KIO::filesize_t size )
00067 {
00068     char charbuf[256];
00069     sprintf(charbuf, "%lld", size);
00070     return QLatin1String(charbuf);
00071 }
00072 
00073 KIO_EXPORT unsigned int KIO::calculateRemainingSeconds( KIO::filesize_t totalSize,
00074                                                         KIO::filesize_t processedSize, KIO::filesize_t speed )
00075 {
00076   if ( (speed != 0) && (totalSize != 0) )
00077     return ( totalSize - processedSize ) / speed;
00078   else
00079     return 0;
00080 }
00081 
00082 KIO_EXPORT QString KIO::convertSeconds( unsigned int seconds )
00083 {
00084   unsigned int days  = seconds / 86400;
00085   unsigned int hours = (seconds - (days * 86400)) / 3600;
00086   unsigned int mins  = (seconds - (days * 86400) - (hours * 3600)) / 60;
00087   seconds            = (seconds - (days * 86400) - (hours * 3600) - (mins * 60));
00088 
00089   const QTime time(hours, mins, seconds);
00090   const QString timeStr( KGlobal::locale()->formatTime(time, true /*with seconds*/, true /*duration*/) );
00091   if ( days > 0 )
00092     return i18np("1 day %2", "%1 days %2", days, timeStr);
00093   else
00094     return timeStr;
00095 }
00096 
00097 KIO_EXPORT QTime KIO::calculateRemaining( KIO::filesize_t totalSize, KIO::filesize_t processedSize, KIO::filesize_t speed )
00098 {
00099   QTime remainingTime;
00100 
00101   if ( speed != 0 ) {
00102     KIO::filesize_t secs;
00103     if ( totalSize == 0 ) {
00104       secs = 0;
00105     } else {
00106       secs = ( totalSize - processedSize ) / speed;
00107     }
00108     if (secs >= (24*60*60)) // Limit to 23:59:59
00109        secs = (24*60*60)-1;
00110     int hr = secs / ( 60 * 60 );
00111     int mn = ( secs - hr * 60 * 60 ) / 60;
00112     int sc = ( secs - hr * 60 * 60 - mn * 60 );
00113 
00114     remainingTime.setHMS( hr, mn, sc );
00115   }
00116 
00117   return remainingTime;
00118 }
00119 
00120 KIO_EXPORT QString KIO::itemsSummaryString(uint items, uint files, uint dirs, KIO::filesize_t size, bool showSize)
00121 {
00122     const QString itemsText = items == 0 ? i18n( "No Items" ) : i18np( "One Item", "%1 Items", items );
00123     const QString filesText = files == 0 ? i18n( "No Files" ) : i18np( "One File", "%1 Files", files );
00124     const QString foldersText = dirs == 0 ? i18n( "No Folders" ) : i18np("One Folder", "%1 Folders", dirs);
00125     if ( showSize && files > 0 ) {
00126         const QString sizeText = i18n("(%1 Total)", KIO::convertSize( size ) );
00127         return i18nc("Items (Folders, Files), Size", "%1 (%2, %3), %4", itemsText, foldersText, filesText, sizeText);
00128     }
00129     return i18nc("Items (Folders, Files)", "%1 (%2, %3)", itemsText, foldersText, filesText);
00130 }
00131 
00132 KIO_EXPORT QString KIO::encodeFileName( const QString & _str )
00133 {
00134     QString str( _str );
00135 
00136     int i = 0;
00137     while ( ( i = str.indexOf( '%', i ) ) != -1 ) {
00138         str.replace( i, 1, "%%");
00139         i += 2;
00140     }
00141     while ( ( i = str.indexOf( '/' ) ) != -1 )
00142         str.replace( i, 1, "%2f");
00143     return str;
00144 }
00145 
00146 KIO_EXPORT QString KIO::decodeFileName( const QString & _str )
00147 {
00148     const int len = _str.length();
00149     QString text;
00150     text.reserve(len);
00151     for ( int i = 0; i < len ; ++i ) {
00152         if ( _str[i] == '%' && i+1 < len ) {
00153             const QChar nextChar = _str[i+1];
00154             if ( nextChar == '%' ) { // %% -> %
00155                 text.append(QLatin1Char('%'));
00156                 ++i;
00157             } else if ( nextChar == '2' && (i+2<len) && _str[i+2].toLower()=='f' ) { // %2f -> /
00158                 text.append(QLatin1Char('/'));
00159                 i += 2;
00160             } else {
00161                 text.append(QLatin1Char('%'));
00162             }
00163         } else {
00164             text.append(_str[i]);
00165         }
00166     }
00167     text.squeeze();
00168 
00169     return text;
00170 }
00171 
00172 KIO_EXPORT QString KIO::Job::errorString() const
00173 {
00174   return KIO::buildErrorString(error(), errorText());
00175 }
00176 
00177 KIO_EXPORT QString KIO::buildErrorString(int errorCode, const QString &errorText)
00178 {
00179   QString result;
00180 
00181   switch( errorCode )
00182     {
00183     case  KIO::ERR_CANNOT_OPEN_FOR_READING:
00184       result = i18n( "Could not read %1." ,  errorText );
00185       break;
00186     case  KIO::ERR_CANNOT_OPEN_FOR_WRITING:
00187       result = i18n( "Could not write to %1." ,  errorText );
00188       break;
00189     case  KIO::ERR_CANNOT_LAUNCH_PROCESS:
00190       result = i18n( "Could not start process %1." ,  errorText );
00191       break;
00192     case  KIO::ERR_INTERNAL:
00193       result = i18n( "Internal Error\nPlease send a full bug report at http://bugs.kde.org\n%1" ,  errorText );
00194       break;
00195     case  KIO::ERR_MALFORMED_URL:
00196       result = i18n( "Malformed URL %1." ,  errorText );
00197       break;
00198     case  KIO::ERR_UNSUPPORTED_PROTOCOL:
00199       result = i18n( "The protocol %1 is not supported." ,  errorText );
00200       break;
00201     case  KIO::ERR_NO_SOURCE_PROTOCOL:
00202       result = i18n( "The protocol %1 is only a filter protocol.",  errorText );
00203       break;
00204     case  KIO::ERR_UNSUPPORTED_ACTION:
00205       result = errorText;
00206 //       result = i18n( "Unsupported action %1" ).arg( errorText );
00207       break;
00208     case  KIO::ERR_IS_DIRECTORY:
00209       result = i18n( "%1 is a folder, but a file was expected." ,  errorText );
00210       break;
00211     case  KIO::ERR_IS_FILE:
00212       result = i18n( "%1 is a file, but a folder was expected." ,  errorText );
00213       break;
00214     case  KIO::ERR_DOES_NOT_EXIST:
00215       result = i18n( "The file or folder %1 does not exist." ,  errorText );
00216       break;
00217     case  KIO::ERR_FILE_ALREADY_EXIST:
00218       result = i18n( "A file named %1 already exists." ,  errorText );
00219       break;
00220     case  KIO::ERR_DIR_ALREADY_EXIST:
00221       result = i18n( "A folder named %1 already exists." ,  errorText );
00222       break;
00223     case  KIO::ERR_UNKNOWN_HOST:
00224       result = errorText.isEmpty() ? i18n( "No hostname specified." ) : i18n( "Unknown host %1" ,  errorText );
00225       break;
00226     case  KIO::ERR_ACCESS_DENIED:
00227       result = i18n( "Access denied to %1." ,  errorText );
00228       break;
00229     case  KIO::ERR_WRITE_ACCESS_DENIED:
00230       result = i18n( "Access denied.\nCould not write to %1." ,  errorText );
00231       break;
00232     case  KIO::ERR_CANNOT_ENTER_DIRECTORY:
00233       result = i18n( "Could not enter folder %1." ,  errorText );
00234       break;
00235     case  KIO::ERR_PROTOCOL_IS_NOT_A_FILESYSTEM:
00236       result = i18n( "The protocol %1 does not implement a folder service." ,  errorText );
00237       break;
00238     case  KIO::ERR_CYCLIC_LINK:
00239       result = i18n( "Found a cyclic link in %1." ,  errorText );
00240       break;
00241     case  KIO::ERR_USER_CANCELED:
00242       // Do nothing in this case. The user doesn't need to be told what he just did.
00243       break;
00244     case  KIO::ERR_CYCLIC_COPY:
00245       result = i18n( "Found a cyclic link while copying %1." ,  errorText );
00246       break;
00247     case  KIO::ERR_COULD_NOT_CREATE_SOCKET:
00248       result = i18n( "Could not create socket for accessing %1." ,  errorText );
00249       break;
00250     case  KIO::ERR_COULD_NOT_CONNECT:
00251       result = i18n( "Could not connect to host %1." ,  errorText.isEmpty() ? QLatin1String("localhost") : errorText );
00252       break;
00253     case  KIO::ERR_CONNECTION_BROKEN:
00254       result = i18n( "Connection to host %1 is broken." ,  errorText );
00255       break;
00256     case  KIO::ERR_NOT_FILTER_PROTOCOL:
00257       result = i18n( "The protocol %1 is not a filter protocol." ,  errorText );
00258       break;
00259     case  KIO::ERR_COULD_NOT_MOUNT:
00260       result = i18n( "Could not mount device.\nThe reported error was:\n%1" ,  errorText );
00261       break;
00262     case  KIO::ERR_COULD_NOT_UNMOUNT:
00263       result = i18n( "Could not unmount device.\nThe reported error was:\n%1" ,  errorText );
00264       break;
00265     case  KIO::ERR_COULD_NOT_READ:
00266       result = i18n( "Could not read file %1." ,  errorText );
00267       break;
00268     case  KIO::ERR_COULD_NOT_WRITE:
00269       result = i18n( "Could not write to file %1." ,  errorText );
00270       break;
00271     case  KIO::ERR_COULD_NOT_BIND:
00272       result = i18n( "Could not bind %1." ,  errorText );
00273       break;
00274     case  KIO::ERR_COULD_NOT_LISTEN:
00275       result = i18n( "Could not listen %1." ,  errorText );
00276       break;
00277     case  KIO::ERR_COULD_NOT_ACCEPT:
00278       result = i18n( "Could not accept %1." ,  errorText );
00279       break;
00280     case  KIO::ERR_COULD_NOT_LOGIN:
00281       result = errorText;
00282       break;
00283     case  KIO::ERR_COULD_NOT_STAT:
00284       result = i18n( "Could not access %1." ,  errorText );
00285       break;
00286     case  KIO::ERR_COULD_NOT_CLOSEDIR:
00287       result = i18n( "Could not terminate listing %1." ,  errorText );
00288       break;
00289     case  KIO::ERR_COULD_NOT_MKDIR:
00290       result = i18n( "Could not make folder %1." ,  errorText );
00291       break;
00292     case  KIO::ERR_COULD_NOT_RMDIR:
00293       result = i18n( "Could not remove folder %1." ,  errorText );
00294       break;
00295     case  KIO::ERR_CANNOT_RESUME:
00296       result = i18n( "Could not resume file %1." ,  errorText );
00297       break;
00298     case  KIO::ERR_CANNOT_RENAME:
00299       result = i18n( "Could not rename file %1." ,  errorText );
00300       break;
00301     case  KIO::ERR_CANNOT_CHMOD:
00302       result = i18n( "Could not change permissions for %1." ,  errorText );
00303       break;
00304     case  KIO::ERR_CANNOT_CHOWN:
00305       result = i18n( "Could not change ownership for %1." ,  errorText );
00306       break;
00307     case  KIO::ERR_CANNOT_DELETE:
00308       result = i18n( "Could not delete file %1." ,  errorText );
00309       break;
00310     case  KIO::ERR_SLAVE_DIED:
00311       result = i18n( "The process for the %1 protocol died unexpectedly." ,  errorText );
00312       break;
00313     case  KIO::ERR_OUT_OF_MEMORY:
00314       result = i18n( "Error. Out of memory.\n%1" ,  errorText );
00315       break;
00316     case  KIO::ERR_UNKNOWN_PROXY_HOST:
00317       result = i18n( "Unknown proxy host\n%1" ,  errorText );
00318       break;
00319     case  KIO::ERR_COULD_NOT_AUTHENTICATE:
00320       result = i18n( "Authorization failed, %1 authentication not supported" ,  errorText );
00321       break;
00322     case  KIO::ERR_ABORTED:
00323       result = i18n( "User canceled action\n%1" ,  errorText );
00324       break;
00325     case  KIO::ERR_INTERNAL_SERVER:
00326       result = i18n( "Internal error in server\n%1" ,  errorText );
00327       break;
00328     case  KIO::ERR_SERVER_TIMEOUT:
00329       result = i18n( "Timeout on server\n%1" ,  errorText );
00330       break;
00331     case  KIO::ERR_UNKNOWN:
00332       result = i18n( "Unknown error\n%1" ,  errorText );
00333       break;
00334     case  KIO::ERR_UNKNOWN_INTERRUPT:
00335       result = i18n( "Unknown interrupt\n%1" ,  errorText );
00336       break;
00337 /*
00338     case  KIO::ERR_CHECKSUM_MISMATCH:
00339       if (errorText)
00340         result = i18n( "Warning: MD5 Checksum for %1 does not match checksum returned from server" ).arg(errorText);
00341       else
00342         result = i18n( "Warning: MD5 Checksum for %1 does not match checksum returned from server" ).arg("document");
00343       break;
00344 */
00345     case KIO::ERR_CANNOT_DELETE_ORIGINAL:
00346       result = i18n( "Could not delete original file %1.\nPlease check permissions." ,  errorText );
00347       break;
00348     case KIO::ERR_CANNOT_DELETE_PARTIAL:
00349       result = i18n( "Could not delete partial file %1.\nPlease check permissions." ,  errorText );
00350       break;
00351     case KIO::ERR_CANNOT_RENAME_ORIGINAL:
00352       result = i18n( "Could not rename original file %1.\nPlease check permissions." ,  errorText );
00353       break;
00354     case KIO::ERR_CANNOT_RENAME_PARTIAL:
00355       result = i18n( "Could not rename partial file %1.\nPlease check permissions." ,  errorText );
00356       break;
00357     case KIO::ERR_CANNOT_SYMLINK:
00358       result = i18n( "Could not create symlink %1.\nPlease check permissions." ,  errorText );
00359       break;
00360     case KIO::ERR_NO_CONTENT:
00361       result = errorText;
00362       break;
00363     case KIO::ERR_DISK_FULL:
00364       result = i18n( "Could not write file %1.\nDisk full." ,  errorText );
00365       break;
00366     case KIO::ERR_IDENTICAL_FILES:
00367       result = i18n( "The source and destination are the same file.\n%1" ,  errorText );
00368       break;
00369     case KIO::ERR_SLAVE_DEFINED:
00370       result = errorText;
00371       break;
00372     case KIO::ERR_UPGRADE_REQUIRED:
00373       result = i18n( "%1 is required by the server, but is not available." , errorText);
00374       break;
00375     case KIO::ERR_POST_DENIED:
00376       result = i18n( "Access to restricted port in POST denied.");
00377       break;
00378     default:
00379       result = i18n( "Unknown error code %1\n%2\nPlease send a full bug report at http://bugs.kde.org." ,  errorCode ,  errorText );
00380       break;
00381     }
00382 
00383   return result;
00384 }
00385 
00386 KIO_EXPORT QString KIO::unsupportedActionErrorString(const QString &protocol, int cmd) {
00387   switch (cmd) {
00388     case CMD_CONNECT:
00389       return i18n("Opening connections is not supported with the protocol %1." , protocol);
00390     case CMD_DISCONNECT:
00391       return i18n("Closing connections is not supported with the protocol %1." , protocol);
00392     case CMD_STAT:
00393       return i18n("Accessing files is not supported with the protocol %1.", protocol);
00394     case CMD_PUT:
00395       return i18n("Writing to %1 is not supported.", protocol);
00396     case CMD_SPECIAL:
00397       return i18n("There are no special actions available for protocol %1.", protocol);
00398     case CMD_LISTDIR:
00399       return i18n("Listing folders is not supported for protocol %1.", protocol);
00400     case CMD_GET:
00401       return i18n("Retrieving data from %1 is not supported.", protocol);
00402     case CMD_MIMETYPE:
00403       return i18n("Retrieving mime type information from %1 is not supported.", protocol);
00404     case CMD_RENAME:
00405       return i18n("Renaming or moving files within %1 is not supported.", protocol);
00406     case CMD_SYMLINK:
00407       return i18n("Creating symlinks is not supported with protocol %1.", protocol);
00408     case CMD_COPY:
00409       return i18n("Copying files within %1 is not supported.", protocol);
00410     case CMD_DEL:
00411       return i18n("Deleting files from %1 is not supported.", protocol);
00412     case CMD_MKDIR:
00413       return i18n("Creating folders is not supported with protocol %1.", protocol);
00414     case CMD_CHMOD:
00415       return i18n("Changing the attributes of files is not supported with protocol %1.", protocol);
00416     case CMD_CHOWN:
00417       return i18n("Changing the ownership of files is not supported with protocol %1.", protocol);
00418     case CMD_SUBURL:
00419       return i18n("Using sub-URLs with %1 is not supported.", protocol);
00420     case CMD_MULTI_GET:
00421       return i18n("Multiple get is not supported with protocol %1.", protocol);
00422     case CMD_OPEN:
00423       return i18n("Opening files is not supported with protocol %1.", protocol);
00424     default:
00425       return i18n("Protocol %1 does not support action %2.", protocol, cmd);
00426   }/*end switch*/
00427 }
00428 
00429 KIO_EXPORT QStringList KIO::Job::detailedErrorStrings( const KUrl *reqUrl /*= 0L*/,
00430                                             int method /*= -1*/ ) const
00431 {
00432   QString errorName, techName, description, ret2;
00433   QStringList causes, solutions, ret;
00434 
00435   QByteArray raw = rawErrorDetail( error(), errorText(), reqUrl, method );
00436   QDataStream stream(raw);
00437 
00438   stream >> errorName >> techName >> description >> causes >> solutions;
00439 
00440   QString url, protocol, datetime;
00441   if ( reqUrl ) {
00442     url = Qt::escape(reqUrl->prettyUrl());
00443     protocol = reqUrl->protocol();
00444   } else {
00445     url = i18nc("@info url", "(unknown)" );
00446   }
00447 
00448   datetime = KGlobal::locale()->formatDateTime( QDateTime::currentDateTime(),
00449                                                 KLocale::LongDate );
00450 
00451   ret << errorName;
00452   ret << i18nc( "@info %1 error name, %2 description",
00453                 "<qt><p><b>%1</b></p><p>%2</p></qt>", errorName, description);
00454 
00455   ret2 = QLatin1String( "<qt>" );
00456   if ( !techName.isEmpty() )
00457     ret2 += QLatin1String( "<p>" ) + i18n( "<b>Technical reason</b>: " ) +
00458             techName + QLatin1String( "</p>" );
00459   ret2 += QLatin1String( "<p>" ) + i18n( "<b>Details of the request</b>:" ) +
00460           QLatin1String( "</p><ul>" ) + i18n( "<li>URL: %1</li>", url );
00461   if ( !protocol.isEmpty() ) {
00462     ret2 += i18n( "<li>Protocol: %1</li>" , protocol );
00463   }
00464   ret2 += i18n( "<li>Date and time: %1</li>", datetime ) +
00465           i18n( "<li>Additional information: %1</li>" ,  errorText() ) +
00466           QLatin1String( "</ul>" );
00467   if ( !causes.isEmpty() ) {
00468     ret2 += QLatin1String( "<p>" ) + i18n( "<b>Possible causes</b>:" ) +
00469             QLatin1String( "</p><ul><li>" ) + causes.join( "</li><li>" ) +
00470             QLatin1String( "</li></ul>" );
00471   }
00472   if ( !solutions.isEmpty() ) {
00473     ret2 += QLatin1String( "<p>" ) + i18n( "<b>Possible solutions</b>:" ) +
00474             QLatin1String( "</p><ul><li>" ) + solutions.join( "</li><li>" ) +
00475             QLatin1String( "</li></ul>" );
00476   }
00477   ret2 += QLatin1String( "</qt>" );
00478   ret << ret2;
00479 
00480   return ret;
00481 }
00482 
00483 KIO_EXPORT QByteArray KIO::rawErrorDetail(int errorCode, const QString &errorText,
00484                                const KUrl *reqUrl /*= 0L*/, int /*method = -1*/ )
00485 {
00486   QString url, host, protocol, datetime, domain, path, dir, filename;
00487   bool isSlaveNetwork = false;
00488   if ( reqUrl ) {
00489     url = reqUrl->prettyUrl();
00490     host = reqUrl->host();
00491     protocol = reqUrl->protocol();
00492 
00493     if ( host.startsWith( QLatin1String( "www." ) ) )
00494       domain = host.mid(4);
00495     else
00496       domain = host;
00497 
00498     path = reqUrl->path(KUrl::AddTrailingSlash);
00499     filename = reqUrl->fileName();
00500     dir =  path + filename;
00501 
00502     // detect if protocol is a network protocol...
00503     // add your hacks here...
00504     if ( protocol == "http" ||
00505          protocol == "https" ||
00506          protocol == "ftp" ||
00507          protocol == "sftp" ||
00508          protocol == "webdav" ||
00509          protocol == "webdavs" ||
00510          protocol == "finger" ||
00511          protocol == "fish" ||
00512          protocol == "gopher" ||
00513          protocol == "imap" ||
00514          protocol == "imaps" ||
00515          protocol == "lan" ||
00516          protocol == "ldap" ||
00517          protocol == "mailto" ||
00518          protocol == "news" ||
00519          protocol == "nntp" ||
00520          protocol == "pop3" ||
00521          protocol == "pop3s" ||
00522          protocol == "smtp" ||
00523          protocol == "smtps" ||
00524          protocol == "telnet"
00525         ) {
00526       isSlaveNetwork = false;
00527     }
00528   } else {
00529     // assume that the errorText has the location we are interested in
00530     url = host = domain = path = filename = dir = errorText;
00531     protocol = i18nc("@info protocol", "(unknown)" );
00532   }
00533 
00534   datetime = KGlobal::locale()->formatDateTime( QDateTime::currentDateTime(),
00535                                                 KLocale::LongDate );
00536 
00537   QString errorName, techName, description;
00538   QStringList causes, solutions;
00539 
00540   // c == cause, s == solution
00541   QString sSysadmin = i18n( "Contact your appropriate computer support system, "
00542     "whether the system administrator, or technical support group for further "
00543     "assistance." );
00544   QString sServeradmin = i18n( "Contact the administrator of the server "
00545     "for further assistance." );
00546   // FIXME active link to permissions dialog
00547   QString sAccess = i18n( "Check your access permissions on this resource." );
00548   QString cAccess = i18n( "Your access permissions may be inadequate to "
00549     "perform the requested operation on this resource." );
00550   QString cLocked = i18n( "The file may be in use (and thus locked) by "
00551     "another user or application." );
00552   QString sQuerylock = i18n( "Check to make sure that no other "
00553     "application or user is using the file or has locked the file." );
00554   QString cHardware = i18n( "Although unlikely, a hardware error may have "
00555     "occurred." );
00556   QString cBug = i18n( "You may have encountered a bug in the program." );
00557   QString cBuglikely = i18n( "This is most likely to be caused by a bug in the "
00558     "program. Please consider submitting a full bug report as detailed below." );
00559   QString sUpdate = i18n( "Update your software to the latest version. "
00560     "Your distribution should provide tools to update your software." );
00561   QString sBugreport = i18n( "When all else fails, please consider helping the "
00562     "KDE team or the third party maintainer of this software by submitting a "
00563     "high quality bug report. If the software is provided by a third party, "
00564     "please contact them directly. Otherwise, first look to see if "
00565     "the same bug has been submitted by someone else by searching at the "
00566     "<a href=\"http://bugs.kde.org/\">KDE bug reporting website</a>. If not, take "
00567     "note of the details given above, and include them in your bug report, along "
00568     "with as many other details as you think might help." );
00569   QString cNetwork = i18n( "There may have been a problem with your network "
00570     "connection." );
00571   // FIXME netconf kcontrol link
00572   QString cNetconf = i18n( "There may have been a problem with your network "
00573     "configuration. If you have been accessing the Internet with no problems "
00574     "recently, this is unlikely." );
00575   QString cNetpath = i18n( "There may have been a problem at some point along "
00576     "the network path between the server and this computer." );
00577   QString sTryagain = i18n( "Try again, either now or at a later time." );
00578   QString cProtocol = i18n( "A protocol error or incompatibility may have occurred." );
00579   QString sExists = i18n( "Ensure that the resource exists, and try again." );
00580   QString cExists = i18n( "The specified resource may not exist." );
00581   QString cTypo = i18n( "You may have incorrectly typed the location." );
00582   QString sTypo = i18n( "Double-check that you have entered the correct location "
00583     "and try again." );
00584   QString sNetwork = i18n( "Check your network connection status." );
00585 
00586   switch( errorCode ) {
00587     case  KIO::ERR_CANNOT_OPEN_FOR_READING:
00588       errorName = i18n( "Cannot Open Resource For Reading" );
00589       description = i18n( "This means that the contents of the requested file "
00590         "or folder <strong>%1</strong> could not be retrieved, as read "
00591         "access could not be obtained." ,  dir );
00592       causes << i18n( "You may not have permissions to read the file or open "
00593         "the folder.") << cLocked << cHardware;
00594       solutions << sAccess << sQuerylock << sSysadmin;
00595       break;
00596 
00597     case  KIO::ERR_CANNOT_OPEN_FOR_WRITING:
00598       errorName = i18n( "Cannot Open Resource For Writing" );
00599       description = i18n( "This means that the file, <strong>%1</strong>, could "
00600         "not be written to as requested, because access with permission to "
00601         "write could not be obtained." ,  filename );
00602       causes << cAccess << cLocked << cHardware;
00603       solutions << sAccess << sQuerylock << sSysadmin;
00604       break;
00605 
00606     case  KIO::ERR_CANNOT_LAUNCH_PROCESS:
00607       errorName = i18n( "Cannot Initiate the %1 Protocol" ,  protocol );
00608       techName = i18n( "Unable to Launch Process" );
00609       description = i18n( "The program on your computer which provides access "
00610         "to the <strong>%1</strong> protocol could not be started. This is "
00611         "usually due to technical reasons." ,  protocol );
00612       causes << i18n( "The program which provides compatibility with this "
00613         "protocol may not have been updated with your last update of KDE. "
00614         "This can cause the program to be incompatible with the current version "
00615         "and thus not start." ) << cBug;
00616       solutions << sUpdate << sSysadmin;
00617       break;
00618 
00619     case  KIO::ERR_INTERNAL:
00620       errorName = i18n( "Internal Error" );
00621       description = i18n( "The program on your computer which provides access "
00622         "to the <strong>%1</strong> protocol has reported an internal error." ,
00623           protocol );
00624       causes << cBuglikely;
00625       solutions << sUpdate << sBugreport;
00626       break;
00627 
00628     case  KIO::ERR_MALFORMED_URL:
00629       errorName = i18n( "Improperly Formatted URL" );
00630       description = i18n( "The <strong>U</strong>niform <strong>R</strong>esource "
00631         "<strong>L</strong>ocator (URL) that you entered was not properly "
00632         "formatted. The format of a URL is generally as follows:"
00633         "<blockquote><strong>protocol://user:password@www.example.org:port/folder/"
00634         "filename.extension?query=value</strong></blockquote>" );
00635       solutions << sTypo;
00636       break;
00637 
00638     case  KIO::ERR_UNSUPPORTED_PROTOCOL:
00639       errorName = i18n( "Unsupported Protocol %1" ,  protocol );
00640       description = i18n( "The protocol <strong>%1</strong> is not supported "
00641         "by the KDE programs currently installed on this computer." ,
00642           protocol );
00643       causes << i18n( "The requested protocol may not be supported." )
00644         << i18n( "The versions of the %1 protocol supported by this computer and "
00645         "the server may be incompatible." ,  protocol );
00646       solutions << i18n( "You may perform a search on the Internet for a KDE "
00647         "program (called a kioslave or ioslave) which supports this protocol. "
00648         "Places to search include <a href=\"http://kde-apps.org/\">"
00649         "http://kde-apps.org/</a> and <a href=\"http://freshmeat.net/\">"
00650         "http://freshmeat.net/</a>." )
00651         << sUpdate << sSysadmin;
00652       break;
00653 
00654     case  KIO::ERR_NO_SOURCE_PROTOCOL:
00655       errorName = i18n( "URL Does Not Refer to a Resource." );
00656       techName = i18n( "Protocol is a Filter Protocol" );
00657       description = i18n( "The <strong>U</strong>niform <strong>R</strong>esource "
00658         "<strong>L</strong>ocator (URL) that you entered did not refer to a "
00659         "specific resource." );
00660       causes << i18n( "KDE is able to communicate through a protocol within a "
00661         "protocol; the protocol specified is only for use in such situations, "
00662         "however this is not one of these situations. This is a rare event, and "
00663         "is likely to indicate a programming error." );
00664       solutions << sTypo;
00665       break;
00666 
00667     case  KIO::ERR_UNSUPPORTED_ACTION:
00668       errorName = i18n( "Unsupported Action: %1" ,  errorText );
00669       description = i18n( "The requested action is not supported by the KDE "
00670         "program which is implementing the <strong>%1</strong> protocol." ,
00671           protocol );
00672       causes << i18n( "This error is very much dependent on the KDE program. The "
00673         "additional information should give you more information than is available "
00674         "to the KDE input/output architecture." );
00675       solutions << i18n( "Attempt to find another way to accomplish the same "
00676         "outcome." );
00677       break;
00678 
00679     case  KIO::ERR_IS_DIRECTORY:
00680       errorName = i18n( "File Expected" );
00681       description = i18n( "The request expected a file, however the "
00682         "folder <strong>%1</strong> was found instead." ,  dir );
00683       causes << i18n( "This may be an error on the server side." ) << cBug;
00684       solutions << sUpdate << sSysadmin;
00685       break;
00686 
00687     case  KIO::ERR_IS_FILE:
00688       errorName = i18n( "Folder Expected" );
00689       description = i18n( "The request expected a folder, however "
00690         "the file <strong>%1</strong> was found instead." ,  filename );
00691       causes << cBug;
00692       solutions << sUpdate << sSysadmin;
00693       break;
00694 
00695     case  KIO::ERR_DOES_NOT_EXIST:
00696       errorName = i18n( "File or Folder Does Not Exist" );
00697       description = i18n( "The specified file or folder <strong>%1</strong> "
00698         "does not exist." ,  dir );
00699       causes << cBug;
00700       solutions << sUpdate << sSysadmin;
00701       break;
00702 
00703     case  KIO::ERR_FILE_ALREADY_EXIST:
00704       errorName = i18n( "File Already Exists" );
00705       description = i18n( "The requested file could not be created because a "
00706         "file with the same name already exists." );
00707       solutions << i18n ( "Try moving the current file out of the way first, "
00708         "and then try again." )
00709         << i18n ( "Delete the current file and try again." )
00710         << i18n( "Choose an alternate filename for the new file." );
00711       break;
00712 
00713     case  KIO::ERR_DIR_ALREADY_EXIST:
00714       errorName = i18n( "Folder Already Exists" );
00715       description = i18n( "The requested folder could not be created because "
00716         "a folder with the same name already exists." );
00717       solutions << i18n( "Try moving the current folder out of the way first, "
00718         "and then try again." )
00719         << i18n( "Delete the current folder and try again." )
00720         << i18n( "Choose an alternate name for the new folder." );
00721       break;
00722 
00723     case  KIO::ERR_UNKNOWN_HOST:
00724       errorName = i18n( "Unknown Host" );
00725       description = i18n( "An unknown host error indicates that the server with "
00726         "the requested name, <strong>%1</strong>, could not be "
00727         "located on the Internet." ,  host );
00728       causes << i18n( "The name that you typed, %1, may not exist: it may be "
00729         "incorrectly typed." ,  host )
00730         << cNetwork << cNetconf;
00731       solutions << sNetwork << sSysadmin;
00732       break;
00733 
00734     case  KIO::ERR_ACCESS_DENIED:
00735       errorName = i18n( "Access Denied" );
00736       description = i18n( "Access was denied to the specified resource, "
00737         "<strong>%1</strong>." ,  url );
00738       causes << i18n( "You may have supplied incorrect authentication details or "
00739         "none at all." )
00740         << i18n( "Your account may not have permission to access the "
00741         "specified resource." );
00742       solutions << i18n( "Retry the request and ensure your authentication details "
00743         "are entered correctly." ) << sSysadmin;
00744       if ( !isSlaveNetwork ) solutions << sServeradmin;
00745       break;
00746 
00747     case  KIO::ERR_WRITE_ACCESS_DENIED:
00748       errorName = i18n( "Write Access Denied" );
00749       description = i18n( "This means that an attempt to write to the file "
00750         "<strong>%1</strong> was rejected." ,  filename );
00751       causes << cAccess << cLocked << cHardware;
00752       solutions << sAccess << sQuerylock << sSysadmin;
00753       break;
00754 
00755     case  KIO::ERR_CANNOT_ENTER_DIRECTORY:
00756       errorName = i18n( "Unable to Enter Folder" );
00757       description = i18n( "This means that an attempt to enter (in other words, "
00758         "to open) the requested folder <strong>%1</strong> was rejected." ,
00759           dir );
00760       causes << cAccess << cLocked;
00761       solutions << sAccess << sQuerylock << sSysadmin;
00762       break;
00763 
00764     case  KIO::ERR_PROTOCOL_IS_NOT_A_FILESYSTEM:
00765       errorName = i18n( "Folder Listing Unavailable" );
00766       techName = i18n( "Protocol %1 is not a Filesystem" ,  protocol );
00767       description = i18n( "This means that