QTfrontend/ui/page/pagevideos.cpp
changeset 7280 fd707afbc3a2
parent 7235 baa69bd025d9
child 7306 3cff5c769509
equal deleted inserted replaced
7278:000e4543f204 7280:fd707afbc3a2
    23 #include <QCheckBox>
    23 #include <QCheckBox>
    24 #include <QLabel>
    24 #include <QLabel>
    25 #include <QLineEdit>
    25 #include <QLineEdit>
    26 #include <QSpinBox>
    26 #include <QSpinBox>
    27 #include <QTableWidget>
    27 #include <QTableWidget>
    28 
    28 #include <QDir>
       
    29 #include <QProgressBar>
       
    30 #include <QStringList>
       
    31 #include <QDesktopServices>
       
    32 #include <QUrl>
       
    33 #include <QList>
       
    34 #include <QMessageBox>
       
    35 #include <QHeaderView>
       
    36 #include <QKeyEvent>
       
    37 #include <QVBoxLayout>
       
    38 #include <QFileSystemWatcher>
       
    39 
       
    40 #include "hwconsts.h"
    29 #include "pagevideos.h"
    41 #include "pagevideos.h"
    30 #include "igbox.h"
    42 #include "igbox.h"
    31 #include "libav_iteraction.h"
    43 #include "libav_iteraction.h"
    32 #include "gameuiconfig.h"
    44 #include "gameuiconfig.h"
       
    45 #include "recorder.h"
       
    46 
       
    47 // columns in table with list of video files
       
    48 enum VideosColumns
       
    49 {
       
    50     vcName,
       
    51     vcSize,
       
    52     vcProgress,
       
    53 
       
    54     vcNumColumns,
       
    55 };
       
    56 
       
    57 class VideoItem : public QTableWidgetItem
       
    58 {
       
    59     // note: QTableWidgetItem is not Q_OBJECT
       
    60 
       
    61     public:
       
    62         VideoItem(const QString& name);
       
    63         ~VideoItem();
       
    64 
       
    65         QString name;
       
    66         QString desc; // description
       
    67         HWRecorder * pRecorder; // non NULL if file is being encoded
       
    68         bool seen; // used when updating directory
       
    69         float lastSizeUpdate;
       
    70 
       
    71         bool ready()
       
    72         { return !pRecorder; }
       
    73 
       
    74         QString path()
       
    75         { return cfgdir->absoluteFilePath("Videos/" + name);  }
       
    76 };
       
    77 
       
    78 VideoItem::VideoItem(const QString& name)
       
    79     : QTableWidgetItem(name, UserType)
       
    80 {
       
    81     this->name = name;
       
    82     pRecorder = NULL;
       
    83     lastSizeUpdate = 0;
       
    84 }
       
    85 
       
    86 VideoItem::~VideoItem()
       
    87 {}
    33 
    88 
    34 QLayout * PageVideos::bodyLayoutDefinition()
    89 QLayout * PageVideos::bodyLayoutDefinition()
    35 {
    90 {
    36     QGridLayout * pageLayout = new QGridLayout();
    91     QGridLayout * pPageLayout = new QGridLayout();
    37     pageLayout->setColumnStretch(0, 1);
    92     pPageLayout->setColumnStretch(0, 1);
    38     pageLayout->setColumnStretch(1, 1);
    93     pPageLayout->setColumnStretch(1, 1);
    39 
    94 
    40     {
    95     {
    41         IconedGroupBox* groupRec = new IconedGroupBox(this);
    96         IconedGroupBox* pOptionsGroup = new IconedGroupBox(this);
    42         groupRec->setIcon(QIcon(":/res/graphicsicon.png"));
    97         pOptionsGroup->setIcon(QIcon(":/res/graphicsicon.png"));
    43         groupRec->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    98         pOptionsGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    44         groupRec->setTitle(QGroupBox::tr("Video recording options"));
    99         pOptionsGroup->setTitle(QGroupBox::tr("Video recording options"));
    45         QGridLayout * RecLayout = new QGridLayout(groupRec);
   100         QGridLayout * pOptLayout = new QGridLayout(pOptionsGroup);
    46 
   101 
    47         // Label for format
   102         // label for format
    48         QLabel *labelFormat = new QLabel(groupRec);
   103         QLabel *labelFormat = new QLabel(pOptionsGroup);
    49         labelFormat->setText(QLabel::tr("Format"));
   104         labelFormat->setText(QLabel::tr("Format"));
    50         RecLayout->addWidget(labelFormat, 0, 0);
   105         pOptLayout->addWidget(labelFormat, 0, 0);
    51 
   106 
    52         // List of supported formats
   107         // list of supported formats
    53         CBAVFormats = new QComboBox(groupRec);
   108         comboAVFormats = new QComboBox(pOptionsGroup);
    54         RecLayout->addWidget(CBAVFormats, 0, 1, 1, 4);
   109         pOptLayout->addWidget(comboAVFormats, 0, 1, 1, 4);
    55         LibavIteraction::instance().FillFormats(CBAVFormats);
   110         LibavIteraction::instance().fillFormats(comboAVFormats);
    56 
   111 
    57         QFrame * hr = new QFrame(groupRec);
   112         // separator
       
   113         QFrame * hr = new QFrame(pOptionsGroup);
    58         hr->setFrameStyle(QFrame::HLine);
   114         hr->setFrameStyle(QFrame::HLine);
    59         hr->setLineWidth(3);
   115         hr->setLineWidth(3);
    60         hr->setFixedHeight(10);
   116         hr->setFixedHeight(10);
    61         RecLayout->addWidget(hr, 1, 0, 1, 5);
   117         pOptLayout->addWidget(hr, 1, 0, 1, 5);
    62 
   118 
    63         // Label for audio codec
   119         // label for audio codec
    64         QLabel *labelACodec = new QLabel(groupRec);
   120         QLabel *labelACodec = new QLabel(pOptionsGroup);
    65         labelACodec->setText(QLabel::tr("Audio codec"));
   121         labelACodec->setText(QLabel::tr("Audio codec"));
    66         RecLayout->addWidget(labelACodec, 2, 0);
   122         pOptLayout->addWidget(labelACodec, 2, 0);
    67 
   123 
    68         // List of supported audio codecs
   124         // list of supported audio codecs
    69         CBAudioCodecs = new QComboBox(groupRec);
   125         comboAudioCodecs = new QComboBox(pOptionsGroup);
    70         RecLayout->addWidget(CBAudioCodecs, 2, 1, 1, 3);
   126         pOptLayout->addWidget(comboAudioCodecs, 2, 1, 1, 3);
    71 
   127 
    72         // record audio
   128         // checkbox 'record audio'
    73         CBRecordAudio = new QCheckBox(groupRec);
   129         checkRecordAudio = new QCheckBox(pOptionsGroup);
    74         CBRecordAudio->setText(QCheckBox::tr("Record audio"));
   130         checkRecordAudio->setText(QCheckBox::tr("Record audio"));
    75         RecLayout->addWidget(CBRecordAudio, 2, 4);
   131         pOptLayout->addWidget(checkRecordAudio, 2, 4);
    76 
   132 
    77         hr = new QFrame(groupRec);
   133         // separator
       
   134         hr = new QFrame(pOptionsGroup);
    78         hr->setFrameStyle(QFrame::HLine);
   135         hr->setFrameStyle(QFrame::HLine);
    79         hr->setLineWidth(3);
   136         hr->setLineWidth(3);
    80         hr->setFixedHeight(10);
   137         hr->setFixedHeight(10);
    81         RecLayout->addWidget(hr, 3, 0, 1, 5);
   138         pOptLayout->addWidget(hr, 3, 0, 1, 5);
    82 
   139 
    83         // Label for video codec
   140         // label for video codec
    84         QLabel *labelVCodec = new QLabel(groupRec);
   141         QLabel *labelVCodec = new QLabel(pOptionsGroup);
    85         labelVCodec->setText(QLabel::tr("Video codec"));
   142         labelVCodec->setText(QLabel::tr("Video codec"));
    86         RecLayout->addWidget(labelVCodec, 4, 0);
   143         pOptLayout->addWidget(labelVCodec, 4, 0);
    87 
   144 
    88         // List of supported video codecs
   145         // list of supported video codecs
    89         CBVideoCodecs = new QComboBox(groupRec);
   146         comboVideoCodecs = new QComboBox(pOptionsGroup);
    90         RecLayout->addWidget(CBVideoCodecs, 4, 1, 1, 4);
   147         pOptLayout->addWidget(comboVideoCodecs, 4, 1, 1, 4);
    91 
   148 
    92         // Label for resolution
   149         // label for resolution
    93         QLabel *labelRes = new QLabel(groupRec);
   150         QLabel *labelRes = new QLabel(pOptionsGroup);
    94         labelRes->setText(QLabel::tr("Resolution"));
   151         labelRes->setText(QLabel::tr("Resolution"));
    95         RecLayout->addWidget(labelRes, 5, 0);
   152         pOptLayout->addWidget(labelRes, 5, 0);
    96 
   153 
    97         // width
   154         // width
    98         widthEdit = new QLineEdit(groupRec);
   155         widthEdit = new QLineEdit(pOptionsGroup);
    99         widthEdit->setValidator(new QIntValidator(this));
   156         widthEdit->setValidator(new QIntValidator(this));
   100         RecLayout->addWidget(widthEdit, 5, 1);
   157         pOptLayout->addWidget(widthEdit, 5, 1);
   101 
   158 
   102         // x
   159         // x
   103         QLabel *labelX = new QLabel(groupRec);
   160         QLabel *labelX = new QLabel(pOptionsGroup);
   104         labelX->setText("X");
   161         labelX->setText("X");
   105         RecLayout->addWidget(labelX, 5, 2);
   162         pOptLayout->addWidget(labelX, 5, 2);
   106 
   163 
   107         // height
   164         // height
   108         heightEdit = new QLineEdit(groupRec);
   165         heightEdit = new QLineEdit(pOptionsGroup);
   109         heightEdit->setValidator(new QIntValidator(groupRec));
   166         heightEdit->setValidator(new QIntValidator(pOptionsGroup));
   110         RecLayout->addWidget(heightEdit, 5, 3);
   167         pOptLayout->addWidget(heightEdit, 5, 3);
   111 
   168 
   112         // use game res
   169         // checkbox 'use game resolution'
   113         CBUseGameRes = new QCheckBox(groupRec);
   170         checkUseGameRes = new QCheckBox(pOptionsGroup);
   114         CBUseGameRes->setText(QCheckBox::tr("Use game resolution"));
   171         checkUseGameRes->setText(QCheckBox::tr("Use game resolution"));
   115         RecLayout->addWidget(CBUseGameRes, 5, 4);
   172         pOptLayout->addWidget(checkUseGameRes, 5, 4);
   116 
   173 
   117         // Label for framerate
   174         // label for framerate
   118         QLabel *labelFramerate = new QLabel(groupRec);
   175         QLabel *labelFramerate = new QLabel(pOptionsGroup);
   119         labelFramerate->setText(QLabel::tr("Framerate"));
   176         labelFramerate->setText(QLabel::tr("Framerate"));
   120         RecLayout->addWidget(labelFramerate, 6, 0);
   177         pOptLayout->addWidget(labelFramerate, 6, 0);
   121 
   178 
   122         // framerate
   179         // framerate
   123         framerateBox = new QSpinBox(groupRec);
   180         framerateBox = new QSpinBox(pOptionsGroup);
   124         framerateBox->setRange(1, 200);
   181         framerateBox->setRange(1, 200);
   125         framerateBox->setSingleStep(1);
   182         framerateBox->setSingleStep(1);
   126         RecLayout->addWidget(framerateBox, 6, 1);
   183         pOptLayout->addWidget(framerateBox, 6, 1);
   127 
   184 
   128         BtnDefaults = new QPushButton(groupRec);
   185         // button 'set default options'
   129         BtnDefaults->setText(QPushButton::tr("Set default options"));
   186         btnDefaults = new QPushButton(pOptionsGroup);
   130         RecLayout->addWidget(BtnDefaults, 7, 0, 1, 5);
   187         btnDefaults->setText(QPushButton::tr("Set default options"));
   131 
   188         pOptLayout->addWidget(btnDefaults, 7, 0, 1, 5);
   132         pageLayout->addWidget(groupRec, 0, 0);
   189 
   133     }
   190         pPageLayout->addWidget(pOptionsGroup, 1, 0);
   134 
   191     }
   135     {
   192 
   136         IconedGroupBox* groupTable = new IconedGroupBox(this);
   193     {
   137         //groupRec->setContentTopPadding(0);
   194         IconedGroupBox* pTableGroup = new IconedGroupBox(this);
   138         groupTable->setIcon(QIcon(":/res/graphicsicon.png"));
   195         pTableGroup->setIcon(QIcon(":/res/graphicsicon.png"));
   139         groupTable->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
   196         pTableGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
   140         groupTable->setTitle(QGroupBox::tr("Videos"));
   197         pTableGroup->setTitle(QGroupBox::tr("Videos"));
   141 
   198 
   142         QStringList columns;
   199         QStringList columns;
   143         columns << tr("Name") << tr("Lenght") << tr("...");
   200         columns << tr("Name");
   144 
   201         columns << tr("Size");
   145         filesTable = new QTableWidget(groupTable);
   202         columns << tr("...");
   146         filesTable->setColumnCount(3);
   203 
       
   204         filesTable = new QTableWidget(pTableGroup);
       
   205         filesTable->setColumnCount(vcNumColumns);
   147         filesTable->setHorizontalHeaderLabels(columns);
   206         filesTable->setHorizontalHeaderLabels(columns);
   148         QVBoxLayout *box = new QVBoxLayout(groupTable);
   207         filesTable->setSelectionBehavior(QAbstractItemView::SelectRows);
       
   208         filesTable->setEditTriggers(QAbstractItemView::SelectedClicked);
       
   209         filesTable->verticalHeader()->hide();
       
   210 
       
   211         QHeaderView * header = filesTable->horizontalHeader();
       
   212         int length = header->length(); // FIXME
       
   213         // header->setResizeMode(QHeaderView::ResizeToContents);
       
   214         header->resizeSection(vcName, length/2);
       
   215         header->resizeSection(vcSize, length/4);
       
   216         header->resizeSection(vcProgress, length/4);
       
   217 
       
   218         btnOpenDir = new QPushButton(QPushButton::tr("Open videos directory"), pTableGroup);
       
   219 
       
   220         QVBoxLayout *box = new QVBoxLayout(pTableGroup);
   149         box->addWidget(filesTable);
   221         box->addWidget(filesTable);
   150 
   222         box->addWidget(btnOpenDir);
   151         pageLayout->addWidget(groupTable, 0, 1, 2, 1);
   223 
   152     }
   224         pPageLayout->addWidget(pTableGroup, 0, 1, 2, 1);
   153 
   225     }
   154     return pageLayout;
   226 
       
   227     {
       
   228         IconedGroupBox* pDescGroup = new IconedGroupBox(this);
       
   229         pDescGroup->setIcon(QIcon(":/res/graphicsicon.png"));
       
   230         pDescGroup->setTitle(QGroupBox::tr("Description"));
       
   231         QGridLayout* pDescLayout = new QGridLayout(pDescGroup);
       
   232 
       
   233         labelThumbnail = new QLabel(pDescGroup);
       
   234         pDescLayout->addWidget(labelThumbnail, 0, 0);
       
   235 
       
   236         // label with file description
       
   237         labelDesc = new QLabel(pDescGroup);
       
   238         labelDesc->setAlignment(Qt::AlignLeft | Qt::AlignTop);
       
   239         pDescLayout->addWidget(labelDesc, 0, 1);
       
   240 
       
   241         // buttons: play and delete
       
   242         btnPlay = new QPushButton(QPushButton::tr("Play"), pDescGroup);
       
   243         pDescLayout->addWidget(btnPlay, 1, 0);
       
   244         btnDelete = new QPushButton(QPushButton::tr("Delete"), pDescGroup);
       
   245         pDescLayout->addWidget(btnDelete, 1, 1);
       
   246 
       
   247         pPageLayout->addWidget(pDescGroup, 0, 0);
       
   248     }
       
   249 
       
   250     return pPageLayout;
   155 }
   251 }
   156 
   252 
   157 QLayout * PageVideos::footerLayoutDefinition()
   253 QLayout * PageVideos::footerLayoutDefinition()
   158 {
   254 {
   159     return NULL;
   255     return NULL;
   160 }
   256 }
   161 
   257 
   162 void PageVideos::connectSignals()
   258 void PageVideos::connectSignals()
   163 {
   259 {
   164     connect(CBUseGameRes, SIGNAL(stateChanged(int)), this, SLOT(changeUseGameRes(int)));
   260     connect(checkUseGameRes, SIGNAL(stateChanged(int)), this, SLOT(changeUseGameRes(int)));
   165     connect(CBRecordAudio, SIGNAL(stateChanged(int)), this, SLOT(changeRecordAudio(int)));
   261     connect(checkRecordAudio, SIGNAL(stateChanged(int)), this, SLOT(changeRecordAudio(int)));
   166     connect(CBAVFormats, SIGNAL(currentIndexChanged(int)), this, SLOT(changeAVFormat(int)));
   262     connect(comboAVFormats, SIGNAL(currentIndexChanged(int)), this, SLOT(changeAVFormat(int)));
   167     connect(BtnDefaults, SIGNAL(clicked()), this, SLOT(setDefaultOptions()));
   263     connect(btnDefaults, SIGNAL(clicked()), this, SLOT(setDefaultOptions()));
   168 }
   264     connect(filesTable, SIGNAL(cellDoubleClicked(int, int)), this, SLOT(cellDoubleClicked(int, int)));
   169 
   265     connect(filesTable, SIGNAL(cellChanged(int,int)), this, SLOT(cellChanged(int, int)));
   170 PageVideos::PageVideos(QWidget* parent) : AbstractPage(parent)
   266     connect(filesTable, SIGNAL(currentCellChanged(int,int,int,int)), this, SLOT(currentCellChanged(int,int,int,int)));
   171 {
   267     connect(btnPlay,   SIGNAL(clicked()), this, SLOT(playSelectedFile()));
       
   268     connect(btnDelete, SIGNAL(clicked()), this, SLOT(deleteSelectedFiles()));
       
   269     connect(btnOpenDir, SIGNAL(clicked()), this, SLOT(openVideosDirectory()));
       
   270 
       
   271     QString path = cfgdir->absolutePath() + "/Videos";
       
   272     QFileSystemWatcher * pWatcher = new QFileSystemWatcher(this);
       
   273     pWatcher->addPath(path);
       
   274     connect(pWatcher, SIGNAL(directoryChanged(const QString &)), this, SLOT(updateFileList(const QString &)));
       
   275     updateFileList(path);
       
   276 }
       
   277 
       
   278 PageVideos::PageVideos(QWidget* parent) : AbstractPage(parent),
       
   279     config(0)
       
   280 {
       
   281     nameChangedFromCode = false;
   172     initPage();
   282     initPage();
   173 }
   283 }
   174 
   284 
       
   285 // user changed file format, we need to update list of codecs
   175 void PageVideos::changeAVFormat(int index)
   286 void PageVideos::changeAVFormat(int index)
   176 {
   287 {
   177     QString prevVCodec = getVideoCodec();
   288     // remember selected codecs
   178     QString prevACodec = getAudioCodec();
   289     QString prevVCodec = videoCodec();
   179     CBVideoCodecs->clear();
   290     QString prevACodec = audioCodec();
   180     CBAudioCodecs->clear();
   291 
   181     LibavIteraction::instance().FillCodecs(CBAVFormats->itemData(index), CBVideoCodecs, CBAudioCodecs);
   292     // clear lists of codecs
   182     if (CBAudioCodecs->count() == 0)
   293     comboVideoCodecs->clear();
   183     {
   294     comboAudioCodecs->clear();
   184         CBRecordAudio->setChecked(false);
   295 
   185         CBRecordAudio->setEnabled(false);
   296     // get list of codecs for specified format
       
   297     LibavIteraction::instance().fillCodecs(comboAVFormats->itemData(index).toString(), comboVideoCodecs, comboAudioCodecs);
       
   298 
       
   299     // disable audio if there is no audio codec
       
   300     if (comboAudioCodecs->count() == 0)
       
   301     {
       
   302         checkRecordAudio->setChecked(false);
       
   303         checkRecordAudio->setEnabled(false);
   186     }
   304     }
   187     else
   305     else
   188         CBRecordAudio->setEnabled(true);
   306         checkRecordAudio->setEnabled(true);
   189     int iVCodec = CBVideoCodecs->findData(prevVCodec);
   307 
       
   308     // restore selected codecs if possible
       
   309     int iVCodec = comboVideoCodecs->findData(prevVCodec);
   190     if (iVCodec != -1)
   310     if (iVCodec != -1)
   191         CBVideoCodecs->setCurrentIndex(iVCodec);
   311         comboVideoCodecs->setCurrentIndex(iVCodec);
   192     int iACodec = CBAudioCodecs->findData(prevACodec);
   312     int iACodec = comboAudioCodecs->findData(prevACodec);
   193     if (iACodec != -1)
   313     if (iACodec != -1)
   194         CBAudioCodecs->setCurrentIndex(iACodec);
   314         comboAudioCodecs->setCurrentIndex(iACodec);
   195 }
   315 }
   196 
   316 
       
   317 // user switched checkbox 'use game resolution'
   197 void PageVideos::changeUseGameRes(int state)
   318 void PageVideos::changeUseGameRes(int state)
   198 {
   319 {
   199     if (state && config)
   320     if (state && config)
   200     {
   321     {
       
   322         // set resolution to game resolution
   201         QRect resolution = config->vid_Resolution();
   323         QRect resolution = config->vid_Resolution();
   202         widthEdit->setText(QString::number(resolution.width()));
   324         widthEdit->setText(QString::number(resolution.width()));
   203         heightEdit->setText(QString::number(resolution.height()));
   325         heightEdit->setText(QString::number(resolution.height()));
   204     }
   326     }
   205     widthEdit->setEnabled(!state);
   327     widthEdit->setEnabled(!state);
   206     heightEdit->setEnabled(!state);
   328     heightEdit->setEnabled(!state);
   207 }
   329 }
   208 
   330 
       
   331 // user switched checkbox 'record audio'
   209 void PageVideos::changeRecordAudio(int state)
   332 void PageVideos::changeRecordAudio(int state)
   210 {
   333 {
   211     CBAudioCodecs->setEnabled(!!state);
   334     comboAudioCodecs->setEnabled(!!state);
   212 }
   335 }
   213 
   336 
   214 void PageVideos::setDefaultCodecs()
   337 void PageVideos::setDefaultCodecs()
   215 {
   338 {
   216     if (tryCodecs("mp4", "libx264", "libmp3lame"))
   339     if (tryCodecs("mp4", "libx264", "libmp3lame"))
   217         return;
   340         return;
   218     if (tryCodecs("mp4", "libx264", "ac3_fixed"))
   341     if (tryCodecs("mp4", "libx264", "libfaac"))
       
   342         return;
       
   343     if (tryCodecs("mp4", "libx264", "libvo_aacenc"))
       
   344         return;
       
   345     if (tryCodecs("mp4", "libx264", "aac"))
       
   346         return;
       
   347     if (tryCodecs("mp4", "libx264", "mp2"))
   219         return;
   348         return;
   220     if (tryCodecs("avi", "libxvid", "libmp3lame"))
   349     if (tryCodecs("avi", "libxvid", "libmp3lame"))
   221         return;
   350         return;
   222     if (tryCodecs("avi", "libxvid", "ac3_fixed"))
   351     if (tryCodecs("avi", "libxvid", "ac3_fixed"))
   223         return;
   352         return;
       
   353     if (tryCodecs("avi", "libxvid", "mp2"))
       
   354         return;
   224     if (tryCodecs("avi", "mpeg4", "libmp3lame"))
   355     if (tryCodecs("avi", "mpeg4", "libmp3lame"))
   225         return;
   356         return;
   226     if (tryCodecs("avi", "mpeg4", "ac3_fixed"))
   357     if (tryCodecs("avi", "mpeg4", "ac3_fixed"))
       
   358         return;
       
   359     if (tryCodecs("avi", "mpeg4", "mp2"))
   227         return;
   360         return;
   228 
   361 
   229     // this shouldn't happen, just in case
   362     // this shouldn't happen, just in case
   230     if (tryCodecs("ogg", "libtheora", "libvorbis"))
   363     if (tryCodecs("ogg", "libtheora", "libvorbis"))
   231         return;
   364         return;
   233 }
   366 }
   234 
   367 
   235 void PageVideos::setDefaultOptions()
   368 void PageVideos::setDefaultOptions()
   236 {
   369 {
   237     framerateBox->setValue(25);
   370     framerateBox->setValue(25);
   238     CBRecordAudio->setChecked(true);
   371     checkRecordAudio->setChecked(true);
   239     CBUseGameRes->setChecked(true);
   372     checkUseGameRes->setChecked(true);
   240     setDefaultCodecs();
   373     setDefaultCodecs();
   241 }
   374 }
   242 
   375 
   243 bool PageVideos::tryCodecs(const QString & format, const QString & vcodec, const QString & acodec)
   376 bool PageVideos::tryCodecs(const QString & format, const QString & vcodec, const QString & acodec)
   244 {
   377 {
   245     int iFormat = CBAVFormats->findData(format);
   378     // first we should change format
       
   379     int iFormat = comboAVFormats->findData(format);
   246     if (iFormat == -1)
   380     if (iFormat == -1)
   247         return false;
   381         return false;
   248     CBAVFormats->setCurrentIndex(iFormat);
   382     comboAVFormats->setCurrentIndex(iFormat);
   249 
   383 
   250     int iVCodec = CBVideoCodecs->findData(vcodec);
   384     // try to find video codec
       
   385     int iVCodec = comboVideoCodecs->findData(vcodec);
   251     if (iVCodec == -1)
   386     if (iVCodec == -1)
   252         return false;
   387         return false;
   253     CBVideoCodecs->setCurrentIndex(iVCodec);
   388     comboVideoCodecs->setCurrentIndex(iVCodec);
   254 
   389 
   255     int iACodec = CBAudioCodecs->findData(acodec);
   390     // try to find audio codec
   256     if (iACodec == -1 && CBRecordAudio->isChecked())
   391     int iACodec = comboAudioCodecs->findData(acodec);
       
   392     if (iACodec == -1 && checkRecordAudio->isChecked())
   257         return false;
   393         return false;
   258     if (iACodec != -1)
   394     if (iACodec != -1)
   259         CBAudioCodecs->setCurrentIndex(iACodec);
   395         comboAudioCodecs->setCurrentIndex(iACodec);
   260 
   396 
   261     return true;
   397     return true;
   262 }
   398 }
       
   399 
       
   400 // get file size as string
       
   401 QString FileSizeStr(const QString & path)
       
   402 {
       
   403     quint64 size = QFileInfo(path).size();
       
   404 
       
   405     quint64 KiB = 1024;
       
   406     quint64 MiB = 1024*KiB;
       
   407     quint64 GiB = 1024*MiB;
       
   408     QString sizeStr;
       
   409     if (size >= GiB)
       
   410         return QString("%1 GiB").arg(QString::number(float(size)/GiB, 'f', 2));
       
   411     if (size >= MiB)
       
   412         return QString("%1 MiB").arg(QString::number(float(size)/MiB, 'f', 2));
       
   413      if (size >= KiB)
       
   414         return QString("%1 KiB").arg(QString::number(float(size)/KiB, 'f', 2));
       
   415     return PageVideos::tr("%1 bytes").arg(QString::number(size));
       
   416 }
       
   417 
       
   418 // set file size in file list in specified row
       
   419 void PageVideos::updateSize(int row)
       
   420 {
       
   421     VideoItem * item = nameItem(row);
       
   422     QString path = item->ready()? item->path() : cfgdir->absoluteFilePath("VideoTemp/" + item->pRecorder->name);
       
   423     filesTable->item(row, vcSize)->setText(FileSizeStr(path));
       
   424 }
       
   425 
       
   426 void PageVideos::updateFileList(const QString & path)
       
   427 {
       
   428     // mark all files as non seen
       
   429     int numRows = filesTable->rowCount();
       
   430     for (int i = 0; i < numRows; i++)
       
   431         nameItem(i)->seen = false;
       
   432 
       
   433     QStringList files = QDir(path).entryList(QDir::Files);
       
   434     foreach (const QString & name, files)
       
   435     {
       
   436         int row = -1;
       
   437         foreach (QTableWidgetItem * item, filesTable->findItems(name, Qt::MatchExactly))
       
   438         {
       
   439             if (item->type() != QTableWidgetItem::UserType || !((VideoItem*)item)->ready())
       
   440                 continue;
       
   441             row = item->row();
       
   442             break;
       
   443         }
       
   444         if (row == -1)
       
   445             row = appendRow(name);
       
   446         VideoItem * item = nameItem(row);
       
   447         item->seen = true;
       
   448         item->desc = "";
       
   449         updateSize(row);
       
   450     }
       
   451 
       
   452     // remove all non seen files
       
   453     for (int i = 0; i < filesTable->rowCount();)
       
   454     {
       
   455         VideoItem * item = nameItem(i);
       
   456         if (item->ready() && !item->seen)
       
   457             filesTable->removeRow(i);
       
   458         else
       
   459             i++;
       
   460     }
       
   461 }
       
   462 
       
   463 void PageVideos::addRecorder(HWRecorder* pRecorder)
       
   464 {
       
   465     int row = appendRow(pRecorder->name);
       
   466     VideoItem * item = nameItem(row);
       
   467     item->pRecorder = pRecorder;
       
   468     pRecorder->item = item;
       
   469 
       
   470     // add progress bar
       
   471     QProgressBar * progressBar = new QProgressBar(filesTable);
       
   472     progressBar->setMinimum(0);
       
   473     progressBar->setMaximum(10000);
       
   474     progressBar->setValue(0);
       
   475     connect(pRecorder, SIGNAL(onProgress(float)), this, SLOT(updateProgress(float)));
       
   476     connect(pRecorder, SIGNAL(encodingFinished(bool)), this, SLOT(encodingFinished(bool)));
       
   477     filesTable->setCellWidget(row, vcProgress, progressBar);
       
   478 }
       
   479 
       
   480 void PageVideos::updateProgress(float value)
       
   481 {
       
   482     HWRecorder * pRecorder = (HWRecorder*)sender();
       
   483     VideoItem * item = (VideoItem*)pRecorder->item;
       
   484     int row = filesTable->row(item);
       
   485 
       
   486     // update file size every percent
       
   487     if (value - item->lastSizeUpdate > 0.01)
       
   488     {
       
   489         updateSize(row);
       
   490         item->lastSizeUpdate = value;
       
   491     }
       
   492 
       
   493     // update progress bar
       
   494     QProgressBar * progressBar = (QProgressBar*)filesTable->cellWidget(row, vcProgress);
       
   495     progressBar->setValue(value*10000);
       
   496     progressBar->setFormat(QString("%1%").arg(value*100, 0, 'f', 2));
       
   497 }
       
   498 
       
   499 void PageVideos::encodingFinished(bool success)
       
   500 {
       
   501     HWRecorder * pRecorder = (HWRecorder*)sender();
       
   502     VideoItem * item = (VideoItem*)pRecorder->item;
       
   503     int row = filesTable->row(item);
       
   504 
       
   505     if (success)
       
   506     {
       
   507         // move file to destination
       
   508         success = cfgdir->rename("VideoTemp/" + pRecorder->name, "Videos/" + item->name);
       
   509         if (!success)
       
   510         {
       
   511             // unable to rename for some reason (maybe user entered incorrect name);
       
   512             // try to use temp name instead.
       
   513             success = cfgdir->rename("VideoTemp/" + pRecorder->name, "Videos/" + pRecorder->name);
       
   514             if (success)
       
   515                 setName(item, pRecorder->name);
       
   516         }
       
   517     }
       
   518 
       
   519     if (!success)
       
   520     {
       
   521         filesTable->removeRow(row);
       
   522         return;
       
   523     }
       
   524 
       
   525     filesTable->setCellWidget(row, vcProgress, NULL); // remove progress bar
       
   526     item->pRecorder = NULL;
       
   527     updateSize(row);
       
   528     updateDescription();
       
   529 }
       
   530 
       
   531 void PageVideos::cellDoubleClicked(int row, int column)
       
   532 {
       
   533     play(row);
       
   534 }
       
   535 
       
   536 void PageVideos::cellChanged(int row, int column)
       
   537 {
       
   538     // user can only edit name
       
   539     if (column != vcName || nameChangedFromCode)
       
   540         return;
       
   541 
       
   542     // user has edited filename, so we should rename the file
       
   543     VideoItem * item = nameItem(row);
       
   544     QString oldName = item->name;
       
   545     QString newName = item->text();
       
   546     item->name = newName;
       
   547     if (item->ready())
       
   548     {
       
   549         if(!cfgdir->rename("Videos/" + oldName, "Videos/" + newName))
       
   550         {
       
   551             // unable to rename for some reason (maybe user entered incorrect name),
       
   552             // therefore restore old name in cell
       
   553             setName(item, oldName);
       
   554         }
       
   555     }
       
   556 }
       
   557 
       
   558 void PageVideos::setName(VideoItem * item, const QString & newName)
       
   559 {
       
   560     nameChangedFromCode = true;
       
   561     item->setText(newName);
       
   562     nameChangedFromCode = false;
       
   563     item->name = newName;
       
   564 }
       
   565 
       
   566 int PageVideos::appendRow(const QString & name)
       
   567 {
       
   568     int row = filesTable->rowCount();
       
   569     filesTable->setRowCount(row+1);
       
   570 
       
   571     // add 'name' item
       
   572     QTableWidgetItem * item = new VideoItem(name);
       
   573     item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable);
       
   574     nameChangedFromCode = true;
       
   575     filesTable->setItem(row, vcName, item);
       
   576     nameChangedFromCode = false;
       
   577 
       
   578     // add 'size' item
       
   579     item = new QTableWidgetItem();
       
   580     item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
       
   581     item->setTextAlignment(Qt::AlignRight);
       
   582     filesTable->setItem(row, vcSize, item);
       
   583 
       
   584     // add 'progress' item
       
   585     item = new QTableWidgetItem();
       
   586     item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
       
   587     filesTable->setItem(row, vcProgress, item);
       
   588 
       
   589     return row;
       
   590 }
       
   591 
       
   592 VideoItem* PageVideos::nameItem(int row)
       
   593 {
       
   594     return (VideoItem*)filesTable->item(row, vcName);
       
   595 }
       
   596 
       
   597 void PageVideos::updateDescription()
       
   598 {
       
   599     VideoItem * item = nameItem(filesTable->currentRow());
       
   600     QString desc = "";
       
   601     if (item)
       
   602     {
       
   603         QString t = item->name;
       
   604         desc += item->name + "\n";
       
   605         // t.replace(".mp4", ".bmp");
       
   606         // QMessageBox::information(this, "1", cfgdir->absoluteFilePath("Screenshots/" + t));
       
   607        //  m_pic.load(cfgdir->absoluteFilePath("Screenshots/" + t));
       
   608        //  m_pic = m_pic.scaledToWidth(400);
       
   609         // m_thumbnail.setPixmap(m_pic);
       
   610 
       
   611         if (item->ready())
       
   612         {
       
   613             QString path = item->path();
       
   614             desc += tr("\nSize: ") + FileSizeStr(path) + "\n";
       
   615             if (item->desc == "")
       
   616                 item->desc = LibavIteraction::instance().getFileInfo(path);
       
   617             desc += item->desc;
       
   618         }
       
   619         else
       
   620             desc += tr("(in progress...)");
       
   621     }
       
   622     labelDesc->setText(desc);
       
   623 }
       
   624 
       
   625 // user selected another cell, so we should change description
       
   626 void PageVideos::currentCellChanged(int row, int column, int previousRow, int previousColumn)
       
   627 {
       
   628     updateDescription();
       
   629 }
       
   630 
       
   631 // open video file in external media player
       
   632 void PageVideos::play(int row)
       
   633 {
       
   634     VideoItem * item = nameItem(row);
       
   635     if (item->ready())
       
   636         QDesktopServices::openUrl(QUrl("file:///" + item->path()));
       
   637 }
       
   638 
       
   639 void PageVideos::playSelectedFile()
       
   640 {
       
   641     int index = filesTable->currentRow();
       
   642     if (index != -1)
       
   643         play(index);
       
   644 }
       
   645 
       
   646 void PageVideos::deleteSelectedFiles()
       
   647 {
       
   648     QList<QTableWidgetItem*> items = filesTable->selectedItems();
       
   649     int num = items.size() / vcNumColumns;
       
   650     if (num == 0)
       
   651         return;
       
   652 
       
   653     // ask user if (s)he is serious
       
   654     if (QMessageBox::question(this,
       
   655                               tr("Are you sure?"),
       
   656                               tr("Do you really want do remove %1 file(s)?").arg(num),
       
   657                               QMessageBox::Yes | QMessageBox::No)
       
   658             != QMessageBox::Yes)
       
   659         return;
       
   660 
       
   661     // remove
       
   662     foreach (QTableWidgetItem * witem, items)
       
   663     {
       
   664         if (witem->type() != QTableWidgetItem::UserType)
       
   665             continue;
       
   666         VideoItem * item = (VideoItem*)witem;
       
   667         if (!item->ready())
       
   668             item->pRecorder->deleteLater();
       
   669         else
       
   670             cfgdir->remove("Videos/" + item->name);
       
   671     }
       
   672 }
       
   673 
       
   674 void PageVideos::keyPressEvent(QKeyEvent * pEvent)
       
   675 {
       
   676     if (filesTable->hasFocus())
       
   677     {
       
   678         if (pEvent->key() == Qt::Key_Delete)
       
   679         {
       
   680             deleteSelectedFiles();
       
   681             return;
       
   682         }
       
   683         if (pEvent->key() == Qt::Key_Enter) // doesn't work
       
   684         {
       
   685             playSelectedFile();
       
   686             return;
       
   687         }
       
   688     }
       
   689     AbstractPage::keyPressEvent(pEvent);
       
   690 }
       
   691 
       
   692 void PageVideos::openVideosDirectory()
       
   693 {
       
   694     QDesktopServices::openUrl(QUrl("file:///"+cfgdir->absolutePath() + "/Videos"));
       
   695 }