107 QLayout * PageVideos::bodyLayoutDefinition() |
107 QLayout * PageVideos::bodyLayoutDefinition() |
108 { |
108 { |
109 QGridLayout * pPageLayout = new QGridLayout(); |
109 QGridLayout * pPageLayout = new QGridLayout(); |
110 pPageLayout->setColumnStretch(0, 1); |
110 pPageLayout->setColumnStretch(0, 1); |
111 pPageLayout->setColumnStretch(1, 2); |
111 pPageLayout->setColumnStretch(1, 2); |
112 pPageLayout->setRowStretch(0, 1); |
|
113 pPageLayout->setRowStretch(1, 1); |
|
114 |
|
115 // options |
|
116 { |
|
117 IconedGroupBox* pOptionsGroup = new IconedGroupBox(this); |
|
118 pOptionsGroup->setIcon(QIcon(":/res/Settings.png")); // FIXME |
|
119 pOptionsGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
|
120 pOptionsGroup->setTitle(QGroupBox::tr("Video recording options")); |
|
121 QGridLayout * pOptLayout = new QGridLayout(pOptionsGroup); |
|
122 |
|
123 // label for format |
|
124 QLabel *labelFormat = new QLabel(pOptionsGroup); |
|
125 labelFormat->setText(QLabel::tr("Format")); |
|
126 pOptLayout->addWidget(labelFormat, 0, 0); |
|
127 |
|
128 // list of supported formats |
|
129 comboAVFormats = new QComboBox(pOptionsGroup); |
|
130 pOptLayout->addWidget(comboAVFormats, 0, 1, 1, 4); |
|
131 LibavInteraction::instance().fillFormats(comboAVFormats); |
|
132 |
|
133 // separator |
|
134 QFrame * hr = new QFrame(pOptionsGroup); |
|
135 hr->setFrameStyle(QFrame::HLine); |
|
136 hr->setLineWidth(3); |
|
137 hr->setFixedHeight(10); |
|
138 pOptLayout->addWidget(hr, 1, 0, 1, 5); |
|
139 |
|
140 // label for audio codec |
|
141 QLabel *labelACodec = new QLabel(pOptionsGroup); |
|
142 labelACodec->setText(QLabel::tr("Audio codec")); |
|
143 pOptLayout->addWidget(labelACodec, 2, 0); |
|
144 |
|
145 // list of supported audio codecs |
|
146 comboAudioCodecs = new QComboBox(pOptionsGroup); |
|
147 pOptLayout->addWidget(comboAudioCodecs, 2, 1, 1, 3); |
|
148 |
|
149 // checkbox 'record audio' |
|
150 checkRecordAudio = new QCheckBox(pOptionsGroup); |
|
151 checkRecordAudio->setText(QCheckBox::tr("Record audio")); |
|
152 pOptLayout->addWidget(checkRecordAudio, 2, 4); |
|
153 |
|
154 // separator |
|
155 hr = new QFrame(pOptionsGroup); |
|
156 hr->setFrameStyle(QFrame::HLine); |
|
157 hr->setLineWidth(3); |
|
158 hr->setFixedHeight(10); |
|
159 pOptLayout->addWidget(hr, 3, 0, 1, 5); |
|
160 |
|
161 // label for video codec |
|
162 QLabel *labelVCodec = new QLabel(pOptionsGroup); |
|
163 labelVCodec->setText(QLabel::tr("Video codec")); |
|
164 pOptLayout->addWidget(labelVCodec, 4, 0); |
|
165 |
|
166 // list of supported video codecs |
|
167 comboVideoCodecs = new QComboBox(pOptionsGroup); |
|
168 pOptLayout->addWidget(comboVideoCodecs, 4, 1, 1, 4); |
|
169 |
|
170 // label for resolution |
|
171 QLabel *labelRes = new QLabel(pOptionsGroup); |
|
172 labelRes->setText(QLabel::tr("Resolution")); |
|
173 pOptLayout->addWidget(labelRes, 5, 0); |
|
174 |
|
175 // width |
|
176 widthEdit = new QLineEdit(pOptionsGroup); |
|
177 widthEdit->setValidator(new QIntValidator(this)); |
|
178 pOptLayout->addWidget(widthEdit, 5, 1); |
|
179 |
|
180 // x |
|
181 QLabel *labelX = new QLabel(pOptionsGroup); |
|
182 labelX->setText("X"); |
|
183 pOptLayout->addWidget(labelX, 5, 2); |
|
184 |
|
185 // height |
|
186 heightEdit = new QLineEdit(pOptionsGroup); |
|
187 heightEdit->setValidator(new QIntValidator(pOptionsGroup)); |
|
188 pOptLayout->addWidget(heightEdit, 5, 3); |
|
189 |
|
190 // checkbox 'use game resolution' |
|
191 checkUseGameRes = new QCheckBox(pOptionsGroup); |
|
192 checkUseGameRes->setText(QCheckBox::tr("Use game resolution")); |
|
193 pOptLayout->addWidget(checkUseGameRes, 5, 4); |
|
194 |
|
195 // label for framerate |
|
196 QLabel *labelFramerate = new QLabel(pOptionsGroup); |
|
197 labelFramerate->setText(QLabel::tr("Framerate")); |
|
198 pOptLayout->addWidget(labelFramerate, 6, 0); |
|
199 |
|
200 // framerate |
|
201 framerateBox = new QSpinBox(pOptionsGroup); |
|
202 framerateBox->setRange(1, 200); |
|
203 framerateBox->setSingleStep(1); |
|
204 pOptLayout->addWidget(framerateBox, 6, 1); |
|
205 |
|
206 // label for Bitrate |
|
207 QLabel *labelBitrate = new QLabel(pOptionsGroup); |
|
208 labelBitrate->setText(QLabel::tr("Bitrate (Kbps)")); |
|
209 pOptLayout->addWidget(labelBitrate, 6, 2); |
|
210 |
|
211 // bitrate |
|
212 bitrateBox = new QSpinBox(pOptionsGroup); |
|
213 bitrateBox->setRange(100, 5000); |
|
214 bitrateBox->setSingleStep(100); |
|
215 pOptLayout->addWidget(bitrateBox, 6, 3); |
|
216 |
|
217 // button 'set default options' |
|
218 btnDefaults = new QPushButton(pOptionsGroup); |
|
219 btnDefaults->setText(QPushButton::tr("Set default options")); |
|
220 btnDefaults->setWhatsThis(QPushButton::tr("Restore default coding parameters")); |
|
221 pOptLayout->addWidget(btnDefaults, 7, 0, 1, 5); |
|
222 |
|
223 pPageLayout->addWidget(pOptionsGroup, 1, 0); |
|
224 } |
|
225 |
112 |
226 // list of videos |
113 // list of videos |
227 { |
114 { |
228 IconedGroupBox* pTableGroup = new IconedGroupBox(this); |
115 IconedGroupBox* pTableGroup = new IconedGroupBox(this); |
229 pTableGroup->setIcon(QIcon(":/res/graphicsicon.png")); // FIXME |
116 pTableGroup->setIcon(QIcon(":/res/graphicsicon.png")); // FIXME |
255 |
142 |
256 QVBoxLayout *box = new QVBoxLayout(pTableGroup); |
143 QVBoxLayout *box = new QVBoxLayout(pTableGroup); |
257 box->addWidget(filesTable); |
144 box->addWidget(filesTable); |
258 box->addWidget(btnOpenDir); |
145 box->addWidget(btnOpenDir); |
259 |
146 |
260 pPageLayout->addWidget(pTableGroup, 0, 1, 2, 1); |
147 pPageLayout->addWidget(pTableGroup, 0, 1); |
261 } |
148 } |
262 |
149 |
263 // description |
150 // description |
264 { |
151 { |
265 IconedGroupBox* pDescGroup = new IconedGroupBox(this); |
152 IconedGroupBox* pDescGroup = new IconedGroupBox(this); |
266 pDescGroup->setIcon(QIcon(":/res/graphicsicon.png")); // FIXME |
153 pDescGroup->setIcon(QIcon(":/res/graphicsicon.png")); // FIXME |
267 pDescGroup->setTitle(QGroupBox::tr("Description")); |
154 pDescGroup->setTitle(QGroupBox::tr("Description")); |
268 |
155 |
269 QVBoxLayout* pDescLayout = new QVBoxLayout(pDescGroup); |
156 QVBoxLayout* pDescLayout = new QVBoxLayout(pDescGroup); |
270 QHBoxLayout* pTopDescLayout = new QHBoxLayout(0); // picture and text |
|
271 QHBoxLayout* pBottomDescLayout = new QHBoxLayout(0); // buttons |
157 QHBoxLayout* pBottomDescLayout = new QHBoxLayout(0); // buttons |
272 |
158 |
273 // label with thumbnail picture |
159 // label with thumbnail picture |
274 labelThumbnail = new QLabel(pDescGroup); |
160 labelThumbnail = new QLabel(pDescGroup); |
275 labelThumbnail->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); |
161 labelThumbnail->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); |
280 "border-width: 3px;" |
166 "border-width: 3px;" |
281 "border-color: #ffcc00;" |
167 "border-color: #ffcc00;" |
282 "border-radius: 4px;" |
168 "border-radius: 4px;" |
283 "}" ); |
169 "}" ); |
284 clearThumbnail(); |
170 clearThumbnail(); |
285 pTopDescLayout->addWidget(labelThumbnail, 2); |
|
286 |
171 |
287 // label with file description |
172 // label with file description |
288 labelDesc = new QLabel(pDescGroup); |
173 labelDesc = new QLabel(pDescGroup); |
289 labelDesc->setAlignment(Qt::AlignLeft | Qt::AlignTop); |
174 labelDesc->setAlignment(Qt::AlignLeft | Qt::AlignTop); |
290 labelDesc->setTextInteractionFlags(Qt::TextSelectableByMouse | |
175 labelDesc->setTextInteractionFlags(Qt::TextSelectableByMouse | |
291 Qt::TextSelectableByKeyboard | |
176 Qt::TextSelectableByKeyboard | |
292 Qt::LinksAccessibleByMouse | |
177 Qt::LinksAccessibleByMouse | |
293 Qt::LinksAccessibleByKeyboard); |
178 Qt::LinksAccessibleByKeyboard); |
294 labelDesc->setTextFormat(Qt::RichText); |
179 labelDesc->setTextFormat(Qt::RichText); |
295 labelDesc->setOpenExternalLinks(true); |
180 labelDesc->setOpenExternalLinks(true); |
296 pTopDescLayout->addWidget(labelDesc, 1); |
181 labelDesc->setMinimumSize(ThumbnailSize); |
|
182 //pTopDescLayout->addWidget(labelDesc, 1); |
297 |
183 |
298 // buttons: play and delete |
184 // buttons: play and delete |
299 btnPlay = new QPushButton(QPushButton::tr("Play"), pDescGroup); |
185 btnPlay = new QPushButton(QPushButton::tr("Play"), pDescGroup); |
300 btnPlay->setEnabled(false); |
186 btnPlay->setEnabled(false); |
301 btnPlay->setWhatsThis(QPushButton::tr("Play this video")); |
187 btnPlay->setWhatsThis(QPushButton::tr("Play this video")); |
325 return NULL; |
213 return NULL; |
326 } |
214 } |
327 |
215 |
328 void PageVideos::connectSignals() |
216 void PageVideos::connectSignals() |
329 { |
217 { |
330 connect(checkUseGameRes, SIGNAL(stateChanged(int)), this, SLOT(changeUseGameRes(int))); |
|
331 connect(checkRecordAudio, SIGNAL(stateChanged(int)), this, SLOT(changeRecordAudio(int))); |
|
332 connect(comboAVFormats, SIGNAL(currentIndexChanged(int)), this, SLOT(changeAVFormat(int))); |
|
333 connect(btnDefaults, SIGNAL(clicked()), this, SLOT(setDefaultOptions())); |
|
334 connect(filesTable, SIGNAL(cellDoubleClicked(int, int)), this, SLOT(cellDoubleClicked(int, int))); |
218 connect(filesTable, SIGNAL(cellDoubleClicked(int, int)), this, SLOT(cellDoubleClicked(int, int))); |
335 connect(filesTable, SIGNAL(cellChanged(int,int)), this, SLOT(cellChanged(int, int))); |
219 connect(filesTable, SIGNAL(cellChanged(int,int)), this, SLOT(cellChanged(int, int))); |
336 connect(filesTable, SIGNAL(currentCellChanged(int,int,int,int)), this, SLOT(currentCellChanged())); |
220 connect(filesTable, SIGNAL(currentCellChanged(int,int,int,int)), this, SLOT(currentCellChanged())); |
337 connect(btnPlay, SIGNAL(clicked()), this, SLOT(playSelectedFile())); |
221 connect(btnPlay, SIGNAL(clicked()), this, SLOT(playSelectedFile())); |
338 connect(btnDelete, SIGNAL(clicked()), this, SLOT(deleteSelectedFiles())); |
222 connect(btnDelete, SIGNAL(clicked()), this, SLOT(deleteSelectedFiles())); |
358 pWatcher->addPath(path); |
242 pWatcher->addPath(path); |
359 connect(pWatcher, SIGNAL(directoryChanged(const QString &)), this, SLOT(updateFileList(const QString &))); |
243 connect(pWatcher, SIGNAL(directoryChanged(const QString &)), this, SLOT(updateFileList(const QString &))); |
360 updateFileList(path); |
244 updateFileList(path); |
361 |
245 |
362 startEncoding(); // this is for videos recorded from demos which were executed directly (without frontend) |
246 startEncoding(); // this is for videos recorded from demos which were executed directly (without frontend) |
363 } |
|
364 |
|
365 // user changed file format, we need to update list of codecs |
|
366 void PageVideos::changeAVFormat(int index) |
|
367 { |
|
368 // remember selected codecs |
|
369 QString prevVCodec = videoCodec(); |
|
370 QString prevACodec = audioCodec(); |
|
371 |
|
372 // clear lists of codecs |
|
373 comboVideoCodecs->clear(); |
|
374 comboAudioCodecs->clear(); |
|
375 |
|
376 // get list of codecs for specified format |
|
377 LibavInteraction::instance().fillCodecs(comboAVFormats->itemData(index).toString(), comboVideoCodecs, comboAudioCodecs); |
|
378 |
|
379 // disable audio if there is no audio codec |
|
380 if (comboAudioCodecs->count() == 0) |
|
381 { |
|
382 checkRecordAudio->setChecked(false); |
|
383 checkRecordAudio->setEnabled(false); |
|
384 } |
|
385 else |
|
386 checkRecordAudio->setEnabled(true); |
|
387 |
|
388 // restore selected codecs if possible |
|
389 int iVCodec = comboVideoCodecs->findData(prevVCodec); |
|
390 if (iVCodec != -1) |
|
391 comboVideoCodecs->setCurrentIndex(iVCodec); |
|
392 int iACodec = comboAudioCodecs->findData(prevACodec); |
|
393 if (iACodec != -1) |
|
394 comboAudioCodecs->setCurrentIndex(iACodec); |
|
395 } |
|
396 |
|
397 // user switched checkbox 'use game resolution' |
|
398 void PageVideos::changeUseGameRes(int state) |
|
399 { |
|
400 if (state && config) |
|
401 { |
|
402 // set resolution to game resolution |
|
403 QRect resolution = config->vid_Resolution(); |
|
404 widthEdit->setText(QString::number(resolution.width())); |
|
405 heightEdit->setText(QString::number(resolution.height())); |
|
406 } |
|
407 widthEdit->setEnabled(!state); |
|
408 heightEdit->setEnabled(!state); |
|
409 } |
|
410 |
|
411 // user switched checkbox 'record audio' |
|
412 void PageVideos::changeRecordAudio(int state) |
|
413 { |
|
414 comboAudioCodecs->setEnabled(!!state); |
|
415 } |
|
416 |
|
417 void PageVideos::setDefaultCodecs() |
|
418 { |
|
419 // VLC should be able to handle any of these configurations |
|
420 // Quicktime X only opens the first one |
|
421 // Windows Media Player TODO |
|
422 if (tryCodecs("mp4", "libx264", "aac")) |
|
423 return; |
|
424 if (tryCodecs("mp4", "libx264", "libfaac")) |
|
425 return; |
|
426 if (tryCodecs("mp4", "libx264", "libmp3lame")) |
|
427 return; |
|
428 if (tryCodecs("mp4", "libx264", "mp2")) |
|
429 return; |
|
430 if (tryCodecs("avi", "libxvid", "libmp3lame")) |
|
431 return; |
|
432 if (tryCodecs("avi", "libxvid", "ac3_fixed")) |
|
433 return; |
|
434 if (tryCodecs("avi", "libxvid", "mp2")) |
|
435 return; |
|
436 if (tryCodecs("avi", "mpeg4", "libmp3lame")) |
|
437 return; |
|
438 if (tryCodecs("avi", "mpeg4", "ac3_fixed")) |
|
439 return; |
|
440 if (tryCodecs("avi", "mpeg4", "mp2")) |
|
441 return; |
|
442 |
|
443 // this shouldn't happen, just in case |
|
444 if (tryCodecs("ogg", "libtheora", "libvorbis")) |
|
445 return; |
|
446 tryCodecs("ogg", "libtheora", "flac"); |
|
447 } |
|
448 |
|
449 void PageVideos::setDefaultOptions() |
|
450 { |
|
451 framerateBox->setValue(30); |
|
452 bitrateBox->setValue(1000); |
|
453 checkRecordAudio->setChecked(true); |
|
454 checkUseGameRes->setChecked(true); |
|
455 setDefaultCodecs(); |
|
456 } |
|
457 |
|
458 bool PageVideos::tryCodecs(const QString & format, const QString & vcodec, const QString & acodec) |
|
459 { |
|
460 // first we should change format |
|
461 int iFormat = comboAVFormats->findData(format); |
|
462 if (iFormat == -1) |
|
463 return false; |
|
464 comboAVFormats->setCurrentIndex(iFormat); |
|
465 // format was changed, so lists of codecs were automatically updated to codecs supported by this format |
|
466 |
|
467 // try to find video codec |
|
468 int iVCodec = comboVideoCodecs->findData(vcodec); |
|
469 if (iVCodec == -1) |
|
470 return false; |
|
471 comboVideoCodecs->setCurrentIndex(iVCodec); |
|
472 |
|
473 // try to find audio codec |
|
474 int iACodec = comboAudioCodecs->findData(acodec); |
|
475 if (iACodec == -1 && checkRecordAudio->isChecked()) |
|
476 return false; |
|
477 if (iACodec != -1) |
|
478 comboAudioCodecs->setCurrentIndex(iACodec); |
|
479 |
|
480 return true; |
|
481 } |
247 } |
482 |
248 |
483 // get file size as string |
249 // get file size as string |
484 static QString FileSizeStr(const QString & path) |
250 static QString FileSizeStr(const QString & path) |
485 { |
251 { |