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

KHTML

khtml_ext.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 2 -*-
00002 /* This file is part of the KDE project
00003  *
00004  * Copyright (C) 2000-2003 Simon Hausmann <hausmann@kde.org>
00005  *               2001-2003 George Staikos <staikos@kde.org>
00006  *               2001-2003 Laurent Montel <montel@kde.org>
00007  *               2001-2003 Dirk Mueller <mueller@kde.org>
00008  *               2001-2003 Waldo Bastian <bastian@kde.org>
00009  *               2001-2003 David Faure <faure@kde.org>
00010  *               2001-2003 Daniel Naber <dnaber@kde.org>
00011  *
00012  * This library is free software; you can redistribute it and/or
00013  * modify it under the terms of the GNU Library General Public
00014  * License as published by the Free Software Foundation; either
00015  * version 2 of the License, or (at your option) any later version.
00016  *
00017  * This library is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020  * Library General Public License for more details.
00021  *
00022  * You should have received a copy of the GNU Library General Public License
00023  * along with this library; see the file COPYING.LIB.  If not, write to
00024  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00025  * Boston, MA 02110-1301, USA.
00026  */
00027 
00028 #include <assert.h>
00029 #include "khtml_ext.h"
00030 #include "khtmlview.h"
00031 #include "khtml_pagecache.h"
00032 #include "rendering/render_form.h"
00033 #include "rendering/render_image.h"
00034 #include "html/html_imageimpl.h"
00035 #include "misc/loader.h"
00036 #include "dom/html_form.h"
00037 #include "dom/html_image.h"
00038 #include <qclipboard.h>
00039 #include <qfileinfo.h>
00040 #include <qpopupmenu.h>
00041 #include <qurl.h>
00042 #include <qmetaobject.h>
00043 #include <private/qucomextra_p.h>
00044 #include <qdragobject.h>
00045 
00046 #include <kdebug.h>
00047 #include <klocale.h>
00048 #include <kfiledialog.h>
00049 #include <kio/job.h>
00050 #include <kprocess.h>
00051 #include <ktoolbarbutton.h>
00052 #include <ktoolbar.h>
00053 #include <ksavefile.h>
00054 #include <kurldrag.h>
00055 #include <kstringhandler.h>
00056 #include <kapplication.h>
00057 #include <kmessagebox.h>
00058 #include <kstandarddirs.h>
00059 #include <krun.h>
00060 #include <kurifilter.h>
00061 #include <kiconloader.h>
00062 #include <kdesktopfile.h>
00063 #include <kmultipledrag.h>
00064 #include <kinputdialog.h>
00065 
00066 #include "khtml_factory.h"
00067 
00068 #include "dom/dom_element.h"
00069 #include "misc/htmltags.h"
00070 
00071 #include "khtmlpart_p.h"
00072 
00073 KHTMLPartBrowserExtension::KHTMLPartBrowserExtension( KHTMLPart *parent, const char *name )
00074 : KParts::BrowserExtension( parent, name )
00075 {
00076     m_part = parent;
00077     setURLDropHandlingEnabled( true );
00078 
00079     enableAction( "cut", false );
00080     enableAction( "copy", false );
00081     enableAction( "paste", false );
00082 
00083     m_connectedToClipboard = false;
00084 }
00085 
00086 int KHTMLPartBrowserExtension::xOffset()
00087 {
00088     return m_part->view()->contentsX();
00089 }
00090 
00091 int KHTMLPartBrowserExtension::yOffset()
00092 {
00093   return m_part->view()->contentsY();
00094 }
00095 
00096 void KHTMLPartBrowserExtension::saveState( QDataStream &stream )
00097 {
00098   //kdDebug( 6050 ) << "saveState!" << endl;
00099   m_part->saveState( stream );
00100 }
00101 
00102 void KHTMLPartBrowserExtension::restoreState( QDataStream &stream )
00103 {
00104   //kdDebug( 6050 ) << "restoreState!" << endl;
00105   m_part->restoreState( stream );
00106 }
00107 
00108 void KHTMLPartBrowserExtension::editableWidgetFocused( QWidget *widget )
00109 {
00110     m_editableFormWidget = widget;
00111     updateEditActions();
00112 
00113     if ( !m_connectedToClipboard && m_editableFormWidget )
00114     {
00115         connect( QApplication::clipboard(), SIGNAL( dataChanged() ),
00116                  this, SLOT( updateEditActions() ) );
00117 
00118         if ( m_editableFormWidget->inherits( "QLineEdit" ) || m_editableFormWidget->inherits( "QTextEdit" ) )
00119             connect( m_editableFormWidget, SIGNAL( selectionChanged() ),
00120                      this, SLOT( updateEditActions() ) );
00121 
00122         m_connectedToClipboard = true;
00123     }
00124     editableWidgetFocused();
00125 }
00126 
00127 void KHTMLPartBrowserExtension::editableWidgetBlurred( QWidget * /*widget*/ )
00128 {
00129     QWidget *oldWidget = m_editableFormWidget;
00130 
00131     m_editableFormWidget = 0;
00132     enableAction( "cut", false );
00133     enableAction( "paste", false );
00134     m_part->emitSelectionChanged();
00135 
00136     if ( m_connectedToClipboard )
00137     {
00138         disconnect( QApplication::clipboard(), SIGNAL( dataChanged() ),
00139                     this, SLOT( updateEditActions() ) );
00140 
00141         if ( oldWidget )
00142         {
00143             if ( oldWidget->inherits( "QLineEdit" ) || oldWidget->inherits( "QTextEdit" ) )
00144                 disconnect( oldWidget, SIGNAL( selectionChanged() ),
00145                             this, SLOT( updateEditActions() ) );
00146         }
00147 
00148         m_connectedToClipboard = false;
00149     }
00150     editableWidgetBlurred();
00151 }
00152 
00153 void KHTMLPartBrowserExtension::setExtensionProxy( KParts::BrowserExtension *proxy )
00154 {
00155     if ( m_extensionProxy )
00156     {
00157         disconnect( m_extensionProxy, SIGNAL( enableAction( const char *, bool ) ),
00158                     this, SLOT( extensionProxyActionEnabled( const char *, bool ) ) );
00159         if ( m_extensionProxy->inherits( "KHTMLPartBrowserExtension" ) )
00160         {
00161             disconnect( m_extensionProxy, SIGNAL( editableWidgetFocused() ),
00162                         this, SLOT( extensionProxyEditableWidgetFocused() ) );
00163             disconnect( m_extensionProxy, SIGNAL( editableWidgetBlurred() ),
00164                         this, SLOT( extensionProxyEditableWidgetBlurred() ) );
00165         }
00166     }
00167 
00168     m_extensionProxy = proxy;
00169 
00170     if ( m_extensionProxy )
00171     {
00172         connect( m_extensionProxy, SIGNAL( enableAction( const char *, bool ) ),
00173                  this, SLOT( extensionProxyActionEnabled( const char *, bool ) ) );
00174         if ( m_extensionProxy->inherits( "KHTMLPartBrowserExtension" ) )
00175         {
00176             connect( m_extensionProxy, SIGNAL( editableWidgetFocused() ),
00177                      this, SLOT( extensionProxyEditableWidgetFocused() ) );
00178             connect( m_extensionProxy, SIGNAL( editableWidgetBlurred() ),
00179                      this, SLOT( extensionProxyEditableWidgetBlurred() ) );
00180         }
00181 
00182         enableAction( "cut", m_extensionProxy->isActionEnabled( "cut" ) );
00183         enableAction( "copy", m_extensionProxy->isActionEnabled( "copy" ) );
00184         enableAction( "paste", m_extensionProxy->isActionEnabled( "paste" ) );
00185     }
00186     else
00187     {
00188         updateEditActions();
00189         enableAction( "copy", false ); // ### re-check this
00190     }
00191 }
00192 
00193 void KHTMLPartBrowserExtension::cut()
00194 {
00195     if ( m_extensionProxy )
00196     {
00197         callExtensionProxyMethod( "cut()" );
00198         return;
00199     }
00200 
00201     if ( !m_editableFormWidget )
00202         return;
00203 
00204     if ( m_editableFormWidget->inherits( "QLineEdit" ) )
00205         static_cast<QLineEdit *>( &(*m_editableFormWidget) )->cut();
00206     else if ( m_editableFormWidget->inherits( "QTextEdit" ) )
00207         static_cast<QTextEdit *>( &(*m_editableFormWidget) )->cut();
00208 }
00209 
00210 void KHTMLPartBrowserExtension::copy()
00211 {
00212     if ( m_extensionProxy )
00213     {
00214         callExtensionProxyMethod( "copy()" );
00215         return;
00216     }
00217 
00218     kdDebug( 6050 ) << "************! KHTMLPartBrowserExtension::copy()" << endl;
00219     if ( !m_editableFormWidget )
00220     {
00221         // get selected text and paste to the clipboard
00222         QString text= m_part->selectedText();
00223     text.replace( QChar( 0xa0 ), ' ' );
00224 
00225 
00226         QClipboard *cb = QApplication::clipboard();
00227         disconnect( cb, SIGNAL( selectionChanged() ), m_part, SLOT( slotClearSelection() ) );
00228 #ifndef QT_NO_MIMECLIPBOARD
00229     QString htmltext;
00230     /*
00231      * When selectionModeEnabled, that means the user has just selected
00232      * the text, not ctrl+c to copy it.  The selection clipboard
00233      * doesn't seem to support mime type, so to save time, don't calculate
00234      * the selected text as html.
00235      * optomisation disabled for now until everything else works.
00236     */
00237     //if(!cb->selectionModeEnabled())
00238         htmltext = m_part->selectedTextAsHTML();
00239     QTextDrag *textdrag = new QTextDrag(text, 0L);
00240     KMultipleDrag *drag = new KMultipleDrag( m_editableFormWidget );
00241     drag->addDragObject( textdrag );
00242     if(!htmltext.isEmpty()) {
00243         htmltext.replace( QChar( 0xa0 ), ' ' );
00244         QTextDrag *htmltextdrag = new QTextDrag(htmltext, 0L);
00245         htmltextdrag->setSubtype("html");
00246         drag->addDragObject( htmltextdrag );
00247     }
00248         cb->setData(drag);
00249 #else
00250     cb->setText(text);
00251 #endif
00252 
00253         connect( cb, SIGNAL( selectionChanged() ), m_part, SLOT( slotClearSelection() ) );
00254     }
00255     else
00256     {
00257         if ( m_editableFormWidget->inherits( "QLineEdit" ) )
00258             static_cast<QLineEdit *>( &(*m_editableFormWidget) )->copy();
00259         else if ( m_editableFormWidget->inherits( "QTextEdit" ) )
00260             static_cast<QTextEdit *>( &(*m_editableFormWidget) )->copy();
00261     }
00262 }
00263 
00264 void KHTMLPartBrowserExtension::searchProvider()
00265 {
00266     // action name is of form "previewProvider[<searchproviderprefix>:]"
00267     const QString searchProviderPrefix = QString( sender()->name() ).mid( 14 );
00268 
00269     KURIFilterData data;
00270     QStringList list;
00271     data.setData( searchProviderPrefix + m_part->selectedText() );
00272     list << "kurisearchfilter" << "kuriikwsfilter";
00273 
00274     if( !KURIFilter::self()->filterURI(data, list) )
00275     {
00276         KDesktopFile file("searchproviders/google.desktop", true, "services");
00277     QString encodedSearchTerm = m_part->selectedText();
00278     QUrl::encode(encodedSearchTerm);
00279     data.setData(file.readEntry("Query").replace("\\{@}", encodedSearchTerm));
00280     }
00281 
00282     KParts::URLArgs args;
00283     args.frameName = "_blank";
00284 
00285     emit m_part->browserExtension()->openURLRequest( data.uri(), args );
00286 }
00287 
00288 void KHTMLPartBrowserExtension::openSelection()
00289 {
00290     KParts::URLArgs args;
00291     args.frameName = "_blank";
00292 
00293     emit m_part->browserExtension()->openURLRequest( m_part->selectedText(), args );
00294 }
00295 
00296 void KHTMLPartBrowserExtension::paste()
00297 {
00298     if ( m_extensionProxy )
00299     {
00300         callExtensionProxyMethod( "paste()" );
00301         return;
00302     }
00303 
00304     if ( !m_editableFormWidget )
00305         return;
00306 
00307     if ( m_editableFormWidget->inherits( "QLineEdit" ) )
00308         static_cast<QLineEdit *>( &(*m_editableFormWidget) )->paste();
00309     else if ( m_editableFormWidget->inherits( "QTextEdit" ) )
00310         static_cast<QTextEdit *>( &(*m_editableFormWidget) )->paste();
00311 }
00312 
00313 void KHTMLPartBrowserExtension::callExtensionProxyMethod( const char *method )
00314 {
00315     if ( !m_extensionProxy )
00316         return;
00317 
00318     int slot = m_extensionProxy->metaObject()->findSlot( method );
00319     if ( slot == -1 )
00320         return;
00321 
00322     QUObject o[ 1 ];
00323     m_extensionProxy->qt_invoke( slot, o );
00324 }
00325 
00326 void KHTMLPartBrowserExtension::updateEditActions()
00327 {
00328     if ( !m_editableFormWidget )
00329     {
00330         enableAction( "cut", false );
00331         enableAction( "copy", false );
00332         enableAction( "paste", false );
00333         return;
00334     }
00335 
00336     // ### duplicated from KonqMainWindow::slotClipboardDataChanged
00337 #ifndef QT_NO_MIMECLIPBOARD // Handle minimalized versions of Qt Embedded
00338     QMimeSource *data = QApplication::clipboard()->data();
00339     enableAction( "paste", data->provides( "text/plain" ) );
00340 #else
00341     QString data=QApplication::clipboard()->text();
00342     enableAction( "paste", data.contains("://"));
00343 #endif
00344     bool hasSelection = false;
00345 
00346     if( m_editableFormWidget) {
00347         if ( ::qt_cast<QLineEdit*>(m_editableFormWidget))
00348             hasSelection = static_cast<QLineEdit *>( &(*m_editableFormWidget) )->hasSelectedText();
00349         else if(::qt_cast<QTextEdit*>(m_editableFormWidget))
00350             hasSelection = static_cast<QTextEdit *>( &(*m_editableFormWidget) )->hasSelectedText();
00351     }
00352 
00353     enableAction( "copy", hasSelection );
00354     enableAction( "cut", hasSelection );
00355 }
00356 
00357 void KHTMLPartBrowserExtension::extensionProxyEditableWidgetFocused() {
00358     editableWidgetFocused();
00359 }
00360 
00361 void KHTMLPartBrowserExtension::extensionProxyEditableWidgetBlurred() {
00362     editableWidgetBlurred();
00363 }
00364 
00365 void KHTMLPartBrowserExtension::extensionProxyActionEnabled( const char *action, bool enable )
00366 {
00367     // only forward enableAction calls for actions we actually do forward
00368     if ( strcmp( action, "cut" ) == 0 ||
00369          strcmp( action, "copy" ) == 0 ||
00370          strcmp( action, "paste" ) == 0 ) {
00371         enableAction( action, enable );
00372     }
00373 }
00374 
00375 void KHTMLPartBrowserExtension::reparseConfiguration()
00376 {
00377   m_part->reparseConfiguration();
00378 }
00379 
00380 void KHTMLPartBrowserExtension::print()
00381 {
00382   m_part->view()->print();
00383 }
00384 
00385 void KHTMLPartBrowserExtension::disableScrolling()
00386 {
00387   QScrollView *scrollView = m_part->view();
00388   if (scrollView) {
00389     scrollView->setVScrollBarMode(QScrollView::AlwaysOff);
00390     scrollView->setHScrollBarMode(QScrollView::AlwaysOff);
00391   }
00392 }
00393 
00394 class KHTMLPopupGUIClient::KHTMLPopupGUIClientPrivate
00395 {
00396 public:
00397   KHTMLPart *m_khtml;
00398   KURL m_url;
00399   KURL m_imageURL;
00400   QPixmap m_pixmap;
00401   QString m_suggestedFilename;
00402 };
00403 
00404 
00405 KHTMLPopupGUIClient::KHTMLPopupGUIClient( KHTMLPart *khtml, const QString &doc, const KURL &url )
00406   : QObject( khtml )
00407 {
00408   d = new KHTMLPopupGUIClientPrivate;
00409   d->m_khtml = khtml;
00410   d->m_url = url;
00411   bool isImage = false;
00412   bool hasSelection = khtml->hasSelection();
00413   setInstance( khtml->instance() );
00414 
00415   DOM::Element e;
00416   e = khtml->nodeUnderMouse();
00417 
00418   if ( !e.isNull() && (e.elementId() == ID_IMG ||
00419                        (e.elementId() == ID_INPUT && !static_cast<DOM::HTMLInputElement>(e).src().isEmpty())))
00420   {
00421     if (e.elementId() == ID_IMG) {
00422       DOM::HTMLImageElementImpl *ie = static_cast<DOM::HTMLImageElementImpl*>(e.handle());
00423       khtml::RenderImage *ri = dynamic_cast<khtml::RenderImage*>(ie->renderer());
00424       if (ri && ri->contentObject()) {
00425         d->m_suggestedFilename = static_cast<khtml::CachedImage*>(ri->contentObject())->suggestedFilename();
00426       }
00427     }
00428     isImage=true;
00429   }
00430 
00431   if (hasSelection)
00432   {
00433       KAction* copyAction = KStdAction::copy( d->m_khtml->browserExtension(), SLOT( copy() ), actionCollection(), "copy" );
00434       copyAction->setText(i18n("&Copy Text"));
00435       copyAction->setEnabled(d->m_khtml->browserExtension()->isActionEnabled( "copy" ));
00436       actionCollection()->insert( khtml->actionCollection()->action( "selectAll" ) );
00437 
00438 
00439       // Fill search provider entries
00440       KConfig config("kuriikwsfilterrc");
00441       config.setGroup("General");
00442       const QString defaultEngine = config.readEntry("DefaultSearchEngine", "google");
00443       const char keywordDelimiter = config.readNumEntry("KeywordDelimiter", ':');
00444 
00445       // search text
00446       QString selectedText = khtml->selectedText();
00447       selectedText.replace("&", "&&");
00448       if ( selectedText.length()>18 ) {
00449         selectedText.truncate(15);
00450         selectedText+="...";
00451       }
00452 
00453       // default search provider
00454       KService::Ptr service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(defaultEngine));
00455 
00456       // search provider icon
00457       QPixmap icon;
00458       KURIFilterData data;
00459       QStringList list;
00460       data.setData( QString("some keyword") );
00461       list << "kurisearchfilter" << "kuriikwsfilter";
00462 
00463       QString name;
00464       if ( KURIFilter::self()->filterURI(data, list) )
00465       {
00466         QString iconPath = locate("cache", KMimeType::favIconForURL(data.uri()) + ".png");
00467         if ( iconPath.isEmpty() )
00468           icon = SmallIcon("find");
00469         else
00470           icon = QPixmap( iconPath );
00471         name = service->name();
00472       }
00473       else
00474       {
00475         icon = SmallIcon("google");
00476         name = "Google";
00477       }
00478 
00479       // using .arg(foo, bar) instead of .arg(foo).arg(bar), as foo can contain %x
00480       new KAction( i18n( "Search for '%1' with %2" ).arg( selectedText, name ), icon, 0, d->m_khtml->browserExtension(),
00481                      SLOT( searchProvider() ), actionCollection(), "searchProvider" );
00482 
00483       // favorite search providers
00484       QStringList favoriteEngines;
00485       favoriteEngines << "google" << "google_groups" << "google_news" << "webster" << "dmoz" << "wikipedia";
00486       favoriteEngines = config.readListEntry("FavoriteSearchEngines", favoriteEngines);
00487 
00488       if ( !favoriteEngines.isEmpty()) {
00489         KActionMenu* providerList = new KActionMenu( i18n( "Search for '%1' with" ).arg( selectedText ), actionCollection(), "searchProviderList" );
00490 
00491         QStringList::ConstIterator it = favoriteEngines.begin();
00492         for ( ; it != favoriteEngines.end(); ++it ) {
00493           if (*it==defaultEngine)
00494             continue;
00495           service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(*it));
00496           if (!service)
00497             continue;
00498           const QString searchProviderPrefix = *(service->property("Keys").toStringList().begin()) + keywordDelimiter;
00499           data.setData( searchProviderPrefix + "some keyword" );
00500 
00501           if ( KURIFilter::self()->filterURI(data, list) )
00502           {
00503             QString iconPath = locate("cache", KMimeType::favIconForURL(data.uri()) + ".png");
00504             if ( iconPath.isEmpty() )
00505               icon = SmallIcon("find");
00506             else
00507               icon = QPixmap( iconPath );
00508             name = service->name();
00509 
00510             providerList->insert( new KAction( name, icon, 0, d->m_khtml->browserExtension(),
00511               SLOT( searchProvider() ), actionCollection(), QString( "searchProvider" + searchProviderPrefix ).latin1() ) );
00512           }
00513         }
00514       }
00515 
00516 
00517       if ( selectedText.contains("://") && KURL(selectedText).isValid() )
00518          new KAction( i18n( "Open '%1'" ).arg( selectedText ), "window_new", 0,
00519          d->m_khtml->browserExtension(), SLOT( openSelection() ), actionCollection(), "openSelection" );
00520   }
00521   else if ( url.isEmpty() && !isImage )
00522   {
00523       actionCollection()->insert( khtml->actionCollection()->action( "security" ) );
00524       actionCollection()->insert( khtml->actionCollection()->action( "setEncoding" ) );
00525       new KAction( i18n( "Stop Animations" ), 0, this, SLOT( slotStopAnimations() ),
00526                    actionCollection(), "stopanimations" );
00527   }
00528 
00529   if ( !url.isEmpty() )
00530   {
00531     if (url.protocol() == "mailto")
00532     {
00533       new KAction( i18n( "Copy Email Address" ), 0, this, SLOT( slotCopyLinkLocation() ),
00534                  actionCollection(), "copylinklocation" );
00535     }
00536     else
00537     {
00538       new KAction( i18n( "&Save Link As..." ), 0, this, SLOT( slotSaveLinkAs() ),
00539                  actionCollection(), "savelinkas" );
00540       new KAction( i18n( "Copy &Link Address" ), 0, this, SLOT( slotCopyLinkLocation() ),
00541                  actionCollection(), "copylinklocation" );
00542     }
00543   }
00544 
00545   // frameset? -> add "Reload Frame" etc.
00546   if (!hasSelection)
00547   {
00548     if ( khtml->parentPart() )
00549     {
00550       new KAction( i18n( "Open in New &Window" ), "window_new", 0, this, SLOT( slotFrameInWindow() ),
00551                                           actionCollection(), "frameinwindow" );
00552       new KAction( i18n( "Open in &This Window" ), 0, this, SLOT( slotFrameInTop() ),
00553                                           actionCollection(), "frameintop" );
00554       new KAction( i18n( "Open in &New Tab" ), "tab_new", 0, this, SLOT( slotFrameInTab() ),
00555                                        actionCollection(), "frameintab" );
00556       new KAction( i18n( "Reload Frame" ), 0, this, SLOT( slotReloadFrame() ),
00557                                         actionCollection(), "reloadframe" );
00558 
00559       if ( KHTMLFactory::defaultHTMLSettings()->isAdFilterEnabled() ) {
00560           if ( khtml->d->m_frame->m_type == khtml::ChildFrame::IFrame )
00561               new KAction( i18n( "Block IFrame..." ), 0, this, SLOT( slotBlockIFrame() ), actionCollection(), "blockiframe" );
00562       }
00563 
00564       new KAction( i18n( "View Frame Source" ), 0, d->m_khtml, SLOT( slotViewDocumentSource() ),
00565                                           actionCollection(), "viewFrameSource" );
00566       new KAction( i18n( "View Frame Information" ), 0, d->m_khtml, SLOT( slotViewPageInfo() ), actionCollection(), "viewFrameInfo" );
00567       // This one isn't in khtml_popupmenu.rc anymore, because Print isn't either,
00568       // and because print frame is already in the toolbar and the menu.
00569       // But leave this here, so that it's easy to read it.
00570       new KAction( i18n( "Print Frame..." ), "frameprint", 0, d->m_khtml->browserExtension(), SLOT( print() ), actionCollection(), "printFrame" );
00571       new KAction( i18n( "Save &Frame As..." ), 0, d->m_khtml, SLOT( slotSaveFrame() ), actionCollection(), "saveFrame" );
00572 
00573       actionCollection()->insert( khtml->parentPart()->actionCollection()->action( "viewDocumentSource" ) );
00574       actionCollection()->insert( khtml->parentPart()->actionCollection()->action( "viewPageInfo" ) );
00575     } else {
00576       actionCollection()->insert( khtml->actionCollection()->action( "viewDocumentSource" ) );
00577       actionCollection()->insert( khtml->actionCollection()->action( "viewPageInfo" ) );
00578     }
00579   } else if (isImage || !url.isEmpty()) {
00580     actionCollection()->insert( khtml->actionCollection()->action( "viewDocumentSource" ) );
00581     actionCollection()->insert( khtml->actionCollection()->action( "viewPageInfo" ) );
00582     new KAction( i18n( "Stop Animations" ), 0, this, SLOT( slotStopAnimations() ),
00583                  actionCollection(), "stopanimations" );
00584   }
00585 
00586   if (isImage)
00587   {
00588     if ( e.elementId() == ID_IMG ) {
00589       d->m_imageURL = KURL( static_cast<DOM::HTMLImageElement>( e ).src().string() );
00590       DOM::HTMLImageElementImpl *imageimpl = static_cast<DOM::HTMLImageElementImpl *>( e.handle() );
00591       Q_ASSERT(imageimpl);
00592       if(imageimpl) // should be true always.  right?
00593       {
00594         if(imageimpl->complete()) {
00595       d->m_pixmap = imageimpl->currentPixmap();
00596     }
00597       }
00598     }
00599     else
00600       d->m_imageURL = KURL( static_cast<DOM::HTMLInputElement>( e ).src().string() );
00601     new KAction( i18n( "Save Image As..." ), 0, this, SLOT( slotSaveImageAs() ),
00602                  actionCollection(), "saveimageas" );
00603     new KAction( i18n( "Send Image..." ), 0, this, SLOT( slotSendImage() ),
00604                  actionCollection(), "sendimage" );
00605 
00606 
00607 #ifndef QT_NO_MIMECLIPBOARD
00608     (new KAction( i18n( "Copy Image" ), 0, this, SLOT( slotCopyImage() ),
00609                  actionCollection(), "copyimage" ))->setEnabled(!d->m_pixmap.isNull());
00610 #endif
00611 
00612     if(d->m_pixmap.isNull()) {    //fallback to image location if still loading the image.  this will always be true if ifdef QT_NO_MIMECLIPBOARD
00613       new KAction( i18n( "Copy Image Location" ), 0, this, SLOT( slotCopyImageLocation() ),
00614                    actionCollection(), "copyimagelocation" );
00615     }
00616 
00617     QString name = KStringHandler::csqueeze(d->m_imageURL.fileName()+d->m_imageURL.query(), 25);
00618     new KAction( i18n( "View Image (%1)" ).arg(d->m_suggestedFilename.isEmpty() ? name.replace("&", "&&") : d->m_suggestedFilename.replace("&", "&&")), 0, this, SLOT( slotViewImage() ),
00619                  actionCollection(), "viewimage" );
00620 
00621     if (KHTMLFactory::defaultHTMLSettings()->isAdFilterEnabled())
00622     {
00623       new KAction( i18n( "Block Image..." ), 0, this, SLOT( slotBlockImage() ),
00624                    actionCollection(), "blockimage" );
00625 
00626       if (!d->m_imageURL.host().isEmpty() &&
00627           !d->m_imageURL.protocol().isEmpty())
00628       {
00629         new KAction( i18n( "Block Images From %1" ).arg(d->m_imageURL.host()), 0, this, SLOT( slotBlockHost() ),
00630                      actionCollection(), "blockhost" );
00631       }
00632     }
00633   }
00634 
00635   setXML( doc );
00636   setDOMDocument( QDomDocument(), true ); // ### HACK
00637 
00638   QDomElement menu = domDocument().documentElement().namedItem( "Menu" ).toElement();
00639 
00640   if ( actionCollection()->count() > 0 )
00641     menu.insertBefore( domDocument().createElement( "separator" ), menu.firstChild() );
00642 }
00643 
00644 KHTMLPopupGUIClient::~KHTMLPopupGUIClient()
00645 {
00646   delete d;
00647 }
00648 
00649 void KHTMLPopupGUIClient::slotSaveLinkAs()
00650 {
00651   KIO::MetaData metaData;
00652   metaData["referrer"] = d->m_khtml->referrer();
00653   saveURL( d->m_khtml->widget(), i18n( "Save Link As" ), d->m_url, metaData );
00654 }
00655 
00656 void KHTMLPopupGUIClient::slotSendImage()
00657 {
00658     QStringList urls;
00659     urls.append( d->m_imageURL.url());
00660     QString subject = d->m_imageURL.url();
00661     kapp->invokeMailer(QString::null, QString::null, QString::null, subject,
00662                        QString::null, //body
00663                        QString::null,
00664                        urls); // attachments
00665 
00666 
00667 }
00668 
00669 void KHTMLPopupGUIClient::slotSaveImageAs()
00670 {
00671   KIO::MetaData metaData;
00672   metaData["referrer"] = d->m_khtml->referrer();
00673   saveURL( d->m_khtml->widget(), i18n( "Save Image As" ), d->m_imageURL, metaData, QString::null, 0, d->m_suggestedFilename );
00674 }
00675 
00676 void KHTMLPopupGUIClient::slotBlockHost()
00677 {
00678     QString name=d->m_imageURL.protocol()+"://"+d->m_imageURL.host()+"/*";
00679     KHTMLFactory::defaultHTMLSettings()->addAdFilter( name );
00680     d->m_khtml->reparseConfiguration();
00681 }
00682 
00683 void KHTMLPopupGUIClient::slotBlockImage()
00684 {
00685     bool ok = false;
00686 
00687     QString url = KInputDialog::getText( i18n("Add URL to Filter"),
00688                                          i18n("Enter the URL:"),
00689                                          d->m_imageURL.url(),
00690                                          &ok);
00691     if ( ok ) {
00692         KHTMLFactory::defaultHTMLSettings()->addAdFilter( url );
00693         d->m_khtml->reparseConfiguration();
00694     }
00695 }
00696 
00697 void KHTMLPopupGUIClient::slotBlockIFrame()
00698 {
00699     bool ok = false;
00700     QString url = KInputDialog::getText( i18n( "Add URL to Filter"),
00701                                                i18n("Enter the URL:"),
00702                                                d->m_khtml->url().url(),
00703                                                &ok );
00704     if ( ok ) {
00705         KHTMLFactory::defaultHTMLSettings()->addAdFilter( url );
00706         d->m_khtml->reparseConfiguration();
00707     }
00708 }
00709 
00710 void KHTMLPopupGUIClient::slotCopyLinkLocation()
00711 {
00712   KURL safeURL(d->m_url);
00713   safeURL.setPass(QString::null);
00714 #ifndef QT_NO_MIMECLIPBOARD
00715   // Set it in both the mouse selection and in the clipboard
00716   KURL::List lst;
00717   lst.append( safeURL );
00718   QApplication::clipboard()->setData( new KURLDrag( lst ), QClipboard::Clipboard );
00719   QApplication::clipboard()->setData( new KURLDrag( lst ), QClipboard::Selection );
00720 #else
00721   QApplication::clipboard()->setText( safeURL.url() ); //FIXME(E): Handle multiple entries
00722 #endif
00723 }
00724 
00725 void KHTMLPopupGUIClient::slotStopAnimations()
00726 {
00727   d->m_khtml->stopAnimations();
00728 }
00729 
00730 void KHTMLPopupGUIClient::slotCopyImage()
00731 {
00732 #ifndef QT_NO_MIMECLIPBOARD
00733   KURL safeURL(d->m_imageURL);
00734   safeURL.setPass(QString::null);
00735 
00736   KURL::List lst;
00737   lst.append( safeURL );
00738   KMultipleDrag *drag = new KMultipleDrag(d->m_khtml->view(), "Image");
00739 
00740   drag->addDragObject( new QImageDrag(d->m_pixmap.convertToImage()) );
00741   drag->addDragObject( new KURLDrag(lst, d->m_khtml->view(), "Image URL") );
00742 
00743   // Set it in both the mouse selection and in the clipboard
00744   QApplication::clipboard()->setData( drag, QClipboard::Clipboard );
00745   QApplication::clipboard()->setData( new KURLDrag(lst), QClipboard::Selection );
00746 #else
00747   kdDebug() << "slotCopyImage called when the clipboard does not support this.  This should not be possible." << endl;
00748 #endif
00749 }
00750 
00751 void KHTMLPopupGUIClient::slotCopyImageLocation()
00752 {
00753   KURL safeURL(d->m_imageURL);
00754   safeURL.setPass(QString::null);
00755 #ifndef QT_NO_MIMECLIPBOARD
00756   // Set it in both the mouse selection and in the clipboard
00757   KURL::List lst;
00758   lst.append( safeURL );
00759   QApplication::clipboard()->setData( new KURLDrag( lst ), QClipboard::Clipboard );
00760   QApplication::clipboard()->setData( new KURLDrag( lst ), QClipboard::Selection );
00761 #else
00762   QApplication::clipboard()->setText( safeURL.url() ); //FIXME(E): Handle multiple entries
00763 #endif
00764 }
00765 
00766 void KHTMLPopupGUIClient::slotViewImage()
00767 {
00768   d->m_khtml->browserExtension()->createNewWindow(d->m_imageURL);
00769 }
00770 
00771 void KHTMLPopupGUIClient::slotReloadFrame()
00772 {
00773   KParts::URLArgs args( d->m_khtml->browserExtension()->urlArgs() );
00774   args.reload = true;
00775   args.metaData()["referrer"] = d->m_khtml->pageReferrer();
00776   // reload document
00777   d->m_khtml->closeURL();
00778   d->m_khtml->browserExtension()->setURLArgs( args );
00779   d->m_khtml->openURL( d->m_khtml->url() );
00780 }
00781 
00782 void KHTMLPopupGUIClient::slotFrameInWindow()
00783 {
00784   KParts::URLArgs args( d->m_khtml->browserExtension()->urlArgs() );
00785   args.metaData()["referrer"] = d->m_khtml->pageReferrer();
00786   args.metaData()["forcenewwindow"] = "true";
00787   emit d->m_khtml->browserExtension()->createNewWindow( d->m_khtml->url(), args );
00788 }
00789 
00790 void KHTMLPopupGUIClient::slotFrameInTop()
00791 {
00792   KParts::URLArgs args( d->m_khtml->browserExtension()->urlArgs() );
00793   args.metaData()["referrer"] = d->m_khtml->pageReferrer();
00794   args.frameName = "_top";
00795   emit d->m_khtml->browserExtension()->openURLRequest( d->m_khtml->url(), args );
00796 }
00797 
00798 void KHTMLPopupGUIClient::slotFrameInTab()
00799 {
00800   KParts::URLArgs args( d->m_khtml->browserExtension()->urlArgs() );
00801   args.metaData()["referrer"] = d->m_khtml->pageReferrer();
00802   args.setNewTab(true);
00803   emit d->m_khtml->browserExtension()->createNewWindow( d->m_khtml->url(), args );
00804 }
00805 
00806 void KHTMLPopupGUIClient::saveURL( QWidget *parent, const QString &caption,
00807                                    const KURL &url,
00808                                    const QMap<QString, QString> &metadata,
00809                                    const QString &filter, long cacheId,
00810                                    const QString & suggestedFilename )
00811 {
00812   QString name = QString::fromLatin1( "index.html" );
00813   if ( !suggestedFilename.isEmpty() )
00814     name = suggestedFilename;
00815   else if ( !url.fileName().isEmpty() )
00816     name = url.fileName();
00817 
00818   KURL destURL;
00819   int query;
00820   do {
00821     query = KMessageBox::Yes;
00822     destURL = KFileDialog::getSaveURL( name, filter, parent, caption );
00823       if( destURL.isLocalFile() )
00824       {
00825         QFileInfo info( destURL.path() );
00826         if( info.exists() ) {
00827           // TODO: use KIO::RenameDlg (shows more information)
00828           query = KMessageBox::warningContinueCancel( parent, i18n( "A file named \"%1\" already exists. " "Are you sure you want to overwrite it?" ).arg( info.fileName() ), i18n( "Overwrite File?" ), i18n( "Overwrite" ) );
00829         }
00830        }
00831    } while ( query == KMessageBox::Cancel );
00832 
00833   if ( destURL.isValid() )
00834     saveURL(url, destURL, metadata, cacheId);
00835 }
00836 
00837 void KHTMLPopupGUIClient::saveURL( const KURL &url, const KURL &destURL,
00838                                    const QMap<QString, QString> &metadata,
00839                                    long cacheId )
00840 {
00841     if ( destURL.isValid() )
00842     {
00843         bool saved = false;
00844         if (KHTMLPageCache::self()->isComplete(cacheId))
00845         {
00846             if (destURL.isLocalFile())
00847             {
00848                 KSaveFile destFile(destURL.path());
00849                 if (destFile.status() == 0)
00850                 {
00851                     KHTMLPageCache::self()->saveData(cacheId, destFile.dataStream());
00852                     saved = true;
00853                 }
00854             }
00855             else
00856             {
00857                 // save to temp file, then move to final destination.
00858                 KTempFile destFile;
00859                 if (destFile.status() == 0)
00860                 {
00861                     KHTMLPageCache::self()->saveData(cacheId, destFile.dataStream());
00862                     destFile.close();
00863                     KURL url2 = KURL();
00864                     url2.setPath(destFile.name());
00865                     KIO::file_move(url2, destURL, -1, true /*overwrite*/);
00866                     saved = true;
00867                 }
00868             }
00869         }
00870         if(!saved)
00871         {
00872           // DownloadManager <-> konqueror integration
00873           // find if the integration is enabled
00874           // the empty key  means no integration
00875           // only use download manager for non-local urls!
00876           bool downloadViaKIO = true;
00877           if ( !url.isLocalFile() )
00878           {
00879             KConfig cfg("konquerorrc", false, false);
00880             cfg.setGroup("HTML Settings");
00881             QString downloadManger = cfg.readPathEntry("DownloadManager");
00882             if (!downloadManger.isEmpty())
00883             {
00884                 // then find the download manager location
00885                 kdDebug(1000) << "Using: "<<downloadManger <<" as Download Manager" <<endl;
00886                 QString cmd = KStandardDirs::findExe(downloadManger);
00887                 if (cmd.isEmpty())
00888                 {
00889                     QString errMsg=i18n("The Download Manager (%1) could not be found in your $PATH ").arg(downloadManger);
00890                     QString errMsgEx= i18n("Try to reinstall it  \n\nThe integration with Konqueror will be disabled!");
00891                     KMessageBox::detailedSorry(0,errMsg,errMsgEx);
00892                     cfg.writePathEntry("DownloadManager",QString::null);
00893                     cfg.sync ();
00894                 }
00895                 else
00896                 {
00897                     downloadViaKIO = false;
00898                     KURL cleanDest = destURL;
00899                     cleanDest.setPass( QString::null ); // don't put password into commandline
00900                     cmd += " " + KProcess::quote(url.url()) + " " +
00901                            KProcess::quote(cleanDest.url());
00902                     kdDebug(1000) << "Calling command  "<<cmd<<endl;
00903                     KRun::runCommand(cmd);
00904                 }
00905             }
00906           }
00907 
00908           if ( downloadViaKIO )
00909           {
00910               KIO::Job *job = KIO::file_copy( url, destURL, -1, true /*overwrite*/ );
00911               job->setMetaData(metadata);
00912               job->addMetaData("MaxCacheSize", "0"); // Don't store in http cache.
00913               job->addMetaData("cache", "cache"); // Use entry from cache if available.
00914               job->setAutoErrorHandlingEnabled( true );
00915           }
00916         } //end if(!saved)
00917     }
00918 }
00919 
00920 KHTMLPartBrowserHostExtension::KHTMLPartBrowserHostExtension( KHTMLPart *part )
00921 : KParts::BrowserHostExtension( part )
00922 {
00923   m_part = part;
00924 }
00925 
00926 KHTMLPartBrowserHostExtension::~KHTMLPartBrowserHostExtension()
00927 {
00928 }
00929 
00930 QStringList KHTMLPartBrowserHostExtension::frameNames() const
00931 {
00932   return m_part->frameNames();
00933 }
00934 
00935 const QPtrList<KParts::ReadOnlyPart> KHTMLPartBrowserHostExtension::frames() const
00936 {
00937   return m_part->frames();
00938 }
00939 
00940 bool KHTMLPartBrowserHostExtension::openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs )
00941 {
00942   return m_part->openURLInFrame( url, urlArgs );
00943 }
00944 
00945 void KHTMLPartBrowserHostExtension::virtual_hook( int id, void *data )
00946 {
00947   if (id == VIRTUAL_FIND_FRAME_PARENT)
00948   {
00949     FindFrameParentParams *param = static_cast<FindFrameParentParams*>(data);
00950     KHTMLPart *parentPart = m_part->findFrameParent(param->callingPart, param->frame);
00951     if (parentPart)
00952        param->parent = parentPart->browserHostExtension();
00953     return;
00954   }
00955   BrowserHostExtension::virtual_hook( id, data );
00956 }
00957 
00958 
00959 // defined in khtml_part.cpp
00960 extern const int KDE_NO_EXPORT fastZoomSizes[];
00961 extern const int KDE_NO_EXPORT fastZoomSizeCount;
00962 
00963 // BCI: remove in KDE 4
00964 KHTMLZoomFactorAction::KHTMLZoomFactorAction( KHTMLPart *part, bool direction, const QString &text, const QString &icon, const QObject *receiver, const char *slot, QObject *parent, const char *name )
00965     : KAction( text, icon, 0, receiver, slot, parent, name )
00966 {
00967     init(part, direction);
00968 }
00969 
00970 KHTMLZoomFactorAction::KHTMLZoomFactorAction( KHTMLPart *part, bool direction, const QString &text, const QString &icon, const KShortcut &cut, const QObject *receiver, const char *slot, QObject *parent, const char *name )
00971     : KAction( text, icon, cut, receiver, slot, parent, name )
00972 {
00973     init(part, direction);
00974 }
00975 
00976 void KHTMLZoomFactorAction::init(KHTMLPart *part, bool direction)
00977 {
00978     m_direction = direction;
00979     m_part = part;
00980 
00981     m_popup = new QPopupMenu;
00982     // xgettext: no-c-format
00983     m_popup->insertItem( i18n( "Default Font Size (100%)" ) );
00984 
00985     int m = m_direction ? 1 : -1;
00986     int ofs = fastZoomSizeCount / 2;       // take index of 100%
00987 
00988     // this only works if there is an odd number of elements in fastZoomSizes[]
00989     for ( int i = m; i != m*(ofs+1); i += m )
00990     {
00991         int num = i * m;
00992         QString numStr = QString::number( num );
00993         if ( num > 0 ) numStr.prepend( '+' );
00994 
00995         // xgettext: no-c-format
00996         m_popup->insertItem( i18n( "%1%" ).arg( fastZoomSizes[ofs + i] ) );
00997     }
00998 
00999     connect( m_popup, SIGNAL( activated( int ) ), this, SLOT( slotActivated( int ) ) );
01000 }
01001 
01002 KHTMLZoomFactorAction::~KHTMLZoomFactorAction()
01003 {
01004     delete m_popup;
01005 }
01006 
01007 int KHTMLZoomFactorAction::plug( QWidget *w, int index )
01008 {
01009     int containerId = KAction::plug( w, index );
01010     if ( containerId == -1 || !w->inherits( "KToolBar" ) )
01011         return containerId;
01012 
01013     KToolBarButton *button = static_cast<KToolBar *>( w )->getButton( itemId( containerId ) );
01014     if ( !button )
01015         return containerId;
01016 
01017     button->setDelayedPopup( m_popup );
01018     return containerId;
01019 }
01020 
01021 void KHTMLZoomFactorAction::slotActivated( int id )
01022 {
01023     int idx = m_popup->indexOf( id );
01024 
01025     if (idx == 0)
01026         m_part->setZoomFactor(100);
01027     else
01028         m_part->setZoomFactor(fastZoomSizes[fastZoomSizeCount/2 + (m_direction ? 1 : -1)*idx]);
01029 }
01030 
01031 #include "khtml_ext.moc"
01032 

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