You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
soundkonverter/src/filelist.cpp

1446 lines
60 KiB

#include "filelist.h"
#include "cdmanager.h"
#include "tagengine.h"
#include "options.h"
#include "convert.h"
#include "optionseditor.h"
#include "outputdirectory.h"
#include "config.h"
#include "logger.h"
#include "convertpluginloader.h" // NOTE DEBUG
#include <klocale.h>
#include <kpopupmenu.h>
#include <kaction.h>
#include <kactioncollection.h>
#include <kmimetype.h>
#include <kurl.h>
#include <kmountpoint.h>
#include <kstandarddirs.h>
#include <kurldrag.h>
#include <kapplication.h>
#include <tqlayout.h>
#include <tqfileinfo.h>
#include <tqsimplerichtext.h>
#include <tqpainter.h>
#include <tqapplication.h>
#include <tqdragobject.h>
#include <tqheader.h>
#include <tqdir.h>
#include <kprogress.h>
#include <kuser.h>
// TODO when stopping items by using the context menu, the queue mode restarts that item
// TODO when dropping items, don't let the user select the position
// ### soundkonverter 0.4: draw tooltip like bubble info box
FileListItem::FileListItem( TDEListView* parent, FileListItem* after )
: TDEListViewItem( parent, after )
{
tags = 0;
converting = false;
time = 0;
ripping = false;
}
FileListItem::FileListItem( TDEListView* parent )
: TDEListViewItem( parent )
{
tags = 0;
converting = false;
time = 0;
ripping = false;
}
FileListItem::~FileListItem()
{}
void FileListItem::paintCell( TQPainter *p, const TQColorGroup &cg, int column, int width, int alignment )
{
// NOTE speed up this function
// NOTE calculate the red color
TQColorGroup _cg( cg );
TQColor c;
if( column == ((FileList*)listView())->columnByName(i18n("Input")) || column == ((FileList*)listView())->columnByName(i18n("Output")) )
{
int margin = listView()->itemMargin();
int w = width - 2*margin;
int h = height();
TQRect textRect = p->boundingRect( margin, 0, w, h, alignment, text(column) );
if( textRect.width() > w ) {
alignment = TQt::AlignRight | TQt::SingleLine;
}
/*if ( textRect.width() <= w ) {
p->drawText( margin, 0, w, h, alignment | TQt::SingleLine | TQt::ExpandTabs, text(column), -1 );
}
else {
textRect = p->boundingRect( margin, 0, w, h, TQt::AlignLeft, "... " );
p->drawText( margin, 0, textRect.width(), h, TQt::AlignLeft | TQt::SingleLine | TQt::ExpandTabs, "...", -1 );
p->drawText( margin+textRect.width(), 0, w-textRect.width(), h, TQt::AlignRight | TQt::SingleLine | TQt::ExpandTabs, text(column), -1 );
}*/
}
if( isSelected() && converting ) {
_cg.setColor( TQColorGroup::Highlight, TQColor( 215, 62, 62 ) );
TQListViewItem::paintCell( p, _cg, column, width, alignment );
return;
}
else if( converting && column != listView()->sortColumn() ) {
_cg.setColor( TQColorGroup::Base, TQColor( 255, 234, 234 ) );
TQListViewItem::paintCell( p, _cg, column, width, alignment );
return;
}
else if( converting && column == listView()->sortColumn() ) {
_cg.setColor( TQColorGroup::Base, TQColor( 247, 227, 227 ) );
TQListViewItem::paintCell( p, _cg, column, width, alignment );
return;
}
TDEListViewItem::paintCell( p, _cg, column, width, alignment );
}
/*void FileListItem::updateOutputCell()
{
setText( ((FileList*)listView())->columnByName(i18n("Output")), OutputDirectory::calcPath(this) ); // FIXME no config !!!
}
void FileListItem::updateOptionsCell()
{
setText( ((FileList*)listView())->columnByName(i18n("Quality")), ((FileList*)listView())->config->getProfileName(options) );
}*/
FileList::FileList( CDManager* _cdManager, TagEngine* _tagEngine, Config* _config, Options* _options, Logger* _logger, TQWidget* parent, const char* name )
: TDEListView( parent, name )
{
cdManager = _cdManager;
tagEngine = _tagEngine;
config = _config;
options = _options;
logger = _logger;
optionsEditor = 0;
queue = false;
notify = "";
setAcceptDrops( true );
setDragEnabled( true );
addColumn( i18n("State"), 120 );
addColumn( i18n("Input"), 180 );
addColumn( i18n("Output"), 180 );
addColumn( i18n("Quality") );
header()->setClickEnabled( false );
setSelectionMode( TQListView::Extended );
setAllColumnsShowFocus( true );
setResizeMode( LastColumn );
setSorting( -1 ); // NOTE if commented out, items aren't moveable anymore
setMinimumHeight( 200 );
TQGridLayout* grid = new TQGridLayout( this, 2, 1, 11, 6 );
grid->setRowStretch( 0, 1 );
grid->setRowStretch( 2, 1 );
grid->setColStretch( 0, 1 );
grid->setColStretch( 2, 1 );
pScanStatus = new KProgress( this, "pScanStatus" );
pScanStatus->setMinimumHeight( pScanStatus->height() );
pScanStatus->setFormat( "%v / %m" );
pScanStatus->hide();
grid->addWidget( pScanStatus, 1, 1 );
grid->setColStretch( 1, 2 );
contextMenu = new TDEPopupMenu( this );
connect( TQT_TQOBJECT(this), TQT_SIGNAL(contextMenuRequested( TQListViewItem*, const TQPoint&, int )),
TQT_TQOBJECT(this), TQT_SLOT(showContextMenu( TQListViewItem*, const TQPoint&, int ))
);
// we haven't got access to the action collection of soundKonverter, so let's create a new one
actionCollection = new TDEActionCollection( this );
edit = new TDEAction( i18n("Edit options ..."), "view_text", 0, TQT_TQOBJECT(this), TQT_SLOT(showOptionsEditorDialog()), actionCollection, "edit_options" );
start = new TDEAction( i18n("Start conversion"), "run", 0, TQT_TQOBJECT(this), TQT_SLOT(convertSelectedItems()), actionCollection, "start_conversion" );
stop = new TDEAction( i18n("Stop conversion"), "stop", 0, TQT_TQOBJECT(this), TQT_SLOT(stopSelectedItems()), actionCollection, "stop_conversion" );
remove = new TDEAction( i18n("Remove"), "edittrash", Key_Delete, TQT_TQOBJECT(this), TQT_SLOT(removeSelectedItems()), actionCollection, "remove" );
paste = new TDEAction( i18n("Paste"), "editpaste", 0, TQT_TQOBJECT(this), 0, actionCollection, "paste" ); // TODO paste
connect( TQT_TQOBJECT(this), TQT_SIGNAL(selectionChanged()),
TQT_TQOBJECT(this), TQT_SLOT(itemsSelected())
);
// connect( TQT_TQOBJECT(this), TQT_SIGNAL(clicked(TQListViewItem*,const TQPoint&,int)),
// TQT_TQOBJECT(this), TQT_SLOT(clickedSomewhere(TQListViewItem*,const TQPoint&,int))
// );
bubble = new TQSimpleRichText( i18n( "<div align=center>"
"<h3>File List</h3>"
"Select your desired output options in the form above and add some files.<br/>"
"You can add files by clicking on \"Add files ...\" or dropping them here."
// "<br/><a href=\"documenation:about_compression\">Learn more about audio compression ...</a>"
"</div>" ), TQApplication::font() );
connect( header(), TQT_SIGNAL(sizeChange( int, int, int )),
TQT_SLOT(columnResizeEvent( int, int, int ))
);
connect( TQT_TQOBJECT(this), TQT_SIGNAL( dropped(TQDropEvent*, TQListViewItem*, TQListViewItem*) ),
TQT_SLOT( slotDropped(TQDropEvent*, TQListViewItem*, TQListViewItem*) )
);
// if( TQFile::exists(locateLocal("data","soundkonverter/filelist.autosave.xml")) ) load( true );
// debug(); // NOTE DEBUG
}
FileList::~FileList()
{
delete optionsEditor;
}
int FileList::columnByName( const TQString& name )
{
for( int i = 0; i < columns(); ++i ) {
if( columnText( i ) == name ) return i;
}
return -1;
}
void FileList::viewportPaintEvent( TQPaintEvent* e )
{
TDEListView::viewportPaintEvent( e );
// the bubble help
if( childCount() == 0 ) {
TQPainter p( viewport() );
bubble->setWidth( width() - 50 );
const uint w = bubble->width() + 20;
const uint h = bubble->height() + 20;
p.setBrush( colorGroup().background() );
p.drawRoundRect( 15, 15, w, h, (8*200)/w, (8*200)/h );
bubble->draw( &p, 20, 20, TQRect(), colorGroup() );
}
}
void FileList::viewportResizeEvent( TQResizeEvent* )
{
// needed for correct redraw of bubble help
triggerUpdate();
}
void FileList::columnResizeEvent( int, int, int )
{
// needed for correct redraw of bubble help
triggerUpdate();
}
// void FileList::clickedSomewhere( TQListViewItem*, const TQPoint& pos, int )
// {
// /* if( childCount() == 0 ) {
// kdDebug() << "clicked: `" << bubble->anchorAt(mapFromGlobal(pos)-TQPoint(24,0)) << " (" << pos.x() << " | " << pos.y() << ")'" << endl;
// }*/
// }
bool FileList::acceptDrag( TQDropEvent* e ) const
{
return ( e->source() == viewport() || KURLDrag::canDecode(e) ); // TODO verify the files
}
void FileList::slotDropped( TQDropEvent* e, TQListViewItem*, TQListViewItem* itemAfter )
{
TQString file;
KURL::List list;
TQStringList files;
if( KURLDrag::decode( e, list ) ) // TODO local?
{
save( true );
for( KURL::List::Iterator it = list.begin(); it != list.end(); ++it )
{
// TODO verify the files (necessary when multiple files are being dropped)
// TODO implement cdda:/
file = TQDir::convertSeparators( (*it).pathOrURL() ); // TODO implement that in the url/file dialog, too?
TQFileInfo fileInfo( file );
if( fileInfo.isDir() )
{
addDir( file );
}
else
{
files.append( (*it).url() );
}
}
addFiles( files, (FileListItem*)itemAfter, true );
save( true );
}
}
void FileList::showContextMenu( TQListViewItem* item, const TQPoint& point, int )
{
// if item is null, we can abort here
if( !item ) return;
// remove all items from the context menu
contextMenu->clear();
// add a tilte to our context manu
//contextMenu->insertTitle( static_cast<FileListItem*>(item)->fileName ); // TODO sqeeze or something else
// TODO implement pasting, etc.
// is this file (of our item) beeing converted at the moment?
if( !static_cast<FileListItem*>(item)->converting ) {
edit->plug( contextMenu );
contextMenu->insertSeparator();
remove->plug( contextMenu );
//paste->plug( contextMenu );
contextMenu->insertSeparator();
start->plug( contextMenu );
}
else {
stop->plug( contextMenu );
//contextMenu->insertSeparator();
//remove->plug( contextMenu );
//paste->plug( contextMenu );
}
// show the popup menu
contextMenu->popup( point );
}
void FileList::removeSelectedItems()
{
FileListItem *item = firstChild(), *nextitem = 0;
while( item != 0 ) {
if( item->isSelected() && !item->converting ) {
nextitem = item->nextSibling();
emit decreaseTime( item->time );
delete item;
item = nextitem;
}
else {
item = item->nextSibling();
}
}
emit fileCountChanged( childCount() );
itemsSelected();
}
void FileList::convertSelectedItems()
{
FileListItem* item = firstChild();
while( item != 0 ) {
if( item->isSelected() && !item->converting ) {
emit convertItem( item );
}
item = item->nextSibling();
}
itemsSelected();
emit startedConversion();
}
void FileList::stopSelectedItems()
{
FileListItem* item = firstChild();
while( item != 0 ) {
if( item->isSelected() && item->converting ) {
emit stopItem( item );
}
item = item->nextSibling();
}
}
int FileList::listDir( const TQString& directory, TQStringList filter, bool recursive, bool fast, int count )
{ // NOTE speed up?
TQDir dir( directory );
dir.setFilter( TQDir::Files | TQDir::Dirs | TQDir::NoSymLinks | TQDir::Readable );
TQStringList list = dir.entryList();
for( TQStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
if( *it == "." || *it == ".." ) continue;
TQFileInfo fileInfo( directory + "/" + *it );
if( fast ) {
if( fileInfo.isDir() && recursive ) {
count = listDir( fileInfo.filePath(), filter, recursive, fast, count );
}
else if( !fileInfo.isDir() || !recursive ) { // NOTE checking for isFile may not work with all file names
// NOTE filter feature
for( TQStringList::Iterator jt = filter.begin(); jt != filter.end(); ++jt ) {
if( (*it).endsWith("."+(*jt),false) ) {
count++;
pScanStatus->setTotalSteps( count );
break;
}
}
if( filter.first() == "" ) {
count++;
pScanStatus->setTotalSteps( count );
}
}
}
else {
if( fileInfo.isDir() && recursive ) {
count = listDir( fileInfo.filePath(), filter, recursive, fast, count );
}
else if( !fileInfo.isDir() || !recursive ) { // NOTE checking for isFile may not work with all file names
// NOTE filter feature
for( TQStringList::Iterator jt = filter.begin(); jt != filter.end(); ++jt ) {
if( (*it).endsWith("."+(*jt),false) ) {
addFiles( KURL::encode_string(directory + "/" + *it) );
count++;
pScanStatus->setProgress( count );
break;
}
}
if( filter.first() == "" ) {
addFiles( KURL::encode_string(directory + "/" + *it) );
count++;
pScanStatus->setProgress( count );
}
}
}
}
return count;
}
// NOTE progressbar when adding files?
void FileList::addFiles( TQStringList fileList, FileListItem* after, bool enabled )
{
// TODO test if everything works with remote files (http://) and local files (media://)
FileListItem* lastListItem;
if( !after && !enabled ) lastListItem = lastItem();
else lastListItem = after;
TQString filePathName;
TQString device;
for( TQStringList::Iterator it = fileList.begin(); it != fileList.end(); ++it ) {
FileListItem* newItem = new FileListItem( this, lastListItem );
lastListItem = newItem;
newItem->options = options->getCurrentOptions(); // FIXME speed up
newItem->notify = notify;
newItem->local = false;
newItem->track = -1;
newItem->url = *it;
if( (*it).left( 1 ) == "/" ) {
filePathName = *it;
newItem->local = true;
}
else if( (*it).left( 7 ) == "file://" ) {
filePathName = *it;
filePathName.remove( 0, 7 );
newItem->local = true;
}
else if( (*it).left( 13 ) == "system:/home/" ) {
filePathName = *it;
filePathName.remove( 0, 13 );
filePathName = TQDir::homeDirPath() + "/" + filePathName;
newItem->local = true;
}
else if( (*it).left( 14 ) == "system:/users/" || (*it).left( 6 ) == "home:/" ) {
int length = ( (*it).left(6) == "home:/" ) ? 6 : 14;
TQString username = *it;
username.remove( 0, length );
username = username.left( username.find("/") );
filePathName = *it;
filePathName.remove( 0, length + username.length() );
KUser user( username );
filePathName = user.homeDir() + filePathName;
newItem->local = true;
}
else if( (*it).left( 14 ) == "system:/media/" || (*it).left( 7 ) == "media:/" ) {
int length = ( (*it).left(7) == "media:/" ) ? 7 : 14;
device = *it;
device.remove( 0, length );
device = "/dev/" + device.left( device.find( "/" ) );
KMountPoint::List mountPoints = KMountPoint::possibleMountPoints();
for( KMountPoint::List::ConstIterator jt = mountPoints.begin(); jt != mountPoints.end(); ++jt )
{
12 years ago
const TDESharedPtr<KMountPoint> mp = *jt;
logger->log( 1000, mp->mountedFrom() + " : " + mp->mountPoint() );
if( mp->mountedFrom() == device )
{
filePathName = ( mp->mountPoint() == "/" ) ? mp->mountPoint() : mp->mountPoint() + "/";
filePathName += (*it).right( (*it).length() - device.length() - length + 4 );
}
}
newItem->local = true;
}
// else if( (*it).left( 14 ) == "system:/trash/" || (*it).left( 7 ) == "trash:/" ) {
// }
if( newItem->local == true ) {
// logger->log( 1000, i18n("Adding file") + ": " + filePathName );
newItem->mimeType = KMimeType::findByFileContent( filePathName )->name();
newItem->fileFormat = KMimeType::findByFileContent( filePathName )->patterns().first().lower();
newItem->fileFormat.remove( 0, 2 );
// logger->log( 1000, " " + i18n("Mime type") + ": " + newItem->mimeType + " (" + i18n("Format") + ": " + newItem->fileFormat + ")" );
// newItem->mimeType="";
if( newItem->mimeType.isEmpty() || newItem->mimeType == "application/octet-stream" || newItem->mimeType == "text/plain" ) {
newItem->mimeType = KMimeType::findByURL( filePathName.lower() )->name();
newItem->fileFormat = KMimeType::findByURL( filePathName.lower() )->patterns().first().lower();
newItem->fileFormat.remove( 0, 2 );
// logger->log( 1000, " " + i18n("Mime type") + ": " + newItem->mimeType + " (" + i18n("Format") + ": " + newItem->fileFormat + ")" );
// newItem->mimeType="";
// HACK last choise is to use the extension without KDE's help
if( newItem->mimeType.isEmpty() || newItem->mimeType == "application/octet-stream" || newItem->mimeType == "text/plain" ) {
newItem->fileFormat = filePathName.right( filePathName.length() - filePathName.findRev(".") - 1 );
FormatItem *formatItem = config->getFormatItem( newItem->fileFormat );
if( formatItem ) newItem->mimeType = formatItem->mime_types.first();
// logger->log( 1000, " " + i18n("Mime type") + ": " + newItem->mimeType + " (" + i18n("Format") + ": " + newItem->fileFormat + ")" );
}
}
// logger->log( 1000, " " + i18n("Mime type") + ": " + newItem->mimeType + " (" + i18n("Format") + ": " + newItem->fileFormat + ")" );
// check whether the mime type has a decoder registered
if( !config->acceptFile( newItem->mimeType ) || ( newItem->fileFormat == "wav" && newItem->options.encodingOptions.sFormat == "wav" ) ) {
delete newItem;
continue;
}
newItem->options.filePathName = filePathName;
TQFileInfo fileInfo( filePathName );
newItem->fileName = fileInfo.fileName();
newItem->tags = tagEngine->readTags( KURL::decode_string(filePathName) );
if( newItem->tags == 0 ) {
// logger->log( 1000, " " + i18n("Reading tags failed") );
// FIXME check for wav files
FormatItem* formatItem = config->getFormatItem( newItem->mimeType );
if( formatItem && formatItem->size > 0 ) {
newItem->time = fileInfo.size() / formatItem->size;
}
else {
newItem->time = 210;
}
}
else {
// logger->log( 1000, " " + i18n("Tags successfully read") );
newItem->time = newItem->tags->length;
}
}
else {
// logger->log( 1000, " File is remote (not yet implemented) (" + *it + ")" );
filePathName = *it;
newItem->fileName = filePathName.right( filePathName.length() - filePathName.findRev("/") - 1 );
newItem->fileFormat = newItem->fileName.right( newItem->fileName.length() - newItem->fileName.findRev(".") - 1 ).lower();
// NOTE http will not work with KMimeType - this just works
if( filePathName.startsWith("http://") ) {
newItem->mimeType = KMimeType::findByURL( "file:///" + newItem->fileName.lower() )->name();
}
else {
newItem->mimeType = KMimeType::findByURL( filePathName.lower() )->name();
}
// check whether the mime type has a decoder registered
if( newItem->mimeType == "" ) {
newItem->mimeType = newItem->fileFormat;
}
if( !config->acceptFile( newItem->mimeType ) || ( newItem->fileFormat == "wav" && newItem->options.encodingOptions.sFormat == "wav" ) ) {
delete newItem;
continue;
}
newItem->options.filePathName = filePathName;
newItem->tags = 0;
newItem->time = 210; // NOTE we can't neither get the length nor guess it without accessing the file
// TODO get the file size and guess the length
}
updateItem( newItem );
emit increaseTime( newItem->time );
}
emit fileCountChanged( childCount() );
}
void FileList::addDir( const TQString& directory, const TQStringList& filter, bool recursive )
{
pScanStatus->setProgress( 0 );
pScanStatus->setTotalSteps( 0 );
pScanStatus->show(); // show the status while scanning the directories
kapp->processEvents();
int count = listDir( directory, filter, recursive, true );
listDir( directory, filter, recursive );
pScanStatus->hide(); // hide the status bar, when the scan is done
}
void FileList::addTracks( const TQString& device, TQValueList<int> trackList )
{
for( TQValueList<int>::Iterator it = trackList.begin(); it != trackList.end(); ++it ) {
// logger->log( 1000, i18n("Adding track") + TQString().sprintf(" %02i",*it) );
FileListItem* newItem = new FileListItem( this, lastItem() );
newItem->options = options->getCurrentOptions(); // FIXME speed up
// if( newItem->options.outputOptions.mode != OutputDirectory::Specify ) newItem->options.outputOptions.mode = OutputDirectory::MetaData;
newItem->notify = notify;
newItem->track = (*it);
newItem->fileName = i18n("Audio CD (%1)").arg(device) + ": " + i18n("Track") + TQString().sprintf(" %02i",newItem->track);
newItem->mimeType = "application/x-cda";
newItem->fileFormat = "cda";
newItem->local = true;
newItem->device = device;
newItem->tags = cdManager->getTags( device, newItem->track );
if( newItem->tags == 0 ) { // NOTE shouldn't happen
// logger->log( 1000, " " + i18n("Reading tags failed") );
newItem->time = 210;
newItem->options.filePathName = TQDir::homeDirPath() + "/" + i18n("Track") + TQString().sprintf(" %02i",newItem->track) + "." + newItem->fileFormat;
}
else {
// logger->log( 1000, " " + i18n("Tags successfully read") );
newItem->time = newItem->tags->length;
newItem->options.filePathName = TQDir::homeDirPath() + "/" + TQString().sprintf("%02i - ",newItem->track) + newItem->tags->title + "." + newItem->fileFormat;
newItem->fileName = i18n("Audio CD (%1)").arg(device) + ": " + TQString().sprintf("%02i - ",newItem->track) + newItem->tags->title;
}
updateItem( newItem );
emit increaseTime( newItem->time );
}
emit fileCountChanged( childCount() );
}
void FileList::addDisc( const TQString& device )
{
// logger->log( 1000, i18n("Adding full audio CD (%1)").arg(device) );
FileListItem* newItem = new FileListItem( this, lastItem() );
newItem->options = options->getCurrentOptions();
// if( newItem->options.outputOptions.mode != OutputDirectory::Specify ) newItem->options.outputOptions.mode = OutputDirectory::MetaData;
newItem->notify = notify;
newItem->track = 0;
newItem->fileName = i18n("Full audio CD (%1)").arg(device);
newItem->mimeType = "application/x-cda";
newItem->fileFormat = "cda";
newItem->local = true;
newItem->device = device;
newItem->tags = cdManager->getTags( device, 0 );
if( newItem->tags == 0 ) { // NOTE shouldn't happen
// logger->log( 1000, " " + i18n("Reading tags failed") );
newItem->time = 3600;
newItem->options.filePathName = TQDir::homeDirPath() + "/" + i18n("Audio CD") + "." + newItem->fileFormat;
}
else {
// logger->log( 1000, " " + i18n("Tags successfully read") );
newItem->time = newItem->tags->length;
newItem->options.filePathName = TQDir::homeDirPath() + newItem->tags->title + "." + newItem->fileFormat;
newItem->fileName = i18n("Full audio CD (%1)").arg(device) + ": " + newItem->tags->title;
}
updateItem( newItem );
emit increaseTime( newItem->time );
emit fileCountChanged( childCount() );
}
void FileList::itemFinished( FileListItem* item, int state )
{
if( state == 0 ) {
if( item ) delete item;
itemsSelected();
}
else if( state == 1 ) {
item->setText( columnByName(i18n("State")), i18n("Stopped") );
}
else {
item->setText( columnByName(i18n("State")), i18n("Failed") );
}
save( true );
FileListItem* it = firstChild();
int waitingCount = 0, convertingCount = 0;
while( it != 0 ) {
if( it->text(columnByName(i18n("State"))) != i18n("Failed") && it->text(columnByName(i18n("State"))) != i18n("Stopped") && it->text(columnByName(i18n("State"))) != i18n("Will be skipped") ) {
if( it->text(columnByName(i18n("State"))) == i18n("Waiting") /*|| it->text(columnByName(i18n("State"))) == i18n("Stopped")*/ ) {
waitingCount++;
}
else {
convertingCount++;
}
}
it = it->nextSibling();
}
if( waitingCount > 0 && queue ) {
convertNextItem();
}
else if( convertingCount == 0 ) {
queue = false;
float time = 0;
it = firstChild();
while( it != 0 ) {
// it->setText( columnByName(i18n("State")), i18n("Waiting") );
updateItem( it );
time += it->time;
it = it->nextSibling();
}
emit finished( time );
emit stoppedConversion();
emit fileCountChanged( childCount() );
}
}
void FileList::rippingFinished( const TQString& device )
{
if( !queue ) return;
int count = 0;
FileListItem *item = firstChild();
while( item != 0 ) {
if( item->converting ) {
count++;
}
item = item->nextSibling();
}
// look for "Waiting" files first ...
item = firstChild();
while( item != 0 && count < config->data.general.numFiles ) {
if( !item->converting && item->text(columnByName(i18n("State"))) == i18n("Waiting") ) {
if( item->track >= 0 && item->device == device ) {
convertItem( item );
itemsSelected();
return;
}
}
item = item->nextSibling();
}
// ... then convert the stopped, too
/* item = firstChild();
while( item != 0 && count < config->data.general.numFiles ) {
if( !item->converting && item->text(columnByName(i18n("State"))) == i18n("Stopped") ) {
if( item->track >= 0 && item->device == device ) {
convertItem( item );
itemsSelected();
return;
}
}
item = item->nextSibling();
}*/
}
void FileList::updateItem( FileListItem* item )
{
if( !item ) return;
if( !item->converting ) {
if( config->data.general.conflictHandling == 1 && TQFile::exists(KURL::decode_string(OutputDirectory::calcPath(item,config))) ) { // was: .replace("%2f","%252f")
item->setText( columnByName(i18n("State")), i18n("Will be skipped") );
}
else {
item->setText( columnByName(i18n("State")), i18n("Waiting") );
}
}
else {
item->setText( columnByName(i18n("State")), i18n("Converting") );
}
if( item->track >= 0 ) item->setText( columnByName(i18n("Input")), KURL::decode_string(item->fileName).replace("%2f","/").replace("%%","%") );
else item->setText( columnByName(i18n("Input")), KURL::decode_string(item->options.filePathName).replace("%2f","/").replace("%%","%") );
item->setText( columnByName(i18n("Output")), KURL::decode_string(OutputDirectory::uniqueFileName(OutputDirectory::calcPath(item,config))).replace("%2f","/").replace("%%","%") );
item->setText( columnByName(i18n("Quality")), config->getProfileName(item->options) );
}
void FileList::showOptionsEditorDialog()
{
// FIXME options are set to defaults
if( optionsEditor == 0 ) {
optionsEditor = new OptionsEditor( tagEngine, config, this, 0, "optionsEditor" );
if( optionsEditor == 0 ) {
// TODO error message
return;
}
// }
connect( TQT_TQOBJECT(this), TQT_SIGNAL(editItems(TQValueList<FileListItem*>)),
optionsEditor, TQT_SLOT(itemsSelected(TQValueList<FileListItem*>))
);
connect( TQT_TQOBJECT(this), TQT_SIGNAL(setPreviousItemEnabled(bool)),
optionsEditor, TQT_SLOT(setPreviousEnabled(bool))
);
connect( TQT_TQOBJECT(this), TQT_SIGNAL(setNextItemEnabled(bool)),
optionsEditor, TQT_SLOT(setNextEnabled(bool))
);
connect( optionsEditor, TQT_SIGNAL(user2Clicked()),
TQT_TQOBJECT(this), TQT_SLOT(selectPreviousItem())
);
connect( optionsEditor, TQT_SIGNAL(user1Clicked()),
TQT_TQOBJECT(this), TQT_SLOT(selectNextItem())
);
/*connect( TQT_TQOBJECT(this), TQT_SIGNAL(moveEditor(int,int)),
optionsEditor, TQT_SLOT(moveWindow(int,int))
);*/
}
itemsSelected();
optionsEditor->show();
}
// FIXME still makes some troubles (wreaks some items) and crashes
void FileList::selectPreviousItem()
{
if( selectedFiles.first() == 0 ) return;
FileListItem* item = selectedFiles.first()->itemAbove();
if( item != 0 ) {
item->setSelected( true );
repaintItem( item );
ensureItemVisible( item );
}
for( TQValueList<FileListItem*>::Iterator it = selectedFiles.begin(); it != selectedFiles.end(); ++it ) {
(*it)->setSelected( false );
repaintItem( *it );
}
itemsSelected();
}
void FileList::selectNextItem()
{
if( selectedFiles.last() == 0 ) return;
FileListItem* item = selectedFiles.last()->itemBelow();
if( item != 0 ) {
item->setSelected( true );
repaintItem( item );
ensureItemVisible( item );
}
for( TQValueList<FileListItem*>::Iterator it = selectedFiles.begin(); it != selectedFiles.end(); ++it ) {
(*it)->setSelected( false );
repaintItem( *it );
}
itemsSelected();
}
void FileList::itemsSelected()
{
selectedFiles.clear();
for( FileListItem *item = firstChild(); item != NULL; item = item->nextSibling() ) {
if( item->isSelected() ) {
selectedFiles.append( item );
}
}
if( selectedFiles.count() > 0 ) {
if( selectedFiles.first()->itemAbove() != 0 ) emit setPreviousItemEnabled( true );
else emit setPreviousItemEnabled( false );
if( selectedFiles.last()->itemBelow() != 0 ) emit setNextItemEnabled( true );
else emit setNextItemEnabled( false );
}
else {
emit setPreviousItemEnabled( false );
emit setNextItemEnabled( false );
}
emit editItems( selectedFiles );
}
/*void FileList::moveOptionsEditor( int x, int y )
{
emit moveEditor( x, y );
}*/
void FileList::startConversion()
{
// iterate through all items and set the state to "Waiting"
FileListItem* it = firstChild();
while( it != 0 ) {
// it->setText( columnByName(i18n("State")), i18n("Waiting") );
if( !it->converting && it->text(columnByName(i18n("State"))) != i18n("Will be skipped") ) {
it->setText( columnByName(i18n("State")), i18n("Waiting") );
}
it = it->nextSibling();
}
queue = true;
emit startedConversion();
convertNextItem();
}
void FileList::stopConversion()
{
queue = false;
emit stopClicked();
}
void FileList::continueConversion()
{
queue = true;
emit continueClicked();
}
void FileList::killConversion()
{
queue = false;
FileListItem *item = firstChild();
while( item != 0 ) {
if( item->converting ) {
emit stopItem( item );
}
item = item->nextSibling();
}
}
void FileList::convertNextItem()
{
if( !queue ) return;
TQStringList devices;
// look for tracks that are being ripped
int count = 0;
FileListItem *item = firstChild();
while( item != 0 ) {
if( item->converting ) {
count++;
if( item->ripping ) {
devices += item->device;
}
}
item = item->nextSibling();
}
// look for "Waiting" files first ...
item = firstChild();
while( item != 0 && count < config->data.general.numFiles ) {
if( !item->converting && item->text(columnByName(i18n("State"))) == i18n("Waiting") ) {
if( item->track >= 0 && devices.findIndex(item->device) == -1 ) {
convertItem( item );
count++;
devices += item->device;
}
else if( item->track < 0 ) {
convertItem( item );
count++;
}
}
item = item->nextSibling();
}
// ... then convert the stopped, too
// item = firstChild();
// while( item != 0 && count < config->data.general.numFiles ) {
// if( !item->converting && item->text(columnByName(i18n("State"))) == i18n("Stopped") ) {
// if( item->track >= 0 && devices.findIndex(item->device) == -1 ) {
// convertItem( item );
// count++;
// devices += item->device;
// }
// else if( item->track < 0 ) {
// convertItem( item );
// count++;
// }
// }
// item = item->nextSibling();
// }
itemsSelected();
FileListItem* it = firstChild();
int waitingCount = 0, convertingCount = 0;
while( it != 0 ) {
if( it->text(columnByName(i18n("State"))) != i18n("Failed") && it->text(columnByName(i18n("State"))) != i18n("Stopped") && it->text(columnByName(i18n("State"))) != i18n("Will be skipped") ) {
if( it->text(columnByName(i18n("State"))) == i18n("Waiting") /*|| it->text(columnByName(i18n("State"))) == i18n("Stopped")*/ ) {
waitingCount++;
}
else {
convertingCount++;
}
}
it = it->nextSibling();
}
if( waitingCount == 0 && convertingCount == 0 ) itemFinished( 0, 0 );
}
void FileList::load( bool autosave )
{
// NOTE clear the file list befor adding the saved items?
int version;
TQString name;
FileListItem* lastListItem = lastItem();
TQString filename;
if( autosave ) filename = locateLocal("data","soundkonverter/filelist.autosave.xml");
else filename = locateLocal("data","soundkonverter/filelist.xml");
TQDomDocument domTree;
TQFile opmlFile( filename );
if( !opmlFile.open( IO_ReadOnly ) ) return;
if( !domTree.setContent( &opmlFile ) ) return;
opmlFile.close();
TQDomElement root = domTree.documentElement();
if( root.attribute("type") != "filelist" ) return;
TQDomNode node, sub1Node, sub2Node;
node = root.firstChild();
while( !node.isNull() ) {
if( node.isElement() && node.nodeName() == "info" ) {
version = node.toElement().attribute("version").toInt();
}
else if( node.isElement() && node.nodeName() == "file" ) {
FileListItem* item = new FileListItem( this, lastListItem );
lastListItem = item;
item->fileName = node.toElement().attribute("fileName");
item->mimeType = node.toElement().attribute("mimeType");
item->fileFormat = node.toElement().attribute("fileFormat");
item->local = node.toElement().attribute("local").toInt();
item->track = node.toElement().attribute("track").toInt();
item->time = node.toElement().attribute("time").toInt();
item->options.filePathName = node.toElement().attribute("filePathName");
item->options.outputFilePathName = node.toElement().attribute("outputFilePathName");
sub1Node = node.toElement().firstChild();
while( !sub1Node.isNull() ) {
if( sub1Node.isElement() && sub1Node.nodeName() == "encodingOptions" ) {
item->options.encodingOptions.sFormat = sub1Node.toElement().attribute("sFormat");
item->options.encodingOptions.sQualityMode = sub1Node.toElement().attribute("sQualityMode");
item->options.encodingOptions.iQuality = sub1Node.toElement().attribute("iQuality").toInt();
item->options.encodingOptions.sBitrateMode = sub1Node.toElement().attribute("sBitrateMode");
item->options.encodingOptions.bBitrateRange = sub1Node.toElement().attribute("bBitrateRange").toInt();
item->options.encodingOptions.iMinBitrate = sub1Node.toElement().attribute("iMinBitrate").toInt();
item->options.encodingOptions.iMaxBitrate = sub1Node.toElement().attribute("iMaxBitrate").toInt();
item->options.encodingOptions.sInOutFiles = sub1Node.toElement().attribute("sInOutFiles");
sub2Node = sub1Node.toElement().firstChild();
while( !sub2Node.isNull() ) {
if( sub2Node.isElement() && sub2Node.nodeName() == "samplingRate" ) {
item->options.encodingOptions.samplingRate.bEnabled = sub2Node.toElement().attribute("bEnabled").toInt();
item->options.encodingOptions.samplingRate.iSamplingRate = sub2Node.toElement().attribute("iSamplingRate").toInt();
}
else if( sub2Node.isElement() && sub2Node.nodeName() == "channels" ) {
item->options.encodingOptions.channels.bEnabled = sub2Node.toElement().attribute("bEnabled").toInt();
item->options.encodingOptions.channels.sChannels = sub2Node.toElement().attribute("sChannels");
}
else if( sub2Node.isElement() && sub2Node.nodeName() == "replaygain" ) {
item->options.encodingOptions.replaygain.bEnabled = sub2Node.toElement().attribute("bEnabled").toInt();
}
sub2Node = sub2Node.nextSibling();
}
}
else if( sub1Node.isElement() && sub1Node.nodeName() == "outputOptions" ) {
item->options.outputOptions.mode = (OutputDirectory::Mode)sub1Node.toElement().attribute("mode").toInt();
item->options.outputOptions.directory = sub1Node.toElement().attribute("directory");
}
else if( sub1Node.isElement() && sub1Node.nodeName() == "tags" ) {
item->tags = new TagData();
item->tags->artist = sub1Node.toElement().attribute("artist");
item->tags->composer = sub1Node.toElement().attribute("composer");
item->tags->album = sub1Node.toElement().attribute("album");
item->tags->title = sub1Node.toElement().attribute("title");
item->tags->genre = sub1Node.toElement().attribute("genre");
item->tags->comment = sub1Node.toElement().attribute("comment");
item->tags->track = sub1Node.toElement().attribute("track").toInt();
item->tags->disc = sub1Node.toElement().attribute("disc").toInt();
item->tags->year = sub1Node.toElement().attribute("year").toInt();
item->tags->track_gain = sub1Node.toElement().attribute("track_gain").toFloat();
item->tags->album_gain = sub1Node.toElement().attribute("album_gain").toFloat();
item->tags->length = sub1Node.toElement().attribute("length").toInt();
item->tags->fileSize = sub1Node.toElement().attribute("fileSize").toInt();
item->tags->bitrate = sub1Node.toElement().attribute("bitrate").toInt();
item->tags->samplingRate = sub1Node.toElement().attribute("samplingRate").toInt();
}
sub1Node = sub1Node.nextSibling();
}
updateItem( item );
emit increaseTime( item->time );
}
node = node.nextSibling();
}
emit fileCountChanged( childCount() );
}
void FileList::save( bool autosave )
{
// NOTE filenames should be encoded before saving - but it works fine without it (hm...)
TQTime time;
time.start();
TQDomDocument domTree;
TQDomElement root = domTree.createElement( "soundkonverter" );
root.setAttribute( "type", "filelist" );
domTree.appendChild( root );
TQDomElement info = domTree.createElement( "info" );
info.setAttribute( "version", "300" );
root.appendChild( info );
for( FileListItem* item = firstChild(); item != 0; item = item->nextSibling() ) {
TQDomElement file = domTree.createElement( "file" );
file.setAttribute( "fileName", item->fileName );
file.setAttribute( "mimeType", item->mimeType );
file.setAttribute( "fileFormat", item->fileFormat );
file.setAttribute( "local", item->local );
file.setAttribute( "track", item->track );
file.setAttribute( "device", item->device );
file.setAttribute( "time", item->time );
file.setAttribute( "filePathName", item->options.filePathName );
file.setAttribute( "outputFilePathName", item->options.outputFilePathName );
TQDomElement encodingOptions = domTree.createElement( "encodingOptions" );
encodingOptions.setAttribute( "sFormat", item->options.encodingOptions.sFormat );
encodingOptions.setAttribute( "sQualityMode", item->options.encodingOptions.sQualityMode );
encodingOptions.setAttribute( "iQuality", item->options.encodingOptions.iQuality );
encodingOptions.setAttribute( "sBitrateMode", item->options.encodingOptions.sBitrateMode );
encodingOptions.setAttribute( "bBitrateRange", item->options.encodingOptions.bBitrateRange );
encodingOptions.setAttribute( "iMinBitrate", item->options.encodingOptions.iMinBitrate );
encodingOptions.setAttribute( "iMaxBitrate", item->options.encodingOptions.iMaxBitrate );
TQDomElement samplingRate = domTree.createElement( "samplingRate" );
samplingRate.setAttribute( "bEnabled", item->options.encodingOptions.samplingRate.bEnabled );
samplingRate.setAttribute( "iSamplingRate", item->options.encodingOptions.samplingRate.iSamplingRate );
encodingOptions.appendChild( samplingRate );
TQDomElement channels = domTree.createElement( "channels" );
channels.setAttribute( "bEnabled", item->options.encodingOptions.channels.bEnabled );
channels.setAttribute( "sChannels", item->options.encodingOptions.channels.sChannels );
encodingOptions.appendChild( channels );
TQDomElement replaygain = domTree.createElement( "replaygain" );
replaygain.setAttribute( "bEnabled", item->options.encodingOptions.replaygain.bEnabled );
encodingOptions.appendChild( replaygain );
encodingOptions.setAttribute( "sInOutFiles", item->options.encodingOptions.sInOutFiles );
file.appendChild( encodingOptions );
TQDomElement outputOptions = domTree.createElement( "outputOptions" );
outputOptions.setAttribute( "mode", int(item->options.outputOptions.mode) );
outputOptions.setAttribute( "directory", item->options.outputOptions.directory );
file.appendChild( outputOptions );
if( item->tags )
{
TQDomElement tags = domTree.createElement( "tags" );
tags.setAttribute( "artist", item->tags->artist );
tags.setAttribute( "composer", item->tags->composer );
tags.setAttribute( "album", item->tags->album );
tags.setAttribute( "title", item->tags->title );
tags.setAttribute( "genre", item->tags->genre );
tags.setAttribute( "comment", item->tags->comment );
tags.setAttribute( "track", item->tags->track );
tags.setAttribute( "disc", item->tags->disc );
tags.setAttribute( "year", item->tags->year );
tags.setAttribute( "track_gain", item->tags->track_gain );
tags.setAttribute( "album_gain", item->tags->album_gain );
tags.setAttribute( "length", item->tags->length );
tags.setAttribute( "fileSize", item->tags->fileSize );
tags.setAttribute( "bitrate", item->tags->bitrate );
tags.setAttribute( "samplingRate", item->tags->samplingRate );
file.appendChild( tags );
}
root.appendChild( file );
}
TQString filename;
if( autosave ) filename = locateLocal("data","soundkonverter/filelist.autosave.xml");
else filename = locateLocal("data","soundkonverter/filelist.xml");
TQFile opmlFile( filename );
if( !opmlFile.open( IO_WriteOnly ) ) return;
TQTextStream ts( &opmlFile );
ts << domTree.toString();
opmlFile.close();
logger->log( 1000, "save file list: " + TQString::number(time.elapsed()) );
}
void FileList::debug() // NOTE DEBUG
{
logger->log( 1000, "DEBUG begin" );
ConversionOptions conversionOptions;
TQStringList formats = config->allEncodableFormats();
for( TQStringList::Iterator a = formats.begin(); a != formats.end(); ++a )
{
logger->log( 1000, "format: " + (*a) );
FormatItem* formatItem = config->getFormatItem( *a );
if( formatItem == 0 ) continue;
for( TQValueList<ConvertPlugin*>::Iterator b = formatItem->encoders.begin(); b != formatItem->encoders.end(); ++b ) {
logger->log( 1000, " encoder: " + (*b)->enc.bin );
formatItem->encoder = (*b);
if( (*b)->enc.strength.enabled ) {
formatItem->compressionLevel = (*b)->enc.strength.default_value;
}
if( (*b)->enc.replaygain.enabled ) {
formatItem->internalReplayGain = true;
}
if( (*b)->enc.lossless.enabled ) {
options->setProfile( "Lossless" );
options->setFormat( *a );
options->setOutputDirectory( "/home/daniel/soundKonverter/test_output" );
conversionOptions = options->getCurrentOptions();
conversionOptions.encodingOptions.sInOutFiles = debug_params( conversionOptions, formatItem );
options->setCurrentOptions( conversionOptions );
addFiles( "/home/daniel/soundKonverter/test.mp3" );
}
if( (*b)->enc.lossy.enabled ) {
options->setProfile( "Medium" );
if( (*b)->enc.lossy.bitrate.cbr.enabled ) {
options->setFormat( *a );
conversionOptions = options->getCurrentOptions();
conversionOptions.encodingOptions.sQualityMode = i18n("Bitrate");
conversionOptions.encodingOptions.sBitrateMode = "cbr";
conversionOptions.encodingOptions.iQuality = 128;
conversionOptions.encodingOptions.sInOutFiles = debug_params( conversionOptions, formatItem );
options->setCurrentOptions( conversionOptions );
options->setOutputDirectory( "/home/daniel/soundKonverter/test_output" );
addFiles( "/home/daniel/soundKonverter/test.mp3" );
}
if( (*b)->enc.lossy.bitrate.abr.enabled ) {
options->setFormat( *a );
conversionOptions = options->getCurrentOptions();
conversionOptions.encodingOptions.sQualityMode = i18n("Bitrate");
conversionOptions.encodingOptions.sBitrateMode = "abr";
conversionOptions.encodingOptions.iQuality = 128;
conversionOptions.encodingOptions.sInOutFiles = debug_params( conversionOptions, formatItem );
options->setCurrentOptions( conversionOptions );
options->setOutputDirectory( "/home/daniel/soundKonverter/test_output" );
addFiles( "/home/daniel/soundKonverter/test.mp3" );
if( (*b)->enc.lossy.bitrate.abr.bitrate_range.enabled ) {
options->setFormat( *a );
conversionOptions = options->getCurrentOptions();
conversionOptions.encodingOptions.sQualityMode = i18n("Bitrate");
conversionOptions.encodingOptions.sBitrateMode = "abr";
conversionOptions.encodingOptions.iQuality = 128;
conversionOptions.encodingOptions.bBitrateRange = true;
conversionOptions.encodingOptions.iMinBitrate = 64;
conversionOptions.encodingOptions.iMaxBitrate = 192;
conversionOptions.encodingOptions.sInOutFiles = debug_params( conversionOptions, formatItem );
options->setCurrentOptions( conversionOptions );
options->setOutputDirectory( "/home/daniel/soundKonverter/test_output" );
addFiles( "/home/daniel/soundKonverter/test.mp3" );
}
}
if( (*b)->enc.lossy.quality.enabled ) {
options->setFormat( *a );
conversionOptions = options->getCurrentOptions();
conversionOptions.encodingOptions.sQualityMode = i18n("Quality");
conversionOptions.encodingOptions.iQuality = 40;
conversionOptions.encodingOptions.sInOutFiles = debug_params( conversionOptions, formatItem );
options->setCurrentOptions( conversionOptions );
options->setOutputDirectory( "/home/daniel/soundKonverter/test_output" );
addFiles( "/home/daniel/soundKonverter/test.mp3" );
}
}
}
for( TQValueList<ConvertPlugin*>::Iterator b = formatItem->decoders.begin(); b != formatItem->decoders.end(); ++b ) {
formatItem->decoder = (*b);
}
for( TQValueList<ReplayGainPlugin*>::Iterator b = formatItem->replaygains.begin(); b != formatItem->replaygains.end(); ++b ) {
formatItem->replaygain = (*b);
}
}
logger->log( 1000, "DEBUG end" );
}
TQString FileList::debug_params( ConversionOptions conversionOptions, FormatItem* formatItem ) // NOTE DEBUG
{
ConvertPlugin* plugin = formatItem->encoder;
TQString sStrength;
TQString sBitrate;
TQString sQuality;
TQString sMinBitrate;
TQString sMaxBitrate;
TQString sSamplingRate;
int t_int;
float t_float;
TQString param = "";
if( !plugin->enc.param.isEmpty() ) param.append( " " + plugin->enc.param );
if( !plugin->enc.overwrite.isEmpty() ) param.append( " " + plugin->enc.overwrite );
if( plugin->enc.strength.enabled ) {
param.append( " " + plugin->enc.strength.param );
int compressionLevel = formatItem->compressionLevel;
if( plugin->enc.strength.profiles.empty() ) {
if( plugin->enc.strength.step < 1 ) {
if( plugin->enc.strength.range_max >= plugin->enc.strength.range_min )
sStrength = TQString::number( compressionLevel );
else
sStrength = TQString::number( plugin->enc.strength.range_min - compressionLevel );
}
else {
if( plugin->enc.strength.range_max >= plugin->enc.strength.range_min )
sStrength = TQString::number( int(compressionLevel) );
else
sStrength = TQString::number( int(plugin->enc.strength.range_min - compressionLevel) );
}
if( plugin->enc.strength.separator != '.' ) sStrength.replace( TQChar('.'), plugin->enc.strength.separator );
}
else {
TQStringList::Iterator it = plugin->enc.strength.profiles.at( compressionLevel );
sStrength = *it;
}
}
if( conversionOptions.encodingOptions.sQualityMode == i18n("Bitrate") ) {
if( conversionOptions.encodingOptions.sBitrateMode == "cbr" && plugin->enc.lossy.bitrate.cbr.enabled ) {
param.append( " " + plugin->enc.lossy.bitrate.cbr.param );
sBitrate = TQString::number( conversionOptions.encodingOptions.iQuality );
}
else if( conversionOptions.encodingOptions.sBitrateMode == "abr" && plugin->enc.lossy.bitrate.abr.enabled ) {
param.append( " " + plugin->enc.lossy.bitrate.abr.param );
sBitrate = TQString::number( conversionOptions.encodingOptions.iQuality );
if( conversionOptions.encodingOptions.bBitrateRange && plugin->enc.lossy.bitrate.abr.bitrate_range.enabled ) {
param.append( " " + plugin->enc.lossy.bitrate.abr.bitrate_range.param_min );
sMinBitrate = TQString::number( conversionOptions.encodingOptions.iMinBitrate );
param.append( " " + plugin->enc.lossy.bitrate.abr.bitrate_range.param_max );
sMaxBitrate = TQString::number( conversionOptions.encodingOptions.iMaxBitrate );
}
}
}
else if( conversionOptions.encodingOptions.sQualityMode == i18n("Quality") && plugin->enc.lossy.quality.enabled ) {
param.append( " " + plugin->enc.lossy.quality.param );
if( plugin->enc.lossy.quality.profiles.empty() ) {
if( plugin->enc.lossy.quality.step < 1 ) {
if( plugin->enc.lossy.quality.range_max >= plugin->enc.lossy.quality.range_min)
t_float = ( (float)conversionOptions.encodingOptions.iQuality * ( plugin->enc.lossy.quality.range_max - plugin->enc.lossy.quality.range_min ) / 100 ) + plugin->enc.lossy.quality.range_min;
else
t_float = ( (100.0f - (float)conversionOptions.encodingOptions.iQuality) * ( plugin->enc.lossy.quality.range_min - plugin->enc.lossy.quality.range_max ) / 100 ) + plugin->enc.lossy.quality.range_max;
//t_float -= t_float%plugin->enc.quality.step;
//sQuality = TQString().sprintf( "%.2f", t_float );
sQuality = TQString::number( t_float );
}
else {
if( plugin->enc.lossy.quality.range_max >= plugin->enc.lossy.quality.range_min)
t_int = ( conversionOptions.encodingOptions.iQuality * (int)( plugin->enc.lossy.quality.range_max - plugin->enc.lossy.quality.range_min ) / 100) + (int)plugin->enc.lossy.quality.range_min;
else
t_int = ( (100 - conversionOptions.encodingOptions.iQuality) * (int)( plugin->enc.lossy.quality.range_min - plugin->enc.lossy.quality.range_max ) / 100) + (int)plugin->enc.lossy.quality.range_max;
//t_int -= t_int%plugin->enc.quality.step;
sQuality = TQString::number( t_int );
}
if( plugin->enc.bin == "oggenc" ) sQuality.replace(TQChar('.'),TDEGlobal::locale()->decimalSymbol());
else if( plugin->enc.lossy.quality.separator != '.' ) sQuality.replace(TQChar('.'),plugin->enc.lossy.quality.separator);
}
else {
TQStringList::Iterator it = plugin->enc.lossy.quality.profiles.at( int(conversionOptions.encodingOptions.iQuality*plugin->enc.lossy.quality.range_max/100) );
sQuality = *it;
}
}
else if( conversionOptions.encodingOptions.sQualityMode == i18n("Lossless") && plugin->enc.lossless.enabled ) {
param.append( " " + plugin->enc.lossless.param );
}
else if( conversionOptions.encodingOptions.sQualityMode == i18n("Hybrid") && plugin->enc.hybrid.enabled ) {
param.append( " " + plugin->enc.hybrid.param );
sBitrate = TQString::number( conversionOptions.encodingOptions.iQuality );
}
if( conversionOptions.encodingOptions.samplingRate.bEnabled && plugin->enc.lossy.samplingrate.enabled ) {
param.append( " " + plugin->enc.lossy.samplingrate.param );
if( plugin->enc.lossy.samplingrate.unit == PluginLoaderBase::Hz ) {
sSamplingRate = TQString::number( conversionOptions.encodingOptions.samplingRate.iSamplingRate );
}
else {
sSamplingRate = TQString::number( (float)conversionOptions.encodingOptions.samplingRate.iSamplingRate/1000 );
}
}
if( conversionOptions.encodingOptions.channels.bEnabled ) {
if( conversionOptions.encodingOptions.channels.sChannels == i18n("Mono") && plugin->enc.lossy.channels.mono_enabled ) {
param.append( " " + plugin->enc.lossy.channels.mono_param );
}
else if( conversionOptions.encodingOptions.channels.sChannels == i18n("Stereo") && plugin->enc.lossy.channels.stereo_enabled ) {
param.append( " " + plugin->enc.lossy.channels.stereo_param );
}
else if( conversionOptions.encodingOptions.channels.sChannels == i18n("Joint-Stereo") && plugin->enc.lossy.channels.joint_stereo_enabled ) {
param.append( " " + plugin->enc.lossy.channels.joint_stereo_param );
}
else if( conversionOptions.encodingOptions.channels.sChannels == i18n("Forced Joint-Stereo") && plugin->enc.lossy.channels.forced_joint_stereo_enabled ) {
param.append( " " + plugin->enc.lossy.channels.forced_joint_stereo_param );
}
else if( conversionOptions.encodingOptions.channels.sChannels == i18n("Dual Channels") && plugin->enc.lossy.channels.dual_channels_enabled ) {
param.append( " " + plugin->enc.lossy.channels.dual_channels_param );
}
}
if( conversionOptions.encodingOptions.replaygain.bEnabled && plugin->enc.replaygain.enabled && plugin->enc.replaygain.use && formatItem->internalReplayGain ) {
param.append( " " + plugin->enc.replaygain.use );
}
else if( plugin->enc.replaygain.enabled && plugin->enc.replaygain.avoid ) {
param.append( " " + plugin->enc.replaygain.avoid );
}
// if( !tagEngine->canWrite(conversionOptions.encodingOptions.sFormat) && item->fileListItem->tags && plugin->enc.tag.enabled ) {
if( plugin->enc.tag.enabled && conversionOptions.encodingOptions.sFormat != "aac" ) { // HACK don't write metadata to aac
if( !plugin->enc.tag.param.isEmpty() ) param.append( " " + plugin->enc.tag.param );
if( !plugin->enc.tag.artist.isEmpty() ) param.append( " " + plugin->enc.tag.artist );
if( !plugin->enc.tag.album.isEmpty() ) param.append( " " + plugin->enc.tag.album );
if( !plugin->enc.tag.comment.isEmpty() ) param.append( " " + plugin->enc.tag.comment );
if( !plugin->enc.tag.disc.isEmpty() ) param.append( " " + plugin->enc.tag.disc );
if( !plugin->enc.tag.genre.isEmpty() ) param.append( " " + plugin->enc.tag.genre );
if( !plugin->enc.tag.track.isEmpty() ) param.append( " " + plugin->enc.tag.track );
if( !plugin->enc.tag.composer.isEmpty() ) param.append( " " + plugin->enc.tag.composer );
if( !plugin->enc.tag.title.isEmpty() ) param.append( " " + plugin->enc.tag.title );
if( !plugin->enc.tag.year.isEmpty() ) param.append( " " + plugin->enc.tag.year );
}
param.replace( "%c", sStrength );
param.replace( "%b", sBitrate );
param.replace( "%q", sQuality );
param.replace( "%m", sMinBitrate );
param.replace( "%M", sMaxBitrate );
param.replace( "%s", sSamplingRate );
return conversionOptions.encodingOptions.sInOutFiles.replace( "%p", param );
}