# 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 )
{
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 ) ;
}