1
2 #include "cdopener.h"
3 #include "../metadata/tagengine.h"
4 #include "../config.h"
5 #include "../options.h"
6 #include "../outputdirectory.h"
7 #include "../global.h"
8
9 #include <KLocale>
10 #include <KPushButton>
11 #include <KLineEdit>
12 #include <KComboBox>
13 #include <KNumInput>
14 #include <KTextEdit>
15 #include <KFileDialog>
16 #include <KMessageBox>
17 #include <KStandardDirs>
18 #include <KInputDialog>
19 #include <KIcon>
20
21 #include <QApplication>
22 #include <QLayout>
23 #include <QBoxLayout>
24 #include <QGridLayout>
25 #include <QLabel>
26 #include <QGroupBox>
27 #include <QTreeWidget>
28 #include <QDateTime>
29 #include <QColor>
30 #include <QDir>
31 #include <QFile>
32 #include <QCheckBox>
33 #include <QHeaderView>
34
35 #include <solid/device.h>
36 #include <solid/block.h>
37 #include <solid/opticaldisc.h>
38
39
PlayerWidget(Phonon::MediaObject * mediaObject,int _track,QTreeWidgetItem * _treeWidgetItem,QWidget * parent,Qt::WindowFlags f)40 PlayerWidget::PlayerWidget( Phonon::MediaObject *mediaObject, int _track, QTreeWidgetItem *_treeWidgetItem, QWidget *parent, Qt::WindowFlags f )
41 : QWidget( parent, f ),
42 track( _track ),
43 m_treeWidgetItem( _treeWidgetItem )
44 {
45 const int fontHeight = QFontMetrics(QApplication::font()).boundingRect("M").size().height();
46
47 QHBoxLayout *trackPlayerBox = new QHBoxLayout();
48 setLayout( trackPlayerBox );
49
50 pStartPlayback = new KPushButton( KIcon("media-playback-start"), "", this );
51 pStartPlayback->setFixedSize( 1.5*fontHeight, 1.5*fontHeight );
52 trackPlayerBox->addWidget( pStartPlayback );
53 connect( pStartPlayback, SIGNAL(clicked()), this, SLOT(startPlaybackClicked()) );
54 pStopPlayback = new KPushButton( KIcon("media-playback-stop"), "", this );
55 pStopPlayback->setFixedSize( 1.5*fontHeight, 1.5*fontHeight );
56 pStopPlayback->hide();
57 trackPlayerBox->addWidget( pStopPlayback );
58 connect( pStopPlayback, SIGNAL(clicked()), this, SLOT(stopPlaybackClicked()) );
59 seekSlider = new Phonon::SeekSlider( this );
60 seekSlider->setMediaObject( mediaObject );
61 seekSlider->setIconVisible( false );
62 seekSlider->hide();
63 trackPlayerBox->addWidget( seekSlider, 1 );
64 trackPlayerBox->addStretch();
65 }
66
~PlayerWidget()67 PlayerWidget::~PlayerWidget()
68 {}
69
startPlaybackClicked()70 void PlayerWidget::startPlaybackClicked()
71 {
72 /* playing = true;
73 pStartPlayback->hide();
74 pStopPlayback->show();
75 seekSlider->show();*/
76 emit startPlayback( track );
77 }
78
stopPlaybackClicked()79 void PlayerWidget::stopPlaybackClicked()
80 {
81 /* playing = false;
82 pStartPlayback->show();
83 pStopPlayback->hide();
84 seekSlider->hide();*/
85 emit stopPlayback();
86 }
87
trackChanged(int _track)88 void PlayerWidget::trackChanged( int _track )
89 {
90 if( _track != track )
91 {
92 playing = false;
93 pStartPlayback->show();
94 pStopPlayback->hide();
95 seekSlider->hide();
96 }
97 else
98 {
99 playing = true;
100 pStartPlayback->hide();
101 pStopPlayback->show();
102 seekSlider->show();
103 }
104 }
105
106
CDOpener(Config * _config,const QString & _device,QWidget * parent,Qt::WFlags f)107 CDOpener::CDOpener( Config *_config, const QString& _device, QWidget *parent, Qt::WFlags f )
108 : KDialog( parent, f ),
109 noCdFound( false ),
110 config( _config ),
111 cdDrive( 0 ),
112 cdParanoia( 0 ),
113 cddb( 0 ),
114 cdTextFound( false ),
115 cddbFound( false )
116 {
117 setButtons( 0 );
118
119 page = CdOpenPage;
120
121 const int fontHeight = QFontMetrics(QApplication::font()).boundingRect("M").size().height();
122
123 // let the dialog look nice
124 setCaption( i18n("Add CD tracks") );
125 setWindowIcon( KIcon("media-optical-audio") );
126
127 QWidget *widget = new QWidget( this );
128 QGridLayout *mainGrid = new QGridLayout( widget );
129 QGridLayout *topGrid = new QGridLayout();
130 mainGrid->addLayout( topGrid, 0, 0 );
131 setMainWidget( widget );
132
133 lSelector = new QLabel( i18n("1. Select CD tracks"), widget );
134 QFont font;
135 font.setBold( true );
136 lSelector->setFont( font );
137 topGrid->addWidget( lSelector, 0, 0 );
138 lOptions = new QLabel( i18n("2. Set conversion options"), widget );
139 topGrid->addWidget( lOptions, 0, 1 );
140
141 // draw a horizontal line
142 QFrame *lineFrame = new QFrame( widget );
143 lineFrame->setFrameShape( QFrame::HLine );
144 lineFrame->setFrameShadow( QFrame::Sunken );
145 mainGrid->addWidget( lineFrame, 1, 0 );
146
147
148 // CD Opener Widget
149
150 cdOpenerWidget = new QWidget( widget );
151 mainGrid->addWidget( cdOpenerWidget, 2, 0 );
152
153 // the grid for all widgets in the dialog
154 QGridLayout *gridLayout = new QGridLayout( cdOpenerWidget );
155
156 // the box for the cover and artist/album grid
157 QHBoxLayout *topBoxLayout = new QHBoxLayout();
158 gridLayout->addLayout( topBoxLayout, 0, 0 );
159
160 // the album cover
161 QLabel *lAlbumCover = new QLabel( "", cdOpenerWidget );
162 topBoxLayout->addWidget( lAlbumCover );
163 lAlbumCover->setPixmap( QPixmap( KStandardDirs::locate("data","soundkonverter/images/nocover.png") ) );
164 lAlbumCover->setContentsMargins( 0, 0, 0.5*fontHeight, 0 );
165
166 // the grid for the artist and album input
167 QGridLayout *topGridLayout = new QGridLayout();
168 topBoxLayout->addLayout( topGridLayout );
169
170 // set up the first row at the top
171 QLabel *lArtistLabel = new QLabel( i18n("Album artist:"), cdOpenerWidget );
172 topGridLayout->addWidget( lArtistLabel, 0, 0 );
173 lArtist = new KLineEdit( cdOpenerWidget );
174 topGridLayout->addWidget( lArtist, 0, 1 );
175 connect( lArtist, SIGNAL(textChanged(const QString&)), this, SLOT(artistChanged(const QString&)) );
176
177 // set up the second row at the top
178 QLabel *lAlbumLabel = new QLabel( i18n("Album:"), cdOpenerWidget );
179 topGridLayout->addWidget( lAlbumLabel, 1, 0 );
180 lAlbum = new KLineEdit( cdOpenerWidget );
181 topGridLayout->addWidget( lAlbum, 1, 1 );
182
183 // set up the third row at the top
184 QLabel *lDiscLabel = new QLabel( i18n("Disc No.:"), cdOpenerWidget );
185 topGridLayout->addWidget( lDiscLabel, 2, 0 );
186 // add a horizontal box layout for the year and genre
187 QHBoxLayout *yearBox = new QHBoxLayout();
188 topGridLayout->addLayout( yearBox, 2, 1 );
189 // and fill it up
190 iDisc = new KIntSpinBox( 1, 99, 1, 1, cdOpenerWidget );
191 yearBox->addWidget( iDisc );
192 QLabel *lDiscTotalLabel = new QLabel( i18nc("Track/Disc No. x of y","of"), cdOpenerWidget );
193 lDiscTotalLabel->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
194 yearBox->addWidget( lDiscTotalLabel );
195 iDiscTotal = new KIntSpinBox( 1, 99, 1, 1, cdOpenerWidget );
196 yearBox->addWidget( iDiscTotal );
197 QLabel *lYearLabel = new QLabel( i18n("Year:"), cdOpenerWidget );
198 lYearLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
199 yearBox->addWidget( lYearLabel );
200 iYear = new KIntSpinBox( 0, 99999, 1, QDate::currentDate().year(), cdOpenerWidget );
201 yearBox->addWidget( iYear );
202 QLabel *lGenreLabel = new QLabel( i18n("Genre:"), cdOpenerWidget );
203 lGenreLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
204 yearBox->addWidget( lGenreLabel );
205 cGenre = new KComboBox( true, cdOpenerWidget );
206 cGenre->addItems( config->tagEngine()->genreList );
207 cGenre->setEditText( "" );
208 KCompletion *cGenreCompletion = cGenre->completionObject();
209 cGenreCompletion->insertItems( config->tagEngine()->genreList );
210 cGenreCompletion->setIgnoreCase( true );
211 yearBox->addWidget( cGenre );
212
213 topGridLayout->setColumnStretch( 1, 1 );
214
215
216 // generate the list view for the tracks
217 trackList = new QTreeWidget( cdOpenerWidget );
218 gridLayout->addWidget( trackList, 1, 0 );
219 // and fill in the headers
220 trackList->setColumnCount( 5 );
221 QStringList labels;
222 labels.append( i18nc("column title","Rip") );
223 labels.append( i18n("Track") );
224 labels.append( i18n("Artist") );
225 labels.append( i18n("Composer") );
226 labels.append( i18n("Title") );
227 labels.append( i18n("Length") );
228 labels.append( i18n("Player") );
229 trackList->setHeaderLabels( labels );
230 trackList->setSelectionBehavior( QAbstractItemView::SelectRows );
231 trackList->setSelectionMode( QAbstractItemView::ExtendedSelection );
232 trackList->setSortingEnabled( false );
233 trackList->setRootIsDecorated( false );
234 trackList->header()->setResizeMode( Column_Artist, QHeaderView::ResizeToContents );
235 trackList->header()->setResizeMode( Column_Composer, QHeaderView::ResizeToContents );
236 trackList->header()->setResizeMode( Column_Title, QHeaderView::ResizeToContents );
237 // trackList->setMouseTracking( true );
238 connect( trackList, SIGNAL(itemSelectionChanged()), this, SLOT(trackChanged()) );
239 // connect( trackList, SIGNAL(itemEntered(QTreeWidgetItem*,int)), this, SLOT(itemHighlighted(QTreeWidgetItem*,int)) );
240 gridLayout->setRowStretch( 1, 1 );
241
242
243 // create the box at the bottom for editing the tags
244 tagGroupBox = new QGroupBox( i18n("No track selected"), cdOpenerWidget );
245 gridLayout->addWidget( tagGroupBox, 2, 0 );
246 QGridLayout *tagGridLayout = new QGridLayout( tagGroupBox );
247
248 // add the up and down buttons
249 pTrackUp = new KPushButton( "", tagGroupBox );
250 pTrackUp->setIcon( KIcon("arrow-up") );
251 pTrackUp->setFixedSize( pTrackUp->sizeHint().height(), pTrackUp->sizeHint().height() );
252 pTrackUp->setAutoRepeat( true );
253 connect( pTrackUp, SIGNAL(clicked()), this, SLOT(trackUpPressed()) );
254 tagGridLayout->addWidget( pTrackUp, 0, 0 );
255 pTrackDown = new KPushButton( "", tagGroupBox );
256 pTrackDown->setIcon( KIcon("arrow-down") );
257 pTrackDown->setFixedSize( pTrackDown->sizeHint().height(), pTrackDown->sizeHint().height() );
258 pTrackDown->setAutoRepeat( true );
259 connect( pTrackDown, SIGNAL(clicked()), this, SLOT(trackDownPressed()) );
260 tagGridLayout->addWidget( pTrackDown, 1, 0 );
261
262 setTabOrder(pTrackDown, pTrackUp);
263
264 // add the inputs
265 // add a horizontal box layout for the title
266 QHBoxLayout *trackTitleBox = new QHBoxLayout();
267 tagGridLayout->addLayout( trackTitleBox, 0, 2 );
268 // and fill it up
269 QLabel *lTrackTitleLabel = new QLabel( i18n("Title:"), tagGroupBox );
270 tagGridLayout->addWidget( lTrackTitleLabel, 0, 1 );
271 lTrackTitle = new KLineEdit( tagGroupBox );
272 trackTitleBox->addWidget( lTrackTitle );
273 connect( lTrackTitle, SIGNAL(textChanged(const QString&)), this, SLOT(trackTitleChanged(const QString&)) );
274 pTrackTitleEdit = new KPushButton( "", tagGroupBox );
275 pTrackTitleEdit->setIcon( KIcon("document-edit") );
276 pTrackTitleEdit->setFixedSize( lTrackTitle->sizeHint().height(), lTrackTitle->sizeHint().height() );
277 pTrackTitleEdit->hide();
278 trackTitleBox->addWidget( pTrackTitleEdit );
279 connect( pTrackTitleEdit, SIGNAL(clicked()), this, SLOT(editTrackTitleClicked()) );
280 // add a horizontal box layout for the composer
281 QHBoxLayout *trackArtistBox = new QHBoxLayout();
282 tagGridLayout->addLayout( trackArtistBox, 1, 2 );
283 // and fill it up
284 QLabel *lTrackArtistLabel = new QLabel( i18n("Artist:"), tagGroupBox );
285 tagGridLayout->addWidget( lTrackArtistLabel, 1, 1 );
286 lTrackArtist = new KLineEdit( tagGroupBox );
287 trackArtistBox->addWidget( lTrackArtist );
288 connect( lTrackArtist, SIGNAL(textChanged(const QString&)), this, SLOT(trackArtistChanged(const QString&)) );
289 pTrackArtistEdit = new KPushButton( "", tagGroupBox );
290 pTrackArtistEdit->setIcon( KIcon("document-edit") );
291 pTrackArtistEdit->setFixedSize( lTrackArtist->sizeHint().height(), lTrackArtist->sizeHint().height() );
292 pTrackArtistEdit->hide();
293 trackArtistBox->addWidget( pTrackArtistEdit );
294 connect( pTrackArtistEdit, SIGNAL(clicked()), this, SLOT(editTrackArtistClicked()) );
295 QLabel *lTrackComposerLabel = new QLabel( i18n("Composer:"), tagGroupBox );
296 trackArtistBox->addWidget( lTrackComposerLabel );
297 lTrackComposer = new KLineEdit( tagGroupBox );
298 trackArtistBox->addWidget( lTrackComposer );
299 connect( lTrackComposer, SIGNAL(textChanged(const QString&)), this, SLOT(trackComposerChanged(const QString&)) );
300 pTrackComposerEdit = new KPushButton( "", tagGroupBox );
301 pTrackComposerEdit->setIcon( KIcon("document-edit") );
302 pTrackComposerEdit->setFixedSize( lTrackComposer->sizeHint().height(), lTrackComposer->sizeHint().height() );
303 pTrackComposerEdit->hide();
304 trackArtistBox->addWidget( pTrackComposerEdit );
305 connect( pTrackComposerEdit, SIGNAL(clicked()), this, SLOT(editTrackComposerClicked()) );
306 // add a horizontal box layout for the comment
307 QHBoxLayout *trackCommentBox = new QHBoxLayout();
308 tagGridLayout->addLayout( trackCommentBox, 2, 2 );
309 // and fill it up
310 QLabel *lTrackCommentLabel = new QLabel( i18n("Comment:"), tagGroupBox );
311 tagGridLayout->addWidget( lTrackCommentLabel, 2, 1 );
312 tTrackComment = new KTextEdit( tagGroupBox );
313 trackCommentBox->addWidget( tTrackComment );
314 tTrackComment->setFixedHeight( 4*fontHeight );
315 connect( tTrackComment, SIGNAL(textChanged()), this, SLOT(trackCommentChanged()) );
316 pTrackCommentEdit = new KPushButton( "", tagGroupBox );
317 pTrackCommentEdit->setIcon( KIcon("document-edit") );
318 pTrackCommentEdit->setFixedSize( lTrackTitle->sizeHint().height(), lTrackTitle->sizeHint().height() );
319 pTrackCommentEdit->hide();
320 trackCommentBox->addWidget( pTrackCommentEdit );
321 connect( pTrackCommentEdit, SIGNAL(clicked()), this, SLOT(editTrackCommentClicked()) );
322
323
324 audioOutput = new Phonon::AudioOutput( Phonon::MusicCategory, this );
325 audioOutput->setVolume( 0.5 );
326 mediaObject = new Phonon::MediaObject( this );
327 mediaObject->setTickInterval( 500 );
328
329 Phonon::createPath( mediaObject, audioOutput );
330
331 mediaController = new Phonon::MediaController( mediaObject );
332 mediaController->setAutoplayTitles( false );
333
334 connect( mediaController, SIGNAL(titleChanged(int)), this, SLOT(playbackTitleChanged(int)) );
335 connect( mediaObject, SIGNAL(stateChanged(Phonon::State,Phonon::State)), this, SLOT(playbackStateChanged(Phonon::State,Phonon::State)) );
336
337
338
339 // Cd Opener Overlay Widget
340
341 cdOpenerOverlayWidget = new QWidget( widget );
342 mainGrid->addWidget( cdOpenerOverlayWidget, 2, 0 );
343 QHBoxLayout *cdOpenerOverlayLayout = new QHBoxLayout();
344 cdOpenerOverlayWidget->setLayout( cdOpenerOverlayLayout );
345 // lOverlayLabel = new QLabel( i18n("Please wait, trying to read audio CD ..."), cdOpenerOverlayWidget );
346 lOverlayLabel = new QLabel( cdOpenerOverlayWidget );
347 cdOpenerOverlayLayout->addWidget( lOverlayLabel );
348 lOverlayLabel->setAlignment( Qt::AlignCenter );
349 cdOpenerOverlayWidget->setAutoFillBackground( true );
350 QPalette newPalette = cdOpenerOverlayWidget->palette();
351 newPalette.setBrush( QPalette::Window, brushSetAlpha( newPalette.window(), 192 ) );
352 cdOpenerOverlayWidget->setPalette( newPalette );
353
354
355 // Conversion Options Widget
356
357 // add a vertical box layout for the options widget
358 QVBoxLayout *optionsBox = new QVBoxLayout();
359 mainGrid->addLayout( optionsBox, 2, 0 );
360
361 options = new Options( config, i18n("Select your desired output options and click on \"Ok\"."), widget );
362 optionsBox->addWidget( options );
363 options->hide();
364 optionsBox->addStretch();
365
366
367 // draw a horizontal line
368 QFrame *buttonLineFrame = new QFrame( widget );
369 buttonLineFrame->setFrameShape( QFrame::HLine );
370 buttonLineFrame->setFrameShadow( QFrame::Sunken );
371 buttonLineFrame->setFrameShape( QFrame::HLine );
372 mainGrid->addWidget( buttonLineFrame, 4, 0 );
373
374 // add a horizontal box layout for the control elements
375 QHBoxLayout *controlBox = new QHBoxLayout();
376 mainGrid->addLayout( controlBox, 5, 0 );
377
378 // add the control elements
379 pSaveCue = new KPushButton( KIcon("document-save"), i18n("Save cue sheet..."), widget );
380 controlBox->addWidget( pSaveCue );
381 connect( pSaveCue, SIGNAL(clicked()), this, SLOT(saveCuesheetClicked()) );
382 controlBox->addSpacing( fontHeight );
383
384 pCDDB = new KPushButton( KIcon("download"), i18n("Request CDDB"), widget );
385 controlBox->addWidget( pCDDB );
386 connect( pCDDB, SIGNAL(clicked()), this, SLOT(requestCddb()) );
387 controlBox->addStretch();
388
389 cEntireCd = new QCheckBox( i18n("Rip entire CD to one file"), widget );
390 QStringList errorList;
391 cEntireCd->setEnabled( config->pluginLoader()->canRipEntireCd(&errorList) );
392 if( !cEntireCd->isEnabled() )
393 {
394 QPalette notificationPalette = cEntireCd->palette();
395 notificationPalette.setColor( QPalette::Disabled, QPalette::WindowText, QColor(174,127,130) ); // QColor(181,96,101)
396 cEntireCd->setPalette( notificationPalette );
397 if( !errorList.isEmpty() )
398 {
399 errorList.prepend( i18n("Ripping an entire cd to a single file is not supported by the installed backends.\nPossible solutions are listed below.\n") );
400 }
401 else
402 {
403 errorList += i18n("Ripping an entire cd to a single file is not supported by the installed backends.\nPlease check your distribution's package manager in order to install an additional ripper plugin which supports ripping to one file.");
404 }
405 cEntireCd->setToolTip( errorList.join("\n") );
406 }
407 controlBox->addWidget( cEntireCd );
408 controlBox->addSpacing( 2*fontHeight );
409
410 pProceed = new KPushButton( KIcon("go-next"), i18n("Proceed"), widget );
411 controlBox->addWidget( pProceed );
412 connect( pProceed, SIGNAL(clicked()), this, SLOT(proceedClicked()) );
413 pAdd = new KPushButton( KIcon("dialog-ok"), i18n("Ok"), widget );
414 controlBox->addWidget( pAdd );
415 pAdd->hide();
416 connect( pAdd, SIGNAL(clicked()), this, SLOT(addClicked()) );
417 pCancel = new KPushButton( KIcon("dialog-cancel"), i18n("Cancel"), widget );
418 controlBox->addWidget( pCancel );
419 connect( pCancel, SIGNAL(clicked()), this, SLOT(reject()) );
420
421 connect( &fadeTimer, SIGNAL(timeout()), this, SLOT(fadeAnim()) );
422 fadeAlpha = 255.0f;
423
424
425 cddb = new KCDDB::Client();
426 connect( cddb, SIGNAL(finished(KCDDB::Result)), this, SLOT(lookup_cddb_done(KCDDB::Result)) );
427
428
429 // set up timeout timer
430 timeoutTimer.setSingleShot( true );
431 connect( &timeoutTimer, SIGNAL(timeout()), this, SLOT(timeout()) );
432
433
434 if( !_device.isEmpty() )
435 {
436 device = _device;
437 }
438 else
439 {
440 const QMap<QString,QString> devices = cdDevices();
441 if( devices.count() <= 0 )
442 {
443 noCdFound = true;
444 return;
445 }
446 else if( devices.count() == 1 )
447 {
448 device = devices.keys().at(0);
449 }
450 else
451 {
452 QStringList list;
453 foreach( const QString& desc, devices.values() )
454 {
455 list.append( desc );
456 }
457 bool ok = false;
458 const QString selection = KInputDialog::getItem( i18n("Select CD-ROM drive"), i18n("Multiple CD-ROM drives where found. Please select one:"), list, 0, false, &ok, this );
459
460 if( ok )
461 {
462 // The user selected an item and pressed OK
463 device = devices.keys().at(list.indexOf(selection));
464 }
465 else
466 {
467 noCdFound = true;
468 return;
469 }
470 }
471 }
472
473 const bool success = openCdDevice( device );
474 if( !success )
475 {
476 KMessageBox::information(this,"success = false, couldn't open audio device.\nplease report this bug.");
477 noCdFound = true;
478 return;
479 }
480
481
482 mediaSource = new Phonon::MediaSource( Phonon::Cd, device );
483 mediaObject->setCurrentSource( *mediaSource ); // WARNING doesn't work with phonon-xine
484
485
486 // Prevent the dialog from beeing too wide because of the directory history
487 if( parent && width() > parent->width() )
488 setInitialSize( QSize(parent->width()-fontHeight,sizeHint().height()) );
489
490 KSharedConfig::Ptr conf = KGlobal::config();
491 KConfigGroup group = conf->group( "CDOpener" );
492 restoreDialogSize( group );
493 }
494
~CDOpener()495 CDOpener::~CDOpener()
496 {
497 KSharedConfig::Ptr conf = KGlobal::config();
498 KConfigGroup group = conf->group( "CDOpener" );
499 saveDialogSize( group );
500
501 if( cdParanoia )
502 {
503 paranoia_free( cdParanoia );
504 // delete cdParanoia;
505 }
506 if( cdDrive )
507 {
508 cdda_close( cdDrive );
509 // delete cdDrive;
510 }
511
512 if( cddb )
513 delete cddb;
514 }
515
setProfile(const QString & profile)516 void CDOpener::setProfile( const QString& profile )
517 {
518 options->setProfile( profile );
519 }
520
setFormat(const QString & format)521 void CDOpener::setFormat( const QString& format )
522 {
523 options->setFormat( format );
524 }
525
setOutputDirectory(const QString & directory)526 void CDOpener::setOutputDirectory( const QString& directory )
527 {
528 options->setOutputDirectory( directory );
529 }
530
setCommand(const QString & _command)531 void CDOpener::setCommand( const QString& _command )
532 {
533 command = _command;
534 }
535
cdDevices()536 QMap<QString,QString> CDOpener::cdDevices()
537 {
538 QMap<QString,QString> devices;
539
540 QList<Solid::Device> solidDevices = Solid::Device::listFromType(Solid::DeviceInterface::OpticalDisc, QString());
541 foreach( Solid::Device solidDevice, solidDevices )
542 {
543 Solid::OpticalDisc *opticalDisc = solidDevice.as<Solid::OpticalDisc>();
544 if( opticalDisc && opticalDisc->availableContent() & Solid::OpticalDisc::Audio )
545 {
546 Solid::Block *block = solidDevice.as<Solid::Block>();
547 if( block )
548 {
549 const QString device = block->device();
550 const Solid::Device parentDevice( solidDevice.parentUdi() );
551 const QString name = parentDevice.product();
552
553 cdDrive = cdda_identify( device.toAscii(), CDDA_MESSAGE_PRINTIT, 0 );
554 if( cdDrive && cdda_open(cdDrive) == 0 )
555 {
556 const QString desc = i18n("%1 (%2): Audio CD with %3 tracks").arg(name).arg(device).arg(cdda_audio_tracks(cdDrive));
557 devices.insert( device, desc );
558 }
559 }
560 }
561 }
562
563 return devices;
564 }
565
cdda_audio_tracks(cdrom_drive * cdDrive) const566 int CDOpener::cdda_audio_tracks( cdrom_drive *cdDrive ) const
567 {
568 const int nrOfTracks = cdda_tracks(cdDrive);
569 for( int i=1; i<=nrOfTracks; i++ )
570 {
571 if( !(IS_AUDIO(cdDrive,i-1)) )
572 return i-1;
573 }
574 return nrOfTracks;
575 }
576
openCdDevice(const QString & _device)577 bool CDOpener::openCdDevice( const QString& _device )
578 {
579 // paranoia init
580
581 QFile deviceFile(_device);
582
583 if( !deviceFile.exists() )
584 {
585 return false;
586 }
587 else
588 {
589 cdDrive = cdda_identify( _device.toAscii(), CDDA_MESSAGE_PRINTIT, 0 );
590 if( !cdDrive || cdda_open( cdDrive ) != 0 )
591 {
592 return false;
593 }
594 }
595 cdParanoia = paranoia_init( cdDrive );
596
597 // cd text
598
599 // const int status = wm_cd_init( device.toAscii().data(), "", "", "", &wmHandle );
600 //
601 // struct cdtext_info *info = 0;
602 //
603 // if( !WM_CDS_ERROR(status) )
604 // {
605 // info = wm_cd_get_cdtext( wmHandle );
606 //
607 // if( !info || !info->valid || info->count_of_entries != cdda_tracks(cdDrive) )
608 // if( !info || !info->valid )
609 // {
610 // kDebug() << "no or invalid CDTEXT";
611 // info = 0;
612 // }
613 // }
614
615
616 // add tracks to list
617
618 qDeleteAll( tags );
619 tags.clear();
620
621 TagData *newTags = new TagData();
622 newTags->track = 1;
623 newTags->trackTotal = 1;
624 newTags->disc = 1;
625 newTags->discTotal = 1;
626 newTags->year = (QDate::currentDate()).year();
627 tags += newTags;
628
629 const int trackTotal = cdda_audio_tracks( cdDrive );
630 for( int i=0; i<trackTotal; i++ )
631 {
632 TagData *newTags = new TagData();
633 newTags->track = i+1;
634 newTags->trackTotal = trackTotal;
635 const long size = CD_FRAMESIZE_RAW * (cdda_track_lastsector(cdDrive,newTags->track)-cdda_track_firstsector(cdDrive,newTags->track));
636 newTags->length = (8 * size) / (44100 * 2 * 16);
637 tags += newTags;
638
639 QStringList data;
640 data.append( "" );
641 data.append( QString().sprintf("%02i",newTags->track) );
642 data.append( newTags->artist );
643 data.append( newTags->composer );
644 data.append( newTags->title );
645 data.append( QString().sprintf("%i:%02i",newTags->length/60,newTags->length%60) );
646 QTreeWidgetItem *item = new QTreeWidgetItem( trackList, data );
647 PlayerWidget *playerWidget = new PlayerWidget( mediaObject, newTags->track, item, this );
648 // playerWidget->hide();
649 connect( playerWidget, SIGNAL(startPlayback(int)), this, SLOT(startPlayback(int)) );
650 connect( playerWidget, SIGNAL(stopPlayback()), this, SLOT(stopPlayback()) );
651 playerWidgets.append( playerWidget );
652 trackList->setItemWidget( item, Column_Player, playerWidget );
653 item->setCheckState( 0, Qt::Checked );
654 }
655 trackList->resizeColumnToContents( Column_Rip );
656 trackList->resizeColumnToContents( Column_Track );
657 trackList->resizeColumnToContents( Column_Length );
658
659 if( trackList->topLevelItem(0) )
660 trackList->topLevelItem(0)->setSelected( true );
661
662 lArtist->setText( tags.at(0)->artist );
663 lAlbum->setText( tags.at(0)->album );
664 iDisc->setValue( tags.at(0)->disc );
665 iDiscTotal->setValue( tags.at(0)->discTotal );
666 iYear->setValue( tags.at(0)->year );
667 cGenre->setEditText( tags.at(0)->genre );
668
669 artistChanged( lArtist->text() );
670 adjustComposerColumn();
671
672
673 // request cddb data
674 requestCddb( true );
675
676 return true;
677 }
678
requestCddb(bool autoRequest)679 void CDOpener::requestCddb( bool autoRequest )
680 {
681 lOverlayLabel->setText( i18n("Please wait, trying to download CDDB data ...") );
682
683 timeoutTimer.start( autoRequest ? 10000 : 20000 );
684
685 // cddb needs offsets +150 frames (2 seconds * 75 frames per second)
686 KCDDB::TrackOffsetList offsets;
687 for( int i=1; i<=cdda_tracks(cdDrive); i++ )
688 {
689 if( !(IS_AUDIO(cdDrive,i-1)) )
690 break;
691
692 offsets.append( cdda_track_firstsector(cdDrive,i) + 150 );
693 }
694 offsets.append( cdda_disc_lastsector(cdDrive) + 150 + 1 );
695
696 cddb->config().reparse();
697 cddb->setBlockingMode( false );
698 cddb->lookup( offsets );
699 }
700
lookup_cddb_done(KCDDB::Result result)701 void CDOpener::lookup_cddb_done( KCDDB::Result result )
702 {
703 timeoutTimer.stop();
704
705 if( result != KCDDB::Success && result != KCDDB::MultipleRecordFound )
706 {
707 // TODO error message if request was initiated by the user
708 // Error(i18n("No entry found in CDDB."), i18n("This means no data found in the CDDB database. Please enter the data manually. Maybe try another CDDB server."), Error::ERROR, this);
709 fadeOut();
710 return;
711 }
712
713 cddbFound = true;
714
715 KCDDB::CDInfo info = cddb->lookupResponse().first();
716 if( cddb->lookupResponse().count() > 1 || cdTextFound )
717 {
718 KCDDB::CDInfoList cddb_info = cddb->lookupResponse();
719 QStringList list;
720 if( cdTextFound )
721 {
722 // list.append( QString("CD Text: %1, %2").arg(compact_disc->discArtist()).arg(compact_disc->discTitle()) );
723 }
724 for( int i=0; i<cddb_info.count(); i++ )
725 {
726 list.append( QString("%1, %2, %3").arg(cddb_info.at(i).get(KCDDB::Artist).toString()).arg(cddb_info.at(i).get(KCDDB::Title).toString()).arg(cddb_info.at(i).get(KCDDB::Genre).toString()) );
727 }
728
729 bool ok = false;
730 const QString cddbItem = KInputDialog::getItem( i18n("Select CDDB Entry"), i18n("Multiple CDDB entries where found. Please select one:"), list, 0, false, &ok, this );
731
732 if( ok )
733 {
734 // The user selected and item and pressed OK
735 const int offset = cdTextFound ? 1 : 0;
736 const int index = list.indexOf( cddbItem );
737 if( index - offset < 0 )
738 {
739 fadeOut();
740 return;
741 }
742 info = cddb_info.at( index - offset );
743 }
744 else
745 {
746 // user pressed Cancel
747 fadeOut();
748 return;
749 }
750 }
751
752 for( int i=1; i<=cdda_audio_tracks(cdDrive); i++ )
753 {
754 tags.at(i)->artist = info.track(i-1).get(KCDDB::Artist).toString();
755 tags.at(i)->title = info.track(i-1).get(KCDDB::Title).toString();
756 tags.at(i)->comment = info.track(i-1).get(KCDDB::Comment).toString();
757
758 QTreeWidgetItem *item = trackList->topLevelItem(i-1);
759 item->setText( 2, tags.at(i)->artist );
760 item->setText( 4, tags.at(i)->title );
761 }
762
763 tags.at(0)->album = info.get(KCDDB::Title).toString();
764 tags.at(0)->artist = info.get(KCDDB::Artist).toString();
765 tags.at(0)->year = info.get(KCDDB::Year).toInt();
766 tags.at(0)->genre = info.get(KCDDB::Genre).toString();
767
768 // TODO resize colums up to a certain width
769
770 lArtist->setText( tags.at(0)->artist );
771 lAlbum->setText( tags.at(0)->album );
772 iDisc->setValue( tags.at(0)->disc );
773 iDiscTotal->setValue( tags.at(0)->discTotal );
774 iYear->setValue( tags.at(0)->year );
775 cGenre->setEditText( tags.at(0)->genre );
776
777 artistChanged( lArtist->text() );
778
779 fadeOut();
780 }
781
timeout()782 void CDOpener::timeout()
783 {
784 fadeOut();
785 }
786
trackUpPressed()787 void CDOpener::trackUpPressed()
788 {
789 QTreeWidgetItem *item = trackList->topLevelItem( selectedTracks.first() - 2 );
790
791 if( !item )
792 return;
793
794 disconnect( trackList, SIGNAL(itemSelectionChanged()), 0, 0 ); // avoid backfireing
795
796 for( int i=0; i<selectedTracks.count(); i++ )
797 {
798 QTreeWidgetItem *item = trackList->topLevelItem( selectedTracks.at(i)-1 );
799 if( item )
800 item->setSelected( false );
801 }
802
803 item->setSelected( true );
804 trackList->scrollToItem( item );
805
806 connect( trackList, SIGNAL(itemSelectionChanged()), this, SLOT(trackChanged()) );
807
808 trackChanged();
809 }
810
trackDownPressed()811 void CDOpener::trackDownPressed()
812 {
813 QTreeWidgetItem *item = trackList->topLevelItem( selectedTracks.last() );
814
815 if( !item )
816 return;
817
818 disconnect( trackList, SIGNAL(itemSelectionChanged()), 0, 0 ); // avoid backfireing
819
820 for( int i=0; i<selectedTracks.count(); i++ )
821 {
822 QTreeWidgetItem *item = trackList->topLevelItem( selectedTracks.at(i)-1 );
823 if( item )
824 item->setSelected( false );
825 }
826
827 item->setSelected( true );
828 trackList->scrollToItem( item );
829
830 connect( trackList, SIGNAL(itemSelectionChanged()), this, SLOT(trackChanged()) );
831
832 trackChanged();
833 }
834
trackChanged()835 void CDOpener::trackChanged()
836 {
837 // NOTE if no track is selected soundkonverter could use the current item as default item (like qlistview does)
838
839 // rebuild the list of the selected tracks
840 selectedTracks.clear();
841 for( int i=0; i<trackList->topLevelItemCount(); i++ )
842 {
843 QTreeWidgetItem *item = trackList->topLevelItem( i );
844 if( item->isSelected() )
845 {
846 selectedTracks.append( i+1 );
847 }
848 }
849
850 // insert the new values
851 if( selectedTracks.count() < 1 )
852 {
853 pTrackUp->setEnabled( false );
854 pTrackDown->setEnabled( false );
855
856 lTrackTitle->setEnabled( false );
857 lTrackTitle->setText( "" );
858 pTrackTitleEdit->hide();
859 lTrackArtist->setEnabled( false );
860 lTrackArtist->setText( "" );
861 pTrackArtistEdit->hide();
862 lTrackComposer->setEnabled( false );
863 lTrackComposer->setText( "" );
864 pTrackComposerEdit->hide();
865 tTrackComment->setEnabled( false );
866 tTrackComment->setReadOnly( true );
867 tTrackComment->setText( "" );
868 pTrackCommentEdit->hide();
869
870 pTrackUp->setEnabled( false );
871 pTrackDown->setEnabled( false );
872
873 return;
874 }
875 else if( selectedTracks.count() > 1 )
876 {
877 if( selectedTracks.first() > 1 )
878 pTrackUp->setEnabled( true );
879 else
880 pTrackUp->setEnabled( false );
881
882 if( selectedTracks.last() < trackList->topLevelItemCount() )
883 pTrackDown->setEnabled( true );
884 else
885 pTrackDown->setEnabled( false );
886
887 QString trackListString = "";
888 if( selectedTracks.count() == trackList->topLevelItemCount() )
889 {
890 trackListString = i18n("All tracks");
891 }
892 else
893 {
894 trackListString = i18n("Tracks") + QString().sprintf( " %02i", selectedTracks.at(0) );
895 for( int i=1; i<selectedTracks.count(); i++ )
896 {
897 trackListString += QString().sprintf( ", %02i", selectedTracks.at(i) );
898 }
899 }
900 tagGroupBox->setTitle( trackListString );
901
902 const QString title = tags.at(selectedTracks.at(0))->title;
903 bool equalTitles = true;
904 const QString artist = tags.at(selectedTracks.at(0))->artist;
905 bool equalArtists = true;
906 const QString composer = tags.at(selectedTracks.at(0))->composer;
907 bool equalComposers = true;
908 const QString comment = tags.at(selectedTracks.at(0))->comment;
909 bool equalComments = true;
910 for( int i=1; i<selectedTracks.count(); i++ )
911 {
912 if( title != tags.at(selectedTracks.at(i))->title )
913 equalTitles = false;
914 if( artist != tags.at(selectedTracks.at(i))->artist )
915 equalArtists = false;
916 if( composer != tags.at(selectedTracks.at(i))->composer )
917 equalComposers = false;
918 if( comment != tags.at(selectedTracks.at(i))->comment )
919 equalComments = false;
920 }
921
922 if( equalTitles )
923 {
924 lTrackTitle->setEnabled( true );
925 lTrackTitle->setText( title );
926 pTrackTitleEdit->hide();
927 }
928 else
929 {
930 lTrackTitle->setEnabled( false );
931 lTrackTitle->setText( "" );
932 pTrackTitleEdit->show();
933 }
934
935 if( equalArtists )
936 {
937 lTrackArtist->setEnabled( true );
938 lTrackArtist->setText( artist );
939 pTrackArtistEdit->hide();
940 }
941 else
942 {
943 lTrackArtist->setEnabled( false );
944 lTrackArtist->setText( "" );
945 pTrackArtistEdit->show();
946 }
947
948 if( equalComposers )
949 {
950 lTrackComposer->setEnabled( true );
951 lTrackComposer->setText( composer );
952 pTrackComposerEdit->hide();
953 }
954 else
955 {
956 lTrackComposer->setEnabled( false );
957 lTrackComposer->setText( "" );
958 pTrackComposerEdit->show();
959 }
960
961 if( equalComments )
962 {
963 tTrackComment->setEnabled( true );
964 tTrackComment->setReadOnly( false );
965 tTrackComment->setText( comment );
966 pTrackCommentEdit->hide();
967 }
968 else
969 {
970 tTrackComment->setEnabled( false );
971 tTrackComment->setReadOnly( true );
972 tTrackComment->setText( "" );
973 pTrackCommentEdit->show();
974 }
975 }
976 else
977 {
978 if( selectedTracks.first() > 1 )
979 pTrackUp->setEnabled( true );
980 else
981 pTrackUp->setEnabled( false );
982
983 if( selectedTracks.last() < trackList->topLevelItemCount() )
984 pTrackDown->setEnabled( true );
985 else
986 pTrackDown->setEnabled( false );
987
988 tagGroupBox->setTitle( i18n("Track") + QString().sprintf(" %02i",selectedTracks.at(0)) );
989
990 lTrackTitle->setEnabled( true );
991 lTrackTitle->setText( tags.at(selectedTracks.at(0))->title );
992 pTrackTitleEdit->hide();
993
994 lTrackArtist->setEnabled( true );
995 lTrackArtist->setText( tags.at(selectedTracks.at(0))->artist );
996 pTrackArtistEdit->hide();
997
998 lTrackComposer->setEnabled( true );
999 lTrackComposer->setText( tags.at(selectedTracks.at(0))->composer );
1000 pTrackComposerEdit->hide();
1001
1002 tTrackComment->setEnabled( true );
1003 tTrackComment->setReadOnly( false );
1004 tTrackComment->setText( tags.at(selectedTracks.at(0))->comment );
1005 pTrackCommentEdit->hide();
1006 }
1007 }
1008
artistChanged(const QString & text)1009 void CDOpener::artistChanged( const QString& text )
1010 {
1011 for( int i=1; i<tags.count(); i++ )
1012 {
1013 if( tags.at(i)->artist == lastAlbumArtist )
1014 {
1015 tags.at(i)->artist = text;
1016 if( QTreeWidgetItem *item = trackList->topLevelItem( i-1 ) )
1017 {
1018 item->setText( Column_Artist, text );
1019 }
1020 }
1021 }
1022
1023 tags.at(0)->artist = text;
1024
1025 lastAlbumArtist = text;
1026
1027 adjustArtistColumn();
1028 trackChanged();
1029 }
1030
adjustArtistColumn()1031 void CDOpener::adjustArtistColumn()
1032 {
1033 QString albumArtist = tags.at(0)->artist;
1034
1035 for( int i=1; i<tags.count(); i++ )
1036 {
1037 if( tags.at(i)->artist != albumArtist )
1038 {
1039 trackList->setColumnHidden( Column_Artist, false );
1040 return;
1041 }
1042 }
1043
1044 trackList->setColumnHidden( Column_Artist, true );
1045 }
1046
adjustComposerColumn()1047 void CDOpener::adjustComposerColumn()
1048 {
1049 for( int i=1; i<tags.count(); i++ )
1050 {
1051 if( !tags.at(i)->composer.isEmpty() )
1052 {
1053 trackList->setColumnHidden( Column_Composer, false );
1054 return;
1055 }
1056 }
1057
1058 trackList->setColumnHidden( Column_Composer, true );
1059 }
1060
trackTitleChanged(const QString & text)1061 void CDOpener::trackTitleChanged( const QString& text )
1062 {
1063 if( !lTrackTitle->isEnabled() )
1064 return;
1065
1066 for( int i=0; i<selectedTracks.count(); i++ )
1067 {
1068 QTreeWidgetItem *item = trackList->topLevelItem( selectedTracks.at(i)-1 );
1069 if( item )
1070 item->setText( Column_Title, text );
1071 tags.at(selectedTracks.at(i))->title = text;
1072 }
1073 }
1074
trackArtistChanged(const QString & text)1075 void CDOpener::trackArtistChanged( const QString& text )
1076 {
1077 if( !lTrackArtist->isEnabled() )
1078 return;
1079
1080 for( int i=0; i<selectedTracks.count(); i++ )
1081 {
1082 QTreeWidgetItem *item = trackList->topLevelItem( selectedTracks.at(i)-1 );
1083 if( item )
1084 item->setText( Column_Artist, text );
1085 tags.at(selectedTracks.at(i))->artist = text;
1086 }
1087
1088 adjustArtistColumn();
1089 }
1090
trackComposerChanged(const QString & text)1091 void CDOpener::trackComposerChanged( const QString& text )
1092 {
1093 if( !lTrackComposer->isEnabled() )
1094 return;
1095
1096 for( int i=0; i<selectedTracks.count(); i++ )
1097 {
1098 QTreeWidgetItem *item = trackList->topLevelItem( selectedTracks.at(i)-1 );
1099 if( item )
1100 item->setText( Column_Composer, text );
1101 tags.at(selectedTracks.at(i))->composer = text;
1102 }
1103
1104 adjustComposerColumn();
1105 }
1106
trackCommentChanged()1107 void CDOpener::trackCommentChanged()
1108 {
1109 QString text = tTrackComment->toPlainText();
1110
1111 if( !tTrackComment->isEnabled() )
1112 return;
1113
1114 for( int i=0; i<selectedTracks.count(); i++ )
1115 {
1116 tags.at(selectedTracks.at(i))->comment = text;
1117 }
1118 }
1119
editTrackTitleClicked()1120 void CDOpener::editTrackTitleClicked()
1121 {
1122 lTrackTitle->setEnabled( true );
1123 lTrackTitle->setFocus();
1124 pTrackTitleEdit->hide();
1125 trackTitleChanged( lTrackTitle->text() );
1126 }
1127
editTrackArtistClicked()1128 void CDOpener::editTrackArtistClicked()
1129 {
1130 lTrackArtist->setEnabled( true );
1131 lTrackArtist->setFocus();
1132 pTrackArtistEdit->hide();
1133 trackArtistChanged( lTrackArtist->text() );
1134 }
1135
editTrackComposerClicked()1136 void CDOpener::editTrackComposerClicked()
1137 {
1138 lTrackComposer->setEnabled( true );
1139 lTrackComposer->setFocus();
1140 pTrackComposerEdit->hide();
1141 trackComposerChanged( lTrackComposer->text() );
1142 }
1143
editTrackCommentClicked()1144 void CDOpener::editTrackCommentClicked()
1145 {
1146 tTrackComment->setEnabled( true );
1147 tTrackComment->setReadOnly( false );
1148 tTrackComment->setFocus();
1149 pTrackCommentEdit->hide();
1150 trackCommentChanged();
1151 }
1152
fadeIn()1153 void CDOpener::fadeIn()
1154 {
1155 fadeTimer.start( 50 );
1156 fadeMode = 1;
1157 cdOpenerOverlayWidget->show();
1158 }
1159
fadeOut()1160 void CDOpener::fadeOut()
1161 {
1162 fadeTimer.start( 50 );
1163 fadeMode = 2;
1164 }
1165
fadeAnim()1166 void CDOpener::fadeAnim()
1167 {
1168 if( fadeMode == 1 )
1169 {
1170 fadeAlpha += 255.0f/50.0f*8.0f;
1171 }
1172 else if( fadeMode == 2 )
1173 {
1174 fadeAlpha -= 255.0f/50.0f*8.0f;
1175 }
1176
1177 if( fadeAlpha <= 0.0f )
1178 {
1179 fadeAlpha = 0.0f;
1180 fadeMode = 0;
1181 cdOpenerOverlayWidget->hide();
1182 }
1183 else if( fadeAlpha >= 255.0f )
1184 {
1185 fadeAlpha = 255.0f;
1186 fadeMode = 0;
1187 }
1188 else
1189 {
1190 fadeTimer.start( 50 );
1191 }
1192
1193 QPalette newPalette = cdOpenerOverlayWidget->palette();
1194 newPalette.setBrush( QPalette::Window, brushSetAlpha( newPalette.window(), 192.0f/255.0f*fadeAlpha ) );
1195 cdOpenerOverlayWidget->setPalette( newPalette );
1196
1197 newPalette = lOverlayLabel->palette();
1198 newPalette.setBrush( QPalette::WindowText, brushSetAlpha( newPalette.windowText(), fadeAlpha ) );
1199 lOverlayLabel->setPalette( newPalette );
1200 }
1201
proceedClicked()1202 void CDOpener::proceedClicked()
1203 {
1204 int trackCount = 0;
1205
1206 for( int i=0; i<trackList->topLevelItemCount(); i++ )
1207 {
1208 if( trackList->topLevelItem(i)->checkState(0) == Qt::Checked )
1209 trackCount++;
1210 }
1211
1212 if( trackCount == 0 )
1213 {
1214 KMessageBox::error( this, i18n("Please select at least one track in order to proceed.") );
1215 return;
1216 }
1217
1218 if( options->currentConversionOptions() && options->currentConversionOptions()->outputDirectoryMode == OutputDirectory::Source )
1219 {
1220 options->setOutputDirectoryMode( (int)OutputDirectory::MetaData );
1221 }
1222
1223 cdOpenerWidget->hide();
1224 pSaveCue->hide();
1225 pCDDB->hide();
1226 cEntireCd->hide();
1227 options->show();
1228 page = ConversionOptionsPage;
1229 QFont font;
1230 font.setBold( false );
1231 lSelector->setFont( font );
1232 font.setBold( true );
1233 lOptions->setFont( font );
1234 pProceed->hide();
1235 pAdd->show();
1236 }
1237
addClicked()1238 void CDOpener::addClicked()
1239 {
1240 ConversionOptions *conversionOptions = options->currentConversionOptions();
1241 if( conversionOptions )
1242 {
1243 QList<int> tracks;
1244 QList<TagData*> tagList;
1245 const int trackCount = cdda_audio_tracks( cdDrive );
1246
1247 if( cEntireCd->isEnabled() && cEntireCd->isChecked() )
1248 {
1249 tags.at(0)->title = lAlbum->text();
1250 tags.at(0)->artist = lArtist->text();
1251 tags.at(0)->albumArtist = lArtist->text();
1252 tags.at(0)->album = lAlbum->text();
1253 tags.at(0)->disc = iDisc->value();
1254 tags.at(0)->discTotal = iDiscTotal->value();
1255 tags.at(0)->year = iYear->value();
1256 tags.at(0)->genre = cGenre->currentText();
1257 const long size = CD_FRAMESIZE_RAW * (cdda_track_lastsector(cdDrive,trackCount)-cdda_track_firstsector(cdDrive,1));
1258 tags.at(0)->length = (8 * size) / (44100 * 2 * 16);
1259
1260 tagList.append( tags.at(0) );
1261 tracks.append( 0 );
1262 }
1263 else
1264 {
1265 for( int i=0; i<trackList->topLevelItemCount(); i++ )
1266 {
1267 if( trackList->topLevelItem(i)->checkState(0) == Qt::Checked )
1268 {
1269 tags.at(i+1)->albumArtist = lArtist->text();
1270 tags.at(i+1)->album = lAlbum->text();
1271 tags.at(i+1)->disc = iDisc->value();
1272 tags.at(i+1)->discTotal = iDiscTotal->value();
1273 tags.at(i+1)->year = iYear->value();
1274 tags.at(i+1)->genre = cGenre->currentText();
1275 const long size = CD_FRAMESIZE_RAW * (cdda_track_lastsector(cdDrive,i+1)-cdda_track_firstsector(cdDrive,i+1));
1276 tags.at(i+1)->length = (8 * size) / (44100 * 2 * 16);
1277
1278 tagList.append( tags.at(i+1) );
1279 tracks.append( i+1 );
1280 }
1281 }
1282 }
1283
1284 options->accepted();
1285
1286 emit addTracks( device, tracks, trackCount, tagList, conversionOptions, command );
1287
1288 accept();
1289 }
1290 else
1291 {
1292 KMessageBox::error( this, i18n("No conversion options selected.") );
1293 }
1294 }
1295
saveCuesheetClicked()1296 void CDOpener::saveCuesheetClicked()
1297 {
1298 QString filename = KFileDialog::getSaveFileName( QDir::homePath(), "*.cue" );
1299 if( filename.isEmpty() )
1300 return;
1301
1302 QFile cueFile( filename );
1303 if( cueFile.exists() )
1304 {
1305 const int ret = KMessageBox::questionYesNo( this,
1306 i18n("A file with this name already exists.\n\nDo you want to overwrite the existing one?"),
1307 i18n("File already exists") );
1308 if( ret == KMessageBox::No )
1309 return;
1310 }
1311 if( !cueFile.open( QIODevice::WriteOnly ) )
1312 return;
1313
1314 QString content;
1315
1316 content.append( "REM COMMENT \"soundKonverter " + QString(SOUNDKONVERTER_VERSION_STRING) + "\"\n" );
1317 content.append( "TITLE \"" + lAlbum->text() + "\"\n" );
1318 content.append( "PERFORMER \"" + lArtist->text() + "\"\n" );
1319 content.append( "FILE \"\" WAVE\n" );
1320
1321 for( int i=1; i<tags.count(); i++ )
1322 {
1323 content.append( QString().sprintf(" TRACK %02i AUDIO\n",tags.at(i)->track ) );
1324 content.append( " TITLE \"" + tags.at(i)->title + "\"\n" );
1325 content.append( " PERFORMER \"" + tags.at(i)->artist + "\"\n" );
1326 content.append( " SONGWRITER \"" + tags.at(i)->composer + "\"\n" );
1327 const long size = CD_FRAMESIZE_RAW * cdda_track_firstsector(cdDrive,i);
1328 const long length = (8 * size) / (44100 * 2 * 16);
1329 const long frames = (8 * size) / (588 * 2 * 16);
1330 content.append( QString().sprintf(" INDEX 01 %02li:%02li:%02li\n",length/60,length%60,frames%75) );
1331 }
1332
1333 QTextStream ts( &cueFile );
1334 ts << content;
1335
1336 cueFile.close();
1337 }
1338
1339 // void CDOpener::itemHighlighted( QTreeWidgetItem *item, int column )
1340 // {
1341 // for( int i=0; i<playerWidgets.count(); i++ )
1342 // {
1343 // if( item == playerWidgets.at(i)->treeWidgetItem() )
1344 // playerWidgets[i]->show();
1345 // else if( !playerWidgets.at(i)->isPlaying() )
1346 // playerWidgets[i]->hide();
1347 // }
1348 // }
1349
startPlayback(int track)1350 void CDOpener::startPlayback( int track )
1351 {
1352 for( int i=0; i<playerWidgets.count(); i++ )
1353 {
1354 if( i+1 != track && playerWidgets.at(i)->isPlaying() )
1355 playerWidgets[i]->trackChanged( track );
1356 }
1357
1358 mediaController->setCurrentTitle( track );
1359 mediaObject->play();
1360 }
1361
stopPlayback()1362 void CDOpener::stopPlayback()
1363 {
1364 mediaObject->stop();
1365 }
1366
playbackTitleChanged(int title)1367 void CDOpener::playbackTitleChanged( int title )
1368 {
1369 for( int i=0; i<playerWidgets.count(); i++ )
1370 {
1371 if( ( i+1 != title && playerWidgets.at(i)->isPlaying() ) ||
1372 ( i+1 == title && !playerWidgets.at(i)->isPlaying() )
1373 )
1374 playerWidgets[i]->trackChanged( title );
1375 }
1376 }
1377
playbackStateChanged(Phonon::State newstate,Phonon::State oldstate)1378 void CDOpener::playbackStateChanged( Phonon::State newstate, Phonon::State oldstate )
1379 {
1380 Q_UNUSED(oldstate)
1381
1382 if( newstate == Phonon::StoppedState )
1383 {
1384 playbackTitleChanged( 0 );
1385 }
1386 else if( newstate == Phonon::PlayingState )
1387 {
1388 playbackTitleChanged( mediaController->currentTitle() );
1389 }
1390 }
1391
1392
1393