📄 loader.cpp
字号:
/* This file is part of the KDE libraries Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) Copyright (C) 2001 Dirk Mueller (mueller@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. This class provides all functionality needed for loading images, style sheets and html pages from the web. It has a memory cache for these objects.*/#undef CACHE_DEBUG//#define CACHE_DEBUG#include "loader.h"// up to which size is a picture for sure cacheable#define MAXCACHEABLE 40*1024// default cache size#define DEFCACHESIZE 512*1024#include <qasyncio.h>#include <qasyncimageio.h>#include <qpainter.h>#include <qbitmap.h>#include <qmovie.h>#include <kio/job.h>#include <kio/jobclasses.h>#include <kglobal.h>#include <kimageio.h>#include <kcharsets.h>#include <kiconloader.h>#include <scheduler.h>#include <kdebug.h>#include "khtml_factory.h"#include "khtml_part.h"#include "css/css_stylesheetimpl.h"using namespace khtml;using namespace DOM;void CachedObject::finish(){ if( m_size > MAXCACHEABLE ) { m_status = Uncacheable; //Cache::flush(true); // Force flush. } else m_status = Cached; KURL url(m_url.string()); if (m_expireDate && url.protocol().startsWith("http")) { KIO::http_update_cache(url, false, m_expireDate);#ifdef CACHE_DEBUG kdDebug(6060) << " Setting expire date for image "<<m_url.string()<<" to " << m_expireDate << endl;#endif }#ifdef CACHE_DEBUG else kdDebug(6060) << " No expire date for image "<<m_url.string()<<endl;#endif}void CachedObject::setExpireDate(int _expireDate){ // assert(_expireDate); if ( _expireDate != m_expireDate && (m_status == Uncacheable || m_status == Cached)) { finish(); } m_expireDate = _expireDate;}void CachedObject::setRequest(Request *_request){ if ( _request && !m_request ) m_status = Pending; m_request = _request; if (canDelete() && m_free) delete this;}// -------------------------------------------------------------------------------------------CachedCSSStyleSheet::CachedCSSStyleSheet(const DOMString &url, const DOMString &baseURL, bool reload, int _expireDate, const QString& charset) : CachedObject(url, CSSStyleSheet, reload, _expireDate){ // It's css we want. setAccept( QString::fromLatin1("text/css") ); // load the file Cache::loader()->load(this, baseURL, false); loading = true; bool b; m_codec = KGlobal::charsets()->codecForName(charset, b);}CachedCSSStyleSheet::~CachedCSSStyleSheet(){}void CachedCSSStyleSheet::ref(CachedObjectClient *c){ // make sure we don't get it twice... m_clients.remove(c); m_clients.append(c); if(!loading) c->setStyleSheet( m_url, m_sheet );}void CachedCSSStyleSheet::deref(CachedObjectClient *c){ m_clients.remove(c); if ( canDelete() && m_free ) delete this;}void CachedCSSStyleSheet::data( QBuffer &buffer, bool eof ){ if(!eof) return; buffer.close(); m_size = buffer.buffer().size(); QString data = m_codec->toUnicode( buffer.buffer().data(), m_size ); m_sheet = DOMString(data); loading = false; checkNotify();}void CachedCSSStyleSheet::checkNotify(){ if(loading) return;#ifdef CACHE_DEBUG kdDebug( 6060 ) << "CachedCSSStyleSheet:: finishedLoading " << m_url.string() << endl;#endif CachedObjectClient *c; for ( c = m_clients.first(); c != 0; c = m_clients.next() ) c->setStyleSheet( m_url, m_sheet );}void CachedCSSStyleSheet::error( int /*err*/, const char */*text*/ ){ loading = false; checkNotify();}// -------------------------------------------------------------------------------------------CachedScript::CachedScript(const DOMString &url, const DOMString &baseURL, bool reload, int _expireDate, const QString& charset) : CachedObject(url, Script, reload, _expireDate){ // It's javascript we want. setAccept( QString::fromLatin1("application/x-javascript") ); // load the file Cache::loader()->load(this, baseURL, false); loading = true; bool b; m_codec = KGlobal::charsets()->codecForName(charset, b);}CachedScript::~CachedScript(){}void CachedScript::ref(CachedObjectClient *c){ // make sure we don't get it twice... m_clients.remove(c); m_clients.append(c); if(!loading) c->notifyFinished(this);}void CachedScript::deref(CachedObjectClient *c){ m_clients.remove(c); if ( canDelete() && m_free ) delete this;}void CachedScript::data( QBuffer &buffer, bool eof ){ if(!eof) return; buffer.close(); m_size = buffer.buffer().size(); QString data = m_codec->toUnicode( buffer.buffer().data(), m_size ); m_script = DOMString(data); loading = false; checkNotify();}void CachedScript::checkNotify(){ if(loading) return; CachedObjectClient *c; for ( c = m_clients.first(); c != 0; c = m_clients.next() ) c->notifyFinished(this);}void CachedScript::error( int /*err*/, const char */*text*/ ){ loading = false; checkNotify();}// ------------------------------------------------------------------------------------------namespace khtml{ class ImageSource : public QDataSource { public: ImageSource(QByteArray buf); /** * Overload QDataSource::readyToSend() and returns the number * of bytes ready to send if not eof instead of returning -1. */ int readyToSend(); /*! Reads and sends a block of data. */ void sendTo(QDataSink*, int count); /** * Sets the EOF state. */ void setEOF( bool state ); /*! KHTMLImageSource's is rewindable. */ bool rewindable() const; /*! Enables rewinding. No special action is taken. */ void enableRewind(bool on); /* Calls reset() on the QIODevice. */ void rewind(); /* Indicates that the buffered data is no longer needed. */ void cleanBuffer(); QByteArray buffer; unsigned int pos; private: bool eof : 1; bool rew : 1; bool rewable : 1; };}/*! This Class defines the DataSource for incremental loading of images.*/ImageSource::ImageSource(QByteArray buf){ buffer = buf; rew = false; pos = 0; eof = false; rewable = true;}/** * Overload QDataSource::readyToSend() and returns the number * of bytes ready to send if not eof instead of returning -1.*/int ImageSource::readyToSend(){ if(eof && pos == buffer.size()) return -1; return buffer.size() - pos;}/*! Reads and sends a block of data.*/void ImageSource::sendTo(QDataSink* sink, int n){ sink->receive((const uchar*)&buffer.at(pos), n); pos += n; // buffer is no longer needed if(eof && pos == buffer.size() && !rewable) { buffer.resize(0); pos = 0; }}/** * Sets the EOF state. */void ImageSource::setEOF( bool state ){ eof = state;}// ImageSource's is rewindable.bool ImageSource::rewindable() const{ return rewable;}// Enables rewinding. No special action is taken.void ImageSource::enableRewind(bool on){ rew = on;}// Calls reset() on the QIODevice.void ImageSource::rewind(){ pos = 0; if (!rew) { QDataSource::rewind(); } else ready();}void ImageSource::cleanBuffer(){ // if we need to be able to rewind, buffer is needed if(rew) return; rewable = false; // buffer is no longer needed if(eof && pos == buffer.size()) { buffer.resize(0); pos = 0; }}static QString buildAcceptHeader(){ QString result = KImageIO::mimeTypes( KImageIO::Reading ).join(", "); if (result.right(2) == ", ") result = result.left(result.length()-2); return result;}// -------------------------------------------------------------------------------------CachedImage::CachedImage(const DOMString &url, const DOMString &baseURL, bool reload, int _expireDate) : QObject(), CachedObject(url, Image, reload, _expireDate){ static const QString &acceptHeader = KGlobal::staticQString( buildAcceptHeader() ); m = 0; p = 0; pixPart = 0; bg = 0; bgColor = qRgba( 0, 0, 0, 0xFF ); typeChecked = false; isFullyTransparent = false; errorOccured = false; monochrome = false; formatType = 0; m_status = Unknown; m_size = 0; imgSource = 0; m_baseURL = baseURL; setAccept( acceptHeader );}CachedImage::~CachedImage(){ clear();}void CachedImage::ref( CachedObjectClient *c ){#ifdef CACHE_DEBUG kdDebug( 6060 ) << this << " CachedImage::ref(" << c << ") " << endl;#endif // make sure we don't get it twice... m_clients.remove(c); m_clients.append(c); if( m ) { m->unpause(); if( m->finished() ) m->restart(); } // for mouseovers, dynamic changes if ( m_status >= Persistent && !valid_rect().isNull() ) c->setPixmap( pixmap(), valid_rect(), this, 0L);}void CachedImage::deref( CachedObjectClient *c ){#ifdef CACHE_DEBUG kdDebug( 6060 ) << this << " CachedImage::deref(" << c << ") " << endl;#endif m_clients.remove( c ); if(m && m_clients.isEmpty() && m->running()) m->pause(); if ( canDelete() && m_free ) delete this;}#define BGMINWIDTH 32#define BGMINHEIGHT 32const QPixmap &CachedImage::tiled_pixmap(const QColor& newc){ if ( newc.rgb() != bgColor ) { delete bg; bg = 0; } if (bg) return *bg; const QPixmap &r = pixmap(); if (r.isNull()) return r; // no error indication for background images if(errorOccured) return *Cache::nullPixmap;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -