00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "khtml_ext.h"
00028 #include "khtmlview.h"
00029 #include "khtml_pagecache.h"
00030 #include "rendering/render_form.h"
00031 #include "rendering/render_image.h"
00032 #include "html/html_imageimpl.h"
00033 #include "misc/loader.h"
00034 #include "dom/html_form.h"
00035 #include "dom/html_image.h"
00036 #include <QtGui/QClipboard>
00037 #include <QtCore/QFileInfo>
00038 #include <QtGui/QMenu>
00039 #include <QtCore/QUrl>
00040 #include <QtCore/QMetaEnum>
00041 #include <assert.h>
00042
00043 #include <kdebug.h>
00044 #include <klocale.h>
00045 #include <kfiledialog.h>
00046 #include <kjobuidelegate.h>
00047 #include <kio/job.h>
00048 #include <kshell.h>
00049 #include <ktoolbar.h>
00050 #include <ksavefile.h>
00051 #include <kstringhandler.h>
00052 #include <ktoolinvocation.h>
00053 #include <kmessagebox.h>
00054 #include <kstandarddirs.h>
00055 #include <krun.h>
00056 #include <kurifilter.h>
00057 #include <kicon.h>
00058 #include <kiconloader.h>
00059 #include <kdesktopfile.h>
00060 #include <kinputdialog.h>
00061 #include <ktemporaryfile.h>
00062 #include "khtml_global.h"
00063 #include <kstandardaction.h>
00064 #include <kactioncollection.h>
00065 #include <kactionmenu.h>
00066
00067 #include "dom/dom_element.h"
00068 #include "misc/htmltags.h"
00069
00070 #include "khtmlpart_p.h"
00071
00072 KHTMLPartBrowserExtension::KHTMLPartBrowserExtension( KHTMLPart *parent )
00073 : KParts::BrowserExtension( parent )
00074 {
00075 m_part = parent;
00076 setURLDropHandlingEnabled( true );
00077
00078 enableAction( "cut", false );
00079 enableAction( "copy", false );
00080 enableAction( "paste", false );
00081
00082 m_connectedToClipboard = false;
00083 }
00084
00085 int KHTMLPartBrowserExtension::xOffset()
00086 {
00087 return m_part->view()->contentsX();
00088 }
00089
00090 int KHTMLPartBrowserExtension::yOffset()
00091 {
00092 return m_part->view()->contentsY();
00093 }
00094
00095 void KHTMLPartBrowserExtension::saveState( QDataStream &stream )
00096 {
00097
00098 m_part->saveState( stream );
00099 }
00100
00101 void KHTMLPartBrowserExtension::restoreState( QDataStream &stream )
00102 {
00103
00104 m_part->restoreState( stream );
00105 }
00106
00107 void KHTMLPartBrowserExtension::editableWidgetFocused( QWidget *widget )
00108 {
00109 m_editableFormWidget = widget;
00110 updateEditActions();
00111
00112 if ( !m_connectedToClipboard && m_editableFormWidget )
00113 {
00114 connect( QApplication::clipboard(), SIGNAL( dataChanged() ),
00115 this, SLOT( updateEditActions() ) );
00116
00117 if ( m_editableFormWidget->inherits( "QLineEdit" ) || m_editableFormWidget->inherits( "QTextEdit" ) )
00118 connect( m_editableFormWidget, SIGNAL( selectionChanged() ),
00119 this, SLOT( updateEditActions() ) );
00120
00121 m_connectedToClipboard = true;
00122 }
00123 editableWidgetFocused();
00124 }
00125
00126 void KHTMLPartBrowserExtension::editableWidgetBlurred( QWidget * )
00127 {
00128 QWidget *oldWidget = m_editableFormWidget;
00129
00130 m_editableFormWidget = 0;
00131 enableAction( "cut", false );
00132 enableAction( "paste", false );
00133 m_part->emitSelectionChanged();
00134
00135 if ( m_connectedToClipboard )
00136 {
00137 disconnect( QApplication::clipboard(), SIGNAL( dataChanged() ),
00138 this, SLOT( updateEditActions() ) );
00139
00140 if ( oldWidget )
00141 {
00142 if ( oldWidget->inherits( "QLineEdit" ) || oldWidget->inherits( "QTextEdit" ) )
00143 disconnect( oldWidget, SIGNAL( selectionChanged() ),
00144 this, SLOT( updateEditActions() ) );
00145 }
00146
00147 m_connectedToClipboard = false;
00148 }
00149 editableWidgetBlurred();
00150 }
00151
00152 void KHTMLPartBrowserExtension::setExtensionProxy( KParts::BrowserExtension *proxy )
00153 {
00154 if ( m_extensionProxy )
00155 {
00156 disconnect( m_extensionProxy, SIGNAL( enableAction( const char *, bool ) ),
00157 this, SLOT( extensionProxyActionEnabled( const char *, bool ) ) );
00158 if ( m_extensionProxy->inherits( "KHTMLPartBrowserExtension" ) )
00159 {
00160 disconnect( m_extensionProxy, SIGNAL( editableWidgetFocused() ),
00161 this, SLOT( extensionProxyEditableWidgetFocused() ) );
00162 disconnect( m_extensionProxy, SIGNAL( editableWidgetBlurred() ),
00163 this, SLOT( extensionProxyEditableWidgetBlurred() ) );
00164 }
00165 }
00166
00167 m_extensionProxy = proxy;
00168
00169 if ( m_extensionProxy )
00170 {
00171 connect( m_extensionProxy, SIGNAL( enableAction( const char *, bool ) ),
00172 this, SLOT( extensionProxyActionEnabled( const char *, bool ) ) );
00173 if ( m_extensionProxy->inherits( "KHTMLPartBrowserExtension" ) )
00174 {
00175 connect( m_extensionProxy, SIGNAL( editableWidgetFocused() ),
00176 this, SLOT( extensionProxyEditableWidgetFocused() ) );
00177 connect( m_extensionProxy, SIGNAL( editableWidgetBlurred() ),
00178 this, SLOT( extensionProxyEditableWidgetBlurred() ) );
00179 }
00180
00181 enableAction( "cut", m_extensionProxy->isActionEnabled( "cut" ) );
00182 enableAction( "copy", m_extensionProxy->isActionEnabled( "copy" ) );
00183 enableAction( "paste", m_extensionProxy->isActionEnabled( "paste" ) );
00184 }
00185 else
00186 {
00187 updateEditActions();
00188 enableAction( "copy", false );
00189 }
00190 }
00191
00192 void KHTMLPartBrowserExtension::cut()
00193 {
00194 if ( m_extensionProxy )
00195 {
00196 callExtensionProxyMethod( "cut" );
00197 return;
00198 }
00199
00200 if ( !m_editableFormWidget )
00201 return;
00202
00203 QLineEdit* lineEdit = qobject_cast<QLineEdit *>( m_editableFormWidget );
00204 if ( lineEdit && !lineEdit->isReadOnly() )
00205 lineEdit->cut();
00206 QTextEdit* textEdit = qobject_cast<QTextEdit *>( m_editableFormWidget );
00207 if ( textEdit && !textEdit->isReadOnly() )
00208 textEdit->cut();
00209 }
00210
00211 void KHTMLPartBrowserExtension::copy()
00212 {
00213 if ( m_extensionProxy )
00214 {
00215 callExtensionProxyMethod( "copy" );
00216 return;
00217 }
00218
00219 if ( !m_editableFormWidget )
00220 {
00221
00222 QString text = m_part->selectedText();
00223 text.replace( QChar( 0xa0 ), ' ' );
00224
00225
00226 QClipboard *cb = QApplication::clipboard();
00227 disconnect( cb, SIGNAL( selectionChanged() ), m_part, SLOT( slotClearSelection() ) );
00228 #ifndef QT_NO_MIMECLIPBOARD
00229 QString htmltext;
00230
00231
00232
00233
00234
00235
00236
00237
00238 htmltext = m_part->selectedTextAsHTML();
00239 QMimeData *mimeData = new QMimeData;
00240 mimeData->setText(text);
00241 if(!htmltext.isEmpty()) {
00242 htmltext.replace( QChar( 0xa0 ), ' ' );
00243 mimeData->setHtml(htmltext);
00244 }
00245 cb->setMimeData(mimeData);
00246 #else
00247 cb->setText(text);
00248 #endif
00249
00250 connect( cb, SIGNAL( selectionChanged() ), m_part, SLOT( slotClearSelection() ) );
00251 }
00252 else
00253 {
00254 QLineEdit* lineEdit = qobject_cast<QLineEdit *>( m_editableFormWidget );
00255 if ( lineEdit )
00256 lineEdit->copy();
00257 QTextEdit* textEdit = qobject_cast<QTextEdit *>( m_editableFormWidget );
00258 if ( textEdit )
00259 textEdit->copy();
00260 }
00261 }
00262
00263 void KHTMLPartBrowserExtension::searchProvider()
00264 {
00265
00266 const QString searchProviderPrefix = QString( sender()->objectName() ).mid( 14 );
00267
00268 const QString text = m_part->simplifiedSelectedText();
00269 KUriFilterData data;
00270 QStringList list;
00271 data.setData( searchProviderPrefix + text );
00272 list << "kurisearchfilter" << "kuriikwsfilter";
00273
00274 if( !KUriFilter::self()->filterUri(data, list) )
00275 {
00276 KDesktopFile file("services", "searchproviders/google.desktop");
00277 QString encodedSearchTerm = QUrl::toPercentEncoding(text);
00278 KConfigGroup cg(file.desktopGroup());
00279 data.setData(cg.readEntry("Query").replace("\\{@}", encodedSearchTerm));
00280 }
00281
00282 KParts::BrowserArguments browserArgs;
00283 browserArgs.frameName = "_blank";
00284
00285 emit m_part->browserExtension()->openUrlRequest( data.uri(), KParts::OpenUrlArguments(), browserArgs );
00286 }
00287
00288 void KHTMLPartBrowserExtension::paste()
00289 {
00290 if ( m_extensionProxy )
00291 {
00292 callExtensionProxyMethod( "paste" );
00293 return;
00294 }
00295
00296 if ( !m_editableFormWidget )
00297 return;
00298
00299 QLineEdit* lineEdit = qobject_cast<QLineEdit *>( m_editableFormWidget );
00300 if ( lineEdit && !lineEdit->isReadOnly() )
00301 lineEdit->paste();
00302 QTextEdit* textEdit = qobject_cast<QTextEdit *>( m_editableFormWidget );
00303 if ( textEdit && !textEdit->isReadOnly() )
00304 textEdit->paste();
00305 }
00306
00307 void KHTMLPartBrowserExtension::callExtensionProxyMethod( const char *method )
00308 {
00309 if ( !m_extensionProxy )
00310 return;
00311
00312 QMetaObject::invokeMethod(m_extensionProxy, method, Qt::DirectConnection);
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
00326 #ifndef QT_NO_MIMECLIPBOARD // Handle minimalized versions of Qt Embedded
00327 const QMimeData *data = QApplication::clipboard()->mimeData();
00328 enableAction( "paste", data->hasFormat( "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 ( qobject_cast<QLineEdit*>(m_editableFormWidget))
00337 hasSelection = static_cast<QLineEdit *>( &(*m_editableFormWidget) )->hasSelectedText();
00338 else if(qobject_cast<QTextEdit*>(m_editableFormWidget))
00339 hasSelection = static_cast<QTextEdit *>( &(*m_editableFormWidget) )->textCursor().hasSelection();
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
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 void KHTMLPartBrowserExtension::disableScrolling()
00375 {
00376 QScrollArea *scrollArea = m_part->view();
00377 if (scrollArea) {
00378 scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00379 scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00380 }
00381 }
00382
00383 class KHTMLPopupGUIClient::KHTMLPopupGUIClientPrivate
00384 {
00385 public:
00386 KHTMLPart *m_khtml;
00387 KUrl m_url;
00388 KUrl m_imageURL;
00389 QPixmap m_pixmap;
00390 QString m_suggestedFilename;
00391 KActionCollection* m_actionCollection;
00392 KParts::BrowserExtension::ActionGroupMap actionGroups;
00393 };
00394
00395
00396 KHTMLPopupGUIClient::KHTMLPopupGUIClient( KHTMLPart *khtml, const KUrl &url )
00397 : QObject( khtml ), d(new KHTMLPopupGUIClientPrivate)
00398 {
00399 d->m_khtml = khtml;
00400 d->m_url = url;
00401 d->m_actionCollection = new KActionCollection(this);
00402 bool isImage = false;
00403 bool hasSelection = khtml->hasSelection();
00404
00405 DOM::Element e = khtml->nodeUnderMouse();
00406
00407 if ( !e.isNull() && (e.elementId() == ID_IMG ||
00408 (e.elementId() == ID_INPUT && !static_cast<DOM::HTMLInputElement>(e).src().isEmpty())))
00409 {
00410 if (e.elementId() == ID_IMG) {
00411 DOM::HTMLImageElementImpl *ie = static_cast<DOM::HTMLImageElementImpl*>(e.handle());
00412 khtml::RenderImage *ri = dynamic_cast<khtml::RenderImage*>(ie->renderer());
00413 if (ri && ri->contentObject()) {
00414 d->m_suggestedFilename = static_cast<khtml::CachedImage*>(ri->contentObject())->suggestedFilename();
00415 }
00416 }
00417 isImage=true;
00418 }
00419
00420 if (hasSelection) {
00421 QList<QAction *> editActions;
00422 QAction* copyAction = d->m_actionCollection->addAction( KStandardAction::Copy, "copy",
00423 d->m_khtml->browserExtension(), SLOT( copy() ) );
00424
00425 copyAction->setText(i18n("&Copy Text"));
00426 copyAction->setEnabled(d->m_khtml->browserExtension()->isActionEnabled( "copy" ));
00427 editActions.append(copyAction);
00428
00429 editActions.append(khtml->actionCollection()->action("selectAll"));
00430
00431 addSearchActions(editActions);
00432
00433 QString selectedTextURL = selectedTextAsOneLine();
00434 if ( selectedTextURL.contains("://") && KUrl(selectedTextURL).isValid() ) {
00435 if (selectedTextURL.length() > 18) {
00436 selectedTextURL.truncate(15);
00437 selectedTextURL += "...";
00438 }
00439 KAction *action = new KAction(i18n("Open '%1'", selectedTextURL), this);
00440 d->m_actionCollection->addAction( "openSelection", action );
00441 action->setIcon( KIcon( "window-new" ) );
00442 connect( action, SIGNAL(triggered(bool)), this, SLOT( openSelection() ) );
00443 editActions.append(action);
00444 }
00445
00446 KAction* separator = new KAction(d->m_actionCollection);
00447 separator->setSeparator(true);
00448 editActions.append(separator);
00449
00450 d->actionGroups.insert("editactions", editActions);
00451 }
00452
00453 if (!url.isEmpty()) {
00454 QList<QAction *> linkActions;
00455 if (url.protocol() == "mailto") {
00456 KAction *action = new KAction( i18n( "&Copy Email Address" ), this );
00457 d->m_actionCollection->addAction( "copylinklocation", action );
00458 connect( action, SIGNAL(triggered(bool)), this, SLOT(slotCopyLinkLocation()) );
00459 linkActions.append(action);
00460 } else {
00461 KAction *action = new KAction( i18n( "&Save Link As..." ), this );
00462 d->m_actionCollection->addAction( "savelinkas", action );
00463 connect( action, SIGNAL(triggered(bool)), this, SLOT(slotSaveLinkAs()) );
00464 linkActions.append(action);
00465
00466 action = new KAction( i18n( "&Copy Link Address" ), this );
00467 d->m_actionCollection->addAction( "copylinklocation", action );
00468 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotCopyLinkLocation() ) );
00469 linkActions.append(action);
00470 }
00471 d->actionGroups.insert("linkactions", linkActions);
00472 }
00473
00474 QList<QAction *> partActions;
00475
00476 if (!hasSelection) {
00477 if ( khtml->parentPart() ) {
00478 KActionMenu* menu = new KActionMenu( i18nc("@title:menu HTML frame/iframe", "Frame"), this);
00479 KAction *action = new KAction( i18n( "Open in New &Window" ), this );
00480 d->m_actionCollection->addAction( "frameinwindow", action );
00481 action->setIcon( KIcon( "window-new" ) );
00482 connect( action, SIGNAL(triggered(bool)), this, SLOT(slotFrameInWindow()) );
00483 menu->addAction(action);
00484
00485 action = new KAction( i18n( "Open in &This Window" ), this );
00486 d->m_actionCollection->addAction( "frameintop", action );
00487 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotFrameInTop() ) );
00488 menu->addAction(action);
00489
00490 action = new KAction( i18n( "Open in &New Tab" ), this );
00491 d->m_actionCollection->addAction( "frameintab", action );
00492 action->setIcon( KIcon( "tab-new" ) );
00493 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotFrameInTab() ) );
00494 menu->addAction(action);
00495
00496 action = new KAction(d->m_actionCollection);
00497 action->setSeparator(true);
00498 menu->addAction(action);
00499
00500 action = new KAction( i18n( "Reload Frame" ), this );
00501 d->m_actionCollection->addAction( "reloadframe", action );
00502 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotReloadFrame() ) );
00503 menu->addAction(action);
00504
00505 action = new KAction( i18n( "Print Frame..." ), this );
00506 d->m_actionCollection->addAction( "printFrame", action );
00507 action->setIcon( KIcon( "document-print-frame" ) );
00508 connect( action, SIGNAL(triggered(bool)), d->m_khtml->browserExtension(), SLOT( print() ) );
00509 menu->addAction(action);
00510
00511 action = new KAction( i18n( "Save &Frame As..." ), this );
00512 d->m_actionCollection->addAction( "saveFrame", action );
00513 connect( action, SIGNAL(triggered(bool)), d->m_khtml, SLOT( slotSaveFrame() ) );
00514 menu->addAction(action);
00515
00516 action = new KAction( i18n( "View Frame Source" ), this );
00517 d->m_actionCollection->addAction( "viewFrameSource", action );
00518 connect( action, SIGNAL(triggered(bool)), d->m_khtml, SLOT( slotViewDocumentSource() ) );
00519 menu->addAction(action);
00520
00521 action = new KAction( i18n( "View Frame Information" ), this );
00522 d->m_actionCollection->addAction( "viewFrameInfo", action );
00523 connect( action, SIGNAL(triggered(bool)), d->m_khtml, SLOT( slotViewPageInfo() ) );
00524
00525 action = new KAction(d->m_actionCollection);
00526 action->setSeparator(true);
00527 menu->addAction(action);
00528
00529 if ( KHTMLGlobal::defaultHTMLSettings()->isAdFilterEnabled() ) {
00530 if ( khtml->d->m_frame->m_type == khtml::ChildFrame::IFrame ) {
00531 action = new KAction( i18n( "Block IFrame..." ), this );
00532 d->m_actionCollection->addAction( "blockiframe", action );
00533 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotBlockIFrame() ) );
00534 menu->addAction(action);
00535 }
00536 }
00537
00538 partActions.append(menu);
00539 }
00540 }
00541
00542 if (isImage) {
00543 if ( e.elementId() == ID_IMG ) {
00544 d->m_imageURL = KUrl( static_cast<DOM::HTMLImageElement>( e ).src().string() );
00545 DOM::HTMLImageElementImpl *imageimpl = static_cast<DOM::HTMLImageElementImpl *>( e.handle() );
00546 Q_ASSERT(imageimpl);
00547 if(imageimpl)
00548 {
00549 if(imageimpl->complete()) {
00550 d->m_pixmap = imageimpl->currentPixmap();
00551 }
00552 }
00553 }
00554 else
00555 d->m_imageURL = KUrl( static_cast<DOM::HTMLInputElement>( e ).src().string() );
00556 KAction *action = new KAction( i18n( "Save Image As..." ), this );
00557 d->m_actionCollection->addAction( "saveimageas", action );
00558 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotSaveImageAs() ) );
00559 partActions.append(action);
00560
00561 action = new KAction( i18n( "Send Image..." ), this );
00562 d->m_actionCollection->addAction( "sendimage", action );
00563 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotSendImage() ) );
00564 partActions.append(action);
00565
00566 #ifndef QT_NO_MIMECLIPBOARD
00567 action = new KAction( i18n( "Copy Image" ), this );
00568 d->m_actionCollection->addAction( "copyimage", action );
00569 action->setEnabled(!d->m_pixmap.isNull());
00570 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotCopyImage() ) );
00571 partActions.append(action);
00572 #endif
00573
00574 if(d->m_pixmap.isNull()) {
00575 action = new KAction( i18n( "Copy Image Location" ), this );
00576 d->m_actionCollection->addAction( "copyimagelocation", action );
00577 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotCopyImageLocation() ) );
00578 partActions.append(action);
00579 }
00580
00581 QString actionText = d->m_suggestedFilename.isEmpty() ?
00582 KStringHandler::csqueeze(d->m_imageURL.fileName()+d->m_imageURL.query(), 25)
00583 : d->m_suggestedFilename;
00584 action = new KAction( i18n("View Image (%1)", actionText.replace("&", "&&")), this );
00585 d->m_actionCollection->addAction( "viewimage", action );
00586 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotViewImage() ) );
00587 partActions.append(action);
00588
00589 if (KHTMLGlobal::defaultHTMLSettings()->isAdFilterEnabled()) {
00590 action = new KAction( i18n( "Block Image..." ), this );
00591 d->m_actionCollection->addAction( "blockimage", action );
00592 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotBlockImage() ) );
00593 partActions.append(action);
00594
00595 if (!d->m_imageURL.host().isEmpty() &&
00596 !d->m_imageURL.protocol().isEmpty())
00597 {
00598 action = new KAction( i18n( "Block Images From %1" , d->m_imageURL.host()), this );
00599 d->m_actionCollection->addAction( "blockhost", action );
00600 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotBlockHost() ) );
00601 partActions.append(action);
00602 }
00603 }
00604 KAction* separator = new KAction(d->m_actionCollection);
00605 separator->setSeparator(true);
00606 partActions.append(separator);
00607 }
00608
00609 if ( isImage || url.isEmpty() ) {
00610 KAction *action = new KAction( i18n( "Stop Animations" ), this );
00611 d->m_actionCollection->addAction( "stopanimations", action );
00612 connect( action, SIGNAL(triggered(bool)), this, SLOT(slotStopAnimations()) );
00613 partActions.append(action);
00614 KAction* separator = new KAction(d->m_actionCollection);
00615 separator->setSeparator(true);
00616 partActions.append(separator);
00617 }
00618 if (!hasSelection && url.isEmpty()) {
00619 partActions.append(khtml->actionCollection()->action("viewDocumentSource"));
00620 }
00621 if (!hasSelection && url.isEmpty() && !isImage) {
00622 partActions.append(khtml->actionCollection()->action("setEncoding"));
00623 }
00624 d->actionGroups.insert("partactions", partActions);
00625 }
00626
00627 KHTMLPopupGUIClient::~KHTMLPopupGUIClient()
00628 {
00629 delete d->m_actionCollection;
00630 delete d;
00631 }
00632
00633 void KHTMLPopupGUIClient::addSearchActions(QList<QAction *>& editActions)
00634 {
00635
00636 KConfig config("kuriikwsfilterrc");
00637 KConfigGroup cg = config.group("General");
00638 const QString defaultEngine = cg.readEntry("DefaultSearchEngine", "google");
00639 const char keywordDelimiter = cg.readEntry("KeywordDelimiter", static_cast<int>(':'));
00640
00641
00642 QString selectedText = d->m_khtml->simplifiedSelectedText();
00643 if (selectedText.isEmpty())
00644 return;
00645
00646 selectedText.replace("&", "&&");
00647 if (selectedText.length() > 18) {
00648 selectedText.truncate(15);
00649 selectedText += "...";
00650 }
00651
00652
00653 KService::Ptr service;
00654 if( !defaultEngine.isEmpty())
00655 service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(defaultEngine));
00656
00657
00658 KIcon icon;
00659 KUriFilterData data;
00660 QStringList list;
00661 data.setData(QString("some keyword"));
00662 list << "kurisearchfilter" << "kuriikwsfilter";
00663
00664 QString name;
00665 if (KUriFilter::self()->filterUri(data, list)) {
00666 QString iconPath = KStandardDirs::locate("cache", KMimeType::favIconForUrl(data.uri()) + ".png");
00667 if (iconPath.isEmpty())
00668 icon = KIcon("edit-find");
00669 else
00670 icon = KIcon(QPixmap(iconPath));
00671 name = service->name();
00672 } else {
00673 icon = KIcon("google");
00674 name = "Google";
00675 }
00676
00677 KAction *action = new KAction(i18n("Search for '%1' with %2", selectedText, name), this);
00678 d->m_actionCollection->addAction("searchProvider", action);
00679 editActions.append(action);
00680 action->setIcon(icon);
00681 connect(action, SIGNAL(triggered(bool)), d->m_khtml->browserExtension(), SLOT(searchProvider()));
00682
00683
00684 QStringList favoriteEngines;
00685 favoriteEngines << "google" << "google_groups" << "google_news" << "webster" << "dmoz" << "wikipedia";
00686 favoriteEngines = cg.readEntry("FavoriteSearchEngines", favoriteEngines);
00687
00688 if (!favoriteEngines.isEmpty()) {
00689 KActionMenu* providerList = new KActionMenu(i18n("Search for '%1' with", selectedText), this);
00690 d->m_actionCollection->addAction("searchProviderList", providerList);
00691 editActions.append(providerList);
00692
00693 QStringList::ConstIterator it = favoriteEngines.constBegin();
00694 for (; it != favoriteEngines.constEnd(); ++it) {
00695 if (*it==defaultEngine)
00696 continue;
00697 service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(*it));
00698 if (!service)
00699 continue;
00700 const QString searchProviderPrefix = *(service->property("Keys").toStringList().begin()) + keywordDelimiter;
00701 data.setData(searchProviderPrefix + "some keyword");
00702
00703 if (KUriFilter::self()->filterUri(data, list)) {
00704 const QString iconPath = KStandardDirs::locate("cache", KMimeType::favIconForUrl(data.uri()) + ".png");
00705 if (iconPath.isEmpty())
00706 icon = KIcon("edit-find");
00707 else
00708 icon = KIcon(iconPath);
00709 name = service->name();
00710
00711 KAction *action = new KAction(name, this);
00712 d->m_actionCollection->addAction(QString("searchProvider" + searchProviderPrefix).toLatin1().constData(), action);
00713 action->setIcon(icon);
00714 connect(action, SIGNAL(triggered(bool)), d->m_khtml->browserExtension(), SLOT(searchProvider()));
00715
00716 providerList->addAction(action);
00717 }
00718 }
00719 }
00720 }
00721
00722 QString KHTMLPopupGUIClient::selectedTextAsOneLine() const
00723 {
00724 QString text = d->m_khtml->simplifiedSelectedText();
00725
00726
00727
00728 text.remove(QRegExp("[\\s]*\\n+[\\s]*"));
00729 return text;
00730 }
00731
00732 void KHTMLPopupGUIClient::openSelection()
00733 {
00734 KParts::BrowserArguments browserArgs;
00735 browserArgs.frameName = "_blank";
00736
00737 emit d->m_khtml->browserExtension()->openUrlRequest(selectedTextAsOneLine(), KParts::OpenUrlArguments(), browserArgs);
00738 }
00739
00740 KParts::BrowserExtension::ActionGroupMap KHTMLPopupGUIClient::actionGroups() const
00741 {
00742 return d->actionGroups;
00743 }
00744
00745 void KHTMLPopupGUIClient::slotSaveLinkAs()
00746 {
00747 KIO::MetaData metaData;
00748 metaData["referrer"] = d->m_khtml->referrer();
00749 saveURL( d->m_khtml->widget(), i18n( "Save Link As" ), d->m_url, metaData );
00750 }
00751
00752 void KHTMLPopupGUIClient::slotSendImage()
00753 {
00754 QStringList urls;
00755 urls.append( d->m_imageURL.url());
00756 QString subject = d->m_imageURL.url();
00757 KToolInvocation::invokeMailer(QString(), QString(), QString(), subject,
00758 QString(),
00759 QString(),
00760 urls);
00761
00762
00763 }
00764
00765 void KHTMLPopupGUIClient::slotSaveImageAs()
00766 {
00767 KIO::MetaData metaData;
00768 metaData["referrer"] = d->m_khtml->referrer();
00769 saveURL( d->m_khtml->widget(), i18n( "Save Image As" ), d->m_imageURL, metaData, QString(), 0, d->m_suggestedFilename );
00770 }
00771
00772 void KHTMLPopupGUIClient::slotBlockHost()
00773 {
00774 QString name=d->m_imageURL.protocol()+"://"+d->m_imageURL.host()+"/*";
00775 KHTMLGlobal::defaultHTMLSettings()->addAdFilter( name );
00776 d->m_khtml->reparseConfiguration();
00777 }
00778
00779 void KHTMLPopupGUIClient::slotBlockImage()
00780 {
00781 bool ok = false;
00782
00783 QString url = KInputDialog::getText( i18n("Add URL to Filter"),
00784 i18n("Enter the URL:"),
00785 d->m_imageURL.url(),
00786 &ok);
00787 if ( ok ) {
00788 KHTMLGlobal::defaultHTMLSettings()->addAdFilter( url );
00789 d->m_khtml->reparseConfiguration();
00790 }
00791 }
00792
00793 void KHTMLPopupGUIClient::slotBlockIFrame()
00794 {
00795 bool ok = false;
00796 QString url = KInputDialog::getText( i18n( "Add URL to Filter"),
00797 i18n("Enter the URL:"),
00798 d->m_khtml->url().url(),
00799 &ok );
00800 if ( ok ) {
00801 KHTMLGlobal::defaultHTMLSettings()->addAdFilter( url );
00802 d->m_khtml->reparseConfiguration();
00803 }
00804 }
00805
00806 void KHTMLPopupGUIClient::slotCopyLinkLocation()
00807 {
00808 KUrl safeURL(d->m_url);
00809 safeURL.setPass(QString());
00810 #ifndef QT_NO_MIMECLIPBOARD
00811
00812 QMimeData* mimeData = new QMimeData;
00813 safeURL.populateMimeData( mimeData );
00814 QApplication::clipboard()->setMimeData( mimeData, QClipboard::Clipboard );
00815
00816 mimeData = new QMimeData;
00817 safeURL.populateMimeData( mimeData );
00818 QApplication::clipboard()->setMimeData( mimeData, QClipboard::Selection );
00819
00820 #else
00821 QApplication::clipboard()->setText( safeURL.url() );
00822 #endif
00823 }
00824
00825 void KHTMLPopupGUIClient::slotStopAnimations()
00826 {
00827 d->m_khtml->stopAnimations();
00828 }
00829
00830 void KHTMLPopupGUIClient::slotCopyImage()
00831 {
00832 #ifndef QT_NO_MIMECLIPBOARD
00833 KUrl safeURL(d->m_imageURL);
00834 safeURL.setPass(QString());
00835
00836
00837 QMimeData* mimeData = new QMimeData;
00838 mimeData->setImageData( d->m_pixmap );
00839 safeURL.populateMimeData( mimeData );
00840 QApplication::clipboard()->setMimeData( mimeData, QClipboard::Clipboard );
00841
00842 mimeData = new QMimeData;
00843 mimeData->setImageData( d->m_pixmap );
00844 safeURL.populateMimeData( mimeData );
00845 QApplication::clipboard()->setMimeData( mimeData, QClipboard::Selection );
00846 #else
00847 kDebug() << "slotCopyImage called when the clipboard does not support this. This should not be possible.";
00848 #endif
00849 }
00850
00851 void KHTMLPopupGUIClient::slotCopyImageLocation()
00852 {
00853 KUrl safeURL(d->m_imageURL);
00854 safeURL.setPass(QString());
00855 #ifndef QT_NO_MIMECLIPBOARD
00856
00857 QMimeData* mimeData = new QMimeData;
00858 safeURL.populateMimeData( mimeData );
00859 QApplication::clipboard()->setMimeData( mimeData, QClipboard::Clipboard );
00860 mimeData = new QMimeData;
00861 safeURL.populateMimeData( mimeData );
00862 QApplication::clipboard()->setMimeData( mimeData, QClipboard::Selection );
00863 #else
00864 QApplication::clipboard()->setText( safeURL.url() );
00865 #endif
00866 }
00867
00868 void KHTMLPopupGUIClient::slotViewImage()
00869 {
00870 d->m_khtml->browserExtension()->createNewWindow(d->m_imageURL);
00871 }
00872
00873 void KHTMLPopupGUIClient::slotReloadFrame()
00874 {
00875 KParts::OpenUrlArguments args = d->m_khtml->arguments();
00876 args.setReload( true );
00877 args.metaData()["referrer"] = d->m_khtml->pageReferrer();
00878
00879 d->m_khtml->closeUrl();
00880 d->m_khtml->setArguments( args );
00881 d->m_khtml->openUrl( d->m_khtml->url() );
00882 }
00883
00884 void KHTMLPopupGUIClient::slotFrameInWindow()
00885 {
00886 KParts::OpenUrlArguments args = d->m_khtml->arguments();
00887 args.metaData()["referrer"] = d->m_khtml->pageReferrer();
00888 args.metaData()["forcenewwindow"] = "true";
00889 emit d->m_khtml->browserExtension()->createNewWindow( d->m_khtml->url(), args );
00890 }
00891
00892 void KHTMLPopupGUIClient::slotFrameInTop()
00893 {
00894 KParts::OpenUrlArguments args = d->m_khtml->arguments();
00895 args.metaData()["referrer"] = d->m_khtml->pageReferrer();
00896 KParts::BrowserArguments browserArgs( d->m_khtml->browserExtension()->browserArguments() );
00897 browserArgs.frameName = "_top";
00898 emit d->m_khtml->browserExtension()->openUrlRequest( d->m_khtml->url(), args, browserArgs );
00899 }
00900
00901 void KHTMLPopupGUIClient::slotFrameInTab()
00902 {
00903 KParts::OpenUrlArguments args = d->m_khtml->arguments();
00904 args.metaData()["referrer"] = d->m_khtml->pageReferrer();
00905 KParts::BrowserArguments browserArgs( d->m_khtml->browserExtension()->browserArguments() );
00906 browserArgs.setNewTab(true);
00907 emit d->m_khtml->browserExtension()->createNewWindow( d->m_khtml->url(), args, browserArgs );
00908 }
00909
00910 void KHTMLPopupGUIClient::saveURL( QWidget *parent, const QString &caption,
00911 const KUrl &url,
00912 const QMap<QString, QString> &metadata,
00913 const QString &filter, long cacheId,
00914 const QString & suggestedFilename )
00915 {
00916 QString name = QLatin1String( "index.html" );
00917 if ( !suggestedFilename.isEmpty() )
00918 name = suggestedFilename;
00919 else if ( !url.fileName().isEmpty() )
00920 name = url.fileName();
00921
00922 KUrl destURL;
00923 int query;
00924 do {
00925 query = KMessageBox::Yes;
00926 destURL = KFileDialog::getSaveUrl( name, filter, parent, caption );
00927 if( destURL.isLocalFile() )
00928 {
00929 QFileInfo info( destURL.toLocalFile() );
00930 if( info.exists() ) {
00931
00932 query = KMessageBox::warningContinueCancel( parent, i18n( "A file named \"%1\" already exists. " "Are you sure you want to overwrite it?" , info.fileName() ), i18n( "Overwrite File?" ), KGuiItem(i18n( "Overwrite" )) );
00933 }
00934 }
00935 } while ( query == KMessageBox::Cancel );
00936
00937 if ( destURL.isValid() )
00938 saveURL(parent, url, destURL, metadata, cacheId);
00939 }
00940
00941 void KHTMLPopupGUIClient::saveURL( QWidget* parent, const KUrl &url, const KUrl &destURL,
00942 const QMap<QString, QString> &metadata,
00943 long cacheId )
00944 {
00945 if ( destURL.isValid() )
00946 {
00947 bool saved = false;
00948 if (KHTMLPageCache::self()->isComplete(cacheId))
00949 {
00950 if (destURL.isLocalFile())
00951 {
00952 KSaveFile destFile(destURL.toLocalFile());
00953 if (destFile.open())
00954 {
00955 QDataStream stream ( &destFile );
00956 KHTMLPageCache::self()->saveData(cacheId, &stream);
00957 saved = true;
00958 }
00959 }
00960 else
00961 {
00962
00963 KTemporaryFile destFile;
00964 if (destFile.open())
00965 {
00966 QDataStream stream ( &destFile );
00967 KHTMLPageCache::self()->saveData(cacheId, &stream);
00968 KUrl url2 = KUrl();
00969 url2.setPath(destFile.fileName());
00970 KIO::file_move(url2, destURL, -1, KIO::Overwrite);
00971 saved = true;
00972 }
00973 }
00974 }
00975 if(!saved)
00976 {
00977
00978
00979
00980
00981 bool downloadViaKIO = true;
00982 if ( !url.isLocalFile() )
00983 {
00984 KConfigGroup cfg = KSharedConfig::openConfig("konquerorrc", KConfig::NoGlobals)->group("HTML Settings");
00985 QString downloadManger = cfg.readPathEntry("DownloadManager", QString());
00986 if (!downloadManger.isEmpty())
00987 {
00988
00989 kDebug(1000) << "Using: "<<downloadManger <<" as Download Manager";
00990 QString cmd = KStandardDirs::findExe(downloadManger);
00991 if (cmd.isEmpty())
00992 {
00993 QString errMsg=i18n("The Download Manager (%1) could not be found in your $PATH ", downloadManger);
00994 QString errMsgEx= i18n("Try to reinstall it \n\nThe integration with Konqueror will be disabled.");
00995 KMessageBox::detailedSorry(0,errMsg,errMsgEx);
00996 cfg.writePathEntry("DownloadManager",QString());
00997 cfg.sync ();
00998 }
00999 else
01000 {
01001 downloadViaKIO = false;
01002 KUrl cleanDest = destURL;
01003 cleanDest.setPass( QString() );
01004 cmd += ' ' + KShell::quoteArg(url.url()) + ' ' +
01005 KShell::quoteArg(cleanDest.url());
01006 kDebug(1000) << "Calling command "<<cmd;
01007 KRun::runCommand(cmd, parent->topLevelWidget());
01008 }
01009 }
01010 }
01011
01012 if ( downloadViaKIO )
01013 {
01014 KIO::Job *job = KIO::file_copy( url, destURL, -1, KIO::Overwrite );
01015 job->setMetaData(metadata);
01016 job->addMetaData("MaxCacheSize", "0");
01017 job->addMetaData("cache", "cache");
01018 job->uiDelegate()->setAutoErrorHandlingEnabled( true );
01019 }
01020 }
01021 }
01022 }
01023
01024 KHTMLPartBrowserHostExtension::KHTMLPartBrowserHostExtension( KHTMLPart *part )
01025 : KParts::BrowserHostExtension( part )
01026 {
01027 m_part = part;
01028 }
01029
01030 KHTMLPartBrowserHostExtension::~KHTMLPartBrowserHostExtension()
01031 {
01032 }
01033
01034 QStringList KHTMLPartBrowserHostExtension::frameNames() const
01035 {
01036 return m_part->frameNames();
01037 }
01038
01039 const QList<KParts::ReadOnlyPart*> KHTMLPartBrowserHostExtension::frames() const
01040 {
01041 return m_part->frames();
01042 }
01043
01044 bool KHTMLPartBrowserHostExtension::openUrlInFrame(const KUrl &url, const KParts::OpenUrlArguments& arguments, const KParts::BrowserArguments &browserArguments)
01045 {
01046 return m_part->openUrlInFrame( url, arguments, browserArguments );
01047 }
01048
01049 KParts::BrowserHostExtension* KHTMLPartBrowserHostExtension::findFrameParent( KParts::ReadOnlyPart
01050 *callingPart, const QString &frame )
01051 {
01052 KHTMLPart *parentPart = m_part->findFrameParent(callingPart, frame);
01053 if (parentPart)
01054 return parentPart->browserHostExtension();
01055 return 0;
01056 }
01057
01058
01059
01060 extern const int KDE_NO_EXPORT fastZoomSizes[];
01061 extern const int KDE_NO_EXPORT fastZoomSizeCount;
01062
01063 KHTMLZoomFactorAction::KHTMLZoomFactorAction( KHTMLPart *part, bool direction, const QString &icon, const QString &text, QObject *parent )
01064 : KSelectAction( text, parent )
01065 {
01066 setIcon( KIcon( icon ) );
01067
01068 setToolBarMode(MenuMode);
01069 setToolButtonPopupMode(QToolButton::DelayedPopup);
01070
01071 init(part, direction);
01072 }
01073
01074 void KHTMLZoomFactorAction::init(KHTMLPart *part, bool direction)
01075 {
01076 m_direction = direction;
01077 m_part = part;
01078
01079
01080 addAction( i18n( "Default Font Size (100%)" ) );
01081
01082 int m = m_direction ? 1 : -1;
01083 int ofs = fastZoomSizeCount / 2;
01084
01085
01086 for ( int i = m; i != m*(ofs+1); i += m )
01087 {
01088 int num = i * m;
01089 QString numStr = QString::number( num );
01090 if ( num > 0 ) numStr.prepend( QLatin1Char('+') );
01091
01092
01093 addAction( i18n( "%1%" , fastZoomSizes[ofs + i] ) );
01094 }
01095
01096 connect( selectableActionGroup(), SIGNAL( triggered(QAction*) ), this, SLOT( slotTriggered(QAction*) ) );
01097 }
01098
01099 KHTMLZoomFactorAction::~KHTMLZoomFactorAction()
01100 {
01101 }
01102
01103 void KHTMLZoomFactorAction::slotTriggered(QAction* action)
01104 {
01105 int idx = selectableActionGroup()->actions().indexOf(action);
01106
01107 if (idx == 0)
01108 m_part->setFontScaleFactor(100);
01109 else
01110 m_part->setFontScaleFactor(fastZoomSizes[fastZoomSizeCount/2 + (m_direction ? 1 : -1)*idx]);
01111 setCurrentAction( 0L );
01112 }
01113
01114 #include "khtml_ext.moc"
01115