35 #include <QHeaderView> |
35 #include <QHeaderView> |
36 #include <QKeyEvent> |
36 #include <QKeyEvent> |
37 #include <QVBoxLayout> |
37 #include <QVBoxLayout> |
38 #include <QHBoxLayout> |
38 #include <QHBoxLayout> |
39 #include <QFileSystemWatcher> |
39 #include <QFileSystemWatcher> |
|
40 #include <QDateTime> |
|
41 #include <QRegExp> |
40 |
42 |
41 #include "hwconsts.h" |
43 #include "hwconsts.h" |
42 #include "pagevideos.h" |
44 #include "pagevideos.h" |
43 #include "igbox.h" |
45 #include "igbox.h" |
44 #include "libav_iteraction.h" |
46 #include "libav_iteraction.h" |
45 #include "gameuiconfig.h" |
47 #include "gameuiconfig.h" |
46 #include "recorder.h" |
48 #include "recorder.h" |
47 #include "ask_quit.h" |
49 #include "ask_quit.h" |
48 |
50 |
49 const int ThumbnailSize = 400; |
51 const QSize ThumbnailSize(350, 350*3/5); |
50 |
52 |
51 // columns in table with list of video files |
53 // columns in table with list of video files |
52 enum VideosColumns |
54 enum VideosColumns |
53 { |
55 { |
54 vcName, |
56 vcName, |
98 pPageLayout->setColumnStretch(0, 1); |
100 pPageLayout->setColumnStretch(0, 1); |
99 pPageLayout->setColumnStretch(1, 2); |
101 pPageLayout->setColumnStretch(1, 2); |
100 pPageLayout->setRowStretch(0, 1); |
102 pPageLayout->setRowStretch(0, 1); |
101 pPageLayout->setRowStretch(1, 1); |
103 pPageLayout->setRowStretch(1, 1); |
102 |
104 |
|
105 // options |
103 { |
106 { |
104 IconedGroupBox* pOptionsGroup = new IconedGroupBox(this); |
107 IconedGroupBox* pOptionsGroup = new IconedGroupBox(this); |
105 pOptionsGroup->setIcon(QIcon(":/res/graphicsicon.png")); |
108 pOptionsGroup->setIcon(QIcon(":/res/Settings.png")); |
106 pOptionsGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
109 pOptionsGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
107 pOptionsGroup->setTitle(QGroupBox::tr("Video recording options")); |
110 pOptionsGroup->setTitle(QGroupBox::tr("Video recording options")); |
108 QGridLayout * pOptLayout = new QGridLayout(pOptionsGroup); |
111 QGridLayout * pOptLayout = new QGridLayout(pOptionsGroup); |
109 |
112 |
110 // label for format |
113 // label for format |
196 pOptLayout->addWidget(btnDefaults, 7, 0, 1, 5); |
199 pOptLayout->addWidget(btnDefaults, 7, 0, 1, 5); |
197 |
200 |
198 pPageLayout->addWidget(pOptionsGroup, 1, 0); |
201 pPageLayout->addWidget(pOptionsGroup, 1, 0); |
199 } |
202 } |
200 |
203 |
|
204 // list of videos |
201 { |
205 { |
202 IconedGroupBox* pTableGroup = new IconedGroupBox(this); |
206 IconedGroupBox* pTableGroup = new IconedGroupBox(this); |
203 pTableGroup->setIcon(QIcon(":/res/graphicsicon.png")); |
207 pTableGroup->setIcon(QIcon(":/res/graphicsicon.png")); |
204 pTableGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
208 pTableGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
205 pTableGroup->setTitle(QGroupBox::tr("Videos")); |
209 pTableGroup->setTitle(QGroupBox::tr("Videos")); |
213 filesTable->setColumnCount(vcNumColumns); |
217 filesTable->setColumnCount(vcNumColumns); |
214 filesTable->setHorizontalHeaderLabels(columns); |
218 filesTable->setHorizontalHeaderLabels(columns); |
215 filesTable->setSelectionBehavior(QAbstractItemView::SelectRows); |
219 filesTable->setSelectionBehavior(QAbstractItemView::SelectRows); |
216 filesTable->setEditTriggers(QAbstractItemView::SelectedClicked); |
220 filesTable->setEditTriggers(QAbstractItemView::SelectedClicked); |
217 filesTable->verticalHeader()->hide(); |
221 filesTable->verticalHeader()->hide(); |
|
222 filesTable->setMinimumWidth(400); |
218 |
223 |
219 QHeaderView * header = filesTable->horizontalHeader(); |
224 QHeaderView * header = filesTable->horizontalHeader(); |
220 header->setResizeMode(vcName, QHeaderView::ResizeToContents); |
225 header->setResizeMode(vcName, QHeaderView::ResizeToContents); |
221 header->setResizeMode(vcSize, QHeaderView::Fixed); |
226 header->setResizeMode(vcSize, QHeaderView::Fixed); |
222 header->resizeSection(vcSize, 100); |
227 header->resizeSection(vcSize, 100); |
229 box->addWidget(btnOpenDir); |
234 box->addWidget(btnOpenDir); |
230 |
235 |
231 pPageLayout->addWidget(pTableGroup, 0, 1, 2, 1); |
236 pPageLayout->addWidget(pTableGroup, 0, 1, 2, 1); |
232 } |
237 } |
233 |
238 |
|
239 // description |
234 { |
240 { |
235 IconedGroupBox* pDescGroup = new IconedGroupBox(this); |
241 IconedGroupBox* pDescGroup = new IconedGroupBox(this); |
236 pDescGroup->setIcon(QIcon(":/res/graphicsicon.png")); |
242 pDescGroup->setIcon(QIcon(":/res/graphicsicon.png")); |
237 pDescGroup->setTitle(QGroupBox::tr("Description")); |
243 pDescGroup->setTitle(QGroupBox::tr("Description")); |
238 |
244 |
241 QHBoxLayout* pBottomDescLayout = new QHBoxLayout(0); // buttons |
247 QHBoxLayout* pBottomDescLayout = new QHBoxLayout(0); // buttons |
242 |
248 |
243 // label with thumbnail picture |
249 // label with thumbnail picture |
244 labelThumbnail = new QLabel(pDescGroup); |
250 labelThumbnail = new QLabel(pDescGroup); |
245 labelThumbnail->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); |
251 labelThumbnail->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); |
|
252 labelThumbnail->setMaximumSize(ThumbnailSize); |
246 labelThumbnail->setStyleSheet( |
253 labelThumbnail->setStyleSheet( |
247 "QFrame {" |
254 "QFrame {" |
248 "border: solid;" |
255 "border: solid;" |
249 "border-width: 3px;" |
256 "border-width: 3px;" |
250 "border-color: #ffcc00;" |
257 "border-color: #ffcc00;" |
251 "border-radius: 4px;" |
258 "border-radius: 4px;" |
252 "}" ); |
259 "}" ); |
253 pTopDescLayout->addWidget(labelThumbnail); |
260 clearThumbnail(); |
|
261 pTopDescLayout->addWidget(labelThumbnail, 2); |
254 |
262 |
255 // label with file description |
263 // label with file description |
256 labelDesc = new QLabel(pDescGroup); |
264 labelDesc = new QLabel(pDescGroup); |
257 labelDesc->setAlignment(Qt::AlignLeft | Qt::AlignTop); |
265 labelDesc->setAlignment(Qt::AlignLeft | Qt::AlignTop); |
258 pTopDescLayout->addWidget(labelDesc); |
266 pTopDescLayout->addWidget(labelDesc, 1); |
259 |
267 |
260 // buttons: play and delete |
268 // buttons: play and delete |
261 btnPlay = new QPushButton(QPushButton::tr("Play"), pDescGroup); |
269 btnPlay = new QPushButton(QPushButton::tr("Play"), pDescGroup); |
|
270 btnPlay->setEnabled(false); |
262 pBottomDescLayout->addWidget(btnPlay); |
271 pBottomDescLayout->addWidget(btnPlay); |
263 btnDelete = new QPushButton(QPushButton::tr("Delete"), pDescGroup); |
272 btnDelete = new QPushButton(QPushButton::tr("Delete"), pDescGroup); |
|
273 btnDelete->setEnabled(false); |
264 pBottomDescLayout->addWidget(btnDelete); |
274 pBottomDescLayout->addWidget(btnDelete); |
265 |
275 |
266 pDescLayout->addStretch(1); |
276 pDescLayout->addStretch(1); |
267 pDescLayout->addLayout(pTopDescLayout, 0); |
277 pDescLayout->addLayout(pTopDescLayout, 0); |
268 pDescLayout->addStretch(1); |
278 pDescLayout->addStretch(1); |
571 |
581 |
572 // user has edited filename, so we should rename the file |
582 // user has edited filename, so we should rename the file |
573 VideoItem * item = nameItem(row); |
583 VideoItem * item = nameItem(row); |
574 QString oldName = item->name; |
584 QString oldName = item->name; |
575 QString newName = item->text(); |
585 QString newName = item->text(); |
576 if (!newName.contains('.')) |
586 if (!newName.contains('.')) // user forgot an extension |
577 { |
587 { |
578 // user forgot an extension |
|
579 int pt = oldName.lastIndexOf('.'); |
588 int pt = oldName.lastIndexOf('.'); |
580 if (pt != -1) |
589 if (pt != -1) |
|
590 { |
581 newName += oldName.right(oldName.length() - pt); |
591 newName += oldName.right(oldName.length() - pt); |
|
592 setName(item, newName); |
|
593 } |
|
594 } |
|
595 #ifdef Q_WS_WIN |
|
596 // there is a bug in qt, QDir::rename() doesn't fail on such names but damages files |
|
597 if (newName.contains(QRegExp("[\"*:<>?\/|]"))) |
|
598 { |
|
599 setName(item, oldName); |
|
600 return; |
|
601 } |
|
602 #endif |
|
603 if (item->ready() && !cfgdir->rename("Videos/" + oldName, "Videos/" + newName)) |
|
604 { |
|
605 // unable to rename for some reason (maybe user entered incorrect name), |
|
606 // therefore restore old name in cell |
|
607 setName(item, oldName); |
|
608 return; |
582 } |
609 } |
583 item->name = newName; |
610 item->name = newName; |
584 if (item->ready()) |
|
585 { |
|
586 if(cfgdir->rename("Videos/" + oldName, "Videos/" + newName)) |
|
587 updateDescription(); |
|
588 else |
|
589 { |
|
590 // unable to rename for some reason (maybe user entered incorrect name), |
|
591 // therefore restore old name in cell |
|
592 setName(item, oldName); |
|
593 } |
|
594 } |
|
595 updateDescription(); |
611 updateDescription(); |
596 } |
612 } |
597 |
613 |
598 void PageVideos::setName(VideoItem * item, const QString & newName) |
614 void PageVideos::setName(VideoItem * item, const QString & newName) |
599 { |
615 { |
632 VideoItem* PageVideos::nameItem(int row) |
648 VideoItem* PageVideos::nameItem(int row) |
633 { |
649 { |
634 return (VideoItem*)filesTable->item(row, vcName); |
650 return (VideoItem*)filesTable->item(row, vcName); |
635 } |
651 } |
636 |
652 |
|
653 void PageVideos::clearThumbnail() |
|
654 { |
|
655 // add empty image for proper sizing |
|
656 QPixmap pic(ThumbnailSize); |
|
657 pic.fill(QColor(0,0,0,0)); |
|
658 labelThumbnail->setPixmap(pic); |
|
659 } |
|
660 |
637 void PageVideos::updateDescription() |
661 void PageVideos::updateDescription() |
638 { |
662 { |
639 VideoItem * item = nameItem(filesTable->currentRow()); |
663 VideoItem * item = nameItem(filesTable->currentRow()); |
640 if (!item) |
664 if (!item) |
641 { |
665 { |
642 labelDesc->clear(); |
666 labelDesc->clear(); |
643 labelThumbnail->clear(); |
667 clearThumbnail(); |
644 return; |
668 btnPlay->setEnabled(false); |
645 } |
669 btnDelete->setEnabled(false); |
646 |
670 return; |
647 QString desc = ""; |
671 } |
648 desc += item->name + "\n"; |
672 |
649 |
673 btnPlay->setEnabled(item->ready()); |
|
674 btnDelete->setEnabled(true); |
|
675 |
|
676 QString desc = item->name + "\n\n"; |
650 QString thumbName = ""; |
677 QString thumbName = ""; |
651 |
678 |
652 if (item->ready()) |
679 if (item->ready()) |
653 { |
680 { |
654 QString path = item->path(); |
681 QString path = item->path(); |
655 desc += tr("\nSize: ") + FileSizeStr(path) + "\n"; |
682 desc += tr("Date: ") + QFileInfo(path).created().toString(Qt::DefaultLocaleLongDate) + "\n"; |
|
683 desc += tr("Size: ") + FileSizeStr(path) + "\n"; |
656 if (item->desc == "") |
684 if (item->desc == "") |
657 item->desc = LibavIteraction::instance().getFileInfo(path); |
685 item->desc = LibavIteraction::instance().getFileInfo(path); |
658 desc += item->desc; |
686 desc += item->desc; |
659 |
687 |
660 // extract thumbnail name fron description |
688 // extract thumbnail name fron description |
683 } |
711 } |
684 |
712 |
685 if (!thumbName.isEmpty()) |
713 if (!thumbName.isEmpty()) |
686 { |
714 { |
687 thumbName = cfgdir->absoluteFilePath("VideoTemp/" + thumbName); |
715 thumbName = cfgdir->absoluteFilePath("VideoTemp/" + thumbName); |
688 if (picThumbnail.load(thumbName + ".png") || picThumbnail.load(thumbName + ".bmp")) |
716 QPixmap pic; |
|
717 if (pic.load(thumbName + ".png") || pic.load(thumbName + ".bmp")) |
689 { |
718 { |
690 if (picThumbnail.width() > picThumbnail.height()) |
719 if (pic.height()*ThumbnailSize.width() > pic.width()*ThumbnailSize.height()) |
691 picThumbnail = picThumbnail.scaledToWidth(ThumbnailSize); |
720 pic = pic.scaledToWidth(ThumbnailSize.width()); |
692 else |
721 else |
693 picThumbnail = picThumbnail.scaledToHeight(ThumbnailSize); |
722 pic = pic.scaledToHeight(ThumbnailSize.height()); |
694 labelThumbnail->setMaximumSize(picThumbnail.size()); |
723 labelThumbnail->setPixmap(pic); |
695 labelThumbnail->setPixmap(picThumbnail); |
|
696 } |
724 } |
697 else |
725 else |
698 labelThumbnail->clear(); |
726 clearThumbnail(); |
699 } |
727 } |
700 labelDesc->setText(desc); |
728 labelDesc->setText(desc); |
701 } |
729 } |
702 |
730 |
703 // user selected another cell, so we should change description |
731 // user selected another cell, so we should change description |
709 // open video file in external media player |
737 // open video file in external media player |
710 void PageVideos::play(int row) |
738 void PageVideos::play(int row) |
711 { |
739 { |
712 VideoItem * item = nameItem(row); |
740 VideoItem * item = nameItem(row); |
713 if (item->ready()) |
741 if (item->ready()) |
714 QDesktopServices::openUrl(QUrl("file:///" + item->path())); |
742 QDesktopServices::openUrl(QUrl("file:///" + QDir::toNativeSeparators(item->path()))); |
715 } |
743 } |
716 |
744 |
717 void PageVideos::playSelectedFile() |
745 void PageVideos::playSelectedFile() |
718 { |
746 { |
719 int index = filesTable->currentRow(); |
747 int index = filesTable->currentRow(); |
767 AbstractPage::keyPressEvent(pEvent); |
795 AbstractPage::keyPressEvent(pEvent); |
768 } |
796 } |
769 |
797 |
770 void PageVideos::openVideosDirectory() |
798 void PageVideos::openVideosDirectory() |
771 { |
799 { |
772 QDesktopServices::openUrl(QUrl("file:///"+cfgdir->absolutePath() + "/Videos")); |
800 QString path = QDir::toNativeSeparators(cfgdir->absolutePath() + "/Videos"); |
|
801 QDesktopServices::openUrl(QUrl("file:///" + path)); |
|
802 } |
|
803 |
|
804 // clear VideoTemp directory (except for thumbnails) |
|
805 void PageVideos::clearTemp() |
|
806 { |
|
807 QDir temp(cfgdir->absolutePath() + "/VideoTemp"); |
|
808 QStringList files = temp.entryList(QDir::Files); |
|
809 foreach (const QString& file, files) |
|
810 { |
|
811 if (!file.endsWith(".bmp") && !file.endsWith(".png")) |
|
812 temp.remove(file); |
|
813 } |
773 } |
814 } |
774 |
815 |
775 bool PageVideos::tryQuit(HWForm * form) |
816 bool PageVideos::tryQuit(HWForm * form) |
776 { |
817 { |
777 if (numRecorders == 0) |
818 bool quit = true; |
778 return true; |
819 if (numRecorders != 0) |
779 |
820 { |
780 // ask user what to do - abort or wait |
821 // ask user what to do - abort or wait |
781 HWAskQuitDialog * askd = new HWAskQuitDialog(this, form); |
822 HWAskQuitDialog * askd = new HWAskQuitDialog(this, form); |
782 bool answer = askd->exec(); |
823 quit = askd->exec(); |
783 delete askd; |
824 delete askd; |
784 return answer; |
825 } |
|
826 if (quit) |
|
827 clearTemp(); |
|
828 return quit; |
785 } |
829 } |
786 |
830 |
787 // returns multi-line string with list of videos in progress |
831 // returns multi-line string with list of videos in progress |
788 QString PageVideos::getVideosInProgress() |
832 QString PageVideos::getVideosInProgress() |
789 { |
833 { |