diff --git a/common/lc_blenderpreferences.cpp b/common/lc_blenderpreferences.cpp
index 9689e33b..26d44461 100644
--- a/common/lc_blenderpreferences.cpp
+++ b/common/lc_blenderpreferences.cpp
@@ -50,6 +50,7 @@ const QLatin1String LineEnding("\r\n");
#define LC_BLENDER_ADDON_API_STR LC_BLENDER_ADDON_REPO_API_STR "/blenderldrawrender/"
#define LC_BLENDER_ADDON_LATEST_URL LC_BLENDER_ADDON_API_STR "releases/latest"
#define LC_BLENDER_ADDON_URL LC_BLENDER_ADDON_STR "releases/latest/download/" LC_BLENDER_ADDON_FILE
+#define LC_BLENDER_ADDON_SHA_HASH_URL LC_BLENDER_ADDON_URL ".sha256"
#define LC_THEME_DARK_PALETTE_MIDLIGHT "#3E3E3E" // 62, 62, 62, 255
#define LC_THEME_DEFAULT_PALETTE_LIGHT "#AEADAC" // 174, 173, 172, 255
@@ -106,12 +107,13 @@ lcBlenderPreferences::BlenderPaths lcBlenderPreferences::mDefaultPaths [NUM_PAT
/* Key: MM Key: Value: Label: Tooltip (Description):*/
/* 0 PATH_BLENDER */ {"blenderpath", "blenderpath", "", QObject::tr("Blender Path"), QObject::tr("Full file path to Blender application executable")},
/* 1 PATH_BLENDFILE */ {"blendfile", "blendfile", "", QObject::tr("Blendfile Path"), QObject::tr("Full file path to a supplement .blend file - specify to append additional settings")},
- /* 2. PATH_ENVIRONMENT */ {"environmentfile", "environmentfile", "", QObject::tr("Environment Texture Path"), QObject::tr("Full file path to .exr environment texture file - specify if not using default bundled in addon")},
+ /* 2 PATH_ENVIRONMENT */ {"environmentfile", "environmentfile", "", QObject::tr("Environment Texture Path"), QObject::tr("Full file path to .exr environment texture file - specify if not using default bundled in addon")},
/* 3 PATH_LDCONFIG */ {"customldconfigfile", "customldconfigfile", "", QObject::tr("Custom LDConfig Path"), QObject::tr("Full file path to custom LDConfig file - specify if not %1 alternate LDConfig file").arg(LC_PRODUCTNAME_STR)},
/* 4 PATH_LDRAW */ {"ldrawdirectory", "ldrawpath", "", QObject::tr("LDraw Directory"), QObject::tr("Full directory path to the LDraw parts library (download from https://library.ldraw.org)")},
/* 5 PATH_LSYNTH */ {"lsynthdirectory", "", "", QObject::tr("LSynth Directory"), QObject::tr("Full directory path to LSynth primitives - specify if not using default bundled in addon")},
/* 6 PATH_STUD_LOGO */ {"studlogodirectory", "", "", QObject::tr("Stud Logo Directory"), QObject::tr("Full directory path to stud logo primitives - if stud logo enabled, specify if unofficial parts not used or not using default bundled in addon")},
- /* 7 PATH_STUDIO_LDRAW */ {"", "studioldrawpath", "", QObject::tr("Stud.io LDraw Path"), QObject::tr("Full filepath to the Stud.io LDraw Parts Library (download from https://www.bricklink.com/v3/studio/download.page)")}
+ /* 7 PATH_STUDIO_LDRAW */ {"", "studioldrawpath", "", QObject::tr("Stud.io LDraw Path"), QObject::tr("Full filepath to the Stud.io LDraw Parts Library (download from https://www.bricklink.com/v3/studio/download.page)")},
+ /* 8 PATH_STUDIO_CUSTOM_PARTS */ {"", "studiocustompartspath", "", QObject::tr("Stud.io Custom Parts Path"),QObject::tr("Full filepath to the Stud.io LDraw Custom Parts")}
};
lcBlenderPreferences::BlenderSettings lcBlenderPreferences::mBlenderSettings [NUM_SETTINGS];
@@ -212,7 +214,7 @@ lcBlenderPreferences::BlenderSettings lcBlenderPreferences::mDefaultSettingsMM
/* 25 LBL_PREFER_UNOFFICIAL */ {"preferunofficial", "0", QObject::tr("Prefer Unofficial Parts"), QObject::tr("Search for unofficial parts first")},
/* 26 LBL_PROFILE */ {"profile", "0", QObject::tr("Profile"), QObject::tr("Profile import performance")},
/* 27 LBL_RECALCULATE_NORMALS */ {"recalculatenormals", "0", QObject::tr("Recalculate Normals"), QObject::tr("Recalculate normals. Not recommended if BFC processing is active")},
- /* 28 LBL_REMOVE_DOUBLES_MM */ {"removedoubles", "1", QObject::tr("No Duplicate Vertices"), QObject::tr("Merge vertices that are within a certain distance.")},
+ /* 28 LBL_REMOVE_DOUBLES_MM */ {"removedoubles", "0", QObject::tr("No Duplicate Vertices"), QObject::tr("Merge vertices that are within a certain distance.")},
/* 29 LBL_RENDER_WINDOW_MM */ {"renderwindow", "1", QObject::tr("Display Render Window"), QObject::tr("Specify whether to display the render window during Blender user interface image file render")},
/* 30 LBL_SEARCH_ADDL_PATHS_MM */ {"searchadditionalpaths", "0", QObject::tr("Search Additional Paths"), QObject::tr("Specify whether to search additional LDraw paths")},
/* 31 LBL_SETEND_FRAME */ {"setendframe", "1", QObject::tr("Set Step End Frame"), QObject::tr("Set the end frame to the last step")},
@@ -240,8 +242,8 @@ lcBlenderPreferences::BlenderSettings lcBlenderPreferences::mDefaultSettingsMM
/* 52/00 LBL_CHOSEN_LOGO */ {"chosenlogo", "logo3", QObject::tr("Chosen Logo"), QObject::tr("Which logo to display. logo and logo2 aren't used and are only included for completeness")},
/* 53/01 LBL_COLOUR_SCHEME_MM */ {"usecolourscheme", "lgeo", QObject::tr("Colour Scheme"), QObject::tr("Colour scheme options - Realistic (lgeo), Original (LDConfig), Alternate (LDCfgalt), Custom (User Defined)")},
- /* 54/02 LBL_COLOUR_STRATEGY */ {"colorstrategy", "material", QObject::tr("How To Color Parts"), QObject::tr("Colour strategy options - Material (Default - use if exporting), Vertex colors (slightly quicker to import)")},
- /* 55/03 LBL_RESOLUTION_MM */ {"resolution", "Standard", QObject::tr("Resolution"), QObject::tr("Resolution of part primitives, ie. how much geometry they have")},
+ /* 54/02 LBL_RESOLUTION_MM */ {"resolution", "Standard", QObject::tr("Resolution"), QObject::tr("Resolution of part primitives, ie. how much geometry they have")},
+ /* 55/03 LBL_SCALE_STRATEGY */ {"scalestrategy", "mesh", QObject::tr("How To Scale Parts"), QObject::tr("Apply import scaling to mesh - Recommended for rendering, Apply import scaling to object - Recommended for part editing")},
/* 56/04 LBL_SMOOTH_TYPE */ {"smoothtype", "edge_split", QObject::tr("Smooth Type"), QObject::tr("Use either autosmooth or an edge split modifier to smooth part faces")}
};
@@ -250,13 +252,22 @@ lcBlenderPreferences::ComboItems lcBlenderPreferences::mComboItemsMM [NUM_COMBO
/* FIRST item set as default Data Item: */
/* 00 LBL_CHOSEN_LOGO */ {"logo3|logo4|logo5", QObject::tr("Raised flattened logo geometry(3)|Raised rounded logo geometry(4)|Subtle rounded logo geometry(5)")},
/* 01 LBL_COLOUR_SCHEME_MM */ {"lgeo|ldraw|alt|custom", QObject::tr("Realistic Colours|Original LDraw Colours|Alternate LDraw Colours|Custom Colours")},
- /* 02 LBL_COLOUR_STRATEGY */ {"material|vertex_colors", QObject::tr("Material|Vertex Colors")},
- /* 03 LBL_RESOLUTION_MM */ {"Low|Standard|High", QObject::tr("Low Resolution Primitives|Standard Primitives|High Resolution Primitives")},
+ /* 02 LBL_RESOLUTION_MM */ {"Low|Standard|High", QObject::tr("Low Resolution Primitives|Standard Primitives|High Resolution Primitives")},
+ /* 03 LBL_SCALE_STRATEGY */ {"mesh|object", QObject::tr("Scale Mesh|Scale Object")},
/* 04 LBL_SMOOTH_TYPE */ {"edge_split|auto_smooth|bmesh_split", QObject::tr("Smooth part faces with edge split modifier|Auto-smooth part faces|Split during initial mesh processing")}
};
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)
: QDialog(Parent)
{
@@ -1056,6 +1067,7 @@ void lcBlenderPreferences::ConfigureBlenderAddon(bool TestBlender, bool AddonUpd
mProgressBar->setValue(1);
TestBlender |= sender() == mPathLineEditList[PATH_BLENDER];
+ mAddonVersionLabel->setText(tr("Installing..."));
if (TestBlender)
{
mExeGridLayout->replaceWidget(mBlenderVersionEdit, mProgressBar);
@@ -1156,6 +1168,7 @@ void lcBlenderPreferences::ConfigureBlenderAddon(bool TestBlender, bool AddonUpd
mProgressBar->setMinimum(0);
mProgressBar->setValue(1);
mAddonGridLayout->replaceWidget(mAddonVersionEdit, mProgressBar);
+ mAddonVersionLabel->setText(tr("Downloading..."));
mProgressBar->show();
}
@@ -1177,7 +1190,8 @@ void lcBlenderPreferences::ConfigureBlenderAddon(bool TestBlender, bool AddonUpd
mAddonUpdateButton->setEnabled(mConfigured);
if (mProgressBar)
{
- mExeGridLayout->replaceWidget(mProgressBar, mAddonVersionEdit);
+ mAddonGridLayout->replaceWidget(mProgressBar, mAddonVersionEdit);
+ mAddonVersionLabel->setText(tr("Blender Addon"));
mProgressBar->close();
}
}
@@ -1187,11 +1201,11 @@ void lcBlenderPreferences::ConfigureBlenderAddon(bool TestBlender, bool AddonUpd
if (!QFileInfo(BlenderInstallFile).exists())
{
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;
}
- StatusUpdate(true, false, tr("Install addon..."));
+ StatusUpdate(true, false, tr("Installing..."));
QDir ConfigDir(BlenderConfigDir);
if(!QDir(ConfigDir).exists())
@@ -1271,7 +1285,7 @@ void lcBlenderPreferences::ConfigureBlenderAddon(bool TestBlender, bool AddonUpd
Result = ProcessCommand(PR_INSTALL);
if (Result != PR_OK)
- StatusUpdate(true, true, tr("Addon install failed."));
+ StatusUpdate(true, true, tr("Install failed."));
}
else
ShowMessage(tr("Blender executable not found at [%1]").arg(BlenderExe), tr("Addon install failed."));
@@ -1279,57 +1293,41 @@ void lcBlenderPreferences::ConfigureBlenderAddon(bool TestBlender, bool AddonUpd
bool lcBlenderPreferences::ExtractBlenderAddon(const QString& BlenderDir)
{
- bool Proceed = true;
+ bool Extracted = false;
QDir Dir(BlenderDir);
if (!Dir.exists())
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));
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);
if (Result.size())
Message.append(" "+Result);
ShowMessage(Message, tr("Extract addon"));
-
- Proceed = false;
}
}
- if (!Proceed)
- gAddonPreferences->StatusUpdate(true, true,tr("Extract addon failed."));
-
- return Proceed;
+ return Extracted;
}
-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 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));
bool ExtractedAddon = QFileInfo(AddonVersionFile).isReadable();
- bool BlenderAddonExists = ExtractedAddon || QFileInfo(BlenderAddonFile).isReadable();
- QString AddonStatus = tr("Installing Blender addon...");
+ bool BlenderAddonValidated = ExtractedAddon || QFileInfo(BlenderAddonFile).isReadable();
AddonEnc AddonAction = ADDON_DOWNLOAD;
QString LocalVersion, OnlineVersion;
@@ -1442,11 +1440,11 @@ bool lcBlenderPreferences::GetBlenderAddon(const QString& BlenderDir)
return true; // Reload existing archive
};
- if (BlenderAddonExists)
+ if (BlenderAddonValidated)
{
if (GetBlenderAddonVersionMatch())
{
- AddonAction = ADDON_RELOAD;
+ AddonAction = ADDON_NO_ACTION;
}
else if (gMainWindow)
{
@@ -1460,89 +1458,136 @@ bool lcBlenderPreferences::GetBlenderAddon(const QString& BlenderDir)
int Exec = ShowMessage(Header, Title, Body, QString(), MBB_YES, QMessageBox::NoIcon);
if (Exec == QMessageBox::Cancel)
{
- AddonStatus = tr("Blender addon setup cancelled");
- AddonAction = ADDON_CANCEL;
+ AddonAction = ADDON_CANCELED;
+ gAddonPreferences->mDialogCancelled = true;
}
else if (Exec == QMessageBox::No)
+ AddonAction = ADDON_NO_ACTION;
+ }
+ else
+ AddonAction = ADDON_NO_ACTION;
+ }
+
+ if (AddonAction != ADDON_DOWNLOAD)
+ return AddonAction;
+ }
+
+ auto RemoveOldBlenderAddon = [&] (const QString& OldBlenderAddonFile)
+ {
+ if (QFileInfo(BlenderAddonDir).exists())
+ {
+ bool Result = true;
+ QDir Dir(BlenderAddonDir);
+ for (QFileInfo const& FileInfo : Dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks, QDir::DirsFirst))
+ {
+ if (FileInfo.isDir())
+ Result &= QDir(FileInfo.absoluteFilePath()).removeRecursively();
+ else
+ Result &= QFile::remove(FileInfo.absoluteFilePath());
+ }
+
+ if (QFileInfo(OldBlenderAddonFile).exists())
+ Result &= QFile::remove(OldBlenderAddonFile);
+
+ Result &= Dir.rmdir(BlenderAddonDir);
+ if (!Result)
+ ShowMessage(tr("Failed to properly remove Blender addon: %1").arg(BlenderAddonDir), tr("Remove Existing Addon"), QString(), QString(), MBB_OK, QMessageBox::Warning);
+ }
+ };
+
+ BlenderAddonValidated = false;
+ lcHttpManager* HttpManager = new lcHttpManager(gAddonPreferences);
+ connect(HttpManager, SIGNAL(DownloadFinished(lcHttpReply*)), gAddonPreferences, SLOT(DownloadFinished(lcHttpReply*)));
+ gAddonPreferences->mHttpReply = HttpManager->DownloadFile(QLatin1String(LC_BLENDER_ADDON_URL));
+ while (gAddonPreferences->mHttpReply)
+ QApplication::processEvents();
+ if (!gAddonPreferences->mData.isEmpty())
+ {
+ const QString OldBlenderAddonFile = QString("%1.hold").arg(BlenderAddonFile);
+ if (QFileInfo(BlenderAddonFile).exists())
+ {
+ if (!QFile::rename(BlenderAddonFile, OldBlenderAddonFile))
+ ShowMessage(tr("Failed to rename existing Blender addon archive %1.").arg(BlenderAddonFile));
+ }
+
+ QString ArchiveFileName, OldArchiveFileName = QFileInfo(OldBlenderAddonFile).fileName();
+ QFile File(BlenderAddonFile);
+ if (File.open(QIODevice::WriteOnly))
+ {
+ File.write(gAddonPreferences->mData);
+ File.close();
+ if (File.open(QIODevice::ReadOnly))
+ {
+ QCryptographicHash Sha256Hash(QCryptographicHash::Sha256);
+ qint64 DataSize = File.size();
+ const qint64 BufferSize = Q_INT64_C(1000);
+ char Buf[BufferSize];
+ int BytesRead;
+ int ReadSize = qMin(DataSize, BufferSize);
+ while (ReadSize > 0 && (BytesRead = File.read(Buf, ReadSize)) > 0)
{
- AddonAction = ADDON_RELOAD;
+ DataSize -= BytesRead;
+ Sha256Hash.addData(Buf, BytesRead);
+ ReadSize = qMin(DataSize, BufferSize);
}
- }
- else
- {
- AddonAction = ADDON_RELOAD;
- }
- }
-
- if (AddonAction == ADDON_DOWNLOAD)
- AddonStatus = tr("Download addon...");
-
- gAddonPreferences->StatusUpdate(true, false, AddonStatus);
-
- if (AddonAction == ADDON_CANCEL)
- {
- gAddonPreferences->mDialogCancelled = true;
- return false;
- }
- }
-
- if (QFileInfo(BlenderAddonDir).exists())
- {
- bool Result = true;
- QDir Dir(BlenderAddonDir);
- for (QFileInfo const& FileInfo : Dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks, QDir::DirsFirst))
- {
- if (FileInfo.isDir())
- Result &= QDir(FileInfo.absoluteFilePath()).removeRecursively();
- else
- Result &= QFile::remove(FileInfo.absoluteFilePath());
- }
-
- Result &= Dir.rmdir(BlenderAddonDir);
- if (!Result)
- ShowMessage(tr("Failed to remove Blender addon: %1").arg(BlenderAddonDir), tr("Remove Existing Addon"), QString(), QString(), MBB_OK, QMessageBox::Warning);
- }
-
- if (AddonAction == ADDON_DOWNLOAD)
- {
- BlenderAddonExists = false;
- lcHttpManager* HttpManager = new lcHttpManager(gAddonPreferences);
- connect(HttpManager, SIGNAL(DownloadFinished(lcHttpReply*)), gAddonPreferences, SLOT(DownloadFinished(lcHttpReply*)));
- gAddonPreferences->mHttpReply = HttpManager->DownloadFile(QLatin1String(LC_BLENDER_ADDON_URL));
- while (gAddonPreferences->mHttpReply)
- QApplication::processEvents();
- if (!gAddonPreferences->mData.isEmpty())
- {
- if (QFileInfo(BlenderAddonFile).exists())
- {
- QDir Dir(BlenderDir);
- if (!Dir.remove(BlenderAddonFile))
- ShowMessage(tr("Failed to remove Blender addon archive:
%1").arg(BlenderAddonFile));
- }
- QFile File(BlenderAddonFile);
- if (File.open(QIODevice::WriteOnly))
- {
- File.write(gAddonPreferences->mData);
File.close();
- BlenderAddonExists = true;
+ const QString ShaCalculated = Sha256Hash.result().toHex();
+
gAddonPreferences->mData.clear();
+ gAddonPreferences->mHttpReply = HttpManager->DownloadFile(QLatin1String(LC_BLENDER_ADDON_SHA_HASH_URL));
+ while (gAddonPreferences->mHttpReply)
+ QApplication::processEvents();
+ if (!gAddonPreferences->mData.isEmpty())
+ {
+ const QStringList ShaReceived = QString(gAddonPreferences->mData).trimmed().split(" ", SkipEmptyParts);
+ if (ShaReceived.first() == ShaCalculated)
+ {
+ ArchiveFileName = QFileInfo(BlenderAddonFile).fileName();
+ if (ArchiveFileName == ShaReceived.last())
+ {
+ RemoveOldBlenderAddon(OldBlenderAddonFile);
+ BlenderAddonValidated = true;
+ }
+ else
+ ShowMessage(tr("Failed to validate Blender addon file name
Downloaded:%1
Received:%2").arg(ArchiveFileName, ShaReceived.last()));
+ }
+ else
+ ShowMessage(tr("Failed to validate Blender addon SHA hash
Calculated:%1
Received:%2").arg(ShaCalculated, ShaReceived.first()));
+ gAddonPreferences->mData.clear();
+ }
+ else
+ ShowMessage(tr("Failed to receive SHA hash for Blender addon %1.sha256").arg(LC_BLENDER_ADDON_FILE));
}
else
- ShowMessage(tr("Failed to open Blender addon file:
%1:
%2").arg(BlenderAddonFile).arg(File.errorString()));
+ ShowMessage(tr("Failed to read Blender addon archive:
%1:
%2").arg(BlenderAddonFile).arg(File.errorString()));
}
else
- ShowMessage(tr("Failed to download Blender addon archive:
%1").arg(BlenderAddonFile));
+ ShowMessage(tr("Failed to write Blender addon archive:
%1:
%2").arg(BlenderAddonFile).arg(File.errorString()));
- if (!BlenderAddonExists)
+ if (!BlenderAddonValidated)
{
- AddonStatus = tr("Download addon failed.");
- gAddonPreferences->StatusUpdate(true, true, AddonStatus);
+ if (QFileInfo(BlenderAddonFile).exists())
+ if (!QFile::remove(BlenderAddonFile))
+ ShowMessage(tr("Failed to remove invalid Blender addon archive:
%1").arg(BlenderAddonFile));
+ if (QFileInfo(OldBlenderAddonFile).exists())
+ if (!QFile::rename(OldBlenderAddonFile, BlenderAddonFile))
+ ShowMessage(tr("Failed to restore Blender addon archive:
%1 from %2").arg(ArchiveFileName, OldArchiveFileName));
+ AddonAction = ADDON_FAIL;
}
}
- else if (!BlenderAddonExists)
- ShowMessage(tr("Blender addon archive %1 was not found").arg(BlenderAddonFile));
+ else
+ {
+ ShowMessage(tr("Failed to download Blender addon archive:
%1").arg(BlenderAddonFile));
+ AddonAction = ADDON_FAIL;
+ }
- return BlenderAddonExists;
+ if (!BlenderAddonValidated)
+ gAddonPreferences->StatusUpdate(true, true, tr("Download failed."));
+
+ if (!QDir(BlenderAddonDir).exists() && QFileInfo(BlenderAddonFile).exists())
+ AddonAction = ADDON_EXTRACT;
+
+ return AddonAction;
}
void lcBlenderPreferences::StatusUpdate(bool Addon, bool Error, const QString& Message)
@@ -1560,6 +1605,8 @@ void lcBlenderPreferences::StatusUpdate(bool Addon, bool Error, const QString& M
mExeGridLayout->replaceWidget(mProgressBar, mBlenderVersionEdit);
mProgressBar->hide();
}
+
+ mAddonVersionLabel->setText(Which);
}
if (Error)
{
@@ -1571,10 +1618,11 @@ void lcBlenderPreferences::StatusUpdate(bool Addon, bool Error, const QString& M
const lcPreferences& Preferences = lcGetPreferences();
Label = ! Message.isEmpty() ? Message : tr("%1 not configured").arg(Which);
Colour = Message.startsWith("Error:", Qt::CaseInsensitive)
- ? QLatin1String("red")
- : Preferences.mColorTheme == lcColorTheme::Dark
- ? QLatin1String(LC_THEME_DARK_DECORATE_QUOTED_TEXT)
- : QLatin1String("blue");
+ ? QLatin1String("red")
+ : Preferences.mColorTheme == lcColorTheme::Dark
+ ? QLatin1String(LC_THEME_DARK_DECORATE_QUOTED_TEXT)
+ : QLatin1String("blue");
+
mDialogCancelled = true;
}
else
@@ -1612,7 +1660,7 @@ void lcBlenderPreferences::ShowResult()
{
const QString BlenderDir = QString("%1/Blender").arg(mDataDir);
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;
const QString& Title = tr ("%1 Blender Addon Install").arg(LC_PRODUCTNAME_STR);
@@ -2419,14 +2467,15 @@ void lcBlenderPreferences::LoadSettings()
const QString DefaultBlendFile = QString("%1/Blender/config/%2").arg(gAddonPreferences->mDataDir).arg(LC_BLENDER_ADDON_BLEND_FILE);
QStringList const AddonPaths = QStringList()
- /* PATH_BLENDER */ << lcGetProfileString(LC_PROFILE_BLENDER_PATH)
- /* PATH_BLENDFILE */ << (QFileInfo(DefaultBlendFile).exists() ? DefaultBlendFile : QString())
- /* PATH_ENVIRONMENT */ << QString()
- /* PATH_LDCONFIG */ << lcGetProfileString(LC_PROFILE_COLOR_CONFIG)
- /* PATH_LDRAW */ << QFileInfo(lcGetProfileString(LC_PROFILE_PARTS_LIBRARY)).absolutePath()
- /* PATH_LSYNTH */ << QString()
- /* PATH_STUD_LOGO */ << QString()
- /* PATH_STUDIO_LDRAW */ << QString();
+ /* 0 PATH_BLENDER */ << lcGetProfileString(LC_PROFILE_BLENDER_PATH)
+ /* 1 PATH_BLENDFILE */ << (QFileInfo(DefaultBlendFile).exists() ? DefaultBlendFile : QString())
+ /* 2 PATH_ENVIRONMENT */ << QString()
+ /* 3 PATH_LDCONFIG */ << lcGetProfileString(LC_PROFILE_COLOR_CONFIG)
+ /* 4 PATH_LDRAW */ << QFileInfo(lcGetProfileString(LC_PROFILE_PARTS_LIBRARY)).absolutePath()
+ /* 5 PATH_LSYNTH */ << QString()
+ /* 6 PATH_STUD_LOGO */ << QString()
+ /* 7 PATH_STUDIO_LDRAW */ << QString()
+ /* 8 PATH_STUDIO_CUSTOM_PARTS */ << QString();
for (int LblIdx = 0; LblIdx < NumPaths(DEFAULT_SETTINGS); LblIdx++)
{
mBlenderPaths[LblIdx] =
@@ -2478,7 +2527,7 @@ void lcBlenderPreferences::LoadSettings()
for (int LblIdx = 1/*skip blender executable*/; LblIdx < NumPaths(); LblIdx++)
{
- if (LblIdx == PATH_STUDIO_LDRAW)
+ if (LblIdx >= PATH_STUDIO_LDRAW)
continue;
const QString& Key = QString("%1/%2").arg(LC_BLENDER_ADDON, mBlenderPaths[LblIdx].key);
const QString& Value = Settings.value(Key, QString()).toString();
@@ -2614,12 +2663,12 @@ void lcBlenderPreferences::SaveSettings()
for (int LblIdx = 1/*skip blender executable*/; LblIdx < NumPaths(); LblIdx++)
{
- if (LblIdx == PATH_STUDIO_LDRAW)
+ if (LblIdx >= PATH_STUDIO_LDRAW)
continue;
Key = mBlenderPaths[LblIdx].key;
Value = QDir::toNativeSeparators(mBlenderPaths[LblIdx].value);
- if (Settings.contains(Key))
+ if (!Key.isEmpty())
Settings.setValue(Key, QVariant(Value));
}
@@ -2643,7 +2692,7 @@ void lcBlenderPreferences::SaveSettings()
Key = mBlenderSettings[LblIdx].key;
- if (Settings.contains(Key))
+ if (!Key.isEmpty())
Settings.setValue(Key, QVariant(Value));
}
@@ -2662,7 +2711,7 @@ void lcBlenderPreferences::SaveSettings()
Key = mBlenderPaths[LblIdx].key_mm;
Value = QDir::toNativeSeparators(mBlenderPaths[LblIdx].value);
- if (Settings.contains(Key))
+ if (!Key.isEmpty())
Settings.setValue(Key, QVariant(Value));
}
@@ -2683,7 +2732,7 @@ void lcBlenderPreferences::SaveSettings()
Key = mBlenderSettingsMM[LblIdx].key;
- if (Settings.contains(Key))
+ if (!Key.isEmpty())
Settings.setValue(Key, QVariant(Value));
}
diff --git a/common/lc_blenderpreferences.h b/common/lc_blenderpreferences.h
index 522b61c7..8dba2af7 100644
--- a/common/lc_blenderpreferences.h
+++ b/common/lc_blenderpreferences.h
@@ -76,7 +76,7 @@ protected:
static int NumPaths(bool DefaultSettings = false);
static int NumSettings(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 void LoadDefaultParameters(QByteArray& Buffer, int Which);
static bool OverwriteFile(const QString& File);
@@ -121,14 +121,15 @@ private slots:
private:
enum BlenderPathType
{
- PATH_BLENDER, // 0 QLineEdit/QPushButton
- PATH_BLENDFILE, // 1 QLineEdit/QPushButton
- PATH_ENVIRONMENT, // 2 QLineEdit/QPushButton
- PATH_LDCONFIG, // 3 QLineEdit/QPushButton
- PATH_LDRAW, // 4 QLineEdit/QPushButton
- PATH_LSYNTH, // 5 QLineEdit/QPushButton
- PATH_STUD_LOGO, // 6 QLineEdit/QPushButton
- PATH_STUDIO_LDRAW, // 7 QLineEdit/QPushButton
+ PATH_BLENDER, // 0 QLineEdit/QPushButton
+ PATH_BLENDFILE, // 1 QLineEdit/QPushButton
+ PATH_ENVIRONMENT, // 2 QLineEdit/QPushButton
+ PATH_LDCONFIG, // 3 QLineEdit/QPushButton
+ PATH_LDRAW, // 4 QLineEdit/QPushButton
+ PATH_LSYNTH, // 5 QLineEdit/QPushButton
+ PATH_STUD_LOGO, // 6 QLineEdit/QPushButton
+ PATH_STUDIO_LDRAW, // 7 QLineEdit/QPushButton
+ PATH_STUDIO_CUSTOM_PARTS, // 8 QLineEdit/QPushButton
NUM_PATHS
};
@@ -239,10 +240,10 @@ private:
LBL_BLEND_FILE_TRUSTED_MM, // 2 QCheckBox
LBL_CASE_SENSITIVE_FILESYSTEM, // 3 QCheckBox
LBL_CROP_IMAGE_MM, // 4 QCheckBox
- LBL_DISPLAY_LOGO, // 5 QCheckBox
+ NUM_COMBO_ITEMS_MM, // 5
+ LBL_DISPLAY_LOGO = NUM_COMBO_ITEMS_MM, // 5 QCheckBox
LBL_IMPORT_CAMERAS_MM, // 6 QCheckBox
- NUM_COMBO_ITEMS_MM, // 7
- LBL_IMPORT_EDGES = NUM_COMBO_ITEMS_MM, // 7 QCheckBox
+ LBL_IMPORT_EDGES, // 7 QCheckBox
LBL_IMPORT_LIGHTS_MM, // 8 QCheckBox
LBL_KEEP_ASPECT_RATIO_MM, // 9 QCheckBox
LBL_MAKE_GAPS, // 10 QCheckBox
@@ -291,8 +292,8 @@ private:
LBL_CHOSEN_LOGO, // 52/ 0 QComboBox
LBL_COLOUR_SCHEME_MM, // 53/ 1 QComboBox
- LBL_COLOUR_STRATEGY, // 54/ 2 QComboBox
- LBL_RESOLUTION_MM, // 55/ 3 QComboBox
+ LBL_RESOLUTION_MM, // 54/ 2 QComboBox
+ LBL_SCALE_STRATEGY, // 55/ 3 QComboBox
LBL_SMOOTH_TYPE, // 56/ 4 QComboBox
NUM_SETTINGS_MM
@@ -309,10 +310,10 @@ private:
CTL_COLOUR_SCHEME_COMBO_MM = CTL_BEVEL_EDGES_BOX_MM, // 1
CTL_BLEND_FILE_TRUSTED_BOX_MM, // 2
CTL_BEVEL_WIDTH_EDIT_MM = CTL_BLEND_FILE_TRUSTED_BOX_MM,// 2
- CTL_COLOUR_STRATEGY_COMBO = CTL_BLEND_FILE_TRUSTED_BOX_MM,// 2
CTL_CASE_SENSITIVE_FILESYSTEM_BOX, // 3
CTL_CAMERA_BORDER_PERCENT_EDIT_MM = CTL_CASE_SENSITIVE_FILESYSTEM_BOX,// 3
CTL_RESOLUTION_COMBO_MM = CTL_CASE_SENSITIVE_FILESYSTEM_BOX,// 3
+ CTL_SCALE_STRATEGY_COMBO = CTL_CASE_SENSITIVE_FILESYSTEM_BOX,// 3
CTL_CROP_IMAGE_BOX_MM, // 4
CTL_FRAMES_PER_STEP_EDIT = CTL_CROP_IMAGE_BOX_MM, // 4
CTL_SMOOTH_TYPE_COMBO = CTL_CROP_IMAGE_BOX_MM, // 4