]> git.sesse.net Git - pkanalytics/blobdiff - mainwindow.cpp
Add support for stallouts.
[pkanalytics] / mainwindow.cpp
index 7eec2cb4d2b8767aa89542edef5941c9827dbea1..b8322cbb856c20f0c5902251d45e8135afd242e2 100644 (file)
@@ -3,6 +3,7 @@
 #include <QApplication>
 #include <QGridLayout>
 #include <QShortcut>
+#include <QFileDialog>
 #include <QInputDialog>
 #include <QTimer>
 #include <algorithm>
@@ -35,14 +36,86 @@ string format_timestamp(uint64_t pos)
        return buf;
 }
 
+string get_video_filename(sqlite3 *db, int match_id)
+{
+       sqlite3_stmt *stmt;
+
+       int ret = sqlite3_prepare_v2(db, "SELECT video_filename FROM match WHERE match=?", -1, &stmt, 0);
+       if (ret != SQLITE_OK) {
+               fprintf(stderr, "SELECT prepare: %s\n", sqlite3_errmsg(db));
+               abort();
+       }
+
+       sqlite3_bind_int64(stmt, 1, match_id);
+
+       ret = sqlite3_step(stmt);
+       if (ret != SQLITE_ROW) {
+               fprintf(stderr, "SELECT step: %s\n", sqlite3_errmsg(db));
+               abort();
+       }
+
+       if (sqlite3_column_type(stmt, 0) != SQLITE_TEXT) {
+               return "";
+       }
+       string filename = (const char *)sqlite3_column_text(stmt, 0);
+
+       ret = sqlite3_finalize(stmt);
+       if (ret != SQLITE_OK) {
+               fprintf(stderr, "SELECT finalize: %s\n", sqlite3_errmsg(db));
+               abort();
+       }
+       return filename;
+}
+
+void save_video_filename(sqlite3 *db, int match_id, const string &filename)
+{
+       sqlite3_stmt *stmt;
+
+       int ret = sqlite3_prepare_v2(db, "UPDATE match SET video_filename=? WHERE match=?", -1, &stmt, 0);
+       if (ret != SQLITE_OK) {
+               fprintf(stderr, "SELECT prepare: %s\n", sqlite3_errmsg(db));
+               abort();
+       }
+
+       sqlite3_bind_text(stmt, 1, filename.data(), filename.size(), SQLITE_STATIC);
+       sqlite3_bind_int64(stmt, 2, match_id);
+
+       ret = sqlite3_step(stmt);
+       if (ret == SQLITE_ROW) {
+               fprintf(stderr, "INSERT step: %s\n", sqlite3_errmsg(db));
+               abort();
+       }
+
+       ret = sqlite3_finalize(stmt);
+       if (ret != SQLITE_OK) {
+               fprintf(stderr, "SELECT finalize: %s\n", sqlite3_errmsg(db));
+               abort();
+       }
+}
+
 MainWindow::MainWindow(EventsModel *events, PlayersModel *players,
-                       FormationsModel *offensive_formations, FormationsModel *defensive_formations)
-       : events(events), players(players), offensive_formations(offensive_formations), defensive_formations(defensive_formations)
+                       FormationsModel *offensive_formations, FormationsModel *defensive_formations,
+                       sqlite3 *db, int match_id)
+       : events(events), players(players), offensive_formations(offensive_formations), defensive_formations(defensive_formations), db(db), match_id(match_id)
 {
        ui = new Ui::MainWindow;
        ui->setupUi(this);
 
-       ui->video->open("/home/sesse/dev/stats/ultimate-prores.mkv");
+       string filename = get_video_filename(db, match_id);
+       bool need_save_filename = false;
+       for ( ;; ) {
+               if (!filename.empty() && ui->video->open(filename.c_str())) {
+                       break;
+               }
+
+               // TODO: Probably relativize this path, so that we can move the .db
+               // more easily with the videos.
+               filename = QFileDialog::getOpenFileName(this, "Open video").toUtf8();
+               need_save_filename = true;
+       }
+       if (need_save_filename) {
+               save_video_filename(db, match_id, filename);
+       }
        ui->video->play();
 
        ui->event_view->setModel(events);
@@ -139,8 +212,23 @@ MainWindow::MainWindow(EventsModel *events, PlayersModel *players,
        });
        connect(ui->drop, &QPushButton::clicked, [this]() { set_current_event_type("drop"); });
        connect(ui->goal, &QPushButton::clicked, [this]() { set_current_event_type("goal"); });
-       connect(ui->offensive_soft_plus, &QPushButton::clicked, [this]() { set_current_event_type("offensive_soft_plus"); });
-       connect(ui->offensive_soft_minus, &QPushButton::clicked, [this]() { set_current_event_type("offensive_soft_minus"); });
+       connect(ui->stallout, &QPushButton::clicked, [this]() { set_current_event_type("stallout"); });
+       connect(ui->soft_plus, &QPushButton::clicked, [this, events]() {
+               EventsModel::Status s = events->get_status_at(ui->video->get_position());
+               if (s.attack_state == EventsModel::Status::OFFENSE) {
+                       set_current_event_type("offensive_soft_plus");
+               } else if (s.attack_state == EventsModel::Status::DEFENSE) {
+                       set_current_event_type("defensive_soft_plus");
+               }
+       });
+       connect(ui->soft_minus, &QPushButton::clicked, [this, events]() {
+               EventsModel::Status s = events->get_status_at(ui->video->get_position());
+               if (s.attack_state == EventsModel::Status::OFFENSE) {
+                       set_current_event_type("offensive_soft_minus");
+               } else if (s.attack_state == EventsModel::Status::DEFENSE) {
+                       set_current_event_type("defensive_soft_minus");
+               }
+       });
        connect(ui->pull_or_was_d, &QPushButton::clicked, [this, events]() {
                EventsModel::Status s = events->get_status_at(ui->video->get_position());
                if (s.pull_state == EventsModel::Status::SHOULD_PULL) {
@@ -164,8 +252,6 @@ MainWindow::MainWindow(EventsModel *events, PlayersModel *players,
                }
        });
        connect(ui->our_defense, &QPushButton::clicked, [this]() { set_current_event_type("defense"); });
-       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); });
@@ -412,15 +498,14 @@ void MainWindow::update_action_buttons(uint64_t t)
                ui->throwaway->setEnabled(false);
                ui->drop->setEnabled(false);
                ui->goal->setEnabled(false);
-               ui->offensive_soft_plus->setEnabled(false);
-               ui->offensive_soft_minus->setEnabled(false);
+               ui->stallout->setEnabled(false);
+               ui->soft_plus->setEnabled(false);
+               ui->soft_minus->setEnabled(false);
                ui->pull_or_was_d->setEnabled(false);
                ui->interception->setEnabled(false);
                ui->their_throwaway->setEnabled(false);
                ui->our_defense->setEnabled(false);
                ui->their_goal->setEnabled(false);
-               ui->defensive_soft_plus->setEnabled(false);
-               ui->defensive_soft_minus->setEnabled(false);
                ui->their_pull->setEnabled(false);
                return;
        } else {
@@ -444,14 +529,13 @@ void MainWindow::update_action_buttons(uint64_t t)
                ui->throwaway->setEnabled(false);
                ui->drop->setEnabled(false);
                ui->goal->setEnabled(false);
-               ui->offensive_soft_plus->setEnabled(false);
-               ui->offensive_soft_minus->setEnabled(false);
+               ui->stallout->setEnabled(false);
+               ui->soft_plus->setEnabled(false);
+               ui->soft_minus->setEnabled(false);
                ui->interception->setEnabled(false);
                ui->their_throwaway->setEnabled(false);
                ui->our_defense->setEnabled(false);
                ui->their_goal->setEnabled(false);
-               ui->defensive_soft_plus->setEnabled(false);
-               ui->defensive_soft_minus->setEnabled(false);
                return;
        }
        if (s.pull_state == EventsModel::Status::PULL_IN_AIR) {
@@ -472,14 +556,13 @@ void MainWindow::update_action_buttons(uint64_t t)
                ui->catch_->setEnabled(false);
                ui->drop->setEnabled(false);
                ui->goal->setEnabled(false);
-               ui->offensive_soft_plus->setEnabled(false);
-               ui->offensive_soft_minus->setEnabled(false);
+               ui->stallout->setEnabled(false);
+               ui->soft_plus->setEnabled(false);
+               ui->soft_minus->setEnabled(false);
                ui->interception->setEnabled(false);
                ui->their_throwaway->setEnabled(false);
                ui->our_defense->setEnabled(false);
                ui->their_goal->setEnabled(false);
-               ui->defensive_soft_plus->setEnabled(false);
-               ui->defensive_soft_minus->setEnabled(false);
                return;
        }
 
@@ -492,16 +575,15 @@ void MainWindow::update_action_buttons(uint64_t t)
        ui->throwaway->setEnabled(s.attack_state == EventsModel::Status::OFFENSE && has_selection_with_player);
        ui->drop->setEnabled(s.attack_state == EventsModel::Status::OFFENSE && has_selection_with_player);
        ui->goal->setEnabled(s.attack_state == EventsModel::Status::OFFENSE && has_selection_with_player);
-       ui->offensive_soft_plus->setEnabled(s.attack_state == EventsModel::Status::OFFENSE && has_selection_with_player);
-       ui->offensive_soft_minus->setEnabled(s.attack_state == EventsModel::Status::OFFENSE && has_selection_with_player);
+       ui->stallout->setEnabled(s.attack_state == EventsModel::Status::OFFENSE && has_selection_with_player);
+       ui->soft_plus->setEnabled(s.attack_state != EventsModel::Status::NOT_STARTED && has_selection_with_player);
+       ui->soft_minus->setEnabled(s.attack_state != EventsModel::Status::NOT_STARTED && has_selection_with_player);
        ui->pull_or_was_d->setEnabled(s.attack_state == EventsModel::Status::OFFENSE && has_selection_with_player);  // Was d-ed.
 
        ui->interception->setEnabled(s.attack_state == EventsModel::Status::DEFENSE && has_selection_with_player);
        ui->their_throwaway->setEnabled(s.attack_state == EventsModel::Status::DEFENSE);
        ui->our_defense->setEnabled(s.attack_state == EventsModel::Status::DEFENSE && has_selection_with_player);
        ui->their_goal->setEnabled(s.attack_state == EventsModel::Status::DEFENSE);
-       ui->defensive_soft_plus->setEnabled(s.attack_state == EventsModel::Status::DEFENSE && has_selection_with_player);
-       ui->defensive_soft_minus->setEnabled(s.attack_state == EventsModel::Status::DEFENSE && has_selection_with_player);
        ui->their_pull->setEnabled(false);
 }