From c55c544af9adc30f3323e7a6b92af47f1702cf2a Mon Sep 17 00:00:00 2001 From: Gerd Wachsmuth Date: Sun, 14 Jan 2024 08:16:56 +0100 Subject: [PATCH] Improve search/replace feature The replace feature was quite bugged: - in the replace widget, there was no difference between the buttons 'Find next' and 'Replace next' and between 'Find all' and 'Replace all' - 'Replace all' did not work - the logic for replacing colors was bugged --- common/lc_mainwindow.cpp | 10 +++--- common/lc_model.cpp | 73 +++++++++++++++++++++++++++------------- common/lc_model.h | 2 +- 3 files changed, 55 insertions(+), 30 deletions(-) diff --git a/common/lc_mainwindow.cpp b/common/lc_mainwindow.cpp index 09332692..1bb19afa 100644 --- a/common/lc_mainwindow.cpp +++ b/common/lc_mainwindow.cpp @@ -2705,17 +2705,17 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId) case LC_EDIT_FIND_NEXT: if (ActiveModel) - ActiveModel->FindReplacePiece(true, false); + ActiveModel->FindReplacePiece(true, false, false); break; case LC_EDIT_FIND_PREVIOUS: if (ActiveModel) - ActiveModel->FindReplacePiece(false, false); + ActiveModel->FindReplacePiece(false, false, false); break; case LC_EDIT_FIND_ALL: if (ActiveModel) - ActiveModel->FindReplacePiece(true, true); + ActiveModel->FindReplacePiece(true, true, false); break; case LC_EDIT_REPLACE: @@ -2725,12 +2725,12 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId) case LC_EDIT_REPLACE_ALL: if (ActiveModel) - ActiveModel->FindReplacePiece(true, true); + ActiveModel->FindReplacePiece(true, true, true); break; case LC_EDIT_REPLACE_NEXT: if (ActiveModel) - ActiveModel->FindReplacePiece(true, false); + ActiveModel->FindReplacePiece(true, false, true); break; case LC_EDIT_SELECT_ALL: diff --git a/common/lc_model.cpp b/common/lc_model.cpp index f50be800..1cd91b91 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -4123,15 +4123,21 @@ void lcModel::UnhideAllPieces() SaveCheckpoint(tr("Unhide")); } -void lcModel::FindReplacePiece(bool SearchForward, bool FindAll) +void lcModel::FindReplacePiece(bool SearchForward, bool FindAll, bool Replace) { if (mPieces.IsEmpty()) return; - auto PieceMatches = [](const lcPiece* Piece) - { - const lcFindReplaceParams& Params = lcView::GetFindReplaceParams(); + const lcFindReplaceParams& Params = lcView::GetFindReplaceParams(); + // Are we going to replace colors? + const bool ReplaceColor = lcGetColorCode(Params.ReplaceColorIndex) != LC_COLOR_NOCOLOR; + + // Check if we are supposed to actually replace something + const bool Replacing = Replace && (ReplaceColor || Params.ReplacePieceInfo); + + auto PieceMatches = [&Params](const lcPiece* Piece) + { if (Params.FindInfo && Params.FindInfo != Piece->mPieceInfo) return false; @@ -4141,36 +4147,40 @@ void lcModel::FindReplacePiece(bool SearchForward, bool FindAll) return (lcGetColorCode(Params.FindColorIndex) == LC_COLOR_NOCOLOR) || (Piece->GetColorIndex() == Params.FindColorIndex); }; - const lcFindReplaceParams& Params = lcView::GetFindReplaceParams(); + auto ReplacePiece = [&Params, ReplaceColor](lcPiece* Piece) + { + if (ReplaceColor) + Piece->SetColorIndex(Params.ReplaceColorIndex); + + if (Params.ReplacePieceInfo) + Piece->SetPieceInfo(Params.ReplacePieceInfo, QString(), true); + }; + int StartIdx = mPieces.GetSize() - 1; - for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) + bool ReplacedSomething = false; + + if (!FindAll) { - lcPiece* Piece = mPieces[PieceIdx]; + // We have to find the currently focused piece, in order to find next/prev match and (optionally) to replace it + lcPiece* const FocusedPiece = dynamic_cast(GetFocusObject()); - if (Piece->IsFocused() && Piece->IsVisible(mCurrentStep)) + if (FocusedPiece) { - if (PieceMatches(Piece)) + for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) { - const bool ReplaceColor = lcGetColorCode(Params.FindColorIndex) != LC_COLOR_NOCOLOR; - - if (ReplaceColor) - Piece->SetColorIndex(Params.ReplaceColorIndex); - - if (Params.ReplacePieceInfo) - Piece->SetPieceInfo(Params.ReplacePieceInfo, QString(), true); - - if (ReplaceColor || Params.ReplacePieceInfo) + if (FocusedPiece == mPieces[PieceIdx]) { - SaveCheckpoint(tr("Replacing Part")); - gMainWindow->UpdateSelectedObjects(false); - UpdateAllViews(); - gMainWindow->UpdateTimeline(false, true); + StartIdx = PieceIdx; + break; } } - StartIdx = PieceIdx; - break; + if (Replacing && PieceMatches(FocusedPiece)) + { + ReplacePiece(FocusedPiece); + ReplacedSomething = true; + } } } @@ -4195,7 +4205,14 @@ void lcModel::FindReplacePiece(bool SearchForward, bool FindAll) if (Current->IsVisible(mCurrentStep) && PieceMatches(Current)) { if (FindAll) + { Selection.Add(Current); + if (Replacing) + { + ReplacePiece(Current); + ReplacedSomething = true; + } + } else { Focus = Current; @@ -4211,6 +4228,14 @@ void lcModel::FindReplacePiece(bool SearchForward, bool FindAll) SetSelectionAndFocus(Selection, nullptr, 0, false); else ClearSelectionAndSetFocus(Focus, LC_PIECE_SECTION_POSITION, false); + + if (ReplacedSomething) + { + SaveCheckpoint(tr("Replacing Part")); + gMainWindow->UpdateSelectedObjects(false); + UpdateAllViews(); + gMainWindow->UpdateTimeline(false, true); + } } void lcModel::UndoAction() diff --git a/common/lc_model.h b/common/lc_model.h index 59bee78c..a54e433e 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -312,7 +312,7 @@ public: void UnhideSelectedPieces(); void UnhideAllPieces(); - void FindReplacePiece(bool SearchForward, bool FindAll); + void FindReplacePiece(bool SearchForward, bool FindAll, bool Replace); void UndoAction(); void RedoAction();