/*************************************************************************** begin : Sat Jun 7 2003 copyright : (C) 2003 - 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 "viewmode.h" #include "playlistbox.h" #include "searchplaylist.h" #include "treeviewitemplaylist.h" #include "collectionlist.h" //////////////////////////////////////////////////////////////////////////////// // ViewMode //////////////////////////////////////////////////////////////////////////////// ViewMode::ViewMode(PlaylistBox *b) : TQObject(b), m_playlistBox(b), m_visible(false), m_needsRefresh(false) { m_playlistBox->viewport()->installEventFilter(this); } ViewMode::~ViewMode() { } void ViewMode::paintCell(PlaylistBox::Item *item, TQPainter *painter, const TQColorGroup &colorGroup, int column, int width, int) { if(width < item->pixmap(column)->width()) return; if(m_needsRefresh) updateHeights(); TQFontMetrics fm = painter->fontMetrics(); int y = item->listView()->itemMargin() + border; const TQPixmap *pm = item->pixmap(column); if(item->isSelected()) { painter->eraseRect(0, 0, width, item->height()); TQPen oldPen = painter->pen(); TQPen newPen = oldPen; newPen.setWidth(5); newPen.setJoinStyle(Qt::RoundJoin); newPen.setColor(TQColorGroup::Highlight); painter->setPen(newPen); painter->drawRect(border, border, width - border * 2, item->height() - border * 2 + 1); painter->setPen(oldPen); painter->fillRect(border, border, width - border * 2, item->height() - border * 2 + 1, colorGroup.brush(TQColorGroup::Highlight)); painter->setPen(colorGroup.highlightedText()); } else painter->eraseRect(0, 0, width, item->height()); if (!pm->isNull()) { int x = (width - pm->width()) / 2; x = TQMAX(x, item->listView()->itemMargin()); painter->drawPixmap(x, y, *pm); } y += pm->height() + fm.height() - fm.descent(); for(TQStringList::Iterator it = m_lines[item].begin(); it != m_lines[item].end(); ++it) { int x = (width - fm.width(*it)) / 2; x = TQMAX(x, item->listView()->itemMargin()); painter->drawText(x, y, *it); y += fm.height() - fm.descent(); } if(item == item->listView()->dropItem()) paintDropIndicator(painter, width, item->height()); } bool ViewMode::eventFilter(TQObject *watched, TQEvent *e) { if(m_visible && TQT_BASE_OBJECT(watched) == TQT_BASE_OBJECT(m_playlistBox->viewport()) && e->type() == TQEvent::Resize) { TQResizeEvent *re = TQT_TQRESIZEEVENT(e); if(re->size().width() != re->oldSize().width()) m_needsRefresh = true; } if(e->type() == TQEvent::Hide) m_needsRefresh = true; return TQObject::eventFilter(watched, e); } void ViewMode::setShown(bool shown) { m_visible = shown; if(shown) { updateIcons(32); m_needsRefresh = true; } } void ViewMode::updateIcons(int size) { for(TQListViewItemIterator it(m_playlistBox); it.current(); ++it) { PlaylistBox::Item *i = static_cast(*it); i->setPixmap(0, SmallIcon(i->iconName(), size)); } } void ViewMode::setupItem(PlaylistBox::Item *item) const { const PlaylistBox *box = item->listView(); const int width = box->width() - box->verticalScrollBar()->width() - border * 2; const int baseHeight = 2 * box->itemMargin() + 32 + border * 2; const TQFontMetrics fm = box->fontMetrics(); item->setHeight(baseHeight + (fm.height() - fm.descent()) * lines(item, fm, width).count()); } void ViewMode::updateHeights() { const int width = m_playlistBox->width() - m_playlistBox->verticalScrollBar()->width() - border * 2; const int baseHeight = 2 * m_playlistBox->itemMargin() + 32 + border * 2; const TQFontMetrics fm = m_playlistBox->fontMetrics(); for(TQListViewItemIterator it(m_playlistBox); it.current(); ++it) { PlaylistBox::Item *i = static_cast(it.current()); m_lines[i] = lines(i, fm, width); const int height = baseHeight + (fm.height() - fm.descent()) * m_lines[i].count(); i->setHeight(height); } m_needsRefresh = false; } void ViewMode::paintDropIndicator(TQPainter *painter, int width, int height) // static { static const int border = 1; static const int lineWidth = 2; TQPen oldPen = painter->pen(); TQPen newPen = oldPen; newPen.setWidth(lineWidth); newPen.setStyle(Qt::DotLine); painter->setPen(newPen); painter->drawRect(border, border, width - border * 2, height - border * 2); painter->setPen(oldPen); } TQStringList ViewMode::lines(const PlaylistBox::Item *item, const TQFontMetrics &fm, int width) { // Here 32 is a bit arbitrary, but that's the width of the icons in this // mode and seems to a reasonable lower bound. if(width < 32) return TQStringList(); TQString line = item->text(); TQStringList l; while(!line.isEmpty()) { int textLength = line.length(); while(textLength > 0 && fm.width(line.mid(0, textLength).stripWhiteSpace()) + item->listView()->itemMargin() * 2 > width) { int i = line.findRev(TQRegExp( "\\W"), textLength - 1); if(i > 0) textLength = i; else textLength--; } l.append(line.mid(0, textLength).stripWhiteSpace()); line = line.mid(textLength); } return l; } /////////////////////////////////////////////////////////////////////////////// // CompactViewMode //////////////////////////////////////////////////////////////////////////////// CompactViewMode::CompactViewMode(PlaylistBox *b) : ViewMode(b) { } CompactViewMode::~CompactViewMode() { } void CompactViewMode::paintCell(PlaylistBox::Item *item, TQPainter *painter, const TQColorGroup &colorGroup, int column, int width, int align) { item->TDEListViewItem::paintCell(painter, colorGroup, column, width, align); if(item == item->listView()->dropItem()) paintDropIndicator(painter, width, item->height()); } void CompactViewMode::setShown(bool shown) { setVisible(shown); if(shown) { updateIcons(16); updateHeights(); } } void CompactViewMode::updateHeights() { for(TQListViewItemIterator it(playlistBox()); it.current(); ++it) it.current()->setup(); } //////////////////////////////////////////////////////////////////////////////// // TreeViewMode //////////////////////////////////////////////////////////////////////////////// TreeViewMode::TreeViewMode(PlaylistBox *b) : CompactViewMode(b), m_treeViewItems(5003, false), m_dynamicListsFrozen(false), m_setup(false) { } TreeViewMode::~TreeViewMode() { } void TreeViewMode::setShown(bool show) { CompactViewMode::setShown(show); playlistBox()->setRootIsDecorated(show); if(show) { PlaylistBox::Item *collectionItem = PlaylistBox::Item::collectionItem(); if(!collectionItem) return; if(collectionItem && m_searchCategories.isEmpty()) setupDynamicPlaylists(); else { for(TQDictIterator it(m_searchCategories); it.current(); ++it) it.current()->setVisible(true); } if(!m_setup) { m_setup = true; playlistBox()->setSorting(-1); CollectionList::instance()->setupTreeViewEntries(this); playlistBox()->setSorting(0); playlistBox()->sort(); } } else { for(TQDictIterator it(m_searchCategories); it.current(); ++it) it.current()->setVisible(false); } } void TreeViewMode::removeItem(const TQString &item, unsigned column) { if(!m_setup) return; TQString itemKey; if(column == PlaylistItem::ArtistColumn) itemKey = "artists" + item; else if(column == PlaylistItem::GenreColumn) itemKey = "genres" + item; else if(column == PlaylistItem::AlbumColumn) itemKey = "albums" + item; else { kdWarning() << k_funcinfo << "Unhandled column type " << column << endl; return; } if(!m_treeViewItems.find(itemKey)) return; TreeViewItemPlaylist *itemPlaylist = m_treeViewItems[itemKey]; if(m_dynamicListsFrozen) { m_pendingItemsToRemove << itemKey; return; } m_treeViewItems.remove(itemKey); itemPlaylist->deleteLater(); emit signalPlaylistDestroyed(itemPlaylist); } void TreeViewMode::addItems(const TQStringList &items, unsigned column) { if(!m_setup) return; TQString searchCategory; if(column == PlaylistItem::ArtistColumn) searchCategory = "artists"; else if(column == PlaylistItem::GenreColumn) searchCategory = "genres"; else if(column == PlaylistItem::AlbumColumn) searchCategory = "albums"; else { kdWarning() << k_funcinfo << "Unhandled column type " << column << endl; return; } TQValueList columns; columns.append(column); PlaylistSearch::Component::MatchMode mode = PlaylistSearch::Component::ContainsWord; if(column != PlaylistItem::ArtistColumn) mode = PlaylistSearch::Component::Exact; PlaylistSearch::ComponentList components; PlaylistList playlists; playlists.append(CollectionList::instance()); TQString itemKey, item; PlaylistBox::Item *itemParent = m_searchCategories[searchCategory]; for(TQStringList::ConstIterator it = items.begin(); it != items.end(); ++it) { item = *it; itemKey = searchCategory + item; if(m_treeViewItems.find(itemKey)) continue; components.clear(); components.append(PlaylistSearch::Component(item, false, columns, mode)); PlaylistSearch s(playlists, components, PlaylistSearch::MatchAny, false); TreeViewItemPlaylist *p = new TreeViewItemPlaylist(playlistBox(), s, item); playlistBox()->setupPlaylist(p, "audio-midi", itemParent); m_treeViewItems.insert(itemKey, p); } } void TreeViewMode::setDynamicListsFrozen(bool frozen) { m_dynamicListsFrozen = frozen; if(frozen) return; TQStringList categories; categories << "artists" << "albums" << "genres"; for(TQStringList::ConstIterator it = m_pendingItemsToRemove.begin(); it != m_pendingItemsToRemove.end(); ++it) { m_treeViewItems[*it]->deleteLater(); m_treeViewItems.remove(*it); } m_pendingItemsToRemove.clear(); } void TreeViewMode::setupDynamicPlaylists() { PlaylistBox::Item *i; PlaylistBox::Item *collectionItem = PlaylistBox::Item::collectionItem(); i = new PlaylistBox::Item(collectionItem, "application-x-cd-image", i18n("Artists")); m_searchCategories.insert("artists", i); i = new PlaylistBox::Item(collectionItem, "application-x-cd-image", i18n("Albums")); m_searchCategories.insert("albums", i); i = new PlaylistBox::Item(collectionItem, "application-x-cd-image", i18n("Genres")); m_searchCategories.insert("genres", i); } //////////////////////////////////////////////////////////////////////////////// // CoverManagerMode //////////////////////////////////////////////////////////////////////////////// CoverManagerMode::CoverManagerMode(PlaylistBox *b) : ViewMode(b) { } #include "viewmode.moc"