#include <QApplication>
#include <QGridLayout>
#include <QShortcut>
+#include <QFileDialog>
#include <QInputDialog>
#include <QTimer>
#include <algorithm>
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();
});
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");
}
});
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); });
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 {
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);
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) {
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;
}
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);
}