tdehtmlimage.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., 51 Franklin Street, Fifth Floor, 00017 Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "tdehtmlimage.h" 00021 #include "tdehtmlview.h" 00022 #include "tdehtml_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 <tqvbox.h> 00030 #include <tqtimer.h> 00031 00032 #include <tdeio/job.h> 00033 #include <kinstance.h> 00034 #include <kmimetype.h> 00035 #include <tdelocale.h> 00036 00037 K_EXPORT_COMPONENT_FACTORY( tdehtmlimagefactory /*NOT the part name, see Makefile.am*/, TDEHTMLImageFactory ) 00038 00039 TDEInstance *TDEHTMLImageFactory::s_instance = 0; 00040 00041 TDEHTMLImageFactory::TDEHTMLImageFactory() 00042 { 00043 s_instance = new TDEInstance( "tdehtmlimage" ); 00044 } 00045 00046 TDEHTMLImageFactory::~TDEHTMLImageFactory() 00047 { 00048 delete s_instance; 00049 } 00050 00051 KParts::Part *TDEHTMLImageFactory::createPartObject( TQWidget *parentWidget, const char *widgetName, 00052 TQObject *parent, const char *name, 00053 const char *className, const TQStringList & ) 00054 { 00055 TDEHTMLPart::GUIProfile prof = TDEHTMLPart::DefaultGUI; 00056 if ( strcmp( className, "Browser/View" ) == 0 ) 00057 prof = TDEHTMLPart::BrowserViewGUI; 00058 return new TDEHTMLImage( parentWidget, widgetName, parent, name, prof ); 00059 } 00060 00061 TDEHTMLImage::TDEHTMLImage( TQWidget *parentWidget, const char *widgetName, 00062 TQObject *parent, const char *name, TDEHTMLPart::GUIProfile prof ) 00063 : KParts::ReadOnlyPart( parent, name ), m_image( 0 ) 00064 { 00065 TDEHTMLPart* parentPart = ::tqqt_cast<TDEHTMLPart *>( parent ); 00066 setInstance( TDEHTMLImageFactory::instance(), prof == TDEHTMLPart::BrowserViewGUI && !parentPart ); 00067 00068 TQVBox *box = new TQVBox( parentWidget, widgetName ); 00069 00070 m_tdehtml = new TDEHTMLPart( box, widgetName, this, "htmlimagepart", prof ); 00071 m_tdehtml->setAutoloadImages( true ); 00072 m_tdehtml->widget()->installEventFilter(this); 00073 connect( m_tdehtml->view(), TQT_SIGNAL( finishedLayout() ), this, TQT_SLOT( restoreScrollPosition() ) ); 00074 00075 setWidget( box ); 00076 00077 // VBox can't take focus, so pass it on to sub-widget 00078 box->setFocusProxy( m_tdehtml->widget() ); 00079 00080 m_ext = new TDEHTMLImageBrowserExtension( this, "be" ); 00081 00082 // Remove unnecessary actions. 00083 TDEAction *encodingAction = actionCollection()->action( "setEncoding" ); 00084 if ( encodingAction ) 00085 { 00086 encodingAction->unplugAll(); 00087 delete encodingAction; 00088 } 00089 TDEAction *viewSourceAction= actionCollection()->action( "viewDocumentSource" ); 00090 if ( viewSourceAction ) 00091 { 00092 viewSourceAction->unplugAll(); 00093 delete viewSourceAction; 00094 } 00095 00096 TDEAction *selectAllAction= actionCollection()->action( "selectAll" ); 00097 if ( selectAllAction ) 00098 { 00099 selectAllAction->unplugAll(); 00100 delete selectAllAction; 00101 } 00102 00103 // forward important signals from the tdehtml part 00104 00105 // forward opening requests to parent frame (if existing) 00106 TDEHTMLPart *p = ::tqqt_cast<TDEHTMLPart *>(parent); 00107 KParts::BrowserExtension *be = p ? p->browserExtension() : m_ext; 00108 connect(m_tdehtml->browserExtension(), TQT_SIGNAL(openURLRequestDelayed(const KURL &, const KParts::URLArgs &)), 00109 be, TQT_SIGNAL(openURLRequestDelayed(const KURL &, const KParts::URLArgs &))); 00110 00111 connect( m_tdehtml->browserExtension(), TQT_SIGNAL( popupMenu( KXMLGUIClient *, const TQPoint &, const KURL &, 00112 const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t) ), m_ext, TQT_SIGNAL( popupMenu( KXMLGUIClient *, const TQPoint &, const KURL &, 00113 const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t) ) ); 00114 00115 connect( m_tdehtml->browserExtension(), TQT_SIGNAL( enableAction( const char *, bool ) ), 00116 m_ext, TQT_SIGNAL( enableAction( const char *, bool ) ) ); 00117 00118 m_ext->setURLDropHandlingEnabled( true ); 00119 } 00120 00121 TDEHTMLImage::~TDEHTMLImage() 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_tdehtml ) 00133 delete static_cast<TDEHTMLPart *>( m_tdehtml ); 00134 } 00135 00136 bool TDEHTMLImage::openURL( const KURL &url ) 00137 { 00138 static const TQString &html = TDEGlobal::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_tdehtml->begin( m_url ); 00156 m_tdehtml->setAutoloadImages( true ); 00157 00158 DOM::DocumentImpl *impl = dynamic_cast<DOM::DocumentImpl *>( m_tdehtml->document().handle() ); // ### hack ;-) 00159 if (!impl) return false; 00160 if ( m_ext->urlArgs().reload ) 00161 impl->docLoader()->setCachePolicy( TDEIO::CC_Reload ); 00162 00163 tdehtml::DocLoader *dl = impl->docLoader(); 00164 m_image = dl->requestImage( m_url.url() ); 00165 if ( m_image ) 00166 m_image->ref( this ); 00167 00168 m_tdehtml->write( html.arg( m_url.url() ) ); 00169 m_tdehtml->end(); 00170 00171 /* 00172 connect( tdehtml::Cache::loader(), TQT_SIGNAL( requestDone( tdehtml::DocLoader*, tdehtml::CachedObject *) ), 00173 this, TQT_SLOT( updateWindowCaption() ) ); 00174 */ 00175 return true; 00176 } 00177 00178 bool TDEHTMLImage::closeURL() 00179 { 00180 disposeImage(); 00181 return m_tdehtml->closeURL(); 00182 } 00183 00184 // This can happen after openURL returns, or directly from m_image->ref() 00185 void TDEHTMLImage::notifyFinished( tdehtml::CachedObject *o ) 00186 { 00187 if ( !m_image || o != m_image ) 00188 return; 00189 00190 const TQPixmap &pix = m_image->pixmap(); 00191 TQString 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 TDEHTMLImage::restoreScrollPosition() 00218 { 00219 if ( m_tdehtml->view()->contentsY() == 0 ) { 00220 m_tdehtml->view()->setContentsPos( m_xOffset, m_yOffset ); 00221 } 00222 } 00223 00224 void TDEHTMLImage::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 TDEHTMLImage::slotImageJobFinished( TDEIO::Job *job ) 00236 { 00237 if ( job->error() ) 00238 { 00239 job->showErrorDialog(); 00240 emit canceled( job->errorString() ); 00241 } 00242 else 00243 { 00244 emit completed(); 00245 TQTimer::singleShot( 0, this, TQT_SLOT( updateWindowCaption() ) ); 00246 } 00247 } 00248 00249 void TDEHTMLImage::updateWindowCaption() 00250 { 00251 if ( !m_tdehtml ) 00252 return; 00253 00254 DOM::HTMLDocumentImpl *impl = dynamic_cast<DOM::HTMLDocumentImpl *>( m_tdehtml->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 tdehtml::RenderImage *renderImage = dynamic_cast<tdehtml::RenderImage *>( image->renderer() ); 00267 if ( !renderImage ) 00268 return; 00269 00270 TQPixmap pix = renderImage->pixmap(); 00271 00272 TQString 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 TDEHTMLImage::disposeImage() 00291 { 00292 if ( !m_image ) 00293 return; 00294 00295 m_image->deref( this ); 00296 m_image = 0; 00297 } 00298 00299 bool TDEHTMLImage::eventFilter(TQObject *, TQEvent *e) { 00300 switch (e->type()) { 00301 case TQEvent::DragEnter: 00302 case TQEvent::DragMove: 00303 case TQEvent::DragLeave: 00304 case TQEvent::Drop: { 00305 // find out if this part is embedded in a frame, and send the 00306 // event to its outside widget 00307 TDEHTMLPart *p = ::tqqt_cast<TDEHTMLPart *>(parent()); 00308 if (p) 00309 return TQApplication::sendEvent(p->widget(), e); 00310 // otherwise simply forward all dnd events to the part widget, 00311 // konqueror will handle them properly there 00312 return TQApplication::sendEvent(widget(), e); 00313 } 00314 default: ; 00315 } 00316 return false; 00317 } 00318 00319 TDEHTMLImageBrowserExtension::TDEHTMLImageBrowserExtension( TDEHTMLImage *parent, const char *name ) 00320 : KParts::BrowserExtension( parent, name ) 00321 { 00322 m_imgPart = parent; 00323 } 00324 00325 int TDEHTMLImageBrowserExtension::xOffset() 00326 { 00327 return m_imgPart->doc()->view()->contentsX(); 00328 } 00329 00330 int TDEHTMLImageBrowserExtension::yOffset() 00331 { 00332 return m_imgPart->doc()->view()->contentsY(); 00333 } 00334 00335 void TDEHTMLImageBrowserExtension::print() 00336 { 00337 static_cast<TDEHTMLPartBrowserExtension *>( m_imgPart->doc()->browserExtension() )->print(); 00338 } 00339 00340 void TDEHTMLImageBrowserExtension::reparseConfiguration() 00341 { 00342 static_cast<TDEHTMLPartBrowserExtension *>( m_imgPart->doc()->browserExtension() )->reparseConfiguration(); 00343 m_imgPart->doc()->setAutoloadImages( true ); 00344 } 00345 00346 00347 void TDEHTMLImageBrowserExtension::disableScrolling() 00348 { 00349 static_cast<TDEHTMLPartBrowserExtension *>( m_imgPart->doc()->browserExtension() )->disableScrolling(); 00350 } 00351 00352 using namespace KParts; 00353 00354 /* vim: et sw=4 ts=4 00355 */ 00356 00357 #include "tdehtmlimage.moc"