]> git.sesse.net Git - nageru/blob - clip_list.cpp
Support editing descriptions.
[nageru] / clip_list.cpp
1 #include "mainwindow.h"
2
3 #include <math.h>
4 #include <string>
5 #include <vector>
6
7 #include "clip_list.h"
8 #include "ui_mainwindow.h"
9
10 using namespace std;
11
12 string pts_to_string(int64_t pts)
13 {
14         // FIXME: This depends on a fixed timebase.
15         int64_t t = lrint((pts / 12800.0) * 1e3);  // In milliseconds.
16         int ms = t % 1000;
17         t /= 1000;
18         int sec = t % 60;
19         t /= 60;
20         int min = t % 60;
21         t /= 60;
22         int hour = t;
23
24         char buf[256];
25         snprintf(buf, sizeof(buf), "%d:%02d:%02d.%03d", hour, min, sec, ms);
26         return buf;
27 }
28
29 string duration_to_string(int64_t pts_diff)
30 {
31         // FIXME: This depends on a fixed timebase.
32         int64_t t = lrint((pts_diff / 12800.0) * 1e3);  // In milliseconds.
33         int ms = t % 1000;
34         t /= 1000;
35         int sec = t % 60;
36         t /= 60;
37         int min = t;
38
39         char buf[256];
40         snprintf(buf, sizeof(buf), "%d:%02d.%03d", min, sec, ms);
41         return buf;
42 }
43
44 int ClipList::rowCount(const QModelIndex &parent) const {
45         if (parent.isValid()) return 0;
46         return clips.size();
47 }
48
49 int PlayList::rowCount(const QModelIndex &parent) const {
50         if (parent.isValid()) return 0;
51         return clips.size();
52 }
53
54 int ClipList::columnCount(const QModelIndex &parent) const {
55         if (parent.isValid()) return 0;
56         return int(Column::NUM_COLUMNS);
57 }
58
59 int PlayList::columnCount(const QModelIndex &parent) const {
60         if (parent.isValid()) return 0;
61         return int(Column::NUM_COLUMNS);
62 }
63
64 QVariant ClipList::data(const QModelIndex &parent, int role) const {
65         if (!parent.isValid())
66                 return QVariant();
67         const int row = parent.row(), column = parent.column();
68         if (size_t(row) >= clips.size())
69                 return QVariant();
70
71         if (role == Qt::TextAlignmentRole) {
72                 switch (Column(column)) {
73                 case Column::IN:
74                 case Column::OUT:
75                 case Column::DURATION:
76                         return Qt::AlignRight + Qt::AlignVCenter;
77                 default:
78                         return Qt::AlignLeft + Qt::AlignVCenter;
79                 }
80         }
81
82         if (role != Qt::DisplayRole)
83                 return QVariant();
84
85         switch (Column(column)) {
86         case Column::IN:
87                 return QString::fromStdString(pts_to_string(clips[row].pts_in));
88         case Column::OUT:
89                 if (clips[row].pts_out >= 0) {
90                         return QString::fromStdString(pts_to_string(clips[row].pts_out));
91                 } else {
92                         return QVariant();
93                 }
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));
97                 } else {
98                         return QVariant();
99                 }
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]);
106         }
107         default:
108                 return "";
109         }
110 }
111
112 QVariant PlayList::data(const QModelIndex &parent, int role) const {
113         if (!parent.isValid())
114                 return QVariant();
115         const int row = parent.row(), column = parent.column();
116         if (size_t(row) >= clips.size())
117                 return QVariant();
118
119         if (role == Qt::TextAlignmentRole) {
120                 switch (Column(column)) {
121                 case Column::PLAYING:
122                         return Qt::AlignCenter;
123                 case Column::IN:
124                 case Column::OUT:
125                 case Column::DURATION:
126                         return Qt::AlignRight + Qt::AlignVCenter;
127                 case Column::CAMERA:
128                         return Qt::AlignCenter;
129                 default:
130                         return Qt::AlignLeft + Qt::AlignVCenter;
131                 }
132         }
133
134         if (role != Qt::DisplayRole)
135                 return QVariant();
136
137         switch (Column(column)) {
138         case Column::PLAYING:
139                 return (row == currently_playing_index) ? "→" : "";
140         case Column::IN:
141                 return QString::fromStdString(pts_to_string(clips[row].pts_in));
142         case Column::OUT:
143                 if (clips[row].pts_out >= 0) {
144                         return QString::fromStdString(pts_to_string(clips[row].pts_out));
145                 } else {
146                         return QVariant();
147                 }
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));
151                 } else {
152                         return QVariant();
153                 }
154         case Column::CAMERA:
155                 return qlonglong(clips[row].stream_idx + 1);
156         case Column::DESCRIPTION:
157                 return QString::fromStdString(clips[row].descriptions[clips[row].stream_idx]);
158         default:
159                 return "";
160         }
161 }
162
163 QVariant ClipList::headerData(int section, Qt::Orientation orientation, int role) const {
164         if (role != Qt::DisplayRole)
165                 return QVariant();
166         if (orientation != Qt::Horizontal)
167                 return QVariant();
168
169         switch (Column(section)) {
170         case Column::IN:
171                 return "In";
172         case Column::OUT:
173                 return "Out";
174         case Column::DURATION:
175                 return "Duration";
176         case Column::CAMERA_1:
177                 return "Camera 1";
178         case Column::CAMERA_2:
179                 return "Camera 2";
180         case Column::CAMERA_3:
181                 return "Camera 3";
182         case Column::CAMERA_4:
183                 return "Camera 4";
184         default:
185                 return "";
186         }
187 }
188
189 QVariant PlayList::headerData(int section, Qt::Orientation orientation, int role) const {
190         if (role != Qt::DisplayRole)
191                 return QVariant();
192         if (orientation != Qt::Horizontal)
193                 return QVariant();
194
195         switch (Column(section)) {
196         case Column::PLAYING:
197                 return "";
198         case Column::IN:
199                 return "In";
200         case Column::OUT:
201                 return "Out";
202         case Column::DURATION:
203                 return "Duration";
204         case Column::CAMERA:
205                 return "Camera";
206         case Column::DESCRIPTION:
207                 return "Description";
208         default:
209                 return "";
210         }
211 }
212
213 Qt::ItemFlags ClipList::flags(const QModelIndex &index) const
214 {
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;
220
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;
227         default:
228                 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
229         }
230 }
231
232 bool ClipList::setData(const QModelIndex &index, const QVariant &value, int role)
233 {
234         if (!index.isValid() || role != Qt::EditRole) {
235                 return false;
236         }
237
238         const int row = index.row(), column = index.column();
239         if (size_t(row) >= clips.size())
240                 return false;
241
242         switch (Column(column)) {
243         case Column::CAMERA_1:
244         case Column::CAMERA_2:
245         case Column::CAMERA_3:
246         case Column::CAMERA_4: {
247                 unsigned stream_idx = column - int(Column::CAMERA_1);
248                 clips[row].descriptions[stream_idx] = value.toString().toStdString();
249                 emit_data_changed(row);
250                 return true;
251         }
252         default:
253                 return false;
254         }
255 }
256
257 void ClipList::add_clip(const Clip &clip)
258 {
259         beginInsertRows(QModelIndex(), clips.size(), clips.size());
260         clips.push_back(clip);
261         endInsertRows();
262 }
263
264 void PlayList::add_clip(const Clip &clip)
265 {
266         beginInsertRows(QModelIndex(), clips.size(), clips.size());
267         clips.push_back(clip);
268         endInsertRows();
269 }
270
271 void ClipList::emit_data_changed(size_t row)
272 {
273         emit dataChanged(index(row, 0), index(row, int(Column::NUM_COLUMNS)));
274 }
275
276 void PlayList::emit_data_changed(size_t row)
277 {
278         emit dataChanged(index(row, 0), index(row, int(Column::NUM_COLUMNS)));
279 }
280
281 void PlayList::set_currently_playing(int index)
282 {
283         int old_index = currently_playing_index;
284         if (index != old_index) {
285                 currently_playing_index = index;
286                 if (old_index != -1) {
287                         emit_data_changed(old_index);
288                 }
289                 if (index != -1) {
290                         emit_data_changed(index);
291                 }
292         }
293 }