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 Tue Apr 12 23:31:26 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003