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