KHTML
khtml_ext.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE project 00002 * 00003 * Copyright (C) 2000-2003 Simon Hausmann <hausmann@kde.org> 00004 * 2001-2003 George Staikos <staikos@kde.org> 00005 * 2001-2003 Laurent Montel <montel@kde.org> 00006 * 2001-2003 Dirk Mueller <mueller@kde.org> 00007 * 2001-2003 Waldo Bastian <bastian@kde.org> 00008 * 2001-2003 David Faure <faure@kde.org> 00009 * 2001-2003 Daniel Naber <dnaber@kde.org> 00010 * 00011 * This library is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU Library General Public 00013 * License as published by the Free Software Foundation; either 00014 * version 2 of the License, or (at your option) any later version. 00015 * 00016 * This library is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 * Library General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Library General Public License 00022 * along with this library; see the file COPYING.LIB. If not, write to 00023 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00024 * Boston, MA 02110-1301, USA. 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 "dom/dom_string.h" 00037 #include "dom/html_document.h" 00038 #include "dom/dom_element.h" 00039 #include "xml/dom_elementimpl.h" 00040 #include <QtGui/QClipboard> 00041 #include <QtCore/QFileInfo> 00042 #include <QtGui/QMenu> 00043 #include <QtCore/QUrl> 00044 #include <QtCore/QMetaEnum> 00045 #include <assert.h> 00046 00047 #include <kdebug.h> 00048 #include <klocale.h> 00049 #include <kfiledialog.h> 00050 #include <kjobuidelegate.h> 00051 #include <kio/job.h> 00052 #include <kshell.h> 00053 #include <ktoolbar.h> 00054 #include <ksavefile.h> 00055 #include <kstringhandler.h> 00056 #include <ktoolinvocation.h> 00057 #include <kmessagebox.h> 00058 #include <kstandarddirs.h> 00059 #include <krun.h> 00060 #include <kurifilter.h> 00061 #include <kicon.h> 00062 #include <kiconloader.h> 00063 #include <kdesktopfile.h> 00064 #include <kinputdialog.h> 00065 #include <ktemporaryfile.h> 00066 #include "khtml_global.h" 00067 #include <kstandardaction.h> 00068 #include <kactioncollection.h> 00069 #include <kactionmenu.h> 00070 00071 #include "khtmlpart_p.h" 00072 00073 KHTMLPartBrowserExtension::KHTMLPartBrowserExtension( KHTMLPart *parent ) 00074 : KParts::BrowserExtension( parent ) 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( QDataStream &stream ) 00097 { 00098 //kDebug( 6050 ) << "saveState!"; 00099 m_part->saveState( stream ); 00100 } 00101 00102 void KHTMLPartBrowserExtension::restoreState( QDataStream &stream ) 00103 { 00104 //kDebug( 6050 ) << "restoreState!"; 00105 m_part->restoreState( stream ); 00106 } 00107 00108 void KHTMLPartBrowserExtension::editableWidgetFocused( QWidget *widget ) 00109 { 00110 m_editableFormWidget = widget; 00111 updateEditActions(); 00112 00113 if ( !m_connectedToClipboard && m_editableFormWidget ) 00114 { 00115 connect( QApplication::clipboard(), SIGNAL( dataChanged() ), 00116 this, SLOT( updateEditActions() ) ); 00117 00118 if ( m_editableFormWidget->inherits( "QLineEdit" ) || m_editableFormWidget->inherits( "QTextEdit" ) ) 00119 connect( m_editableFormWidget, SIGNAL( selectionChanged() ), 00120 this, SLOT( updateEditActions() ) ); 00121 00122 m_connectedToClipboard = true; 00123 } 00124 editableWidgetFocused(); 00125 } 00126 00127 void KHTMLPartBrowserExtension::editableWidgetBlurred( QWidget * /*widget*/ ) 00128 { 00129 QWidget *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( QApplication::clipboard(), SIGNAL( dataChanged() ), 00139 this, SLOT( updateEditActions() ) ); 00140 00141 if ( oldWidget ) 00142 { 00143 if ( oldWidget->inherits( "QLineEdit" ) || oldWidget->inherits( "QTextEdit" ) ) 00144 disconnect( oldWidget, SIGNAL( selectionChanged() ), 00145 this, 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, SIGNAL( enableAction( const char *, bool ) ), 00158 this, SLOT( extensionProxyActionEnabled( const char *, bool ) ) ); 00159 if ( m_extensionProxy->inherits( "KHTMLPartBrowserExtension" ) ) 00160 { 00161 disconnect( m_extensionProxy, SIGNAL( editableWidgetFocused() ), 00162 this, SLOT( extensionProxyEditableWidgetFocused() ) ); 00163 disconnect( m_extensionProxy, SIGNAL( editableWidgetBlurred() ), 00164 this, SLOT( extensionProxyEditableWidgetBlurred() ) ); 00165 } 00166 } 00167 00168 m_extensionProxy = proxy; 00169 00170 if ( m_extensionProxy ) 00171 { 00172 connect( m_extensionProxy, SIGNAL( enableAction( const char *, bool ) ), 00173 this, SLOT( extensionProxyActionEnabled( const char *, bool ) ) ); 00174 if ( m_extensionProxy->inherits( "KHTMLPartBrowserExtension" ) ) 00175 { 00176 connect( m_extensionProxy, SIGNAL( editableWidgetFocused() ), 00177 this, SLOT( extensionProxyEditableWidgetFocused() ) ); 00178 connect( m_extensionProxy, SIGNAL( editableWidgetBlurred() ), 00179 this, 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 QLineEdit* lineEdit = qobject_cast<QLineEdit *>( m_editableFormWidget ); 00205 if ( lineEdit && !lineEdit->isReadOnly() ) 00206 lineEdit->cut(); 00207 QTextEdit* textEdit = qobject_cast<QTextEdit *>( m_editableFormWidget ); 00208 if ( textEdit && !textEdit->isReadOnly() ) 00209 textEdit->cut(); 00210 } 00211 00212 void KHTMLPartBrowserExtension::copy() 00213 { 00214 if ( m_extensionProxy ) 00215 { 00216 callExtensionProxyMethod( "copy" ); 00217 return; 00218 } 00219 00220 if ( !m_editableFormWidget ) 00221 { 00222 // get selected text and paste to the clipboard 00223 QString text = m_part->selectedText(); 00224 text.replace( QChar( 0xa0 ), ' ' ); 00225 //kDebug(6050) << text; 00226 00227 QClipboard *cb = QApplication::clipboard(); 00228 disconnect( cb, SIGNAL( selectionChanged() ), m_part, SLOT( slotClearSelection() ) ); 00229 #ifndef QT_NO_MIMECLIPBOARD 00230 QString htmltext; 00231 /* 00232 * When selectionModeEnabled, that means the user has just selected 00233 * the text, not ctrl+c to copy it. The selection clipboard 00234 * doesn't seem to support mime type, so to save time, don't calculate 00235 * the selected text as html. 00236 * optomisation disabled for now until everything else works. 00237 */ 00238 //if(!cb->selectionModeEnabled()) 00239 htmltext = m_part->selectedTextAsHTML(); 00240 QMimeData *mimeData = new QMimeData; 00241 mimeData->setText(text); 00242 if(!htmltext.isEmpty()) { 00243 htmltext.replace( QChar( 0xa0 ), ' ' ); 00244 mimeData->setHtml(htmltext); 00245 } 00246 cb->setMimeData(mimeData); 00247 #else 00248 cb->setText(text); 00249 #endif 00250 00251 connect( cb, SIGNAL( selectionChanged() ), m_part, SLOT( slotClearSelection() ) ); 00252 } 00253 else 00254 { 00255 QLineEdit* lineEdit = qobject_cast<QLineEdit *>( m_editableFormWidget ); 00256 if ( lineEdit ) 00257 lineEdit->copy(); 00258 QTextEdit* textEdit = qobject_cast<QTextEdit *>( m_editableFormWidget ); 00259 if ( textEdit ) 00260 textEdit->copy(); 00261 } 00262 } 00263 00264 void KHTMLPartBrowserExtension::searchProvider() 00265 { 00266 KAction *action = qobject_cast<KAction*>(sender()); 00267 if (action) { 00268 KUrl url = action->data().toUrl(); 00269 if (url.host().isEmpty()) { 00270 KUriFilterData data(action->data().toString()); 00271 if (KUriFilter::self()->filterSearchUri(data, KUriFilter::WebShortcutFilter)) 00272 url = data.uri(); 00273 } 00274 00275 KParts::BrowserArguments browserArgs; 00276 browserArgs.frameName = "_blank"; 00277 emit m_part->browserExtension()->openUrlRequest( url, KParts::OpenUrlArguments(), browserArgs ); 00278 } 00279 } 00280 00281 void KHTMLPartBrowserExtension::paste() 00282 { 00283 if ( m_extensionProxy ) 00284 { 00285 callExtensionProxyMethod( "paste" ); 00286 return; 00287 } 00288 00289 if ( !m_editableFormWidget ) 00290 return; 00291 00292 QLineEdit* lineEdit = qobject_cast<QLineEdit *>( m_editableFormWidget ); 00293 if ( lineEdit && !lineEdit->isReadOnly() ) 00294 lineEdit->paste(); 00295 QTextEdit* textEdit = qobject_cast<QTextEdit *>( m_editableFormWidget ); 00296 if ( textEdit && !textEdit->isReadOnly() ) 00297 textEdit->paste(); 00298 } 00299 00300 void KHTMLPartBrowserExtension::callExtensionProxyMethod( const char *method ) 00301 { 00302 if ( !m_extensionProxy ) 00303 return; 00304 00305 QMetaObject::invokeMethod(m_extensionProxy, method, Qt::DirectConnection); 00306 } 00307 00308 void KHTMLPartBrowserExtension::updateEditActions() 00309 { 00310 if ( !m_editableFormWidget ) 00311 { 00312 enableAction( "cut", false ); 00313 enableAction( "copy", false ); 00314 enableAction( "paste", false ); 00315 return; 00316 } 00317 00318 // ### duplicated from KonqMainWindow::slotClipboardDataChanged 00319 #ifndef QT_NO_MIMECLIPBOARD // Handle minimalized versions of Qt Embedded 00320 const QMimeData *data = QApplication::clipboard()->mimeData(); 00321 enableAction( "paste", data->hasFormat( "text/plain" ) ); 00322 #else 00323 QString data=QApplication::clipboard()->text(); 00324 enableAction( "paste", data.contains("://")); 00325 #endif 00326 bool hasSelection = false; 00327 00328 if( m_editableFormWidget) { 00329 if ( qobject_cast<QLineEdit*>(m_editableFormWidget)) 00330 hasSelection = static_cast<QLineEdit *>( &(*m_editableFormWidget) )->hasSelectedText(); 00331 else if(qobject_cast<QTextEdit*>(m_editableFormWidget)) 00332 hasSelection = static_cast<QTextEdit *>( &(*m_editableFormWidget) )->textCursor().hasSelection(); 00333 } 00334 00335 enableAction( "copy", hasSelection ); 00336 enableAction( "cut", hasSelection ); 00337 } 00338 00339 void KHTMLPartBrowserExtension::extensionProxyEditableWidgetFocused() { 00340 editableWidgetFocused(); 00341 } 00342 00343 void KHTMLPartBrowserExtension::extensionProxyEditableWidgetBlurred() { 00344 editableWidgetBlurred(); 00345 } 00346 00347 void KHTMLPartBrowserExtension::extensionProxyActionEnabled( const char *action, bool enable ) 00348 { 00349 // only forward enableAction calls for actions we actually do forward 00350 if ( strcmp( action, "cut" ) == 0 || 00351 strcmp( action, "copy" ) == 0 || 00352 strcmp( action, "paste" ) == 0 ) { 00353 enableAction( action, enable ); 00354 } 00355 } 00356 00357 void KHTMLPartBrowserExtension::reparseConfiguration() 00358 { 00359 m_part->reparseConfiguration(); 00360 } 00361 00362 void KHTMLPartBrowserExtension::print() 00363 { 00364 m_part->view()->print(); 00365 } 00366 00367 void KHTMLPartBrowserExtension::disableScrolling() 00368 { 00369 QScrollArea *scrollArea = m_part->view(); 00370 if (scrollArea) { 00371 scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 00372 scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 00373 } 00374 } 00375 00376 class KHTMLPopupGUIClient::KHTMLPopupGUIClientPrivate 00377 { 00378 public: 00379 KHTMLPart *m_khtml; 00380 KUrl m_url; 00381 KUrl m_imageURL; 00382 QPixmap m_pixmap; 00383 QString m_suggestedFilename; 00384 KActionCollection* m_actionCollection; 00385 KParts::BrowserExtension::ActionGroupMap actionGroups; 00386 }; 00387 00388 00389 KHTMLPopupGUIClient::KHTMLPopupGUIClient( KHTMLPart *khtml, const KUrl &url ) 00390 : QObject( khtml ), d(new KHTMLPopupGUIClientPrivate) 00391 { 00392 d->m_khtml = khtml; 00393 d->m_url = url; 00394 d->m_actionCollection = new KActionCollection(this); 00395 bool isImage = false; 00396 bool hasSelection = khtml->hasSelection(); 00397 00398 DOM::Element e = khtml->nodeUnderMouse(); 00399 00400 if ( !e.isNull() && (e.elementId() == ID_IMG || 00401 (e.elementId() == ID_INPUT && !static_cast<DOM::HTMLInputElement>(e).src().isEmpty()))) 00402 { 00403 if (e.elementId() == ID_IMG) { 00404 DOM::HTMLImageElementImpl *ie = static_cast<DOM::HTMLImageElementImpl*>(e.handle()); 00405 khtml::RenderImage *ri = dynamic_cast<khtml::RenderImage*>(ie->renderer()); 00406 if (ri && ri->contentObject()) { 00407 d->m_suggestedFilename = static_cast<khtml::CachedImage*>(ri->contentObject())->suggestedFilename(); 00408 } 00409 } 00410 isImage=true; 00411 } 00412 00413 if (hasSelection) { 00414 QList<QAction *> editActions; 00415 QAction* copyAction = d->m_actionCollection->addAction( KStandardAction::Copy, "copy", 00416 d->m_khtml->browserExtension(), SLOT( copy() ) ); 00417 00418 copyAction->setText(i18n("&Copy Text")); 00419 copyAction->setEnabled(d->m_khtml->browserExtension()->isActionEnabled( "copy" )); 00420 editActions.append(copyAction); 00421 00422 editActions.append(khtml->actionCollection()->action("selectAll")); 00423 00424 addSearchActions(editActions); 00425 00426 QString selectedTextURL = selectedTextAsOneLine(d->m_khtml); 00427 if ( selectedTextURL.contains("://") && KUrl(selectedTextURL).isValid() ) { 00428 if (selectedTextURL.length() > 18) { 00429 selectedTextURL.truncate(15); 00430 selectedTextURL += "..."; 00431 } 00432 KAction *action = new KAction(i18n("Open '%1'", selectedTextURL), this); 00433 d->m_actionCollection->addAction( "openSelection", action ); 00434 action->setIcon( KIcon( "window-new" ) ); 00435 connect( action, SIGNAL(triggered(bool)), this, SLOT( openSelection() ) ); 00436 editActions.append(action); 00437 } 00438 00439 KAction* separator = new KAction(d->m_actionCollection); 00440 separator->setSeparator(true); 00441 editActions.append(separator); 00442 00443 d->actionGroups.insert("editactions", editActions); 00444 } 00445 00446 if (!url.isEmpty()) { 00447 QList<QAction *> linkActions; 00448 if (url.protocol() == "mailto") { 00449 KAction *action = new KAction( i18n( "&Copy Email Address" ), this ); 00450 d->m_actionCollection->addAction( "copylinklocation", action ); 00451 connect( action, SIGNAL(triggered(bool)), this, SLOT(slotCopyLinkLocation()) ); 00452 linkActions.append(action); 00453 } else { 00454 KAction *action = new KAction( i18n( "&Save Link As..." ), this ); 00455 d->m_actionCollection->addAction( "savelinkas", action ); 00456 connect( action, SIGNAL(triggered(bool)), this, SLOT(slotSaveLinkAs()) ); 00457 linkActions.append(action); 00458 00459 action = new KAction( i18n( "&Copy Link Address" ), this ); 00460 d->m_actionCollection->addAction( "copylinklocation", action ); 00461 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotCopyLinkLocation() ) ); 00462 linkActions.append(action); 00463 } 00464 d->actionGroups.insert("linkactions", linkActions); 00465 } 00466 00467 QList<QAction *> partActions; 00468 // frameset? -> add "Reload Frame" etc. 00469 if (!hasSelection) { 00470 if ( khtml->parentPart() ) { 00471 KActionMenu* menu = new KActionMenu( i18nc("@title:menu HTML frame/iframe", "Frame"), this); 00472 KAction *action = new KAction( i18n( "Open in New &Window" ), this ); 00473 d->m_actionCollection->addAction( "frameinwindow", action ); 00474 action->setIcon( KIcon( "window-new" ) ); 00475 connect( action, SIGNAL(triggered(bool)), this, SLOT(slotFrameInWindow()) ); 00476 menu->addAction(action); 00477 00478 action = new KAction( i18n( "Open in &This Window" ), this ); 00479 d->m_actionCollection->addAction( "frameintop", action ); 00480 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotFrameInTop() ) ); 00481 menu->addAction(action); 00482 00483 action = new KAction( i18n( "Open in &New Tab" ), this ); 00484 d->m_actionCollection->addAction( "frameintab", action ); 00485 action->setIcon( KIcon( "tab-new" ) ); 00486 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotFrameInTab() ) ); 00487 menu->addAction(action); 00488 00489 action = new KAction(d->m_actionCollection); 00490 action->setSeparator(true); 00491 menu->addAction(action); 00492 00493 action = new KAction( i18n( "Reload Frame" ), this ); 00494 d->m_actionCollection->addAction( "reloadframe", action ); 00495 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotReloadFrame() ) ); 00496 menu->addAction(action); 00497 00498 action = new KAction( i18n( "Print Frame..." ), this ); 00499 d->m_actionCollection->addAction( "printFrame", action ); 00500 action->setIcon( KIcon( "document-print-frame" ) ); 00501 connect( action, SIGNAL(triggered(bool)), d->m_khtml->browserExtension(), SLOT( print() ) ); 00502 menu->addAction(action); 00503 00504 action = new KAction( i18n( "Save &Frame As..." ), this ); 00505 d->m_actionCollection->addAction( "saveFrame", action ); 00506 connect( action, SIGNAL(triggered(bool)), d->m_khtml, SLOT( slotSaveFrame() ) ); 00507 menu->addAction(action); 00508 00509 action = new KAction( i18n( "View Frame Source" ), this ); 00510 d->m_actionCollection->addAction( "viewFrameSource", action ); 00511 connect( action, SIGNAL(triggered(bool)), d->m_khtml, SLOT( slotViewDocumentSource() ) ); 00512 menu->addAction(action); 00513 00514 action = new KAction( i18n( "View Frame Information" ), this ); 00515 d->m_actionCollection->addAction( "viewFrameInfo", action ); 00516 connect( action, SIGNAL(triggered(bool)), d->m_khtml, SLOT( slotViewPageInfo() ) ); 00517 00518 action = new KAction(d->m_actionCollection); 00519 action->setSeparator(true); 00520 menu->addAction(action); 00521 00522 if ( KHTMLGlobal::defaultHTMLSettings()->isAdFilterEnabled() ) { 00523 if ( khtml->d->m_frame->m_type == khtml::ChildFrame::IFrame ) { 00524 action = new KAction( i18n( "Block IFrame..." ), this ); 00525 d->m_actionCollection->addAction( "blockiframe", action ); 00526 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotBlockIFrame() ) ); 00527 menu->addAction(action); 00528 } 00529 } 00530 00531 partActions.append(menu); 00532 } 00533 } 00534 00535 if (isImage) { 00536 if ( e.elementId() == ID_IMG ) { 00537 d->m_imageURL = KUrl( static_cast<DOM::HTMLImageElement>( e ).src().string() ); 00538 DOM::HTMLImageElementImpl *imageimpl = static_cast<DOM::HTMLImageElementImpl *>( e.handle() ); 00539 Q_ASSERT(imageimpl); 00540 if(imageimpl) // should be true always. right? 00541 { 00542 if(imageimpl->complete()) { 00543 d->m_pixmap = imageimpl->currentPixmap(); 00544 } 00545 } 00546 } 00547 else 00548 d->m_imageURL = KUrl( static_cast<DOM::HTMLInputElement>( e ).src().string() ); 00549 KAction *action = new KAction( i18n( "Save Image As..." ), this ); 00550 d->m_actionCollection->addAction( "saveimageas", action ); 00551 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotSaveImageAs() ) ); 00552 partActions.append(action); 00553 00554 action = new KAction( i18n( "Send Image..." ), this ); 00555 d->m_actionCollection->addAction( "sendimage", action ); 00556 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotSendImage() ) ); 00557 partActions.append(action); 00558 00559 #ifndef QT_NO_MIMECLIPBOARD 00560 action = new KAction( i18n( "Copy Image" ), this ); 00561 d->m_actionCollection->addAction( "copyimage", action ); 00562 action->setEnabled(!d->m_pixmap.isNull()); 00563 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotCopyImage() ) ); 00564 partActions.append(action); 00565 #endif 00566 00567 if(d->m_pixmap.isNull()) { //fallback to image location if still loading the image. this will always be true if ifdef QT_NO_MIMECLIPBOARD 00568 action = new KAction( i18n( "Copy Image Location" ), this ); 00569 d->m_actionCollection->addAction( "copyimagelocation", action ); 00570 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotCopyImageLocation() ) ); 00571 partActions.append(action); 00572 } 00573 00574 QString actionText = d->m_suggestedFilename.isEmpty() ? 00575 KStringHandler::csqueeze(d->m_imageURL.fileName()+d->m_imageURL.query(), 25) 00576 : d->m_suggestedFilename; 00577 action = new KAction( i18n("View Image (%1)", actionText.replace("&", "&&")), this ); 00578 d->m_actionCollection->addAction( "viewimage", action ); 00579 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotViewImage() ) ); 00580 partActions.append(action); 00581 00582 if (KHTMLGlobal::defaultHTMLSettings()->isAdFilterEnabled()) { 00583 action = new KAction( i18n( "Block Image..." ), this ); 00584 d->m_actionCollection->addAction( "blockimage", action ); 00585 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotBlockImage() ) ); 00586 partActions.append(action); 00587 00588 if (!d->m_imageURL.host().isEmpty() && 00589 !d->m_imageURL.protocol().isEmpty()) 00590 { 00591 action = new KAction( i18n( "Block Images From %1" , d->m_imageURL.host()), this ); 00592 d->m_actionCollection->addAction( "blockhost", action ); 00593 connect( action, SIGNAL(triggered(bool)), this, SLOT( slotBlockHost() ) ); 00594 partActions.append(action); 00595 } 00596 } 00597 KAction* separator = new KAction(d->m_actionCollection); 00598 separator->setSeparator(true); 00599 partActions.append(separator); 00600 } 00601 00602 if ( isImage || url.isEmpty() ) { 00603 KAction *action = new KAction( i18n( "Stop Animations" ), this ); 00604 d->m_actionCollection->addAction( "stopanimations", action ); 00605 connect( action, SIGNAL(triggered(bool)), this, SLOT(slotStopAnimations()) ); 00606 partActions.append(action); 00607 KAction* separator = new KAction(d->m_actionCollection); 00608 separator->setSeparator(true); 00609 partActions.append(separator); 00610 } 00611 if (!hasSelection && url.isEmpty()) { // only when right-clicking on the page itself 00612 partActions.append(khtml->actionCollection()->action("viewDocumentSource")); 00613 } 00614 if (!hasSelection && url.isEmpty() && !isImage) { 00615 partActions.append(khtml->actionCollection()->action("setEncoding")); 00616 } 00617 d->actionGroups.insert("partactions", partActions); 00618 } 00619 00620 KHTMLPopupGUIClient::~KHTMLPopupGUIClient() 00621 { 00622 delete d->m_actionCollection; 00623 delete d; 00624 } 00625 00626 void KHTMLPopupGUIClient::addSearchActions(QList<QAction *>& editActions) 00627 { 00628 const QString selectedText = d->m_khtml->simplifiedSelectedText(); 00629 if (selectedText.isEmpty()) 00630 return; 00631 00632 KUriFilterData data(selectedText); 00633 QStringList alternateProviders; 00634 alternateProviders << "google" << "google_groups" << "google_news" << "webster" << "dmoz" << "wikipedia"; 00635 data.setAlternateSearchProviders(alternateProviders); 00636 data.setAlternateDefaultSearchProvider("google"); 00637 00638 if (KUriFilter::self()->filterSearchUri(data, KUriFilter::NormalTextFilter)) { 00639 const QString squeezedText = KStringHandler::rsqueeze(selectedText, 21); 00640 KAction *action = new KAction(i18n("Search for '%1' with %2", 00641 squeezedText, data.searchProvider()), this); 00642 action->setData(QUrl(data.uri())); 00643 action->setIcon(KIcon(data.iconName())); 00644 connect(action, SIGNAL(triggered(bool)), d->m_khtml->browserExtension(), SLOT(searchProvider())); 00645 d->m_actionCollection->addAction("defaultSearchProvider", action); 00646 editActions.append(action); 00647 00648 const QStringList preferredSearchProviders = data.preferredSearchProviders(); 00649 if (!preferredSearchProviders.isEmpty()) { 00650 KActionMenu* providerList = new KActionMenu(i18n("Search for '%1' with", squeezedText), this); 00651 Q_FOREACH(const QString &searchProvider, preferredSearchProviders) { 00652 if (searchProvider == data.searchProvider()) 00653 continue; 00654 KAction *action = new KAction(searchProvider, this); 00655 action->setData(data.queryForPreferredSearchProvider(searchProvider)); 00656 d->m_actionCollection->addAction(searchProvider, action); 00657 action->setIcon(KIcon(data.iconNameForPreferredSearchProvider(searchProvider))); 00658 connect(action, SIGNAL(triggered(bool)), d->m_khtml->browserExtension(), SLOT(searchProvider())); 00659 providerList->addAction(action); 00660 } 00661 d->m_actionCollection->addAction("searchProviderList", providerList); 00662 editActions.append(providerList); 00663 } 00664 } 00665 } 00666 00667 QString KHTMLPopupGUIClient::selectedTextAsOneLine(KHTMLPart* part) 00668 { 00669 QString text = part->simplifiedSelectedText(); 00670 // in addition to what simplifiedSelectedText does, 00671 // remove linefeeds and any whitespace surrounding it (#113177), 00672 // to get it all in a single line. 00673 text.remove(QRegExp("[\\s]*\\n+[\\s]*")); 00674 return text; 00675 } 00676 00677 void KHTMLPopupGUIClient::openSelection() 00678 { 00679 KParts::BrowserArguments browserArgs; 00680 browserArgs.frameName = "_blank"; 00681 00682 emit d->m_khtml->browserExtension()->openUrlRequest(selectedTextAsOneLine(d->m_khtml), KParts::OpenUrlArguments(), browserArgs); 00683 } 00684 00685 KParts::BrowserExtension::ActionGroupMap KHTMLPopupGUIClient::actionGroups() const 00686 { 00687 return d->actionGroups; 00688 } 00689 00690 void KHTMLPopupGUIClient::slotSaveLinkAs() 00691 { 00692 KIO::MetaData metaData; 00693 metaData["referrer"] = d->m_khtml->referrer(); 00694 saveURL( d->m_khtml->widget(), i18n( "Save Link As" ), d->m_url, metaData ); 00695 } 00696 00697 void KHTMLPopupGUIClient::slotSendImage() 00698 { 00699 QStringList urls; 00700 urls.append( d->m_imageURL.url()); 00701 QString subject = d->m_imageURL.url(); 00702 KToolInvocation::invokeMailer(QString(), QString(), QString(), subject, 00703 QString(), //body 00704 QString(), 00705 urls); // attachments 00706 00707 00708 } 00709 00710 void KHTMLPopupGUIClient::slotSaveImageAs() 00711 { 00712 KIO::MetaData metaData; 00713 metaData["referrer"] = d->m_khtml->referrer(); 00714 saveURL( d->m_khtml->widget(), i18n( "Save Image As" ), d->m_imageURL, metaData, QString(), 0, d->m_suggestedFilename ); 00715 } 00716 00717 void KHTMLPopupGUIClient::slotBlockHost() 00718 { 00719 QString name=d->m_imageURL.protocol()+"://"+d->m_imageURL.host()+"/*"; 00720 KHTMLGlobal::defaultHTMLSettings()->addAdFilter( name ); 00721 d->m_khtml->reparseConfiguration(); 00722 } 00723 00724 void KHTMLPopupGUIClient::slotBlockImage() 00725 { 00726 bool ok = false; 00727 00728 QString url = KInputDialog::getText( i18n("Add URL to Filter"), 00729 i18n("Enter the URL:"), 00730 d->m_imageURL.url(), 00731 &ok); 00732 if ( ok ) { 00733 KHTMLGlobal::defaultHTMLSettings()->addAdFilter( url ); 00734 d->m_khtml->reparseConfiguration(); 00735 } 00736 } 00737 00738 void KHTMLPopupGUIClient::slotBlockIFrame() 00739 { 00740 bool ok = false; 00741 QString url = KInputDialog::getText( i18n( "Add URL to Filter"), 00742 i18n("Enter the URL:"), 00743 d->m_khtml->url().url(), 00744 &ok ); 00745 if ( ok ) { 00746 KHTMLGlobal::defaultHTMLSettings()->addAdFilter( url ); 00747 d->m_khtml->reparseConfiguration(); 00748 } 00749 } 00750 00751 void KHTMLPopupGUIClient::slotCopyLinkLocation() 00752 { 00753 KUrl safeURL(d->m_url); 00754 safeURL.setPass(QString()); 00755 #ifndef QT_NO_MIMECLIPBOARD 00756 // Set it in both the mouse selection and in the clipboard 00757 QMimeData* mimeData = new QMimeData; 00758 safeURL.populateMimeData( mimeData ); 00759 QApplication::clipboard()->setMimeData( mimeData, QClipboard::Clipboard ); 00760 00761 mimeData = new QMimeData; 00762 safeURL.populateMimeData( mimeData ); 00763 QApplication::clipboard()->setMimeData( mimeData, QClipboard::Selection ); 00764 00765 #else 00766 QApplication::clipboard()->setText( safeURL.url() ); //FIXME(E): Handle multiple entries 00767 #endif 00768 } 00769 00770 void KHTMLPopupGUIClient::slotStopAnimations() 00771 { 00772 d->m_khtml->stopAnimations(); 00773 } 00774 00775 void KHTMLPopupGUIClient::slotCopyImage() 00776 { 00777 #ifndef QT_NO_MIMECLIPBOARD 00778 KUrl safeURL(d->m_imageURL); 00779 safeURL.setPass(QString()); 00780 00781 // Set it in both the mouse selection and in the clipboard 00782 QMimeData* mimeData = new QMimeData; 00783 mimeData->setImageData( d->m_pixmap ); 00784 safeURL.populateMimeData( mimeData ); 00785 QApplication::clipboard()->setMimeData( mimeData, QClipboard::Clipboard ); 00786 00787 mimeData = new QMimeData; 00788 mimeData->setImageData( d->m_pixmap ); 00789 safeURL.populateMimeData( mimeData ); 00790 QApplication::clipboard()->setMimeData( mimeData, QClipboard::Selection ); 00791 #else 00792 kDebug() << "slotCopyImage called when the clipboard does not support this. This should not be possible."; 00793 #endif 00794 } 00795 00796 void KHTMLPopupGUIClient::slotCopyImageLocation() 00797 { 00798 KUrl safeURL(d->m_imageURL); 00799 safeURL.setPass(QString()); 00800 #ifndef QT_NO_MIMECLIPBOARD 00801 // Set it in both the mouse selection and in the clipboard 00802 QMimeData* mimeData = new QMimeData; 00803 safeURL.populateMimeData( mimeData ); 00804 QApplication::clipboard()->setMimeData( mimeData, QClipboard::Clipboard ); 00805 mimeData = new QMimeData; 00806 safeURL.populateMimeData( mimeData ); 00807 QApplication::clipboard()->setMimeData( mimeData, QClipboard::Selection ); 00808 #else 00809 QApplication::clipboard()->setText( safeURL.url() ); //FIXME(E): Handle multiple entries 00810 #endif 00811 } 00812 00813 void KHTMLPopupGUIClient::slotViewImage() 00814 { 00815 d->m_khtml->browserExtension()->createNewWindow(d->m_imageURL); 00816 } 00817 00818 void KHTMLPopupGUIClient::slotReloadFrame() 00819 { 00820 KParts::OpenUrlArguments args = d->m_khtml->arguments(); 00821 args.setReload( true ); 00822 args.metaData()["referrer"] = d->m_khtml->pageReferrer(); 00823 // reload document 00824 d->m_khtml->closeUrl(); 00825 d->m_khtml->setArguments( args ); 00826 d->m_khtml->openUrl( d->m_khtml->url() ); 00827 } 00828 00829 void KHTMLPopupGUIClient::slotFrameInWindow() 00830 { 00831 KParts::OpenUrlArguments args = d->m_khtml->arguments(); 00832 args.metaData()["referrer"] = d->m_khtml->pageReferrer(); 00833 KParts::BrowserArguments browserArgs( d->m_khtml->browserExtension()->browserArguments() ); 00834 browserArgs.setForcesNewWindow(true); 00835 emit d->m_khtml->browserExtension()->createNewWindow( d->m_khtml->url(), args, browserArgs ); 00836 } 00837 00838 void KHTMLPopupGUIClient::slotFrameInTop() 00839 { 00840 KParts::OpenUrlArguments args = d->m_khtml->arguments(); 00841 args.metaData()["referrer"] = d->m_khtml->pageReferrer(); 00842 KParts::BrowserArguments browserArgs( d->m_khtml->browserExtension()->browserArguments() ); 00843 browserArgs.frameName = "_top"; 00844 emit d->m_khtml->browserExtension()->openUrlRequest( d->m_khtml->url(), args, browserArgs ); 00845 } 00846 00847 void KHTMLPopupGUIClient::slotFrameInTab() 00848 { 00849 KParts::OpenUrlArguments args = d->m_khtml->arguments(); 00850 args.metaData()["referrer"] = d->m_khtml->pageReferrer(); 00851 KParts::BrowserArguments browserArgs( d->m_khtml->browserExtension()->browserArguments() ); 00852 browserArgs.setNewTab(true); 00853 emit d->m_khtml->browserExtension()->createNewWindow( d->m_khtml->url(), args, browserArgs ); 00854 } 00855 00856 void KHTMLPopupGUIClient::saveURL( QWidget *parent, const QString &caption, 00857 const KUrl &url, 00858 const QMap<QString, QString> &metadata, 00859 const QString &filter, long cacheId, 00860 const QString & suggestedFilename ) 00861 { 00862 QString name = QLatin1String( "index.html" ); 00863 if ( !suggestedFilename.isEmpty() ) 00864 name = suggestedFilename; 00865 else if ( !url.fileName(KUrl::ObeyTrailingSlash).isEmpty() ) 00866 name = url.fileName(KUrl::ObeyTrailingSlash); 00867 00868 KUrl destURL; 00869 int query; 00870 do { 00871 query = KMessageBox::Yes; 00872 // convert filename to URL using fromPath to avoid trouble with ':' in filenames (#184202) 00873 destURL = KFileDialog::getSaveUrl( KUrl::fromPath(name), filter, parent, caption ); 00874 if( destURL.isLocalFile() ) 00875 { 00876 QFileInfo info( destURL.toLocalFile() ); 00877 if( info.exists() ) { 00878 // TODO: use KIO::RenameDlg (shows more information) 00879 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" )) ); 00880 } 00881 } 00882 } while ( query == KMessageBox::Cancel ); 00883 00884 if ( destURL.isValid() ) 00885 saveURL(parent, url, destURL, metadata, cacheId); 00886 } 00887 00888 void KHTMLPopupGUIClient::saveURL( QWidget* parent, const KUrl &url, const KUrl &destURL, 00889 const QMap<QString, QString> &metadata, 00890 long cacheId ) 00891 { 00892 if ( destURL.isValid() ) 00893 { 00894 bool saved = false; 00895 if (KHTMLPageCache::self()->isComplete(cacheId)) 00896 { 00897 if (destURL.isLocalFile()) 00898 { 00899 KSaveFile destFile(destURL.toLocalFile()); 00900 if (destFile.open()) 00901 { 00902 QDataStream stream ( &destFile ); 00903 KHTMLPageCache::self()->saveData(cacheId, &stream); 00904 saved = true; 00905 } 00906 } 00907 else 00908 { 00909 // save to temp file, then move to final destination. 00910 KTemporaryFile destFile; 00911 if (destFile.open()) 00912 { 00913 QDataStream stream ( &destFile ); 00914 KHTMLPageCache::self()->saveData(cacheId, &stream); 00915 KUrl url2 = KUrl(); 00916 url2.setPath(destFile.fileName()); 00917 KIO::file_move(url2, destURL, -1, KIO::Overwrite); 00918 saved = true; 00919 } 00920 } 00921 } 00922 if(!saved) 00923 { 00924 // DownloadManager <-> konqueror integration 00925 // find if the integration is enabled 00926 // the empty key means no integration 00927 // only use download manager for non-local urls! 00928 bool downloadViaKIO = true; 00929 if ( !url.isLocalFile() ) 00930 { 00931 KConfigGroup cfg = KSharedConfig::openConfig("konquerorrc", KConfig::NoGlobals)->group("HTML Settings"); 00932 QString downloadManger = cfg.readPathEntry("DownloadManager", QString()); 00933 if (!downloadManger.isEmpty()) 00934 { 00935 // then find the download manager location 00936 kDebug(1000) << "Using: "<<downloadManger <<" as Download Manager"; 00937 QString cmd = KStandardDirs::findExe(downloadManger); 00938 if (cmd.isEmpty()) 00939 { 00940 QString errMsg=i18n("The Download Manager (%1) could not be found in your $PATH ", downloadManger); 00941 QString errMsgEx= i18n("Try to reinstall it \n\nThe integration with Konqueror will be disabled."); 00942 KMessageBox::detailedSorry(0,errMsg,errMsgEx); 00943 cfg.writePathEntry("DownloadManager",QString()); 00944 cfg.sync (); 00945 } 00946 else 00947 { 00948 downloadViaKIO = false; 00949 KUrl cleanDest = destURL; 00950 cleanDest.setPass( QString() ); // don't put password into commandline 00951 cmd += ' ' + KShell::quoteArg(url.url()) + ' ' + 00952 KShell::quoteArg(cleanDest.url()); 00953 kDebug(1000) << "Calling command "<<cmd; 00954 KRun::runCommand(cmd, parent->topLevelWidget()); 00955 } 00956 } 00957 } 00958 00959 if ( downloadViaKIO ) 00960 { 00961 KParts::BrowserRun::saveUrlUsingKIO(url, destURL, parent, metadata); 00962 } 00963 } //end if(!saved) 00964 } 00965 } 00966 00967 KHTMLPartBrowserHostExtension::KHTMLPartBrowserHostExtension( KHTMLPart *part ) 00968 : KParts::BrowserHostExtension( part ) 00969 { 00970 m_part = part; 00971 } 00972 00973 KHTMLPartBrowserHostExtension::~KHTMLPartBrowserHostExtension() 00974 { 00975 } 00976 00977 QStringList KHTMLPartBrowserHostExtension::frameNames() const 00978 { 00979 return m_part->frameNames(); 00980 } 00981 00982 const QList<KParts::ReadOnlyPart*> KHTMLPartBrowserHostExtension::frames() const 00983 { 00984 return m_part->frames(); 00985 } 00986 00987 bool KHTMLPartBrowserHostExtension::openUrlInFrame(const KUrl &url, const KParts::OpenUrlArguments& arguments, const KParts::BrowserArguments &browserArguments) 00988 { 00989 return m_part->openUrlInFrame( url, arguments, browserArguments ); 00990 } 00991 00992 KParts::BrowserHostExtension* KHTMLPartBrowserHostExtension::findFrameParent( KParts::ReadOnlyPart 00993 *callingPart, const QString &frame ) 00994 { 00995 KHTMLPart *parentPart = m_part->d->findFrameParent(callingPart, frame, 0, true /* navigation*/); 00996 if (parentPart) 00997 return parentPart->browserHostExtension(); 00998 return 0; 00999 } 01000 01001 01002 // defined in khtml_part.cpp 01003 extern const int KDE_NO_EXPORT fastZoomSizes[]; 01004 extern const int KDE_NO_EXPORT fastZoomSizeCount; 01005 01006 KHTMLZoomFactorAction::KHTMLZoomFactorAction( KHTMLPart *part, bool direction, const QString &icon, const QString &text, QObject *parent ) 01007 : KSelectAction( text, parent ) 01008 { 01009 setIcon( KIcon( icon ) ); 01010 01011 setToolBarMode(MenuMode); 01012 setToolButtonPopupMode(QToolButton::DelayedPopup); 01013 01014 init(part, direction); 01015 } 01016 01017 void KHTMLZoomFactorAction::init(KHTMLPart *part, bool direction) 01018 { 01019 m_direction = direction; 01020 m_part = part; 01021 01022 // xgettext: no-c-format 01023 addAction( i18n( "Default Font Size (100%)" ) ); 01024 01025 int m = m_direction ? 1 : -1; 01026 int ofs = fastZoomSizeCount / 2; // take index of 100% 01027 01028 // this only works if there is an odd number of elements in fastZoomSizes[] 01029 for ( int i = m; i != m*(ofs+1); i += m ) 01030 { 01031 int num = i * m; 01032 QString numStr = QString::number( num ); 01033 if ( num > 0 ) numStr.prepend( QLatin1Char('+') ); 01034 01035 // xgettext: no-c-format 01036 addAction( i18n( "%1%" , fastZoomSizes[ofs + i] ) ); 01037 } 01038 01039 connect( selectableActionGroup(), SIGNAL( triggered(QAction*) ), this, SLOT( slotTriggered(QAction*) ) ); 01040 } 01041 01042 KHTMLZoomFactorAction::~KHTMLZoomFactorAction() 01043 { 01044 } 01045 01046 void KHTMLZoomFactorAction::slotTriggered(QAction* action) 01047 { 01048 int idx = selectableActionGroup()->actions().indexOf(action); 01049 01050 if (idx == 0) 01051 m_part->setFontScaleFactor(100); 01052 else 01053 m_part->setFontScaleFactor(fastZoomSizes[fastZoomSizeCount/2 + (m_direction ? 1 : -1)*idx]); 01054 setCurrentAction( 0L ); 01055 } 01056 01057 KHTMLTextExtension::KHTMLTextExtension(KHTMLPart* part) 01058 : KParts::TextExtension(part) 01059 { 01060 connect(part, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged())); 01061 } 01062 01063 KHTMLPart* KHTMLTextExtension::part() const 01064 { 01065 return static_cast<KHTMLPart*>(parent()); 01066 } 01067 01068 bool KHTMLTextExtension::hasSelection() const 01069 { 01070 return part()->hasSelection(); 01071 } 01072 01073 QString KHTMLTextExtension::selectedText(Format format) const 01074 { 01075 switch(format) { 01076 case PlainText: 01077 return part()->selectedText(); 01078 case HTML: 01079 return part()->selectedTextAsHTML(); 01080 } 01081 return QString(); 01082 } 01083 01084 QString KHTMLTextExtension::completeText(Format format) const 01085 { 01086 switch(format) { 01087 case PlainText: 01088 return part()->htmlDocument().body().innerText().string(); 01089 case HTML: 01090 return part()->htmlDocument().body().innerHTML().string(); 01091 } 01092 return QString(); 01093 } 01094 01096 01097 KHTMLHtmlExtension::KHTMLHtmlExtension(KHTMLPart* part) 01098 : KParts::HtmlExtension(part) 01099 { 01100 } 01101 01102 KUrl KHTMLHtmlExtension::baseUrl() const 01103 { 01104 return part()->baseURL(); 01105 } 01106 01107 bool KHTMLHtmlExtension::hasSelection() const 01108 { 01109 return part()->hasSelection(); 01110 } 01111 01112 KParts::SelectorInterface::QueryMethods KHTMLHtmlExtension::supportedQueryMethods() const 01113 { 01114 return (KParts::SelectorInterface::SelectedContent | KParts::SelectorInterface::EntireContent); 01115 } 01116 01117 static KParts::SelectorInterface::Element convertDomElement(const DOM::ElementImpl* domElem) 01118 { 01119 KParts::SelectorInterface::Element elem; 01120 elem.setTagName(domElem->tagName().string()); 01121 const DOM::NamedAttrMapImpl* attrMap = domElem->attributes(true /*readonly*/); 01122 if (attrMap) { 01123 for (unsigned i = 0; i < attrMap->length(); ++i) { 01124 const DOM::AttributeImpl& attr = attrMap->attributeAt(i); 01125 elem.setAttribute(attr.localName().string(), attr.value().string()); 01126 // we could have a setAttributeNS too. 01127 } 01128 } 01129 return elem; 01130 } 01131 01132 KParts::SelectorInterface::Element KHTMLHtmlExtension::querySelector(const QString& query, KParts::SelectorInterface::QueryMethod method) const 01133 { 01134 KParts::SelectorInterface::Element element; 01135 01136 // If the specified method is None, return an empty list; similarly 01137 // if the document is null, which may be possible in case of an error 01138 if (method == KParts::SelectorInterface::None || part()->document().isNull()) 01139 return element; 01140 01141 if (!(supportedQueryMethods() & method)) 01142 return element; 01143 01144 switch (method) { 01145 case KParts::SelectorInterface::EntireContent: { 01146 int ec = 0; // exceptions are ignored 01147 WTF::RefPtr<DOM::ElementImpl> domElem = part()->document().handle()->querySelector(query, ec); 01148 element = convertDomElement(domElem.get()); 01149 break; 01150 } 01151 case KParts::SelectorInterface::SelectedContent: 01152 if (part()->hasSelection()) { 01153 DOM::Element domElem = part()->selection().cloneContents().querySelector(query); 01154 element = convertDomElement(static_cast<DOM::ElementImpl*>(domElem.handle())); 01155 } 01156 break; 01157 default: 01158 break; 01159 } 01160 01161 return element; 01162 } 01163 01164 QList<KParts::SelectorInterface::Element> KHTMLHtmlExtension::querySelectorAll(const QString& query, KParts::SelectorInterface::QueryMethod method) const 01165 { 01166 QList<KParts::SelectorInterface::Element> elements; 01167 01168 // If the specified method is None, return an empty list; similarly 01169 // if the document is null, which may be possible in case of an error 01170 if (method == KParts::SelectorInterface::None || part()->document().isNull()) 01171 return elements; 01172 01173 // If the specified method is not supported, return an empty list... 01174 if (!(supportedQueryMethods() & method)) 01175 return elements; 01176 01177 switch (method) { 01178 case KParts::SelectorInterface::EntireContent: { 01179 int ec = 0; // exceptions are ignored 01180 WTF::RefPtr<DOM::NodeListImpl> nodes = part()->document().handle()->querySelectorAll(query, ec); 01181 const unsigned long len = nodes->length(); 01182 elements.reserve(len); 01183 for (unsigned long i = 0; i < len; ++i) { 01184 DOM::NodeImpl* node = nodes->item(i); 01185 if (node->isElementNode()) { // should be always true 01186 elements.append(convertDomElement(static_cast<DOM::ElementImpl*>(node))); 01187 } 01188 } 01189 break; 01190 } 01191 case KParts::SelectorInterface::SelectedContent: 01192 if (part()->hasSelection()) { 01193 DOM::NodeList nodes = part()->selection().cloneContents().querySelectorAll(query); 01194 const unsigned long len = nodes.length(); 01195 for (unsigned long i = 0; i < len; ++i) { 01196 DOM::NodeImpl* node = nodes.item(i).handle(); 01197 if (node->isElementNode()) 01198 elements.append(convertDomElement(static_cast<DOM::ElementImpl*>(node))); 01199 } 01200 } 01201 break; 01202 default: 01203 break; 01204 } 01205 01206 return elements; 01207 } 01208 01209 KHTMLPart* KHTMLHtmlExtension::part() const 01210 { 01211 return static_cast<KHTMLPart*>(parent()); 01212 } 01213 01214 #include "khtml_ext.moc"
KDE 4.6 API Reference