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.
1263 lines
46 KiB
1263 lines
46 KiB
15 years ago
|
|
||
|
#include "replaygainfilelist.h"
|
||
|
#include "tagengine.h"
|
||
|
#include "logger.h"
|
||
|
#include "config.h"
|
||
|
#include "replaygain.h"
|
||
|
#include "replaygainpluginloader.h"
|
||
|
|
||
|
#include <qdir.h>
|
||
|
#include <qpainter.h>
|
||
|
#include <qsimplerichtext.h>
|
||
|
#include <qapplication.h>
|
||
|
#include <qheader.h>
|
||
|
#include <qlayout.h>
|
||
|
#include <qtimer.h>
|
||
|
|
||
|
#include <klocale.h>
|
||
|
#include <kiconloader.h>
|
||
|
#include <kurldrag.h>
|
||
|
#include <kpopupmenu.h>
|
||
|
#include <kaction.h>
|
||
|
#include <kactioncollection.h>
|
||
|
#include <kmessagebox.h>
|
||
|
#include <kmountpoint.h>
|
||
|
#include <kprogress.h>
|
||
|
#include <kprocess.h>
|
||
|
#include <kmimetype.h>
|
||
|
#include <kapplication.h>
|
||
|
#include <kuser.h>
|
||
|
|
||
|
// TODO move listDir, addFiles, addDir, etc -- done?
|
||
|
|
||
|
// ### soundkonverter 0.4: give the 'track' and 'album' column a minimum width and fill the rest of the space with the 'file' column - make some margins, too
|
||
|
|
||
|
|
||
|
ReplayGainFileListItem::ReplayGainFileListItem( QListView* parent )
|
||
|
: KListViewItem( parent )
|
||
|
{
|
||
|
m_type = File;
|
||
|
mimeType = "application/octet-stream";
|
||
|
addingReplayGain = false;
|
||
|
queued = false;
|
||
|
}
|
||
|
|
||
|
// ReplayGainFileListItem::ReplayGainFileListItem( QListView* parent, QListViewItem* after )
|
||
|
// : KListViewItem( parent, after )
|
||
|
// {
|
||
|
// m_type = File;
|
||
|
// mimeType = "application/octet-stream";
|
||
|
// addingReplayGain = false;
|
||
|
// queued = false;
|
||
|
// }
|
||
|
|
||
|
ReplayGainFileListItem::ReplayGainFileListItem( ReplayGainFileListItem* parent )
|
||
|
: KListViewItem( parent )
|
||
|
{
|
||
|
m_type = File;
|
||
|
mimeType = "application/octet-stream";
|
||
|
addingReplayGain = false;
|
||
|
queued = false;
|
||
|
}
|
||
|
|
||
|
ReplayGainFileListItem::~ReplayGainFileListItem()
|
||
|
{}
|
||
|
|
||
|
void ReplayGainFileListItem::paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int alignment )
|
||
|
{
|
||
|
// NOTE speed up this function
|
||
|
// NOTE calculate the red color
|
||
|
|
||
|
QColorGroup _cg( cg );
|
||
|
QColor c;
|
||
|
|
||
|
if( column == ((ReplayGainFileList*)listView())->columnByName(i18n("File")) )
|
||
|
{
|
||
|
int margin = listView()->itemMargin();
|
||
|
int w = width - 2*margin;
|
||
|
int h = height();
|
||
|
QRect textRect = p->boundingRect( margin, 0, w, h, alignment, text(column) );
|
||
|
|
||
|
if( textRect.width() > w ) {
|
||
|
alignment = Qt::AlignRight | Qt::SingleLine;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( isSelected() && addingReplayGain ) {
|
||
|
_cg.setColor( QColorGroup::Highlight, QColor( 215, 62, 62 ) );
|
||
|
QListViewItem::paintCell( p, _cg, column, width, alignment );
|
||
|
return;
|
||
|
}
|
||
|
else if( addingReplayGain && column != listView()->sortColumn() ) {
|
||
|
_cg.setColor( QColorGroup::Base, QColor( 255, 234, 234 ) );
|
||
|
QListViewItem::paintCell( p, _cg, column, width, alignment );
|
||
|
return;
|
||
|
}
|
||
|
else if( addingReplayGain && column == listView()->sortColumn() ) {
|
||
|
_cg.setColor( QColorGroup::Base, QColor( 247, 227, 227 ) );
|
||
|
QListViewItem::paintCell( p, _cg, column, width, alignment );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if( isSelected() && queued ) {
|
||
|
_cg.setColor( QColorGroup::Highlight, QColor( 230, 232, 100 ) );
|
||
|
QListViewItem::paintCell( p, _cg, column, width, alignment );
|
||
|
return;
|
||
|
}
|
||
|
else if( queued && column != listView()->sortColumn() ) {
|
||
|
_cg.setColor( QColorGroup::Base, QColor( 255, 255, 190 ) );
|
||
|
QListViewItem::paintCell( p, _cg, column, width, alignment );
|
||
|
return;
|
||
|
}
|
||
|
else if( queued && column == listView()->sortColumn() ) {
|
||
|
_cg.setColor( QColorGroup::Base, QColor( 255, 243, 168 ) );
|
||
|
QListViewItem::paintCell( p, _cg, column, width, alignment );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
KListViewItem::paintCell( p, _cg, column, width, alignment );
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileListItem::setType( Type type )
|
||
|
{
|
||
|
if( type == m_type ) return;
|
||
|
|
||
|
m_type = type;
|
||
|
|
||
|
if( type == Album ) {
|
||
|
setOpen( true );
|
||
|
setPixmap( 0, KGlobal::iconLoader()->loadIcon("cdrom_unmount",KIcon::Small) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileListItem::updateReplayGainCells( TagData* tags )
|
||
|
{
|
||
|
if( !tags ) {
|
||
|
setText( ((ReplayGainFileList*)listView())->columnByName(i18n("Track")), i18n("Unknown") );
|
||
|
setText( ((ReplayGainFileList*)listView())->columnByName(i18n("Album")), i18n("Unknown") );
|
||
|
}
|
||
|
else {
|
||
|
if( tags->track_gain != 210588 ) {
|
||
|
setText( ((ReplayGainFileList*)listView())->columnByName(i18n("Track")), QString().sprintf("%+.2f dB",tags->track_gain) );
|
||
|
}
|
||
|
else {
|
||
|
setText( ((ReplayGainFileList*)listView())->columnByName(i18n("Track")), i18n("Unknown") );
|
||
|
}
|
||
|
if( tags->album_gain != 210588 ) {
|
||
|
setText( ((ReplayGainFileList*)listView())->columnByName(i18n("Album")), QString().sprintf("%+.2f dB",tags->album_gain) );
|
||
|
}
|
||
|
else {
|
||
|
setText( ((ReplayGainFileList*)listView())->columnByName(i18n("Album")), i18n("Unknown") );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int ReplayGainFileListItem::compare( QListViewItem* item, int column, bool ascending ) const
|
||
|
{
|
||
|
// NOTE looking at the types, not the strings would be better
|
||
|
if( text(1) == "" && item->text(1) != "" ) return -1;
|
||
|
else if( text(1) != "" && item->text(1) == "" ) return 1;
|
||
|
else return KListViewItem::compare( item, column, ascending );
|
||
|
}
|
||
|
|
||
|
ReplayGainFileList::ReplayGainFileList( TagEngine* _tagEngine, Config* _config, Logger* _logger, QWidget *parent, const char *name )
|
||
|
: KListView( parent, name )
|
||
|
{
|
||
|
tagEngine = _tagEngine;
|
||
|
config = _config;
|
||
|
logger = _logger;
|
||
|
|
||
|
processing = false;
|
||
|
queue = false;
|
||
|
|
||
|
time = 0;
|
||
|
processedTime = 0;
|
||
|
|
||
|
addColumn( i18n("File"), 390 );
|
||
|
setColumnWidthMode( 0, QListView::Manual );
|
||
|
addColumn( i18n("Track"), 90 );
|
||
|
setColumnAlignment( 1, Qt::AlignRight );
|
||
|
addColumn( i18n("Album"), 90 );
|
||
|
setColumnAlignment( 2, Qt::AlignRight );
|
||
|
|
||
|
setSelectionMode( QListView::Extended );
|
||
|
setAllColumnsShowFocus( true );
|
||
|
setResizeMode( QListView::LastColumn );
|
||
|
setShowSortIndicator( true );
|
||
|
setSorting( 0 );
|
||
|
setRootIsDecorated( true );
|
||
|
|
||
|
setDragEnabled( true );
|
||
|
setAcceptDrops( true );
|
||
|
|
||
|
QGridLayout* grid = new QGridLayout( 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 KPopupMenu( this );
|
||
|
connect( this, SIGNAL(contextMenuRequested(QListViewItem*,const QPoint&,int)),
|
||
|
this, SLOT(showContextMenu(QListViewItem*,const QPoint&,int))
|
||
|
);
|
||
|
|
||
|
// we haven't got access to the action collection of soundKonverter, so let's create a new one
|
||
|
actionCollection = new KActionCollection( this );
|
||
|
|
||
|
calc_gain = new KAction( i18n("Calculate Replay Gain tags"), "apply", 0, this, SLOT(calcSelectedItemsGain()), actionCollection, "calc_album" );
|
||
|
remove_gain = new KAction( i18n("Remove Replay Gain tags"), "cancel", 0, this, SLOT(removeSelectedItemsGain()), actionCollection, "remove_gain" );
|
||
|
remove = new KAction( i18n("Remove"), "edittrash", Key_Delete, this, SLOT(removeSelectedItems()), actionCollection, "remove" );
|
||
|
paste = new KAction( i18n("Paste"), "editpaste", 0, this, 0, actionCollection, "paste" );
|
||
|
newalbum = new KAction( i18n("New album"), "filenew", 0, this, SLOT(createNewAlbum()), actionCollection, "newalbum" );
|
||
|
open_albums = new KAction( i18n("Open all albums"), "view_tree", 0, this, SLOT(openAlbums()), actionCollection, "open_albums" );
|
||
|
close_albums = new KAction( i18n("Cloase all albums"), "view_text", 0, this, SLOT(closeAlbums()), actionCollection, "close_albums" );
|
||
|
|
||
|
replayGain = new ReplayGain( config, logger );
|
||
|
|
||
|
bubble = new QSimpleRichText( i18n( "<div align=center>"
|
||
|
"<h3>Replay Gain Tool</h3>"
|
||
|
"With this tool you can add Replay Gain tags to your audio files and remove them."
|
||
|
//"<br>Replay Gain adds a volume correction information to the files for playing them at the same volume."
|
||
|
//"Replay Gain allows you to play all audio files at the same volume level without modifying the audio data."
|
||
|
"<br>Replay Gain adds a volume correction information to the files so that they can be played at an equal volume level."
|
||
|
// "<br><a href=\"documenation:replaygaintool\">Learn more about Replay Gain ...</a><br/>"
|
||
|
"</div>" ), QApplication::font() );
|
||
|
|
||
|
connect( header(), SIGNAL(sizeChange( int, int, int )),
|
||
|
SLOT(columnResizeEvent( int, int, int ))
|
||
|
);
|
||
|
connect( this, SIGNAL( dropped(QDropEvent*, QListViewItem*, QListViewItem*) ),
|
||
|
SLOT( slotDropped(QDropEvent*, QListViewItem*, QListViewItem*) )
|
||
|
);
|
||
|
|
||
|
process = new KProcess();
|
||
|
connect( process, SIGNAL(receivedStdout(KProcess*,char*,int)),
|
||
|
this, SLOT(processOutput(KProcess*,char*,int))
|
||
|
);
|
||
|
connect( process, SIGNAL(receivedStderr(KProcess*,char*,int)),
|
||
|
this, SLOT(processOutput(KProcess*,char*,int))
|
||
|
);
|
||
|
connect( process, SIGNAL(processExited(KProcess*)),
|
||
|
this, SLOT(processExit(KProcess*))
|
||
|
);
|
||
|
|
||
|
tUpdateProgress = new QTimer( this, "tUpdateProgress" );
|
||
|
connect( tUpdateProgress, SIGNAL(timeout()),
|
||
|
this, SLOT(update())
|
||
|
);
|
||
|
}
|
||
|
|
||
|
ReplayGainFileList::~ReplayGainFileList()
|
||
|
{
|
||
|
delete replayGain;
|
||
|
}
|
||
|
|
||
|
int ReplayGainFileList::columnByName( const QString& name )
|
||
|
{
|
||
|
for( int i = 0; i < columns(); ++i ) {
|
||
|
if( columnText( i ) == name ) return i;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::viewportPaintEvent( QPaintEvent* e )
|
||
|
{
|
||
|
KListView::viewportPaintEvent( e );
|
||
|
|
||
|
// the bubble help
|
||
|
if( childCount() == 0 ) {
|
||
|
QPainter 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, QRect(), colorGroup() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::viewportResizeEvent( QResizeEvent* )
|
||
|
{
|
||
|
// needed for correct redraw of bubble help
|
||
|
triggerUpdate();
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::columnResizeEvent( int, int, int )
|
||
|
{
|
||
|
// needed for correct redraw of bubble help
|
||
|
triggerUpdate();
|
||
|
}
|
||
|
|
||
|
bool ReplayGainFileList::acceptDrag( QDropEvent* e ) const
|
||
|
{
|
||
|
return ( e->source() == viewport() || KURLDrag::canDecode(e) ); // TODO verify the files
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::slotDropped( QDropEvent* e, QListViewItem*, QListViewItem* )
|
||
|
{
|
||
|
QString file;
|
||
|
KURL::List list;
|
||
|
if( KURLDrag::decode( e, list ) )
|
||
|
{
|
||
|
for( KURL::List::Iterator it = list.begin(); it != list.end(); ++it )
|
||
|
{
|
||
|
// TODO verify the files (necessary when multiple files are being dropped)
|
||
|
file = QDir::convertSeparators( (*it).pathOrURL() );
|
||
|
QFileInfo fileInfo( file );
|
||
|
if( fileInfo.isDir() )
|
||
|
{
|
||
|
addDir( file );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
addFile( (*it).url() );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::contentsDragEnterEvent( QDragEnterEvent *e )
|
||
|
{
|
||
|
e->accept( e->source() == viewport() || KURLDrag::canDecode(e) );
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::contentsDragMoveEvent( QDragMoveEvent *e )
|
||
|
{ // the mouse has moved while dragging some stuff
|
||
|
|
||
|
// if the file is added from an external app, don't let the user select the position to drop
|
||
|
if( e->source() != viewport() ) {
|
||
|
setDropHighlighter( false );
|
||
|
setDropVisualizer( false );
|
||
|
cleanItemHighlighter();
|
||
|
cleanDropVisualizer();
|
||
|
|
||
|
// the rest is handled by KListView
|
||
|
KListView::contentsDragMoveEvent( e );
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// translate the coordinates of the mouse pointer
|
||
|
QPoint vp = contentsToViewport( e->pos() );
|
||
|
// and get the list view item below the pointer
|
||
|
ReplayGainFileListItem* item = itemAt( vp );
|
||
|
|
||
|
if( item && item->type() == ReplayGainFileListItem::Album ) { // the pointer is above an 'album' element
|
||
|
// draw a nice rect around the item
|
||
|
setDropHighlighter( true );
|
||
|
setDropVisualizer( false );
|
||
|
cleanDropVisualizer();
|
||
|
}
|
||
|
else if( item ) { // the pointer is above an 'file' element
|
||
|
// draw a line above or below the item
|
||
|
setDropVisualizer( true );
|
||
|
setDropHighlighter( false );
|
||
|
cleanItemHighlighter();
|
||
|
}
|
||
|
|
||
|
// the rest is handled by KListView
|
||
|
KListView::contentsDragMoveEvent( e );
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::contentsDropEvent( QDropEvent *e )
|
||
|
{ // the stuff has been dropped
|
||
|
|
||
|
emit dropped( e, 0, 0 ); // NOTE it works this way
|
||
|
|
||
|
bool formatError = false;
|
||
|
|
||
|
cleanDropVisualizer();
|
||
|
cleanItemHighlighter();
|
||
|
|
||
|
// get the item below the mouse pointer, where the stuff has been dropped
|
||
|
QPoint vp = contentsToViewport( e->pos() );
|
||
|
ReplayGainFileListItem* newParent = itemAt( vp );
|
||
|
|
||
|
// if the item is a 'file', use the parent item
|
||
|
if( newParent && newParent->type() != ReplayGainFileListItem::Album ) {
|
||
|
newParent = newParent->parent();
|
||
|
}
|
||
|
|
||
|
// TODO if the mouse is on the left side under the parent but not under the sibling item, use the parent
|
||
|
/* if( newParent == 0 && vp.x() >= 2*treeStepSize() ) {
|
||
|
QPoint p = vp;
|
||
|
int height = 0;
|
||
|
if( firstChild() ) {
|
||
|
height = firstChild()->height();
|
||
|
}
|
||
|
p.setY( p.y() - height );
|
||
|
ReplayGainFileListItem* it = itemAt( p );
|
||
|
if( it && it->type() != ReplayGainFileListItem::Album ) {
|
||
|
newParent = it->parent();
|
||
|
}
|
||
|
else if( it ) {
|
||
|
newParent = it;
|
||
|
}
|
||
|
}*/
|
||
|
|
||
|
ReplayGainFileListItem* i;
|
||
|
|
||
|
// iterate through all items and move all selected ones
|
||
|
for( ReplayGainFileListItem* item = firstChild(); item != 0; ) {
|
||
|
if( item->type() == ReplayGainFileListItem::File ) {
|
||
|
if( newParent == 0 ) {
|
||
|
item = item->nextSibling();
|
||
|
continue;
|
||
|
}
|
||
|
if( item->isSelected() ) {
|
||
|
if( newParent == 0 || newParent->mimeType == item->mimeType || newParent->mimeType == "application/octet-stream" ) {
|
||
|
if( newParent->mimeType == "application/octet-stream" ) newParent->mimeType = item->mimeType;
|
||
|
i = item;
|
||
|
item = item->nextSibling();
|
||
|
takeItem( i );
|
||
|
if( newParent ) newParent->insertItem( i );
|
||
|
else insertItem( i );
|
||
|
}
|
||
|
else {
|
||
|
item = item->nextSibling();
|
||
|
formatError = true;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
item = item->nextSibling();
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
if( item == newParent ) {
|
||
|
item = item->nextSibling();
|
||
|
continue;
|
||
|
}
|
||
|
if( item->isSelected() ) {
|
||
|
if( newParent == 0 || newParent->mimeType == item->mimeType || newParent->mimeType == "application/octet-stream" ) {
|
||
|
if( newParent->mimeType == "application/octet-stream" ) newParent->mimeType = item->mimeType;
|
||
|
for( ReplayGainFileListItem* sub_item = item->firstChild(); sub_item != 0; ) {
|
||
|
i = sub_item;
|
||
|
sub_item = sub_item->nextSibling();
|
||
|
item->takeItem( i );
|
||
|
if( newParent ) newParent->insertItem( i );
|
||
|
else insertItem( i );
|
||
|
}
|
||
|
i = item;
|
||
|
item = item->nextSibling();
|
||
|
delete i;
|
||
|
}
|
||
|
else {
|
||
|
item = item->nextSibling();
|
||
|
formatError = true;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
for( ReplayGainFileListItem* sub_item = item->firstChild(); sub_item != 0; ) {
|
||
|
if( sub_item->isSelected() ) {
|
||
|
if( newParent == 0 || newParent->mimeType == item->mimeType || newParent->mimeType == "application/octet-stream" ) {
|
||
|
if( newParent && newParent->mimeType == "application/octet-stream" ) newParent->mimeType = item->mimeType;
|
||
|
i = sub_item;
|
||
|
sub_item = sub_item->nextSibling();
|
||
|
item->takeItem( i );
|
||
|
if( newParent ) newParent->insertItem( i );
|
||
|
else insertItem( i );
|
||
|
}
|
||
|
else {
|
||
|
sub_item = sub_item->nextSibling();
|
||
|
formatError = true;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
sub_item = sub_item->nextSibling();
|
||
|
}
|
||
|
}
|
||
|
if( item->childCount() == 0 ) {
|
||
|
i = item;
|
||
|
item = item->nextSibling();
|
||
|
delete i;
|
||
|
}
|
||
|
else {
|
||
|
item = item->nextSibling();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// FIXME make the mouse pointer look normal
|
||
|
|
||
|
if( formatError ) {
|
||
|
KMessageBox::information( this,
|
||
|
i18n("You can't place files of different formats in the same \'album\'."), i18n("Different file formats") );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int ReplayGainFileList::listDir( const QString& directory, QStringList filter, bool recursive, bool fast, int count )
|
||
|
{ // NOTE speed up?
|
||
|
QDir dir( directory );
|
||
|
dir.setFilter( QDir::Files | QDir::Dirs | QDir::NoSymLinks | QDir::Readable );
|
||
|
|
||
|
QStringList list = dir.entryList();
|
||
|
|
||
|
for( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
|
||
|
if( *it == "." || *it == ".." ) continue;
|
||
|
QFileInfo fileInfo( directory + "/" + *it );
|
||
|
if( fast ) {
|
||
|
if( fileInfo.isDir() && recursive ) {
|
||
|
count = listDir( directory + "/" + *it, filter, recursive, fast, count );
|
||
|
}
|
||
|
else if( !fileInfo.isDir() || !recursive ) { // NOTE checking for isFile may not work with all file names
|
||
|
// NOTE filter feature
|
||
|
for( QStringList::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( directory + "/" + *it, filter, recursive, fast, count );
|
||
|
}
|
||
|
else if( !fileInfo.isDir() || !recursive ) { // NOTE checking for isFile may not work with all file names
|
||
|
// NOTE filter feature
|
||
|
for( QStringList::Iterator jt = filter.begin(); jt != filter.end(); ++jt ) {
|
||
|
if( (*it).endsWith("."+(*jt),false) ) {
|
||
|
addFile( KURL::encode_string(directory + "/" + *it) );
|
||
|
count++;
|
||
|
pScanStatus->setProgress( count );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if( filter.first() == "" ) {
|
||
|
addFile( KURL::encode_string(directory + "/" + *it) );
|
||
|
count++;
|
||
|
pScanStatus->setProgress( count );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::showContextMenu( QListViewItem* item, const QPoint& point, int )
|
||
|
{
|
||
|
// remove all items from the context menu
|
||
|
contextMenu->clear();
|
||
|
|
||
|
// add a tilte to our context manu
|
||
|
//contextMenu->insertTitle( static_cast<FileListItem*>(item)->fileName );
|
||
|
|
||
|
// if item is null, we can abort here
|
||
|
if( item ) {
|
||
|
if( !processing ) {
|
||
|
calc_gain->plug( contextMenu );
|
||
|
if( item->text(columnByName(i18n("Track"))) != i18n("Unknown") || item->text(columnByName(i18n("Album"))) != i18n("Unknown") ) {
|
||
|
remove_gain->plug( contextMenu );
|
||
|
}
|
||
|
}
|
||
|
newalbum->plug( contextMenu );
|
||
|
remove->plug( contextMenu );
|
||
|
}
|
||
|
else {
|
||
|
newalbum->plug( contextMenu );
|
||
|
}
|
||
|
paste->plug( contextMenu );
|
||
|
contextMenu->insertSeparator();
|
||
|
open_albums->plug( contextMenu );
|
||
|
close_albums->plug( contextMenu );
|
||
|
|
||
|
// show the popup menu
|
||
|
contextMenu->popup( point );
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::addFile( const QString& file )
|
||
|
{
|
||
|
QString filename = file;
|
||
|
QString filePathName;
|
||
|
QString device;
|
||
|
|
||
|
if( filename.left( 1 ) == "/" ) {
|
||
|
filePathName = filename;
|
||
|
}
|
||
|
else if( filename.left( 7 ) == "file://" ) {
|
||
|
filePathName = filename;
|
||
|
filePathName.remove( 0, 7 );
|
||
|
}
|
||
|
else if( filename.left( 13 ) == "system:/home/" ) {
|
||
|
filePathName = filename;
|
||
|
filePathName.remove( 0, 13 );
|
||
|
filePathName = QDir::homeDirPath() + "/" + filePathName;
|
||
|
}
|
||
|
else if( filename.left( 14 ) == "system:/users/" || filename.left( 6 ) == "home:/" ) {
|
||
|
int length = ( filename.left(6) == "home:/" ) ? 6 : 14;
|
||
|
QString username = filename;
|
||
|
username.remove( 0, length );
|
||
|
username = username.left( username.find("/") );
|
||
|
filePathName = filename;
|
||
|
filePathName.remove( 0, length + username.length() );
|
||
|
KUser user( username );
|
||
|
filePathName = user.homeDir() + filePathName;
|
||
|
}
|
||
|
else if( filename.left( 14 ) == "system:/media/" || filename.left( 7 ) == "media:/" ) {
|
||
|
int length = ( filename.left(7) == "media:/" ) ? 7 : 14;
|
||
|
device = filename;
|
||
|
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 KSharedPtr<KMountPoint> mp = *jt;
|
||
|
if( mp->mountedFrom() == device )
|
||
|
{
|
||
|
filePathName = ( mp->mountPoint() == "/" ) ? mp->mountPoint() : mp->mountPoint() + "/";
|
||
|
filePathName += filename.right( filename.length() - device.length() - length + 4 );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
TagData* tags = tagEngine->readTags( KURL::decode_string(filePathName) );
|
||
|
if( !tags || tags->album.isEmpty() ) {
|
||
|
ReplayGainFileListItem* item = new ReplayGainFileListItem( this );
|
||
|
item->originalFileFormat = filePathName.right( filePathName.length() - filePathName.findRev(".") - 1 );
|
||
|
item->mimeType = KMimeType::findByFileContent( filePathName )->name();
|
||
|
item->fileFormat = KMimeType::findByFileContent( filePathName )->patterns().first();
|
||
|
if( item->mimeType.isEmpty() || item->mimeType == "application/octet-stream" || item->mimeType == "text/plain" ) {
|
||
|
item->mimeType = KMimeType::findByURL( filePathName.lower() )->name();
|
||
|
item->fileFormat = KMimeType::findByURL( filePathName.lower() )->patterns().first();
|
||
|
}
|
||
|
// check whether the mime type has a decoder registered
|
||
|
if( !config->acceptReplayGainFile( item->mimeType ) ) {
|
||
|
delete item;
|
||
|
return;
|
||
|
}
|
||
|
item->filePathName = filePathName;
|
||
|
if( tags ) item->time = tags->length;
|
||
|
else {
|
||
|
FormatItem* formatItem = config->getFormatItem( item->mimeType );
|
||
|
if( formatItem && formatItem->size > 0 ) {
|
||
|
QFileInfo fileInfo( filePathName );
|
||
|
item->time = fileInfo.size() / formatItem->size;
|
||
|
}
|
||
|
else {
|
||
|
item->time = 210;
|
||
|
}
|
||
|
}
|
||
|
item->setText( columnByName(i18n("File")), KURL::decode_string(filePathName).replace("%2f","/").replace("%%","%") );
|
||
|
if( tags && tags->track_gain != 210588 ) {
|
||
|
item->setText( columnByName(i18n("Track")), QString().sprintf("%+.2f dB",tags->track_gain) );
|
||
|
}
|
||
|
else {
|
||
|
item->setText( columnByName(i18n("Track")), i18n("Unknown") );
|
||
|
}
|
||
|
if( tags && tags->album_gain != 210588 ) {
|
||
|
item->setText( columnByName(i18n("Album")), QString().sprintf("%+.2f dB",tags->album_gain) );
|
||
|
}
|
||
|
else {
|
||
|
item->setText( columnByName(i18n("Album")), i18n("Unknown") );
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
QString mimeType = KMimeType::findByFileContent( filePathName )->name();
|
||
|
QString fileFormat = KMimeType::findByFileContent( filePathName )->patterns().first();
|
||
|
if( mimeType.isEmpty() || mimeType == "application/octet-stream" || mimeType == "text/plain" ) {
|
||
|
mimeType = KMimeType::findByURL( filePathName.lower() )->name();
|
||
|
fileFormat = KMimeType::findByURL( filePathName.lower() )->patterns().first();
|
||
|
}
|
||
|
// check whether the mime type has a decoder registered
|
||
|
if( !config->acceptReplayGainFile( mimeType ) ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for( ReplayGainFileListItem* it = firstChild(); it != 0; it = it->nextSibling() ) {
|
||
|
//if( it->text(0) == QString(tags->artist+" - "+tags->album) ) {
|
||
|
if( it->text(columnByName(i18n("File"))) == tags->album && it->type() == ReplayGainFileListItem::Album && it->mimeType == mimeType ) {
|
||
|
ReplayGainFileListItem* item = new ReplayGainFileListItem( it );
|
||
|
item->originalFileFormat = filePathName.right( filePathName.length() - filePathName.findRev(".") - 1 );
|
||
|
item->filePathName = filePathName;
|
||
|
item->mimeType = mimeType;
|
||
|
item->fileFormat = fileFormat;
|
||
|
item->time = tags->length;
|
||
|
item->setText( columnByName(i18n("File")), KURL::decode_string(filePathName).replace("%2f","/").replace("%%","%") );
|
||
|
if( tags->track_gain != 210588 ) {
|
||
|
item->setText( columnByName(i18n("Track")), QString().sprintf("%+.2f dB",tags->track_gain) );
|
||
|
}
|
||
|
else {
|
||
|
item->setText( columnByName(i18n("Track")), i18n("Unknown") );
|
||
|
}
|
||
|
if( tags->album_gain != 210588 ) {
|
||
|
item->setText( columnByName(i18n("Album")), QString().sprintf("%+.2f dB",tags->album_gain) );
|
||
|
}
|
||
|
else {
|
||
|
item->setText( columnByName(i18n("Album")), i18n("Unknown") );
|
||
|
}
|
||
|
tags = 0; // <--,
|
||
|
break; // |
|
||
|
} // |
|
||
|
} // |
|
||
|
if( tags ) { // <--'
|
||
|
ReplayGainFileListItem* parent = new ReplayGainFileListItem( this );
|
||
|
//parent->setText( 0, tags->artist+" - "+tags->album );
|
||
|
parent->setText( columnByName(i18n("File")), tags->album );
|
||
|
parent->setType( ReplayGainFileListItem::Album );
|
||
|
parent->mimeType = mimeType;
|
||
|
parent->fileFormat = fileFormat;
|
||
|
ReplayGainFileListItem* item = new ReplayGainFileListItem( parent );
|
||
|
item->originalFileFormat = filePathName.right( filePathName.length() - filePathName.findRev(".") - 1 );
|
||
|
item->filePathName = filePathName;
|
||
|
item->mimeType = mimeType;
|
||
|
item->fileFormat = fileFormat;
|
||
|
item->time = tags->length;
|
||
|
item->setText( columnByName(i18n("File")), KURL::decode_string(filePathName).replace("%2f","/").replace("%%","%") );
|
||
|
if( tags->track_gain != 210588 ) {
|
||
|
item->setText( columnByName(i18n("Track")), QString().sprintf("%+.2f dB",tags->track_gain) );
|
||
|
}
|
||
|
else {
|
||
|
item->setText( columnByName(i18n("Track")), i18n("Unknown") );
|
||
|
}
|
||
|
if( tags->album_gain != 210588 ) {
|
||
|
item->setText( columnByName(i18n("Album")), QString().sprintf("%+.2f dB",tags->album_gain) );
|
||
|
}
|
||
|
else {
|
||
|
item->setText( columnByName(i18n("Album")), i18n("Unknown") );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::addDir( const QString& directory, const QStringList& 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 ReplayGainFileList::openAlbums()
|
||
|
{
|
||
|
// iterate through all items and open all albums
|
||
|
for( ReplayGainFileListItem* item = firstChild(); item != 0; item = item->nextSibling() ) {
|
||
|
if( item->type() == ReplayGainFileListItem::Album ) {
|
||
|
item->setOpen( true );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::closeAlbums()
|
||
|
{
|
||
|
// iterate through all items and close all albums
|
||
|
for( ReplayGainFileListItem* item = firstChild(); item != 0; item = item->nextSibling() ) {
|
||
|
if( item->type() == ReplayGainFileListItem::Album ) {
|
||
|
item->setOpen( false );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::removeSelectedItems()
|
||
|
{
|
||
|
ReplayGainFileListItem* i;
|
||
|
|
||
|
// iterate through all items and remove all selected ones
|
||
|
for( ReplayGainFileListItem* item = firstChild(); item != 0; ) {
|
||
|
if( item->type() == ReplayGainFileListItem::File ) {
|
||
|
if( item->isSelected() ) {
|
||
|
i = item;
|
||
|
item = item->nextSibling();
|
||
|
delete i;
|
||
|
}
|
||
|
else {
|
||
|
item = item->nextSibling();
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
if( item->isSelected() ) {
|
||
|
i = item;
|
||
|
item = item->nextSibling();
|
||
|
delete i;
|
||
|
}
|
||
|
else {
|
||
|
for( ReplayGainFileListItem* sub_item = item->firstChild(); sub_item != 0; ) {
|
||
|
if( sub_item->isSelected() ) {
|
||
|
i = sub_item;
|
||
|
sub_item = sub_item->nextSibling();
|
||
|
delete i;
|
||
|
}
|
||
|
else {
|
||
|
sub_item = sub_item->nextSibling();
|
||
|
}
|
||
|
}
|
||
|
if( item->childCount() == 0 ) {
|
||
|
i = item;
|
||
|
item = item->nextSibling();
|
||
|
delete i;
|
||
|
}
|
||
|
else {
|
||
|
item = item->nextSibling();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::createNewAlbum()
|
||
|
{
|
||
|
ReplayGainFileListItem* item = new ReplayGainFileListItem( this );
|
||
|
item->setText( columnByName(i18n("File")), i18n("New album") );
|
||
|
item->setType( ReplayGainFileListItem::Album );
|
||
|
item->mimeType = "application/octet-stream";
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::calcSelectedItemsGain()
|
||
|
{
|
||
|
if( processing ) return;
|
||
|
|
||
|
// iterate through all items and remove the replay gain from all selected ones
|
||
|
for( ReplayGainFileListItem* item = firstChild(); item != 0; item = item->nextSibling() ) {
|
||
|
if( item->type() == ReplayGainFileListItem::File ) {
|
||
|
if( item->isSelected() ) {
|
||
|
item->queued = true;
|
||
|
item->repaint();
|
||
|
item->mode = ReplayGainFileListItem::force;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
if( item->isSelected() ) {
|
||
|
item->queued = true;
|
||
|
item->repaint();
|
||
|
item->mode = ReplayGainFileListItem::force;
|
||
|
for( ReplayGainFileListItem* sub_item = item->firstChild(); sub_item != 0; sub_item = sub_item->nextSibling() ) {
|
||
|
sub_item->queued = true;
|
||
|
sub_item->repaint();
|
||
|
sub_item->mode = ReplayGainFileListItem::force;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
for( ReplayGainFileListItem* sub_item = item->firstChild(); sub_item != 0; sub_item = sub_item->nextSibling() ) {
|
||
|
if( sub_item->isSelected() ) {
|
||
|
item->queued = true;
|
||
|
item->repaint();
|
||
|
item->mode = ReplayGainFileListItem::force;
|
||
|
for( ReplayGainFileListItem* sub_item2 = item->firstChild(); sub_item2 != 0; sub_item2 = sub_item2->nextSibling() ) {
|
||
|
sub_item2->queued = true;
|
||
|
sub_item2->repaint();
|
||
|
sub_item2->mode = ReplayGainFileListItem::force;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
startProcess();
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::removeSelectedItemsGain()
|
||
|
{
|
||
|
// iterate through all items and remove the replay gain from all selected ones
|
||
|
for( ReplayGainFileListItem* item = firstChild(); item != 0; item = item->nextSibling() ) {
|
||
|
if( item->type() == ReplayGainFileListItem::File ) {
|
||
|
if( item->isSelected() && !item->addingReplayGain ) {
|
||
|
item->queued = true;
|
||
|
item->repaint();
|
||
|
item->mode = ReplayGainFileListItem::remove;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
if( item->isSelected() && !item->addingReplayGain ) {
|
||
|
item->queued = true;
|
||
|
item->repaint();
|
||
|
item->mode = ReplayGainFileListItem::remove;
|
||
|
for( ReplayGainFileListItem* sub_item = item->firstChild(); sub_item != 0; sub_item = sub_item->nextSibling() ) {
|
||
|
sub_item->queued = true;
|
||
|
sub_item->repaint();
|
||
|
sub_item->mode = ReplayGainFileListItem::remove;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
for( ReplayGainFileListItem* sub_item = item->firstChild(); sub_item != 0; sub_item = sub_item->nextSibling() ) {
|
||
|
if( sub_item->isSelected() && !sub_item->addingReplayGain ) {
|
||
|
sub_item->queued = true;
|
||
|
sub_item->repaint();
|
||
|
sub_item->mode = ReplayGainFileListItem::remove;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
startProcess();
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::calcReplayGain( ReplayGainFileListItem* item )
|
||
|
{
|
||
|
logID = logger->registerProcess( KURL::encode_string(item->text(columnByName(i18n("File")))) );
|
||
|
logger->log( logID, "Mime Type: " + item->mimeType );
|
||
|
logger->log( logID, i18n("Applying Replay Gain") );
|
||
|
|
||
|
QStringList fileList;
|
||
|
bool force = false;
|
||
|
if( mode & ReplayGainFileListItem::force ) force = true;
|
||
|
QString album_gain = "";
|
||
|
bool skip = true;
|
||
|
|
||
|
timeCount = 0;
|
||
|
file = 0;
|
||
|
files = 0;
|
||
|
|
||
|
if( item->type() == ReplayGainFileListItem::Album ) {
|
||
|
item->queued = false;
|
||
|
item->addingReplayGain = true;
|
||
|
item->repaint();
|
||
|
for( ReplayGainFileListItem* sub_item = item->firstChild(); sub_item != 0; sub_item = sub_item->nextSibling() ) {
|
||
|
if( sub_item->queued && sub_item->mode & ReplayGainFileListItem::force ) force = true; // NOTE can this be replaced by checking item?
|
||
|
sub_item->queued = false;
|
||
|
sub_item->addingReplayGain = true;
|
||
|
sub_item->repaint();
|
||
|
|
||
|
fileList += sub_item->filePathName;
|
||
|
files++;
|
||
|
timeCount += sub_item->time;
|
||
|
|
||
|
QString current_gain = sub_item->text( columnByName(i18n("Album")) );
|
||
|
if( album_gain == "" ) album_gain = current_gain;
|
||
|
else if( album_gain != current_gain ) skip = false;
|
||
|
}
|
||
|
|
||
|
if( !skip || album_gain == i18n("Unknown") || force ) {
|
||
|
if( force ) {
|
||
|
replayGain->apply( fileList, item->mimeType, process, logID, ReplayGain::Mode(ReplayGain::calc_album|ReplayGain::force) );
|
||
|
}
|
||
|
else {
|
||
|
replayGain->apply( fileList, item->mimeType, process, logID );
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
logger->processCompleted( logID, 0 );
|
||
|
item->addingReplayGain = false;
|
||
|
item->repaint();
|
||
|
for( ReplayGainFileListItem* sub_item = item->firstChild(); sub_item != 0; sub_item = sub_item->nextSibling() ) {
|
||
|
sub_item->addingReplayGain = false;
|
||
|
sub_item->repaint();
|
||
|
}
|
||
|
processNextFile();
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
if( item->queued && item->mode & ReplayGainFileListItem::force ) force = true;
|
||
|
|
||
|
item->queued = false;
|
||
|
item->addingReplayGain = true;
|
||
|
item->repaint();
|
||
|
|
||
|
files = 1;
|
||
|
timeCount = item->time;
|
||
|
|
||
|
if( force ) {
|
||
|
replayGain->apply( item->filePathName, item->mimeType, process, logID, ReplayGain::Mode(ReplayGain::calc_album|ReplayGain::force) );
|
||
|
}
|
||
|
else {
|
||
|
replayGain->apply( item->filePathName, item->mimeType, process, logID );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::removeReplayGain( ReplayGainFileListItem* item )
|
||
|
{
|
||
|
logID = logger->registerProcess( KURL::encode_string(item->text(columnByName(i18n("File")))) );
|
||
|
logger->log( logID, "Mime Type: " + item->mimeType );
|
||
|
logger->log( logID, i18n("Removing Replay Gain") );
|
||
|
|
||
|
if( item->type() == ReplayGainFileListItem::File ) {
|
||
|
item->queued = false;
|
||
|
item->addingReplayGain = true;
|
||
|
item->repaint();
|
||
|
timeCount = item->time;
|
||
|
replayGain->apply( item->filePathName, item->mimeType, process, logID, ReplayGain::remove );
|
||
|
}
|
||
|
else {
|
||
|
item->queued = false;
|
||
|
item->repaint();
|
||
|
processNextFile();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::calcAllReplayGain( bool force )
|
||
|
{
|
||
|
queue = true;
|
||
|
if( force ) mode = ReplayGainFileListItem::force;
|
||
|
else mode = ReplayGainFileListItem::Mode(0x0000);
|
||
|
startProcess();
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::removeAllReplayGain()
|
||
|
{
|
||
|
queue = true;
|
||
|
mode = ReplayGainFileListItem::remove;
|
||
|
startProcess();
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::cancelProcess()
|
||
|
{
|
||
|
queue = false;
|
||
|
if( process->isRunning() )
|
||
|
{
|
||
|
bool ret = process->kill( SIGKILL );
|
||
|
if( ret ) {
|
||
|
logger->log( logID, i18n("Killing process ...") );
|
||
|
}
|
||
|
else {
|
||
|
logger->log( logID, i18n("Killing process failed. Stopping after files are completed ...") );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::startProcess()
|
||
|
{
|
||
|
emit processStarted();
|
||
|
processing = true;
|
||
|
time = 0;
|
||
|
|
||
|
for( ReplayGainFileListItem* item = firstChild(); item != 0; item = item->nextSibling() ) {
|
||
|
if( item->type() == ReplayGainFileListItem::File ) {
|
||
|
if( queue ) {
|
||
|
time += item->time;
|
||
|
}
|
||
|
else if( item->queued ) {
|
||
|
time += item->time;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
for( ReplayGainFileListItem* sub_item = item->firstChild(); sub_item != 0; sub_item = sub_item->nextSibling() ) {
|
||
|
if( queue ) {
|
||
|
time += sub_item->time;
|
||
|
}
|
||
|
else if( sub_item->queued ) {
|
||
|
time += sub_item->time;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
emit updateProgress( 0, 100 );
|
||
|
if( !tUpdateProgress->isActive() ) {
|
||
|
tUpdateProgress->start( 200 ); // TODO use config value
|
||
|
}
|
||
|
|
||
|
currentItem = 0;
|
||
|
processNextFile();
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::processNextFile()
|
||
|
{
|
||
|
percent = 0;
|
||
|
lastPercent = 0;
|
||
|
|
||
|
ReplayGainFileListItem* currentSubItem = 0;
|
||
|
|
||
|
if( !currentItem ) { currentItem = firstChild(); }
|
||
|
else if( currentItem->type() == ReplayGainFileListItem::File && currentItem->parent() == 0 ) { currentItem = currentItem->nextSibling(); }
|
||
|
else if( currentItem->type() == ReplayGainFileListItem::Album ) { currentItem = currentItem->nextSibling(); }
|
||
|
else { currentSubItem = currentItem->nextSibling(); currentItem = currentItem->parent(); if( !currentSubItem ) { currentItem = currentItem->nextSibling(); } }
|
||
|
|
||
|
for( ReplayGainFileListItem* item = currentItem; item != 0; item = item->nextSibling() ) {
|
||
|
if( item->type() == ReplayGainFileListItem::File ) {
|
||
|
if( queue ) {
|
||
|
currentItem = item;
|
||
|
if( mode & ReplayGainFileListItem::remove ) removeReplayGain( item );
|
||
|
else calcReplayGain( item );
|
||
|
return;
|
||
|
}
|
||
|
else if( item->queued ) {
|
||
|
currentItem = item;
|
||
|
if( item->mode & ReplayGainFileListItem::remove ) removeReplayGain( item );
|
||
|
else calcReplayGain( item );
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
if( queue ) {
|
||
|
currentItem = item;
|
||
|
if( mode & ReplayGainFileListItem::remove ) {}
|
||
|
else { calcReplayGain( item ); return; }
|
||
|
}
|
||
|
else if( item->queued ) {
|
||
|
currentItem = item;
|
||
|
if( item->mode & ReplayGainFileListItem::remove ) { item->queued = false; }
|
||
|
else { calcReplayGain( item ); return; }
|
||
|
}
|
||
|
|
||
|
if( !currentSubItem ) currentSubItem = item->firstChild();
|
||
|
for( ReplayGainFileListItem* sub_item = currentSubItem; sub_item != 0; sub_item = sub_item->nextSibling() ) {
|
||
|
if( queue ) {
|
||
|
currentItem = sub_item;
|
||
|
if( mode & ReplayGainFileListItem::remove ) removeReplayGain( sub_item );
|
||
|
return;
|
||
|
}
|
||
|
else if( sub_item->queued ) {
|
||
|
currentItem = sub_item;
|
||
|
if( sub_item->mode & ReplayGainFileListItem::remove ) removeReplayGain( sub_item );
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
currentSubItem = 0;
|
||
|
}
|
||
|
}
|
||
|
queue = false;
|
||
|
tUpdateProgress->stop();
|
||
|
processedTime = 0;
|
||
|
processing = false;
|
||
|
emit processStopped();
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::processOutput( KProcess* proc, char* data, int )
|
||
|
{
|
||
|
int iPercent = 0, iTime = 0, iPos = 0, iNum = 0;
|
||
|
|
||
|
QString log_data = data;
|
||
|
log_data.replace("\n","\\n");
|
||
|
log_data.replace("\t","\\t");
|
||
|
log_data.replace("\r","\\r");
|
||
|
log_data.replace("\b","\\b");
|
||
|
logger->log( logID, " " + i18n("Output") + ": " + log_data );
|
||
|
|
||
|
ReplayGainPlugin* plugin = config->replaygainForFormat( currentItem->mimeType );
|
||
|
if( plugin == 0 ) { // shouldn't happen
|
||
|
logger->log( logID, " NULL POINTER: ReplayGainScanner::processOutput( ... ) / plugin" );
|
||
|
return;
|
||
|
}
|
||
|
if( plugin->info.name == i18n("built-in") ) { // shouldn't happen // TODO implement a check for this
|
||
|
logger->log( logID, " Backend is an encoder" );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
QString outputPattern = ( files > 1 ) ? plugin->replaygain.output_multiple : plugin->replaygain.output_single;
|
||
|
//outputPattern.replace( "%i", "%p" ); // for compatibility with old plugins
|
||
|
|
||
|
if( outputPattern.find("%p") != -1 || outputPattern.find("%a") != -1 ) {
|
||
|
outputPattern.replace( "%p", "%i" );
|
||
|
//outputPattern.replace( "%a", "%i" ); // for compatibility with old plugins
|
||
|
sscanf( data, outputPattern, &iPercent );
|
||
|
}
|
||
|
/*else if( outputPattern.find("%t") != -1 ) { // NOTE a little bit complicated and not necessary
|
||
|
outputPattern.replace( "%t", "%i" );
|
||
|
sscanf( data, outputPattern, &iTime );
|
||
|
iPercent = iTime * 100 / currentItem->time;
|
||
|
}*/
|
||
|
else if( outputPattern.find("%0") != -1 && outputPattern.find("%1") != -1 ) {
|
||
|
if( outputPattern.find("%0") < outputPattern.find("%1") ) {
|
||
|
outputPattern.replace( "%0", "%i" );
|
||
|
outputPattern.replace( "%1", "%i" );
|
||
|
sscanf( data, outputPattern, &iPos, &iNum );
|
||
|
}
|
||
|
else {
|
||
|
outputPattern.replace( "%0", "%i" );
|
||
|
outputPattern.replace( "%1", "%i" );
|
||
|
sscanf( data, outputPattern, &iNum, &iPos );
|
||
|
}
|
||
|
if( iPos != 0 && iNum != 0 ) iPercent = iPos * 100 / iNum;
|
||
|
}
|
||
|
|
||
|
if( iPercent > 0 && iPercent <= 100 )
|
||
|
{
|
||
|
// TODO guess progress, when no signal is received
|
||
|
//lastOutputTimer.start();
|
||
|
if( files > 1 ) {
|
||
|
if( iPercent < lastPercent ) file++;
|
||
|
lastPercent = iPercent;
|
||
|
percent = file * 100 / files + iPercent / files;
|
||
|
}
|
||
|
else {
|
||
|
percent = iPercent;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::processExit( KProcess* proc )
|
||
|
{
|
||
|
logger->processCompleted( logID, ( proc->signalled() ) ? -1 : 0 );
|
||
|
|
||
|
for( ReplayGainFileListItem* item = firstChild(); item != 0; item = item->nextSibling() ) {
|
||
|
if( item->type() == ReplayGainFileListItem::File ) {
|
||
|
if( item->addingReplayGain ) {
|
||
|
processedTime += item->time;
|
||
|
item->addingReplayGain = false;
|
||
|
item->repaint();
|
||
|
item->updateReplayGainCells( tagEngine->readTags(KURL::decode_string(item->filePathName)) );
|
||
|
}
|
||
|
if( item->queued && proc->signalled() ) {
|
||
|
item->queued = false;
|
||
|
item->repaint();
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
if( item->addingReplayGain ) {
|
||
|
item->addingReplayGain = false;
|
||
|
item->repaint();
|
||
|
for( ReplayGainFileListItem* sub_item = item->firstChild(); sub_item != 0; sub_item = sub_item->nextSibling() ) {
|
||
|
processedTime += sub_item->time;
|
||
|
sub_item->addingReplayGain = false;
|
||
|
sub_item->repaint();
|
||
|
sub_item->updateReplayGainCells( tagEngine->readTags(KURL::decode_string(sub_item->filePathName)) );
|
||
|
}
|
||
|
}
|
||
|
if( item->queued && proc->signalled() ) {
|
||
|
item->queued = false;
|
||
|
item->repaint();
|
||
|
for( ReplayGainFileListItem* sub_item = item->firstChild(); sub_item != 0; sub_item = sub_item->nextSibling() ) {
|
||
|
sub_item->queued = false;
|
||
|
sub_item->repaint();
|
||
|
}
|
||
|
}
|
||
|
for( ReplayGainFileListItem* sub_item = item->firstChild(); sub_item != 0; sub_item = sub_item->nextSibling() ) {
|
||
|
if( sub_item->addingReplayGain ) {
|
||
|
processedTime += sub_item->time;
|
||
|
sub_item->addingReplayGain = false;
|
||
|
sub_item->repaint();
|
||
|
sub_item->updateReplayGainCells( tagEngine->readTags(KURL::decode_string(sub_item->filePathName)) );
|
||
|
}
|
||
|
if( sub_item->queued && proc->signalled() ) {
|
||
|
sub_item->queued = false;
|
||
|
sub_item->repaint();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if( proc->signalled() ) {
|
||
|
queue = false;
|
||
|
tUpdateProgress->stop();
|
||
|
processedTime = 0;
|
||
|
processing = false;
|
||
|
emit processStopped();
|
||
|
return;
|
||
|
}
|
||
|
else {
|
||
|
processNextFile();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ReplayGainFileList::update()
|
||
|
{
|
||
|
emit updateProgress( int(processedTime) + percent * int(timeCount) / 100, int(time) );
|
||
|
}
|
||
|
|