diff --git a/common/lc_library.cpp b/common/lc_library.cpp index fceecc88..bae9646f 100644 --- a/common/lc_library.cpp +++ b/common/lc_library.cpp @@ -1827,7 +1827,7 @@ void lcPiecesLibrary::GetPatternedPieces(PieceInfo* Parent, lcArray& } } -void lcPiecesLibrary::GetParts(lcArray& Parts) +void lcPiecesLibrary::GetParts(lcArray& Parts) const { Parts.SetSize(0); Parts.AllocGrow(mPieces.size()); @@ -1836,6 +1836,72 @@ void lcPiecesLibrary::GetParts(lcArray& Parts) Parts.Add(PartIt.second); } +std::vector lcPiecesLibrary::GetFavorites() const +{ + QStringList Favorites = lcGetProfileStringList(LC_PROFILE_LIBRARY_FAVORITES); + std::vector Parts; + Parts.reserve(Favorites.size()); + + for (const QString& Favorite : Favorites) + { + std::map::const_iterator PartIt = mPieces.find(Favorite.toStdString()); + + if (PartIt != mPieces.end()) + Parts.push_back(PartIt->second); + } + + return Parts; +} + +bool lcPiecesLibrary::IsFavorite(const PieceInfo* Info) const +{ + std::map::const_iterator PartIt = std::find_if(mPieces.begin(), mPieces.end(), [Info](const std::pair& PartIt) + { + return PartIt.second == Info; + }); + + if (PartIt == mPieces.end()) + return false; + + QStringList Favorites = lcGetProfileStringList(LC_PROFILE_LIBRARY_FAVORITES); + + return Favorites.contains(QString::fromStdString(PartIt->first)); +} + +void lcPiecesLibrary::AddToFavorites(const PieceInfo* Info) const +{ + std::map::const_iterator PartIt = std::find_if(mPieces.begin(), mPieces.end(), [Info](const std::pair& PartIt) + { + return PartIt.second == Info; + }); + + if (PartIt == mPieces.end()) + return; + + QStringList Favorites = lcGetProfileStringList(LC_PROFILE_LIBRARY_FAVORITES); + + Favorites.append(QString::fromStdString(PartIt->first)); + + lcSetProfileStringList(LC_PROFILE_LIBRARY_FAVORITES, Favorites); +} + +void lcPiecesLibrary::RemoveFromFavorites(const PieceInfo* Info) const +{ + std::map::const_iterator PartIt = std::find_if(mPieces.begin(), mPieces.end(), [Info](const std::pair& PartIt) + { + return PartIt.second == Info; + }); + + if (PartIt == mPieces.end()) + return; + + QStringList Favorites = lcGetProfileStringList(LC_PROFILE_LIBRARY_FAVORITES); + + Favorites.removeOne(QString::fromStdString(PartIt->first)); + + lcSetProfileStringList(LC_PROFILE_LIBRARY_FAVORITES, Favorites); +} + bool lcPiecesLibrary::LoadBuiltinPieces() { QResource Resource(":/resources/library.zip"); diff --git a/common/lc_library.h b/common/lc_library.h index 9eea8ee7..aff1ae4f 100644 --- a/common/lc_library.h +++ b/common/lc_library.h @@ -101,7 +101,12 @@ public: void GetCategoryEntries(int CategoryIndex, bool GroupPieces, lcArray& SinglePieces, lcArray& GroupedPieces); void GetCategoryEntries(const char* CategoryKeywords, bool GroupPieces, lcArray& SinglePieces, lcArray& GroupedPieces); void GetPatternedPieces(PieceInfo* Parent, lcArray& Pieces) const; - void GetParts(lcArray& Parts); + void GetParts(lcArray& Parts) const; + + std::vector GetFavorites() const; + bool IsFavorite(const PieceInfo* Info) const; + void AddToFavorites(const PieceInfo* Info) const; + void RemoveFromFavorites(const PieceInfo* Info) const; void GetPrimitiveFile(lcLibraryPrimitive* Primitive, std::function Callback); void GetPieceFile(const char* FileName, std::function Callback); diff --git a/common/lc_partselectionwidget.cpp b/common/lc_partselectionwidget.cpp index 5d628bda..efdd4793 100644 --- a/common/lc_partselectionwidget.cpp +++ b/common/lc_partselectionwidget.cpp @@ -185,6 +185,26 @@ void lcPartSelectionListModel::SetModelsCategory() SetFilter(mFilter); } +void lcPartSelectionListModel::SetFavoritesCategory() +{ + ClearRequests(); + + beginResetModel(); + + mParts.clear(); + + std::vector Favorites = lcGetPiecesLibrary()->GetFavorites(); + + mParts.reserve(Favorites.size()); + + for (PieceInfo* Favorite : Favorites) + mParts.emplace_back(QPair(Favorite, QPixmap())); + + endResetModel(); + + SetFilter(mFilter); +} + void lcPartSelectionListModel::SetCurrentModelCategory() { ClearRequests(); @@ -475,6 +495,31 @@ void lcPartSelectionListView::CustomContextMenuRequested(QPoint Pos) { QMenu* Menu = new QMenu(this); + QModelIndex Index = indexAt(Pos); + if (Index.isValid()) + { + PieceInfo* Info = mListModel->GetPieceInfo(Index.row()); + lcPiecesLibrary* Library = lcGetPiecesLibrary(); + + if (!Library->IsFavorite(Info)) + { + Menu->addAction(tr("Add to Favorites"), [Library, Info]() + { + Library->AddToFavorites(Info); + }); + } + else + { + Menu->addAction(tr("Remove from Favorites"), [this, Library, Info]() + { + Library->RemoveFromFavorites(Info); + emit FavoriteRemoved(); + }); + } + + Menu->addSeparator(); + } + if (gSupportsFramebufferObjectARB || gSupportsFramebufferObjectEXT) { QActionGroup* IconGroup = new QActionGroup(Menu); @@ -672,6 +717,7 @@ lcPartSelectionWidget::lcPartSelectionWidget(QWidget* Parent) Layout->addWidget(mSplitter); setLayout(Layout); + connect(mPartsWidget, SIGNAL(FavoriteRemoved()), this, SLOT(FavoriteRemoved())); connect(mPartsWidget->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(PartChanged(const QModelIndex&, const QModelIndex&))); connect(mFilterWidget, SIGNAL(textChanged(const QString&)), this, SLOT(FilterChanged(const QString&))); connect(mCategoriesWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(CategoryChanged(QTreeWidgetItem*, QTreeWidgetItem*))); @@ -787,10 +833,12 @@ void lcPartSelectionWidget::CategoryChanged(QTreeWidgetItem* Current, QTreeWidge ListModel->SetModelsCategory(); else if (Current == mCurrentModelCategoryItem) ListModel->SetCurrentModelCategory(); + else if (Current == mFavoritesCategoryItem) + ListModel->SetFavoritesCategory(); else if (Current == mAllPartsCategoryItem) ListModel->SetCategory(-1); else - ListModel->SetCategory(mCategoriesWidget->indexOfTopLevelItem(Current) - 2); + ListModel->SetCategory(mCategoriesWidget->indexOfTopLevelItem(Current) - 3); mPartsWidget->setCurrentIndex(ListModel->index(0, 0)); } @@ -803,6 +851,12 @@ void lcPartSelectionWidget::PartChanged(const QModelIndex& Current, const QModel gMainWindow->SetCurrentPieceInfo(mPartsWidget->GetCurrentPart()); } +void lcPartSelectionWidget::FavoriteRemoved() +{ + if (mCategoriesWidget->currentItem() == mFavoritesCategoryItem) + mPartsWidget->GetListModel()->SetFavoritesCategory(); +} + void lcPartSelectionWidget::Redraw() { mPartsWidget->GetListModel()->Redraw(); @@ -829,6 +883,7 @@ void lcPartSelectionWidget::UpdateCategories() mCategoriesWidget->clear(); mAllPartsCategoryItem = new QTreeWidgetItem(mCategoriesWidget, QStringList(tr("All Parts"))); + mFavoritesCategoryItem = new QTreeWidgetItem(mCategoriesWidget, QStringList(tr("Favorites"))); mCurrentModelCategoryItem = new QTreeWidgetItem(mCategoriesWidget, QStringList(tr("Parts In Use"))); for (int CategoryIdx = 0; CategoryIdx < gCategories.GetSize(); CategoryIdx++) diff --git a/common/lc_partselectionwidget.h b/common/lc_partselectionwidget.h index ef2f0640..f712f43e 100644 --- a/common/lc_partselectionwidget.h +++ b/common/lc_partselectionwidget.h @@ -81,6 +81,7 @@ public: void ToggleListMode(); void SetCategory(int CategoryIndex); void SetModelsCategory(); + void SetFavoritesCategory(); void SetCurrentModelCategory(); void SetFilter(const QString& Filter); void RequestPreview(int InfoIndex); @@ -131,6 +132,9 @@ public: void UpdateViewMode(); +signals: + void FavoriteRemoved(); + public slots: void CustomContextMenuRequested(QPoint Pos); void SetNoIcons(); @@ -176,6 +180,7 @@ protected slots: void FilterTriggered(); void CategoryChanged(QTreeWidgetItem* Current, QTreeWidgetItem* Previous); void PartChanged(const QModelIndex& Current, const QModelIndex& Previous); + void FavoriteRemoved(); protected: virtual void resizeEvent(QResizeEvent* Event); @@ -183,6 +188,7 @@ protected: QTreeWidget* mCategoriesWidget; QTreeWidgetItem* mAllPartsCategoryItem; + QTreeWidgetItem* mFavoritesCategoryItem; QTreeWidgetItem* mCurrentModelCategoryItem; QTreeWidgetItem* mModelsCategoryItem; QLineEdit* mFilterWidget; diff --git a/common/lc_profile.cpp b/common/lc_profile.cpp index e53c47ae..e370f0e3 100644 --- a/common/lc_profile.cpp +++ b/common/lc_profile.cpp @@ -77,6 +77,7 @@ static lcProfileEntry gProfileEntries[LC_NUM_PROFILE_KEYS] = lcProfileEntry("Settings", "CheckUpdates", 1), // LC_PROFILE_CHECK_UPDATES lcProfileEntry("Settings", "ProjectsPath", ""), // LC_PROFILE_PROJECTS_PATH lcProfileEntry("Settings", "PartsLibrary", ""), // LC_PROFILE_PARTS_LIBRARY + lcProfileEntry("Settings", "LibraryFavorites", QStringList()), // LC_PROFILE_LIBRARY_FAVORITES lcProfileEntry("Settings", "MinifigSettings", ""), // LC_PROFILE_MINIFIG_SETTINGS lcProfileEntry("Settings", "ColorConfig", ""), // LC_PROFILE_COLOR_CONFIG lcProfileEntry("Settings", "Shortcuts"), // LC_PROFILE_KEYBOARD_SHORTCUTS diff --git a/common/lc_profile.h b/common/lc_profile.h index fa94efcd..cef08757 100644 --- a/common/lc_profile.h +++ b/common/lc_profile.h @@ -25,6 +25,7 @@ enum LC_PROFILE_KEY LC_PROFILE_CHECK_UPDATES, LC_PROFILE_PROJECTS_PATH, LC_PROFILE_PARTS_LIBRARY, + LC_PROFILE_LIBRARY_FAVORITES, LC_PROFILE_MINIFIG_SETTINGS, LC_PROFILE_COLOR_CONFIG, LC_PROFILE_KEYBOARD_SHORTCUTS,