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"