File indexing completed on 2024-05-12 04:51:52

0001 /*
0002     SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "k3bvideodvdrippingwidget.h"
0007 
0008 #include "k3bvideodvdtitletranscodingjob.h"
0009 #include "k3bglobals.h"
0010 #include "k3bintmapcombobox.h"
0011 
0012 #include <KLineEdit>
0013 #include <KColorScheme>
0014 #include <KLazyLocalizedString>
0015 #include <KIO/Global>
0016 #include <KUrlRequester>
0017 #include <KUrlLabel>
0018 
0019 #include <QTimer>
0020 #include <QCheckBox>
0021 #include <QComboBox>
0022 #include <QDialog>
0023 #include <QDialogButtonBox>
0024 #include <QGridLayout>
0025 #include <QLabel>
0026 #include <QPushButton>
0027 #include <QSpinBox>
0028 #include <QWhatsThis>
0029 #include <QStorageInfo>
0030 
0031 
0032 static const int s_mp3Bitrates[] = {
0033     32,
0034     40,
0035     48,
0036     56,
0037     64,
0038     80,
0039     96,
0040     112,
0041     128,
0042     160,
0043     192,
0044     224,
0045     256,
0046     320,
0047     0 // just used for the loops below
0048 };
0049 
0050 
0051 static const int PICTURE_SIZE_ORIGINAL = 0;
0052 static const int PICTURE_SIZE_640 = 1;
0053 static const int PICTURE_SIZE_320 = 2;
0054 static const int PICTURE_SIZE_CUSTOM = 3;
0055 static const int PICTURE_SIZE_MAX = 4;
0056 
0057 static const KLazyLocalizedString s_pictureSizeNames[] = {
0058     kli18n("Keep original dimensions"),
0059     kli18n("640x? (automatic height)"),
0060     kli18n("320x? (automatic height)"),
0061     kli18n("Custom")
0062 };
0063 
0064 
0065 K3b::VideoDVDRippingWidget::VideoDVDRippingWidget( QWidget* parent )
0066     : QWidget( parent ),
0067       m_neededSize( 0 )
0068 {
0069     setupUi( this );
0070 
0071     m_editBaseDir->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly );
0072 
0073     //
0074     // Example filename pattern
0075     //
0076     m_comboFilenamePattern->addItem( QString( "%b - %1 %t (%n %a %c)").arg(i18n("Title") ) );
0077     m_comboFilenamePattern->addItem( QString( "%{volumeid} (%{title})" ) );
0078 
0079 
0080     //
0081     // Add the Audio bitrates
0082     //
0083     for( int i = 0; s_mp3Bitrates[i]; ++i )
0084         m_comboAudioBitrate->addItem( i18n("%1 kbps" ,s_mp3Bitrates[i]) );
0085 
0086 
0087     for( int i = 0; i < K3b::VideoDVDTitleTranscodingJob::VIDEO_CODEC_NUM_ENTRIES; ++i ) {
0088         K3b::VideoDVDTitleTranscodingJob::VideoCodec codec( (K3b::VideoDVDTitleTranscodingJob::VideoCodec)i );
0089         if( K3b::VideoDVDTitleTranscodingJob::transcodeBinaryHasSupportFor( codec ) )
0090             m_comboVideoCodec->insertItem( i,
0091                                            K3b::VideoDVDTitleTranscodingJob::videoCodecString( codec ),
0092                                            K3b::VideoDVDTitleTranscodingJob::videoCodecDescription( codec ) );
0093     }
0094     for( int i = 0; i < K3b::VideoDVDTitleTranscodingJob::AUDIO_CODEC_NUM_ENTRIES; ++i ) {
0095         K3b::VideoDVDTitleTranscodingJob::AudioCodec codec( (K3b::VideoDVDTitleTranscodingJob::AudioCodec)i );
0096         if( K3b::VideoDVDTitleTranscodingJob::transcodeBinaryHasSupportFor( codec ) )
0097             m_comboAudioCodec->insertItem( i,
0098                                            K3b::VideoDVDTitleTranscodingJob::audioCodecString( codec ),
0099                                            K3b::VideoDVDTitleTranscodingJob::audioCodecDescription( codec ) );
0100     }
0101 
0102     for( int i = 0; i < PICTURE_SIZE_MAX; ++i ) {
0103         m_comboVideoSize->addItem( s_pictureSizeNames[i].toString() );
0104     }
0105 
0106     slotAudioCodecChanged( m_comboAudioCodec->selectedValue() );
0107 
0108     connect( m_comboAudioBitrate, SIGNAL(textChanged(QString)),
0109              this, SIGNAL(changed()) );
0110     connect( m_spinVideoBitrate, SIGNAL(valueChanged(int)),
0111              this, SIGNAL(changed()) );
0112     connect( m_checkBlankReplace, SIGNAL(toggled(bool)),
0113              this, SIGNAL(changed()) );
0114     connect( m_editBlankReplace, SIGNAL(textChanged(QString)),
0115              this, SIGNAL(changed()) );
0116     connect( m_comboFilenamePattern, SIGNAL(textChanged(QString)),
0117              this, SIGNAL(changed()) );
0118     connect( m_editBaseDir, SIGNAL(textChanged(QString)),
0119              this, SIGNAL(changed()) );
0120 
0121     connect( m_comboAudioCodec, SIGNAL(valueChanged(int)),
0122              this, SLOT(slotAudioCodecChanged(int)) );
0123     connect( m_specialStringsLabel, SIGNAL(leftClickedUrl()),
0124              this, SLOT(slotSeeSpecialStrings()) );
0125     connect( m_buttonCustomPictureSize, SIGNAL(clicked()),
0126              this, SLOT(slotCustomPictureSize()) );
0127     connect( m_comboVideoSize, SIGNAL(activated(int)),
0128              this, SLOT(slotVideoSizeChanged(int)) );
0129 
0130     // refresh every 2 seconds
0131     m_freeSpaceUpdateTimer = new QTimer( this );
0132     connect( m_freeSpaceUpdateTimer, SIGNAL(timeout()),
0133              this, SLOT(slotUpdateFreeTempSpace()) );
0134     m_freeSpaceUpdateTimer->start(2000);
0135     slotUpdateFreeTempSpace();
0136 }
0137 
0138 
0139 K3b::VideoDVDRippingWidget::~VideoDVDRippingWidget()
0140 {
0141 }
0142 
0143 
0144 K3b::VideoDVDTitleTranscodingJob::VideoCodec K3b::VideoDVDRippingWidget::selectedVideoCodec() const
0145 {
0146     return (K3b::VideoDVDTitleTranscodingJob::VideoCodec)m_comboVideoCodec->selectedValue();
0147 }
0148 
0149 
0150 QSize K3b::VideoDVDRippingWidget::selectedPictureSize() const
0151 {
0152     switch( m_comboVideoSize->currentIndex() ) {
0153     case PICTURE_SIZE_ORIGINAL:
0154         return QSize(0,0);
0155     case PICTURE_SIZE_640:
0156         return QSize(640,0);
0157     case PICTURE_SIZE_320:
0158         return QSize(320,0);
0159     default:
0160         return m_customVideoSize;
0161     }
0162 }
0163 
0164 
0165 void K3b::VideoDVDRippingWidget::setSelectedPictureSize( const QSize& size )
0166 {
0167     m_customVideoSize = size;
0168     if( size == QSize(0,0) )
0169         m_comboVideoSize->setCurrentIndex( PICTURE_SIZE_ORIGINAL );
0170     else if( size == QSize(640,0) )
0171         m_comboVideoSize->setCurrentIndex( PICTURE_SIZE_640 );
0172     else if( size == QSize(320,0) )
0173         m_comboVideoSize->setCurrentIndex( PICTURE_SIZE_320 );
0174     else {
0175         m_comboVideoSize->setItemText( PICTURE_SIZE_CUSTOM,
0176                                        s_pictureSizeNames[PICTURE_SIZE_CUSTOM].toString()
0177                                        + QString(" (%1x%2)")
0178                                        .arg(size.width() == 0 ? i18n("auto") : QString::number(size.width()))
0179                                        .arg(size.height() == 0 ? i18n("auto") : QString::number(size.height())));
0180         m_comboVideoSize->setCurrentIndex( PICTURE_SIZE_CUSTOM );
0181     }
0182 }
0183 
0184 
0185 void K3b::VideoDVDRippingWidget::setSelectedVideoCodec( K3b::VideoDVDTitleTranscodingJob::VideoCodec codec )
0186 {
0187     m_comboVideoCodec->setSelectedValue( (int)codec );
0188 }
0189 
0190 
0191 K3b::VideoDVDTitleTranscodingJob::AudioCodec K3b::VideoDVDRippingWidget::selectedAudioCodec() const
0192 {
0193     return (K3b::VideoDVDTitleTranscodingJob::AudioCodec)m_comboAudioCodec->selectedValue();
0194 }
0195 
0196 
0197 void K3b::VideoDVDRippingWidget::setSelectedAudioCodec( K3b::VideoDVDTitleTranscodingJob::AudioCodec codec )
0198 {
0199     m_comboAudioCodec->setSelectedValue( (int)codec );
0200     slotAudioCodecChanged( (int)codec );
0201 }
0202 
0203 
0204 int K3b::VideoDVDRippingWidget::selectedAudioBitrate() const
0205 {
0206     if( selectedAudioCodec() == K3b::VideoDVDTitleTranscodingJob::AUDIO_CODEC_MP3 )
0207         return s_mp3Bitrates[m_comboAudioBitrate->currentIndex()];
0208     else
0209         return m_spinAudioBitrate->value();
0210 }
0211 
0212 
0213 void K3b::VideoDVDRippingWidget::setSelectedAudioBitrate( int bitrate )
0214 {
0215     m_spinAudioBitrate->setValue( bitrate );
0216 
0217     // select the bitrate closest to "bitrate"
0218     int bi = 0;
0219     int diff = 1000;
0220     for( int i = 0; s_mp3Bitrates[i]; ++i ) {
0221         int newDiff = s_mp3Bitrates[i] - bitrate;
0222         if( newDiff < 0 )
0223             newDiff = -1 * newDiff;
0224         if( newDiff < diff ) {
0225             diff = newDiff;
0226             bi = i;
0227         }
0228     }
0229 
0230     m_comboAudioBitrate->setCurrentIndex( bi );
0231 }
0232 
0233 
0234 void K3b::VideoDVDRippingWidget::slotUpdateFreeTempSpace()
0235 {
0236     QString path = m_editBaseDir->url().toLocalFile();
0237 
0238     if( !QFile::exists( path ) )
0239         path.truncate( path.lastIndexOf('/') );
0240 
0241     const KColorScheme colorScheme( isEnabled() ? QPalette::Normal : QPalette::Disabled, KColorScheme::Window );
0242     QColor textColor;
0243 
0244     const QStorageInfo free( path );
0245     if( free.isValid() ) {
0246         m_labelFreeSpace->setText( KIO::convertSizeFromKiB(free.bytesFree()/1024) );
0247         if( free.bytesFree() < m_neededSize )
0248             textColor = colorScheme.foreground( KColorScheme::NegativeText ).color();
0249         else
0250             textColor = colorScheme.foreground( KColorScheme::NormalText ).color();
0251     }
0252     else {
0253         textColor = colorScheme.foreground( KColorScheme::NormalText ).color();
0254         m_labelFreeSpace->setText("-");
0255     }
0256 
0257     QPalette pal( m_labelFreeSpace->palette() );
0258     pal.setColor( QPalette::Text, textColor );
0259     m_labelFreeSpace->setPalette( pal );
0260 }
0261 
0262 
0263 void K3b::VideoDVDRippingWidget::setNeededSize( KIO::filesize_t size )
0264 {
0265     m_neededSize = size;
0266     if( size > 0 )
0267         m_labelNeededSpace->setText( KIO::convertSize( size ) );
0268     else
0269         m_labelNeededSpace->setText( i18n("unknown") );
0270 
0271     slotUpdateFreeTempSpace();
0272 }
0273 
0274 
0275 void K3b::VideoDVDRippingWidget::slotSeeSpecialStrings()
0276 {
0277     QWhatsThis::showText( QCursor::pos(),
0278                           i18n( "<p><b>Pattern special strings:</b>"
0279                                 "<p>The following strings will be replaced with their respective meaning in every "
0280                                 "track name.<br>"
0281                                 "<p><table border=\"0\">"
0282                                 "<tr><td></td><td><em>Meaning</em></td><td><em>Alternatives</em></td></tr>"
0283                                 "<tr><td>%t</td><td>title number</td><td>%{t} or %{title_number}</td></tr>"
0284                                 "<tr><td>%i</td><td>volume id (mostly the name of the Video DVD)</td><td>%{i} or %{volume_id}</td></tr>"
0285                                 "<tr><td>%b</td><td>beautified volume id</td><td>%{b} or %{beautified_volume_id}</td></tr>"
0286                                 "<tr><td>%l</td><td>two chars language code</td><td>%{l} or %{lang_code}</td></tr>"
0287                                 "<tr><td>%n</td><td>language name</td><td>%{n} or %{lang_name}</td></tr>"
0288                                 "<tr><td>%a</td><td>audio format (on the Video DVD)</td><td>%{a} or %{audio_format}</td></tr>"
0289                                 "<tr><td>%c</td><td>number of audio channels (on the Video DVD)</td><td>%{c} or %{channels}</td></tr>"
0290                                 "<tr><td>%v</td><td>size of the original video</td><td>%{v} or %{orig_video_size}</td></tr>"
0291                                 "<tr><td>%s</td><td>size of the resulting video (<em>Caution: auto-clipping values are not taken into account.</em>)</td><td>%{s} or %{video_size}</td></tr>"
0292                                 "<tr><td>%r</td><td>aspect ratio of the original video</td><td>%{r} or %{aspect_ratio}</td></tr>"
0293                                 "<tr><td>%d</td><td>current date</td><td>%{d} or %{date}</td></tr>"
0294                                 "</table>"
0295                                 "<p><em>Hint: K3b also accepts slight variations of the long special strings. "
0296                                 "One can, for example, leave out the underscores.</em>"),
0297                           this );
0298 }
0299 
0300 
0301 void K3b::VideoDVDRippingWidget::slotAudioCodecChanged( int codec )
0302 {
0303     switch( codec ) {
0304     case K3b::VideoDVDTitleTranscodingJob::AUDIO_CODEC_MP3:
0305         m_stackAudioQuality->setCurrentWidget( m_stackPageAudioQualityMp3 );
0306         break;
0307     case K3b::VideoDVDTitleTranscodingJob::AUDIO_CODEC_AC3_STEREO:
0308         m_stackAudioQuality->setCurrentWidget( m_stackPageAudioQualityAC3 );
0309         break;
0310     case K3b::VideoDVDTitleTranscodingJob::AUDIO_CODEC_AC3_PASSTHROUGH:
0311         m_stackAudioQuality->setCurrentWidget( m_stackPageAudioQualityAC3Pt );
0312         break;
0313     }
0314 
0315     emit changed();
0316 }
0317 
0318 
0319 void K3b::VideoDVDRippingWidget::slotVideoSizeChanged( int sizeIndex )
0320 {
0321     if( sizeIndex == PICTURE_SIZE_CUSTOM )
0322         slotCustomPictureSize();
0323     else
0324         emit changed();
0325 }
0326 
0327 
0328 void K3b::VideoDVDRippingWidget::slotCustomPictureSize()
0329 {
0330     QDialog dlg( this );
0331     dlg.setWindowTitle( i18n("Video Picture Size") );
0332 
0333     QLabel* label = new QLabel( i18n("<p>Please choose the width and height of the resulting video. "
0334                                      "If one value is set to <em>Auto</em> K3b will choose this value "
0335                                      "depending on the aspect ratio of the video picture.<br>"
0336                                      "Be aware that setting both the width and the height to fixed values "
0337                                      "will result in no aspect ratio correction being performed."),
0338                                 &dlg );
0339     label->setWordWrap( true );
0340     QSpinBox* spinWidth = new QSpinBox( &dlg );
0341     spinWidth->setRange( 0, 20000 );
0342     spinWidth->setSingleStep( 16 );
0343     QSpinBox* spinHeight = new QSpinBox( &dlg );
0344     spinHeight->setRange( 0, 20000 );
0345     spinHeight->setSingleStep( 16 );
0346     spinWidth->setSpecialValueText( i18n("Auto") );
0347     spinHeight->setSpecialValueText( i18n("Auto") );
0348     QLabel* labelW = new QLabel( i18n("Width:"), &dlg );
0349     labelW->setBuddy( spinWidth );
0350     QLabel* labelH = new QLabel( i18n("Height:"), &dlg );
0351     labelH->setBuddy( spinHeight );
0352     labelW->setAlignment( Qt::AlignRight|Qt::AlignVCenter );
0353     labelH->setAlignment( Qt::AlignRight|Qt::AlignVCenter );
0354 
0355     QDialogButtonBox* buttonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dlg );
0356     connect( buttonBox, SIGNAL(accepted()), &dlg, SLOT(accept()) );
0357     connect( buttonBox, SIGNAL(rejected()), &dlg, SLOT(reject()) );
0358 
0359     QGridLayout* grid = new QGridLayout( &dlg );
0360     grid->setContentsMargins( 0, 0, 0, 0 );
0361     grid->addWidget( label, 0, 0, 1, 4 );
0362     grid->addWidget( labelW, 1, 0 );
0363     grid->addWidget( spinWidth, 1, 1 );
0364     grid->addWidget( labelH, 1, 2 );
0365     grid->addWidget( spinHeight, 1, 3 );
0366     grid->addWidget( buttonBox, 2, 0, 1, 4 );
0367 
0368     spinWidth->setValue( m_customVideoSize.width() );
0369     spinHeight->setValue( m_customVideoSize.height() );
0370 
0371     if( dlg.exec() ) {
0372         setSelectedPictureSize( QSize( spinWidth->value(), spinHeight->value() ) );
0373         emit changed();
0374     }
0375 }
0376 
0377 #include "moc_k3bvideodvdrippingwidget.cpp"