From: Steinar H. Gunderson Date: Tue, 30 May 2023 21:10:06 +0000 (+0200) Subject: Make the formation buttons actually do something. X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=1f701edba5013eedf60558b568b3c72ab81a2c08;p=pkanalytics Make the formation buttons actually do something. --- diff --git a/events.cpp b/events.cpp index cbdb303..0a50f3b 100644 --- a/events.cpp +++ b/events.cpp @@ -295,6 +295,34 @@ void EventsModel::set_event_type(unsigned pos, const string &type) } } +void EventsModel::set_event_formation(unsigned pos, int formation_id) +{ + events[pos].formation_id = formation_id; + emit dataChanged(createIndex(pos, 0), createIndex(pos, 2)); + + sqlite3_stmt *stmt; + int ret = sqlite3_prepare_v2(db, "UPDATE event SET formation=? WHERE event=?", -1, &stmt, 0); + if (ret != SQLITE_OK) { + fprintf(stderr, "INSERT prepare: %s\n", sqlite3_errmsg(db)); + abort(); + } + + sqlite3_bind_int64(stmt, 1, formation_id); + sqlite3_bind_int64(stmt, 2, events[pos].event_id); + + ret = sqlite3_step(stmt); + if (ret == SQLITE_ROW) { + fprintf(stderr, "UPDATE step: %s\n", sqlite3_errmsg(db)); + abort(); + } + + ret = sqlite3_finalize(stmt); + if (ret != SQLITE_OK) { + fprintf(stderr, "UPDATE finalize: %s\n", sqlite3_errmsg(db)); + abort(); + } +} + unsigned EventsModel::get_last_event_pos(uint64_t t) const { // upper_bound() gives first where e.t > t, diff --git a/events.h b/events.h index 8922496..df5fcb6 100644 --- a/events.h +++ b/events.h @@ -27,7 +27,9 @@ public: unsigned insert_event(uint64_t t, std::optional player_id, std::optional formation_id, const std::string &type = "unknown"); // Returns the row. void delete_event(unsigned row); + std::string get_event_type(unsigned row) { return events[row].type; } void set_event_type(unsigned row, const std::string &type); + void set_event_formation(unsigned row, int formation_id); uint64_t get_time(unsigned row) { return events[row].t; } unsigned get_last_event_pos(uint64_t t) const; // Last event that happened at or before t. QModelIndex get_last_event_qt(uint64_t t) const { diff --git a/main.cpp b/main.cpp index 01b1583..2edd111 100644 --- a/main.cpp +++ b/main.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -68,7 +69,9 @@ MainWindow::MainWindow(EventsModel *events, PlayersModel *players, ui->player_view->horizontalHeader()->setStretchLastSection(true); auto formation_changed = [this](const QModelIndex ¤t, const QModelIndex &previous) { - update_action_buttons(video->position()); + QTimer::singleShot(1, [=]{ // The selection is wrong until the callback actually returns. + update_action_buttons(video->position()); + }); }; ui->offensive_formation_view->setModel(offensive_formations); ui->defensive_formation_view->setModel(defensive_formations); @@ -177,6 +180,9 @@ MainWindow::MainWindow(EventsModel *events, PlayersModel *players, connect(ui->defensive_soft_plus, &QPushButton::clicked, [this]() { set_current_event_type("defensive_soft_plus"); }); connect(ui->defensive_soft_minus, &QPushButton::clicked, [this]() { set_current_event_type("defensive_soft_minus"); }); + connect(ui->offensive_formation, &QPushButton::clicked, [this]() { insert_or_change_formation(/*offense=*/true); }); + connect(ui->defensive_formation, &QPushButton::clicked, [this]() { insert_or_change_formation(/*offense=*/false); }); + // Misc. events connect(ui->substitution, &QPushButton::clicked, [this]() { make_substitution(); }); connect(ui->stoppage, &QPushButton::clicked, [this, events]() { @@ -267,6 +273,39 @@ void MainWindow::set_current_event_type(const string &type) update_ui_from_time(video->position()); } +// Formation buttons either modify the existing formation (if we've selected +// a formation change event), or insert a new one (if not). +void MainWindow::insert_or_change_formation(bool offense) +{ + FormationsModel *formations = offense ? offensive_formations : defensive_formations; + QListView *formation_view = offense ? ui->offensive_formation_view : ui->defensive_formation_view; + if (!formation_view->selectionModel()->hasSelection()) { + // This shouldn't happen; the button should not have been enabled. + return; + } + int formation_row = formation_view->selectionModel()->selectedRows().front().row(); // Should only be one, due to our selection behavior. + int formation_id = formations->get_formation_id(formation_row); + if (formation_id == -1) { + // This also shouldn't happen (“Add new…” selected). + return; + } + + QItemSelectionModel *select = ui->event_view->selectionModel(); + if (select->hasSelection()) { + int row = select->selectedRows().front().row(); // Should only be one, due to our selection behavior. + string expected_type = offense ? "formation_offense" : "formation_defense"; + if (events->get_event_type(row) == expected_type) { + events->set_event_formation(row, formation_id); + update_ui_from_time(video->position()); + return; + } + } + + // Insert a new formation event instead (same as double-click on the selected one). + events->set_formation_at(video->position(), offense, formation_id); + update_ui_from_time(video->position()); +} + void MainWindow::delete_current_event() { QItemSelectionModel *select = ui->event_view->selectionModel(); @@ -506,6 +545,7 @@ void MainWindow::formation_double_clicked(bool offense, unsigned row) } else { events->set_formation_at(video->position(), offense, id); } + update_ui_from_time(video->position()); } sqlite3 *open_db(const char *filename) diff --git a/mainwindow.h b/mainwindow.h index 83ed909..9408436 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -23,6 +23,7 @@ private: void insert_player_event(int button_id); void insert_noplayer_event(const std::string &type); void set_current_event_type(const std::string &type); + void insert_or_change_formation(bool offense); void delete_current_event(); void make_substitution(); void formation_double_clicked(bool offense, unsigned row); diff --git a/mainwindow.ui b/mainwindow.ui index 0c92265..771fe11 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -275,7 +275,7 @@ true - Formation (&o) + Formation (&p) O