diff --git a/search/search_quality/assessment_tool/context.cpp b/search/search_quality/assessment_tool/context.cpp index 5eda346d10..5704f1e56c 100644 --- a/search/search_quality/assessment_tool/context.cpp +++ b/search/search_quality/assessment_tool/context.cpp @@ -31,14 +31,14 @@ search::Sample Context::MakeSample(search::FeatureLoader & loader) const if (!m_initialized) return outSample; - auto const & foundRelevances = m_foundResultsEdits.GetRelevances(); - auto const & nonFoundRelevances = m_nonFoundResultsEdits.GetRelevances(); + auto const & foundEntries = m_foundResultsEdits.GetEntries(); + auto const & nonFoundEntries = m_nonFoundResultsEdits.GetEntries(); auto & outResults = outSample.m_results; outResults.clear(); CHECK_EQUAL(m_goldenMatching.size(), m_sample.m_results.size(), ()); - CHECK_EQUAL(m_actualMatching.size(), foundRelevances.size(), ()); + CHECK_EQUAL(m_actualMatching.size(), foundEntries.size(), ()); CHECK_EQUAL(m_actualMatching.size(), m_foundResults.GetCount(), ()); // Iterates over original (loaded from the file with search samples) @@ -53,8 +53,10 @@ search::Sample Context::MakeSample(search::FeatureLoader & loader) const // assessor. But we want to keep them. if (j == search::Matcher::kInvalidId) { - auto const relevance = nonFoundRelevances[k++]; - if (relevance != search::Sample::Result::Relevance::Irrelevant) + auto const & entry = nonFoundEntries[k++]; + auto const deleted = entry.m_deleted; + auto const relevance = entry.m_curr; + if (!deleted && relevance != search::Sample::Result::Relevance::Irrelevant) { auto result = m_sample.m_results[i]; result.m_relevance = relevance; @@ -64,11 +66,11 @@ search::Sample Context::MakeSample(search::FeatureLoader & loader) const } // No need to keep irrelevant results. - if (foundRelevances[j] == search::Sample::Result::Relevance::Irrelevant) + if (foundEntries[j].m_curr == search::Sample::Result::Relevance::Irrelevant) continue; auto result = m_sample.m_results[i]; - result.m_relevance = foundRelevances[j]; + result.m_relevance = foundEntries[j].m_curr; outResults.push_back(move(result)); } @@ -83,7 +85,7 @@ search::Sample Context::MakeSample(search::FeatureLoader & loader) const } // No need to keep irrelevant results. - if (foundRelevances[i] == search::Sample::Result::Relevance::Irrelevant) + if (foundEntries[i].m_curr == search::Sample::Result::Relevance::Irrelevant) continue; auto const & result = m_foundResults[i]; @@ -93,7 +95,7 @@ search::Sample Context::MakeSample(search::FeatureLoader & loader) const FeatureType ft; CHECK(loader.Load(result.GetFeatureID(), ft), ()); - outResults.push_back(search::Sample::Result::Build(ft, foundRelevances[i])); + outResults.push_back(search::Sample::Result::Build(ft, foundEntries[i].m_curr)); } return outSample; @@ -103,8 +105,8 @@ void Context::ApplyEdits() { if (!m_initialized) return; - m_foundResultsEdits.ResetRelevances(m_foundResultsEdits.GetRelevances()); - m_nonFoundResultsEdits.ResetRelevances(m_nonFoundResultsEdits.GetRelevances()); + m_foundResultsEdits.Apply(); + m_nonFoundResultsEdits.Apply(); } // ContextList ------------------------------------------------------------------------------------- diff --git a/search/search_quality/assessment_tool/edits.cpp b/search/search_quality/assessment_tool/edits.cpp index b94c9f39ed..62df175cb2 100644 --- a/search/search_quality/assessment_tool/edits.cpp +++ b/search/search_quality/assessment_tool/edits.cpp @@ -15,52 +15,82 @@ bool Edits::RelevanceEditor::Set(Relevance relevance) Edits::Relevance Edits::RelevanceEditor::Get() const { - auto const & relevances = m_parent.GetRelevances(); - CHECK_LESS(m_index, relevances.size(), ()); - return relevances[m_index]; + return m_parent.Get(m_index).m_curr; } -bool Edits::RelevanceEditor::HasChanges() const -{ - return m_parent.HasChanges(m_index); -} +bool Edits::RelevanceEditor::HasChanges() const { return m_parent.HasChanges(m_index); } // Edits ------------------------------------------------------------------------------------------- -void Edits::ResetRelevances(std::vector const & relevances) +void Edits::Apply() { - WithObserver(Update::AllRelevancesUpdate(), [this, &relevances]() { - m_origRelevances = relevances; - m_currRelevances = relevances; + WithObserver(Update::MakeAll(), [this]() { + for (auto & entry : m_entries) + entry.m_orig = entry.m_curr; + m_numEdits = 0; + }); +} + +void Edits::Reset(std::vector const & relevances) +{ + WithObserver(Update::MakeAll(), [this, &relevances]() { + m_entries.resize(relevances.size()); + for (size_t i = 0; i < relevances.size(); ++i) + { + m_entries[i].m_orig = relevances[i]; + m_entries[i].m_curr = relevances[i]; + m_entries[i].m_deleted = false; + } m_numEdits = 0; }); } bool Edits::SetRelevance(size_t index, Relevance relevance) { - return WithObserver(Update::SingleRelevanceUpdate(index), [this, index, relevance]() { - CHECK_LESS(index, m_currRelevances.size(), ()); - CHECK_EQUAL(m_currRelevances.size(), m_origRelevances.size(), ()); + return WithObserver(Update::MakeSingle(index), [this, index, relevance]() { + CHECK_LESS(index, m_entries.size(), ()); - if (m_currRelevances[index] != m_origRelevances[index] && relevance == m_origRelevances[index]) - { + auto & entry = m_entries[index]; + + if (entry.m_curr != entry.m_orig && relevance == entry.m_orig) --m_numEdits; - } - else if (m_currRelevances[index] == m_origRelevances[index] && - relevance != m_origRelevances[index]) - { + else if (entry.m_curr == entry.m_orig && relevance != entry.m_orig) ++m_numEdits; - } - m_currRelevances[index] = relevance; - return m_currRelevances[index] != m_origRelevances[index]; + entry.m_curr = relevance; + return entry.m_curr != entry.m_orig; }); } +void Edits::Delete(size_t index) +{ + return WithObserver(Update::MakeDelete(index), [this, index]() { + CHECK_LESS(index, m_entries.size(), ()); + + auto & entry = m_entries[index]; + CHECK(!entry.m_deleted, ()); + entry.m_deleted = true; + ++m_numEdits; + }); +} + +std::vector Edits::GetRelevances() const +{ + std::vector relevances(m_entries.size()); + for (size_t i = 0; i < m_entries.size(); ++i) + relevances[i] = m_entries[i].m_curr; + return relevances; +} + +Edits::Entry const & Edits::Get(size_t index) const +{ + CHECK_LESS(index, m_entries.size(), ()); + return m_entries[index]; +} + void Edits::Clear() { - WithObserver(Update::AllRelevancesUpdate(), [this]() { - m_origRelevances.clear(); - m_currRelevances.clear(); + WithObserver(Update::MakeAll(), [this]() { + m_entries.clear(); m_numEdits = 0; }); } @@ -69,7 +99,7 @@ bool Edits::HasChanges() const { return m_numEdits != 0; } bool Edits::HasChanges(size_t index) const { - CHECK_LESS(index, m_currRelevances.size(), ()); - CHECK_LESS(index, m_origRelevances.size(), ()); - return m_currRelevances[index] != m_origRelevances[index]; + CHECK_LESS(index, m_entries.size(), ()); + auto const & entry = m_entries[index]; + return entry.m_curr != entry.m_orig; } diff --git a/search/search_quality/assessment_tool/edits.hpp b/search/search_quality/assessment_tool/edits.hpp index 2932b56904..8a1d9e5ace 100644 --- a/search/search_quality/assessment_tool/edits.hpp +++ b/search/search_quality/assessment_tool/edits.hpp @@ -13,32 +13,42 @@ class Edits { public: + using Relevance = search::Sample::Result::Relevance; + + struct Entry + { + Entry() = default; + + Relevance m_curr = Relevance::Irrelevant; + Relevance m_orig = Relevance::Irrelevant; + bool m_deleted = false; + }; + struct Update { static auto constexpr kInvalidIndex = std::numeric_limits::max(); enum class Type { - SingleRelevance, - AllRelevances + Single, + All, + Delete }; - static Update AllRelevancesUpdate() { return Update{}; } + Update() = default; + Update(Type type, size_t index): m_type(type), m_index(index) {} - static Update SingleRelevanceUpdate(size_t index) - { - Update result; - result.m_index = index; - result.m_type = Type::SingleRelevance; - return result; - } + static Update MakeAll() { return Update{}; } + static Update MakeSingle(size_t index) { return Update{Type::Single, index}; } + + static Update MakeDelete(size_t index) { return Update{Type::Delete, index}; } + + Type m_type = Type::All; size_t m_index = kInvalidIndex; - Type m_type = Type::AllRelevances; }; using OnUpdate = std::function; - using Relevance = search::Sample::Result::Relevance; class RelevanceEditor { @@ -58,13 +68,21 @@ public: explicit Edits(OnUpdate onUpdate) : m_onUpdate(onUpdate) {} - void ResetRelevances(std::vector const & relevances); + void Apply(); + void Reset(std::vector const & relevances); // Sets relevance at |index| to |relevance|. Returns true iff // |relevance| differs from the original one. bool SetRelevance(size_t index, Relevance relevance); - std::vector const & GetRelevances() const { return m_currRelevances; } + // Marks entry at |index| as deleted. + void Delete(size_t index); + + std::vector const & GetEntries() const { return m_entries; } + std::vector GetRelevances() const; + + Entry const & Get(size_t index) const; + void Clear(); bool HasChanges() const; @@ -81,8 +99,7 @@ private: return fn(); } - std::vector m_origRelevances; - std::vector m_currRelevances; + std::vector m_entries; size_t m_numEdits = 0; diff --git a/search/search_quality/assessment_tool/main_model.cpp b/search/search_quality/assessment_tool/main_model.cpp index 14466dedd1..37b90764e2 100644 --- a/search/search_quality/assessment_tool/main_model.cpp +++ b/search/search_quality/assessment_tool/main_model.cpp @@ -232,6 +232,14 @@ void MainModel::OnUpdate(View::ResultType type, size_t sampleIndex, Edits::Updat m_view->OnResultChanged(sampleIndex, type, update); m_view->OnSampleChanged(sampleIndex, context.HasChanges()); m_view->OnSamplesChanged(m_contexts.HasChanges()); + + if (update.m_type == Edits::Update::Type::Delete) + { + CHECK(context.m_initialized, ()); + + CHECK_EQUAL(type, View::ResultType::NonFound, ()); + ShowMarks(context); + } } void MainModel::OnResults(uint64_t timestamp, size_t sampleIndex, search::Results const & results, @@ -256,7 +264,7 @@ void MainModel::OnResults(uint64_t timestamp, size_t sampleIndex, search::Result if (!context.m_initialized) { - context.m_foundResultsEdits.ResetRelevances(relevances); + context.m_foundResultsEdits.Reset(relevances); context.m_goldenMatching = goldenMatching; context.m_actualMatching = actualMatching; @@ -273,20 +281,21 @@ void MainModel::OnResults(uint64_t timestamp, size_t sampleIndex, search::Result nonFound.push_back(context.m_sample.m_results[i]); relevances.push_back(nonFound.back().m_relevance); } - context.m_nonFoundResultsEdits.ResetRelevances(relevances); + context.m_nonFoundResultsEdits.Reset(relevances); } context.m_initialized = true; } - m_view->ShowNonFoundResults(context.m_nonFoundResults); + m_view->ShowNonFoundResults(context.m_nonFoundResults, + context.m_nonFoundResultsEdits.GetEntries()); + ShowMarks(context); m_view->OnResultChanged(sampleIndex, View::ResultType::Found, - Edits::Update::AllRelevancesUpdate()); + Edits::Update::MakeAll()); m_view->OnResultChanged(sampleIndex, View::ResultType::NonFound, - Edits::Update::AllRelevancesUpdate()); + Edits::Update::MakeAll()); m_view->OnSampleChanged(sampleIndex, context.HasChanges()); - m_view->EnableSampleEditing(sampleIndex, context.m_foundResultsEdits, - context.m_nonFoundResultsEdits); + m_view->SetEdits(sampleIndex, context.m_foundResultsEdits, context.m_nonFoundResultsEdits); m_view->OnSearchCompleted(); } @@ -296,3 +305,11 @@ void MainModel::ResetSearch() if (auto handle = m_queryHandle.lock()) handle->Cancel(); } + +void MainModel::ShowMarks(Context const & context) +{ + m_view->ClearSearchResultMarks(); + m_view->ShowFoundResultsMarks(context.m_foundResults.begin(), context.m_foundResults.end()); + m_view->ShowNonFoundResultsMarks(context.m_nonFoundResults, + context.m_nonFoundResultsEdits.GetEntries()); +} diff --git a/search/search_quality/assessment_tool/main_model.hpp b/search/search_quality/assessment_tool/main_model.hpp index 69c9cc5774..462d309489 100644 --- a/search/search_quality/assessment_tool/main_model.hpp +++ b/search/search_quality/assessment_tool/main_model.hpp @@ -49,6 +49,7 @@ private: std::vector const & actualMatching); void ResetSearch(); + void ShowMarks(Context const & context); Framework & m_framework; Index const & m_index; diff --git a/search/search_quality/assessment_tool/main_view.cpp b/search/search_quality/assessment_tool/main_view.cpp index 6d1cee23f5..191ae3e8ae 100644 --- a/search/search_quality/assessment_tool/main_view.cpp +++ b/search/search_quality/assessment_tool/main_view.cpp @@ -72,8 +72,8 @@ void MainView::ShowSample(size_t sampleIndex, search::Sample const & sample, boo m_sampleView->SetContents(sample, positionAvailable); m_sampleView->show(); - OnResultChanged(sampleIndex, ResultType::Found, Edits::Update::AllRelevancesUpdate()); - OnResultChanged(sampleIndex, ResultType::NonFound, Edits::Update::AllRelevancesUpdate()); + OnResultChanged(sampleIndex, ResultType::Found, Edits::Update::MakeAll()); + OnResultChanged(sampleIndex, ResultType::NonFound, Edits::Update::MakeAll()); OnSampleChanged(sampleIndex, hasEdits); } @@ -82,11 +82,27 @@ void MainView::ShowFoundResults(search::Results::ConstIter begin, search::Result m_sampleView->ShowFoundResults(begin, end); } -void MainView::ShowNonFoundResults(std::vector const & results) +void MainView::ShowNonFoundResults(std::vector const & results, + std::vector const & entries) { - m_sampleView->ShowNonFoundResults(results); + m_sampleView->ShowNonFoundResults(results, entries); } +void MainView::ShowFoundResultsMarks(search::Results::ConstIter begin, + search::Results::ConstIter end) + +{ + m_sampleView->ShowFoundResultsMarks(begin, end); +} + +void MainView::ShowNonFoundResultsMarks(std::vector const & results, + std::vector const & entries) +{ + m_sampleView->ShowNonFoundResultsMarks(results, entries); +} + +void MainView::ClearSearchResultMarks() { m_sampleView->ClearSearchResultMarks(); } + void MainView::MoveViewportToResult(search::Result const & result) { m_framework.SelectSearchResult(result, false /* animation */); @@ -132,11 +148,10 @@ void MainView::OnSamplesChanged(bool hasEdits) m_saveAs->setEnabled(hasEdits); } -void MainView::EnableSampleEditing(size_t sampleIndex, Edits & foundResultsEdits, - Edits & nonFoundResultsEdits) +void MainView::SetEdits(size_t sampleIndex, Edits & foundResultsEdits, Edits & nonFoundResultsEdits) { CHECK(m_samplesView->IsSelected(sampleIndex), ()); - m_sampleView->EnableEditing(foundResultsEdits, nonFoundResultsEdits); + m_sampleView->SetEdits(foundResultsEdits, nonFoundResultsEdits); } void MainView::ShowError(std::string const & msg) diff --git a/search/search_quality/assessment_tool/main_view.hpp b/search/search_quality/assessment_tool/main_view.hpp index faecaef037..82011ff908 100644 --- a/search/search_quality/assessment_tool/main_view.hpp +++ b/search/search_quality/assessment_tool/main_view.hpp @@ -32,16 +32,24 @@ public: void OnSearchCompleted() override; void ShowSample(size_t sampleIndex, search::Sample const & sample, bool positionAvailable, bool hasEdits) override; + void ShowFoundResults(search::Results::ConstIter begin, search::Results::ConstIter end) override; - void ShowNonFoundResults(std::vector const & results) override; + void ShowNonFoundResults(std::vector const & results, + std::vector const & entries) override; + + void ShowFoundResultsMarks(search::Results::ConstIter begin, + search::Results::ConstIter end) override; + void ShowNonFoundResultsMarks(std::vector const & results, + std::vector const & entries) override; + void ClearSearchResultMarks() override; void MoveViewportToResult(search::Result const & result) override; void MoveViewportToResult(search::Sample::Result const & result) override; void MoveViewportToRect(m2::RectD const & rect) override; void OnResultChanged(size_t sampleIndex, ResultType type, Edits::Update const & update) override; - void EnableSampleEditing(size_t sampleIndex, Edits & foundResultsEdits, - Edits & nonFoundResultsEdits) override; + void SetEdits(size_t sampleIndex, Edits & foundResultsEdits, + Edits & nonFoundResultsEdits) override; void OnSampleChanged(size_t sampleIndex, bool hasEdits) override; void OnSamplesChanged(bool hasEdits) override; diff --git a/search/search_quality/assessment_tool/result_view.cpp b/search/search_quality/assessment_tool/result_view.cpp index ac82239ee8..d6da1e95a7 100644 --- a/search/search_quality/assessment_tool/result_view.cpp +++ b/search/search_quality/assessment_tool/result_view.cpp @@ -63,7 +63,7 @@ ResultView::ResultView(search::Sample::Result const & result, QWidget & parent) { } -void ResultView::EnableEditing(Edits::RelevanceEditor && editor) +void ResultView::SetEditor(Edits::RelevanceEditor && editor) { m_editor = my::make_unique(std::move(editor)); diff --git a/search/search_quality/assessment_tool/result_view.hpp b/search/search_quality/assessment_tool/result_view.hpp index 47b7ebac29..0a42c47e16 100644 --- a/search/search_quality/assessment_tool/result_view.hpp +++ b/search/search_quality/assessment_tool/result_view.hpp @@ -24,7 +24,7 @@ public: ResultView(search::Result const & result, QWidget & parent); ResultView(search::Sample::Result const & result, QWidget & parent); - void EnableEditing(Edits::RelevanceEditor && editor); + void SetEditor(Edits::RelevanceEditor && editor); void Update(); diff --git a/search/search_quality/assessment_tool/results_view.cpp b/search/search_quality/assessment_tool/results_view.cpp index 2a2ca6f09c..246bba6dbb 100644 --- a/search/search_quality/assessment_tool/results_view.cpp +++ b/search/search_quality/assessment_tool/results_view.cpp @@ -21,12 +21,12 @@ ResultsView::ResultsView(QWidget & parent) : QListWidget(&parent) { setAlternati void ResultsView::Add(search::Result const & result) { - AddImpl(result); + AddImpl(result, false /* hidden */); } -void ResultsView::Add(search::Sample::Result const & result) +void ResultsView::Add(search::Sample::Result const & result, Edits::Entry const & entry) { - AddImpl(result); + AddImpl(result, entry.m_deleted /* hidden */); } ResultView & ResultsView::Get(size_t i) @@ -45,15 +45,26 @@ void ResultsView::Update(Edits::Update const & update) { switch (update.m_type) { - case Edits::Update::Type::SingleRelevance: + case Edits::Update::Type::Single: + { CHECK_LESS(update.m_index, m_results.size(), ()); m_results[update.m_index]->Update(); break; - case Edits::Update::Type::AllRelevances: + } + case Edits::Update::Type::All: + { for (auto * result : m_results) result->Update(); break; } + case Edits::Update::Type::Delete: + { + auto const index = update.m_index; + CHECK_LESS(index, Size(), ()); + item(static_cast(index))->setHidden(true); + break; + } + }; } void ResultsView::Clear() @@ -63,9 +74,10 @@ void ResultsView::Clear() } template -void ResultsView::AddImpl(Result const & result) +void ResultsView::AddImpl(Result const & result, bool hidden) { auto * item = new QListWidgetItem(this /* parent */); + item->setHidden(hidden); addItem(item); auto * view = new ResultView(result, *this /* parent */); diff --git a/search/search_quality/assessment_tool/results_view.hpp b/search/search_quality/assessment_tool/results_view.hpp index f053b7d5a7..f41938b78a 100644 --- a/search/search_quality/assessment_tool/results_view.hpp +++ b/search/search_quality/assessment_tool/results_view.hpp @@ -23,7 +23,7 @@ public: explicit ResultsView(QWidget & parent); void Add(search::Result const & result); - void Add(search::Sample::Result const & result); + void Add(search::Sample::Result const & result, Edits::Entry const & entry); ResultView & Get(size_t i); ResultView const & Get(size_t i) const; @@ -38,7 +38,7 @@ signals: private: template - void AddImpl(Result const & result); + void AddImpl(Result const & result, bool hidden); std::vector m_results; }; diff --git a/search/search_quality/assessment_tool/sample_view.cpp b/search/search_quality/assessment_tool/sample_view.cpp index 21dde29059..1a4de6f029 100644 --- a/search/search_quality/assessment_tool/sample_view.cpp +++ b/search/search_quality/assessment_tool/sample_view.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -125,6 +126,22 @@ SampleView::SampleView(QWidget * parent, Framework & framework) layout->addWidget(new QLabel(tr("Non found results"))); m_nonFoundResults = new ResultsView(*this /* parent */); + m_nonFoundResults->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_nonFoundResults, &ResultsView::customContextMenuRequested, [&](QPoint pos) { + pos = m_nonFoundResults->mapToGlobal(pos); + + auto const items = m_nonFoundResults->selectedItems(); + for (auto const * item : items) + { + int const row = m_nonFoundResults->row(item); + + QMenu menu; + auto const * action = menu.addAction("Remove result"); + connect(action, &QAction::triggered, [this, row]() { OnRemoveNonFoundResult(row); }); + + menu.exec(pos); + } + }); layout->addWidget(m_nonFoundResults); } @@ -165,41 +182,73 @@ void SampleView::ShowFoundResults(search::Results::ConstIter begin, search::Resu { for (auto it = begin; it != end; ++it) m_foundResults->Add(*it /* result */); - m_framework.FillSearchResultsMarks(begin, end); } -void SampleView::ShowNonFoundResults(std::vector const & results) +void SampleView::ShowNonFoundResults(std::vector const & results, + std::vector const & entries) { + CHECK_EQUAL(results.size(), entries.size(), ()); + auto & bookmarkManager = m_framework.GetBookmarkManager(); UserMarkControllerGuard guard(bookmarkManager, UserMarkType::SEARCH_MARK); guard.m_controller.SetIsVisible(true); guard.m_controller.SetIsDrawable(true); - for (auto const & result : results) + bool allDeleted = true; + for (size_t i = 0; i < results.size(); ++i) { - m_nonFoundResults->Add(result); + m_nonFoundResults->Add(results[i], entries[i]); + if (!entries[i].m_deleted) + allDeleted = false; + } + if (!allDeleted) + m_nonFoundResultsBox->show(); +} + +void SampleView::ShowFoundResultsMarks(search::Results::ConstIter begin, search::Results::ConstIter end) +{ + m_framework.FillSearchResultsMarks(begin, end); +} + +void SampleView::ShowNonFoundResultsMarks(std::vector const & results, + std::vector const & entries) + +{ + CHECK_EQUAL(results.size(), entries.size(), ()); + + auto & bookmarkManager = m_framework.GetBookmarkManager(); + UserMarkControllerGuard guard(bookmarkManager, UserMarkType::SEARCH_MARK); + guard.m_controller.SetIsVisible(true); + guard.m_controller.SetIsDrawable(true); + + for (size_t i = 0; i < results.size(); ++i) + { + auto const & result = results[i]; + auto const & entry = entries[i]; + if (entry.m_deleted) + continue; SearchMarkPoint * mark = static_cast(guard.m_controller.CreateUserMark(result.m_pos)); mark->SetCustomSymbol("non-found-search-result"); } - - if (!results.empty()) - m_nonFoundResultsBox->show(); } +void SampleView::ClearSearchResultMarks() { m_framework.ClearSearchResultsMarks(); } + void SampleView::ClearAllResults() { m_foundResults->Clear(); m_nonFoundResults->Clear(); m_nonFoundResultsBox->hide(); - m_framework.ClearSearchResultsMarks(); + ClearSearchResultMarks(); } -void SampleView::EnableEditing(Edits & resultsEdits, Edits & nonFoundResultsEdits) +void SampleView::SetEdits(Edits & resultsEdits, Edits & nonFoundResultsEdits) { - EnableEditing(*m_foundResults, resultsEdits); - EnableEditing(*m_nonFoundResults, nonFoundResultsEdits); + SetEdits(*m_foundResults, resultsEdits); + SetEdits(*m_nonFoundResults, nonFoundResultsEdits); + m_nonFoundResultsEdits = &nonFoundResultsEdits; } void SampleView::Clear() @@ -224,10 +273,12 @@ void SampleView::OnLocationChanged(Qt::DockWidgetArea area) layout()->setContentsMargins(m_defaultMargins); } -void SampleView::EnableEditing(ResultsView & results, Edits & edits) +void SampleView::SetEdits(ResultsView & results, Edits & edits) { size_t const numRelevances = edits.GetRelevances().size(); CHECK_EQUAL(results.Size(), numRelevances, ()); for (size_t i = 0; i < numRelevances; ++i) - results.Get(i).EnableEditing(Edits::RelevanceEditor(edits, i)); + results.Get(i).SetEditor(Edits::RelevanceEditor(edits, i)); } + +void SampleView::OnRemoveNonFoundResult(int row) { m_nonFoundResultsEdits->Delete(row); } diff --git a/search/search_quality/assessment_tool/sample_view.hpp b/search/search_quality/assessment_tool/sample_view.hpp index 820e0e862d..0b8a01f688 100644 --- a/search/search_quality/assessment_tool/sample_view.hpp +++ b/search/search_quality/assessment_tool/sample_view.hpp @@ -26,10 +26,17 @@ public: void SetContents(search::Sample const & sample, bool positionAvailable); void OnSearchStarted(); void OnSearchCompleted(); - void ShowFoundResults(search::Results::ConstIter begin, search::Results::ConstIter end); - void ShowNonFoundResults(std::vector const & results); - void EnableEditing(Edits & resultsEdits, Edits & nonFoundResultsEdits); + void ShowFoundResults(search::Results::ConstIter begin, search::Results::ConstIter end); + void ShowNonFoundResults(std::vector const & results, + std::vector const & entries); + + void ShowFoundResultsMarks(search::Results::ConstIter begin, search::Results::ConstIter end); + void ShowNonFoundResultsMarks(std::vector const & results, + std::vector const & entries); + void ClearSearchResultMarks(); + + void SetEdits(Edits & resultsEdits, Edits & nonFoundResultsEdits); void Clear(); @@ -44,7 +51,8 @@ signals: private: void ClearAllResults(); - void EnableEditing(ResultsView & results, Edits & edits); + void SetEdits(ResultsView & results, Edits & edits); + void OnRemoveNonFoundResult(int row); Framework & m_framework; @@ -58,12 +66,15 @@ private: QPushButton * m_showViewport = nullptr; QPushButton * m_showPosition = nullptr; + ResultsView * m_foundResults = nullptr; QWidget * m_foundResultsBox = nullptr; ResultsView * m_nonFoundResults = nullptr; QWidget * m_nonFoundResultsBox = nullptr; + Edits * m_nonFoundResultsEdits = nullptr; + QMargins m_rightAreaMargins; QMargins m_defaultMargins; }; diff --git a/search/search_quality/assessment_tool/view.hpp b/search/search_quality/assessment_tool/view.hpp index 9b876ca052..22c64b8296 100644 --- a/search/search_quality/assessment_tool/view.hpp +++ b/search/search_quality/assessment_tool/view.hpp @@ -32,9 +32,17 @@ public: virtual void OnSearchCompleted() = 0; virtual void ShowSample(size_t index, search::Sample const & sample, bool positionAvailable, bool hasEdits) = 0; + virtual void ShowFoundResults(search::Results::ConstIter begin, search::Results::ConstIter end) = 0; - virtual void ShowNonFoundResults(std::vector const & results) = 0; + virtual void ShowNonFoundResults(std::vector const & results, + std::vector const & entries) = 0; + + virtual void ShowFoundResultsMarks(search::Results::ConstIter begin, + search::Results::ConstIter end) = 0; + virtual void ShowNonFoundResultsMarks(std::vector const & results, + std::vector const & entries) = 0; + virtual void ClearSearchResultMarks() = 0; virtual void MoveViewportToResult(search::Result const & result) = 0; virtual void MoveViewportToResult(search::Sample::Result const & result) = 0; @@ -42,8 +50,7 @@ public: virtual void OnResultChanged(size_t sampleIndex, ResultType type, Edits::Update const & update) = 0; - virtual void EnableSampleEditing(size_t index, Edits & foundResultsEdits, - Edits & nonFoundResultsEdits) = 0; + virtual void SetEdits(size_t index, Edits & foundResultsEdits, Edits & nonFoundResultsEdits) = 0; virtual void OnSampleChanged(size_t sampleIndex, bool hasEdits) = 0; virtual void OnSamplesChanged(bool hasEdits) = 0; @@ -54,3 +61,13 @@ public: protected: Model * m_model = nullptr; }; + +inline std::string DebugPrint(View::ResultType type) +{ + switch (type) + { + case View::ResultType::Found: return "Found"; + case View::ResultType::NonFound: return "NonFound"; + } + return "Unknown"; +}