1
mirror of https://invent.kde.org/network/falkon.git synced 2024-12-24 12:46:35 +01:00

Merge pull request #1889 from trnkava1/downloadScripts

Greasemonkey: add script updating
This commit is contained in:
David Rosca 2016-03-20 19:17:38 +01:00
commit 80ad43ba42
11 changed files with 128 additions and 32 deletions

View File

@ -16,7 +16,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "gm_downloader.h"
#include "gm_addscriptdialog.h"
#include "gm_manager.h"
#include "gm_script.h"
@ -38,6 +37,11 @@ GM_Downloader::GM_Downloader(const QUrl &url, GM_Manager* manager)
connect(m_reply, SIGNAL(finished()), this, SLOT(scriptDownloaded()));
}
void GM_Downloader::updateScript(const QString &fileName)
{
m_fileName = fileName;
}
void GM_Downloader::scriptDownloaded()
{
if (m_reply != qobject_cast<FollowRedirectReply*>(sender())) {
@ -52,13 +56,15 @@ void GM_Downloader::scriptDownloaded()
const QByteArray response = QString::fromUtf8(m_reply->readAll()).toUtf8();
if (response.contains(QByteArray("// ==UserScript=="))) {
const QString filePath = QString("%1/%2").arg(m_manager->scriptsDirectory(), QzTools::getFileNameFromUrl(m_reply->url()));
m_fileName = QzTools::ensureUniqueFilename(filePath);
if (m_fileName.isEmpty()) {
const QString filePath = QString("%1/%2").arg(m_manager->scriptsDirectory(), QzTools::getFileNameFromUrl(m_reply->url()));
m_fileName = QzTools::ensureUniqueFilename(filePath);
}
QFile file(m_fileName);
if (!file.open(QFile::WriteOnly)) {
qWarning() << "GreaseMonkey: Cannot open file for writing" << m_fileName;
emit error();
deleteLater();
return;
}
@ -91,6 +97,7 @@ void GM_Downloader::scriptDownloaded()
void GM_Downloader::requireDownloaded()
{
if (m_reply != qobject_cast<FollowRedirectReply*>(sender())) {
emit error();
deleteLater();
return;
}
@ -109,6 +116,7 @@ void GM_Downloader::requireDownloaded()
if (!file.open(QFile::WriteOnly)) {
qWarning() << "GreaseMonkey: Cannot open file for writing" << fileName;
emit error();
deleteLater();
return;
}
@ -135,24 +143,7 @@ void GM_Downloader::downloadRequires()
connect(m_reply, SIGNAL(finished()), this, SLOT(requireDownloaded()));
}
else {
bool deleteScript = true;
GM_Script* script = new GM_Script(m_manager, m_fileName);
if (script->isValid()) {
if (!m_manager->containsScript(script->fullName())) {
GM_AddScriptDialog dialog(m_manager, script);
deleteScript = dialog.exec() != QDialog::Accepted;
}
else {
m_manager->showNotification(tr("'%1' is already installed").arg(script->name()));
}
}
if (deleteScript) {
delete script;
QFile(m_fileName).remove();
}
emit finished(m_fileName);
deleteLater();
}
}

View File

@ -32,6 +32,12 @@ class GM_Downloader : public QObject
public:
explicit GM_Downloader(const QUrl &url, GM_Manager* manager);
void updateScript(const QString& fileName);
signals:
void finished(const QString& fileName);
void error();
private slots:
void scriptDownloaded();
void requireDownloaded();

View File

@ -20,6 +20,7 @@
#include "gm_downloader.h"
#include "gm_icon.h"
#include "gm_urlinterceptor.h"
#include "gm_addscriptdialog.h"
#include "settings/gm_settings.h"
#include "browserwindow.h"
@ -256,7 +257,25 @@ void GM_Manager::scriptChanged()
void GM_Manager::doDownloadScript(const QUrl &url)
{
new GM_Downloader(url, this);
GM_Downloader *downloader = new GM_Downloader(url, this);
connect(downloader, &GM_Downloader::finished, this, [=](const QString &fileName) {
bool deleteScript = true;
GM_Script *script = new GM_Script(this, fileName);
if (script->isValid()) {
if (!containsScript(script->fullName())) {
GM_AddScriptDialog dialog(this, script);
deleteScript = dialog.exec() != QDialog::Accepted;
}
else {
showNotification(tr("'%1' is already installed").arg(script->name()));
}
}
if (deleteScript) {
delete script;
QFile(fileName).remove();
}
});
}
bool GM_Manager::canRunOnScheme(const QString &scheme)

View File

@ -17,9 +17,12 @@
* ============================================================ */
#include "gm_script.h"
#include "gm_manager.h"
#include "gm_downloader.h"
#include "qzregexp.h"
#include "delayedfilewatcher.h"
#include "followredirectreply.h"
#include "mainapplication.h"
#include <QFile>
#include <QStringList>
@ -36,6 +39,7 @@ GM_Script::GM_Script(GM_Manager* manager, const QString &filePath)
, m_fileName(filePath)
, m_enabled(true)
, m_valid(false)
, m_updating(false)
{
parseScript();
@ -148,6 +152,31 @@ QWebEngineScript GM_Script::webScript() const
return script;
}
bool GM_Script::isUpdating()
{
return m_updating;
}
void GM_Script::updateScript()
{
if (!m_downloadUrl.isValid() || m_updating)
return;
m_updating = true;
emit updatingChanged(m_updating);
GM_Downloader *downloader = new GM_Downloader(m_downloadUrl, m_manager);
downloader->updateScript(m_fileName);
connect(downloader, &GM_Downloader::finished, this, [this]() {
m_updating = false;
emit updatingChanged(m_updating);
});
connect(downloader, &GM_Downloader::error, this, [this]() {
m_updating = false;
emit updatingChanged(m_updating);
});
}
void GM_Script::watchedFileChanged(const QString &file)
{
if (m_fileName == file) {
@ -254,6 +283,9 @@ void GM_Script::parseScript()
m_version = value;
}
else if (key == QLatin1String("@updateURL")) {
m_updateUrl = QUrl(value);
}
else if (key == QLatin1String("@downloadURL")) {
m_downloadUrl = QUrl(value);
}
else if (key == QLatin1String("@include") || key == QLatin1String("@match")) {
@ -276,12 +308,6 @@ void GM_Script::parseScript()
m_startAt = DocumentIdle;
}
}
else if (key == QLatin1String("@downloadURL") && m_downloadUrl.isEmpty()) {
m_downloadUrl = QUrl(value);
}
else if (key == QLatin1String("@updateURL") && m_updateUrl.isEmpty()) {
m_updateUrl = QUrl(value);
}
}
if (m_include.isEmpty()) {

View File

@ -62,8 +62,12 @@ public:
QWebEngineScript webScript() const;
bool isUpdating();
void updateScript();
signals:
void scriptChanged();
void updatingChanged(bool updating);
private slots:
void watchedFileChanged(const QString &file);
@ -91,6 +95,7 @@ private:
QString m_fileName;
bool m_enabled;
bool m_valid;
bool m_updating;
};
#endif // GM_SCRIPT_H

View File

@ -38,6 +38,8 @@ GM_Settings::GM_Settings(GM_Manager* manager, QWidget* parent)
connect(ui->listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
this, SLOT(showItemInfo(QListWidgetItem*)));
connect(ui->listWidget, SIGNAL(updateItemRequested(QListWidgetItem*)),
this, SLOT(updateItem(QListWidgetItem*)));
connect(ui->listWidget, SIGNAL(removeItemRequested(QListWidgetItem*)),
this, SLOT(removeItem(QListWidgetItem*)));
connect(ui->openDirectory, SIGNAL(clicked()),
@ -69,6 +71,15 @@ void GM_Settings::showItemInfo(QListWidgetItem* item)
dialog->open();
}
void GM_Settings::updateItem(QListWidgetItem* item)
{
GM_Script *script = getScript(item);
if (!script) {
return;
}
script->updateScript();
}
void GM_Settings::removeItem(QListWidgetItem* item)
{
GM_Script* script = getScript(item);
@ -148,6 +159,8 @@ void GM_Settings::loadScripts()
item->setText(script->name());
item->setData(Qt::UserRole, script->version());
item->setData(Qt::UserRole + 1, script->description());
item->setData(Qt::UserRole + 2, !script->downloadUrl().isEmpty());
item->setData(Qt::UserRole + 3, script->isUpdating());
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(script->isEnabled() ? Qt::Checked : Qt::Unchecked);

View File

@ -40,6 +40,7 @@ public:
private slots:
void showItemInfo(QListWidgetItem* item);
void updateItem(QListWidgetItem* item);
void removeItem(QListWidgetItem* item);
void itemChanged(QListWidgetItem* item);

View File

@ -29,6 +29,7 @@ GM_SettingsListDelegate::GM_SettingsListDelegate(QObject* parent)
, m_padding(0)
{
m_removePixmap = IconProvider::standardIcon(QStyle::SP_DialogCloseButton).pixmap(16);
m_updateIcon = IconProvider::standardIcon(QStyle::SP_BrowserReload);
}
int GM_SettingsListDelegate::padding() const
@ -63,6 +64,8 @@ void GM_SettingsListDelegate::paint(QPainter* painter, const QStyleOptionViewIte
int leftPosition = m_padding;
int rightPosition = opt.rect.right() - m_padding - 16; // 16 for remove button
if (index.data(Qt::UserRole + 2).toBool())
rightPosition -= m_padding + 16; // 16 for update button
// Draw background
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, w);
@ -109,6 +112,16 @@ void GM_SettingsListDelegate::paint(QPainter* painter, const QStyleOptionViewIte
painter->setFont(opt.font);
style->drawItemText(painter, infoRect, Qt::TextSingleLine | Qt::AlignLeft, opt.palette, true, info, colorRole);
// Draw update button
if (index.data(Qt::UserRole + 2).toBool()) {
const int updateIconSize = 16;
const int updateIconYPos = center - (updateIconSize / 2);
const QPixmap updatePixmap = m_updateIcon.pixmap(16, index.data(Qt::UserRole + 3).toBool() ? QIcon::Disabled : QIcon::Normal);
QRect updateIconRect(rightPosition, updateIconYPos, updateIconSize, updateIconSize);
painter->drawPixmap(updateIconRect, updatePixmap);
rightPosition += m_padding + 16;
}
// Draw remove button
const int removeIconSize = 16;
const int removeIconYPos = center - (removeIconSize / 2);

View File

@ -32,6 +32,7 @@ public:
private:
QPixmap m_removePixmap;
QIcon m_updateIcon;
mutable int m_rowHeight;
mutable int m_padding;

View File

@ -36,15 +36,18 @@ void GM_SettingsListWidget::mousePressEvent(QMouseEvent* event)
return;
}
if (containsUpdateIcon(event->pos())) {
emit updateItemRequested(itemAt(event->pos()));
return;
}
QListWidget::mousePressEvent(event);
}
void GM_SettingsListWidget::mouseDoubleClickEvent(QMouseEvent* event)
{
if (containsRemoveIcon(event->pos())) {
emit removeItemRequested(itemAt(event->pos()));
if (containsRemoveIcon(event->pos()) || containsUpdateIcon(event->pos()))
return;
}
QListWidget::mouseDoubleClickEvent(event);
}
@ -65,3 +68,19 @@ bool GM_SettingsListWidget::containsRemoveIcon(const QPoint &pos) const
return removeIconRect.contains(pos);
}
bool GM_SettingsListWidget::containsUpdateIcon(const QPoint &pos) const
{
QListWidgetItem *item = itemAt(pos);
if (!item || !item->data(Qt::UserRole + 2).toBool())
return false;
const QRect rect = visualItemRect(item);
const int updateIconPosition = rect.right() - m_delegate->padding() * 2 - 16 * 2;
const int center = rect.height() / 2 + rect.top();
const int updateIconYPos = center - (16 / 2);
QRect updateIconRect(updateIconPosition, updateIconYPos, 16, 16);
return updateIconRect.contains(pos);
}

View File

@ -30,11 +30,13 @@ public:
signals:
void removeItemRequested(QListWidgetItem* item);
void updateItemRequested(QListWidgetItem* item);
public slots:
private:
bool containsRemoveIcon(const QPoint &pos) const;
bool containsUpdateIcon(const QPoint &pos) const;
void mousePressEvent(QMouseEvent* event);
void mouseDoubleClickEvent(QMouseEvent* event);