khtml Library API Documentation

khtmlimage.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
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 "khtmlimage.h"
00021 #include "khtmlview.h"
00022 #include "khtml_ext.h"
00023 #include "xml/dom_docimpl.h"
00024 #include "html/html_documentimpl.h"
00025 #include "html/html_elementimpl.h"
00026 #include "rendering/render_image.h"
00027 #include "misc/loader.h"
00028 
00029 #include <qvbox.h>
00030 #include <qtimer.h>
00031 
00032 #include <kio/job.h>
00033 #include <kinstance.h>
00034 #include <kmimetype.h>
00035 #include <klocale.h>
00036 
00037 K_EXPORT_COMPONENT_FACTORY( khtmlimagefactory /*NOT the part name, see Makefile.am*/, KHTMLImageFactory )
00038 
00039 KInstance *KHTMLImageFactory::s_instance = 0;
00040 
00041 KHTMLImageFactory::KHTMLImageFactory()
00042 {
00043     s_instance = new KInstance( "khtmlimage" );
00044 }
00045 
00046 KHTMLImageFactory::~KHTMLImageFactory()
00047 {
00048     delete s_instance;
00049 }
00050 
00051 KParts::Part *KHTMLImageFactory::createPartObject( QWidget *parentWidget, const char *widgetName,
00052                                                    QObject *parent, const char *name,
00053                                                    const char *className, const QStringList & )
00054 {
00055   KHTMLPart::GUIProfile prof = KHTMLPart::DefaultGUI;
00056   if ( strcmp( className, "Browser/View" ) == 0 )
00057     prof = KHTMLPart::BrowserViewGUI;
00058   return new KHTMLImage( parentWidget, widgetName, parent, name, prof );
00059 }
00060 
00061 KHTMLImage::KHTMLImage( QWidget *parentWidget, const char *widgetName,
00062                         QObject *parent, const char *name, KHTMLPart::GUIProfile prof )
00063     : KParts::ReadOnlyPart( parent, name ), m_image( 0 )
00064 {
00065     KHTMLPart* parentPart = ::qt_cast<KHTMLPart *>( parent );
00066     setInstance( KHTMLImageFactory::instance(), prof == KHTMLPart::BrowserViewGUI && !parentPart );
00067 
00068     QVBox *box = new QVBox( parentWidget, widgetName );
00069 
00070     m_khtml = new KHTMLPart( box, widgetName, this, "htmlimagepart", prof );
00071     m_khtml->setAutoloadImages( true );
00072     m_khtml->widget()->installEventFilter(this);
00073 
00074     setWidget( box );
00075 
00076     // VBox can't take focus, so pass it on to sub-widget
00077     box->setFocusProxy( m_khtml->widget() );
00078 
00079     m_ext = new KHTMLImageBrowserExtension( this, "be" );
00080 
00081     // Remove unnecessary actions.
00082     KAction *encodingAction = actionCollection()->action( "setEncoding" );
00083     if ( encodingAction )
00084     {
00085         encodingAction->unplugAll();
00086         delete encodingAction;
00087     }
00088     KAction *viewSourceAction= actionCollection()->action( "viewDocumentSource" );
00089     if ( viewSourceAction )
00090     {
00091         viewSourceAction->unplugAll();
00092         delete viewSourceAction;
00093     }
00094 
00095     KAction *selectAllAction= actionCollection()->action( "selectAll" );
00096     if ( selectAllAction )
00097     {
00098         selectAllAction->unplugAll();
00099         delete selectAllAction;
00100     }
00101 
00102     // forward important signals from the khtml part
00103 
00104     // forward opening requests to parent frame (if existing)
00105     KHTMLPart *p = ::qt_cast<KHTMLPart *>(parent);
00106     KParts::BrowserExtension *be = p ? p->browserExtension() : m_ext;
00107     connect(m_khtml->browserExtension(), SIGNAL(openURLRequestDelayed(const KURL &, const KParts::URLArgs &)),
00108             be, SIGNAL(openURLRequestDelayed(const KURL &, const KParts::URLArgs &)));
00109 
00110     connect( m_khtml->browserExtension(), SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &,
00111              const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t) ), m_ext, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &,
00112              const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t) ) );
00113 
00114     connect( m_khtml->browserExtension(), SIGNAL( enableAction( const char *, bool ) ),
00115              m_ext, SIGNAL( enableAction( const char *, bool ) ) );
00116 
00117     m_ext->setURLDropHandlingEnabled( true );
00118 }
00119 
00120 KHTMLImage::~KHTMLImage()
00121 {
00122     disposeImage();
00123 
00124     // important: delete the html part before the part or qobject destructor runs.
00125     // we now delete the htmlpart which deletes the part's widget which makes
00126     // _OUR_ m_widget 0 which in turn avoids our part destructor to delete the
00127     // widget ;-)
00128     // ### additional note: it _can_ be that the part has been deleted before:
00129     // when we're in a html frameset and the view dies first, then it will also
00130     // kill the htmlpart
00131     if ( m_khtml )
00132         delete static_cast<KHTMLPart *>( m_khtml );
00133 }
00134 
00135 bool KHTMLImage::openURL( const KURL &url )
00136 {
00137     static const QString &html = KGlobal::staticQString( "<html><body><img src=\"%1\"></body></html>" );
00138 
00139     disposeImage();
00140 
00141     m_url = url;
00142 
00143     emit started( 0 );
00144 
00145     KParts::URLArgs args = m_ext->urlArgs();
00146     m_mimeType = args.serviceType;
00147 
00148     emit setWindowCaption( url.prettyURL() );
00149 
00150     m_khtml->begin( m_url, args.xOffset, args.yOffset );
00151     m_khtml->setAutoloadImages( true );
00152 
00153     DOM::DocumentImpl *impl = dynamic_cast<DOM::DocumentImpl *>( m_khtml->document().handle() ); // ### hack ;-)
00154     if ( impl && m_ext->urlArgs().reload )
00155         impl->docLoader()->setCachePolicy( KIO::CC_Reload );
00156 
00157     khtml::DocLoader *dl = impl ? impl->docLoader() : 0;
00158     m_image = dl->requestImage( m_url.url() );
00159     if ( m_image )
00160         m_image->ref( this );
00161 
00162     m_khtml->write( html.arg( m_url.url() ) );
00163     m_khtml->end();
00164 
00165     /*
00166     connect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
00167             this, SLOT( updateWindowCaption() ) );
00168             */
00169     return true;
00170 }
00171 
00172 bool KHTMLImage::closeURL()
00173 {
00174     disposeImage();
00175     return m_khtml->closeURL();
00176 }
00177 
00178 void KHTMLImage::notifyFinished( khtml::CachedObject *o )
00179 {
00180     if ( !m_image || o != m_image )
00181         return;
00182 
00183     const QPixmap &pix = m_image->pixmap();
00184     QString caption;
00185 
00186     KMimeType::Ptr mimeType;
00187     if ( !m_mimeType.isEmpty() )
00188         mimeType = KMimeType::mimeType( m_mimeType );
00189 
00190     if ( mimeType ) {
00191         if (m_image && !m_image->suggestedTitle().isEmpty()) {
00192             caption = i18n( "%1 (%2 - %3x%4 Pixels)" ).arg( m_image->suggestedTitle(), mimeType->comment() ).arg( pix.width() ).arg( pix.height() );
00193         } else {
00194             caption = i18n( "%1 - %2x%3 Pixels" ).arg( mimeType->comment() )
00195                 .arg( pix.width() ).arg( pix.height() );
00196         }
00197     } else {
00198         if (m_image && !m_image->suggestedTitle().isEmpty()) {
00199             caption = i18n( "%1 (%2x%3 Pixels)" ).arg(m_image->suggestedTitle()).arg( pix.width() ).arg( pix.height() );
00200         } else {
00201             caption = i18n( "Image - %1x%2 Pixels" ).arg( pix.width() ).arg( pix.height() );
00202         }
00203     }
00204 
00205     emit setWindowCaption( caption );
00206     emit completed();
00207     emit setStatusBarText(i18n("Done."));
00208 }
00209 
00210 void KHTMLImage::guiActivateEvent( KParts::GUIActivateEvent *e )
00211 {
00212     // prevent the base implementation from emitting setWindowCaption with
00213     // our url. It destroys our pretty, previously caption. Konq saves/restores
00214     // the caption for us anyway.
00215     if ( e->activated() )
00216         return;
00217     KParts::ReadOnlyPart::guiActivateEvent(e);
00218 }
00219 
00220 /*
00221 void KHTMLImage::slotImageJobFinished( KIO::Job *job )
00222 {
00223     if ( job->error() )
00224     {
00225         job->showErrorDialog();
00226         emit canceled( job->errorString() );
00227     }
00228     else
00229     {
00230         if ( m_khtml->view()->contentsY() == 0 )
00231         {
00232             KParts::URLArgs args = m_ext->urlArgs();
00233             m_khtml->view()->setContentsPos( args.xOffset, args.yOffset );
00234         }
00235 
00236         emit completed();
00237 
00238         QTimer::singleShot( 0, this, SLOT( updateWindowCaption() ) );
00239     }
00240 }
00241 
00242 void KHTMLImage::updateWindowCaption()
00243 {
00244     if ( !m_khtml )
00245         return;
00246 
00247     DOM::HTMLDocumentImpl *impl = dynamic_cast<DOM::HTMLDocumentImpl *>( m_khtml->document().handle() );
00248     if ( !impl )
00249         return;
00250 
00251     DOM::HTMLElementImpl *body = impl->body();
00252     if ( !body )
00253         return;
00254 
00255     DOM::NodeImpl *image = body->firstChild();
00256     if ( !image )
00257         return;
00258 
00259     khtml::RenderImage *renderImage = dynamic_cast<khtml::RenderImage *>( image->renderer() );
00260     if ( !renderImage )
00261         return;
00262 
00263     QPixmap pix = renderImage->pixmap();
00264 
00265     QString caption;
00266 
00267     KMimeType::Ptr mimeType;
00268     if ( !m_mimeType.isEmpty() )
00269         mimeType = KMimeType::mimeType( m_mimeType );
00270 
00271     if ( mimeType )
00272         caption = i18n( "%1 - %2x%3 Pixels" ).arg( mimeType->comment() )
00273                   .arg( pix.width() ).arg( pix.height() );
00274     else
00275         caption = i18n( "Image - %1x%2 Pixels" ).arg( pix.width() ).arg( pix.height() );
00276 
00277     emit setWindowCaption( caption );
00278     emit completed();
00279     emit setStatusBarText(i18n("Done."));
00280 }
00281 */
00282 
00283 void KHTMLImage::disposeImage()
00284 {
00285     if ( !m_image )
00286         return;
00287 
00288     m_image->deref( this );
00289     m_image = 0;
00290 }
00291 
00292 bool KHTMLImage::eventFilter(QObject *, QEvent *e) {
00293     switch (e->type()) {
00294       case QEvent::DragEnter:
00295       case QEvent::DragMove:
00296       case QEvent::DragLeave:
00297       case QEvent::Drop: {
00298         // find out if this part is embedded in a frame, and send the
00299     // event to its outside widget
00300     KHTMLPart *p = ::qt_cast<KHTMLPart *>(parent());
00301     if (p)
00302         return QApplication::sendEvent(p->widget(), e);
00303         // otherwise simply forward all dnd events to the part widget,
00304     // konqueror will handle them properly there
00305         return QApplication::sendEvent(widget(), e);
00306       }
00307       default: ;
00308     }
00309     return false;
00310 }
00311 
00312 KHTMLImageBrowserExtension::KHTMLImageBrowserExtension( KHTMLImage *parent, const char *name )
00313     : KParts::BrowserExtension( parent, name )
00314 {
00315     m_imgPart = parent;
00316 }
00317 
00318 int KHTMLImageBrowserExtension::xOffset()
00319 {
00320     return m_imgPart->doc()->view()->contentsX();
00321 }
00322 
00323 int KHTMLImageBrowserExtension::yOffset()
00324 {
00325     return m_imgPart->doc()->view()->contentsY();
00326 }
00327 
00328 void KHTMLImageBrowserExtension::print()
00329 {
00330     static_cast<KHTMLPartBrowserExtension *>( m_imgPart->doc()->browserExtension() )->print();
00331 }
00332 
00333 void KHTMLImageBrowserExtension::reparseConfiguration()
00334 {
00335     static_cast<KHTMLPartBrowserExtension *>( m_imgPart->doc()->browserExtension() )->reparseConfiguration();
00336     m_imgPart->doc()->setAutoloadImages( true );
00337 }
00338 
00339 using namespace KParts;
00340 
00341 /* vim: et sw=4 ts=4
00342  */
00343 
00344 #include "khtmlimage.moc"
KDE Logo
This file is part of the documentation for khtml Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Nov 1 10:35:31 2005 by doxygen 1.4.3 written by Dimitri van Heesch, © 1997-2003