Extract plugin install wizard

It will become more complicated, so pull it into its own files.

Change-Id: If362f0775cc9d97a3c715c046d32d6a20c30a1f9
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Eike Ziller
2020-06-03 15:56:43 +02:00
parent 65ced9733b
commit 4613199548
6 changed files with 322 additions and 219 deletions

View File

@@ -28,6 +28,7 @@
#include "icore.h"
#include "dialogs/restartdialog.h"
#include "plugininstallwizard.h"
#include <app/app_version.h>
@@ -37,24 +38,15 @@
#include <extensionsystem/pluginspec.h>
#include <extensionsystem/pluginview.h>
#include <utils/archive.h>
#include <utils/fancylineedit.h>
#include <utils/infolabel.h>
#include <utils/pathchooser.h>
#include <utils/wizard.h>
#include <utils/wizardpage.h>
#include <QButtonGroup>
#include <QCheckBox>
#include <QDebug>
#include <QDialog>
#include <QDialogButtonBox>
#include <QDir>
#include <QFileInfo>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QRadioButton>
#include <QVBoxLayout>
using namespace Utils;
@@ -64,163 +56,6 @@ namespace Internal {
static bool s_isRestartRequired = false;
const char kPath[] = "Path";
const char kApplicationInstall[] = "ApplicationInstall";
static bool hasLibSuffix(const FilePath &path)
{
return (HostOsInfo().isWindowsHost() && path.endsWith(".dll"))
|| (HostOsInfo().isLinuxHost() && path.toFileInfo().completeSuffix().startsWith(".so"))
|| (HostOsInfo().isMacHost() && path.endsWith(".dylib"));
}
class SourcePage : public WizardPage
{
public:
SourcePage(QWidget *parent)
: WizardPage(parent)
{
setTitle(PluginDialog::tr("Source"));
auto vlayout = new QVBoxLayout;
setLayout(vlayout);
auto label = new QLabel(
"<p>"
+ PluginDialog::tr(
"Choose source location. This can be a plugin library file or a zip file.")
+ "</p>");
label->setWordWrap(true);
vlayout->addWidget(label);
auto path = new PathChooser;
path->setExpectedKind(PathChooser::Any);
vlayout->addWidget(path);
registerFieldWithName(kPath, path, "path", SIGNAL(pathChanged(QString)));
connect(path, &PathChooser::pathChanged, this, &SourcePage::updateWarnings);
m_info = new InfoLabel;
m_info->setType(InfoLabel::Error);
m_info->setVisible(false);
vlayout->addWidget(m_info);
}
void updateWarnings()
{
m_info->setVisible(!isComplete());
emit completeChanged();
}
bool isComplete() const
{
const auto path = FilePath::fromVariant(field(kPath));
if (!QFile::exists(path.toString())) {
m_info->setText(PluginDialog::tr("File does not exist."));
return false;
}
if (hasLibSuffix(path))
return true;
QString error;
if (!Archive::supportsFile(path, &error)) {
m_info->setText(error);
return false;
}
return true;
}
InfoLabel *m_info = nullptr;
};
class InstallLocationPage : public WizardPage
{
public:
InstallLocationPage(QWidget *parent)
: WizardPage(parent)
{
setTitle(PluginDialog::tr("Install Location"));
auto vlayout = new QVBoxLayout;
setLayout(vlayout);
auto label = new QLabel("<p>" + PluginDialog::tr("Choose install location.") + "</p>");
label->setWordWrap(true);
vlayout->addWidget(label);
vlayout->addSpacing(10);
auto localInstall = new QRadioButton(PluginDialog::tr("User plugins"));
localInstall->setChecked(true);
auto localLabel = new QLabel(
PluginDialog::tr("The plugin will be available to all compatible %1 "
"installations, but only for the current user.")
.arg(Constants::IDE_DISPLAY_NAME));
localLabel->setWordWrap(true);
localLabel->setAttribute(Qt::WA_MacSmallSize, true);
vlayout->addWidget(localInstall);
vlayout->addWidget(localLabel);
vlayout->addSpacing(10);
auto appInstall = new QRadioButton(
PluginDialog::tr("%1 installation").arg(Constants::IDE_DISPLAY_NAME));
auto appLabel = new QLabel(
PluginDialog::tr("The plugin will be available only to this %1 "
"installation, but for all users that can access it.")
.arg(Constants::IDE_DISPLAY_NAME));
appLabel->setWordWrap(true);
appLabel->setAttribute(Qt::WA_MacSmallSize, true);
vlayout->addWidget(appInstall);
vlayout->addWidget(appLabel);
auto group = new QButtonGroup(this);
group->addButton(localInstall);
group->addButton(appInstall);
registerFieldWithName(kApplicationInstall, this);
setField(kApplicationInstall, false);
connect(appInstall, &QRadioButton::toggled, this, [this](bool toggled) {
setField(kApplicationInstall, toggled);
});
}
};
static FilePath pluginInstallPath(QWizard *wizard)
{
return FilePath::fromString(wizard->field(kApplicationInstall).toBool()
? ICore::pluginPath()
: ICore::userPluginPath());
}
static FilePath pluginFilePath(QWizard *wizard)
{
return FilePath::fromVariant(wizard->field(kPath));
}
class SummaryPage : public WizardPage
{
public:
SummaryPage(QWidget *parent)
: WizardPage(parent)
{
setTitle(PluginDialog::tr("Summary"));
auto vlayout = new QVBoxLayout;
setLayout(vlayout);
m_summaryLabel = new QLabel(this);
m_summaryLabel->setWordWrap(true);
vlayout->addWidget(m_summaryLabel);
}
void initializePage()
{
m_summaryLabel->setText(PluginDialog::tr("\"%1\" will be installed into \"%2\".")
.arg(pluginFilePath(wizard()).toUserOutput(),
pluginInstallPath(wizard()).toUserOutput()));
}
private:
QLabel *m_summaryLabel;
};
PluginDialog::PluginDialog(QWidget *parent)
: QDialog(parent),
m_view(new ExtensionSystem::PluginView(this))
@@ -298,59 +133,10 @@ void PluginDialog::closeDialog()
accept();
}
static bool copyPluginFile(const FilePath &src, const FilePath &dest)
{
const FilePath destFile = dest.pathAppended(src.fileName());
if (QFile::exists(destFile.toString())) {
QMessageBox box(QMessageBox::Question,
PluginDialog::tr("Overwrite File"),
PluginDialog::tr("The file \"%1\" exists. Overwrite?")
.arg(destFile.toUserOutput()),
QMessageBox::Cancel,
ICore::dialogParent());
QPushButton *acceptButton = box.addButton(PluginDialog::tr("Overwrite"), QMessageBox::AcceptRole);
box.setDefaultButton(acceptButton);
box.exec();
if (box.clickedButton() != acceptButton)
return false;
QFile::remove(destFile.toString());
}
QDir(dest.toString()).mkpath(".");
if (!QFile::copy(src.toString(), destFile.toString())) {
QMessageBox::warning(ICore::dialogParent(),
PluginDialog::tr("Failed to Write File"),
PluginDialog::tr("Failed to write file \"%1\".")
.arg(destFile.toUserOutput()));
return false;
}
return true;
}
void PluginDialog::showInstallWizard()
{
Wizard wizard(ICore::dialogParent());
wizard.setWindowTitle(tr("Install Plugin"));
auto filePage = new SourcePage(&wizard);
wizard.addPage(filePage);
auto installLocationPage = new InstallLocationPage(&wizard);
wizard.addPage(installLocationPage);
auto summaryPage = new SummaryPage(&wizard);
wizard.addPage(summaryPage);
if (wizard.exec()) {
const FilePath path = pluginFilePath(&wizard);
const FilePath installPath = pluginInstallPath(&wizard);
if (hasLibSuffix(path)) {
if (copyPluginFile(path, installPath))
updateRestartRequired();
} else if (Archive::supportsFile(path)) {
if (Archive::unarchive(path, installPath, ICore::dialogParent()))
updateRestartRequired();
}
}
if (PluginInstallWizard::exec())
updateRestartRequired();
}
void PluginDialog::updateRestartRequired()