• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

KHTML

khtmlimage.cpp

Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor,
00017    Boston, MA 02110-1301, 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     connect( m_khtml->view(), SIGNAL( finishedLayout() ), this, SLOT( restoreScrollPosition() ) );
00074 
00075     setWidget( box );
00076 
00077     // VBox can't take focus, so pass it on to sub-widget
00078     box->setFocusProxy( m_khtml->widget() );
00079 
00080     m_ext = new KHTMLImageBrowserExtension( this, "be" );
00081 
00082     // Remove unnecessary actions.
00083     KAction *encodingAction = actionCollection()->action( "setEncoding" );
00084     if ( encodingAction )
00085     {
00086         encodingAction->unplugAll();
00087         delete encodingAction;
00088     }
00089     KAction *viewSourceAction= actionCollection()->action( "viewDocumentSource" );
00090     if ( viewSourceAction )
00091     {
00092         viewSourceAction->unplugAll();
00093         delete viewSourceAction;
00094     }
00095 
00096     KAction *selectAllAction= actionCollection()->action( "selectAll" );
00097     if ( selectAllAction )
00098     {
00099         selectAllAction->unplugAll();
00100         delete selectAllAction;
00101     }
00102 
00103     // forward important signals from the khtml part
00104 
00105     // forward opening requests to parent frame (if existing)
00106     KHTMLPart *p = ::qt_cast<KHTMLPart *>(parent);
00107     KParts::BrowserExtension *be = p ? p->browserExtension() : m_ext;
00108     connect(m_khtml->browserExtension(), SIGNAL(openURLRequestDelayed(const KURL &, const KParts::URLArgs &)),
00109             be, SIGNAL(openURLRequestDelayed(const KURL &, const KParts::URLArgs &)));
00110 
00111     connect( m_khtml->browserExtension(), SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &,
00112              const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t) ), m_ext, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &,
00113              const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t) ) );
00114 
00115     connect( m_khtml->browserExtension(), SIGNAL( enableAction( const char *, bool ) ),
00116              m_ext, SIGNAL( enableAction( const char *, bool ) ) );
00117 
00118     m_ext->setURLDropHandlingEnabled( true );
00119 }
00120 
00121 KHTMLImage::~KHTMLImage()
00122 {
00123     disposeImage();
00124 
00125     // important: delete the html part before the part or qobject destructor runs.
00126     // we now delete the htmlpart which deletes the part's widget which makes
00127     // _OUR_ m_widget 0 which in turn avoids our part destructor to delete the
00128     // widget ;-)
00129     // ### additional note: it _can_ be that the part has been deleted before:
00130     // when we're in a html frameset and the view dies first, then it will also
00131     // kill the htmlpart
00132     if ( m_khtml )
00133         delete static_cast<KHTMLPart *>( m_khtml );
00134 }
00135 
00136 bool KHTMLImage::openURL( const KURL &url )
00137 {
00138     static const QString &html = KGlobal::staticQString( "<html><body><img src=\"%1\"></body></html>" );
00139 
00140     disposeImage();
00141 
00142     m_url = url;
00143 
00144     emit started( 0 );
00145 
00146     KParts::URLArgs args = m_ext->urlArgs();
00147     m_mimeType = args.serviceType;
00148 
00149     emit setWindowCaption( url.prettyURL() );
00150 
00151     // Need to keep a copy of the offsets since they are cleared when emitting completed
00152     m_xOffset = args.xOffset;
00153     m_yOffset = args.yOffset;
00154 
00155     m_khtml->begin( m_url );
00156     m_khtml->setAutoloadImages( true );
00157 
00158     DOM::DocumentImpl *impl = dynamic_cast<DOM::DocumentImpl *>( m_khtml->document().handle() ); // ### hack ;-)
00159     if (!impl) return false;
00160     if ( m_ext->urlArgs().reload )
00161         impl->docLoader()->setCachePolicy( KIO::CC_Reload );
00162 
00163     khtml::DocLoader *dl = impl->docLoader();
00164     m_image = dl->requestImage( m_url.url() );
00165     if ( m_image )
00166         m_image->ref( this );
00167 
00168     m_khtml->write( html.arg( m_url.url() ) );
00169     m_khtml->end();
00170 
00171     /*
00172     connect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
00173             this, SLOT( updateWindowCaption() ) );
00174             */
00175     return true;
00176 }
00177 
00178 bool KHTMLImage::closeURL()
00179 {
00180     disposeImage();
00181     return m_khtml->closeURL();
00182 }
00183 
00184 // This can happen after openURL returns, or directly from m_image->ref()
00185 void KHTMLImage::notifyFinished( khtml::CachedObject *o )
00186 {
00187     if ( !m_image || o != m_image )
00188         return;
00189 
00190     const QPixmap &pix = m_image->pixmap();
00191     QString caption;
00192 
00193     KMimeType::Ptr mimeType;
00194     if ( !m_mimeType.isEmpty() )
00195         mimeType = KMimeType::mimeType( m_mimeType );
00196 
00197     if ( mimeType ) {
00198         if (m_image && !m_image->suggestedTitle().isEmpty()) {
00199             caption = i18n( "%1 (%2 - %3x%4 Pixels)" ).arg( m_image->suggestedTitle(), mimeType->comment() ).arg( pix.width() ).arg( pix.height() );
00200         } else {
00201             caption = i18n( "%1 - %2x%3 Pixels" ).arg( mimeType->comment() )
00202                 .arg( pix.width() ).arg( pix.height() );
00203         }
00204     } else {
00205         if (m_image && !m_image->suggestedTitle().isEmpty()) {
00206             caption = i18n( "%1 (%2x%3 Pixels)" ).arg(m_image->suggestedTitle()).arg( pix.width() ).arg( pix.height() );
00207         } else {
00208             caption = i18n( "Image - %1x%2 Pixels" ).arg( pix.width() ).arg( pix.height() );
00209         }
00210     }
00211 
00212     emit setWindowCaption( caption );
00213     emit completed();
00214     emit setStatusBarText(i18n("Done."));
00215 }
00216 
00217 void KHTMLImage::restoreScrollPosition()
00218 {
00219     if ( m_khtml->view()->contentsY() == 0 ) {
00220         m_khtml->view()->setContentsPos( m_xOffset, m_yOffset );
00221     }
00222 }
00223 
00224 void KHTMLImage::guiActivateEvent( KParts::GUIActivateEvent *e )
00225 {
00226     // prevent the base implementation from emitting setWindowCaption with
00227     // our url. It destroys our pretty, previously caption. Konq saves/restores
00228     // the caption for us anyway.
00229     if ( e->activated() )
00230         return;
00231     KParts::ReadOnlyPart::guiActivateEvent(e);
00232 }
00233 
00234 /*
00235 void KHTMLImage::slotImageJobFinished( KIO::Job *job )
00236 {
00237     if ( job->error() )
00238     {
00239         job->showErrorDialog();
00240         emit canceled( job->errorString() );
00241     }
00242     else
00243     {
00244         emit completed();
00245         QTimer::singleShot( 0, this, SLOT( updateWindowCaption() ) );
00246     }
00247 }
00248 
00249 void KHTMLImage::updateWindowCaption()
00250 {
00251     if ( !m_khtml )
00252         return;
00253 
00254     DOM::HTMLDocumentImpl *impl = dynamic_cast<DOM::HTMLDocumentImpl *>( m_khtml->document().handle() );
00255     if ( !impl )
00256         return;
00257 
00258     DOM::HTMLElementImpl *body = impl->body();
00259     if ( !body )
00260         return;
00261 
00262     DOM::NodeImpl *image = body->firstChild();
00263     if ( !image )
00264         return;
00265 
00266     khtml::RenderImage *renderImage = dynamic_cast<khtml::RenderImage *>( image->renderer() );
00267     if ( !renderImage )
00268         return;
00269 
00270     QPixmap pix = renderImage->pixmap();
00271 
00272     QString caption;
00273 
00274     KMimeType::Ptr mimeType;
00275     if ( !m_mimeType.isEmpty() )
00276         mimeType = KMimeType::mimeType( m_mimeType );
00277 
00278     if ( mimeType )
00279         caption = i18n( "%1 - %2x%3 Pixels" ).arg( mimeType->comment() )
00280                   .arg( pix.width() ).arg( pix.height() );
00281     else
00282         caption = i18n( "Image - %1x%2 Pixels" ).arg( pix.width() ).arg( pix.height() );
00283 
00284     emit setWindowCaption( caption );
00285     emit completed();
00286     emit setStatusBarText(i18n("Done."));
00287 }
00288 */
00289 
00290 void KHTMLImage::disposeImage()
00291 {
00292     if ( !m_image )
00293         return;
00294 
00295     m_image->deref( this );
00296     m_image = 0;
00297 }
00298 
00299 bool KHTMLImage::eventFilter(QObject *, QEvent *e) {
00300     switch (e->type()) {
00301       case QEvent::DragEnter:
00302       case QEvent::DragMove:
00303       case QEvent::DragLeave:
00304       case QEvent::Drop: {
00305         // find out if this part is embedded in a frame, and send the
00306     // event to its outside widget
00307     KHTMLPart *p = ::qt_cast<KHTMLPart *>(parent());
00308     if (p)
00309         return QApplication::sendEvent(p->widget(), e);
00310         // otherwise simply forward all dnd events to the part widget,
00311     // konqueror will handle them properly there
00312         return QApplication::sendEvent(widget(), e);
00313       }
00314       default: ;
00315     }
00316     return false;
00317 }
00318 
00319 KHTMLImageBrowserExtension::KHTMLImageBrowserExtension( KHTMLImage *parent, const char *name )
00320     : KParts::BrowserExtension( parent, name )
00321 {
00322     m_imgPart = parent;
00323 }
00324 
00325 int KHTMLImageBrowserExtension::xOffset()
00326 {
00327     return m_imgPart->doc()->view()->contentsX();
00328 }
00329 
00330 int KHTMLImageBrowserExtension::yOffset()
00331 {
00332     return m_imgPart->doc()->view()->contentsY();
00333 }
00334 
00335 void KHTMLImageBrowserExtension::print()
00336 {
00337     static_cast<KHTMLPartBrowserExtension *>( m_imgPart->doc()->browserExtension() )->print();
00338 }
00339 
00340 void KHTMLImageBrowserExtension::reparseConfiguration()
00341 {
00342     static_cast<KHTMLPartBrowserExtension *>( m_imgPart->doc()->browserExtension() )->reparseConfiguration();
00343     m_imgPart->doc()->setAutoloadImages( true );
00344 }
00345 
00346 
00347 void KHTMLImageBrowserExtension::disableScrolling()
00348 {
00349     static_cast<KHTMLPartBrowserExtension *>( m_imgPart->doc()->browserExtension() )->disableScrolling();
00350 }
00351 
00352 using namespace KParts;
00353 
00354 /* vim: et sw=4 ts=4
00355  */
00356 
00357 #include "khtmlimage.moc"

KHTML

Skip menu "KHTML"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal