2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2016 BlackBerry Limited. All rights reserved.
|
2022-12-21 10:12:09 +01:00
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
2014-02-10 14:16:55 +01:00
|
|
|
|
2014-05-27 12:46:24 +02:00
|
|
|
#include "qnxdeployqtlibrariesdialog.h"
|
2014-02-10 14:16:55 +01:00
|
|
|
|
2017-01-11 14:43:48 +01:00
|
|
|
#include "qnxconstants.h"
|
2014-05-27 12:46:24 +02:00
|
|
|
#include "qnxqtversion.h"
|
2022-07-11 14:22:42 +02:00
|
|
|
#include "qnxtr.h"
|
2014-02-10 14:16:55 +01:00
|
|
|
|
|
|
|
|
#include <projectexplorer/deployablefile.h>
|
2023-01-09 12:56:43 +01:00
|
|
|
#include <projectexplorer/devicesupport/filetransfer.h>
|
2022-04-12 21:01:45 +02:00
|
|
|
#include <projectexplorer/devicesupport/idevice.h>
|
2023-01-09 12:56:43 +01:00
|
|
|
|
2014-02-10 14:16:55 +01:00
|
|
|
#include <qtsupport/qtversionmanager.h>
|
2017-01-11 14:43:48 +01:00
|
|
|
|
|
|
|
|
#include <utils/algorithm.h>
|
2023-01-09 12:56:43 +01:00
|
|
|
#include <utils/hostosinfo.h>
|
2022-07-21 10:01:05 +02:00
|
|
|
#include <utils/layoutbuilder.h>
|
2023-01-09 12:56:43 +01:00
|
|
|
#include <utils/processinterface.h>
|
2014-02-10 14:16:55 +01:00
|
|
|
#include <utils/qtcassert.h>
|
2023-01-09 12:56:43 +01:00
|
|
|
#include <utils/qtcprocess.h>
|
2014-02-10 14:16:55 +01:00
|
|
|
|
2022-07-11 12:29:52 +02:00
|
|
|
#include <QComboBox>
|
2014-02-10 14:16:55 +01:00
|
|
|
#include <QDir>
|
2022-07-11 12:29:52 +02:00
|
|
|
#include <QLabel>
|
|
|
|
|
#include <QLineEdit>
|
2014-02-10 14:16:55 +01:00
|
|
|
#include <QMessageBox>
|
2022-07-11 12:29:52 +02:00
|
|
|
#include <QPlainTextEdit>
|
|
|
|
|
#include <QProgressBar>
|
|
|
|
|
#include <QPushButton>
|
2014-02-10 14:16:55 +01:00
|
|
|
|
2016-03-15 09:26:34 +01:00
|
|
|
using namespace ProjectExplorer;
|
2022-05-04 19:08:32 +02:00
|
|
|
using namespace QtSupport;
|
|
|
|
|
using namespace Utils;
|
2023-01-09 12:56:43 +01:00
|
|
|
using namespace Utils::Tasking;
|
2015-04-24 10:31:27 +02:00
|
|
|
|
2022-07-21 09:19:41 +02:00
|
|
|
namespace Qnx::Internal {
|
2015-04-24 10:31:27 +02:00
|
|
|
|
2023-01-09 12:56:43 +01:00
|
|
|
const int MaxConcurrentStatCalls = 10;
|
|
|
|
|
|
|
|
|
|
class QnxDeployQtLibrariesDialogPrivate : public QObject
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
QnxDeployQtLibrariesDialogPrivate(QnxDeployQtLibrariesDialog *parent,
|
|
|
|
|
const IDevice::ConstPtr &device);
|
|
|
|
|
|
2023-01-26 16:09:13 +01:00
|
|
|
void start();
|
|
|
|
|
void stop();
|
|
|
|
|
|
2023-01-09 12:56:43 +01:00
|
|
|
void updateProgress(const QString &progressMessage);
|
|
|
|
|
void handleUploadFinished();
|
|
|
|
|
|
|
|
|
|
QList<ProjectExplorer::DeployableFile> gatherFiles();
|
|
|
|
|
QList<ProjectExplorer::DeployableFile> gatherFiles(const QString &dirPath,
|
|
|
|
|
const QString &baseDir = {},
|
|
|
|
|
const QStringList &nameFilters = {});
|
|
|
|
|
|
2023-01-26 16:09:13 +01:00
|
|
|
QString fullRemoteDirectory() const { return m_remoteDirectory->text(); }
|
2023-01-09 12:56:43 +01:00
|
|
|
|
|
|
|
|
QnxDeployQtLibrariesDialog *q;
|
|
|
|
|
|
|
|
|
|
QComboBox *m_qtLibraryCombo;
|
|
|
|
|
QPushButton *m_deployButton;
|
|
|
|
|
QLabel *m_basePathLabel;
|
|
|
|
|
QLineEdit *m_remoteDirectory;
|
|
|
|
|
QProgressBar *m_deployProgress;
|
|
|
|
|
QPlainTextEdit *m_deployLogWindow;
|
|
|
|
|
QPushButton *m_closeButton;
|
|
|
|
|
|
|
|
|
|
ProjectExplorer::IDeviceConstPtr m_device;
|
|
|
|
|
|
|
|
|
|
int m_progressCount = 0;
|
|
|
|
|
|
|
|
|
|
void emitProgressMessage(const QString &msg)
|
|
|
|
|
{
|
|
|
|
|
updateProgress(msg);
|
|
|
|
|
m_deployLogWindow->appendPlainText(msg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void emitErrorMessage(const QString &msg)
|
|
|
|
|
{
|
|
|
|
|
m_deployLogWindow->appendPlainText(msg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void emitWarningMessage(const QString &message)
|
|
|
|
|
{
|
|
|
|
|
if (!message.contains("stat:"))
|
|
|
|
|
m_deployLogWindow->appendPlainText(message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Group deployRecipe();
|
2023-01-26 16:09:13 +01:00
|
|
|
TaskItem checkDirTask();
|
|
|
|
|
TaskItem removeDirTask();
|
2023-01-09 12:56:43 +01:00
|
|
|
TaskItem uploadTask();
|
|
|
|
|
TaskItem chmodTask(const DeployableFile &file);
|
|
|
|
|
TaskItem chmodTree();
|
|
|
|
|
|
2023-01-26 16:09:13 +01:00
|
|
|
enum class CheckResult { RemoveDir, SkipRemoveDir, Abort };
|
|
|
|
|
CheckResult m_checkResult = CheckResult::Abort;
|
2023-01-09 12:56:43 +01:00
|
|
|
mutable QList<DeployableFile> m_deployableFiles;
|
|
|
|
|
std::unique_ptr<TaskTree> m_taskTree;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
QList<DeployableFile> collectFilesToUpload(const DeployableFile &deployable)
|
|
|
|
|
{
|
|
|
|
|
QList<DeployableFile> collected;
|
|
|
|
|
FilePath localFile = deployable.localFilePath();
|
|
|
|
|
if (localFile.isDir()) {
|
|
|
|
|
const FilePaths files = localFile.dirEntries(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
|
|
|
|
|
const QString remoteDir = deployable.remoteDirectory() + '/' + localFile.fileName();
|
|
|
|
|
for (const FilePath &localFilePath : files)
|
|
|
|
|
collected.append(collectFilesToUpload(DeployableFile(localFilePath, remoteDir)));
|
|
|
|
|
} else {
|
|
|
|
|
collected << deployable;
|
|
|
|
|
}
|
|
|
|
|
return collected;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-26 16:09:13 +01:00
|
|
|
TaskItem QnxDeployQtLibrariesDialogPrivate::checkDirTask()
|
2023-01-09 12:56:43 +01:00
|
|
|
{
|
2023-01-26 16:09:13 +01:00
|
|
|
const auto setupHandler = [this](QtcProcess &process) {
|
|
|
|
|
m_deployLogWindow->appendPlainText(Tr::tr("Checking existence of \"%1\"")
|
|
|
|
|
.arg(fullRemoteDirectory()));
|
|
|
|
|
process.setCommand({m_device->filePath("test"), {"-d", fullRemoteDirectory()}});
|
2023-01-09 12:56:43 +01:00
|
|
|
};
|
2023-01-26 16:09:13 +01:00
|
|
|
const auto doneHandler = [this](const QtcProcess &process) {
|
|
|
|
|
Q_UNUSED(process)
|
|
|
|
|
const int answer = QMessageBox::question(q, q->windowTitle(),
|
|
|
|
|
Tr::tr("The remote directory \"%1\" already exists.\n"
|
|
|
|
|
"Deploying to that directory will remove any files already present.\n\n"
|
|
|
|
|
"Are you sure you want to continue?").arg(fullRemoteDirectory()),
|
|
|
|
|
QMessageBox::Yes | QMessageBox::No);
|
|
|
|
|
m_checkResult = answer == QMessageBox::Yes ? CheckResult::RemoveDir : CheckResult::Abort;
|
|
|
|
|
};
|
|
|
|
|
const auto errorHandler = [this](const QtcProcess &process) {
|
|
|
|
|
if (process.result() != ProcessResult::FinishedWithError) {
|
|
|
|
|
m_deployLogWindow->appendPlainText(Tr::tr("Connection failed: %1")
|
|
|
|
|
.arg(process.errorString()));
|
|
|
|
|
m_checkResult = CheckResult::Abort;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
m_checkResult = CheckResult::SkipRemoveDir;
|
|
|
|
|
};
|
|
|
|
|
return Process(setupHandler, doneHandler, errorHandler);
|
2023-01-09 12:56:43 +01:00
|
|
|
}
|
|
|
|
|
|
2023-01-26 16:09:13 +01:00
|
|
|
TaskItem QnxDeployQtLibrariesDialogPrivate::removeDirTask()
|
2023-01-09 12:56:43 +01:00
|
|
|
{
|
2023-01-26 16:09:13 +01:00
|
|
|
const auto setupHandler = [this](QtcProcess &process) {
|
|
|
|
|
if (m_checkResult != CheckResult::RemoveDir)
|
|
|
|
|
return TaskAction::StopWithDone;
|
|
|
|
|
m_deployLogWindow->appendPlainText(Tr::tr("Removing \"%1\"").arg(fullRemoteDirectory()));
|
|
|
|
|
process.setCommand({m_device->filePath("rm"), {"-rf", fullRemoteDirectory()}});
|
|
|
|
|
return TaskAction::Continue;
|
|
|
|
|
};
|
|
|
|
|
const auto errorHandler = [this](const QtcProcess &process) {
|
|
|
|
|
QTC_ASSERT(process.exitCode() == 0, return);
|
|
|
|
|
m_deployLogWindow->appendPlainText(Tr::tr("Connection failed: %1")
|
|
|
|
|
.arg(process.errorString()));
|
|
|
|
|
};
|
|
|
|
|
return Process(setupHandler, {}, errorHandler);
|
2023-01-09 12:56:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TaskItem QnxDeployQtLibrariesDialogPrivate::uploadTask()
|
|
|
|
|
{
|
|
|
|
|
const auto setupHandler = [this](FileTransfer &transfer) {
|
|
|
|
|
if (m_deployableFiles.isEmpty()) {
|
|
|
|
|
emitProgressMessage(Tr::tr("No files need to be uploaded."));
|
|
|
|
|
return TaskAction::StopWithDone;
|
|
|
|
|
}
|
|
|
|
|
emitProgressMessage(Tr::tr("%n file(s) need to be uploaded.", "",
|
|
|
|
|
m_deployableFiles.size()));
|
|
|
|
|
FilesToTransfer files;
|
|
|
|
|
for (const DeployableFile &file : std::as_const(m_deployableFiles)) {
|
|
|
|
|
if (!file.localFilePath().exists()) {
|
|
|
|
|
const QString message = Tr::tr("Local file \"%1\" does not exist.")
|
|
|
|
|
.arg(file.localFilePath().toUserOutput());
|
|
|
|
|
emitErrorMessage(message);
|
|
|
|
|
return TaskAction::StopWithError;
|
|
|
|
|
}
|
|
|
|
|
files.append({file.localFilePath(), m_device->filePath(file.remoteFilePath())});
|
|
|
|
|
}
|
|
|
|
|
if (files.isEmpty()) {
|
|
|
|
|
emitProgressMessage(Tr::tr("No files need to be uploaded."));
|
|
|
|
|
return TaskAction::StopWithDone;
|
|
|
|
|
}
|
|
|
|
|
transfer.setFilesToTransfer(files);
|
|
|
|
|
QObject::connect(&transfer, &FileTransfer::progress,
|
|
|
|
|
this, &QnxDeployQtLibrariesDialogPrivate::emitProgressMessage);
|
|
|
|
|
return TaskAction::Continue;
|
|
|
|
|
};
|
|
|
|
|
const auto errorHandler = [this](const FileTransfer &transfer) {
|
|
|
|
|
emitErrorMessage(transfer.resultData().m_errorString);
|
|
|
|
|
};
|
|
|
|
|
return Transfer(setupHandler, {}, errorHandler);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TaskItem QnxDeployQtLibrariesDialogPrivate::chmodTask(const DeployableFile &file)
|
|
|
|
|
{
|
|
|
|
|
const auto setupHandler = [=](QtcProcess &process) {
|
|
|
|
|
process.setCommand({m_device->filePath("chmod"),
|
|
|
|
|
{"a+x", Utils::ProcessArgs::quoteArgUnix(file.remoteFilePath())}});
|
|
|
|
|
};
|
|
|
|
|
const auto errorHandler = [=](const QtcProcess &process) {
|
|
|
|
|
const QString error = process.errorString();
|
|
|
|
|
if (!error.isEmpty()) {
|
|
|
|
|
emitWarningMessage(Tr::tr("Remote chmod failed for file \"%1\": %2")
|
|
|
|
|
.arg(file.remoteFilePath(), error));
|
|
|
|
|
} else if (process.exitCode() != 0) {
|
|
|
|
|
emitWarningMessage(Tr::tr("Remote chmod failed for file \"%1\": %2")
|
|
|
|
|
.arg(file.remoteFilePath(), process.cleanedStdErr()));
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
return Process(setupHandler, {}, errorHandler);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TaskItem QnxDeployQtLibrariesDialogPrivate::chmodTree()
|
|
|
|
|
{
|
|
|
|
|
const auto setupChmodHandler = [=](TaskTree &tree) {
|
|
|
|
|
QList<DeployableFile> filesToChmod;
|
|
|
|
|
for (const DeployableFile &file : std::as_const(m_deployableFiles)) {
|
|
|
|
|
if (file.isExecutable())
|
|
|
|
|
filesToChmod << file;
|
|
|
|
|
}
|
|
|
|
|
QList<TaskItem> chmodList{optional, ParallelLimit(MaxConcurrentStatCalls)};
|
|
|
|
|
for (const DeployableFile &file : std::as_const(filesToChmod)) {
|
|
|
|
|
QTC_ASSERT(file.isValid(), continue);
|
|
|
|
|
chmodList.append(chmodTask(file));
|
|
|
|
|
}
|
|
|
|
|
tree.setupRoot(chmodList);
|
|
|
|
|
};
|
|
|
|
|
return Tree{setupChmodHandler};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Group QnxDeployQtLibrariesDialogPrivate::deployRecipe()
|
|
|
|
|
{
|
|
|
|
|
const auto setupHandler = [this] {
|
|
|
|
|
if (!m_device) {
|
|
|
|
|
emitErrorMessage(Tr::tr("No device configuration set."));
|
|
|
|
|
return TaskAction::StopWithError;
|
|
|
|
|
}
|
|
|
|
|
QList<DeployableFile> collected;
|
|
|
|
|
for (int i = 0; i < m_deployableFiles.count(); ++i)
|
|
|
|
|
collected.append(collectFilesToUpload(m_deployableFiles.at(i)));
|
|
|
|
|
|
|
|
|
|
QTC_CHECK(collected.size() >= m_deployableFiles.size());
|
|
|
|
|
m_deployableFiles = collected;
|
|
|
|
|
if (!m_deployableFiles.isEmpty())
|
|
|
|
|
return TaskAction::Continue;
|
|
|
|
|
|
|
|
|
|
emitProgressMessage(Tr::tr("No deployment action necessary. Skipping."));
|
|
|
|
|
return TaskAction::StopWithDone;
|
|
|
|
|
};
|
|
|
|
|
const auto doneHandler = [this] {
|
|
|
|
|
emitProgressMessage(Tr::tr("All files successfully deployed."));
|
|
|
|
|
};
|
2023-01-26 16:09:13 +01:00
|
|
|
const auto subGroupSetupHandler = [this] {
|
|
|
|
|
if (m_checkResult == CheckResult::Abort)
|
|
|
|
|
return TaskAction::StopWithError;
|
|
|
|
|
return TaskAction::Continue;
|
|
|
|
|
};
|
2023-01-09 12:56:43 +01:00
|
|
|
const Group root {
|
|
|
|
|
OnGroupSetup(setupHandler),
|
2023-01-26 16:09:13 +01:00
|
|
|
Group {
|
|
|
|
|
optional,
|
|
|
|
|
checkDirTask()
|
|
|
|
|
},
|
|
|
|
|
Group {
|
|
|
|
|
OnGroupSetup(subGroupSetupHandler),
|
|
|
|
|
removeDirTask(),
|
|
|
|
|
uploadTask(),
|
|
|
|
|
chmodTree()
|
|
|
|
|
},
|
2023-01-09 12:56:43 +01:00
|
|
|
OnGroupDone(doneHandler)
|
|
|
|
|
};
|
|
|
|
|
return root;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-26 16:09:13 +01:00
|
|
|
void QnxDeployQtLibrariesDialogPrivate::start()
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(m_device, return);
|
|
|
|
|
QTC_ASSERT(!m_taskTree, return);
|
|
|
|
|
if (m_remoteDirectory->text().isEmpty()) {
|
|
|
|
|
QMessageBox::warning(q, q->windowTitle(),
|
|
|
|
|
Tr::tr("Please input a remote directory to deploy to."));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_progressCount = 0;
|
|
|
|
|
m_deployProgress->setValue(0);
|
|
|
|
|
m_remoteDirectory->setEnabled(false);
|
|
|
|
|
m_deployButton->setEnabled(false);
|
|
|
|
|
m_qtLibraryCombo->setEnabled(false);
|
|
|
|
|
m_deployLogWindow->clear();
|
|
|
|
|
|
|
|
|
|
m_checkResult = CheckResult::Abort;
|
|
|
|
|
|
|
|
|
|
m_deployableFiles = gatherFiles();
|
|
|
|
|
m_deployProgress->setRange(0, m_deployableFiles.count());
|
|
|
|
|
|
|
|
|
|
m_taskTree.reset(new TaskTree(deployRecipe()));
|
|
|
|
|
const auto endHandler = [this] {
|
|
|
|
|
m_taskTree.release()->deleteLater();
|
|
|
|
|
handleUploadFinished();
|
|
|
|
|
};
|
|
|
|
|
connect(m_taskTree.get(), &TaskTree::done, this, endHandler);
|
|
|
|
|
connect(m_taskTree.get(), &TaskTree::errorOccurred, this, endHandler);
|
|
|
|
|
m_taskTree->start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QnxDeployQtLibrariesDialogPrivate::stop()
|
|
|
|
|
{
|
|
|
|
|
if (!m_taskTree)
|
|
|
|
|
return;
|
|
|
|
|
m_taskTree.reset();
|
|
|
|
|
handleUploadFinished();
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-15 09:26:34 +01:00
|
|
|
QnxDeployQtLibrariesDialog::QnxDeployQtLibrariesDialog(const IDevice::ConstPtr &device,
|
2022-05-04 19:08:32 +02:00
|
|
|
QWidget *parent)
|
2023-01-09 12:56:43 +01:00
|
|
|
: QDialog(parent), d(new QnxDeployQtLibrariesDialogPrivate(this, device))
|
2014-02-10 14:16:55 +01:00
|
|
|
{
|
2022-07-11 14:22:42 +02:00
|
|
|
setWindowTitle(Tr::tr("Deploy Qt to QNX Device"));
|
2023-01-09 12:56:43 +01:00
|
|
|
}
|
2014-02-10 14:16:55 +01:00
|
|
|
|
2023-01-09 12:56:43 +01:00
|
|
|
QnxDeployQtLibrariesDialogPrivate::QnxDeployQtLibrariesDialogPrivate(
|
|
|
|
|
QnxDeployQtLibrariesDialog *parent, const IDevice::ConstPtr &device)
|
|
|
|
|
: q(parent), m_device(device)
|
|
|
|
|
{
|
|
|
|
|
m_qtLibraryCombo = new QComboBox(q);
|
2022-05-04 19:08:32 +02:00
|
|
|
const QList<QtVersion*> qtVersions = QtVersionManager::sortVersions(
|
|
|
|
|
QtVersionManager::versions(QtVersion::isValidPredicate(
|
|
|
|
|
equal(&QtVersion::type, QString::fromLatin1(Constants::QNX_QNX_QT)))));
|
2022-01-21 16:06:36 +01:00
|
|
|
for (QtVersion *v : qtVersions)
|
2022-07-11 12:29:52 +02:00
|
|
|
m_qtLibraryCombo->addItem(v->displayName(), v->uniqueId());
|
2014-02-10 14:16:55 +01:00
|
|
|
|
2023-01-09 12:56:43 +01:00
|
|
|
m_deployButton = new QPushButton(Tr::tr("Deploy"), q);
|
2022-07-11 12:29:52 +02:00
|
|
|
m_deployButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
|
|
|
|
|
2023-01-09 12:56:43 +01:00
|
|
|
m_basePathLabel = new QLabel(q);
|
2022-07-11 12:29:52 +02:00
|
|
|
|
2023-01-09 12:56:43 +01:00
|
|
|
m_remoteDirectory = new QLineEdit(q);
|
2022-07-11 12:29:52 +02:00
|
|
|
m_remoteDirectory->setText(QLatin1String("/qt"));
|
|
|
|
|
|
2023-01-09 12:56:43 +01:00
|
|
|
m_deployProgress = new QProgressBar(q);
|
2022-07-11 12:29:52 +02:00
|
|
|
m_deployProgress->setValue(0);
|
|
|
|
|
m_deployProgress->setTextVisible(true);
|
|
|
|
|
|
2023-01-09 12:56:43 +01:00
|
|
|
m_deployLogWindow = new QPlainTextEdit(q);
|
2014-05-27 12:46:24 +02:00
|
|
|
|
2023-01-09 12:56:43 +01:00
|
|
|
m_closeButton = new QPushButton(Tr::tr("Close"), q);
|
2014-02-10 14:16:55 +01:00
|
|
|
|
2022-07-21 10:01:05 +02:00
|
|
|
using namespace Layouting;
|
|
|
|
|
|
|
|
|
|
Column {
|
|
|
|
|
Form {
|
|
|
|
|
Tr::tr("Qt library to deploy:"), m_qtLibraryCombo, m_deployButton, br,
|
|
|
|
|
Tr::tr("Remote directory:"), m_basePathLabel, m_remoteDirectory, br
|
|
|
|
|
},
|
|
|
|
|
m_deployProgress,
|
|
|
|
|
m_deployLogWindow,
|
|
|
|
|
Row { st, m_closeButton }
|
2023-01-09 12:56:43 +01:00
|
|
|
}.attachTo(q);
|
2014-02-10 14:16:55 +01:00
|
|
|
|
2022-07-11 12:29:52 +02:00
|
|
|
connect(m_deployButton, &QAbstractButton::clicked,
|
2023-01-26 16:09:13 +01:00
|
|
|
this, &QnxDeployQtLibrariesDialogPrivate::start);
|
2022-07-11 12:29:52 +02:00
|
|
|
connect(m_closeButton, &QAbstractButton::clicked,
|
2023-01-09 12:56:43 +01:00
|
|
|
q, &QWidget::close);
|
2014-02-10 14:16:55 +01:00
|
|
|
}
|
|
|
|
|
|
2023-01-09 12:56:43 +01:00
|
|
|
QnxDeployQtLibrariesDialog::~QnxDeployQtLibrariesDialog()
|
|
|
|
|
{
|
|
|
|
|
delete d;
|
|
|
|
|
}
|
2014-02-10 14:16:55 +01:00
|
|
|
|
2014-05-27 12:46:24 +02:00
|
|
|
int QnxDeployQtLibrariesDialog::execAndDeploy(int qtVersionId, const QString &remoteDirectory)
|
2014-02-10 14:16:55 +01:00
|
|
|
{
|
2023-01-09 12:56:43 +01:00
|
|
|
d->m_remoteDirectory->setText(remoteDirectory);
|
|
|
|
|
d->m_qtLibraryCombo->setCurrentIndex(d->m_qtLibraryCombo->findData(qtVersionId));
|
2014-02-10 14:16:55 +01:00
|
|
|
|
2023-01-26 16:09:13 +01:00
|
|
|
d->start();
|
2014-02-10 14:16:55 +01:00
|
|
|
return exec();
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-27 12:46:24 +02:00
|
|
|
void QnxDeployQtLibrariesDialog::closeEvent(QCloseEvent *event)
|
2014-02-10 14:16:55 +01:00
|
|
|
{
|
|
|
|
|
// A disabled Deploy button indicates the upload is still running
|
2023-01-09 12:56:43 +01:00
|
|
|
if (!d->m_deployButton->isEnabled()) {
|
2022-05-04 19:08:32 +02:00
|
|
|
const int answer = QMessageBox::question(this, windowTitle(),
|
2022-07-11 14:22:42 +02:00
|
|
|
Tr::tr("Closing the dialog will stop the deployment. Are you sure you want to do this?"),
|
2022-05-04 19:08:32 +02:00
|
|
|
QMessageBox::Yes | QMessageBox::No);
|
2014-02-10 14:16:55 +01:00
|
|
|
if (answer == QMessageBox::No)
|
|
|
|
|
event->ignore();
|
|
|
|
|
else if (answer == QMessageBox::Yes)
|
2023-01-09 12:56:43 +01:00
|
|
|
d->stop();
|
2014-02-10 14:16:55 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-09 12:56:43 +01:00
|
|
|
void QnxDeployQtLibrariesDialogPrivate::updateProgress(const QString &progressMessage)
|
2014-02-10 14:16:55 +01:00
|
|
|
{
|
2022-04-01 13:25:06 +10:00
|
|
|
const int progress = progressMessage.count("sftp> put") + progressMessage.count("sftp> ln -s");
|
2019-10-01 15:07:40 +02:00
|
|
|
if (progress != 0) {
|
|
|
|
|
m_progressCount += progress;
|
2022-07-11 12:29:52 +02:00
|
|
|
m_deployProgress->setValue(m_progressCount);
|
2019-10-01 15:07:40 +02:00
|
|
|
}
|
2014-02-10 14:16:55 +01:00
|
|
|
}
|
|
|
|
|
|
2023-01-09 12:56:43 +01:00
|
|
|
void QnxDeployQtLibrariesDialogPrivate::handleUploadFinished()
|
2014-02-10 14:16:55 +01:00
|
|
|
{
|
2022-07-11 12:29:52 +02:00
|
|
|
m_remoteDirectory->setEnabled(true);
|
|
|
|
|
m_deployButton->setEnabled(true);
|
|
|
|
|
m_qtLibraryCombo->setEnabled(true);
|
2014-02-10 14:16:55 +01:00
|
|
|
}
|
|
|
|
|
|
2023-01-09 12:56:43 +01:00
|
|
|
QList<DeployableFile> QnxDeployQtLibrariesDialogPrivate::gatherFiles()
|
2014-02-10 14:16:55 +01:00
|
|
|
{
|
2016-03-15 09:26:34 +01:00
|
|
|
QList<DeployableFile> result;
|
2014-02-10 14:16:55 +01:00
|
|
|
|
2022-07-11 12:29:52 +02:00
|
|
|
const int qtVersionId = m_qtLibraryCombo->itemData(m_qtLibraryCombo->currentIndex()).toInt();
|
2014-05-27 12:46:24 +02:00
|
|
|
|
2018-11-24 15:03:28 +01:00
|
|
|
auto qtVersion = dynamic_cast<const QnxQtVersion *>(QtVersionManager::version(qtVersionId));
|
2014-02-10 14:16:55 +01:00
|
|
|
|
|
|
|
|
QTC_ASSERT(qtVersion, return result);
|
|
|
|
|
|
2022-05-04 19:08:32 +02:00
|
|
|
if (HostOsInfo::isWindowsHost()) {
|
2023-01-09 12:56:43 +01:00
|
|
|
result.append(gatherFiles(qtVersion->libraryPath().toString(), {}, {{"*.so.?"}}));
|
2019-09-30 14:34:31 +02:00
|
|
|
result.append(gatherFiles(qtVersion->libraryPath().toString() + QLatin1String("/fonts")));
|
2014-12-04 11:45:06 -02:00
|
|
|
} else {
|
2019-09-30 14:34:31 +02:00
|
|
|
result.append(gatherFiles(qtVersion->libraryPath().toString()));
|
2014-12-04 11:45:06 -02:00
|
|
|
}
|
|
|
|
|
|
2019-09-30 14:34:31 +02:00
|
|
|
result.append(gatherFiles(qtVersion->pluginPath().toString()));
|
|
|
|
|
result.append(gatherFiles(qtVersion->importsPath().toString()));
|
2017-09-27 16:10:13 +02:00
|
|
|
result.append(gatherFiles(qtVersion->qmlPath().toString()));
|
2014-02-10 14:16:55 +01:00
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-09 12:56:43 +01:00
|
|
|
QList<DeployableFile> QnxDeployQtLibrariesDialogPrivate::gatherFiles(
|
2014-12-04 11:45:06 -02:00
|
|
|
const QString &dirPath, const QString &baseDirPath, const QStringList &nameFilters)
|
2014-02-10 14:16:55 +01:00
|
|
|
{
|
2016-03-15 09:26:34 +01:00
|
|
|
QList<DeployableFile> result;
|
2014-02-13 10:46:14 +01:00
|
|
|
if (dirPath.isEmpty())
|
|
|
|
|
return result;
|
|
|
|
|
|
2019-06-21 13:51:56 +02:00
|
|
|
static const QStringList unusedDirs = {"include", "mkspecs", "cmake", "pkgconfig"};
|
|
|
|
|
const QString dp = dirPath.endsWith('/') ? dirPath.left(dirPath.size() - 1) : dirPath;
|
|
|
|
|
if (unusedDirs.contains(dp))
|
|
|
|
|
return result;
|
|
|
|
|
|
2022-05-04 19:08:32 +02:00
|
|
|
const QDir dir(dirPath);
|
2023-01-26 16:09:13 +01:00
|
|
|
const QFileInfoList list = dir.entryInfoList(nameFilters,
|
|
|
|
|
QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
|
|
|
|
|
for (const QFileInfo &fileInfo : list) {
|
2014-02-10 14:16:55 +01:00
|
|
|
if (fileInfo.isDir()) {
|
|
|
|
|
result.append(gatherFiles(fileInfo.absoluteFilePath(), baseDirPath.isEmpty() ?
|
|
|
|
|
dirPath : baseDirPath));
|
|
|
|
|
} else {
|
2019-06-21 13:51:56 +02:00
|
|
|
static const QStringList unusedSuffixes = {"cmake", "la", "prl", "a", "pc"};
|
|
|
|
|
if (unusedSuffixes.contains(fileInfo.suffix()))
|
|
|
|
|
continue;
|
|
|
|
|
|
2014-02-10 14:16:55 +01:00
|
|
|
QString remoteDir;
|
|
|
|
|
if (baseDirPath.isEmpty()) {
|
2023-01-26 16:09:13 +01:00
|
|
|
remoteDir = fullRemoteDirectory() + '/' + QFileInfo(dirPath).baseName();
|
2014-02-10 14:16:55 +01:00
|
|
|
} else {
|
|
|
|
|
QDir baseDir(baseDirPath);
|
|
|
|
|
baseDir.cdUp();
|
2023-01-26 16:09:13 +01:00
|
|
|
remoteDir = fullRemoteDirectory() + '/' + baseDir.relativeFilePath(dirPath);
|
2014-02-10 14:16:55 +01:00
|
|
|
}
|
2022-05-04 19:08:32 +02:00
|
|
|
result.append(DeployableFile(FilePath::fromString(fileInfo.absoluteFilePath()),
|
2021-09-13 12:55:01 +02:00
|
|
|
remoteDir));
|
2014-02-10 14:16:55 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-21 09:19:41 +02:00
|
|
|
} // Qnx::Internal
|