116 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			116 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // 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 <QtCore/QUrl>
 | |
| #include <QtCore/QRegularExpression>
 | |
| #include <QtGui/QDesktopServices>
 | |
| #include <QtGui/QGuiApplication>
 | |
| 
 | |
| 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 };
 | |
| }
 | 
