khtml Library API Documentation

khtml_ext.cpp

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