X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=mainwindow.cpp;h=0ff813b7ac7465c48192de94d08120d0daebd7a6;hb=ec69f2a6b3a2da85c0345ef983afe2a04fb94efc;hp=5a1b7456cd90e6d701a6e9479d88504fe8353b6c;hpb=9e95c15a6754fa571199c36d73ac2dc1d45e5c64;p=pkanalytics diff --git a/mainwindow.cpp b/mainwindow.cpp index 5a1b745..0ff813b 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -35,16 +36,85 @@ 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); - if (!ui->video->open("/home/sesse/dev/stats/ultimate-prores.mkv")) { - // TODO: Pop up a dialog box here instead - fprintf(stderr, "WARNING: Video opening failed\n"); + 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(); @@ -142,11 +212,27 @@ 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) { + if (s.pull_state == EventsModel::Status::SHOULD_PULL || + events->get_status_at(ui->video->get_position() - 1).pull_state == EventsModel::Status::SHOULD_PULL) { set_current_event_type("pull"); } else if (s.pull_state == EventsModel::Status::PULL_IN_AIR) { insert_noplayer_event("pull_landed"); @@ -167,8 +253,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); }); @@ -268,7 +352,7 @@ void MainWindow::insert_or_change_formation(bool offense) 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"; + EventType expected_type = offense ? EventType::FORMATION_OFFENSE : EventType::FORMATION_DEFENSE; if (events->get_event_type(row) == expected_type) { events->set_event_formation(row, formation_id); update_ui_from_time(ui->video->get_position()); @@ -415,15 +499,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 { @@ -439,7 +522,8 @@ void MainWindow::update_action_buttons(uint64_t t) ui->throwaway->setText("Throwaway (&t)"); ui->throwaway->setShortcut(QCoreApplication::translate("MainWindow", "T", nullptr)); - if (s.pull_state == EventsModel::Status::SHOULD_PULL) { + if (s.pull_state == EventsModel::Status::SHOULD_PULL || + (has_selection_with_player && events->get_status_at(ui->video->get_position() - 1).pull_state == EventsModel::Status::SHOULD_PULL)) { // Can change this event to pull. ui->pull_or_was_d->setEnabled(s.attack_state == EventsModel::Status::DEFENSE && has_selection_with_player); ui->their_pull->setEnabled(s.attack_state == EventsModel::Status::OFFENSE); @@ -447,14 +531,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) { @@ -475,14 +558,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; } @@ -495,16 +577,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); }