1 #include "mainwindow.h"
8 #include "ui_mainwindow.h"
12 string pts_to_string(int64_t pts)
14 // FIXME: This depends on a fixed timebase.
15 int64_t t = lrint((pts / 12800.0) * 1e3); // In milliseconds.
25 snprintf(buf, sizeof(buf), "%d:%02d:%02d.%03d", hour, min, sec, ms);
29 string duration_to_string(int64_t pts_diff)
31 // FIXME: This depends on a fixed timebase.
32 int64_t t = lrint((pts_diff / 12800.0) * 1e3); // In milliseconds.
40 snprintf(buf, sizeof(buf), "%d:%02d.%03d", min, sec, ms);
44 int ClipList::rowCount(const QModelIndex &parent) const {
45 if (parent.isValid()) return 0;
49 int PlayList::rowCount(const QModelIndex &parent) const {
50 if (parent.isValid()) return 0;
54 int ClipList::columnCount(const QModelIndex &parent) const {
55 if (parent.isValid()) return 0;
56 return int(Column::NUM_COLUMNS);
59 int PlayList::columnCount(const QModelIndex &parent) const {
60 if (parent.isValid()) return 0;
61 return int(Column::NUM_COLUMNS);
64 QVariant ClipList::data(const QModelIndex &parent, int role) const {
65 if (!parent.isValid())
67 const int row = parent.row(), column = parent.column();
68 if (size_t(row) >= clips.size())
71 if (role == Qt::TextAlignmentRole) {
72 switch (Column(column)) {
75 case Column::DURATION:
76 return Qt::AlignRight + Qt::AlignVCenter;
78 return Qt::AlignLeft + Qt::AlignVCenter;
82 if (role != Qt::DisplayRole && role != Qt::EditRole)
85 switch (Column(column)) {
87 return QString::fromStdString(pts_to_string(clips[row].pts_in));
89 if (clips[row].pts_out >= 0) {
90 return QString::fromStdString(pts_to_string(clips[row].pts_out));
94 case Column::DURATION:
95 if (clips[row].pts_out >= 0) {
96 return QString::fromStdString(duration_to_string(clips[row].pts_out - clips[row].pts_in));
100 case Column::CAMERA_1:
101 case Column::CAMERA_2:
102 case Column::CAMERA_3:
103 case Column::CAMERA_4: {
104 unsigned stream_idx = column - int(Column::CAMERA_1);
105 return QString::fromStdString(clips[row].descriptions[stream_idx]);
112 QVariant PlayList::data(const QModelIndex &parent, int role) const {
113 if (!parent.isValid())
115 const int row = parent.row(), column = parent.column();
116 if (size_t(row) >= clips.size())
119 if (role == Qt::TextAlignmentRole) {
120 switch (Column(column)) {
121 case Column::PLAYING:
122 return Qt::AlignCenter;
125 case Column::DURATION:
126 return Qt::AlignRight + Qt::AlignVCenter;
128 return Qt::AlignCenter;
130 return Qt::AlignLeft + Qt::AlignVCenter;
134 if (role != Qt::DisplayRole && role != Qt::EditRole)
137 switch (Column(column)) {
138 case Column::PLAYING:
139 return (row == currently_playing_index) ? "→" : "";
141 return QString::fromStdString(pts_to_string(clips[row].pts_in));
143 if (clips[row].pts_out >= 0) {
144 return QString::fromStdString(pts_to_string(clips[row].pts_out));
148 case Column::DURATION:
149 if (clips[row].pts_out >= 0) {
150 return QString::fromStdString(duration_to_string(clips[row].pts_out - clips[row].pts_in));
155 return qlonglong(clips[row].stream_idx + 1);
156 case Column::DESCRIPTION:
157 return QString::fromStdString(clips[row].descriptions[clips[row].stream_idx]);
163 QVariant ClipList::headerData(int section, Qt::Orientation orientation, int role) const {
164 if (role != Qt::DisplayRole)
166 if (orientation != Qt::Horizontal)
169 switch (Column(section)) {
174 case Column::DURATION:
176 case Column::CAMERA_1:
178 case Column::CAMERA_2:
180 case Column::CAMERA_3:
182 case Column::CAMERA_4:
189 QVariant PlayList::headerData(int section, Qt::Orientation orientation, int role) const {
190 if (role != Qt::DisplayRole)
192 if (orientation != Qt::Horizontal)
195 switch (Column(section)) {
196 case Column::PLAYING:
202 case Column::DURATION:
206 case Column::DESCRIPTION:
207 return "Description";
213 Qt::ItemFlags ClipList::flags(const QModelIndex &index) const
215 if (!index.isValid())
216 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
217 const int row = index.row(), column = index.column();
218 if (size_t(row) >= clips.size())
219 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
221 switch (Column(column)) {
222 case Column::CAMERA_1:
223 case Column::CAMERA_2:
224 case Column::CAMERA_3:
225 case Column::CAMERA_4:
226 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
228 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
232 Qt::ItemFlags PlayList::flags(const QModelIndex &index) const
234 if (!index.isValid())
235 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
236 const int row = index.row(), column = index.column();
237 if (size_t(row) >= clips.size())
238 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
240 switch (Column(column)) {
241 case Column::DESCRIPTION:
243 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
244 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
246 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
250 bool ClipList::setData(const QModelIndex &index, const QVariant &value, int role)
252 if (!index.isValid() || role != Qt::EditRole) {
256 const int row = index.row(), column = index.column();
257 if (size_t(row) >= clips.size())
260 switch (Column(column)) {
261 case Column::CAMERA_1:
262 case Column::CAMERA_2:
263 case Column::CAMERA_3:
264 case Column::CAMERA_4: {
265 unsigned stream_idx = column - int(Column::CAMERA_1);
266 clips[row].descriptions[stream_idx] = value.toString().toStdString();
267 emit_data_changed(row);
275 bool PlayList::setData(const QModelIndex &index, const QVariant &value, int role)
277 if (!index.isValid() || role != Qt::EditRole) {
281 const int row = index.row(), column = index.column();
282 if (size_t(row) >= clips.size())
285 switch (Column(column)) {
286 case Column::DESCRIPTION:
287 clips[row].descriptions[clips[row].stream_idx] = value.toString().toStdString();
288 emit_data_changed(row);
290 case Column::CAMERA: {
292 int camera_idx = value.toInt(&ok);
293 if (!ok || camera_idx < 1 || camera_idx > NUM_CAMERAS) {
296 clips[row].stream_idx = camera_idx - 1;
297 emit_data_changed(row);
305 void ClipList::add_clip(const Clip &clip)
307 beginInsertRows(QModelIndex(), clips.size(), clips.size());
308 clips.push_back(clip);
312 void PlayList::add_clip(const Clip &clip)
314 beginInsertRows(QModelIndex(), clips.size(), clips.size());
315 clips.push_back(clip);
319 void PlayList::duplicate_clips(size_t first, size_t last)
321 beginInsertRows(QModelIndex(), first, last);
322 clips.insert(clips.begin() + first, clips.begin() + first, clips.begin() + last + 1);
326 void PlayList::erase_clips(size_t first, size_t last)
328 beginRemoveRows(QModelIndex(), first, last);
329 clips.erase(clips.begin() + first, clips.begin() + last + 1);
333 void PlayList::move_clips(size_t first, size_t last, int delta)
336 beginMoveRows(QModelIndex(), first, last, QModelIndex(), first - 1);
337 rotate(clips.begin() + first - 1, clips.begin() + first, clips.begin() + last + 1);
339 beginMoveRows(QModelIndex(), first, last, QModelIndex(), first + (last-first+1) + 1);
340 first = clips.size() - first - 1;
341 last = clips.size() - last - 1;
342 rotate(clips.rbegin() + last - 1, clips.rbegin() + last, clips.rbegin() + first + 1);
347 void ClipList::emit_data_changed(size_t row)
349 emit dataChanged(index(row, 0), index(row, int(Column::NUM_COLUMNS)));
352 void PlayList::emit_data_changed(size_t row)
354 emit dataChanged(index(row, 0), index(row, int(Column::NUM_COLUMNS)));
357 void PlayList::set_currently_playing(int index)
359 int old_index = currently_playing_index;
360 if (index != old_index) {
361 currently_playing_index = index;
362 if (old_index != -1) {
363 emit_data_changed(old_index);
366 emit_data_changed(index);