From cf973c46fb1084416b511e6dc35b2965b0c0b1f4 Mon Sep 17 00:00:00 2001 From: nowrep Date: Fri, 16 Mar 2012 15:55:34 +0100 Subject: [PATCH] Fixed bad behaviour of QWebPage on leaveEvent. - when leaving web widget, QWebPagePrivate generates fake mouse move event, but unfortunately with bad coordinates. So sometimes it just hovered a link and the link's url got stuck in status bar message. --- src/lib/3rdparty/lineedit.cpp | 2 +- src/lib/3rdparty/lineedit.h | 6 +-- src/lib/navigation/locationbar.cpp | 7 ++++ src/lib/other/sourceviewer.cpp | 64 +++++++++++++++++++++++++----- src/lib/other/sourceviewer.h | 18 +++++++-- src/lib/other/statusbarmessage.cpp | 23 +---------- src/lib/other/statusbarmessage.h | 3 -- src/lib/webview/webpage.cpp | 24 +++++++++++ src/lib/webview/webpage.h | 1 + 9 files changed, 105 insertions(+), 43 deletions(-) diff --git a/src/lib/3rdparty/lineedit.cpp b/src/lib/3rdparty/lineedit.cpp index 373784946..28b27b6b5 100644 --- a/src/lib/3rdparty/lineedit.cpp +++ b/src/lib/3rdparty/lineedit.cpp @@ -162,7 +162,7 @@ void LineEdit::updateTextMargins() else { left = m_leftMargin; } - int right = textMargin(LineEdit::RightSide); + int right = textMargin(LineEdit::RightSide) + 3; int top = 0; int bottom = 0; setTextMargins(left, top, right, bottom); diff --git a/src/lib/3rdparty/lineedit.h b/src/lib/3rdparty/lineedit.h index baa43ab01..ab47f390a 100644 --- a/src/lib/3rdparty/lineedit.h +++ b/src/lib/3rdparty/lineedit.h @@ -71,13 +71,13 @@ public: void setLeftMargin(int margin); +public slots: + void updateTextMargins(); + protected: void resizeEvent(QResizeEvent* event); bool event(QEvent* event); -protected slots: - void updateTextMargins(); - private: void init(); void updateSideWidgetLocations(); diff --git a/src/lib/navigation/locationbar.cpp b/src/lib/navigation/locationbar.cpp index 8d7ca9d63..642c38b67 100644 --- a/src/lib/navigation/locationbar.cpp +++ b/src/lib/navigation/locationbar.cpp @@ -150,6 +150,8 @@ void LocationBar::showGoButton() m_bookmarkIcon->hide(); m_rssIcon->hide(); m_goIcon->show(); + + updateTextMargins(); } void LocationBar::hideGoButton() @@ -161,6 +163,8 @@ void LocationBar::hideGoButton() m_rssIcon->setVisible(m_rssIconVisible); m_bookmarkIcon->show(); m_goIcon->hide(); + + updateTextMargins(); } void LocationBar::showMostVisited() @@ -172,6 +176,7 @@ void LocationBar::showMostVisited() QKeyEvent event(QEvent::KeyPress, Qt::Key_unknown, Qt::NoModifier, QString(" ")); keyPressEvent(&event); } + m_locationCompleter->showMostVisited(); } @@ -196,6 +201,8 @@ void LocationBar::rssIconClicked() void LocationBar::showRSSIcon(bool state) { m_rssIcon->setVisible(state); + + updateTextMargins(); } void LocationBar::showUrl(const QUrl &url) diff --git a/src/lib/other/sourceviewer.cpp b/src/lib/other/sourceviewer.cpp index 5fcb6853d..178193c57 100644 --- a/src/lib/other/sourceviewer.cpp +++ b/src/lib/other/sourceviewer.cpp @@ -31,12 +31,12 @@ #include #include #include - -#include +#include SourceViewer::SourceViewer(QWebFrame* frame, const QString &selectedHtml) : QWidget(0) , m_frame(frame) + , m_selectedHtml(selectedHtml) { setAttribute(Qt::WA_DeleteOnClose); setWindowTitle(tr("Source of ") + frame->url().toString()); @@ -72,13 +72,12 @@ SourceViewer::SourceViewer(QWebFrame* frame, const QString &selectedHtml) menuBar->addMenu(menuFile); QMenu* menuEdit = new QMenu(tr("Edit")); - menuEdit->addAction(QIcon::fromTheme("edit-undo"), tr("Undo"), m_sourceEdit, SLOT(undo()))->setShortcut(QKeySequence("Ctrl+Z")); - menuEdit->addAction(QIcon::fromTheme("edit-redo"), tr("Redo"), m_sourceEdit, SLOT(redo()))->setShortcut(QKeySequence("Ctrl+Shift+Z")); + m_actionUndo = menuEdit->addAction(QIcon::fromTheme("edit-undo"), tr("Undo"), m_sourceEdit, SLOT(undo())); + m_actionRedo = menuEdit->addAction(QIcon::fromTheme("edit-redo"), tr("Redo"), m_sourceEdit, SLOT(redo())); menuEdit->addSeparator(); - menuEdit->addAction(QIcon::fromTheme("edit-cut"), tr("Cut"), m_sourceEdit, SLOT(cut()))->setShortcut(QKeySequence("Ctrl+X")); - menuEdit->addAction(QIcon::fromTheme("edit-copy"), tr("Copy"), m_sourceEdit, SLOT(copy()))->setShortcut(QKeySequence("Ctrl+C")); - menuEdit->addAction(QIcon::fromTheme("edit-paste"), tr("Paste"), m_sourceEdit, SLOT(paste()))->setShortcut(QKeySequence("Ctrl+V")); - menuEdit->addAction(QIcon::fromTheme("edit-delete"), tr("Delete"))->setShortcut(QKeySequence("Del")); + m_actionCut = menuEdit->addAction(QIcon::fromTheme("edit-cut"), tr("Cut"), m_sourceEdit, SLOT(cut())); + m_actionCopy = menuEdit->addAction(QIcon::fromTheme("edit-copy"), tr("Copy"), m_sourceEdit, SLOT(copy())); + m_actionPaste = menuEdit->addAction(QIcon::fromTheme("edit-paste"), tr("Paste"), m_sourceEdit, SLOT(paste())); menuEdit->addSeparator(); menuEdit->addAction(QIcon::fromTheme("edit-select-all"), tr("Select All"), m_sourceEdit, SLOT(selectAll()))->setShortcut(QKeySequence("Ctrl+A")); menuEdit->addAction(QIcon::fromTheme("edit-find"), tr("Find"), this, SLOT(findText()))->setShortcut(QKeySequence("Ctrl+F")); @@ -86,6 +85,12 @@ SourceViewer::SourceViewer(QWebFrame* frame, const QString &selectedHtml) menuEdit->addAction(QIcon::fromTheme("go-jump"), tr("Go to Line..."), this, SLOT(goToLine()))->setShortcut(QKeySequence("Ctrl+L")); menuBar->addMenu(menuEdit); + m_actionUndo->setShortcut(QKeySequence("Ctrl+Z")); + m_actionRedo->setShortcut(QKeySequence("Ctrl+Shift+Z")); + m_actionCut->setShortcut(QKeySequence("Ctrl+X")); + m_actionCopy->setShortcut(QKeySequence("Ctrl+C")); + m_actionPaste->setShortcut(QKeySequence("Ctrl+V")); + QMenu* menuView = new QMenu(tr("View")); menuView->addAction(IconProvider::standardIcon(QStyle::SP_BrowserReload), tr("Reload"), this, SLOT(reload()))->setShortcut(QKeySequence("F5")); menuView->addSeparator(); @@ -96,11 +101,48 @@ SourceViewer::SourceViewer(QWebFrame* frame, const QString &selectedHtml) qz_centerWidgetToParent(this, frame->page()->view()); - m_sourceEdit->setPlainText(frame->toHtml()); + connect(m_sourceEdit, SIGNAL(copyAvailable(bool)), this, SLOT(copyAvailable(bool))); + connect(m_sourceEdit, SIGNAL(redoAvailable(bool)), this, SLOT(redoAvailable(bool))); + connect(m_sourceEdit, SIGNAL(undoAvailable(bool)), this, SLOT(undoAvailable(bool))); + connect(menuEdit, SIGNAL(aboutToShow()), this, SLOT(pasteAvailable())); + + QTimer::singleShot(0, this, SLOT(loadSource())); +} + +void SourceViewer::copyAvailable(bool yes) +{ + m_actionCopy->setEnabled(yes); + m_actionCut->setEnabled(yes); +} + +void SourceViewer::redoAvailable(bool available) +{ + m_actionRedo->setEnabled(available); +} + +void SourceViewer::undoAvailable(bool available) +{ + m_actionUndo->setEnabled(available); +} + +void SourceViewer::pasteAvailable() +{ + m_actionPaste->setEnabled(m_sourceEdit->canPaste()); +} + +void SourceViewer::loadSource() +{ + m_actionUndo->setEnabled(false); + m_actionRedo->setEnabled(false); + m_actionCut->setEnabled(false); + m_actionCopy->setEnabled(false); + m_actionPaste->setEnabled(false); + + m_sourceEdit->setPlainText(m_frame.data()->toHtml()); //Highlight selectedHtml - if (!selectedHtml.isEmpty()) { - m_sourceEdit->find(selectedHtml, QTextDocument::FindWholeWords); + if (!m_selectedHtml.isEmpty()) { + m_sourceEdit->find(m_selectedHtml, QTextDocument::FindWholeWords); } else { m_sourceEdit->moveCursor(QTextCursor::Start); diff --git a/src/lib/other/sourceviewer.h b/src/lib/other/sourceviewer.h index f598a0543..39358ec26 100644 --- a/src/lib/other/sourceviewer.h +++ b/src/lib/other/sourceviewer.h @@ -36,11 +36,13 @@ public: explicit SourceViewer(QWebFrame* frame, const QString &selectedHtml); PlainEditWithLines* sourceEdit() { return m_sourceEdit; } -signals: - -public slots: - private slots: + void copyAvailable(bool yes); + void redoAvailable(bool available); + void undoAvailable(bool available); + void pasteAvailable(); + + void loadSource(); void save(); void findText(); void reload(); @@ -53,6 +55,14 @@ private: PlainEditWithLines* m_sourceEdit; QWeakPointer m_frame; QStatusBar* m_statusBar; + + QString m_selectedHtml; + + QAction* m_actionUndo; + QAction* m_actionRedo; + QAction* m_actionCut; + QAction* m_actionCopy; + QAction* m_actionPaste; }; #endif // SOURCEVIEWER_H diff --git a/src/lib/other/statusbarmessage.cpp b/src/lib/other/statusbarmessage.cpp index 47da0c136..d03394325 100644 --- a/src/lib/other/statusbarmessage.cpp +++ b/src/lib/other/statusbarmessage.cpp @@ -30,7 +30,6 @@ TipLabel::TipLabel(QWidget* parent) : SqueezeLabelV1(parent) - , p_QupZilla(0) , m_connected(false) { setWindowFlags(Qt::ToolTip); @@ -44,21 +43,6 @@ TipLabel::TipLabel(QWidget* parent) qApp->installEventFilter(this); } -void TipLabel::setMainWindow(QupZilla* main) -{ - p_QupZilla = main; -} - -void TipLabel::show() -{ - if (p_QupZilla && !m_connected) { - connect(p_QupZilla->tabWidget(), SIGNAL(currentChanged(int)), this, SLOT(hide())); - m_connected = true; - } - - SqueezeLabelV1::show(); -} - void TipLabel::paintEvent(QPaintEvent* ev) { QStylePainter p(this); @@ -97,7 +81,6 @@ StatusBarMessage::StatusBarMessage(QupZilla* mainClass) : p_QupZilla(mainClass) , m_statusBarText(new TipLabel(mainClass)) { - m_statusBarText->setMainWindow(p_QupZilla); } void StatusBarMessage::showMessage(const QString &message) @@ -128,10 +111,8 @@ void StatusBarMessage::showMessage(const QString &message) m_statusBarText->setMaximumWidth(view->width() - verticalScrollSize); m_statusBarText->resize(m_statusBarText->sizeHint()); - QPoint position; - position.setY(view->height() - horizontalScrollSize - m_statusBarText->height()); - - QRect statusRect = QRect(view->mapToGlobal(QPoint(0, position.y())), m_statusBarText->size()); + QPoint position(0, view->height() - horizontalScrollSize - m_statusBarText->height()); + const QRect &statusRect = QRect(view->mapToGlobal(QPoint(0, position.y())), m_statusBarText->size()); if (statusRect.contains(QCursor::pos())) { position.setY(position.y() - m_statusBarText->height()); diff --git a/src/lib/other/statusbarmessage.h b/src/lib/other/statusbarmessage.h index 413375f72..6d96d2c71 100644 --- a/src/lib/other/statusbarmessage.h +++ b/src/lib/other/statusbarmessage.h @@ -31,10 +31,7 @@ class QT_QUPZILLA_EXPORT TipLabel : public SqueezeLabelV1 public: TipLabel(QWidget* parent); - void setMainWindow(QupZilla* main); - bool eventFilter(QObject* o, QEvent* e); - void show(); private: void paintEvent(QPaintEvent* ev); diff --git a/src/lib/webview/webpage.cpp b/src/lib/webview/webpage.cpp index 7836a61ba..0959e2ce9 100644 --- a/src/lib/webview/webpage.cpp +++ b/src/lib/webview/webpage.cpp @@ -294,6 +294,30 @@ void WebPage::featurePermissionRequested(QWebFrame* frame, const QWebPage::Featu } #endif +bool WebPage::event(QEvent *event) +{ + if (event->type() == QEvent::Leave) { + // QWebPagePrivate::leaveEvent(): + // Fake a mouse move event just outside of the widget, since all + // the interesting mouse-out behavior like invalidating scrollbars + // is handled by the WebKit event handler's mouseMoved function. + + // However, its implementation fake mouse move event on QCursor::pos() + // position that is in global screen coordinates. So instead of + // really faking it, it just creates mouse move event somewhere in + // page. It can for example focus a link, and then link url gets + // stuck in status bar message. + + // So we are faking mouse move event with proper coordinates for + // so called "just outside of the widget" position + + QMouseEvent fakeEvent(QEvent::MouseMove, QPoint(0, -1), Qt::NoButton, Qt::NoButton, Qt::NoModifier); + return QWebPage::event(&fakeEvent); + } + + return QWebPage::event(event); +} + void WebPage::setSSLCertificate(const QSslCertificate &cert) { // if (cert != m_SslCert) diff --git a/src/lib/webview/webpage.h b/src/lib/webview/webpage.h index cc3c1dcfe..83bf841b3 100644 --- a/src/lib/webview/webpage.h +++ b/src/lib/webview/webpage.h @@ -95,6 +95,7 @@ private slots: #endif protected: + bool event(QEvent* event); QWebPage* createWindow(QWebPage::WebWindowType type); private: