diff --git a/common/lc_application.cpp b/common/lc_application.cpp index c2447ec2..52e5af28 100644 --- a/common/lc_application.cpp +++ b/common/lc_application.cpp @@ -5,6 +5,7 @@ #include "lc_profile.h" #include "project.h" #include "lc_mainwindow.h" +#include "lc_partselectionwidget.h" #include "lc_shortcuts.h" #include "view.h" @@ -82,20 +83,23 @@ void lcApplication::ExportClipboard(const QByteArray& Clipboard) SetClipboard(Clipboard); } -bool lcApplication::LoadPiecesLibrary(const QList>& LibraryPaths) +bool lcApplication::LoadPartsLibrary(const QList>& LibraryPaths, bool OnlyUsePaths) { if (mLibrary == nullptr) mLibrary = new lcPiecesLibrary(); - char* EnvPath = getenv("LEOCAD_LIB"); + if (!OnlyUsePaths) + { + char* EnvPath = getenv("LEOCAD_LIB"); - if (EnvPath && EnvPath[0]) - return mLibrary->Load(EnvPath); + if (EnvPath && EnvPath[0]) + return mLibrary->Load(EnvPath); - QString CustomPath = lcGetProfileString(LC_PROFILE_PARTS_LIBRARY); + QString CustomPath = lcGetProfileString(LC_PROFILE_PARTS_LIBRARY); - if (!CustomPath.isEmpty()) - return mLibrary->Load(CustomPath); + if (!CustomPath.isEmpty()) + return mLibrary->Load(CustomPath); + } for (const QPair& LibraryPathEntry : LibraryPaths) { @@ -149,6 +153,7 @@ void lcApplication::ParseStringArgument(int* CurArg, int argc, char* argv[], con bool lcApplication::Initialize(int argc, char* argv[], QList>& LibraryPaths, bool& ShowWindow) { // todo: parse command line using Qt to handle multibyte strings. + bool OnlyUseLibraryPaths = false; bool SaveImage = false; bool SaveWavefront = false; bool Save3DS = false; @@ -182,6 +187,7 @@ bool lcApplication::Initialize(int argc, char* argv[], QList(LibPath, false); + OnlyUseLibraryPaths = true; } } else if ((strcmp(Param, "-i") == 0) || (strcmp(Param, "--image") == 0)) @@ -320,7 +326,7 @@ bool lcApplication::Initialize(int argc, char* argv[], QListSetColorIndex(lcGetColorIndex(4)); + gMainWindow->GetPartSelectionWidget()->SetDefaultPart(); + gMainWindow->UpdateRecentFiles(); + gMainWindow->show(); + } + return true; } diff --git a/common/lc_application.h b/common/lc_application.h index d37f99ce..e1c0cdcf 100644 --- a/common/lc_application.h +++ b/common/lc_application.h @@ -46,7 +46,7 @@ public: void Shutdown(); void ShowPreferencesDialog(); - bool LoadPiecesLibrary(const QList>& LibraryPaths); + bool LoadPartsLibrary(const QList>& LibraryPaths, bool OnlyUsePaths); void SetClipboard(const QByteArray& Clipboard); void ExportClipboard(const QByteArray& Clipboard); diff --git a/common/lc_library.cpp b/common/lc_library.cpp index dfa49006..aa76e1a0 100644 --- a/common/lc_library.cpp +++ b/common/lc_library.cpp @@ -534,12 +534,16 @@ bool lcPiecesLibrary::OpenDirectory(const QDir& LibraryDir) } const QLatin1String BaseFolders[] = { QLatin1String("unofficial/"), QLatin1String("") }; + const int NumBaseFolders = sizeof(BaseFolders) / sizeof(BaseFolders[0]); if (mPieces.empty()) { - for (unsigned int BaseFolderIdx = 0; BaseFolderIdx < sizeof(BaseFolders) / sizeof(BaseFolders[0]); BaseFolderIdx++) + QDir BaseDirs[NumBaseFolders]; + + for (unsigned int BaseFolderIdx = 0; BaseFolderIdx < NumBaseFolders; BaseFolderIdx++) { - QDir Dir(QDir(LibraryDir.absoluteFilePath(BaseFolders[BaseFolderIdx])).absoluteFilePath(QLatin1String("parts/")), QLatin1String("*.dat"), QDir::SortFlags(QDir::Name | QDir::IgnoreCase), QDir::Files | QDir::Hidden | QDir::Readable); + BaseDirs[BaseFolderIdx] = QDir(QDir(LibraryDir.absoluteFilePath(BaseFolders[BaseFolderIdx])).absoluteFilePath(QLatin1String("parts/")), QLatin1String("*.dat"), QDir::SortFlags(QDir::Name | QDir::IgnoreCase), QDir::Files | QDir::Hidden | QDir::Readable); + QDir& Dir = BaseDirs[BaseFolderIdx]; QStringList FileList = Dir.entryList(); for (int FileIdx = 0; FileIdx < FileList.size(); FileIdx++) @@ -573,21 +577,40 @@ bool lcPiecesLibrary::OpenDirectory(const QDir& LibraryDir) if (mHasUnofficial && mPieces.find(Name) != mPieces.end()) continue; - lcDiskFile PieceFile(Dir.absoluteFilePath(FileList[FileIdx])); - if (!PieceFile.Open(QIODevice::ReadOnly)) - continue; - - char Line[1024]; - if (!PieceFile.ReadLine(Line, sizeof(Line))) - continue; - PieceInfo* Info = new PieceInfo(); if (BaseFolderIdx == 0) mHasUnofficial = true; - Src = (char*)Line + 2; - Dst = Info->m_strDescription; + strncpy(Info->mFileName, FileString, sizeof(Info->mFileName)); + Info->mFileName[sizeof(Info->mFileName) - 1] = 0; + Info->mUnofficial = (BaseFolderIdx == 0); + + mPieces[Name] = Info; + } + } + + if (!mPieces.empty()) + { + QAtomicInt FilesLoaded; + + auto ReadDescriptions = [&BaseDirs, &FilesLoaded](const std::pair& Entry) + { + PieceInfo* Info = Entry.second; + FilesLoaded += 1; + + QDir& Dir = BaseDirs[Info->mUnofficial ? 0 : 1]; + lcDiskFile PieceFile(Dir.absoluteFilePath(Info->mFileName)); + char Line[1024]; + + if (!PieceFile.Open(QIODevice::ReadOnly) || !PieceFile.ReadLine(Line, sizeof(Line))) + { + strcpy(Info->m_strDescription, "Unknown"); + return; + } + + const char* Src = Line + 2; + char* Dst = Info->m_strDescription; for (;;) { @@ -600,12 +623,28 @@ bool lcPiecesLibrary::OpenDirectory(const QDir& LibraryDir) *Dst = 0; break; } + }; - strncpy(Info->mFileName, FileString, sizeof(Info->mFileName)); - Info->mFileName[sizeof(Info->mFileName) - 1] = 0; + QProgressDialog* ProgressDialog = new QProgressDialog(nullptr); + ProgressDialog->setWindowFlags(ProgressDialog->windowFlags() & ~Qt::WindowCloseButtonHint); + ProgressDialog->setWindowTitle(tr("Initializing")); + ProgressDialog->setLabelText(tr("Loading Parts Library")); + ProgressDialog->setMaximum(mPieces.size()); + ProgressDialog->setMinimum(0); + ProgressDialog->setValue(0); + ProgressDialog->setCancelButton(nullptr); + ProgressDialog->show(); - mPieces[Name] = Info; + QFuture LoadFuture = QtConcurrent::map(mPieces, ReadDescriptions); + + while (!LoadFuture.isFinished()) + { + ProgressDialog->setValue(FilesLoaded); + + QApplication::processEvents(); } + + ProgressDialog->deleteLater(); } } diff --git a/common/pieceinf.h b/common/pieceinf.h index ef07082f..41c2c715 100644 --- a/common/pieceinf.h +++ b/common/pieceinf.h @@ -155,6 +155,7 @@ public: int mZipFileIndex; lcuint32 mFlags; lcPieceInfoState mState; + bool mUnofficial; protected: void ReleaseMesh(); diff --git a/qt/qtmain.cpp b/qt/qtmain.cpp index 72b44b28..174aa5da 100644 --- a/qt/qtmain.cpp +++ b/qt/qtmain.cpp @@ -2,9 +2,6 @@ #include "lc_application.h" #include "lc_qupdatedialog.h" #include "lc_mainwindow.h" -#include "project.h" -#include "lc_colors.h" -#include "lc_partselectionwidget.h" #include #include @@ -178,11 +175,6 @@ int main(int argc, char *argv[]) if (ShowWindow) { - gMainWindow->SetColorIndex(lcGetColorIndex(4)); - gMainWindow->GetPartSelectionWidget()->SetDefaultPart(); - gMainWindow->UpdateRecentFiles(); - gMainWindow->show(); - #if !LC_DISABLE_UPDATE_CHECK lcDoInitialUpdateCheck(); #endif