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

KParts

browserrun.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002  *
00003  * Copyright (C) 2002 David Faure <faure@kde.org>
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 "browserrun.h"
00020 #include <kmessagebox.h>
00021 #include <kfiledialog.h>
00022 #include <kio/job.h>
00023 #include <kio/jobuidelegate.h>
00024 #include <kio/scheduler.h>
00025 #include <kio/copyjob.h>
00026 #include <klocale.h>
00027 #include <kshell.h>
00028 #include <kstringhandler.h>
00029 #include <kmimetypetrader.h>
00030 #include <ktemporaryfile.h>
00031 #include <kdebug.h>
00032 #include <kde_file.h>
00033 #include <kstandarddirs.h>
00034 #include <assert.h>
00035 
00036 using namespace KParts;
00037 
00038 class BrowserRun::BrowserRunPrivate
00039 {
00040 public:
00041     bool m_bHideErrorDialog;
00042     bool m_bRemoveReferrer;
00043     bool m_bTrustedSource;
00044     KParts::OpenUrlArguments m_args;
00045     KParts::BrowserArguments m_browserArgs;
00046 
00047     KParts::ReadOnlyPart *m_part; // QGuardedPtr?
00048     QPointer<QWidget> m_window;
00049     QString m_mimeType;
00050     QString m_contentDisposition;
00051 };
00052 
00053 BrowserRun::BrowserRun( const KUrl& url, const KParts::OpenUrlArguments& args,
00054                         const KParts::BrowserArguments& browserArgs,
00055                         KParts::ReadOnlyPart *part, QWidget* window,
00056                         bool removeReferrer, bool trustedSource, bool hideErrorDialog )
00057     : KRun( url, window, 0 /*mode*/, false /*is_local_file known*/, false /* no GUI */ ),
00058       d(new BrowserRunPrivate)
00059 {
00060     d->m_bHideErrorDialog = hideErrorDialog;
00061     d->m_bRemoveReferrer = removeReferrer;
00062     d->m_bTrustedSource = trustedSource;
00063     d->m_args = args;
00064     d->m_browserArgs = browserArgs;
00065     d->m_part = part;
00066     d->m_window = window;
00067 }
00068 
00069 BrowserRun::~BrowserRun()
00070 {
00071   delete d;
00072 }
00073 
00074 KParts::ReadOnlyPart* BrowserRun::part() const
00075 {
00076     return d->m_part;
00077 }
00078 
00079 KUrl BrowserRun::url() const
00080 {
00081     return KRun::url();
00082 }
00083 
00084 void BrowserRun::init()
00085 {
00086   if ( d->m_bHideErrorDialog )
00087   {
00088     // ### KRun doesn't call a virtual method when it finds out that the URL
00089     // is either malformed, or points to a non-existing local file...
00090     // So we need to reimplement some of the checks, to handle d->m_bHideErrorDialog
00091     if ( !KRun::url().isValid() ) {
00092         redirectToError( KIO::ERR_MALFORMED_URL, KRun::url().url() );
00093         return;
00094     }
00095     if ( !isLocalFile() && !hasError() && KRun::url().isLocalFile() )
00096       setIsLocalFile( true );
00097 
00098     if ( isLocalFile() )  {
00099       KDE_struct_stat buff;
00100       if ( KDE::stat( KRun::url().toLocalFile(), &buff ) == -1 )
00101       {
00102         kDebug(1000) << KRun::url().toLocalFile() << "doesn't exist.";
00103         redirectToError( KIO::ERR_DOES_NOT_EXIST, KRun::url().toLocalFile() );
00104         return;
00105       }
00106       setMode( buff.st_mode ); // while we're at it, save it for KRun::init() to use it
00107     }
00108   }
00109   KRun::init();
00110 }
00111 
00112 void BrowserRun::scanFile()
00113 {
00114   kDebug(1000) << KRun::url();
00115 
00116   // Let's check for well-known extensions
00117   // Not when there is a query in the URL, in any case.
00118   // Optimization for http/https, findByURL doesn't trust extensions over http.
00119   if ( KRun::url().query().isEmpty() && !KRun::url().protocol().startsWith("http") )
00120   {
00121     KMimeType::Ptr mime = KMimeType::findByUrl( KRun::url() );
00122     assert( mime );
00123     if ( mime->name() != "application/octet-stream" || isLocalFile() )
00124     {
00125       kDebug(1000) << "MIME TYPE is" << mime->name();
00126       mimeTypeDetermined( mime->name() );
00127       return;
00128     }
00129   }
00130 
00131     QMap<QString, QString>& metaData = d->m_args.metaData();
00132     if ( d->m_part ) {
00133         const QString proto = d->m_part->url().protocol().toLower();
00134 
00135       if (proto == "https" || proto == "webdavs") {
00136             metaData.insert("main_frame_request", "TRUE" );
00137             metaData.insert("ssl_was_in_use", "TRUE" );
00138            // metaData.insert("ssl_activate_warnings", "TRUE" );
00139       } else if (proto == "http" || proto == "webdav") {
00140            // metaData.insert("ssl_activate_warnings", "TRUE" );
00141             metaData.insert("ssl_was_in_use", "FALSE" );
00142       }
00143 
00144       // Set the PropagateHttpHeader meta-data if it has not already been set...
00145         if (!metaData.contains("PropagateHttpHeader"))
00146             metaData.insert("PropagateHttpHeader", "TRUE");
00147   }
00148 
00149   KIO::TransferJob *job;
00150     if ( d->m_browserArgs.doPost() && KRun::url().protocol().startsWith("http")) {
00151         job = KIO::http_post( KRun::url(), d->m_browserArgs.postData, KIO::HideProgressInfo );
00152         job->addMetaData( "content-type", d->m_browserArgs.contentType() );
00153     } else {
00154         job = KIO::get(KRun::url(),
00155                        d->m_args.reload() ? KIO::Reload : KIO::NoReload,
00156                        KIO::HideProgressInfo);
00157   }
00158 
00159     if ( d->m_bRemoveReferrer )
00160         metaData.remove("referrer");
00161 
00162     job->addMetaData( metaData );
00163     job->ui()->setWindow( d->m_window );
00164   connect( job, SIGNAL( result( KJob *)),
00165            this, SLOT( slotBrowserScanFinished(KJob *)));
00166   connect( job, SIGNAL( mimetype( KIO::Job *, const QString &)),
00167            this, SLOT( slotBrowserMimetype(KIO::Job *, const QString &)));
00168   setJob( job );
00169 }
00170 
00171 void BrowserRun::slotBrowserScanFinished(KJob *job)
00172 {
00173   kDebug(1000) << job->error();
00174   if ( job->error() == KIO::ERR_IS_DIRECTORY )
00175   {
00176       // It is in fact a directory. This happens when HTTP redirects to FTP.
00177       // Due to the "protocol doesn't support listing" code in BrowserRun, we
00178       // assumed it was a file.
00179       kDebug(1000) << "It is in fact a directory!";
00180       // Update our URL in case of a redirection
00181       KRun::setUrl( static_cast<KIO::TransferJob *>(job)->url() );
00182       setJob( 0 );
00183       mimeTypeDetermined( "inode/directory" );
00184   }
00185   else
00186   {
00187       if ( job->error() )
00188           handleError( job );
00189       else
00190           KRun::slotScanFinished(job);
00191   }
00192 }
00193 
00194 void BrowserRun::slotBrowserMimetype( KIO::Job *_job, const QString &type )
00195 {
00196     Q_ASSERT( _job == KRun::job() );
00197     KIO::TransferJob *job = static_cast<KIO::TransferJob *>(KRun::job());
00198     // Update our URL in case of a redirection
00199     //kDebug(1000) << "old URL=" << KRun::url();
00200     //kDebug(1000) << "new URL=" << job->url();
00201     setUrl( job->url() );
00202 
00203     if (job->isErrorPage()) {
00204         d->m_mimeType = type;
00205         handleError(job);
00206         setJob( 0 );
00207     } else {
00208         kDebug(1000) << "found" << type << "for" << KRun::url();
00209 
00210         // Suggested filename given by the server (e.g. HTTP content-disposition)
00211         // When set, we should really be saving instead of embedding
00212         const QString suggestedFileName = job->queryMetaData("content-disposition-filename");
00213         setSuggestedFileName(suggestedFileName); // store it (in KRun)
00214         //kDebug(1000) << "suggestedFileName=" << suggestedFileName;
00215         d->m_contentDisposition = job->queryMetaData("content-disposition-type");
00216 
00217         // Preserve all the SSL related meta data information...       
00218         QMapIterator<QString,QString> it (job->metaData());
00219         while (it.hasNext()) {
00220            it.next();
00221            if (it.key().startsWith(QLatin1String("ssl_"), Qt::CaseInsensitive))
00222              d->m_args.metaData().insert(it.key(), it.value());
00223         }
00224 
00225         // Make a copy to avoid a dead reference
00226         QString _type = type;
00227         job->putOnHold();
00228         setJob( 0 );
00229 
00230         mimeTypeDetermined( _type );
00231     }
00232 }
00233 
00234 BrowserRun::NonEmbeddableResult BrowserRun::handleNonEmbeddable( const QString& _mimeType )
00235 {
00236     QString mimeType( _mimeType );
00237     Q_ASSERT( !hasFinished() ); // only come here if the mimetype couldn't be embedded
00238     // Support for saving remote files.
00239     if ( mimeType != "inode/directory" && // dirs can't be saved
00240          !KRun::url().isLocalFile() )
00241     {
00242         if ( isTextExecutable(mimeType) )
00243             mimeType = QLatin1String("text/plain"); // view, don't execute
00244         kDebug(1000) << "ask for saving";
00245         KService::Ptr offer = KMimeTypeTrader::self()->preferredService(mimeType, "Application");
00246         // ... -> ask whether to save
00247         KParts::BrowserRun::AskSaveResult res = askSave( KRun::url(), offer, mimeType, suggestedFileName() );
00248         if ( res == KParts::BrowserRun::Save ) {
00249             save( KRun::url(), suggestedFileName() );
00250             kDebug(1000) << "Save: returning Handled";
00251             setFinished( true );
00252             return Handled;
00253         }
00254         else if ( res == KParts::BrowserRun::Cancel ) {
00255             // saving done or canceled
00256             kDebug(1000) << "Cancel: returning Handled";
00257             setFinished( true );
00258             return Handled;
00259         }
00260         else // "Open" chosen (done by KRun::foundMimeType, called when returning NotHandled)
00261         {
00262             // If we were in a POST, we can't just pass a URL to an external application.
00263             // We must save the data to a tempfile first.
00264             if ( d->m_browserArgs.doPost() )
00265             {
00266                 kDebug(1000) << "request comes from a POST, can't pass a URL to another app, need to save";
00267                 d->m_mimeType = mimeType;
00268                 QString extension;
00269                 QString fileName = suggestedFileName().isEmpty() ? KRun::url().fileName() : suggestedFileName();
00270                 int extensionPos = fileName.lastIndexOf( '.' );
00271                 if ( extensionPos != -1 )
00272                     extension = fileName.mid( extensionPos ); // keep the '.'
00273                 KTemporaryFile tempFile;
00274                 tempFile.setSuffix(extension);
00275                 tempFile.setAutoRemove(false);
00276                 tempFile.open();
00277                 KUrl destURL;
00278                 destURL.setPath( tempFile.fileName() );
00279                 KIO::Job *job = KIO::file_copy( KRun::url(), destURL, 0600, KIO::Overwrite );
00280                 job->ui()->setWindow(d->m_window);
00281                 connect( job, SIGNAL(result(KJob *)),
00282                          this, SLOT(slotCopyToTempFileResult(KJob *)) );
00283                 return Delayed; // We'll continue after the job has finished
00284             }
00285         }
00286     }
00287 
00288     // Check if running is allowed
00289     if ( !d->m_bTrustedSource && // ... and untrusted source...
00290          !allowExecution( mimeType, KRun::url() ) ) // ...and the user said no (for executables etc.)
00291     {
00292         setFinished( true );
00293         return Handled;
00294     }
00295 
00296     KIO::SimpleJob::removeOnHold(); // Kill any slave that was put on hold.
00297     return NotHandled;
00298 }
00299 
00300 //static
00301 bool BrowserRun::allowExecution( const QString &mimeType, const KUrl &url )
00302 {
00303     if ( !KRun::isExecutable( mimeType ) )
00304       return true;
00305 
00306     if ( !url.isLocalFile() ) // Don't permit to execute remote files
00307         return false;
00308 
00309     return ( KMessageBox::warningContinueCancel( 0,
00310                                                  i18n( "Do you really want to execute '%1'?", url.prettyUrl() ),
00311     i18n("Execute File?"), KGuiItem(i18n("Execute")) ) == KMessageBox::Continue );
00312 }
00313 
00314 static QString makeQuestion( const KUrl& url, const QString& mimeType, const QString& suggestedFileName )
00315 {
00316     QString surl = url.prettyUrl();
00317     KMimeType::Ptr mime = KMimeType::mimeType(mimeType, KMimeType::ResolveAliases);
00318     QString comment = mimeType;
00319 
00320     // Test if the mimeType is not recognize as octet-stream.
00321     // If so then keep mime-type as comment
00322     if (mime && mime->name() != KMimeType::defaultMimeType()) {
00323         // The mime-type is known so display the comment instead of mime-type
00324         comment = mime->comment();
00325     }
00326     // The strange order in the i18n() calls below is due to the possibility
00327     // of surl containing a '%'
00328     if ( suggestedFileName.isEmpty() )
00329         return i18n("Open '%2'?\nType: %1", comment, surl);
00330     else
00331         return i18n("Open '%3'?\nName: %2\nType: %1", comment, suggestedFileName, surl);
00332 }
00333 
00334 //static
00335 // TODO should take a QWidget* parent argument
00336 BrowserRun::AskSaveResult BrowserRun::askSave( const KUrl & url, KService::Ptr offer, const QString& mimeType, const QString & suggestedFileName )
00337 {
00338     // SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC
00339     // NOTE: Keep this function in sync with kdebase/kcontrol/filetypes/filetypedetails.cpp
00340     //       FileTypeDetails::updateAskSave()
00341 
00342     QString question = makeQuestion( url, mimeType, suggestedFileName );
00343 
00344     // text and icon used for the open button
00345     KGuiItem openItem;
00346     if (offer && !offer->name().isEmpty())
00347         openItem = KGuiItem(i18n("&Open with '%1'", offer->name()), offer->icon());
00348     else
00349         openItem = KGuiItem(i18n("&Open with..."), "system-run");
00350 
00351     int choice = KMessageBox::questionYesNoCancel(
00352         0, question, url.host(),
00353         KStandardGuiItem::saveAs(), openItem, KStandardGuiItem::cancel(),
00354         QLatin1String("askSave")+ mimeType ); // dontAskAgainName, KEEP IN SYNC!!!
00355 
00356     return choice == KMessageBox::Yes ? Save : ( choice == KMessageBox::No ? Open : Cancel );
00357     // SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC
00358 }
00359 
00360 //static
00361 // TODO should take a QWidget* parent argument
00362 BrowserRun::AskSaveResult BrowserRun::askEmbedOrSave( const KUrl & url, const QString& mimeType, const QString & suggestedFileName, int flags )
00363 {
00364     // SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC
00365     // NOTE: Keep this function in sync with
00366     // kdebase/apps/konqueror/settings/filetypes/filetypedetails.cpp
00367     //       FileTypeDetails::updateAskSave()
00368 
00369     KMimeType::Ptr mime = KMimeType::mimeType(mimeType, KMimeType::ResolveAliases);
00370     // Don't ask for:
00371     // - html (even new tabs would ask, due to about:blank!)
00372     // - dirs obviously (though not common over HTTP :),
00373     // - images (reasoning: no need to save, most of the time, because fast to see)
00374     // e.g. postscript is different, because takes longer to read, so
00375     // it's more likely that the user might want to save it.
00376     // - multipart/* ("server push", see kmultipart)
00377     // - other strange 'internal' mimetypes like print/manager...
00378     // KEEP IN SYNC!!!
00379     if (flags != (int)AttachmentDisposition && mime && (
00380          mime->is( "text/html" ) ||
00381          mime->is( "application/xml" ) ||
00382          mime->is( "inode/directory" ) ||
00383          mimeType.startsWith( "image" ) ||
00384          mime->is( "multipart/x-mixed-replace" ) ||
00385          mime->is( "multipart/replace" ) ||
00386          mimeType.startsWith( "print" ) ) )
00387         return Open;
00388 
00389     QString question = makeQuestion( url, mimeType, suggestedFileName );
00390 
00391     // don't use KStandardGuiItem::open() here which has trailing ellipsis!
00392     int choice = KMessageBox::questionYesNoCancel(
00393         0, question, url.host(),
00394         KStandardGuiItem::saveAs(), KGuiItem( i18n( "&Open" ), "document-open"), KStandardGuiItem::cancel(),
00395         QLatin1String("askEmbedOrSave")+ mimeType ); // dontAskAgainName, KEEP IN SYNC!!!
00396     return choice == KMessageBox::Yes ? Save : ( choice == KMessageBox::No ? Open : Cancel );
00397     // SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC
00398 }
00399 
00400 // Default implementation, overridden in KHTMLRun
00401 void BrowserRun::save( const KUrl & url, const QString & suggestedFileName )
00402 {
00403     simpleSave( url, suggestedFileName, d->m_window );
00404 }
00405 
00406 // static
00407 void BrowserRun::simpleSave( const KUrl & url, const QString & suggestedFileName,
00408                              QWidget* window )
00409 {
00410     // DownloadManager <-> konqueror integration
00411     // find if the integration is enabled
00412     // the empty key  means no integration
00413     // only use the downloadmanager for non-local urls
00414     if ( !url.isLocalFile() )
00415     {
00416         KConfigGroup cfg = KSharedConfig::openConfig("konquerorrc", KConfig::NoGlobals)->group("HTML Settings");
00417         QString downloadManger = cfg.readPathEntry("DownloadManager", QString());
00418         if (!downloadManger.isEmpty())
00419         {
00420             // then find the download manager location
00421             kDebug(1000) << "Using: "<<downloadManger <<" as Download Manager";
00422             QString cmd=KStandardDirs::findExe(downloadManger);
00423             if (cmd.isEmpty())
00424             {
00425                 QString errMsg=i18n("The Download Manager (%1) could not be found in your $PATH ", downloadManger);
00426                 QString errMsgEx= i18n("Try to reinstall it  \n\nThe integration with Konqueror will be disabled.");
00427                 KMessageBox::detailedSorry(0,errMsg,errMsgEx);
00428                 cfg.writePathEntry("DownloadManager",QString());
00429                 cfg.sync ();
00430             }
00431             else
00432             {
00433                 // ### suggestedFileName not taken into account. Fix this (and
00434                 // the duplicated code) with shiny new KDownload class for 3.2 (pfeiffer)
00435                 // Until the shiny new class comes about, send the suggestedFileName
00436                 // along with the actual URL to download. (DA)
00437                 cmd += " " + KShell::quoteArg(url.url());
00438                 if ( !suggestedFileName.isEmpty() )
00439                     cmd +=" " + KShell::quoteArg(suggestedFileName);
00440 
00441                 kDebug(1000) << "Calling command" << cmd;
00442                 // slave is already on hold (slotBrowserMimetype())
00443                 KIO::Scheduler::publishSlaveOnHold();
00444                 KRun::runCommand(cmd, window);
00445                 return;
00446             }
00447         }
00448     }
00449 
00450     // no download manager available, let's do it ourself
00451     KFileDialog *dlg = new KFileDialog( QString(), QString() /*all files*/,
00452                                         window);
00453     dlg->setOperationMode( KFileDialog::Saving );
00454     dlg->setCaption(i18n("Save As"));
00455 
00456     dlg->setSelection( suggestedFileName.isEmpty() ? url.fileName() : suggestedFileName );
00457     if ( dlg->exec() )
00458     {
00459         KUrl destURL( dlg->selectedUrl() );
00460         if ( destURL.isValid() )
00461         {
00462             KIO::Job *job = KIO::copy( url, destURL );
00463             job->ui()->setWindow (window);
00464             job->ui()->setAutoErrorHandlingEnabled( true );
00465         }
00466     }
00467     delete dlg;
00468 }
00469 
00470 void BrowserRun::slotStatResult( KJob *job )
00471 {
00472     if ( job->error() ) {
00473         kDebug(1000) << job->errorString();
00474         handleError( job );
00475     } else
00476         KRun::slotStatResult( job );
00477 }
00478 
00479 void BrowserRun::handleError( KJob * job )
00480 {
00481     if ( !job ) { // Shouldn't happen, see docu.
00482         kWarning(1000) << "handleError called with job=0! hideErrorDialog=" << d->m_bHideErrorDialog;
00483         return;
00484     }
00485 
00486     KIO::TransferJob *tjob = qobject_cast<KIO::TransferJob *>(job);
00487     if (tjob && tjob->isErrorPage() && !job->error()) {
00488         // The default handling of error pages is to show them like normal pages
00489         // But this is done here in handleError so that KHTMLRun can reimplement it
00490         tjob->putOnHold();
00491         setJob(0);
00492         if (!d->m_mimeType.isEmpty())
00493             mimeTypeDetermined(d->m_mimeType);
00494         return;
00495     }
00496 
00497     if (d->m_bHideErrorDialog && job->error() != KIO::ERR_NO_CONTENT)
00498     {
00499         redirectToError( job->error(), job->errorText() );
00500         return;
00501     }
00502 
00503     // Reuse code in KRun, to benefit from d->m_showingError etc.
00504     KRun::slotStatResult( job );
00505 }
00506 
00507 void BrowserRun::redirectToError( int error, const QString& errorText )
00508 {
00519     KUrl newURL(QString("error:/?error=%1&errText=%2")
00520                 .arg( error )
00521                 .arg( QString::fromUtf8( QUrl::toPercentEncoding( errorText ) ) ) );
00522     KUrl runURL = KRun::url();
00523     runURL.setPass( QString() ); // don't put the password in the error URL
00524 
00525     KUrl::List lst;
00526     lst << newURL << runURL;
00527     KRun::setUrl( KUrl::join( lst ) );
00528 
00529     setJob( 0 );
00530     mimeTypeDetermined( "text/html" );
00531 }
00532 
00533 void BrowserRun::slotCopyToTempFileResult(KJob *job)
00534 {
00535     if ( job->error() ) {
00536         job->uiDelegate()->showErrorMessage();
00537     } else {
00538         // Same as KRun::foundMimeType but with a different URL
00539         (void) (KRun::runUrl( static_cast<KIO::FileCopyJob *>(job)->destUrl(), d->m_mimeType, d->m_window ));
00540     }
00541     setError( true ); // see above
00542     setFinished( true );
00543     timer().start( 0 );
00544 }
00545 
00546 bool BrowserRun::isTextExecutable( const QString &mimeType )
00547 {
00548     return ( mimeType == "application/x-desktop" ||
00549              mimeType == "application/x-shellscript" );
00550 }
00551 
00552 bool BrowserRun::hideErrorDialog() const
00553 {
00554     return d->m_bHideErrorDialog;
00555 }
00556 
00557 QString BrowserRun::contentDisposition() const {
00558     return d->m_contentDisposition;
00559 }
00560 
00561 KParts::OpenUrlArguments& KParts::BrowserRun::arguments()
00562 {
00563     return d->m_args;
00564 }
00565 
00566 KParts::BrowserArguments& KParts::BrowserRun::browserArguments()
00567 {
00568     return d->m_browserArgs;
00569 }
00570 
00571 #include "browserrun.moc"

KParts

Skip menu "KParts"
  • Main Page
  • 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
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
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