/* * disc.cpp * * Copyright (C) 2006 Christophe Thommeret * * 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 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "cddb.h" #include "mrl.h" #include "disc.h" #include "disc.moc" MLabel::MLabel( TQWidget *parent ) : TQLabel( parent ) { setText("
"+i18n("Audio CD")+"
"); } void MLabel::paintEvent( TQPaintEvent *pe ) { TQLabel::paintEvent( pe ); TQColorGroup cg = parentWidget()->colorGroup(); TQColor base = cg.base(); TQColor selection = cg.highlight(); int r = (base.red() + selection.red()) / 2; int b = (base.blue() + selection.blue()) / 2; int g = (base.green() + selection.green()) / 2; setPaletteBackgroundColor( TQColor(r, g, b) ); } MListView::MListView( TQWidget *parent ) : TDEListView( parent ) { } void MListView::resizeEvent( TQResizeEvent *rev ) { int width = contentsRect().width(); setColumnWidth(0, 40); /* Track */ setColumnWidth(1, width-90); /* title */ setColumnWidth(2, 50); /* duration */ TDEListView::resizeEvent(rev); } Disc::Disc( TQWidget* parent, TQObject *objParent, const char *name ) : KaffeineInput(objParent , name) { mainWidget = new TQVBox( parent ); mainWidget->setSizePolicy( TQSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Preferred) ); split = new TQSplitter( mainWidget ); split->setOpaqueResize( true ); widg = new TQWidget( split ); widg->setMinimumWidth( 200 ); widg->setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::MinimumExpanding ) ); TQVBoxLayout *wb = new TQVBoxLayout( widg, 0, 0 ); discLab = new MLabel( widg ); wb->addWidget( discLab ); playerBox = new TQVBox( widg ); wb->addWidget( playerBox ); playerBox->setMinimumWidth( 200 ); playerBox->setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::MinimumExpanding ) ); panel = new TQFrame( split ); split->moveToFirst( panel ); panel->setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::MinimumExpanding ) ); split->setResizeMode( panel, TQSplitter::KeepSize ); TQVBoxLayout *vb = new TQVBoxLayout( panel, 3, 3 ); cdBtn = new TQToolButton( panel ); cdBtn->setTextLabel( i18n("Play CD") ); cdBtn->setTextPosition( TQToolButton::Under ); cdBtn->setUsesTextLabel( true ); cdBtn->setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Fixed ) ); TQToolTip::add( cdBtn, i18n("Play CD")); ripBtn = new TQToolButton( panel ); ripBtn->setTextLabel( i18n("Rip CD") ); ripBtn->setTextPosition( TQToolButton::Under ); ripBtn->setUsesTextLabel( true ); ripBtn->setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Fixed ) ); TQToolTip::add( ripBtn, i18n("Rip CD")); TQHBoxLayout *h1 = new TQHBoxLayout(); h1->addWidget( cdBtn ); h1->addWidget( ripBtn ); vb->addLayout( h1 ); cdBtn->setIconSet( TDEGlobal::iconLoader()->loadIconSet("cdaudio_unmount", TDEIcon::Toolbar) ); ripBtn->setIconSet( TDEGlobal::iconLoader()->loadIconSet("kilogram", TDEIcon::Toolbar) ); connect( cdBtn, TQT_SIGNAL(clicked()), this, TQT_SLOT(startCD()) ); connect( ripBtn, TQT_SIGNAL(clicked()), this, TQT_SLOT(startRIP()) ); h1 = new TQHBoxLayout(); h1->addWidget( new TQLabel( i18n("Artist:"), panel ) ); artistLab = new TQLabel( "", panel ); artistLab->setLineWidth(1); artistLab->setFrameStyle(TQFrame::Panel|TQFrame::Sunken); artistLab->setSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Preferred ) ); h1->addWidget( artistLab ); vb->addLayout( h1 ); h1 = new TQHBoxLayout(); h1->addWidget( new TQLabel( i18n("Album:"), panel ) ); albumLab = new TQLabel( "", panel ); albumLab->setLineWidth(1); albumLab->setFrameStyle(TQFrame::Panel|TQFrame::Sunken); albumLab->setSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Preferred ) ); h1->addWidget( albumLab ); vb->addLayout( h1 ); list = new MListView( panel ); list->setHScrollBarMode( TQListView::AlwaysOff ); connect( list, TQT_SIGNAL(doubleClicked(TQListViewItem*)), this, TQT_SLOT(trackSelected(TQListViewItem*)) ); list->addColumn( i18n("Track") ); list->addColumn( i18n("Title") ); list->addColumn( i18n("Duration") ); //list->setSortColumn( -1 ); list->setAllColumnsShowFocus( true ); list->setSelectionMode(TQListView::Extended); list->setColumnWidthMode( 0, TQListView::Manual ); list->setColumnWidthMode( 1, TQListView::Manual ); list->setColumnWidthMode( 2, TQListView::Manual ); list->setResizeMode( TQListView::NoColumn ); vb->addWidget( list ); encodeWidget = new TQWidget( panel ); TQGridLayout *grid = new TQGridLayout( encodeWidget, 2, 2, 0, 3 ); TQLabel *lab = new TQLabel( i18n("Select the tracks you want to rip and click the Encode button."), encodeWidget ); grid->addMultiCellWidget( lab, 0, 1, 0, 0); enc = new TQToolButton( encodeWidget ); grid->addMultiCellWidget( enc, 0, 0, 1, 1); enc->setTextLabel( i18n("Encode...") ); enc->setTextPosition( TQToolButton::Under ); enc->setUsesTextLabel( true ); enc->setIconSet( TDEGlobal::iconLoader()->loadIconSet("kilogram", TDEIcon::Small) ); enc->setSizePolicy( TQSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Fixed ) ); connect( enc, TQT_SIGNAL(clicked()), this, TQT_SLOT(encode()) ); vb->addWidget( encodeWidget ); encodeWidget->hide(); progressBar = new TQProgressBar( 100, panel ); vb->addWidget( progressBar ); progressBar->hide(); vb->addItem( new TQSpacerItem( 1, 1, TQSizePolicy::Preferred, TQSizePolicy::Preferred ) ); artistLab->setPaletteBackgroundColor( list->paletteBackgroundColor() ); albumLab->setPaletteBackgroundColor( list->paletteBackgroundColor() ); connect( &encodeTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(encodeProgress()) ); setXMLFile("kaffeinedisc.rc"); setupActions(); loadConfig( TDEGlobal::config() ); para = NULL; trackCurrent = 0; currentPixmap = UserIcon("playing"); } Disc::~Disc() { } void Disc::togglePanel() { if ( panel->isHidden() ) panel->show(); else panel->hide(); } void Disc::getTargets( TQStringList &uiNames, TQStringList &iconNames, TQStringList &targetNames ) { uiNames.append( i18n("Audio CD encoding") ); iconNames.append( "kilogram" ); targetNames.append( "DISC_RIP" ); uiNames.append( i18n("Play Audio CD") ); iconNames.append( "cdaudio_unmount" ); targetNames.append( "DISC_CDDA" ); uiNames.append( i18n("Play DVD") ); iconNames.append( "dvd_unmount" ); targetNames.append( "DISC_DVD" ); uiNames.append( i18n("Play VCD") ); iconNames.append( "cdrom_unmount" ); targetNames.append( "DISC_VCD" ); } bool Disc::execTarget( const TQString &target ) { if ( target=="DISC_CDDA" ) { //emit showMe( this ); TQTimer::singleShot( 100, this, TQT_SLOT(startCD()) ); return true; } else if ( target=="DISC_RIP" ) { TQTimer::singleShot( 100, this, TQT_SLOT(startRIP()) ); return true; } else if ( target=="DISC_DVD" ) { TQTimer::singleShot( 100, this, TQT_SLOT(startDVD()) ); return true; } else if ( target=="DISC_VCD" ) { TQTimer::singleShot( 100, this, TQT_SLOT(startVCD()) ); return true; } return false; } void Disc::loadConfig( TDEConfig* config ) { TQValueList sl; config->setGroup("Disc"); sl = config->readIntListEntry("SplitSizes"); split->setSizes( sl ); } void Disc::saveConfig() { TDEConfig* config = TDEGlobal::config(); config->setGroup("Disc"); config->writeEntry( "SplitSizes", split->sizes() ); } TQWidget* Disc::wantPlayerWindow() { return playerBox; } TQWidget* Disc::inputMainWidget() { return mainWidget; } void Disc::setupActions() { new TDEAction(i18n("Open &DVD"), "dvd_unmount", 0, this, TQT_SLOT(startDVD()), actionCollection(), "file_open_dvd"); new TDEAction(i18n("Open &VCD"), "cdrom_unmount", 0, this, TQT_SLOT(startVCD()), actionCollection(), "file_open_vcd"); new TDEAction(i18n("Open &Audio-CD"), "cdaudio_unmount", 0, this, TQT_SLOT(startCD()), actionCollection(), "file_open_audiocd"); } void Disc::playerStopped() { trackCurrent = 0; if ( !list->isEnabled() ) return; list->clear(); artistLab->setText( "" ); albumLab->setText( "" ); encodeWidget->hide(); } void Disc::setEncoding( bool b ) { list->setEnabled( !b ); artistLab->setEnabled( !b ); albumLab->setEnabled( !b ); cdBtn->setEnabled( !b ); ripBtn->setEnabled( !b ); enc->setEnabled( !b ); if ( b ) { progressBar->setProgress( 0 ); progressBar->show(); } else progressBar->hide(); } void Disc::encode() { TQListViewItem *it; TQStringList tracklist; it = list->firstChild(); if ( !it ) return; tracklist.append( artistLab->text() ); tracklist.append( albumLab->text() ); while ( it!=0 ) { if ( it->isSelected() ) tracklist.append( it->text(0)+"-"+it->text(1) ); it = it->nextSibling(); } if ( (int)tracklist.count()<3 ) { KMessageBox::information( mainWidget, i18n("You must select the tracks to rip."), i18n("Warning") ); return; } setEncoding( true ); if ( trackCurrent ) emit stop(); para = new Paranoia(); if ( !para->init( currentDevice ) ) { KMessageBox::information( mainWidget, i18n("Unable to initialize cdparanoia."), i18n("Warning") ); delete para; para = NULL; setEncoding( false ); return; } if ( para->encode( tracklist, mainWidget ) ) encodeTimer.start( 1000 ); else { delete para; para = NULL; setEncoding( false ); } } void Disc::encodeProgress() { if ( para->running() ) progressBar->setProgress( para->getProgress() ); else { encodeTimer.stop(); delete para; para = NULL; setEncoding( false ); } } void Disc::setCurrent( int n ) { TQListViewItem *it; it = list->firstChild(); while ( it!=0 ) { if ( it->text(0).toInt()==n ) it->setPixmap( 1, currentPixmap ); else it->setPixmap( 1, TQPixmap() ); it = it->nextSibling(); } } void Disc::trackSelected( TQListViewItem *it ) { if ( !it ) return; MRL mrl( TQString("cdda://%1/%2").arg( currentDevice ).arg( it->text(0).toInt() ) ); mrl.setTitle( it->text(1) ); mrl.setArtist( artistLab->text() ); mrl.setAlbum( albumLab->text() ); mrl.setTrack( it->text(0) ); mrl.setMime( TQString("audio/cdda") ); trackCurrent = it->text(0).toInt(); setCurrent( trackCurrent ); emit play( mrl, this ); } void Disc::startRIP() { startCD( "", true ); } void Disc::startCD( const TQString &device, bool rip ) { TQStringList s; bool init=false; TQValueList qvl; int i; TDEListViewItem *it; MRL mrl; TQStringList dcopList, devList; bool ok=false; if ( !cdBtn->isEnabled() ) { emit showMe( this ); return; } if ( !device.isEmpty() ) s.append( device ); else { DCOPRef mediamanager("kded","mediamanager"); DCOPReply reply = mediamanager.call("fullList()"); if ( reply.isValid() ) { dcopList = reply; i=0; while ( i<(int)dcopList.count() ) { //kdDebug() << dcopList[i+5] << " * " << dcopList[i+6] << " * " << dcopList[i+10] << endl; if ( dcopList[i+10]=="media/audiocd" ) { devList.append( dcopList[i+5] ); } i+=13; } if ( devList.count()>1 ) { TQString choice = KInputDialog::getItem( i18n("Audio CD"), i18n("Several Audio CD found. Choose one:"), devList, 0, false, &ok ); if ( ok ) s.append( choice ); else return; } else if ( devList.count()==1 ) s.append( devList[0] ); else { s.append( "/dev/cdrom" ); s.append( "/dev/dvd" ); } } else { s.append( "/dev/cdrom" ); s.append( "/dev/dvd" ); } } TQApplication::setOverrideCursor( TQCursor(TQt::WaitCursor) ); tqApp->processEvents(); para = new Paranoia(); for ( i=0; i<(int)s.count(); i++ ) { if ( (init = para->init( s[i] )) ) { currentDevice = s[i]; break; } } if ( init ) { list->clear(); artistLab->setText( "" ); albumLab->setText( "" ); for ( i=0; igetTracks(); i++) qvl.append( para->trackFirstSector(i+1) + 150 ); qvl.append( para->discFirstSector() ); qvl.append( para->discLastSector() ); CDDB *cddb = new CDDB(); cddb->save_cddb( true ); if ( cddb->queryCD(qvl) ) { artistLab->setText( cddb->artist() ); albumLab->setText( cddb->title() ); for ( i=0; igetTracks(); i++ ) { it = new TDEListViewItem( list, TQString().sprintf("%02d", i+1), cddb->track( i ), para->trackTime(i) ); if ( i==0 ) { mrl.setURL( TQString("cdda://%1/1").arg( currentDevice ) ); mrl.setTitle( cddb->track(i) ); mrl.setArtist( artistLab->text() ); mrl.setAlbum( albumLab->text() ); mrl.setTrack( TQString().sprintf("%02d", i+1) ); } } } else { cddb->set_server( "freedb.freedb.org", 8880 ); if ( cddb->queryCD(qvl) ) { artistLab->setText( cddb->artist() ); albumLab->setText( cddb->title() ); for ( i=0; igetTracks(); i++ ) { it = new TDEListViewItem( list, TQString().sprintf("%02d", i+1), cddb->track( i ), para->trackTime(i) ); if ( i==0 ) { mrl.setURL( TQString("cdda://%1/1").arg( currentDevice ) ); mrl.setTitle( cddb->track(i) ); mrl.setArtist( artistLab->text() ); mrl.setAlbum( albumLab->text() ); mrl.setTrack( TQString().sprintf("%02d", i+1) ); } } } else { artistLab->setText( i18n("Unknown") ); albumLab->setText( i18n("Unknown") ); for ( i=0; igetTracks(); i++ ) { it = new TDEListViewItem( list, TQString().sprintf("%02d", i+1), i18n("Track")+TQString().sprintf("%02d", i+1), para->trackTime(i) ); if ( i==0 ) { mrl.setURL( TQString("cdda://%1/1").arg( currentDevice ) ); mrl.setTitle( i18n("Track")+TQString().sprintf("%02d", i+1) ); mrl.setArtist( artistLab->text() ); mrl.setAlbum( albumLab->text() ); mrl.setTrack( TQString().sprintf("%02d", i+1) ); } } } } delete cddb; TQApplication::restoreOverrideCursor(); encodeWidget->show(); emit showMe( this ); if ( !rip && !mrl.isEmpty() ) { mrl.setMime( TQString("audio/cdda") ); trackCurrent = mrl.track().toInt(); setCurrent( trackCurrent ); emit play( mrl, this ); } } else { TQApplication::restoreOverrideCursor(); KMessageBox::information( 0, i18n("No audio CD found."), i18n("Warning") ); } delete para; para = NULL; } void Disc::startDVD( const TQString &device ) { MRL mrl; TQStringList dcopList, devList; int i; bool ok=false; if ( !device.isEmpty() ) mrl.setURL( TQString("dvd://%1").arg(device) ); else { DCOPRef mediamanager("kded","mediamanager"); DCOPReply reply = mediamanager.call("fullList()"); if ( reply.isValid() ) { dcopList = reply; i=0; while ( i<(int)dcopList.count() ) { //kdDebug() << dcopList[i+5] << " * " << dcopList[i+6] << " * " << dcopList[i+10] << endl; if ( dcopList[i+10]=="media/dvdvideo" ) { devList.append( dcopList[i+5] ); } else if ( dcopList[i+10]=="media/cdrom_mounted" || dcopList[i+10]=="media/cdwriter_mounted" || dcopList[i+10]=="media/dvd_mounted" ) { if ( TQFile::exists(dcopList[i+6]+"/video_ts") || TQFile::exists(dcopList[i+6]+"/VIDEO_TS") ) devList.append( dcopList[i+5] ); } i+=13; } if ( devList.count()>1 ) { TQString choice = KInputDialog::getItem( i18n("DVD Video"), i18n("Several DVD Video found. Choose one:"), devList, 0, false, &ok ); if ( ok ) mrl.setURL( TQString("dvd://%1").arg(choice) ); else return; } else if ( devList.count()==1 ) mrl.setURL( TQString("dvd://%1").arg(devList[0]) ); else { //KMessageBox::information( 0, i18n("No DVD Video found."), i18n("Warning") ); //return; mrl.setURL( TQString("dvd://") ); } } else mrl.setURL( TQString("dvd://") ); } mrl.setMime( TQString("video/dvd") ); if ( !progressBar->isVisible() ) { list->clear(); artistLab->setText( "" ); albumLab->setText( "" ); encodeWidget->hide(); } trackCurrent = 0; emit play( mrl, this ); } void Disc::startVCD( const TQString &device ) { MRL mrl; TQStringList dcopList, devList; int i; bool ok=false; if ( !device.isEmpty() ) mrl.setURL( TQString("vcd://%1").arg(device) ); else { DCOPRef mediamanager("kded","mediamanager"); DCOPReply reply = mediamanager.call("fullList()"); if ( reply.isValid() ) { dcopList = reply; i=0; while ( i<(int)dcopList.count() ) { //kdDebug() << dcopList[i+5] << " * " << dcopList[i+6] << " * " << dcopList[i+10] << endl; if ( dcopList[i+10]=="media/vcd" || dcopList[i+10]=="media/svcd" ) { devList.append( dcopList[i+5] ); } i+=13; } if ( devList.count()>1 ) { TQString choice = KInputDialog::getItem( i18n("VCD-SVCD"), i18n("Several (S)VCD found. Choose one:"), devList, 0, false, &ok ); if ( ok ) mrl.setURL( TQString("vcd://%1").arg(choice) ); else return; } else if ( devList.count()==1 ) mrl.setURL( TQString("vcd://%1").arg(devList[0]) ); else { //KMessageBox::information( 0, i18n("No (S)VCD found."), i18n("Warning") ); //return; mrl.setURL( TQString("vcd://") ); } } else mrl.setURL( TQString("vcd://") ); } mrl.setMime( TQString("video/vcd") ); if ( !progressBar->isVisible() ) { list->clear(); artistLab->setText( "" ); albumLab->setText( "" ); encodeWidget->hide(); } trackCurrent = 0; emit play( mrl, this ); } bool Disc::currentTrack( MRL &mrl ) { TQListViewItem *it; if ( !trackCurrent ) return false; it = list->firstChild(); if ( !it ) return false; while ( it!=0 ) { if ( it->text(0).toInt()==trackCurrent ) { mrl.setURL( TQString("cdda://%1/%2").arg( currentDevice ).arg( it->text(0).toInt() ) ); mrl.setTitle( it->text(1) ); mrl.setArtist( artistLab->text() ); mrl.setAlbum( albumLab->text() ); mrl.setTrack( it->text(0) ); mrl.setMime( TQString("audio/cdda") ); setCurrent( trackCurrent ); return true; } it = it->nextSibling(); } return false; } bool Disc::playbackFinished( MRL &mrl ) { return nextTrack( mrl ); } bool Disc::nextTrack( MRL &mrl ) { TQListViewItem *it; if ( !trackCurrent ) return false; it = list->firstChild(); if ( !it ) return false; while ( it!=0 ) { if ( it->text(0).toInt()==trackCurrent+1 ) { mrl.setURL( TQString("cdda://%1/%2").arg( currentDevice ).arg( it->text(0).toInt() ) ); mrl.setTitle( it->text(1) ); mrl.setArtist( artistLab->text() ); mrl.setAlbum( albumLab->text() ); mrl.setTrack( it->text(0) ); mrl.setMime( TQString("audio/cdda") ); ++trackCurrent; setCurrent( trackCurrent ); return true; } it = it->nextSibling(); } it = list->firstChild(); mrl.setURL( TQString("cdda://%1/%2").arg( currentDevice ).arg( it->text(0).toInt() ) ); mrl.setTitle( it->text(1) ); mrl.setArtist( artistLab->text() ); mrl.setAlbum( albumLab->text() ); mrl.setTrack( it->text(0) ); mrl.setMime( TQString("audio/cdda") ); trackCurrent = 1; setCurrent( trackCurrent ); return true; } bool Disc::previousTrack( MRL &mrl ) { TQListViewItem *it; if ( !trackCurrent ) return false; it = list->firstChild(); if ( !it ) return false; while ( it!=0 ) { if ( it->text(0).toInt()==trackCurrent-1 ) { mrl.setURL( TQString("cdda://%1/%2").arg( currentDevice ).arg( it->text(0).toInt() ) ); mrl.setTitle( it->text(1) ); mrl.setArtist( artistLab->text() ); mrl.setAlbum( albumLab->text() ); mrl.setTrack( it->text(0) ); mrl.setMime( TQString("audio/cdda") ); --trackCurrent; setCurrent( trackCurrent ); return true; } it = it->nextSibling(); } return false; } bool Disc::trackNumber( int number, MRL &mrl ) { TQListViewItem *it; if ( !trackCurrent ) return false; it = list->firstChild(); if ( !it ) return false; while ( it!=0 ) { if ( it->text(0).toInt()==number ) { mrl.setURL( TQString("cdda://%1/%2").arg( currentDevice ).arg( it->text(0).toInt() ) ); mrl.setTitle( it->text(1) ); mrl.setArtist( artistLab->text() ); mrl.setAlbum( albumLab->text() ); mrl.setTrack( it->text(0) ); mrl.setMime( TQString("audio/cdda") ); trackCurrent=number; setCurrent( trackCurrent ); return true; } it = it->nextSibling(); } return false; } void Disc::mergeMeta( const MRL& ) { }