6 #include <QDesktopServices>
10 #include <QMessageBox>
12 #include <QStandardPaths>
15 #include "ui_installxswiftbuscomponent.h"
26 using namespace swift::config;
28 using namespace swift::misc::db;
29 using namespace swift::misc::network;
30 using namespace swift::misc::simulation;
31 using namespace swift::misc::simulation::settings;
32 using namespace swift::misc::simulation::xplane;
36 CInstallXSwiftBusComponent::CInstallXSwiftBusComponent(QWidget *parent)
41 ui->le_XSwiftBusPluginDir->setText(this->getXPlanePluginDirectory());
42 ui->le_DownloadDir->setText(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
43 ui->cb_DownloadFile->setEnabled(
false);
45 connect(ui->tb_DialogInstallDir, &QPushButton::pressed,
this,
46 &CInstallXSwiftBusComponent::selectPluginDirectory);
47 connect(ui->tb_DialogDownloadDir, &QPushButton::pressed,
this,
48 &CInstallXSwiftBusComponent::selectDownloadDirectory);
49 connect(ui->pb_Download, &QPushButton::pressed,
this,
50 &CInstallXSwiftBusComponent::triggerDownloadingOfXSwiftBusFile);
51 connect(ui->pb_OpenDownloadDir, &QPushButton::pressed,
this, &CInstallXSwiftBusComponent::openDownloadDir);
52 connect(ui->pb_OpenInstallDir, &QPushButton::pressed,
this, &CInstallXSwiftBusComponent::openInstallDir);
55 this->updatesChanged();
62 m_defaultDownloadName = defaultDownload;
63 this->updatesChanged();
66 void CInstallXSwiftBusComponent::selectPluginDirectory()
68 QString xPlanePluginDir = CFileUtils::fixWindowsUncPath(ui->le_XSwiftBusPluginDir->text().trimmed());
69 xPlanePluginDir = QFileDialog::getExistingDirectory(parentWidget(), tr(
"Choose your X-Plane plugin directory"),
70 xPlanePluginDir, m_fileDialogOptions);
72 if (xPlanePluginDir.isEmpty()) {
return; }
73 if (!QDir(xPlanePluginDir).exists())
76 .
warning(u
"'%1' is not a valid X-Plane plugin directory")
81 ui->le_XSwiftBusPluginDir->setText(xPlanePluginDir);
84 void CInstallXSwiftBusComponent::selectDownloadDirectory()
86 QString downloadDir = CFileUtils::fixWindowsUncPath(ui->le_DownloadDir->text().trimmed());
87 downloadDir = QFileDialog::getExistingDirectory(parentWidget(), tr(
"Choose your X-Plane plugin directory"),
88 downloadDir, m_fileDialogOptions);
90 if (downloadDir.isEmpty()) {
return; }
91 if (!QDir(downloadDir).exists())
99 ui->le_DownloadDir->setText(downloadDir);
102 void CInstallXSwiftBusComponent::installXSwiftBus()
104 const CRemoteFile rf = this->getRemoteFileSelected();
105 const QString downloadFileName = CFileUtils::appendFilePathsAndFixUnc(this->downloadDir(), rf.
getBaseName());
106 QPointer<CInstallXSwiftBusComponent> myself(
this);
107 QFile downloadFile(downloadFileName);
109 if (!downloadFile.exists())
112 CStatusMessage(
this, CLogCategories::validation()).
error(u
"Cannot read downloaded file '%1'")
118 const QString xSwiftBusDirectory = this->xSwiftBusDir();
119 if (xSwiftBusDirectory.isEmpty())
127 const QDir installDir(xSwiftBusDirectory);
128 if (!installDir.exists())
132 << xSwiftBusDirectory;
137 const QString destFileName = CFileUtils::appendFilePathsAndFixUnc(xSwiftBusDirectory, rf.
getBaseName());
139 QFile destFile(destFileName);
140 if (destFile.exists())
142 const bool removed = destFile.remove();
146 CStatusMessage(
this, CLogCategories::validation()).
error(u
"Cannot remove '%1'") << destFileName;
153 const bool copied = QFile::copy(downloadFileName, destFileName);
158 << downloadFileName << destFileName;
164 const QFileInfo destFile(destFileName);
165 if (!destFile.exists())
168 CStatusMessage(
this, CLogCategories::validation()).
error(u
"xswiftbus file '%1' does not exist")
175 QStringList stdOutAndError;
176 if (CCompressUtils::zip7Uncompress(destFile.absoluteFilePath(), xSwiftBusDirectory, &stdOutAndError))
180 CStatusMessage(
this, CLogCategories::validation()).
info(u
"Uncompressed xswiftbus in '%1'")
181 << xSwiftBusDirectory;
183 if (!myself) {
return; }
184 QFile downloadFile(downloadFileName);
185 if (!downloadFile.exists()) {
return; }
186 const bool removed = downloadFile.remove();
195 <<
safeAt(stdOutAndError, 0) <<
safeAt(stdOutAndError, 1);
200 const QMessageBox::StandardButton reply =
201 QMessageBox::question(
this,
"Install XSwiftXBus",
202 "You need to manually unzip xswiftbus into the plugins directory.\nIt needs to look "
203 "like 'plugin/xswiftbus'.\n\nOpen the archive?",
204 QMessageBox::Yes | QMessageBox::No);
206 if (reply == QMessageBox::Yes) { QDesktopServices::openUrl(QUrl::fromLocalFile(destFile.absoluteFilePath())); }
209 void CInstallXSwiftBusComponent::triggerDownloadingOfXSwiftBusFile()
211 using namespace std::chrono_literals;
213 const CRemoteFile rf = this->getRemoteFileSelected();
214 if (!rf.
getBaseName().contains(CBuildConfig::getVersionString()))
216 const QMessageBox::StandardButton reply = QMessageBox::question(
217 this,
"Download xswiftbus",
218 QStringLiteral(u
"The xswiftbus versions seems to be for a different version\n"
219 u
"Your version is '%1'. Use this version.\n\n"
220 u
"If not available, you can try the version next to your version number.\n\n"
221 u
"Continue with this version?")
222 .arg(CBuildConfig::getVersionString()),
223 QMessageBox::Yes | QMessageBox::No);
224 if (reply != QMessageBox::Yes) {
return; }
227 if (!this->existsDownloadDir())
239 CStatusMessage(
this, CLogCategories::validation()).
error(u
"No download URL for file name '%1'")
245 const QString saveAsFile = CFileUtils::appendFilePathsAndFixUnc(ui->le_DownloadDir->text(), rf.
getBaseName());
246 const QFile saveFile(saveAsFile);
247 if (saveFile.exists())
249 const QMessageBox::StandardButton reply = QMessageBox::question(
250 this,
"The file already exists",
"Do you want to use the existing '" + saveAsFile +
"'?",
251 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
252 if (reply == QMessageBox::Cancel) {
return; }
253 if (reply == QMessageBox::Yes)
256 const QPointer<CInstallXSwiftBusComponent> guard(
this);
258 if (guard.isNull()) { return; }
259 this->downloadedXSwiftBusFile(msg);
266 download, saveAsFile, {
this, &CInstallXSwiftBusComponent::downloadedXSwiftBusFile });
275 CStatusMessage(
this, CLogCategories::validation()).
error(u
"Starting download for '%1' failed")
281 void CInstallXSwiftBusComponent::downloadedXSwiftBusFile(
const CStatusMessage &status)
290 if (!this->existsXSwiftBusPluginDir())
297 static const QString confirm(
"Install in '%1'?");
299 QTimer::singleShot(0, this, &CInstallXSwiftBusComponent::installXSwiftBus);
303 CRemoteFile CInstallXSwiftBusComponent::getRemoteFileSelected()
const
305 const QString baseNameAndSize = ui->cb_DownloadFile->currentText();
311 QString CInstallXSwiftBusComponent::downloadDir()
const
313 return CFileUtils::fixWindowsUncPath(ui->le_DownloadDir->text().trimmed());
316 QString CInstallXSwiftBusComponent::xSwiftBusDir()
const
318 return CFileUtils::fixWindowsUncPath(ui->le_XSwiftBusPluginDir->text().trimmed());
321 bool CInstallXSwiftBusComponent::existsDownloadDir()
const
323 const QDir dir(this->downloadDir());
324 return dir.exists() && dir.isReadable();
327 bool CInstallXSwiftBusComponent::existsXSwiftBusPluginDir()
const
329 const QDir dir(this->xSwiftBusDir());
330 return dir.exists() && dir.isReadable();
333 QString CInstallXSwiftBusComponent::getXPlanePluginDirectory()
const
339 void CInstallXSwiftBusComponent::updatesChanged()
345 if (artifacts.
isEmpty()) {
return; }
351 m_xSwiftBusArtifacts = artifacts;
352 ui->cb_DownloadFile->addItems(xSwiftBusFiles);
355 QString current = xSwiftBusFiles.front();
356 if (m_defaultDownloadName.isEmpty())
371 ui->cb_DownloadFile->setEnabled(!remoteFiles.
isEmpty());
374 void CInstallXSwiftBusComponent::openInstallDir()
376 if (!this->existsXSwiftBusPluginDir()) {
return; }
377 const QString file = CFileUtils::fixWindowsUncPath(ui->le_XSwiftBusPluginDir->text());
378 QDesktopServices::openUrl(QUrl::fromLocalFile(file));
381 void CInstallXSwiftBusComponent::openDownloadDir()
383 if (!this->existsDownloadDir()) {
return; }
384 const QString file = CFileUtils::fixWindowsUncPath(ui->le_DownloadDir->text());
385 QDesktopServices::openUrl(QUrl::fromLocalFile(file));
QNetworkReply * downloadFromNetwork(const swift::misc::network::CUrl &url, const QString &saveAsFileName, const swift::misc::CSlot< void(const swift::misc::CStatusMessage &)> &callback, int maxRedirects=DefaultMaxRedirects)
Download file from network and store it as passed.
bool hasWebDataServices() const
Web data services available?
bool isShuttingDown() const
Is application shutting down?
Enable widget class for load indicator.
void showLoading(std::chrono::milliseconds timeout=std::chrono::milliseconds(0), bool processEvents=true)
Show load indicator.
void hideLoading()
Hide load indicator.
bool showOverlayMessage(const swift::misc::CStatusMessage &message, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show single message.
void showOverlayMessagesWithConfirmation(const swift::misc::CStatusMessageList &messages, bool appendOldMessages, const QString &confirmationMessage, std::function< void()> okLambda, QMessageBox::StandardButton defaultButton=QMessageBox::Cancel, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show multiple messages with confirmation bar.
Using this class provides a QFrame with the overlay functionality already integrated.
Download and install xswiftbus.
void setDefaultDownloadName(const QString &defaultDownload)
Set a default name for download.
virtual ~CInstallXSwiftBusComponent()
Dtor.
virtual bool validatePage()
T get() const
Get a copy of the current value.
Class for emitting a log message.
Derived & warning(const char16_t(&format)[N])
Set the severity to warning, providing a format string.
Derived & error(const char16_t(&format)[N])
Set the severity to error, providing a format string.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
const_reference frontOrDefault() const
Access the first element, or a default-initialized value if the sequence is empty.
bool isEmpty() const
Synonym for empty.
Streamable status message, e.g.
bool isWarningOrAbove() const
Warning or above.
CArtifactList findWithUnrestrictedDistributions() const
Find artifacts with public (unrestricted) distributions.
network::CRemoteFileList asRemoteFiles() const
As remote files.
Update info, i.e. artifacts and distributions.
CArtifactList getArtifactsXSwiftBusLatestVersionFirst() const
Artifacts (xswiftbus)
const CArtifactList & getArtifactsXSwiftBus() const
Artifacts (xswiftbus)
QString getBaseName() const
Name with directory stripped.
CUrl getSmartUrl() const
Automatically concatenates the name if missing.
bool hasName() const
Has name?
QString getBaseNameAndSize() const
Name + human readable size.
Value object encapsulating a list of remote files.
CRemoteFile findFirstContainingNameOrDefault(const QString &name, Qt::CaseSensitivity cs) const
First by name contained of default.
QStringList getBaseNamesPlusSize(bool sorted=true) const
All file names plus size.
CRemoteFile findFirstByMatchingBaseNameOrDefault(const QString &name) const
Find first matching name of default.
Value object encapsulating information of a location, kind of simplified CValueObject compliant versi...
bool isEmpty() const
Empty.
const QString & getHost() const
Get host.
QString getFullUrl(bool withQuery=true) const
Qualified name.
CSimulatorSettings getSettings(const CSimulatorInfo &simulator) const
Settings per simulator.
XPlane specific settings.
QString getPluginDirOrDefault() const
Plugin directory or default plugin dir.
SWIFT_GUI_EXPORT swift::gui::CGuiApplication * sGui
Single instance of GUI application object.
High level reusable GUI components.
Free functions in swift::misc.
const QString & safeAt(const QStringList &stringList, int index)
Safe "at" function, returns empty string if index does not exists.
auto singleShot(int msec, QObject *target, F &&task)
Starts a single-shot timer which will call a task in the thread of the given object when it times out...