}
}
+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,
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 {
#include <QVideoWidget>
#include <QShortcut>
#include <QInputDialog>
+#include <QTimer>
#include <algorithm>
#include <string>
#include <map>
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);
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]() {
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();
} else {
events->set_formation_at(video->position(), offense, id);
}
+ update_ui_from_time(video->position());
}
sqlite3 *open_db(const char *filename)