diff --git a/admin/mac/Info.plist b/admin/mac/Info.plist index 3187e4438..e1114d48c 100644 --- a/admin/mac/Info.plist +++ b/admin/mac/Info.plist @@ -23,6 +23,36 @@ CFBundleName Tomahawk LSMinimumSystemVersion - 10.5.0 + 10.5.0 + CFBundleURLTypes + + + CFBundleURLName + Tomahawk URL + CFBundleURLSchemes + + tomahawk + + + + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + xspf + + CFBundleTypeIconFile + Generic.icns + CFBundleTypeMIMETypes + + application/xspf+xml + + CFBundleTypeName + XSPF Playlist + CFBundleTypeRole + Viewer + + diff --git a/admin/win/revision.txt b/admin/win/revision.txt index 4e9e28848..b44fe09a7 100644 --- a/admin/win/revision.txt +++ b/admin/win/revision.txt @@ -1 +1 @@ -63 \ No newline at end of file +65 \ No newline at end of file diff --git a/admin/win/tomahawk.nsi b/admin/win/tomahawk.nsi index 0bc84cbaf..5a56f4327 100755 --- a/admin/win/tomahawk.nsi +++ b/admin/win/tomahawk.nsi @@ -304,6 +304,7 @@ Section "Tomahawk Player" SEC_TOMAHAWK_PLAYER File "${MING_LIB}\libclucene-core.dll" File "${QXTWEB_DLL_PATH}\libqxtweb-standalone.dll" + File "${ROOT_PATH}\build\thirdparty\jdns\libtomahawk_jdns.dll" SectionEnd SectionGroup "Shortcuts" diff --git a/include/tomahawk/tomahawkapp.h b/include/tomahawk/tomahawkapp.h index 7f0fc2005..be8e7d16b 100644 --- a/include/tomahawk/tomahawkapp.h +++ b/include/tomahawk/tomahawkapp.h @@ -4,6 +4,7 @@ #define APP TomahawkApp::instance() #include "headlesscheck.h" +#include "mac/tomahawkapp_mac.h" // for PlatforInterface #include #include @@ -28,6 +29,7 @@ class XMPPBot; namespace Tomahawk { + class ShortcutHandler; namespace InfoSystem { class InfoSystem; @@ -47,7 +49,7 @@ class TomahawkWindow; // this also acts as a a container for important top-level objects // that other parts of the app need to find // (eg, library, pipeline, friends list) -class TomahawkApp : public TOMAHAWK_APPLICATION +class TomahawkApp : public TOMAHAWK_APPLICATION, public Tomahawk::PlatformInterface { Q_OBJECT @@ -69,6 +71,10 @@ public: void addScriptResolver( const QString& scriptPath ); void removeScriptResolver( const QString& scriptPath ); + // PlatformInterface + virtual void activate(); + virtual bool loadUrl( const QString& url ); + signals: void settingsChanged(); @@ -94,6 +100,7 @@ private: SipHandler* m_sipHandler; Servent* m_servent; XMPPBot* m_xmppBot; + Tomahawk::ShortcutHandler* m_shortcutHandler; #ifndef NO_LIBLASTFM Scrobbler* m_scrobbler; diff --git a/src/CMakeLists.osx.txt b/src/CMakeLists.osx.txt index 77590e8b5..256e34746 100644 --- a/src/CMakeLists.osx.txt +++ b/src/CMakeLists.osx.txt @@ -2,6 +2,31 @@ SET( OS_SPECIFIC_LINK_LIBRARIES ${OS_SPECIFIC_LINK_LIBRARIES} ${COREAUDIO_LIBRARY} ${COREFOUNDATION_LIBRARY} + + /System/Library/Frameworks/AppKit.framework + /System/Library/Frameworks/Carbon.framework + /System/Library/Frameworks/DiskArbitration.framework + /System/Library/Frameworks/Foundation.framework + /System/Library/Frameworks/IOKit.framework + rtaudio tomahawklib ) + +if (APPLE) +# find_library(GROWL Growl) +# option(ENABLE_SPARKLE "Sparkle updating" ON) +# find_library(SPARKLE Sparkle) +# if (ENABLE_SPARKLE AND SPARKLE) +# set(HAVE_SPARKLE ON) +# endif (ENABLE_SPARKLE AND SPARKLE) + # Uses Darwin kernel version. + # 9.8.0 -> 10.5/Leopard + # 10.4.0 -> 10.6/Snow Leopard + string(REGEX MATCH "[0-9]+" DARWIN_VERSION ${CMAKE_HOST_SYSTEM_VERSION}) + if (DARWIN_VERSION GREATER 9) + SET(SNOW_LEOPARD 1) + elseif (DARWIN_VERSION GREATER 8) + SET(LEOPARD 1) + endif (DARWIN_VERSION GREATER 9) +endif (APPLE) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 80630f77b..477781072 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -40,6 +40,7 @@ SET( tomahawkSources ${tomahawkSources} musicscanner.cpp scriptresolver.cpp scrobbler.cpp + shortcuthandler.cpp tomahawkapp.cpp main.cpp @@ -58,6 +59,12 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui} tomahawkwindow.cpp ) + +IF( APPLE ) + SET( tomahawkHeaders ${tomahawkHeaders} mac/tomahawkapp_mac.h mac/macshortcuthandler.h ) + SET( tomahawkSources ${tomahawkSources} mac/tomahawkapp_mac.mm mac/macshortcuthandler.cpp ) +ENDIF( APPLE ) + SET( tomahawkHeaders ${tomahawkHeaders} "${TOMAHAWK_INC_DIR}/tomahawk/tomahawkapp.h" "${TOMAHAWK_INC_DIR}/tomahawk/infosystem.h" @@ -74,6 +81,7 @@ SET( tomahawkHeaders ${tomahawkHeaders} musicscanner.h scriptresolver.h scrobbler.h + shortcuthandler.h ) SET( tomahawkHeadersGui ${tomahawkHeadersGui} @@ -111,6 +119,7 @@ INCLUDE_DIRECTORIES( topbar utils libtomahawk + mac ../alsa-playback ../rtaudio @@ -142,6 +151,9 @@ kde4_add_app_icon( tomahawkSources "${CMAKE_CURRENT_SOURCE_DIR}/../data/icons/to qt4_add_resources( RC_SRCS "../resources.qrc" ) qt4_wrap_cpp( tomahawkMoc ${tomahawkHeaders} ) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in + ${CMAKE_CURRENT_BINARY_DIR}/config.h) + SET( final_src ${final_src} ${tomahawkMoc} ${tomahawkSources} ${tomahawkHeaders} ) IF( "${gui}" STREQUAL "no" ) @@ -156,6 +168,8 @@ IF( UNIX AND NOT APPLE ) ENDIF( UNIX AND NOT APPLE ) IF( APPLE ) ADD_EXECUTABLE( tomahawk MACOSX_BUNDLE ${final_src} ) + SET_TARGET_PROPERTIES(tomahawk PROPERTIES MACOSX_BUNDLE_INFO_PLIST "../admin/mac/Info.plist" +) ENDIF( APPLE ) IF( WIN32 ) ADD_EXECUTABLE( tomahawk ${final_src} ) diff --git a/src/config.h.in b/src/config.h.in new file mode 100644 index 000000000..a06d239a5 --- /dev/null +++ b/src/config.h.in @@ -0,0 +1,10 @@ +#ifndef CONFIG_H_IN +#define CONFIG_H_IN + +#define CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" + +#cmakedefine SNOW_LEOPARD +#cmakedefine LEOPARD +#cmakedefine HAVE_SPARKLE + +#endif // CONFIG_H_IN diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index df1e593f3..e6e2083f4 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -50,7 +50,6 @@ set( libSources database/databasecommand_logplayback.cpp database/databasecommand_addsource.cpp database/databasecommand_sourceoffline.cpp - database/databasecommand_collectionstats.cpp database/databasecommand_loadplaylistentries.cpp database/databasecommand_modifyplaylist.cpp database/databasecommand_playbackhistory.cpp @@ -365,13 +364,13 @@ target_link_libraries( tomahawklib ${QT_LIBRARIES} ${OS_SPECIFIC_LINK_LIBRARIES} ${LIBECHONEST_LIBRARY} + tomahawk_jdns portfwd qjson mad vorbisfile ogg FLAC++ - tomahawk_jdns tomahawk_qtweetlib ${CLUCENE_LIBRARY} ) diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index 7ebbf9197..7231e3a72 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -62,6 +62,15 @@ AudioEngine::~AudioEngine() delete m_audio; } +void +AudioEngine::playPause() +{ + if( m_audio->isPlaying() ) + pause(); + else + play(); + +} void AudioEngine::play() @@ -141,6 +150,11 @@ AudioEngine::setVolume( int percentage ) emit volumeChanged( percentage ); } +void +AudioEngine::mute() +{ + setVolume( 0 ); +} void AudioEngine::onTrackAboutToClose() diff --git a/src/libtomahawk/audio/audioengine.h b/src/libtomahawk/audio/audioengine.h index e763c9235..a94a5359b 100644 --- a/src/libtomahawk/audio/audioengine.h +++ b/src/libtomahawk/audio/audioengine.h @@ -40,6 +40,7 @@ public: PlaylistInterface* playlist() const { return m_playlist; } public slots: + void playPause(); void play(); void pause(); void stop(); @@ -51,6 +52,7 @@ public slots: void lowerVolume() { setVolume( volume() - AUDIO_VOLUME_STEP ); } void raiseVolume() { setVolume( volume() + AUDIO_VOLUME_STEP ); } void onVolumeChanged( float volume ) { emit volumeChanged( volume * 100 ); } + void mute(); void playItem( PlaylistInterface* playlist, const Tomahawk::result_ptr& result ); void setPlaylist( PlaylistInterface* playlist ) { m_playlist = playlist; } diff --git a/src/libtomahawk/database/databasecommand_updatesearchindex.cpp b/src/libtomahawk/database/databasecommand_updatesearchindex.cpp index 67d9e9b60..3e461dd2c 100644 --- a/src/libtomahawk/database/databasecommand_updatesearchindex.cpp +++ b/src/libtomahawk/database/databasecommand_updatesearchindex.cpp @@ -23,6 +23,7 @@ DatabaseCommand_UpdateSearchIndex::indexTable( DatabaseImpl* db, const QString& } db->m_fuzzyIndex->appendFields( table, fields ); + qDebug() << "Building index for" << table << "finished."; } diff --git a/src/libtomahawk/database/databaseworker.cpp b/src/libtomahawk/database/databaseworker.cpp index 510d53064..2e732f085 100644 --- a/src/libtomahawk/database/databaseworker.cpp +++ b/src/libtomahawk/database/databaseworker.cpp @@ -40,6 +40,13 @@ DatabaseWorker::run() void DatabaseWorker::enqueue( const QSharedPointer& cmd ) { + if ( QThread::currentThread() != thread() ) + { +// qDebug() << Q_FUNC_INFO << "Reinvoking in correct thread."; + QMetaObject::invokeMethod( this, "enqueue", Qt::QueuedConnection, Q_ARG( QSharedPointer, cmd ) ); + return; + } + m_outstanding++; QMutexLocker lock( &m_mut ); diff --git a/src/libtomahawk/database/databaseworker.h b/src/libtomahawk/database/databaseworker.h index 83ecd1562..87073e9df 100644 --- a/src/libtomahawk/database/databaseworker.h +++ b/src/libtomahawk/database/databaseworker.h @@ -25,11 +25,12 @@ public: DatabaseWorker( DatabaseImpl*, Database*, bool mutates ); ~DatabaseWorker(); - void enqueue( const QSharedPointer& ); - bool busy() const { return m_outstanding > 0; } unsigned int outstandingJobs() const { return m_outstanding; } +public slots: + void enqueue( const QSharedPointer& ); + protected: void run(); diff --git a/src/libtomahawk/database/fuzzyindex.cpp b/src/libtomahawk/database/fuzzyindex.cpp index 7e1074c23..1a6cdb724 100644 --- a/src/libtomahawk/database/fuzzyindex.cpp +++ b/src/libtomahawk/database/fuzzyindex.cpp @@ -45,7 +45,21 @@ void FuzzyIndex::beginIndexing() { m_mutex.lock(); - IndexWriter luceneWriter = IndexWriter( m_luceneDir, m_analyzer, true ); + + delete m_luceneSearcher; + delete m_luceneReader; + m_luceneSearcher = 0; + m_luceneReader = 0; + + try + { + IndexWriter luceneWriter = IndexWriter( m_luceneDir, m_analyzer, true ); + } + catch( CLuceneError& error ) + { + qDebug() << "Caught CLucene error:" << error.what(); + Q_ASSERT( false ); + } } @@ -60,39 +74,42 @@ FuzzyIndex::endIndexing() void FuzzyIndex::appendFields( const QString& table, const QMap< unsigned int, QString >& fields ) { - delete m_luceneSearcher; - delete m_luceneReader; - m_luceneSearcher = 0; - m_luceneReader = 0; - - bool create = !IndexReader::indexExists( TomahawkUtils::appDataDir().absoluteFilePath( "tomahawk.lucene" ).toStdString().c_str() ); - IndexWriter luceneWriter = IndexWriter( m_luceneDir, m_analyzer, create ); - Document doc; - - QMapIterator< unsigned int, QString > it( fields ); - while ( it.hasNext() ) + try { - it.next(); - unsigned int id = it.key(); - QString name = it.value(); + bool create = !IndexReader::indexExists( TomahawkUtils::appDataDir().absoluteFilePath( "tomahawk.lucene" ).toStdString().c_str() ); + IndexWriter luceneWriter = IndexWriter( m_luceneDir, m_analyzer, create ); + Document doc; + QMapIterator< unsigned int, QString > it( fields ); + while ( it.hasNext() ) { - Field* field = _CLNEW Field( table.toStdWString().c_str(), name.toStdWString().c_str(), - Field::STORE_YES | Field::INDEX_UNTOKENIZED ); - doc.add( *field ); + it.next(); + unsigned int id = it.key(); + QString name = it.value(); + + { + Field* field = _CLNEW Field( table.toStdWString().c_str(), name.toStdWString().c_str(), + Field::STORE_YES | Field::INDEX_UNTOKENIZED ); + doc.add( *field ); + } + + { + Field* field = _CLNEW Field( _T( "id" ), QString::number( id ).toStdWString().c_str(), + Field::STORE_YES | Field::INDEX_NO ); + doc.add( *field ); + } + + luceneWriter.addDocument( &doc ); + doc.clear(); } - - { - Field* field = _CLNEW Field( _T( "id" ), QString::number( id ).toStdWString().c_str(), - Field::STORE_YES | Field::INDEX_NO ); - doc.add( *field ); - } - - luceneWriter.addDocument( &doc ); - doc.clear(); + + luceneWriter.close(); + } + catch( CLuceneError& error ) + { + qDebug() << "Caught CLucene error:" << error.what(); + Q_ASSERT( false ); } - - luceneWriter.close(); } @@ -109,47 +126,55 @@ FuzzyIndex::search( const QString& table, const QString& name ) QMutexLocker lock( &m_mutex ); QMap< int, float > resultsmap; - if ( !m_luceneReader ) + try { - if ( !IndexReader::indexExists( TomahawkUtils::appDataDir().absoluteFilePath( "tomahawk.lucene" ).toStdString().c_str() ) ) + if ( !m_luceneReader ) { - qDebug() << Q_FUNC_INFO << "index didn't exist."; + if ( !IndexReader::indexExists( TomahawkUtils::appDataDir().absoluteFilePath( "tomahawk.lucene" ).toStdString().c_str() ) ) + { + qDebug() << Q_FUNC_INFO << "index didn't exist."; + return resultsmap; + } + + m_luceneReader = IndexReader::open( m_luceneDir ); + m_luceneSearcher = _CLNEW IndexSearcher( m_luceneReader ); + } + + if ( name.isEmpty() ) return resultsmap; - } - m_luceneReader = IndexReader::open( m_luceneDir ); - m_luceneSearcher = _CLNEW IndexSearcher( m_luceneReader ); - } + SimpleAnalyzer analyzer; + QueryParser parser( table.toStdWString().c_str(), m_analyzer ); + Hits* hits = 0; - if ( name.isEmpty() ) - return resultsmap; + FuzzyQuery* qry = _CLNEW FuzzyQuery( _CLNEW Term( table.toStdWString().c_str(), name.toStdWString().c_str() ) ); + hits = m_luceneSearcher->search( qry ); - SimpleAnalyzer analyzer; - QueryParser parser( table.toStdWString().c_str(), m_analyzer ); - Hits* hits = 0; - - FuzzyQuery* qry = _CLNEW FuzzyQuery( _CLNEW Term( table.toStdWString().c_str(), name.toStdWString().c_str() ) ); - hits = m_luceneSearcher->search( qry ); - - for ( int i = 0; i < hits->length(); i++ ) - { - Document* d = &hits->doc( i ); - - float score = hits->score( i ); - int id = QString::fromWCharArray( d->get( _T( "id" ) ) ).toInt(); - QString result = QString::fromWCharArray( d->get( table.toStdWString().c_str() ) ); - - if ( result.toLower() == name.toLower() ) - score = 1.0; - else - score = qMin( score, (float)0.99 ); - - if ( score > 0.05 ) + for ( int i = 0; i < hits->length(); i++ ) { - resultsmap.insert( id, score ); -// qDebug() << "Hitres:" << result << id << score << table << name; + Document* d = &hits->doc( i ); + + float score = hits->score( i ); + int id = QString::fromWCharArray( d->get( _T( "id" ) ) ).toInt(); + QString result = QString::fromWCharArray( d->get( table.toStdWString().c_str() ) ); + + if ( result.toLower() == name.toLower() ) + score = 1.0; + else + score = qMin( score, (float)0.99 ); + + if ( score > 0.05 ) + { + resultsmap.insert( id, score ); + // qDebug() << "Hitres:" << result << id << score << table << name; + } } } + catch( CLuceneError& error ) + { + qDebug() << "Caught CLucene error:" << error.what(); + Q_ASSERT( false ); + } return resultsmap; } diff --git a/src/libtomahawk/playlist/collectionview.cpp b/src/libtomahawk/playlist/collectionview.cpp index 0847849e8..2df2a594e 100644 --- a/src/libtomahawk/playlist/collectionview.cpp +++ b/src/libtomahawk/playlist/collectionview.cpp @@ -13,7 +13,6 @@ using namespace Tomahawk; CollectionView::CollectionView( QWidget* parent ) : TrackView( parent ) { - setGuid( "collectionview" ); setProxyModel( new CollectionProxyModel( this ) ); setSortingEnabled( true ); @@ -37,6 +36,7 @@ void CollectionView::setModel( TrackModel* model ) { TrackView::setModel( model ); + setGuid( "collectionview" ); connect( model, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) ); } diff --git a/src/libtomahawk/playlist/playlistview.cpp b/src/libtomahawk/playlist/playlistview.cpp index b11255f2e..9e45175ab 100644 --- a/src/libtomahawk/playlist/playlistview.cpp +++ b/src/libtomahawk/playlist/playlistview.cpp @@ -14,7 +14,6 @@ using namespace Tomahawk; PlaylistView::PlaylistView( QWidget* parent ) : TrackView( parent ) { - setGuid( "playlistview" ); setProxyModel( new PlaylistProxyModel( this ) ); setContextMenuPolicy( Qt::CustomContextMenu ); @@ -31,14 +30,16 @@ PlaylistView::~PlaylistView() void PlaylistView::setModel( PlaylistModel* model ) { - if ( !model->playlist().isNull() ) - setGuid( QString( "playlistview/%1" ).arg( model->playlist()->guid() ) ); - m_model = model; TrackView::setModel( model ); setColumnHidden( 5, true ); // Hide age column per default + if ( !model->playlist().isNull() ) + setGuid( QString( "playlistview/%1" ).arg( model->playlist()->guid() ) ); + else + setGuid( "playlistview" ); + connect( model, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) ); } diff --git a/src/libtomahawk/playlist/trackheader.cpp b/src/libtomahawk/playlist/trackheader.cpp index 7df6fb8ea..42080b98b 100644 --- a/src/libtomahawk/playlist/trackheader.cpp +++ b/src/libtomahawk/playlist/trackheader.cpp @@ -14,28 +14,35 @@ TrackHeader::TrackHeader( TrackView* 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( true ); setResizeMode( QHeaderView::Interactive ); setMinimumSectionSize( 60 ); setDefaultAlignment( Qt::AlignLeft ); setMovable( true ); + setStretchLastSection( true ); // setCascadingSectionResizes( 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( this, SIGNAL( sectionResized( int, int, int ) ), SLOT( onSectionResized() ) ); connect( m_sigmap, SIGNAL( mapped( int ) ), SLOT( toggleVisibility( int ) ) ); } TrackHeader::~TrackHeader() { - saveColumnsState(); +} + + +void +TrackHeader::onSectionResized() +{ + if ( !m_init ) + return; + + TomahawkSettings::instance()->setPlaylistColumnSizes( m_parent->guid(), saveState() ); } @@ -47,39 +54,27 @@ TrackHeader::visibleSectionCount() const void -TrackHeader::onSectionResized( int logicalidx, int oldSize, int newSize ) +TrackHeader::checkState() { - if ( !m_init ) + if ( !count() || m_init ) return; - int width = m_parent->viewport()->width(); - for ( int x = 0; x < m_columnWeights.count(); x++ ) + QByteArray state = TomahawkSettings::instance()->playlistColumnSizes( m_parent->guid() ); + if ( !state.isEmpty() ) + restoreState( state ); + else { - if ( sectionSize( x ) ) + QList< double > m_columnWeights; + m_columnWeights << 0.21 << 0.22 << 0.20 << 0.05 << 0.05 << 0.05 << 0.05 << 0.05; // << 0.12; + + for ( int i = 0; i < count() - 1; i++ ) { - // not hidden - m_columnWeights[x] = (double)sectionSize( x ) / (double)width; - } - } -} + if ( isSectionHidden( i ) ) + continue; - -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 - double nw = (double)width * m_columnWeights[x]; - resizeSection( x, qMax( minimumSectionSize(), int( nw ) ) ); + double nw = (double)m_parent->width() * m_columnWeights.at( i ); + qDebug() << "Setting default size:" << i << nw; + resizeSection( i, qMax( minimumSectionSize(), int( nw - 0.5 ) ) ); } } @@ -87,35 +82,6 @@ TrackHeader::onResized() } -void -TrackHeader::restoreColumnsState() -{ - QList list = TomahawkSettings::instance()->playlistColumnSizes( m_parent->guid() ); - - 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() -{ - QList wlist; - - foreach( double w, m_columnWeights ) - wlist << QVariant( w ); - - TomahawkSettings::instance()->setPlaylistColumnSizes( m_parent->guid(), wlist ); -} - - void TrackHeader::addColumnToMenu( int index ) { @@ -158,6 +124,4 @@ TrackHeader::toggleVisibility( int index ) showSection( index ); else hideSection( index ); - - onResized(); } diff --git a/src/libtomahawk/playlist/trackheader.h b/src/libtomahawk/playlist/trackheader.h index 75db27b0d..21b9e3243 100644 --- a/src/libtomahawk/playlist/trackheader.h +++ b/src/libtomahawk/playlist/trackheader.h @@ -19,32 +19,24 @@ public: int visibleSectionCount() const; public slots: - void onResized(); void toggleVisibility( int index ); + void checkState(); protected: void contextMenuEvent( QContextMenuEvent* e ); private slots: - void onSectionResized( int logicalIndex, int oldSize, int newSize ); - + void onSectionResized(); void onToggleResizeColumns(); private: void addColumnToMenu( int index ); - void restoreColumnsState(); - void saveColumnsState(); - TrackView* m_parent; QMenu* m_menu; QSignalMapper* m_sigmap; QList m_visActions; - - QList m_columnWeights; - int m_hiddenWidth; - double m_hiddenPct; bool m_init; }; diff --git a/src/libtomahawk/playlist/trackmodel.cpp b/src/libtomahawk/playlist/trackmodel.cpp index 7cb73631b..a39eecc76 100644 --- a/src/libtomahawk/playlist/trackmodel.cpp +++ b/src/libtomahawk/playlist/trackmodel.cpp @@ -190,7 +190,7 @@ TrackModel::headerData( int section, Qt::Orientation orientation, int role ) con { QStringList headers; 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 ) + if ( role == Qt::DisplayRole && section >= 0 ) { return headers.at( section ); } diff --git a/src/libtomahawk/playlist/trackview.cpp b/src/libtomahawk/playlist/trackview.cpp index 3317bd21b..c2a972ed1 100644 --- a/src/libtomahawk/playlist/trackview.cpp +++ b/src/libtomahawk/playlist/trackview.cpp @@ -40,6 +40,7 @@ TrackView::TrackView( QWidget* parent ) setRootIsDecorated( false ); setUniformRowHeights( true ); setMinimumWidth( 300 ); +// setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn ); setHeader( m_header ); @@ -61,6 +62,13 @@ TrackView::~TrackView() } +void +TrackView::setGuid( const QString& guid ) +{ + m_guid = guid; +} + + void TrackView::setProxyModel( TrackProxyModel* model ) { @@ -156,7 +164,8 @@ TrackView::addItemsToQueue() void TrackView::resizeEvent( QResizeEvent* event ) { - m_header->onResized(); + QTreeView::resizeEvent( event ); + m_header->checkState(); } diff --git a/src/libtomahawk/playlist/trackview.h b/src/libtomahawk/playlist/trackview.h index 51207506a..337d004a5 100644 --- a/src/libtomahawk/playlist/trackview.h +++ b/src/libtomahawk/playlist/trackview.h @@ -23,7 +23,7 @@ public: ~TrackView(); virtual QString guid() const { return m_guid; } - virtual void setGuid( const QString& guid ) { m_guid = guid; } + virtual void setGuid( const QString& guid ); virtual void setModel( TrackModel* model ); void setProxyModel( TrackProxyModel* model ); diff --git a/src/libtomahawk/qtsingleapp/qtlockedfile_win.cpp b/src/libtomahawk/qtsingleapp/qtlockedfile_win.cpp index 4cd200397..8090470cd 100644 --- a/src/libtomahawk/qtsingleapp/qtlockedfile_win.cpp +++ b/src/libtomahawk/qtsingleapp/qtlockedfile_win.cpp @@ -45,6 +45,8 @@ // Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS #define MAX_READERS MAXIMUM_WAIT_OBJECTS +#define TCHAR WCHAR + Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate) { if (mutexname.isEmpty()) { diff --git a/src/libtomahawk/qtsingleapp/qtsingleapplication.h b/src/libtomahawk/qtsingleapp/qtsingleapplication.h index 7bf6837ae..c696d60ce 100644 --- a/src/libtomahawk/qtsingleapp/qtsingleapplication.h +++ b/src/libtomahawk/qtsingleapp/qtsingleapplication.h @@ -40,25 +40,11 @@ #include +#include "dllmacro.h" + class QtLocalPeer; -#if defined(Q_WS_WIN) -# if !defined(QT_QTSINGLEAPPLICATION_EXPORT) && !defined(QT_QTSINGLEAPPLICATION_IMPORT) -# define QT_QTSINGLEAPPLICATION_EXPORT -# elif defined(QT_QTSINGLEAPPLICATION_IMPORT) -# if defined(QT_QTSINGLEAPPLICATION_EXPORT) -# undef QT_QTSINGLEAPPLICATION_EXPORT -# endif -# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllimport) -# elif defined(QT_QTSINGLEAPPLICATION_EXPORT) -# undef QT_QTSINGLEAPPLICATION_EXPORT -# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllexport) -# endif -#else -# define QT_QTSINGLEAPPLICATION_EXPORT -#endif - -class QT_QTSINGLEAPPLICATION_EXPORT QtSingleApplication : public QApplication +class DLLEXPORT QtSingleApplication : public QApplication { Q_OBJECT diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index 2b6b9935f..611bb4cf5 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -20,12 +20,9 @@ TomahawkSettings::instance() TomahawkSettings::TomahawkSettings( QObject* parent ) : QSettings( parent ) - , m_safety() { s_instance = this; - m_safety = new QMutex(); - QMutexLocker locker( m_safety ); #ifndef TOMAHAWK_HEADLESS if( !contains( "configversion") ) { @@ -53,7 +50,6 @@ TomahawkSettings::~TomahawkSettings() QString TomahawkSettings::scannerPath() const { - QMutexLocker locker( m_safety ); #ifndef TOMAHAWK_HEADLESS return value( "scannerpath", QDesktopServices::storageLocation( QDesktopServices::MusicLocation ) ).toString(); #else @@ -65,7 +61,6 @@ TomahawkSettings::scannerPath() const void TomahawkSettings::setScannerPath( const QString& path ) { - QMutexLocker locker( m_safety ); setValue( "scannerpath", path ); } @@ -73,7 +68,6 @@ TomahawkSettings::setScannerPath( const QString& path ) bool TomahawkSettings::hasScannerPath() const { - QMutexLocker locker( m_safety ); return contains( "scannerpath" ); } @@ -81,7 +75,6 @@ TomahawkSettings::hasScannerPath() const bool TomahawkSettings::httpEnabled() const { - QMutexLocker locker( m_safety ); return value( "network/http", true ).toBool(); } @@ -89,7 +82,6 @@ TomahawkSettings::httpEnabled() const void TomahawkSettings::setHttpEnabled( bool enable ) { - QMutexLocker locker( m_safety ); setValue( "network/http", enable ); } @@ -97,7 +89,6 @@ TomahawkSettings::setHttpEnabled( bool enable ) QString TomahawkSettings::proxyHost() const { - QMutexLocker locker( m_safety ); return value( "network/proxy/host", QString() ).toString(); } @@ -105,7 +96,6 @@ TomahawkSettings::proxyHost() const void TomahawkSettings::setProxyHost( const QString& host ) { - QMutexLocker locker( m_safety ); setValue( "network/proxy/host", host ); } @@ -113,7 +103,6 @@ TomahawkSettings::setProxyHost( const QString& host ) qulonglong TomahawkSettings::proxyPort() const { - QMutexLocker locker( m_safety ); return value( "network/proxy/port", 1080 ).toULongLong(); } @@ -121,7 +110,6 @@ TomahawkSettings::proxyPort() const void TomahawkSettings::setProxyPort( const qulonglong port ) { - QMutexLocker locker( m_safety ); setValue( "network/proxy/port", port ); } @@ -129,7 +117,6 @@ TomahawkSettings::setProxyPort( const qulonglong port ) QString TomahawkSettings::proxyUsername() const { - QMutexLocker locker( m_safety ); return value( "network/proxy/username", QString() ).toString(); } @@ -137,7 +124,6 @@ TomahawkSettings::proxyUsername() const void TomahawkSettings::setProxyUsername( const QString& username ) { - QMutexLocker locker( m_safety ); setValue( "network/proxy/username", username ); } @@ -145,7 +131,6 @@ TomahawkSettings::setProxyUsername( const QString& username ) QString TomahawkSettings::proxyPassword() const { - QMutexLocker locker( m_safety ); return value( "network/proxy/password", QString() ).toString(); } @@ -153,7 +138,6 @@ TomahawkSettings::proxyPassword() const void TomahawkSettings::setProxyPassword( const QString& password ) { - QMutexLocker locker( m_safety ); setValue( "network/proxy/password", password ); } @@ -161,7 +145,6 @@ TomahawkSettings::setProxyPassword( const QString& password ) int TomahawkSettings::proxyType() const { - QMutexLocker locker( m_safety ); return value( "network/proxy/type", 0 ).toInt(); } @@ -169,7 +152,6 @@ TomahawkSettings::proxyType() const void TomahawkSettings::setProxyType( const int type ) { - QMutexLocker locker( m_safety ); setValue( "network/proxy/type", type ); } @@ -177,7 +159,6 @@ TomahawkSettings::setProxyType( const int type ) QByteArray TomahawkSettings::mainWindowGeometry() const { - QMutexLocker locker( m_safety ); return value( "ui/mainwindow/geometry" ).toByteArray(); } @@ -185,7 +166,6 @@ TomahawkSettings::mainWindowGeometry() const void TomahawkSettings::setMainWindowGeometry( const QByteArray& geom ) { - QMutexLocker locker( m_safety ); setValue( "ui/mainwindow/geometry", geom ); } @@ -193,7 +173,6 @@ TomahawkSettings::setMainWindowGeometry( const QByteArray& geom ) QByteArray TomahawkSettings::mainWindowState() const { - QMutexLocker locker( m_safety ); return value( "ui/mainwindow/state" ).toByteArray(); } @@ -201,31 +180,27 @@ TomahawkSettings::mainWindowState() const void TomahawkSettings::setMainWindowState( const QByteArray& state ) { - QMutexLocker locker( m_safety ); setValue( "ui/mainwindow/state", state ); } -QList +QByteArray TomahawkSettings::playlistColumnSizes( const QString& playlistid ) const { - QMutexLocker locker( m_safety ); - return value( QString( "ui/playlist/%1/columnSizes" ).arg( playlistid ) ).toList(); + return value( QString( "ui/playlist/%1/columnSizes" ).arg( playlistid ) ).toByteArray(); } void -TomahawkSettings::setPlaylistColumnSizes( const QString& playlistid, const QList& cols ) +TomahawkSettings::setPlaylistColumnSizes( const QString& playlistid, const QByteArray& state ) { - QMutexLocker locker( m_safety ); - setValue( QString( "ui/playlist/%1/columnSizes" ).arg( playlistid ), cols ); + setValue( QString( "ui/playlist/%1/columnSizes" ).arg( playlistid ), state ); } QList TomahawkSettings::recentlyPlayedPlaylists() const { - QMutexLocker locker( m_safety ); QStringList playlist_guids = value( "playlists/recentlyPlayed" ).toStringList(); QList playlists; @@ -243,7 +218,6 @@ TomahawkSettings::recentlyPlayedPlaylists() const void TomahawkSettings::appendRecentlyPlayedPlaylist( const Tomahawk::playlist_ptr& playlist ) { - QMutexLocker locker( m_safety ); QStringList playlist_guids = value( "playlists/recentlyPlayed" ).toStringList(); playlist_guids.removeAll( playlist->guid() ); @@ -256,7 +230,6 @@ TomahawkSettings::appendRecentlyPlayedPlaylist( const Tomahawk::playlist_ptr& pl bool TomahawkSettings::jabberAutoConnect() const { - QMutexLocker locker( m_safety ); return value( "jabber/autoconnect", true ).toBool(); } @@ -264,7 +237,6 @@ TomahawkSettings::jabberAutoConnect() const void TomahawkSettings::setJabberAutoConnect( bool autoconnect ) { - QMutexLocker locker( m_safety ); setValue( "jabber/autoconnect", autoconnect ); } @@ -272,7 +244,6 @@ TomahawkSettings::setJabberAutoConnect( bool autoconnect ) unsigned int TomahawkSettings::jabberPort() const { - QMutexLocker locker( m_safety ); return value( "jabber/port", 5222 ).toUInt(); } @@ -280,7 +251,6 @@ TomahawkSettings::jabberPort() const void TomahawkSettings::setJabberPort( int port ) { - QMutexLocker locker( m_safety ); if ( port < 0 ) return; setValue( "jabber/port", port ); @@ -290,7 +260,6 @@ TomahawkSettings::setJabberPort( int port ) QString TomahawkSettings::jabberServer() const { - QMutexLocker locker( m_safety ); return value( "jabber/server" ).toString(); } @@ -298,7 +267,6 @@ TomahawkSettings::jabberServer() const void TomahawkSettings::setJabberServer( const QString& server ) { - QMutexLocker locker( m_safety ); setValue( "jabber/server", server ); } @@ -306,7 +274,6 @@ TomahawkSettings::setJabberServer( const QString& server ) QString TomahawkSettings::jabberUsername() const { - QMutexLocker locker( m_safety ); return value( "jabber/username" ).toString(); } @@ -314,7 +281,6 @@ TomahawkSettings::jabberUsername() const void TomahawkSettings::setJabberUsername( const QString& username ) { - QMutexLocker locker( m_safety ); setValue( "jabber/username", username ); } @@ -322,7 +288,6 @@ TomahawkSettings::setJabberUsername( const QString& username ) QString TomahawkSettings::jabberPassword() const { - QMutexLocker locker( m_safety ); return value( "jabber/password" ).toString(); } @@ -330,7 +295,6 @@ TomahawkSettings::jabberPassword() const void TomahawkSettings::setJabberPassword( const QString& pw ) { - QMutexLocker locker( m_safety ); setValue( "jabber/password", pw ); } @@ -338,7 +302,6 @@ TomahawkSettings::setJabberPassword( const QString& pw ) TomahawkSettings::ExternalAddressMode TomahawkSettings::externalAddressMode() const { - QMutexLocker locker( m_safety ); return (TomahawkSettings::ExternalAddressMode) value( "network/external-address-mode", TomahawkSettings::Upnp ).toInt(); } @@ -346,35 +309,30 @@ TomahawkSettings::externalAddressMode() const void TomahawkSettings::setExternalAddressMode( ExternalAddressMode externalAddressMode ) { - QMutexLocker locker( m_safety ); setValue( "network/external-address-mode", externalAddressMode ); } QString TomahawkSettings::externalHostname() const { - QMutexLocker locker( m_safety ); return value( "network/external-hostname" ).toString(); } void TomahawkSettings::setExternalHostname(const QString& externalHostname) { - QMutexLocker locker( m_safety ); setValue( "network/external-hostname", externalHostname ); } int TomahawkSettings::externalPort() const { - QMutexLocker locker( m_safety ); return value( "network/external-port", 50210 ).toInt(); } void TomahawkSettings::setExternalPort(int externalPort) { - QMutexLocker locker( m_safety ); if ( externalPort == 0 ) setValue( "network/external-port", 50210); else @@ -385,7 +343,6 @@ TomahawkSettings::setExternalPort(int externalPort) QString TomahawkSettings::lastFmPassword() const { - QMutexLocker locker( m_safety ); return value( "lastfm/password" ).toString(); } @@ -393,7 +350,6 @@ TomahawkSettings::lastFmPassword() const void TomahawkSettings::setLastFmPassword( const QString& password ) { - QMutexLocker locker( m_safety ); setValue( "lastfm/password", password ); } @@ -401,7 +357,6 @@ TomahawkSettings::setLastFmPassword( const QString& password ) QByteArray TomahawkSettings::lastFmSessionKey() const { - QMutexLocker locker( m_safety ); return value( "lastfm/session" ).toByteArray(); } @@ -409,7 +364,6 @@ TomahawkSettings::lastFmSessionKey() const void TomahawkSettings::setLastFmSessionKey( const QByteArray& key ) { - QMutexLocker locker( m_safety ); setValue( "lastfm/session", key ); } @@ -417,7 +371,6 @@ TomahawkSettings::setLastFmSessionKey( const QByteArray& key ) QString TomahawkSettings::lastFmUsername() const { - QMutexLocker locker( m_safety ); return value( "lastfm/username" ).toString(); } @@ -425,112 +378,96 @@ TomahawkSettings::lastFmUsername() const void TomahawkSettings::setLastFmUsername( const QString& username ) { - QMutexLocker locker( m_safety ); setValue( "lastfm/username", username ); } QString TomahawkSettings::twitterScreenName() const { - QMutexLocker locker( m_safety ); return value( "twitter/ScreenName" ).toString(); } void TomahawkSettings::setTwitterScreenName( const QString& screenName ) { - QMutexLocker locker( m_safety ); setValue( "twitter/ScreenName", screenName ); } QString TomahawkSettings::twitterOAuthToken() const { - QMutexLocker locker( m_safety ); return value( "twitter/OAuthToken" ).toString(); } void TomahawkSettings::setTwitterOAuthToken( const QString& oauthtoken ) { - QMutexLocker locker( m_safety ); setValue( "twitter/OAuthToken", oauthtoken ); } QString TomahawkSettings::twitterOAuthTokenSecret() const { - QMutexLocker locker( m_safety ); return value( "twitter/OAuthTokenSecret" ).toString(); } void TomahawkSettings::setTwitterOAuthTokenSecret( const QString& oauthtokensecret ) { - QMutexLocker locker( m_safety ); setValue( "twitter/OAuthTokenSecret", oauthtokensecret ); } qint64 TomahawkSettings::twitterCachedFriendsSinceId() const { - QMutexLocker locker( m_safety ); return value( "twitter/CachedFriendsSinceID", 0 ).toLongLong(); } void TomahawkSettings::setTwitterCachedFriendsSinceId( qint64 cachedId ) { - QMutexLocker locker( m_safety ); setValue( "twitter/CachedFriendsSinceID", cachedId ); } qint64 TomahawkSettings::twitterCachedMentionsSinceId() const { - QMutexLocker locker( m_safety ); return value( "twitter/CachedMentionsSinceID", 0 ).toLongLong(); } void TomahawkSettings::setTwitterCachedMentionsSinceId( qint64 cachedId ) { - QMutexLocker locker( m_safety ); setValue( "twitter/CachedMentionsSinceID", cachedId ); } qint64 TomahawkSettings::twitterCachedDirectMessagesSinceId() const { - QMutexLocker locker( m_safety ); return value( "twitter/CachedDirectMessagesSinceID", 0 ).toLongLong(); } void TomahawkSettings::setTwitterCachedDirectMessagesSinceId( qint64 cachedId ) { - QMutexLocker locker( m_safety ); setValue( "twitter/CachedDirectMessagesSinceID", cachedId ); } QHash TomahawkSettings::twitterCachedPeers() const { - QMutexLocker locker( m_safety ); return value( "twitter/CachedPeers", QHash() ).toHash(); } void TomahawkSettings::setTwitterCachedPeers( const QHash &cachedPeers ) { - QMutexLocker locker( m_safety ); setValue( "twitter/CachedPeers", cachedPeers ); } bool TomahawkSettings::scrobblingEnabled() const { - QMutexLocker locker( m_safety ); return value( "lastfm/enablescrobbling", false ).toBool(); } @@ -538,7 +475,6 @@ TomahawkSettings::scrobblingEnabled() const void TomahawkSettings::setScrobblingEnabled( bool enable ) { - QMutexLocker locker( m_safety ); setValue( "lastfm/enablescrobbling", enable ); } @@ -546,7 +482,6 @@ TomahawkSettings::setScrobblingEnabled( bool enable ) QString TomahawkSettings::xmppBotServer() const { - QMutexLocker locker( m_safety ); return value( "xmppBot/server", QString() ).toString(); } @@ -554,7 +489,6 @@ TomahawkSettings::xmppBotServer() const void TomahawkSettings::setXmppBotServer( const QString& server ) { - QMutexLocker locker( m_safety ); setValue( "xmppBot/server", server ); } @@ -562,7 +496,6 @@ TomahawkSettings::setXmppBotServer( const QString& server ) QString TomahawkSettings::xmppBotJid() const { - QMutexLocker locker( m_safety ); return value( "xmppBot/jid", QString() ).toString(); } @@ -570,7 +503,6 @@ TomahawkSettings::xmppBotJid() const void TomahawkSettings::setXmppBotJid( const QString& component ) { - QMutexLocker locker( m_safety ); setValue( "xmppBot/jid", component ); } @@ -578,7 +510,6 @@ TomahawkSettings::setXmppBotJid( const QString& component ) QString TomahawkSettings::xmppBotPassword() const { - QMutexLocker locker( m_safety ); return value( "xmppBot/password", QString() ).toString(); } @@ -586,7 +517,6 @@ TomahawkSettings::xmppBotPassword() const void TomahawkSettings::setXmppBotPassword( const QString& password ) { - QMutexLocker locker( m_safety ); setValue( "xmppBot/password", password ); } @@ -594,7 +524,6 @@ TomahawkSettings::setXmppBotPassword( const QString& password ) int TomahawkSettings::xmppBotPort() const { - QMutexLocker locker( m_safety ); return value( "xmppBot/port", -1 ).toInt(); } @@ -602,27 +531,23 @@ TomahawkSettings::xmppBotPort() const void TomahawkSettings::setXmppBotPort( const int port ) { - QMutexLocker locker( m_safety ); setValue( "xmppBot/port", -1 ); } void TomahawkSettings::addScriptResolver(const QString& resolver) { - QMutexLocker locker( m_safety ); setValue( "script/resolvers", scriptResolvers() << resolver ); } QStringList TomahawkSettings::scriptResolvers() const { - QMutexLocker locker( m_safety ); return value( "script/resolvers" ).toStringList(); } void TomahawkSettings::setScriptResolvers( const QStringList& resolver ) { - QMutexLocker locker( m_safety ); setValue( "script/resolvers", resolver ); } diff --git a/src/libtomahawk/tomahawksettings.h b/src/libtomahawk/tomahawksettings.h index 249495026..19bbbf492 100644 --- a/src/libtomahawk/tomahawksettings.h +++ b/src/libtomahawk/tomahawksettings.h @@ -32,8 +32,8 @@ public: void setMainWindowState( const QByteArray& state ); /// Playlist stuff - QList playlistColumnSizes( const QString& playlistid ) const; - void setPlaylistColumnSizes( const QString& playlistid, const QList& cols ); + QByteArray playlistColumnSizes( const QString& playlistid ) const; + void setPlaylistColumnSizes( const QString& playlistid, const QByteArray& state ); QList recentlyPlayedPlaylists() const; void appendRecentlyPlayedPlaylist( const Tomahawk::playlist_ptr& playlist ); @@ -139,7 +139,6 @@ public: private: static TomahawkSettings* s_instance; - QMutex *m_safety; }; #endif diff --git a/src/libtomahawk/utils/proxystyle.cpp b/src/libtomahawk/utils/proxystyle.cpp index 2778e47ee..34feb8f93 100644 --- a/src/libtomahawk/utils/proxystyle.cpp +++ b/src/libtomahawk/utils/proxystyle.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -19,8 +20,12 @@ ProxyStyle::drawControl( ControlElement ce, const QStyleOption* opt, QPainter* p { if ( ce == CE_Splitter ) { - p->setPen( QColor( 0x8c, 0x8c, 0x8c ) ); - p->drawLine( opt->rect.topLeft(), opt->rect.bottomRight() ); + const QSplitter* splitter = qobject_cast< const QSplitter* >( w ); + if ( !splitter->sizes().contains( 0 ) ) + { + p->setPen( QColor( 0x8c, 0x8c, 0x8c ) ); + p->drawLine( opt->rect.topLeft(), opt->rect.bottomRight() ); + } } else QProxyStyle::drawControl( ce, opt, p, w ); diff --git a/src/mac/macshortcuthandler.cpp b/src/mac/macshortcuthandler.cpp new file mode 100644 index 000000000..80bc64815 --- /dev/null +++ b/src/mac/macshortcuthandler.cpp @@ -0,0 +1,31 @@ +#include "macshortcuthandler.h" + +#include +#include + +using namespace Tomahawk; + +MacShortcutHandler::MacShortcutHandler(QObject *parent) : + Tomahawk::ShortcutHandler(parent) +{ + +} + +void +MacShortcutHandler::macMediaKeyPressed( int key ) +{ + switch (key) { + case NX_KEYTYPE_PLAY: + qDebug() << "emitting PlayPause pressed"; + emit playPause(); + break; + case NX_KEYTYPE_FAST: + qDebug() << "emitting next pressed"; + emit next(); + break; + case NX_KEYTYPE_REWIND: + qDebug() << "emitting prev pressed"; + emit previous(); + break; + } +} diff --git a/src/mac/macshortcuthandler.h b/src/mac/macshortcuthandler.h new file mode 100644 index 000000000..014d71421 --- /dev/null +++ b/src/mac/macshortcuthandler.h @@ -0,0 +1,22 @@ +#ifndef MACSHORTCUTHANDLER_H +#define MACSHORTCUTHANDLER_H + +#include "shortcuthandler.h" + +#include + +namespace Tomahawk { + + +class MacShortcutHandler : public ShortcutHandler +{ + Q_OBJECT +public: + explicit MacShortcutHandler(QObject *parent = 0); + + void macMediaKeyPressed( int key ); +}; + +} + +#endif // MACSHORTCUTHANDLER_H diff --git a/src/mac/tomahawkapp_mac.h b/src/mac/tomahawkapp_mac.h new file mode 100644 index 000000000..c242b2e0a --- /dev/null +++ b/src/mac/tomahawkapp_mac.h @@ -0,0 +1,30 @@ +#ifndef TOMAHAWKAPP_MAC_H +#define TOMAHAWKAPP_MAC_H + +// this file and tomahawk_app.mm copied and inspired by mac_startup.* in clementine player, +// copyright David Sansome 2010 + +class QString; + +namespace Tomahawk { + +class MacShortcutHandler; + +/// Interface between cocoa and tomahawk +class PlatformInterface { + public: + // Called when the application should show itself. + virtual void activate() = 0; + virtual bool loadUrl( const QString& url ) = 0; + + virtual ~PlatformInterface() {} +}; + +void macMain(); +void setShortcutHandler(Tomahawk::MacShortcutHandler* engine); +// used for opening files with tomahawk +void setApplicationHandler(PlatformInterface* handler); + +}; + +#endif diff --git a/src/mac/tomahawkapp_mac.mm b/src/mac/tomahawkapp_mac.mm new file mode 100644 index 000000000..cf60300b0 --- /dev/null +++ b/src/mac/tomahawkapp_mac.mm @@ -0,0 +1,205 @@ +#include "tomahawkapp_mac.h" +#include "tomahawkapp_macdelegate.h" +#include "macshortcuthandler.h" +#include + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +// Capture global media keys on Mac (Cocoa only!) +// See: http://www.rogueamoeba.com/utm/2007/09/29/apple-keyboard-media-key-event-handling/ + +@interface MacApplication :NSApplication { + Tomahawk::MacShortcutHandler* shortcut_handler_; + Tomahawk::PlatformInterface* application_handler_; +} + +- (Tomahawk::MacShortcutHandler*) shortcutHandler; +- (void) setShortcutHandler: (Tomahawk::MacShortcutHandler*)handler; + +- (Tomahawk::PlatformInterface*) application_handler; +- (void) setApplicationHandler: (Tomahawk::PlatformInterface*)handler; +- (void) getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent; +- (void) mediaKeyEvent: (int)key state: (BOOL)state repeat: (BOOL)repeat; +@end + + +@implementation AppDelegate + +- (id) init { + if ((self = [super init])) { + application_handler_ = nil; +// dock_menu_ = nil; + } + return self; +} + +- (id) initWithHandler: (Tomahawk::PlatformInterface*)handler { + application_handler_ = handler; + return self; +} + +- (BOOL) applicationShouldHandleReopen: (NSApplication*)app hasVisibleWindows:(BOOL)flag { + if (application_handler_) { + application_handler_->activate(); + } + return YES; +} +/* +- (void) setDockMenu: (NSMenu*)menu { + dock_menu_ = menu; +} + +- (NSMenu*) applicationDockMenu: (NSApplication*)sender { + return dock_menu_; +} +*/ +- (BOOL) application: (NSApplication*)app openFile:(NSString*)filename { + qDebug() << "Wants to open:" << [filename UTF8String]; + + if (application_handler_->loadUrl(QString::fromUtf8([filename UTF8String]))) { + return YES; + } + + return NO; +} +@end + +@implementation MacApplication + +- (id) init { + if ((self = [super init])) { + [self setShortcutHandler:nil]; + [self setApplicationHandler:nil]; + } + return self; +} + +- (Tomahawk::MacShortcutHandler*) shortcutHandler { + return shortcut_handler_; +} + +- (void) setShortcutHandler: (Tomahawk::MacShortcutHandler*)handler { + qDebug() << "Setting shortcut handler of MacAPp"; + shortcut_handler_ = handler; +} + +- (Tomahawk::PlatformInterface*) application_handler { + return application_handler_; +} + +- (void) setApplicationHandler: (Tomahawk::PlatformInterface*)handler { + AppDelegate* delegate = [[AppDelegate alloc] initWithHandler:handler]; + [self setDelegate:delegate]; +} + +-(void) sendEvent: (NSEvent*)event { + if ([event type] == NSSystemDefined && [event subtype] == 8) { + int keycode = (([event data1] & 0xFFFF0000) >> 16); + int keyflags = ([event data1] & 0x0000FFFF); + int keystate = (((keyflags & 0xFF00) >> 8)) == 0xA; + int keyrepeat = (keyflags & 0x1); + + [self mediaKeyEvent: keycode state: keystate repeat: keyrepeat]; + } + + [super sendEvent: event]; +} + +-(void) mediaKeyEvent: (int)key state: (BOOL)state repeat: (BOOL)repeat { + if (!shortcut_handler_) { + return; + } + if (state == 0) { + shortcut_handler_->macMediaKeyPressed(key); + } +} + +@end + +void Tomahawk::macMain() { + [[NSAutoreleasePool alloc] init]; + // Creates and sets the magic global variable so QApplication will find it. + [MacApplication sharedApplication]; + #ifdef HAVE_SPARKLE + // Creates and sets the magic global variable for Sparkle. + [[SUUpdater sharedUpdater] setDelegate: NSApp]; + #endif +} + + +void Tomahawk::setShortcutHandler(Tomahawk::MacShortcutHandler* handler) { + [NSApp setShortcutHandler: handler]; +} + +void Tomahawk::setApplicationHandler(Tomahawk::PlatformInterface* handler) { + [NSApp setApplicationHandler: handler]; +} + +void CheckForUpdates() { + #ifdef HAVE_SPARKLE + [[SUUpdater sharedUpdater] checkForUpdates: NSApp]; + #endif +} + +QString GetBundlePath() { + CFURLRef app_url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); + CFStringRef mac_path = CFURLCopyFileSystemPath(app_url, kCFURLPOSIXPathStyle); + const char* path = CFStringGetCStringPtr(mac_path, CFStringGetSystemEncoding()); + QString bundle_path = QString::fromUtf8(path); + CFRelease(app_url); + CFRelease(mac_path); + return bundle_path; +} + +QString GetResourcesPath() { + QString bundle_path = GetBundlePath(); + return bundle_path + "/Contents/Resources"; +} + +QString GetApplicationSupportPath() { + NSAutoreleasePool* pool = [NSAutoreleasePool alloc]; + [pool init]; + NSArray* paths = NSSearchPathForDirectoriesInDomains( + NSApplicationSupportDirectory, + NSUserDomainMask, + YES); + QString ret; + if ([paths count] > 0) { + NSString* user_path = [paths objectAtIndex:0]; + ret = QString::fromUtf8([user_path UTF8String]); + } else { + ret = "~/Library/Application Support"; + } + [pool drain]; + return ret; +} + +QString GetMusicDirectory() { + NSAutoreleasePool* pool = [NSAutoreleasePool alloc]; + [pool init]; + NSArray* paths = NSSearchPathForDirectoriesInDomains( + NSMusicDirectory, + NSUserDomainMask, + YES); + QString ret; + if ([paths count] > 0) { + NSString* user_path = [paths objectAtIndex:0]; + ret = QString::fromUtf8([user_path UTF8String]); + } else { + ret = "~/Music"; + } + [pool drain]; + return ret; +} + diff --git a/src/main.cpp b/src/main.cpp index 4519a116e..d755703d2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,24 @@ #include "tomahawk/tomahawkapp.h" +#ifdef Q_WS_MAC +#include "tomahawkapp_mac.h" +#include +static pascal OSErr appleEventHandler( const AppleEvent*, AppleEvent*, long ); +#endif + #include int main( int argc, char *argv[] ) { +#ifdef Q_WS_MAC + // Do Mac specific startup to get media keys working. + // This must go before QApplication initialisation. + Tomahawk::macMain(); + + // used for url handler + AEEventHandlerUPP h = AEEventHandlerUPP( appleEventHandler ); + AEInstallEventHandler( 'GURL', 'GURL', h, 0, false ); + +#endif try { TomahawkApp a( argc, argv ); return a.exec(); @@ -10,3 +26,31 @@ int main( int argc, char *argv[] ) return 0; } } + +#ifdef Q_WS_MAC +static pascal OSErr appleEventHandler( const AppleEvent* e, AppleEvent*, long ) +{ + OSType id = typeWildCard; + AEGetAttributePtr( e, keyEventIDAttr, typeType, 0, &id, sizeof(id), 0 ); + + switch (id) + { + case 'GURL': + { + DescType type; + Size size; + + char buf[1024]; + AEGetParamPtr( e, keyDirectObject, typeChar, &type, &buf, 1023, &size ); + buf[size] = '\0'; + + QString url = QString::fromUtf8( buf ); + static_cast(qApp)->loadUrl( url ); + return noErr; + } + + default: + return unimpErr; + } +} +#endif diff --git a/src/shortcuthandler.cpp b/src/shortcuthandler.cpp new file mode 100644 index 000000000..7709789ca --- /dev/null +++ b/src/shortcuthandler.cpp @@ -0,0 +1,13 @@ +#include "shortcuthandler.h" + +using namespace Tomahawk; + +ShortcutHandler::ShortcutHandler( QObject *parent ) + : QObject( parent ) +{ + +} + + ShortcutHandler::~ShortcutHandler() + { + } diff --git a/src/shortcuthandler.h b/src/shortcuthandler.h new file mode 100644 index 000000000..6462c0ebf --- /dev/null +++ b/src/shortcuthandler.h @@ -0,0 +1,34 @@ +#ifndef SHORTCUTHANDLER_H +#define SHORTCUTHANDLER_H + +#include + +namespace Tomahawk { +/** + Base class for various shortcut plugins on different platforms + */ +class ShortcutHandler : public QObject +{ + Q_OBJECT +public: + virtual ~ShortcutHandler(); + +signals: + // add more as needed + void playPause(); + void pause(); + void stop(); + void previous(); + void next(); + + void volumeUp(); + void volumeDown(); + void mute(); +protected: + explicit ShortcutHandler( QObject *parent = 0 ); + +}; + +} + +#endif // SHORTCUTHANDLER_H diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index d91a306e2..19fbadec9 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include "artist.h" #include "album.h" @@ -22,8 +24,11 @@ #include "web/api_v1.h" #include "scriptresolver.h" #include "sourcelist.h" +#include "shortcuthandler.h" +#include "tomahawksettings.h" #include "audio/audioengine.h" +#include "utils/xspfloader.h" #ifndef TOMAHAWK_HEADLESS #include "tomahawkwindow.h" @@ -31,13 +36,15 @@ #include #endif +#ifdef Q_WS_MAC +#include "mac/macshortcuthandler.h" +#endif + #include #include #define LOGFILE TomahawkUtils::appDataDir().filePath( "tomahawk.log" ).toLocal8Bit() #define LOGFILE_SIZE 1024 * 512 -#include "tomahawksettings.h" -#include using namespace std; ofstream logfile; @@ -108,6 +115,7 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) , m_audioEngine( 0 ) , m_sipHandler( 0 ) , m_servent( 0 ) + , m_shortcutHandler( 0 ) , m_mainwindow( 0 ) , m_infoSystem( 0 ) { @@ -154,31 +162,49 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) qDebug() << "Init Echonest Factory."; GeneratorFactory::registerFactory( "echonest", new EchonestFactory ); + // Register shortcut handler for this platform +#ifdef Q_WS_MAC + m_shortcutHandler = new MacShortcutHandler( this ); + Tomahawk::setShortcutHandler( static_cast( m_shortcutHandler) ); + + Tomahawk::setApplicationHandler( this ); +#endif + + // Connect up shortcuts + connect( m_shortcutHandler, SIGNAL( playPause() ), m_audioEngine, SLOT( playPause() ) ); + connect( m_shortcutHandler, SIGNAL( pause() ), m_audioEngine, SLOT( pause() ) ); + connect( m_shortcutHandler, SIGNAL( stop() ), m_audioEngine, SLOT( stop() ) ); + connect( m_shortcutHandler, SIGNAL( previous() ), m_audioEngine, SLOT( previous() ) ); + connect( m_shortcutHandler, SIGNAL( next() ), m_audioEngine, SLOT( next() ) ); + connect( m_shortcutHandler, SIGNAL( volumeUp() ), m_audioEngine, SLOT( raiseVolume() ) ); + connect( m_shortcutHandler, SIGNAL( volumeDown() ), m_audioEngine, SLOT( lowerVolume() ) ); + connect( m_shortcutHandler, SIGNAL( mute() ), m_audioEngine, SLOT( mute() ) ); + #ifndef NO_LIBLASTFM - qDebug() << "Init Scrobbler."; - m_scrobbler = new Scrobbler( this ); - qDebug() << "Setting NAM."; - TomahawkUtils::setNam( new lastfm::NetworkAccessManager( this ) ); + qDebug() << "Init Scrobbler."; + m_scrobbler = new Scrobbler( this ); + qDebug() << "Setting NAM."; + TomahawkUtils::setNam( new lastfm::NetworkAccessManager( this ) ); - connect( m_audioEngine, SIGNAL( started( const Tomahawk::result_ptr& ) ), - m_scrobbler, SLOT( trackStarted( const Tomahawk::result_ptr& ) ), Qt::QueuedConnection ); + connect( m_audioEngine, SIGNAL( started( const Tomahawk::result_ptr& ) ), + m_scrobbler, SLOT( trackStarted( const Tomahawk::result_ptr& ) ), Qt::QueuedConnection ); - connect( m_audioEngine, SIGNAL( paused() ), - m_scrobbler, SLOT( trackPaused() ), Qt::QueuedConnection ); + connect( m_audioEngine, SIGNAL( paused() ), + m_scrobbler, SLOT( trackPaused() ), Qt::QueuedConnection ); - connect( m_audioEngine, SIGNAL( resumed() ), - m_scrobbler, SLOT( trackResumed() ), Qt::QueuedConnection ); + connect( m_audioEngine, SIGNAL( resumed() ), + m_scrobbler, SLOT( trackResumed() ), Qt::QueuedConnection ); - connect( m_audioEngine, SIGNAL( stopped() ), - m_scrobbler, SLOT( trackStopped() ), Qt::QueuedConnection ); + connect( m_audioEngine, SIGNAL( stopped() ), + m_scrobbler, SLOT( trackStopped() ), Qt::QueuedConnection ); #else - qDebug() << "Setting NAM."; - TomahawkUtils::setNam( new QNetworkAccessManager ); + qDebug() << "Setting NAM."; + TomahawkUtils::setNam( new QNetworkAccessManager ); #endif // Set up proxy if( TomahawkSettings::instance()->proxyType() != QNetworkProxy::NoProxy && - !TomahawkSettings::instance()->proxyHost().isEmpty() ) + !TomahawkSettings::instance()->proxyHost().isEmpty() ) { qDebug() << "Setting proxy to saved values"; TomahawkUtils::setProxy( new QNetworkProxy( static_cast(TomahawkSettings::instance()->proxyType()), TomahawkSettings::instance()->proxyHost(), TomahawkSettings::instance()->proxyPort(), TomahawkSettings::instance()->proxyUsername(), TomahawkSettings::instance()->proxyPassword() ) ); @@ -455,16 +481,20 @@ TomahawkApp::setupSIP() } } -void -TomahawkApp::messageReceived( const QString& msg ) + +void +TomahawkApp::activate() { - qDebug() << "MESSAGE RECEIVED" << msg; - if( msg.isEmpty() ) { - return; - } - - if( msg.contains( "tomahawk://" ) ) { - QString cmd = msg.mid( 11 ); +#ifndef TOMAHAWK_HEADLESS + mainWindow()->show(); +#endif +} + +bool +TomahawkApp::loadUrl( const QString& url ) +{ + if( url.contains( "tomahawk://" ) ) { + QString cmd = url.mid( 11 ); qDebug() << "tomahawk!s" << cmd; if( cmd.startsWith( "load/" ) ) { cmd = cmd.mid( 5 ); @@ -475,7 +505,26 @@ TomahawkApp::messageReceived( const QString& msg ) l->load( QUrl( cmd.mid( 5 ) ) ); } } - - } + } else { + QFile f( url ); + QFileInfo info( f ); + if( f.exists() && info.suffix() == "xspf" ) { + XSPFLoader* l = new XSPFLoader( true, this ); + qDebug() << "Loading spiff:" << url; + l->load( QUrl( url ) ); + } + } + return true; +} + +void +TomahawkApp::messageReceived( const QString& msg ) +{ + qDebug() << "MESSAGE RECEIVED" << msg; + if( msg.isEmpty() ) { + return; + } + + loadUrl( msg ); } diff --git a/src/tomahawkapp_macdelegate.h b/src/tomahawkapp_macdelegate.h new file mode 100644 index 000000000..a5884e225 --- /dev/null +++ b/src/tomahawkapp_macdelegate.h @@ -0,0 +1,25 @@ +#import + +#include "config.h" + +// this file copied and inspired by mac_startup.* in clementine player, +// copyright David Sansome 2010 +namespace Tomahawk { + class PlatformInterface; +} + +#ifdef SNOW_LEOPARD +@interface AppDelegate : NSObject { +#else +@interface AppDelegate : NSObject { +#endif + Tomahawk::PlatformInterface* application_handler_; + //NSMenu* dock_menu_; +} + +- (id) initWithHandler: (Tomahawk::PlatformInterface*)handler; +// NSApplicationDelegate +- (BOOL) applicationShouldHandleReopen: (NSApplication*)app hasVisibleWindows:(BOOL)flag; +//- (NSMenu*) applicationDockMenu: (NSApplication*)sender; +//- (void) setDockMenu: (NSMenu*)menu; +@end diff --git a/src/tomahawkwindow.cpp b/src/tomahawkwindow.cpp index 7ec798e29..36e71f8e4 100644 --- a/src/tomahawkwindow.cpp +++ b/src/tomahawkwindow.cpp @@ -87,22 +87,22 @@ TomahawkWindow::TomahawkWindow( QWidget* parent ) sidebar->addWidget( transferView ); sidebar->hide( 1, false ); - QWidget* buttonWidget = new QWidget(); +/* QWidget* buttonWidget = new QWidget(); buttonWidget->setLayout( new QVBoxLayout() ); m_statusButton = new QPushButton(); - buttonWidget->layout()->addWidget( m_statusButton ); + buttonWidget->layout()->addWidget( m_statusButton );*/ sidebarWidget->layout()->addWidget( sidebar ); - sidebarWidget->layout()->addWidget( buttonWidget ); +// sidebarWidget->layout()->addWidget( buttonWidget ); sidebarWidget->setContentsMargins( 0, 0, 0, 0 ); sidebarWidget->layout()->setContentsMargins( 0, 0, 0, 0 ); sidebarWidget->layout()->setMargin( 0 ); sidebarWidget->layout()->setSpacing( 0 ); - buttonWidget->setContentsMargins( 0, 0, 0, 0 ); +/* buttonWidget->setContentsMargins( 0, 0, 0, 0 ); buttonWidget->layout()->setContentsMargins( 0, 0, 0, 0 ); buttonWidget->layout()->setMargin( 0 ); - buttonWidget->layout()->setSpacing( 0 ); + buttonWidget->layout()->setSpacing( 0 );*/ ui->splitter->addWidget( sidebarWidget ); ui->splitter->addWidget( PlaylistManager::instance()->widget() ); @@ -181,7 +181,7 @@ TomahawkWindow::setupSignals() connect( ui->actionCreate_New_Station, SIGNAL( triggered() ), SLOT( createStation() )); connect( ui->actionAboutTomahawk, SIGNAL( triggered() ), SLOT( showAboutTomahawk() ) ); connect( ui->actionExit, SIGNAL( triggered() ), APP, SLOT( quit() ) ); - connect( m_statusButton, SIGNAL( clicked() ), APP->sipHandler(), SLOT( toggleConnect() ) ); +// connect( m_statusButton, SIGNAL( clicked() ), APP->sipHandler(), SLOT( toggleConnect() ) ); // connect( APP->sipHandler(), SIGNAL( connected() ), SLOT( onSipConnected() ) ); @@ -392,14 +392,14 @@ TomahawkWindow::onPlaybackLoading( const Tomahawk::result_ptr& result ) void TomahawkWindow::onSipConnected() { - m_statusButton->setText( tr( "Online" ) ); +// m_statusButton->setText( tr( "Online" ) ); } void TomahawkWindow::onSipDisconnected() { - m_statusButton->setText( tr( "Offline" ) ); +// m_statusButton->setText( tr( "Offline" ) ); } diff --git a/thirdparty/jdns/CMakeLists.txt b/thirdparty/jdns/CMakeLists.txt index 573c9e994..59f820b93 100644 --- a/thirdparty/jdns/CMakeLists.txt +++ b/thirdparty/jdns/CMakeLists.txt @@ -44,6 +44,7 @@ ADD_LIBRARY(tomahawk_jdns SHARED ${TOMAHAWK_JDNS_SOURCES} ${TOMAHAWK_JDNS_MOC}) target_link_libraries(tomahawk_jdns ${QT_LIBRARIES} + ${PLATFORM_SPECIFIC_LIBS} ) SET_TARGET_PROPERTIES( tomahawk_jdns PROPERTIES DEFINE_SYMBOL MAKE_JDNS_LIB ) diff --git a/thirdparty/jdns/jdnsshared/jdnsshared.h b/thirdparty/jdns/jdnsshared/jdnsshared.h index 701c7115e..9b8acf6b6 100644 --- a/thirdparty/jdns/jdnsshared/jdnsshared.h +++ b/thirdparty/jdns/jdnsshared/jdnsshared.h @@ -23,6 +23,8 @@ #include "qjdns.h" +#include "../jdns_export.h" + class JDnsShared; class JDnsSharedPrivate; class JDnsSharedRequestPrivate; @@ -194,7 +196,7 @@ pub->publish(QJDns::Unique, rec); \sa JDnsShared */ -class JDnsSharedRequest : public QObject +class JDNS_EXPORT JDnsSharedRequest : public QObject { Q_OBJECT public: @@ -401,7 +403,7 @@ dns->addInterface(addr); \sa JDnsSharedRequest */ -class JDnsShared : public QObject +class JDNS_EXPORT JDnsShared : public QObject { Q_OBJECT public: