mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-03-21 16:29:43 +01:00
* Fixed TWK-91: Support multi-folder scanning.
This commit is contained in:
parent
19da9ef754
commit
e4918e777e
@ -181,6 +181,7 @@ set( libSources
|
||||
utils/shortenedlinkparser.cpp
|
||||
utils/stylehelper.cpp
|
||||
|
||||
widgets/checkdirtree.cpp
|
||||
widgets/querylabel.cpp
|
||||
widgets/imagebutton.cpp
|
||||
widgets/animatedsplitter.cpp
|
||||
@ -379,6 +380,7 @@ set( libHeaders
|
||||
utils/rdioparser.h
|
||||
utils/shortenedlinkparser.h
|
||||
|
||||
widgets/checkdirtree.h
|
||||
widgets/querylabel.h
|
||||
widgets/animatedcounterlabel.h
|
||||
widgets/imagebutton.h
|
||||
|
@ -180,34 +180,13 @@ TomahawkSettings::infoSystemCacheVersion() const
|
||||
QStringList
|
||||
TomahawkSettings::scannerPaths()
|
||||
{
|
||||
//FIXME: After enough time, remove this hack (and make const)
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
if( value( "scanner/paths" ).isNull() )
|
||||
{
|
||||
if ( !value( "scannerpath" ).isNull() )
|
||||
setValue( "scanner/paths", QStringList( value( "scannerpath" ).toString() ) );
|
||||
else if ( !value( "scannerpaths" ).isNull() )
|
||||
setValue( "scanner/paths", value( "scannerpaths" ) );
|
||||
sync();
|
||||
remove( "scannerpath" );
|
||||
remove( "scannerpaths" );
|
||||
sync();
|
||||
}
|
||||
return value( "scanner/paths", QDesktopServices::storageLocation( QDesktopServices::MusicLocation ) ).toStringList();
|
||||
#else
|
||||
if( value( "scanner/paths" ).isNull() )
|
||||
{
|
||||
if ( !value( "scannerpath" ).isNull() )
|
||||
setValue( "scanner/paths", QStringList( value( "scannerpath" ).toString() ) );
|
||||
else if ( !value( "scannerpaths" ).isNull() )
|
||||
setValue( "scanner/paths", value( "scannerpaths" ) );
|
||||
sync();
|
||||
remove( "scannerpath" );
|
||||
remove( "scannerpaths" );
|
||||
sync();
|
||||
}
|
||||
return value( "scanner/paths", "" ).toStringList();
|
||||
#endif
|
||||
QString musicLocation;
|
||||
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
musicLocation = QDesktopServices::storageLocation( QDesktopServices::MusicLocation );
|
||||
#endif
|
||||
|
||||
return value( "scanner/paths", musicLocation ).toStringList();
|
||||
}
|
||||
|
||||
|
||||
|
300
src/libtomahawk/widgets/checkdirtree.cpp
Normal file
300
src/libtomahawk/widgets/checkdirtree.cpp
Normal file
@ -0,0 +1,300 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "checkdirtree.h"
|
||||
|
||||
#include "utils/logger.h"
|
||||
|
||||
|
||||
CheckDirModel::CheckDirModel( QWidget* parent )
|
||||
: QDirModel( parent )
|
||||
{
|
||||
setLazyChildCount( false );
|
||||
}
|
||||
|
||||
|
||||
Qt::ItemFlags
|
||||
CheckDirModel::flags( const QModelIndex& index ) const
|
||||
{
|
||||
return QDirModel::flags( index ) | Qt::ItemIsUserCheckable;
|
||||
}
|
||||
|
||||
|
||||
QVariant
|
||||
CheckDirModel::data( const QModelIndex& index, int role ) const
|
||||
{
|
||||
if ( role == Qt::CheckStateRole )
|
||||
{
|
||||
return m_checkTable.contains( index ) ? m_checkTable.value( index ) : Qt::Unchecked;
|
||||
}
|
||||
else
|
||||
{
|
||||
return QDirModel::data( index, role );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CheckDirModel::setData( const QModelIndex& index, const QVariant& value, int role )
|
||||
{
|
||||
bool b = QDirModel::setData( index, value, role );
|
||||
|
||||
if ( role == Qt::CheckStateRole )
|
||||
{
|
||||
m_checkTable.insert( index, (Qt::CheckState)value.toInt() );
|
||||
emit dataChanged( index, index );
|
||||
emit dataChangedByUser( index );
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CheckDirModel::setCheck( const QModelIndex& index, const QVariant& value )
|
||||
{
|
||||
QDirModel::setData( index, value, Qt::CheckStateRole );
|
||||
m_checkTable.insert( index, (Qt::CheckState)value.toInt() );
|
||||
emit dataChanged( index, index );
|
||||
}
|
||||
|
||||
|
||||
Qt::CheckState
|
||||
CheckDirModel::getCheck( const QModelIndex& index )
|
||||
{
|
||||
return (Qt::CheckState)data( index, Qt::CheckStateRole ).toInt();
|
||||
}
|
||||
|
||||
|
||||
CheckDirTree::CheckDirTree( QWidget* parent )
|
||||
: QTreeView( parent )
|
||||
{
|
||||
m_dirModel.setFilter( QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks );
|
||||
setModel( &m_dirModel );
|
||||
setColumnHidden( 1, true );
|
||||
setColumnHidden( 2, true );
|
||||
setColumnHidden( 3, true );
|
||||
//header()->hide();
|
||||
|
||||
connect( &m_dirModel, SIGNAL( dataChangedByUser( QModelIndex ) ),
|
||||
SLOT( updateNode( QModelIndex ) ) );
|
||||
connect( &m_dirModel, SIGNAL( dataChangedByUser( const QModelIndex& ) ),
|
||||
SIGNAL( changed() ) );
|
||||
|
||||
connect( this, SIGNAL( collapsed( QModelIndex ) ),
|
||||
SLOT( onCollapse( QModelIndex ) ) );
|
||||
connect( this, SIGNAL( expanded( QModelIndex ) ),
|
||||
SLOT( onExpand( QModelIndex ) ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CheckDirTree::checkPath( const QString& path, Qt::CheckState state )
|
||||
{
|
||||
QModelIndex index = m_dirModel.index( path );
|
||||
m_dirModel.setCheck( index, state );
|
||||
updateNode( index );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CheckDirTree::setExclusions( const QStringList& list )
|
||||
{
|
||||
foreach ( const QString& path, list )
|
||||
{
|
||||
checkPath( path, Qt::Unchecked );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QStringList
|
||||
CheckDirTree::getCheckedPaths()
|
||||
{
|
||||
QStringList checks;
|
||||
QModelIndex root = rootIndex();
|
||||
|
||||
getChecksForNode( root, checks );
|
||||
return checks;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CheckDirTree::getChecksForNode( const QModelIndex& index, QStringList& checks )
|
||||
{
|
||||
// Look at first node
|
||||
// Is it checked?
|
||||
// - move on to next node
|
||||
// Is it unchecked?
|
||||
// - add to list
|
||||
// - move to next node
|
||||
// Is it partially checked?
|
||||
// - recurse
|
||||
|
||||
int numChildren = m_dirModel.rowCount( index );
|
||||
for ( int i = 0; i < numChildren; ++i )
|
||||
{
|
||||
QModelIndex kid = m_dirModel.index( i, 0, index );
|
||||
Qt::CheckState check = m_dirModel.getCheck( kid );
|
||||
if ( check == Qt::Checked )
|
||||
{
|
||||
checks.append( m_dirModel.filePath( kid ) );
|
||||
}
|
||||
else if ( check == Qt::Unchecked )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if ( check == Qt::PartiallyChecked )
|
||||
{
|
||||
getChecksForNode( kid, checks );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_ASSERT( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QStringList
|
||||
CheckDirTree::getExclusions()
|
||||
{
|
||||
QStringList exclusions;
|
||||
QModelIndex root = rootIndex();
|
||||
|
||||
getExclusionsForNode( root, exclusions );
|
||||
return exclusions;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CheckDirTree::getExclusionsForNode( const QModelIndex& index, QStringList& exclusions )
|
||||
{
|
||||
// Look at first node
|
||||
// Is it checked?
|
||||
// - move on to next node
|
||||
// Is it unchecked?
|
||||
// - add to list
|
||||
// - move to next node
|
||||
// Is it partially checked?
|
||||
// - recurse
|
||||
|
||||
int numChildren = m_dirModel.rowCount( index );
|
||||
for ( int i = 0; i < numChildren; ++i )
|
||||
{
|
||||
QModelIndex kid = m_dirModel.index( i, 0, index );
|
||||
Qt::CheckState check = m_dirModel.getCheck( kid );
|
||||
if ( check == Qt::Checked )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if ( check == Qt::Unchecked )
|
||||
{
|
||||
exclusions.append( m_dirModel.filePath( kid ) );
|
||||
}
|
||||
else if ( check == Qt::PartiallyChecked )
|
||||
{
|
||||
getExclusionsForNode( kid, exclusions );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_ASSERT( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CheckDirTree::onCollapse( const QModelIndex& /*idx*/ )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CheckDirTree::onExpand( const QModelIndex& idx )
|
||||
{
|
||||
// If the node is partially checked, that means we have been below it
|
||||
// setting some stuff, so only fill down if we are unchecked.
|
||||
if ( m_dirModel.getCheck( idx ) != Qt::PartiallyChecked )
|
||||
{
|
||||
fillDown( idx );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CheckDirTree::updateNode( const QModelIndex& idx )
|
||||
{
|
||||
// Start by recursing down to the bottom and then work upwards
|
||||
fillDown( idx );
|
||||
updateParent( idx );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CheckDirTree::fillDown( const QModelIndex& parent )
|
||||
{
|
||||
// Recursion stops when we reach a directory which has never been expanded
|
||||
// or one that has no children.
|
||||
if ( !isExpanded( parent ) || !m_dirModel.hasChildren( parent ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Qt::CheckState state = m_dirModel.getCheck( parent );
|
||||
int numChildren = m_dirModel.rowCount( parent );
|
||||
for ( int i = 0; i < numChildren; ++i )
|
||||
{
|
||||
QModelIndex kid = m_dirModel.index( i, 0, parent );
|
||||
m_dirModel.setCheck( kid, state );
|
||||
fillDown( kid );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CheckDirTree::updateParent( const QModelIndex& index )
|
||||
{
|
||||
QModelIndex parent = index.parent();
|
||||
if ( !parent.isValid() )
|
||||
{
|
||||
// We have reached the root
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialise overall state to state of first child
|
||||
QModelIndex kid = m_dirModel.index( 0, 0, parent );
|
||||
Qt::CheckState overall = m_dirModel.getCheck( kid );
|
||||
|
||||
int numChildren = m_dirModel.rowCount( parent );
|
||||
for ( int i = 1; i <= numChildren; ++i )
|
||||
{
|
||||
kid = m_dirModel.index( i, 0, parent );
|
||||
Qt::CheckState state = m_dirModel.getCheck( kid );
|
||||
if ( state != overall )
|
||||
{
|
||||
// If we ever come across a state different than the first child,
|
||||
// we are partially checked
|
||||
overall = Qt::PartiallyChecked;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_dirModel.setCheck( parent, overall );
|
||||
updateParent( parent );
|
||||
}
|
80
src/libtomahawk/widgets/checkdirtree.h
Normal file
80
src/libtomahawk/widgets/checkdirtree.h
Normal file
@ -0,0 +1,80 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CHECKDIRTREE_H
|
||||
#define CHECKDIRTREE_H
|
||||
|
||||
#include "dllmacro.h"
|
||||
|
||||
#include <QDirModel>
|
||||
#include <QTreeView>
|
||||
|
||||
class DLLEXPORT CheckDirModel : public QDirModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CheckDirModel( QWidget* parent = 0 );
|
||||
|
||||
virtual Qt::ItemFlags flags( const QModelIndex& index ) const;
|
||||
virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const;
|
||||
virtual bool setData( const QModelIndex& index, const QVariant& value, int role = Qt::EditRole );
|
||||
|
||||
void setCheck( const QModelIndex& index, const QVariant& value );
|
||||
Qt::CheckState getCheck( const QModelIndex& index );
|
||||
|
||||
signals:
|
||||
void dataChangedByUser( const QModelIndex & index );
|
||||
|
||||
private:
|
||||
QHash<QPersistentModelIndex, Qt::CheckState> m_checkTable;
|
||||
};
|
||||
|
||||
|
||||
class DLLEXPORT CheckDirTree : public QTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CheckDirTree( QWidget* parent );
|
||||
|
||||
void checkPath( const QString& path, Qt::CheckState state );
|
||||
|
||||
void setExclusions( const QStringList& list );
|
||||
QStringList getExclusions();
|
||||
QStringList getCheckedPaths();
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
private slots:
|
||||
void onCollapse( const QModelIndex& idx );
|
||||
void onExpand( const QModelIndex& idx );
|
||||
void updateNode( const QModelIndex& idx );
|
||||
|
||||
private:
|
||||
CheckDirModel m_dirModel;
|
||||
QSet<qint64> m_expandedSet;
|
||||
|
||||
void fillDown( const QModelIndex& index );
|
||||
void updateParent( const QModelIndex& index );
|
||||
void getExclusionsForNode( const QModelIndex& index, QStringList& exclusions );
|
||||
void getChecksForNode( const QModelIndex& index, QStringList& checks );
|
||||
};
|
||||
|
||||
#endif // CHECKDIRTREE_H
|
@ -40,19 +40,21 @@ DirLister::go()
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "Recursive? :" << (m_recursive ? "true" : "false");
|
||||
tLog() << Q_FUNC_INFO << "Manual full? :" << (m_manualFull ? "true" : "false");
|
||||
if( !m_recursive )
|
||||
|
||||
if ( !m_recursive )
|
||||
{
|
||||
foreach( QString dir, m_dirs )
|
||||
foreach ( const QString& dir, m_dirs )
|
||||
{
|
||||
if( m_dirmtimes.contains( dir ) )
|
||||
if ( m_dirmtimes.contains( dir ) )
|
||||
{
|
||||
tDebug( LOGEXTRA ) << "Removing" << dir << "from m_dirmtimes because it's specifically requested";
|
||||
m_dirmtimes.remove( dir );
|
||||
}
|
||||
|
||||
QStringList filtered = QStringList( m_dirmtimes.keys() ).filter( dir );
|
||||
foreach( QString filteredDir, filtered )
|
||||
foreach ( const QString& filteredDir, filtered )
|
||||
{
|
||||
if( !QDir( filteredDir ).exists() )
|
||||
if ( !QDir( filteredDir ).exists() )
|
||||
{
|
||||
tDebug( LOGEXTRA ) << "Removing" << filteredDir << "from m_dirmtimes because it does not exist";
|
||||
m_dirmtimes.remove( filteredDir );
|
||||
@ -62,7 +64,7 @@ DirLister::go()
|
||||
m_newdirmtimes = m_dirmtimes;
|
||||
}
|
||||
|
||||
foreach( QString dir, m_dirs )
|
||||
foreach ( const QString& dir, m_dirs )
|
||||
{
|
||||
m_opcount++;
|
||||
QMetaObject::invokeMethod( this, "scanDir", Qt::QueuedConnection, Q_ARG( QDir, QDir( dir, 0 ) ), Q_ARG( int, 0 ), Q_ARG( DirLister::Mode, ( m_recursive ? DirLister::Recursive : DirLister::NonRecursive ) ) );
|
||||
@ -83,7 +85,7 @@ DirLister::scanDir( QDir dir, int depth, DirLister::Mode mode )
|
||||
}
|
||||
|
||||
tDebug( LOGVERBOSE ) << "DirLister::scanDir scanning:" << dir.canonicalPath() << "with mode" << mode;
|
||||
if( !dir.exists() )
|
||||
if ( !dir.exists() )
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << "Dir no longer exists, not scanning";
|
||||
|
||||
@ -104,7 +106,7 @@ DirLister::scanDir( QDir dir, int depth, DirLister::Mode mode )
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_manualFull ||
|
||||
if ( m_manualFull ||
|
||||
( m_mode == TomahawkSettings::Dirs
|
||||
&& ( m_dirmtimes.contains( dir.canonicalPath() ) || !m_recursive )
|
||||
&& mtime != m_dirmtimes.value( dir.canonicalPath() ) ) )
|
||||
@ -116,17 +118,18 @@ DirLister::scanDir( QDir dir, int depth, DirLister::Mode mode )
|
||||
dir.setFilter( QDir::Files | QDir::Readable | QDir::NoDotAndDotDot );
|
||||
dir.setSorting( QDir::Name );
|
||||
dirs = dir.entryInfoList();
|
||||
foreach( const QFileInfo& di, dirs )
|
||||
|
||||
foreach ( const QFileInfo& di, dirs )
|
||||
emit fileToScan( di );
|
||||
}
|
||||
dir.setFilter( QDir::Dirs | QDir::Readable | QDir::NoDotAndDotDot );
|
||||
dirs = dir.entryInfoList();
|
||||
|
||||
foreach( const QFileInfo& di, dirs )
|
||||
foreach ( const QFileInfo& di, dirs )
|
||||
{
|
||||
const QString canonical = di.canonicalFilePath();
|
||||
const bool haveDi = m_dirmtimes.contains( canonical );
|
||||
if( !m_newdirmtimes.contains( canonical ) && ( mode == DirLister::Recursive || !haveDi ) ) {
|
||||
if ( !m_newdirmtimes.contains( canonical ) && ( mode == DirLister::Recursive || !haveDi ) ) {
|
||||
m_opcount++;
|
||||
QMetaObject::invokeMethod( this, "scanDir", Qt::QueuedConnection, Q_ARG( QDir, di.canonicalFilePath() ), Q_ARG( int, depth + 1 ), Q_ARG( DirLister::Mode, DirLister::Recursive ) );
|
||||
}
|
||||
@ -149,12 +152,12 @@ MusicScanner::MusicScanner( const QStringList& dirs, TomahawkSettings::ScannerMo
|
||||
{
|
||||
m_ext2mime.insert( "mp3", TomahawkUtils::extensionToMimetype( "mp3" ) );
|
||||
m_ext2mime.insert( "ogg", TomahawkUtils::extensionToMimetype( "ogg" ) );
|
||||
m_ext2mime.insert( "flac", TomahawkUtils::extensionToMimetype( "flac" ) );
|
||||
m_ext2mime.insert( "mpc", TomahawkUtils::extensionToMimetype( "mpc" ) );
|
||||
m_ext2mime.insert( "wma", TomahawkUtils::extensionToMimetype( "wma" ) );
|
||||
m_ext2mime.insert( "aac", TomahawkUtils::extensionToMimetype( "aac" ) );
|
||||
m_ext2mime.insert( "m4a", TomahawkUtils::extensionToMimetype( "m4a" ) );
|
||||
m_ext2mime.insert( "mp4", TomahawkUtils::extensionToMimetype( "mp4" ) );
|
||||
m_ext2mime.insert( "flac", TomahawkUtils::extensionToMimetype( "flac" ) );
|
||||
}
|
||||
|
||||
|
||||
@ -236,11 +239,11 @@ MusicScanner::scan()
|
||||
m_dirLister.data()->moveToThread( m_dirListerThreadController );
|
||||
|
||||
connect( m_dirLister.data(), SIGNAL( fileToScan( QFileInfo ) ),
|
||||
SLOT( scanFile( QFileInfo ) ), Qt::QueuedConnection );
|
||||
SLOT( scanFile( QFileInfo ) ), Qt::QueuedConnection );
|
||||
|
||||
// queued, so will only fire after all dirs have been scanned:
|
||||
connect( m_dirLister.data(), SIGNAL( finished( QMap< QString, unsigned int > ) ),
|
||||
SLOT( listerFinished( QMap< QString, unsigned int > ) ), Qt::QueuedConnection );
|
||||
SLOT( listerFinished( QMap< QString, unsigned int > ) ), Qt::QueuedConnection );
|
||||
|
||||
m_dirListerThreadController->start();
|
||||
QMetaObject::invokeMethod( m_dirLister.data(), "go" );
|
||||
@ -253,7 +256,7 @@ MusicScanner::listerFinished( const QMap<QString, unsigned int>& newmtimes )
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO;
|
||||
|
||||
// any remaining stuff that wasnt emitted as a batch:
|
||||
foreach( QString key, m_filemtimes.keys() )
|
||||
foreach( const QString& key, m_filemtimes.keys() )
|
||||
{
|
||||
m_filesToDelete << m_filemtimes[ key ].keys().first();
|
||||
}
|
||||
@ -273,7 +276,7 @@ MusicScanner::listerFinished( const QMap<QString, unsigned int>& newmtimes )
|
||||
"( scanned" << m_scanned << "skipped" << m_skipped << ")";
|
||||
|
||||
tDebug( LOGEXTRA ) << "Skipped the following files (no tags / no valid audio):";
|
||||
foreach( const QString& s, m_skippedFiles )
|
||||
foreach ( const QString& s, m_skippedFiles )
|
||||
tDebug( LOGEXTRA ) << s;
|
||||
|
||||
// save mtimes, then quit thread
|
||||
@ -350,16 +353,16 @@ MusicScanner::readFile( const QFileInfo& fi )
|
||||
{
|
||||
const QString suffix = fi.suffix().toLower();
|
||||
|
||||
if ( ! m_ext2mime.contains( suffix ) )
|
||||
if ( !m_ext2mime.contains( suffix ) )
|
||||
{
|
||||
m_skipped++;
|
||||
return QVariantMap(); // invalid extension
|
||||
}
|
||||
|
||||
if ( m_scanned )
|
||||
if( m_scanned % 3 == 0 )
|
||||
if ( m_scanned % 3 == 0 )
|
||||
SourceList::instance()->getLocal()->scanningProgress( m_scanned );
|
||||
if( m_scanned % 100 == 0 )
|
||||
if ( m_scanned % 100 == 0 )
|
||||
tDebug( LOGINFO ) << "Scan progress:" << m_scanned << fi.canonicalFilePath();
|
||||
|
||||
#ifdef COMPLEX_TAGLIB_FILENAME
|
||||
|
@ -123,27 +123,23 @@ SettingsDialog::SettingsDialog( QWidget *parent )
|
||||
|
||||
ui->staticHostName->setText( s->externalHostname() );
|
||||
ui->staticPort->setValue( s->externalPort() );
|
||||
|
||||
ui->proxyButton->setVisible( true );
|
||||
|
||||
// MUSIC SCANNER
|
||||
//FIXME: MULTIPLECOLLECTIONDIRS
|
||||
if ( s->scannerPaths().count() )
|
||||
ui->lineEditMusicPath_2->setText( s->scannerPaths().first() );
|
||||
else
|
||||
{
|
||||
ui->lineEditMusicPath_2->setText( QDesktopServices::storageLocation( QDesktopServices::MusicLocation ) );
|
||||
}
|
||||
|
||||
ui->checkBoxWatchForChanges->setChecked( s->watchForChanges() );
|
||||
ui->scannerTimeSpinBox->setValue( s->scannerTime() );
|
||||
connect( ui->checkBoxWatchForChanges, SIGNAL( clicked( bool ) ), SLOT( updateScanOptionsView() ) );
|
||||
connect( ui->scannerDirModeButton, SIGNAL( clicked( bool ) ), SLOT( updateScanOptionsView() ) );
|
||||
connect( ui->scannerFileModeButton, SIGNAL( clicked( bool ) ), SLOT( updateScanOptionsView() ) );
|
||||
|
||||
if ( s->scannerMode() == TomahawkSettings::Files )
|
||||
{
|
||||
ui->scannerFileModeButton->setChecked( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->scannerDirModeButton->setChecked( true );
|
||||
}
|
||||
|
||||
if ( ui->checkBoxWatchForChanges->isChecked() )
|
||||
{
|
||||
ui->scanTimeLabel->show();
|
||||
@ -163,11 +159,16 @@ SettingsDialog::SettingsDialog( QWidget *parent )
|
||||
ui->scanInformationLabelDirs->hide();
|
||||
}
|
||||
|
||||
foreach ( const QString& dir, TomahawkSettings::instance()->scannerPaths() )
|
||||
{
|
||||
tDebug() << "FOO:" << dir;
|
||||
ui->dirTree->checkPath( dir, Qt::Checked );
|
||||
}
|
||||
|
||||
// NOW PLAYING
|
||||
#ifdef Q_WS_MAC
|
||||
ui->checkBoxEnableAdium->setChecked( s->nowPlayingEnabled() );
|
||||
#else
|
||||
ui->nowPlaying->hide();
|
||||
ui->checkBoxEnableAdium->hide();
|
||||
#endif
|
||||
|
||||
@ -175,7 +176,7 @@ SettingsDialog::SettingsDialog( QWidget *parent )
|
||||
ui->checkBoxEnableLastfm->setChecked( s->scrobblingEnabled() );
|
||||
ui->lineEditLastfmUsername->setText( s->lastFmUsername() );
|
||||
ui->lineEditLastfmPassword->setText(s->lastFmPassword() );
|
||||
connect( ui->pushButtonTestLastfmLogin, SIGNAL( clicked( bool) ), this, SLOT( testLastFmLogin() ) );
|
||||
connect( ui->pushButtonTestLastfmLogin, SIGNAL( clicked( bool) ), SLOT( testLastFmLogin() ) );
|
||||
|
||||
#ifdef Q_WS_MAC // FIXME
|
||||
ui->pushButtonTestLastfmLogin->setVisible( false );
|
||||
@ -184,19 +185,18 @@ SettingsDialog::SettingsDialog( QWidget *parent )
|
||||
// SCRIPT RESOLVER
|
||||
ui->removeScript->setEnabled( false );
|
||||
ResolverConfigDelegate* del = new ResolverConfigDelegate( this );
|
||||
connect( del, SIGNAL( openConfig( QString ) ), this, SLOT( openResolverConfig( QString ) ) );
|
||||
connect( del, SIGNAL( openConfig( QString ) ), SLOT( openResolverConfig( QString ) ) );
|
||||
ui->scriptList->setItemDelegate( del );
|
||||
m_resolversModel = new ResolversModel( s->allScriptResolvers(), s->enabledScriptResolvers(), this );
|
||||
ui->scriptList->setModel( m_resolversModel );
|
||||
|
||||
connect( ui->scriptList->selectionModel(), SIGNAL( selectionChanged( QItemSelection,QItemSelection ) ), this, SLOT( scriptSelectionChanged() ) );
|
||||
connect( ui->addScript, SIGNAL( clicked( bool ) ), this, SLOT( addScriptResolver() ) );
|
||||
connect( ui->removeScript, SIGNAL( clicked( bool ) ), this, SLOT( removeScriptResolver() ) );
|
||||
connect( ui->scriptList->selectionModel(), SIGNAL( selectionChanged( QItemSelection,QItemSelection ) ), SLOT( scriptSelectionChanged() ) );
|
||||
connect( ui->addScript, SIGNAL( clicked( bool ) ), SLOT( addScriptResolver() ) );
|
||||
connect( ui->removeScript, SIGNAL( clicked( bool ) ), SLOT( removeScriptResolver() ) );
|
||||
|
||||
connect( ui->buttonBrowse_2, SIGNAL( clicked() ), SLOT( showPathSelector() ) );
|
||||
connect( ui->proxyButton, SIGNAL( clicked() ), SLOT( showProxySettings() ) );
|
||||
connect( ui->checkBoxStaticPreferred, SIGNAL( toggled(bool) ), SLOT( toggleUpnp(bool) ) );
|
||||
connect( this, SIGNAL( rejected() ), SLOT( onRejected() ) );
|
||||
connect( this, SIGNAL( rejected() ), SLOT( onRejected() ) );
|
||||
|
||||
ui->listWidget->setCurrentRow( 0 );
|
||||
ui->listWidget->setItemDelegate(new SettingsListDelegate());
|
||||
@ -218,7 +218,7 @@ SettingsDialog::~SettingsDialog()
|
||||
s->setExternalHostname( ui->staticHostName->text() );
|
||||
s->setExternalPort( ui->staticPort->value() );
|
||||
|
||||
s->setScannerPaths( QStringList( ui->lineEditMusicPath_2->text() ) );
|
||||
s->setScannerPaths( ui->dirTree->getCheckedPaths() );
|
||||
s->setWatchForChanges( ui->checkBoxWatchForChanges->isChecked() );
|
||||
s->setScannerTime( ui->scannerTimeSpinBox->value() );
|
||||
s->setScannerMode( ui->scannerFileModeButton->isChecked() ? TomahawkSettings::Files : TomahawkSettings::Dirs );
|
||||
@ -334,7 +334,7 @@ SettingsDialog::setupSipButtons()
|
||||
void
|
||||
SettingsDialog::changePage( QListWidgetItem* current, QListWidgetItem* previous )
|
||||
{
|
||||
if( !current )
|
||||
if ( !current )
|
||||
current = previous;
|
||||
|
||||
ui->stackedWidget->setCurrentIndex( ui->listWidget->row(current) );
|
||||
@ -353,7 +353,7 @@ SettingsDialog::showPathSelector()
|
||||
if ( path.isEmpty() )
|
||||
return;
|
||||
|
||||
ui->lineEditMusicPath_2->setText( path );
|
||||
// ui->lineEditMusicPath_2->setText( path );
|
||||
}
|
||||
|
||||
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>641</width>
|
||||
<height>393</height>
|
||||
<width>808</width>
|
||||
<height>464</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -24,7 +24,7 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
@ -32,9 +32,15 @@
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QListWidget" name="listWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -209,111 +215,75 @@
|
||||
<property name="title">
|
||||
<string>Local Music Information</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<property name="margin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_17">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Path to scan for music files:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEditMusicPath_2"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonBrowse_2">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
<string>Path to scan for music files:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="CheckDirTree" name="dirTree"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxWatchForChanges">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Watch for changes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_16">
|
||||
<item>
|
||||
<widget class="QLabel" name="scanTimeLabel">
|
||||
<widget class="QCheckBox" name="checkBoxWatchForChanges">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Time between scans, in seconds:</string>
|
||||
<string>Watch for changes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="scannerTimeSpinBox">
|
||||
<property name="minimum">
|
||||
<number>60</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="scannerFileModeButton">
|
||||
<property name="text">
|
||||
<string>Files Mode (Recommended)</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="scanTimeLabel">
|
||||
<property name="text">
|
||||
<string>Time between scans, in seconds:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="scannerTimeSpinBox">
|
||||
<property name="minimum">
|
||||
<number>60</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="scannerDirModeButton">
|
||||
<property name="text">
|
||||
<string>Directory Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="scannerFileModeButton">
|
||||
<property name="text">
|
||||
<string>Files Mode (Recommended)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="scannerDirModeButton">
|
||||
<property name="text">
|
||||
<string>Directory Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_21">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
@ -347,63 +317,11 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="nowPlaying">
|
||||
<property name="title">
|
||||
<string>Now Playing Information</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,0">
|
||||
<property name="margin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Applications to update with currently playing track:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxEnableAdium">
|
||||
<property name="text">
|
||||
<string>Adium</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_1">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="lastfmPage">
|
||||
@ -414,74 +332,106 @@
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Last.fm Login</string>
|
||||
<string>Now Playing Information</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<property name="margin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_15">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxEnableLastfm">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Scrobble tracks to Last.fm</string>
|
||||
<string>Applications to update with currently playing track:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Username:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEditLastfmUsername"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Password:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lineEditLastfmPassword">
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonTestLastfmLogin">
|
||||
<property name="text">
|
||||
<string>Test Login</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxEnableAdium">
|
||||
<property name="text">
|
||||
<string>Adium</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxEnableLastfm">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Scrobble tracks to Last.fm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Username:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEditLastfmUsername"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Password:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lineEditLastfmPassword">
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonTestLastfmLogin">
|
||||
<property name="text">
|
||||
<string>Test Login</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@ -774,6 +724,13 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>CheckDirTree</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header location="global">widgets/checkdirtree.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../resources.qrc"/>
|
||||
</resources>
|
||||
|
Loading…
x
Reference in New Issue
Block a user