30 #include "rendering/render_form.h"
31 #include "rendering/render_image.h"
32 #include "html/html_imageimpl.h"
33 #include "misc/loader.h"
39 #include "xml/dom_elementimpl.h"
40 #include <QtGui/QClipboard>
41 #include <QtCore/QFileInfo>
42 #include <QtGui/QMenu>
43 #include <QtCore/QUrl>
44 #include <QtCore/QMetaEnum>
74 : KParts::BrowserExtension( parent )
83 m_connectedToClipboard =
false;
110 m_editableFormWidget = widget;
113 if ( !m_connectedToClipboard && m_editableFormWidget )
115 connect( QApplication::clipboard(), SIGNAL(dataChanged()),
118 if ( m_editableFormWidget->inherits(
"QLineEdit" ) || m_editableFormWidget->inherits(
"QTextEdit" ) )
119 connect( m_editableFormWidget, SIGNAL(selectionChanged()),
122 m_connectedToClipboard =
true;
129 QWidget *oldWidget = m_editableFormWidget;
131 m_editableFormWidget = 0;
134 m_part->emitSelectionChanged();
136 if ( m_connectedToClipboard )
138 disconnect( QApplication::clipboard(), SIGNAL(dataChanged()),
143 if ( oldWidget->inherits(
"QLineEdit" ) || oldWidget->inherits(
"QTextEdit" ) )
144 disconnect( oldWidget, SIGNAL(selectionChanged()),
148 m_connectedToClipboard =
false;
155 if ( m_extensionProxy )
157 disconnect( m_extensionProxy, SIGNAL(
enableAction(
const char*,
bool)),
158 this, SLOT(extensionProxyActionEnabled(
const char*,
bool)) );
159 if ( m_extensionProxy->inherits(
"KHTMLPartBrowserExtension" ) )
162 this, SLOT(extensionProxyEditableWidgetFocused()) );
164 this, SLOT(extensionProxyEditableWidgetBlurred()) );
168 m_extensionProxy = proxy;
170 if ( m_extensionProxy )
172 connect( m_extensionProxy, SIGNAL(
enableAction(
const char*,
bool)),
173 this, SLOT(extensionProxyActionEnabled(
const char*,
bool)) );
174 if ( m_extensionProxy->inherits(
"KHTMLPartBrowserExtension" ) )
177 this, SLOT(extensionProxyEditableWidgetFocused()) );
179 this, SLOT(extensionProxyEditableWidgetBlurred()) );
182 enableAction(
"cut", m_extensionProxy->isActionEnabled(
"cut" ) );
183 enableAction(
"copy", m_extensionProxy->isActionEnabled(
"copy" ) );
184 enableAction(
"paste", m_extensionProxy->isActionEnabled(
"paste" ) );
195 if ( m_extensionProxy )
197 callExtensionProxyMethod(
"cut" );
201 if ( !m_editableFormWidget )
205 if ( lineEdit && !lineEdit->isReadOnly() )
208 if ( textEdit && !textEdit->isReadOnly() )
214 if ( m_extensionProxy )
216 callExtensionProxyMethod(
"copy" );
220 if ( !m_editableFormWidget )
224 text.replace( QChar( 0xa0 ),
' ' );
227 QClipboard *cb = QApplication::clipboard();
228 disconnect( cb, SIGNAL(selectionChanged()), m_part, SLOT(slotClearSelection()) );
229 #ifndef QT_NO_MIMECLIPBOARD
240 QMimeData *mimeData =
new QMimeData;
241 mimeData->setText(text);
242 if(!htmltext.isEmpty()) {
243 htmltext.replace( QChar( 0xa0 ),
' ' );
244 mimeData->setHtml(htmltext);
246 cb->setMimeData(mimeData);
251 connect( cb, SIGNAL(selectionChanged()), m_part, SLOT(slotClearSelection()) );
268 KUrl url = action->data().toUrl();
269 if (url.host().isEmpty()) {
283 if ( m_extensionProxy )
285 callExtensionProxyMethod(
"paste" );
289 if ( !m_editableFormWidget )
293 if ( lineEdit && !lineEdit->isReadOnly() )
296 if ( textEdit && !textEdit->isReadOnly() )
300 void KHTMLPartBrowserExtension::callExtensionProxyMethod(
const char *method )
302 if ( !m_extensionProxy )
305 QMetaObject::invokeMethod(m_extensionProxy, method, Qt::DirectConnection);
310 if ( !m_editableFormWidget )
319 #ifndef QT_NO_MIMECLIPBOARD // Handle minimalized versions of Qt Embedded
320 const QMimeData *data = QApplication::clipboard()->mimeData();
321 enableAction(
"paste", data->hasFormat(
"text/plain" ) );
323 QString data=QApplication::clipboard()->text();
326 bool hasSelection =
false;
328 if( m_editableFormWidget) {
329 if ( qobject_cast<QLineEdit*>(m_editableFormWidget))
330 hasSelection = static_cast<QLineEdit *>( &(*m_editableFormWidget) )->hasSelectedText();
331 else if(qobject_cast<QTextEdit*>(m_editableFormWidget))
332 hasSelection = static_cast<QTextEdit *>( &(*m_editableFormWidget) )->textCursor().hasSelection();
339 void KHTMLPartBrowserExtension::extensionProxyEditableWidgetFocused() {
343 void KHTMLPartBrowserExtension::extensionProxyEditableWidgetBlurred() {
347 void KHTMLPartBrowserExtension::extensionProxyActionEnabled(
const char *action,
bool enable )
350 if (
strcmp( action,
"cut" ) == 0 ||
351 strcmp( action,
"copy" ) == 0 ||
352 strcmp( action,
"paste" ) == 0 ) {
359 m_part->reparseConfiguration();
371 scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
372 scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
376 class KHTMLPopupGUIClient::KHTMLPopupGUIClientPrivate
390 :
QObject( khtml ),
d(new KHTMLPopupGUIClientPrivate)
395 bool isImage =
false;
404 DOM::HTMLImageElementImpl *ie =
static_cast<DOM::HTMLImageElementImpl*
>(e.
handle());
405 khtml::RenderImage *ri =
dynamic_cast<khtml::RenderImage*
>(ie->renderer());
406 if (ri && ri->contentObject()) {
407 d->m_suggestedFilename =
static_cast<khtml::CachedImage*
>(ri->contentObject())->suggestedFilename();
416 d->m_khtml->browserExtension(), SLOT(
copy()) );
418 copyAction->setText(
i18n(
"&Copy Text"));
419 copyAction->setEnabled(d->m_khtml->browserExtension()->isActionEnabled(
"copy" ));
420 editActions.append(copyAction);
424 addSearchActions(editActions);
427 if ( selectedTextURL.contains(
"://") &&
KUrl(selectedTextURL).isValid() ) {
428 if (selectedTextURL.length() > 18) {
429 selectedTextURL.truncate(15);
430 selectedTextURL +=
"...";
433 d->m_actionCollection->addAction(
"openSelection", action );
434 action->setIcon(
KIcon(
"window-new" ) );
435 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(openSelection()) );
436 editActions.append(action);
440 separator->setSeparator(
true);
441 editActions.append(separator);
443 d->actionGroups.insert(
"editactions", editActions);
446 if (!url.isEmpty()) {
450 d->m_actionCollection->addAction(
"copylinklocation", action );
451 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotCopyLinkLocation()) );
452 linkActions.append(action);
455 d->m_actionCollection->addAction(
"savelinkas", action );
456 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotSaveLinkAs()) );
457 linkActions.append(action);
459 action =
new KAction(
i18n(
"&Copy Link Address" ),
this );
460 d->m_actionCollection->addAction(
"copylinklocation", action );
461 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotCopyLinkLocation()) );
462 linkActions.append(action);
464 d->actionGroups.insert(
"linkactions", linkActions);
473 d->m_actionCollection->addAction(
"frameinwindow", action );
474 action->setIcon(
KIcon(
"window-new" ) );
475 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotFrameInWindow()) );
478 action =
new KAction(
i18n(
"Open in &This Window" ),
this );
479 d->m_actionCollection->addAction(
"frameintop", action );
480 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotFrameInTop()) );
483 action =
new KAction(
i18n(
"Open in &New Tab" ),
this );
484 d->m_actionCollection->addAction(
"frameintab", action );
485 action->setIcon(
KIcon(
"tab-new" ) );
486 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotFrameInTab()) );
489 action =
new KAction(d->m_actionCollection);
490 action->setSeparator(
true);
493 action =
new KAction(
i18n(
"Reload Frame" ),
this );
494 d->m_actionCollection->addAction(
"reloadframe", action );
495 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotReloadFrame()) );
498 action =
new KAction(
i18n(
"Print Frame..." ),
this );
499 d->m_actionCollection->addAction(
"printFrame", action );
500 action->setIcon(
KIcon(
"document-print-frame" ) );
501 connect( action, SIGNAL(triggered(
bool)), d->m_khtml->browserExtension(), SLOT(
print()) );
504 action =
new KAction(
i18n(
"Save &Frame As..." ),
this );
505 d->m_actionCollection->addAction(
"saveFrame", action );
506 connect( action, SIGNAL(triggered(
bool)), d->m_khtml, SLOT(slotSaveFrame()) );
509 action =
new KAction(
i18n(
"View Frame Source" ),
this );
510 d->m_actionCollection->addAction(
"viewFrameSource", action );
511 connect( action, SIGNAL(triggered(
bool)), d->m_khtml, SLOT(slotViewDocumentSource()) );
514 action =
new KAction(
i18n(
"View Frame Information" ),
this );
515 d->m_actionCollection->addAction(
"viewFrameInfo", action );
516 connect( action, SIGNAL(triggered(
bool)), d->m_khtml, SLOT(slotViewPageInfo()) );
518 action =
new KAction(d->m_actionCollection);
519 action->setSeparator(
true);
524 action =
new KAction(
i18n(
"Block IFrame..." ),
this );
525 d->m_actionCollection->addAction(
"blockiframe", action );
526 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotBlockIFrame()) );
531 partActions.append(menu);
537 d->m_imageURL =
KUrl( static_cast<DOM::HTMLImageElement>( e ).src().
string() );
538 DOM::HTMLImageElementImpl *imageimpl =
static_cast<DOM::HTMLImageElementImpl *
>( e.
handle() );
542 if(imageimpl->complete()) {
543 d->m_pixmap = imageimpl->currentPixmap();
548 d->m_imageURL =
KUrl( static_cast<DOM::HTMLInputElement>( e ).src().
string() );
550 d->m_actionCollection->addAction(
"saveimageas", action );
551 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotSaveImageAs()) );
552 partActions.append(action);
554 action =
new KAction(
i18n(
"Send Image..." ),
this );
555 d->m_actionCollection->addAction(
"sendimage", action );
556 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotSendImage()) );
557 partActions.append(action);
559 #ifndef QT_NO_MIMECLIPBOARD
560 action =
new KAction(
i18n(
"Copy Image" ),
this );
561 d->m_actionCollection->addAction(
"copyimage", action );
562 action->setEnabled(!d->m_pixmap.isNull());
563 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotCopyImage()) );
564 partActions.append(action);
567 if(d->m_pixmap.isNull()) {
568 action =
new KAction(
i18n(
"Copy Image Location" ),
this );
569 d->m_actionCollection->addAction(
"copyimagelocation", action );
570 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotCopyImageLocation()) );
571 partActions.append(action);
574 QString actionText = d->m_suggestedFilename.isEmpty() ?
576 : d->m_suggestedFilename;
577 action =
new KAction(
i18n(
"View Image (%1)", actionText.replace(
"&",
"&&")),
this );
578 d->m_actionCollection->addAction(
"viewimage", action );
579 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotViewImage()) );
580 partActions.append(action);
583 action =
new KAction(
i18n(
"Block Image..." ),
this );
584 d->m_actionCollection->addAction(
"blockimage", action );
585 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotBlockImage()) );
586 partActions.append(action);
588 if (!d->m_imageURL.host().isEmpty() &&
589 !d->m_imageURL.protocol().isEmpty())
591 action =
new KAction(
i18n(
"Block Images From %1" , d->m_imageURL.host()),
this );
592 d->m_actionCollection->addAction(
"blockhost", action );
593 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotBlockHost()) );
594 partActions.append(action);
598 separator->setSeparator(
true);
599 partActions.append(separator);
602 if ( isImage || url.isEmpty() ) {
604 d->m_actionCollection->addAction(
"stopanimations", action );
605 connect( action, SIGNAL(triggered(
bool)),
this, SLOT(slotStopAnimations()) );
606 partActions.append(action);
608 separator->setSeparator(
true);
609 partActions.append(separator);
611 if (!hasSelection && url.isEmpty()) {
614 if (!hasSelection && url.isEmpty() && !isImage) {
617 d->actionGroups.insert(
"partactions", partActions);
622 delete d->m_actionCollection;
628 const QString selectedText = d->m_khtml->simplifiedSelectedText();
629 if (selectedText.isEmpty())
634 alternateProviders <<
"google" <<
"google_groups" <<
"google_news" <<
"webster" <<
"dmoz" <<
"wikipedia";
635 data.setAlternateSearchProviders(alternateProviders);
636 data.setAlternateDefaultSearchProvider(
"google");
641 squeezedText, data.searchProvider()),
this);
642 action->setData(
QUrl(data.uri()));
643 action->setIcon(
KIcon(data.iconName()));
644 connect(action, SIGNAL(triggered(
bool)), d->m_khtml->browserExtension(), SLOT(searchProvider()));
645 d->m_actionCollection->addAction(
"defaultSearchProvider", action);
646 editActions.append(action);
648 const QStringList preferredSearchProviders = data.preferredSearchProviders();
649 if (!preferredSearchProviders.isEmpty()) {
651 Q_FOREACH(
const QString &searchProvider, preferredSearchProviders) {
652 if (searchProvider == data.searchProvider())
655 action->setData(data.queryForPreferredSearchProvider(searchProvider));
656 d->m_actionCollection->addAction(searchProvider, action);
657 action->setIcon(
KIcon(data.iconNameForPreferredSearchProvider(searchProvider)));
658 connect(action, SIGNAL(triggered(
bool)), d->m_khtml->browserExtension(), SLOT(searchProvider()));
661 d->m_actionCollection->addAction(
"searchProviderList", providerList);
662 editActions.append(providerList);
669 QString text = part->simplifiedSelectedText();
673 text.remove(QRegExp(
"[\\s]*\\n+[\\s]*"));
677 void KHTMLPopupGUIClient::openSelection()
687 return d->actionGroups;
690 void KHTMLPopupGUIClient::slotSaveLinkAs()
693 metaData[
"referrer"] = d->m_khtml->referrer();
694 saveURL( d->m_khtml->widget(),
i18n(
"Save Link As" ), d->m_url, metaData );
697 void KHTMLPopupGUIClient::slotSendImage()
700 urls.append( d->m_imageURL.url());
701 QString subject = d->m_imageURL.url();
710 void KHTMLPopupGUIClient::slotSaveImageAs()
713 metaData[
"referrer"] = d->m_khtml->referrer();
714 saveURL( d->m_khtml->widget(),
i18n(
"Save Image As" ), d->m_imageURL, metaData,
QString(), 0, d->m_suggestedFilename );
717 void KHTMLPopupGUIClient::slotBlockHost()
719 QString name=d->m_imageURL.protocol()+
"://"+d->m_imageURL.host()+
"/*";
721 d->m_khtml->reparseConfiguration();
724 void KHTMLPopupGUIClient::slotBlockImage()
729 i18n(
"Enter the URL:"),
734 d->m_khtml->reparseConfiguration();
738 void KHTMLPopupGUIClient::slotBlockIFrame()
742 i18n(
"Enter the URL:"),
743 d->m_khtml->url().url(),
747 d->m_khtml->reparseConfiguration();
751 void KHTMLPopupGUIClient::slotCopyLinkLocation()
753 KUrl safeURL(d->m_url);
755 #ifndef QT_NO_MIMECLIPBOARD
757 QMimeData* mimeData =
new QMimeData;
758 safeURL.populateMimeData( mimeData );
759 QApplication::clipboard()->setMimeData( mimeData, QClipboard::Clipboard );
761 mimeData =
new QMimeData;
762 safeURL.populateMimeData( mimeData );
763 QApplication::clipboard()->setMimeData( mimeData, QClipboard::Selection );
766 QApplication::clipboard()->setText( safeURL.url() );
770 void KHTMLPopupGUIClient::slotStopAnimations()
772 d->m_khtml->stopAnimations();
775 void KHTMLPopupGUIClient::slotCopyImage()
777 #ifndef QT_NO_MIMECLIPBOARD
778 KUrl safeURL(d->m_imageURL);
782 QMimeData* mimeData =
new QMimeData;
783 mimeData->setImageData( d->m_pixmap );
784 safeURL.populateMimeData( mimeData );
785 QApplication::clipboard()->setMimeData( mimeData, QClipboard::Clipboard );
787 mimeData =
new QMimeData;
788 mimeData->setImageData( d->m_pixmap );
789 safeURL.populateMimeData( mimeData );
790 QApplication::clipboard()->setMimeData( mimeData, QClipboard::Selection );
792 kDebug() <<
"slotCopyImage called when the clipboard does not support this. This should not be possible.";
796 void KHTMLPopupGUIClient::slotCopyImageLocation()
798 KUrl safeURL(d->m_imageURL);
800 #ifndef QT_NO_MIMECLIPBOARD
802 QMimeData* mimeData =
new QMimeData;
803 safeURL.populateMimeData( mimeData );
804 QApplication::clipboard()->setMimeData( mimeData, QClipboard::Clipboard );
805 mimeData =
new QMimeData;
806 safeURL.populateMimeData( mimeData );
807 QApplication::clipboard()->setMimeData( mimeData, QClipboard::Selection );
809 QApplication::clipboard()->setText( safeURL.url() );
813 void KHTMLPopupGUIClient::slotViewImage()
815 d->m_khtml->browserExtension()->createNewWindow(d->m_imageURL);
818 void KHTMLPopupGUIClient::slotReloadFrame()
822 args.
metaData()[
"referrer"] = d->m_khtml->pageReferrer();
824 d->m_khtml->closeUrl();
825 d->m_khtml->setArguments( args );
826 d->m_khtml->openUrl( d->m_khtml->url() );
829 void KHTMLPopupGUIClient::slotFrameInWindow()
832 args.
metaData()[
"referrer"] = d->m_khtml->pageReferrer();
835 emit d->m_khtml->browserExtension()->createNewWindow( d->m_khtml->url(), args, browserArgs );
838 void KHTMLPopupGUIClient::slotFrameInTop()
841 args.
metaData()[
"referrer"] = d->m_khtml->pageReferrer();
844 emit d->m_khtml->browserExtension()->openUrlRequest( d->m_khtml->url(), args, browserArgs );
847 void KHTMLPopupGUIClient::slotFrameInTab()
850 args.
metaData()[
"referrer"] = d->m_khtml->pageReferrer();
853 emit d->m_khtml->browserExtension()->createNewWindow( d->m_khtml->url(), args, browserArgs );
859 const QString &filter,
long cacheId,
860 const QString & suggestedFilename )
862 QString name = QLatin1String(
"index.html" );
863 if ( !suggestedFilename.isEmpty() )
864 name = suggestedFilename;
877 if( info.exists() ) {
884 if ( destURL.isValid() )
885 saveURL(parent, url, destURL, metadata, cacheId);
892 if ( destURL.isValid() )
902 QDataStream stream ( &destFile );
913 QDataStream stream ( &destFile );
916 url2.
setPath(destFile.fileName());
928 bool downloadViaKIO =
true;
933 if (!downloadManger.isEmpty())
936 kDebug(1000) <<
"Using: "<<downloadManger <<
" as Download Manager";
940 QString errMsg=
i18n(
"The Download Manager (%1) could not be found in your $PATH ", downloadManger);
941 QString errMsgEx=
i18n(
"Try to reinstall it \n\nThe integration with Konqueror will be disabled.");
948 downloadViaKIO =
false;
949 KUrl cleanDest = destURL;
953 kDebug(1000) <<
"Calling command "<<cmd;
959 if ( downloadViaKIO )
968 : KParts::BrowserHostExtension( part )
989 return m_part->openUrlInFrame( url, arguments, browserArguments );
993 *callingPart,
const QString &frame )
1009 setIcon(
KIcon( icon ) );
1014 init(part, direction);
1017 void KHTMLZoomFactorAction::init(
KHTMLPart *part,
bool direction)
1019 m_direction = direction;
1025 int m = m_direction ? 1 : -1;
1026 int ofs = fastZoomSizeCount / 2;
1029 for (
int i = m; i != m*(ofs+1); i += m )
1032 QString numStr = QString::number( num );
1033 if ( num > 0 ) numStr.prepend( QLatin1Char(
'+') );
1053 m_part->
setFontScaleFactor(fastZoomSizes[fastZoomSizeCount/2 + (m_direction ? 1 : -1)*idx]);
1058 : KParts::TextExtension(part)
1065 return static_cast<KHTMLPart*
>(parent());
1098 : KParts::HtmlExtension(part)
1120 elem.
setTagName(domElem->tagName().string());
1121 const DOM::NamedAttrMapImpl* attrMap = domElem->attributes(
true );
1123 for (
unsigned i = 0; i < attrMap->length(); ++i) {
1124 const DOM::AttributeImpl& attr = attrMap->attributeAt(i);
1125 elem.
setAttribute(attr.localName().string(), attr.value().string());
1147 WTF::RefPtr<DOM::ElementImpl> domElem =
part()->
document().
handle()->querySelector(query, ec);
1180 WTF::RefPtr<DOM::NodeListImpl> nodes =
part()->
document().
handle()->querySelectorAll(query, ec);
1181 const unsigned long len = nodes->length();
1182 elements.reserve(len);
1183 for (
unsigned long i = 0; i < len; ++i) {
1184 DOM::NodeImpl* node = nodes->item(i);
1185 if (node->isElementNode()) {
1194 const unsigned long len = nodes.
length();
1195 for (
unsigned long i = 0; i < len; ++i) {
1196 DOM::NodeImpl* node = nodes.
item(i).
handle();
1197 if (node->isElementNode())
1257 const KUrl url (value.toUrl());
1258 if (url.protocol() == QLatin1String(
"data")) {
1259 const QByteArray data (url.encodedPath());
1260 if (!data.isEmpty()) {
1261 const int index = data.indexOf(
',');
1262 const QByteArray decodedData ((index > -1 ? QByteArray::fromBase64(data.mid(index)) : QByteArray()));
1263 p->
setUserStyleSheet(QString::fromUtf8(decodedData.constData(), decodedData.size()));
1281 return static_cast<KHTMLPart*
>(parent());
1284 #include "khtml_ext.moc"