|
|
|
/***************************************************************************
|
|
|
|
Interface to access KsCD
|
|
|
|
-------------------
|
|
|
|
begin : Sat Dec 04 13:36:00 CET 2004
|
|
|
|
copyright : (C) 2004 by Michal Startek
|
|
|
|
adapted from JuK interface which is (C) 2001-2002 by Stefan Gehn
|
|
|
|
email : michal.startek@op.pl
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* *
|
|
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#include "kscdInterface.h"
|
|
|
|
#include "kscdInterface.moc"
|
|
|
|
|
|
|
|
#include <tdeapplication.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <tqstringlist.h>
|
|
|
|
#include <tqstrlist.h>
|
|
|
|
#include <kurldrag.h>
|
|
|
|
#include <tdelocale.h>
|
|
|
|
|
|
|
|
#define TIMER_FAST 250
|
|
|
|
|
|
|
|
KsCDInterface::KsCDInterface() : PlayerInterface()
|
|
|
|
{
|
|
|
|
mKsCDTimer = new TQTimer(this, "mKsCDTimer");
|
|
|
|
|
|
|
|
connect(mKsCDTimer, TQT_SIGNAL(timeout()), TQT_SLOT(updateSlider()) );
|
|
|
|
kapp->dcopClient()->setNotifications ( true );
|
|
|
|
|
|
|
|
connect(kapp->dcopClient(), TQT_SIGNAL(applicationRegistered(const TQCString&)),
|
|
|
|
TQT_SLOT(appRegistered(const TQCString&)) );
|
|
|
|
|
|
|
|
connect(kapp->dcopClient(), TQT_SIGNAL(applicationRemoved(const TQCString&)),
|
|
|
|
TQT_SLOT(appRemoved(const TQCString&)));
|
|
|
|
|
|
|
|
TQTimer::singleShot(0, this, TQT_SLOT(myInit()));
|
|
|
|
}
|
|
|
|
|
|
|
|
KsCDInterface::~KsCDInterface()
|
|
|
|
{
|
|
|
|
kapp->dcopClient()->setNotifications(false);
|
|
|
|
delete mKsCDTimer;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KsCDInterface::myInit()
|
|
|
|
{
|
|
|
|
// Start the timer if KsCD is already running
|
|
|
|
// Needed if user adds applet while running KsCD
|
|
|
|
if (findRunningKsCD())
|
|
|
|
{
|
|
|
|
emit playerStarted();
|
|
|
|
mKsCDTimer->start(TIMER_FAST);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
emit playerStopped();
|
|
|
|
emit newSliderPosition(0,0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KsCDInterface::appRegistered(const TQCString &appId)
|
|
|
|
{
|
|
|
|
if((appId) == "kscd")
|
|
|
|
{
|
|
|
|
mAppId = appId;
|
|
|
|
emit playerStarted();
|
|
|
|
mKsCDTimer->start(TIMER_FAST);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KsCDInterface::appRemoved(const TQCString &appId)
|
|
|
|
{
|
|
|
|
if ((appId) == "kscd")
|
|
|
|
{
|
|
|
|
// is there still another KsCD alive?
|
|
|
|
// Okay, KsCD does not allow multiple instances
|
|
|
|
// of it to run at the same time, but
|
|
|
|
// this can change.
|
|
|
|
if (findRunningKsCD())
|
|
|
|
return;
|
|
|
|
mKsCDTimer->stop();
|
|
|
|
emit playerStopped();
|
|
|
|
emit newSliderPosition(0,0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KsCDInterface::updateSlider()
|
|
|
|
{
|
|
|
|
// length/time in secs, -1 means "no playobject in kscd"
|
|
|
|
int len = -1;
|
|
|
|
int time = -1;
|
|
|
|
TQByteArray data, replyData;
|
|
|
|
TQCString replyType;
|
|
|
|
|
|
|
|
if (kapp->dcopClient()->call(mAppId, "CDPlayer", "currentTrackLength()", data,
|
|
|
|
replyType, replyData))
|
|
|
|
{
|
|
|
|
TQDataStream reply(replyData, IO_ReadOnly);
|
|
|
|
if (replyType == "int")
|
|
|
|
reply >> len;
|
|
|
|
}
|
|
|
|
|
|
|
|
data = 0;
|
|
|
|
replyData = 0;
|
|
|
|
replyType = 0;
|
|
|
|
|
|
|
|
if (kapp->dcopClient()->call(mAppId, "CDPlayer", "currentPosition()", data,
|
|
|
|
replyType, replyData))
|
|
|
|
{
|
|
|
|
TQDataStream reply(replyData, IO_ReadOnly);
|
|
|
|
if (replyType == "int")
|
|
|
|
reply >> time;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( (time < 0) || (len < 0)) // KsCD isn't playing and thus returns -1
|
|
|
|
{
|
|
|
|
len = 0;
|
|
|
|
time = 0;
|
|
|
|
}
|
|
|
|
emit newSliderPosition(len,time);
|
|
|
|
emit playingStatusChanged(playingStatus());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Drag-n-Drop stuff =================================================================
|
|
|
|
// As far as I know there is currently no way to drag an AudioCD track to KsCD,
|
|
|
|
// or even no application to drag AudioCD track from (not the KIO-wrapped track
|
|
|
|
// path (audiocd:/...) like from Konqueror)
|
|
|
|
|
|
|
|
void KsCDInterface::dragEnterEvent(TQDragEnterEvent* event)
|
|
|
|
{
|
|
|
|
event->ignore();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KsCDInterface::dropEvent(TQDropEvent* event)
|
|
|
|
{
|
|
|
|
event->ignore();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ====================================================================================
|
|
|
|
|
|
|
|
void KsCDInterface::sliderStartDrag()
|
|
|
|
{
|
|
|
|
mKsCDTimer->stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KsCDInterface::sliderStopDrag()
|
|
|
|
{
|
|
|
|
mKsCDTimer->start(TIMER_FAST);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KsCDInterface::jumpToTime(int sec)
|
|
|
|
{
|
|
|
|
TQByteArray data;
|
|
|
|
TQDataStream arg(data, IO_WriteOnly);
|
|
|
|
arg << sec;
|
|
|
|
kapp->dcopClient()->send(mAppId, "CDPlayer", "jumpTo(int)", data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KsCDInterface::playpause()
|
|
|
|
{
|
|
|
|
if (!findRunningKsCD())
|
|
|
|
startPlayer("kscd");
|
|
|
|
TQByteArray data;
|
|
|
|
kapp->dcopClient()->send(mAppId, "CDPlayer", "play()", data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KsCDInterface::stop()
|
|
|
|
{
|
|
|
|
TQByteArray data;
|
|
|
|
kapp->dcopClient()->send(mAppId, "CDPlayer", "stop()", data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KsCDInterface::next()
|
|
|
|
{
|
|
|
|
TQByteArray data;
|
|
|
|
kapp->dcopClient()->send(mAppId, "CDPlayer", "next()", data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KsCDInterface::prev()
|
|
|
|
{
|
|
|
|
TQByteArray data;
|
|
|
|
kapp->dcopClient()->send(mAppId, "CDPlayer", "previous()", data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KsCDInterface::volumeUp()
|
|
|
|
{
|
|
|
|
TQByteArray data;
|
|
|
|
kapp->dcopClient()->send(mAppId, "CDPlayer", "volumeUp()", data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KsCDInterface::volumeDown()
|
|
|
|
{
|
|
|
|
TQByteArray data;
|
|
|
|
kapp->dcopClient()->send(mAppId, "CDPlayer", "volumeDown()", data);
|
|
|
|
}
|
|
|
|
|
|
|
|
const TQString KsCDInterface::getTrackTitle() const
|
|
|
|
{
|
|
|
|
TQString title, artist, album, result;
|
|
|
|
TQByteArray data, replyData;
|
|
|
|
TQCString replyType;
|
|
|
|
|
|
|
|
// Get track title from KsCD...
|
|
|
|
if (kapp->dcopClient()->call(mAppId, "CDPlayer", "currentTrackTitle()", data,
|
|
|
|
replyType, replyData))
|
|
|
|
{
|
|
|
|
TQDataStream reply(replyData, IO_ReadOnly);
|
|
|
|
if (replyType == TQSTRING_OBJECT_NAME_STRING)
|
|
|
|
{
|
|
|
|
reply >> title;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Album...
|
|
|
|
if (kapp->dcopClient()->call(mAppId, "CDPlayer", "currentAlbum()", data,
|
|
|
|
replyType, replyData))
|
|
|
|
{
|
|
|
|
TQDataStream reply(replyData, IO_ReadOnly);
|
|
|
|
if (replyType == TQSTRING_OBJECT_NAME_STRING)
|
|
|
|
{
|
|
|
|
reply >> album;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Artist...
|
|
|
|
if (kapp->dcopClient()->call(mAppId, "CDPlayer", "currentArtist()", data,
|
|
|
|
replyType, replyData))
|
|
|
|
{
|
|
|
|
TQDataStream reply(replyData, IO_ReadOnly);
|
|
|
|
if (replyType == TQSTRING_OBJECT_NAME_STRING)
|
|
|
|
{
|
|
|
|
reply >> artist;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// And compose them into one string that will be displayed...
|
|
|
|
if(album.isEmpty())
|
|
|
|
{
|
|
|
|
if(artist.isEmpty())
|
|
|
|
{
|
|
|
|
result = title;
|
|
|
|
}
|
|
|
|
else // artist is non-empty
|
|
|
|
{
|
|
|
|
if(title.isEmpty())
|
|
|
|
{
|
|
|
|
result = artist;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
result = i18n("artist - trackname", "%1 - %2").arg(artist, title);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else // album is non-empty
|
|
|
|
{
|
|
|
|
if(artist.isEmpty())
|
|
|
|
{
|
|
|
|
if(title.isEmpty())
|
|
|
|
{
|
|
|
|
result = album;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
result = i18n("(album) - trackname", "(%1) - %2").arg(artist, title);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else // artist is non-empty
|
|
|
|
{
|
|
|
|
if(title.isEmpty())
|
|
|
|
{
|
|
|
|
result = i18n("artistname (albumname)", "%1 (%2)").arg(artist, album);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
result = i18n("artistname (albumname) - trackname", "%1 (%2) - %3").arg(artist, album, title);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KsCDInterface::findRunningKsCD()
|
|
|
|
{
|
|
|
|
QCStringList allApps = kapp->dcopClient()->registeredApplications();
|
|
|
|
TQValueList<TQCString>::const_iterator iterator;
|
|
|
|
|
|
|
|
for (iterator = allApps.constBegin(); iterator != allApps.constEnd(); ++iterator)
|
|
|
|
{
|
|
|
|
if ((*iterator) == "kscd")
|
|
|
|
{
|
|
|
|
mAppId = *iterator;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int KsCDInterface::playingStatus()
|
|
|
|
{
|
|
|
|
TQByteArray data, replyData;
|
|
|
|
TQCString replyType;
|
|
|
|
|
|
|
|
if (kapp->dcopClient()->call(mAppId, "CDPlayer", "getStatus()", data, replyType,
|
|
|
|
replyData))
|
|
|
|
{
|
|
|
|
int status = 0;
|
|
|
|
TQDataStream reply(replyData, IO_ReadOnly);
|
|
|
|
if (replyType == "int")
|
|
|
|
reply >> status;
|
|
|
|
|
|
|
|
switch (status)
|
|
|
|
{
|
|
|
|
case 2:
|
|
|
|
return Playing;
|
|
|
|
case 4:
|
|
|
|
return Paused;
|
|
|
|
default:
|
|
|
|
return Stopped;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Stopped;
|
|
|
|
}
|