1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-22 13:43:11 +02:00

Merge remote branch 'origin/master' into tweetsip

Conflicts:
	src/libtomahawk/CMakeLists.txt
	src/libtomahawk/tomahawksettings.cpp
This commit is contained in:
Jeff Mitchell
2011-02-14 13:43:58 -05:00
38 changed files with 763 additions and 288 deletions

View File

@@ -23,6 +23,36 @@
<key>CFBundleName</key>
<string>Tomahawk</string>
<key>LSMinimumSystemVersion</key>
<string>10.5.0</string>
<string>10.5.0</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>Tomahawk URL</string>
<key>CFBundleURLSchemes</key>
<array>
<string>tomahawk</string>
</array>
</dict>
</array>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>xspf</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>Generic.icns</string>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/xspf+xml</string>
</array>
<key>CFBundleTypeName</key>
<string>XSPF Playlist</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
</array>
</dict>
</plist>

View File

@@ -1 +1 @@
63
65

View File

@@ -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"

View File

@@ -4,6 +4,7 @@
#define APP TomahawkApp::instance()
#include "headlesscheck.h"
#include "mac/tomahawkapp_mac.h" // for PlatforInterface
#include <QRegExp>
#include <QFile>
@@ -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;

View File

@@ -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)

View File

@@ -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} )

10
src/config.h.in Normal file
View File

@@ -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

View File

@@ -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}
)

View File

@@ -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()

View File

@@ -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; }

View File

@@ -23,6 +23,7 @@ DatabaseCommand_UpdateSearchIndex::indexTable( DatabaseImpl* db, const QString&
}
db->m_fuzzyIndex->appendFields( table, fields );
qDebug() << "Building index for" << table << "finished.";
}

View File

@@ -40,6 +40,13 @@ DatabaseWorker::run()
void
DatabaseWorker::enqueue( const QSharedPointer<DatabaseCommand>& cmd )
{
if ( QThread::currentThread() != thread() )
{
// qDebug() << Q_FUNC_INFO << "Reinvoking in correct thread.";
QMetaObject::invokeMethod( this, "enqueue", Qt::QueuedConnection, Q_ARG( QSharedPointer<DatabaseCommand>, cmd ) );
return;
}
m_outstanding++;
QMutexLocker lock( &m_mut );

View File

@@ -25,11 +25,12 @@ public:
DatabaseWorker( DatabaseImpl*, Database*, bool mutates );
~DatabaseWorker();
void enqueue( const QSharedPointer<DatabaseCommand>& );
bool busy() const { return m_outstanding > 0; }
unsigned int outstandingJobs() const { return m_outstanding; }
public slots:
void enqueue( const QSharedPointer<DatabaseCommand>& );
protected:
void run();

View File

@@ -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;
}

View File

@@ -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 ) ) );
}

View File

@@ -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 ) ) );
}

View File

@@ -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<QVariant> 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<QVariant> 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();
}

View File

@@ -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<QAction*> m_visActions;
QList<double> m_columnWeights;
int m_hiddenWidth;
double m_hiddenPct;
bool m_init;
};

View File

@@ -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 );
}

View File

@@ -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();
}

View File

@@ -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 );

View File

@@ -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()) {

View File

@@ -40,25 +40,11 @@
#include <QtGui/QApplication>
#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

View File

@@ -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<QVariant>
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<QVariant>& 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<Tomahawk::playlist_ptr>
TomahawkSettings::recentlyPlayedPlaylists() const
{
QMutexLocker locker( m_safety );
QStringList playlist_guids = value( "playlists/recentlyPlayed" ).toStringList();
QList<Tomahawk::playlist_ptr> 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<QString, QVariant>
TomahawkSettings::twitterCachedPeers() const
{
QMutexLocker locker( m_safety );
return value( "twitter/CachedPeers", QHash<QString, QVariant>() ).toHash();
}
void
TomahawkSettings::setTwitterCachedPeers( const QHash<QString, QVariant> &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 );
}

View File

@@ -32,8 +32,8 @@ public:
void setMainWindowState( const QByteArray& state );
/// Playlist stuff
QList<QVariant> playlistColumnSizes( const QString& playlistid ) const;
void setPlaylistColumnSizes( const QString& playlistid, const QList<QVariant>& cols );
QByteArray playlistColumnSizes( const QString& playlistid ) const;
void setPlaylistColumnSizes( const QString& playlistid, const QByteArray& state );
QList<Tomahawk::playlist_ptr> recentlyPlayedPlaylists() const;
void appendRecentlyPlayedPlaylist( const Tomahawk::playlist_ptr& playlist );
@@ -139,7 +139,6 @@ public:
private:
static TomahawkSettings* s_instance;
QMutex *m_safety;
};
#endif

View File

@@ -2,6 +2,7 @@
#include <QDebug>
#include <QPainter>
#include <QSplitter>
#include <QStyleOption>
#include <QWidget>
@@ -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 );

View File

@@ -0,0 +1,31 @@
#include "macshortcuthandler.h"
#include <QDebug>
#include <IOKit/hidsystem/ev_keymap.h>
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;
}
}

View File

@@ -0,0 +1,22 @@
#ifndef MACSHORTCUTHANDLER_H
#define MACSHORTCUTHANDLER_H
#include "shortcuthandler.h"
#include <QObject>
namespace Tomahawk {
class MacShortcutHandler : public ShortcutHandler
{
Q_OBJECT
public:
explicit MacShortcutHandler(QObject *parent = 0);
void macMediaKeyPressed( int key );
};
}
#endif // MACSHORTCUTHANDLER_H

30
src/mac/tomahawkapp_mac.h Normal file
View File

@@ -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

205
src/mac/tomahawkapp_mac.mm Normal file
View File

@@ -0,0 +1,205 @@
#include "tomahawkapp_mac.h"
#include "tomahawkapp_macdelegate.h"
#include "macshortcuthandler.h"
#include <QDebug>
#import <AppKit/NSApplication.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSBundle.h>
#import <Foundation/NSError.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSPathUtilities.h>
#import <Foundation/NSThread.h>
#import <Foundation/NSTimer.h>
#import <Foundation/NSAppleEventManager.h>
#import <Foundation/NSURL.h>
#import <AppKit/NSEvent.h>
#import <AppKit/NSNibDeclarations.h>
// 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;
}

View File

@@ -1,8 +1,24 @@
#include "tomahawk/tomahawkapp.h"
#ifdef Q_WS_MAC
#include "tomahawkapp_mac.h"
#include </System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/Headers/AppleEvents.h>
static pascal OSErr appleEventHandler( const AppleEvent*, AppleEvent*, long );
#endif
#include <exception>
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<TomahawkApp*>(qApp)->loadUrl( url );
return noErr;
}
default:
return unimpErr;
}
}
#endif

13
src/shortcuthandler.cpp Normal file
View File

@@ -0,0 +1,13 @@
#include "shortcuthandler.h"
using namespace Tomahawk;
ShortcutHandler::ShortcutHandler( QObject *parent )
: QObject( parent )
{
}
ShortcutHandler::~ShortcutHandler()
{
}

34
src/shortcuthandler.h Normal file
View File

@@ -0,0 +1,34 @@
#ifndef SHORTCUTHANDLER_H
#define SHORTCUTHANDLER_H
#include <QObject>
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

View File

@@ -5,6 +5,8 @@
#include <QMetaType>
#include <QTime>
#include <QNetworkReply>
#include <QFile>
#include <QFileInfo>
#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 <QMessageBox>
#endif
#ifdef Q_WS_MAC
#include "mac/macshortcuthandler.h"
#endif
#include <iostream>
#include <fstream>
#define LOGFILE TomahawkUtils::appDataDir().filePath( "tomahawk.log" ).toLocal8Bit()
#define LOGFILE_SIZE 1024 * 512
#include "tomahawksettings.h"
#include <utils/xspfloader.h>
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<MacShortcutHandler*>( 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<QNetworkProxy::ProxyType>(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 )
{
qDebug() << "MESSAGE RECEIVED" << msg;
if( msg.isEmpty() ) {
return;
}
if( msg.contains( "tomahawk://" ) ) {
QString cmd = msg.mid( 11 );
void
TomahawkApp::activate()
{
#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 );
}

View File

@@ -0,0 +1,25 @@
#import <AppKit/NSApplication.h>
#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 <NSApplicationDelegate> {
#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

View File

@@ -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() ) );
// <SipHandler>
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" ) );
}

View File

@@ -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 )

View File

@@ -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: