1 #include "mainwindow.h"
9 #include "ui_mainwindow.h"
13 string pts_to_string(int64_t pts)
15 int64_t t = lrint((pts / double(TIMEBASE)) * 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 int64_t t = lrint((pts_diff / double(TIMEBASE)) * 1e3); // In milliseconds.
39 snprintf(buf, sizeof(buf), "%d:%02d.%03d", min, sec, ms);
43 int ClipList::rowCount(const QModelIndex &parent) const {
44 if (parent.isValid()) return 0;
48 int PlayList::rowCount(const QModelIndex &parent) const {
49 if (parent.isValid()) return 0;
53 int ClipList::columnCount(const QModelIndex &parent) const {
54 if (parent.isValid()) return 0;
55 return int(Column::NUM_COLUMNS);
58 int PlayList::columnCount(const QModelIndex &parent) const {
59 if (parent.isValid()) return 0;
60 return int(Column::NUM_COLUMNS);
63 QVariant ClipList::data(const QModelIndex &parent, int role) const {
64 if (!parent.isValid())
66 const int row = parent.row(), column = parent.column();
67 if (size_t(row) >= clips.size())
70 if (role == Qt::TextAlignmentRole) {
71 switch (Column(column)) {
74 case Column::DURATION:
75 return Qt::AlignRight + Qt::AlignVCenter;
77 return Qt::AlignLeft + Qt::AlignVCenter;
81 if (role != Qt::DisplayRole && role != Qt::EditRole)
84 switch (Column(column)) {
86 return QString::fromStdString(pts_to_string(clips[row].pts_in));
88 if (clips[row].pts_out >= 0) {
89 return QString::fromStdString(pts_to_string(clips[row].pts_out));
93 case Column::DURATION:
94 if (clips[row].pts_out >= 0) {
95 return QString::fromStdString(duration_to_string(clips[row].pts_out - clips[row].pts_in));
99 case Column::CAMERA_1:
100 case Column::CAMERA_2:
101 case Column::CAMERA_3:
102 case Column::CAMERA_4: {
103 unsigned stream_idx = column - int(Column::CAMERA_1);
104 return QString::fromStdString(clips[row].descriptions[stream_idx]);
111 QVariant PlayList::data(const QModelIndex &parent, int role) const {
112 if (!parent.isValid())
114 const int row = parent.row(), column = parent.column();
115 if (size_t(row) >= clips.size())
118 if (role == Qt::TextAlignmentRole) {
119 switch (Column(column)) {
120 case Column::PLAYING:
121 return Qt::AlignCenter;
124 case Column::DURATION:
125 return Qt::AlignRight + Qt::AlignVCenter;
127 return Qt::AlignCenter;
129 return Qt::AlignLeft + Qt::AlignVCenter;
133 if (role != Qt::DisplayRole && role != Qt::EditRole)
136 switch (Column(column)) {
137 case Column::PLAYING:
138 return (row == currently_playing_index) ? "→" : "";
140 return QString::fromStdString(pts_to_string(clips[row].pts_in));
142 if (clips[row].pts_out >= 0) {
143 return QString::fromStdString(pts_to_string(clips[row].pts_out));
147 case Column::DURATION:
148 if (clips[row].pts_out >= 0) {
149 return QString::fromStdString(duration_to_string(clips[row].pts_out - clips[row].pts_in));
154 return qlonglong(clips[row].stream_idx + 1);
155 case Column::DESCRIPTION:
156 return QString::fromStdString(clips[row].descriptions[clips[row].stream_idx]);
162 QVariant ClipList::headerData(int section, Qt::Orientation orientation, int role) const {
163 if (role != Qt::DisplayRole)
165 if (orientation != Qt::Horizontal)
168 switch (Column(section)) {
173 case Column::DURATION:
175 case Column::CAMERA_1:
177 case Column::CAMERA_2:
179 case Column::CAMERA_3:
181 case Column::CAMERA_4:
188 QVariant PlayList::headerData(int section, Qt::Orientation orientation, int role) const {
189 if (role != Qt::DisplayRole)
191 if (orientation != Qt::Horizontal)
194 switch (Column(section)) {
195 case Column::PLAYING:
201 case Column::DURATION:
205 case Column::DESCRIPTION:
206 return "Description";
212 Qt::ItemFlags ClipList::flags(const QModelIndex &index) const
214 if (!index.isValid())
215 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
216 const int row = index.row(), column = index.column();
217 if (size_t(row) >= clips.size())
218 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
220 switch (Column(column)) {
221 case Column::CAMERA_1:
222 case Column::CAMERA_2:
223 case Column::CAMERA_3:
224 case Column::CAMERA_4:
225 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
227 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
231 Qt::ItemFlags PlayList::flags(const QModelIndex &index) const
233 if (!index.isValid())
234 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
235 const int row = index.row(), column = index.column();
236 if (size_t(row) >= clips.size())
237 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
239 switch (Column(column)) {
240 case Column::DESCRIPTION:
242 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
243 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
245 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
249 bool ClipList::setData(const QModelIndex &index, const QVariant &value, int role)
251 if (!index.isValid() || role != Qt::EditRole) {
255 const int row = index.row(), column = index.column();
256 if (size_t(row) >= clips.size())
259 switch (Column(column)) {
260 case Column::CAMERA_1:
261 case Column::CAMERA_2:
262 case Column::CAMERA_3:
263 case Column::CAMERA_4: {
264 unsigned stream_idx = column - int(Column::CAMERA_1);
265 clips[row].descriptions[stream_idx] = value.toString().toStdString();
266 emit_data_changed(row);
274 bool PlayList::setData(const QModelIndex &index, const QVariant &value, int role)
276 if (!index.isValid() || role != Qt::EditRole) {
280 const int row = index.row(), column = index.column();
281 if (size_t(row) >= clips.size())
284 switch (Column(column)) {
285 case Column::DESCRIPTION:
286 clips[row].descriptions[clips[row].stream_idx] = value.toString().toStdString();
287 emit_data_changed(row);
289 case Column::CAMERA: {
291 int camera_idx = value.toInt(&ok);
292 if (!ok || camera_idx < 1 || camera_idx > NUM_CAMERAS) {
295 clips[row].stream_idx = camera_idx - 1;
296 emit_data_changed(row);
304 void ClipList::add_clip(const Clip &clip)
306 beginInsertRows(QModelIndex(), clips.size(), clips.size());
307 clips.push_back(clip);
311 void PlayList::add_clip(const Clip &clip)
313 beginInsertRows(QModelIndex(), clips.size(), clips.size());
314 clips.push_back(clip);
318 void PlayList::duplicate_clips(size_t first, size_t last)
320 beginInsertRows(QModelIndex(), first, last);
321 clips.insert(clips.begin() + first, clips.begin() + first, clips.begin() + last + 1);
325 void PlayList::erase_clips(size_t first, size_t last)
327 beginRemoveRows(QModelIndex(), first, last);
328 clips.erase(clips.begin() + first, clips.begin() + last + 1);
332 void PlayList::move_clips(size_t first, size_t last, int delta)
335 beginMoveRows(QModelIndex(), first, last, QModelIndex(), first - 1);
336 rotate(clips.begin() + first - 1, clips.begin() + first, clips.begin() + last + 1);
338 beginMoveRows(QModelIndex(), first, last, QModelIndex(), first + (last-first+1) + 1);
339 first = clips.size() - first - 1;
340 last = clips.size() - last - 1;
341 rotate(clips.rbegin() + last - 1, clips.rbegin() + last, clips.rbegin() + first + 1);
346 void ClipList::emit_data_changed(size_t row)
348 emit dataChanged(index(row, 0), index(row, int(Column::NUM_COLUMNS)));
351 void PlayList::emit_data_changed(size_t row)
353 emit dataChanged(index(row, 0), index(row, int(Column::NUM_COLUMNS)));
356 void PlayList::set_currently_playing(int index)
358 int old_index = currently_playing_index;
359 if (index != old_index) {
360 currently_playing_index = index;
361 if (old_index != -1) {
362 emit_data_changed(old_index);
365 emit_data_changed(index);