1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-13 20:39:57 +01:00

* Let's not try to be too clever in TrackHeader. QHeaderView is a bit annoying.

* Store release year in database when scanning music.
* Added Year & Filesize columns to the TrackModel / Header / View.
This commit is contained in:
Christian Muehlhaeuser 2010-12-03 14:10:29 +01:00
parent e6ca3dc5dd
commit 55591eb2c8
15 changed files with 300 additions and 165 deletions

View File

@ -34,6 +34,10 @@ public:
unsigned int size() const { return m_size; }
unsigned int albumpos() const { return m_albumpos; }
unsigned int modificationTime() const { return m_modtime; }
int year() const { return m_year; }
QVariantMap attributes() const { return m_attributes; }
void setAttributes( const QVariantMap& map ) { m_attributes = map; updateAttributes(); }
unsigned int dbid() const { return m_id; }
@ -45,6 +49,8 @@ signals:
void becomingUnavailable();
private:
void updateAttributes();
QVariant m_v;
mutable RID m_rid;
collection_ptr m_collection;
@ -60,6 +66,9 @@ private:
unsigned int m_size;
unsigned int m_albumpos;
unsigned int m_modtime;
int m_year;
QVariantMap m_attributes;
unsigned int m_id;
};

View File

@ -122,6 +122,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
playlist/trackmodel.cpp
playlist/trackproxymodel.cpp
playlist/trackview.cpp
playlist/trackheader.cpp
playlist/albumitem.cpp
playlist/albummodel.cpp
playlist/albumproxymodel.cpp
@ -253,6 +254,7 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
playlist/trackmodel.h
playlist/trackproxymodel.h
playlist/trackview.h
playlist/trackheader.h
playlist/albumitem.h
playlist/albummodel.h
playlist/albumproxymodel.h

View File

@ -64,12 +64,15 @@ DatabaseCommand_AddFiles::exec( DatabaseImpl* dbi )
TomahawkSqlQuery query_file = dbi->newquery();
TomahawkSqlQuery query_filejoin = dbi->newquery();
TomahawkSqlQuery query_trackattr = dbi->newquery();
TomahawkSqlQuery query_file_del = dbi->newquery();
query_file.prepare( "INSERT INTO file(source, url, size, mtime, md5, mimetype, duration, bitrate) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)" );
query_filejoin.prepare( "INSERT INTO file_join(file, artist ,album, track, albumpos) "
"VALUES (?,?,?,?,?)" );
query_trackattr.prepare( "INSERT INTO track_attributes(id, k, v) "
"VALUES (?,?,?)" );
query_file_del.prepare( QString( "DELETE FROM file WHERE source %1 AND url = ?" )
.arg( source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( source()->id() )
) );
@ -100,6 +103,7 @@ DatabaseCommand_AddFiles::exec( DatabaseImpl* dbi )
QString album = m.value( "album" ).toString();
QString track = m.value( "track" ).toString();
int albumpos = m.value( "albumpos" ).toInt();
int year = m.value( "year" ).toInt();
int fileid = 0;
query_file_del.bindValue( 0, url );
@ -158,6 +162,12 @@ DatabaseCommand_AddFiles::exec( DatabaseImpl* dbi )
qDebug() << "Error inserting into file_join table";
continue;
}
query_trackattr.bindValue( 0, trkid );
query_trackattr.bindValue( 1, "releaseyear" );
query_trackattr.bindValue( 2, year );
query_trackattr.exec();
added++;
}
qDebug() << "Inserted" << added;

View File

@ -29,7 +29,7 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
QString sql = QString(
"SELECT file.id, artist.name, album.name, track.name, file.size, "
"file.duration, file.bitrate, file.url, file.source, file.mtime, file.mimetype, file_join.albumpos, artist.id, album.id "
"file.duration, file.bitrate, file.url, file.source, file.mtime, file.mimetype, file_join.albumpos, artist.id, album.id, track.id "
"FROM file, artist, track, file_join "
"LEFT OUTER JOIN album "
"ON file_join.album = album.id "
@ -52,7 +52,10 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
while( query.next() )
{
QVariantMap t;
QVariantMap attr;
QString url;
TomahawkSqlQuery attrQuery = dbi->newquery();
url = query.value( 7 ).toString();
if( m_collection->source()->isLocal() )
t["url"] = url;
@ -71,12 +74,23 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
t["mtime"] = query.value( 9 ).toInt();
t["mimetype"] = query.value( 10 ).toString();
t["albumpos"] = query.value( 11 ).toUInt();
unsigned int trkid = query.value( 14 ).toInt();
attrQuery.prepare( "SELECT k, v FROM track_attributes WHERE id = ?" );
attrQuery.bindValue( 0, trkid );
attrQuery.exec();
while ( attrQuery.next() )
{
attr[ attrQuery.value( 0 ).toString() ] = attrQuery.value( 1 ).toString();
}
Tomahawk::query_ptr query = Tomahawk::query_ptr( new Tomahawk::Query( t ) );
t["score"] = 1.0;
QList<Tomahawk::result_ptr> results;
Tomahawk::result_ptr result = Tomahawk::result_ptr( new Tomahawk::Result( t, m_collection ) );
result->setAttributes( attr );
QList<Tomahawk::result_ptr> results;
results << result;
query->addResults( results );

View File

@ -206,6 +206,7 @@ MusicScanner::readFile( const QFileInfo& fi )
m["album"] = album;
m["track"] = track;
m["albumpos"] = tag->track();
m["year"] = tag->year();
m_scanned++;
return m;

View File

@ -29,7 +29,7 @@ PlaylistView::setModel( TrackModel* model )
{
TrackView::setModel( model );
// setColumnHidden( 5, true ); // Hide age column per default
setColumnHidden( 5, true ); // Hide age column per default
}

View File

@ -0,0 +1,157 @@
#include "trackheader.h"
#include <QContextMenuEvent>
#include <QDebug>
#include <QMenu>
#include "tomahawk/tomahawkapp.h"
#include "tomahawksettings.h"
#include "playlist/trackmodel.h"
#include "playlist/trackview.h"
TrackHeader::TrackHeader( TrackView* parent )
: QHeaderView( Qt::Horizontal, parent )
, m_parent( parent )
, m_menu( new QMenu( this ) )
, m_sigmap( new QSignalMapper( this ) )
, m_hiddenWidth( 0 )
, m_hiddenPct( 0.0 )
, m_init( false )
{
setStretchLastSection( false );
setResizeMode( QHeaderView::Interactive );
setMinimumSectionSize( 60 );
setDefaultAlignment( Qt::AlignLeft );
setMovable( true );
m_menu->addAction( tr( "Resize columns to fit window" ), this, SLOT( onToggleResizeColumns() ) );
m_menu->addSeparator();
connect( this, SIGNAL( sectionResized( int, int, int ) ), SLOT( onSectionResized( int, int, int ) ) );
connect( m_sigmap, SIGNAL( mapped( int ) ), SLOT( toggleVisibility( int ) ) );
}
TrackHeader::~TrackHeader()
{
saveColumnsState();
}
void
TrackHeader::onSectionResized( int logicalidx, int oldSize, int newSize )
{
if ( !m_init )
return;
int width = m_parent->viewport()->width();
for ( int x = 0; x < m_columnWeights.count(); x++ )
{
if ( sectionSize( x ) )
{
// not hidden
m_columnWeights[x] = (double)sectionSize( x ) / (double)width;
}
}
}
void
TrackHeader::onResized()
{
if ( !m_init && count() )
restoreColumnsState();
m_init = false;
int width = m_parent->viewport()->width();
for ( int x = 0; x < m_columnWeights.count(); x++ )
{
if ( sectionSize( x ) )
{
// not hidden
resizeSection( x, int( (double)width * m_columnWeights[x] ) );
}
}
m_init = true;
}
void
TrackHeader::restoreColumnsState()
{
TomahawkSettings* s = APP->settings();
QList<QVariant> list = s->playlistColumnSizes();
if ( list.count() != count() ) // FIXME: const
{
m_columnWeights << 0.21 << 0.22 << 0.20 << 0.05 << 0.05 << 0.05 << 0.05 << 0.05 << 0.12;
}
else
{
foreach( const QVariant& v, list )
m_columnWeights << v.toDouble();
}
}
void
TrackHeader::saveColumnsState()
{
TomahawkSettings *s = APP->settings();
QList<QVariant> wlist;
foreach( double w, m_columnWeights )
wlist << QVariant( w );
s->setPlaylistColumnSizes( wlist );
}
void
TrackHeader::addColumnToMenu( int index )
{
QString title = m_parent->model()->headerData( index, Qt::Horizontal, Qt::DisplayRole ).toString();
QAction* action = m_menu->addAction( title, m_sigmap, SLOT( map() ) );
action->setCheckable( true );
action->setChecked( !isSectionHidden( index ) );
m_visActions << action;
m_sigmap->setMapping( action, index );
}
void
TrackHeader::contextMenuEvent( QContextMenuEvent* e )
{
qDeleteAll( m_visActions );
m_visActions.clear();
for ( int i = 0; i < count(); i++ )
addColumnToMenu( i );
m_menu->popup( e->globalPos() );
}
void
TrackHeader::onToggleResizeColumns()
{
}
void
TrackHeader::toggleVisibility( int index )
{
qDebug() << Q_FUNC_INFO << index;
if ( isSectionHidden( index ) )
showSection( index );
else
hideSection( index );
onResized();
}

View File

@ -0,0 +1,47 @@
#ifndef TRACKHEADER_H
#define TRACKHEADER_H
#include <QHeaderView>
#include <QSignalMapper>
class TrackView;
class TrackHeader : public QHeaderView
{
Q_OBJECT
public:
explicit TrackHeader( TrackView* parent = 0 );
~TrackHeader();
public slots:
void onResized();
void toggleVisibility( int index );
protected:
void contextMenuEvent( QContextMenuEvent* e );
private slots:
void onSectionResized( int logicalIndex, int oldSize, int newSize );
void onToggleResizeColumns();
private:
void addColumnToMenu( int index );
void restoreColumnsState();
void saveColumnsState();
TrackView* m_parent;
QMenu* m_menu;
QSignalMapper* m_sigmap;
QList<QAction*> m_visActions;
QList<double> m_columnWeights;
int m_hiddenWidth;
double m_hiddenPct;
bool m_init;
};
#endif

View File

@ -60,7 +60,7 @@ TrackModel::rowCount( const QModelIndex& parent ) const
int
TrackModel::columnCount( const QModelIndex& parent ) const
{
return 7;
return 9;
}
@ -127,15 +127,15 @@ TrackModel::data( const QModelIndex& index, int role ) const
{
switch( index.column() )
{
case 0:
case Artist:
return query->artist();
break;
case 1:
case Track:
return query->track();
break;
case 2:
case Album:
return query->album();
break;
}
@ -144,31 +144,39 @@ TrackModel::data( const QModelIndex& index, int role ) const
{
switch( index.column() )
{
case 0:
case Artist:
return query->results().first()->artist()->name();
break;
case 1:
case Track:
return query->results().first()->track();
break;
case 2:
case Album:
return query->results().first()->album()->name();
break;
case 3:
case Duration:
return TomahawkUtils::timeToString( query->results().first()->duration() );
break;
case 4:
case Bitrate:
return query->results().first()->bitrate();
break;
case 5:
case Age:
return TomahawkUtils::ageToString( QDateTime::fromTime_t( query->results().first()->modificationTime() ) );
break;
case 6:
case Year:
return query->results().first()->year();
break;
case Filesize:
return TomahawkUtils::filesizeToString( query->results().first()->size() );
break;
case Origin:
return query->results().first()->collection()->source()->friendlyName();
break;
}
@ -182,7 +190,7 @@ QVariant
TrackModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
QStringList headers;
headers << tr( "Artist" ) << tr( "Track" ) << tr( "Album" ) << tr( "Duration" ) << tr( "Bitrate" ) << tr( "Age" ) << tr( "Origin" );
headers << tr( "Artist" ) << tr( "Track" ) << tr( "Album" ) << tr( "Duration" ) << tr( "Bitrate" ) << tr( "Age" ) << tr( "Year" ) << tr( "Size" ) << tr( "Origin" );
if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 )
{
return headers.at( section );

View File

@ -20,7 +20,9 @@ public:
Duration = 3,
Bitrate = 4,
Age = 5,
Origin = 6
Year = 6,
Filesize = 7,
Origin = 8
};
explicit TrackModel( QObject* parent = 0 );

View File

@ -6,10 +6,10 @@
#include <QScrollBar>
#include "tomahawk/tomahawkapp.h"
#include "playlist/trackheader.h"
#include "playlist/playlistmanager.h"
#include "playlist/queueview.h"
#include "audioengine.h"
#include "tomahawksettings.h"
#include "trackmodel.h"
#include "trackproxymodel.h"
@ -367,125 +367,3 @@ TrackView::createDragPixmap( int itemCount ) const
return dragPixmap;
}
TrackHeader::TrackHeader( TrackView* parent )
: QHeaderView( Qt::Horizontal, parent )
, m_parent( parent )
, m_init( false )
{
setStretchLastSection( false );
setResizeMode( QHeaderView::Interactive );
setMinimumSectionSize( 60 );
setDefaultAlignment( Qt::AlignLeft );
setMovable( true );
connect( this, SIGNAL( sectionResized( int, int, int ) ), SLOT( onSectionResized( int, int, int ) ) );
}
TrackHeader::~TrackHeader()
{
saveColumnsState();
}
void
TrackHeader::onSectionResized( int logicalidx, int oldSize, int newSize )
{
if ( !m_init )
return;
blockSignals( true );
int visualidx = visualIndex( logicalidx );
for ( int i = visualidx + 1; i < count(); i++ )
{
int ns = sectionSize( logicalIndex( i ) ) + oldSize - newSize;
if ( ns < minimumSectionSize() )
{
resizeSection( logicalidx, newSize - ( minimumSectionSize() - ns ) );
ns = minimumSectionSize();
}
resizeSection( logicalIndex( i ), ns );
break;
}
blockSignals( false );
uint w = 0;
for ( int x = 0; x < m_columnWeights.count(); x++ )
{
w += sectionSize( x );
}
for ( int x = 0; x < m_columnWeights.count(); x++ )
{
m_columnWeights[x] = (double)sectionSize( x ) / double( w );
}
saveColumnsState();
}
void
TrackHeader::onResized()
{
if ( !m_init && count() )
restoreColumnsState();
m_init = false;
blockSignals( true );
double width = m_parent->contentsRect().width();
#ifdef Q_WS_MAC
if ( m_parent->verticalScrollBar() && m_parent->verticalScrollBar()->isVisible() )
{
width -= m_parent->verticalScrollBar()->width() + 1;
}
#endif
blockSignals( false );
for ( int i = 0; i < m_columnWeights.count(); i++ )
{
if ( m_columnWeights[i] > 0 )
resizeSection( i, int( width * m_columnWeights[i] ) );
}
m_init = true;
}
void
TrackHeader::restoreColumnsState()
{
TomahawkSettings* s = APP->settings();
QList<QVariant> list = s->playlistColumnSizes();
if ( list.count() != count() ) // FIXME: const
{
m_columnWeights << 0.20 << 0.24 << 0.19 << 0.07 << 0.07 << 0.07 << 0.15;
}
else
{
foreach( const QVariant& v, list )
m_columnWeights << v.toDouble();
}
}
void
TrackHeader::saveColumnsState()
{
TomahawkSettings *s = APP->settings();
QList<QVariant> wlist;
foreach( double w, m_columnWeights )
wlist << QVariant( w );
s->setPlaylistColumnSizes( wlist );
}

View File

@ -1,40 +1,15 @@
#ifndef TRACKVIEW_H
#define TRACKVIEW_H
#include <QHeaderView>
#include <QTreeView>
#include <QSortFilterProxyModel>
#include "playlistitemdelegate.h"
class PlaylistInterface;
class TrackHeader;
class TrackModel;
class TrackProxyModel;
class TrackView;
class TrackHeader : public QHeaderView
{
Q_OBJECT
public:
explicit TrackHeader( TrackView* parent = 0 );
~TrackHeader();
public slots:
void onResized();
private slots:
void onSectionResized( int logicalIndex, int oldSize, int newSize );
private:
void restoreColumnsState();
void saveColumnsState();
TrackView* m_parent;
QList<double> m_columnWeights;
bool m_init;
};
class TrackView : public QTreeView
{
@ -49,6 +24,7 @@ public:
TrackModel* model() { return m_model; }
TrackProxyModel* proxyModel() { return (TrackProxyModel*)m_proxyModel; }
PlaylistItemDelegate* delegate() { return m_delegate; }
TrackHeader* header() { return m_header; }
void setModel( TrackModel* model );

View File

@ -22,6 +22,7 @@ Result::Result( const QVariant& v, const collection_ptr& collection )
m_size = m.value( "size" ).toUInt();
m_albumpos = m.value( "albumpos" ).toUInt();
m_modtime = m.value( "mtime" ).toUInt();
m_year = 0;
m_id = m.value( "id" ).toUInt();
@ -53,3 +54,13 @@ Result::toString() const
{
return QString( "Result(%1 %2\t%3 - %4 %5" ).arg( id() ).arg( score() ).arg( artist()->name() ).arg( track() ).arg( url() );
}
void
Result::updateAttributes()
{
if ( m_attributes.contains( "releaseyear" ) )
{
m_year = m_attributes.value( "releaseyear" ).toInt();
}
}

View File

@ -191,4 +191,23 @@ ageToString( const QDateTime& time )
return QString();
}
QString
filesizeToString( unsigned int size )
{
int kb = size / 1024;
int mb = kb / 1024;
if ( mb )
{
return QString( "%1.%2 Mb" ).arg( mb ).arg( int( ( kb % 1024 ) / 100 ) );
}
else if ( kb )
{
return QString( "%1 Kb" ).arg( kb );
}
else
return QString::number( size );
}
} // ns

View File

@ -12,6 +12,7 @@ namespace TomahawkUtils
QString timeToString( int seconds );
QString ageToString( const QDateTime& time );
QString filesizeToString( unsigned int size );
}
#endif // TOMAHAWKUTILS_H