File indexing completed on 2024-05-12 04:58:09

0001 /* ============================================================
0002 * Falkon - Qt web browser
0003 * Copyright (C) 2010-2018 David Rosca <nowrep@gmail.com>
0004 *
0005 * This program is free software: you can redistribute it and/or modify
0006 * it under the terms of the GNU General Public License as published by
0007 * the Free Software Foundation, either version 3 of the License, or
0008 * (at your option) any later version.
0009 *
0010 * This program is distributed in the hope that it will be useful,
0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 * GNU General Public License for more details.
0014 *
0015 * You should have received a copy of the GNU General Public License
0016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0017 * ============================================================ */
0018 #include "siteicon.h"
0019 #include "siteinfowidget.h"
0020 #include "locationbar.h"
0021 #include "tabbedwebview.h"
0022 #include "qztools.h"
0023 #include "siteinfo.h"
0024 
0025 #include <QDrag>
0026 #include <QTimer>
0027 #include <QMimeData>
0028 #include <QApplication>
0029 #include <QContextMenuEvent>
0030 
0031 SiteIcon::SiteIcon(LocationBar *parent)
0032     : ToolButton(parent)
0033     , m_window(nullptr)
0034     , m_locationBar(parent)
0035     , m_view(nullptr)
0036 {
0037     setObjectName("locationbar-siteicon");
0038     setToolButtonStyle(Qt::ToolButtonIconOnly);
0039     setCursor(Qt::ArrowCursor);
0040     setToolTip(LocationBar::tr("Show information about this page"));
0041     setFocusPolicy(Qt::NoFocus);
0042 
0043     m_updateTimer = new QTimer(this);
0044     m_updateTimer->setInterval(100);
0045     m_updateTimer->setSingleShot(true);
0046     connect(m_updateTimer, &QTimer::timeout, this, &SiteIcon::updateIcon);
0047 }
0048 
0049 void SiteIcon::setBrowserWindow(BrowserWindow *window)
0050 {
0051     m_window = window;
0052 }
0053 
0054 void SiteIcon::setWebView(WebView* view)
0055 {
0056     m_view = view;
0057 }
0058 
0059 void SiteIcon::setIcon(const QIcon &icon)
0060 {
0061     bool wasNull = m_icon.isNull();
0062 
0063     m_icon = icon;
0064 
0065     if (wasNull) {
0066         updateIcon();
0067     }
0068     else {
0069         m_updateTimer->start();
0070     }
0071 }
0072 
0073 void SiteIcon::updateIcon()
0074 {
0075     ToolButton::setIcon(m_icon);
0076 }
0077 
0078 void SiteIcon::popupClosed()
0079 {
0080     setDown(false);
0081 }
0082 
0083 void SiteIcon::contextMenuEvent(QContextMenuEvent* e)
0084 {
0085     // Prevent propagating to LocationBar
0086     e->accept();
0087 }
0088 
0089 void SiteIcon::mousePressEvent(QMouseEvent* e)
0090 {
0091     if (e->buttons() == Qt::LeftButton) {
0092         m_dragStartPosition = e->pos();
0093     }
0094 
0095     // Prevent propagating to LocationBar
0096     e->accept();
0097 
0098     ToolButton::mousePressEvent(e);
0099 }
0100 
0101 void SiteIcon::mouseReleaseEvent(QMouseEvent* e)
0102 {
0103     // Mouse release event is restoring Down state
0104     // So we pause updates to prevent flicker
0105 
0106     bool activated = false;
0107 
0108     if (e->button() == Qt::LeftButton && rect().contains(e->pos())) {
0109         // Popup may not be always shown, eg. on falkon: pages
0110         activated = showPopup();
0111     }
0112 
0113     if (activated) {
0114         setUpdatesEnabled(false);
0115     }
0116 
0117     ToolButton::mouseReleaseEvent(e);
0118 
0119     if (activated) {
0120         setDown(true);
0121         setUpdatesEnabled(true);
0122     }
0123 }
0124 
0125 void SiteIcon::mouseMoveEvent(QMouseEvent* e)
0126 {
0127     if (!m_locationBar || e->buttons() != Qt::LeftButton) {
0128         ToolButton::mouseMoveEvent(e);
0129         return;
0130     }
0131 
0132     int manhattanLength = (e->pos() - m_dragStartPosition).manhattanLength();
0133     if (manhattanLength <= QApplication::startDragDistance()) {
0134         ToolButton::mouseMoveEvent(e);
0135         return;
0136     }
0137 
0138     const QUrl url = m_locationBar->webView()->url();
0139     const QString title = m_locationBar->webView()->title();
0140 
0141     if (url.isEmpty() || title.isEmpty()) {
0142         ToolButton::mouseMoveEvent(e);
0143         return;
0144     }
0145 
0146     auto* drag = new QDrag(this);
0147     auto* mime = new QMimeData;
0148     mime->setUrls(QList<QUrl>() << url);
0149     mime->setText(title);
0150     mime->setImageData(icon().pixmap(16).toImage());
0151 
0152     drag->setMimeData(mime);
0153     drag->setPixmap(QzTools::createPixmapForSite(icon(), title, url.toString()));
0154     drag->exec();
0155 
0156     // Restore Down state
0157     setDown(false);
0158 }
0159 
0160 bool SiteIcon::showPopup()
0161 {
0162     if (!m_view || !m_window) {
0163         return false;
0164     }
0165 
0166     QUrl url = m_view->url();
0167 
0168     if (!SiteInfo::canShowSiteInfo(url))
0169         return false;
0170 
0171     setDown(true);
0172 
0173     auto* info = new SiteInfoWidget(m_window);
0174     info->showAt(parentWidget());
0175 
0176     connect(info, &QObject::destroyed, this, &SiteIcon::popupClosed);
0177 
0178     return true;
0179 }