# khtml Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kmultipart.cpp

    00001 /* This file is part of the KDE project
    00002    Copyright (C) 2002 David Faure <david@mandrakesoft.com>
    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., 59 Temple Place - Suite 330,
    00017    Boston, MA 02111-1307, USA.
    00018 */
    00019
    00020 #include "kmultipart.h"
    00021
    00022 #include <qvbox.h>
    00023 #include <kinstance.h>
    00024 #include <kmimetype.h>
    00025 #include <klocale.h>
    00026 #include <kio/job.h>
    00027 #include <qfile.h>
    00028 #include <ktempfile.h>
    00029 #include <kmessagebox.h>
    00030 #include <kparts/componentfactory.h>
    00031 #include <kparts/genericfactory.h>
    00032 #include <khtml_part.h>
    00033 #include <unistd.h>
    00034 #include <kxmlguifactory.h>
    00035 #include <qtimer.h>
    00036
    00037 typedef KParts::GenericFactory<KMultiPart> KMultiPartFactory; // factory for the part
    00038 K_EXPORT_COMPONENT_FACTORY( libkmultipart /*library name*/, KMultiPartFactory )
    00039
    00040 //#define DEBUG_PARSING
    00041
    00042 class KLineParser
    00043 {
    00044 public:
    00045     KLineParser() {
    00046         m_lineComplete = false;
    00047     }
    00048     void addChar( char c, bool storeNewline ) {
    00049         if ( !storeNewline && c == '\r' )
    00050             return;
    00051         Q_ASSERT( !m_lineComplete );
    00052         if ( storeNewline || c != '\n' ) {
    00053             int sz = m_currentLine.size();
    00054             m_currentLine.resize( sz+1, QGArray::SpeedOptim );
    00055             m_currentLine[sz] = c;
    00056         }
    00057         if ( c == '\n' )
    00058             m_lineComplete = true;
    00059     }
    00060     bool isLineComplete() const {
    00061         return m_lineComplete;
    00062     }
    00063     QByteArray currentLine() const {
    00064         return m_currentLine;
    00065     }
    00066     void clearLine() {
    00067         Q_ASSERT( m_lineComplete );
    00068         reset();
    00069     }
    00070     void reset() {
    00071         m_currentLine.resize( 0, QGArray::SpeedOptim );
    00072         m_lineComplete = false;
    00073     }
    00074 private:
    00075     QByteArray m_currentLine;
    00076     bool m_lineComplete; // true when ending with '\n'
    00077 };
    00078
    00079 /* testcase:
    00080    Content-type: multipart/mixed;boundary=ThisRandomString
    00081
    00082 --ThisRandomString
    00083 Content-type: text/plain
    00084
    00085 Data for the first object.
    00086
    00087 --ThisRandomString
    00088 Content-type: text/plain
    00089
    00090 Data for the second and last object.
    00091
    00092 --ThisRandomString--
    00093 */
    00094
    00095
    00096 KMultiPart::KMultiPart( QWidget *parentWidget, const char *widgetName,
    00097                         QObject *parent, const char *name, const QStringList& )
    00098     : KParts::ReadOnlyPart( parent, name )
    00099 {
    00100     m_filter = 0L;
    00101
    00102     setInstance( KMultiPartFactory::instance() );
    00103
    00104     QVBox *box = new QVBox( parentWidget, widgetName );
    00105     setWidget( box );
    00106
    00107     m_extension = new KParts::BrowserExtension( this );
    00108
    00109     // We probably need to use m_extension to get the urlArgs in openURL...
    00110
    00111     m_part = 0L;
    00112     m_isHTMLPart = false;
    00113     m_job = 0L;
    00114     m_lineParser = new KLineParser;
    00115     m_tempFile = 0L;
    00116
    00117     m_timer = new QTimer( this );
    00118     connect( m_timer, SIGNAL( timeout() ), this, SLOT( slotProgressInfo() ) );
    00119 }
    00120
    00121 KMultiPart::~KMultiPart()
    00122 {
    00123     // important: delete the nested part before the part or qobject destructor runs.
    00124     // we now delete the nested part which deletes the part's widget which makes
    00125     // _OUR_ m_widget 0 which in turn avoids our part destructor to delete the
    00126     // widget ;-)
    00127     // ### additional note: it _can_ be that the part has been deleted before:
    00128     // when we're in a html frameset and the view dies first, then it will also
    00129     // kill the htmlpart
    00130     if ( m_part )
    00131         delete static_cast<KParts::ReadOnlyPart *>( m_part );
    00132     delete m_job;
    00133     delete m_lineParser;
    00134     if ( m_tempFile ) {
    00135         m_tempFile->setAutoDelete( true );
    00136         delete m_tempFile;
    00137     }
    00138     delete m_filter;
    00139     m_filter = 0L;
    00140 }
    00141
    00142
    00143 void KMultiPart::startHeader()
    00144 {
    00145     m_bParsingHeader = true; // we expect a header to come first
    00146     m_bGotAnyHeader = false;
    00147     m_gzip = false;
    00148     // just to be sure for now
    00149     delete m_filter;
    00150     m_filter = 0L;
    00151 }
    00152
    00153
    00154 bool KMultiPart::openURL( const KURL &url )
    00155 {
    00156     m_url = url;
    00157     m_lineParser->reset();
    00158     startHeader();
    00159
    00160     KParts::URLArgs args = m_extension->urlArgs();
    00161     //m_mimeType = args.serviceType;
    00162
    00163     // Hmm, args.reload is set to true when reloading, but this doesn't seem to be enough...
    00164     // I get "HOLD: Reusing held slave for <url>", and the old data
    00165
    00166     m_job = KIO::get( url, args.reload, false );
    00167
    00168     emit started( 0 /*m_job*/ ); // don't pass the job, it would interfer with our own infoMessage
    00169
    00170     connect( m_job, SIGNAL( result( KIO::Job * ) ),
    00171              this, SLOT( slotJobFinished( KIO::Job * ) ) );
    00172     connect( m_job, SIGNAL( data( KIO::Job *, const QByteArray & ) ),
    00173              this, SLOT( slotData( KIO::Job *, const QByteArray & ) ) );
    00174
    00175     m_numberOfFrames = 0;
    00176     m_numberOfFramesSkipped = 0;
    00177     m_totalNumberOfFrames = 0;
    00178     m_qtime.start();
    00179     m_timer->start( 1000 ); //1s
    00180
    00181     return true;
    00182 }
    00183
    00184 // Yes, libkdenetwork's has such a parser already (MultiPart),
    00185 // but it works on the complete string, expecting the whole data to be available....
    00186 // The version here is asynchronous.
    00187 void KMultiPart::slotData( KIO::Job *job, const QByteArray &data )
    00188 {
    00189     if (m_boundary.isNull())
    00190     {
    00191        QString tmp = job->queryMetaData("media-boundary");
    00192        kdDebug() << "Got Boundary from kio-http '" << tmp << "'" << endl;
    00193        if ( !tmp.isEmpty() ) {
    00194            m_boundary = QCString("--")+tmp.latin1();
    00195            m_boundaryLength = m_boundary.length();
    00196        }
    00197     }
    00198     // Append to m_currentLine until eol
    00199     for ( uint i = 0; i < data.size() ; ++i )
    00200     {
    00201         // Store char. Skip if '\n' and currently parsing a header.
    00202         m_lineParser->addChar( data[i], !m_bParsingHeader );
    00203         if ( m_lineParser->isLineComplete() )
    00204         {
    00205             QByteArray lineData = m_lineParser->currentLine();
    00206 #ifdef DEBUG_PARSING
    00207             kdDebug() << "lineData.size()=" << lineData.size() << endl;
    00208 #endif
    00209             QCString line( lineData.data(), lineData.size()+1 ); // deep copy
    00210             // 0-terminate the data, but only for the line-based tests below
    00211             // We want to keep the raw data in case it ends up in sendData()
    00212             int sz = line.size();
    00213             if ( sz > 0 )
    00214                 line[sz-1] = '\0';
    00215 #ifdef DEBUG_PARSING
    00216             kdDebug() << "[" << m_bParsingHeader << "] line='" << line << "'" << endl;
    00217 #endif
    00218             if ( m_bParsingHeader )
    00219             {
    00220                 if ( !line.isEmpty() )
    00221                     m_bGotAnyHeader = true;
    00222                 if ( m_boundary.isNull() )
    00223                 {
    00224                     if ( !line.isEmpty() ) {
    00225 #ifdef DEBUG_PARSING
    00226                         kdDebug() << "Boundary is " << line << endl;
    00227 #endif
    00228                         m_boundary = line;
    00229                         m_boundaryLength = m_boundary.length();
    00230                     }
    00231                 }
    00232                 else if ( !qstrnicmp( line.data(), "Content-Encoding:", 17 ) )
    00233                 {
    00234                     QString encoding = QString::fromLatin1(line.data()+17).stripWhiteSpace().lower();
    00235                     if (encoding == "gzip" || encoding == "x-gzip") {
    00236                         m_gzip = true;
    00237                     } else {
    00238                         kdDebug() << "FIXME: unhandled encoding type in KMultiPart: " << encoding << endl;
    00239                     }
    00240                 }
    00241                 // parse Content-Type
    00242                 else if ( !qstrnicmp( line.data(), "Content-Type:", 13 ) )
    00243                 {
    00244                     Q_ASSERT( m_nextMimeType.isNull() );
    00245                     m_nextMimeType = QString::fromLatin1( line.data() + 14 ).stripWhiteSpace();
    00246                     int semicolon = m_nextMimeType.find( ';' );
    00247                     if ( semicolon != -1 )
    00248                         m_nextMimeType = m_nextMimeType.left( semicolon );
    00249                     kdDebug() << "m_nextMimeType=" << m_nextMimeType << endl;
    00250                 }
    00251                 // Empty line, end of headers (if we had any header line before)
    00252                 else if ( line.isEmpty() && m_bGotAnyHeader )
    00253                 {
    00254                     m_bParsingHeader = false;
    00255 #ifdef DEBUG_PARSING
    00256                     kdDebug() << "end of headers" << endl;
    00257 #endif
    00258                     startOfData();
    00259                 }
    00260                 // First header (when we know it from kio_http)
    00261                 else if ( line == m_boundary )
    00262                     ; // nothing to do
    00263                 else if ( !line.isEmpty() ) // this happens with e.g. Set-Cookie:
    00264                     kdDebug() << "Ignoring header " << line << endl;
    00265             } else {
    00266                 if ( !qstrncmp( line, m_boundary, m_boundaryLength ) )
    00267                 {
    00268 #ifdef DEBUG_PARSING
    00269                     kdDebug() << "boundary found!" << endl;
    00270                     kdDebug() << "after it is " << line.data() + m_boundaryLength << endl;
    00271 #endif
    00272                     // Was it the very last boundary ?
    00273                     if ( !qstrncmp( line.data() + m_boundaryLength, "--", 2 ) )
    00274                     {
    00275 #ifdef DEBUG_PARSING
    00276                         kdDebug() << "Completed!" << endl;
    00277 #endif
    00278                         endOfData();
    00279                         emit completed();
    00280                     } else
    00281                     {
    00282                         char nextChar = *(line.data() + m_boundaryLength);
    00283 #ifdef DEBUG_PARSING
    00284                         kdDebug() << "KMultiPart::slotData nextChar='" << nextChar << "'" << endl;
    00285 #endif
    00286                         if ( nextChar == '\n' || nextChar == '\r' ) {
    00287                             endOfData();
    00288                             startHeader();
    00289                         }
    00290                         else {
    00291                             // otherwise, false hit, it has trailing stuff
    00292                             sendData( lineData );
    00293                         }
    00294                     }
    00295                 } else {
    00296                     // send to part
    00297                     sendData( lineData );
    00298                 }
    00299             }
    00300             m_lineParser->clearLine();
    00301         }
    00302     }
    00303 }
    00304
    00305 void KMultiPart::setPart( const QString& mimeType )
    00306 {
    00307     KXMLGUIFactory *guiFactory = factory();
    00308     if ( guiFactory ) // seems to be 0 when restoring from SM
    00309         guiFactory->removeClient( this );
    00310     kdDebug() << "KMultiPart::setPart " << mimeType << endl;
    00311     delete m_part;
    00312     // Try to find an appropriate viewer component
    00313     m_part = KParts::ComponentFactory::createPartInstanceFromQuery<KParts::ReadOnlyPart>
    00314              ( m_mimeType, QString::null, widget(), 0L, this, 0L );
    00315     if ( !m_part ) {
    00316         // TODO launch external app
    00317         KMessageBox::error( widget(), i18n("No handler found for %1!").arg(m_mimeType) );
    00318         return;
    00319     }
    00320     // By making the part a child XMLGUIClient of ours, we get its GUI merged in.
    00321     insertChildClient( m_part );
    00322     m_part->widget()->show();
    00323
    00324     connect( m_part, SIGNAL( completed() ),
    00325              this, SLOT( slotPartCompleted() ) );
    00326
    00327     m_isHTMLPart = ( mimeType == "text/html" );
    00328     KParts::BrowserExtension* childExtension = KParts::BrowserExtension::childObject( m_part );
    00329
    00330     if ( childExtension )
    00331     {
    00332
    00333         // Forward signals from the part's browser extension
    00334         // this is very related (but not exactly like) KHTMLPart::processObjectRequest
    00335
    00336         connect( childExtension, SIGNAL( openURLNotify() ),
    00337                  m_extension, SIGNAL( openURLNotify() ) );
    00338
    00339         connect( childExtension, SIGNAL( openURLRequestDelayed( const KURL &, const KParts::URLArgs & ) ),
    00340                  m_extension, SIGNAL( openURLRequest( const KURL &, const KParts::URLArgs & ) ) );
    00341
    00342         connect( childExtension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ),
    00343                  m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ) );
    00344         connect( childExtension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs &, const KParts::WindowArgs &, KParts::ReadOnlyPart *& ) ),
    00345                  m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & , const KParts::WindowArgs &, KParts::ReadOnlyPart *&) ) );
    00346
    00347         // Keep in sync with khtml_part.cpp
    00348         connect( childExtension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ),
    00349                  m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ) );
    00350         connect( childExtension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ),
    00351                  m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ) );
    00352         connect( childExtension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags ) ),
    00353                  m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags ) ) );
    00354         connect( childExtension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ),
    00355                  m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ) );
    00356         connect( childExtension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ),
    00357                  m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ) );
    00358         connect( childExtension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t ) ),
    00359                  m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t ) ) );
    00360
    00361
    00362         if ( m_isHTMLPart )
    00363             connect( childExtension, SIGNAL( infoMessage( const QString & ) ),
    00364                      m_extension, SIGNAL( infoMessage( const QString & ) ) );
    00365         // For non-HTML we prefer to show our infoMessage ourselves.
    00366
    00367         childExtension->setBrowserInterface( m_extension->browserInterface() );
    00368
    00369         connect( childExtension, SIGNAL( enableAction( const char *, bool ) ),
    00370                  m_extension, SIGNAL( enableAction( const char *, bool ) ) );
    00371         connect( childExtension, SIGNAL( setLocationBarURL( const QString& ) ),
    00372                  m_extension, SIGNAL( setLocationBarURL( const QString& ) ) );
    00373         connect( childExtension, SIGNAL( setIconURL( const KURL& ) ),
    00374                  m_extension, SIGNAL( setIconURL( const KURL& ) ) );
    00375         connect( childExtension, SIGNAL( loadingProgress( int ) ),
    00376                  m_extension, SIGNAL( loadingProgress( int ) ) );
    00377         if ( m_isHTMLPart ) // for non-HTML we have our own
    00378             connect( childExtension, SIGNAL( speedProgress( int ) ),
    00379                      m_extension, SIGNAL( speedProgress( int ) ) );
    00380         connect( childExtension, SIGNAL( selectionInfo( const KFileItemList& ) ),
    00381                  m_extension, SIGNAL( selectionInfo( const KFileItemList& ) ) );
    00382         connect( childExtension, SIGNAL( selectionInfo( const QString& ) ),
    00383                  m_extension, SIGNAL( selectionInfo( const QString& ) ) );
    00384         connect( childExtension, SIGNAL( selectionInfo( const KURL::List& ) ),
    00385                  m_extension, SIGNAL( selectionInfo( const KURL::List& ) ) );
    00386         connect( childExtension, SIGNAL( mouseOverInfo( const KFileItem* ) ),
    00387                  m_extension, SIGNAL( mouseOverInfo( const KFileItem* ) ) );
    00388         connect( childExtension, SIGNAL( moveTopLevelWidget( int, int ) ),
    00389                  m_extension, SIGNAL( moveTopLevelWidget( int, int ) ) );
    00390         connect( childExtension, SIGNAL( resizeTopLevelWidget( int, int ) ),
    00391                  m_extension, SIGNAL( resizeTopLevelWidget( int, int ) ) );
    00392     }
    00393
    00394     m_partIsLoading = false;
    00395     // Load the part's plugins too.
    00396     // ###### This is a hack. The bug is that KHTMLPart doesn't load its plugins
    00397     // if className != "Browser/View".
    00398     loadPlugins( this, m_part, m_part->instance() );
    00399     // Get the part's GUI to appear
    00400     if ( guiFactory )
    00401         guiFactory->addClient( this );
    00402 }
    00403
    00404 void KMultiPart::startOfData()
    00405 {
    00406     kdDebug() << "KMultiPart::startOfData" << endl;
    00407     Q_ASSERT( !m_nextMimeType.isNull() );
    00408     if( m_nextMimeType.isNull() )
    00409         return;
    00410
    00411     if ( m_gzip )
    00412     {
    00413         m_filter = new HTTPFilterGZip;
    00414         connect( m_filter, SIGNAL( output( const QByteArray& ) ), this, SLOT( reallySendData( const QByteArray& ) ) );
    00415     }
    00416
    00417     if ( m_mimeType != m_nextMimeType )
    00418     {
    00419         // Need to switch parts (or create the initial one)
    00420         m_mimeType = m_nextMimeType;
    00421         setPart( m_mimeType );
    00422     }
    00423     Q_ASSERT( m_part );
    00424     // Pass URLArgs (e.g. reload)
    00425     KParts::BrowserExtension* childExtension = KParts::BrowserExtension::childObject( m_part );
    00426     if ( childExtension )
    00427         childExtension->setURLArgs( m_extension->urlArgs() );
    00428
    00429     m_nextMimeType = QString::null;
    00430     if ( m_tempFile ) {
    00431         m_tempFile->setAutoDelete( true );
    00432         delete m_tempFile;
    00433         m_tempFile = 0;
    00434     }
    00435     if ( m_isHTMLPart )
    00436     {
    00437         KHTMLPart* htmlPart = static_cast<KHTMLPart *>( static_cast<KParts::ReadOnlyPart *>( m_part ) );
    00438         htmlPart->begin( url() );
    00439     }
    00440     else
    00441     {
    00442         // ###### TODO use a QByteArray and a data: URL instead
    00443         m_tempFile = new KTempFile;
    00444     }
    00445 }
    00446
    00447 void KMultiPart::sendData( const QByteArray& line )
    00448 {
    00449     if ( m_filter )
    00450     {
    00451         m_filter->slotInput( line );
    00452     }
    00453     else
    00454     {
    00455         reallySendData( line );
    00456     }
    00457 }
    00458
    00459 void KMultiPart::reallySendData( const QByteArray& line )
    00460 {
    00461     if ( m_isHTMLPart )
    00462     {
    00463         KHTMLPart* htmlPart = static_cast<KHTMLPart *>( static_cast<KParts::ReadOnlyPart *>( m_part ) );
    00464         htmlPart->write( line.data(), line.size() );
    00465     }
    00466     else if ( m_tempFile )
    00467     {
    00468         m_tempFile->file()->writeBlock( line.data(), line.size() );
    00469     }
    00470 }
    00471
    00472 void KMultiPart::endOfData()
    00473 {
    00474     Q_ASSERT( m_part );
    00475     if ( m_isHTMLPart )
    00476     {
    00477         KHTMLPart* htmlPart = static_cast<KHTMLPart *>( static_cast<KParts::ReadOnlyPart *>( m_part ) );
    00478         htmlPart->end();
    00479     } else if ( m_tempFile )
    00480     {
    00481         m_tempFile->close();
    00482         if ( m_partIsLoading )
    00483         {
    00484             // The part is still loading the last data! Let it proceed then
    00485             // Otherwise we'd keep cancelling it, and nothing would ever show up...
    00486             kdDebug() << "KMultiPart::endOfData part isn't ready, skipping frame" << endl;
    00487             ++m_numberOfFramesSkipped;
    00488             m_tempFile->setAutoDelete( true );
    00489         }
    00490         else
    00491         {
    00492             kdDebug() << "KMultiPart::endOfData opening " << m_tempFile->name() << endl;
    00493             KURL url;
    00494             url.setPath( m_tempFile->name() );
    00495             m_partIsLoading = true;
    00496             (void) m_part->openURL( url );
    00497         }
    00498         delete m_tempFile;
    00499         m_tempFile = 0L;
    00500     }
    00501 }
    00502
    00503 void KMultiPart::slotPartCompleted()
    00504 {
    00505     if ( !m_isHTMLPart )
    00506     {
    00507         Q_ASSERT( m_part );
    00508         // Delete temp file used by the part
    00509         Q_ASSERT( m_part->url().isLocalFile() );
    00510     kdDebug() << "slotPartCompleted deleting " << m_part->url().path() << endl;
    00511         (void) unlink( QFile::encodeName( m_part->url().path() ) );
    00512         m_partIsLoading = false;
    00513         ++m_numberOfFrames;
    00514         // Do not emit completed from here.
    00515     }
    00516 }
    00517
    00518 bool KMultiPart::closeURL()
    00519 {
    00520     m_timer->stop();
    00521     if ( m_part )
    00522         return m_part->closeURL();
    00523     return true;
    00524 }
    00525
    00526 void KMultiPart::guiActivateEvent( KParts::GUIActivateEvent * )
    00527 {
    00528     // Not public!
    00529     //if ( m_part )
    00530     //    m_part->guiActivateEvent( e );
    00531 }
    00532
    00533 void KMultiPart::slotJobFinished( KIO::Job *job )
    00534 {
    00535     if ( job->error() )
    00536     {
    00537         // TODO use khtml's error:// scheme
    00538         job->showErrorDialog();
    00539         emit canceled( job->errorString() );
    00540     }
    00541     else
    00542     {
    00543         /*if ( m_khtml->view()->contentsY() == 0 )
    00544         {
    00545             KParts::URLArgs args = m_ext->urlArgs();
    00546             m_khtml->view()->setContentsPos( args.xOffset, args.yOffset );
    00547         }*/
    00548
    00549         emit completed();
    00550
    00551         //QTimer::singleShot( 0, this, SLOT( updateWindowCaption() ) );
    00552     }
    00553     m_job = 0L;
    00554 }
    00555
    00556 void KMultiPart::slotProgressInfo()
    00557 {
    00558     int time = m_qtime.elapsed();
    00559     if ( !time ) return;
    00560     if ( m_totalNumberOfFrames == m_numberOfFrames + m_numberOfFramesSkipped )
    00561         return; // No change, don't overwrite statusbar messages if any
    00562     //kdDebug() << m_numberOfFrames << " in " << time << " milliseconds" << endl;
    00563     QString str( "%1 frames per second, %2 frames skipped per second" );
    00564     str = str.arg( 1000.0 * (double)m_numberOfFrames / (double)time );
    00565     str = str.arg( 1000.0 * (double)m_numberOfFramesSkipped / (double)time );
    00566     m_totalNumberOfFrames = m_numberOfFrames + m_numberOfFramesSkipped;
    00567     //kdDebug() << str << endl;
    00568     emit m_extension->infoMessage( str );
    00569 }
    00570
    00571 KAboutData* KMultiPart::createAboutData()
    00572 {
    00573     KAboutData* aboutData = new KAboutData( "kmultipart", I18N_NOOP("KMultiPart"),
    00574                                              "0.1",
    00575                                             I18N_NOOP( "Embeddable component for multipart/mixed" ),
    00576                                              KAboutData::License_GPL,
    00577                                              "(c) 2001, David Faure <david@mandrakesoft.com>");
    00578     return aboutData;
    00579 }
    00580
    00581 #if 0
    00582 KMultiPartBrowserExtension::KMultiPartBrowserExtension( KMultiPart *parent, const char *name )
    00583     : KParts::BrowserExtension( parent, name )
    00584 {
    00585     m_imgPart = parent;
    00586 }
    00587
    00588 int KMultiPartBrowserExtension::xOffset()
    00589 {
    00590     return m_imgPart->doc()->view()->contentsX();
    00591 }
    00592
    00593 int KMultiPartBrowserExtension::yOffset()
    00594 {
    00595     return m_imgPart->doc()->view()->contentsY();
    00596 }
    00597
    00598 void KMultiPartBrowserExtension::print()
    00599 {
    00600     static_cast<KHTMLPartBrowserExtension *>( m_imgPart->doc()->browserExtension() )->print();
    00601 }
    00602
    00603 void KMultiPartBrowserExtension::reparseConfiguration()
    00604 {
    00605     static_cast<KHTMLPartBrowserExtension *>( m_imgPart->doc()->browserExtension() )->reparseConfiguration();
    00606     m_imgPart->doc()->setAutoloadImages( true );
    00607 }
    00608 #endif
    00609
    00610 #include "kmultipart.moc"

This file is part of the documentation for khtml Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:33:19 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003