// This file is part of Desktop App Toolkit, // a set of libraries for developing nice desktop applications. // // For license and copyright information please follow this link: // https://github.com/desktop-app/legal/blob/master/LEGAL // #include "ui/basic_click_handlers.h" #include "ui/widgets/tooltip.h" #include "ui/text/text_entity.h" #include "ui/integration.h" #include "base/qthelp_url.h" #include #include #include #include QString TextClickHandler::readable() const { const auto result = url(); return result.startsWith(qstr("internal:")) ? QString() : result; } UrlClickHandler::UrlClickHandler(const QString &url, bool fullDisplayed) : TextClickHandler(fullDisplayed) , _originalUrl(url) { if (isEmail()) { _readable = _originalUrl; } else if (!_originalUrl.startsWith(qstr("internal:"))) { const auto original = QUrl(_originalUrl); const auto good = QUrl(original.isValid() ? original.toEncoded() : QString()); _readable = good.isValid() ? good.toDisplayString() : _originalUrl; } } QString UrlClickHandler::copyToClipboardContextItemText() const { return isEmail() ? Ui::Integration::Instance().phraseContextCopyEmail() : Ui::Integration::Instance().phraseContextCopyLink(); } QString UrlClickHandler::EncodeForOpening(const QString &originalUrl) { if (IsEmail(originalUrl)) { return originalUrl; } const auto u = QUrl(originalUrl); const auto good = QUrl(u.isValid() ? u.toEncoded() : QString()); const auto result = good.isValid() ? QString::fromUtf8(good.toEncoded()) : originalUrl; if (!result.isEmpty() && !QRegularExpression( QStringLiteral("^[a-zA-Z]+:")).match(result).hasMatch()) { // No protocol. return QStringLiteral("http://") + result; } return result; } void UrlClickHandler::Open(QString url, QVariant context) { Ui::Tooltip::Hide(); if (!Ui::Integration::Instance().handleUrlClick(url, context) && !url.isEmpty()) { if (IsEmail(url)) { url = "mailto: " + url; } QDesktopServices::openUrl(url); } } bool UrlClickHandler::IsSuspicious(const QString &url) { static const auto Check1 = QRegularExpression( "^((https?|s?ftp)://)?([^/#\\:]+)([/#\\:]|$)", QRegularExpression::CaseInsensitiveOption); const auto match1 = Check1.match(url); if (!match1.hasMatch()) { return false; } const auto domain = match1.capturedRef(3); static const auto Check2 = QRegularExpression("^(.*)\\.[a-zA-Z]+$"); const auto match2 = Check2.match(domain); if (!match2.hasMatch()) { return false; } const auto part = match2.capturedRef(1); static const auto Check3 = QRegularExpression("[^a-zA-Z0-9\\.\\-]"); return Check3.match(part).hasMatch(); } QString UrlClickHandler::ShowEncoded(const QString &url) { if (const auto u = QUrl(url); u.isValid()) { return QString::fromUtf8(u.toEncoded()); } static const auto Check1 = QRegularExpression( "^(https?://)?([^/#\\:]+)([/#\\:]|$)", QRegularExpression::CaseInsensitiveOption); if (const auto match1 = Check1.match(url); match1.hasMatch()) { const auto domain = match1.captured(1).append(match1.capturedRef(2)); if (const auto u = QUrl(domain); u.isValid()) { return QString( ).append(QString::fromUtf8(u.toEncoded()) ).append(url.midRef(match1.capturedEnd(2))); } } return url; } auto UrlClickHandler::getTextEntity() const -> TextEntity { const auto type = isEmail() ? EntityType::Email : EntityType::Url; return { type, _originalUrl }; }