#include #include #include #include #include #include #include #include #include #include #include #include #include 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 *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 find("(?:(?:\\\\\\\\))*\\$\\((.*)"); int start=0; while (start != -1) { start = find.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.replace(start-1, len/2+1, ""); start=start-1+len/2+find.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.replace(start, len/2, ""); start=start+len/2; } // "sth"foo"sth" TQString cont(find.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.replace('\n', ' '); } if (propval.length()) { propval = prefix+propval+suffix; format.replace(start, i+2, propval); start += propval.length(); } else { format.replace(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(source)->addRef(); removeRef(); mData=const_cast(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 *parent, const char *name) : TQObject(parent, 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 Playlist::select( const TQStringList &keys, const TQStringList &values, int limit, bool exact, bool caseSensitive ) { TQValueList 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).find(v, 0, caseSensitive)!=-1) { list.append(i); limit--; goto nextSong; } } } } nextSong: ; } return list; } TQValueList 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"