2 This file is part of the KDE libraries
4 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
5 Copyright (C) 2001-2003 Dirk Mueller <mueller@kde.org>
6 Copyright (C) 2003 Apple Computer, Inc
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA.
23 This class provides all functionality needed for loading images, style sheets and html
24 pages from the web. It has a memory cache for these objects.
26 #ifndef _khtml_loader_h
27 #define _khtml_loader_h
32 #include "loader_client.h"
34 #include "loader_jpeg.h"
38 #include <QtCore/QObject>
39 #include <QtGui/QPixmap>
40 #include <QtCore/QBuffer>
41 #include <QtCore/QStringList>
42 #include <QtCore/QTextCodec>
43 #include <QtCore/QTimer>
44 #include <QtCore/QSet>
45 #include <QLinkedList>
48 #include <kio/global.h>
50 #include <khtml_settings.h>
51 #include <dom/dom_string.h>
52 #include "imload/image.h"
53 #include "imload/imageowner.h"
76 * A cached object. Classes who want to use this object should derive
77 * from CachedObjectClient, to get the function calls in case the requested data has arrived.
79 * This class also does the actual communication with kio and loads the file.
92 Unknown
, // let imagecache decide what to do with it
93 New
, // inserting new image
94 Pending
, // only partially loaded
95 Persistent
, // never delete this pixmap
96 Cached
// regular case
100 PreloadNotReferenced
= 0,
102 PreloadReferencedWhileLoading
,
103 PreloadReferencedWhileComplete
106 PreloadResult
preloadResult() const { return m_preloadResult
; }
107 void setProspectiveRequest() { m_prospectiveRequest
= true; }
109 CachedObject(const DOM::DOMString
&url
, Type type
, KIO::CacheControl _cachePolicy
, int size
)
110 : m_url(url
), m_type(type
), m_cachePolicy(_cachePolicy
),
111 m_expireDate(0), m_size(size
)
115 m_cachePolicy
= _cachePolicy
;
120 m_wasBlocked
= false;
123 m_preloadResult
= PreloadNotReferenced
;
124 m_prospectiveRequest
= false;
126 virtual ~CachedObject();
128 virtual void data( QBuffer
&buffer
, bool eof
) = 0;
129 virtual void error( int err
, const char *text
) = 0;
131 const DOM::DOMString
&url() const { return m_url
; }
132 Type
type() const { return m_type
; }
134 virtual void ref(CachedObjectClient
*consumer
);
135 virtual void deref(CachedObjectClient
*consumer
);
137 int count() const { return m_clients
.count(); }
138 int accessCount() const { return m_accessCount
; }
140 bool isPreloaded() const { return m_preloadCount
; }
141 void increasePreloadCount() { ++m_preloadCount
; }
142 void decreasePreloadCount() { assert(m_preloadCount
); --m_preloadCount
; }
144 void setStatus(Status s
) { m_status
= s
; }
145 Status
status() const { return m_status
; }
147 virtual void setCharset( const QString
& /*charset*/ ) {}
149 QTextCodec
* codecForBuffer( const QString
& charset
, const QByteArray
& buffer
) const;
151 int size() const { return m_size
; }
153 bool isLoaded() const { return !m_loading
; }
154 bool hadError() const { return m_hadError
; }
156 bool free() const { return m_free
; }
158 KIO::CacheControl
cachePolicy() const { return m_cachePolicy
; }
160 void setRequest(Request
*_request
);
162 bool canDelete() const { return (m_clients
.count() == 0 && !m_request
&& !m_preloadCount
); }
164 void setExpireDate(time_t _expireDate
) { m_expireDate
= _expireDate
; }
166 bool isExpired() const;
168 virtual bool schedule() const { return false; }
169 virtual void finish();
172 * List of acceptable mimetypes separated by ",". A mimetype may contain a wildcard.
175 QString
accept() const { return m_accept
; }
176 void setAccept(const QString
&_accept
) { m_accept
= _accept
; }
178 // the mimetype that was eventually used
179 QString
mimetype() const { return m_mimetype
; }
182 void setSize(int size
);
183 QHash
<CachedObjectClient
*,CachedObjectClient
*> m_clients
;
184 DOM::DOMString m_url
;
191 KIO::CacheControl m_cachePolicy
;
194 unsigned m_preloadCount
;
195 PreloadResult m_preloadResult
: 3;
200 bool m_wasBlocked
: 1;
201 bool m_prospectiveRequest
: 1;
204 bool allowInLRUList() const { return canDelete() && !m_free
&& status() != Persistent
; }
205 CachedObject
* m_next
;
206 CachedObject
* m_prev
;
208 friend class ::KHTMLPart
;
213 bool isAcceptableCSSMimetype( const DOM::DOMString
& mimetype
);
216 * a cached style sheet. also used for loading xml documents.
218 * ### rename to CachedTextDoc or something since it's more generic than just for css
220 class CachedCSSStyleSheet
: public CachedObject
223 CachedCSSStyleSheet(DocLoader
* dl
, const DOM::DOMString
&url
, KIO::CacheControl cachePolicy
,
225 CachedCSSStyleSheet(const DOM::DOMString
&url
, const QString
&stylesheet_data
);
227 const DOM::DOMString
&sheet() const { return m_sheet
; }
229 virtual void ref(CachedObjectClient
*consumer
);
231 virtual void data( QBuffer
&buffer
, bool eof
);
232 virtual void error( int err
, const char *text
);
234 virtual bool schedule() const { return true; }
235 void setCharsetHint( const QString
& charset
) { m_charsetHint
= charset
; }
236 void setCharset( const QString
& charset
) { m_charset
= charset
; }
242 DOM::DOMString m_sheet
;
244 QString m_charsetHint
;
252 class CachedScript
: public CachedObject
255 CachedScript(DocLoader
* dl
, const DOM::DOMString
&url
, KIO::CacheControl cachePolicy
, const char* accept
);
256 CachedScript(const DOM::DOMString
&url
, const QString
&script_data
);
258 const DOM::DOMString
&script() const { return m_script
; }
260 virtual void ref(CachedObjectClient
*consumer
);
262 virtual void data( QBuffer
&buffer
, bool eof
);
263 virtual void error( int err
, const char *text
);
265 virtual bool schedule() const { return false; }
269 bool isLoaded() const { return !m_loading
; }
270 void setCharset( const QString
& charset
) { m_charset
= charset
; }
274 DOM::DOMString m_script
;
282 class CachedImage
: public QObject
, public CachedObject
, public khtmlImLoad::ImageOwner
286 CachedImage(DocLoader
* dl
, const DOM::DOMString
&url
, KIO::CacheControl cachePolicy
, const char* accept
);
287 virtual ~CachedImage();
289 QPixmap
pixmap() const;
290 QPixmap
* scaled_pixmap(int xWidth
, int xHeight
);
291 QPixmap
tiled_pixmap(const QColor
& bg
, int xWidth
= -1, int xHeight
= -1);
293 QSize
pixmap_size() const; // returns the size of the complete (i.e. when finished) loading
294 //QRect valid_rect() const; // returns the rectangle of pixmap that has been loaded already
296 bool canRender() const { return !isErrorImage() && pixmap_size().width() > 0 && pixmap_size().height() > 0; }
297 void ref(CachedObjectClient
*consumer
);
298 virtual void deref(CachedObjectClient
*consumer
);
301 virtual void data( QBuffer
&buffer
, bool eof
);
302 virtual void error( int err
, const char *text
);
305 bool isComplete() const { return i
&& i
->complete(); }
306 bool isTransparent() const { return false; } //### isFullyTransparent; }
307 bool isErrorImage() const { return m_hadError
; }
308 bool isBlockedImage() const { return m_wasBlocked
; }
309 const QString
& suggestedFilename() const { return m_suggestedFilename
; }
310 void setSuggestedFilename( const QString
& s
) { m_suggestedFilename
= s
; }
312 const QString
& suggestedTitle() const { return m_suggestedTitle
; }
313 void setSuggestedTitle( const QString
& s
) { m_suggestedTitle
= s
; }
315 const QString
& suggestedTitle() const { return m_suggestedFilename
; }
318 void setShowAnimations( KHTMLSettings::KAnimationAdvice
);
319 void pauseAnimations();
320 void resumeAnimations();
322 virtual bool schedule() const { return true; }
324 virtual void finish();
327 khtmlImLoad::Image
* image() { return i
; }
334 Interface to the image
336 virtual void imageHasGeometry(khtmlImLoad::Image
* img
, int width
, int height
);
337 virtual void imageChange (khtmlImLoad::Image
* img
, QRect region
);
338 virtual void imageError (khtmlImLoad::Image
* img
);
339 virtual void imageDone (khtmlImLoad::Image
* img
);
341 void doNotifyFinished();
343 void do_notify(const QRect
& r
);
344 khtmlImLoad::Image
* i
;
346 QString m_suggestedFilename
;
348 QString m_suggestedTitle
;
355 ImageSource
* imgSource
;
356 const char* formatType
; // Is the name of the movie format type
361 // Is set if movie format type ( incremental/animation) was checked
362 bool typeChecked
: 1;
363 bool isFullyTransparent
: 1;
367 friend class ::KHTMLPart
;
373 class CachedSound
: public CachedObject
376 CachedSound(DocLoader
* dl
, const DOM::DOMString
&url
, KIO::CacheControl cachePolicy
, const char* accept
);
378 QByteArray
sound() const { return m_sound
; }
380 virtual void ref(CachedObjectClient
*consumer
);
381 virtual void data( QBuffer
&buffer
, bool eof
);
382 virtual void error( int err
, const char *text
);
383 virtual bool schedule() const { return false; }
387 bool isLoaded() const { return !m_loading
; }
397 * Manages the loading of scripts/images/stylesheets for a particular document
402 DocLoader(KHTMLPart
*, DOM::DocumentImpl
*);
405 CachedImage
*requestImage( const DOM::DOMString
&url
);
406 CachedCSSStyleSheet
*requestStyleSheet( const DOM::DOMString
&url
, const QString
& charsetHint
,
407 const char *accept
= "text/css", bool userSheet
= false );
408 CachedScript
*requestScript( const DOM::DOMString
&url
, const QString
& charset
);
409 CachedSound
*requestSound( const DOM::DOMString
&url
);
411 bool autoloadImages() const { return m_bautoloadImages
; }
412 KIO::CacheControl
cachePolicy() const { return m_cachePolicy
; }
413 KHTMLSettings::KAnimationAdvice
showAnimations() const { return m_showAnimations
; }
414 time_t expireDate() const { return m_expireDate
; }
415 KHTMLPart
* part() const { return m_part
; }
416 DOM::DocumentImpl
* doc() const { return m_doc
; }
418 void setCacheCreationDate( time_t );
419 void setExpireDate( time_t, bool relative
);
420 void setAutoloadImages( bool );
421 void setCachePolicy( KIO::CacheControl cachePolicy
) { m_cachePolicy
= cachePolicy
; }
422 void setShowAnimations( KHTMLSettings::KAnimationAdvice
);
423 void pauseAnimations();
424 void resumeAnimations();
425 void insertCachedObject( CachedObject
* o
) const;
426 void removeCachedObject( CachedObject
* o
) const { m_docObjects
.remove( o
); }
427 void clearPreloads();
428 void registerPreload(CachedObject
*);
429 void printPreloadStats();
432 bool needReload(CachedObject
*existing
, const QString
&fullUrl
);
435 friend class DOM::DocumentImpl
;
436 friend class ::KHTMLPart
;
438 QStringList m_reloadedURLs
;
439 mutable QSet
<CachedObject
*> m_docObjects
;
440 QSet
<CachedObject
*> m_preloads
;
442 time_t m_creationDate
;
443 KIO::CacheControl m_cachePolicy
;
444 bool m_bautoloadImages
: 1;
445 KHTMLSettings::KAnimationAdvice m_showAnimations
: 2;
447 DOM::DocumentImpl
* m_doc
;
456 Request(DocLoader
* dl
, CachedObject
*_object
, bool _incremental
);
460 CachedObject
*object
;
461 DocLoader
* m_docLoader
;
467 class Loader
: public QObject
476 void load(DocLoader
* dl
, CachedObject
*object
, bool incremental
= true, bool highPriority
= false);
478 int numRequests( DocLoader
* dl
) const;
479 void cancelRequests( DocLoader
* dl
);
482 KIO::Job
*jobForRequest( const DOM::DOMString
&url
) const;
485 void requestStarted( khtml::DocLoader
* dl
, khtml::CachedObject
* obj
);
486 void requestDone( khtml::DocLoader
* dl
, khtml::CachedObject
*obj
);
487 void requestFailed( khtml::DocLoader
* dl
, khtml::CachedObject
*obj
);
490 void slotFinished( KJob
* );
491 void slotMimetype( KIO::Job
*, const QString
& s
);
492 void slotData( KIO::Job
*, const QByteArray
& );
493 void servePendingRequests();
496 QLinkedList
<Request
*> m_requestsPending
;
497 Request
* m_highPriorityRequestPending
;
498 QHash
<KIO::Job
*,Request
*> m_requestsLoading
;
500 // TODO KJPEGFormatType m_jpegloader;
508 * Provides a cache/loader for objects needed for displaying the html page.
509 * At the moment these are stylesheets, scripts and images
513 friend class DocLoader
;
515 template<typename CachedObjectType
, enum CachedObject::Type CachedType
>
516 static CachedObjectType
* requestObject( DocLoader
* dl
, const KUrl
& kurl
, const char* accept
);
520 * init the cache in case it's not already. This needs to get called once
523 KHTML_EXPORT
static void init();
526 * Ask the cache for some url. Will return a cachedObject, and
527 * load the requested data in case it's not cached
528 * if the DocLoader is zero, the url must be full-qualified.
529 * Otherwise, it is automatically base-url expanded
531 // static CachedImage *requestImage(const KUrl& url)
532 // { return Cache::requestObject<CachedImage, CachedObject::Image>( 0, url, 0 ); }
535 * Pre-loads a stylesheet into the cache.
537 static void preloadStyleSheet(const QString
&url
, const QString
&stylesheet_data
);
540 * Pre-loads a script into the cache.
542 static void preloadScript(const QString
&url
, const QString
&script_data
);
544 static void setSize( int bytes
);
545 static int size() { return maxSize
; }
546 static void statistics();
547 KHTML_EXPORT
static void flush(bool force
=false);
551 * Warning: call this only at the end of your program, to clean
552 * up memory (useful for finding memory holes)
554 KHTML_EXPORT
static void clear();
556 static Loader
*loader() { return m_loader
; }
558 static QPixmap
*nullPixmap
;
559 static QPixmap
*brokenPixmap
;
560 static QPixmap
*blockedPixmap
;
561 static int cacheSize
;
563 static void removeCacheEntry( CachedObject
*object
);
567 static void checkLRUAndUncacheableListIntegrity();
569 friend class CachedObject
;
571 static QHash
<QString
,CachedObject
*> *cache
;
572 static QLinkedList
<DocLoader
*>* docloader
;
573 static QLinkedList
<CachedObject
*> *freeList
;
574 static void insertInLRUList(CachedObject
*);
575 static void removeFromLRUList(CachedObject
*);
577 static int totalSizeOfLRU
;
580 static Loader
*m_loader
;