QTfrontend/ui/page/pagevideos.cpp
branchui-scaling
changeset 15283 c4fd2813b127
parent 15250 8dd3602a4500
equal deleted inserted replaced
13390:0135e64c6c66 15283:c4fd2813b127
    46 #include "igbox.h"
    46 #include "igbox.h"
    47 #include "LibavInteraction.h"
    47 #include "LibavInteraction.h"
    48 #include "gameuiconfig.h"
    48 #include "gameuiconfig.h"
    49 #include "recorder.h"
    49 #include "recorder.h"
    50 #include "ask_quit.h"
    50 #include "ask_quit.h"
       
    51 #include "util/MessageDialog.h"
    51 
    52 
    52 static const QSize ThumbnailSize(350, 350*3/5);
    53 static const QSize ThumbnailSize(350, 350*3/5);
    53 
    54 
    54 // columns in table with list of video files
    55 // columns in table with list of video files
    55 enum VideosColumns
    56 enum VideosColumns
   120         filesTable->setColumnCount(vcNumColumns);
   121         filesTable->setColumnCount(vcNumColumns);
   121         filesTable->setHorizontalHeaderLabels(columns);
   122         filesTable->setHorizontalHeaderLabels(columns);
   122         filesTable->setSelectionBehavior(QAbstractItemView::SelectRows);
   123         filesTable->setSelectionBehavior(QAbstractItemView::SelectRows);
   123         filesTable->setSelectionMode(QAbstractItemView::SingleSelection);
   124         filesTable->setSelectionMode(QAbstractItemView::SingleSelection);
   124         filesTable->setEditTriggers(QAbstractItemView::SelectedClicked);
   125         filesTable->setEditTriggers(QAbstractItemView::SelectedClicked);
       
   126         filesTable->setShowGrid(false);
       
   127         filesTable->setAlternatingRowColors(true);
   125         filesTable->verticalHeader()->hide();
   128         filesTable->verticalHeader()->hide();
   126         filesTable->setMinimumWidth(400);
   129         filesTable->setMinimumWidth(400);
   127 
   130 
   128         QHeaderView * header = filesTable->horizontalHeader();
   131         QHeaderView * header = new QHeaderView(Qt::Horizontal, filesTable);
       
   132         filesTable->setHorizontalHeader(header);
       
   133         header = filesTable->horizontalHeader();
       
   134         header->setStretchLastSection(true);
       
   135         header->setSectionsClickable(false);
   129         header->setSectionResizeMode(vcName, QHeaderView::ResizeToContents);
   136         header->setSectionResizeMode(vcName, QHeaderView::ResizeToContents);
   130         header->setSectionResizeMode(vcSize, QHeaderView::Fixed);
   137         header->setSectionResizeMode(vcSize, QHeaderView::Fixed);
   131         header->resizeSection(vcSize, 100);
   138         header->resizeSection(vcSize, 100);
   132         header->setStretchLastSection(true);
       
   133 
   139 
   134         btnOpenDir = new QPushButton(QPushButton::tr("Open videos directory"), pTableGroup);
   140         btnOpenDir = new QPushButton(QPushButton::tr("Open videos directory"), pTableGroup);
   135         btnOpenDir->setWhatsThis(QPushButton::tr("Open the video directory in your system"));
   141         btnOpenDir->setWhatsThis(QPushButton::tr("Open the video directory in your system"));
   136 
   142 
   137         QVBoxLayout *box = new QVBoxLayout(pTableGroup);
   143         QVBoxLayout *box = new QVBoxLayout(pTableGroup);
   168         labelDesc->setAlignment(Qt::AlignLeft | Qt::AlignTop);
   174         labelDesc->setAlignment(Qt::AlignLeft | Qt::AlignTop);
   169         labelDesc->setTextInteractionFlags(Qt::TextSelectableByMouse |
   175         labelDesc->setTextInteractionFlags(Qt::TextSelectableByMouse |
   170                                            Qt::TextSelectableByKeyboard |
   176                                            Qt::TextSelectableByKeyboard |
   171                                            Qt::LinksAccessibleByMouse |
   177                                            Qt::LinksAccessibleByMouse |
   172                                            Qt::LinksAccessibleByKeyboard);
   178                                            Qt::LinksAccessibleByKeyboard);
   173         labelDesc->setTextFormat(Qt::RichText);
   179         labelDesc->setTextFormat(Qt::PlainText);
   174         labelDesc->setWordWrap(true);
   180         labelDesc->setWordWrap(true);
   175         labelDesc->setOpenExternalLinks(true);
   181         labelDesc->setOpenExternalLinks(false);
   176 
   182 
   177         // buttons: play and delete
   183         // buttons: play and delete
   178         btnPlay = new QPushButton(QPushButton::tr("Play"), pDescGroup);
   184         btnPlay = new QPushButton(QPushButton::tr("Play"), pDescGroup);
   179         btnPlay->setEnabled(false);
   185         btnPlay->setEnabled(false);
   180         btnPlay->setWhatsThis(QPushButton::tr("Play this video"));
   186         btnPlay->setWhatsThis(QPushButton::tr("Play this video"));
   213 PageVideos::PageVideos(QWidget* parent) : AbstractPage(parent),
   219 PageVideos::PageVideos(QWidget* parent) : AbstractPage(parent),
   214     config(0)
   220     config(0)
   215 {
   221 {
   216     nameChangedFromCode = false;
   222     nameChangedFromCode = false;
   217     numRecorders = 0;
   223     numRecorders = 0;
       
   224     // Clear VideoTemp at launch in case some garbage remained in here after a crash
       
   225     clearTemp();
   218     initPage();
   226     initPage();
   219 }
   227 }
   220 
   228 
   221 void PageVideos::init(GameUIConfig * config)
   229 void PageVideos::init(GameUIConfig * config)
   222 {
   230 {
   285         if (row == -1)
   293         if (row == -1)
   286             row = appendRow(name);
   294             row = appendRow(name);
   287         VideoItem * item = nameItem(row);
   295         VideoItem * item = nameItem(row);
   288         item->seen = true;
   296         item->seen = true;
   289         item->desc = "";
   297         item->desc = "";
       
   298         setName(item, item->name);
   290         updateSize(row);
   299         updateSize(row);
   291     }
   300     }
   292 
   301 
   293     // remove all non seen files
   302     // remove all non seen files
   294     for (int i = 0; i < filesTable->rowCount();)
   303     for (int i = 0; i < filesTable->rowCount();)
   313     progressBar->setMinimum(0);
   322     progressBar->setMinimum(0);
   314     progressBar->setMaximum(10000);
   323     progressBar->setMaximum(10000);
   315     progressBar->setValue(0);
   324     progressBar->setValue(0);
   316     connect(pRecorder, SIGNAL(onProgress(float)), this, SLOT(updateProgress(float)));
   325     connect(pRecorder, SIGNAL(onProgress(float)), this, SLOT(updateProgress(float)));
   317     connect(pRecorder, SIGNAL(encodingFinished(bool)), this, SLOT(encodingFinished(bool)));
   326     connect(pRecorder, SIGNAL(encodingFinished(bool)), this, SLOT(encodingFinished(bool)));
       
   327     connect(pRecorder, SIGNAL(ErrorMessage(const QString &)), this, SLOT(ShowFatalErrorMessage(const QString &)), Qt::QueuedConnection);
   318     filesTable->setCellWidget(row, vcProgress, progressBar);
   328     filesTable->setCellWidget(row, vcProgress, progressBar);
   319 
   329 
   320     numRecorders++;
   330     numRecorders++;
   321 }
   331 }
   322 
   332 
   393         return;
   403         return;
   394 
   404 
   395     // user has edited filename, so we should rename the file
   405     // user has edited filename, so we should rename the file
   396     VideoItem * item = nameItem(row);
   406     VideoItem * item = nameItem(row);
   397     QString oldName = item->name;
   407     QString oldName = item->name;
       
   408     int pointPos = oldName.lastIndexOf('.');
       
   409     QString oldPrefix = item->name;
       
   410     oldPrefix.truncate(pointPos);
   398     QString newName = item->text();
   411     QString newName = item->text();
   399     if (!newName.contains('.')) // user forgot an extension
   412     if (!newName.contains('.')) // user forgot an extension
   400     {
   413     {
   401         // restore old extension
   414         // restore old extension
   402         int pt = oldName.lastIndexOf('.');
   415         pointPos = oldName.lastIndexOf('.');
   403         if (pt != -1)
   416         if (pointPos != -1)
   404         {
   417         {
   405             newName += oldName.right(oldName.length() - pt);
   418             newName += oldName.right(oldName.length() - pointPos);
   406             setName(item, newName);
   419             setName(item, newName);
       
   420         }
       
   421     }
       
   422     QString newPrefix;
       
   423     if (newName.contains('.'))
       
   424     {
       
   425         pointPos = newName.lastIndexOf('.');
       
   426         if (pointPos != -1)
       
   427         {
       
   428             newPrefix = newName;
       
   429             newPrefix.truncate(pointPos);
       
   430         }
       
   431     }
       
   432     else
       
   433         newPrefix = newName;
       
   434     for (int i = 0; i < filesTable->rowCount(); i++)
       
   435     {
       
   436         // don't allow rename if duplicate prefix
       
   437         VideoItem * iterateItem = nameItem(i);
       
   438         if ((i != row) && (newPrefix == iterateItem->prefix))
       
   439         {
       
   440             setName(item, oldName);
       
   441             return;
   407         }
   442         }
   408     }
   443     }
   409 #ifdef Q_OS_WIN
   444 #ifdef Q_OS_WIN
   410     // there is a bug in qt, QDir::rename() doesn't fail on such names but damages files
   445     // there is a bug in qt, QDir::rename() doesn't fail on such names but damages files
   411     if (newName.contains(QRegExp("[\"*:<>?\\/|]")))
   446     if (newName.contains(QRegExp("[\"*:<>?\\/|]")))
   419         // unable to rename for some reason (maybe user entered incorrect name),
   454         // unable to rename for some reason (maybe user entered incorrect name),
   420         // therefore restore old name in cell
   455         // therefore restore old name in cell
   421         setName(item, oldName);
   456         setName(item, oldName);
   422         return;
   457         return;
   423     }
   458     }
       
   459     if (item->ready())
       
   460     {
       
   461         cfgdir->rename("VideoThumbnails/" + oldPrefix + ".png", "VideoThumbnails/" + newPrefix + ".png");
       
   462         cfgdir->rename("VideoThumbnails/" + oldPrefix + ".bmp", "VideoThumbnails/" + newPrefix + ".bmp");
       
   463     }
   424     item->name = newName;
   464     item->name = newName;
       
   465     item->prefix = newPrefix;
   425     updateDescription();
   466     updateDescription();
   426 }
   467 }
   427 
   468 
   428 void PageVideos::setName(VideoItem * item, const QString & newName)
   469 void PageVideos::setName(VideoItem * item, const QString & newName)
   429 {
   470 {
   430     nameChangedFromCode = true;
   471     nameChangedFromCode = true;
   431     item->setText(newName);
   472     item->setText(newName);
   432     nameChangedFromCode = false;
   473     nameChangedFromCode = false;
   433     item->name = newName;
   474     item->name = newName;
       
   475     // try to extract prefix
       
   476     if (item->ready())
       
   477         item->prefix = item->name;
       
   478     else
       
   479         item->prefix = item->pRecorder->name;
       
   480     // remove extension
       
   481     int pt = item->prefix.lastIndexOf('.');
       
   482     if (pt != -1)
       
   483         item->prefix.truncate(pt);
   434 }
   484 }
   435 
   485 
   436 int PageVideos::appendRow(const QString & name)
   486 int PageVideos::appendRow(const QString & name)
   437 {
   487 {
   438     int row = filesTable->rowCount();
   488     int row = filesTable->rowCount();
   515             }
   565             }
   516         }
   566         }
   517         desc += item->desc + '\n';
   567         desc += item->desc + '\n';
   518     }
   568     }
   519 
   569 
   520     if (item->prefix.isEmpty())
   570     if (item->prefix.isNull() || item->prefix.isEmpty())
   521     {
   571     {
   522         // try to extract prefix from file name instead
   572         // try to extract prefix from file name instead
   523         if (item->ready())
   573         if (item->ready())
   524             item->prefix = item->name;
   574             item->prefix = item->name;
   525         else
   575         else
   529         int pt = item->prefix.lastIndexOf('.');
   579         int pt = item->prefix.lastIndexOf('.');
   530         if (pt != -1)
   580         if (pt != -1)
   531             item->prefix.truncate(pt);
   581             item->prefix.truncate(pt);
   532     }
   582     }
   533 
   583 
   534     desc.replace("\n", "<br/>");
       
   535 
       
   536     labelDesc->setText(desc);
   584     labelDesc->setText(desc);
   537 
   585 
   538     if (!item->prefix.isEmpty())
   586     if (!item->prefix.isEmpty())
   539     {
   587     {
   540         QString thumbName = cfgdir->absoluteFilePath("VideoTemp/" + item->prefix);
   588         QString thumbName = cfgdir->absoluteFilePath("VideoThumbnails/" + item->prefix);
   541         QPixmap pic;
   589         QPixmap pic;
   542         if (pic.load(thumbName + ".png") || pic.load(thumbName + ".bmp"))
   590         if (pic.load(thumbName + ".png") || pic.load(thumbName + ".bmp"))
   543         {
   591         {
   544             if (pic.height()*ThumbnailSize.width() > pic.width()*ThumbnailSize.height())
   592             if (pic.height()*ThumbnailSize.width() > pic.width()*ThumbnailSize.height())
   545                 pic = pic.scaledToWidth(ThumbnailSize.width());
   593                 pic = pic.scaledToWidth(ThumbnailSize.width());
   586     // ask user if (s)he is serious
   634     // ask user if (s)he is serious
   587     QMessageBox reallyDeleteMsg(this);
   635     QMessageBox reallyDeleteMsg(this);
   588     reallyDeleteMsg.setIcon(QMessageBox::Question);
   636     reallyDeleteMsg.setIcon(QMessageBox::Question);
   589     reallyDeleteMsg.setWindowTitle(QMessageBox::tr("Videos - Are you sure?"));
   637     reallyDeleteMsg.setWindowTitle(QMessageBox::tr("Videos - Are you sure?"));
   590     reallyDeleteMsg.setText(QMessageBox::tr("Do you really want to delete the video '%1'?").arg(item->name));
   638     reallyDeleteMsg.setText(QMessageBox::tr("Do you really want to delete the video '%1'?").arg(item->name));
       
   639     reallyDeleteMsg.setTextFormat(Qt::PlainText);
   591     reallyDeleteMsg.setWindowModality(Qt::WindowModal);
   640     reallyDeleteMsg.setWindowModality(Qt::WindowModal);
   592     reallyDeleteMsg.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
   641     reallyDeleteMsg.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
   593 
   642 
   594     if (reallyDeleteMsg.exec() != QMessageBox::Ok)
   643     if (reallyDeleteMsg.exec() != QMessageBox::Ok)
   595         return;
   644         return;
   596 
   645 
   597     // remove
   646     // abort / remove
   598     if (!item->ready())
   647     if (!item->ready())
   599         item->pRecorder->deleteLater();
   648         item->pRecorder->abort();
   600     else
   649     else
   601     {
   650     {
   602         cfgdir->remove("Videos/" + item->name);
   651         cfgdir->remove("Videos/" + item->name);
   603         // we have no idea whether screenshot is going to be bmp or png so let's delete both
   652         // we have no idea whether screenshot is going to be bmp or png so let's delete both
   604         cfgdir->remove("VideoTemp/" + item->prefix + ".png");
   653         cfgdir->remove("VideoThumbnails/" + item->prefix + ".png");
   605         cfgdir->remove("VideoTemp/" + item->prefix + ".bmp");
   654         cfgdir->remove("VideoThumbnails/" + item->prefix + ".bmp");
   606     }
   655     }
   607 
   656 
   608 // this code is for removing several files when multiple selection is enabled
   657 // this code is for removing several files when multiple selection is enabled
   609 #if 0
   658 #if 0
   610     QList<QTableWidgetItem*> items = filesTable->selectedItems();
   659     QList<QTableWidgetItem*> items = filesTable->selectedItems();
   659 {
   708 {
   660     QString path = QDir::toNativeSeparators(cfgdir->absolutePath() + "/Videos");
   709     QString path = QDir::toNativeSeparators(cfgdir->absolutePath() + "/Videos");
   661     QDesktopServices::openUrl(QUrl("file:///" + path));
   710     QDesktopServices::openUrl(QUrl("file:///" + path));
   662 }
   711 }
   663 
   712 
   664 // clear VideoTemp directory (except for thumbnails)
   713 // clear VideoTemp directory
   665 void PageVideos::clearTemp()
   714 void PageVideos::clearTemp()
   666 {
   715 {
       
   716     qDebug("Clearing VideoTemp directory ...");
   667     QDir temp(cfgdir->absolutePath() + "/VideoTemp");
   717     QDir temp(cfgdir->absolutePath() + "/VideoTemp");
   668     QStringList files = temp.entryList(QDir::Files);
   718     QStringList files = temp.entryList(QDir::Files);
   669     foreach (const QString& file, files)
   719     foreach (const QString& file, files)
   670     {
   720     {
   671         if (!file.endsWith(".bmp") && !file.endsWith(".png"))
   721         // Legacy support: Move thumbnails to correct dir
       
   722         if (file.endsWith(".bmp") || file.endsWith(".png"))
       
   723         {
       
   724             qDebug("Moving video thumbnail '%s' to VideoThumbnails directory", qPrintable(file));
       
   725             cfgdir->rename("VideoTemp/" + file, "VideoThumbnails/" + file);
       
   726         }
       
   727         else
   672             temp.remove(file);
   728             temp.remove(file);
   673     }
   729     }
   674 }
   730 }
   675 
   731 
   676 bool PageVideos::tryQuit(HWForm * form)
   732 bool PageVideos::tryQuit(HWForm * form)
   742         }
   798         }
   743         addRecorder(pRecorder);
   799         addRecorder(pRecorder);
   744     }
   800     }
   745 }
   801 }
   746 
   802 
       
   803 void PageVideos::ShowFatalErrorMessage(const QString & msg)
       
   804 {
       
   805     MessageDialog::ShowFatalMessage(msg, this);
       
   806 }
       
   807