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 00030 #include <QtCore/QTimer> 00031 00032 #include <kjobuidelegate.h> 00033 #include <kio/job.h> 00034 #include <kcomponentdata.h> 00035 #include <kmimetype.h> 00036 #include <klocale.h> 00037 #include <kvbox.h> 00038 #include <kactioncollection.h> 00039 00040 KComponentData *KHTMLImageFactory::s_componentData = 0; 00041 00042 KHTMLImageFactory::KHTMLImageFactory() 00043 { 00044 s_componentData = new KComponentData( "khtmlimage" ); 00045 } 00046 00047 KHTMLImageFactory::~KHTMLImageFactory() 00048 { 00049 delete s_componentData; 00050 } 00051 00052 QObject * KHTMLImageFactory::create(const char* iface, 00053 QWidget *parentWidget, 00054 QObject *parent, 00055 const QVariantList& args, 00056 const QString &keyword) 00057 { 00058 Q_UNUSED(keyword); 00059 KHTMLPart::GUIProfile prof = KHTMLPart::DefaultGUI; 00060 if (strcmp( iface, "Browser/View" ) == 0) // old hack, now unused - KDE5: remove 00061 prof = KHTMLPart::BrowserViewGUI; 00062 if (args.contains("Browser/View")) 00063 prof = KHTMLPart::BrowserViewGUI; 00064 return new KHTMLImage( parentWidget, parent, prof ); 00065 } 00066 00067 KHTMLImage::KHTMLImage( QWidget *parentWidget, 00068 QObject *parent, KHTMLPart::GUIProfile prof ) 00069 : KParts::ReadOnlyPart( parent ), m_image( 0 ) 00070 { 00071 KHTMLPart* parentPart = qobject_cast<KHTMLPart*>( parent ); 00072 setComponentData( KHTMLImageFactory::componentData(), prof == KHTMLPart::BrowserViewGUI && !parentPart ); 00073 00074 KVBox *box = new KVBox( parentWidget ); 00075 box->setAcceptDrops( true ); 00076 00077 m_khtml = new KHTMLPart( box, this, prof ); 00078 m_khtml->setAutoloadImages( true ); 00079 00080 // We do not want our subpart to be destroyed when its widget is, 00081 // since that may cause all KHTMLParts to die when we're dealing 00082 // with 00083 m_khtml->setAutoDeletePart( false ); 00084 00085 connect( m_khtml->view(), SIGNAL( finishedLayout() ), this, SLOT( restoreScrollPosition() ) ); 00086 00087 setWidget( box ); 00088 00089 // VBox can't take focus, so pass it on to sub-widget 00090 box->setFocusProxy( m_khtml->widget() ); 00091 00092 m_ext = new KHTMLImageBrowserExtension( this ); 00093 m_ext->setObjectName( "be" ); 00094 00095 m_sbExt = new KParts::StatusBarExtension( this ); 00096 m_sbExt->setObjectName( "sbe" ); 00097 00098 // Remove unnecessary actions. 00099 delete actionCollection()->action( "setEncoding" ); 00100 delete actionCollection()->action( "viewDocumentSource" ); 00101 delete actionCollection()->action( "selectAll" ); 00102 00103 // forward important signals from the khtml part 00104 00105 // forward opening requests to parent frame (if existing) 00106 KHTMLPart *p = qobject_cast<KHTMLPart*>(parent); 00107 KParts::BrowserExtension *be = p ? p->browserExtension() : m_ext; 00108 connect(m_khtml->browserExtension(), SIGNAL(openUrlRequestDelayed(const KUrl &, const KParts::OpenUrlArguments&, const KParts::BrowserArguments &)), 00109 be, SIGNAL(openUrlRequestDelayed(const KUrl &, const KParts::OpenUrlArguments&, const KParts::BrowserArguments &))); 00110 00111 connect(m_khtml->browserExtension(), SIGNAL(popupMenu(QPoint,KUrl,mode_t,KParts::OpenUrlArguments,KParts::BrowserArguments,KParts::BrowserExtension::PopupFlags,KParts::BrowserExtension::ActionGroupMap)), 00112 this, SLOT(slotPopupMenu(QPoint,KUrl,mode_t,KParts::OpenUrlArguments,KParts::BrowserArguments,KParts::BrowserExtension::PopupFlags,KParts::BrowserExtension::ActionGroupMap))); 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 // Propagate statusbar to our kid part. 00140 KParts::StatusBarExtension::childObject( m_khtml )->setStatusBar( m_sbExt->statusBar() ); 00141 00142 disposeImage(); 00143 00144 setUrl(url); 00145 00146 emit started( 0 ); 00147 00148 KParts::OpenUrlArguments args = arguments(); 00149 m_mimeType = args.mimeType(); 00150 00151 emit setWindowCaption( url.prettyUrl() ); 00152 00153 // Need to keep a copy of the offsets since they are cleared when emitting completed 00154 m_xOffset = args.xOffset(); 00155 m_yOffset = args.yOffset(); 00156 00157 m_khtml->begin( this->url() ); 00158 m_khtml->setAutoloadImages( true ); 00159 00160 DOM::DocumentImpl *impl = dynamic_cast<DOM::DocumentImpl *>( m_khtml->document().handle() ); // ### hack ;-) 00161 if (!impl) return false; 00162 00163 if ( arguments().reload() ) 00164 impl->docLoader()->setCachePolicy( KIO::CC_Reload ); 00165 00166 khtml::DocLoader *dl = impl->docLoader(); 00167 m_image = dl->requestImage( this->url().url() ); 00168 if ( m_image ) 00169 m_image->ref( this ); 00170 00171 m_khtml->write( html.arg( this->url().url() ) ); 00172 m_khtml->end(); 00173 00174 /* 00175 connect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ), 00176 this, SLOT( updateWindowCaption() ) ); 00177 */ 00178 return true; 00179 } 00180 00181 bool KHTMLImage::closeUrl() 00182 { 00183 disposeImage(); 00184 return m_khtml->closeUrl(); 00185 } 00186 00187 // This can happen after openUrl returns, or directly from m_image->ref() 00188 void KHTMLImage::notifyFinished( khtml::CachedObject *o ) 00189 { 00190 if ( !m_image || o != m_image ) 00191 return; 00192 00193 //const QPixmap &pix = m_image->pixmap(); 00194 QString caption; 00195 00196 KMimeType::Ptr mimeType; 00197 if ( !m_mimeType.isEmpty() ) 00198 mimeType = KMimeType::mimeType(m_mimeType, KMimeType::ResolveAliases); 00199 00200 if ( mimeType ) { 00201 if (m_image && !m_image->suggestedTitle().isEmpty()) { 00202 caption = i18n( "%1 (%2 - %3x%4 Pixels)", m_image->suggestedTitle(), mimeType->comment(), m_image->pixmap_size().width(), m_image->pixmap_size().height() ); 00203 } else { 00204 caption = i18n( "%1 - %2x%3 Pixels" , mimeType->comment() , 00205 m_image->pixmap_size().width() , m_image->pixmap_size().height() ); 00206 } 00207 } else { 00208 if (m_image && !m_image->suggestedTitle().isEmpty()) { 00209 caption = i18n( "%1 (%2x%3 Pixels)" , m_image->suggestedTitle(), m_image->pixmap_size().width() , m_image->pixmap_size().height() ); 00210 } else { 00211 caption = i18n( "Image - %1x%2 Pixels" , m_image->pixmap_size().width() , m_image->pixmap_size().height() ); 00212 } 00213 } 00214 00215 emit setWindowCaption( caption ); 00216 emit completed(); 00217 emit setStatusBarText(i18n("Done.")); 00218 } 00219 00220 void KHTMLImage::restoreScrollPosition() 00221 { 00222 if ( m_khtml->view()->contentsY() == 0 ) { 00223 m_khtml->view()->setContentsPos( m_xOffset, m_yOffset ); 00224 } 00225 } 00226 00227 void KHTMLImage::guiActivateEvent( KParts::GUIActivateEvent *e ) 00228 { 00229 // prevent the base implementation from emitting setWindowCaption with 00230 // our url. It destroys our pretty, previously caption. Konq saves/restores 00231 // the caption for us anyway. 00232 if ( e->activated() ) 00233 return; 00234 KParts::ReadOnlyPart::guiActivateEvent(e); 00235 } 00236 00237 /* 00238 void KHTMLImage::slotImageJobFinished( KIO::Job *job ) 00239 { 00240 if ( job->error() ) 00241 { 00242 job->uiDelegate()->showErrorMessage(); 00243 emit canceled( job->errorString() ); 00244 } 00245 else 00246 { 00247 emit completed(); 00248 QTimer::singleShot( 0, this, SLOT( updateWindowCaption() ) ); 00249 } 00250 } 00251 00252 void KHTMLImage::updateWindowCaption() 00253 { 00254 if ( !m_khtml ) 00255 return; 00256 00257 DOM::HTMLDocumentImpl *impl = dynamic_cast<DOM::HTMLDocumentImpl *>( m_khtml->document().handle() ); 00258 if ( !impl ) 00259 return; 00260 00261 DOM::HTMLElementImpl *body = impl->body(); 00262 if ( !body ) 00263 return; 00264 00265 DOM::NodeImpl *image = body->firstChild(); 00266 if ( !image ) 00267 return; 00268 00269 khtml::RenderImage *renderImage = dynamic_cast<khtml::RenderImage *>( image->renderer() ); 00270 if ( !renderImage ) 00271 return; 00272 00273 QPixmap pix = renderImage->pixmap(); 00274 00275 QString caption; 00276 00277 KMimeType::Ptr mimeType; 00278 if ( !m_mimeType.isEmpty() ) 00279 mimeType = KMimeType::mimeType( m_mimeType, KMimeType::ResolveAliases ); 00280 00281 if ( mimeType ) 00282 caption = i18n( "%1 - %2x%3 Pixels" ).arg( mimeType->comment() ) 00283 .arg( pix.width() ).arg( pix.height() ); 00284 else 00285 caption = i18n( "Image - %1x%2 Pixels" ).arg( pix.width() ).arg( pix.height() ); 00286 00287 emit setWindowCaption( caption ); 00288 emit completed(); 00289 emit setStatusBarText(i18n("Done.")); 00290 } 00291 */ 00292 00293 void KHTMLImage::disposeImage() 00294 { 00295 if ( !m_image ) 00296 return; 00297 00298 m_image->deref( this ); 00299 m_image = 0; 00300 } 00301 00302 KHTMLImageBrowserExtension::KHTMLImageBrowserExtension( KHTMLImage *parent ) 00303 : KParts::BrowserExtension( parent ) 00304 { 00305 m_imgPart = parent; 00306 } 00307 00308 int KHTMLImageBrowserExtension::xOffset() 00309 { 00310 return m_imgPart->doc()->view()->contentsX(); 00311 } 00312 00313 int KHTMLImageBrowserExtension::yOffset() 00314 { 00315 return m_imgPart->doc()->view()->contentsY(); 00316 } 00317 00318 void KHTMLImageBrowserExtension::print() 00319 { 00320 static_cast<KHTMLPartBrowserExtension *>( m_imgPart->doc()->browserExtension() )->print(); 00321 } 00322 00323 void KHTMLImageBrowserExtension::reparseConfiguration() 00324 { 00325 static_cast<KHTMLPartBrowserExtension *>( m_imgPart->doc()->browserExtension() )->reparseConfiguration(); 00326 m_imgPart->doc()->setAutoloadImages( true ); 00327 } 00328 00329 00330 void KHTMLImageBrowserExtension::disableScrolling() 00331 { 00332 static_cast<KHTMLPartBrowserExtension *>( m_imgPart->doc()->browserExtension() )->disableScrolling(); 00333 } 00334 00335 void KHTMLImage::slotPopupMenu( const QPoint &global, const KUrl &url, mode_t mode, 00336 const KParts::OpenUrlArguments &origArgs, 00337 const KParts::BrowserArguments &browserArgs, 00338 KParts::BrowserExtension::PopupFlags flags, 00339 const KParts::BrowserExtension::ActionGroupMap& actionGroups ) 00340 { 00341 KParts::OpenUrlArguments args = origArgs; 00342 args.setMimeType(m_mimeType); 00343 m_ext->popupMenu(global, url, mode, args, browserArgs, flags, actionGroups); 00344 } 00345 00346 #include "khtmlimage.moc"
KDE 4.6 API Reference