34 #include <QFileDialog>
35 #include <QHeaderView>
36 #include <QImageReader>
38 #include <QMessageBox>
50 #include "ui_pluginselectdialog.h"
52 #define SETTINGS_KEY(name) "SearchPluginSelectDialog/" name
67 , m_pluginManager(pluginManager)
70 setAttribute(Qt::WA_DeleteOnClose);
75 unused.setVerticalHeader(
m_ui->pluginsTree->header());
76 m_ui->pluginsTree->header()->setParent(
m_ui->pluginsTree);
77 unused.setVerticalHeader(
new QHeaderView(Qt::Horizontal));
79 m_ui->pluginsTree->setRootIsDecorated(
false);
81 m_ui->pluginsTree->header()->setSortIndicator(0, Qt::AscendingOrder);
110 event->acceptProposedAction();
113 if (event->mimeData()->hasUrls())
115 for (
const QUrl &url :
asConst(event->mimeData()->urls()))
119 if (url.scheme().compare(
"file", Qt::CaseInsensitive) == 0)
120 files << url.toLocalFile();
122 files << url.toString();
128 files =
event->mimeData()->text().split(
'\n');
131 if (
files.isEmpty())
return;
135 qDebug(
"dropped %s", qUtf8Printable(
file));
144 for (
const QString &mime :
asConst(event->mimeData()->formats()))
146 qDebug(
"mimeData: %s", qUtf8Printable(mime));
149 if (event->mimeData()->hasFormat(QLatin1String(
"text/plain")) || event->mimeData()->hasFormat(QLatin1String(
"text/uri-list")))
151 event->acceptProposedAction();
180 const QList<QTreeWidgetItem *> items =
m_ui->pluginsTree->selectedItems();
181 if (items.isEmpty())
return;
183 QMenu *myContextMenu =
new QMenu(
this);
184 myContextMenu->setAttribute(Qt::WA_DeleteOnClose);
186 const QString firstID = items.first()->text(
PLUGIN_ID);
188 myContextMenu->addAction(
m_ui->actionEnable);
189 myContextMenu->addSeparator();
190 myContextMenu->addAction(
m_ui->actionUninstall);
192 myContextMenu->popup(QCursor::pos());
203 for (QTreeWidgetItem *item :
asConst(
m_ui->pluginsTree->selectedItems()))
205 int index =
m_ui->pluginsTree->indexOfTopLevelItem(item);
206 Q_ASSERT(index != -1);
223 QMessageBox::warning(
this, tr(
"Uninstall warning"), tr(
"Some plugins could not be uninstalled because they are included in qBittorrent. Only the ones you added yourself can be uninstalled.\nThose plugins were disabled."));
225 QMessageBox::information(
this, tr(
"Uninstall success"), tr(
"All selected plugins were uninstalled successfully"));
230 for (QTreeWidgetItem *item :
asConst(
m_ui->pluginsTree->selectedItems()))
232 int index =
m_ui->pluginsTree->indexOfTopLevelItem(item);
233 Q_ASSERT(index != -1);
252 QTreeWidgetItem *item =
m_ui->pluginsTree->topLevelItem(row);
253 for (
int i = 0; i <
m_ui->pluginsTree->columnCount(); ++i)
255 item->setData(i, Qt::ForegroundRole, QColor(color));
261 QVector<QTreeWidgetItem*> res;
262 res.reserve(
m_ui->pluginsTree->topLevelItemCount());
264 for (
int i = 0; i <
m_ui->pluginsTree->topLevelItemCount(); ++i)
266 QTreeWidgetItem *item =
m_ui->pluginsTree->topLevelItem(i);
267 if (url.startsWith(item->text(
PLUGIN_URL), Qt::CaseInsensitive))
276 for (
int i = 0; i <
m_ui->pluginsTree->topLevelItemCount(); ++i)
278 QTreeWidgetItem *item =
m_ui->pluginsTree->topLevelItem(i);
289 m_ui->pluginsTree->clear();
296 auto *item =
new QTreeWidgetItem(
m_ui->pluginsTree);
312 if (QFile::exists(plugin->
iconPath))
321 DownloadManager::instance()->download(
332 setCursor(QCursor(Qt::WaitCursor));
339 setCursor(QCursor(Qt::ArrowCursor));
348 QMessageBox::information(
this, tr(
"Search plugin update"), tr(
"Plugins installed or updated: %1").arg(
m_updatedPlugins.join(
", ")));
363 QString clipTxt = qApp->clipboard()->text();
364 QString defaultUrl =
"http://";
366 defaultUrl = clipTxt;
368 this, tr(
"New search engine plugin URL"),
369 tr(
"URL:"), QLineEdit::Normal, defaultUrl, &ok
372 while (ok && !url.isEmpty() && !url.endsWith(
".py"))
374 QMessageBox::warning(
this, tr(
"Invalid link"), tr(
"The link doesn't seem to point to a search engine plugin."));
376 this, tr(
"New search engine plugin URL"),
377 tr(
"URL:"), QLineEdit::Normal, url, &ok
381 if (ok && !url.isEmpty())
390 const QStringList pathsList = QFileDialog::getOpenFileNames(
391 nullptr, tr(
"Select search plugins"), QDir::homePath(),
392 tr(
"qBittorrent search plugin") + QLatin1String(
" (*.py)")
394 for (
const QString &path : pathsList)
405 qDebug(
"Could not download favicon: %s, reason: %s", qUtf8Printable(result.
url), qUtf8Printable(result.
errorString));
412 QIcon icon(filePath);
414 QList<QSize> sizes = icon.availableSizes();
415 bool invalid = (sizes.isEmpty() || icon.pixmap(sizes.first()).isNull());
422 if (!plugin)
continue;
424 QString iconPath = QString(
"%1/%2.%3")
427 , result.
url.endsWith(
".ico", Qt::CaseInsensitive) ?
"ico" :
"png");
433 QIcon iconWithExt(iconPath);
434 QList<QSize> sizesExt = iconWithExt.availableSizes();
435 bool invalidExt = (sizesExt.isEmpty() || iconWithExt.pixmap(sizesExt.first()).isNull());
442 item->setData(
PLUGIN_NAME, Qt::DecorationRole, iconWithExt);
454 if (updateInfo.isEmpty())
456 QMessageBox::information(
this, tr(
"Search plugin update"), tr(
"All your plugins are already up to date."));
460 for (
auto i = updateInfo.cbegin(); i != updateInfo.cend(); ++i)
471 QMessageBox::warning(
this, tr(
"Search plugin update"), tr(
"Sorry, couldn't check for plugin updates. %1").arg(reason));
485 QMessageBox::information(
this, tr(
"Search plugin install")
486 , tr(
"Couldn't install \"%1\" search engine plugin. %2").arg(name, reason));
503 QMessageBox::information(
this, tr(
"Search plugin update")
504 , tr(
"Couldn't update \"%1\" search engine plugin. %2").arg(name, reason));
static QString getText(QWidget *parent, const QString &title, const QString &label, QLineEdit::EchoMode mode=QLineEdit::Normal, const QString &text={}, bool *ok=nullptr, bool excludeExtension=false, Qt::InputMethodHints inputMethodHints=Qt::ImhNone)
static bool hasSupportedScheme(const QString &url)
Ui::PluginSelectDialog * m_ui
PluginSelectDialog(SearchPluginManager *pluginManager, QWidget *parent=nullptr)
void on_actionUninstall_triggered()
void on_installButton_clicked()
void togglePluginState(QTreeWidgetItem *, int)
void setRowColor(int row, const QString &color)
void on_closeButton_clicked()
void finishPluginUpdate()
void on_updateButton_clicked()
void iconDownloadFinished(const Net::DownloadResult &result)
~PluginSelectDialog() override
void checkForUpdatesFinished(const QHash< QString, PluginVersion > &updateInfo)
void pluginInstallationFailed(const QString &name, const QString &reason)
void displayContextMenu(const QPoint &)
void dragEnterEvent(QDragEnterEvent *event) override
void pluginUpdateFailed(const QString &name, const QString &reason)
QStringList m_updatedPlugins
QVector< QTreeWidgetItem * > findItemsWithUrl(const QString &url)
SearchPluginManager * m_pluginManager
SettingValue< QSize > m_storeDialogSize
void enableSelection(bool enable)
void addNewPlugin(const QString &pluginName)
void pluginInstalled(const QString &name)
QTreeWidgetItem * findItemWithID(const QString &id)
void loadSupportedSearchPlugins()
void checkForUpdatesFailed(const QString &reason)
void dropEvent(QDropEvent *event) override
void pluginUpdated(const QString &name)
void updatePlugin(const QString &name)
PluginInfo * pluginInfo(const QString &name) const
void enablePlugin(const QString &name, bool enabled=true)
void pluginUpdated(const QString &name)
void pluginInstallationFailed(const QString &name, const QString &reason)
static void updateIconPath(PluginInfo *const plugin)
static QString pluginsLocation()
void pluginInstalled(const QString &name)
QStringList allPlugins() const
void installPlugin(const QString &source)
void checkForUpdatesFinished(const QHash< QString, PluginVersion > &updateInfo)
void checkForUpdatesFailed(const QString &reason)
bool uninstallPlugin(const QString &name)
void pluginUpdateFailed(const QString &name, const QString &reason)
static UIThemeManager * instance()
constexpr std::add_const_t< T > & asConst(T &t) noexcept
flag icons free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to copy
flag icons free of to any person obtaining a copy of this software and associated documentation files(the "Software")
QString toUniformPath(const QString &path)
bool forceRemove(const QString &filePath)
void resize(QWidget *widget, const QSize &newSize={})
#define SETTINGS_KEY(name)
file(GLOB QBT_TS_FILES "${qBittorrent_SOURCE_DIR}/src/lang/*.ts") set_source_files_properties($