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., 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 <tqclipboard.h> 00039 #include <tqfileinfo.h> 00040 #include <tqpopupmenu.h> 00041 #include <tqurl.h> 00042 #include <tqmetaobject.h> 00043 #include <tqucomextra_p.h> 00044 #include <tqdragobject.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( TQDataStream &stream ) 00097 { 00098 //kdDebug( 6050 ) << "saveState!" << endl; 00099 m_part->saveState( stream ); 00100 } 00101 00102 void KHTMLPartBrowserExtension::restoreState( TQDataStream &stream ) 00103 { 00104 //kdDebug( 6050 ) << "restoreState!" << endl; 00105 m_part->restoreState( stream ); 00106 } 00107 00108 void KHTMLPartBrowserExtension::editableWidgetFocused( TQWidget *widget ) 00109 { 00110 m_editableFormWidget = widget; 00111 updateEditActions(); 00112 00113 if ( !m_connectedToClipboard && m_editableFormWidget ) 00114 { 00115 connect( TQApplication::clipboard(), TQT_SIGNAL( dataChanged() ), 00116 this, TQT_SLOT( updateEditActions() ) ); 00117 00118 if ( m_editableFormWidget->inherits( TQLINEEDIT_OBJECT_NAME_STRING ) || m_editableFormWidget->inherits( TQTEXTEDIT_OBJECT_NAME_STRING ) ) 00119 connect( m_editableFormWidget, TQT_SIGNAL( selectionChanged() ), 00120 this, TQT_SLOT( updateEditActions() ) ); 00121 00122 m_connectedToClipboard = true; 00123 } 00124 editableWidgetFocused(); 00125 } 00126 00127 void KHTMLPartBrowserExtension::editableWidgetBlurred( TQWidget * /*widget*/ ) 00128 { 00129 TQWidget *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( TQApplication::clipboard(), TQT_SIGNAL( dataChanged() ), 00139 this, TQT_SLOT( updateEditActions() ) ); 00140 00141 if ( oldWidget ) 00142 { 00143 if ( oldWidget->inherits( TQLINEEDIT_OBJECT_NAME_STRING ) || oldWidget->inherits( TQTEXTEDIT_OBJECT_NAME_STRING ) ) 00144 disconnect( oldWidget, TQT_SIGNAL( selectionChanged() ), 00145 this, TQT_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, TQT_SIGNAL( enableAction( const char *, bool ) ), 00158 this, TQT_SLOT( extensionProxyActionEnabled( const char *, bool ) ) ); 00159 if ( m_extensionProxy->inherits( "KHTMLPartBrowserExtension" ) ) 00160 { 00161 disconnect( m_extensionProxy, TQT_SIGNAL( editableWidgetFocused() ), 00162 this, TQT_SLOT( extensionProxyEditableWidgetFocused() ) ); 00163 disconnect( m_extensionProxy, TQT_SIGNAL( editableWidgetBlurred() ), 00164 this, TQT_SLOT( extensionProxyEditableWidgetBlurred() ) ); 00165 } 00166 } 00167 00168 m_extensionProxy = proxy; 00169 00170 if ( m_extensionProxy ) 00171 { 00172 connect( m_extensionProxy, TQT_SIGNAL( enableAction( const char *, bool ) ), 00173 this, TQT_SLOT( extensionProxyActionEnabled( const char *, bool ) ) ); 00174 if ( m_extensionProxy->inherits( "KHTMLPartBrowserExtension" ) ) 00175 { 00176 connect( m_extensionProxy, TQT_SIGNAL( editableWidgetFocused() ), 00177 this, TQT_SLOT( extensionProxyEditableWidgetFocused() ) ); 00178 connect( m_extensionProxy, TQT_SIGNAL( editableWidgetBlurred() ), 00179 this, TQT_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( TQLINEEDIT_OBJECT_NAME_STRING ) ) 00205 static_cast<TQLineEdit *>( &(*m_editableFormWidget) )->cut(); 00206 else if ( m_editableFormWidget->inherits( TQTEXTEDIT_OBJECT_NAME_STRING ) ) 00207 static_cast<TQTextEdit *>( &(*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 TQString text= m_part->selectedText(); 00223 text.replace( TQChar( 0xa0 ), ' ' ); 00224 00225 00226 TQClipboard *cb = TQApplication::clipboard(); 00227 disconnect( cb, TQT_SIGNAL( selectionChanged() ), m_part, TQT_SLOT( slotClearSelection() ) ); 00228 #ifndef QT_NO_MIMECLIPBOARD 00229 TQString 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 TQTextDrag *textdrag = new TQTextDrag(text, 0L); 00240 KMultipleDrag *drag = new KMultipleDrag( m_editableFormWidget ); 00241 drag->addDragObject( textdrag ); 00242 if(!htmltext.isEmpty()) { 00243 htmltext.replace( TQChar( 0xa0 ), ' ' ); 00244 TQTextDrag *htmltextdrag = new TQTextDrag(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, TQT_SIGNAL( selectionChanged() ), m_part, TQT_SLOT( slotClearSelection() ) ); 00254 } 00255 else 00256 { 00257 if ( m_editableFormWidget->inherits( TQLINEEDIT_OBJECT_NAME_STRING ) ) 00258 static_cast<TQLineEdit *>( &(*m_editableFormWidget) )->copy(); 00259 else if ( m_editableFormWidget->inherits( TQTEXTEDIT_OBJECT_NAME_STRING ) ) 00260 static_cast<TQTextEdit *>( &(*m_editableFormWidget) )->copy(); 00261 } 00262 } 00263 00264 void KHTMLPartBrowserExtension::searchProvider() 00265 { 00266 // action name is of form "previewProvider[<searchproviderprefix>:]" 00267 const TQString searchProviderPrefix = TQString( TQT_TQOBJECT_CONST(sender())->name() ).mid( 14 ); 00268 00269 KURIFilterData data; 00270 TQStringList 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 TQString encodedSearchTerm = m_part->selectedText(); 00278 TQUrl::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( TQLINEEDIT_OBJECT_NAME_STRING ) ) 00308 static_cast<TQLineEdit *>( &(*m_editableFormWidget) )->paste(); 00309 else if ( m_editableFormWidget->inherits( TQTEXTEDIT_OBJECT_NAME_STRING ) ) 00310 static_cast<TQTextEdit *>( &(*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 TQUObject 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 TQMimeSource *data = TQApplication::clipboard()->data(); 00339 enableAction( "paste", data->provides( "text/plain" ) ); 00340 #else 00341 TQString data=TQApplication::clipboard()->text(); 00342 enableAction( "paste", data.contains("://")); 00343 #endif 00344 bool hasSelection = false; 00345 00346 if( m_editableFormWidget) { 00347 if ( ::tqqt_cast<TQLineEdit*>(m_editableFormWidget)) 00348 hasSelection = static_cast<TQLineEdit *>( &(*m_editableFormWidget) )->hasSelectedText(); 00349 else if(::tqqt_cast<TQTextEdit*>(m_editableFormWidget)) 00350 hasSelection = static_cast<TQTextEdit *>( &(*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 TQScrollView *scrollView = m_part->view(); 00388 if (scrollView) { 00389 scrollView->setVScrollBarMode(TQScrollView::AlwaysOff); 00390 scrollView->setHScrollBarMode(TQScrollView::AlwaysOff); 00391 } 00392 } 00393 00394 class KHTMLPopupGUIClient::KHTMLPopupGUIClientPrivate 00395 { 00396 public: 00397 KHTMLPart *m_khtml; 00398 KURL m_url; 00399 KURL m_imageURL; 00400 TQPixmap m_pixmap; 00401 TQString m_suggestedFilename; 00402 }; 00403 00404 00405 KHTMLPopupGUIClient::KHTMLPopupGUIClient( KHTMLPart *khtml, const TQString &doc, const KURL &url ) 00406 : TQObject( 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(), TQT_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 TQString defaultEngine = config.readEntry("DefaultSearchEngine", "google"); 00443 const char keywordDelimiter = config.readNumEntry("KeywordDelimiter", ':'); 00444 00445 // search text 00446 TQString 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(TQString("searchproviders/%1.desktop").arg(defaultEngine)); 00455 00456 // search provider icon 00457 TQPixmap icon; 00458 KURIFilterData data; 00459 TQStringList list; 00460 data.setData( TQString("some keyword") ); 00461 list << "kurisearchfilter" << "kuriikwsfilter"; 00462 00463 TQString name; 00464 if ( KURIFilter::self()->filterURI(data, list) ) 00465 { 00466 TQString iconPath = locate("cache", KMimeType::favIconForURL(data.uri()) + ".png"); 00467 if ( iconPath.isEmpty() ) 00468 icon = SmallIcon("find"); 00469 else 00470 icon = TQPixmap( 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 TQT_SLOT( searchProvider() ), actionCollection(), "searchProvider" ); 00482 00483 // favorite search providers 00484 TQStringList 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 TQStringList::ConstIterator it = favoriteEngines.begin(); 00492 for ( ; it != favoriteEngines.end(); ++it ) { 00493 if (*it==defaultEngine) 00494 continue; 00495 service = KService::serviceByDesktopPath(TQString("searchproviders/%1.desktop").arg(*it)); 00496 if (!service) 00497 continue; 00498 const TQString searchProviderPrefix = *(service->property("Keys").toStringList().begin()) + keywordDelimiter; 00499 data.setData( searchProviderPrefix + "some keyword" ); 00500 00501 if ( KURIFilter::self()->filterURI(data, list) ) 00502 { 00503 TQString iconPath = locate("cache", KMimeType::favIconForURL(data.uri()) + ".png"); 00504 if ( iconPath.isEmpty() ) 00505 icon = SmallIcon("find"); 00506 else 00507 icon = TQPixmap( iconPath ); 00508 name = service->name(); 00509 00510 providerList->insert( new KAction( name, icon, 0, d->m_khtml->browserExtension(), 00511 TQT_SLOT( searchProvider() ), actionCollection(), TQString( "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(), TQT_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, TQT_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, TQT_SLOT( slotCopyLinkLocation() ), 00534 actionCollection(), "copylinklocation" ); 00535 } 00536 else 00537 { 00538 new KAction( i18n( "&Save Link As..." ), 0, this, TQT_SLOT( slotSaveLinkAs() ), 00539 actionCollection(), "savelinkas" ); 00540 new KAction( i18n( "Copy &Link Address" ), 0, this, TQT_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, TQT_SLOT( slotFrameInWindow() ), 00551 actionCollection(), "frameinwindow" ); 00552 new KAction( i18n( "Open in &This Window" ), 0, this, TQT_SLOT( slotFrameInTop() ), 00553 actionCollection(), "frameintop" ); 00554 new KAction( i18n( "Open in &New Tab" ), "tab_new", 0, this, TQT_SLOT( slotFrameInTab() ), 00555 actionCollection(), "frameintab" ); 00556 new KAction( i18n( "Reload Frame" ), 0, this, TQT_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, TQT_SLOT( slotBlockIFrame() ), actionCollection(), "blockiframe" ); 00562 } 00563 00564 new KAction( i18n( "View Frame Source" ), 0, d->m_khtml, TQT_SLOT( slotViewDocumentSource() ), 00565 actionCollection(), "viewFrameSource" ); 00566 new KAction( i18n( "View Frame Information" ), 0, d->m_khtml, TQT_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(), TQT_SLOT( print() ), actionCollection(), "printFrame" ); 00571 new KAction( i18n( "Save &Frame As..." ), 0, d->m_khtml, TQT_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, TQT_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, TQT_SLOT( slotSaveImageAs() ), 00602 actionCollection(), "saveimageas" ); 00603 new KAction( i18n( "Send Image..." ), 0, this, TQT_SLOT( slotSendImage() ), 00604 actionCollection(), "sendimage" ); 00605 00606 00607 #ifndef QT_NO_MIMECLIPBOARD 00608 (new KAction( i18n( "Copy Image" ), 0, this, TQT_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, TQT_SLOT( slotCopyImageLocation() ), 00614 actionCollection(), "copyimagelocation" ); 00615 } 00616 00617 TQString 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, TQT_SLOT( slotViewImage() ), 00619 actionCollection(), "viewimage" ); 00620 00621 if (KHTMLFactory::defaultHTMLSettings()->isAdFilterEnabled()) 00622 { 00623 new KAction( i18n( "Block Image..." ), 0, this, TQT_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, TQT_SLOT( slotBlockHost() ), 00630 actionCollection(), "blockhost" ); 00631 } 00632 } 00633 } 00634 00635 setXML( doc ); 00636 setDOMDocument( TQDomDocument(), true ); // ### HACK 00637 00638 TQDomElement 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 TQStringList urls; 00659 urls.append( d->m_imageURL.url()); 00660 TQString subject = d->m_imageURL.url(); 00661 kapp->invokeMailer(TQString::null, TQString::null, TQString::null, subject, 00662 TQString::null, //body 00663 TQString::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, TQString::null, 0, d->m_suggestedFilename ); 00674 } 00675 00676 void KHTMLPopupGUIClient::slotBlockHost() 00677 { 00678 TQString 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 TQString 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 TQString 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(TQString::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 TQApplication::clipboard()->setData( new KURLDrag( lst ), TQClipboard::Clipboard ); 00719 TQApplication::clipboard()->setData( new KURLDrag( lst ), TQClipboard::Selection ); 00720 #else 00721 TQApplication::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(TQString::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 TQImageDrag(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 TQApplication::clipboard()->setData( drag, TQClipboard::Clipboard ); 00745 TQApplication::clipboard()->setData( new KURLDrag(lst), TQClipboard::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(TQString::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 TQApplication::clipboard()->setData( new KURLDrag( lst ), TQClipboard::Clipboard ); 00760 TQApplication::clipboard()->setData( new KURLDrag( lst ), TQClipboard::Selection ); 00761 #else 00762 TQApplication::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( TQWidget *parent, const TQString &caption, 00807 const KURL &url, 00808 const TQMap<TQString, TQString> &metadata, 00809 const TQString &filter, long cacheId, 00810 const TQString & suggestedFilename ) 00811 { 00812 TQString name = TQString::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 TQFileInfo 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 TQMap<TQString, TQString> &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 TQString 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 TQString cmd = KStandardDirs::findExe(downloadManger); 00887 if (cmd.isEmpty()) 00888 { 00889 TQString errMsg=i18n("The Download Manager (%1) could not be found in your $PATH ").arg(downloadManger); 00890 TQString errMsgEx= i18n("Try to reinstall it \n\nThe integration with Konqueror will be disabled!"); 00891 KMessageBox::detailedSorry(0,errMsg,errMsgEx); 00892 cfg.writePathEntry("DownloadManager",TQString::null); 00893 cfg.sync (); 00894 } 00895 else 00896 { 00897 downloadViaKIO = false; 00898 KURL cleanDest = destURL; 00899 cleanDest.setPass( TQString::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 TQStringList KHTMLPartBrowserHostExtension::frameNames() const 00931 { 00932 return m_part->frameNames(); 00933 } 00934 00935 const TQPtrList<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 TQString &text, const TQString &icon, const TQObject *receiver, const char *slot, TQObject *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 TQString &text, const TQString &icon, const KShortcut &cut, const TQObject *receiver, const char *slot, TQObject *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 TQPopupMenu; 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 TQString numStr = TQString::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, TQT_SIGNAL( activated( int ) ), this, TQT_SLOT( slotActivated( int ) ) ); 01000 } 01001 01002 KHTMLZoomFactorAction::~KHTMLZoomFactorAction() 01003 { 01004 delete m_popup; 01005 } 01006 01007 int KHTMLZoomFactorAction::plug( TQWidget *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