QTfrontend/ui/page/pagevideos.cpp
changeset 7386 e82a076df09b
parent 7353 0e55228e1303
child 7392 bc3306c59a08
equal deleted inserted replaced
7383:8f675ab05802 7386:e82a076df09b
    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 {