1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-17 19:37:09 +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.
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.
* 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
@@ -17,9 +21,10 @@ Version 0.0.3:
* Don't automatically try to resolve all incoming playback logs. This
speeds up importing sources a lot.
* 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.
* (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:
* Don't reconnect to Jabber if the settings dialog is closed successfully
@@ -35,7 +40,6 @@ Version 0.0.2:
the Tomahawk XMPP presence.
* Incompatible change: Twitter SIP protocol has changed slightly. 0.0.1
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.
* 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_QUICK_LAUNCH
!define OPTION_FINISHPAGE
;!define OPTION_FINISHPAGE_LAUNCHER
!define OPTION_FINISHPAGE_LAUNCHER
!define OPTION_FINISHPAGE_RELEASE_NOTES
;-----------------------------------------------------------------------------

View File

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

View File

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

View File

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

View File

@@ -154,29 +154,54 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
, m_mainwindow( 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();
setOrganizationName( QLatin1String( ORGANIZATION_NAME ) );
setOrganizationDomain( QLatin1String( ORGANIZATION_DOMAIN ) );
setApplicationName( QLatin1String( APPLICATION_NAME ) );
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();
setupLogfile();
Echonest::Config::instance()->setAPIKey( "JRIHWEP6GPOER2QQ6" );
new TomahawkSettings( this );
m_audioEngine = new AudioEngine;
m_scanManager = new ScanManager( this );
new Pipeline( this );
m_servent = new Servent( this );
connect( m_servent, SIGNAL( ready() ), SLOT( setupSIP() ) );
@@ -185,15 +210,15 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
qDebug() << "Init Echonest Factory.";
GeneratorFactory::registerFactory( "echonest", new EchonestFactory );
m_scrubFriendlyName = arguments().contains( "--demo" );
// Register shortcut handler for this platform
#ifdef Q_WS_MAC
#ifdef Q_WS_MAC
m_shortcutHandler = new MacShortcutHandler( this );
Tomahawk::setShortcutHandler( static_cast<MacShortcutHandler*>( m_shortcutHandler) );
Tomahawk::setApplicationHandler( this );
#endif
#endif
// Connect up shortcuts
if ( m_shortcutHandler )
@@ -228,10 +253,10 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
connect( m_audioEngine, SIGNAL( stopped() ),
m_scrobbler, SLOT( trackStopped() ), Qt::QueuedConnection );
#else
#else
qDebug() << "Setting NAM.";
TomahawkUtils::setNam( new QNetworkAccessManager );
#endif
#endif
// Set up proxy
//FIXME: This overrides the lastfm proxy above?
@@ -248,10 +273,10 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
else
TomahawkUtils::setProxy( new QNetworkProxy( QNetworkProxy::NoProxy ) );
Echonest::Config::instance()->setAPIKey( "JRIHWEP6GPOER2QQ6" );
Echonest::Config::instance()->setNetworkAccessManager( TomahawkUtils::nam() );
QNetworkProxy::setApplicationProxy( *TomahawkUtils::proxy() );
qDebug() << "Init SIP system.";
@@ -265,7 +290,7 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
m_mainwindow->setWindowTitle( "Tomahawk" );
m_mainwindow->show();
}
#endif
#endif
qDebug() << "Init Local Collection.";
initLocalCollection();
@@ -339,7 +364,7 @@ TomahawkApp::registerMetaTypes()
qRegisterMetaType< QMap<QString, unsigned int> >("QMap<QString, unsigned int>");
qRegisterMetaType< QMap< QString, plentry_ptr > >("QMap< QString, plentry_ptr >");
qRegisterMetaType< QHash< QString, QMap<quint32, quint16> > >("QHash< QString, QMap<quint32, quint16> >");
qRegisterMetaType< GeneratorMode>("GeneratorMode");
qRegisterMetaType<Tomahawk::GeneratorMode>("Tomahawk::GeneratorMode");
// 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 )
{
qDebug() << "INSTANCE STARTED!" << instance.pid << instance.arguments;
if( instance.arguments.size() < 2 )
if( instance.arguments.size() < 2 )
{
return;
}
loadUrl( instance.arguments.at( 1 ) );
}