diff --git a/src/plugins/GreaseMonkey/gm_downloader.cpp b/src/plugins/GreaseMonkey/gm_downloader.cpp
index b202c8eaf..3bdbc7bfb 100644
--- a/src/plugins/GreaseMonkey/gm_downloader.cpp
+++ b/src/plugins/GreaseMonkey/gm_downloader.cpp
@@ -16,7 +16,6 @@
* along with this program. If not, see .
* ============================================================ */
#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(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(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();
}
}
diff --git a/src/plugins/GreaseMonkey/gm_downloader.h b/src/plugins/GreaseMonkey/gm_downloader.h
index 31f79eed6..900f90072 100644
--- a/src/plugins/GreaseMonkey/gm_downloader.h
+++ b/src/plugins/GreaseMonkey/gm_downloader.h
@@ -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();
diff --git a/src/plugins/GreaseMonkey/gm_manager.cpp b/src/plugins/GreaseMonkey/gm_manager.cpp
index 1f0411b80..10117a861 100644
--- a/src/plugins/GreaseMonkey/gm_manager.cpp
+++ b/src/plugins/GreaseMonkey/gm_manager.cpp
@@ -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)
diff --git a/src/plugins/GreaseMonkey/gm_script.cpp b/src/plugins/GreaseMonkey/gm_script.cpp
index d467babfc..1cd3b2bc3 100644
--- a/src/plugins/GreaseMonkey/gm_script.cpp
+++ b/src/plugins/GreaseMonkey/gm_script.cpp
@@ -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
#include
@@ -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()) {
diff --git a/src/plugins/GreaseMonkey/gm_script.h b/src/plugins/GreaseMonkey/gm_script.h
index aa7ae2626..2075e1340 100644
--- a/src/plugins/GreaseMonkey/gm_script.h
+++ b/src/plugins/GreaseMonkey/gm_script.h
@@ -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
diff --git a/src/plugins/GreaseMonkey/settings/gm_settings.cpp b/src/plugins/GreaseMonkey/settings/gm_settings.cpp
index 09927eb32..63ac24bdd 100644
--- a/src/plugins/GreaseMonkey/settings/gm_settings.cpp
+++ b/src/plugins/GreaseMonkey/settings/gm_settings.cpp
@@ -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);
diff --git a/src/plugins/GreaseMonkey/settings/gm_settings.h b/src/plugins/GreaseMonkey/settings/gm_settings.h
index 519bc82b4..050ae5aab 100644
--- a/src/plugins/GreaseMonkey/settings/gm_settings.h
+++ b/src/plugins/GreaseMonkey/settings/gm_settings.h
@@ -40,6 +40,7 @@ public:
private slots:
void showItemInfo(QListWidgetItem* item);
+ void updateItem(QListWidgetItem* item);
void removeItem(QListWidgetItem* item);
void itemChanged(QListWidgetItem* item);
diff --git a/src/plugins/GreaseMonkey/settings/gm_settingslistdelegate.cpp b/src/plugins/GreaseMonkey/settings/gm_settingslistdelegate.cpp
index 5b1730f46..4d4f5fff2 100644
--- a/src/plugins/GreaseMonkey/settings/gm_settingslistdelegate.cpp
+++ b/src/plugins/GreaseMonkey/settings/gm_settingslistdelegate.cpp
@@ -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);
diff --git a/src/plugins/GreaseMonkey/settings/gm_settingslistdelegate.h b/src/plugins/GreaseMonkey/settings/gm_settingslistdelegate.h
index 53f91be72..30668f408 100644
--- a/src/plugins/GreaseMonkey/settings/gm_settingslistdelegate.h
+++ b/src/plugins/GreaseMonkey/settings/gm_settingslistdelegate.h
@@ -32,6 +32,7 @@ public:
private:
QPixmap m_removePixmap;
+ QIcon m_updateIcon;
mutable int m_rowHeight;
mutable int m_padding;
diff --git a/src/plugins/GreaseMonkey/settings/gm_settingslistwidget.cpp b/src/plugins/GreaseMonkey/settings/gm_settingslistwidget.cpp
index 3baca0095..55a90ccaf 100644
--- a/src/plugins/GreaseMonkey/settings/gm_settingslistwidget.cpp
+++ b/src/plugins/GreaseMonkey/settings/gm_settingslistwidget.cpp
@@ -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);
+}
diff --git a/src/plugins/GreaseMonkey/settings/gm_settingslistwidget.h b/src/plugins/GreaseMonkey/settings/gm_settingslistwidget.h
index f70583408..d43598caa 100644
--- a/src/plugins/GreaseMonkey/settings/gm_settingslistwidget.h
+++ b/src/plugins/GreaseMonkey/settings/gm_settingslistwidget.h
@@ -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);