diff options
Diffstat (limited to 'tdehtml/misc/loader.h')
-rw-r--r-- | tdehtml/misc/loader.h | 522 |
1 files changed, 522 insertions, 0 deletions
diff --git a/tdehtml/misc/loader.h b/tdehtml/misc/loader.h new file mode 100644 index 000000000..97e637120 --- /dev/null +++ b/tdehtml/misc/loader.h @@ -0,0 +1,522 @@ +/* + This file is part of the KDE libraries + + Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) + Copyright (C) 2001-2003 Dirk Mueller <mueller@kde.org> + Copyright (C) 2003 Apple Computer, Inc + + 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, 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. +*/ +#ifndef _tdehtml_loader_h +#define _tdehtml_loader_h + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <time.h> + +#include "loader_client.h" +#ifdef HAVE_LIBJPEG +#include "loader_jpeg.h" +#endif + +#include <stdlib.h> +#include <tqptrlist.h> +#include <tqobject.h> +#include <tqptrdict.h> +#include <tqdict.h> +#include <tqpixmap.h> +#include <tqbuffer.h> +#include <tqstringlist.h> +#include <tqtextcodec.h> +#include <tqtimer.h> + +#include <kurl.h> +#include <kio/global.h> + +#include <tdehtml_settings.h> +#include <dom/dom_string.h> + +class TQMovie; +class KHTMLPart; + +namespace TDEIO { + class Job; + class TransferJob; +} + +namespace DOM +{ + class CSSStyleSheetImpl; + class DocumentImpl; +} + +namespace tdehtml +{ + class CachedObject; + class Request; + class DocLoader; + + /** + * @internal + * + * A cached object. Classes who want to use this object should derive + * from CachedObjectClient, to get the function calls in case the requested data has arrived. + * + * This class also does the actual communication with kio and loads the file. + */ + class CachedObject + { + public: + enum Type { + Image, + CSSStyleSheet, + Script + }; + + enum Status { + Unknown, // let imagecache decide what to do with it + New, // inserting new image + Pending, // only partially loaded + Persistent, // never delete this pixmap + Cached // regular case + }; + + CachedObject(const DOM::DOMString &url, Type type, TDEIO::CacheControl _cachePolicy, int size) + : m_url(url), m_type(type), m_cachePolicy(_cachePolicy), + m_expireDate(0), m_size(size) + { + m_status = Pending; + m_accessCount = 0; + m_cachePolicy = _cachePolicy; + m_request = 0; + m_deleted = false; + m_free = false; + m_hadError = false; + m_wasBlocked = false; + m_prev = m_next = 0; + } + virtual ~CachedObject(); + + virtual void data( TQBuffer &buffer, bool eof) = 0; + virtual void error( int err, const char *text ) = 0; + + const DOM::DOMString &url() const { return m_url; } + Type type() const { return m_type; } + + virtual void ref(CachedObjectClient *consumer); + virtual void deref(CachedObjectClient *consumer); + + int count() const { return m_clients.count(); } + int accessCount() const { return m_accessCount; } + + void setStatus(Status s) { m_status = s; } + Status status() const { return m_status; } + + virtual void setCharset( const TQString& /*charset*/ ) {} + + TQTextCodec* codecForBuffer( const TQString& charset, const TQByteArray& buffer ) const; + + int size() const { return m_size; } + + bool isLoaded() const { return !m_loading; } + + bool free() const { return m_free; } + + TDEIO::CacheControl cachePolicy() const { return m_cachePolicy; } + + void setRequest(Request *_request); + + bool canDelete() const { return (m_clients.count() == 0 && !m_request); } + + void setExpireDate(time_t _expireDate) { m_expireDate = _expireDate; } + + bool isExpired() const; + + virtual bool schedule() const { return false; } + virtual void finish(); + + /** + * List of acceptable mimetypes separated by ",". A mimetype may contain a wildcard. + */ + // e.g. "text/*" + TQString accept() const { return m_accept; } + void setAccept(const TQString &_accept) { m_accept = _accept; } + + protected: + void setSize(int size); + TQPtrDict<CachedObjectClient> m_clients; + DOM::DOMString m_url; + TQString m_accept; + Request *m_request; + Type m_type; + Status m_status; + int m_accessCount; + TDEIO::CacheControl m_cachePolicy; + time_t m_expireDate; + int m_size; + bool m_deleted : 1; + bool m_loading : 1; + bool m_free : 1; + bool m_hadError : 1; + bool m_wasBlocked : 1; + + private: + bool allowInLRUList() const { return canDelete() && !m_free && status() != Persistent; } + CachedObject* m_next; + CachedObject* m_prev; + friend class Cache; + friend class ::KHTMLPart; + }; + + + /** + * a cached style sheet. also used for loading xml documents. + * + * ### rename to CachedTextDoc or something since it's more generic than just for css + */ + class CachedCSSStyleSheet : public CachedObject + { + public: + CachedCSSStyleSheet(DocLoader* dl, const DOM::DOMString &url, TDEIO::CacheControl cachePolicy, + const char *accept); + CachedCSSStyleSheet(const DOM::DOMString &url, const TQString &stylesheet_data); + + const DOM::DOMString &sheet() const { return m_sheet; } + + virtual void ref(CachedObjectClient *consumer); + + virtual void data( TQBuffer &buffer, bool eof ); + virtual void error( int err, const char *text ); + + virtual bool schedule() const { return true; } + void setCharsetHint( const TQString& charset ) { m_charsetHint = charset; } + void setCharset( const TQString& charset ) { m_charset = charset; } + + protected: + void checkNotify(); + + DOM::DOMString m_sheet; + TQString m_charset; + TQString m_charsetHint; + int m_err; + TQString m_errText; + }; + + /** + * a cached script + */ + class CachedScript : public CachedObject + { + public: + CachedScript(DocLoader* dl, const DOM::DOMString &url, TDEIO::CacheControl cachePolicy, const char* accept ); + CachedScript(const DOM::DOMString &url, const TQString &script_data); + + const DOM::DOMString &script() const { return m_script; } + + virtual void ref(CachedObjectClient *consumer); + + virtual void data( TQBuffer &buffer, bool eof ); + virtual void error( int err, const char *text ); + + virtual bool schedule() const { return false; } + + void checkNotify(); + + bool isLoaded() const { return !m_loading; } + void setCharset( const TQString& charset ) { m_charset = charset; } + + protected: + TQString m_charset; + DOM::DOMString m_script; + }; + + class ImageSource; + + /** + * a cached image + */ + class CachedImage : public TQObject, public CachedObject + { + Q_OBJECT + public: + CachedImage(DocLoader* dl, const DOM::DOMString &url, TDEIO::CacheControl cachePolicy, const char* accept); + virtual ~CachedImage(); + + const TQPixmap &pixmap() const; + const TQPixmap &scaled_pixmap(int xWidth, int xHeight); + const TQPixmap &tiled_pixmap(const TQColor& bg, int xWidth = -1, int xHeight = -1); + + TQSize pixmap_size() const; // returns the size of the complete (i.e. when finished) loading + TQRect valid_rect() const; // returns the rectangle of pixmap that has been loaded already + + bool canRender() const { return !isErrorImage() && pixmap_size().width() > 0 && pixmap_size().height() > 0; } + void ref(CachedObjectClient *consumer); + virtual void deref(CachedObjectClient *consumer); + + virtual void data( TQBuffer &buffer, bool eof ); + virtual void error( int err, const char *text ); + + bool isTransparent() const { return isFullyTransparent; } + bool isErrorImage() const { return m_hadError; } + bool isBlockedImage() const { return m_wasBlocked; } + const TQString& suggestedFilename() const { return m_suggestedFilename; } + void setSuggestedFilename( const TQString& s ) { m_suggestedFilename = s; } +#ifdef IMAGE_TITLES + const TQString& suggestedTitle() const { return m_suggestedTitle; } + void setSuggestedTitle( const TQString& s ) { m_suggestedTitle = s; } +#else + const TQString& suggestedTitle() const { return m_suggestedFilename; } +#endif + + void setShowAnimations( KHTMLSettings::KAnimationAdvice ); + void pauseAnimations(); + void resumeAnimations(); + + virtual bool schedule() const { return true; } + + virtual void finish(); + + protected: + void clear(); + + private slots: + /** + * gets called, whenever a TQMovie changes frame + */ + void movieUpdated( const TQRect &rect ); + void movieStatus(int); + void movieResize(const TQSize&); + void deleteMovie(); + + private: + void do_notify(const TQPixmap& p, const TQRect& r); + + TQString m_suggestedFilename; +#ifdef IMAGE_TITLES + TQString m_suggestedTitle; +#endif + TQMovie* m; + TQPixmap* p; + TQPixmap* scaled; + TQPixmap* bg; + QRgb bgColor; + TQSize bgSize; + mutable TQPixmap* pixPart; + + ImageSource* imgSource; + const char* formatType; // Is the name of the movie format type + + int width; + int height; + + // Is set if movie format type ( incremental/animation) was checked + bool typeChecked : 1; + bool isFullyTransparent : 1; + bool monochrome : 1; + KHTMLSettings::KAnimationAdvice m_showAnimations : 2; + + friend class Cache; + friend class ::KHTMLPart; + }; + + /** + * @internal + * + * Manages the loading of scripts/images/stylesheets for a particular document + */ + class DocLoader + { + public: + DocLoader(KHTMLPart*, DOM::DocumentImpl*); + ~DocLoader(); + + CachedImage *requestImage( const DOM::DOMString &url); + CachedCSSStyleSheet *requestStyleSheet( const DOM::DOMString &url, const TQString& charsetHint, + const char *accept = "text/css", bool userSheet = false ); + CachedScript *requestScript( const DOM::DOMString &url, const TQString& charset); + + bool autoloadImages() const { return m_bautoloadImages; } + TDEIO::CacheControl cachePolicy() const { return m_cachePolicy; } + KHTMLSettings::KAnimationAdvice showAnimations() const { return m_showAnimations; } + time_t expireDate() const { return m_expireDate; } + KHTMLPart* part() const { return m_part; } + DOM::DocumentImpl* doc() const { return m_doc; } + + void setCacheCreationDate( time_t ); + void setExpireDate( time_t, bool relative ); + void setAutoloadImages( bool ); + void setCachePolicy( TDEIO::CacheControl cachePolicy ) { m_cachePolicy = cachePolicy; } + void setShowAnimations( KHTMLSettings::KAnimationAdvice ); + void pauseAnimations(); + void resumeAnimations(); + void insertCachedObject( CachedObject* o ) const; + void removeCachedObject( CachedObject* o) const { m_docObjects.remove( o ); } + + private: + bool needReload(CachedObject *existing, const TQString &fullUrl); + + friend class Cache; + friend class DOM::DocumentImpl; + friend class ::KHTMLPart; + + TQStringList m_reloadedURLs; + mutable TQPtrDict<CachedObject> m_docObjects; + time_t m_expireDate; + time_t m_creationDate; + TDEIO::CacheControl m_cachePolicy; + bool m_bautoloadImages : 1; + KHTMLSettings::KAnimationAdvice m_showAnimations : 2; + KHTMLPart* m_part; + DOM::DocumentImpl* m_doc; + }; + + /** + * @internal + */ + class Request + { + public: + Request(DocLoader* dl, CachedObject *_object, bool _incremental); + ~Request(); + bool incremental; + TQBuffer m_buffer; + CachedObject *object; + DocLoader* m_docLoader; + }; + + /** + * @internal + */ + class Loader : public TQObject + { + Q_OBJECT + + public: + Loader(); + + void load(DocLoader* dl, CachedObject *object, bool incremental = true); + + int numRequests( DocLoader* dl ) const; + void cancelRequests( DocLoader* dl ); + + // may return 0L + TDEIO::Job *jobForRequest( const DOM::DOMString &url ) const; + + signals: + void requestStarted( tdehtml::DocLoader* dl, tdehtml::CachedObject* obj ); + void requestDone( tdehtml::DocLoader* dl, tdehtml::CachedObject *obj ); + void requestFailed( tdehtml::DocLoader* dl, tdehtml::CachedObject *obj ); + + protected slots: + void slotFinished( TDEIO::Job * ); + void slotData( TDEIO::Job *, const TQByteArray & ); + void servePendingRequests(); + + protected: + TQPtrList<Request> m_requestsPending; + TQPtrDict<Request> m_requestsLoading; +#ifdef HAVE_LIBJPEG + KJPEGFormatType m_jpegloader; +#endif + TQTimer m_timer; + }; + + /** + * @internal + * + * Provides a cache/loader for objects needed for displaying the html page. + * At the moment these are stylesheets, scripts and images + */ + class Cache + { + friend class DocLoader; + + template<typename CachedObjectType, enum CachedObject::Type CachedType> + static CachedObjectType* requestObject( DocLoader* dl, const KURL& kurl, const char* accept ); + + public: + /** + * init the cache in case it's not already. This needs to get called once + * before using it. + */ + KDE_EXPORT static void init(); + + /** + * Ask the cache for some url. Will return a cachedObject, and + * load the requested data in case it's not cached + * if the DocLoader is zero, the url must be full-qualified. + * Otherwise, it is automatically base-url expanded + */ +// static CachedImage *requestImage(const KURL& url) +// { return Cache::requestObject<CachedImage, CachedObject::Image>( 0, url, 0 ); } + + /** + * Pre-loads a stylesheet into the cache. + */ + static void preloadStyleSheet(const TQString &url, const TQString &stylesheet_data); + + /** + * Pre-loads a script into the cache. + */ + static void preloadScript(const TQString &url, const TQString &script_data); + + static void setSize( int bytes ); + static int size() { return maxSize; }; + static void statistics(); + KDE_EXPORT static void flush(bool force=false); + + /** + * clears the cache + * Warning: call this only at the end of your program, to clean + * up memory (useful for finding memory holes) + */ + KDE_EXPORT static void clear(); + + static Loader *loader() { return m_loader; } + + static TQPixmap *nullPixmap; + static TQPixmap *brokenPixmap; + static TQPixmap *blockedPixmap; + static int cacheSize; + + static void removeCacheEntry( CachedObject *object ); + + private: + + static void checkLRUAndUncacheableListIntegrity(); + + friend class CachedObject; + + static TQDict<CachedObject> *cache; + static TQPtrList<DocLoader>* docloader; + static TQPtrList<CachedObject> *freeList; + static void insertInLRUList(CachedObject*); + static void removeFromLRUList(CachedObject*); + + static int totalSizeOfLRU; + static int maxSize; + + static Loader *m_loader; + }; + +} // namespace + +#endif |