mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-30 17:20:26 +02:00
Merge branch 'master' of github.com:tomahawk-player/tomahawk
This commit is contained in:
@@ -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)
|
||||
|
@@ -28,6 +28,7 @@ SET( TOMAHAWK_INC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../include/" )
|
||||
|
||||
SET( tomahawkSources ${tomahawkSources}
|
||||
sip/SipHandler.cpp
|
||||
sip/twitter/tomahawkoauthtwitter.cpp
|
||||
|
||||
infosystem/infosystem.cpp
|
||||
infosystem/infoplugins/echonestplugin.cpp
|
||||
@@ -39,6 +40,7 @@ SET( tomahawkSources ${tomahawkSources}
|
||||
musicscanner.cpp
|
||||
scriptresolver.cpp
|
||||
scrobbler.cpp
|
||||
shortcuthandler.cpp
|
||||
|
||||
tomahawkapp.cpp
|
||||
main.cpp
|
||||
@@ -57,11 +59,18 @@ 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"
|
||||
|
||||
sip/SipHandler.h
|
||||
sip/twitter/tomahawkoauthtwitter.h
|
||||
|
||||
infosystem/infoplugins/echonestplugin.h
|
||||
infosystem/infoplugins/musixmatchplugin.h
|
||||
@@ -72,6 +81,7 @@ SET( tomahawkHeaders ${tomahawkHeaders}
|
||||
musicscanner.h
|
||||
scriptresolver.h
|
||||
scrobbler.h
|
||||
shortcuthandler.h
|
||||
)
|
||||
|
||||
SET( tomahawkHeadersGui ${tomahawkHeadersGui}
|
||||
@@ -109,10 +119,12 @@ INCLUDE_DIRECTORIES(
|
||||
topbar
|
||||
utils
|
||||
libtomahawk
|
||||
mac
|
||||
|
||||
../alsa-playback
|
||||
../rtaudio
|
||||
../qxt/qxtweb-standalone/qxtweb
|
||||
../thirdparty/qtweetlib/qtweetlib/src
|
||||
|
||||
/usr/include/taglib
|
||||
/usr/local/include/taglib
|
||||
@@ -132,12 +144,16 @@ IF( UNIX )
|
||||
ENDIF( UNIX )
|
||||
|
||||
ADD_SUBDIRECTORY( sip/jabber )
|
||||
ADD_SUBDIRECTORY( sip/twitter )
|
||||
ADD_SUBDIRECTORY( sip/zeroconf )
|
||||
|
||||
kde4_add_app_icon( tomahawkSources "${CMAKE_CURRENT_SOURCE_DIR}/../data/icons/tomahawk-icon-*.png" )
|
||||
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" )
|
||||
@@ -152,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} )
|
||||
@@ -167,6 +185,7 @@ TARGET_LINK_LIBRARIES( tomahawk
|
||||
|
||||
qjson
|
||||
tag
|
||||
tomahawk_qtweetlib
|
||||
)
|
||||
|
||||
INCLUDE( "CPack.txt" )
|
||||
|
10
src/config.h.in
Normal file
10
src/config.h.in
Normal 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
|
@@ -308,6 +308,7 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ..
|
||||
../../thirdparty/jdns
|
||||
../../thirdparty/jdns/jdns
|
||||
../../thirdparty/jdns/jdnsshared
|
||||
../../thirdparty/qtweetlib/qtweetlib/src
|
||||
playlist
|
||||
)
|
||||
|
||||
@@ -371,6 +372,7 @@ target_link_libraries( tomahawklib
|
||||
vorbisfile
|
||||
ogg
|
||||
FLAC++
|
||||
tomahawk_qtweetlib
|
||||
${CLUCENE_LIBRARY}
|
||||
)
|
||||
|
||||
|
@@ -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()
|
||||
|
@@ -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; }
|
||||
|
@@ -46,6 +46,11 @@ FuzzyIndex::beginIndexing()
|
||||
{
|
||||
m_mutex.lock();
|
||||
|
||||
delete m_luceneSearcher;
|
||||
delete m_luceneReader;
|
||||
m_luceneSearcher = 0;
|
||||
m_luceneReader = 0;
|
||||
|
||||
try
|
||||
{
|
||||
IndexWriter luceneWriter = IndexWriter( m_luceneDir, m_analyzer, true );
|
||||
@@ -71,11 +76,6 @@ FuzzyIndex::appendFields( const QString& table, const QMap< unsigned int, QStrin
|
||||
{
|
||||
try
|
||||
{
|
||||
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;
|
||||
|
@@ -123,15 +123,20 @@ Servent::startListening( QHostAddress ha, bool upnp, int port )
|
||||
|
||||
|
||||
QString
|
||||
Servent::createConnectionKey( const QString& name )
|
||||
Servent::createConnectionKey( const QString& name, const QString &nodeid, const QString &key, bool onceOnly )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
Q_ASSERT( this->thread() == QThread::currentThread() );
|
||||
|
||||
QString key = uuid();
|
||||
QString _key = ( key.isEmpty() ? uuid() : key );
|
||||
ControlConnection* cc = new ControlConnection( this );
|
||||
cc->setName( name.isEmpty() ? QString( "KEY(%1)" ).arg( key ) : name );
|
||||
registerOffer( key, cc );
|
||||
return key;
|
||||
if( !nodeid.isEmpty() )
|
||||
cc->setId( nodeid );
|
||||
cc->setOnceOnly( onceOnly );
|
||||
qDebug() << "Creating connection key with name of " << cc->name() << " and id of " << cc->id() << " and key of " << _key << "; key is once only? : " << (onceOnly ? "true" : "false");
|
||||
registerOffer( _key, cc );
|
||||
return _key;
|
||||
}
|
||||
|
||||
|
||||
@@ -141,9 +146,18 @@ Servent::setExternalAddress( QHostAddress ha, unsigned int port )
|
||||
m_externalAddress = ha;
|
||||
m_externalPort = port;
|
||||
|
||||
if( m_externalPort == 0 )
|
||||
if( m_externalPort == 0 || m_externalAddress.toString().isEmpty() )
|
||||
{
|
||||
qDebug() << "No external access, LAN and outbound connections only!";
|
||||
if( !TomahawkSettings::instance()->externalHostname().isEmpty() &&
|
||||
!TomahawkSettings::instance()->externalPort() == 0 )
|
||||
{
|
||||
qDebug() << "UPnP failed, have external address/port -- falling back";
|
||||
m_externalHostname = TomahawkSettings::instance()->externalHostname();
|
||||
m_externalPort = TomahawkSettings::instance()->externalPort();
|
||||
qDebug() << m_externalHostname << m_externalPort;
|
||||
}
|
||||
else
|
||||
qDebug() << "No external access, LAN and outbound connections only!";
|
||||
}
|
||||
|
||||
emit ready();
|
||||
@@ -260,7 +274,7 @@ Servent::readyRead()
|
||||
|
||||
qDebug() << m;
|
||||
|
||||
if( !nodeid.isEmpty() && cc != 0 ) // only control connections send nodeid
|
||||
if( !nodeid.isEmpty() ) // only control connections send nodeid
|
||||
{
|
||||
foreach( ControlConnection* con, m_controlconnections )
|
||||
{
|
||||
|
@@ -78,7 +78,7 @@ public:
|
||||
int port() const { return m_port; }
|
||||
|
||||
// creates new token that allows a controlconnection to be set up
|
||||
QString createConnectionKey( const QString& name = "" );
|
||||
QString createConnectionKey( const QString& name = "", const QString &nodeid = "", const QString &key = "", bool onceOnly = true );
|
||||
|
||||
void registerOffer( const QString& key, Connection* conn );
|
||||
|
||||
|
@@ -14,10 +14,13 @@ public:
|
||||
enum SipErrorCode { AuthError, ConnectionError }; // Placeholder for errors, to be defined
|
||||
|
||||
virtual ~SipPlugin() {}
|
||||
|
||||
virtual bool isValid() = 0;
|
||||
virtual const QString name() = 0;
|
||||
|
||||
public slots:
|
||||
virtual bool connect( bool startup = false ) = 0;
|
||||
virtual void disconnect() = 0;
|
||||
virtual bool connectPlugin( bool startup = false ) = 0;
|
||||
virtual void disconnectPlugin() = 0;
|
||||
|
||||
virtual void addContact( const QString &jid, const QString& msg = QString() ) = 0;
|
||||
virtual void sendMsg( const QString& to, const QString& msg ) = 0;
|
||||
|
@@ -327,13 +327,16 @@ TomahawkSettings::setExternalHostname(const QString& externalHostname)
|
||||
int
|
||||
TomahawkSettings::externalPort() const
|
||||
{
|
||||
return value( "network/external-port" ).toInt();
|
||||
return value( "network/external-port", 50210 ).toInt();
|
||||
}
|
||||
|
||||
void
|
||||
TomahawkSettings::setExternalPort(int externalPort)
|
||||
{
|
||||
setValue( "network/external-port", externalPort);
|
||||
if ( externalPort == 0 )
|
||||
setValue( "network/external-port", 50210);
|
||||
else
|
||||
setValue( "network/external-port", externalPort);
|
||||
}
|
||||
|
||||
|
||||
@@ -378,6 +381,89 @@ TomahawkSettings::setLastFmUsername( const QString& username )
|
||||
setValue( "lastfm/username", username );
|
||||
}
|
||||
|
||||
QString
|
||||
TomahawkSettings::twitterScreenName() const
|
||||
{
|
||||
return value( "twitter/ScreenName" ).toString();
|
||||
}
|
||||
|
||||
void
|
||||
TomahawkSettings::setTwitterScreenName( const QString& screenName )
|
||||
{
|
||||
setValue( "twitter/ScreenName", screenName );
|
||||
}
|
||||
|
||||
QString
|
||||
TomahawkSettings::twitterOAuthToken() const
|
||||
{
|
||||
return value( "twitter/OAuthToken" ).toString();
|
||||
}
|
||||
|
||||
void
|
||||
TomahawkSettings::setTwitterOAuthToken( const QString& oauthtoken )
|
||||
{
|
||||
setValue( "twitter/OAuthToken", oauthtoken );
|
||||
}
|
||||
|
||||
QString
|
||||
TomahawkSettings::twitterOAuthTokenSecret() const
|
||||
{
|
||||
return value( "twitter/OAuthTokenSecret" ).toString();
|
||||
}
|
||||
|
||||
void
|
||||
TomahawkSettings::setTwitterOAuthTokenSecret( const QString& oauthtokensecret )
|
||||
{
|
||||
setValue( "twitter/OAuthTokenSecret", oauthtokensecret );
|
||||
}
|
||||
|
||||
qint64
|
||||
TomahawkSettings::twitterCachedFriendsSinceId() const
|
||||
{
|
||||
return value( "twitter/CachedFriendsSinceID", 0 ).toLongLong();
|
||||
}
|
||||
|
||||
void
|
||||
TomahawkSettings::setTwitterCachedFriendsSinceId( qint64 cachedId )
|
||||
{
|
||||
setValue( "twitter/CachedFriendsSinceID", cachedId );
|
||||
}
|
||||
|
||||
qint64
|
||||
TomahawkSettings::twitterCachedMentionsSinceId() const
|
||||
{
|
||||
return value( "twitter/CachedMentionsSinceID", 0 ).toLongLong();
|
||||
}
|
||||
|
||||
void
|
||||
TomahawkSettings::setTwitterCachedMentionsSinceId( qint64 cachedId )
|
||||
{
|
||||
setValue( "twitter/CachedMentionsSinceID", cachedId );
|
||||
}
|
||||
|
||||
qint64
|
||||
TomahawkSettings::twitterCachedDirectMessagesSinceId() const
|
||||
{
|
||||
return value( "twitter/CachedDirectMessagesSinceID", 0 ).toLongLong();
|
||||
}
|
||||
|
||||
void
|
||||
TomahawkSettings::setTwitterCachedDirectMessagesSinceId( qint64 cachedId )
|
||||
{
|
||||
setValue( "twitter/CachedDirectMessagesSinceID", cachedId );
|
||||
}
|
||||
|
||||
QHash<QString, QVariant>
|
||||
TomahawkSettings::twitterCachedPeers() const
|
||||
{
|
||||
return value( "twitter/CachedPeers", QHash<QString, QVariant>() ).toHash();
|
||||
}
|
||||
|
||||
void
|
||||
TomahawkSettings::setTwitterCachedPeers( const QHash<QString, QVariant> &cachedPeers )
|
||||
{
|
||||
setValue( "twitter/CachedPeers", cachedPeers );
|
||||
}
|
||||
|
||||
bool
|
||||
TomahawkSettings::scrobblingEnabled() const
|
||||
|
@@ -95,7 +95,29 @@ public:
|
||||
|
||||
QByteArray lastFmSessionKey() const;
|
||||
void setLastFmSessionKey( const QByteArray& key );
|
||||
|
||||
/// Twitter settings
|
||||
QString twitterScreenName() const;
|
||||
void setTwitterScreenName( const QString& screenName );
|
||||
|
||||
QString twitterOAuthToken() const;
|
||||
void setTwitterOAuthToken( const QString& oauthtoken );
|
||||
|
||||
QString twitterOAuthTokenSecret() const;
|
||||
void setTwitterOAuthTokenSecret( const QString& oauthtokensecret );
|
||||
|
||||
qint64 twitterCachedFriendsSinceId() const;
|
||||
void setTwitterCachedFriendsSinceId( qint64 sinceid );
|
||||
|
||||
qint64 twitterCachedMentionsSinceId() const;
|
||||
void setTwitterCachedMentionsSinceId( qint64 sinceid );
|
||||
|
||||
qint64 twitterCachedDirectMessagesSinceId() const;
|
||||
void setTwitterCachedDirectMessagesSinceId( qint64 sinceid );
|
||||
|
||||
QHash<QString, QVariant> twitterCachedPeers() const;
|
||||
void setTwitterCachedPeers( const QHash<QString, QVariant> &cachedPeers );
|
||||
|
||||
/// XMPP Component Settings
|
||||
QString xmppBotServer() const;
|
||||
void setXmppBotServer( const QString &server );
|
||||
|
31
src/mac/macshortcuthandler.cpp
Normal file
31
src/mac/macshortcuthandler.cpp
Normal 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;
|
||||
}
|
||||
}
|
22
src/mac/macshortcuthandler.h
Normal file
22
src/mac/macshortcuthandler.h
Normal 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
30
src/mac/tomahawkapp_mac.h
Normal 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
205
src/mac/tomahawkapp_mac.mm
Normal 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;
|
||||
}
|
||||
|
44
src/main.cpp
44
src/main.cpp
@@ -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
|
||||
|
@@ -1,7 +1,3 @@
|
||||
#include "settingsdialog.h"
|
||||
#include "ui_settingsdialog.h"
|
||||
#include "ui_proxydialog.h"
|
||||
|
||||
#include <QCryptographicHash>
|
||||
#include <QDebug>
|
||||
#include <QDesktopServices>
|
||||
@@ -14,11 +10,18 @@
|
||||
#include <lastfm/XmlQuery>
|
||||
#endif
|
||||
|
||||
#include <qtweetaccountverifycredentials.h>
|
||||
#include <qtweetstatusupdate.h>
|
||||
|
||||
#include "settingsdialog.h"
|
||||
#include "ui_settingsdialog.h"
|
||||
#include "ui_proxydialog.h"
|
||||
#include "tomahawk/tomahawkapp.h"
|
||||
#include "musicscanner.h"
|
||||
#include "tomahawksettings.h"
|
||||
#include "sip/SipHandler.h"
|
||||
|
||||
#include "sip/twitter/tomahawkoauthtwitter.h"
|
||||
#include <database/database.h>
|
||||
|
||||
static QString
|
||||
md5( const QByteArray& src )
|
||||
@@ -47,19 +50,23 @@ SettingsDialog::SettingsDialog( QWidget *parent )
|
||||
ui->jabberPassword->setText( s->jabberPassword() );
|
||||
ui->jabberServer->setText( s->jabberServer() );
|
||||
ui->jabberPort->setValue( s->jabberPort() );
|
||||
|
||||
ui->staticHostName->setText( s->externalHostname() );
|
||||
ui->proxyButton->setVisible( false );
|
||||
ui->staticPort->setValue( s->externalPort() );
|
||||
|
||||
if ( ui->jabberPort->text().toInt() != 5222 || !ui->jabberServer->text().isEmpty() )
|
||||
ui->proxyButton->setVisible( false );
|
||||
|
||||
if ( s->twitterOAuthToken().isEmpty() || s->twitterOAuthTokenSecret().isEmpty() )
|
||||
{
|
||||
ui->checkBoxAdvanced->setChecked( true );
|
||||
ui->twitterStatusLabel->setText("Status: No saved credentials");
|
||||
ui->twitterAuthenticateButton->setText( "Authenticate" );
|
||||
ui->twitterInstructionsBox->setVisible( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
// hide advanved settings
|
||||
ui->checkBoxAdvanced->setChecked( false );
|
||||
ui->groupBoxJabberAdvanced->setVisible( false );
|
||||
ui->groupBoxNetworkAdvanced->setVisible( false );
|
||||
ui->twitterStatusLabel->setText("Status: Credentials saved");
|
||||
ui->twitterAuthenticateButton->setText( "Re-authenticate" );
|
||||
ui->twitterInstructionsBox->setVisible( true );
|
||||
}
|
||||
|
||||
// MUSIC SCANNER
|
||||
@@ -118,6 +125,7 @@ SettingsDialog::~SettingsDialog()
|
||||
s->setJabberPort( ui->jabberPort->value() );
|
||||
|
||||
s->setExternalHostname( ui->staticHostName->text() );
|
||||
s->setExternalPort( ui->staticPort->value() );
|
||||
|
||||
s->setScannerPath( ui->lineEditMusicPath->text() );
|
||||
|
||||
@@ -140,8 +148,8 @@ SettingsDialog::~SettingsDialog()
|
||||
|
||||
if( rejabber )
|
||||
{
|
||||
APP->sipHandler()->disconnect();
|
||||
APP->sipHandler()->connect();
|
||||
APP->sipHandler()->disconnectPlugins();
|
||||
APP->sipHandler()->connectPlugins();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -273,6 +281,91 @@ SettingsDialog::onLastFmFinished()
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
SettingsDialog::authenticateTwitter()
|
||||
{
|
||||
TomahawkOAuthTwitter *twitAuth = new TomahawkOAuthTwitter( this );
|
||||
twitAuth->setNetworkAccessManager( TomahawkUtils::nam() );
|
||||
twitAuth->authorizePin();
|
||||
if ( !twitAuth->oauthToken().isEmpty() && !twitAuth->oauthTokenSecret().isEmpty() )
|
||||
{
|
||||
TomahawkSettings* s = TomahawkSettings::instance();
|
||||
s->setTwitterOAuthToken( twitAuth->oauthToken() );
|
||||
s->setTwitterOAuthTokenSecret( twitAuth->oauthTokenSecret() );
|
||||
ui->twitterStatusLabel->setText("Status: Credentials saved");
|
||||
ui->twitterAuthenticateButton->setText( "Re-authenticate" );
|
||||
ui->twitterInstructionsBox->setVisible( true );
|
||||
TomahawkSettings::instance()->setTwitterCachedFriendsSinceId( 0 );
|
||||
TomahawkSettings::instance()->setTwitterCachedMentionsSinceId( 0 );
|
||||
TomahawkApp::instance()->sipHandler()->connectPlugins( false, "SIPTWITTER" );
|
||||
}
|
||||
else
|
||||
{
|
||||
TomahawkSettings* s = TomahawkSettings::instance();
|
||||
s->setTwitterOAuthToken( QString() );
|
||||
s->setTwitterOAuthTokenSecret( QString() );
|
||||
ui->twitterStatusLabel->setText("Status: No saved credentials");
|
||||
ui->twitterAuthenticateButton->setText( "Authenticate" );
|
||||
ui->twitterInstructionsBox->setVisible( false );
|
||||
QMessageBox::critical( 0, QString("Tweetin' Error"), QString("There was an error validating your authentication") );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SettingsDialog::startPostGotTomahawkStatus()
|
||||
{
|
||||
qDebug() << "Posting Got Tomahawk status";
|
||||
TomahawkSettings* s = TomahawkSettings::instance();
|
||||
if ( s->twitterOAuthToken().isEmpty() || s->twitterOAuthTokenSecret().isEmpty() )
|
||||
{
|
||||
QMessageBox::critical( 0, QString("Tweetin' Error"), QString("Your saved credentials could not be loaded.\nYou may wish to try re-authenticating.") );
|
||||
return;
|
||||
}
|
||||
TomahawkOAuthTwitter *twitAuth = new TomahawkOAuthTwitter( this );
|
||||
twitAuth->setNetworkAccessManager( TomahawkUtils::nam() );
|
||||
twitAuth->setOAuthToken( s->twitterOAuthToken().toLatin1() );
|
||||
twitAuth->setOAuthTokenSecret( s->twitterOAuthTokenSecret().toLatin1() );
|
||||
QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( twitAuth, this );
|
||||
connect( credVerifier, SIGNAL( parsedUser(const QTweetUser &) ), SLOT( postGotTomahawkStatusAuthVerifyReply(const QTweetUser &) ) );
|
||||
credVerifier->verify();
|
||||
}
|
||||
|
||||
void
|
||||
SettingsDialog::postGotTomahawkStatusAuthVerifyReply( const QTweetUser &user )
|
||||
{
|
||||
if ( user.id() == 0 )
|
||||
{
|
||||
QMessageBox::critical( 0, QString("Tweetin' Error"), QString("Your saved credentials could not be verified.\nYou may wish to try re-authenticating.") );
|
||||
return;
|
||||
}
|
||||
TomahawkSettings* s = TomahawkSettings::instance();
|
||||
s->setTwitterScreenName( user.screenName() );
|
||||
TomahawkOAuthTwitter *twitAuth = new TomahawkOAuthTwitter( this );
|
||||
twitAuth->setNetworkAccessManager( TomahawkUtils::nam() );
|
||||
twitAuth->setOAuthToken( s->twitterOAuthToken().toLatin1() );
|
||||
twitAuth->setOAuthTokenSecret( s->twitterOAuthTokenSecret().toLatin1() );
|
||||
QTweetStatusUpdate *statUpdate = new QTweetStatusUpdate( twitAuth, this );
|
||||
connect( statUpdate, SIGNAL( postedStatus(const QTweetStatus &) ), SLOT( postGotTomahawkStatusUpdateReply(const QTweetStatus &) ) );
|
||||
connect( statUpdate, SIGNAL( error(QTweetNetBase::ErrorCode, const QString&) ), SLOT( postGotTomahawkStatusUpdateError(QTweetNetBase::ErrorCode, const QString &) ) );
|
||||
QString uuid = QUuid::createUuid();
|
||||
statUpdate->post( QString( "Got Tomahawk? {" ) + Database::instance()->dbid() + QString( "} (" ) + uuid.mid( 1, 8 ) + QString( ")" ) );
|
||||
}
|
||||
|
||||
void
|
||||
SettingsDialog::postGotTomahawkStatusUpdateReply( const QTweetStatus& status )
|
||||
{
|
||||
if ( status.id() == 0 )
|
||||
QMessageBox::critical( 0, QString("Tweetin' Error"), QString("There was an error posting your status -- sorry!") );
|
||||
else
|
||||
QMessageBox::information( 0, QString("Tweeted!"), QString("Your tweet has been posted!") );
|
||||
}
|
||||
void
|
||||
SettingsDialog::postGotTomahawkStatusUpdateError( QTweetNetBase::ErrorCode code, const QString& errorMsg )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
qDebug() << "Error posting Got Tomahawk message, error code is " << code << ", error message is " << errorMsg;
|
||||
QMessageBox::critical( 0, QString("Tweetin' Error"), QString("There was an error posting your status -- sorry!") );
|
||||
}
|
||||
|
||||
ProxyDialog::ProxyDialog( QWidget *parent )
|
||||
: QDialog( parent )
|
||||
|
@@ -3,6 +3,10 @@
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <qtweetstatus.h>
|
||||
#include <qtweetuser.h>
|
||||
#include <qtweetnetbase.h>
|
||||
|
||||
class QNetworkReply;
|
||||
|
||||
namespace Ui
|
||||
@@ -50,7 +54,13 @@ private slots:
|
||||
|
||||
void testLastFmLogin();
|
||||
void onLastFmFinished();
|
||||
|
||||
|
||||
void authenticateTwitter();
|
||||
void startPostGotTomahawkStatus();
|
||||
void postGotTomahawkStatusAuthVerifyReply( const QTweetUser &user );
|
||||
void postGotTomahawkStatusUpdateReply( const QTweetStatus &status );
|
||||
void postGotTomahawkStatusUpdateError( QTweetNetBase::ErrorCode, const QString &errorMsg );
|
||||
|
||||
void addScriptResolver();
|
||||
void scriptSelectionChanged();
|
||||
void removeScriptResolver();
|
||||
|
@@ -40,36 +40,30 @@
|
||||
<number>16</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="horizontalSpacing">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<item row="2" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Jabber ID:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>jabberUsername</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="jabberUsername">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -79,20 +73,23 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Password:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>jabberPassword</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="jabberPassword">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@@ -108,22 +105,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="checkBoxAdvanced">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show Advanced Settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@@ -227,72 +208,6 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxNetworkAdvanced">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Advanced Network Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="staticHostNameHLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="staticHostNameLabel">
|
||||
<property name="text">
|
||||
<string>Static Host Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="staticHostName"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="proxySettingsHLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="proxyButton">
|
||||
<property name="text">
|
||||
<string>Proxy Settings...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
@@ -306,50 +221,189 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxHttp">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Playdar HTTP API - NO AUTH</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxUpnp">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use UPnP to establish port forward</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxJabberAutoConnect">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Connect automatically when Tomahawk starts</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabNetwork">
|
||||
<attribute name="title">
|
||||
<string>Network</string>
|
||||
</attribute>
|
||||
<widget class="QGroupBox" name="groupBoxNetworkAdvanced">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>10</y>
|
||||
<width>551</width>
|
||||
<height>341</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Advanced Network Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>If you're having difficulty connecting to peers, try setting this to your external IP address/host name and a port number (default 50210). Make sure to forward that port to this machine!</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="staticHostNameLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Static Host Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="staticHostName"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="staticPortLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Static Port:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="staticPort">
|
||||
<property name="maximum">
|
||||
<number>65535</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50210</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="proxySettingsHLayout">
|
||||
<item>
|
||||
<spacer name="proxySettingsLeftSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="proxyButton">
|
||||
<property name="text">
|
||||
<string>Proxy Settings...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="proxySettingsRightSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxHttp">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Playdar HTTP API - NO AUTH</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxJabberAutoConnect">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Connect automatically when Tomahawk starts</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxUpnp">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use UPnP to establish port forward</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabMusic">
|
||||
<attribute name="title">
|
||||
<string>Music</string>
|
||||
<string>Local Music</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<property name="margin">
|
||||
@@ -412,6 +466,104 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabTwitter">
|
||||
<attribute name="title">
|
||||
<string>Twitter</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_10">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="twitterVertLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="twitterInfoLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Authenticating with Twitter allows you to discover and play music from your Twitter friends running Tomahawk.
|
||||
|
||||
This feature works best when you have set a static host name in the "Network" settings tab under Advanced Settings, but may work even if you do not. Please note: this discovery uses Direct Messages and will only work when both Twitter users have followed each other. Tomahawk will attempt to "clean up" after itself to keep your Direct Message inbox tidy, but may miss some.
|
||||
|
||||
When you press the button your web browser will launch and take you to Twitter.com to authenticate. You must copy and paste the PIN number into the dialog box that appears.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="twitterHorizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="twitterStatusLabel">
|
||||
<property name="text">
|
||||
<string>Status: No saved credentials</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::AutoText</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="twitterAuthenticateButton">
|
||||
<property name="text">
|
||||
<string>Authenticate with Twitter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="twitterInstructionsBox">
|
||||
<property name="title">
|
||||
<string>Instructions</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_12">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="twitterInstructionsVLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="twitterInstructionsInfoLabel">
|
||||
<property name="text">
|
||||
<string>How it works is simple: just press the button below to tweet "Got Tomahawk?" and some necessary information. Then be (very) patient. Twitter is an asynchronous protocol so it can take a bit!
|
||||
|
||||
If connections to peers seem to have been lost, just press the button again to re-post a tweet for resynchronization.
|
||||
</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="twitterTweetGotTomahawkButton">
|
||||
<property name="text">
|
||||
<string>Press here to have Tomahawk post a tweet</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="twitterVertSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabLastfm">
|
||||
<attribute name="title">
|
||||
<string>Last.fm</string>
|
||||
@@ -641,50 +793,34 @@
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>checkBoxAdvanced</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>proxyButton</receiver>
|
||||
<slot>setVisible(bool)</slot>
|
||||
<sender>twitterAuthenticateButton</sender>
|
||||
<signal>pressed()</signal>
|
||||
<receiver>SettingsDialog</receiver>
|
||||
<slot>authenticateTwitter()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>310</x>
|
||||
<y>110</y>
|
||||
<x>459</x>
|
||||
<y>205</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>368</x>
|
||||
<y>194</y>
|
||||
<x>310</x>
|
||||
<y>216</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>checkBoxAdvanced</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>groupBoxJabberAdvanced</receiver>
|
||||
<slot>setVisible(bool)</slot>
|
||||
<sender>twitterTweetGotTomahawkButton</sender>
|
||||
<signal>pressed()</signal>
|
||||
<receiver>SettingsDialog</receiver>
|
||||
<slot>startPostGotTomahawkStatus()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>310</x>
|
||||
<y>115</y>
|
||||
<y>313</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>310</x>
|
||||
<y>174</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>checkBoxAdvanced</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>groupBoxNetworkAdvanced</receiver>
|
||||
<slot>setVisible(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>310</x>
|
||||
<y>115</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>310</x>
|
||||
<y>262</y>
|
||||
<y>216</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
|
13
src/shortcuthandler.cpp
Normal file
13
src/shortcuthandler.cpp
Normal 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
34
src/shortcuthandler.h
Normal 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
|
@@ -13,14 +13,15 @@
|
||||
|
||||
SipHandler::SipHandler( QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_connected( false )
|
||||
{
|
||||
m_connected = false;
|
||||
loadPlugins( findPlugins() );
|
||||
}
|
||||
|
||||
|
||||
SipHandler::~SipHandler()
|
||||
{
|
||||
disconnectPlugins();
|
||||
}
|
||||
|
||||
|
||||
@@ -114,30 +115,39 @@ SipHandler::loadPlugin( QObject* plugin )
|
||||
|
||||
|
||||
void
|
||||
SipHandler::connect( bool startup )
|
||||
SipHandler::connectPlugins( bool startup, const QString &pluginName )
|
||||
{
|
||||
foreach( SipPlugin* sip, m_plugins )
|
||||
sip->connect( startup );
|
||||
{
|
||||
if ( pluginName.isEmpty() || ( !pluginName.isEmpty() && sip->name() == pluginName ) )
|
||||
sip->connectPlugin( startup );
|
||||
}
|
||||
m_connected = true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SipHandler::disconnect()
|
||||
SipHandler::disconnectPlugins( const QString &pluginName )
|
||||
{
|
||||
foreach( SipPlugin* sip, m_plugins )
|
||||
sip->disconnect();
|
||||
SourceList::instance()->removeAllRemote();
|
||||
m_connected = false;
|
||||
{
|
||||
if ( pluginName.isEmpty() || ( !pluginName.isEmpty() && sip->name() == pluginName ) )
|
||||
sip->disconnectPlugin();
|
||||
}
|
||||
if( pluginName.isEmpty() )
|
||||
{
|
||||
SourceList::instance()->removeAllRemote();
|
||||
m_connected = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SipHandler::toggleConnect()
|
||||
{
|
||||
if( m_connected )
|
||||
disconnect();
|
||||
disconnectPlugins();
|
||||
else
|
||||
connect();
|
||||
connectPlugins();
|
||||
}
|
||||
|
||||
|
||||
|
@@ -19,8 +19,8 @@ public:
|
||||
public slots:
|
||||
void addContact( const QString& id ) { qDebug() << Q_FUNC_INFO << id; }
|
||||
|
||||
void connect( bool startup = false );
|
||||
void disconnect();
|
||||
void connectPlugins( bool startup = false, const QString &pluginName = QString() );
|
||||
void disconnectPlugins( const QString &pluginName = QString() );
|
||||
void toggleConnect();
|
||||
|
||||
signals:
|
||||
|
@@ -12,9 +12,14 @@ JabberPlugin::setProxy( QNetworkProxy* proxy )
|
||||
p->setProxy( proxy );
|
||||
}
|
||||
|
||||
const QString
|
||||
JabberPlugin::name()
|
||||
{
|
||||
return QString( MYNAME );
|
||||
}
|
||||
|
||||
bool
|
||||
JabberPlugin::connect( bool startup )
|
||||
JabberPlugin::connectPlugin( bool startup )
|
||||
{
|
||||
qDebug() << "JabberPlugin::connect";
|
||||
if ( startup && !TomahawkSettings::instance()->jabberAutoConnect() )
|
||||
|
@@ -6,6 +6,8 @@
|
||||
|
||||
#include "../sipdllmacro.h"
|
||||
|
||||
#define MYNAME "SIPJABBER"
|
||||
|
||||
class SIPDLLEXPORT JabberPlugin : public SipPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -18,12 +20,16 @@ public:
|
||||
|
||||
virtual ~JabberPlugin() { delete p; }
|
||||
|
||||
//FIXME: Make this more correct
|
||||
virtual bool isValid() { return true; }
|
||||
virtual const QString name();
|
||||
|
||||
void setProxy( QNetworkProxy* proxy );
|
||||
|
||||
public slots:
|
||||
virtual bool connect( bool startup );
|
||||
virtual bool connectPlugin( bool startup );
|
||||
|
||||
void disconnect()
|
||||
void disconnectPlugin()
|
||||
{
|
||||
QMetaObject::invokeMethod( p,
|
||||
"disconnect",
|
||||
|
45
src/sip/twitter/CMakeLists.txt
Normal file
45
src/sip/twitter/CMakeLists.txt
Normal file
@@ -0,0 +1,45 @@
|
||||
project( tomahawk )
|
||||
|
||||
include( ${QT_USE_FILE} )
|
||||
add_definitions( ${QT_DEFINITIONS} )
|
||||
add_definitions( -DQT_PLUGIN )
|
||||
add_definitions( -DQT_SHARED )
|
||||
add_definitions( -DSIPDLLEXPORT_PRO )
|
||||
|
||||
set( twitterSources
|
||||
twitter.cpp
|
||||
tomahawkoauthtwitter.cpp
|
||||
)
|
||||
|
||||
set( twitterHeaders
|
||||
twitter.h
|
||||
tomahawkoauthtwitter.h
|
||||
)
|
||||
|
||||
include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ..
|
||||
${QT_INCLUDE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/thirdparty/qtweetlib/src
|
||||
)
|
||||
|
||||
qt4_wrap_cpp( twitterMoc ${twitterHeaders} )
|
||||
add_library( sip_twitter SHARED ${twitterSources} ${twitterMoc} )
|
||||
|
||||
IF( WIN32 )
|
||||
SET( OS_SPECIFIC_LINK_LIBRARIES
|
||||
${OS_SPECIFIC_LINK_LIBRARIES}
|
||||
"winmm.dll"
|
||||
"iphlpapi.a"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../../build/src/libtomahawk/libtomahawklib.dll"
|
||||
)
|
||||
ENDIF( WIN32 )
|
||||
|
||||
target_link_libraries( sip_twitter
|
||||
${QT_LIBRARIES}
|
||||
${OS_SPECIFIC_LINK_LIBRARIES}
|
||||
)
|
||||
|
||||
IF( APPLE )
|
||||
SET( CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-undefined dynamic_lookup" )
|
||||
ENDIF( APPLE )
|
||||
|
||||
install( TARGETS sip_twitter DESTINATION lib )
|
18
src/sip/twitter/tomahawkoauthtwitter.cpp
Normal file
18
src/sip/twitter/tomahawkoauthtwitter.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "tomahawkoauthtwitter.h"
|
||||
#include <QInputDialog>
|
||||
|
||||
TomahawkOAuthTwitter::TomahawkOAuthTwitter( QObject* parent )
|
||||
: OAuthTwitter( parent )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int TomahawkOAuthTwitter::authorizationWidget()
|
||||
{
|
||||
bool ok;
|
||||
int i = QInputDialog::getInt(0, QString( "Twitter PIN" ), QString( "After authenticating on Twitter's web site,\nenter the displayed PIN number here:" ), 0, 0, 2147483647, 1, &ok);
|
||||
if (ok)
|
||||
return i;
|
||||
|
||||
return 0;
|
||||
}
|
21
src/sip/twitter/tomahawkoauthtwitter.h
Normal file
21
src/sip/twitter/tomahawkoauthtwitter.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef TOMAHAWKOAUTHTWITTER
|
||||
#define TOMAHAWKOAUTHTWITTER
|
||||
|
||||
#include <oauthtwitter.h>
|
||||
|
||||
#include "../sipdllmacro.h"
|
||||
|
||||
class SIPDLLEXPORT TomahawkOAuthTwitter : public OAuthTwitter
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TomahawkOAuthTwitter( QObject *parent = 0 );
|
||||
|
||||
~TomahawkOAuthTwitter() {}
|
||||
|
||||
protected:
|
||||
virtual int authorizationWidget();
|
||||
};
|
||||
|
||||
#endif
|
548
src/sip/twitter/twitter.cpp
Normal file
548
src/sip/twitter/twitter.cpp
Normal file
@@ -0,0 +1,548 @@
|
||||
#include "twitter.h"
|
||||
|
||||
#include <QtPlugin>
|
||||
#include <QRegExp>
|
||||
#include <QStringList>
|
||||
|
||||
#include <qtweetaccountverifycredentials.h>
|
||||
#include <qtweetuser.h>
|
||||
#include <qtweetstatus.h>
|
||||
|
||||
#include <utils/tomahawkutils.h>
|
||||
#include <tomahawksettings.h>
|
||||
#include <database/database.h>
|
||||
#include <network/servent.h>
|
||||
|
||||
|
||||
TwitterPlugin::TwitterPlugin()
|
||||
: SipPlugin()
|
||||
, m_isAuthed( false )
|
||||
, m_isOnline( false )
|
||||
, m_checkTimer( this )
|
||||
, m_connectTimer( this )
|
||||
, m_cachedFriendsSinceId( 0 )
|
||||
, m_cachedMentionsSinceId( 0 )
|
||||
, m_cachedDirectMessagesSinceId( 0 )
|
||||
, m_cachedPeers()
|
||||
, m_keyCache()
|
||||
, m_finishedFriends( false )
|
||||
, m_finishedMentions( false )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
m_checkTimer.setInterval( 60000 );
|
||||
m_checkTimer.setSingleShot( false );
|
||||
connect( &m_checkTimer, SIGNAL( timeout() ), SLOT( checkTimerFired() ) );
|
||||
m_checkTimer.start();
|
||||
|
||||
m_connectTimer.setInterval( 60000 );
|
||||
m_connectTimer.setSingleShot( false );
|
||||
connect( &m_connectTimer, SIGNAL( timeout() ), SLOT( connectTimerFired() ) );
|
||||
m_connectTimer.start();
|
||||
}
|
||||
|
||||
bool
|
||||
TwitterPlugin::isValid()
|
||||
{
|
||||
return m_isAuthed || !m_cachedPeers.isEmpty();
|
||||
}
|
||||
|
||||
const QString
|
||||
TwitterPlugin::name()
|
||||
{
|
||||
qDebug() << "TwitterPlugin returning plugin name " << QString( MYNAME );
|
||||
return QString( MYNAME );
|
||||
}
|
||||
|
||||
bool
|
||||
TwitterPlugin::connectPlugin( bool /*startup*/ )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
TomahawkSettings *settings = TomahawkSettings::instance();
|
||||
|
||||
m_cachedPeers = settings->twitterCachedPeers();
|
||||
QList<QString> peerlist = m_cachedPeers.keys();
|
||||
qStableSort( peerlist.begin(), peerlist.end() );
|
||||
foreach( QString screenName, peerlist )
|
||||
{
|
||||
QHash< QString, QVariant > cachedPeer = m_cachedPeers[screenName].toHash();
|
||||
foreach( QString prop, cachedPeer.keys() )
|
||||
qDebug() << "TwitterPlugin : " << screenName << ", key " << prop << ", value " << ( cachedPeer[prop].canConvert< QString >() ? cachedPeer[prop].toString() : QString::number( cachedPeer[prop].toInt() ) );
|
||||
QMetaObject::invokeMethod( this, "registerOffer", Q_ARG( QString, screenName ), QGenericArgument( "QHash< QString, QVariant >", (const void*)&cachedPeer ) );
|
||||
}
|
||||
|
||||
if ( settings->twitterOAuthToken().isEmpty() || settings->twitterOAuthTokenSecret().isEmpty() )
|
||||
{
|
||||
qDebug() << "TwitterPlugin has empty Twitter credentials; not connecting";
|
||||
return m_cachedPeers.isEmpty();
|
||||
}
|
||||
|
||||
delete m_twitterAuth.data();
|
||||
m_twitterAuth = QWeakPointer<TomahawkOAuthTwitter>( new TomahawkOAuthTwitter( this ) );
|
||||
m_twitterAuth.data()->setNetworkAccessManager( TomahawkUtils::nam() );
|
||||
m_twitterAuth.data()->setOAuthToken( settings->twitterOAuthToken().toLatin1() );
|
||||
m_twitterAuth.data()->setOAuthTokenSecret( settings->twitterOAuthTokenSecret().toLatin1() );
|
||||
|
||||
QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( m_twitterAuth.data(), this );
|
||||
connect( credVerifier, SIGNAL( parsedUser(const QTweetUser &) ), SLOT( connectAuthVerifyReply(const QTweetUser &) ) );
|
||||
credVerifier->verify();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TwitterPlugin::disconnectPlugin()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if( !m_friendsTimeline.isNull() )
|
||||
m_friendsTimeline.data()->deleteLater();
|
||||
if( !m_twitterAuth.isNull() )
|
||||
m_twitterAuth.data()->deleteLater();
|
||||
|
||||
m_cachedPeers.empty();
|
||||
delete m_twitterAuth.data();
|
||||
m_isOnline = false;
|
||||
}
|
||||
|
||||
void
|
||||
TwitterPlugin::connectAuthVerifyReply( const QTweetUser &user )
|
||||
{
|
||||
if ( user.id() == 0 )
|
||||
{
|
||||
qDebug() << "TwitterPlugin could not authenticate to Twitter";
|
||||
m_isAuthed = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "TwitterPlugin successfully authenticated to Twitter as user " << user.screenName();
|
||||
m_isAuthed = true;
|
||||
if ( !m_twitterAuth.isNull() )
|
||||
{
|
||||
TomahawkSettings::instance()->setTwitterScreenName( user.screenName() );
|
||||
m_friendsTimeline = QWeakPointer<QTweetFriendsTimeline>( new QTweetFriendsTimeline( m_twitterAuth.data(), this ) );
|
||||
m_mentions = QWeakPointer<QTweetMentions>( new QTweetMentions( m_twitterAuth.data(), this ) );
|
||||
m_directMessages = QWeakPointer<QTweetDirectMessages>( new QTweetDirectMessages( m_twitterAuth.data(), this ) );
|
||||
m_directMessageNew = QWeakPointer<QTweetDirectMessageNew>( new QTweetDirectMessageNew( m_twitterAuth.data(), this ) );
|
||||
m_directMessageDestroy = QWeakPointer<QTweetDirectMessageDestroy>( new QTweetDirectMessageDestroy( m_twitterAuth.data(), this ) );
|
||||
connect( m_friendsTimeline.data(), SIGNAL( parsedStatuses(const QList< QTweetStatus > &) ), SLOT( friendsTimelineStatuses(const QList<QTweetStatus> &) ) );
|
||||
connect( m_mentions.data(), SIGNAL( parsedStatuses(const QList< QTweetStatus > &) ), SLOT( mentionsStatuses(const QList<QTweetStatus> &) ) );
|
||||
connect( m_directMessages.data(), SIGNAL( parsedDirectMessages(const QList<QTweetDMStatus> &)), SLOT( directMessages(const QList<QTweetDMStatus> &) ) );
|
||||
connect( m_directMessageNew.data(), SIGNAL( parsedDirectMessage(const QTweetDMStatus &)), SLOT( directMessagePosted(const QTweetDMStatus &) ) );
|
||||
connect( m_directMessageNew.data(), SIGNAL( error(QTweetNetBase::ErrorCode, const QString &) ), SLOT( directMessagePostError(QTweetNetBase::ErrorCode, const QString &) ) );
|
||||
connect( m_directMessageDestroy.data(), SIGNAL( parsedDirectMessage(const QTweetDMStatus &) ), SLOT( directMessageDestroyed(const QTweetDMStatus &) ) );
|
||||
m_isOnline = true;
|
||||
QMetaObject::invokeMethod( this, "checkTimerFired", Qt::AutoConnection );
|
||||
QTimer::singleShot( 20000, this, SLOT( connectTimerFired() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "TwitterPlugin auth pointer was null!";
|
||||
m_isAuthed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TwitterPlugin::checkTimerFired()
|
||||
{
|
||||
if ( !isValid() )
|
||||
return;
|
||||
|
||||
if ( m_cachedFriendsSinceId == 0 )
|
||||
m_cachedFriendsSinceId = TomahawkSettings::instance()->twitterCachedFriendsSinceId();
|
||||
|
||||
qDebug() << "TwitterPlugin looking at friends timeline since id " << m_cachedFriendsSinceId;
|
||||
|
||||
if ( !m_friendsTimeline.isNull() )
|
||||
m_friendsTimeline.data()->fetch( m_cachedFriendsSinceId, 0, 800 );
|
||||
|
||||
|
||||
if ( m_cachedMentionsSinceId == 0 )
|
||||
m_cachedMentionsSinceId = TomahawkSettings::instance()->twitterCachedMentionsSinceId();
|
||||
|
||||
qDebug() << "TwitterPlugin looking at mentions timeline since id " << m_cachedMentionsSinceId;
|
||||
|
||||
if ( !m_mentions.isNull() )
|
||||
m_mentions.data()->fetch( m_cachedMentionsSinceId, 0, 800 );
|
||||
}
|
||||
|
||||
void
|
||||
TwitterPlugin::connectTimerFired()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if ( !isValid() || m_cachedPeers.isEmpty() )
|
||||
return;
|
||||
|
||||
QString myScreenName = TomahawkSettings::instance()->twitterScreenName();
|
||||
QList<QString> peerlist = m_cachedPeers.keys();
|
||||
qStableSort( peerlist.begin(), peerlist.end() );
|
||||
foreach( QString screenName, peerlist )
|
||||
{
|
||||
QHash< QString, QVariant > peerData = m_cachedPeers[screenName].toHash();
|
||||
|
||||
if ( !peerData.contains( "host" ) || !peerData.contains( "port" ) || !peerData.contains( "pkey" ) )
|
||||
{
|
||||
qDebug() << "TwitterPlugin does not have host, port and/or pkey values for " << screenName;
|
||||
continue;
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod( this, "registerOffer", Q_ARG( QString, screenName ), QGenericArgument( "QHash< QString, QVariant >", (const void*)&peerData ) );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TwitterPlugin::friendsTimelineStatuses( const QList< QTweetStatus > &statuses )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
QRegExp regex( QString( "^(@[a-zA-Z0-9]+ )?(Got Tomahawk\\?) (\\{[a-fA-F0-9\\-]+\\}) (.*)$" ), Qt::CaseSensitive, QRegExp::RegExp2 );
|
||||
QString myScreenName = TomahawkSettings::instance()->twitterScreenName();
|
||||
|
||||
QHash< QString, QTweetStatus > latestHash;
|
||||
foreach ( QTweetStatus status, statuses )
|
||||
{
|
||||
if ( !latestHash.contains( status.user().screenName() ) )
|
||||
latestHash[status.user().screenName()] = status;
|
||||
else
|
||||
{
|
||||
if ( status.id() > latestHash[status.user().screenName()].id() )
|
||||
latestHash[status.user().screenName()] = status;
|
||||
}
|
||||
}
|
||||
|
||||
foreach( QTweetStatus status, latestHash.values() )
|
||||
{
|
||||
if ( status.id() > m_cachedFriendsSinceId )
|
||||
m_cachedFriendsSinceId = status.id();
|
||||
|
||||
if ( regex.exactMatch( status.text() ) )
|
||||
{
|
||||
qDebug() << "TwitterPlugin found an exact tweet from friend " << status.user().screenName();
|
||||
if ( status.text().startsWith( '@' ) && regex.captureCount() >= 2 && regex.cap( 1 ) != QString( '@' + myScreenName ) )
|
||||
{
|
||||
qDebug() << "TwitterPlugin skipping tweet because it's directed @someone that isn't us";
|
||||
continue;
|
||||
}
|
||||
|
||||
QString node;
|
||||
for ( int i = 0; i < regex.captureCount(); ++i )
|
||||
{
|
||||
if ( regex.cap( i ) == QString( "Got Tomahawk?" ) )
|
||||
{
|
||||
QString nodeCap = regex.cap( i + 1 );
|
||||
nodeCap.chop( 1 );
|
||||
node = nodeCap.mid( 1 );
|
||||
}
|
||||
}
|
||||
if ( node.isEmpty() )
|
||||
{
|
||||
qDebug() << "TwitterPlugin could not parse node out of the tweet";
|
||||
continue;
|
||||
}
|
||||
else
|
||||
qDebug() << "TwitterPlugin parsed node " << node << " out of the tweet";
|
||||
|
||||
if ( status.user().screenName() == myScreenName && node == Database::instance()->dbid() )
|
||||
continue;
|
||||
|
||||
QHash< QString, QVariant > peerData;
|
||||
if( m_cachedPeers.contains( status.user().screenName() ) )
|
||||
{
|
||||
peerData = m_cachedPeers[status.user().screenName()].toHash();
|
||||
//force a re-send of info but no need to re-register
|
||||
peerData["resend"] = QVariant::fromValue< bool >( true );
|
||||
}
|
||||
peerData["node"] = QVariant::fromValue< QString >( node );
|
||||
QMetaObject::invokeMethod( this, "registerOffer", Q_ARG( QString, status.user().screenName() ), QGenericArgument( "QHash< QString, QVariant >", (const void*)&peerData ) );
|
||||
}
|
||||
}
|
||||
|
||||
TomahawkSettings::instance()->setTwitterCachedFriendsSinceId( m_cachedFriendsSinceId );
|
||||
|
||||
m_finishedFriends = true;
|
||||
QMetaObject::invokeMethod( this, "pollDirectMessages", Qt::AutoConnection );
|
||||
}
|
||||
|
||||
void
|
||||
TwitterPlugin::mentionsStatuses( const QList< QTweetStatus > &statuses )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
QRegExp regex( QString( "^(@[a-zA-Z0-9]+ )?(Got Tomahawk\\?) (\\{[a-fA-F0-9\\-]+\\}) (.*)$" ), Qt::CaseSensitive, QRegExp::RegExp2 );
|
||||
QString myScreenName = TomahawkSettings::instance()->twitterScreenName();
|
||||
|
||||
QHash< QString, QTweetStatus > latestHash;
|
||||
foreach ( QTweetStatus status, statuses )
|
||||
{
|
||||
if ( !latestHash.contains( status.user().screenName() ) )
|
||||
latestHash[status.user().screenName()] = status;
|
||||
else
|
||||
{
|
||||
if ( status.id() > latestHash[status.user().screenName()].id() )
|
||||
latestHash[status.user().screenName()] = status;
|
||||
}
|
||||
}
|
||||
|
||||
foreach( QTweetStatus status, latestHash.values() )
|
||||
{
|
||||
if ( status.id() > m_cachedMentionsSinceId )
|
||||
m_cachedMentionsSinceId = status.id();
|
||||
|
||||
if ( regex.exactMatch( status.text() ) )
|
||||
{
|
||||
qDebug() << "TwitterPlugin found an exact matching mention from user " << status.user().screenName();
|
||||
if ( status.text().startsWith( '@' ) && regex.captureCount() >= 2 && regex.cap( 1 ) != QString( '@' + myScreenName ) )
|
||||
{
|
||||
qDebug() << "TwitterPlugin skipping mention because it's directed @someone that isn't us";
|
||||
continue;
|
||||
}
|
||||
|
||||
QString node;
|
||||
for ( int i = 0; i < regex.captureCount(); ++i )
|
||||
{
|
||||
if ( regex.cap( i ) == QString( "Got Tomahawk?" ) )
|
||||
{
|
||||
QString nodeCap = regex.cap( i + 1 );
|
||||
nodeCap.chop( 1 );
|
||||
node = nodeCap.mid( 1 );
|
||||
}
|
||||
}
|
||||
if ( node.isEmpty() )
|
||||
{
|
||||
qDebug() << "TwitterPlugin could not parse node out of the tweet";
|
||||
continue;
|
||||
}
|
||||
else
|
||||
qDebug() << "TwitterPlugin parsed node " << node << " out of the tweet";
|
||||
|
||||
if ( status.user().screenName() == myScreenName && node == Database::instance()->dbid() )
|
||||
continue;
|
||||
|
||||
QHash< QString, QVariant > peerData;
|
||||
if( m_cachedPeers.contains( status.user().screenName() ) )
|
||||
{
|
||||
peerData = m_cachedPeers[status.user().screenName()].toHash();
|
||||
//force a re-send of info but no need to re-register
|
||||
peerData["resend"] = QVariant::fromValue< bool >( true );
|
||||
}
|
||||
peerData["node"] = QVariant::fromValue< QString >( node );
|
||||
QMetaObject::invokeMethod( this, "registerOffer", Q_ARG( QString, status.user().screenName() ), QGenericArgument( "QHash< QString, QVariant >", (const void*)&peerData ) );
|
||||
}
|
||||
}
|
||||
|
||||
TomahawkSettings::instance()->setTwitterCachedMentionsSinceId( m_cachedMentionsSinceId );
|
||||
|
||||
m_finishedMentions = true;
|
||||
QMetaObject::invokeMethod( this, "pollDirectMessages", Qt::AutoConnection );
|
||||
}
|
||||
|
||||
void
|
||||
TwitterPlugin::pollDirectMessages()
|
||||
{
|
||||
if ( !m_finishedMentions || !m_finishedFriends )
|
||||
return;
|
||||
|
||||
m_finishedFriends = false;
|
||||
m_finishedMentions = false;
|
||||
|
||||
if ( !isValid() )
|
||||
return;
|
||||
|
||||
if ( m_cachedDirectMessagesSinceId == 0 )
|
||||
m_cachedDirectMessagesSinceId = TomahawkSettings::instance()->twitterCachedDirectMessagesSinceId();
|
||||
|
||||
qDebug() << "TwitterPlugin looking for direct messages since id " << m_cachedDirectMessagesSinceId;
|
||||
|
||||
if ( !m_directMessages.isNull() )
|
||||
m_directMessages.data()->fetch( m_cachedDirectMessagesSinceId, 0, 800 );
|
||||
}
|
||||
|
||||
void
|
||||
TwitterPlugin::directMessages( const QList< QTweetDMStatus > &messages )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
QHash< QString, QTweetDMStatus > latestHash;
|
||||
foreach ( QTweetDMStatus status, messages )
|
||||
{
|
||||
if ( !latestHash.contains( status.senderScreenName() ) )
|
||||
latestHash[status.senderScreenName()] = status;
|
||||
else
|
||||
{
|
||||
if ( status.id() > latestHash[status.senderScreenName()].id() )
|
||||
latestHash[status.senderScreenName()] = status;
|
||||
}
|
||||
}
|
||||
|
||||
foreach( QTweetDMStatus status, latestHash.values() )
|
||||
{
|
||||
qDebug() << "TwitterPlugin checking direct message from " << status.senderScreenName() << " with content " << status.text();
|
||||
if ( status.id() > m_cachedDirectMessagesSinceId )
|
||||
m_cachedDirectMessagesSinceId = status.id();
|
||||
QStringList splitList = status.text().split(':');
|
||||
qDebug() << "TwitterPlugin found " << splitList.length() << " parts to the message; the parts are:";
|
||||
foreach( QString part, splitList )
|
||||
qDebug() << part;
|
||||
if ( splitList.length() != 5 )
|
||||
continue;
|
||||
if ( splitList[0] != "TOMAHAWKPEER" )
|
||||
continue;
|
||||
if ( !splitList[1].startsWith( "Host=" ) || !splitList[2].startsWith( "Port=" ) || !splitList[3].startsWith( "Node=" ) || !splitList[4].startsWith( "PKey=" ) )
|
||||
continue;
|
||||
int port = splitList[2].mid( 5 ).toInt();
|
||||
if ( port == 0 )
|
||||
continue;
|
||||
QString host = splitList[1].mid( 5 );
|
||||
QString node = splitList[3].mid( 5 );
|
||||
QString pkey = splitList[4].mid( 5 );
|
||||
qDebug() << "TwitterPlugin found a peerstart message from " << status.senderScreenName() << " with host " << host << " and port " << port << " and pkey " << pkey << " destined for node " << node;
|
||||
|
||||
if ( node != Database::instance()->dbid() )
|
||||
{
|
||||
qDebug() << "Not destined for this node; leaving it alone and not answering";
|
||||
continue;
|
||||
}
|
||||
|
||||
QHash< QString, QVariant > peerData = ( m_cachedPeers.contains( status.senderScreenName() ) ) ?
|
||||
m_cachedPeers[status.senderScreenName()].toHash() :
|
||||
QHash< QString, QVariant >();
|
||||
|
||||
peerData["host"] = QVariant::fromValue< QString >( host );
|
||||
peerData["port"] = QVariant::fromValue< int >( port );
|
||||
peerData["pkey"] = QVariant::fromValue< QString >( pkey );
|
||||
peerData["dirty"] = QVariant::fromValue< bool >( true );
|
||||
|
||||
QMetaObject::invokeMethod( this, "registerOffer", Q_ARG( QString, status.senderScreenName() ), QGenericArgument( "QHash< QString, QVariant >", (const void*)&peerData ) );
|
||||
|
||||
if ( !m_directMessageDestroy.isNull() )
|
||||
m_directMessageDestroy.data()->destroyMessage( status.id() );
|
||||
}
|
||||
|
||||
TomahawkSettings::instance()->setTwitterCachedDirectMessagesSinceId( m_cachedDirectMessagesSinceId );
|
||||
}
|
||||
|
||||
void
|
||||
TwitterPlugin::registerOffer( const QString &screenName, const QHash< QString, QVariant > &peerData )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
bool peersChanged = false;
|
||||
bool needToSend = false;
|
||||
bool needToAddToCache = false;
|
||||
|
||||
QString friendlyName = QString( '@' + screenName );
|
||||
|
||||
QHash< QString, QVariant > _peerData( peerData );
|
||||
|
||||
if ( _peerData.contains( "dirty" ) )
|
||||
{
|
||||
peersChanged = true;
|
||||
_peerData.remove( "dirty" );
|
||||
}
|
||||
|
||||
if ( _peerData.contains( "resend" ) )
|
||||
{
|
||||
needToSend = true;
|
||||
peersChanged = true;
|
||||
_peerData.remove( "resend" );
|
||||
}
|
||||
|
||||
if ( !_peerData.contains( "okey" ) )
|
||||
{
|
||||
QString okey = QUuid::createUuid().toString().split( '-' ).last();
|
||||
okey.chop( 1 );
|
||||
_peerData["okey"] = QVariant::fromValue< QString >( okey );
|
||||
peersChanged = true;
|
||||
needToAddToCache = true;
|
||||
needToSend = true;
|
||||
}
|
||||
|
||||
if ( !m_keyCache.contains( _peerData["okey"].toString() ) )
|
||||
needToAddToCache = true;
|
||||
|
||||
if ( !_peerData.contains( "ohst" ) || !_peerData.contains( "oprt" ) ||
|
||||
_peerData["ohst"].toString() != Servent::instance()->externalAddress() ||
|
||||
_peerData["oprt"].toInt() != Servent::instance()->externalPort()
|
||||
)
|
||||
needToSend = true;
|
||||
|
||||
if( needToAddToCache && _peerData.contains( "node" ) )
|
||||
{
|
||||
qDebug() << "TwitterPlugin registering offer to " << friendlyName << " with node " << _peerData["node"].toString() << " and offeredkey " << _peerData["okey"].toString();
|
||||
m_keyCache << Servent::instance()->createConnectionKey( friendlyName, _peerData["node"].toString(), _peerData["okey"].toString(), false );
|
||||
}
|
||||
|
||||
if( needToSend && _peerData.contains( "node") )
|
||||
{
|
||||
qDebug() << "TwitterPlugin needs to send and has node";
|
||||
_peerData["ohst"] = QVariant::fromValue< QString >( Servent::instance()->externalAddress() );
|
||||
_peerData["oprt"] = QVariant::fromValue< int >( Servent::instance()->externalPort() );
|
||||
peersChanged = true;
|
||||
if( !Servent::instance()->externalAddress().isEmpty() && !Servent::instance()->externalPort() == 0 )
|
||||
QMetaObject::invokeMethod( this, "sendOffer", Q_ARG( QString, screenName ), QGenericArgument( "QHash< QString, QVariant >", (const void*)&_peerData ) );
|
||||
else
|
||||
qDebug() << "TwitterPlugin did not send offer because external address is " << Servent::instance()->externalAddress() << " and external port is " << Servent::instance()->externalPort();
|
||||
}
|
||||
|
||||
if ( m_isOnline && _peerData.contains( "host" ) && _peerData.contains( "port" ) && _peerData.contains( "pkey" ) )
|
||||
QMetaObject::invokeMethod( this, "makeConnection", Q_ARG( QString, screenName ), QGenericArgument( "QHash< QString, QVariant >", (const void*)&_peerData ) );
|
||||
|
||||
if ( peersChanged )
|
||||
{
|
||||
m_cachedPeers[screenName] = QVariant::fromValue< QHash< QString, QVariant > >( _peerData );
|
||||
TomahawkSettings::instance()->setTwitterCachedPeers( m_cachedPeers );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TwitterPlugin::sendOffer( const QString &screenName, const QHash< QString, QVariant > &peerData )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
QString offerString = QString( "TOMAHAWKPEER:Host=%1:Port=%2:Node=%3:PKey=%4" ).arg( peerData["ohst"].toString() )
|
||||
.arg( peerData["oprt"].toString() )
|
||||
.arg( peerData["node"].toString() )
|
||||
.arg( peerData["okey"].toString() );
|
||||
qDebug() << "TwitterPlugin sending message to " << screenName << ": " << offerString;
|
||||
if( !m_directMessageNew.isNull() )
|
||||
m_directMessageNew.data()->post( screenName, offerString );
|
||||
}
|
||||
|
||||
void
|
||||
TwitterPlugin::makeConnection( const QString &screenName, const QHash< QString, QVariant > &peerData )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if ( !peerData.contains( "host" ) || !peerData.contains( "port" ) || !peerData.contains( "pkey" ) || !peerData.contains( "node" ) )
|
||||
{
|
||||
qDebug() << "TwitterPlugin could not find host and/or port and/or pkey for peer " << screenName;
|
||||
return;
|
||||
}
|
||||
QString friendlyName = QString( '@' + screenName );
|
||||
if ( !Servent::instance()->connectedToSession( peerData["node"].toString() ) )
|
||||
Servent::instance()->connectToPeer( peerData["host"].toString(),
|
||||
peerData["port"].toString().toInt(),
|
||||
peerData["pkey"].toString(),
|
||||
friendlyName,
|
||||
peerData["node"].toString() );
|
||||
}
|
||||
|
||||
void
|
||||
TwitterPlugin::directMessagePosted( const QTweetDMStatus& message )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
qDebug() << "TwitterPlugin sent message to " << message.recipientScreenName() << " containing: " << message.text();
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
TwitterPlugin::directMessagePostError( QTweetNetBase::ErrorCode errorCode, const QString &message )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
qDebug() << "TwitterPlugin received an error posting direct message: " << m_directMessageNew.data()->lastErrorMessage();
|
||||
}
|
||||
|
||||
void
|
||||
TwitterPlugin::directMessageDestroyed( const QTweetDMStatus& message )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
qDebug() << "TwitterPlugin destroyed message " << message.text();
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN2( sip, TwitterPlugin )
|
88
src/sip/twitter/twitter.h
Normal file
88
src/sip/twitter/twitter.h
Normal file
@@ -0,0 +1,88 @@
|
||||
#ifndef TWITTER_H
|
||||
#define TWITTER_H
|
||||
|
||||
#include <QTimer>
|
||||
#include <QWeakPointer>
|
||||
#include <QSet>
|
||||
|
||||
#include <qtweetuser.h>
|
||||
#include <qtweetnetbase.h>
|
||||
#include <qtweetfriendstimeline.h>
|
||||
#include <qtweetdirectmessages.h>
|
||||
#include <qtweetdirectmessagenew.h>
|
||||
#include <qtweetdirectmessagedestroy.h>
|
||||
#include <qtweetmentions.h>
|
||||
#include <qtweetdmstatus.h>
|
||||
|
||||
#include "../sipdllmacro.h"
|
||||
#include "sip/SipPlugin.h"
|
||||
#include "tomahawkoauthtwitter.h"
|
||||
|
||||
#define MYNAME "SIPTWITTER"
|
||||
|
||||
class SIPDLLEXPORT TwitterPlugin : public SipPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES( SipPlugin )
|
||||
|
||||
public:
|
||||
TwitterPlugin();
|
||||
|
||||
virtual ~TwitterPlugin() {}
|
||||
|
||||
virtual bool isValid();
|
||||
virtual const QString name();
|
||||
|
||||
public slots:
|
||||
virtual bool connectPlugin( bool startup );
|
||||
|
||||
void disconnectPlugin();
|
||||
|
||||
void sendMsg( const QString& to, const QString& msg )
|
||||
{
|
||||
}
|
||||
|
||||
void broadcastMsg( const QString &msg )
|
||||
{
|
||||
}
|
||||
|
||||
void addContact( const QString &jid, const QString& msg = QString() )
|
||||
{
|
||||
}
|
||||
|
||||
private slots:
|
||||
void connectAuthVerifyReply( const QTweetUser &user );
|
||||
void checkTimerFired();
|
||||
void connectTimerFired();
|
||||
void friendsTimelineStatuses( const QList< QTweetStatus > &statuses );
|
||||
void mentionsStatuses( const QList< QTweetStatus > &statuses );
|
||||
void pollDirectMessages();
|
||||
void directMessages( const QList< QTweetDMStatus > &messages );
|
||||
void directMessagePosted( const QTweetDMStatus &message );
|
||||
void directMessagePostError( QTweetNetBase::ErrorCode errorCode, const QString &message );
|
||||
void directMessageDestroyed( const QTweetDMStatus &message );
|
||||
void registerOffer( const QString &screenName, const QHash< QString, QVariant > &peerdata );
|
||||
void sendOffer( const QString &screenName, const QHash< QString, QVariant > &peerdata );
|
||||
void makeConnection( const QString &screenName, const QHash< QString, QVariant > &peerdata );
|
||||
|
||||
private:
|
||||
QWeakPointer< TomahawkOAuthTwitter > m_twitterAuth;
|
||||
QWeakPointer< QTweetFriendsTimeline > m_friendsTimeline;
|
||||
QWeakPointer< QTweetMentions > m_mentions;
|
||||
QWeakPointer< QTweetDirectMessages > m_directMessages;
|
||||
QWeakPointer< QTweetDirectMessageNew > m_directMessageNew;
|
||||
QWeakPointer< QTweetDirectMessageDestroy > m_directMessageDestroy;
|
||||
bool m_isAuthed;
|
||||
bool m_isOnline;
|
||||
QTimer m_checkTimer;
|
||||
QTimer m_connectTimer;
|
||||
qint64 m_cachedFriendsSinceId;
|
||||
qint64 m_cachedMentionsSinceId;
|
||||
qint64 m_cachedDirectMessagesSinceId;
|
||||
QHash< QString, QVariant > m_cachedPeers;
|
||||
QSet<QString> m_keyCache;
|
||||
bool m_finishedFriends;
|
||||
bool m_finishedMentions;
|
||||
};
|
||||
|
||||
#endif
|
@@ -2,9 +2,14 @@
|
||||
|
||||
#include <QtPlugin>
|
||||
|
||||
const QString
|
||||
ZeroconfPlugin::name()
|
||||
{
|
||||
return QString( MYNAME );
|
||||
}
|
||||
|
||||
bool
|
||||
ZeroconfPlugin::connect( bool /*startup*/ )
|
||||
ZeroconfPlugin::connectPlugin( bool /*startup*/ )
|
||||
{
|
||||
delete m_zeroconf;
|
||||
m_zeroconf = new TomahawkZeroconf( Servent::instance()->port(), this );
|
||||
@@ -12,15 +17,41 @@ ZeroconfPlugin::connect( bool /*startup*/ )
|
||||
SLOT( lanHostFound( const QString&, int, const QString&, const QString& ) ) );
|
||||
|
||||
m_zeroconf->advertise();
|
||||
|
||||
m_isOnline = true;
|
||||
|
||||
foreach( QStringList *currNode, m_cachedNodes )
|
||||
{
|
||||
QStringList nodeSet = *currNode;
|
||||
if ( !Servent::instance()->connectedToSession( nodeSet[3] ) )
|
||||
Servent::instance()->connectToPeer( nodeSet[0], nodeSet[1].toInt(), "whitelist", nodeSet[2], nodeSet[3] );
|
||||
delete currNode;
|
||||
}
|
||||
m_cachedNodes.empty();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ZeroconfPlugin::disconnectPlugin()
|
||||
{
|
||||
m_isOnline = false;
|
||||
}
|
||||
|
||||
void
|
||||
ZeroconfPlugin::lanHostFound( const QString& host, int port, const QString& name, const QString& nodeid )
|
||||
{
|
||||
qDebug() << "Found LAN host:" << host << port << nodeid;
|
||||
|
||||
//FIXME: This doesn't work...why? I never see Found LAN host in debug either, but somehow nodes are being connected...
|
||||
if ( !m_isOnline )
|
||||
{
|
||||
qDebug() << "Not online, so not connecting";
|
||||
QStringList *nodeSet = new QStringList();
|
||||
*nodeSet << host << QString::number( port ) << name << nodeid;
|
||||
m_cachedNodes.insert( nodeSet );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Servent::instance()->connectedToSession( nodeid ) )
|
||||
Servent::instance()->connectToPeer( host, port, "whitelist", name, nodeid );
|
||||
|
@@ -6,6 +6,8 @@
|
||||
|
||||
#include "../sipdllmacro.h"
|
||||
|
||||
#define MYNAME "SIPZEROCONF"
|
||||
|
||||
class SIPDLLEXPORT ZeroconfPlugin : public SipPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -14,16 +16,19 @@ class SIPDLLEXPORT ZeroconfPlugin : public SipPlugin
|
||||
public:
|
||||
ZeroconfPlugin()
|
||||
: m_zeroconf( 0 )
|
||||
, m_isOnline( false )
|
||||
, m_cachedNodes()
|
||||
{}
|
||||
|
||||
virtual ~ZeroconfPlugin() {}
|
||||
|
||||
virtual bool isValid() { return true; }
|
||||
virtual const QString name();
|
||||
|
||||
public slots:
|
||||
virtual bool connect( bool startup );
|
||||
virtual bool connectPlugin( bool startup );
|
||||
|
||||
void disconnect()
|
||||
{
|
||||
}
|
||||
void disconnectPlugin();
|
||||
|
||||
void sendMsg( const QString& to, const QString& msg )
|
||||
{
|
||||
@@ -42,6 +47,8 @@ private slots:
|
||||
|
||||
private:
|
||||
TomahawkZeroconf* m_zeroconf;
|
||||
bool m_isOnline;
|
||||
QSet< QStringList* > m_cachedNodes;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -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() ) );
|
||||
@@ -445,25 +471,30 @@ TomahawkApp::setupSIP()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
if( !arguments().contains( "--nosip" ) )
|
||||
//FIXME: jabber autoconnect is really more, now that there is sip -- should be renamed and/or split out of jabber-specific settings
|
||||
if( !arguments().contains( "--nosip" ) && TomahawkSettings::instance()->jabberAutoConnect() )
|
||||
{
|
||||
m_xmppBot = new XMPPBot( this );
|
||||
qDebug() << "Connecting SIP classes";
|
||||
m_sipHandler->connect( true );
|
||||
m_sipHandler->connectPlugins( true );
|
||||
// m_sipHandler->setProxy( *TomahawkUtils::proxy() );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TomahawkApp::messageReceived( const QString& msg )
|
||||
|
||||
void
|
||||
TomahawkApp::activate()
|
||||
{
|
||||
qDebug() << "MESSAGE RECEIVED" << msg;
|
||||
if( msg.isEmpty() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( msg.contains( "tomahawk://" ) ) {
|
||||
QString cmd = msg.mid( 11 );
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
mainWindow()->show();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
TomahawkApp::loadUrl( const QString& url )
|
||||
{
|
||||
if( url.contains( "tomahawk://" ) ) {
|
||||
QString cmd = url.mid( 11 );
|
||||
qDebug() << "tomahawk!s" << cmd;
|
||||
if( cmd.startsWith( "load/" ) ) {
|
||||
cmd = cmd.mid( 5 );
|
||||
@@ -474,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 );
|
||||
}
|
||||
|
||||
|
25
src/tomahawkapp_macdelegate.h
Normal file
25
src/tomahawkapp_macdelegate.h
Normal 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
|
Reference in New Issue
Block a user