Index: runtime/knotify/notifybysound.h =================================================================== --- runtime/knotify/notifybysound.h (revision 1204313) +++ runtime/knotify/notifybysound.h (working copy) @@ -43,12 +43,17 @@ public: void setVolume( int v ); + void canberraDone( int id ); +/* protected: void timerEvent(QTimerEvent *); +*/ private Q_SLOTS: +/* void slotSoundFinished(int id); +*/ void closeNow(); }; Index: runtime/knotify/CMakeLists.txt =================================================================== --- runtime/knotify/CMakeLists.txt (revision 1204313) +++ runtime/knotify/CMakeLists.txt (working copy) @@ -1,3 +1,6 @@ +pkg_check_modules(CANBERRA libcanberra) +macro_log_feature(CANBERRA_FOUND "libcanberra" "libcanberra audio library" "http://0pointer.de/lennart/projects/libcanberra/" FALSE "" "libcanberra is needed for knotify event sounds") + add_subdirectory( sounds ) ########### next target ############### @@ -41,8 +44,10 @@ set_target_properties(knotify PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Notify") endif (Q_WS_MAC) -target_link_libraries( knotify ${KDE4_KDEUI_LIBS} ${KDE4_PHONON_LIBS} ${KDE4_SOLID_LIBS} knotifyplugin) +include_directories(${CANBERRA_INCLUDE_DIRS}) +target_link_libraries( knotify ${KDE4_KDEUI_LIBS} ${KDE4_PHONON_LIBS} ${KDE4_SOLID_LIBS} ${CANBERRA_LIBRARIES} knotifyplugin) + target_link_libraries( knotifyplugin ${KDE4_KDECORE_LIBS} ${KDE4_KDEUI_LIBS}) Index: runtime/knotify/notifybysound.cpp =================================================================== --- runtime/knotify/notifybysound.cpp (revision 1204313) +++ runtime/knotify/notifybysound.cpp (working copy) @@ -51,6 +51,10 @@ #include #include +// Canberra headers +#include + +/* struct Player { Player() @@ -128,11 +132,13 @@ p->setVolume(v); } } +*/ class NotifyBySound::Private { public: - enum { NoSound, UsePhonon, ExternalPlayer } playerMode; + enum { NoSound, UseCanberra /*, UsePhonon, ExternalPlayer*/ } playerMode; +/* QString externalPlayer; QHash processes; @@ -140,23 +146,46 @@ QSignalMapper *signalmapper; PlayerPool playerPool; QBasicTimer poolTimer; +*/ QQueue closeQueue; int volume; + ca_context* canberra; }; +static void canberra_callback(ca_context *, uint32_t id, int, void *userdata) +{ + Q_ASSERT(userdata); + NotifyBySound* notify = reinterpret_cast(userdata); + notify->canberraDone(id); +} + NotifyBySound::NotifyBySound(QObject *parent) : KNotifyPlugin(parent),d(new Private) { +/* d->signalmapper = new QSignalMapper(this); connect(d->signalmapper, SIGNAL(mapped(int)), this, SLOT(slotSoundFinished(int))); +*/ loadConfig(); + d->canberra = NULL; + if (Private::UseCanberra == d->playerMode) + { + int rv; + if ((rv = ca_context_create(&d->canberra)) < 0) + { + kDebug() << "Unable to initialise Canberra" << ca_strerror(rv); + d->playerMode = Private::NoSound; + } + } } NotifyBySound::~NotifyBySound() { + if (d->canberra) + ca_context_destroy(d->canberra); delete d; } @@ -167,6 +196,8 @@ KSharedConfig::Ptr kc = KGlobal::config(); KConfigGroup cg(kc, "Sounds"); + d->playerMode = Private::UseCanberra; +/* d->playerMode = Private::UsePhonon; if(cg.readEntry( "Use external player", false )) { @@ -183,7 +214,7 @@ } } } - else if(cg.readEntry( "No sound" , false )) + else*/ if(cg.readEntry( "No sound" , false )) { d->playerMode = Private::NoSound; } @@ -202,16 +233,28 @@ return; } +/* if(d->playerObjects.contains(eventId) || d->processes.contains(eventId) ) { //a sound is already playing for this notification, we don't support playing two sounds. finish( eventId ); return; } +*/ KUrl soundFileURL = config->readEntry( "Sound" , true ); QString soundFile = soundFileURL.toLocalFile(); + // Check for FDO Sound Theme Spec Format + QString soundThemeName = ""; + if (soundFileURL.protocol() == "sound-theme" && soundFileURL.host().size() > 0) + { + soundThemeName = soundFileURL.host(); + kDebug() << "Using sound theme id" << soundThemeName; + } + else + { + if (soundFile.isEmpty()) { finish( eventId ); @@ -234,7 +277,35 @@ return; } + } + kDebug() << " going to play " << soundFile; + if (Private::UseCanberra == d->playerMode) + { + kDebug() << "Using Canberra for" << eventId; + Q_ASSERT(d->canberra); + ca_proplist* proplist; + ca_proplist_create(&proplist); + Q_ASSERT(proplist); + + ca_proplist_sets(proplist, CA_PROP_MEDIA_ROLE, "event"); + ca_proplist_sets(proplist, CA_PROP_CANBERRA_CACHE_CONTROL, "permanent"); + + if (!soundThemeName.isEmpty()) + ca_proplist_sets(proplist, CA_PROP_EVENT_ID, soundThemeName.toUtf8().constData()); + else + ca_proplist_sets(proplist, CA_PROP_MEDIA_FILENAME, soundFile.toUtf8().constData()); + + // TODO Set volume: CA_PROP_CANBERRA_VOLUME is in dB, so not directly related to 0-100% + int rv; + if ((rv = ca_context_play_full(d->canberra, eventId, proplist, canberra_callback, this)) < 0) { + kDebug() << "Unable to trigger Canberra Play :( " << ca_strerror(rv); + finish(eventId); + } + + ca_proplist_destroy(proplist); + } +/* d->poolTimer.stop(); if(d->playerMode == Private::UsePhonon) @@ -256,6 +327,7 @@ (*proc) << d->externalPlayer << soundFile; proc->start(); } +*/ } @@ -264,10 +336,19 @@ if ( volume<0 ) volume=0; if ( volume>=100 ) volume=100; d->volume = volume; +/* d->playerPool.setVolume(d->volume / 100.0); +*/ } +void NotifyBySound::canberraDone( int id ) +{ + Q_ASSERT(Private::UseCanberra == d->playerMode); + kDebug() << "Canberra is done with" << id; + finish(id); +} +/* void NotifyBySound::timerEvent(QTimerEvent *e) { if (e->timerId() == d->poolTimer.timerId()) { @@ -295,6 +376,7 @@ } finish(id); } +*/ void NotifyBySound::close(int id) { @@ -307,6 +389,12 @@ void NotifyBySound::closeNow() { const int id = d->closeQueue.dequeue(); + if (Private::UseCanberra == d->playerMode) + { + Q_ASSERT(d->canberra); + ca_context_cancel(d->canberra, id); + } +/* if(d->playerObjects.contains(id)) { Player *p = d->playerObjects.take(id); @@ -320,6 +408,7 @@ d->processes[id]->deleteLater(); d->processes.remove(id); } +*/ } #include "notifybysound.moc" Index: runtime/kcontrol/knotify/knotify.cpp =================================================================== --- runtime/kcontrol/knotify/knotify.cpp (revision 1204438) +++ runtime/kcontrol/knotify/knotify.cpp (working copy) @@ -221,28 +221,17 @@ load(); - connect( m_ui->cbExternal, SIGNAL( toggled( bool ) ), this, SLOT( externalToggled( bool ) ) ); connect( m_ui->cbArts, SIGNAL(clicked(bool)), this, SLOT(slotChanged())); - connect( m_ui->cbExternal, SIGNAL(clicked(bool)), this, SLOT(slotChanged())); connect( m_ui->cbNone, SIGNAL(clicked(bool)), this, SLOT(slotChanged())); - connect( m_ui->volumeSlider, SIGNAL( valueChanged ( int ) ), this, SLOT( slotChanged() ) ); - connect( m_ui->reqExternal, SIGNAL( textChanged( const QString& ) ), this, SLOT( slotChanged() ) ); - m_ui->reqExternal->setMode(KFile::File|KFile::ExistingOnly|KFile::LocalOnly); } void PlayerSettingsDialog::load() { KConfig _config( "knotifyrc", KConfig::NoGlobals ); KConfigGroup config(&_config, "Sounds" ); - bool useExternal = config.readEntry( "Use external player", false ); - m_ui->cbExternal->setChecked( useExternal ); - m_ui->reqExternal->setUrl( config.readPathEntry( "External player", QString() ) ); - m_ui->volumeSlider->setValue( config.readEntry( "Volume", 100 ) ); - if ( !m_ui->cbExternal->isChecked() ) - { - m_ui->cbNone->setChecked( config.readEntry( "No sound", false ) ); - } + m_ui->cbNone->setChecked( config.readEntry( "No sound", false ) ); + emit changed( false ); m_change=false; } @@ -256,9 +245,6 @@ KConfig _config("knotifyrc", KConfig::NoGlobals); KConfigGroup config(&_config, "Sounds" ); - config.writePathEntry( "External player", m_ui->reqExternal->url().path() ); - config.writeEntry( "Use external player", m_ui->cbExternal->isChecked() ); - config.writeEntry( "Volume", m_ui->volumeSlider->value() ); config.writeEntry( "No sound", m_ui->cbNone->isChecked() ); config.sync(); @@ -282,14 +268,6 @@ emit changed(true); } -void PlayerSettingsDialog::externalToggled( bool on ) -{ - if ( on ) - m_ui->reqExternal->setFocus(); - else - m_ui->reqExternal->clearFocus(); -} - PlayerSettingsDialog::~ PlayerSettingsDialog( ) { delete m_ui; Index: runtime/kcontrol/knotify/knotify.h =================================================================== --- runtime/kcontrol/knotify/knotify.h (revision 1204438) +++ runtime/kcontrol/knotify/knotify.h (working copy) @@ -74,7 +74,6 @@ void defaults(); protected Q_SLOTS: - void externalToggled( bool on ); void slotChanged(); signals: Index: runtime/kcontrol/knotify/playersettings.ui =================================================================== --- runtime/kcontrol/knotify/playersettings.ui (revision 1204438) +++ runtime/kcontrol/knotify/playersettings.ui (working copy) @@ -22,141 +22,6 @@ - - - 0 - - - - - 100% - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 261 - 16 - - - - - - - - 0% - - - - - - - &Volume: - - - volumeSlider - - - - - - - 100 - - - 10 - - - 100 - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 20 - 41 - - - - - - - - - - &Use an external player - - - - - - - 0 - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - false - - - &Player: - - - reqExternal - - - - - - - false - - - - 10 - 0 - - - - - - - &No audio output @@ -178,111 +43,6 @@ - - - KUrlRequester - QWidget -
kurlrequester.h
- 1 -
-
- - - cbArts - toggled(bool) - volumeSlider - setEnabled(bool) - - - 84 - 31 - - - 126 - 60 - - - - - cbArts - toggled(bool) - textLabel3 - setEnabled(bool) - - - 234 - 34 - - - 308 - 83 - - - - - cbArts - toggled(bool) - textLabel4 - setEnabled(bool) - - - 49 - 32 - - - 62 - 61 - - - - - cbArts - toggled(bool) - textLabel2 - setEnabled(bool) - - - 161 - 27 - - - 108 - 85 - - - - - cbExternal - toggled(bool) - textLabel5 - setEnabled(bool) - - - 87 - 114 - - - 86 - 143 - - - - - cbExternal - toggled(bool) - reqExternal - setEnabled(bool) - - - 236 - 112 - - - 240 - 137 - - - - +