[search] Added buttons to mark all results as Relevant or Irrelevant.

This commit is contained in:
Maxim Pimenov 2018-03-13 18:01:06 +03:00 committed by Tatiana Yan
parent b0916a05c8
commit b32966a1f4
11 changed files with 138 additions and 29 deletions

View file

@ -2,6 +2,17 @@
#include "base/assert.hpp"
namespace
{
void UpdateNumEdits(Edits::Entry const & entry, Edits::MaybeRelevance const & r, size_t & numEdits)
{
if (entry.m_curr != entry.m_orig && r == entry.m_orig)
--numEdits;
if (entry.m_curr == entry.m_orig && r != entry.m_orig)
++numEdits;
}
} // namespace
// Edits::Editor -----------------------------------------------------------------------------------
Edits::Editor::Editor(Edits & parent, size_t index)
: m_parent(parent), m_index(index)
@ -63,16 +74,27 @@ bool Edits::SetRelevance(size_t index, Relevance relevance)
MaybeRelevance const r(relevance);
if (entry.m_curr != entry.m_orig && r == entry.m_orig)
--m_numEdits;
else if (entry.m_curr == entry.m_orig && r != entry.m_orig)
++m_numEdits;
UpdateNumEdits(entry, r, m_numEdits);
entry.m_curr = r;
return entry.m_curr != entry.m_orig;
});
}
void Edits::SetAllRelevances(Relevance relevance)
{
WithObserver(Update::MakeAll(), [this, relevance]() {
for (auto & entry : m_entries)
{
MaybeRelevance const r(relevance);
UpdateNumEdits(entry, r, m_numEdits);
entry.m_curr = r;
}
});
}
void Edits::Add(Relevance relevance)
{
auto const index = m_entries.size();

View file

@ -119,6 +119,9 @@ public:
// |relevance| differs from the original one.
bool SetRelevance(size_t index, Relevance relevance);
// Sets relevances of all entries to |relevance|.
void SetAllRelevances(Relevance relevance);
// Adds a new entry.
void Add(Relevance relevance);
@ -145,7 +148,7 @@ private:
template <typename Fn>
std::result_of_t<Fn()> WithObserver(Update const & update, Fn && fn)
{
MY_SCOPE_GUARD(cleanup, ([this, &update]() {
MY_SCOPE_GUARD(obsCall, ([this, &update]() {
if (m_onUpdate)
m_onUpdate(update);
}));

View file

@ -201,7 +201,7 @@ void MainModel::OnNonFoundResultSelected(int index)
void MainModel::OnShowViewportClicked()
{
CHECK(m_selectedSample != kInvalidIndex, ());
CHECK(m_selectedSample < m_contexts.Size(), ());
CHECK_LESS(m_selectedSample, m_contexts.Size(), ());
auto const & context = m_contexts[m_selectedSample];
m_view->MoveViewportToRect(context.m_sample.m_viewport);
@ -210,7 +210,7 @@ void MainModel::OnShowViewportClicked()
void MainModel::OnShowPositionClicked()
{
CHECK(m_selectedSample != kInvalidIndex, ());
CHECK(m_selectedSample < m_contexts.Size(), ());
CHECK_LESS(m_selectedSample, m_contexts.Size(), ());
static int constexpr kViewportAroundTopResultsSizeM = 100;
static double constexpr kViewportAroundTopResultsScale = 1.2;
@ -244,6 +244,16 @@ void MainModel::OnShowPositionClicked()
m_view->MoveViewportToRect(m2::Add(boundingBox, minRect));
}
void MainModel::OnMarkAllAsRelevantClicked()
{
OnChangeAllRelevancesClicked(Edits::Relevance::Relevant);
}
void MainModel::OnMarkAllAsIrrelevantClicked()
{
OnChangeAllRelevancesClicked(Edits::Relevance::Irrelevant);
}
bool MainModel::HasChanges() { return m_contexts.HasChanges(); }
bool MainModel::AlreadyInSamples(FeatureID const & id)
@ -383,6 +393,21 @@ void MainModel::ShowMarks(Context const & context)
context.m_nonFoundResultsEdits.GetEntries());
}
void MainModel::OnChangeAllRelevancesClicked(Edits::Relevance relevance)
{
CHECK_GREATER_OR_EQUAL(m_selectedSample, 0, ());
CHECK_LESS(m_selectedSample, m_contexts.Size(), ());
auto & context = m_contexts[m_selectedSample];
context.m_foundResultsEdits.SetAllRelevances(relevance);
context.m_nonFoundResultsEdits.SetAllRelevances(relevance);
m_view->OnResultChanged(m_selectedSample, View::ResultType::Found, Edits::Update::MakeAll());
m_view->OnResultChanged(m_selectedSample, View::ResultType::NonFound, Edits::Update::MakeAll());
m_view->OnSampleChanged(m_selectedSample, context.HasChanges());
m_view->OnSamplesChanged(m_contexts.HasChanges());
}
template <typename Fn>
void MainModel::ForAnyMatchingEntry(Context & context, FeatureID const & id, Fn && fn)
{

View file

@ -37,6 +37,8 @@ public:
void OnNonFoundResultSelected(int index) override;
void OnShowViewportClicked() override;
void OnShowPositionClicked() override;
void OnMarkAllAsRelevantClicked() override;
void OnMarkAllAsIrrelevantClicked() override;
bool HasChanges() override;
bool AlreadyInSamples(FeatureID const & id) override;
void AddNonFoundResult(FeatureID const & id) override;
@ -54,6 +56,8 @@ private:
void ResetSearch();
void ShowMarks(Context const & context);
void OnChangeAllRelevancesClicked(Edits::Relevance relevance);
template <typename Fn>
void ForAnyMatchingEntry(Context & context, FeatureID const & id, Fn && fn);

View file

@ -341,6 +341,11 @@ void MainView::InitDocks()
connect(m_sampleView, &SampleView::OnShowPositionClicked,
[this]() { m_model->OnShowPositionClicked(); });
connect(m_sampleView, &SampleView::OnMarkAllAsRelevantClicked,
[this]() { m_model->OnMarkAllAsRelevantClicked(); });
connect(m_sampleView, &SampleView::OnMarkAllAsIrrelevantClicked,
[this]() { m_model->OnMarkAllAsIrrelevantClicked(); });
{
auto const & view = m_sampleView->GetFoundResultsView();
connect(&view, &ResultsView::OnResultSelected,

View file

@ -21,6 +21,8 @@ public:
virtual void OnNonFoundResultSelected(int index) = 0;
virtual void OnShowViewportClicked() = 0;
virtual void OnShowPositionClicked() = 0;
virtual void OnMarkAllAsRelevantClicked() = 0;
virtual void OnMarkAllAsIrrelevantClicked() = 0;
virtual bool HasChanges() = 0;
virtual bool AlreadyInSamples(FeatureID const & id) = 0;

View file

@ -67,39 +67,33 @@ void ResultView::SetEditor(Edits::Editor && editor)
{
m_editor = my::make_unique<Edits::Editor>(std::move(editor));
m_irrelevant->setChecked(false);
m_relevant->setChecked(false);
m_vital->setChecked(false);
auto const & r = m_editor->Get();
if (!r.m_unknown)
{
switch (r.m_relevance)
{
case Relevance::Irrelevant: m_irrelevant->setChecked(true); break;
case Relevance::Relevant: m_relevant->setChecked(true); break;
case Relevance::Vital: m_vital->setChecked(true); break;
}
}
UpdateRelevanceRadioButtons();
setEnabled(true);
}
void ResultView::Update()
{
if (m_editor)
if (!m_editor)
{
if (m_editor->GetType() == Edits::Entry::Type::Created)
setStyleSheet("#result {background: rgba(173, 223, 173, 50%)}");
else if (m_editor->HasChanges())
setStyleSheet("#result {background: rgba(255, 255, 200, 50%)}");
else
setStyleSheet("");
setStyleSheet("");
return;
}
if (m_editor->GetType() == Edits::Entry::Type::Created)
{
setStyleSheet("#result {background: rgba(173, 223, 173, 50%)}");
}
else if (m_editor->HasChanges())
{
setStyleSheet("#result {background: rgba(255, 255, 200, 50%)}");
}
else
{
setStyleSheet("");
}
UpdateRelevanceRadioButtons();
}
void ResultView::Init()
@ -167,3 +161,24 @@ void ResultView::OnRelevanceChanged()
m_editor->Set(relevance);
}
void ResultView::UpdateRelevanceRadioButtons()
{
if (!m_editor)
return;
m_irrelevant->setChecked(false);
m_relevant->setChecked(false);
m_vital->setChecked(false);
auto const & r = m_editor->Get();
if (!r.m_unknown)
{
switch (r.m_relevance)
{
case Relevance::Irrelevant: m_irrelevant->setChecked(true); break;
case Relevance::Relevant: m_relevant->setChecked(true); break;
case Relevance::Vital: m_vital->setChecked(true); break;
}
}
}

View file

@ -38,6 +38,7 @@ private:
QRadioButton * CreateRatioButton(string const & label, QLayout & layout);
void OnRelevanceChanged();
void UpdateRelevanceRadioButtons();
QLabel * m_name = nullptr;
QLabel * m_type = nullptr;

View file

@ -7,13 +7,17 @@
#include <QtWidgets/QListWidgetItem>
ResultsView::ResultsView(QWidget & parent) : QListWidget(&parent) { setAlternatingRowColors(true);
ResultsView::ResultsView(QWidget & parent) : QListWidget(&parent)
{
setAlternatingRowColors(true);
connect(selectionModel(), &QItemSelectionModel::selectionChanged,
[&](QItemSelection const & current) {
auto const indexes = current.indexes();
for (auto const & index : indexes)
emit OnResultSelected(index.row());
});
connect(this, &ResultsView::itemClicked, [&](QListWidgetItem * item) {
auto const index = indexFromItem(item);
emit OnResultSelected(index.row());

View file

@ -104,6 +104,20 @@ SampleView::SampleView(QWidget * parent, Framework & framework)
layout->addWidget(m_relatedQueries);
}
{
auto * layout = BuildSubLayout<QHBoxLayout>(*mainLayout, *this /* parent */);
m_markAllAsRelevant = new QPushButton(tr("Mark all as Relevant"), this /* parent */);
connect(m_markAllAsRelevant, &QPushButton::clicked,
[this]() { emit OnMarkAllAsRelevantClicked(); });
layout->addWidget(m_markAllAsRelevant);
m_markAllAsIrrelevant = new QPushButton(tr("Mark all as Irrelevant"), this /* parent */);
connect(m_markAllAsIrrelevant, &QPushButton::clicked,
[this]() { emit OnMarkAllAsIrrelevantClicked(); });
layout->addWidget(m_markAllAsIrrelevant);
}
{
auto * layout =
BuildSubLayout<QVBoxLayout>(*mainLayout, *this /* parent */, &m_foundResultsBox);
@ -186,6 +200,9 @@ void SampleView::OnSearchStarted()
{
m_spinner->Show();
m_showPosition->setEnabled(false);
m_markAllAsRelevant->setEnabled(false);
m_markAllAsIrrelevant->setEnabled(false);
}
void SampleView::OnSearchCompleted()
@ -209,6 +226,9 @@ void SampleView::OnSearchCompleted()
{
m_showPosition->setEnabled(false);
}
m_markAllAsRelevant->setEnabled(resultsAvailable);
m_markAllAsIrrelevant->setEnabled(resultsAvailable);
}
void SampleView::AddFoundResults(search::Results::ConstIter begin, search::Results::ConstIter end)
@ -291,6 +311,9 @@ void SampleView::Clear()
m_showViewport->setEnabled(false);
m_showPosition->setEnabled(false);
m_markAllAsRelevant->setEnabled(false);
m_markAllAsIrrelevant->setEnabled(false);
m_relatedQueriesBox->hide();
ClearAllResults();

View file

@ -51,6 +51,8 @@ public:
signals:
void OnShowViewportClicked();
void OnShowPositionClicked();
void OnMarkAllAsRelevantClicked();
void OnMarkAllAsIrrelevantClicked();
private:
void ClearAllResults();
@ -73,6 +75,9 @@ private:
QPushButton * m_showViewport = nullptr;
QPushButton * m_showPosition = nullptr;
QPushButton * m_markAllAsRelevant = nullptr;
QPushButton * m_markAllAsIrrelevant = nullptr;
ResultsView * m_foundResults = nullptr;
QWidget * m_foundResultsBox = nullptr;