1 /* This file is part of the KDE project
2 Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
20 #include "khtmlimage.h"
21 #include "khtmlview.h"
22 #include "khtml_ext.h"
23 #include "xml/dom_docimpl.h"
24 #include "html/html_documentimpl.h"
25 #include "html/html_elementimpl.h"
26 #include "rendering/render_image.h"
27 #include "misc/loader.h"
30 #include <QtCore/QTimer>
32 #include <kjobuidelegate.h>
34 #include <kcomponentdata.h>
35 #include <kmimetype.h>
38 #include <kactioncollection.h>
40 // Export init_khtmlimagefactory. This way we don't have to export the whole class
41 // just for khtmlimagepart. See khtmlimage_init.cpp
42 K_EXPORT_COMPONENT_FACTORY( khtmlimagefactory
, KHTMLImageFactory
)
44 KComponentData
*KHTMLImageFactory::s_componentData
= 0;
46 KHTMLImageFactory::KHTMLImageFactory()
48 s_componentData
= new KComponentData( "khtmlimage" );
51 KHTMLImageFactory::~KHTMLImageFactory()
53 delete s_componentData
;
56 KParts::Part
*KHTMLImageFactory::createPartObject( QWidget
*parentWidget
,
58 const char *className
, const QStringList
&args
)
60 KHTMLPart::GUIProfile prof
= KHTMLPart::DefaultGUI
;
61 if ( strcmp( className
, "Browser/View" ) == 0 ) // old hack
62 prof
= KHTMLPart::BrowserViewGUI
;
63 if (args
.contains("Browser/View"))
64 prof
= KHTMLPart::BrowserViewGUI
;
65 return new KHTMLImage( parentWidget
, parent
, prof
);
68 KHTMLImage::KHTMLImage( QWidget
*parentWidget
,
69 QObject
*parent
, KHTMLPart::GUIProfile prof
)
70 : KParts::ReadOnlyPart( parent
), m_image( 0 )
72 KHTMLPart
* parentPart
= qobject_cast
<KHTMLPart
*>( parent
);
73 setComponentData( KHTMLImageFactory::componentData(), prof
== KHTMLPart::BrowserViewGUI
&& !parentPart
);
75 KVBox
*box
= new KVBox( parentWidget
);
76 box
->setAcceptDrops( true );
78 m_khtml
= new KHTMLPart( box
, this, prof
);
79 m_khtml
->setAutoloadImages( true );
81 connect( m_khtml
->view(), SIGNAL( finishedLayout() ), this, SLOT( restoreScrollPosition() ) );
85 // VBox can't take focus, so pass it on to sub-widget
86 box
->setFocusProxy( m_khtml
->widget() );
88 m_ext
= new KHTMLImageBrowserExtension( this );
89 m_ext
->setObjectName( "be" );
91 // Remove unnecessary actions.
92 delete actionCollection()->action( "setEncoding" );
93 delete actionCollection()->action( "viewDocumentSource" );
94 delete actionCollection()->action( "selectAll" );
96 // forward important signals from the khtml part
98 // forward opening requests to parent frame (if existing)
99 KHTMLPart
*p
= qobject_cast
<KHTMLPart
*>(parent
);
100 KParts::BrowserExtension
*be
= p
? p
->browserExtension() : m_ext
;
101 connect(m_khtml
->browserExtension(), SIGNAL(openUrlRequestDelayed(const KUrl
&, const KParts::OpenUrlArguments
&, const KParts::BrowserArguments
&)),
102 be
, SIGNAL(openUrlRequestDelayed(const KUrl
&, const KParts::OpenUrlArguments
&, const KParts::BrowserArguments
&)));
104 connect(m_khtml
->browserExtension(), SIGNAL(popupMenu(QPoint
,KUrl
,mode_t
,KParts::OpenUrlArguments
,KParts::BrowserArguments
,KParts::BrowserExtension::PopupFlags
,KParts::BrowserExtension::ActionGroupMap
)),
105 this, SLOT(slotPopupMenu(QPoint
,KUrl
,mode_t
,KParts::OpenUrlArguments
,KParts::BrowserArguments
,KParts::BrowserExtension::PopupFlags
,KParts::BrowserExtension::ActionGroupMap
)));
107 connect( m_khtml
->browserExtension(), SIGNAL( enableAction( const char *, bool ) ),
108 m_ext
, SIGNAL( enableAction( const char *, bool ) ) );
110 m_ext
->setURLDropHandlingEnabled( true );
113 KHTMLImage::~KHTMLImage()
117 // important: delete the html part before the part or qobject destructor runs.
118 // we now delete the htmlpart which deletes the part's widget which makes
119 // _OUR_ m_widget 0 which in turn avoids our part destructor to delete the
121 // ### additional note: it _can_ be that the part has been deleted before:
122 // when we're in a html frameset and the view dies first, then it will also
125 delete static_cast<KHTMLPart
*>( m_khtml
);
128 bool KHTMLImage::openUrl( const KUrl
&url
)
130 static const QString
&html
= KGlobal::staticQString( "<html><body><img src=\"%1\"></body></html>" );
138 KParts::OpenUrlArguments args
= arguments();
139 m_mimeType
= args
.mimeType();
141 emit
setWindowCaption( url
.prettyUrl() );
143 // Need to keep a copy of the offsets since they are cleared when emitting completed
144 m_xOffset
= args
.xOffset();
145 m_yOffset
= args
.yOffset();
147 m_khtml
->begin( this->url() );
148 m_khtml
->setAutoloadImages( true );
150 DOM::DocumentImpl
*impl
= dynamic_cast<DOM::DocumentImpl
*>( m_khtml
->document().handle() ); // ### hack ;-)
151 if (!impl
) return false;
153 if ( arguments().reload() )
154 impl
->docLoader()->setCachePolicy( KIO::CC_Reload
);
156 khtml::DocLoader
*dl
= impl
->docLoader();
157 m_image
= dl
->requestImage( this->url().url() );
159 m_image
->ref( this );
161 m_khtml
->write( html
.arg( this->url().url() ) );
165 connect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
166 this, SLOT( updateWindowCaption() ) );
171 bool KHTMLImage::closeUrl()
174 return m_khtml
->closeUrl();
177 // This can happen after openUrl returns, or directly from m_image->ref()
178 void KHTMLImage::notifyFinished( khtml::CachedObject
*o
)
180 if ( !m_image
|| o
!= m_image
)
183 //const QPixmap &pix = m_image->pixmap();
186 KMimeType::Ptr mimeType
;
187 if ( !m_mimeType
.isEmpty() )
188 mimeType
= KMimeType::mimeType(m_mimeType
, KMimeType::ResolveAliases
);
191 if (m_image
&& !m_image
->suggestedTitle().isEmpty()) {
192 caption
= i18n( "%1 (%2 - %3x%4 Pixels)", m_image
->suggestedTitle(), mimeType
->comment(), m_image
->pixmap_size().width(), m_image
->pixmap_size().height() );
194 caption
= i18n( "%1 - %2x%3 Pixels" , mimeType
->comment() ,
195 m_image
->pixmap_size().width() , m_image
->pixmap_size().height() );
198 if (m_image
&& !m_image
->suggestedTitle().isEmpty()) {
199 caption
= i18n( "%1 (%2x%3 Pixels)" , m_image
->suggestedTitle(), m_image
->pixmap_size().width() , m_image
->pixmap_size().height() );
201 caption
= i18n( "Image - %1x%2 Pixels" , m_image
->pixmap_size().width() , m_image
->pixmap_size().height() );
205 emit
setWindowCaption( caption
);
207 emit
setStatusBarText(i18n("Done."));
210 void KHTMLImage::restoreScrollPosition()
212 if ( m_khtml
->view()->contentsY() == 0 ) {
213 m_khtml
->view()->setContentsPos( m_xOffset
, m_yOffset
);
217 void KHTMLImage::guiActivateEvent( KParts::GUIActivateEvent
*e
)
219 // prevent the base implementation from emitting setWindowCaption with
220 // our url. It destroys our pretty, previously caption. Konq saves/restores
221 // the caption for us anyway.
222 if ( e
->activated() )
224 KParts::ReadOnlyPart::guiActivateEvent(e
);
228 void KHTMLImage::slotImageJobFinished( KIO::Job *job )
232 job->uiDelegate()->showErrorMessage();
233 emit canceled( job->errorString() );
238 QTimer::singleShot( 0, this, SLOT( updateWindowCaption() ) );
242 void KHTMLImage::updateWindowCaption()
247 DOM::HTMLDocumentImpl *impl = dynamic_cast<DOM::HTMLDocumentImpl *>( m_khtml->document().handle() );
251 DOM::HTMLElementImpl *body = impl->body();
255 DOM::NodeImpl *image = body->firstChild();
259 khtml::RenderImage *renderImage = dynamic_cast<khtml::RenderImage *>( image->renderer() );
263 QPixmap pix = renderImage->pixmap();
267 KMimeType::Ptr mimeType;
268 if ( !m_mimeType.isEmpty() )
269 mimeType = KMimeType::mimeType( m_mimeType, KMimeType::ResolveAliases );
272 caption = i18n( "%1 - %2x%3 Pixels" ).arg( mimeType->comment() )
273 .arg( pix.width() ).arg( pix.height() );
275 caption = i18n( "Image - %1x%2 Pixels" ).arg( pix.width() ).arg( pix.height() );
277 emit setWindowCaption( caption );
279 emit setStatusBarText(i18n("Done."));
283 void KHTMLImage::disposeImage()
288 m_image
->deref( this );
292 KHTMLImageBrowserExtension::KHTMLImageBrowserExtension( KHTMLImage
*parent
)
293 : KParts::BrowserExtension( parent
)
298 int KHTMLImageBrowserExtension::xOffset()
300 return m_imgPart
->doc()->view()->contentsX();
303 int KHTMLImageBrowserExtension::yOffset()
305 return m_imgPart
->doc()->view()->contentsY();
308 void KHTMLImageBrowserExtension::print()
310 static_cast<KHTMLPartBrowserExtension
*>( m_imgPart
->doc()->browserExtension() )->print();
313 void KHTMLImageBrowserExtension::reparseConfiguration()
315 static_cast<KHTMLPartBrowserExtension
*>( m_imgPart
->doc()->browserExtension() )->reparseConfiguration();
316 m_imgPart
->doc()->setAutoloadImages( true );
320 void KHTMLImageBrowserExtension::disableScrolling()
322 static_cast<KHTMLPartBrowserExtension
*>( m_imgPart
->doc()->browserExtension() )->disableScrolling();
325 void KHTMLImage::slotPopupMenu( const QPoint
&global
, const KUrl
&url
, mode_t mode
,
326 const KParts::OpenUrlArguments
&origArgs
,
327 const KParts::BrowserArguments
&browserArgs
,
328 KParts::BrowserExtension::PopupFlags flags
,
329 const KParts::BrowserExtension::ActionGroupMap
& actionGroups
)
331 KParts::OpenUrlArguments args
= origArgs
;
332 args
.setMimeType(m_mimeType
);
333 m_ext
->popupMenu(global
, url
, mode
, args
, browserArgs
, flags
, actionGroups
);
336 #include "khtmlimage.moc"