/*************************************************************************** begin : Tue Nov 9 2004 copyright : (C) 2004 by Scott Wheeler email : wheeler@kde.org ***************************************************************************/ /*************************************************************************** * * * 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 #include #include #include #include #include #include #include #include #include #include #include #include "nowplaying.h" #include "playlistcollection.h" #include "playermanager.h" #include "coverinfo.h" #include "covermanager.h" #include "tag.h" #include "playlistitem.h" #include "collectionlist.h" #include "historyplaylist.h" static const int imageSize = 64; struct Line : public TQFrame { Line(TQWidget *parent) : TQFrame(parent) { setFrameShape(VLine); } }; //////////////////////////////////////////////////////////////////////////////// // NowPlaying //////////////////////////////////////////////////////////////////////////////// NowPlaying::NowPlaying(TQWidget *parent, PlaylistCollection *collection, const char *name) : TQHBox(parent, name), m_observer(this, collection), m_collection(collection) { // m_observer is set to watch the PlaylistCollection, also watch for // changes that come from CollectionList. CollectionList::instance()->addObserver(&m_observer); layout()->setMargin(5); layout()->setSpacing(3); setFixedHeight(imageSize + 2 + layout()->margin() * 2); setStretchFactor(new CoverItem(this), 0); setStretchFactor(new TrackItem(this), 2); setStretchFactor(new Line(this), 0); setStretchFactor(new HistoryItem(this), 1); connect(PlayerManager::instance(), TQT_SIGNAL(signalPlay()), this, TQT_SLOT(slotUpdate())); connect(PlayerManager::instance(), TQT_SIGNAL(signalStop()), this, TQT_SLOT(slotUpdate())); hide(); } void NowPlaying::addItem(NowPlayingItem *item) { m_items.append(item); } PlaylistCollection *NowPlaying::collection() const { return m_collection; } void NowPlaying::slotUpdate() { FileHandle file = PlayerManager::instance()->playingFile(); if(file.isNull()) { hide(); return; } else show(); for(TQValueList::Iterator it = m_items.begin(); it != m_items.end(); ++it) { (*it)->update(file); } } //////////////////////////////////////////////////////////////////////////////// // CoverItem //////////////////////////////////////////////////////////////////////////////// CoverItem::CoverItem(NowPlaying *parent) : TQLabel(parent, "CoverItem"), NowPlayingItem(parent) { setFixedHeight(parent->height() - parent->layout()->margin() * 2); setFrameStyle(Box | Plain); setLineWidth(1); setMargin(1); setAcceptDrops(true); } void CoverItem::update(const FileHandle &file) { m_file = file; if(file.coverInfo()->hasCover()) { show(); TQImage image = file.coverInfo()->pixmap(CoverInfo::Thumbnail).convertToImage(); setPixmap(image.smoothScale(imageSize, imageSize, TQ_ScaleMin)); } else hide(); } void CoverItem::mouseReleaseEvent(TQMouseEvent *event) { if(m_dragging) { m_dragging = false; return; } if(event->x() >= 0 && event->y() >= 0 && event->x() < width() && event->y() < height() && event->button() == Qt::LeftButton && m_file.coverInfo()->hasCover()) { m_file.coverInfo()->popup(); } TQLabel::mousePressEvent(event); } void CoverItem::mousePressEvent(TQMouseEvent *e) { m_dragging = false; m_dragStart = e->globalPos(); } void CoverItem::mouseMoveEvent(TQMouseEvent *e) { if(m_dragging) return; TQPoint diff = m_dragStart - e->globalPos(); if(TQABS(diff.x()) > 1 || TQABS(diff.y()) > 1) { // Start a drag. m_dragging = true; CoverDrag *drag = new CoverDrag(m_file.coverInfo()->coverId(), this); drag->drag(); } } void CoverItem::dragEnterEvent(TQDragEnterEvent *e) { e->accept(TQImageDrag::canDecode(e) || KURLDrag::canDecode(e) || CoverDrag::canDecode(e)); } void CoverItem::dropEvent(TQDropEvent *e) { TQImage image; KURL::List urls; coverKey key; if(e->source() == this) return; if(TQImageDrag::decode(e, image)) { m_file.coverInfo()->setCover(image); update(m_file); } else if(CoverDrag::decode(e, key)) { m_file.coverInfo()->setCoverId(key); update(m_file); } else if(KURLDrag::decode(e, urls)) { TQString fileName; if(TDEIO::NetAccess::download(urls.front(), fileName, this)) { if(image.load(fileName)) { m_file.coverInfo()->setCover(image); update(m_file); } else kdError(65432) << "Unable to load image from " << urls.front() << endl; TDEIO::NetAccess::removeTempFile(fileName); } else kdError(65432) << "Unable to download " << urls.front() << endl; } } //////////////////////////////////////////////////////////////////////////////// // TrackItem //////////////////////////////////////////////////////////////////////////////// TrackItem::TrackItem(NowPlaying *parent) : TQWidget(parent, "TrackItem"), NowPlayingItem(parent) { setFixedHeight(parent->height() - parent->layout()->margin() * 2); setSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Fixed); TQVBoxLayout *layout = new TQVBoxLayout(this); m_label = new LinkLabel(this); m_label->setLinkUnderline(false); layout->addStretch(); layout->addWidget(m_label); layout->addStretch(); connect(m_label, TQT_SIGNAL(linkClicked(const TQString &)), this, TQT_SLOT(slotOpenLink(const TQString &))); } void TrackItem::update(const FileHandle &file) { m_file = file; TQTimer::singleShot(0, this, TQT_SLOT(slotUpdate())); } void TrackItem::slotOpenLink(const TQString &link) { PlaylistCollection *collection = NowPlayingItem::parent()->collection(); if(link == "artist") collection->showMore(m_file.tag()->artist()); else if(link == "album") collection->showMore(m_file.tag()->artist(), m_file.tag()->album()); else if(link == "clear") collection->clearShowMore(); update(m_file); } void TrackItem::slotUpdate() { TQString title = TQStyleSheet::escape(m_file.tag()->title()); TQString artist = TQStyleSheet::escape(m_file.tag()->artist()); TQString album = TQStyleSheet::escape(m_file.tag()->album()); TQString separator = (artist.isNull() || album.isNull()) ? TQString() : TQString(" - "); // This block-o-nastiness makes the font smaller and smaller until it actually fits. int size = 4; TQString format = "%2" "
" "%4%5%6"; if(NowPlayingItem::parent()->collection()->showMoreActive()) format.append(TQString(" (%1)").arg(i18n("back to playlist"))); format.append(""); do { m_label->setText(format.arg(size).arg(title).arg(size - 2) .arg(artist).arg(separator).arg(album)); --size; } while(m_label->heightForWidth(m_label->width()) > imageSize && size >= 0); m_label->setFixedHeight(TQMIN(imageSize, m_label->heightForWidth(m_label->width()))); } //////////////////////////////////////////////////////////////////////////////// // HistoryItem //////////////////////////////////////////////////////////////////////////////// HistoryItem::HistoryItem(NowPlaying *parent) : LinkLabel(parent, "HistoryItem"), NowPlayingItem(parent) { setFixedHeight(parent->height() - parent->layout()->margin() * 2); setSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Fixed); setLinkUnderline(false); setText(TQString("%1").arg(i18n("History"))); m_timer = new TQTimer(this); connect(m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotAddPlaying())); } void HistoryItem::update(const FileHandle &file) { if(file.isNull() || (!m_history.isEmpty() && m_history.front().file == file)) return; if(m_history.count() >= 10) m_history.remove(m_history.fromLast()); TQString format = "
%2"; TQString current = TQString("%1").arg(i18n("History")); TQString previous; for(TQValueList::ConstIterator it = m_history.begin(); it != m_history.end(); ++it) { previous = current; current.append(format.arg((*it).anchor).arg(TQStyleSheet::escape((*it).file.tag()->title()))); setText(current); if(heightForWidth(width()) > imageSize) { setText(previous); break; } } m_file = file; m_timer->stop(); m_timer->start(HistoryPlaylist::delay(), true); } void HistoryItem::openLink(const TQString &link) { for(TQValueList::ConstIterator it = m_history.begin(); it != m_history.end(); ++it) { if((*it).anchor == link) { if((*it).playlist) { CollectionListItem *collectionItem = CollectionList::instance()->lookup((*it).file.absFilePath()); PlaylistItem *item = collectionItem->itemForPlaylist((*it).playlist); (*it).playlist->clearSelection(); (*it).playlist->setSelected(item, true); (*it).playlist->ensureItemVisible(item); NowPlayingItem::parent()->collection()->raise((*it).playlist); } break; } } } void HistoryItem::slotAddPlaying() { // More or less copied from the HistoryPlaylist PlayerManager *manager = PlayerManager::instance(); if(manager->playing() && manager->playingFile() == m_file) { m_history.prepend(Item(TDEApplication::randomString(20), m_file, Playlist::playingItem()->playlist())); } m_file = FileHandle::null(); } #include "nowplaying.moc" // vim: set et sw=4 ts=8: