diff --git a/search/search_quality/assessment_tool/main_model.cpp b/search/search_quality/assessment_tool/main_model.cpp index 8cb97f2c63..ffb2e55fb1 100644 --- a/search/search_quality/assessment_tool/main_model.cpp +++ b/search/search_quality/assessment_tool/main_model.cpp @@ -60,6 +60,8 @@ void MainModel::Open(string const & path) ResetSearch(); + m_view->Clear(); + m_contexts.Resize(samples.size()); for (size_t i = 0; i < samples.size(); ++i) { diff --git a/search/search_quality/assessment_tool/main_view.cpp b/search/search_quality/assessment_tool/main_view.cpp index eafa614079..df47e47459 100644 --- a/search/search_quality/assessment_tool/main_view.cpp +++ b/search/search_quality/assessment_tool/main_view.cpp @@ -14,6 +14,7 @@ #include "base/string_utils.hpp" #include +#include #include #include #include @@ -76,19 +77,13 @@ void MainView::OnSampleChanged(size_t index, Edits::Update const & update, bool m_samplesView->OnUpdate(index); if (!m_samplesView->IsSelected(index)) return; - if (hasEdits) - m_sampleDock->setWindowTitle(tr("Sample *")); - else - m_sampleDock->setWindowTitle(tr("Sample")); + SetSampleDockTitle(hasEdits); m_sampleView->Update(update); } void MainView::OnSamplesChanged(bool hasEdits) { - if (hasEdits) - m_samplesDock->setWindowTitle("Samples *"); - else - m_samplesDock->setWindowTitle("Samples"); + SetSamplesDockTitle(hasEdits); m_save->setEnabled(hasEdits); m_saveAs->setEnabled(hasEdits); } @@ -107,6 +102,23 @@ void MainView::ShowError(std::string const & msg) box.exec(); } +void MainView::Clear() +{ + m_samplesView->Clear(); + SetSamplesDockTitle(false /* hasEdits */); + + m_sampleView->Clear(); + SetSampleDockTitle(false /* hasEdits */); +} + +void MainView::closeEvent(QCloseEvent * event) +{ + if (TryToSaveEdits(tr("Save changes before closing?")) == SaveResult::Cancelled) + event->ignore(); + else + event->accept(); +} + void MainView::OnSampleSelected(QItemSelection const & current) { CHECK(m_model, ()); @@ -200,18 +212,23 @@ void MainView::InitDocks() SLOT(OnSampleSelected(QItemSelection const &))); } - m_samplesDock = CreateDock("Samples", *m_samplesView); + m_samplesDock = CreateDock(*m_samplesView); addDockWidget(Qt::RightDockWidgetArea, m_samplesDock); + SetSamplesDockTitle(false /* hasEdits */); m_sampleView = new SampleView(this /* parent */); - m_sampleDock = CreateDock("Sample", *m_sampleView); + m_sampleDock = CreateDock(*m_sampleView); addDockWidget(Qt::RightDockWidgetArea, m_sampleDock); + SetSampleDockTitle(false /* hasEdits */); } void MainView::Open() { CHECK(m_model, ()); + if (TryToSaveEdits(tr("Save changes before opening samples?")) == SaveResult::Cancelled) + return; + auto const name = QFileDialog::getOpenFileName(this /* parent */, tr("Open samples..."), QString() /* dir */, tr(kJSON)); auto const file = name.toStdString(); @@ -232,9 +249,49 @@ void MainView::SaveAs() m_model->SaveAs(file); } -QDockWidget * MainView::CreateDock(std::string const & title, QWidget & widget) +void MainView::SetSamplesDockTitle(bool hasEdits) { - auto * dock = new QDockWidget(ToQString(title), this /* parent */, Qt::Widget); + CHECK(m_samplesDock, ()); + if (hasEdits) + m_samplesDock->setWindowTitle(tr("Samples *")); + else + m_samplesDock->setWindowTitle(tr("Samples")); +} + +void MainView::SetSampleDockTitle(bool hasEdits) +{ + CHECK(m_sampleDock, ()); + if (hasEdits) + m_sampleDock->setWindowTitle(tr("Sample *")); + else + m_sampleDock->setWindowTitle(tr("Sample")); +} + +MainView::SaveResult MainView::TryToSaveEdits(QString const & msg) +{ + CHECK(m_model, ()); + + if (!m_model->HasChanges()) + return SaveResult::NoEdits; + + QMessageBox box(QMessageBox::Question /* icon */, tr("Save edits?") /* title */, msg /* text */, + QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel /* buttons */, + this /* parent */); + auto const button = box.exec(); + switch (button) + { + case QMessageBox::Save: Save(); return SaveResult::Saved; + case QMessageBox::Discard: return SaveResult::Discarded; + case QMessageBox::Cancel: return SaveResult::Cancelled; + } + + CHECK(false, ()); + return SaveResult::Cancelled; +} + +QDockWidget * MainView::CreateDock(QWidget & widget) +{ + auto * dock = new QDockWidget(QString(), this /* parent */, Qt::Widget); dock->setFeatures(QDockWidget::AllDockWidgetFeatures); dock->setWidget(&widget); return dock; diff --git a/search/search_quality/assessment_tool/main_view.hpp b/search/search_quality/assessment_tool/main_view.hpp index f98c2baf7e..be8964db5f 100644 --- a/search/search_quality/assessment_tool/main_view.hpp +++ b/search/search_quality/assessment_tool/main_view.hpp @@ -37,10 +37,24 @@ public: void ShowError(std::string const & msg) override; + void Clear() override; + +protected: + // QMainWindow overrides: + void closeEvent(QCloseEvent * event) override; + private Q_SLOTS: void OnSampleSelected(QItemSelection const & current); private: + enum class SaveResult + { + NoEdits, + Saved, + Discarded, + Cancelled + }; + void InitMapWidget(); void InitDocks(); void InitMenuBar(); @@ -49,7 +63,11 @@ private: void Save(); void SaveAs(); - QDockWidget * CreateDock(std::string const & title, QWidget & widget); + void SetSamplesDockTitle(bool hasEdits); + void SetSampleDockTitle(bool hasEdits); + SaveResult TryToSaveEdits(QString const & msg); + + QDockWidget * CreateDock(QWidget & widget); Framework & m_framework; diff --git a/search/search_quality/assessment_tool/samples_view.hpp b/search/search_quality/assessment_tool/samples_view.hpp index 502c2fb2db..f656234619 100644 --- a/search/search_quality/assessment_tool/samples_view.hpp +++ b/search/search_quality/assessment_tool/samples_view.hpp @@ -18,6 +18,7 @@ public: void SetSamples(ContextList::SamplesSlice const & samples) { m_model->SetSamples(samples); } bool IsSelected(size_t index) const; void OnUpdate(size_t index) { m_model->OnUpdate(index); } + void Clear() { m_model->SetSamples(ContextList::SamplesSlice{}); } private: class Model : public QStandardItemModel diff --git a/search/search_quality/assessment_tool/view.hpp b/search/search_quality/assessment_tool/view.hpp index a8797c3a59..6d2411fa41 100644 --- a/search/search_quality/assessment_tool/view.hpp +++ b/search/search_quality/assessment_tool/view.hpp @@ -28,6 +28,8 @@ public: virtual void ShowError(std::string const & msg) = 0; + virtual void Clear() = 0; + protected: Model * m_model = nullptr; };