Blender addon - refactor update and properly terminate cancelled action

This commit is contained in:
Trevor SANDY 2024-10-16 08:18:14 +02:00
parent 6be6e554f6
commit c191c4f719
2 changed files with 109 additions and 123 deletions

View file

@ -259,6 +259,15 @@ lcBlenderPreferences::ComboItems lcBlenderPreferences::mComboItemsMM [NUM_COMBO
lcBlenderPreferences* gAddonPreferences; lcBlenderPreferences* gAddonPreferences;
enum AddonEnc
{
ADDON_EXTRACT,
ADDON_DOWNLOAD,
ADDON_NO_ACTION,
ADDON_CANCELED,
ADDON_FAIL
};
lcBlenderPreferencesDialog::lcBlenderPreferencesDialog(int Width, int Height, double Scale, QWidget* Parent) lcBlenderPreferencesDialog::lcBlenderPreferencesDialog(int Width, int Height, double Scale, QWidget* Parent)
: QDialog(Parent) : QDialog(Parent)
{ {
@ -1058,6 +1067,7 @@ void lcBlenderPreferences::ConfigureBlenderAddon(bool TestBlender, bool AddonUpd
mProgressBar->setValue(1); mProgressBar->setValue(1);
TestBlender |= sender() == mPathLineEditList[PATH_BLENDER]; TestBlender |= sender() == mPathLineEditList[PATH_BLENDER];
mAddonVersionLabel->setText(tr("Installing..."));
if (TestBlender) if (TestBlender)
{ {
mExeGridLayout->replaceWidget(mBlenderVersionEdit, mProgressBar); mExeGridLayout->replaceWidget(mBlenderVersionEdit, mProgressBar);
@ -1158,6 +1168,7 @@ void lcBlenderPreferences::ConfigureBlenderAddon(bool TestBlender, bool AddonUpd
mProgressBar->setMinimum(0); mProgressBar->setMinimum(0);
mProgressBar->setValue(1); mProgressBar->setValue(1);
mAddonGridLayout->replaceWidget(mAddonVersionEdit, mProgressBar); mAddonGridLayout->replaceWidget(mAddonVersionEdit, mProgressBar);
mAddonVersionLabel->setText(tr("Downloading..."));
mProgressBar->show(); mProgressBar->show();
} }
@ -1179,7 +1190,8 @@ void lcBlenderPreferences::ConfigureBlenderAddon(bool TestBlender, bool AddonUpd
mAddonUpdateButton->setEnabled(mConfigured); mAddonUpdateButton->setEnabled(mConfigured);
if (mProgressBar) if (mProgressBar)
{ {
mExeGridLayout->replaceWidget(mProgressBar, mAddonVersionEdit); mAddonGridLayout->replaceWidget(mProgressBar, mAddonVersionEdit);
mAddonVersionLabel->setText(tr("Blender Addon"));
mProgressBar->close(); mProgressBar->close();
} }
} }
@ -1189,11 +1201,11 @@ void lcBlenderPreferences::ConfigureBlenderAddon(bool TestBlender, bool AddonUpd
if (!QFileInfo(BlenderInstallFile).exists()) if (!QFileInfo(BlenderInstallFile).exists())
{ {
ShowMessage(tr ("Could not find addon install file: %1").arg(BlenderInstallFile)); ShowMessage(tr ("Could not find addon install file: %1").arg(BlenderInstallFile));
StatusUpdate(true, true, tr("Addon file not found.")); StatusUpdate(true, true, tr("Not found."));
return; return;
} }
StatusUpdate(true, false, tr("Install addon...")); StatusUpdate(true, false, tr("Installing..."));
QDir ConfigDir(BlenderConfigDir); QDir ConfigDir(BlenderConfigDir);
if(!QDir(ConfigDir).exists()) if(!QDir(ConfigDir).exists())
@ -1273,7 +1285,7 @@ void lcBlenderPreferences::ConfigureBlenderAddon(bool TestBlender, bool AddonUpd
Result = ProcessCommand(PR_INSTALL); Result = ProcessCommand(PR_INSTALL);
if (Result != PR_OK) if (Result != PR_OK)
StatusUpdate(true, true, tr("Addon install failed.")); StatusUpdate(true, true, tr("Install failed."));
} }
else else
ShowMessage(tr("Blender executable not found at [%1]").arg(BlenderExe), tr("Addon install failed.")); ShowMessage(tr("Blender executable not found at [%1]").arg(BlenderExe), tr("Addon install failed."));
@ -1281,57 +1293,41 @@ void lcBlenderPreferences::ConfigureBlenderAddon(bool TestBlender, bool AddonUpd
bool lcBlenderPreferences::ExtractBlenderAddon(const QString& BlenderDir) bool lcBlenderPreferences::ExtractBlenderAddon(const QString& BlenderDir)
{ {
bool Proceed = true; bool Extracted = false;
QDir Dir(BlenderDir); QDir Dir(BlenderDir);
if (!Dir.exists()) if (!Dir.exists())
Dir.mkdir(BlenderDir); Dir.mkdir(BlenderDir);
if (GetBlenderAddon(BlenderDir)) AddonEnc AddonAction = AddonEnc(GetBlenderAddon(BlenderDir));
if (AddonAction == ADDON_EXTRACT)
{ {
gAddonPreferences->StatusUpdate(true, false, tr("Extract addon...")); gAddonPreferences->StatusUpdate(true, false, tr("Extracting..."));
const QString BlenderAddonFile = QDir::toNativeSeparators(QString("%1/%2").arg(BlenderDir).arg(LC_BLENDER_ADDON_FILE)); const QString BlenderAddonFile = QDir::toNativeSeparators(QString("%1/%2").arg(BlenderDir).arg(LC_BLENDER_ADDON_FILE));
QString Result; QString Result;
bool Success = gAddonPreferences->ExtractAddon(BlenderAddonFile, Result); Extracted = gAddonPreferences->ExtractAddon(BlenderAddonFile, Result);
if (!Success) if (!Extracted)
{ {
QString Message = tr("Failed to extract %1 to %2").arg(LC_BLENDER_ADDON_FILE).arg(BlenderDir); QString Message = tr("Failed to extract %1 to %2").arg(LC_BLENDER_ADDON_FILE).arg(BlenderDir);
if (Result.size()) if (Result.size())
Message.append(" "+Result); Message.append(" "+Result);
ShowMessage(Message, tr("Extract addon")); ShowMessage(Message, tr("Extract addon"));
Proceed = false;
} }
} }
if (!Proceed) return Extracted;
gAddonPreferences->StatusUpdate(true, true,tr("Extract addon failed."));
return Proceed;
} }
bool lcBlenderPreferences::GetBlenderAddon(const QString& BlenderDir) int lcBlenderPreferences::GetBlenderAddon(const QString& BlenderDir)
{ {
enum AddonEnc
{
ADDON_FAIL = -1,
ADDON_NOT_FOUND,
ADDON_DOWNLOAD = ADDON_NOT_FOUND,
ADDON_ARCHIVE,
ADDON_EXTRACTED,
ADDON_RELOAD,
ADDON_CANCEL
};
const QString BlenderAddonDir = QDir::toNativeSeparators(QString("%1/addons").arg(BlenderDir)); const QString BlenderAddonDir = QDir::toNativeSeparators(QString("%1/addons").arg(BlenderDir));
const QString BlenderAddonFile = QDir::toNativeSeparators(QString("%1/%2").arg(BlenderDir).arg(LC_BLENDER_ADDON_FILE)); const QString BlenderAddonFile = QDir::toNativeSeparators(QString("%1/%2").arg(BlenderDir).arg(LC_BLENDER_ADDON_FILE));
const QString AddonVersionFile = QDir::toNativeSeparators(QString("%1/%2/__version__.py").arg(BlenderAddonDir).arg(LC_BLENDER_ADDON_FOLDER_STR)); const QString AddonVersionFile = QDir::toNativeSeparators(QString("%1/%2/__version__.py").arg(BlenderAddonDir).arg(LC_BLENDER_ADDON_FOLDER_STR));
bool ExtractedAddon = QFileInfo(AddonVersionFile).isReadable(); bool ExtractedAddon = QFileInfo(AddonVersionFile).isReadable();
bool BlenderAddonValidated = ExtractedAddon || QFileInfo(BlenderAddonFile).isReadable(); bool BlenderAddonValidated = ExtractedAddon || QFileInfo(BlenderAddonFile).isReadable();
QString AddonStatus = tr("Installing Blender addon...");
AddonEnc AddonAction = ADDON_DOWNLOAD; AddonEnc AddonAction = ADDON_DOWNLOAD;
QString LocalVersion, OnlineVersion; QString LocalVersion, OnlineVersion;
@ -1448,7 +1444,7 @@ bool lcBlenderPreferences::GetBlenderAddon(const QString& BlenderDir)
{ {
if (GetBlenderAddonVersionMatch()) if (GetBlenderAddonVersionMatch())
{ {
AddonAction = ADDON_RELOAD; AddonAction = ADDON_NO_ACTION;
} }
else if (gMainWindow) else if (gMainWindow)
{ {
@ -1462,30 +1458,18 @@ bool lcBlenderPreferences::GetBlenderAddon(const QString& BlenderDir)
int Exec = ShowMessage(Header, Title, Body, QString(), MBB_YES, QMessageBox::NoIcon); int Exec = ShowMessage(Header, Title, Body, QString(), MBB_YES, QMessageBox::NoIcon);
if (Exec == QMessageBox::Cancel) if (Exec == QMessageBox::Cancel)
{ {
AddonStatus = tr("Blender addon setup cancelled"); AddonAction = ADDON_CANCELED;
AddonAction = ADDON_CANCEL; gAddonPreferences->mDialogCancelled = true;
} }
else if (Exec == QMessageBox::No) else if (Exec == QMessageBox::No)
{ AddonAction = ADDON_NO_ACTION;
AddonAction = ADDON_RELOAD;
}
} }
else else
{ AddonAction = ADDON_NO_ACTION;
AddonAction = ADDON_RELOAD;
}
} }
if (AddonAction == ADDON_DOWNLOAD) if (AddonAction != ADDON_DOWNLOAD)
AddonStatus = tr("Download addon..."); return AddonAction;
gAddonPreferences->StatusUpdate(true, false, AddonStatus);
if (AddonAction == ADDON_CANCEL)
{
gAddonPreferences->mDialogCancelled = true;
return false;
}
} }
auto RemoveOldBlenderAddon = [&] (const QString& OldBlenderAddonFile) auto RemoveOldBlenderAddon = [&] (const QString& OldBlenderAddonFile)
@ -1511,8 +1495,6 @@ bool lcBlenderPreferences::GetBlenderAddon(const QString& BlenderDir)
} }
}; };
if (AddonAction == ADDON_DOWNLOAD)
{
BlenderAddonValidated = false; BlenderAddonValidated = false;
lcHttpManager* HttpManager = new lcHttpManager(gAddonPreferences); lcHttpManager* HttpManager = new lcHttpManager(gAddonPreferences);
connect(HttpManager, SIGNAL(DownloadFinished(lcHttpReply*)), gAddonPreferences, SLOT(DownloadFinished(lcHttpReply*))); connect(HttpManager, SIGNAL(DownloadFinished(lcHttpReply*)), gAddonPreferences, SLOT(DownloadFinished(lcHttpReply*)));
@ -1549,7 +1531,7 @@ bool lcBlenderPreferences::GetBlenderAddon(const QString& BlenderDir)
ReadSize = qMin(DataSize, BufferSize); ReadSize = qMin(DataSize, BufferSize);
} }
File.close(); File.close();
const QString HexCalculated = Sha256Hash.result().toHex(); const QString ShaCalculated = Sha256Hash.result().toHex();
gAddonPreferences->mData.clear(); gAddonPreferences->mData.clear();
gAddonPreferences->mHttpReply = HttpManager->DownloadFile(QLatin1String(LC_BLENDER_ADDON_SHA_HASH_URL)); gAddonPreferences->mHttpReply = HttpManager->DownloadFile(QLatin1String(LC_BLENDER_ADDON_SHA_HASH_URL));
@ -1557,20 +1539,20 @@ bool lcBlenderPreferences::GetBlenderAddon(const QString& BlenderDir)
QApplication::processEvents(); QApplication::processEvents();
if (!gAddonPreferences->mData.isEmpty()) if (!gAddonPreferences->mData.isEmpty())
{ {
const QStringList HexReceived = QString(gAddonPreferences->mData).trimmed().split(" ", SkipEmptyParts); const QStringList ShaReceived = QString(gAddonPreferences->mData).trimmed().split(" ", SkipEmptyParts);
if (HexReceived.first() == HexCalculated) if (ShaReceived.first() == ShaCalculated)
{ {
ArchiveFileName = QFileInfo(BlenderAddonFile).fileName(); ArchiveFileName = QFileInfo(BlenderAddonFile).fileName();
if (ArchiveFileName == HexReceived.last()) if (ArchiveFileName == ShaReceived.last())
{ {
RemoveOldBlenderAddon(OldBlenderAddonFile); RemoveOldBlenderAddon(OldBlenderAddonFile);
BlenderAddonValidated = true; BlenderAddonValidated = true;
} }
else else
ShowMessage(tr("Failed to validate Blender addon file name<br>Downloaded:%1<br>Received:%2").arg(ArchiveFileName, HexReceived.last())); ShowMessage(tr("Failed to validate Blender addon file name<br>Downloaded:%1<br>Received:%2").arg(ArchiveFileName, ShaReceived.last()));
} }
else else
ShowMessage(tr("Failed to validate Blender addon SHA hash <br>Calculated:%1<br>Received:%2").arg(HexCalculated, HexReceived.first())); ShowMessage(tr("Failed to validate Blender addon SHA hash <br>Calculated:%1<br>Received:%2").arg(ShaCalculated, ShaReceived.first()));
gAddonPreferences->mData.clear(); gAddonPreferences->mData.clear();
} }
else else
@ -1590,21 +1572,22 @@ bool lcBlenderPreferences::GetBlenderAddon(const QString& BlenderDir)
if (QFileInfo(OldBlenderAddonFile).exists()) if (QFileInfo(OldBlenderAddonFile).exists())
if (!QFile::rename(OldBlenderAddonFile, BlenderAddonFile)) if (!QFile::rename(OldBlenderAddonFile, BlenderAddonFile))
ShowMessage(tr("Failed to restore Blender addon archive:<br>%1 from %2").arg(ArchiveFileName, OldArchiveFileName)); ShowMessage(tr("Failed to restore Blender addon archive:<br>%1 from %2").arg(ArchiveFileName, OldArchiveFileName));
AddonAction = ADDON_FAIL;
} }
} }
else else
{
ShowMessage(tr("Failed to download Blender addon archive:<br>%1").arg(BlenderAddonFile)); ShowMessage(tr("Failed to download Blender addon archive:<br>%1").arg(BlenderAddonFile));
AddonAction = ADDON_FAIL;
}
if (!BlenderAddonValidated) if (!BlenderAddonValidated)
{ gAddonPreferences->StatusUpdate(true, true, tr("Download failed."));
AddonStatus = tr("Download addon failed.");
gAddonPreferences->StatusUpdate(true, true, AddonStatus);
}
}
else if (!BlenderAddonValidated)
ShowMessage(tr("Blender addon archive %1 was not found").arg(BlenderAddonFile));
return BlenderAddonValidated; if (!QDir(BlenderAddonDir).exists() && QFileInfo(BlenderAddonFile).exists())
AddonAction = ADDON_EXTRACT;
return AddonAction;
} }
void lcBlenderPreferences::StatusUpdate(bool Addon, bool Error, const QString& Message) void lcBlenderPreferences::StatusUpdate(bool Addon, bool Error, const QString& Message)
@ -1622,6 +1605,8 @@ void lcBlenderPreferences::StatusUpdate(bool Addon, bool Error, const QString& M
mExeGridLayout->replaceWidget(mProgressBar, mBlenderVersionEdit); mExeGridLayout->replaceWidget(mProgressBar, mBlenderVersionEdit);
mProgressBar->hide(); mProgressBar->hide();
} }
mAddonVersionLabel->setText(Which);
} }
if (Error) if (Error)
{ {
@ -1637,6 +1622,7 @@ void lcBlenderPreferences::StatusUpdate(bool Addon, bool Error, const QString& M
: Preferences.mColorTheme == lcColorTheme::Dark : Preferences.mColorTheme == lcColorTheme::Dark
? QLatin1String(LC_THEME_DARK_DECORATE_QUOTED_TEXT) ? QLatin1String(LC_THEME_DARK_DECORATE_QUOTED_TEXT)
: QLatin1String("blue"); : QLatin1String("blue");
mDialogCancelled = true; mDialogCancelled = true;
} }
else else
@ -1674,7 +1660,7 @@ void lcBlenderPreferences::ShowResult()
{ {
const QString BlenderDir = QString("%1/Blender").arg(mDataDir); const QString BlenderDir = QString("%1/Blender").arg(mDataDir);
Message = tr("Addon install failed. See %1/stderr-blender-addon-install for details.").arg(BlenderDir); Message = tr("Addon install failed. See %1/stderr-blender-addon-install for details.").arg(BlenderDir);
StatusUpdate(true, true,tr("%1: Addon install failed.").arg("Error")); StatusUpdate(true, true,tr("Error: Install failed."));
mConfigured = false; mConfigured = false;
const QString& Title = tr ("%1 Blender Addon Install").arg(LC_PRODUCTNAME_STR); const QString& Title = tr ("%1 Blender Addon Install").arg(LC_PRODUCTNAME_STR);

View file

@ -76,7 +76,7 @@ protected:
static int NumPaths(bool DefaultSettings = false); static int NumPaths(bool DefaultSettings = false);
static int NumSettings(bool DefaultSettings = false); static int NumSettings(bool DefaultSettings = false);
static int NumSettingsMM(bool DefaultSettings = false); static int NumSettingsMM(bool DefaultSettings = false);
static bool GetBlenderAddon(const QString& BlenderDir); static int GetBlenderAddon(const QString& BlenderDir);
static bool ExtractBlenderAddon(const QString& BlenderDir); static bool ExtractBlenderAddon(const QString& BlenderDir);
static void LoadDefaultParameters(QByteArray& Buffer, int Which); static void LoadDefaultParameters(QByteArray& Buffer, int Which);
static bool OverwriteFile(const QString& File); static bool OverwriteFile(const QString& File);