File indexing completed on 2024-05-12 16:23:32

0001 /***************************************************************************
0002  *   Copyright (C) 2005-2017 by Linuxstopmotion contributors;              *
0003  *   see the AUTHORS file for details.                                     *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
0019  ***************************************************************************/
0020 #include "src/presentation/frontends/qtfrontend/exporttab.h"
0021 
0022 #include <stdlib.h>
0023 #include <algorithm>
0024 #include <memory>
0025 
0026 #include "graphics/icons/close.xpm"
0027 #include "flexiblelineedit.h"
0028 #include "src/foundation/preferencestool.h"
0029 #include "src/foundation/logger.h"
0030 
0031 #include <QFileDialog>
0032 #include <QGridLayout>
0033 #include <QGroupBox>
0034 #include <QHeaderView>
0035 #include <QInputDialog>
0036 #include <QLabel>
0037 #include <QLineEdit>
0038 #include <QPushButton>
0039 #include <QRadioButton>
0040 #include <QTableWidget>
0041 #include <QTextEdit>
0042 #include <QToolBox>
0043 
0044 
0045 ExportTab::ExportTab(QWidget *parent) : QWidget(parent)
0046 {
0047     addButton          = 0;
0048     removeButton       = 0;
0049     editButton         = 0;
0050     browseButton       = 0;
0051     yesButton          = 0;
0052     noButton           = 0;
0053     closeButton        = 0;
0054     encoderPrefs       = 0;
0055     encoderTable       = 0;
0056     startEncoder       = 0;
0057     stopEncoder        = 0;
0058     startEncoderLabel  = 0;
0059     stopEncoderLabel   = 0;
0060     defaultOutput      = 0;
0061     defaultOutputLabel = 0;
0062     askForOutput       = 0;
0063     infoText           = 0;
0064 
0065     makeGUI();
0066 }
0067 
0068 
0069 void ExportTab::makeGUI()
0070 {
0071     infoText = new QTextEdit;
0072     infoText->setReadOnly(true);
0073     infoText->setMinimumWidth(440);
0074     infoText->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
0075 
0076     encoderTable = new QTableWidget;
0077     encoderTable->setColumnCount(2);
0078     encoderTable->setRowCount(0);
0079     encoderTable->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
0080     encoderTable->setSelectionMode(QAbstractItemView::SingleSelection);
0081     encoderTable->setSelectionBehavior(QAbstractItemView::SelectRows);
0082     encoderTable->verticalHeader()->setVisible(false);
0083 
0084     connect(encoderTable, SIGNAL(cellClicked(int, int)), this, SLOT(activeCellChanged(int, int)));
0085     connect(encoderTable, SIGNAL(cellChanged(int, int)), this, SLOT(contentsChanged(int, int)));
0086 
0087     addButton = new QPushButton(tr("&Add"));
0088     addButton->setFocusPolicy( Qt::NoFocus );
0089     connect(addButton, SIGNAL(clicked()), this, SLOT(addEncoder()) );
0090 
0091     removeButton = new QPushButton(tr("&Remove"));
0092     connect( removeButton, SIGNAL(clicked()), this, SLOT(removeEncoder()) );
0093 
0094     editButton = new QPushButton(tr("&Edit"));
0095     QObject::connect( editButton, SIGNAL(clicked()), this, SLOT(editSettings()) );
0096 
0097     encoderPrefs = new QGroupBox;
0098     encoderPrefs->setTitle( tr("Encoder settings") );
0099     encoderPrefs->hide();
0100 
0101     closeButton = new QPushButton;
0102     closeButton->setIcon(QPixmap(closeicon));
0103     closeButton->setFlat(true);
0104     closeButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum);
0105     connect( closeButton, SIGNAL(clicked()),this, SLOT(closeSettings()) );
0106 
0107     askForOutput = new QLabel(
0108             tr("Do you want to be asked for an output file every time you choose to export?"));
0109 
0110     yesButton = new QRadioButton(tr("Yes"));
0111     yesButton->setChecked(true);
0112     yesButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
0113     connect( yesButton, SIGNAL(clicked()), this, SLOT(setYesButtonOn()) );
0114 
0115     noButton = new QRadioButton(tr("No"));
0116     noButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
0117     noButton->setChecked(false);
0118     connect( noButton, SIGNAL(clicked()), this, SLOT(setNoButtonOn()) );
0119 
0120     defaultOutputLabel = new QLabel( tr("Set default output file:"));
0121     defaultOutput = new FlexibleLineEdit;
0122     defaultOutput->setEnabled(false);
0123     connect( defaultOutput, SIGNAL(textChanged(const QString &)),
0124             this, SLOT(setDefaultOutput(const QString &)) );
0125 
0126     browseButton = new QPushButton(tr("Browse"));
0127     browseButton->setEnabled(false);
0128     browseButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
0129     connect( browseButton, SIGNAL(clicked()), this, SLOT(browseFiles()) );
0130 
0131     startEncoderLabel = new QLabel( tr("Start encoder:") );
0132     startEncoder = new FlexibleLineEdit;
0133     connect( startEncoder, SIGNAL(textChanged(const QString &)),
0134             this, SLOT(updateStartString(const QString &)) );
0135 
0136     stopEncoderLabel = new QLabel( tr("Stop encoder:") );
0137     stopEncoder = new FlexibleLineEdit;
0138     connect( stopEncoder, SIGNAL(textChanged(const QString &)),
0139             this, SLOT(updateStopString(const QString &)) );
0140 
0141     QVBoxLayout *mainLayout = new QVBoxLayout;
0142     mainLayout->addWidget(infoText);
0143     QVBoxLayout *buttonLayout = new QVBoxLayout;
0144     buttonLayout->setContentsMargins(0, 0, 0, 0);
0145     buttonLayout->setSpacing(2);
0146     buttonLayout->addStretch(1);
0147     buttonLayout->addWidget(addButton);
0148     buttonLayout->addWidget(removeButton);
0149     buttonLayout->addWidget(editButton);
0150     QHBoxLayout *encoderLayout = new QHBoxLayout;
0151     encoderLayout->addWidget(encoderTable);
0152     encoderLayout->addLayout(buttonLayout);
0153     mainLayout->addLayout(encoderLayout);
0154     mainLayout->addWidget(encoderPrefs);
0155     setLayout(mainLayout);
0156 
0157     QGridLayout *encoderPrefsLayout = new QGridLayout;
0158     encoderPrefsLayout->addWidget(closeButton, 0, 2);
0159     encoderPrefsLayout->addWidget(askForOutput, 0, 0, 1, 2);
0160     QHBoxLayout* hbLayout = new QHBoxLayout;
0161     hbLayout->addWidget(yesButton);
0162     hbLayout->addWidget(noButton);
0163     hbLayout->addStretch(1);
0164     encoderPrefsLayout->addLayout(hbLayout, 1, 1);
0165     encoderPrefsLayout->addWidget(defaultOutputLabel, 2, 0);
0166     hbLayout = new QHBoxLayout;
0167     hbLayout->addWidget(defaultOutput);
0168     hbLayout->addWidget(browseButton);
0169     encoderPrefsLayout->addLayout(hbLayout, 2, 1, 1, 2);
0170     encoderPrefsLayout->addWidget(startEncoderLabel, 3, 0);
0171     encoderPrefsLayout->addWidget(startEncoder, 3, 1, 1, 2);
0172     encoderPrefsLayout->addWidget(stopEncoderLabel, 4, 0);
0173     encoderPrefsLayout->addWidget(stopEncoder, 4, 1, 1, 2);
0174     encoderPrefs->setLayout(encoderPrefsLayout);
0175 }
0176 
0177 
0178 void ExportTab::initialize()
0179 {
0180     Logger::get().logDebug("Initializing encoder settings");
0181     PreferencesTool *pref = PreferencesTool::get();
0182 
0183     int numEncoders = pref->getPreference("numEncoders", 0);
0184     encoderTable->setRowCount(numEncoders);
0185     for (int i = 0; i < numEncoders; ++i) {
0186         Preference name(QString("encoderName%1").arg(i).toLatin1().constData(),"");
0187         encoderTable->setItem(i, 0, new QTableWidgetItem(name.get()) );
0188         Preference desc(QString("encoderDescription%1").arg(i).toLatin1().constData(),"");
0189         encoderTable->setItem(i, 1, new QTableWidgetItem(desc.get()) );
0190         Preference start(QString("startEncoder%1").arg(i).toLatin1().constData(), "");
0191         startEncoderStrings.push_back(QString(start.get()));
0192         Preference stop(QString("stopEncoder%1").arg(i).toLatin1().constData(), "");
0193         stopEncoderStrings.push_back(QString(stop.get()));
0194         Preference output(QString("outputFile%1").arg(i).toLatin1().constData(), "" );
0195         outputFiles.push_back( QString(output.get()));
0196     }
0197 
0198     int active = pref->getPreference("activeEncoder", -1);
0199     if (active > -1) {
0200         encoderTable->setCurrentCell(active, 0);
0201     }
0202 }
0203 
0204 
0205 void ExportTab::resizeEvent(QResizeEvent *event)
0206 {
0207     contentsChanged(0, 0);
0208     QWidget::resizeEvent(event);
0209 }
0210 
0211 
0212 void ExportTab::apply() {
0213     PreferencesTool *prefs = PreferencesTool::get();
0214 
0215     // Remove old preferences
0216     int numEncoders = prefs->getPreference("numEncoders", -1);
0217     if (numEncoders > 0) {
0218         for (int i = 0; i < numEncoders; ++i) {
0219             prefs->removePreference(QString("encoderName%1").arg(i).toLatin1().constData());
0220             prefs->removePreference(QString("encoderDescription%1").arg(i).toLatin1().constData());
0221             prefs->removePreference(QString("startEncoder%1").arg(i).toLatin1().constData());
0222             prefs->removePreference(QString("stopEncoder%1").arg(i).toLatin1().constData());
0223             prefs->removePreference(QString("outputFile%1").arg(i).toLatin1().constData());
0224         }
0225     }
0226 
0227     // Set new preferences
0228     numEncoders = encoderTable->rowCount();
0229     if (numEncoders > 0) {
0230         prefs->setPreference("numEncoders", numEncoders);
0231         prefs->setPreference("activeEncoder", encoderTable->currentRow());
0232         for (int i = 0; i < numEncoders; ++i) {
0233             prefs->setPreference(QString("encoderName%1").arg(i).toLatin1().constData(),
0234                     encoderTable->item(i, 0)->text().toLatin1().constData());
0235             prefs->setPreference(QString("encoderDescription%1").arg(i).toLatin1().constData(),
0236                     encoderTable->item(i, 1)->text().toLatin1().constData());
0237             prefs->setPreference(QString("startEncoder%1").arg(i).toLatin1().constData(),
0238                     startEncoderStrings[i].toLatin1().constData());
0239             prefs->setPreference(QString("stopEncoder%1").arg(i).toLatin1().constData(),
0240                     stopEncoderStrings[i].toLatin1().constData());
0241             prefs->setPreference(QString("outputFile%1").arg(i).toLatin1().constData(),
0242                     outputFiles[i].toLatin1().constData());
0243         }
0244     } else {
0245         prefs->setPreference("numEncoders", -1);
0246         prefs->setPreference("activeEncoder", -1);
0247     }
0248 }
0249 
0250 
0251 void ExportTab::addEncoder()
0252 {
0253     int newRow = encoderTable->rowCount();
0254     encoderTable->setRowCount(newRow + 1);
0255     encoderTable->setItem(newRow, 0, new QTableWidgetItem(QString("")));
0256     encoderTable->setItem(newRow, 1, new QTableWidgetItem(QString("")));
0257     encoderTable->setCurrentCell(newRow, 0);
0258 
0259     startEncoderStrings.push_back("");
0260     stopEncoderStrings.push_back("");
0261     outputFiles.push_back("");
0262 }
0263 
0264 
0265 void ExportTab::removeEncoder()
0266 {
0267     int selectedRow = encoderTable->currentRow();
0268     if (selectedRow >= 0) {
0269         startEncoderStrings.erase(startEncoderStrings.begin() + selectedRow);
0270         stopEncoderStrings.erase(stopEncoderStrings.begin() + selectedRow);
0271         outputFiles.erase(outputFiles.begin() + selectedRow);
0272         encoderTable->removeRow(selectedRow);
0273         contentsChanged(0, 0);
0274     }
0275 }
0276 
0277 
0278 void ExportTab::contentsChanged(int, int)
0279 {
0280     encoderTable->resizeColumnsToContents();
0281     int totalWidth = encoderTable->columnWidth(0) + encoderTable->columnWidth(1);
0282     int tableWidth = encoderTable->width() - 5;
0283     if ( totalWidth < tableWidth) {
0284         encoderTable->setColumnWidth( 1, tableWidth - encoderTable->columnWidth(0) );
0285     }
0286 }
0287 
0288 
0289 void ExportTab::activeCellChanged(int, int)
0290 {
0291     if ( encoderPrefs->isVisible() ) {
0292         editSettings();
0293     }
0294 }
0295 
0296 
0297 void ExportTab::editSettings()
0298 {
0299     int selected = encoderTable->currentRow();
0300     if (selected >= 0) {
0301         startEncoder->setText(startEncoderStrings[selected]);
0302         stopEncoder->setText(stopEncoderStrings[selected]);
0303         if ( outputFiles[selected] == "" ) {
0304             setYesButtonOn();
0305         }
0306         else {
0307             setNoButtonOn();
0308         }
0309         encoderPrefs->show();
0310     }
0311 }
0312 
0313 
0314 void ExportTab::closeSettings( )
0315 {
0316     encoderPrefs->hide();
0317     this->resize(minimumSize());
0318 }
0319 
0320 
0321 void ExportTab::updateStartString(const QString &txt)
0322 {
0323     startEncoderStrings[encoderTable->currentRow()] = txt;
0324 }
0325 
0326 
0327 void ExportTab::updateStopString(const QString &txt)
0328 {
0329     stopEncoderStrings[encoderTable->currentRow()] = txt;
0330 }
0331 
0332 
0333 void ExportTab::setDefaultOutput(const QString &txt)
0334 {
0335     outputFiles[encoderTable->currentRow()] = txt;
0336 }
0337 
0338 
0339 void ExportTab::setYesButtonOn()
0340 {
0341     yesButton->setChecked(true);
0342     noButton->setChecked(false);
0343     defaultOutput->setText("");
0344     defaultOutput->setEnabled(false);
0345     browseButton->setEnabled(false);
0346     outputFiles[encoderTable->currentRow()] = "";
0347 }
0348 
0349 
0350 void ExportTab::setNoButtonOn()
0351 {
0352     noButton->setChecked(true);
0353     yesButton->setChecked(false);
0354     defaultOutput->setEnabled(true);
0355     browseButton->setEnabled(true);
0356     defaultOutput->setText(outputFiles[encoderTable->currentRow()]);
0357 }
0358 
0359 
0360 void ExportTab::browseFiles()
0361 {
0362     QString file = QFileDialog::getSaveFileName(this, tr("Choose output file"), getenv("PWD"));
0363     if ( !file.isEmpty() ) {
0364         outputFiles[encoderTable->currentRow()] = file;
0365         defaultOutput->setText(file);
0366     }
0367 }
0368 
0369 void ExportTab::retranslateStrings()
0370 {
0371     infoText->setHtml(
0372         "<p>" + tr("Below you can set which program/process Stopmotion should use "
0373         "for encoding the currently active project to a video file.") + "</p><p>" +
0374         tr("You should always use <b>$IMAGEPATH</b> and <b>$VIDEOFILE</b> to represent "
0375         "the image path and the video file, respectively.") + "</p><p>" +
0376         tr("You can use <b>$FRAMERATE</b> to represent the frame rate currently in use "
0377                 "in the project.") + "</p><p>" +
0378         tr("Example with mencoder (jpeg images to mpeg4 video):") + "<br>" +
0379         "mencoder -ovc lavc -lavcopts vcodec=msmpeg4v2:vpass=1 -mf type=jpg:fps=$FRAMERATE -o "
0380         "$VIDEOFILE mf://$IMAGEPATH/*.jpg");
0381 
0382     QStringList lst;
0383     lst << tr("Name") << tr("Description");
0384     encoderTable->setHorizontalHeaderLabels(lst);
0385 
0386     addButton->setText( tr("&Add") );
0387     removeButton->setText( tr("&Remove") );
0388     editButton->setText( tr("&Edit") );
0389 
0390     askForOutput->setText(
0391             tr("Do you want to be asked for an output file every time you choose to export?"));
0392 
0393     yesButton->setText(tr("Yes"));
0394     noButton->setText(tr("No"));
0395     defaultOutputLabel->setText( tr("Set default output file:"));
0396     browseButton->setText(tr("Browse"));
0397     startEncoderLabel->setText(tr("Start encoder:"));
0398     stopEncoderLabel->setText(tr("Stop encoder:"));
0399 }