28 #include <QtCore/QFile>
36 #include <QtCore/QTimer>
43 ki18n(
"Embeddable component for multipart/mixed" ),
45 ki18n(
"Copyright 2001-2011, David Faure <email>faure@kde.org</email>"));
58 m_lineComplete =
false;
60 void addChar(
char c,
bool storeNewline ) {
61 if ( !storeNewline && c ==
'\r' )
63 Q_ASSERT( !m_lineComplete );
64 if ( storeNewline || c !=
'\n' ) {
65 int sz = m_currentLine.size();
66 m_currentLine.resize( sz+1 );
67 m_currentLine[sz] = c;
70 m_lineComplete =
true;
72 bool isLineComplete()
const {
73 return m_lineComplete;
75 QByteArray currentLine()
const {
79 Q_ASSERT( m_lineComplete );
83 m_currentLine.resize( 0 );
84 m_lineComplete =
false;
87 QByteArray m_currentLine;
109 QObject *parent,
const QVariantList& )
110 : KParts::ReadOnlyPart( parent )
122 m_isHTMLPart =
false;
124 m_lineParser =
new KLineParser;
127 m_timer =
new QTimer(
this );
128 connect( m_timer, SIGNAL(
timeout()),
this, SLOT(slotProgressInfo()) );
145 m_tempFile->setAutoRemove(
true );
153 void KMultiPart::startHeader()
155 m_bParsingHeader =
true;
156 m_bGotAnyHeader =
false;
167 m_lineParser->reset();
181 connect( m_job, SIGNAL(result(
KJob*)),
182 this, SLOT(slotJobFinished(
KJob*)) );
183 connect( m_job, SIGNAL(data(
KIO::Job*,QByteArray)),
184 this, SLOT(slotData(
KIO::Job*,QByteArray)) );
186 m_numberOfFrames = 0;
187 m_numberOfFramesSkipped = 0;
188 m_totalNumberOfFrames = 0;
190 m_timer->start( 1000 );
198 void KMultiPart::slotData(
KIO::Job *job,
const QByteArray &data )
200 if (m_boundary.isNull())
202 QString tmp = job->queryMetaData(
"media-boundary");
203 kDebug() <<
"Got Boundary from kio-http '" << tmp <<
"'";
204 if ( !tmp.isEmpty() ) {
217 if (tmp.startsWith(QLatin1String(
"--")) &&
218 job->queryMetaData(
"media-boundary-kio-quoted") !=
"true")
219 m_boundary = tmp.toLatin1();
221 m_boundary = QByteArray(
"--")+tmp.toLatin1();
222 m_boundaryLength = m_boundary.length();
226 for (
int i = 0; i < data.size() ; ++i )
229 m_lineParser->addChar( data[i], !m_bParsingHeader );
230 if ( m_lineParser->isLineComplete() )
232 QByteArray line = m_lineParser->currentLine();
234 kDebug() <<
"line.size()=" << line.size();
237 kDebug() <<
"[" << m_bParsingHeader <<
"] line='" << line <<
"'";
239 if ( m_bParsingHeader )
241 if ( !line.isEmpty() )
242 m_bGotAnyHeader =
true;
243 if ( m_boundary.isNull() )
245 if ( !line.isEmpty() ) {
247 kDebug() <<
"Boundary is " << line;
250 m_boundaryLength = m_boundary.length();
253 else if ( !qstrnicmp( line.data(),
"Content-Encoding:", 17 ) )
255 QString encoding = QString::fromLatin1(line.data()+17).trimmed().toLower();
256 if (encoding ==
"gzip" || encoding ==
"x-gzip") {
259 kDebug() <<
"FIXME: unhandled encoding type in KMultiPart: " << encoding;
263 else if ( !qstrnicmp( line.data(),
"Content-Type:", 13 ) )
265 Q_ASSERT( m_nextMimeType.isNull() );
266 m_nextMimeType = QString::fromLatin1( line.data() + 14 ).trimmed();
267 int semicolon = m_nextMimeType.indexOf(
';' );
268 if ( semicolon != -1 )
269 m_nextMimeType = m_nextMimeType.left( semicolon );
270 kDebug() <<
"m_nextMimeType=" << m_nextMimeType;
273 else if ( line.isEmpty() && m_bGotAnyHeader )
275 m_bParsingHeader =
false;
277 kDebug() <<
"end of headers";
282 else if ( line == m_boundary )
284 else if ( !line.isEmpty() )
285 kDebug() <<
"Ignoring header " << line;
287 if ( !qstrncmp( line, m_boundary, m_boundaryLength ) )
290 kDebug() <<
"boundary found!";
291 kDebug() <<
"after it is " << line.data() + m_boundaryLength;
294 if ( !qstrncmp( line.data() + m_boundaryLength,
"--", 2 ) )
303 char nextChar = *(line.data() + m_boundaryLength);
305 kDebug() <<
"KMultiPart::slotData nextChar='" << nextChar <<
"'";
307 if ( nextChar ==
'\n' || nextChar ==
'\r' ) {
321 m_lineParser->clearLine();
331 kDebug() <<
"KMultiPart::setPart " << mimeType;
334 m_part = KMimeTypeTrader::createPartInstanceFromQuery<KParts::ReadOnlyPart>
335 ( m_mimeType,
widget(), this );
343 m_part->widget()->show();
346 this, SLOT(slotPartCompleted()) );
347 connect( m_part, SIGNAL(
completed(
bool)),
348 this, SLOT(slotPartCompleted()) );
350 m_isHTMLPart = ( mimeType ==
"text/html" );
353 if ( childExtension )
359 connect( childExtension, SIGNAL(openUrlNotify()),
360 m_extension, SIGNAL(openUrlNotify()) );
375 connect( childExtension, SIGNAL(infoMessage(
QString)),
376 m_extension, SIGNAL(infoMessage(
QString)) );
381 connect( childExtension, SIGNAL(enableAction(
const char*,
bool)),
382 m_extension, SIGNAL(enableAction(
const char*,
bool)) );
383 connect( childExtension, SIGNAL(setLocationBarUrl(
QString)),
384 m_extension, SIGNAL(setLocationBarUrl(
QString)) );
385 connect( childExtension, SIGNAL(setIconUrl(
KUrl)),
386 m_extension, SIGNAL(setIconUrl(
KUrl)) );
387 connect( childExtension, SIGNAL(loadingProgress(
int)),
388 m_extension, SIGNAL(loadingProgress(
int)) );
390 connect( childExtension, SIGNAL(speedProgress(
int)),
391 m_extension, SIGNAL(speedProgress(
int)) );
392 connect( childExtension, SIGNAL(selectionInfo(
KFileItemList)),
394 connect( childExtension, SIGNAL(selectionInfo(
QString)),
395 m_extension, SIGNAL(selectionInfo(
QString)) );
396 connect( childExtension, SIGNAL(selectionInfo(
KUrl::List)),
397 m_extension, SIGNAL(selectionInfo(
KUrl::List)) );
398 connect( childExtension, SIGNAL(mouseOverInfo(
KFileItem)),
399 m_extension, SIGNAL(mouseOverInfo(
KFileItem)) );
400 connect( childExtension, SIGNAL(moveTopLevelWidget(
int,
int)),
401 m_extension, SIGNAL(moveTopLevelWidget(
int,
int)) );
402 connect( childExtension, SIGNAL(resizeTopLevelWidget(
int,
int)),
403 m_extension, SIGNAL(resizeTopLevelWidget(
int,
int)) );
406 m_partIsLoading =
false;
410 loadPlugins(
this, m_part, m_part->componentData() );
418 kDebug() <<
"KMultiPart::startOfData";
419 Q_ASSERT( !m_nextMimeType.isNull() );
420 if( m_nextMimeType.isNull() )
429 connect(m_filter, SIGNAL(
output(QByteArray)),
this, SLOT(reallySendData(QByteArray)));
432 if ( m_mimeType != m_nextMimeType )
435 m_mimeType = m_nextMimeType;
442 if ( childExtension )
445 m_nextMimeType.clear();
447 m_tempFile->setAutoRemove(
true );
472 reallySendData( line );
476 void KMultiPart::reallySendData(
const QByteArray& line )
481 htmlPart->
write( line.data(), line.size() );
483 else if ( m_tempFile )
485 m_tempFile->write( line.data(), line.size() );
496 }
else if ( m_tempFile )
498 const QString tempFileName = m_tempFile->fileName();
500 if ( m_partIsLoading )
504 kDebug() <<
"KMultiPart::endOfData part isn't ready, skipping frame";
505 ++m_numberOfFramesSkipped;
506 m_tempFile->setAutoRemove(
true );
510 kDebug() <<
"KMultiPart::endOfData opening " << tempFileName;
512 m_partIsLoading =
true;
513 (void) m_part->openUrl( url );
520 void KMultiPart::slotPartCompleted()
526 Q_ASSERT( m_part->url().isLocalFile() );
527 kDebug() <<
"slotPartCompleted deleting " << m_part->url().toLocalFile();
528 (void) unlink( QFile::encodeName( m_part->url().toLocalFile() ) );
529 m_partIsLoading =
false;
539 return m_part->closeUrl();
550 void KMultiPart::slotJobFinished(
KJob *job )
555 job->uiDelegate()->showErrorMessage();
556 emit
canceled( job->errorString() );
573 void KMultiPart::slotProgressInfo()
575 int time = m_qtime.elapsed();
577 if ( m_totalNumberOfFrames == m_numberOfFrames + m_numberOfFramesSkipped )
580 QString str(
"%1 frames per second, %2 frames skipped per second" );
581 str = str.arg( 1000.0 * (
double)m_numberOfFrames / (
double)time );
582 str = str.arg( 1000.0 * (
double)m_numberOfFramesSkipped / (
double)time );
583 m_totalNumberOfFrames = m_numberOfFrames + m_numberOfFramesSkipped;
590 KMultiPartBrowserExtension::KMultiPartBrowserExtension(
KMultiPart *parent,
const char *name )
591 : KParts::BrowserExtension( parent, name )
596 int KMultiPartBrowserExtension::xOffset()
598 return m_imgPart->doc()->view()->contentsX();
601 int KMultiPartBrowserExtension::yOffset()
603 return m_imgPart->doc()->view()->contentsY();
606 void KMultiPartBrowserExtension::print()
611 void KMultiPartBrowserExtension::reparseConfiguration()
614 m_imgPart->doc()->setAutoloadImages(
true );
618 #include "kmultipart.moc"
QString i18n(const char *text)
KAction * print(const QObject *recvr, const char *slot, QObject *parent)
virtual void guiActivateEvent(KParts::GUIActivateEvent *e)
void removeClient(KXMLGUIClient *client)
void setBrowserInterface(BrowserInterface *impl)
KLocalizedString ki18n(const char *msg)
K_PLUGIN_FACTORY(ProxyScoutFactory, registerPlugin< KPAC::ProxyScout >();) namespace KPAC
void addClient(KXMLGUIClient *client)
TransferJob * get(const KUrl &url, LoadType reload=NoReload, JobFlags flags=DefaultFlags)
This class is khtml's main class.
static KAboutData kmultipartAboutData()
virtual QWidget * widget()
KXMLGUIFactory * factory() const
void setUrl(const KUrl &url)
K_EXPORT_PLUGIN(KMultiPartFactory(kmultipartAboutData())) class KLineParser
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
BrowserArguments browserArguments() const
KMultiPart(QWidget *parentWidget, QObject *parent, const QVariantList &)
http://wp.netscape.com/assist/net_sites/pushpull.html
void sendData(const QByteArray &line)
void canceled(const QString &errMsg)
void output(QList< Action > actions, QHash< QString, QString > domain)
static BrowserExtension * childObject(QObject *obj)
virtual void begin(const KUrl &url=KUrl(), int xOffset=0, int yOffset=0)
Clears the widget and prepares it for new content.
virtual void setComponentData(const KComponentData &componentData)
virtual void write(const char *str, int len=-1)
Writes another part of the HTML code to the widget.
BrowserInterface * browserInterface() const
const KShortcut & reload()
void infoMessage(const QString &)
void setPart(const QString &mimeType)
OpenUrlArguments arguments() const
virtual void setWidget(QWidget *widget)
virtual bool openUrl(const KUrl &url)
virtual void slotInput(const QByteArray &d)=0
virtual void end()
Call this after your last call to write().
This is the BrowserExtension for a KHTMLPart document.
void insertChildClient(KXMLGUIClient *child)
virtual void setBrowserArguments(const BrowserArguments &args)
static void error(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Notify)