diff options
author | Maia Kozheva <sikon@ubuntu.com> | 2009-11-20 18:22:19 +0600 |
---|---|---|
committer | Maia Kozheva <sikon@ubuntu.com> | 2009-11-20 18:22:19 +0600 |
commit | 263b32f108c15cd1c55a8f4eb4704fac6553f1ac (patch) | |
tree | 1c49e7848aa2d3d64a9d9b96b8852cb1884da2f7 /src/videopreview |
Imported Upstream version 0.6.8
Diffstat (limited to 'src/videopreview')
-rw-r--r-- | src/videopreview/async.diff | 309 | ||||
-rw-r--r-- | src/videopreview/main.cpp | 57 | ||||
-rw-r--r-- | src/videopreview/videopreview.cpp | 648 | ||||
-rw-r--r-- | src/videopreview/videopreview.h | 168 | ||||
-rw-r--r-- | src/videopreview/videopreview.pro | 17 | ||||
-rw-r--r-- | src/videopreview/videopreviewconfigdialog.cpp | 155 | ||||
-rw-r--r-- | src/videopreview/videopreviewconfigdialog.h | 67 | ||||
-rw-r--r-- | src/videopreview/videopreviewconfigdialog.ui | 369 |
8 files changed, 1790 insertions, 0 deletions
diff --git a/src/videopreview/async.diff b/src/videopreview/async.diff new file mode 100644 index 0000000..4f12684 --- /dev/null +++ b/src/videopreview/async.diff @@ -0,0 +1,309 @@ +Index: videopreview/main.cpp +=================================================================== +--- videopreview/main.cpp (revisión: 2543) ++++ videopreview/main.cpp (copia de trabajo) +@@ -47,11 +47,17 @@ + */ + //vp.setAspectRatio( 2.35 ); + ++#if VIDEOPREVIEW_ASYNC ++ if (vp.showConfigDialog()) { ++ vp.createThumbnails(); ++ return a.exec(); ++ } ++#else + if ( (vp.showConfigDialog()) && (vp.createThumbnails()) ) { + vp.show(); + vp.adjustWindowSize(); + return a.exec(); + } +- ++#endif + return 0; + } +Index: videopreview/videopreview.cpp +=================================================================== +--- videopreview/videopreview.cpp (revisión: 2543) ++++ videopreview/videopreview.cpp (copia de trabajo) +@@ -105,7 +105,15 @@ + my_layout->addWidget(button_box); + setLayout(my_layout); + ++#if VIDEOPREVIEW_ASYNC ++ process = new QProcess(this); ++ connect( process, SIGNAL(finished(int, QProcess::ExitStatus)), ++ this, SLOT(processFinished(int, QProcess::ExitStatus)) ); + ++ connect( this, SIGNAL(finishedOk()), this, SLOT(workFinishedOK()) ); ++ connect( this, SIGNAL(finishedWithError()), this, SLOT(workFinishedWithError()) ); ++#endif ++ + QList<QByteArray> r_formats = QImageReader::supportedImageFormats(); + QString read_formats; + for (int n=0; n < r_formats.count(); n++) { +@@ -156,6 +164,132 @@ + return "00000005.jpg"; + } + ++#if VIDEOPREVIEW_ASYNC ++void VideoPreview::createThumbnails() { ++ clearThumbnails(); ++ error_message.clear(); ++ ++ // Initalization ++ VideoInfo i = getInfo(mplayer_bin, prop.input_video); ++ int length = i.length; ++ ++ if (length == 0) { ++ if (error_message.isEmpty()) error_message = tr("The length of the video is 0"); ++ emit finishedWithError(); ++ return; ++ } ++ ++ // Create a temporary directory ++ QDir d(QDir::tempPath()); ++ if (!d.exists(output_dir)) { ++ if (!d.mkpath(output_dir)) { ++ qDebug("VideoPreview::extractImages: error: can't create '%s'", full_output_dir.toUtf8().constData()); ++ error_message = tr("The temporary directory (%1) can't be created").arg(full_output_dir); ++ emit finishedWithError(); ++ return; ++ } ++ } ++ ++ displayVideoInfo(i); ++ ++ // Let's begin ++ run.thumbnail_width = 0; ++ ++ run.num_pictures = prop.n_cols * prop.n_rows; ++ length -= prop.initial_step; ++ run.s_step = length / run.num_pictures; ++ ++ run.current_time = prop.initial_step; ++ ++ canceled = false; ++ progress->setLabelText(tr("Creating thumbnails...")); ++ progress->setRange(0, run.num_pictures-1); ++ ++ run.current_picture = 0; ++ progress->setValue( run.current_picture); ++ ++ if (!runMplayer(run.current_time)) { ++ emit finishedWithError(); ++ } ++} ++ ++void VideoPreview::processFinished(int exitCode, QProcess::ExitStatus exitStatus) { ++ qDebug("VideoPreview::processFinished"); ++ ++ if (exitStatus != QProcess::NormalExit) { ++ emit finishedWithError(); ++ return; ++ } ++ ++ // Continue processing ++ QString frame_picture = full_output_dir + "/" + framePicture(); ++ if (!QFile::exists(frame_picture)) { ++ error_message = tr("The file %1 doesn't exist").arg(frame_picture); ++ emit finishedWithError(); ++ return; ++ } ++ ++#if RENAME_PICTURES ++ QDir d(QDir::tempPath()); ++ QString extension = (extractFormat()==PNG) ? "png" : "jpg"; ++ QString output_file = output_dir + QString("/picture_%1.%2").arg(run.current_time, 8, 10, QLatin1Char('0')).arg(extension); ++ d.rename(output_dir + "/" + framePicture(), output_file); ++#else ++ QString output_file = output_dir + "/" + framePicture(); ++#endif ++ ++ if (!addPicture(QDir::tempPath() +"/"+ output_file, run.current_picture, run.current_time)) { ++ emit finishedWithError(); ++ return; ++ } ++ ++ run.current_time += run.s_step; ++ ++ if (canceled) { ++ emit finishedOk(); ++ return; ++ } ++ ++ // Next picture ++ run.current_picture++; ++ ++ if (run.current_picture >= run.num_pictures) { ++ emit finishedOk(); ++ return; ++ } ++ ++ progress->setValue( run.current_picture); ++ ++ if (!runMplayer(run.current_time)) { ++ emit finishedWithError(); ++ } ++} ++ ++void VideoPreview::workFinishedOK() { ++ qDebug("VideoPreview::workFinishedOK"); ++ ++ show(); ++ adjustWindowSize(); ++ ++ cleanDir(full_output_dir); ++} ++ ++void VideoPreview::workFinishedWithError() { ++ qDebug("VideoPreview::workFinishedWithError"); ++ ++ if (!error_message.isEmpty()) { ++ QMessageBox::critical(this, tr("Error"), ++ tr("The following error has occurred while creating the thumbnails:")+"\n"+ error_message ); ++ } ++ ++ cleanDir(full_output_dir); ++ ++ close(); ++} ++ ++ ++#else // VIDEOPREVIEW_ASYNC ++ + bool VideoPreview::createThumbnails() { + clearThumbnails(); + error_message.clear(); +@@ -244,6 +378,7 @@ + + return true; + } ++#endif // VIDEOPREVIEW_ASYNC + + bool VideoPreview::runMplayer(int seek) { + QStringList args; +@@ -283,6 +418,18 @@ + for (int n = 0; n < args.count(); n++) command = command + args[n] + " "; + qDebug("VideoPreview::runMplayer: command: %s", command.toUtf8().constData()); + ++#if VIDEOPREVIEW_ASYNC ++ #ifdef CD_TO_TEMP_DIR ++ process->setWorkingDirectory(full_output_dir); ++ qDebug("VideoPreview::runMplayer: changing working directory of the process to '%s'", full_output_dir.toUtf8().constData()); ++ #endif ++ process->start(mplayer_bin, args); ++ if (!process->waitForStarted()) { ++ qDebug("VideoPreview::runMplayer: error running process"); ++ error_message = tr("The mplayer process didn't run"); ++ return false; ++ } ++#else // VIDEOPREVIEW_ASYNC + QProcess p; + #ifdef CD_TO_TEMP_DIR + p.setWorkingDirectory(full_output_dir); +@@ -294,6 +441,7 @@ + error_message = tr("The mplayer process didn't run"); + return false; + } ++#endif // VIDEOPREVIEW_ASYNC + + return true; + } +Index: videopreview/videopreview.h +=================================================================== +--- videopreview/videopreview.h (revisión: 2543) ++++ videopreview/videopreview.h (copia de trabajo) +@@ -19,10 +19,16 @@ + #ifndef _VIDEOPREVIEW_H_ + #define _VIDEOPREVIEW_H_ + ++#define VIDEOPREVIEW_ASYNC 0 ++ + #include <QWidget> + #include <QString> + #include <QList> + ++#if VIDEOPREVIEW_ASYNC ++#include <QProcess> ++#endif ++ + class QProgressDialog; + class QGridLayout; + class QLabel; +@@ -90,7 +96,11 @@ + void setExtractFormat( ExtractFormat format ) { prop.extract_format = format; }; + ExtractFormat extractFormat() { return prop.extract_format; }; + ++#if VIDEOPREVIEW_ASYNC ++ void createThumbnails(); ++#else + bool createThumbnails(); ++#endif + + bool showConfigDialog(); + +@@ -106,8 +116,23 @@ + void cancelPressed(); + void saveImage(); + ++#if VIDEOPREVIEW_ASYNC ++ void processFinished(int exitCode, QProcess::ExitStatus exitStatus); ++ void workFinishedOK(); ++ void workFinishedWithError(); ++ + protected: ++ QProcess * process; ++ ++signals: ++ void finishedOk(); ++ void finishedWithError(); ++#endif ++ ++protected: ++#if !VIDEOPREVIEW_ASYNC + bool extractImages(); ++#endif + bool runMplayer(int seek); + bool addPicture(const QString & filename, int num, int time); + void displayVideoInfo(const VideoInfo & i); +@@ -144,9 +169,19 @@ + ExtractFormat extract_format; + } prop; + ++#if VIDEOPREVIEW_ASYNC + struct { + int thumbnail_width; ++ int num_pictures; ++ int s_step; ++ int current_time; ++ int current_picture; + } run; ++#else ++ struct { ++ int thumbnail_width; ++ } run; ++#endif + + QString last_directory; + QString error_message; +Index: basegui.cpp +=================================================================== +--- basegui.cpp (revisión: 2543) ++++ basegui.cpp (copia de trabajo) +@@ -4022,10 +4022,16 @@ + + video_preview->setMplayerPath(pref->mplayer_bin); + ++#if VIDEOPREVIEW_ASYNC ++ if (video_preview->showConfigDialog()) { ++ video_preview->createThumbnails(); ++ } ++#else + if ( (video_preview->showConfigDialog()) && (video_preview->createThumbnails()) ) { + video_preview->show(); + video_preview->adjustWindowSize(); + } ++#endif + } + + QNetworkProxy BaseGui::userProxy() { diff --git a/src/videopreview/main.cpp b/src/videopreview/main.cpp new file mode 100644 index 0000000..6cc9e68 --- /dev/null +++ b/src/videopreview/main.cpp @@ -0,0 +1,57 @@ +/* smplayer, GUI front-end for mplayer. + Copyright (C) 2006-2009 Ricardo Villalba <rvm@escomposlinux.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "videopreview.h" +#include <QApplication> +#include <QWidget> +#include <QSettings> +#include <stdio.h> + +int main( int argc, char ** argv ) +{ + QApplication a( argc, argv ); + + QString filename; + + if (a.arguments().count() > 1) { + filename = a.arguments()[1]; + } + + QSettings set(QSettings::IniFormat, QSettings::UserScope, "RVM", "videopreview"); + + VideoPreview vp("mplayer"); + vp.setSettings(&set); + + if (!filename.isEmpty()) + vp.setVideoFile(filename); + + /* + vp.setGrid(4,5); + vp.setMaxWidth(800); + vp.setDisplayOSD(true); + */ + //vp.setAspectRatio( 2.35 ); + + if ( (vp.showConfigDialog(&vp)) && (vp.createThumbnails()) ) { + vp.show(); + vp.adjustWindowSize(); + return a.exec(); + } + + return 0; +} diff --git a/src/videopreview/videopreview.cpp b/src/videopreview/videopreview.cpp new file mode 100644 index 0000000..4e4151c --- /dev/null +++ b/src/videopreview/videopreview.cpp @@ -0,0 +1,648 @@ +/* smplayer, GUI front-end for mplayer. + Copyright (C) 2006-2009 Ricardo Villalba <rvm@escomposlinux.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "videopreview.h" +#include "videopreviewconfigdialog.h" +#include <QProcess> +#include <QRegExp> +#include <QDir> +#include <QTime> +#include <QProgressDialog> +#include <QWidget> +#include <QGridLayout> +#include <QLabel> +#include <QScrollArea> +#include <QDialogButtonBox> +#include <QPushButton> +#include <QPainter> +#include <QFileDialog> +#include <QMessageBox> +#include <QSettings> +#include <QApplication> +#include <QPixmapCache> +#include <QImageWriter> +#include <QImageReader> + +#include <cmath> + +#define RENAME_PICTURES 0 + +VideoPreview::VideoPreview(QString mplayer_path, QWidget * parent) : QWidget(parent, Qt::Window) +{ + setMplayerPath(mplayer_path); + + set = 0; // settings + save_last_directory = true; + + prop.input_video.clear(); + prop.dvd_device.clear(); + prop.n_cols = 4; + prop.n_rows = 4; + prop.initial_step = 20; + prop.max_width = 800; + prop.aspect_ratio = 0; + prop.display_osd = true; + prop.extract_format = JPEG; + + output_dir = "smplayer_preview"; + full_output_dir = QDir::tempPath() +"/"+ output_dir; + + progress = new QProgressDialog(this); + progress->setMinimumDuration(0); + connect( progress, SIGNAL(canceled()), this, SLOT(cancelPressed()) ); + + w_contents = new QWidget(this); + QPalette p = w_contents->palette(); + p.setColor(w_contents->backgroundRole(), Qt::white); + p.setColor(w_contents->foregroundRole(), Qt::black); + w_contents->setPalette(p); + + info = new QLabel(this); + + foot = new QLabel(this); + foot->setAlignment(Qt::AlignRight); + + grid_layout = new QGridLayout; + grid_layout->setSpacing(2); + + QVBoxLayout * l = new QVBoxLayout; + l->setSizeConstraint(QLayout::SetFixedSize); + l->addWidget(info); + l->addLayout(grid_layout); + l->addWidget(foot); + + w_contents->setLayout(l); + + scroll_area = new QScrollArea(this); + scroll_area->setWidgetResizable(true); + scroll_area->setAlignment(Qt::AlignCenter); + scroll_area->setWidget( w_contents ); + + button_box = new QDialogButtonBox(QDialogButtonBox::Close | QDialogButtonBox::Save, Qt::Horizontal, this); + connect( button_box, SIGNAL(rejected()), this, SLOT(close()) ); + connect( button_box->button(QDialogButtonBox::Save), SIGNAL(clicked()), this, SLOT(saveImage()) ); + + QVBoxLayout * my_layout = new QVBoxLayout; + my_layout->addWidget(scroll_area); + my_layout->addWidget(button_box); + setLayout(my_layout); + + retranslateStrings(); + + QList<QByteArray> r_formats = QImageReader::supportedImageFormats(); + QString read_formats; + for (int n=0; n < r_formats.count(); n++) { + read_formats.append(r_formats[n]+" "); + } + qDebug("VideoPreview::VideoPreview: supported formats for reading: %s", read_formats.toUtf8().constData()); + + QList<QByteArray> w_formats = QImageWriter::supportedImageFormats(); + QString write_formats; + for (int n=0; n < w_formats.count(); n++) { + write_formats.append(w_formats[n]+" "); + } + qDebug("VideoPreview::VideoPreview: supported formats for writing: %s", write_formats.toUtf8().constData()); + + toggleInfoAct = new QAction(this); + toggleInfoAct->setCheckable(true); + toggleInfoAct->setChecked(true); + toggleInfoAct->setShortcut( QKeySequence("Ctrl+H") ); + connect( toggleInfoAct, SIGNAL(toggled(bool)), this, SLOT(showInfo(bool)) ); + addAction(toggleInfoAct); +} + +VideoPreview::~VideoPreview() { + if (set) saveSettings(); +} + +void VideoPreview::retranslateStrings() { + progress->setWindowTitle(tr("Video preview")); + progress->setCancelButtonText( tr("Cancel") ); + + foot->setText("<i>"+ tr("Generated by SMPlayer") +" </i>"); +} + +void VideoPreview::setMplayerPath(QString mplayer_path) { + mplayer_bin = mplayer_path; + QFileInfo fi(mplayer_bin); + if (fi.exists() && fi.isExecutable() && !fi.isDir()) { + mplayer_bin = fi.absoluteFilePath(); + } + + qDebug("VideoPreview::setMplayerPath: mplayer_bin: '%s'", mplayer_bin.toUtf8().constData()); +} + +void VideoPreview::setSettings(QSettings * settings) { + set = settings; + loadSettings(); +} + +void VideoPreview::clearThumbnails() { + for (int n=0; n < label_list.count(); n++) { + grid_layout->removeWidget( label_list[n] ); + delete label_list[n]; + } + label_list.clear(); + info->clear(); +} + +QString VideoPreview::framePicture() { + if (prop.extract_format == PNG) + return "00000005.png"; + else + return "00000005.jpg"; +} + +bool VideoPreview::createThumbnails() { + clearThumbnails(); + error_message.clear(); + + button_box->setEnabled(false); + + bool result = extractImages(); + + progress->close(); + + if ((result == false) && (!error_message.isEmpty())) { + QMessageBox::critical(this, tr("Error"), + tr("The following error has occurred while creating the thumbnails:")+"\n"+ error_message ); + } + + button_box->setEnabled(true); + + // Adjust size + //resize( w_contents->sizeHint() ); + + cleanDir(full_output_dir); + return result; +} + +bool VideoPreview::extractImages() { + VideoInfo i = getInfo(mplayer_bin, prop.input_video); + int length = i.length; + + if (length == 0) { + if (error_message.isEmpty()) error_message = tr("The length of the video is 0"); + return false; + } + + // Create a temporary directory + QDir d(QDir::tempPath()); + if (!d.exists(output_dir)) { + if (!d.mkpath(output_dir)) { + qDebug("VideoPreview::extractImages: error: can't create '%s'", full_output_dir.toUtf8().constData()); + error_message = tr("The temporary directory (%1) can't be created").arg(full_output_dir); + return false; + } + } + + displayVideoInfo(i); + + // Let's begin + run.thumbnail_width = 0; + + int num_pictures = prop.n_cols * prop.n_rows; + length -= prop.initial_step; + int s_step = length / num_pictures; + + int current_time = prop.initial_step; + + canceled = false; + progress->setLabelText(tr("Creating thumbnails...")); + progress->setRange(0, num_pictures-1); + progress->show(); + + double aspect_ratio = i.aspect; + if (prop.aspect_ratio != 0) aspect_ratio = prop.aspect_ratio; + + for (int n = 0; n < num_pictures; n++) { + qDebug("VideoPreview::extractImages: getting frame %d of %d...", n+1, num_pictures); + progress->setValue(n); + qApp->processEvents(); + + if (canceled) return false; + + if (!runMplayer(current_time, aspect_ratio)) return false; + + QString frame_picture = full_output_dir + "/" + framePicture(); + if (!QFile::exists(frame_picture)) { + error_message = tr("The file %1 doesn't exist").arg(frame_picture); + return false; + } + +#if RENAME_PICTURES + QString extension = (extractFormat()==PNG) ? "png" : "jpg"; + QString output_file = output_dir + QString("/picture_%1.%2").arg(current_time, 8, 10, QLatin1Char('0')).arg(extension); + d.rename(output_dir + "/" + framePicture(), output_file); +#else + QString output_file = output_dir + "/" + framePicture(); +#endif + + if (!addPicture(QDir::tempPath() +"/"+ output_file, n, current_time)) { + return false; + } + + current_time += s_step; + } + + return true; +} + +bool VideoPreview::runMplayer(int seek, double aspect_ratio) { + QStringList args; + args << "-nosound"; + + if (prop.extract_format == PNG) { + args << "-vo" + << "png:outdir=\""+full_output_dir+"\""; + } else { + args << "-vo" + << "jpeg:outdir=\""+full_output_dir+"\""; + } + + args << "-frames" << "6" << "-ss" << QString::number(seek); + + if (aspect_ratio != 0) { + args << "-aspect" << QString::number(aspect_ratio) << "-zoom"; + } + + if (!prop.dvd_device.isEmpty()) { + args << "-dvd-device" << prop.dvd_device; + } + + /* + if (display_osd) { + args << "-vf" << "expand=osd=1" << "-osdlevel" << "2"; + } + */ + + args << prop.input_video; + + QString command = mplayer_bin + " "; + for (int n = 0; n < args.count(); n++) command = command + args[n] + " "; + qDebug("VideoPreview::runMplayer: command: %s", command.toUtf8().constData()); + + QProcess p; + p.start(mplayer_bin, args); + if (!p.waitForFinished()) { + qDebug("VideoPreview::runMplayer: error running process"); + error_message = tr("The mplayer process didn't run"); + return false; + } + + return true; +} + + +bool VideoPreview::addPicture(const QString & filename, int num, int time) { + int row = num / prop.n_cols; + int col = num % prop.n_cols; + + qDebug("VideoPreview::addPicture: %d (row: %d col: %d) file: '%s'", num, row, col, filename.toUtf8().constData()); + + QPixmapCache::clear(); + QPixmap picture; + if (!picture.load(filename)) { + qDebug("VideoPreview::addPicture: can't load file"); + error_message = tr("The file %1 can't be loaded").arg(filename); + return false; + } + + if (run.thumbnail_width == 0) { + int spacing = grid_layout->horizontalSpacing() * (prop.n_cols-1); + if (spacing < 0) spacing = 0; + qDebug("VideoPreview::addPicture: spacing: %d", spacing); + run.thumbnail_width = (prop.max_width - spacing) / prop.n_cols; + if (run.thumbnail_width > picture.width()) run.thumbnail_width = picture.width(); + qDebug("VideoPreview::addPicture: thumbnail_width set to %d", run.thumbnail_width); + } + + QPixmap scaled_picture = picture.scaledToWidth(run.thumbnail_width, Qt::SmoothTransformation); + + // Add current time text + if (prop.display_osd) { + QString stime = QTime().addSecs(time).toString("hh:mm:ss"); + QFont font("Arial"); + font.setBold(true); + QPainter painter(&scaled_picture); + painter.setPen( Qt::white ); + painter.setFont(font); + painter.drawText(scaled_picture.rect(), Qt::AlignRight | Qt::AlignBottom, stime); + } + + QLabel * l = new QLabel(this); + label_list.append(l); + l->setPixmap(scaled_picture); + //l->setPixmap(picture); + grid_layout->addWidget(l, row, col); + + return true; +} + +void VideoPreview::displayVideoInfo(const VideoInfo & i) { + // Display info about the video + QTime t = QTime().addSecs(i.length); + + QString aspect = QString::number(i.aspect); + if (fabs(1.77 - i.aspect) < 0.1) aspect = "16:9"; + else + if (fabs(1.33 - i.aspect) < 0.1) aspect = "4:3"; + else + if (fabs(2.35 - i.aspect) < 0.1) aspect = "2.35:1"; + + QString no_info = tr("No info"); + + QString fps = (i.fps==0 || i.fps==1000) ? no_info : QString("%1").arg(i.fps); + QString video_bitrate = (i.video_bitrate==0) ? no_info : tr("%1 kbps").arg(i.video_bitrate/1000); + QString audio_bitrate = (i.audio_bitrate==0) ? no_info : tr("%1 kbps").arg(i.audio_bitrate/1000); + QString audio_rate = (i.audio_rate==0) ? no_info : tr("%1 Hz").arg(i.audio_rate); + + info->setText( + "<b><font size=+1>" + i.filename +"</font></b>" + "<table cellspacing=4 cellpadding=4><tr>" + "<td>" + + tr("Size: %1 MB").arg(i.size / (1024*1024)) + "<br>" + + tr("Resolution: %1x%2").arg(i.width).arg(i.height) + "<br>" + + tr("Length: %1").arg(t.toString("hh:mm:ss")) + + "</td>" + "<td>" + + tr("Video format: %1").arg(i.video_format) + "<br>" + + tr("Frames per second: %1").arg(fps) + "<br>" + + tr("Aspect ratio: %1").arg(aspect) + //"<br>" + + "</td>" + "<td>" + + tr("Video bitrate: %1").arg(video_bitrate) + "<br>" + + tr("Audio bitrate: %1").arg(audio_bitrate) + "<br>" + + tr("Audio rate: %1").arg(audio_rate) + //"<br>" + + "</td>" + "</tr></table>" + ); + setWindowTitle( tr("Video preview") + " - " + i.filename ); +} + +void VideoPreview::cleanDir(QString directory) { + QStringList filter; + if (prop.extract_format == PNG) { + filter.append("*.png"); + } else { + filter.append("*.jpg"); + } + + QDir d(directory); + QStringList l = d.entryList( filter, QDir::Files, QDir::Unsorted); + + for (int n = 0; n < l.count(); n++) { + qDebug("VideoPreview::cleanDir: deleting '%s'", l[n].toUtf8().constData()); + d.remove(l[n]); + } + qDebug("VideoPreview::cleanDir: removing directory '%s'", directory.toUtf8().constData()); + d.rmpath(directory); +} + +VideoInfo VideoPreview::getInfo(const QString & mplayer_path, const QString & filename) { + VideoInfo i; + + if (filename.isEmpty()) { + error_message = tr("No filename"); + return i; + } + + QFileInfo fi(filename); + if (fi.exists()) { + i.filename = fi.fileName(); + i.size = fi.size(); + } + + QRegExp rx("^ID_(.*)=(.*)"); + + QProcess p; + p.setProcessChannelMode( QProcess::MergedChannels ); + + QStringList args; + args << "-vo" << "null" << "-ao" << "null" << "-frames" << "1" << "-identify" << "-nocache" << "-noquiet" << filename; + + if (!prop.dvd_device.isEmpty()) { + args << "-dvd-device" << prop.dvd_device; + } + + p.start(mplayer_path, args); + + if (p.waitForFinished()) { + QByteArray line; + while (p.canReadLine()) { + line = p.readLine().trimmed(); + qDebug("VideoPreview::getInfo: '%s'", line.constData()); + if (rx.indexIn(line) > -1) { + QString tag = rx.cap(1); + QString value = rx.cap(2); + qDebug("VideoPreview::getInfo: tag: '%s', value: '%s'", tag.toUtf8().constData(), value.toUtf8().constData()); + + if (tag == "LENGTH") i.length = (int) value.toDouble(); + else + if (tag == "VIDEO_WIDTH") i.width = value.toInt(); + else + if (tag == "VIDEO_HEIGHT") i.height = value.toInt(); + else + if (tag == "VIDEO_FPS") i.fps = value.toDouble(); + else + if (tag == "VIDEO_ASPECT") { + i.aspect = value.toDouble(); + if ((i.aspect == 0) && (i.width != 0) && (i.height != 0)) { + i.aspect = (double) i.width / i.height; + } + } + else + if (tag == "VIDEO_BITRATE") i.video_bitrate = value.toInt(); + else + if (tag == "AUDIO_BITRATE") i.audio_bitrate = value.toInt(); + else + if (tag == "AUDIO_RATE") i.audio_rate = value.toInt(); + else + if (tag == "VIDEO_FORMAT") i.video_format = value; + } + } + } else { + qDebug("VideoPreview::getInfo: error: process didn't start"); + error_message = tr("The mplayer process didn't start while trying to get info about the video"); + } + + qDebug("VideoPreview::getInfo: filename: '%s'", i.filename.toUtf8().constData()); + qDebug("VideoPreview::getInfo: resolution: '%d x %d'", i.width, i.height); + qDebug("VideoPreview::getInfo: length: '%d'", i.length); + qDebug("VideoPreview::getInfo: size: '%d'", (int) i.size); + + return i; +} + +void VideoPreview::showInfo(bool visible) { + qDebug("VideoPreview::showInfo: %d", visible); + info->setShown(visible); + foot->setShown(visible); +} + +void VideoPreview::saveImage() { + qDebug("VideoPreview::saveImage"); + + // Proposed name + QString proposed_name = ""; + if (save_last_directory) proposed_name = last_directory; + + QFileInfo fi(prop.input_video); + if (fi.exists()) { + if (!save_last_directory) proposed_name = fi.absolutePath(); + QString extension = (extractFormat()==PNG) ? "png" : "jpg"; + proposed_name += "/"+ fi.completeBaseName() +"_preview."+ extension; + } + + // Formats + QList<QByteArray> w_formats = QImageWriter::supportedImageFormats(); + QString write_formats; + for (int n=0; n < w_formats.count(); n++) { + write_formats.append("*."+w_formats[n]+" "); + } + if (write_formats.isEmpty()) { + // Shouldn't happen! + write_formats = "*.png *.jpg"; + } + + QString filename = QFileDialog::getSaveFileName(this, tr("Save file"), + proposed_name, tr("Images") +" ("+ write_formats +")"); + + if (!filename.isEmpty()) { + QPixmap image = QPixmap::grabWidget(w_contents); + if (!image.save(filename)) { + // Failed!!! + qDebug("VideoPreview::saveImage: error saving '%s'", filename.toUtf8().constData()); + QMessageBox::warning(this, tr("Error saving file"), + tr("The file couldn't be saved") ); + } else { + last_directory = QFileInfo(filename).absolutePath(); + } + } +} + +bool VideoPreview::showConfigDialog(QWidget * parent) { + VideoPreviewConfigDialog d(parent); + + d.setVideoFile( videoFile() ); + d.setDVDDevice( DVDDevice() ); + d.setCols( cols() ); + d.setRows( rows() ); + d.setInitialStep( initialStep() ); + d.setMaxWidth( maxWidth() ); + d.setDisplayOSD( displayOSD() ); + d.setAspectRatio( aspectRatio() ); + d.setFormat( extractFormat() ); + d.setSaveLastDirectory( save_last_directory ); + + if (d.exec() == QDialog::Accepted) { + setVideoFile( d.videoFile() ); + setDVDDevice( d.DVDDevice() ); + setCols( d.cols() ); + setRows( d.rows() ); + setInitialStep( d.initialStep() ); + setMaxWidth( d.maxWidth() ); + setDisplayOSD( d.displayOSD() ); + setAspectRatio( d.aspectRatio() ); + setExtractFormat(d.format() ); + save_last_directory = d.saveLastDirectory(); + + return true; + } + + return false; +} + +void VideoPreview::saveSettings() { + qDebug("VideoPreview::saveSettings"); + + set->beginGroup("videopreview"); + + set->setValue("columns", cols()); + set->setValue("rows", rows()); + set->setValue("initial_step", initialStep()); + set->setValue("max_width", maxWidth()); + set->setValue("osd", displayOSD()); + set->setValue("format", extractFormat()); + set->setValue("save_last_directory", save_last_directory); + + if (save_last_directory) { + set->setValue("last_directory", last_directory); + } + + set->setValue("filename", videoFile()); + set->setValue("dvd_device", DVDDevice()); + + set->setValue("show_info", toggleInfoAct->isChecked()); + + set->endGroup(); +} + +void VideoPreview::loadSettings() { + qDebug("VideoPreview::loadSettings"); + + set->beginGroup("videopreview"); + + setCols( set->value("columns", cols()).toInt() ); + setRows( set->value("rows", rows()).toInt() ); + setInitialStep( set->value("initial_step", initialStep()).toInt() ); + setMaxWidth( set->value("max_width", maxWidth()).toInt() ); + setDisplayOSD( set->value("osd", displayOSD()).toBool() ); + setExtractFormat( (ExtractFormat) set->value("format", extractFormat()).toInt() ); + save_last_directory = set->value("save_last_directory", save_last_directory).toBool(); + last_directory = set->value("last_directory", last_directory).toString(); + + setVideoFile( set->value("filename", videoFile()).toString() ); + setDVDDevice( set->value("dvd_device", DVDDevice()).toString() ); + + toggleInfoAct->setChecked(set->value("show_info", true).toBool()); + + set->endGroup(); +} + +void VideoPreview::adjustWindowSize() { + qDebug("VideoPreview::adjustWindowSize: window size: %d %d", width(), height()); + qDebug("VideoPreview::adjustWindowSize: scroll_area size: %d %d", scroll_area->width(), scroll_area->height()); + + int diff_width = width() - scroll_area->maximumViewportSize().width(); + int diff_height = height() - scroll_area->maximumViewportSize().height(); + + qDebug("VideoPreview::adjustWindowSize: diff_width: %d diff_height: %d", diff_width, diff_height); + + QSize new_size = w_contents->size() + QSize( diff_width, diff_height); + + qDebug("VideoPreview::adjustWindowSize: new_size: %d %d", new_size.width(), new_size.height()); + + resize(new_size); +} + +void VideoPreview::cancelPressed() { + canceled = true; +} + +// Language change stuff +void VideoPreview::changeEvent(QEvent *e) { + if (e->type() == QEvent::LanguageChange) { + retranslateStrings(); + } else { + QWidget::changeEvent(e); + } +} + +#include "moc_videopreview.cpp" + diff --git a/src/videopreview/videopreview.h b/src/videopreview/videopreview.h new file mode 100644 index 0000000..5e77f32 --- /dev/null +++ b/src/videopreview/videopreview.h @@ -0,0 +1,168 @@ +/* smplayer, GUI front-end for mplayer. + Copyright (C) 2006-2009 Ricardo Villalba <rvm@escomposlinux.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _VIDEOPREVIEW_H_ +#define _VIDEOPREVIEW_H_ + +#include <QWidget> +#include <QString> +#include <QList> + +class QProgressDialog; +class QGridLayout; +class QLabel; +class QScrollArea; +class QDialogButtonBox; +class QSettings; +class QAction; + +class VideoInfo +{ +public: + VideoInfo() { filename.clear(); width = 0; height = 0; length = 0; + size = 0; fps = 0; aspect = 0; video_bitrate = 0; + audio_bitrate = 0; audio_rate = 0; video_format.clear(); }; + ~VideoInfo() {}; + + QString filename; + int width; + int height; + int length; + qint64 size; + double fps; + double aspect; + int video_bitrate; + int audio_bitrate; + int audio_rate; + QString video_format; +}; + +class VideoPreview : public QWidget +{ + Q_OBJECT + +public: + enum ExtractFormat { JPEG = 1, PNG = 2 }; + + VideoPreview(QString mplayer_path, QWidget * parent = 0); + ~VideoPreview(); + + void setMplayerPath(QString mplayer_path); + QString mplayerPath() { return mplayer_bin; }; + + void setVideoFile(QString file) { prop.input_video = file; }; + QString videoFile() { return prop.input_video; }; + + void setDVDDevice(const QString & dvd_device) { prop.dvd_device = dvd_device; }; + QString DVDDevice() { return prop.dvd_device; }; + + void setCols(int cols) { prop.n_cols = cols; }; + int cols() { return prop.n_cols; }; + + void setRows(int rows) { prop.n_rows = rows; }; + int rows() { return prop.n_rows; }; + + void setGrid(int cols, int rows) { prop.n_cols = cols; prop.n_rows = rows; }; + + void setInitialStep(int step) { prop.initial_step = step; }; + int initialStep() { return prop.initial_step; }; + + void setMaxWidth(int w) { prop.max_width = w; }; + int maxWidth() { return prop.max_width; }; + + void setDisplayOSD(bool b) { prop.display_osd = b; }; + bool displayOSD() { return prop.display_osd; }; + + void setAspectRatio(double asp) { prop.aspect_ratio = asp; }; + double aspectRatio() { return prop.aspect_ratio; }; + + void setExtractFormat( ExtractFormat format ) { prop.extract_format = format; }; + ExtractFormat extractFormat() { return prop.extract_format; }; + + bool createThumbnails(); + + bool showConfigDialog(QWidget * parent); + + void setSettings(QSettings * settings); + QSettings * settings() { return set; }; + + VideoInfo getInfo(const QString & mplayer_path, const QString & filename); + QString errorMessage() { return error_message; }; + + void adjustWindowSize(); + +protected slots: + void cancelPressed(); + void saveImage(); + void showInfo(bool visible); + +protected: + virtual void retranslateStrings(); + virtual void changeEvent( QEvent * event ); + +protected: + bool extractImages(); + bool runMplayer(int seek, double aspect_ratio); + bool addPicture(const QString & filename, int num, int time); + void displayVideoInfo(const VideoInfo & i); + void cleanDir(QString directory); + void clearThumbnails(); + QString framePicture(); + void saveSettings(); + void loadSettings(); + + QList <QLabel *> label_list; + + QGridLayout * grid_layout; + QLabel * info; + QLabel * foot; + QWidget * w_contents; + QScrollArea * scroll_area; + QDialogButtonBox * button_box; + + QString mplayer_bin; + + QString output_dir; + QString full_output_dir; + + QProgressDialog * progress; + bool canceled; + + QSettings * set; + + QAction * toggleInfoAct; + + struct Properties { + QString input_video; + QString dvd_device; + int n_cols, n_rows, initial_step, max_width; + double aspect_ratio; + bool display_osd; + ExtractFormat extract_format; + } prop; + + struct { + int thumbnail_width; + } run; + + QString last_directory; + bool save_last_directory; + QString error_message; +}; + +#endif diff --git a/src/videopreview/videopreview.pro b/src/videopreview/videopreview.pro new file mode 100644 index 0000000..b78c910 --- /dev/null +++ b/src/videopreview/videopreview.pro @@ -0,0 +1,17 @@ +CONFIG += debug + +HEADERS = ../filechooser.h videopreviewconfigdialog.h videopreview.h +SOURCES = ../filechooser.cpp videopreviewconfigdialog.cpp videopreview.cpp main.cpp + +FORMS = ../filechooser.ui videopreviewconfigdialog.ui + +INCLUDEPATH += .. +DEPENDPATH += .. +DEFINES += NO_SMPLAYER_SUPPORT + +unix { + UI_DIR = .ui + MOC_DIR = .moc + OBJECTS_DIR = .obj +} + diff --git a/src/videopreview/videopreviewconfigdialog.cpp b/src/videopreview/videopreviewconfigdialog.cpp new file mode 100644 index 0000000..c62af9d --- /dev/null +++ b/src/videopreview/videopreviewconfigdialog.cpp @@ -0,0 +1,155 @@ +/* smplayer, GUI front-end for mplayer. + Copyright (C) 2006-2009 Ricardo Villalba <rvm@escomposlinux.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "videopreviewconfigdialog.h" +#include <QImageReader> + +VideoPreviewConfigDialog::VideoPreviewConfigDialog( QWidget* parent, Qt::WindowFlags f ) + : QDialog(parent, f) +{ + setupUi(this); + + connect(filename_edit->lineEdit(), SIGNAL(textChanged(const QString &)), + this, SLOT(filenameChanged(const QString &)) ); + + dvd_device_label->setVisible(false); + dvd_device_edit->setVisible(false); + + aspect_ratio_combo->addItem(tr("Default"), 0); + aspect_ratio_combo->addItem("4:3", (double) 4/3); + aspect_ratio_combo->addItem("16:9", (double) 16/9); + aspect_ratio_combo->addItem("2.35:1", 2.35); + + format_combo->addItem("png", VideoPreview::PNG); + if (QImageReader::supportedImageFormats().contains("jpg")) { + format_combo->addItem("jpg", VideoPreview::JPEG); + } + + filename_edit->setWhatsThis( tr("The preview will be created for the video you specify here.") ); + dvd_device_edit->setWhatsThis( tr("Enter here the DVD device or a folder with a DVD image.") ); + columns_spin->setWhatsThis( tr("The thumbnails will be arranged on a table.") +" "+ tr("This option specifies the number of columns of the table.") ); + rows_spin->setWhatsThis( tr("The thumbnails will be arranged on a table.") +" "+ tr("This option specifies the number of rows of the table.") ); + osd_check->setWhatsThis( tr("If you check this option, the playing time will be displayed at the bottom of each thumbnail.") ); + aspect_ratio_combo->setWhatsThis( tr("If the aspect ratio of the video is wrong, you can specify a different one here.") ); + initial_step_spin->setWhatsThis( tr("Usually the first frames are black, so it's a good idea to skip some seconds at the beginning of the video. " + "This option allows to specify how many seconds will be skipped.") ); + max_width_spin->setWhatsThis( tr("This option specifies the maximum width in pixels that the generated preview image will have.") ); + format_combo->setWhatsThis( tr("Some frames will be extracted from the video in order to create the preview. Here you can choose " + "the image format for the extracted frames. PNG may give better quality.") ); + + layout()->setSizeConstraint(QLayout::SetFixedSize); +} + +VideoPreviewConfigDialog::~VideoPreviewConfigDialog() { +} + +void VideoPreviewConfigDialog::setVideoFile(const QString & video_file) { + filename_edit->setText(video_file); +} + +QString VideoPreviewConfigDialog::videoFile() { + return filename_edit->text(); +} + +void VideoPreviewConfigDialog::setDVDDevice(const QString & dvd_device) { + dvd_device_edit->setText(dvd_device); +} + +QString VideoPreviewConfigDialog::DVDDevice() { + return dvd_device_edit->text(); +} + +void VideoPreviewConfigDialog::setCols(int cols) { + columns_spin->setValue(cols); +} + +int VideoPreviewConfigDialog::cols() { + return columns_spin->value(); +} + +void VideoPreviewConfigDialog::setRows(int rows) { + rows_spin->setValue(rows); +} + +int VideoPreviewConfigDialog::rows() { + return rows_spin->value(); +} + +void VideoPreviewConfigDialog::setInitialStep(int step) { + initial_step_spin->setValue(step); +} + +int VideoPreviewConfigDialog::initialStep() { + return initial_step_spin->value(); +} + +void VideoPreviewConfigDialog::setMaxWidth(int w) { + max_width_spin->setValue(w); +} + +int VideoPreviewConfigDialog::maxWidth() { + return max_width_spin->value(); +} + +void VideoPreviewConfigDialog::setDisplayOSD(bool b) { + osd_check->setChecked(b); +} + +bool VideoPreviewConfigDialog::displayOSD() { + return osd_check->isChecked(); +} + +void VideoPreviewConfigDialog::setAspectRatio(double asp) { + int idx = aspect_ratio_combo->findData(asp); + if (idx < 0) idx = 0; + aspect_ratio_combo->setCurrentIndex(idx); +} + +double VideoPreviewConfigDialog::aspectRatio() { + int idx = aspect_ratio_combo->currentIndex(); + return aspect_ratio_combo->itemData(idx).toDouble(); +} + +void VideoPreviewConfigDialog::setFormat(VideoPreview::ExtractFormat format) { + int idx = format_combo->findData(format); + if (idx < 0) idx = 0; + format_combo->setCurrentIndex(idx); +} + +VideoPreview::ExtractFormat VideoPreviewConfigDialog::format() { + int idx = format_combo->currentIndex(); + return (VideoPreview::ExtractFormat) format_combo->itemData(idx).toInt(); +} + +void VideoPreviewConfigDialog::setSaveLastDirectory(bool b) { + save_last_directory_check->setChecked(b); +} + +bool VideoPreviewConfigDialog::saveLastDirectory() { + return save_last_directory_check->isChecked(); +} + +void VideoPreviewConfigDialog::filenameChanged(const QString & text) { + qDebug("VideoPreviewConfigDialog::filenameChanged"); + + bool b = text.startsWith("dvd:"); + dvd_device_label->setVisible(b); + dvd_device_edit->setVisible(b); +} + +#include "moc_videopreviewconfigdialog.cpp" diff --git a/src/videopreview/videopreviewconfigdialog.h b/src/videopreview/videopreviewconfigdialog.h new file mode 100644 index 0000000..65d80c2 --- /dev/null +++ b/src/videopreview/videopreviewconfigdialog.h @@ -0,0 +1,67 @@ +/* smplayer, GUI front-end for mplayer. + Copyright (C) 2006-2009 Ricardo Villalba <rvm@escomposlinux.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _VIDEOPREVIEWCONFIGDIALOG_H_ +#define _VIDEOPREVIEWCONFIGDIALOG_H_ + +#include "ui_videopreviewconfigdialog.h" +#include "videopreview.h" + +class VideoPreviewConfigDialog : public QDialog, public Ui::VideoPreviewConfigDialog +{ + Q_OBJECT + +public: + VideoPreviewConfigDialog( QWidget* parent = 0, Qt::WindowFlags f = 0 ); + ~VideoPreviewConfigDialog(); + + void setVideoFile(const QString & video_file); + QString videoFile(); + + void setDVDDevice(const QString & dvd_device); + QString DVDDevice(); + + void setCols(int cols); + int cols(); + + void setRows(int rows); + int rows(); + + void setInitialStep(int step); + int initialStep(); + + void setMaxWidth(int w); + int maxWidth(); + + void setDisplayOSD(bool b); + bool displayOSD(); + + void setAspectRatio(double asp); + double aspectRatio(); + + void setFormat(VideoPreview::ExtractFormat format); + VideoPreview::ExtractFormat format(); + + void setSaveLastDirectory(bool b); + bool saveLastDirectory(); + +protected slots: + void filenameChanged(const QString &); +}; + +#endif diff --git a/src/videopreview/videopreviewconfigdialog.ui b/src/videopreview/videopreviewconfigdialog.ui new file mode 100644 index 0000000..3079272 --- /dev/null +++ b/src/videopreview/videopreviewconfigdialog.ui @@ -0,0 +1,369 @@ +<ui version="4.0" > + <class>VideoPreviewConfigDialog</class> + <widget class="QDialog" name="VideoPreviewConfigDialog" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>452</width> + <height>380</height> + </rect> + </property> + <property name="windowTitle" > + <string>Video Preview</string> + </property> + <layout class="QVBoxLayout" > + <item> + <layout class="QHBoxLayout" > + <item> + <widget class="QLabel" name="label" > + <property name="text" > + <string>&File:</string> + </property> + <property name="buddy" > + <cstring>filename_edit</cstring> + </property> + </widget> + </item> + <item> + <widget class="FileChooser" name="filename_edit" /> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" > + <item> + <widget class="QLabel" name="dvd_device_label" > + <property name="text" > + <string>&DVD device:</string> + </property> + <property name="buddy" > + <cstring>dvd_device_edit</cstring> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="dvd_device_edit" /> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" > + <item> + <widget class="QLabel" name="label_2" > + <property name="text" > + <string>&Columns:</string> + </property> + <property name="alignment" > + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy" > + <cstring>columns_spin</cstring> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="columns_spin" > + <property name="minimum" > + <number>1</number> + </property> + <property name="maximum" > + <number>10</number> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_3" > + <property name="text" > + <string>&Rows:</string> + </property> + <property name="alignment" > + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy" > + <cstring>rows_spin</cstring> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="rows_spin" > + <property name="minimum" > + <number>1</number> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QCheckBox" name="osd_check" > + <property name="text" > + <string>Add playing &time to thumbnails</string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line_2" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" > + <item> + <widget class="QLabel" name="label_5" > + <property name="text" > + <string>&Aspect ratio:</string> + </property> + <property name="buddy" > + <cstring>aspect_ratio_combo</cstring> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="aspect_ratio_combo" /> + </item> + <item> + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" > + <size> + <width>101</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" > + <item> + <widget class="QLabel" name="label_4" > + <property name="text" > + <string>&Seconds to skip at the beginnning:</string> + </property> + <property name="buddy" > + <cstring>initial_step_spin</cstring> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="initial_step_spin" /> + </item> + <item> + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" > + <item> + <widget class="QLabel" name="label_6" > + <property name="text" > + <string>&Maximum width:</string> + </property> + <property name="buddy" > + <cstring>max_width_spin</cstring> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="max_width_spin" > + <property name="minimum" > + <number>100</number> + </property> + <property name="maximum" > + <number>2000</number> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="Line" name="line_3" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" > + <item> + <widget class="QLabel" name="label_7" > + <property name="text" > + <string>&Extract frames as</string> + </property> + <property name="buddy" > + <cstring>format_combo</cstring> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="format_combo" /> + </item> + <item> + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" > + <size> + <width>71</width> + <height>23</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="Line" name="line" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="save_last_directory_check" > + <property name="text" > + <string>Remember folder used to &save the preview</string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line_4" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox" > + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons" > + <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>FileChooser</class> + <extends>QLineEdit</extends> + <header>filechooser.h</header> + </customwidget> + </customwidgets> + <tabstops> + <tabstop>filename_edit</tabstop> + <tabstop>dvd_device_edit</tabstop> + <tabstop>columns_spin</tabstop> + <tabstop>rows_spin</tabstop> + <tabstop>osd_check</tabstop> + <tabstop>aspect_ratio_combo</tabstop> + <tabstop>initial_step_spin</tabstop> + <tabstop>max_width_spin</tabstop> + <tabstop>format_combo</tabstop> + <tabstop>buttonBox</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>VideoPreviewConfigDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel" > + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel" > + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>VideoPreviewConfigDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel" > + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel" > + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> |