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

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

View File

@@ -11,8 +11,8 @@
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
@@ -158,8 +158,8 @@ 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
{ {
@@ -171,7 +171,7 @@ struct InstanceRegister
} }
/*! /*!
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
{ {
@@ -196,7 +196,7 @@ bool operator==( const InstanceRegister& lhs, const InstanceRegister& rhs )
} }
/*! /*!
\internal * \internal
*/ */
class KDSingleApplicationGuard::Private class KDSingleApplicationGuard::Private
{ {
@@ -258,14 +258,14 @@ 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" );
@@ -273,10 +273,10 @@ KDSingleApplicationGuard::KDSingleApplicationGuard( QCoreApplication* parent, Po
// 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;
@@ -298,7 +298,8 @@ KDSingleApplicationGuard::KDSingleApplicationGuard( QCoreApplication* parent, Po
} }
} }
bool killMyself = false;
{
KDLockedSharedMemoryPointer< InstanceRegister > instances( &d->mem ); KDLockedSharedMemoryPointer< InstanceRegister > instances( &d->mem );
if( !created ) if( !created )
@@ -318,7 +319,7 @@ KDSingleApplicationGuard::KDSingleApplicationGuard( QCoreApplication* parent, Po
if( killOurSelf ) if( killOurSelf )
{ {
info.command |= ExitedInstance; info.command |= ExitedInstance;
exit( 1 ); killMyself = true;
} }
} }
else else
@@ -330,20 +331,24 @@ KDSingleApplicationGuard::KDSingleApplicationGuard( QCoreApplication* parent, Po
reg.info[ 0 ] = ProcessInfo( NoCommand, parent->arguments(), QCoreApplication::applicationPid() ); reg.info[ 0 ] = ProcessInfo( NoCommand, parent->arguments(), QCoreApplication::applicationPid() );
*instances = reg; // push this is the process list into shared memory *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 #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()
{ {
@@ -354,14 +359,14 @@ KDSingleApplicationGuard::~KDSingleApplicationGuard()
} }
/*! /*!
\property KDSingleApplicationGuard::primaryInstance * \property KDSingleApplicationGuard::primaryInstance
Determines wheter this instance is the primary instance. * Determines wheter this instance is the primary instance.
The primary instance is the first instance which was started or an instance which * 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 * got selected by KDSingleApplicationGuard's destructor, when the primary instance was
shut down. * shut down.
*
Get this property's value using %isPrimaryInstance(), and monitor changes to it * Get this property's value using %isPrimaryInstance(), and monitor changes to it
using becamePrimaryInstance(). * 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
{ {
@@ -410,9 +415,9 @@ QList< KDSingleApplicationGuard::Instance > KDSingleApplicationGuard::instances(
} }
/*! /*!
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 )
{ {
@@ -615,7 +620,7 @@ KDAB_UNITTEST_SIMPLE( KDSingleApplicationGuard, "kdcoretools" ) {
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

@@ -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,24 +154,49 @@ 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 );
@@ -188,12 +213,12 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
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?
@@ -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();