You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdemultimedia/noatun/library/playlist.cpp

443 lines
7.7 KiB

#include <noatun/playlist.h>
#include <noatun/app.h>
#include <noatun/player.h>
#include <noatun/downloader.h>
#include <noatun/pluginloader.h>
#include <kcmdlineargs.h>
#include <kfile.h>
#include <kmimetype.h>
#include <tqregexp.h>
#include <assert.h>
#include <tqmetaobject.h>
#include <kmedia2.h>
#include <vector>
PlaylistItemData::PlaylistItemData()
{
mRefs=0;
}
PlaylistItemData::~PlaylistItemData()
{
}
TQCString PlaylistItemData::mimetype() const
{
if (isProperty("mimetype"))
return property("mimetype").latin1();
KMimeType::Ptr mimetype = KMimeType::findByURL(url());
return mimetype->name().latin1();
}
TQCString PlaylistItemData::playObject() const
{
if (isProperty("playObject"))
return property("playObject").latin1();
std::string objectType;
Arts::TraderQuery query;
query.supports("Interface","Arts::PlayObject");
query.supports("MimeType", std::string(mimetype()));
std::vector<Arts::TraderOffer> *offers = query.query();
if (!offers) return "";
if(!offers->empty())
objectType = offers->front().interfaceName();
delete offers;
return TQCString(objectType.c_str());
}
TQString PlaylistItemData::title() const
{
if (isProperty("realtitle"))
return property("realtitle");
// "$(property)"
TQString format=napp->titleFormat();
TQRegExp tqfind("(?:(?:\\\\\\\\))*\\$\\((.*)");
int start=0;
while (start != -1)
{
start = tqfind.search(format, start);
if (start == -1) break;
// test if there's an odd amount of backslashes
if (start>0 && format[start-1]=='\\')
{
// yes, so half the amount of backslashes
// count how many there are first
TQRegExp counter("([\\\\]+)");
counter.search(format, start-1);
uint len=counter.cap(1).length()-1;
// and half them, and remove one more
format.tqreplace(start-1, len/2+1, "");
start=start-1+len/2+tqfind.cap(1).length()+3;
continue;
}
// now replace the backslashes with half as many
if (format[start]=='\\')
{
// count how many there are first
TQRegExp counter("([\\\\]+)");
counter.search(format, start);
uint len=counter.cap(1).length();
// and half them
format.tqreplace(start, len/2, "");
start=start+len/2;
}
// "sth"foo"sth"
TQString cont(tqfind.cap(1));
TQString prefix,suffix,propname;
unsigned int i=0;
if (cont[i] == '"')
{
i++;
for (; i < cont.length(); i++)
{
if (cont[i] != '"')
prefix += cont[i];
else
break;
}
i++;
}
for (; i < cont.length(); ++i)
{
if (cont[i]!='"' && cont[i]!=')')
propname += cont[i];
else
break;
}
if (cont[i] == '"')
{
i++;
for (; i < cont.length(); i++)
{
if (cont[i] != '"')
suffix += cont[i];
else
break;
}
i++;
}
i++;
TQString propval = property(propname);
if (propname == "title" && !propval.length())
{
propval = url().filename();
}
else if (propname == "comment")
{
// comments can contain newlines
// these are not wanted in a formatted title
propval.tqreplace('\n', ' ');
}
if (propval.length())
{
propval = prefix+propval+suffix;
format.tqreplace(start, i+2, propval);
start += propval.length();
}
else
{
format.tqreplace(start, i+2, "");
}
}
return format;
}
int PlaylistItemData::length() const
{
return property("length", "-1").toInt();
}
void PlaylistItemData::setLength(int ms)
{
setProperty("length", TQString::number(ms));
}
PlaylistItem::PlaylistItem(const PlaylistItem &source)
{
mData=source.mData;
addRef();
}
PlaylistItem::PlaylistItem(PlaylistItemData *source)
{
mData=source;
addRef();
}
PlaylistItem::~PlaylistItem()
{
removeRef();
}
PlaylistItem &PlaylistItem::operator =(const PlaylistItem &source)
{
if (source)
source.addRef();
removeRef();
mData=source.mData;
return *this;
}
PlaylistItem &PlaylistItem::operator =(PlaylistItemData *source)
{
if (source)
source->addRef();
removeRef();
mData=source;
return *this;
}
const PlaylistItem &PlaylistItem::operator =(const PlaylistItem &source) const
{
if (source)
source.addRef();
removeRef();
mData=source.mData;
return *this;
}
const PlaylistItem &PlaylistItem::operator =(const PlaylistItemData *source) const
{
if (source)
const_cast<PlaylistItemData*>(source)->addRef();
removeRef();
mData=const_cast<PlaylistItemData*>(source);
return *this;
}
// reference counting
void PlaylistItem::removeRef() const
{
if (mData)
{
mData->removeRef();
}
}
void PlaylistItem::addRef() const
{
if (mData)
mData->addRef();
}
TQString PlaylistItemData::lengthString() const
{
if ( length() == -1 ) // no file loaded
return TQString("--:--");
int secs = length()/1000; // convert milliseconds -> seconds
int seconds = secs % 60;
return TQString().sprintf("%.2d:%.2d", ((secs-seconds)/60), seconds);
}
bool PlaylistItemData::operator == (const PlaylistItemData &d) const
{
return &d==this;
}
bool PlaylistItemData::operator != (const PlaylistItemData &d) const
{
return ! (*this==d);
}
Playlist::Playlist(TQObject *tqparent, const char *name) : TQObject(tqparent, name)
{
napp->player()->connect(this, TQT_SIGNAL(playCurrent()), TQT_SLOT(playCurrent()));
napp->player()->connect(this, TQT_SIGNAL(listHidden()), TQT_SIGNAL(playlistHidden()));
napp->player()->connect(this, TQT_SIGNAL(listShown()), TQT_SIGNAL(playlistShown()));
}
Playlist::~Playlist()
{
}
void Playlist::toggleList()
{
if (listVisible())
hideList();
else
showList();
}
int Playlist::handleArguments()
{
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
int i;
bool play= napp->autoPlay();
for (i=0; i < args->count(); i++)
{
KURL u(args->url(i));
if (u.isValid())
addFile(u, play);
play=false;
}
args->clear();
return i;
}
TQValueList<PlaylistItem> Playlist::select(
const TQStringList &keys, const TQStringList &values,
int limit, bool exact, bool caseSensitive
)
{
TQValueList<PlaylistItem> list;
TQString k;
TQString v;
TQStringList::ConstIterator key, val;
for (PlaylistItem i(getFirst()); i && limit; i=getAfter(i))
{
for (key = keys.begin(); key != keys.end() && limit ; ++key)
{
k=*key;
v=i.property(k);
for (val = values.begin(); val != values.end() && limit; ++val)
{
if ((*val).length()==0 && v.length()==0)
{
list.append(i);
limit--;
goto nextSong;
}
else if (exact)
{
if (
(!caseSensitive && (*val).lower()==v.lower())
||
(caseSensitive && (*val)==v)
)
{
list.append(i);
limit--;
goto nextSong;
}
}
else
{
if ((*val).tqfind(v, 0, caseSensitive)!=-1)
{
list.append(i);
limit--;
goto nextSong;
}
}
}
}
nextSong:
;
}
return list;
}
TQValueList<PlaylistItem> Playlist::select(
const TQString &key, const TQString &value,
int limit, bool exact, bool caseSensitive
)
{
TQStringList keys(key);
TQStringList values(value);
return select(keys, values, limit, exact, caseSensitive);
}
void PlaylistItemData::added()
{
PlaylistItem item(this);
for (
PlaylistNotifier *i=napp->player()->mNotifiers.first();
i; i=napp->player()->mNotifiers.next())
{
i->added(item);
}
}
void PlaylistItemData::removed()
{
PlaylistItem item(this);
for (
PlaylistNotifier *i=napp->player()->mNotifiers.first();
i; i=napp->player()->mNotifiers.next())
{
i->removed(item);
}
}
void PlaylistItemData::modified()
{
PlaylistItem item(this);
for (
PlaylistNotifier *i=napp->player()->mNotifiers.first();
i; i=napp->player()->mNotifiers.next())
{
i->modified(item);
}
}
PlaylistItem Playlist::nextSection()
{
return next();
}
PlaylistItem Playlist::previousSection()
{
return previous();
}
PlaylistNotifier::PlaylistNotifier()
{
napp->player()->mNotifiers.append(this);
}
PlaylistNotifier::~PlaylistNotifier()
{
napp->player()->mNotifiers.removeRef(this);
}
#include "playlist.moc"