#include <QGridLayout>
#include <QVideoWidget>
#include <QShortcut>
-#include <iostream>
+#include <algorithm>
+#include <string>
+#include <map>
+#include <vector>
+#include <optional>
+#include <sqlite3.h>
#include "mainwindow.h"
#include "ui_mainwindow.h"
+#include "events.h"
+
+using namespace std;
+
+string format_timestamp(uint64_t pos)
+{
+ int ms = pos % 1000;
+ pos /= 1000;
+ int sec = pos % 60;
+ pos /= 60;
+ int min = pos % 60;
+ int hour = pos / 60;
+
+ char buf[256];
+ snprintf(buf, sizeof(buf), "%d:%02d:%02d.%03d", hour, min, sec, ms);
+ return buf;
+}
MainWindow::MainWindow()
{
player->setSource(QUrl::fromLocalFile("/home/sesse/dev/stats/ultimate-prores.mkv"));
player->play();
- Ui::MainWindow *ui = new Ui::MainWindow;
+ ui = new Ui::MainWindow;
ui->setupUi(this);
- connect(player, &QMediaPlayer::positionChanged, [ui, this](uint64_t pos) {
- int ms = pos % 1000;
- pos /= 1000;
- int sec = pos % 60;
- pos /= 60;
- int min = pos % 60;
- int hour = pos / 60;
-
- char buf[256];
- snprintf(buf, sizeof(buf), "%d:%02d:%02d.%03d", hour, min, sec, ms);
- ui->timestamp->setText(buf);
+ connect(player, &QMediaPlayer::positionChanged, [this](uint64_t pos) {
+ ui->timestamp->setText(QString::fromUtf8(format_timestamp(pos)));
if (buffered_seek) {
player->setPosition(*buffered_seek);
buffered_seek.reset();
player->setVideoOutput(ui->video);
- QShortcut *key_k = new QShortcut(QKeySequence(Qt::Key_K), this);
- connect(key_k, &QShortcut::activated, [this]() { seek(-10000); });
+ connect(ui->minus10s, &QPushButton::clicked, [this]() { seek(-10000); });
+ connect(ui->plus10s, &QPushButton::clicked, [this]() { seek(10000); });
- QShortcut *key_l = new QShortcut(QKeySequence(Qt::Key_L), this);
- connect(key_l, &QShortcut::activated, [this]() { seek(10000); });
-
- QShortcut *key_left = new QShortcut(QKeySequence(Qt::Key_Left), this);
- connect(key_left, &QShortcut::activated, [this]() { seek(-1000); });
-
- QShortcut *key_right = new QShortcut(QKeySequence(Qt::Key_Right), this);
- connect(key_right, &QShortcut::activated, [this]() { seek(1000); });
+ connect(ui->minus2s, &QPushButton::clicked, [this]() { seek(-2000); });
+ connect(ui->plus2s, &QPushButton::clicked, [this]() { seek(2000); });
// TODO: Would be nice to actually have a frame...
- QShortcut *key_comma = new QShortcut(QKeySequence(Qt::Key_Comma), this);
- connect(key_comma, &QShortcut::activated, [this]() { seek(-20); });
-
- QShortcut *key_period = new QShortcut(QKeySequence(Qt::Key_Period), this);
- connect(key_period, &QShortcut::activated, [this]() { seek(20); });
+ connect(ui->minus1f, &QPushButton::clicked, [this]() { seek(-20); });
+ connect(ui->plus1f, &QPushButton::clicked, [this]() { seek(20); });
- QShortcut *key_space = new QShortcut(QKeySequence(Qt::Key_Space), this);
- connect(key_space, &QShortcut::activated, [this]() {
+ connect(ui->play_pause, &QPushButton::clicked, [this]() {
if (playing) {
player->pause();
+ ui->play_pause->setText("Play (space)");
} else {
player->setPlaybackRate(1.0);
player->play();
+ ui->play_pause->setText("Pause (space)");
}
playing = !playing;
+
+ // Needs to be set anew when we modify setText(), evidently.
+ ui->play_pause->setShortcut(QCoreApplication::translate("MainWindow", "Space", nullptr));
+ });
+
+ connect(ui->player_1, &QPushButton::clicked, [this]() {
+ ui->event_view->selectRow(model->insert_event(player->position(), 1));
+ });
+ connect(ui->player_2, &QPushButton::clicked, [this]() {
+ ui->event_view->selectRow(model->insert_event(player->position(), 2));
+ });
+ connect(ui->player_3, &QPushButton::clicked, [this]() {
+ ui->event_view->selectRow(model->insert_event(player->position(), 3));
+ });
+ connect(ui->player_4, &QPushButton::clicked, [this]() {
+ ui->event_view->selectRow(model->insert_event(player->position(), 4));
+ });
+ connect(ui->player_5, &QPushButton::clicked, [this]() {
+ ui->event_view->selectRow(model->insert_event(player->position(), 5));
+ });
+ connect(ui->player_6, &QPushButton::clicked, [this]() {
+ ui->event_view->selectRow(model->insert_event(player->position(), 6));
+ });
+ connect(ui->player_7, &QPushButton::clicked, [this]() {
+ ui->event_view->selectRow(model->insert_event(player->position(), 7));
});
}
+void MainWindow::setModel(EventsModel *model)
+{
+ ui->event_view->setModel(model);
+ this->model = model;
+}
+
void MainWindow::seek(int64_t delta_ms)
{
int64_t current_pos = buffered_seek ? *buffered_seek : player->position();
- uint64_t pos = std::max<int64_t>(current_pos + delta_ms, 0);
+ uint64_t pos = max<int64_t>(current_pos + delta_ms, 0);
buffered_seek = pos;
if (!playing) {
player->setPlaybackRate(0.01);
}
}
+sqlite3 *open_db(const char *filename)
+{
+ sqlite3 *db;
+ int ret = sqlite3_open(filename, &db);
+ if (ret != SQLITE_OK) {
+ fprintf(stderr, "%s: %s\n", filename, sqlite3_errmsg(db));
+ exit(1);
+ }
+
+ sqlite3_exec(db, R"(
+ CREATE TABLE IF NOT EXISTS player (player INTEGER PRIMARY KEY, number VARCHAR, name VARCHAR);
+ )", nullptr, nullptr, nullptr); // Ignore errors.
+
+ sqlite3_exec(db, R"(
+ CREATE TABLE IF NOT EXISTS event (t INTEGER, player INTEGER, type VARCHAR, FOREIGN KEY (player) REFERENCES player(player));
+ )", nullptr, nullptr, nullptr); // Ignore errors.
+
+ sqlite3_exec(db, "PRAGMA journal_mode=WAL", nullptr, nullptr, nullptr); // Ignore errors.
+ sqlite3_exec(db, "PRAGMA synchronous=NORMAL", nullptr, nullptr, nullptr); // Ignore errors.
+ return db;
+}
+
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
+ sqlite3 *db = open_db("ultimate.db");
MainWindow mainWindow;
+ mainWindow.setModel(new EventsModel(db));
mainWindow.resize(QSize(1280, 720));
mainWindow.show();