1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-17 11:30:49 +02:00

Merge branch 'stable'

Conflicts:
	src/main.cpp
	src/tomahawkapp.cpp
This commit is contained in:
Leo Franchi
2011-04-07 08:57:43 -04:00
8 changed files with 190 additions and 150 deletions

View File

@@ -7,6 +7,10 @@ Version 0.1.0:
music collection. music collection.
Version 0.0.3: Version 0.0.3:
* Show spinner while resolving playlists.
* Go back to previous page visible when deleting a playlist.
* Fixed issue where automatic playlists and station summaries were not
updated in the playlist header.
* Fixed an issue which caused duplicate items when rescanning. * Fixed an issue which caused duplicate items when rescanning.
* Revert change introduced in 0.0.2 causing Twitter protocol to not try * Revert change introduced in 0.0.2 causing Twitter protocol to not try
to reconnect to a peer if it couldn't connect the first time the plugin to reconnect to a peer if it couldn't connect the first time the plugin
@@ -17,9 +21,10 @@ Version 0.0.3:
* Don't automatically try to resolve all incoming playback logs. This * Don't automatically try to resolve all incoming playback logs. This
speeds up importing sources a lot. speeds up importing sources a lot.
* Faster painting of playlists with lots of unresolved tracks. * Faster painting of playlists with lots of unresolved tracks.
* The tomahawk:// protocol handler works on Windows now.
* Fixed launching Tomahawk from Windows installer with admin privileges.
* Prefer local results when results' score is equal. * Prefer local results when results' score is equal.
* (Windows) The tomahawk:// protocol handler works on Windows now.
* (Windows) Fixed launching Tomahawk from Windows installer with admin privileges.
* (Windows) Prevent launching a second instance on Windows.
Version 0.0.2: Version 0.0.2:
* Don't reconnect to Jabber if the settings dialog is closed successfully * Don't reconnect to Jabber if the settings dialog is closed successfully
@@ -35,7 +40,6 @@ Version 0.0.2:
the Tomahawk XMPP presence. the Tomahawk XMPP presence.
* Incompatible change: Twitter SIP protocol has changed slightly. 0.0.1 * Incompatible change: Twitter SIP protocol has changed slightly. 0.0.1
clients will not be able to talk to newer clients. clients will not be able to talk to newer clients.
* Hopefully fixed crashes during Twitter authentication.
* Don't let long playlist or summary names force a large Tomahawk window. * Don't let long playlist or summary names force a large Tomahawk window.
* Tomahawk now asks you to authorize new contacts. * Tomahawk now asks you to authorize new contacts.

View File

@@ -1 +1 @@
100 103

View File

@@ -9,7 +9,7 @@
!define OPTION_SECTION_SC_DESKTOP !define OPTION_SECTION_SC_DESKTOP
!define OPTION_SECTION_SC_QUICK_LAUNCH !define OPTION_SECTION_SC_QUICK_LAUNCH
!define OPTION_FINISHPAGE !define OPTION_FINISHPAGE
;!define OPTION_FINISHPAGE_LAUNCHER !define OPTION_FINISHPAGE_LAUNCHER
!define OPTION_FINISHPAGE_RELEASE_NOTES !define OPTION_FINISHPAGE_RELEASE_NOTES
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -79,6 +79,7 @@ public:
TomahawkApp( int& argc, char *argv[] ); TomahawkApp( int& argc, char *argv[] );
virtual ~TomahawkApp(); virtual ~TomahawkApp();
void init();
static TomahawkApp* instance(); static TomahawkApp* instance();
SipHandler* sipHandler() { return m_sipHandler; } SipHandler* sipHandler() { return m_sipHandler; }
@@ -99,10 +100,10 @@ public:
// because QApplication::arguments() is expensive // because QApplication::arguments() is expensive
bool scrubFriendlyName() const { return m_scrubFriendlyName; } bool scrubFriendlyName() const { return m_scrubFriendlyName; }
public slots: public slots:
void instanceStarted( KDSingleApplicationGuard::Instance ); void instanceStarted( KDSingleApplicationGuard::Instance );
private slots: private slots:
void setupSIP(); void setupSIP();
@@ -126,14 +127,14 @@ private:
XMPPBot* m_xmppBot; XMPPBot* m_xmppBot;
Tomahawk::ShortcutHandler* m_shortcutHandler; Tomahawk::ShortcutHandler* m_shortcutHandler;
bool m_scrubFriendlyName; bool m_scrubFriendlyName;
#ifdef LIBLASTFM_FOUND #ifdef LIBLASTFM_FOUND
Scrobbler* m_scrobbler; Scrobbler* m_scrobbler;
#endif #endif
#ifndef TOMAHAWK_HEADLESS #ifndef TOMAHAWK_HEADLESS
TomahawkWindow* m_mainwindow; TomahawkWindow* m_mainwindow;
#endif #endif
bool m_headless; bool m_headless;

View File

@@ -8,11 +8,11 @@
#define KDSINGLEAPPLICATIONGUARD_MAX_COMMAND_LINE 1024 #define KDSINGLEAPPLICATIONGUARD_MAX_COMMAND_LINE 1024
#endif #endif
KDSingleApplicationGuard::Instance::Instance( const QStringList& args, qint64 p ) KDSingleApplicationGuard::Instance::Instance( const QStringList& args, qint64 p )
: arguments( args ), : arguments( args ),
pid( p ) pid( p )
{ {
} }
@@ -61,31 +61,31 @@ void KDSingleApplicationGuard::timerEvent( QTimerEvent* )
using namespace kdtools; using namespace kdtools;
/*! /*!
\class KDSingleApplicationGuard KDSingleApplicationGuard * \class KDSingleApplicationGuard KDSingleApplicationGuard
\brief A guard to protect an application from having several instances. * \brief A guard to protect an application from having several instances.
*
KDSingleApplicationGuard can be used to make sure only one instance of an * KDSingleApplicationGuard can be used to make sure only one instance of an
application is running at the same time. * application is running at the same time.
*
\note As KDSingleApplicationGuard uses QSharedMemory Qt 4.4 or later is required * \note As KDSingleApplicationGuard uses QSharedMemory Qt 4.4 or later is required
*/ */
/*! /*!
\fn void KDSingleApplicationGuard::instanceStarted() * \fn void KDSingleApplicationGuard::instanceStarted()
This signal is emitted by the primary instance when ever one other * This signal is emitted by the primary instance when ever one other
instance was started. * instance was started.
*/ */
/*! /*!
\fn void KDSingleApplicationGuard::instanceExited() * \fn void KDSingleApplicationGuard::instanceExited()
This signal is emitted by the primary instance when ever one other * This signal is emitted by the primary instance when ever one other
instance was exited. * instance was exited.
*/ */
/*! /*!
\fn void KDSingleApplicationGuard::becamePrimaryInstance() * \fn void KDSingleApplicationGuard::becamePrimaryInstance()
This signal is emitted, when the current running application gets the new * This signal is emitted, when the current running application gets the new
primary application. The old primary application has quit. * primary application. The old primary application has quit.
*/ */
enum Command enum Command
@@ -105,8 +105,8 @@ Q_DECLARE_OPERATORS_FOR_FLAGS( Commands )
struct ProcessInfo struct ProcessInfo
{ {
explicit ProcessInfo( Command c = FreeInstance, const QStringList& arguments = QStringList(), qint64 p = -1 ) explicit ProcessInfo( Command c = FreeInstance, const QStringList& arguments = QStringList(), qint64 p = -1 )
: command( c ), : command( c ),
pid( p ) pid( p )
{ {
std::fill_n( commandline, KDSINGLEAPPLICATIONGUARD_MAX_COMMAND_LINE, '\0' ); std::fill_n( commandline, KDSINGLEAPPLICATIONGUARD_MAX_COMMAND_LINE, '\0' );
@@ -149,7 +149,7 @@ struct ProcessInfo
bool operator==( const ProcessInfo& lhs, const ProcessInfo& rhs ) bool operator==( const ProcessInfo& lhs, const ProcessInfo& rhs )
{ {
return lhs.command == rhs.command && return lhs.command == rhs.command &&
::memcmp( lhs.commandline, rhs.commandline, KDSINGLEAPPLICATIONGUARD_MAX_COMMAND_LINE ) == 0; ::memcmp( lhs.commandline, rhs.commandline, KDSINGLEAPPLICATIONGUARD_MAX_COMMAND_LINE ) == 0;
} }
bool operator!=( const ProcessInfo& lhs, const ProcessInfo& rhs ) bool operator!=( const ProcessInfo& lhs, const ProcessInfo& rhs )
@@ -158,21 +158,21 @@ bool operator!=( const ProcessInfo& lhs, const ProcessInfo& rhs )
} }
/*! /*!
This struct contains information about the managed process system. * This struct contains information about the managed process system.
\internal * \internal
*/ */
struct InstanceRegister struct InstanceRegister
{ {
InstanceRegister( KDSingleApplicationGuard::Policy policy = KDSingleApplicationGuard::NoPolicy ) InstanceRegister( KDSingleApplicationGuard::Policy policy = KDSingleApplicationGuard::NoPolicy )
: policy( policy ) : policy( policy )
{ {
std::fill_n( info, KDSINGLEAPPLICATIONGUARD_NUMBER_OF_PROCESSES, ProcessInfo() ); std::fill_n( info, KDSINGLEAPPLICATIONGUARD_NUMBER_OF_PROCESSES, ProcessInfo() );
::memcpy( magicCookie, "kdsingleapp", 12 ); ::memcpy( magicCookie, "kdsingleapp", 12 );
} }
/*! /*!
Returns wheter this register was properly initialized by the first instance. * Returns wheter this register was properly initialized by the first instance.
*/ */
bool isValid() const bool isValid() const
{ {
return ::strcmp( magicCookie, "kdsingleapp" ) == 0; return ::strcmp( magicCookie, "kdsingleapp" ) == 0;
@@ -192,18 +192,18 @@ bool operator==( const InstanceRegister& lhs, const InstanceRegister& rhs )
if( lhs.info[ i ] != rhs.info[ i ] ) if( lhs.info[ i ] != rhs.info[ i ] )
return false; return false;
return true; return true;
} }
/*! /*!
\internal * \internal
*/ */
class KDSingleApplicationGuard::Private class KDSingleApplicationGuard::Private
{ {
public: public:
Private( KDSingleApplicationGuard* qq ) Private( KDSingleApplicationGuard* qq )
: q( qq ), : q( qq ),
id( -1 ) id( -1 )
{ {
if( primaryInstance == 0 ) if( primaryInstance == 0 )
primaryInstance = q; primaryInstance = q;
@@ -258,28 +258,28 @@ void SIGINT_handler( int sig )
#endif #endif
/*! /*!
Creates a new KDSingleApplicationGuard guarding \a parent from mulitply instances. * Creates a new KDSingleApplicationGuard guarding \a parent from mulitply instances.
If \a policy is AutoKillOtherInstances (the default), all instances, which try to start, * If \a policy is AutoKillOtherInstances (the default), all instances, which try to start,
are killed automatically and instanceStarted() is emitted. * are killed automatically and instanceStarted() is emitted.
If \a policy is NoPolicy, the other instance will run and instanceStarted() is emitted. * If \a policy is NoPolicy, the other instance will run and instanceStarted() is emitted.
*/ */
KDSingleApplicationGuard::KDSingleApplicationGuard( QCoreApplication* parent, Policy policy ) KDSingleApplicationGuard::KDSingleApplicationGuard( QCoreApplication* parent, Policy policy )
: QObject( parent ), : QObject( parent ),
d( new Private( this ) ) d( new Private( this ) )
{ {
const QString name = parent->applicationName(); const QString name = parent->applicationName();
Q_ASSERT_X( !name.isEmpty(), "KDSingleApplicationGuard::KDSingleApplicationGuard", "applicationName must not be emty" ); Q_ASSERT_X( !name.isEmpty(), "KDSingleApplicationGuard::KDSingleApplicationGuard", "applicationName must not be emty" );
d->mem.setKey( name ); d->mem.setKey( name );
// if another instance crashed, the shared memory segment is still there on Unix // if another instance crashed, the shared memory segment is still there on Unix
// the following lines trigger deletion in that case // the following lines trigger deletion in that case
#ifndef Q_WS_WIN #ifndef Q_WS_WIN
d->mem.attach(); d->mem.attach();
d->mem.detach(); d->mem.detach();
#endif #endif
d->policy = policy; d->policy = policy;
const bool created = d->mem.create( sizeof( InstanceRegister ) ); const bool created = d->mem.create( sizeof( InstanceRegister ) );
if( !created ) if( !created )
{ {
@@ -288,7 +288,7 @@ KDSingleApplicationGuard::KDSingleApplicationGuard( QCoreApplication* parent, Po
qWarning( "KDSingleApplicationGuard: Could neither create nor attach to shared memory segment." ); qWarning( "KDSingleApplicationGuard: Could neither create nor attach to shared memory segment." );
return; return;
} }
// lets wait till the other instance initialized the register // lets wait till the other instance initialized the register
bool initialized = false; bool initialized = false;
while( !initialized ) while( !initialized )
@@ -298,52 +298,57 @@ KDSingleApplicationGuard::KDSingleApplicationGuard( QCoreApplication* parent, Po
} }
} }
bool killMyself = false;
KDLockedSharedMemoryPointer< InstanceRegister > instances( &d->mem );
if( !created )
{ {
// we're _not_ the first instance KDLockedSharedMemoryPointer< InstanceRegister > instances( &d->mem );
// but the
bool killOurSelf = false;
// find a new slot...
d->id = std::find( instances->info, instances->info + KDSINGLEAPPLICATIONGUARD_NUMBER_OF_PROCESSES, ProcessInfo() ) - instances->info;
ProcessInfo& info = instances->info[ d->id ];
info = ProcessInfo( NewInstance, parent->arguments(), QCoreApplication::applicationPid() );
killOurSelf = instances->policy == AutoKillOtherInstances;
d->policy = instances->policy;
// but the signal that we tried to start was sent to the primary application if( !created )
if( killOurSelf )
{ {
info.command |= ExitedInstance; // we're _not_ the first instance
exit( 1 ); // but the
bool killOurSelf = false;
// find a new slot...
d->id = std::find( instances->info, instances->info + KDSINGLEAPPLICATIONGUARD_NUMBER_OF_PROCESSES, ProcessInfo() ) - instances->info;
ProcessInfo& info = instances->info[ d->id ];
info = ProcessInfo( NewInstance, parent->arguments(), QCoreApplication::applicationPid() );
killOurSelf = instances->policy == AutoKillOtherInstances;
d->policy = instances->policy;
// but the signal that we tried to start was sent to the primary application
if( killOurSelf )
{
info.command |= ExitedInstance;
killMyself = true;
}
}
else
{
// ok.... we are the first instance
InstanceRegister reg( policy ); // create a new list
d->id = 0; // our id = 0
// and we've no command
reg.info[ 0 ] = ProcessInfo( NoCommand, parent->arguments(), QCoreApplication::applicationPid() );
*instances = reg; // push this is the process list into shared memory
} }
} }
else // call exit after we let the locker release our memory, as exit() is not guaranteed to clean up objects on the stack
{ if ( killMyself )
// ok.... we are the first instance exit( 1 );
InstanceRegister reg( policy ); // create a new list
d->id = 0; // our id = 0
// and we've no command
reg.info[ 0 ] = ProcessInfo( NoCommand, parent->arguments(), QCoreApplication::applicationPid() );
*instances = reg; // push this is the process list into shared memory
}
#ifndef Q_WS_WIN #ifndef Q_WS_WIN
::signal( SIGINT, SIGINT_handler ); ::signal( SIGINT, SIGINT_handler );
#endif #endif
// now listen for commands // now listen for commands
startTimer( 250 ); startTimer( 250 );
} }
/*! /*!
Destroys this SingleApplicationGuard. * Destroys this SingleApplicationGuard.
If this instance has been the primary instance and no other instance is existing anymore, * If this instance has been the primary instance and no other instance is existing anymore,
the application is shut down completely. Otherwise the destructor selects another instance to * the application is shut down completely. Otherwise the destructor selects another instance to
be the primary instances. * be the primary instances.
*/ */
KDSingleApplicationGuard::~KDSingleApplicationGuard() KDSingleApplicationGuard::~KDSingleApplicationGuard()
{ {
@@ -352,16 +357,16 @@ KDSingleApplicationGuard::~KDSingleApplicationGuard()
d->shutdownInstance(); d->shutdownInstance();
} }
/*!
\property KDSingleApplicationGuard::primaryInstance
Determines wheter this instance is the primary instance.
The primary instance is the first instance which was started or an instance which
got selected by KDSingleApplicationGuard's destructor, when the primary instance was
shut down.
Get this property's value using %isPrimaryInstance(), and monitor changes to it /*!
using becamePrimaryInstance(). * \property KDSingleApplicationGuard::primaryInstance
* Determines wheter this instance is the primary instance.
* The primary instance is the first instance which was started or an instance which
* got selected by KDSingleApplicationGuard's destructor, when the primary instance was
* shut down.
*
* Get this property's value using %isPrimaryInstance(), and monitor changes to it
* using becamePrimaryInstance().
*/ */
bool KDSingleApplicationGuard::isPrimaryInstance() const bool KDSingleApplicationGuard::isPrimaryInstance() const
{ {
@@ -369,12 +374,12 @@ bool KDSingleApplicationGuard::isPrimaryInstance() const
} }
/*! /*!
\property KDSingleApplicationGuard::Policy * \property KDSingleApplicationGuard::Policy
Specifies the policy KDSingleApplicationGuard is using when new instances are started. * Specifies the policy KDSingleApplicationGuard is using when new instances are started.
This can only be set in the primary instance. * This can only be set in the primary instance.
*
Get this property's value using %policy(), set it using %setPolicy(), and monitor changes * Get this property's value using %policy(), set it using %setPolicy(), and monitor changes
to it using policyChanged(). * to it using policyChanged().
*/ */
KDSingleApplicationGuard::Policy KDSingleApplicationGuard::policy() const KDSingleApplicationGuard::Policy KDSingleApplicationGuard::policy() const
{ {
@@ -394,7 +399,7 @@ void KDSingleApplicationGuard::setPolicy( Policy policy )
} }
/*! /*!
Returns a list of all currently running instances. * Returns a list of all currently running instances.
*/ */
QList< KDSingleApplicationGuard::Instance > KDSingleApplicationGuard::instances() const QList< KDSingleApplicationGuard::Instance > KDSingleApplicationGuard::instances() const
{ {
@@ -409,10 +414,10 @@ QList< KDSingleApplicationGuard::Instance > KDSingleApplicationGuard::instances(
return result; return result;
} }
/*! /*!
Shuts down all other instances. This can only be called from the * Shuts down all other instances. This can only be called from the
the primary instance. * the primary instance.
Shut down is done gracefully via QCoreApplication::quit(). * Shut down is done gracefully via QCoreApplication::quit().
*/ */
void KDSingleApplicationGuard::shutdownOtherInstances() void KDSingleApplicationGuard::shutdownOtherInstances()
{ {
@@ -426,9 +431,9 @@ void KDSingleApplicationGuard::shutdownOtherInstances()
} }
/*! /*!
Kills all other instances. This can only be called from the * Kills all other instances. This can only be called from the
the primary instance. * the primary instance.
Killing is done via exit(1) * Killing is done via exit(1)
*/ */
void KDSingleApplicationGuard::killOtherInstances() void KDSingleApplicationGuard::killOtherInstances()
{ {
@@ -442,7 +447,7 @@ void KDSingleApplicationGuard::killOtherInstances()
} }
/*! /*!
\reimp * \reimp
*/ */
void KDSingleApplicationGuard::timerEvent( QTimerEvent* event ) void KDSingleApplicationGuard::timerEvent( QTimerEvent* event )
{ {
@@ -456,11 +461,11 @@ void KDSingleApplicationGuard::timerEvent( QTimerEvent* event )
{ {
KDLockedSharedMemoryPointer< InstanceRegister > instances( &d->mem ); KDLockedSharedMemoryPointer< InstanceRegister > instances( &d->mem );
for( int i = 1; i < KDSINGLEAPPLICATIONGUARD_NUMBER_OF_PROCESSES; ++i ) for( int i = 1; i < KDSINGLEAPPLICATIONGUARD_NUMBER_OF_PROCESSES; ++i )
{ {
ProcessInfo& info = instances->info[ i ]; ProcessInfo& info = instances->info[ i ];
if( info.command & NewInstance ) if( info.command & NewInstance )
{ {
startedInstances.push_back( Instance( info.arguments(), info.pid ) ); startedInstances.push_back( Instance( info.arguments(), info.pid ) );
info.command &= ~NewInstance; // clear NewInstance flag info.command &= ~NewInstance; // clear NewInstance flag
@@ -472,7 +477,7 @@ void KDSingleApplicationGuard::timerEvent( QTimerEvent* event )
} }
} }
} }
// one signal for every new instance - _after_ the memory segment was unlocked again // one signal for every new instance - _after_ the memory segment was unlocked again
for( QList< Instance >::const_iterator it = startedInstances.begin(); it != startedInstances.end(); ++it ) for( QList< Instance >::const_iterator it = startedInstances.begin(); it != startedInstances.end(); ++it )
emit instanceStarted( *it ); emit instanceStarted( *it );
@@ -495,7 +500,7 @@ void KDSingleApplicationGuard::timerEvent( QTimerEvent* event )
if( instances->info[ d->id ].command & BecomePrimaryCommand ) if( instances->info[ d->id ].command & BecomePrimaryCommand )
{ {
// we became primary! // we became primary!
instances->info[ 0 ] = instances->info[ d->id ]; instances->info[ 0 ] = instances->info[ d->id ];
instances->info[ d->id ] = ProcessInfo(); // change our id to 0 and declare the old slot as free instances->info[ d->id ] = ProcessInfo(); // change our id to 0 and declare the old slot as free
d->id = 0; d->id = 0;
emit becamePrimaryInstance(); emit becamePrimaryInstance();
@@ -510,7 +515,7 @@ void KDSingleApplicationGuard::timerEvent( QTimerEvent* event )
d->id = -1; // becauso our d'tor won't be called anymore d->id = -1; // becauso our d'tor won't be called anymore
} }
} }
if( killOurSelf ) // kill our self takes precedence if( killOurSelf ) // kill our self takes precedence
exit( 1 ); exit( 1 );
else if( shutDownOurSelf ) else if( shutDownOurSelf )
@@ -590,14 +595,14 @@ KDAB_UNITTEST_SIMPLE( KDSingleApplicationGuard, "kdcoretools" ) {
spy3 = new QSignalSpy( guard3, SIGNAL( becamePrimaryInstance() ) ); spy3 = new QSignalSpy( guard3, SIGNAL( becamePrimaryInstance() ) );
assertFalse( guard3->isPrimaryInstance() ); assertFalse( guard3->isPrimaryInstance() );
} }
wait( 1000 ); wait( 1000 );
assertEqual( spy3->count(), 1 ); assertEqual( spy3->count(), 1 );
assertEqual( guard3->instances().count(), 1 ); assertEqual( guard3->instances().count(), 1 );
assertTrue( guard3->isPrimaryInstance() ); assertTrue( guard3->isPrimaryInstance() );
assertEqual( guard3->instances().first().arguments, qApp->arguments() ); assertEqual( guard3->instances().first().arguments, qApp->arguments() );
QSignalSpy spyStarted( guard3, SIGNAL( instanceStarted( KDSingleApplicationGuard::Instance ) ) ); QSignalSpy spyStarted( guard3, SIGNAL( instanceStarted( KDSingleApplicationGuard::Instance ) ) );
QSignalSpy spyExited( guard3, SIGNAL( instanceExited( KDSingleApplicationGuard::Instance ) ) ); QSignalSpy spyExited( guard3, SIGNAL( instanceExited( KDSingleApplicationGuard::Instance ) ) );
@@ -609,13 +614,13 @@ KDAB_UNITTEST_SIMPLE( KDSingleApplicationGuard, "kdcoretools" ) {
assertEqual( spyStarted.count(), 2 ); assertEqual( spyStarted.count(), 2 );
} }
wait( 1000 ); wait( 1000 );
assertEqual( spyExited.count(), 2 ); assertEqual( spyExited.count(), 2 );
delete spy3; delete spy3;
delete guard3; delete guard3;
} }
#endif // KDTOOLSCORE_UNITTESTS #endif // KDTOOLSCORE_UNITTESTS

View File

@@ -110,7 +110,7 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn
connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) ); connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
if( !entry->query()->resolvingFinished() && entry->query()->playable() ) { if( !entry->query()->resolvingFinished() && !entry->query()->playable() ) {
m_waitingForResolved.append( entry->query().data() ); m_waitingForResolved.append( entry->query().data() );
connect( entry->query().data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( trackResolved( bool ) ) ); connect( entry->query().data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( trackResolved( bool ) ) );
} }

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -19,6 +19,7 @@
#include "tomahawk/tomahawkapp.h" #include "tomahawk/tomahawkapp.h"
#include "kdsingleapplicationguard/kdsingleapplicationguard.h" #include "kdsingleapplicationguard/kdsingleapplicationguard.h"
#include <QTranslator> #include <QTranslator>
#ifdef Q_WS_MAC #ifdef Q_WS_MAC
@@ -45,11 +46,15 @@ main( int argc, char *argv[] )
KDSingleApplicationGuard guard( &a, KDSingleApplicationGuard::AutoKillOtherInstances ); KDSingleApplicationGuard guard( &a, KDSingleApplicationGuard::AutoKillOtherInstances );
QObject::connect( &guard, SIGNAL( instanceStarted( KDSingleApplicationGuard::Instance ) ), &a, SLOT( instanceStarted( KDSingleApplicationGuard::Instance ) ) ); QObject::connect( &guard, SIGNAL( instanceStarted( KDSingleApplicationGuard::Instance ) ), &a, SLOT( instanceStarted( KDSingleApplicationGuard::Instance ) ) );
if ( guard.isPrimaryInstance() )
a.init();
QString locale = QLocale::system().name(); QString locale = QLocale::system().name();
QTranslator translator; QTranslator translator;
translator.load( QString( ":/lang/tomahawk_" ) + locale ); translator.load( QString( ":/lang/tomahawk_" ) + locale );
a.installTranslator( &translator ); a.installTranslator( &translator );
return a.exec(); return a.exec();
} }

View File

@@ -154,29 +154,54 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
, m_mainwindow( 0 ) , m_mainwindow( 0 )
, m_infoSystem( 0 ) , m_infoSystem( 0 )
{ {
qsrand( QTime( 0, 0, 0 ).secsTo( QTime::currentTime() ) );
#ifdef TOMAHAWK_HEADLESS
m_headless = true;
#else
m_mainwindow = 0;
m_headless = arguments().contains( "--headless" );
setWindowIcon( QIcon( RESPATH "icons/tomahawk-icon-128x128.png" ) );
#endif
qDebug() << "TomahawkApp thread:" << this->thread(); qDebug() << "TomahawkApp thread:" << this->thread();
setOrganizationName( QLatin1String( ORGANIZATION_NAME ) ); setOrganizationName( QLatin1String( ORGANIZATION_NAME ) );
setOrganizationDomain( QLatin1String( ORGANIZATION_DOMAIN ) ); setOrganizationDomain( QLatin1String( ORGANIZATION_DOMAIN ) );
setApplicationName( QLatin1String( APPLICATION_NAME ) ); setApplicationName( QLatin1String( APPLICATION_NAME ) );
setApplicationVersion( QLatin1String( VERSION ) ); setApplicationVersion( QLatin1String( VERSION ) );
setupLogfile();
}
TomahawkApp::~TomahawkApp()
{
qDebug() << Q_FUNC_INFO;
delete m_sipHandler;
delete m_servent;
#ifndef TOMAHAWK_HEADLESS
delete m_mainwindow;
delete m_audioEngine;
#endif
delete m_database;
}
void
TomahawkApp::init()
{
qsrand( QTime( 0, 0, 0 ).secsTo( QTime::currentTime() ) );
#ifdef TOMAHAWK_HEADLESS
m_headless = true;
#else
m_mainwindow = 0;
m_headless = arguments().contains( "--headless" );
setWindowIcon( QIcon( RESPATH "icons/tomahawk-icon-128x128.png" ) );
#endif
registerMetaTypes(); registerMetaTypes();
setupLogfile(); setupLogfile();
Echonest::Config::instance()->setAPIKey( "JRIHWEP6GPOER2QQ6" );
new TomahawkSettings( this ); new TomahawkSettings( this );
m_audioEngine = new AudioEngine; m_audioEngine = new AudioEngine;
m_scanManager = new ScanManager( this ); m_scanManager = new ScanManager( this );
new Pipeline( this ); new Pipeline( this );
m_servent = new Servent( this ); m_servent = new Servent( this );
connect( m_servent, SIGNAL( ready() ), SLOT( setupSIP() ) ); connect( m_servent, SIGNAL( ready() ), SLOT( setupSIP() ) );
@@ -185,15 +210,15 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
qDebug() << "Init Echonest Factory."; qDebug() << "Init Echonest Factory.";
GeneratorFactory::registerFactory( "echonest", new EchonestFactory ); GeneratorFactory::registerFactory( "echonest", new EchonestFactory );
m_scrubFriendlyName = arguments().contains( "--demo" ); m_scrubFriendlyName = arguments().contains( "--demo" );
// Register shortcut handler for this platform // Register shortcut handler for this platform
#ifdef Q_WS_MAC #ifdef Q_WS_MAC
m_shortcutHandler = new MacShortcutHandler( this ); m_shortcutHandler = new MacShortcutHandler( this );
Tomahawk::setShortcutHandler( static_cast<MacShortcutHandler*>( m_shortcutHandler) ); Tomahawk::setShortcutHandler( static_cast<MacShortcutHandler*>( m_shortcutHandler) );
Tomahawk::setApplicationHandler( this ); Tomahawk::setApplicationHandler( this );
#endif #endif
// Connect up shortcuts // Connect up shortcuts
if ( m_shortcutHandler ) if ( m_shortcutHandler )
@@ -228,10 +253,10 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
connect( m_audioEngine, SIGNAL( stopped() ), connect( m_audioEngine, SIGNAL( stopped() ),
m_scrobbler, SLOT( trackStopped() ), Qt::QueuedConnection ); m_scrobbler, SLOT( trackStopped() ), Qt::QueuedConnection );
#else #else
qDebug() << "Setting NAM."; qDebug() << "Setting NAM.";
TomahawkUtils::setNam( new QNetworkAccessManager ); TomahawkUtils::setNam( new QNetworkAccessManager );
#endif #endif
// Set up proxy // Set up proxy
//FIXME: This overrides the lastfm proxy above? //FIXME: This overrides the lastfm proxy above?
@@ -248,10 +273,10 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
else else
TomahawkUtils::setProxy( new QNetworkProxy( QNetworkProxy::NoProxy ) ); TomahawkUtils::setProxy( new QNetworkProxy( QNetworkProxy::NoProxy ) );
Echonest::Config::instance()->setAPIKey( "JRIHWEP6GPOER2QQ6" ); Echonest::Config::instance()->setAPIKey( "JRIHWEP6GPOER2QQ6" );
Echonest::Config::instance()->setNetworkAccessManager( TomahawkUtils::nam() ); Echonest::Config::instance()->setNetworkAccessManager( TomahawkUtils::nam() );
QNetworkProxy::setApplicationProxy( *TomahawkUtils::proxy() ); QNetworkProxy::setApplicationProxy( *TomahawkUtils::proxy() );
qDebug() << "Init SIP system."; qDebug() << "Init SIP system.";
@@ -265,7 +290,7 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
m_mainwindow->setWindowTitle( "Tomahawk" ); m_mainwindow->setWindowTitle( "Tomahawk" );
m_mainwindow->show(); m_mainwindow->show();
} }
#endif #endif
qDebug() << "Init Local Collection."; qDebug() << "Init Local Collection.";
initLocalCollection(); initLocalCollection();
@@ -339,7 +364,7 @@ TomahawkApp::registerMetaTypes()
qRegisterMetaType< QMap<QString, unsigned int> >("QMap<QString, unsigned int>"); qRegisterMetaType< QMap<QString, unsigned int> >("QMap<QString, unsigned int>");
qRegisterMetaType< QMap< QString, plentry_ptr > >("QMap< QString, plentry_ptr >"); qRegisterMetaType< QMap< QString, plentry_ptr > >("QMap< QString, plentry_ptr >");
qRegisterMetaType< QHash< QString, QMap<quint32, quint16> > >("QHash< QString, QMap<quint32, quint16> >"); qRegisterMetaType< QHash< QString, QMap<quint32, quint16> > >("QHash< QString, QMap<quint32, quint16> >");
qRegisterMetaType< GeneratorMode>("GeneratorMode"); qRegisterMetaType< GeneratorMode>("GeneratorMode");
qRegisterMetaType<Tomahawk::GeneratorMode>("Tomahawk::GeneratorMode"); qRegisterMetaType<Tomahawk::GeneratorMode>("Tomahawk::GeneratorMode");
// Extra definition for namespaced-versions of signals/slots required // Extra definition for namespaced-versions of signals/slots required
@@ -532,16 +557,16 @@ TomahawkApp::loadUrl( const QString& url )
} }
void void
TomahawkApp::instanceStarted( KDSingleApplicationGuard::Instance instance ) TomahawkApp::instanceStarted( KDSingleApplicationGuard::Instance instance )
{ {
qDebug() << "INSTANCE STARTED!" << instance.pid << instance.arguments; qDebug() << "INSTANCE STARTED!" << instance.pid << instance.arguments;
if( instance.arguments.size() < 2 ) if( instance.arguments.size() < 2 )
{ {
return; return;
} }
loadUrl( instance.arguments.at( 1 ) ); loadUrl( instance.arguments.at( 1 ) );
} }