• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KDEUI

kbugreport.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002    Copyright (C) 1999 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 as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public 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
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017    Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "kbugreport.h"
00021 
00022 #include <QtCore/QProcess>
00023 #include <QtCore/QCoreApplication>
00024 #include <QtGui/QPushButton>
00025 #include <QtGui/QLayout>
00026 #include <QtGui/QRadioButton>
00027 #include <QtGui/QGroupBox>
00028 #include <QtGui/QCloseEvent>
00029 
00030 #include <kaboutdata.h>
00031 #include <kcombobox.h>
00032 #include <ktoolinvocation.h>
00033 #include <kdebug.h>
00034 #include <klineedit.h>
00035 #include <klocale.h>
00036 #include <kmessagebox.h>
00037 #include <kstandarddirs.h>
00038 #include <kcomponentdata.h>
00039 #include <kurllabel.h>
00040 #include <ktextedit.h>
00041 #include <ktitlewidget.h>
00042 
00043 #include <stdio.h>
00044 #include <pwd.h>
00045 #include <unistd.h>
00046 #include <sys/utsname.h>
00047 
00048 #include "kdepackages.h"
00049 #include "kdeversion.h"
00050 
00051 #include <config-compiler.h>
00052 
00053 class KBugReportPrivate {
00054 public:
00055     KBugReportPrivate(KBugReport *q): q(q) {}
00056 
00057     void _k_slotConfigureEmail();
00058     void _k_slotSetFrom();
00059     void _k_appChanged(int);
00060     void _k_updateUrl();
00061 
00062     KBugReport *q;
00063     QProcess * m_process;
00064     const KAboutData * m_aboutData;
00065 
00066     KTextEdit * m_lineedit;
00067     KLineEdit * m_subject;
00068     QLabel * m_from;
00069     QLabel * m_version;
00070     QString m_strVersion;
00071     QGroupBox * m_bgSeverity;
00072     QPushButton * m_configureEmail;
00073 
00074     KComboBox *appcombo;
00075     QString lastError;
00076     QString kde_version;
00077     QString appname;
00078     QString os;
00079     KUrl url;
00080     QList<QRadioButton*> severityButtons;
00081     int currentSeverity() {
00082         for (int i=0;i<severityButtons.count();i++)
00083             if (severityButtons[i]->isChecked()) return i;
00084         return -1;
00085     }
00086     bool submitBugWeb;
00087 };
00088 
00089 KBugReport::KBugReport( QWidget * _parent, bool modal, const KAboutData *aboutData )
00090   : KDialog( _parent ), d( new KBugReportPrivate(this) )
00091 {
00092   setCaption( i18n("Submit Bug Report") );
00093   setButtons( Ok | Cancel );
00094   setModal(modal);
00095 
00096   // Use supplied aboutdata, otherwise the one from the active componentData
00097   // otherwise the KGlobal one. _activeInstance should neved be 0L in theory.
00098   d->m_aboutData = aboutData ? aboutData
00099       : (KGlobal::activeComponent().isValid() ? KGlobal::activeComponent().aboutData()
00100                                   : KGlobal::mainComponent().aboutData());
00101   d->m_process = 0;
00102   QWidget * parent = new QWidget(this);
00103   d->submitBugWeb = false;
00104 
00105   if ( d->m_aboutData->bugAddress() == QLatin1String("submit@bugs.kde.org") )
00106   {
00107     // This is a core KDE application -> redirect to the web form
00108     d->submitBugWeb = true;
00109     setButtonGuiItem( Cancel, KStandardGuiItem::close() );
00110   }
00111 
00112   QLabel * tmpLabel;
00113   QVBoxLayout * lay = new QVBoxLayout( parent);
00114 
00115   KTitleWidget *title = new KTitleWidget( this );
00116   title->setText(i18n( "Submit Bug Report" ) );
00117   title->setPixmap( KIcon( "tools-report-bug" ).pixmap( 32 ) );
00118   lay->addWidget( title );
00119 
00120   QGridLayout *glay = new QGridLayout();
00121   lay->addLayout(glay);
00122 
00123   int row = 0;
00124 
00125   if ( !d->submitBugWeb )
00126   {
00127     // From
00128     QString qwtstr = i18n( "Your email address. If incorrect, use the Configure Email button to change it" );
00129     tmpLabel = new QLabel( i18nc("Email sender address", "From:"), parent );
00130     glay->addWidget( tmpLabel, row,0 );
00131     tmpLabel->setWhatsThis(qwtstr );
00132     d->m_from = new QLabel( parent );
00133     glay->addWidget( d->m_from, row, 1 );
00134     d->m_from->setWhatsThis(qwtstr );
00135 
00136 
00137     // Configure email button
00138     d->m_configureEmail = new QPushButton( i18n("Configure Email..."),
00139                                         parent );
00140     connect( d->m_configureEmail, SIGNAL( clicked() ), this,
00141              SLOT( _k_slotConfigureEmail() ) );
00142     glay->addWidget( d->m_configureEmail, 0, 2, 3, 1, Qt::AlignTop|Qt::AlignRight );
00143 
00144     // To
00145     qwtstr = i18n( "The email address this bug report is sent to." );
00146     tmpLabel = new QLabel( i18nc("Email receiver address", "To:"), parent );
00147     glay->addWidget( tmpLabel, ++row,0 );
00148     tmpLabel->setWhatsThis(qwtstr );
00149     tmpLabel = new QLabel( d->m_aboutData->bugAddress(), parent );
00150     tmpLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
00151     glay->addWidget( tmpLabel, row, 1 );
00152     tmpLabel->setWhatsThis(qwtstr );
00153 
00154     setButtonGuiItem( Ok,  KGuiItem( i18n("&Send"), "mail-send", i18n( "Send bug report." ),
00155                     i18n( "Send this bug report to %1." ,  d->m_aboutData->bugAddress() ) ) );
00156     row++;
00157   }
00158   else
00159   {
00160     d->m_configureEmail = 0;
00161     d->m_from = 0;
00162   }
00163 
00164   // Program name
00165   QString qwtstr = i18n( "The application for which you wish to submit a bug report - if incorrect, please use the Report Bug menu item of the correct application" );
00166   tmpLabel = new QLabel( i18n("Application: "), parent );
00167   glay->addWidget( tmpLabel, row, 0 );
00168   tmpLabel->setWhatsThis(qwtstr );
00169   d->appcombo = new KComboBox( false, parent );
00170   d->appcombo->setWhatsThis(qwtstr );
00171   QStringList packageList;
00172   for (int c = 0; packages[c]; ++c)
00173     packageList << QString::fromLatin1(packages[c]);
00174   d->appcombo->addItems(packageList);
00175   connect(d->appcombo, SIGNAL(activated(int)), SLOT(_k_appChanged(int)));
00176   d->appname = d->m_aboutData
00177                                     ? d->m_aboutData->productName()
00178                                     : qApp->applicationName() ;
00179   glay->addWidget( d->appcombo, row, 1 );
00180   int index = 0;
00181   for (; index < d->appcombo->count(); index++) {
00182       if (d->appcombo->itemText(index) == d->appname) {
00183           break;
00184       }
00185   }
00186   if (index == d->appcombo->count()) { // not present
00187       d->appcombo->addItem(d->appname);
00188   }
00189   d->appcombo->setCurrentIndex(index);
00190 
00191   tmpLabel->setWhatsThis(qwtstr );
00192 
00193   // Version
00194   qwtstr = i18n( "The version of this application - please make sure that no newer version is available before sending a bug report" );
00195   tmpLabel = new QLabel( i18n("Version:"), parent );
00196   glay->addWidget( tmpLabel, ++row, 0 );
00197   tmpLabel->setWhatsThis(qwtstr );
00198   if (d->m_aboutData)
00199       d->m_strVersion = d->m_aboutData->version();
00200   else
00201       d->m_strVersion = i18n("no version set (programmer error)");
00202   d->kde_version = QString::fromLatin1( KDE_VERSION_STRING );
00203   d->kde_version += ", " + QString::fromLatin1( KDE_DISTRIBUTION_TEXT );
00204   if ( !d->submitBugWeb )
00205       d->m_strVersion += ' ' + d->kde_version;
00206   d->m_version = new QLabel( d->m_strVersion, parent );
00207   d->m_version->setTextInteractionFlags(Qt::TextBrowserInteraction);
00208   //glay->addWidget( d->m_version, row, 1 );
00209   glay->addWidget( d->m_version, row, 1, 1, 2 );
00210   d->m_version->setWhatsThis(qwtstr );
00211 
00212   tmpLabel = new QLabel(i18n("OS:"), parent);
00213   glay->addWidget( tmpLabel, ++row, 0 );
00214 
00215   struct utsname unameBuf;
00216   uname( &unameBuf );
00217   d->os = QString::fromLatin1( unameBuf.sysname ) +
00218           " (" + QString::fromLatin1( unameBuf.machine ) + ") "
00219           "release " + QString::fromLatin1( unameBuf.release );
00220 
00221   tmpLabel = new QLabel(d->os, parent);
00222   tmpLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
00223   glay->addWidget( tmpLabel, row, 1, 1, 2 );
00224 
00225   tmpLabel = new QLabel(i18n("Compiler:"), parent);
00226   glay->addWidget( tmpLabel, ++row, 0 );
00227   tmpLabel = new QLabel(QString::fromLatin1(KDE_COMPILER_VERSION), parent);
00228   tmpLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
00229   glay->addWidget( tmpLabel, row, 1, 1, 2 );
00230 
00231   if ( !d->submitBugWeb )
00232   {
00233     // Severity
00234     d->m_bgSeverity = new QGroupBox( i18n("Se&verity"), parent );
00235     static const char * const sevNames[5] = { "critical", "grave", "normal", "wishlist", "i18n" };
00236     const QString sevTexts[5] = { i18n("Critical"), i18n("Grave"), i18nc("normal severity","Normal"), i18n("Wishlist"), i18n("Translation") };
00237     QHBoxLayout *severityLayout=new QHBoxLayout(d->m_bgSeverity);
00238     for (int i = 0 ; i < 5 ; i++ )
00239     {
00240       // Store the severity string as the name
00241       QRadioButton *rb = new QRadioButton( sevTexts[i], d->m_bgSeverity);
00242       rb->setObjectName(sevNames[i] );
00243       d->severityButtons.append(rb);
00244       severityLayout->addWidget(rb);
00245       if (i==2) rb->setChecked(true); // default : "normal"
00246     }
00247 
00248     lay->addWidget( d->m_bgSeverity );
00249 
00250     // Subject
00251     QHBoxLayout * hlay = new QHBoxLayout();
00252     lay->addItem(hlay);
00253     tmpLabel = new QLabel( i18n("S&ubject: "), parent );
00254     hlay->addWidget( tmpLabel );
00255     d->m_subject = new KLineEdit( parent );
00256     d->m_subject->setClearButtonShown(true);
00257     d->m_subject->setFocus();
00258     tmpLabel->setBuddy( d->m_subject );
00259     hlay->addWidget( d->m_subject );
00260 
00261     QString text = i18n("Enter the text (in English if possible) that you wish to submit for the "
00262                         "bug report.\n"
00263                         "If you press \"Send\", a mail message will be sent to the maintainer of "
00264                         "this program.\n");
00265     QLabel * label = new QLabel( parent);
00266 
00267     label->setText( text );
00268     lay->addWidget( label );
00269 
00270     // The multiline-edit
00271     d->m_lineedit = new KTextEdit( parent);
00272     d->m_lineedit->setMinimumHeight( 180 ); // make it big
00273     d->m_lineedit->setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
00274     d->m_lineedit->setLineWrapMode(QTextEdit::WidgetWidth);
00275     d->m_lineedit->setCheckSpellingEnabled(true);
00276     d->m_lineedit->setSpellCheckingLanguage("en");
00277     lay->addWidget( d->m_lineedit, 10 /*stretch*/ );
00278 
00279     d->_k_slotSetFrom();
00280   } else {
00281     // Point to the web form
00282 
00283     lay->addSpacing(10);
00284     QString text = i18n("<qt>To submit a bug report, click on the button below. This will open a web browser "
00285                         "window on <a href=\"http://bugs.kde.org\">http://bugs.kde.org</a> where you will find "
00286                         "a form to fill in. The information displayed above will be transferred to that server.</qt>");
00287     QLabel * label = new QLabel( text, parent);
00288     label->setOpenExternalLinks( true );
00289     label->setTextInteractionFlags( Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard );
00290     label->setWordWrap( true );
00291     lay->addWidget( label );
00292     lay->addSpacing(10);
00293 
00294     d->appcombo->setFocus();
00295 
00296     d->_k_updateUrl();
00297 
00298     setButtonText(Ok, i18n("&Launch Bug Report Wizard"));
00299     setButtonIcon(Ok, KIcon("tools-report-bug"));
00300   }
00301   parent->setMinimumHeight( parent->sizeHint().height() + 20 ); // WORKAROUND: prevent "cropped" kcombobox
00302   setMainWidget(parent);
00303 }
00304 
00305 KBugReport::~KBugReport()
00306 {
00307     delete d;
00308 }
00309 
00310 QString KBugReport::messageBody() const
00311 {
00312   if ( !d->submitBugWeb )
00313     return d->m_lineedit->toPlainText();
00314   else
00315     return QString();
00316 }
00317 
00318 void KBugReport::setMessageBody(const QString &messageBody)
00319 {
00320   if ( !d->submitBugWeb )
00321     d->m_lineedit->setPlainText(messageBody);
00322 }
00323 
00324 void KBugReportPrivate::_k_updateUrl()
00325 {
00326     url = KUrl( "https://bugs.kde.org/wizard.cgi" );
00327     url.addQueryItem( "os", os );
00328     url.addQueryItem( "compiler", KDE_COMPILER_VERSION );
00329     url.addQueryItem( "kdeVersion", kde_version );
00330     url.addQueryItem( "appVersion", m_strVersion );
00331     url.addQueryItem( "package", appcombo->currentText() );
00332     url.addQueryItem( "kbugreport", "1" );
00333 }
00334 
00335 void KBugReportPrivate::_k_appChanged(int i)
00336 {
00337     QString appName = appcombo->itemText(i);
00338     int index = appName.indexOf( '/' );
00339     if ( index > 0 )
00340         appName = appName.left( index );
00341     kDebug() << "appName " << appName;
00342 
00343     QString strDisplayVersion; //Version string to show in the UI
00344     if (appname == appName && m_aboutData) {
00345         m_strVersion = m_aboutData->version();
00346         strDisplayVersion = m_strVersion;
00347     } else {
00348         m_strVersion = QLatin1String("unknown"); //English string to put in the bug report
00349         strDisplayVersion = i18nc("unknown program name", "unknown");
00350     }
00351 
00352     if ( !submitBugWeb ) {
00353         m_strVersion += ' ' + kde_version;
00354         strDisplayVersion += ' ' + kde_version;
00355     }
00356 
00357     m_version->setText(strDisplayVersion);
00358     if ( submitBugWeb )
00359         _k_updateUrl();
00360 }
00361 
00362 void KBugReportPrivate::_k_slotConfigureEmail()
00363 {
00364   if (m_process) return;
00365   m_process = new QProcess;
00366   QObject::connect( m_process, SIGNAL(finished( int, QProcess::ExitStatus )), q, SLOT(_k_slotSetFrom()) );
00367   m_process->start( QString::fromLatin1("kcmshell4"), QStringList() << QString::fromLatin1("kcm_useraccount") );
00368   if ( !m_process->waitForStarted() )
00369   {
00370     kDebug() << "Couldn't start kcmshell4..";
00371     delete m_process;
00372     m_process = 0;
00373     return;
00374   }
00375   m_configureEmail->setEnabled(false);
00376 }
00377 
00378 void KBugReportPrivate::_k_slotSetFrom()
00379 {
00380   delete m_process;
00381   m_process = 0;
00382   m_configureEmail->setEnabled(true);
00383 
00384   // ### KDE4: why oh why is KEmailSettings in kio?
00385   KConfig emailConf( QString::fromLatin1("emaildefaults") );
00386 
00387   KConfigGroup cg(&emailConf, "Defaults");
00388   // find out the default profile
00389   QString profile = QString::fromLatin1("PROFILE_");
00390   profile += cg.readEntry( QString::fromLatin1("Profile"),
00391                            QString::fromLatin1("Default") );
00392 
00393   KConfigGroup profileGrp(&emailConf, profile );
00394   QString fromaddr = profileGrp.readEntry( "EmailAddress" );
00395   if (fromaddr.isEmpty()) {
00396      struct passwd *p;
00397      p = getpwuid(getuid());
00398      fromaddr = QString::fromLatin1(p->pw_name);
00399   } else {
00400      QString name = profileGrp.readEntry( "FullName" );
00401      if (!name.isEmpty())
00402         fromaddr = name + QString::fromLatin1(" <") + fromaddr + QString::fromLatin1(">");
00403   }
00404   m_from->setText( fromaddr );
00405 }
00406 
00407 void KBugReport::accept()
00408 {
00409     if ( d->submitBugWeb ) {
00410         KToolInvocation::invokeBrowser( d->url.url() );
00411         return;
00412     }
00413 
00414     if( d->m_lineedit->toPlainText().isEmpty() ||
00415         d->m_subject->text().isEmpty() )
00416     {
00417         QString msg = i18n("You must specify both a subject and a description "
00418                            "before the report can be sent.");
00419         KMessageBox::error(this,msg);
00420         return;
00421     }
00422 
00423     switch ( d->currentSeverity())
00424     {
00425         case 0: // critical
00426             if ( KMessageBox::questionYesNo( this, i18n(
00427                 "<p>You chose the severity <b>Critical</b>. "
00428                 "Please note that this severity is intended only for bugs that:</p>"
00429                 "<ul><li>break unrelated software on the system (or the whole system)</li>"
00430                 "<li>cause serious data loss</li>"
00431                 "<li>introduce a security hole on the system where the affected package is installed</li></ul>\n"
00432                 "<p>Does the bug you are reporting cause any of the above damage? "
00433                 "If it does not, please select a lower severity. Thank you.</p>" ),QString(),KStandardGuiItem::cont(),KStandardGuiItem::cancel() ) == KMessageBox::No )
00434                 return;
00435             break;
00436         case 1: // grave
00437             if ( KMessageBox::questionYesNo( this, i18n(
00438                 "<p>You chose the severity <b>Grave</b>. "
00439                 "Please note that this severity is intended only for bugs that:</p>"
00440                 "<ul><li>make the package in question unusable or mostly so</li>"
00441                 "<li>cause data loss</li>"
00442                 "<li>introduce a security hole allowing access to the accounts of users who use the affected package</li></ul>\n"
00443                 "<p>Does the bug you are reporting cause any of the above damage? "
00444                 "If it does not, please select a lower severity. Thank you.</p>" ),QString(),KStandardGuiItem::cont(),KStandardGuiItem::cancel() ) == KMessageBox::No )
00445                 return;
00446             break;
00447         default:
00448             break;
00449     }
00450     if( !sendBugReport() )
00451     {
00452         QString msg = i18n("Unable to send the bug report.\n"
00453                            "Please submit a bug report manually....\n"
00454                            "See http://bugs.kde.org/ for instructions.");
00455         KMessageBox::error(this, msg + "\n\n" + d->lastError);
00456         return;
00457     }
00458 
00459     KMessageBox::information(this,
00460                              i18n("Bug report sent, thank you for your input."));
00461     KDialog::accept();
00462 }
00463 
00464 void KBugReport::closeEvent( QCloseEvent * e)
00465 {
00466   if( !d->submitBugWeb && ( (d->m_lineedit->toPlainText().length()>0) || d->m_subject->isModified() ) )
00467   {
00468     int rc = KMessageBox::warningYesNo( this,
00469              i18n( "Close and discard\nedited message?" ),
00470              i18n( "Close Message" ), KStandardGuiItem::discard(), KStandardGuiItem::cont() );
00471     if( rc == KMessageBox::No )
00472     {
00473         e->ignore();
00474         return;
00475     }
00476   }
00477   KDialog::closeEvent(e);
00478 }
00479 
00480 
00481 QString KBugReport::text() const
00482 {
00483     kDebug() << d->severityButtons[d->currentSeverity()]->objectName();
00484     // Prepend the pseudo-headers to the contents of the mail
00485   QString severity = d->severityButtons[d->currentSeverity()]->objectName();
00486   QString appname = d->appcombo->currentText();
00487   QString os = QString::fromLatin1("OS: %1 (%2)\n").
00488                arg(KDE_COMPILING_OS).
00489                arg(KDE_DISTRIBUTION_TEXT);
00490   QString bodyText;
00491 /*  for(int i = 0; i < m_lineedit->numLines(); i++)
00492   {
00493      QString line = m_lineedit->textLine(i);
00494      if (!line.endsWith("\n"))
00495         line += '\n';
00496      bodyText += line;
00497   }
00498 */
00499   bodyText=d->m_lineedit->toPlainText();
00500   if (bodyText.length()>0)
00501         if (bodyText[bodyText.length()-1]!='\n') bodyText+='\n';
00502   if (severity == QLatin1String("i18n") && KGlobal::locale()->language() != KLocale::defaultLanguage()) {
00503       // Case 1 : i18n bug
00504       QString package = QString::fromLatin1("i18n_%1").arg(KGlobal::locale()->language());
00505       package = package.replace('_', '-');
00506       return QString::fromLatin1("Package: %1").arg(package) +
00507           QString::fromLatin1("\n"
00508                               "Application: %1\n"
00509                               // not really i18n's version, so better here IMHO
00510                               "Version: %2\n").arg(appname).arg(d->m_strVersion)+
00511           os+QString::fromLatin1("\n")+bodyText;
00512   } else {
00513       appname = appname.replace('_', '-');
00514       // Case 2 : normal bug
00515       return QString::fromLatin1("Package: %1\n"
00516                                  "Version: %2\n"
00517                                  "Severity: %3\n")
00518           .arg(appname).arg(d->m_strVersion).arg(severity)+
00519           QString::fromLatin1("Compiler: %1\n").arg(KDE_COMPILER_VERSION)+
00520           os+QString::fromLatin1("\n")+bodyText;
00521   }
00522 }
00523 
00524 bool KBugReport::sendBugReport()
00525 {
00526   QString recipient ( d->m_aboutData ?
00527     d->m_aboutData->bugAddress() :
00528     QString::fromLatin1("submit@bugs.kde.org") );
00529 
00530   QString command;
00531   command = KStandardDirs::locate("exe", "ksendbugmail");
00532   if (command.isEmpty())
00533       command = KStandardDirs::findExe( QString::fromLatin1("ksendbugmail") );
00534 
00535   QProcess proc;
00536   QStringList args;
00537   args << "--subject" << d->m_subject->text() << "--recipient" << recipient;
00538   proc.start( command, args );
00539   //kDebug() << command << args;
00540   if (!proc.waitForStarted())
00541   {
00542     kError() << "Unable to open a pipe to " << command << endl;
00543     return false;
00544   }
00545   proc.write( text().toUtf8() );
00546   proc.closeWriteChannel();
00547 
00548   proc.waitForFinished();
00549   kDebug() << "kbugreport: sendbugmail exit, status " << proc.exitStatus() << " code " << proc.exitCode();
00550 
00551   QByteArray line;
00552   if (proc.exitStatus() == QProcess::NormalExit && proc.exitCode() != 0) {
00553       // XXX not stderr?
00554       while (!proc.atEnd())
00555           line = proc.readLine();
00556       d->lastError = QString::fromUtf8( line );
00557       return false;
00558   }
00559   return true;
00560 }
00561 
00562 
00563 #include "kbugreport.moc"

KDEUI

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
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