convert.cpp 8.78 KB
Newer Older
1
/*****************************************************************************
Pere Orga's avatar
Pere Orga committed
2
 * convert.cpp : Convertion dialogs
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
 ****************************************************************************
 * Copyright (C) 2009 the VideoLAN team
 * $Id$
 *
 * Authors: Jean-Baptiste Kempf <jb (at) videolan.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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "dialogs/sout.hpp"
#include "dialogs/convert.hpp"
30
#include "components/sout/sout_widgets.hpp"
31 32 33 34 35 36 37 38 39

#include "util/qt_dirs.hpp"

#include <QLabel>
#include <QGroupBox>
#include <QDialogButtonBox>
#include <QFileDialog>
#include <QCheckBox>

40 41 42
#define urlToDisplayString(filestr) toNativeSeparators(QUrl(filestr).toDisplayString(\
    QUrl::RemovePassword | QUrl::PreferLocalFile | QUrl::NormalizePathSegments ))

43
ConvertDialog::ConvertDialog( QWidget *parent, intf_thread_t *_p_intf,
44
                              const QStringList& inputMRLs )
45 46
              : QVLCDialog( parent, _p_intf ),
                singleFileSelected( inputMRLs.length() == 1 )
47 48
{
    setWindowTitle( qtr( "Convert" ) );
Nick Pope's avatar
Nick Pope committed
49
    setWindowRole( "vlc-convert" );
50 51

    QGridLayout *mainLayout = new QGridLayout( this );
52
    SoutInputBox *inputBox = new SoutInputBox( this );
53 54 55 56 57 58 59 60
    incomingMRLs = &inputMRLs;

    if(singleFileSelected)
    {
        inputBox->setMRL( inputMRLs[0] );
    }
    else
    {
61
        inputBox->setMRL( qtr( "Multiple files selected." ) );
62
    }
63
    mainLayout->addWidget( inputBox, 0, 0, 1, -1  );
64 65 66 67 68 69 70

    /**
     * Destination
     **/
    QGroupBox *destBox = new QGroupBox( qtr( "Destination" ) );
    QGridLayout *destLayout = new QGridLayout( destBox );

71
    QLabel *destLabel = new QLabel( qtr( "Destination file:" ) );
72 73 74 75 76
    destLayout->addWidget( destLabel, 0, 0);

    fileLine = new QLineEdit;
    fileLine->setMinimumWidth( 300 );
    fileLine->setFocus( Qt::ActiveWindowFocusReason );
77
    fileLine->setReadOnly(true);
78
    destLabel->setBuddy( fileLine );
79 80 81 82 83 84 85
    // You can set a specific name for only one file.
    if(singleFileSelected)
    {
        QPushButton *fileSelectButton = new QPushButton( qtr( "Browse" ) );
        destLayout->addWidget( fileSelectButton, 0, 2);
        BUTTONACT( fileSelectButton, fileBrowse() );
    }
86

87 88 89
    // but multiple files follow a naming convention
    else
    {
90
        fileLine->setText( qtr( "Multiple Files Selected." ) );
91
        fileLine->setReadOnly(true);
92 93
        fileLine->setToolTip( qtr( "Files will be placed in the same directory "
                "with the same name." ) );
94

95 96 97 98
        appendBox = new QCheckBox( qtr( "Append '-converted' to filename" ) );
        destLayout->addWidget( appendBox, 1, 0 );
    }
    destLayout->addWidget( fileLine, 0, 1 );
99
    mainLayout->addWidget( destBox, 3, 0, 1, -1  );
100 101 102 103 104 105


    /* Profile Editor */
    QGroupBox *settingBox = new QGroupBox( qtr( "Settings" ) );
    QGridLayout *settingLayout = new QGridLayout( settingBox );

106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
    QRadioButton *convertRadio = new QRadioButton( qtr( "Convert" ) );
    dumpRadio = new QRadioButton( qtr( "Dump raw input" ) );
    QButtonGroup *buttonGroup = new QButtonGroup(this);
    buttonGroup->addButton( convertRadio );
    buttonGroup->addButton( dumpRadio );
    convertRadio->setChecked( true );

    settingLayout->addWidget( convertRadio, 1, 0 );

    QWidget *convertPanel = new QWidget( this );
    QVBoxLayout *convertLayout = new QVBoxLayout( convertPanel );

    displayBox = new QCheckBox( qtr( "Display the output" ) );
    displayBox->setToolTip( qtr( "This display the resulting media, but can "
                               "slow things down." ) );
    convertLayout->addWidget( displayBox );
122 123

    deinterBox = new QCheckBox( qtr( "Deinterlace" ) );
124 125 126 127
    convertLayout->addWidget( deinterBox );

    profile = new VLCProfileSelector( this );
    convertLayout->addWidget( profile );
128

129
    settingLayout->addWidget( convertPanel, 2, 0 );
130

131 132 133
    settingLayout->addWidget( dumpRadio, 5, 0 );

    mainLayout->addWidget( settingBox, 1, 0, 1, -1  );
134 135

    /* Buttons */
136
    okButton = new QPushButton( qtr( "&Start" ) );
137 138 139 140 141 142 143 144 145
    QPushButton *cancelButton = new QPushButton( qtr( "&Cancel" ) );
    QDialogButtonBox *buttonBox = new QDialogButtonBox;

    okButton->setDefault( true );
    buttonBox->addButton( okButton, QDialogButtonBox::AcceptRole );
    buttonBox->addButton( cancelButton, QDialogButtonBox::RejectRole );

    mainLayout->addWidget( buttonBox, 5, 3 );

146 147 148
    BUTTONACT(okButton,close());
    BUTTONACT(cancelButton,cancel());

149
    CONNECT( convertRadio, toggled(bool), convertPanel, setEnabled(bool) );
150 151
    CONNECT(profile, optionsChanged(), this, setDestinationFileExtension());
    CONNECT(fileLine, editingFinished(), this, setDestinationFileExtension());
152 153 154
    CONNECT(fileLine, textChanged(const QString&), this, validate());

    validate();
155 156 157 158
}

void ConvertDialog::fileBrowse()
{
159
    QString fileExtension = ( ! profile->isEnabled() ) ? ".*" : "." + profile->getMux();
160

161
    outgoingMRL = QFileDialog::getSaveFileUrl( this, qtr( "Save file..." ),
162
        p_intf->p_sys->filepath,
163
        QString( "%1 (*%2);;%3 (*.*)" ).arg( qtr( "Containers" ) )
164
            .arg( fileExtension ).arg( qtr("All") ), 0, QFileDialog::DontConfirmOverwrite );
165
    fileLine->setText( urlToDisplayString( outgoingMRL ) );
166
    setDestinationFileExtension();
167 168 169 170
}

void ConvertDialog::cancel()
{
171
    reject();
172 173 174 175 176 177
}

void ConvertDialog::close()
{
    hide();

178
    for(int i = 0; i < incomingMRLs->length(); i++)
179
    {
180
        QString mrl;
181
        QString newFileName;
182 183

        if( dumpRadio->isChecked() )
184
        {
185 186 187
            newFileName = fileLine->text();
            newFileName.replace( QChar('\''), "\\\'" );
            mrl = QString( "demux=dump :demuxdump-file='%1'" ).arg( newFileName );
188
        }
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
        else
        {
            mrl = "sout=#" + profile->getTranscode();
            if( deinterBox->isChecked() )
            {
                mrl.remove( '}' );
                mrl += ",deinterlace}";
            }
            mrl += ":";
            if( displayBox->isChecked() )
            {
                mrl += "duplicate{dst=display,dst=";
            }

            // Only one file, use the destination provided
            if(singleFileSelected)
            {
206
                newFileName = outgoingMRL.toLocalFile();
207 208 209 210 211 212 213 214 215 216
            }

            // Multiple, use the convention.
            else
            {
                QString fileExtension = ( ! profile->isEnabled() ) ? ".*" : "." + profile->getMux();

                newFileName = incomingMRLs->at(i);

                // Remove the file:// from the front of our MRL
217
                newFileName = QUrl(newFileName).toLocalFile();
218 219 220 221 222 223 224 225 226

                // Remote the existing extention (if any)
                int extentionPos = newFileName.lastIndexOf('.');
                if(extentionPos >= 0)
                {
                    newFileName = newFileName.remove(extentionPos, newFileName.length() - extentionPos);
                }

                // If we have multiple files (i.e. we have an appenBox) and it's checked
227
                if( appendBox->isChecked() )
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
                {
                    newFileName = newFileName.append("-converted");
                }

                // Stick our new extention on
                newFileName = newFileName.append(fileExtension);
            }

            newFileName.replace( QChar('\''), "\\\'" );

            mrl += "std{access=file{no-overwrite},mux=" + profile->getMux()
                 + ",dst='" + newFileName
                 + "'}";
            if( displayBox->isChecked() )
                mrl += "}";
        }
        msg_Dbg( p_intf, "Transcode MRL: %s", qtu( mrl ) );
        mrls.append(mrl);
246
    }
247
    accept();
248
}
249

250 251
void ConvertDialog::setDestinationFileExtension()
{
252
    if( !outgoingMRL.isEmpty() && profile->isEnabled() )
253
    {
254 255
        QString filepath = outgoingMRL.path(QUrl::FullyEncoded);
        if( filepath.lastIndexOf( "." ) == -1 )
256
        {
257 258 259
            QString newFileExtension = "." + profile->getMux();
            outgoingMRL.setPath(filepath + newFileExtension);
            fileLine->setText( urlToDisplayString( outgoingMRL ) );
260 261 262
        }
    }
}
263 264 265 266 267

void ConvertDialog::validate()
{
    okButton->setEnabled( !fileLine->text().isEmpty() );
}