]> git.sesse.net Git - pkanalytics/commitdiff
Make the formation buttons actually do something.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Tue, 30 May 2023 21:10:06 +0000 (23:10 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Tue, 30 May 2023 21:10:06 +0000 (23:10 +0200)
events.cpp
events.h
main.cpp
mainwindow.h
mainwindow.ui

index cbdb30344e21e2c221b0ae7a7ca7cbba8e76dc08..0a50f3b26de7b5d7c6ce7985ba2de3aa076da3a9 100644 (file)
@@ -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,
index 8922496dc854284fcf4298aec6fabdd3f1d6950d..df5fcb6a9b8c8b08871f2d76ef7804a5501652f7 100644 (file)
--- a/events.h
+++ b/events.h
@@ -27,7 +27,9 @@ public:
 
        unsigned insert_event(uint64_t t, std::optional<int> player_id, std::optional<int> 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 {
index 01b158373c1bc9cf620744055134dbe8a5a3ddf9..2edd111c346de1dd356a5cee6f5b149a6ab66c58 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -5,6 +5,7 @@
 #include <QVideoWidget>
 #include <QShortcut>
 #include <QInputDialog>
+#include <QTimer>
 #include <algorithm>
 #include <string>
 #include <map>
@@ -68,7 +69,9 @@ MainWindow::MainWindow(EventsModel *events, PlayersModel *players,
        ui->player_view->horizontalHeader()->setStretchLastSection(true);
 
        auto formation_changed = [this](const QModelIndex &current, 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)
index 83ed90957118262b443acb0eabbfb318926acb3b..9408436ae6e1e1e8a62f7f98fd62144a715d1202 100644 (file)
@@ -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);
index 0c9226571fa3542b4a7297d0f596ed77ec2b1978..771fe116778d54f6e1f5219e9e6e2609ad054017 100644 (file)
              <bool>true</bool>
             </property>
             <property name="text">
-             <string>Formation (&amp;o)</string>
+             <string>Formation (&amp;p)</string>
             </property>
             <property name="shortcut">
              <string>O</string>